@Test
 public void flattenImmediateDisposeThrewNPE() {
   MyObject a = new MyObject("a");
   from.add(a);
   initForFlattenTest().dispose();
   assertEquals("[a]", from.toString());
 }
 @Test
 public void flattenRemoveWithoutAddThrewNPE() {
   MyObject a = new MyObject("a");
   from.add(a);
   initForFlattenTest();
   from.remove(a);
   assertTrue(from.isEmpty());
 }
  @Test
  public void sortInitial() {
    from.add(new MyObject("a"));
    from.add(new MyObject("c"));
    from.add(new MyObject("b"));

    createSortTransformer().transform(from, toList);

    assertEquals("[a, b, c]", toList.toString());
  }
 @Test
 public void flatten() {
   Transformation<ObservableCollection<MyObject>, ObservableCollection<MyObject>> transformation =
       initForFlattenTest();
   MyObject a = new MyObject("a");
   from.add(a);
   from.remove(a);
   transformation.dispose();
   assertTrue(from.isEmpty());
 }
  @Test
  public void filterHandling() {
    Transformers.filter(IS_A).transform(from, to);
    MyObject objectB = new MyObject("b");

    from.add(new MyObject("a"));
    from.add(objectB);
    from.remove(objectB);

    assertEquals("[a]", "" + to);
  }
  @Test
  public void filterInitial() {
    from.add(new MyObject("a"));
    from.add(new MyObject("b"));

    Transformers.filter(IS_A).transform(from, to);

    assertEquals("[a]", "" + to);
  }
 private Transformation<ObservableCollection<MyObject>, ObservableCollection<MyObject>>
     initForFlattenTest() {
   to.add(new MyObject("b"));
   to.add(new MyObject("c"));
   Function<MyObject, ObservableCollection<MyObject>> selector =
       new Function<MyObject, ObservableCollection<MyObject>>() {
         @Override
         public ObservableCollection<MyObject> apply(MyObject source) {
           return to;
         }
       };
   return Transformers.flatten(selector).transform(from, to);
 }
  @Test
  public void flattenWithTransformer() {
    Function<MyObject, ObservableCollection<String>> f =
        new Function<MyObject, ObservableCollection<String>>() {
          @Override
          public ObservableCollection<String> apply(MyObject input) {
            ObservableHashSet<String> s = new ObservableHashSet<>();
            s.add(input.name.get() + "1");
            s.add(input.name.get() + "2");
            return s;
          }
        };

    Transformer<ObservableCollection<String>, ObservableCollection<MyObject>> t =
        Transformers.oneToOne(
            new Function<String, MyObject>() {
              @Override
              public MyObject apply(String input) {
                return new MyObject(input);
              }
            },
            new Function<MyObject, String>() {
              @Override
              public String apply(MyObject input) {
                return input.name.get();
              }
            });

    Transformer<ObservableCollection<MyObject>, ObservableCollection<MyObject>> flatten =
        Transformers.flatten(f, t);
    from.add(new MyObject("a"));

    flatten.transform(from, to);
    assertTrue(to.size() == 2);

    from.add(new MyObject("b"));
    assertTrue(to.size() == 4);
  }
  @Test
  public void sortWithTwoTransformsRegistrationDisposeBug() {
    Transformer<ObservableCollection<MyObject>, ObservableList<MyObject>> trans =
        createSortTransformer();

    Transformation<ObservableCollection<MyObject>, ObservableList<MyObject>> transformation =
        trans.transform(new ObservableArrayList<MyObject>());

    trans.transform(from, toList);

    transformation.dispose();

    from.add(new MyObject("a"));

    assertEquals("[a]", toList.toString());
  }
 public static <ItemT> ObservableSet<ItemT> toObservable(Set<ItemT> s) {
   ObservableSet<ItemT> result = new ObservableHashSet<>();
   result.addAll(s);
   return result;
 }