anchor.diff:  [NOTE]
   The results of the first and second callback must be symmetric so that fetching all available items using the first callback returns the number of items indicated by the second callback. Thus if you impose any restrictions on e.g. a database query in the first callback, you must also add the same restrictions for the second callback.
   
  +[NOTE]
  +The second type parameter of `DataProvider` defines how the provider can be filtered. In this case the filter type is `Void`, meaning that it doesn't support filtering. Backend filtering will be covered later in this chapter.
  +
  +[[lazy-sorting]]
   === Sorting
   
   It is not practical to order items based on a [interfacename]#Comparator# when the items are loaded on demand, since it would require all items to be loaded and inspected.
  
positive.code: While each listing component has it's own API for configuring exactly how the data is represented and how it can be manipulated, they all share the same mechanisms for receiving data to show.
  
  The items are generally either loaded directly from memory or lazy loaded from some kind of backend.
  Regardless of how the items are loaded, the component is configured with one or several callbacks or JavaBean property names that define how the item should be displayed.
  
  In the following example, a [classname]#ComboBox# that lists status items is configured to use the [classname]#Status#.[methodname]#getCaption()# method to represent each status.
  There is also a [classname]#Grid#, which is configured with one column from the person's name and another column that converts the year of birth to a string for displaying.
  
  [source, java]
  ----
  ComboBox<Status> comboBox = new ComboBox<>();
  comboBox.setItemCaptionProvider(Status::getCaption);
  
  Grid<Person> grid = new Grid<>();
  grid.addColumn("Name", Person::getName);
  grid.addColumn("Year of birth",
    person -> Integer.toString(person.getYearOfBirth()));
  ----
  
  [NOTE]
  In this example, it would not even be necessary to define any item caption provider for the combo box if [classname]#Status#.[methodname]#toString()# would be implemented to return a suitable text. [classname]#ComboBox# is by default configured to use [methodname]#toString()# for finding a caption to show.
  
  [NOTE]
  The `Year of birth` column will use [classname]#Grid#'s default [classname]#TextRenderer# which requires the column value to be a [classname]#String#. We could for instance use a [classname]#NumberRenderer# instead, and then the renderer would take care of converting the the number according to its configuration.
  
  After we have told the component how the data should be shown, we only need to give it some data to actually show. The easiest way of doing that is as a [interfacename]#java.util.Collection# of item instances.
  
  [source, java]
  ----
  comboBox.setItems(EnumSet.allOf(Status.class));
  
  List<Person> persons = Arrays.asList(
    new Person("George Washington", 1732),
    new Person("John Adams", 1735),
    new Person("Thomas Jefferson", 1743),
    new Person("James Madison", 1751));
  
  grid.setItems(persons);
  ----
  
  Listing components that allow the user to control the display order of the items are automatically able to sort data by any property as long as the property type implements [classname]#Comparable#.
  
negative.code: }
  ----
  
  A data provider using this service could use `String` as its filtering type.
  It would then look for a string to filter by in the query and pass it to the service method.
  
  [source, java]
  ----
  DataProvider<Person, String> dataProvider = new BackEndDataProvider<>(
    query -> {
      // getFilter returns Optional<String>
      String filter = query.getFilter().orElse(null);
      return getPersonService().fetchPersons(
        query.getOffset(),
        query.getLimit(),
        filter
      ).stream();
    },
    query -> {
      String filter = query.getFilter().orElse(null);
      return getPersonService().getPersonCount(filter);
    }
  );
  ----
  