@Test
 public void testNoDuplicatesFilteringIterator() {
   List<Integer> ints = Arrays.asList(1, 2, 2, 40, 100, 40, 101, 2, 3);
   Iterator<Integer> iterator = FilteringIterator.noDuplicates(ints.iterator());
   assertEquals((Integer) 1, iterator.next());
   assertEquals((Integer) 2, iterator.next());
   assertEquals((Integer) 40, iterator.next());
   assertEquals((Integer) 100, iterator.next());
   assertEquals((Integer) 101, iterator.next());
   assertEquals((Integer) 3, iterator.next());
 }
    @Override
    public Iterator<LookupElement> iterator() {
      final Set<LookupElement> processed = newIdentityTroveSet(mySrcSet.size());
      final Set<Collection<LookupElement>> arraysProcessed = newIdentityTroveSet();

      final Iterable<LookupElement> next = myNext.classify(mySource, myContext);
      Iterator<LookupElement> base =
          FilteringIterator.create(next.iterator(), element -> processed.add(element));
      return new FlatteningIterator<LookupElement, LookupElement>(base) {
        @Override
        protected Iterator<LookupElement> createValueIterator(LookupElement element) {
          List<LookupElement> shorter = addShorterElements(myToLift.get(element));
          List<LookupElement> singleton = Collections.singletonList(element);
          if (shorter != null) {
            if (myLifted != null) {
              myLifted.addAll(shorter);
            }
            Iterable<LookupElement> lifted = myNext.classify(shorter, myContext);
            return (myLiftBefore
                    ? ContainerUtil.concat(lifted, singleton)
                    : ContainerUtil.concat(singleton, lifted))
                .iterator();
          }
          return singleton.iterator();
        }

        @Nullable
        private List<LookupElement> addShorterElements(@Nullable Collection<LookupElement> from) {
          List<LookupElement> toLift = null;
          if (from == null) {
            return null;
          }

          if (arraysProcessed.add(from)) {
            for (LookupElement shorterElement : from) {
              if (mySrcSet.contains(shorterElement) && processed.add(shorterElement)) {
                if (toLift == null) {
                  toLift = new ArrayList<>();
                }
                toLift.add(shorterElement);
              }
            }
          }
          return toLift;
        }
      };
    }