public List<T> toList(int low, int high) {
    List<T> elements = new ArrayList<T>();

    int startWord = low / 32, startBit = low % 32;

    int endWord = high / 32, endBit = high % 32;

    if (low > high) return elements;

    // Do the first word
    {
      int word = bits[startWord];

      int offset = startWord * 32;
      int lastBit = (startWord != endWord) ? 32 : (endBit + 1);

      for (int j = startBit; j < lastBit; j++) {
        if ((word & (1 << j)) != 0) elements.add(map.getObject(offset + j));
      }
    }

    // Do the in between ones
    if (startWord != endWord && startWord + 1 != endWord) {
      for (int i = startWord + 1; i < endWord; i++) {
        int word = bits[i];
        int offset = i * 32;

        for (int j = 0; j < 32; j++) {
          if ((word & (1 << j)) != 0) elements.add(map.getObject(offset + j));
        }
      }
    }

    // Do the last one
    if (startWord != endWord) {
      int word = bits[endWord];
      int offset = endWord * 32;
      int lastBit = endBit + 1;

      for (int j = 0; j < lastBit; j++) {
        if ((word & (1 << j)) != 0) elements.add(map.getObject(offset + j));
      }
    }

    return elements;
  }
  public List<T> toList() {
    List<T> elements = new ArrayList<T>();

    for (int i = 0; i < bits.length; i++) {
      int word = bits[i];
      int offset = i * 32;

      for (int j = 0; j < 32; j++)
        if ((word & (1 << j)) != 0) elements.add(map.getObject(offset + j));
    }

    return elements;
  }