/* gnu/regexp/RE.java
   Copyright (C) 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package gnu.java.util.regex;

import gnu.java.lang.CPStringBuilder;

import java.io.InputStream;
import java.io.Serializable;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

/**
 * RE provides the user interface for compiling and matching regular
 * expressions.
 * <P>
 * A regular expression object (class RE) is compiled by constructing it
 * from a String, StringBuffer or character array, with optional
 * compilation flags (below)
 * and an optional syntax specification (see RESyntax; if not specified,
 * <code>RESyntax.RE_SYNTAX_PERL5</code> is used).
 * <P>
 * Once compiled, a regular expression object is reusable as well as
 * threadsafe: multiple threads can use the RE instance simultaneously
 * to match against different input text.
 * <P>
 * Various methods attempt to match input text against a compiled
 * regular expression.  These methods are:
 * <LI><code>isMatch</code>: returns true if the input text in its
 * entirety matches the regular expression pattern.
 * <LI><code>getMatch</code>: returns the first match found in the
 * input text, or null if no match is found.
 * <LI><code>getAllMatches</code>: returns an array of all
 * non-overlapping matches found in the input text.  If no matches are
 * found, the array is zero-length.
 * <LI><code>substitute</code>: substitute the first occurence of the
 * pattern in the input text with a replacement string (which may
 * include metacharacters $0-$9, see REMatch.substituteInto).
 * <LI><code>substituteAll</code>: same as above, but repeat for each
 * match before returning.
 * <LI><code>getMatchEnumeration</code>: returns an REMatchEnumeration
 * object that allows iteration over the matches (see
 * REMatchEnumeration for some reasons why you may want to do this
 * instead of using <code>getAllMatches</code>.
 * <P>
 *
 * These methods all have similar argument lists.  The input can be a
 * CharIndexed, String, a character array, a StringBuffer, or an
 * InputStream of some sort.  Note that when using an
 * InputStream, the stream read position cannot be guaranteed after
 * attempting a match (this is not a bug, but a consequence of the way
 * regular expressions work).  Using an REMatchEnumeration can
 * eliminate most positioning problems.
 *
 * Although the input object can be of various types, it is recommended
 * that it should be a CharIndexed because {@link CharIndexed#getLastMatch()}
 * can show the last match found on this input, which helps the expression
 * \G work as the end of the previous match.
 *
 * <P>
 *
 * The optional index argument specifies the offset from the beginning
 * of the text at which the search should start (see the descriptions
 * of some of the execution flags for how this can affect positional
 * pattern operators).  For an InputStream, this means an
 * offset from the current read position, so subsequent calls with the
 * same index argument on an InputStream will not
 * necessarily access the same position on the stream, whereas
 * repeated searches at a given index in a fixed string will return
 * consistent results.
 *
 * <P>
 * You can optionally affect the execution environment by using a
 * combination of execution flags (constants listed below).
 *
 * <P>
 * All operations on a regular expression are performed in a
 * thread-safe manner.
 *
 * @author <A HREF="mailto:wes@cacas.org">Wes Biggs</A>
 * @version 1.1.5-dev, to be released
 */

public class RE extends REToken
{

  private static final class IntPair implements Serializable
  {
    public int first, second;
  }

  private static final class CharUnit implements Serializable
  {
    public char ch;
    public boolean bk;
  }

  // This String will be returned by getVersion()
  private static final String VERSION = "1.1.5-dev";

  // The localized strings are kept in a separate file
  // Used by getLocalizedMessage().
  private static ResourceBundle messages;

  // Name of the bundle that contains the localized messages.
  private static final String bundle = "gnu/java/util/regex/MessagesBundle";

  // These are, respectively, the first and last tokens in our linked list
  // If there is only one token, firstToken == lastToken
  private REToken firstToken, lastToken;

  // This is the number of subexpressions in this regular expression,
  // with a minimum value of zero.  Returned by getNumSubs()
  private int numSubs;

    /** Minimum length, in characters, of any possible match. */
  private int minimumLength;
  private int maximumLength;

  /**
   * Compilation flag. Do  not  differentiate  case.   Subsequent
   * searches  using  this  RE will be case insensitive.
   */
  public static final int REG_ICASE = 0x02;

  /**
   * Compilation flag. The match-any-character operator (dot)
   * will match a newline character.  When set this overrides the syntax
   * bit RE_DOT_NEWLINE (see RESyntax for details).  This is equivalent to
   * the "/s" operator in Perl.
   */
  public static final int REG_DOT_NEWLINE = 0x04;

  /**
   * Compilation flag. Use multiline mode.  In this mode, the ^ and $
   * anchors will match based on newlines within the input. This is
   * equivalent to the "/m" operator in Perl.
   */
  public static final int REG_MULTILINE = 0x08;

  /**
   * Execution flag.
   * The match-beginning operator (^) will not match at the beginning
   * of the input string. Useful for matching on a substring when you
   * know the context of the input is such that position zero of the
   * input to the match test is not actually position zero of the text.
   * <P>
   * This example demonstrates the results of various ways of matching on
   * a substring.
   * <P>
   * <CODE>
   * String s = "food bar fool";<BR>
   * RE exp = new RE("^foo.");<BR>
   * REMatch m0 = exp.getMatch(s);<BR>
   * REMatch m1 = exp.getMatch(s.substring(8));<BR>
   * REMatch m2 = exp.getMatch(s.substring(8),0,RE.REG_NOTBOL); <BR>
   * REMatch m3 = exp.getMatch(s,8);                            <BR>
   * REMatch m4 = exp.getMatch(s,8,RE.REG_ANCHORINDEX);         <BR>
   * <P>
   * // Results:<BR>
   * //  m0.toString(): "food"<BR>
   * //  m1.toString(): "fool"<BR>
   * //  m2.toString(): null<BR>
   * //  m3.toString(): null<BR>
   * //  m4.toString(): "fool"<BR>
   * </CODE>
   */
  public static final int REG_NOTBOL = 0x10;

  /**
   * Execution flag.
   * The match-end operator ($) does not match at the end
   * of the input string. Useful for matching on substrings.
   */
  public static final int REG_NOTEOL = 0x20;

  /**
   * Execution flag.
   * When a match method is invoked that starts matching at a non-zero
   * index into the input, treat the input as if it begins at the index
   * given.  The effect of this flag is that the engine does not "see"
   * any text in the input before the given index.  This is useful so
   * that the match-beginning operator (^) matches not at position 0
   * in the input string, but at the position the search started at
   * (based on the index input given to the getMatch function).  See
   * the example under REG_NOTBOL.  It also affects the use of the \&lt;
   * and \b operators.
   */
  public static final int REG_ANCHORINDEX = 0x40;

  /**
   * Execution flag.
   * The substitute and substituteAll methods will not attempt to
   * interpolate occurrences of $1-$9 in the replacement text with
   * the corresponding subexpressions.  For example, you may want to
   * replace all matches of "one dollar" with "$1".
   */
  public static final int REG_NO_INTERPOLATE = 0x80;

  /**
   * Execution flag.
   * Try to match the whole input string. An implicit match-end operator
   * is added to this regexp.
   */
  public static final int REG_TRY_ENTIRE_MATCH = 0x0100;

  /**
   * Execution flag.
   * The substitute and substituteAll methods will treat the
   * character '\' in the replacement as an escape to a literal
   * character. In this case "\n", "\$", "\\", "\x40" and "\012"
   * will become "n", "$", "\", "x40" and "012" respectively.
   * This flag has no effect if REG_NO_INTERPOLATE is set on.
   */
  public static final int REG_REPLACE_USE_BACKSLASHESCAPE = 0x0200;

  /**
   * Compilation flag. Allow whitespace and comments in pattern.
   * This is equivalent to the "/x" operator in Perl.
   */
  public static final int REG_X_COMMENTS = 0x0400;

  /**
   * Compilation flag. If set, REG_ICASE is effective only for US-ASCII.
   */
  public static final int REG_ICASE_USASCII = 0x0800;

  /**
   * Execution flag.
   * Do not move the position at which the search begins.  If not set,
   * the starting position will be moved until a match is found.
   */
  public static final int REG_FIX_STARTING_POSITION = 0x1000;

  /** Returns a string representing the version of the gnu.regexp package. */
  public static final String version ()
  {
    return VERSION;
  }

  // Retrieves a message from the ResourceBundle
  static final String getLocalizedMessage (String key)
  {
    if (messages == null)
      messages =
        PropertyResourceBundle.getBundle (bundle, Locale.getDefault ());
    return messages.getString (key);
  }

  /**
   * Constructs a regular expression pattern buffer without any compilation
   * flags set, and using the default syntax (RESyntax.RE_SYNTAX_PERL5).
   *
   * @param pattern A regular expression pattern, in the form of a String,
   *   StringBuffer or char[].  Other input types will be converted to
   *   strings using the toString() method.
   * @exception REException The input pattern could not be parsed.
   * @exception NullPointerException The pattern was null.
   */
  public RE (Object pattern) throws REException
  {
    this (pattern, 0, RESyntax.RE_SYNTAX_PERL5, 0, 0);
  }

  /**
   * Constructs a regular expression pattern buffer using the specified
   * compilation flags and the default syntax (RESyntax.RE_SYNTAX_PERL5).
   *
   * @param pattern A regular expression pattern, in the form of a String,
   *   StringBuffer, or char[].  Other input types will be converted to
   *   strings using the toString() method.
   * @param cflags The logical OR of any combination of the compilation flags listed above.
   * @exception REException The input pattern could not be parsed.
   * @exception NullPointerException The pattern was null.
   */
  public RE (Object pattern, int cflags) throws REException
  {
    this (pattern, cflags, RESyntax.RE_SYNTAX_PERL5, 0, 0);
  }

