/*
 * Copyright 2000-2009 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * @author max
 */
package com.intellij.ui.speedSearch;

import com.intellij.openapi.util.Condition;
import com.intellij.ui.CollectionListModel;

import javax.swing.*;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import java.util.ArrayList;
import java.util.List;

/**
 * @author max
 */
public class FilteringListModel<T> extends AbstractListModel {
  private final ListModel myOriginalModel;
  private final List<T> myData = new ArrayList<>();
  private Condition<T> myCondition = null;


  private final ListDataListener myListDataListener = new ListDataListener() {
    @Override
    public void contentsChanged(ListDataEvent e) {
      refilter();
    }

    @Override
    public void intervalAdded(ListDataEvent e) {
      refilter();
    }

    @Override
    public void intervalRemoved(ListDataEvent e) {
      refilter();
    }
  };

  public FilteringListModel(ListModel originalModel) {
    myOriginalModel = originalModel;
    myOriginalModel.addListDataListener(myListDataListener);
  }

  protected FilteringListModel(JList list) {
    this(list.getModel());
    list.setModel(this);
  }

  public void dispose() {
    myOriginalModel.removeListDataListener(myListDataListener);
  }

  public void setFilter(Condition<T> condition) {
    myCondition = condition;
    refilter();
  }

  private void removeAllElements() {
    int index1 = myData.size() - 1;
    if (index1 >= 0) {
      myData.clear();
      fireIntervalRemoved(this, 0, index1);
    }
  }

  public void refilter() {
    removeAllElements();
    int count = 0;
    for (int i = 0; i < myOriginalModel.getSize(); i++) {
      final T elt = (T)myOriginalModel.getElementAt(i);
      if (passElement(elt)) {
        addToFiltered(elt);
        count++;
      }
    }

    if (count > 0) {
      fireIntervalAdded(this, 0, count - 1);
    }
  }

  protected void addToFiltered(T elt) {
    myData.add(elt);
  }

  @Override
  public int getSize() {
    return myData.size();
  }

  @Override
  public T getElementAt(int index) {
    return myData.get(index);
  }

  public int getElementIndex(T element) {
    return myData.indexOf(element);
  }

  private boolean passElement(T element) {
    return myCondition == null || myCondition.value(element);
  }

  public boolean contains(T value) {
    return myData.contains(value);
  }

  public ListModel getOriginalModel() {
    return myOriginalModel;
  }

  public void addAll(List elements) {
    myData.addAll(elements);
    ((CollectionListModel)myOriginalModel).add(elements);
  }

  public void replaceAll(List elements) {
    myData.clear();
    myData.addAll(elements);
    ((CollectionListModel)myOriginalModel).replaceAll(elements);
  }

  public void remove(int index) {
    ((DefaultListModel)myOriginalModel).removeElement(myData.get(index));
  }
}

@@ -984,16 +984,19 @@
 istModel
+%3CT%3E
  %7B%0A  pri
@@ -1015,16 +1015,19 @@
 istModel
+%3CT%3E
  myOrigi
@@ -1108,16 +1108,24 @@
 ndition%3C
+? super 
 T%3E myCon
@@ -1530,16 +1530,19 @@
 istModel
+%3CT%3E
  origina
@@ -1690,16 +1690,19 @@
 el(JList
+%3CT%3E
  list) %7B
@@ -1888,16 +1888,24 @@
 ndition%3C
+? super 
 T%3E condi
@@ -2288,11 +2288,8 @@
 t = 
-(T)
 myOr
@@ -3062,32 +3062,35 @@
 void addAll(List
+%3CT%3E
  elements) %7B%0A   
@@ -3132,32 +3132,35 @@
 lectionListModel
+%3CT%3E
 )myOriginalModel
@@ -3210,16 +3210,19 @@
 All(List
+%3CT%3E
  element
@@ -3292,32 +3292,35 @@
 lectionListModel
+%3CT%3E
 )myOriginalModel
@@ -3404,16 +3404,19 @@
 istModel
+%3CT%3E
 )myOrigi

Fix missing type parameter