String.  
 * For a given range of text, a beginning and ending index,
 * as well as a current index are defined.  These values can be queried
 * by the methods in this interface.  Additionally, various methods allow
 * the index to be set. 
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Tom Tromey StringCharacterIterator to iterate over the entire
   * text of the specified String.  The initial index
   * value will be set to the first character in the string.
   *
   * @param text The String to iterate through.
   */
  public StringCharacterIterator (String text)
  {
    this (text, 0, text.length (), 0);
  }
  /*************************************************************************/
  /**
   * This method initializes a new instance of
   * StringCharacterIterator to iterate over the entire
   * text of the specified String.  The initial index
   * value will be set to the specified value.
   *
   * @param text The String to iterate through.
   * @param index The initial index position.
   */
  public StringCharacterIterator (String text, int index)
  {
    this (text, 0, text.length (), index);
  }
  /*************************************************************************/
  /**
   * This method initializes a new instance of
   * StringCharacterIterator that iterates over the text
   * in a subrange of the specified String.  The
   * beginning and end of the range are specified by the caller, as is
   * the initial index position.
   *
   * @param text The String to iterate through.
   * @param begin The beginning position in the character range.
   * @param end The ending position in the character range.
   * @param index The initial index position.
   *
   * @param IllegalArgumentException If any of the range values are
   * invalid.
   */
  public StringCharacterIterator (String text, int begin, int end, int index)
  {
    int len = text.length ();
    if ((begin < 0) || (begin > len))
      throw new IllegalArgumentException ("Bad begin position");
    if ((end < begin) || (end > len))
      throw new IllegalArgumentException ("Bad end position");
    if ((index < begin) || (index > end))
      throw new IllegalArgumentException ("Bad initial index position");
    this.text = text;
    this.begin = begin;
    this.end = end;
    this.index = index;
  }
  /**
   * This is a package level constructor that copies the text out of
   * an existing StringCharacterIterator and resets the beginning and
   * ending index.
   *
   * @param scci The StringCharacterIterator to copy the info from
   * @param begin The beginning index of the range we are interested in.
   * @param end The ending index of the range we are interested in.
   */
  StringCharacterIterator (StringCharacterIterator sci, int begin, int end)
  {
    this (sci.text, begin, end, begin);
  }
  /**
   * This method returns the character at the current index position
   *
   * @return The character at the current index position.
   */
  public char current ()
  {
    return (index < end) ? text.charAt (index) : DONE;
  }
  /*************************************************************************/
  /**
   * This method increments the current index and then returns the
   * character at the new index value.  If the index is already at
   * getEndIndex () - 1, it will not be incremented.
   *
   * @return The character at the position of the incremented index
   * value, or DONE if the index has reached
   * getEndIndex () - 1.
   */
  public char next ()
  {
    if (index == end)
      return DONE;
    ++index;
    return current ();
  }
  /*************************************************************************/
  /**
   * This method decrements the current index and then returns the
   * character at the new index value.  If the index value is already
   * at the beginning index, it will not be decremented.
   *
   * @return The character at the position of the decremented index
   * value, or DONE if index was already equal to the
   * beginning index value.
   */
  public char previous ()
  {
    if (index == begin)
      return DONE;
    --index;
    return current ();
  }
  /*************************************************************************/
  /**
   * This method sets the index value to the beginning of the range and returns
   * the character there.
   *
   * @return The character at the beginning of the range, or
   * DONE if the range is empty. 
   */
  public char first ()
  {
    index = begin;
    return current ();
  }
  /*************************************************************************/
  /**
   * This method sets the index value to getEndIndex () - 1 and
   * returns the character there.  If the range is empty, then the index value
   * will be set equal to the beginning index.
   *
   * @return The character at the end of the range, or
   * DONE if the range is empty. 
   */
  public char last ()
  {
    if (end == begin)
      return DONE;
    index = end - 1;
    return current ();
  }
  /*************************************************************************/
  /**
   * This method returns the current value of the index.
   *
   * @return The current index value
   */
  public int getIndex ()
  {
    return index;
  }
  /*************************************************************************/
  /**
   * This method sets the value of the index to the specified value, then
   * returns the character at that position.
   *
   * @param index The new index value.
   *
   * @return The character at the new index value or DONE
   * if the index value is equal to getEndIndex. 
   *
   * @exception IllegalArgumentException If the specified index is not valid
   */
  public char setIndex (int index)
  {
    if ((index < begin) || (index > end))
      throw new IllegalArgumentException ("Bad index specified");
    this.index = index;
    return current ();
  }
  /*************************************************************************/
  /**
   * This method returns the character position of the first character in the
   * range.
   *
   * @return The index of the first character in the range.
   */
  public int getBeginIndex ()
  {
    return begin;
  }
  /*************************************************************************/
  /**
   * This method returns the character position of the end of the text range.
   * This will actually be the index of the first character following the
   * end of the range.  In the event the text range is empty, this will be
   * equal to the first character in the range.
   *
   * @return The index of the end of the range.
   */
  public int getEndIndex ()
  {
    return end;
  }
  /*************************************************************************/
  /**
   * This method creates a copy of this CharacterIterator.
   *
   * @return A copy of this CharacterIterator.
   */
  public Object clone ()
  {
    return new StringCharacterIterator (text, begin, end, index);
  }
  /*************************************************************************/
  /**
   * This method tests this object for equality againt the specified 
   * object.  This will be true if and only if the specified object:
   * *
null.StringCharacterIteratortrue if the specified object is equal to this
   * object, false otherwise.
   */
  public boolean equals (Object obj)
  {
    if (! (obj instanceof StringCharacterIterator))
      return false;
    StringCharacterIterator sci = (StringCharacterIterator) obj;
    return (begin == sci.begin
	    && end == sci.end
	    && index == sci.index
	    && text.equals (sci.text));
  }
  /*************************************************************************/
  /**
   * This method allows other classes in java.text to change the value
   * of the underlying text being iterated through.
   *
   * @param text The new String to iterate through.
   */
  public void setText (String text)
  {
    this.text = text;
    this.begin = 0;
    this.end = text.length ();
    this.index = 0;
  }
}