  /**
   * Constructs a regular expression pattern buffer using the specified
   * compilation flags and regular expression syntax.
   *
   * @param pattern A regular expression pattern, in the form of a String,
   *   StringBuffer, or char[].  Other input types will be converted to
   *   strings using the toString() method.
   * @param cflags The logical OR of any combination of the compilation flags listed above.
   * @param syntax The type of regular expression syntax to use.
   * @exception REException The input pattern could not be parsed.
   * @exception NullPointerException The pattern was null.
   */
  public RE (Object pattern, int cflags, RESyntax syntax) throws REException
  {
    this (pattern, cflags, syntax, 0, 0);
  }

  // internal constructor used for alternation
  private RE (REToken first, REToken last, int subs, int subIndex,
              int minLength, int maxLength)
  {
    super (subIndex);
    firstToken = first;
    lastToken = last;
    numSubs = subs;
    minimumLength = minLength;
    maximumLength = maxLength;
    addToken (new RETokenEndSub (subIndex));
  }

  private RE (Object patternObj, int cflags, RESyntax syntax, int myIndex,
              int nextSub) throws REException
  {
    super (myIndex);            // Subexpression index of this token.
    initialize (patternObj, cflags, syntax, myIndex, nextSub);
  }

  // For use by subclasses
  protected RE ()
  {
    super (0);
  }

