@Override
  public final String[] getAttributesForLookup() {
    String[] result = new String[rangedAttributesInNextIteration.size()];
    int index = 0;
    for (String next : rangedAttributesInNextIteration) {
      IncrementalAttributeState state = stateMap.get(next);
      result[index++] = state.getAttributeNameForQuery();
    }

    return result;
  }
  @Override
  public final DefaultIncrementalAttributesMapper mapFromAttributes(Attributes attributes)
      throws NamingException {
    if (!hasMore()) {
      throw new IllegalStateException("No more attributes!");
    }

    // Reset the affected attributes.
    rangedAttributesInNextIteration = new HashSet<String>();

    NamingEnumeration<String> attributeNameEnum = attributes.getIDs();
    while (attributeNameEnum.hasMore()) {
      String attributeName = attributeNameEnum.next();

      String[] attributeNameSplit = attributeName.split(";");
      IncrementalAttributeState state = getState(attributeNameSplit[0]);
      if (attributeNameSplit.length == 1) {
        // No range specification for this attribute
        state.processValues(attributes, attributeName);
      } else {
        for (String option : attributeNameSplit) {
          RangeOption responseRange = RangeOption.parse(option);

          if (responseRange != null) {
            state.processValues(attributes, attributeName);
            state.calculateNextRange(responseRange);
            if (state.hasMore()) {
              rangedAttributesInNextIteration.add(state.getRequestedAttributeName());
            }
          }
        }
      }
    }

    return this;
  }