/**
   * Returns a subset of this map with values that are mapped to keys <code>
   * start</code> through <codE>start+len</code>.
   *
   * @param start Key number from which to start retrieving subset
   * @param len Number of consequetive keys to retrieve their values into the subset
   * @return VIntByteHashMap with values and keys from this map, such that keys' range is <code>
   *     start</code> through <code>start+len</code>
   */
  public VHashMap getSubset(int start, int len) {
    VIntByteHashMap retVal = new VIntByteHashMap(len);

    int[] validKeys = VHashService.getIndicesInRange(start, start + len - 1, this);

    for (int i = 0; i < validKeys.length; i++) {

      retVal.put(validKeys[i] - start, get(validKeys[i]));
    }

    return retVal;
  }
  /**
   * Returns an int to int hashmap that represents a sorted order for the values of this map in the
   * range <code>begin</code> through <code>
   * end</code>.
   *
   * @param begin Key number from which to start retrieving the new order
   * @param end Last key in the section from which to retrieve the new order.
   * @return A VIntIntHashMap with valid keys from the specified section such that for each pair of
   *     keys (i,j) ley (x,y) be their maped values. If (i<=j) then the value that is mapped x is
   *     smaller than or equal to the value that is mapped to y.
   */
  public VIntIntHashMap getSortedOrder(int begin, int end) {

    if (end < begin) {
      return new VIntIntHashMap(0);
    }

    // sorting the valid row numbers
    int[] validKeys = VHashService.getIndicesInRange(begin, end, this);

    // sorting the values
    byte[] values = getValuesInRange(begin, end);

    return getSortedOrder(validKeys, values);
  }
  /**
   * Inserts <code>obj</code> to be mapped to key <code>key<code>. All values
   * mapped to keys <code>key</code> and on will be mapped to a key greater in
   * one.</code></code>
   *
   * @param obj Object to be inserted into the map.
   * @param key The insertion key
   */
  public void insertObject(Object obj, int key) {

    // moving all elements mapped to key through the maximal key
    // to be mapped to a key greater in 1.
    int max = VHashService.getMaxKey(this);
    int[] keysInRange = VHashService.getIndicesInRange(key, max, this);

    for (int i = keysInRange.length - 1; i >= 0; i--) {
      byte removed = remove(keysInRange[i]);
      put(keysInRange[i] + 1, removed);
    }

    // putting the new object in key.
    if (obj != null) {
      put(key, SparseByteColumn.toByte(obj));
    }
  }
  /**
   * Returns the valid values in rows <codE>begin</code> through <codE>end</code>
   *
   * @param begin row number from to begin retrieving of values
   * @param end last row number in the section from which values are retrieved.
   * @return only valid values from rows no. <code>begin</code> through <codE>end</code>, sorted.
   */
  protected Object[] getValuesInRange(int begin, int end) {

    if (end < begin) {
      Object[] retVal = {};
      return retVal;
    }

    int[] indices = VHashService.getIndicesInRange(begin, end, elements);
    Object[] values = new Object[indices.length];
    for (int i = 0; i < indices.length; i++) {
      values[i] = elements.get(indices[i]);
    }
    toComparableArray(values);

    Arrays.sort(values);
    return values;
  }
  /**
   * Returns the values mapped to keys between <code>begin</code> through <code>end</code>, sorted.
   *
   * @param begin Key number from which to begin retrieving of values
   * @param end Greatest key number from which to retrieve value
   * @return Sorted byte array with the values mapped to keys <code>begin
   *         </code> through <code>end</code>.
   */
  public byte[] getValuesInRange(int begin, int end) {

    if (end < begin) {
      byte[] retVal = {};

      return retVal;
    }

    int[] keysInRange = VHashService.getIndicesInRange(begin, end, this);

    if (keysInRange == null) {
      return null;
    }

    byte[] values = new byte[keysInRange.length];

    for (int i = 0; i < keysInRange.length; i++) {
      values[i] = get(keysInRange[i]);
    }

    Arrays.sort(values);

    return values;
  }