  // The meat of construction
  protected void initialize (Object patternObj, int cflags, RESyntax syntax,
                             int myIndex, int nextSub) throws REException
  {
    char[] pattern;
    if (patternObj instanceof String)
      {
        pattern = ((String) patternObj).toCharArray ();
      }
    else if (patternObj instanceof char[])
      {
        pattern = (char[]) patternObj;
      }
    else if (patternObj instanceof StringBuffer)
      {
        pattern = new char[((StringBuffer) patternObj).length ()];
        ((StringBuffer) patternObj).getChars (0, pattern.length, pattern, 0);
      }
    else if (patternObj instanceof StringBuilder)
      {
        pattern = new char[((StringBuilder) patternObj).length ()];
        ((StringBuilder) patternObj).getChars (0, pattern.length, pattern, 0);
      }
    else if (patternObj instanceof CPStringBuilder)
      {
        pattern = new char[((CPStringBuilder) patternObj).length ()];
        ((CPStringBuilder) patternObj).getChars (0, pattern.length, pattern,
                                                 0);
      }
    else
      {
        pattern = patternObj.toString ().toCharArray ();
      }

    int pLength = pattern.length;

    numSubs = 0;                // Number of subexpressions in this token.
    ArrayList < REToken > branches = null;

    // linked list of tokens (sort of -- some closed loops can exist)
    firstToken = lastToken = null;

    // Precalculate these so we don't pay for the math every time we
    // need to access them.
    boolean insens = ((cflags & REG_ICASE) > 0);
    boolean insensUSASCII = ((cflags & REG_ICASE_USASCII) > 0);

    // Parse pattern into tokens.  Does anyone know if it's more efficient
    // to use char[] than a String.charAt()?  I'm assuming so.

    // index tracks the position in the char array
    int index = 0;

    // this will be the current parse character (pattern[index])
    CharUnit unit = new CharUnit ();

    // This is used for {x,y} calculations
    IntPair minMax = new IntPair ();

    // Buffer a token so we can create a TokenRepeated, etc.
    REToken currentToken = null;
    boolean quot = false;

    // Saved syntax and flags.
    RESyntax savedSyntax = null;
    int savedCflags = 0;
    boolean flagsSaved = false;

    while (index < pLength)
      {
        // read the next character unit (including backslash escapes)
        index = getCharUnit (pattern, index, unit, quot);

        if (unit.bk)
          if (unit.ch == 'Q')
            {
              quot = true;
              continue;
            }
          else if (unit.ch == 'E')
            {
              quot = false;
              continue;
            }
        if (quot)
          unit.bk = false;

        if (((cflags & REG_X_COMMENTS) > 0) && (!unit.bk) && (!quot))
          {
            if (Character.isWhitespace (unit.ch))
              {
                continue;
              }
            if (unit.ch == '#')
              {
                for (int i = index; i < pLength; i++)
                  {
                    if (pattern[i] == '\n')
                      {
                        index = i + 1;
                        continue;
                      }
                    else if (pattern[i] == '\r')
                      {
                        if (i + 1 < pLength && pattern[i + 1] == '\n')
                          {
                            index = i + 2;
                          }
                        else
                          {
                            index = i + 1;
                          }
                        continue;
                      }
                  }
                index = pLength;
                continue;
              }
          }

        // ALTERNATION OPERATOR
        //  \| or | (if RE_NO_BK_VBAR) or newline (if RE_NEWLINE_ALT)
        //  not available if RE_LIMITED_OPS is set

        // TODO: the '\n' literal here should be a test against REToken.newline,
        // which unfortunately may be more than a single character.
        if (((unit.ch == '|'
              && (syntax.get (RESyntax.RE_NO_BK_VBAR) ^ (unit.bk || quot)))
             || (syntax.get (RESyntax.RE_NEWLINE_ALT) && (unit.ch == '\n')
                 && !(unit.bk || quot)))
            && !syntax.get (RESyntax.RE_LIMITED_OPS))
          {
            // make everything up to here be a branch. create vector if nec.
            addToken (currentToken);
            RE theBranch =
              new RE (firstToken, lastToken, numSubs, subIndex, minimumLength,
                      maximumLength);
            minimumLength = 0;
            maximumLength = 0;
            if (branches == null)
              {
                branches = new ArrayList < REToken > ();
              }
            branches.add (theBranch);
            firstToken = lastToken = currentToken = null;
          }

        // INTERVAL OPERATOR:
        //  {x} | {x,} | {x,y}  (RE_INTERVALS && RE_NO_BK_BRACES)
        //  \{x\} | \{x,\} | \{x,y\} (RE_INTERVALS && !RE_NO_BK_BRACES)
        //
        // OPEN QUESTION:
        //  what is proper interpretation of '{' at start of string?
        //
        // This method used to check "repeat.empty.token" to avoid such regexp
        // as "(a*){2,}", but now "repeat.empty.token" is allowed.

        else if ((unit.ch == '{') && syntax.get (RESyntax.RE_INTERVALS)
                 && (syntax.
                     get (RESyntax.RE_NO_BK_BRACES) ^ (unit.bk || quot)))
          {
            int newIndex = getMinMax (pattern, index, minMax, syntax);
            if (newIndex > index)
              {
                if (minMax.first > minMax.second)
                  throw new
                    REException (getLocalizedMessage ("interval.order"),
                                 REException.REG_BADRPT, newIndex);
                if (currentToken == null)
                  throw new
                    REException (getLocalizedMessage ("repeat.no.token"),
                                 REException.REG_BADRPT, newIndex);
                if (currentToken instanceof RETokenRepeated)
                  throw new
                    REException (getLocalizedMessage ("repeat.chained"),
                                 REException.REG_BADRPT, newIndex);
                if (currentToken instanceof RETokenWordBoundary
                    || currentToken instanceof RETokenWordBoundary)
                  throw new
                    REException (getLocalizedMessage ("repeat.assertion"),
                                 REException.REG_BADRPT, newIndex);
                index = newIndex;
                currentToken =
                  setRepeated (currentToken, minMax.first, minMax.second,
                               index);
              }
            else
              {
                addToken (currentToken);
                currentToken = new RETokenChar (subIndex, unit.ch, insens);
                if (insensUSASCII)
                  currentToken.unicodeAware = false;
              }
          }

        // LIST OPERATOR:
        //  [...] | [^...]

        else if ((unit.ch == '[') && !(unit.bk || quot))
          {
            // Create a new RETokenOneOf
            ParseCharClassResult result =
              parseCharClass (subIndex, pattern, index, pLength, cflags,
                              syntax, 0);
            addToken (currentToken);
            currentToken = result.token;
            index = result.index;
          }

        // SUBEXPRESSIONS
        //  (...) | \(...\) depending on RE_NO_BK_PARENS

        else if ((unit.ch == '(')
                 && (syntax.
                     get (RESyntax.RE_NO_BK_PARENS) ^ (unit.bk || quot)))
          {
            boolean pure = false;
            boolean comment = false;
            boolean lookAhead = false;
            boolean lookBehind = false;
            boolean independent = false;
            boolean negativelh = false;
            boolean negativelb = false;
            if ((index + 1 < pLength) && (pattern[index] == '?'))
              {
                switch (pattern[index + 1])
                  {
                  case '!':
                    if (syntax.get (RESyntax.RE_LOOKAHEAD))
                      {
                        pure = true;
                        negativelh = true;
                        lookAhead = true;
                        index += 2;
                      }
                    break;
                  case '=':
                    if (syntax.get (RESyntax.RE_LOOKAHEAD))
                      {
                        pure = true;
                        lookAhead = true;
                        index += 2;
                      }
                    break;
                  case '<':
                    // We assume that if the syntax supports look-ahead,
                    // it also supports look-behind.
                    if (syntax.get (RESyntax.RE_LOOKAHEAD))
                      {
                        index++;
                        switch (pattern[index + 1])
                          {
                          case '!':
                            pure = true;
                            negativelb = true;
                            lookBehind = true;
                            index += 2;
                            break;
                          case '=':
                            pure = true;
                            lookBehind = true;
                            index += 2;
                          }
                      }
                    break;
                  case '>':
                    // We assume that if the syntax supports look-ahead,
                    // it also supports independent group.
                    if (syntax.get (RESyntax.RE_LOOKAHEAD))
                      {
                        pure = true;
                        independent = true;
                        index += 2;
                      }
                    break;
                  case 'i':
                  case 'd':
                  case 'm':
                  case 's':
                  case 'u':
                  case 'x':
                  case '-':
                    if (!syntax.get (RESyntax.RE_EMBEDDED_FLAGS))
                      break;
                    // Set or reset syntax flags.
                    int flagIndex = index + 1;
                    int endFlag = -1;
                    RESyntax newSyntax = new RESyntax (syntax);
                    int newCflags = cflags;
                    boolean negate = false;
                    while (flagIndex < pLength && endFlag < 0)
                      {
                        switch (pattern[flagIndex])
                          {
                          case 'i':
                            if (negate)
                              newCflags &= ~REG_ICASE;
                            else
                              newCflags |= REG_ICASE;
                            flagIndex++;
                            break;
                          case 'd':
                            if (negate)
                              newSyntax.setLineSeparator (RESyntax.
                                                          DEFAULT_LINE_SEPARATOR);
                            else
                              newSyntax.setLineSeparator ("\n");
                            flagIndex++;
                            break;
                          case 'm':
                            if (negate)
                              newCflags &= ~REG_MULTILINE;
                            else
                              newCflags |= REG_MULTILINE;
                            flagIndex++;
                            break;
                          case 's':
                            if (negate)
                              newCflags &= ~REG_DOT_NEWLINE;
                            else
                              newCflags |= REG_DOT_NEWLINE;
                            flagIndex++;
                            break;
                          case 'u':
                            if (negate)
                              newCflags |= REG_ICASE_USASCII;
                            else
                              newCflags &= ~REG_ICASE_USASCII;
                            flagIndex++;
                            break;
                          case 'x':
                            if (negate)
                              newCflags &= ~REG_X_COMMENTS;
                            else
                              newCflags |= REG_X_COMMENTS;
                            flagIndex++;
                            break;
                          case '-':
                            negate = true;
                            flagIndex++;
                            break;
                          case ':':
                          case ')':
                            endFlag = pattern[flagIndex];
                            break;
                          default:
                            throw new
                              REException (getLocalizedMessage
                                           ("repeat.no.token"),
                                           REException.REG_BADRPT, index);
                          }
                      }
                    if (endFlag == ')')
                      {
                        syntax = newSyntax;
                        cflags = newCflags;
                        insens = ((cflags & REG_ICASE) > 0);
                        insensUSASCII = ((cflags & REG_ICASE_USASCII) > 0);
                        // This can be treated as though it were a comment.
                        comment = true;
                        index = flagIndex - 1;
                        break;
                      }
                    if (endFlag == ':')
                      {
                        savedSyntax = syntax;
                        savedCflags = cflags;
                        flagsSaved = true;
                        syntax = newSyntax;
                        cflags = newCflags;
                        insens = ((cflags & REG_ICASE) > 0);
                        insensUSASCII = ((cflags & REG_ICASE_USASCII) > 0);
                        index = flagIndex - 1;
                        // Fall through to the next case.
                      }
                    else
                      {
                        throw new
                          REException (getLocalizedMessage
                                       ("unmatched.paren"),
                                       REException.REG_ESUBREG, index);
                      }
                  case ':':
                    if (syntax.get (RESyntax.RE_PURE_GROUPING))
                      {
                        pure = true;
                        index += 2;
                      }
                    break;
                  case '#':
                    if (syntax.get (RESyntax.RE_COMMENTS))
                      {
                        comment = true;
                      }
                    break;
                  default:
                    throw new
                      REException (getLocalizedMessage ("repeat.no.token"),
                                   REException.REG_BADRPT, index);
                  }
              }

            if (index >= pLength)
              {
                throw new
                  REException (getLocalizedMessage ("unmatched.paren"),
                               REException.REG_ESUBREG, index);
              }

            // find end of subexpression
            int endIndex = index;
            int nextIndex = index;
            int nested = 0;

            while (((nextIndex =
                     getCharUnit (pattern, endIndex, unit, false)) > 0)
                   && !(nested == 0 && (unit.ch == ')')
                        && (syntax.
                            get (RESyntax.RE_NO_BK_PARENS) ^ (unit.bk
                                                              || quot))))
              {
                if ((endIndex = nextIndex) >= pLength)
                  throw new
                    REException (getLocalizedMessage ("subexpr.no.end"),
                                 REException.REG_ESUBREG, nextIndex);
                else
              if ((unit.ch == '[') && !(unit.bk || quot))
                {
                  // I hate to do something similar to the LIST OPERATOR matters
                  // above, but ...
                  int listIndex = nextIndex;
                  if (listIndex < pLength && pattern[listIndex] == '^')
                    listIndex++;
                  if (listIndex < pLength && pattern[listIndex] == ']')
                    listIndex++;
                  int listEndIndex = -1;
                  int listNest = 0;
                  while (listIndex < pLength && listEndIndex < 0)
                    {
                      switch (pattern[listIndex++])
                        {
                        case '\\':
                          listIndex++;
                          break;
                        case '[':
                          // Sun's API document says that regexp like "[a-d[m-p]]"
                          // is legal. Even something like "[[[^]]]]" is accepted.
                          listNest++;
                          if (listIndex < pLength
                              && pattern[listIndex] == '^')
                            listIndex++;
                          if (listIndex < pLength
                              && pattern[listIndex] == ']')
                            listIndex++;
                          break;
                        case ']':
                          if (listNest == 0)
                            listEndIndex = listIndex;
                          listNest--;
                          break;
                        }
                    }
                  if (listEndIndex >= 0)
                    {
                      nextIndex = listEndIndex;
                      if ((endIndex = nextIndex) >= pLength)
                        throw new
                          REException (getLocalizedMessage ("subexpr.no.end"),
                                       REException.REG_ESUBREG, nextIndex);
                      else
                      continue;
                    }
                  throw new
                    REException (getLocalizedMessage ("subexpr.no.end"),
                                 REException.REG_ESUBREG, nextIndex);
                }
              else if (unit.ch == '('
                       && (syntax.
                           get (RESyntax.RE_NO_BK_PARENS) ^ (unit.bk
                                                             || quot)))
                nested++;
              else if (unit.ch == ')'
                       && (syntax.
                           get (RESyntax.RE_NO_BK_PARENS) ^ (unit.bk
                                                             || quot)))
                nested--;
              }

            // endIndex is now position at a ')','\)'
            // nextIndex is end of string or position after ')' or '\)'

            if (comment)
              index = nextIndex;
            else
              {                 // not a comment
                // create RE subexpression as token.
                addToken (currentToken);
                if (!pure)
                  {
                    numSubs++;
                  }

                int useIndex = (pure || lookAhead || lookBehind
                                || independent) ? 0 : nextSub + numSubs;
                currentToken =
                  new RE (String.valueOf (pattern, index, endIndex - index).
                          toCharArray (), cflags, syntax, useIndex,
                          nextSub + numSubs);
                numSubs += ((RE) currentToken).getNumSubs ();

                if (lookAhead)
                  {
                    currentToken =
                      new RETokenLookAhead (currentToken, negativelh);
                  }
                else if (lookBehind)
                  {
                    currentToken =
                      new RETokenLookBehind (currentToken, negativelb);
                  }
                else if (independent)
                  {
                    currentToken = new RETokenIndependent (currentToken);
                  }

                index = nextIndex;
                if (flagsSaved)
                  {
                    syntax = savedSyntax;
                    cflags = savedCflags;
                    insens = ((cflags & REG_ICASE) > 0);
                    insensUSASCII = ((cflags & REG_ICASE_USASCII) > 0);
                    flagsSaved = false;
                  }
              }                 // not a comment
          }                     // subexpression

        // UNMATCHED RIGHT PAREN
        // ) or \) throw exception if
        // !syntax.get(RESyntax.RE_UNMATCHED_RIGHT_PAREN_ORD)
        else if (!syntax.get (RESyntax.RE_UNMATCHED_RIGHT_PAREN_ORD)
                 && ((unit.ch == ')')
                     && (syntax.
                         get (RESyntax.RE_NO_BK_PARENS) ^ (unit.bk || quot))))
          {
            throw new REException (getLocalizedMessage ("unmatched.paren"),
                                   REException.REG_EPAREN, index);
          }

        // START OF LINE OPERATOR
        //  ^

        else if ((unit.ch == '^') && !(unit.bk || quot))
          {
            addToken (currentToken);
            currentToken = null;
            RETokenStart token = null;
            if ((cflags & REG_MULTILINE) > 0)
              {
                String sep = syntax.getLineSeparator ();
                if (sep == null)
                  {
                    token = new RETokenStart (subIndex, null, true);
                  }
                else
                  {
                    token = new RETokenStart (subIndex, sep);
                  }
              }
            else
              {
                token = new RETokenStart (subIndex, null);
              }
            addToken (token);
          }

        // END OF LINE OPERATOR
        //  $

        else if ((unit.ch == '$') && !(unit.bk || quot))
          {
            addToken (currentToken);
            currentToken = null;
            RETokenEnd token = null;
            if ((cflags & REG_MULTILINE) > 0)
              {
                String sep = syntax.getLineSeparator ();
                if (sep == null)
                  {
                    token = new RETokenEnd (subIndex, null, true);
                  }
                else
                  {
                    token = new RETokenEnd (subIndex, sep);
                  }
              }
            else
              {
                token = new RETokenEnd (subIndex, null);
              }
            addToken (token);
          }

        // MATCH-ANY-CHARACTER OPERATOR (except possibly newline and null)
        //  .

        else if ((unit.ch == '.') && !(unit.bk || quot))
          {
            addToken (currentToken);
            currentToken =
              new RETokenAny (subIndex, syntax.get (RESyntax.RE_DOT_NEWLINE)
                              || ((cflags & REG_DOT_NEWLINE) > 0),
                              syntax.get (RESyntax.RE_DOT_NOT_NULL));
          }

        // ZERO-OR-MORE REPEAT OPERATOR
        //  *
        //
        // This method used to check "repeat.empty.token" to avoid such regexp
        // as "(a*)*", but now "repeat.empty.token" is allowed.

        else if ((unit.ch == '*') && !(unit.bk || quot))
          {
            if (currentToken == null)
              throw new REException (getLocalizedMessage ("repeat.no.token"),
                                     REException.REG_BADRPT, index);
            if (currentToken instanceof RETokenRepeated)
              throw new REException (getLocalizedMessage ("repeat.chained"),
                                     REException.REG_BADRPT, index);
            if (currentToken instanceof RETokenWordBoundary
                || currentToken instanceof RETokenWordBoundary)
              throw new REException (getLocalizedMessage ("repeat.assertion"),
                                     REException.REG_BADRPT, index);
            currentToken =
              setRepeated (currentToken, 0, Integer.MAX_VALUE, index);
          }

        // ONE-OR-MORE REPEAT OPERATOR / POSSESSIVE MATCHING OPERATOR
        //  + | \+ depending on RE_BK_PLUS_QM
        //  not available if RE_LIMITED_OPS is set
        //
        // This method used to check "repeat.empty.token" to avoid such regexp
        // as "(a*)+", but now "repeat.empty.token" is allowed.

        else if ((unit.ch == '+') && !syntax.get (RESyntax.RE_LIMITED_OPS)
                 && (!syntax.
                     get (RESyntax.RE_BK_PLUS_QM) ^ (unit.bk || quot)))
          {
            if (currentToken == null)
              throw new REException (getLocalizedMessage ("repeat.no.token"),
                                     REException.REG_BADRPT, index);

            // Check for possessive matching on RETokenRepeated
            if (currentToken instanceof RETokenRepeated)
              {
                RETokenRepeated tokenRep = (RETokenRepeated) currentToken;
                if (syntax.get (RESyntax.RE_POSSESSIVE_OPS)
                    && !tokenRep.isPossessive () && !tokenRep.isStingy ())
                  tokenRep.makePossessive ();
                else
                  throw new
                    REException (getLocalizedMessage ("repeat.chained"),
                                 REException.REG_BADRPT, index);

              }
            else if (currentToken instanceof RETokenWordBoundary
                     || currentToken instanceof RETokenWordBoundary)
              throw new REException (getLocalizedMessage ("repeat.assertion"),
                                     REException.REG_BADRPT, index);
            else
            currentToken =
              setRepeated (currentToken, 1, Integer.MAX_VALUE, index);
          }

        // ZERO-OR-ONE REPEAT OPERATOR / STINGY MATCHING OPERATOR
        //  ? | \? depending on RE_BK_PLUS_QM
        //  not available if RE_LIMITED_OPS is set
        //  stingy matching if RE_STINGY_OPS is set and it follows a quantifier

        else if ((unit.ch == '?') && !syntax.get (RESyntax.RE_LIMITED_OPS)
                 && (!syntax.
                     get (RESyntax.RE_BK_PLUS_QM) ^ (unit.bk || quot)))
          {
            if (currentToken == null)
              throw new REException (getLocalizedMessage ("repeat.no.token"),
                                     REException.REG_BADRPT, index);

            // Check for stingy matching on RETokenRepeated
            if (currentToken instanceof RETokenRepeated)
              {
                RETokenRepeated tokenRep = (RETokenRepeated) currentToken;
                if (syntax.get (RESyntax.RE_STINGY_OPS)
                    && !tokenRep.isStingy () && !tokenRep.isPossessive ())
                  tokenRep.makeStingy ();
                else
                  throw new
                    REException (getLocalizedMessage ("repeat.chained"),
                                 REException.REG_BADRPT, index);
              }
            else if (currentToken instanceof RETokenWordBoundary
                     || currentToken instanceof RETokenWordBoundary)
              throw new REException (getLocalizedMessage ("repeat.assertion"),
                                     REException.REG_BADRPT, index);
            else
            currentToken = setRepeated (currentToken, 0, 1, index);
          }

        // OCTAL CHARACTER
        //  \0377

        else if (unit.bk && (unit.ch == '0')
                 && syntax.get (RESyntax.RE_OCTAL_CHAR))
          {
            CharExpression ce =
              getCharExpression (pattern, index - 2, pLength, syntax);
            if (ce == null)
              throw new REException ("invalid octal character",
                                     REException.REG_ESCAPE, index);
            index = index - 2 + ce.len;
            addToken (currentToken);
            currentToken = new RETokenChar (subIndex, ce.ch, insens);
            if (insensUSASCII)
              currentToken.unicodeAware = false;
          }

        // BACKREFERENCE OPERATOR
        //  \1 \2 ... \9 and \10 \11 \12 ...
        // not available if RE_NO_BK_REFS is set
        // Perl recognizes \10, \11, and so on only if enough number of
        // parentheses have opened before it, otherwise they are treated
        // as aliases of \010, \011, ... (octal characters).  In case of
        // Sun's JDK, octal character expression must always begin with \0.
        // We will do as JDK does. But FIXME, take a look at "(a)(b)\29".
        // JDK treats \2 as a back reference to the 2nd group because
        // there are only two groups. But in our poor implementation,
        // we cannot help but treat \29 as a back reference to the 29th group.

        else if (unit.bk && Character.isDigit (unit.ch)
                 && !syntax.get (RESyntax.RE_NO_BK_REFS))
          {
            addToken (currentToken);
            int numBegin = index - 1;
            int numEnd = pLength;
            for (int i = index; i < pLength; i++)
              {
                if (!Character.isDigit (pattern[i]))
                  {
                    numEnd = i;
                    break;
                  }
              }
            int num = parseInt (pattern, numBegin, numEnd - numBegin, 10);

            currentToken = new RETokenBackRef (subIndex, num, insens);
            if (insensUSASCII)
              currentToken.unicodeAware = false;
            index = numEnd;
          }

        // START OF STRING OPERATOR
        //  \A if RE_STRING_ANCHORS is set

        else if (unit.bk && (unit.ch == 'A')
                 && syntax.get (RESyntax.RE_STRING_ANCHORS))
          {
            addToken (currentToken);
            currentToken = new RETokenStart (subIndex, null);
          }

        // WORD BREAK OPERATOR
        //  \b if ????

        else if (unit.bk && (unit.ch == 'b')
                 && syntax.get (RESyntax.RE_STRING_ANCHORS))
          {
            addToken (currentToken);
            currentToken =
              new RETokenWordBoundary (subIndex,
                                       RETokenWordBoundary.
                                       BEGIN | RETokenWordBoundary.END,
                                       false);
          }

        // WORD BEGIN OPERATOR
        //  \< if ????
        else if (unit.bk && (unit.ch == '<'))
          {
            addToken (currentToken);
            currentToken =
              new RETokenWordBoundary (subIndex, RETokenWordBoundary.BEGIN,
                                       false);
          }

        // WORD END OPERATOR
        //  \> if ????
        else if (unit.bk && (unit.ch == '>'))
          {
            addToken (currentToken);
            currentToken =
              new RETokenWordBoundary (subIndex, RETokenWordBoundary.END,
                                       false);
          }

        // NON-WORD BREAK OPERATOR
        // \B if ????

        else if (unit.bk && (unit.ch == 'B')
                 && syntax.get (RESyntax.RE_STRING_ANCHORS))
          {
            addToken (currentToken);
            currentToken =
              new RETokenWordBoundary (subIndex,
                                       RETokenWordBoundary.
                                       BEGIN | RETokenWordBoundary.END, true);
          }


        // DIGIT OPERATOR
        //  \d if RE_CHAR_CLASS_ESCAPES is set

        else if (unit.bk && (unit.ch == 'd')
                 && syntax.get (RESyntax.RE_CHAR_CLASS_ESCAPES))
          {
            addToken (currentToken);
            currentToken =
              new RETokenPOSIX (subIndex, RETokenPOSIX.DIGIT, insens, false);
            if (insensUSASCII)
              currentToken.unicodeAware = false;
          }

        // NON-DIGIT OPERATOR
        //  \D

        else if (unit.bk && (unit.ch == 'D')
                 && syntax.get (RESyntax.RE_CHAR_CLASS_ESCAPES))
          {
            addToken (currentToken);
            currentToken =
              new RETokenPOSIX (subIndex, RETokenPOSIX.DIGIT, insens, true);
            if (insensUSASCII)
              currentToken.unicodeAware = false;
          }

        // NEWLINE ESCAPE
        //  \n

        else if (unit.bk && (unit.ch == 'n'))
          {
            addToken (currentToken);
            currentToken = new RETokenChar (subIndex, '\n', false);
          }

        // RETURN ESCAPE
        //  \r

        else if (unit.bk && (unit.ch == 'r'))
          {
            addToken (currentToken);
            currentToken = new RETokenChar (subIndex, '\r', false);
          }

        // WHITESPACE OPERATOR
        //  \s if RE_CHAR_CLASS_ESCAPES is set

        else if (unit.bk && (unit.ch == 's')
                 && syntax.get (RESyntax.RE_CHAR_CLASS_ESCAPES))
          {
            addToken (currentToken);
            currentToken =
              new RETokenPOSIX (subIndex, RETokenPOSIX.SPACE, insens, false);
            if (insensUSASCII)
              currentToken.unicodeAware = false;
          }

        // NON-WHITESPACE OPERATOR
        //  \S

        else if (unit.bk && (unit.ch == 'S')
                 && syntax.get (RESyntax.RE_CHAR_CLASS_ESCAPES))
          {
            addToken (currentToken);
            currentToken =
              new RETokenPOSIX (subIndex, RETokenPOSIX.SPACE, insens, true);
            if (insensUSASCII)
              currentToken.unicodeAware = false;
          }

        // TAB ESCAPE
        //  \t

        else if (unit.bk && (unit.ch == 't'))
          {
            addToken (currentToken);
            currentToken = new RETokenChar (subIndex, '\t', false);
          }

        // ALPHANUMERIC OPERATOR
        //  \w

        else if (unit.bk && (unit.ch == 'w')
                 && syntax.get (RESyntax.RE_CHAR_CLASS_ESCAPES))
          {
            addToken (currentToken);
            currentToken =
              new RETokenPOSIX (subIndex, RETokenPOSIX.ALNUM, insens, false);
            if (insensUSASCII)
              currentToken.unicodeAware = false;
          }

        // NON-ALPHANUMERIC OPERATOR
        //  \W

        else if (unit.bk && (unit.ch == 'W')
                 && syntax.get (RESyntax.RE_CHAR_CLASS_ESCAPES))
          {
            addToken (currentToken);
            currentToken =
              new RETokenPOSIX (subIndex, RETokenPOSIX.ALNUM, insens, true);
            if (insensUSASCII)
              currentToken.unicodeAware = false;
          }

        // END OF STRING OPERATOR
        //  \Z, \z

        // FIXME: \Z and \z are different in that if the input string
        // ends with a line terminator, \Z matches the position before
        // the final terminator.  This special behavior of \Z is yet
        // to be implemented.

        else if (unit.bk && (unit.ch == 'Z' || unit.ch == 'z') &&
                 syntax.get (RESyntax.RE_STRING_ANCHORS))
          {
            addToken (currentToken);
            currentToken = new RETokenEnd (subIndex, null);
          }

        // HEX CHARACTER, UNICODE CHARACTER
        //  \x1B, \u1234

        else
          if ((unit.bk && (unit.ch == 'x')
               && syntax.get (RESyntax.RE_HEX_CHAR)) || (unit.bk
                                                         && (unit.ch == 'u')
                                                         && syntax.
                                                         get (RESyntax.
                                                              RE_UNICODE_CHAR)))
          {
            CharExpression ce =
              getCharExpression (pattern, index - 2, pLength, syntax);
            if (ce == null)
              throw new REException ("invalid hex character",
                                     REException.REG_ESCAPE, index);
            index = index - 2 + ce.len;
            addToken (currentToken);
            currentToken = new RETokenChar (subIndex, ce.ch, insens);
            if (insensUSASCII)
              currentToken.unicodeAware = false;
          }

        // NAMED PROPERTY
        // \p{prop}, \P{prop}

        else
          if ((unit.bk && (unit.ch == 'p')
               && syntax.get (RESyntax.RE_NAMED_PROPERTY)) || (unit.bk
                                                               && (unit.ch ==
                                                                   'P')
                                                               && syntax.
                                                               get (RESyntax.
                                                                    RE_NAMED_PROPERTY)))
          {
            NamedProperty np = getNamedProperty (pattern, index - 2, pLength);
            if (np == null)
              throw new REException ("invalid escape sequence",
                                     REException.REG_ESCAPE, index);
            index = index - 2 + np.len;
            addToken (currentToken);
            currentToken =
              getRETokenNamedProperty (subIndex, np, insens, index);
            if (insensUSASCII)
              currentToken.unicodeAware = false;
          }

        // END OF PREVIOUS MATCH
        //  \G

        else if (unit.bk && (unit.ch == 'G') &&
                 syntax.get (RESyntax.RE_STRING_ANCHORS))
          {
            addToken (currentToken);
            currentToken = new RETokenEndOfPreviousMatch (subIndex);
          }

        // NON-SPECIAL CHARACTER (or escape to make literal)
        //  c | \* for example

        else
          {                     // not a special character
            addToken (currentToken);
            currentToken = new RETokenChar (subIndex, unit.ch, insens);
            if (insensUSASCII)
              currentToken.unicodeAware = false;
          }
      }                         // end while

    // Add final buffered token and an EndSub marker
    addToken (currentToken);

    if (branches != null)
      {
        branches.
          add (new
               RE (firstToken, lastToken, numSubs, subIndex, minimumLength,
                   maximumLength));
        branches.trimToSize (); // compact the Vector
        minimumLength = 0;
        maximumLength = 0;
        firstToken = lastToken = null;
        addToken (new RETokenOneOf (subIndex, branches, false));
      }
    else
      addToken (new RETokenEndSub (subIndex));

  }

