title: IndexOutOfBoundException on filtering SimpleAdapter
body: <p>I sub classed <code>SimpleAdapter</code> to add some extra functionality to it, like changing background color, custom views and filtering. The background thing is working out great but the filter isn't. If I use the <code>SimpleFilter</code> provided by the adapter there is no problem at all, so I copied the methods from the source and put them into my adapter. Although I didn't touch anything I'll get a <code>IndexOutOfBoundsException</code> when typing in the search term. Usually on the second or third character.</p>
  
  <p>I copied the whole class but the interesting part is the <code>CustomFilter</code> <code>bindView</code> and <code>getView</code> is working great. After implementing the filter changed it stops working. The exception is caused by data.get(position) in the <code>bindView</code> method on the first line but the problem has to be the filter.</p>
  
  <pre><code>public class ChangingColorAdapter extends SimpleAdapter {
  
      int resource;
      int[] to;
  
      List&lt;Map&lt;String, String&gt;&gt; data, mUnfilteredData;
      String[] from;
  
      Context context;
      Resources res;
      Filter filter;
  
      /*
       * A custom adapter which changes background colors on the elements
       * and implements custom filtering
       */
      public ChangingColorAdapter(Context context,
              List&lt;Map&lt;String, String&gt;&gt; data, int resource, String[] from, int[] to) {
  
          super(context, data, resource, from, to);
          this.context = context;
          this.resource = resource;
          this.data = data;
          this.from = from;
          this.to = to;
          this.res = context.getResources();
  
      }
  
      @Override
      public Filter getFilter() {
          if(filter != null) return filter;
          else return filter = new CustomFilter();
      }
  
      /*
       * A custom filter which is copied from the simplefilter in simpleadapter.
       * Changed word check from .startswith to .contains
       */
      private class CustomFilter extends Filter {
  
          @Override
          protected FilterResults performFiltering(CharSequence prefix) {
              FilterResults results = new FilterResults();
  
              if (mUnfilteredData == null) {
                  mUnfilteredData = new ArrayList&lt;Map&lt;String, String&gt;&gt;(data);
              }
  
              if (prefix == null || prefix.length() == 0) {
                  List&lt;Map&lt;String, String&gt;&gt; list = mUnfilteredData;
                  results.values = list;
                  results.count = list.size();
              } else {
                  String prefixString = prefix.toString().toLowerCase();
  
                  List&lt;Map&lt;String, String&gt;&gt; unfilteredValues = mUnfilteredData;
                  int count = unfilteredValues.size();
  
                  ArrayList&lt;Map&lt;String, ?&gt;&gt; newValues = new ArrayList&lt;Map&lt;String, ?&gt;&gt;(count);
  
                  for (int i = 0; i &lt; count; i++) {
                      Map&lt;String, ?&gt; h = unfilteredValues.get(i);
                      if (h != null) {
  
                          int len = to.length;
  
                          for (int j=0; j&lt;len; j++) {
                              String str =  (String)h.get(from[j]);
  
                              String[] words = str.split(" ");
                              int wordCount = words.length;
  
                              for (int k = 0; k &lt; wordCount; k++) {
                                  String word = words[k];
  
                                  if (word.toLowerCase().contains(prefixString)) {
                                      newValues.add(h);
                                      break;
                                  }
                              }
                          }
                      }
                  }
  
                  results.values = newValues;
                  results.count = newValues.size();
              }
  
              return results;
          }
  
          @SuppressWarnings("unchecked")
          @Override
          protected void publishResults(CharSequence constraint, FilterResults results) {
              data = (List&lt;Map&lt;String, String&gt;&gt;) results.values;
              if (results.count &gt; 0) {
                   notifyDataSetChanged();
              } else {
                   notifyDataSetInvalidated();
              }
          }
      }
  
      @Override
      public View getView(int position, View convertView, ViewGroup parent) {
          View v;
          if (convertView == null) {
              LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
              v = inflater.inflate(resource, parent, false);
          } else {
              v = convertView;
          }
  
          bindView(position, v);
  
          if(position%2!=0) {
              v.setBackgroundColor(Color.DKGRAY);
          }
          else {
              v.setBackgroundColor(Color.BLACK);
          }
  
          return v;
      }
  
      /*
       * Iterate over all elements, check which type the given view is and fill in the data
       */
      private void bindView(int position, View view) {
          final Map&lt;String, String&gt; dataSet = data.get(position);
          if (dataSet == null) {
              return;
          }
  
          final ViewBinder binder = getViewBinder();
          final String[] from = this.from;
          final int[] to = this.to;
          final int count = to.length;
  
          for (int i = 0; i &lt; count; i++) {
              final View v = view.findViewById(to[i]);
              if (v != null) {
                  final Object data = dataSet.get(from[i]);
                  String text = data == null ? "" : data.toString();
                  if (text == null) {
                      text = "";
                  }
  
                  boolean bound = false;
                  if (binder != null) {
                      bound = binder.setViewValue(v, data, text);
                  }
  
                  if (!bound) {
                      if (v instanceof Checkable) {
                          if (data instanceof Boolean) {
                              ((Checkable) v).setChecked((Boolean) data);
                          } else if (v instanceof TextView) {
                              setViewText((TextView) v, text);
                          } else {
                              throw new IllegalStateException(v.getClass().getName() +
                                      " should be bound to a Boolean, not a " +
                                      (data == null ? "&lt;unknown type&gt;" : data.getClass()));
                          }
                      } else if (v instanceof TermView) {
                          if(text.length()==10) {
                              int year = Integer.parseInt(text.substring(0,4));
                              if(text.substring(5, 7).equals("04")) {
                                  setViewText((TextView) v, res.getString(R.string.summerterm) + " " + year);
                              }
                              else {
                                  setViewText((TextView) v, res.getString(R.string.winterterm) + " " + year + "/" + (year+1));
                              }   
                          }
                          else {
                              setViewText((TextView) v, text);
                          }
                      } else if (v instanceof TextView) {
                          setViewText((TextView) v, text);
                      } else if (v instanceof ImageView) {
                          if (data instanceof Integer) {
                              setViewImage((ImageView) v, (Integer) data);                            
                          } else {
                              setViewImage((ImageView) v, text);
                          }
                      } else {
                          throw new IllegalStateException(v.getClass().getName() + " is not a " +
                                  " view that can be bounds by this SimpleAdapter");
                      }
                  }
              }
          }
      }
  }
  </code></pre>