private <X extends Element> Iterator<X> iteratorList(final Iterator<X> iterator) {
   final List<X> list = new ArrayList<>();
   while (iterator.hasNext()) {
     final X e = iterator.next();
     if (HasContainer.testAll(e, this.hasContainers)) list.add(e);
   }
   return list.iterator();
 }
  /**
   * Gets an iterator over those vertices/edges that have the specific IDs wanted, or those that
   * have indexed properties with the wanted values, or failing that by just getting all of the
   * vertices or edges.
   *
   * @param getElementsByIds Function that will return an iterator over all the vertices/edges in
   *     the graph that have the specific IDs
   * @param getElementsByIndex Function that returns a stream of all the vertices/edges in the graph
   *     that have an indexed property with a specific value
   * @param getAllElements Function that returns an iterator of all the vertices or all the edges
   *     (i.e. full scan)
   * @return An iterator for all the vertices/edges for this step
   */
  private <ElementType extends Element> Iterator<? extends ElementType> elements(
      BiFunction<OrientGraph, Object[], Iterator<ElementType>> getElementsByIds,
      TriFunction<OrientGraph, OIndex<Object>, Iterator<Object>, Stream<? extends ElementType>>
          getElementsByIndex,
      Function<OrientGraph, Iterator<ElementType>> getAllElements) {
    final OrientGraph graph = getGraph();

    if (this.ids != null && this.ids.length > 0) {
      /** Got some element IDs, so just get the elements using those */
      return this.iteratorList(getElementsByIds.apply(graph, this.ids));
    } else {
      /** Have no element IDs. See if there's an indexed property to use */
      Set<OrientIndexQuery> indexQueryOptions = findIndex();

      if (!indexQueryOptions.isEmpty()) {
        List<ElementType> elements = new ArrayList<>();

        indexQueryOptions.forEach(
            indexQuery -> {
              OLogManager.instance().debug(this, "using " + indexQuery);
              Stream<? extends ElementType> indexedElements =
                  getElementsByIndex.apply(graph, indexQuery.index, indexQuery.values);
              elements.addAll(
                  indexedElements
                      .filter(element -> HasContainer.testAll(element, this.hasContainers))
                      .collect(Collectors.<ElementType>toList()));
            });

        return elements.iterator();
      } else {
        OLogManager.instance()
            .warn(
                this,
                "scanning through all elements without using an index for Traversal "
                    + getTraversal());
        return this.iteratorList(getAllElements.apply(graph));
      }
    }
  }