  private static class ParseCharClassResult
  {
    RETokenOneOf token;
    int index;
    boolean returnAtAndOperator = false;
  }

  /**
   * Parse [...] or [^...] and make an RETokenOneOf instance.
   * @param subIndex subIndex to be given to the created RETokenOneOf instance.
   * @param pattern Input array of characters to be parsed.
   * @param index Index pointing to the character next to the beginning '['.
   * @param pLength Limit of the input array.
   * @param cflags Compilation flags used to parse the pattern.
   * @param pflags Flags that affect the behavior of this method.
   * @param syntax Syntax used to parse the pattern.
   */
  private static ParseCharClassResult parseCharClass (int subIndex,
                                                      char[]pattern,
                                                      int index, int pLength,
                                                      int cflags,
                                                      RESyntax syntax,
                                                      int pflags) throws
    REException
  {

    boolean insens = ((cflags & REG_ICASE) > 0);
    boolean insensUSASCII = ((cflags & REG_ICASE_USASCII) > 0);
    final ArrayList < REToken > options = new ArrayList < REToken > ();
      ArrayList < Object > addition = new ArrayList < Object > ();
    boolean additionAndAppeared = false;
    final int RETURN_AT_AND = 0x01;
    boolean returnAtAndOperator = ((pflags & RETURN_AT_AND) != 0);
    boolean negative = false;
    char ch;

    char lastChar = 0;
    boolean lastCharIsSet = false;
    if (index == pLength)
      throw new REException (getLocalizedMessage ("unmatched.bracket"),
                             REException.REG_EBRACK, index);

    // Check for initial caret, negation
    if ((ch = pattern[index]) == '^')
      {
        negative = true;
        if (++index == pLength)
          throw new REException (getLocalizedMessage ("class.no.end"),
                                 REException.REG_EBRACK, index);
          ch = pattern[index];
      }

    // Check for leading right bracket literal
    if (ch == ']')
      {
        lastChar = ch;
        lastCharIsSet = true;
        if (++index == pLength)
          throw new REException (getLocalizedMessage ("class.no.end"),
                                 REException.REG_EBRACK, index);
      }

    while ((ch = pattern[index++]) != ']')
      {
        if ((ch == '-') && (lastCharIsSet))
          {
            if (index == pLength)
              throw new REException (getLocalizedMessage ("class.no.end"),
                                     REException.REG_EBRACK, index);
            if ((ch = pattern[index]) == ']')
              {
                RETokenChar t = new RETokenChar (subIndex, lastChar, insens);
                if (insensUSASCII)
                  t.unicodeAware = false;
                options.add (t);
                lastChar = '-';
              }
            else
              {
                if ((ch == '\\')
                    && syntax.get (RESyntax.RE_BACKSLASH_ESCAPE_IN_LISTS))
                  {
                    CharExpression ce =
                      getCharExpression (pattern, index, pLength, syntax);
                    if (ce == null)
                      throw new REException ("invalid escape sequence",
                                             REException.REG_ESCAPE, index);
                    ch = ce.ch;
                    index = index + ce.len - 1;
                  }
                RETokenRange t =
                  new RETokenRange (subIndex, lastChar, ch, insens);
                if (insensUSASCII)
                  t.unicodeAware = false;
                options.add (t);
                lastChar = 0;
                lastCharIsSet = false;
                index++;
              }
          }
        else if ((ch == '\\')
                 && syntax.get (RESyntax.RE_BACKSLASH_ESCAPE_IN_LISTS))
          {
            if (index == pLength)
              throw new REException (getLocalizedMessage ("class.no.end"),
                                     REException.REG_EBRACK, index);
            int posixID = -1;
            boolean negate = false;
            char asciiEsc = 0;
            boolean asciiEscIsSet = false;
            NamedProperty np = null;
            if (("dswDSW".indexOf (pattern[index]) != -1)
                && syntax.get (RESyntax.RE_CHAR_CLASS_ESC_IN_LISTS))
              {
                switch (pattern[index])
                  {
                  case 'D':
                    negate = true;
                  case 'd':
                    posixID = RETokenPOSIX.DIGIT;
                    break;
                  case 'S':
                    negate = true;
                  case 's':
                    posixID = RETokenPOSIX.SPACE;
                    break;
                  case 'W':
                    negate = true;
                  case 'w':
                    posixID = RETokenPOSIX.ALNUM;
                    break;
                  }
              }
            if (("pP".indexOf (pattern[index]) != -1)
                && syntax.get (RESyntax.RE_NAMED_PROPERTY))
              {
                np = getNamedProperty (pattern, index - 1, pLength);
                if (np == null)
                  throw new REException ("invalid escape sequence",
                                         REException.REG_ESCAPE, index);
                index = index - 1 + np.len - 1;
              }
            else
              {
                CharExpression ce =
                  getCharExpression (pattern, index - 1, pLength, syntax);
                if (ce == null)
                  throw new REException ("invalid escape sequence",
                                         REException.REG_ESCAPE, index);
                asciiEsc = ce.ch;
                asciiEscIsSet = true;
                index = index - 1 + ce.len - 1;
              }
            if (lastCharIsSet)
              {
                RETokenChar t = new RETokenChar (subIndex, lastChar, insens);
                if (insensUSASCII)
                  t.unicodeAware = false;
                options.add (t);
              }

            if (posixID != -1)
              {
                RETokenPOSIX t =
                  new RETokenPOSIX (subIndex, posixID, insens, negate);
                if (insensUSASCII)
                  t.unicodeAware = false;
                options.add (t);
              }
            else if (np != null)
              {
                RETokenNamedProperty t =
                  getRETokenNamedProperty (subIndex, np, insens, index);
                if (insensUSASCII)
                  t.unicodeAware = false;
                options.add (t);
              }
            else if (asciiEscIsSet)
              {
                lastChar = asciiEsc;
                lastCharIsSet = true;
              }
            else
              {
                lastChar = pattern[index];
                lastCharIsSet = true;
              }
            ++index;
          }
        else if ((ch == '[') && (syntax.get (RESyntax.RE_CHAR_CLASSES))
                 && (index < pLength) && (pattern[index] == ':'))
          {
            CPStringBuilder posixSet = new CPStringBuilder ();
            index = getPosixSet (pattern, index + 1, posixSet);
            int posixId = RETokenPOSIX.intValue (posixSet.toString ());
            if (posixId != -1)
              {
                RETokenPOSIX t =
                  new RETokenPOSIX (subIndex, posixId, insens, false);
                if (insensUSASCII)
                  t.unicodeAware = false;
                options.add (t);
              }
          }
        else if ((ch == '[') && (syntax.get (RESyntax.RE_NESTED_CHARCLASS)))
          {
            ParseCharClassResult result =
              parseCharClass (subIndex, pattern, index, pLength, cflags,
                              syntax, 0);
            addition.add (result.token);
            addition.add ("|");
            index = result.index;
          }
        else if ((ch == '&') &&
                 (syntax.get (RESyntax.RE_NESTED_CHARCLASS)) &&
                 (index < pLength) && (pattern[index] == '&'))
          {
            if (returnAtAndOperator)
              {
                ParseCharClassResult result = new ParseCharClassResult ();
                options.trimToSize ();
                if (additionAndAppeared)
                  addition.add ("&");
                if (addition.size () == 0)
                  addition = null;
                result.token = new RETokenOneOf (subIndex,
                                                 options, addition, negative);
                result.index = index - 1;
                result.returnAtAndOperator = true;
                return result;
              }
            // The precedence of the operator "&&" is the lowest.
            // So we postpone adding "&" until other elements
            // are added. And we insert Boolean.FALSE at the
            // beginning of the list of tokens following "&&".
            // So, "&&[a-b][k-m]" will be stored in the Vecter
            // addition in this order:
            //     Boolean.FALSE, [a-b], "|", [k-m], "|", "&"
            if (additionAndAppeared)
              addition.add ("&");
            addition.add (Boolean.FALSE);
            additionAndAppeared = true;

            // The part on which "&&" operates may be either
            //   (1) explicitly enclosed by []
            //   or
            //   (2) not enclosed by [] and terminated by the
            //       next "&&" or the end of the character list.
            //  Let the preceding else if block do the case (1).
            //  We must do something in case of (2).
            if ((index + 1 < pLength) && (pattern[index + 1] != '['))
              {
                ParseCharClassResult result =
                  parseCharClass (subIndex, pattern, index + 1, pLength,
                                  cflags, syntax,
                                  RETURN_AT_AND);
                addition.add (result.token);
                addition.add ("|");
                // If the method returned at the next "&&", it is OK.
                // Otherwise we have eaten the mark of the end of this
                // character list "]".  In this case we must give back
                // the end mark.
                index = (result.returnAtAndOperator ?
                         result.index : result.index - 1);
              }
          }
        else
          {
            if (lastCharIsSet)
              {
                RETokenChar t = new RETokenChar (subIndex, lastChar, insens);
                if (insensUSASCII)
                  t.unicodeAware = false;
                options.add (t);
              }
            lastChar = ch;
            lastCharIsSet = true;
          }
        if (index == pLength)
          throw new REException (getLocalizedMessage ("class.no.end"),
                                 REException.REG_EBRACK, index);
      }                         // while in list
    // Out of list, index is one past ']'

    if (lastCharIsSet)
      {
        RETokenChar t = new RETokenChar (subIndex, lastChar, insens);
        if (insensUSASCII)
          t.unicodeAware = false;
        options.add (t);
      }

    ParseCharClassResult result = new ParseCharClassResult ();
    // Create a new RETokenOneOf
    options.trimToSize ();
    if (additionAndAppeared)
      addition.add ("&");
    if (addition.size () == 0)
      addition = null;
    result.token = new RETokenOneOf (subIndex, options, addition, negative);
    result.index = index;
    return result;
  }

