// Path: vaadin-grid-util/src/main/java/org/vaadin/gridutil/cell/filter/BetweenFilter.java
// public class BetweenFilter<T extends Comparable<? super T>> implements SerializablePredicate<Comparable<T>> {
//     private final T startValue;
//     private final T endValue;
// 
//     public BetweenFilter(T startValue, T endValue) {
//         this.startValue = startValue;
//         this.endValue = endValue;
//     }
// 
//     @Override
//     public boolean test(Comparable<T> value) {
//         if (value == null) {
//             return startValue == null && endValue == null;
//         }
//         return isAfterStart(value) && isBeforeEnd(value);
//     }
// 
//     private boolean isAfterStart(final Comparable<T> value) {
//         return startValue == null || value.compareTo(startValue) >= 0;
//     }
// 
//     private boolean isBeforeEnd(final Comparable<T> value) {
//         return endValue == null || value.compareTo(endValue) <= 0;
//     }
// 
// }
// 
// Path: vaadin-grid-util/src/main/java/org/vaadin/gridutil/cell/filter/EqualFilter.java
// public class EqualFilter<T> implements SerializablePredicate<T> {
// 
//     final T toCompare;
// 
//     public EqualFilter(T toCompare) {
//         this.toCompare = toCompare;
//     }
// 
//     @Override
//     public boolean test(T value) {
//         if (value == null && toCompare == null) {
//             return true;
//         }
//         if (value == null || toCompare == null) {
//             return false;
//         }
//         return value.equals(toCompare);
//     }
// }
// 
// Path: vaadin-grid-util/src/main/java/org/vaadin/gridutil/cell/filter/SimpleStringFilter.java
// public class SimpleStringFilter implements SerializablePredicate<String> {
// 
//     final String filterString;
//     final boolean ignoreCase;
//     final boolean onlyMatchPrefix;
// 
//     public SimpleStringFilter(String filterString, boolean ignoreCase, boolean onlyMatchPrefix) {
//         this.ignoreCase = ignoreCase;
//         // ignoreCase has to be applied to filterstring too, otherwise uppercase input won't work
//         this.filterString = this.ignoreCase ? filterString.toLowerCase() : filterString;
//         this.onlyMatchPrefix = onlyMatchPrefix;
//     }
// 
//     @Override
//     public boolean test(String value) {
//         if (filterString == null || value == null) {
//             return false;
//         }
//         final String v = ignoreCase ? value.toString()
//                 .toLowerCase()
//                 : value.toString();
// 
//         if (onlyMatchPrefix) {
//             if (!v.startsWith(filterString)) {
//                 return false;
//             }
//         } else {
//             if (!v.contains(filterString)) {
//                 return false;
//             }
//         }
//         return true;
//     }
// }


