/**
  * Make type conversion of keys for specific index.
  *
  * @param index - index for which keys prepared for.
  * @param keys - which should be prepared.
  * @return keys converted to necessary type.
  */
 private Set<Comparable> prepareKeys(OIndex<?> index, Object keys) {
   final OIndexDefinition indexDefinition = index.getDefinition();
   if (keys instanceof Collection) {
     final Set<Comparable> newKeys = new TreeSet<Comparable>();
     for (Object o : ((Collection) keys)) {
       newKeys.add((Comparable) indexDefinition.createValue(o));
     }
     return newKeys;
   } else {
     return Collections.singleton((Comparable) indexDefinition.createValue(keys));
   }
 }
  private static Iterable<List<OIndex<?>>> getIndexesForChain(
      OClass iSchemaClass, OSQLFilterItemField.FieldChain fieldChain) {
    List<OIndex<?>> baseIndexes = prepareBaseIndexes(iSchemaClass, fieldChain);

    if (baseIndexes == null) return Collections.emptyList();

    Collection<OIndex<?>> lastIndexes = prepareLastIndexVariants(iSchemaClass, fieldChain);

    Collection<List<OIndex<?>>> result = new ArrayList<List<OIndex<?>>>();
    for (OIndex<?> lastIndex : lastIndexes) {
      final List<OIndex<?>> indexes = new ArrayList<OIndex<?>>(fieldChain.getItemCount());
      indexes.addAll(baseIndexes);
      indexes.add(lastIndex);

      result.add(indexes);
    }

    return result;
  }
 private OChainedIndexProxy(List<OIndex<?>> indexChain) {
   this.firstIndex = (OIndex<T>) indexChain.get(0);
   this.indexChain = Collections.unmodifiableList(indexChain);
   lastIndex = indexChain.get(indexChain.size() - 1);
 }