  private static int getCharUnit (char[]input, int index, CharUnit unit,
                                  boolean quot) throws REException
  {
    unit.ch = input[index++];
    unit.bk = (unit.ch == '\\'
               && (!quot || index >= input.length || input[index] == 'E'));
    if (unit.bk)
      if (index < input.length)
        unit.ch = input[index++];
      else
        throw new REException (getLocalizedMessage ("ends.with.backslash"),
                               REException.REG_ESCAPE, index);
    return index;
  }

  private static int parseInt (char[]input, int pos, int len, int radix)
  {
    int ret = 0;
    for (int i = pos; i < pos + len; i++)
      {
        ret = ret * radix + Character.digit (input[i], radix);
      }
    return ret;
  }

  /**
   * This class represents various expressions for a character.
   * "a"      : 'a' itself.
   * "\0123"  : Octal char 0123
   * "\x1b"   : Hex char 0x1b
   * "\u1234" : Unicode char \u1234
   */
  private static class CharExpression
  {
    /** character represented by this expression */
    char ch;
    /** String expression */
    String expr;
    /** length of this expression */
    int len;
    public String toString ()
    {
      return expr;
    }
  }

  private static CharExpression getCharExpression (char[]input, int pos,
                                                   int lim, RESyntax syntax)
  {
    CharExpression ce = new CharExpression ();
    char c = input[pos];
    if (c == '\\')
      {
        if (pos + 1 >= lim)
          return null;
        c = input[pos + 1];
        switch (c)
          {
          case 't':
            ce.ch = '\t';
            ce.len = 2;
            break;
          case 'n':
            ce.ch = '\n';
            ce.len = 2;
            break;
          case 'r':
            ce.ch = '\r';
            ce.len = 2;
            break;
          case 'x':
          case 'u':
            if ((c == 'x' && syntax.get (RESyntax.RE_HEX_CHAR)) ||
                (c == 'u' && syntax.get (RESyntax.RE_UNICODE_CHAR)))
              {
                int l = 0;
                int expectedLength = (c == 'x' ? 2 : 4);
                for (int i = pos + 2; i < pos + 2 + expectedLength; i++)
                  {
                    if (i >= lim)
                      break;
                    if (!((input[i] >= '0' && input[i] <= '9') ||
                          (input[i] >= 'A' && input[i] <= 'F') ||
                          (input[i] >= 'a' && input[i] <= 'f')))
                      break;
                    l++;
                  }
                if (l != expectedLength)
                  return null;
                ce.ch = (char) (parseInt (input, pos + 2, l, 16));
                ce.len = l + 2;
              }
            else
              {
                ce.ch = c;
                ce.len = 2;
              }
            break;
          case '0':
            if (syntax.get (RESyntax.RE_OCTAL_CHAR))
              {
                int l = 0;
                for (int i = pos + 2; i < pos + 2 + 3; i++)
                  {
                    if (i >= lim)
                      break;
                    if (input[i] < '0' || input[i] > '7')
                      break;
                    l++;
                  }
                if (l == 3 && input[pos + 2] > '3')
                  l--;
                if (l <= 0)
                  return null;
                ce.ch = (char) (parseInt (input, pos + 2, l, 8));
                ce.len = l + 2;
              }
            else
              {
                ce.ch = c;
                ce.len = 2;
              }
            break;
          default:
            ce.ch = c;
            ce.len = 2;
            break;
          }
      }
    else
      {
        ce.ch = input[pos];
        ce.len = 1;
      }
    ce.expr = new String (input, pos, ce.len);
    return ce;
  }

