code: public StorableIndex<S> findKeyIndex(StorableKey<S> key) {
          if (key == null) {
              throw new IllegalArgumentException();
          }
  
          Set<? extends OrderedProperty<S>> orderedProps = key.getProperties();
  
          Set<StorableProperty<S>> keyProps = new HashSet<StorableProperty<S>>();
          for (OrderedProperty<S> orderedProp : orderedProps) {
              keyProps.add(orderedProp.getChainedProperty().getPrimeProperty());
          }
  
          search: for (StorableIndex<S> index : this) {
              if (!index.isUnique() || index.getPropertyCount() != keyProps.size()) {
                  continue search;
              }
              for (int i=index.getPropertyCount(); --i>=0; ) {
                  if (!keyProps.contains(index.getProperty(i))) {
                      continue search;
                  }
              }
              return index;
          }
  
          return null;
      }
docs: Finds the best index to represent the given key. Should be called after
  calling reduce. As long as the key was added via {@link #addKey addKey},
  this method should never return null.
  
  @throws IllegalArgumentException if key is null