import com.vaadin.data.BeanPropertySet;
import com.vaadin.data.PropertySet;
import com.vaadin.data.ValueProvider;
import com.vaadin.data.converter.LocalDateToDateConverter;
import com.vaadin.data.provider.InMemoryDataProviderHelpers;
import com.vaadin.data.provider.ListDataProvider;
import com.vaadin.icons.VaadinIcons;
import com.vaadin.server.FontIcon;
import com.vaadin.server.SerializablePredicate;
import com.vaadin.server.Sizeable.Unit;
import com.vaadin.shared.ui.ValueChangeMode;
import com.vaadin.ui.*;
import com.vaadin.ui.components.grid.HeaderRow;
import com.vaadin.ui.themes.ValoTheme;
import org.vaadin.gridutil.cell.filter.BetweenFilter;
import org.vaadin.gridutil.cell.filter.EqualFilter;
import org.vaadin.gridutil.cell.filter.SimpleStringFilter;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.Map.Entry;
     * @param columnId        id of property
     * @param ignoreCase      property of SimpleStringFilter
     * @param onlyMatchPrefix property of SimpleStringFilter
     * @return CellFilterComponent that contains TextField
     */
    public CellFilterComponent<TextField> setTextFilter(String columnId, boolean ignoreCase, boolean onlyMatchPrefix) {
        return setTextFilter(columnId, ignoreCase, onlyMatchPrefix, null);
    }

    /**
     * assign a <b>SimpleStringFilter</b> to grid for given columnId<br>
     * could also be used for NumberField when you would like to do filter by startWith for example
     *
     * @param columnId        id of property
     * @param ignoreCase      property of SimpleStringFilter
     * @param onlyMatchPrefix property of SimpleStringFilter
     * @param inputPrompt     hint for user
     * @return CellFilterComponent that contains TextField
     */
    public CellFilterComponent<TextField> setTextFilter(String columnId, boolean ignoreCase, boolean onlyMatchPrefix, String inputPrompt) {
        CellFilterComponent<TextField> filter = new CellFilterComponent<TextField>() {

            TextField textField = new TextField();

            String currentValue = "";

            public void triggerUpdate() {
                if (currentValue == null || currentValue.isEmpty()) {
                    removeFilter(columnId);
                } else {
// Path: vaadin-grid-util/src/main/java/org/vaadin/gridutil/cell/filter/BetweenFilter.java
// public class BetweenFilter<T extends Comparable<? super T>> implements SerializablePredicate<Comparable<T>> {
//     private final T startValue;
//     private final T endValue;
// 
//     public BetweenFilter(T startValue, T endValue) {
//         this.startValue = startValue;
//         this.endValue = endValue;
//     }
// 
//     @Override
//     public boolean test(Comparable<T> value) {
//         if (value == null) {
//             return startValue == null && endValue == null;
//         }
//         return isAfterStart(value) && isBeforeEnd(value);
//     }
// 
//     private boolean isAfterStart(final Comparable<T> value) {
//         return startValue == null || value.compareTo(startValue) >= 0;
//     }
// 
//     private boolean isBeforeEnd(final Comparable<T> value) {
//         return endValue == null || value.compareTo(endValue) <= 0;
//     }
// 
// }
// 
// Path: vaadin-grid-util/src/main/java/org/vaadin/gridutil/cell/filter/EqualFilter.java
// public class EqualFilter<T> implements SerializablePredicate<T> {
// 
//     final T toCompare;
// 
//     public EqualFilter(T toCompare) {
//         this.toCompare = toCompare;
//     }
// 
//     @Override
//     public boolean test(T value) {
//         if (value == null && toCompare == null) {
//             return true;
//         }
//         if (value == null || toCompare == null) {
//             return false;
//         }
//         return value.equals(toCompare);
//     }
// }
// 
// Path: vaadin-grid-util/src/main/java/org/vaadin/gridutil/cell/filter/SimpleStringFilter.java
// public class SimpleStringFilter implements SerializablePredicate<String> {
// 
//     final String filterString;
//     final boolean ignoreCase;
//     final boolean onlyMatchPrefix;
// 
//     public SimpleStringFilter(String filterString, boolean ignoreCase, boolean onlyMatchPrefix) {
//         this.ignoreCase = ignoreCase;
//         // ignoreCase has to be applied to filterstring too, otherwise uppercase input won't work
//         this.filterString = this.ignoreCase ? filterString.toLowerCase() : filterString;
//         this.onlyMatchPrefix = onlyMatchPrefix;
//     }
// 
//     @Override
//     public boolean test(String value) {
//         if (filterString == null || value == null) {
//             return false;
//         }
//         final String v = ignoreCase ? value.toString()
//                 .toLowerCase()
//                 : value.toString();
// 
//         if (onlyMatchPrefix) {
//             if (!v.startsWith(filterString)) {
//                 return false;
//             }
//         } else {
//             if (!v.contains(filterString)) {
//                 return false;
//             }
//         }
//         return true;
//     }
// }


// Path: vaadin-grid-util/src/main/java/org/vaadin/gridutil/cell/GridCellFilter.java
import com.vaadin.data.BeanPropertySet;
import com.vaadin.data.PropertySet;
import com.vaadin.data.ValueProvider;
import com.vaadin.data.converter.LocalDateToDateConverter;
import com.vaadin.data.provider.InMemoryDataProviderHelpers;
import com.vaadin.data.provider.ListDataProvider;
import com.vaadin.icons.VaadinIcons;
import com.vaadin.server.FontIcon;
import com.vaadin.server.SerializablePredicate;
import com.vaadin.server.Sizeable.Unit;
import com.vaadin.shared.ui.ValueChangeMode;
import com.vaadin.ui.*;
import com.vaadin.ui.components.grid.HeaderRow;
import com.vaadin.ui.themes.ValoTheme;
import org.vaadin.gridutil.cell.filter.BetweenFilter;
import org.vaadin.gridutil.cell.filter.EqualFilter;
import org.vaadin.gridutil.cell.filter.SimpleStringFilter;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.Map.Entry;

     * @param columnId        id of property
     * @param ignoreCase      property of SimpleStringFilter
     * @param onlyMatchPrefix property of SimpleStringFilter
     * @return CellFilterComponent that contains TextField
     */
    public CellFilterComponent<TextField> setTextFilter(String columnId, boolean ignoreCase, boolean onlyMatchPrefix) {
        return setTextFilter(columnId, ignoreCase, onlyMatchPrefix, null);
    }

    /**
     * assign a <b>SimpleStringFilter</b> to grid for given columnId<br>
     * could also be used for NumberField when you would like to do filter by startWith for example
     *
     * @param columnId        id of property
     * @param ignoreCase      property of SimpleStringFilter
     * @param onlyMatchPrefix property of SimpleStringFilter
     * @param inputPrompt     hint for user
     * @return CellFilterComponent that contains TextField
     */
    public CellFilterComponent<TextField> setTextFilter(String columnId, boolean ignoreCase, boolean onlyMatchPrefix, String inputPrompt) {
        CellFilterComponent<TextField> filter = new CellFilterComponent<TextField>() {

            TextField textField = new TextField();

            String currentValue = "";

            public void triggerUpdate() {
                if (currentValue == null || currentValue.isEmpty()) {
                    removeFilter(columnId);
                } else {
                    replaceFilter(new SimpleStringFilter(currentValue, ignoreCase, onlyMatchPrefix), columnId);