  /**
   * This class represents a substring in a pattern string expressing
   * a named property.
   * "\pA"      : Property named "A"
   * "\p{prop}" : Property named "prop"
   * "\PA"      : Property named "A" (Negated)
   * "\P{prop}" : Property named "prop" (Negated)
   */
  private static class NamedProperty
  {
    /** Property name */
    String name;
    /** Negated or not */
    boolean negate;
    /** length of this expression */
    int len;
  }

  private static NamedProperty getNamedProperty (char[]input, int pos,
                                                 int lim)
  {
    NamedProperty np = new NamedProperty ();
    char c = input[pos];
    if (c == '\\')
      {
        if (++pos >= lim)
          return null;
        c = input[pos++];
        switch (c)
          {
          case 'p':
            np.negate = false;
            break;
          case 'P':
            np.negate = true;
            break;
          default:
            return null;
          }
        c = input[pos++];
        if (c == '{')
          {
            int p = -1;
            for (int i = pos; i < lim; i++)
              {
                if (input[i] == '}')
                  {
                    p = i;
                    break;
                  }
              }
            if (p < 0)
              return null;
            int len = p - pos;
            np.name = new String (input, pos, len);
            np.len = len + 4;
          }
        else
          {
            np.name = new String (input, pos - 1, 1);
            np.len = 3;
          }
        return np;
      }
    else
      return null;
  }

  private static RETokenNamedProperty getRETokenNamedProperty (int subIndex,
                                                               NamedProperty
                                                               np,
                                                               boolean insens,
                                                               int index)
    throws REException
  {
    try
    {
      return new RETokenNamedProperty (subIndex, np.name, insens, np.negate);
    }
    catch (REException e)
    {
      REException ree;
      ree = new REException (e.getMessage (), REException.REG_ESCAPE, index);
      ree.initCause (e);
      throw ree;
    }
  }

  /**
   * Checks if the regular expression matches the input in its entirety.
   *
   * @param input The input text.
   */
  public boolean isMatch (Object input)
  {
    return isMatch (input, 0, 0);
  }

  /**
   * Checks if the input string, starting from index, is an exact match of
   * this regular expression.
   *
   * @param input The input text.
   * @param index The offset index at which the search should be begin.
   */
  public boolean isMatch (Object input, int index)
  {
    return isMatch (input, index, 0);
  }


  /**
   * Checks if the input, starting from index and using the specified
   * execution flags, is an exact match of this regular expression.
   *
   * @param input The input text.
   * @param index The offset index at which the search should be begin.
   * @param eflags The logical OR of any execution flags above.
   */
  public boolean isMatch (Object input, int index, int eflags)
  {
    return isMatchImpl (makeCharIndexed (input, index), index, eflags);
  }

  private boolean isMatchImpl (CharIndexed input, int index, int eflags)
  {
    if (firstToken == null)     // Trivial case
      return (input.charAt (0) == CharIndexed.OUT_OF_BOUNDS);
    REMatch m = new REMatch (numSubs, index, eflags);
    if (firstToken.match (input, m))
      {
        if (m != null)
          {
            if (input.charAt (m.index) == CharIndexed.OUT_OF_BOUNDS)
              {
                return true;
              }
          }
      }
    return false;
  }

  /**
   * Returns the maximum number of subexpressions in this regular expression.
   * If the expression contains branches, the value returned will be the
   * maximum subexpressions in any of the branches.
   */
  public int getNumSubs ()
  {
    return numSubs;
  }

