/**
   * This method returns an instance of <code>CollationKey</code> for the specified <code>String
   * </code>. The object returned will have a more efficient mechanism for its comparison function
   * that could provide speed benefits if multiple comparisons are performed, such as during a sort.
   *
   * @param source The <code>String</code> to create a <code>CollationKey</code> for.
   * @return A <code>CollationKey</code> for the specified <code>String</code>.
   */
  public CollationKey getCollationKey(String source) {
    CollationElementIterator cei = getCollationElementIterator(source);
    ArrayList vect = new ArrayList();

    int ord = cei.next();
    cei.reset(); // set to start of string

    while (ord != CollationElementIterator.NULLORDER) {
      // If the primary order is null, it means this is an ignorable
      // character.
      if (CollationElementIterator.primaryOrder(ord) == 0) {
        ord = cei.next();
        continue;
      }
      switch (getStrength()) {
        case PRIMARY:
          ord = CollationElementIterator.primaryOrder(ord);
          break;

        case SECONDARY:
          ord = CollationElementIterator.primaryOrder(ord) << 8;
          ord |= CollationElementIterator.secondaryOrder(ord);

        default:
          break;
      }

      vect.add(new Integer(ord));
      ord = cei.next(); // increment to next key
    }

    Object[] objarr = vect.toArray();
    byte[] key = new byte[objarr.length * 4];

    for (int i = 0; i < objarr.length; i++) {
      int j = ((Integer) objarr[i]).intValue();
      key[i * 4] = (byte) ((j & 0xFF000000) >> 24);
      key[i * 4 + 1] = (byte) ((j & 0x00FF0000) >> 16);
      key[i * 4 + 2] = (byte) ((j & 0x0000FF00) >> 8);
      key[i * 4 + 3] = (byte) (j & 0x000000FF);
    }

    return new CollationKey(this, source, key);
  }
  /**
   * This method returns an integer which indicates whether the first specified <code>String</code>
   * is less than, greater than, or equal to the second. The value depends not only on the collation
   * rules in effect, but also the strength and decomposition settings of this object.
   *
   * @param source The first <code>String</code> to compare.
   * @param target A second <code>String</code> to compare to the first.
   * @return A negative integer if source &lt; target, a positive integer if source &gt; target, or
   *     0 if source == target.
   */
  public int compare(String source, String target) {
    CollationElementIterator cs, ct;
    CollationElement ord1block = null;
    CollationElement ord2block = null;
    boolean advance_block_1 = true;
    boolean advance_block_2 = true;

    cs = getCollationElementIterator(source);
    ct = getCollationElementIterator(target);

    for (; ; ) {
      int ord1;
      int ord2;

      /*
       * We have to check whether the characters are ignorable.
       * If it is the case then forget them.
       */
      if (advance_block_1) {
        ord1block = cs.nextBlock();
        if (ord1block != null && ord1block.ignore) continue;
      }

      if (advance_block_2) {
        ord2block = ct.nextBlock();
        if (ord2block != null && ord2block.ignore) {
          advance_block_1 = false;
          continue;
        }
      } else advance_block_2 = true;

      if (!advance_block_1) advance_block_1 = true;

      if (ord1block != null) ord1 = ord1block.getValue();
      else {
        if (ord2block == null) return 0;
        return -1;
      }

      if (ord2block == null) return 1;

      ord2 = ord2block.getValue();

      // We know chars are totally equal, so skip
      if (ord1 == ord2) {
        if (getStrength() == IDENTICAL)
          if (!ord1block.key.equals(ord2block.key)) return ord1block.key.compareTo(ord2block.key);
        continue;
      }

      // Check for primary strength differences
      int prim1 = CollationElementIterator.primaryOrder(ord1);
      int prim2 = CollationElementIterator.primaryOrder(ord2);

      if (prim1 == 0 && getStrength() < TERTIARY) {
        advance_block_2 = false;
        continue;
      } else if (prim2 == 0 && getStrength() < TERTIARY) {
        advance_block_1 = false;
        continue;
      }

      if (prim1 < prim2) return -1;
      else if (prim1 > prim2) return 1;
      else if (getStrength() == PRIMARY) continue;

      // Check for secondary strength differences
      int sec1 = CollationElementIterator.secondaryOrder(ord1);
      int sec2 = CollationElementIterator.secondaryOrder(ord2);

      if (sec1 < sec2) return -1;
      else if (sec1 > sec2) return 1;
      else if (getStrength() == SECONDARY) continue;

      // Check for tertiary differences
      int tert1 = CollationElementIterator.tertiaryOrder(ord1);
      int tert2 = CollationElementIterator.tertiaryOrder(ord2);

      if (tert1 < tert2) return -1;
      else if (tert1 > tert2) return 1;
      else if (getStrength() == TERTIARY) continue;

      // Apparently JDK does this (at least for my test case).
      return ord1block.key.compareTo(ord2block.key);
    }
  }