@Test
  public void testOrderBy() throws Exception {
    Matcher matcher = createMatcher();

    final List<Comparable[]> sortProjections = new ArrayList<Comparable[]>();

    String queryString1 =
        "from org.infinispan.objectfilter.test.model.Person p where p.age > 18 order by p.name, p.surname";
    FilterSubscription filterSubscription =
        matcher.registerFilter(
            queryString1,
            new FilterCallback() {
              @Override
              public void onFilterResult(
                  Object userContext,
                  Object instance,
                  Object eventType,
                  Object[] projection,
                  Comparable[] sortProjection) {
                sortProjections.add(sortProjection);
              }
            });

    matcher.match(null, createPerson1(), null);
    matcher.match(null, createPerson2(), null);

    assertEquals(2, sortProjections.size());

    Collections.sort(sortProjections, filterSubscription.getComparator());

    assertEquals("Cat", sortProjections.get(0)[0]);
    assertEquals("Woman", sortProjections.get(0)[1]);
    assertEquals("John", sortProjections.get(1)[0]);
    assertEquals("Batman", sortProjections.get(1)[1]);
  }
  @Test
  public void testDuplicateProjections() throws Exception {
    String queryString =
        "select p.name, p.name, p.address.postCode from org.infinispan.objectfilter.test.model.Person p where p.name = 'John'";

    Matcher matcher = createMatcher();
    Object person = createPerson1();

    final List<Object[]> result = new ArrayList<Object[]>();

    FilterSubscription filterSubscription =
        matcher.registerFilter(
            queryString,
            new FilterCallback() {
              @Override
              public void onFilterResult(
                  Object userContext,
                  Object instance,
                  Object eventType,
                  Object[] projection,
                  Comparable[] sortProjection) {
                result.add(projection);
              }
            });

    assertNotNull(filterSubscription.getProjection());
    assertEquals(3, filterSubscription.getProjection().length);
    assertEquals("name", filterSubscription.getProjection()[0]);
    assertEquals("name", filterSubscription.getProjection()[1]);
    assertEquals("address.postCode", filterSubscription.getProjection()[2]);

    matcher.match(null, person, null);

    matcher.unregisterFilter(filterSubscription);

    assertEquals(1, result.size());
    assertEquals(3, result.get(0).length);
    assertEquals("John", result.get(0)[0]);
    assertEquals("John", result.get(0)[1]);
    assertEquals("SW12345", result.get(0)[2]);
  }
  @Test
  public void testProjectionOnRepeatedAttribute() throws Exception {
    String queryString =
        "select p.address.postCode, p.phoneNumbers.number from org.infinispan.objectfilter.test.model.Person p where p.name = 'John'";

    Matcher matcher = createMatcher();
    Object person = createPerson1();

    final List<Object[]> result = new ArrayList<Object[]>();

    FilterSubscription filterSubscription =
        matcher.registerFilter(
            queryString,
            new FilterCallback() {
              @Override
              public void onFilterResult(
                  Object userContext,
                  Object instance,
                  Object eventType,
                  Object[] projection,
                  Comparable[] sortProjection) {
                result.add(projection);
              }
            });

    assertNotNull(filterSubscription.getProjection());
    assertEquals(2, filterSubscription.getProjection().length);
    assertEquals("address.postCode", filterSubscription.getProjection()[0]);
    assertEquals("phoneNumbers.number", filterSubscription.getProjection()[1]);

    matcher.match(null, person, null);

    matcher.unregisterFilter(filterSubscription);

    assertEquals(1, result.size());
    assertEquals(2, result.get(0).length);
    assertEquals("SW12345", result.get(0)[0]);
    // todo [anistor] it is unclear what whe should expect here...
    assertEquals("0040888888", result.get(0)[1]); // expect the first phone number
  }