  // Overrides REToken.setUncle
  void setUncle (REToken uncle)
  {
    if (lastToken != null)
      {
        lastToken.setUncle (uncle);
      }
    else
      super.setUncle (uncle);   // to deal with empty subexpressions
  }

  // Overrides REToken.chain

  boolean chain (REToken next)
  {
    super.chain (next);
    setUncle (next);
    return true;
  }

  /**
   * Returns the minimum number of characters that could possibly
   * constitute a match of this regular expression.
   */
  public int getMinimumLength ()
  {
    return minimumLength;
  }

  public int getMaximumLength ()
  {
    return maximumLength;
  }

  /**
   * Returns an array of all matches found in the input.
   *
   * If the regular expression allows the empty string to match, it will
   * substitute matches at all positions except the end of the input.
   *
   * @param input The input text.
   * @return a non-null (but possibly zero-length) array of matches
   */
  public REMatch[] getAllMatches (Object input)
  {
    return getAllMatches (input, 0, 0);
  }

  /**
   * Returns an array of all matches found in the input,
   * beginning at the specified index position.
   *
   * If the regular expression allows the empty string to match, it will
   * substitute matches at all positions except the end of the input.
   *
   * @param input The input text.
   * @param index The offset index at which the search should be begin.
   * @return a non-null (but possibly zero-length) array of matches
   */
  public REMatch[] getAllMatches (Object input, int index)
  {
    return getAllMatches (input, index, 0);
  }

  /**
   * Returns an array of all matches found in the input string,
   * beginning at the specified index position and using the specified
   * execution flags.
   *
   * If the regular expression allows the empty string to match, it will
   * substitute matches at all positions except the end of the input.
   *
   * @param input The input text.
   * @param index The offset index at which the search should be begin.
   * @param eflags The logical OR of any execution flags above.
   * @return a non-null (but possibly zero-length) array of matches
   */
  public REMatch[] getAllMatches (Object input, int index, int eflags)
  {
    return getAllMatchesImpl (makeCharIndexed (input, index), index, eflags);
  }

  // this has been changed since 1.03 to be non-overlapping matches
  private REMatch[] getAllMatchesImpl (CharIndexed input, int index,
                                       int eflags)
  {
    List < REMatch > all = new ArrayList < REMatch > ();
    REMatch m = null;
    while ((m = getMatchImpl (input, index, eflags, null)) != null)
      {
        all.add (m);
        index = m.getEndIndex ();
        if (m.end[0] == 0)
          {                     // handle pathological case of zero-length match
            index++;
            input.move (1);
          }
        else
          {
            input.move (m.end[0]);
          }
        if (!input.isValid ())
          break;
      }
    return all.toArray (new REMatch[all.size ()]);
  }

  /* Implements abstract method REToken.match() */
  boolean match (CharIndexed input, REMatch mymatch)
  {
    input.setHitEnd (mymatch);
    if (firstToken == null)
      {
        return next (input, mymatch);
      }

    // Note the start of this subexpression
    mymatch.start1[subIndex] = mymatch.index;

    return firstToken.match (input, mymatch);
  }

  REMatch findMatch (CharIndexed input, REMatch mymatch)
  {
    if (mymatch.backtrackStack == null)
      mymatch.backtrackStack = new BacktrackStack ();
    boolean b = match (input, mymatch);
    if (b)
      {
        return mymatch;
      }
    return null;
  }

  /**
   * Returns the first match found in the input.  If no match is found,
   * null is returned.
   *
   * @param input The input text.
   * @return An REMatch instance referencing the match, or null if none.
   */
  public REMatch getMatch (Object input)
  {
    return getMatch (input, 0, 0);
  }

  /**
   * Returns the first match found in the input, beginning
   * the search at the specified index.  If no match is found,
   * returns null.
   *
   * @param input The input text.
   * @param index The offset within the text to begin looking for a match.
   * @return An REMatch instance referencing the match, or null if none.
   */
  public REMatch getMatch (Object input, int index)
  {
    return getMatch (input, index, 0);
  }

  /**
   * Returns the first match found in the input, beginning
   * the search at the specified index, and using the specified
   * execution flags.  If no match is found, returns null.
   *
   * @param input The input text.
   * @param index The offset index at which the search should be begin.
   * @param eflags The logical OR of any execution flags above.
   * @return An REMatch instance referencing the match, or null if none.
   */
  public REMatch getMatch (Object input, int index, int eflags)
  {
    return getMatch (input, index, eflags, null);
  }

  /**
   * Returns the first match found in the input, beginning the search
   * at the specified index, and using the specified execution flags.
   * If no match is found, returns null.  If a StringBuffer is
   * provided and is non-null, the contents of the input text from the
   * index to the beginning of the match (or to the end of the input,
   * if there is no match) are appended to the StringBuffer.
   *
   * @param input The input text.
   * @param index The offset index at which the search should be begin.
   * @param eflags The logical OR of any execution flags above.
   * @param buffer The StringBuffer to save pre-match text in.
   * @return An REMatch instance referencing the match, or null if none.  */
  public REMatch getMatch (Object input, int index, int eflags,
                           CPStringBuilder buffer)
  {
    return getMatchImpl (makeCharIndexed (input, index), index, eflags,
                         buffer);
  }

  REMatch getMatchImpl (CharIndexed input, int anchor, int eflags,
                        CPStringBuilder buffer)
  {
    boolean tryEntireMatch = ((eflags & REG_TRY_ENTIRE_MATCH) != 0);
    boolean doMove = ((eflags & REG_FIX_STARTING_POSITION) == 0);
    RE re = (tryEntireMatch ? (RE) this.clone () : this);
    if (tryEntireMatch)
      {
        RETokenEnd reEnd = new RETokenEnd (0, null);
        reEnd.setFake (true);
        re.chain (reEnd);
      }
    // Create a new REMatch to hold results
    REMatch mymatch = new REMatch (numSubs, anchor, eflags);
    do
      {
        /* The following potimization is commented out because
           the matching should be tried even if the length of
           input is obviously too short in order that
           java.util.regex.Matcher#hitEnd() may work correctly.
           // Optimization: check if anchor + minimumLength > length
           if (minimumLength == 0 || input.charAt(minimumLength-1) != CharIndexed.OUT_OF_BOUNDS) {
         */
        if (re.match (input, mymatch))
          {
            REMatch best = mymatch;
            // We assume that the match that coms first is the best.
            // And the following "The longer, the better" rule has
            // been commented out. The longest is not neccesarily
            // the best. For example, "a" out of "aaa" is the best
            // match for /a+?/.
            /*
               // Find best match of them all to observe leftmost longest
               while ((mymatch = mymatch.next) != null) {
               if (mymatch.index > best.index) {
               best = mymatch;
               }
               }
             */
            best.end[0] = best.index;
            best.finish (input);
            input.setLastMatch (best);
            return best;
          }
        /* End of the optimization commented out
           }
         */
        mymatch.clear (++anchor);
        // Append character to buffer if needed
        if (buffer != null && input.charAt (0) != CharIndexed.OUT_OF_BOUNDS)
          {
            buffer.append (input.charAt (0));
          }
        // java.util.regex.Matcher#hitEnd() requires that the search should
        // be tried at the end of input, so we use move1(1) instead of move(1)
      }
    while (doMove && input.move1 (1));

    // Special handling at end of input for e.g. "$"
    if (minimumLength == 0)
      {
        if (match (input, mymatch))
          {
            mymatch.finish (input);
            return mymatch;
          }
      }

    return null;
  }

  /**
   * Returns an REMatchEnumeration that can be used to iterate over the
   * matches found in the input text.
   *
   * @param input The input text.
   * @return A non-null REMatchEnumeration instance.
   */
  public REMatchEnumeration getMatchEnumeration (Object input)
  {
    return getMatchEnumeration (input, 0, 0);
  }


  /**
   * Returns an REMatchEnumeration that can be used to iterate over the
   * matches found in the input text.
   *
   * @param input The input text.
   * @param index The offset index at which the search should be begin.
   * @return A non-null REMatchEnumeration instance, with its input cursor
   *  set to the index position specified.
   */
  public REMatchEnumeration getMatchEnumeration (Object input, int index)
  {
    return getMatchEnumeration (input, index, 0);
  }

  /**
   * Returns an REMatchEnumeration that can be used to iterate over the
   * matches found in the input text.
   *
   * @param input The input text.
   * @param index The offset index at which the search should be begin.
   * @param eflags The logical OR of any execution flags above.
   * @return A non-null REMatchEnumeration instance, with its input cursor
   *  set to the index position specified.
   */
  public REMatchEnumeration getMatchEnumeration (Object input, int index,
                                                 int eflags)
  {
    return new REMatchEnumeration (this, makeCharIndexed (input, index),
                                   index, eflags);
  }


  /**
   * Substitutes the replacement text for the first match found in the input.
   *
   * @param input The input text.
   * @param replace The replacement text, which may contain $x metacharacters (see REMatch.substituteInto).
   * @return A String interpolating the substituted text.
   * @see REMatch#substituteInto
   */
  public String substitute (Object input, String replace)
  {
    return substitute (input, replace, 0, 0);
  }

  /**
   * Substitutes the replacement text for the first match found in the input
   * beginning at the specified index position.  Specifying an index
   * effectively causes the regular expression engine to throw away the
   * specified number of characters.
   *
   * @param input The input text.
   * @param replace The replacement text, which may contain $x metacharacters (see REMatch.substituteInto).
   * @param index The offset index at which the search should be begin.
   * @return A String containing the substring of the input, starting
   *   at the index position, and interpolating the substituted text.
   * @see REMatch#substituteInto
   */
  public String substitute (Object input, String replace, int index)
  {
    return substitute (input, replace, index, 0);
  }

