private List<OIdentifiable> applyTailIndexes(final Object lastIndexResult) {
    final OIndex<?> beforeTheLastIndex = indexChain.get(indexChain.size() - 2);
    Set<Comparable> currentKeys = prepareKeys(beforeTheLastIndex, lastIndexResult);

    for (int j = indexChain.size() - 2; j > 0; j--) {
      final OIndex<?> currentIndex = indexChain.get(j);
      final OIndex<?> nextIndex = indexChain.get(j - 1);

      final Set<Comparable> newKeys;
      if (isComposite(currentIndex)) {
        newKeys = new TreeSet<Comparable>();
        for (Comparable currentKey : currentKeys) {
          final List<OIdentifiable> currentResult = getFromCompositeIndex(currentKey, currentIndex);
          newKeys.addAll(prepareKeys(nextIndex, currentResult));
        }
      } else {
        final OIndexCursor cursor = currentIndex.iterateEntries(currentKeys, true);
        final List<OIdentifiable> keys = cursorToList(cursor);
        newKeys = prepareKeys(nextIndex, keys);
      }

      updateStatistic(currentIndex);

      currentKeys = newKeys;
    }

    return applyFirstIndex(currentKeys);
  }
  private List<OIdentifiable> applyFirstIndex(Collection<Comparable> currentKeys) {
    final List<OIdentifiable> result;
    if (isComposite(firstIndex)) {
      result = new ArrayList<OIdentifiable>();
      for (Comparable key : currentKeys) {
        result.addAll(getFromCompositeIndex(key, firstIndex));
      }
    } else {
      final OIndexCursor cursor = firstIndex.iterateEntries(currentKeys, true);

      result = cursorToList(cursor);
    }

    updateStatistic(firstIndex);

    return result;
  }
 @Override
 public OIndexCursor iterateEntries(Collection<?> keys, boolean ascSortOrder) {
   final OIndexCursor internalCursor = lastIndex.iterateEntries(keys, ascSortOrder);
   return new ExternalIndexCursor(internalCursor);
 }