  /**
   * Substitutes the replacement text for the first match found in the input
   * string, beginning at the specified index position and using the
   * specified execution flags.
   *
   * @param input The input text.
   * @param replace The replacement text, which may contain $x metacharacters (see REMatch.substituteInto).
   * @param index The offset index at which the search should be begin.
   * @param eflags The logical OR of any execution flags above.
   * @return A String containing the substring of the input, starting
   *   at the index position, and interpolating the substituted text.
   * @see REMatch#substituteInto
   */
  public String substitute (Object input, String replace, int index,
                            int eflags)
  {
    return substituteImpl (makeCharIndexed (input, index), replace, index,
                           eflags);
  }

  private String substituteImpl (CharIndexed input, String replace, int index,
                                 int eflags)
  {
    CPStringBuilder buffer = new CPStringBuilder ();
    REMatch m = getMatchImpl (input, index, eflags, buffer);
    if (m == null)
      return buffer.toString ();
    buffer.append (getReplacement (replace, m, eflags));
    if (input.move (m.end[0]))
      {
        do
          {
            buffer.append (input.charAt (0));
          }
        while (input.move (1));
      }
    return buffer.toString ();
  }

  /**
   * Substitutes the replacement text for each non-overlapping match found
   * in the input text.
   *
   * @param input The input text.
   * @param replace The replacement text, which may contain $x metacharacters (see REMatch.substituteInto).
   * @return A String interpolating the substituted text.
   * @see REMatch#substituteInto
   */
  public String substituteAll (Object input, String replace)
  {
    return substituteAll (input, replace, 0, 0);
  }

  /**
   * Substitutes the replacement text for each non-overlapping match found
   * in the input text, starting at the specified index.
   *
   * If the regular expression allows the empty string to match, it will
   * substitute matches at all positions except the end of the input.
   *
   * @param input The input text.
   * @param replace The replacement text, which may contain $x metacharacters (see REMatch.substituteInto).
   * @param index The offset index at which the search should be begin.
   * @return A String containing the substring of the input, starting
   *   at the index position, and interpolating the substituted text.
   * @see REMatch#substituteInto
   */
  public String substituteAll (Object input, String replace, int index)
  {
    return substituteAll (input, replace, index, 0);
  }

  /**
   * Substitutes the replacement text for each non-overlapping match found
   * in the input text, starting at the specified index and using the
   * specified execution flags.
   *
   * @param input The input text.
   * @param replace The replacement text, which may contain $x metacharacters (see REMatch.substituteInto).
   * @param index The offset index at which the search should be begin.
   * @param eflags The logical OR of any execution flags above.
   * @return A String containing the substring of the input, starting
   *   at the index position, and interpolating the substituted text.
   * @see REMatch#substituteInto
   */
  public String substituteAll (Object input, String replace, int index,
                               int eflags)
  {
    return substituteAllImpl (makeCharIndexed (input, index), replace, index,
                              eflags);
  }

  private String substituteAllImpl (CharIndexed input, String replace,
                                    int index, int eflags)
  {
    CPStringBuilder buffer = new CPStringBuilder ();
    REMatch m;
    while ((m = getMatchImpl (input, index, eflags, buffer)) != null)
      {
        buffer.append (getReplacement (replace, m, eflags));
        index = m.getEndIndex ();
        if (m.end[0] == 0)
          {
            char ch = input.charAt (0);
            if (ch != CharIndexed.OUT_OF_BOUNDS)
              buffer.append (ch);
            input.move (1);
          }
        else
          {
            input.move (m.end[0]);
          }

        if (!input.isValid ())
          break;
      }
    return buffer.toString ();
  }

  public static String getReplacement (String replace, REMatch m, int eflags)
  {
    if ((eflags & REG_NO_INTERPOLATE) > 0)
      return replace;
    else
      {
        if ((eflags & REG_REPLACE_USE_BACKSLASHESCAPE) > 0)
          {
            CPStringBuilder sb = new CPStringBuilder ();
            int l = replace.length ();
            for (int i = 0; i < l; i++)
              {
                char c = replace.charAt (i);
                switch (c)
                  {
                  case '\\':
                    i++;
                    // Let StringIndexOutOfBoundsException be thrown.
                    sb.append (replace.charAt (i));
                    break;
                  case '$':
                    int i1 = i + 1;
                    while (i1 < replace.length () &&
                           Character.isDigit (replace.charAt (i1)))
                      i1++;
                    sb.append (m.substituteInto (replace.substring (i, i1)));
                    i = i1 - 1;
                    break;
                  default:
                    sb.append (c);
                  }
              }
            return sb.toString ();
          }
        else
          return m.substituteInto (replace);
      }
  }

  /* Helper function for constructor */
  private void addToken (REToken next)
  {
    if (next == null)
      return;
    minimumLength += next.getMinimumLength ();
    int nmax = next.getMaximumLength ();
    if (nmax < Integer.MAX_VALUE && maximumLength < Integer.MAX_VALUE)
      maximumLength += nmax;
    else
      maximumLength = Integer.MAX_VALUE;

    if (firstToken == null)
      {
        lastToken = firstToken = next;
      }
    else
      {
        // if chain returns false, it "rejected" the token due to
        // an optimization, and next was combined with lastToken
        if (lastToken.chain (next))
          {
            lastToken = next;
          }
      }
  }

  private static REToken setRepeated (REToken current, int min, int max,
                                      int index) throws REException
  {
    if (current == null)
      throw new REException (getLocalizedMessage ("repeat.no.token"),
                             REException.REG_BADRPT, index);
      return new RETokenRepeated (current.subIndex, current, min, max);
  }

  private static int getPosixSet (char[]pattern, int index,
                                  CPStringBuilder buf)
  {
    // Precondition: pattern[index-1] == ':'
    // we will return pos of closing ']'.
    int i;
    for (i = index; i < (pattern.length - 1); i++)
      {
        if ((pattern[i] == ':') && (pattern[i + 1] == ']'))
          return i + 2;
        buf.append (pattern[i]);
      }
    return index;               // didn't match up
  }

  private int getMinMax (char[]input, int index, IntPair minMax,
                         RESyntax syntax) throws REException
  {
    // Precondition: input[index-1] == '{', minMax != null

    boolean mustMatch = !syntax.get (RESyntax.RE_NO_BK_BRACES);
    int startIndex = index;
    if (index == input.length)
      {
        if (mustMatch)
          throw new REException (getLocalizedMessage ("unmatched.brace"),
                                 REException.REG_EBRACE, index);
        else
          return startIndex;
      }

    int min, max = 0;
    CharUnit unit = new CharUnit ();
    CPStringBuilder buf = new CPStringBuilder ();

    // Read string of digits
    do
      {
        index = getCharUnit (input, index, unit, false);
        if (Character.isDigit (unit.ch))
          buf.append (unit.ch);
      }
    while ((index != input.length) && Character.isDigit (unit.ch));

    // Check for {} tomfoolery
    if (buf.length () == 0)
      {
        if (mustMatch)
          throw new REException (getLocalizedMessage ("interval.error"),
                                 REException.REG_EBRACE, index);
        else
        return startIndex;
      }

    min = Integer.parseInt (buf.toString ());

    if ((unit.ch == '}') && (syntax.get (RESyntax.RE_NO_BK_BRACES) ^ unit.bk))
      max = min;
    else if (index == input.length)
      if (mustMatch)
        throw new REException (getLocalizedMessage ("interval.no.end"),
                               REException.REG_EBRACE, index);
    else
    return startIndex;
    else
  if ((unit.ch == ',') && !unit.bk)
    {
      buf = new CPStringBuilder ();
      // Read string of digits
      while (((index =
               getCharUnit (input, index, unit, false)) != input.length)
             && Character.isDigit (unit.ch))
        buf.append (unit.ch);

      if (!
          ((unit.ch == '}')
           && (syntax.get (RESyntax.RE_NO_BK_BRACES) ^ unit.bk)))
        if (mustMatch)
          throw new REException (getLocalizedMessage ("interval.error"),
                                 REException.REG_EBRACE, index);
      else
      return startIndex;

      // This is the case of {x,}
      if (buf.length () == 0)
        max = Integer.MAX_VALUE;
      else
        max = Integer.parseInt (buf.toString ());
    }
  else if (mustMatch)
    throw new REException (getLocalizedMessage ("interval.error"),
                           REException.REG_EBRACE, index);
  else
  return startIndex;

  // We know min and max now, and they are valid.

  minMax.first = min;
  minMax.second = max;

  // return the index following the '}'
  return index;
  }

   /**
    * Return a human readable form of the compiled regular expression,
    * useful for debugging.
    */
  public String toString ()
  {
    CPStringBuilder sb = new CPStringBuilder ();
    dump (sb);
    return sb.toString ();
  }

  void dump (CPStringBuilder os)
  {
    os.append ("(?#startRE subIndex=" + subIndex + ")");
    if (subIndex == 0)
      os.append ("?:");
    if (firstToken != null)
      firstToken.dumpAll (os);
    if (subIndex == 0)
      os.append (")");
    os.append ("(?#endRE subIndex=" + subIndex + ")");
  }

  // Cast input appropriately or throw exception
  // This method was originally a private method, but has been made
  // public because java.util.regex.Matcher uses this.
  public static CharIndexed makeCharIndexed (Object input, int index)
  {
    // The case where input is already a CharIndexed is supposed
    // be the most likely because this is the case with
    // java.util.regex.Matcher.
    // We could let a String or a CharSequence fall through
    // to final input, but since it'a very likely input type,
    // we check it first.
    if (input instanceof CharIndexed)
      {
        CharIndexed ci = (CharIndexed) input;
        ci.setAnchor (index);
        return ci;
      }
    else if (input instanceof CharSequence)
      return new CharIndexedCharSequence ((CharSequence) input, index);
    else if (input instanceof String)
      return new CharIndexedString ((String) input, index);
    else if (input instanceof char[])
      return new CharIndexedCharArray ((char[]) input, index);
    else if (input instanceof StringBuffer)
      return new CharIndexedStringBuffer ((StringBuffer) input, index);
    else if (input instanceof InputStream)
      return new CharIndexedInputStream ((InputStream) input, index);
    else
      return new CharIndexedString (input.toString (), index);
  }
}
