/*
**********************************************************************
*   Copyright (C) 2002-2014, International Business Machines
*   Corporation and others.  All Rights Reserved.
**********************************************************************
*   file name:  regex.h
*   encoding:   US-ASCII
*   indentation:4
*
*   created on: 2002oct22
*   created by: Andy Heninger
*
*   ICU Regular Expressions, API for C++
*/

#ifndef REGEX_H
#define REGEX_H

//#define REGEX_DEBUG

/**
 * \file
 * \brief  C++ API:  Regular Expressions
 *
 * <h2>Regular Expression API</h2>
 *
 * <p>The ICU API for processing regular expressions consists of two classes,
 *  <code>RegexPattern</code> and <code>RegexMatcher</code>.
 *  <code>RegexPattern</code> objects represent a pre-processed, or compiled
 *  regular expression.  They are created from a regular expression pattern string,
 *  and can be used to create <code>RegexMatcher</code> objects for the pattern.</p>
 *
 * <p>Class <code>RegexMatcher</code> bundles together a regular expression
 *  pattern and a target string to which the search pattern will be applied.
 *  <code>RegexMatcher</code> includes API for doing plain find or search
 *  operations, for search and replace operations, and for obtaining detailed
 *  information about bounds of a match. </p>
 *
 * <p>Note that by constructing <code>RegexMatcher</code> objects directly from regular
 * expression pattern strings application code can be simplified and the explicit
 * need for <code>RegexPattern</code> objects can usually be eliminated.
 * </p>
 */

#include "unicode/utypes.h"

#if !UCONFIG_NO_REGULAR_EXPRESSIONS

#include "unicode/uobject.h"
#include "unicode/unistr.h"
#include "unicode/utext.h"
#include "unicode/parseerr.h"

#include "unicode/uregex.h"

// Forward Declarations

U_NAMESPACE_BEGIN

struct Regex8BitSet;
class  RegexCImpl;
class  RegexMatcher;
class  RegexPattern;
struct REStackFrame;
class  RuleBasedBreakIterator;
class  UnicodeSet;
class  UVector;
class  UVector32;
class  UVector64;


/**
  * Class <code>RegexPattern</code> represents a compiled regular expression.  It includes
  * factory methods for creating a RegexPattern object from the source (string) form
  * of a regular expression, methods for creating RegexMatchers that allow the pattern
  * to be applied to input text, and a few convenience methods for simple common
  * uses of regular expressions.
  *
  * <p>Class RegexPattern is not intended to be subclassed.</p>
  *
  * @stable ICU 2.4
  */
class U_I18N_API RegexPattern U_FINAL : public UObject {
public:

    /**
     * default constructor.  Create a RegexPattern object that refers to no actual
     *   pattern.  Not normally needed; RegexPattern objects are usually
     *   created using the factory method <code>compile()</code>.
     *
     * @stable ICU 2.4
     */
    RegexPattern();

    /**
     * Copy Constructor.  Create a new RegexPattern object that is equivalent
     *                    to the source object.
     * @param source the pattern object to be copied.
     * @stable ICU 2.4
     */
    RegexPattern(const RegexPattern &source);

    /**
     * Destructor.  Note that a RegexPattern object must persist so long as any
     *  RegexMatcher objects that were created from the RegexPattern are active.
     * @stable ICU 2.4
     */
    virtual ~RegexPattern();

    /**
     * Comparison operator.  Two RegexPattern objects are considered equal if they
     * were constructed from identical source patterns using the same match flag
     * settings.
     * @param that a RegexPattern object to compare with "this".
     * @return TRUE if the objects are equivalent.
     * @stable ICU 2.4
     */
    UBool           operator==(const RegexPattern& that) const;

    /**
     * Comparison operator.  Two RegexPattern objects are considered equal if they
     * were constructed from identical source patterns using the same match flag
     * settings.
     * @param that a RegexPattern object to compare with "this".
     * @return TRUE if the objects are different.
     * @stable ICU 2.4
     */
    inline UBool    operator!=(const RegexPattern& that) const {return ! operator ==(that);}

    /**
     * Assignment operator.  After assignment, this RegexPattern will behave identically
     *     to the source object.
     * @stable ICU 2.4
     */
    RegexPattern  &operator =(const RegexPattern &source);

    /**
     * Create an exact copy of this RegexPattern object.  Since RegexPattern is not
     * intended to be subclasses, <code>clone()</code> and the copy construction are
     * equivalent operations.
     * @return the copy of this RegexPattern
     * @stable ICU 2.4
     */
    virtual RegexPattern  *clone() const;


   /**
    * Compiles the regular expression in string form into a RegexPattern
    * object.  These compile methods, rather than the constructors, are the usual
    * way that RegexPattern objects are created.
    *
    * <p>Note that RegexPattern objects must not be deleted while RegexMatcher
    * objects created from the pattern are active.  RegexMatchers keep a pointer
    * back to their pattern, so premature deletion of the pattern is a
    * catastrophic error.</p>
    *
    * <p>All pattern match mode flags are set to their default values.</p>
    *
    * <p>Note that it is often more convenient to construct a RegexMatcher directly
    *    from a pattern string rather than separately compiling the pattern and
    *    then creating a RegexMatcher object from the pattern.</p>
    *
    * @param regex The regular expression to be compiled.
    * @param pe    Receives the position (line and column nubers) of any error
    *              within the regular expression.)
    * @param status A reference to a UErrorCode to receive any errors.
    * @return      A regexPattern object for the compiled pattern.
    *
    * @stable ICU 2.4
    */
    static RegexPattern * U_EXPORT2 compile( const UnicodeString &regex,
        UParseError          &pe,
        UErrorCode           &status);

   /**
    * Compiles the regular expression in string form into a RegexPattern
    * object.  These compile methods, rather than the constructors, are the usual
    * way that RegexPattern objects are created.
    *
    * <p>Note that RegexPattern objects must not be deleted while RegexMatcher
    * objects created from the pattern are active.  RegexMatchers keep a pointer
    * back to their pattern, so premature deletion of the pattern is a
    * catastrophic error.</p>
    *
    * <p>All pattern match mode flags are set to their default values.</p>
    *
    * <p>Note that it is often more convenient to construct a RegexMatcher directly
    *    from a pattern string rather than separately compiling the pattern and
    *    then creating a RegexMatcher object from the pattern.</p>
    *
    * @param regex The regular expression to be compiled. Note, the text referred
    *              to by this UText must not be deleted during the lifetime of the
    *              RegexPattern object or any RegexMatcher object created from it.
    * @param pe    Receives the position (line and column nubers) of any error
    *              within the regular expression.)
    * @param status A reference to a UErrorCode to receive any errors.
    * @return      A regexPattern object for the compiled pattern.
    *
    * @stable ICU 4.6
    */
    static RegexPattern * U_EXPORT2 compile( UText *regex,
        UParseError          &pe,
        UErrorCode           &status);

   /**
    * Compiles the regular expression in string form into a RegexPattern
    * object using the specified match mode flags.  These compile methods,
    * rather than the constructors, are the usual way that RegexPattern objects
    * are created.
    *
    * <p>Note that RegexPattern objects must not be deleted while RegexMatcher
    * objects created from the pattern are active.  RegexMatchers keep a pointer
    * back to their pattern, so premature deletion of the pattern is a
    * catastrophic error.</p>
    *
    * <p>Note that it is often more convenient to construct a RegexMatcher directly
    *    from a pattern string instead of than separately compiling the pattern and
    *    then creating a RegexMatcher object from the pattern.</p>
    *
    * @param regex The regular expression to be compiled.
    * @param flags The match mode flags to be used.
    * @param pe    Receives the position (line and column numbers) of any error
    *              within the regular expression.)
    * @param status   A reference to a UErrorCode to receive any errors.
    * @return      A regexPattern object for the compiled pattern.
    *
    * @stable ICU 2.4
    */
    static RegexPattern * U_EXPORT2 compile( const UnicodeString &regex,
        uint32_t             flags,
        UParseError          &pe,
        UErrorCode           &status);

   /**
    * Compiles the regular expression in string form into a RegexPattern
    * object using the specified match mode flags.  These compile methods,
    * rather than the constructors, are the usual way that RegexPattern objects
    * are created.
    *
    * <p>Note that RegexPattern objects must not be deleted while RegexMatcher
    * objects created from the pattern are active.  RegexMatchers keep a pointer
    * back to their pattern, so premature deletion of the pattern is a
    * catastrophic error.</p>
    *
    * <p>Note that it is often more convenient to construct a RegexMatcher directly
    *    from a pattern string instead of than separately compiling the pattern and
    *    then creating a RegexMatcher object from the pattern.</p>
    *
    * @param regex The regular expression to be compiled. Note, the text referred
    *              to by this UText must not be deleted during the lifetime of the
    *              RegexPattern object or any RegexMatcher object created from it.
    * @param flags The match mode flags to be used.
    * @param pe    Receives the position (line and column numbers) of any error
    *              within the regular expression.)
    * @param status   A reference to a UErrorCode to receive any errors.
    * @return      A regexPattern object for the compiled pattern.
    *
    * @stable ICU 4.6
    */
    static RegexPattern * U_EXPORT2 compile( UText *regex,
        uint32_t             flags,
        UParseError          &pe,
        UErrorCode           &status);

   /**
    * Compiles the regular expression in string form into a RegexPattern
    * object using the specified match mode flags.  These compile methods,
    * rather than the constructors, are the usual way that RegexPattern objects
    * are created.
    *
    * <p>Note that RegexPattern objects must not be deleted while RegexMatcher
    * objects created from the pattern are active.  RegexMatchers keep a pointer
    * back to their pattern, so premature deletion of the pattern is a
    * catastrophic error.</p>
    *
    * <p>Note that it is often more convenient to construct a RegexMatcher directly
    *    from a pattern string instead of than separately compiling the pattern and
    *    then creating a RegexMatcher object from the pattern.</p>
    *
    * @param regex The regular expression to be compiled.
    * @param flags The match mode flags to be used.
    * @param status   A reference to a UErrorCode to receive any errors.
    * @return      A regexPattern object for the compiled pattern.
    *
    * @stable ICU 2.6
    */
    static RegexPattern * U_EXPORT2 compile( const UnicodeString &regex,
        uint32_t             flags,
        UErrorCode           &status);

   /**
    * Compiles the regular expression in string form into a RegexPattern
    * object using the specified match mode flags.  These compile methods,
    * rather than the constructors, are the usual way that RegexPattern objects
    * are created.
    *
    * <p>Note that RegexPattern objects must not be deleted while RegexMatcher
    * objects created from the pattern are active.  RegexMatchers keep a pointer
    * back to their pattern, so premature deletion of the pattern is a
    * catastrophic error.</p>
    *
    * <p>Note that it is often more convenient to construct a RegexMatcher directly
    *    from a pattern string instead of than separately compiling the pattern and
    *    then creating a RegexMatcher object from the pattern.</p>
    *
    * @param regex The regular expression to be compiled. Note, the text referred
    *              to by this UText must not be deleted during the lifetime of the
    *              RegexPattern object or any RegexMatcher object created from it.
    * @param flags The match mode flags to be used.
    * @param status   A reference to a UErrorCode to receive any errors.
    * @return      A regexPattern object for the compiled pattern.
    *
    * @stable ICU 4.6
    */
    static RegexPattern * U_EXPORT2 compile( UText *regex,
        uint32_t             flags,
        UErrorCode           &status);

   /**
    * Get the match mode flags that were used when compiling this pattern.
    * @return  the match mode flags
    * @stable ICU 2.4
    */
    virtual uint32_t flags() const;

   /**
    * Creates a RegexMatcher that will match the given input against this pattern.  The
    * RegexMatcher can then be used to perform match, find or replace operations
    * on the input.  Note that a RegexPattern object must not be deleted while
    * RegexMatchers created from it still exist and might possibly be used again.
    * <p>
    * The matcher will retain a reference to the supplied input string, and all regexp
    * pattern matching operations happen directly on this original string.  It is
    * critical that the string not be altered or deleted before use by the regular
    * expression operations is complete.
    *
    * @param input    The input string to which the regular expression will be applied.
    * @param status   A reference to a UErrorCode to receive any errors.
    * @return         A RegexMatcher object for this pattern and input.
    *
    * @stable ICU 2.4
    */
    virtual RegexMatcher *matcher(const UnicodeString &input,
        UErrorCode          &status) const;
        
private:
    /**
     * Cause a compilation error if an application accidentally attempts to
     *   create a matcher with a (UChar *) string as input rather than
     *   a UnicodeString.  Avoids a dangling reference to a temporary string.
     * <p>
     * To efficiently work with UChar *strings, wrap the data in a UnicodeString
     * using one of the aliasing constructors, such as
     * <code>UnicodeString(UBool isTerminated, const UChar *text, int32_t textLength);</code>
     * or in a UText, using
     * <code>utext_openUChars(UText *ut, const UChar *text, int64_t textLength, UErrorCode *status);</code>
     *
     */
    RegexMatcher *matcher(const UChar *input,
        UErrorCode          &status) const;
public:


   /**
    * Creates a RegexMatcher that will match against this pattern.  The
    * RegexMatcher can be used to perform match, find or replace operations.
    * Note that a RegexPattern object must not be deleted while
    * RegexMatchers created from it still exist and might possibly be used again.
    *
    * @param status   A reference to a UErrorCode to receive any errors.
    * @return      A RegexMatcher object for this pattern and input.
    *
    * @stable ICU 2.6
    */
    virtual RegexMatcher *matcher(UErrorCode  &status) const;


   /**
    * Test whether a string matches a regular expression.  This convenience function
    * both compiles the regular expression and applies it in a single operation.
    * Note that if the same pattern needs to be applied repeatedly, this method will be
    * less efficient than creating and reusing a RegexMatcher object.
    *
    * @param regex The regular expression
    * @param input The string data to be matched
    * @param pe Receives the position of any syntax errors within the regular expression
    * @param status A reference to a UErrorCode to receive any errors.
    * @return True if the regular expression exactly matches the full input string.
    *
    * @stable ICU 2.4
    */
    static UBool U_EXPORT2 matches(const UnicodeString   &regex,
        const UnicodeString   &input,
              UParseError     &pe,
              UErrorCode      &status);

   /**
    * Test whether a string matches a regular expression.  This convenience function
    * both compiles the regular expression and applies it in a single operation.
    * Note that if the same pattern needs to be applied repeatedly, this method will be
    * less efficient than creating and reusing a RegexMatcher object.
    *
    * @param regex The regular expression
    * @param input The string data to be matched
    * @param pe Receives the position of any syntax errors within the regular expression
    * @param status A reference to a UErrorCode to receive any errors.
    * @return True if the regular expression exactly matches the full input string.
    *
    * @stable ICU 4.6
    */
    static UBool U_EXPORT2 matches(UText *regex,
        UText           *input,
        UParseError     &pe,
        UErrorCode      &status);

   /**
    * Returns the regular expression from which this pattern was compiled. This method will work
    * even if the pattern was compiled from a UText.
    *
    * Note: If the pattern was originally compiled from a UText, and that UText was modified,
    * the returned string may no longer reflect the RegexPattern object.
    * @stable ICU 2.4
    */
    virtual UnicodeString pattern() const;
    
    
   /**
    * Returns the regular expression from which this pattern was compiled. This method will work
    * even if the pattern was compiled from a UnicodeString.
    *
    * Note: This is the original input, not a clone. If the pattern was originally compiled from a
    * UText, and that UText was modified, the returned UText may no longer reflect the RegexPattern
    * object.
    *
    * @stable ICU 4.6
    */
    virtual UText *patternText(UErrorCode      &status) const;


    /**
     * Split a string into fields.  Somewhat like split() from Perl or Java.
     * Pattern matches identify delimiters that separate the input
     * into fields.  The input data between the delimiters becomes the
     * fields themselves.
     *
     * If the delimiter pattern includes capture groups, the captured text will
     * also appear in the destination array of output strings, interspersed
     * with the fields.  This is similar to Perl, but differs from Java, 
     * which ignores the presence of capture groups in the pattern.
     * 
     * Trailing empty fields will always be returned, assuming sufficient
     * destination capacity.  This differs from the default behavior for Java
     * and Perl where trailing empty fields are not returned.
     *
     * The number of strings produced by the split operation is returned.
     * This count includes the strings from capture groups in the delimiter pattern.
     * This behavior differs from Java, which ignores capture groups.
     *
     * For the best performance on split() operations,
     * <code>RegexMatcher::split</code> is preferable to this function
     *
     * @param input   The string to be split into fields.  The field delimiters
     *                match the pattern (in the "this" object)
     * @param dest    An array of UnicodeStrings to receive the results of the split.
     *                This is an array of actual UnicodeString objects, not an
     *                array of pointers to strings.  Local (stack based) arrays can
     *                work well here.
     * @param destCapacity  The number of elements in the destination array.
     *                If the number of fields found is less than destCapacity, the
     *                extra strings in the destination array are not altered.
     *                If the number of destination strings is less than the number
     *                of fields, the trailing part of the input string, including any
     *                field delimiters, is placed in the last destination string.
     * @param status  A reference to a UErrorCode to receive any errors.
     * @return        The number of fields into which the input string was split.
     * @stable ICU 2.4
     */
    virtual int32_t  split(const UnicodeString &input,
        UnicodeString    dest[],
        int32_t          destCapacity,
        UErrorCode       &status) const;


    /**
     * Split a string into fields.  Somewhat like split() from Perl or Java.
     * Pattern matches identify delimiters that separate the input
     * into fields.  The input data between the delimiters becomes the
     * fields themselves.
     *
     * If the delimiter pattern includes capture groups, the captured text will
     * also appear in the destination array of output strings, interspersed
     * with the fields.  This is similar to Perl, but differs from Java, 
     * which ignores the presence of capture groups in the pattern.
     * 
     * Trailing empty fields will always be returned, assuming sufficient
     * destination capacity.  This differs from the default behavior for Java
     * and Perl where trailing empty fields are not returned.
     *
     * The number of strings produced by the split operation is returned.
     * This count includes the strings from capture groups in the delimiter pattern.
     * This behavior differs from Java, which ignores capture groups.
     *
     *  For the best performance on split() operations,
     *  <code>RegexMatcher::split</code> is preferable to this function
     *
     * @param input   The string to be split into fields.  The field delimiters
     *                match the pattern (in the "this" object)
     * @param dest    An array of mutable UText structs to receive the results of the split.
     *                If a field is NULL, a new UText is allocated to contain the results for
     *                that field. This new UText is not guaranteed to be mutable.
     * @param destCapacity  The number of elements in the destination array.
     *                If the number of fields found is less than destCapacity, the
     *                extra strings in the destination array are not altered.
     *                If the number of destination strings is less than the number
     *                of fields, the trailing part of the input string, including any
     *                field delimiters, is placed in the last destination string.
     * @param status  A reference to a UErrorCode to receive any errors.
     * @return        The number of destination strings used.  
     *
     * @stable ICU 4.6
     */
    virtual int32_t  split(UText *input,
        UText            *dest[],
        int32_t          destCapacity,
        UErrorCode       &status) const;


    /**
     * ICU "poor man's RTTI", returns a UClassID for the actual class.
     *
     * @stable ICU 2.4
     */
    virtual UClassID getDynamicClassID() const;

    /**
     * ICU "poor man's RTTI", returns a UClassID for this class.
     *
     * @stable ICU 2.4
     */
    static UClassID U_EXPORT2 getStaticClassID();

private:
    //
    //  Implementation Data
    //
    UText          *fPattern;      // The original pattern string.
    UnicodeString  *fPatternString; // The original pattern UncodeString if relevant
    uint32_t        fFlags;        // The flags used when compiling the pattern.
                                   //
    UVector64       *fCompiledPat; // The compiled pattern p-code.
    UnicodeString   fLiteralText;  // Any literal string data from the pattern,
                                   //   after un-escaping, for use during the match.

    UVector         *fSets;        // Any UnicodeSets referenced from the pattern.
    Regex8BitSet    *fSets8;       //      (and fast sets for latin-1 range.)


    UErrorCode      fDeferredStatus; // status if some prior error has left this
                                   //  RegexPattern in an unusable state.

    int32_t         fMinMatchLen;  // Minimum Match Length.  All matches will have length
                                   //   >= this value.  For some patterns, this calculated
                                   //   value may be less than the true shortest
                                   //   possible match.
    
    int32_t         fFrameSize;    // Size of a state stack frame in the
                                   //   execution engine.

    int32_t         fDataSize;     // The size of the data needed by the pattern that
                                   //   does not go on the state stack, but has just
                                   //   a single copy per matcher.

    UVector32       *fGroupMap;    // Map from capture group number to position of
                                   //   the group's variables in the matcher stack frame.

    int32_t         fMaxCaptureDigits;

    UnicodeSet     **fStaticSets;  // Ptr to static (shared) sets for predefined
                                   //   regex character classes, e.g. Word.

    Regex8BitSet   *fStaticSets8;  // Ptr to the static (shared) latin-1 only
                                   //  sets for predefined regex classes.

    int32_t         fStartType;    // Info on how a match must start.
    int32_t         fInitialStringIdx;     //
    int32_t         fInitialStringLen;
    UnicodeSet     *fInitialChars;
    UChar32         fInitialChar;
    Regex8BitSet   *fInitialChars8;
    UBool           fNeedsAltInput;

    friend class RegexCompile;
    friend class RegexMatcher;
    friend class RegexCImpl;

    //
    //  Implementation Methods
    //
    void        init();            // Common initialization, for use by constructors.
    void        zap();             // Common cleanup

    void        dumpOp(int32_t index) const;

  public:
#ifndef U_HIDE_INTERNAL_API
    /**
      * Dump a compiled pattern. Internal debug function.
      * @internal
      */
    void        dumpPattern() const;
#endif  /* U_HIDE_INTERNAL_API */
};



/**
 *  class RegexMatcher bundles together a regular expression pattern and
 *  input text to which the expression can be applied.  It includes methods
 *  for testing for matches, and for find and replace operations.
 *
 * <p>Class RegexMatcher is not intended to be subclassed.</p>
 *
 * @stable ICU 2.4
 */
class U_I18N_API RegexMatcher U_FINAL : public UObject {
public:

    /**
      * Construct a RegexMatcher for a regular expression.
      * This is a convenience method that avoids the need to explicitly create
      * a RegexPattern object.  Note that if several RegexMatchers need to be
      * created for the same expression, it will be more efficient to
      * separately create and cache a RegexPattern object, and use
      * its matcher() method to create the RegexMatcher objects.
      *
      *  @param regexp The Regular Expression to be compiled.
      *  @param flags  Regular expression options, such as case insensitive matching.
      *                @see UREGEX_CASE_INSENSITIVE
      *  @param status Any errors are reported by setting this UErrorCode variable.
      *  @stable ICU 2.6
      */
    RegexMatcher(const UnicodeString &regexp, uint32_t flags, UErrorCode &status);

    /**
      * Construct a RegexMatcher for a regular expression.
      * This is a convenience method that avoids the need to explicitly create
      * a RegexPattern object.  Note that if several RegexMatchers need to be
      * created for the same expression, it will be more efficient to
      * separately create and cache a RegexPattern object, and use
      * its matcher() method to create the RegexMatcher objects.
      *
      *  @param regexp The regular expression to be compiled.
      *  @param flags  Regular expression options, such as case insensitive matching.
      *                @see UREGEX_CASE_INSENSITIVE
      *  @param status Any errors are reported by setting this UErrorCode variable.
      *
      *  @stable ICU 4.6
      */
    RegexMatcher(UText *regexp, uint32_t flags, UErrorCode &status);

    /**
      * Construct a RegexMatcher for a regular expression.
      * This is a convenience method that avoids the need to explicitly create
      * a RegexPattern object.  Note that if several RegexMatchers need to be
      * created for the same expression, it will be more efficient to
      * separately create and cache a RegexPattern object, and use
      * its matcher() method to create the RegexMatcher objects.
      * <p>
      * The matcher will retain a reference to the supplied input string, and all regexp
      * pattern matching operations happen directly on the original string.  It is
      * critical that the string not be altered or deleted before use by the regular
      * expression operations is complete.
      *
      *  @param regexp The Regular Expression to be compiled.
      *  @param input  The string to match.  The matcher retains a reference to the
      *                caller's string; mo copy is made.
      *  @param flags  Regular expression options, such as case insensitive matching.
      *                @see UREGEX_CASE_INSENSITIVE
      *  @param status Any errors are reported by setting this UErrorCode variable.
      *  @stable ICU 2.6
      */
    RegexMatcher(const UnicodeString &regexp, const UnicodeString &input,
        uint32_t flags, UErrorCode &status);

    /**
      * Construct a RegexMatcher for a regular expression.
      * This is a convenience method that avoids the need to explicitly create
      * a RegexPattern object.  Note that if several RegexMatchers need to be
      * created for the same expression, it will be more efficient to
      * separately create and cache a RegexPattern object, and use
      * its matcher() method to create the RegexMatcher objects.
      * <p>
      * The matcher will make a shallow clone of the supplied input text, and all regexp
      * pattern matching operations happen on this clone.  While read-only operations on
      * the supplied text are permitted, it is critical that the underlying string not be
      * altered or deleted before use by the regular expression operations is complete.
      *
      *  @param regexp The Regular Expression to be compiled.
      *  @param input  The string to match.  The matcher retains a shallow clone of the text.
      *  @param flags  Regular expression options, such as case insensitive matching.
      *                @see UREGEX_CASE_INSENSITIVE
      *  @param status Any errors are reported by setting this UErrorCode variable.
      *
      *  @stable ICU 4.6
      */
    RegexMatcher(UText *regexp, UText *input,
        uint32_t flags, UErrorCode &status);

private:
    /**
     * Cause a compilation error if an application accidentally attempts to
     *   create a matcher with a (UChar *) string as input rather than
     *   a UnicodeString.    Avoids a dangling reference to a temporary string.
     * <p>
     * To efficiently work with UChar *strings, wrap the data in a UnicodeString
     * using one of the aliasing constructors, such as
     * <code>UnicodeString(UBool isTerminated, const UChar *text, int32_t textLength);</code>
     * or in a UText, using
     * <code>utext_openUChars(UText *ut, const UChar *text, int64_t textLength, UErrorCode *status);</code>
     *
     */
    RegexMatcher(const UnicodeString &regexp, const UChar *input,
        uint32_t flags, UErrorCode &status);
public:


   /**
    *   Destructor.
    *
    *  @stable ICU 2.4
    */
    virtual ~RegexMatcher();


   /**
    *   Attempts to match the entire input region against the pattern.
    *    @param   status     A reference to a UErrorCode to receive any errors.
    *    @return TRUE if there is a match
    *    @stable ICU 2.4
    */
    virtual UBool matches(UErrorCode &status);


   /**
    *   Resets the matcher, then attempts to match the input beginning 
    *   at the specified startIndex, and extending to the end of the input.
    *   The input region is reset to include the entire input string.
    *   A successful match must extend to the end of the input.
    *    @param   startIndex The input string (native) index at which to begin matching.
    *    @param   status     A reference to a UErrorCode to receive any errors.
    *    @return TRUE if there is a match
    *    @stable ICU 2.8
    */
    virtual UBool matches(int64_t startIndex, UErrorCode &status);


   /**
    *   Attempts to match the input string, starting from the beginning of the region,
    *   against the pattern.  Like the matches() method, this function 
    *   always starts at the beginning of the input region;
    *   unlike that function, it does not require that the entire region be matched.
    *
    *   <p>If the match succeeds then more information can be obtained via the <code>start()</code>,
    *     <code>end()</code>, and <code>group()</code> functions.</p>
    *
    *    @param   status     A reference to a UErrorCode to receive any errors.
    *    @return  TRUE if there is a match at the start of the input string.
    *    @stable ICU 2.4
    */
    virtual UBool lookingAt(UErrorCode &status);


  /**
    *   Attempts to match the input string, starting from the specified index, against the pattern.
    *   The match may be of any length, and is not required to extend to the end
    *   of the input string.  Contrast with match().
    *
    *   <p>If the match succeeds then more information can be obtained via the <code>start()</code>,
    *     <code>end()</code>, and <code>group()</code> functions.</p>
    *
    *    @param   startIndex The input string (native) index at which to begin matching.
    *    @param   status     A reference to a UErrorCode to receive any errors.
    *    @return  TRUE if there is a match.
    *    @stable ICU 2.8
    */
    virtual UBool lookingAt(int64_t startIndex, UErrorCode &status);


   /**
    *  Find the next pattern match in the input string.
    *  The find begins searching the input at the location following the end of
    *  the previous match, or at the start of the string if there is no previous match.
    *  If a match is found, <code>start(), end()</code> and <code>group()</code>
    *  will provide more information regarding the match.
    *  <p>Note that if the input string is changed by the application,
    *     use find(startPos, status) instead of find(), because the saved starting
    *     position may not be valid with the altered input string.</p>
    *  @return  TRUE if a match is found.
    *  @stable ICU 2.4
    */
    virtual UBool find();


   /**
    *  Find the next pattern match in the input string.
    *  The find begins searching the input at the location following the end of
    *  the previous match, or at the start of the string if there is no previous match.
    *  If a match is found, <code>start(), end()</code> and <code>group()</code>
    *  will provide more information regarding the match.
    *  <p>Note that if the input string is changed by the application,
    *     use find(startPos, status) instead of find(), because the saved starting
    *     position may not be valid with the altered input string.</p>
    *  @param   status  A reference to a UErrorCode to receive any errors.
    *  @return  TRUE if a match is found.
    *  @internal
    */
    virtual UBool find(UErrorCode &status);

   /**
    *   Resets this RegexMatcher and then attempts to find the next substring of the
    *   input string that matches the pattern, starting at the specified index.
    *
    *   @param   start     The (native) index in the input string to begin the search.
    *   @param   status    A reference to a UErrorCode to receive any errors.
    *   @return  TRUE if a match is found.
    *   @stable ICU 2.4
    */
    virtual UBool find(int64_t start, UErrorCode &status);


   /**
    *   Returns a string containing the text matched by the previous match.
    *   If the pattern can match an empty string, an empty string may be returned.
    *   @param   status      A reference to a UErrorCode to receive any errors.
    *                        Possible errors are  U_REGEX_INVALID_STATE if no match
    *                        has been attempted or the last match failed.
    *   @return  a string containing the matched input text.
    *   @stable ICU 2.4
    */
    virtual UnicodeString group(UErrorCode &status) const;


   /**
    *    Returns a string containing the text captured by the given group
    *    during the previous match operation.  Group(0) is the entire match.
    *
    *    @param groupNum the capture group number
    *    @param   status     A reference to a UErrorCode to receive any errors.
    *                        Possible errors are  U_REGEX_INVALID_STATE if no match
    *                        has been attempted or the last match failed and
    *                        U_INDEX_OUTOFBOUNDS_ERROR for a bad capture group number.
    *    @return the captured text
    *    @stable ICU 2.4
    */
    virtual UnicodeString group(int32_t groupNum, UErrorCode &status) const;


   /**
    *   Returns the number of capturing groups in this matcher's pattern.
    *   @return the number of capture groups
    *   @stable ICU 2.4
    */
    virtual int32_t groupCount() const;


   /**
    *   Returns a shallow clone of the entire live input string with the UText current native index
    *   set to the beginning of the requested group.
    *
    *   @param   dest        The UText into which the input should be cloned, or NULL to create a new UText
    *   @param   group_len   A reference to receive the length of the desired capture group
    *   @param   status      A reference to a UErrorCode to receive any errors.
    *                        Possible errors are  U_REGEX_INVALID_STATE if no match
    *                        has been attempted or the last match failed and
    *                        U_INDEX_OUTOFBOUNDS_ERROR for a bad capture group number.
    *   @return dest if non-NULL, a shallow copy of the input text otherwise
    *
    *   @stable ICU 4.6
    */
    virtual UText *group(UText *dest, int64_t &group_len, UErrorCode &status) const; 

   /**
    *   Returns a shallow clone of the entire live input string with the UText current native index
    *   set to the beginning of the requested group.
    *
    *   @param   groupNum   The capture group number.
    *   @param   dest        The UText into which the input should be cloned, or NULL to create a new UText.
    *   @param   group_len   A reference to receive the length of the desired capture group
    *   @param   status      A reference to a UErrorCode to receive any errors.
    *                        Possible errors are  U_REGEX_INVALID_STATE if no match
    *                        has been attempted or the last match failed and
    *                        U_INDEX_OUTOFBOUNDS_ERROR for a bad capture group number.
    *   @return dest if non-NULL, a shallow copy of the input text otherwise
    *
    *   @stable ICU 4.6
    */
    virtual UText *group(int32_t groupNum, UText *dest, int64_t &group_len, UErrorCode &status) const;

   /**
    *   Returns a string containing the text captured by the given group
    *   during the previous match operation.  Group(0) is the entire match.
    *
    *   @param   groupNum    the capture group number
    *   @param   dest        A mutable UText in which the matching text is placed.
    *                        If NULL, a new UText will be created (which may not be mutable).
    *   @param   status      A reference to a UErrorCode to receive any errors.
    *                        Possible errors are  U_REGEX_INVALID_STATE if no match
    *                        has been attempted or the last match failed.
    *   @return  A string containing the matched input text. If a pre-allocated UText
    *            was provided, it will always be used and returned.
    *
    *   @internal ICU 4.4 technology preview
    */
    virtual UText *group(int32_t groupNum, UText *dest, UErrorCode &status) const;


   /**
    *   Returns the index in the input string of the start of the text matched
    *   during the previous match operation.
    *    @param   status      a reference to a UErrorCode to receive any errors.
    *    @return              The (native) position in the input string of the start of the last match.
    *    @stable ICU 2.4
    */
    virtual int32_t start(UErrorCode &status) const;

   /**
    *   Returns the index in the input string of the start of the text matched
    *   during the previous match operation.
    *    @param   status      a reference to a UErrorCode to receive any errors.
    *    @return              The (native) position in the input string of the start of the last match.
    *   @stable ICU 4.6
    */
    virtual int64_t start64(UErrorCode &status) const;


   /**
    *   Returns the index in the input string of the start of the text matched by the
    *    specified capture group during the previous match operation.  Return -1 if
    *    the capture group exists in the pattern, but was not part of the last match.
    *
    *    @param  group       the capture group number
    *    @param  status      A reference to a UErrorCode to receive any errors.  Possible
    *                        errors are  U_REGEX_INVALID_STATE if no match has been
    *                        attempted or the last match failed, and
    *                        U_INDEX_OUTOFBOUNDS_ERROR for a bad capture group number
    *    @return the (native) start position of substring matched by the specified group.
    *    @stable ICU 2.4
    */
    virtual int32_t start(int32_t group, UErrorCode &status) const;

   /**
    *   Returns the index in the input string of the start of the text matched by the
    *    specified capture group during the previous match operation.  Return -1 if
    *    the capture group exists in the pattern, but was not part of the last match.
    *
    *    @param  group       the capture group number.
    *    @param  status      A reference to a UErrorCode to receive any errors.  Possible
    *                        errors are  U_REGEX_INVALID_STATE if no match has been
    *                        attempted or the last match failed, and
    *                        U_INDEX_OUTOFBOUNDS_ERROR for a bad capture group number.
    *    @return the (native) start position of substring matched by the specified group.
    *    @stable ICU 4.6
    */
    virtual int64_t start64(int32_t group, UErrorCode &status) const;


   /**
    *    Returns the index in the input string of the first character following the
    *    text matched during the previous match operation.
    *
    *   @param   status      A reference to a UErrorCode to receive any errors.  Possible
    *                        errors are  U_REGEX_INVALID_STATE if no match has been
    *                        attempted or the last match failed.
    *    @return the index of the last character matched, plus one.
    *                        The index value returned is a native index, corresponding to
    *                        code units for the underlying encoding type, for example,
    *                        a byte index for UTF-8.
    *   @stable ICU 2.4
    */
    virtual int32_t end(UErrorCode &status) const;

   /**
    *    Returns the index in the input string of the first character following the
    *    text matched during the previous match operation.
    *
    *   @param   status      A reference to a UErrorCode to receive any errors.  Possible
    *                        errors are  U_REGEX_INVALID_STATE if no match has been
    *                        attempted or the last match failed.
    *    @return the index of the last character matched, plus one.
    *                        The index value returned is a native index, corresponding to
    *                        code units for the underlying encoding type, for example,
    *                        a byte index for UTF-8.
    *   @stable ICU 4.6
    */
    virtual int64_t end64(UErrorCode &status) const;


   /**
    *    Returns the index in the input string of the character following the
    *    text matched by the specified capture group during the previous match operation.
    *
    *    @param group  the capture group number
    *    @param   status      A reference to a UErrorCode to receive any errors.  Possible
    *                        errors are  U_REGEX_INVALID_STATE if no match has been
    *                        attempted or the last match failed and
    *                        U_INDEX_OUTOFBOUNDS_ERROR for a bad capture group number
    *    @return  the index of the first character following the text
    *              captured by the specified group during the previous match operation.
    *              Return -1 if the capture group exists in the pattern but was not part of the match.
    *              The index value returned is a native index, corresponding to
    *              code units for the underlying encoding type, for example,
    *              a byte index for UTF8.
    *    @stable ICU 2.4
    */
    virtual int32_t end(int32_t group, UErrorCode &status) const;

   /**
    *    Returns the index in the input string of the character following the
    *    text matched by the specified capture group during the previous match operation.
    *
    *    @param group  the capture group number
    *    @param   status      A reference to a UErrorCode to receive any errors.  Possible
    *                        errors are  U_REGEX_INVALID_STATE if no match has been
    *                        attempted or the last match failed and
    *                        U_INDEX_OUTOFBOUNDS_ERROR for a bad capture group number
    *    @return  the index of the first character following the text
    *              captured by the specified group during the previous match operation.
    *              Return -1 if the capture group exists in the pattern but was not part of the match.
    *              The index value returned is a native index, corresponding to
    *              code units for the underlying encoding type, for example,
    *              a byte index for UTF8.
    *   @stable ICU 4.6
    */
    virtual int64_t end64(int32_t group, UErrorCode &status) const;


   /**
    *   Resets this matcher.  The effect is to remove any memory of previous matches,
    *       and to cause subsequent find() operations to begin at the beginning of
    *       the input string.
    *
    *   @return this RegexMatcher.
    *   @stable ICU 2.4
    */
    virtual RegexMatcher &reset();


   /**
    *   Resets this matcher, and set the current input position.
    *   The effect is to remove any memory of previous matches,
    *       and to cause subsequent find() operations to begin at
    *       the specified (native) position in the input string.
    * <p>
    *   The matcher's region is reset to its default, which is the entire
    *   input string.
    * <p>
    *   An alternative to this function is to set a match region
    *   beginning at the desired index.
    *
    *   @return this RegexMatcher.
    *   @stable ICU 2.8
    */
    virtual RegexMatcher &reset(int64_t index, UErrorCode &status);


   /**
    *   Resets this matcher with a new input string.  This allows instances of RegexMatcher
    *     to be reused, which is more efficient than creating a new RegexMatcher for
    *     each input string to be processed.
    *   @param input The new string on which subsequent pattern matches will operate.
    *                The matcher retains a reference to the callers string, and operates
    *                directly on that.  Ownership of the string remains with the caller.
    *                Because no copy of the string is made, it is essential that the
    *                caller not delete the string until after regexp operations on it
    *                are done.
    *                Note that while a reset on the matcher with an input string that is then
    *                modified across/during matcher operations may be supported currently for UnicodeString,
    *                this was not originally intended behavior, and support for this is not guaranteed
    *                in upcoming versions of ICU.
    *   @return this RegexMatcher.
    *   @stable ICU 2.4
    */
    virtual RegexMatcher &reset(const UnicodeString &input);


   /**
    *   Resets this matcher with a new input string.  This allows instances of RegexMatcher
    *     to be reused, which is more efficient than creating a new RegexMatcher for
    *     each input string to be processed.
    *   @param input The new string on which subsequent pattern matches will operate.
    *                The matcher makes a shallow clone of the given text; ownership of the
    *                original string remains with the caller. Because no deep copy of the
    *                text is made, it is essential that the caller not modify the string
    *                until after regexp operations on it are done.
    *   @return this RegexMatcher.
    *
    *   @stable ICU 4.6
    */
    virtual RegexMatcher &reset(UText *input);


  /**
    *  Set the subject text string upon which the regular expression is looking for matches
    *  without changing any other aspect of the matching state.
    *  The new and previous text strings must have the same content.
    *
    *  This function is intended for use in environments where ICU is operating on 
    *  strings that may move around in memory.  It provides a mechanism for notifying
    *  ICU that the string has been relocated, and providing a new UText to access the
    *  string in its new position.
    *
    *  Note that the regular expression implementation never copies the underlying text
    *  of a string being matched, but always operates directly on the original text 
    *  provided by the user. Refreshing simply drops the references to the old text 
    *  and replaces them with references to the new.
    *
    *  Caution:  this function is normally used only by very specialized,
    *  system-level code.  One example use case is with garbage collection that moves
    *  the text in memory.
    *
    * @param input      The new (moved) text string.
    * @param status     Receives errors detected by this function.
    *
    * @stable ICU 4.8 
    */
    virtual RegexMatcher &refreshInputText(UText *input, UErrorCode &status);

private:
    /**
     * Cause a compilation error if an application accidentally attempts to
     *   reset a matcher with a (UChar *) string as input rather than
     *   a UnicodeString.    Avoids a dangling reference to a temporary string.
     * <p>
     * To efficiently work with UChar *strings, wrap the data in a UnicodeString
     * using one of the aliasing constructors, such as
     * <code>UnicodeString(UBool isTerminated, const UChar *text, int32_t textLength);</code>
     * or in a UText, using
     * <code>utext_openUChars(UText *ut, const UChar *text, int64_t textLength, UErrorCode *status);</code>
     *
     */
    RegexMatcher &reset(const UChar *input);
public:

   /**
    *   Returns the input string being matched.  Ownership of the string belongs to
    *   the matcher; it should not be altered or deleted. This method will work even if the input
    *   was originally supplied as a UText.
    *   @return the input string
    *   @stable ICU 2.4
    */
    virtual const UnicodeString &input() const;
    
   /**
    *   Returns the input string being matched.  This is the live input text; it should not be
    *   altered or deleted. This method will work even if the input was originally supplied as
    *   a UnicodeString.
    *   @return the input text
    *
    *   @stable ICU 4.6
    */
    virtual UText *inputText() const;
    
   /**
    *   Returns the input string being matched, either by copying it into the provided
    *   UText parameter or by returning a shallow clone of the live input. Note that copying
    *   the entire input may cause significant performance and memory issues.
    *   @param dest The UText into which the input should be copied, or NULL to create a new UText
    *   @param status error code
    *   @return dest if non-NULL, a shallow copy of the input text otherwise
    *
    *   @stable ICU 4.6
    */
    virtual UText *getInput(UText *dest, UErrorCode &status) const;
    

   /** Sets the limits of this matcher's region.
     * The region is the part of the input string that will be searched to find a match.
     * Invoking this method resets the matcher, and then sets the region to start
     * at the index specified by the start parameter and end at the index specified
     * by the end parameter.
     *
     * Depending on the transparency and anchoring being used (see useTransparentBounds
     * and useAnchoringBounds), certain constructs such as anchors may behave differently
     * at or around the boundaries of the region
     *
     * The function will fail if start is greater than limit, or if either index
     *  is less than zero or greater than the length of the string being matched.
     *
     * @param start  The (native) index to begin searches at.
     * @param limit  The index to end searches at (exclusive).
     * @param status A reference to a UErrorCode to receive any errors.
     * @stable ICU 4.0
     */
     virtual RegexMatcher &region(int64_t start, int64_t limit, UErrorCode &status);

   /** 
     * Identical to region(start, limit, status) but also allows a start position without
     *  resetting the region state.
     * @param regionStart The region start
     * @param regionLimit the limit of the region
     * @param startIndex  The (native) index within the region bounds at which to begin searches.
     * @param status A reference to a UErrorCode to receive any errors.
     *                If startIndex is not within the specified region bounds, 
     *                U_INDEX_OUTOFBOUNDS_ERROR is returned.
     * @stable ICU 4.6
     */
     virtual RegexMatcher &region(int64_t regionStart, int64_t regionLimit, int64_t startIndex, UErrorCode &status);

   /**
     * Reports the start index of this matcher's region. The searches this matcher
     * conducts are limited to finding matches within regionStart (inclusive) and
     * regionEnd (exclusive).
     *
     * @return The starting (native) index of this matcher's region.
     * @stable ICU 4.0
     */
     virtual int32_t regionStart() const;

   /**
     * Reports the start index of this matcher's region. The searches this matcher
     * conducts are limited to finding matches within regionStart (inclusive) and
     * regionEnd (exclusive).
     *
     * @return The starting (native) index of this matcher's region.
     * @stable ICU 4.6
     */
     virtual int64_t regionStart64() const;


    /**
      * Reports the end (limit) index (exclusive) of this matcher's region. The searches
      * this matcher conducts are limited to finding matches within regionStart
      * (inclusive) and regionEnd (exclusive).
      *
      * @return The ending point (native) of this matcher's region.
      * @stable ICU 4.0
      */
      virtual int32_t regionEnd() const;

   /**
     * Reports the end (limit) index (exclusive) of this matcher's region. The searches
     * this matcher conducts are limited to finding matches within regionStart
     * (inclusive) and regionEnd (exclusive).
     *
     * @return The ending point (native) of this matcher's region.
     * @stable ICU 4.6
     */
      virtual int64_t regionEnd64() const;

    /**
      * Queries the transparency of region bounds for this matcher.
      * See useTransparentBounds for a description of transparent and opaque bounds.
      * By default, a matcher uses opaque region boundaries.
      *
      * @return TRUE if this matcher is using opaque bounds, false if it is not.
      * @stable ICU 4.0
      */
      virtual UBool hasTransparentBounds() const;

    /**
      * Sets the transparency of region bounds for this matcher.
      * Invoking this function with an argument of true will set this matcher to use transparent bounds.
      * If the boolean argument is false, then opaque bounds will be used.
      *
      * Using transparent bounds, the boundaries of this matcher's region are transparent
      * to lookahead, lookbehind, and boundary matching constructs. Those constructs can
      * see text beyond the boundaries of the region while checking for a match.
      *
      * With opaque bounds, no text outside of the matcher's region is visible to lookahead,
      * lookbehind, and boundary matching constructs.
      *
      * By default, a matcher uses opaque bounds.
      *
      * @param   b TRUE for transparent bounds; FALSE for opaque bounds
      * @return  This Matcher;
      * @stable ICU 4.0
      **/
      virtual RegexMatcher &useTransparentBounds(UBool b);

     
    /**
      * Return true if this matcher is using anchoring bounds.
      * By default, matchers use anchoring region bounds.
      *
      * @return TRUE if this matcher is using anchoring bounds.
      * @stable ICU 4.0
      */    
      virtual UBool hasAnchoringBounds() const;


    /**
      * Set whether this matcher is using Anchoring Bounds for its region.
      * With anchoring bounds, pattern anchors such as ^ and $ will match at the start
      * and end of the region.  Without Anchoring Bounds, anchors will only match at
      * the positions they would in the complete text.
      *
      * Anchoring Bounds are the default for regions.
      *
      * @param b TRUE if to enable anchoring bounds; FALSE to disable them.
      * @return  This Matcher
      * @stable ICU 4.0
      */
      virtual RegexMatcher &useAnchoringBounds(UBool b);


    /**
      * Return TRUE if the most recent matching operation attempted to access
      *  additional input beyond the available input text.
      *  In this case, additional input text could change the results of the match.
      *
      *  hitEnd() is defined for both successful and unsuccessful matches.
      *  In either case hitEnd() will return TRUE if if the end of the text was
      *  reached at any point during the matching process.
      *
      *  @return  TRUE if the most recent match hit the end of input
      *  @stable ICU 4.0
      */
      virtual UBool hitEnd() const;

    /**
      * Return TRUE the most recent match succeeded and additional input could cause
      * it to fail. If this method returns false and a match was found, then more input
      * might change the match but the match won't be lost. If a match was not found,
      * then requireEnd has no meaning.
      *
      * @return TRUE if more input could cause the most recent match to no longer match.
      * @stable ICU 4.0
      */
      virtual UBool requireEnd() const;


   /**
    *    Returns the pattern that is interpreted by this matcher.
    *    @return  the RegexPattern for this RegexMatcher
    *    @stable ICU 2.4
    */
    virtual const RegexPattern &pattern() const;


   /**
    *    Replaces every substring of the input that matches the pattern
    *    with the given replacement string.  This is a convenience function that
    *    provides a complete find-and-replace-all operation.
    *
    *    This method first resets this matcher. It then scans the input string
    *    looking for matches of the pattern. Input that is not part of any
    *    match is left unchanged; each match is replaced in the result by the
    *    replacement string. The replacement string may contain references to
    *    capture groups.
    *
    *    @param   replacement a string containing the replacement text.
    *    @param   status      a reference to a UErrorCode to receive any errors.
    *    @return              a string containing the results of the find and replace.
    *    @stable ICU 2.4
    */
    virtual UnicodeString replaceAll(const UnicodeString &replacement, UErrorCode &status);


   /**
    *    Replaces every substring of the input that matches the pattern
    *    with the given replacement string.  This is a convenience function that
    *    provides a complete find-and-replace-all operation.
    *
    *    This method first resets this matcher. It then scans the input string
    *    looking for matches of the pattern. Input that is not part of any
    *    match is left unchanged; each match is replaced in the result by the
    *    replacement string. The replacement string may contain references to
    *    capture groups.
    *
    *    @param   replacement a string containing the replacement text.
    *    @param   dest        a mutable UText in which the results are placed.
    *                          If NULL, a new UText will be created (which may not be mutable).
    *    @param   status      a reference to a UErrorCode to receive any errors.
    *    @return              a string containing the results of the find and replace.
    *                          If a pre-allocated UText was provided, it will always be used and returned.
    *
    *    @stable ICU 4.6
    */
    virtual UText *replaceAll(UText *replacement, UText *dest, UErrorCode &status);
    

   /**
    * Replaces the first substring of the input that matches
    * the pattern with the replacement string.   This is a convenience
    * function that provides a complete find-and-replace operation.
    *
    * <p>This function first resets this RegexMatcher. It then scans the input string
    * looking for a match of the pattern. Input that is not part
    * of the match is appended directly to the result string; the match is replaced
    * in the result by the replacement string. The replacement string may contain
    * references to captured groups.</p>
    *
    * <p>The state of the matcher (the position at which a subsequent find()
    *    would begin) after completing a replaceFirst() is not specified.  The
    *    RegexMatcher should be reset before doing additional find() operations.</p>
    *
    *    @param   replacement a string containing the replacement text.
    *    @param   status      a reference to a UErrorCode to receive any errors.
    *    @return              a string containing the results of the find and replace.
    *    @stable ICU 2.4
    */
    virtual UnicodeString replaceFirst(const UnicodeString &replacement, UErrorCode &status);
    

   /**
    * Replaces the first substring of the input that matches
    * the pattern with the replacement string.   This is a convenience
    * function that provides a complete find-and-replace operation.
    *
    * <p>This function first resets this RegexMatcher. It then scans the input string
    * looking for a match of the pattern. Input that is not part
    * of the match is appended directly to the result string; the match is replaced
    * in the result by the replacement string. The replacement string may contain
    * references to captured groups.</p>
    *
    * <p>The state of the matcher (the position at which a subsequent find()
    *    would begin) after completing a replaceFirst() is not specified.  The
    *    RegexMatcher should be reset before doing additional find() operations.</p>
    *
    *    @param   replacement a string containing the replacement text.
    *    @param   dest        a mutable UText in which the results are placed.
    *                          If NULL, a new UText will be created (which may not be mutable).
    *    @param   status      a reference to a UErrorCode to receive any errors.
    *    @return              a string containing the results of the find and replace.
    *                          If a pre-allocated UText was provided, it will always be used and returned.
    *
    *    @stable ICU 4.6
    */
    virtual UText *replaceFirst(UText *replacement, UText *dest, UErrorCode &status);
    
    
   /**
    *   Implements a replace operation intended to be used as part of an
    *   incremental find-and-replace.
    *
    *   <p>The input string, starting from the end of the previous replacement and ending at
    *   the start of the current match, is appended to the destination string.  Then the
    *   replacement string is appended to the output string,
    *   including handling any substitutions of captured text.</p>
    *
    *   <p>For simple, prepackaged, non-incremental find-and-replace
    *   operations, see replaceFirst() or replaceAll().</p>
    *
    *   @param   dest        A UnicodeString to which the results of the find-and-replace are appended.
    *   @param   replacement A UnicodeString that provides the text to be substituted for
    *                        the input text that matched the regexp pattern.  The replacement
    *                        text may contain references to captured text from the
    *                        input.
    *   @param   status      A reference to a UErrorCode to receive any errors.  Possible
    *                        errors are  U_REGEX_INVALID_STATE if no match has been
    *                        attempted or the last match failed, and U_INDEX_OUTOFBOUNDS_ERROR
    *                        if the replacement text specifies a capture group that
    *                        does not exist in the pattern.
    *
    *   @return  this  RegexMatcher
    *   @stable ICU 2.4
    *
    */
    virtual RegexMatcher &appendReplacement(UnicodeString &dest,
        const UnicodeString &replacement, UErrorCode &status);
    
    
   /**
    *   Implements a replace operation intended to be used as part of an
    *   incremental find-and-replace.
    *
    *   <p>The input string, starting from the end of the previous replacement and ending at
    *   the start of the current match, is appended to the destination string.  Then the
    *   replacement string is appended to the output string,
    *   including handling any substitutions of captured text.</p>
    *
    *   <p>For simple, prepackaged, non-incremental find-and-replace
    *   operations, see replaceFirst() or replaceAll().</p>
    *
    *   @param   dest        A mutable UText to which the results of the find-and-replace are appended.
    *                         Must not be NULL.
    *   @param   replacement A UText that provides the text to be substituted for
    *                        the input text that matched the regexp pattern.  The replacement
    *                        text may contain references to captured text from the input.
    *   @param   status      A reference to a UErrorCode to receive any errors.  Possible
    *                        errors are  U_REGEX_INVALID_STATE if no match has been
    *                        attempted or the last match failed, and U_INDEX_OUTOFBOUNDS_ERROR
    *                        if the replacement text specifies a capture group that
    *                        does not exist in the pattern.
    *
    *   @return  this  RegexMatcher
    *
    *   @stable ICU 4.6
    */
    virtual RegexMatcher &appendReplacement(UText *dest,
        UText *replacement, UErrorCode &status);


   /**
    * As the final step in a find-and-replace operation, append the remainder
    * of the input string, starting at the position following the last appendReplacement(),
    * to the destination string. <code>appendTail()</code> is intended to be invoked after one
    * or more invocations of the <code>RegexMatcher::appendReplacement()</code>.
    *
    *  @param dest A UnicodeString to which the results of the find-and-replace are appended.
    *  @return  the destination string.
    *  @stable ICU 2.4
    */
    virtual UnicodeString &appendTail(UnicodeString &dest);


   /**
    * As the final step in a find-and-replace operation, append the remainder
    * of the input string, starting at the position following the last appendReplacement(),
    * to the destination string. <code>appendTail()</code> is intended to be invoked after one
    * or more invocations of the <code>RegexMatcher::appendReplacement()</code>.
    *
    *  @param dest A mutable UText to which the results of the find-and-replace are appended.
    *               Must not be NULL.
    *  @param status error cod
    *  @return  the destination string.
    *
    *  @stable ICU 4.6
    */
    virtual UText *appendTail(UText *dest, UErrorCode &status);


    /**
     * Split a string into fields.  Somewhat like split() from Perl.
     * The pattern matches identify delimiters that separate the input
     *  into fields.  The input data between the matches becomes the
     *  fields themselves.
     *
     * @param input   The string to be split into fields.  The field delimiters
     *                match the pattern (in the "this" object).  This matcher
     *                will be reset to this input string.
     * @param dest    An array of UnicodeStrings to receive the results of the split.
     *                This is an array of actual UnicodeString objects, not an
     *                array of pointers to strings.  Local (stack based) arrays can
     *                work well here.
     * @param destCapacity  The number of elements in the destination array.
     *                If the number of fields found is less than destCapacity, the
     *                extra strings in the destination array are not altered.
     *                If the number of destination strings is less than the number
     *                of fields, the trailing part of the input string, including any
     *                field delimiters, is placed in the last destination string.
     * @param status  A reference to a UErrorCode to receive any errors.
     * @return        The number of fields into which the input string was split.
     * @stable ICU 2.6
     */
    virtual int32_t  split(const UnicodeString &input,
        UnicodeString    dest[],
        int32_t          destCapacity,
        UErrorCode       &status);


    /**
     * Split a string into fields.  Somewhat like split() from Perl.
     * The pattern matches identify delimiters that separate the input
     *  into fields.  The input data between the matches becomes the
     *  fields themselves.
     *
     * @param input   The string to be split into fields.  The field delimiters
     *                match the pattern (in the "this" object).  This matcher
     *                will be reset to this input string.
     * @param dest    An array of mutable UText structs to receive the results of the split.
     *                If a field is NULL, a new UText is allocated to contain the results for
     *                that field. This new UText is not guaranteed to be mutable.
     * @param destCapacity  The number of elements in the destination array.
     *                If the number of fields found is less than destCapacity, the
     *                extra strings in the destination array are not altered.
     *                If the number of destination strings is less than the number
     *                of fields, the trailing part of the input string, including any
     *                field delimiters, is placed in the last destination string.
     * @param status  A reference to a UErrorCode to receive any errors.
     * @return        The number of fields into which the input string was split.
     *
     * @stable ICU 4.6
     */
    virtual int32_t  split(UText *input,
        UText           *dest[],
        int32_t          destCapacity,
        UErrorCode       &status);
    
  /**
    *   Set a processing time limit for match operations with this Matcher.
    *  
    *   Some patterns, when matching certain strings, can run in exponential time.
    *   For practical purposes, the match operation may appear to be in an
    *   infinite loop.
    *   When a limit is set a match operation will fail with an error if the
    *   limit is exceeded.
    *   <p>
    *   The units of the limit are steps of the match engine.
    *   Correspondence with actual processor time will depend on the speed
    *   of the processor and the details of the specific pattern, but will
    *   typically be on the order of milliseconds.
    *   <p>
    *   By default, the matching time is not limited.
    *   <p>
    *
    *   @param   limit       The limit value, or 0 for no limit.
    *   @param   status      A reference to a UErrorCode to receive any errors.
    *   @stable ICU 4.0
    */
    virtual void setTimeLimit(int32_t limit, UErrorCode &status);

  /**
    * Get the time limit, if any, for match operations made with this Matcher.
    *
    *   @return the maximum allowed time for a match, in units of processing steps.
    *   @stable ICU 4.0
    */
    virtual int32_t getTimeLimit() const;

  /**
    *  Set the amount of heap storage available for use by the match backtracking stack.
    *  The matcher is also reset, discarding any results from previous matches.
    *  <p>
    *  ICU uses a backtracking regular expression engine, with the backtrack stack
    *  maintained on the heap.  This function sets the limit to the amount of memory
    *  that can be used  for this purpose.  A backtracking stack overflow will
    *  result in an error from the match operation that caused it.
    *  <p>
    *  A limit is desirable because a malicious or poorly designed pattern can use
    *  excessive memory, potentially crashing the process.  A limit is enabled
    *  by default.
    *  <p>
    *  @param limit  The maximum size, in bytes, of the matching backtrack stack.
    *                A value of zero means no limit.
    *                The limit must be greater or equal to zero.
    *
    *  @param status   A reference to a UErrorCode to receive any errors.
    *
    *  @stable ICU 4.0
    */
    virtual void setStackLimit(int32_t  limit, UErrorCode &status);
    
  /**
    *  Get the size of the heap storage available for use by the back tracking stack.
    *
    *  @return  the maximum backtracking stack size, in bytes, or zero if the
    *           stack size is unlimited.
    *  @stable ICU 4.0
    */
    virtual int32_t  getStackLimit() const;


  /**
    * Set a callback function for use with this Matcher.
    * During matching operations the function will be called periodically,
    * giving the application the opportunity to terminate a long-running
    * match.
    *
    *    @param   callback    A pointer to the user-supplied callback function.
    *    @param   context     User context pointer.  The value supplied at the
    *                         time the callback function is set will be saved
    *                         and passed to the callback each time that it is called.
    *    @param   status      A reference to a UErrorCode to receive any errors.
    *  @stable ICU 4.0
    */
    virtual void setMatchCallback(URegexMatchCallback     *callback,
                                  const void              *context,
                                  UErrorCode              &status);


  /**
    *  Get the callback function for this URegularExpression.
    *
    *    @param   callback    Out parameter, receives a pointer to the user-supplied 
    *                         callback function.
    *    @param   context     Out parameter, receives the user context pointer that
    *                         was set when uregex_setMatchCallback() was called.
    *    @param   status      A reference to a UErrorCode to receive any errors.
    *    @stable ICU 4.0
    */
    virtual void getMatchCallback(URegexMatchCallback     *&callback,
                                  const void              *&context,
                                  UErrorCode              &status);


  /**
    * Set a progress callback function for use with find operations on this Matcher.
    * During find operations, the callback will be invoked after each return from a
    * match attempt, giving the application the opportunity to terminate a long-running
    * find operation.
    *
    *    @param   callback    A pointer to the user-supplied callback function.
    *    @param   context     User context pointer.  The value supplied at the
    *                         time the callback function is set will be saved
    *                         and passed to the callback each time that it is called.
    *    @param   status      A reference to a UErrorCode to receive any errors.
    *    @stable ICU 4.6
    */
    virtual void setFindProgressCallback(URegexFindProgressCallback      *callback,
                                              const void                              *context,
                                              UErrorCode                              &status);


  /**
    *  Get the find progress callback function for this URegularExpression.
    *
    *    @param   callback    Out parameter, receives a pointer to the user-supplied 
    *                         callback function.
    *    @param   context     Out parameter, receives the user context pointer that
    *                         was set when uregex_setFindProgressCallback() was called.
    *    @param   status      A reference to a UErrorCode to receive any errors.
    *    @stable ICU 4.6
    */
    virtual void getFindProgressCallback(URegexFindProgressCallback      *&callback,
                                              const void                      *&context,
                                              UErrorCode                      &status);

#ifndef U_HIDE_INTERNAL_API
   /**
     *   setTrace   Debug function, enable/disable tracing of the matching engine.
     *              For internal ICU development use only.  DO NO USE!!!!
     *   @internal
     */
    void setTrace(UBool state);
#endif  /* U_HIDE_INTERNAL_API */

    /**
    * ICU "poor man's RTTI", returns a UClassID for this class.
    *
    * @stable ICU 2.2
    */
    static UClassID U_EXPORT2 getStaticClassID();

    /**
     * ICU "poor man's RTTI", returns a UClassID for the actual class.
     *
     * @stable ICU 2.2
     */
    virtual UClassID getDynamicClassID() const;

private:
    // Constructors and other object boilerplate are private.
    // Instances of RegexMatcher can not be assigned, copied, cloned, etc.
    RegexMatcher();                  // default constructor not implemented
    RegexMatcher(const RegexPattern *pat);
    RegexMatcher(const RegexMatcher &other);
    RegexMatcher &operator =(const RegexMatcher &rhs);
    void init(UErrorCode &status);                      // Common initialization
    void init2(UText *t, UErrorCode &e);  // Common initialization, part 2.

    friend class RegexPattern;
    friend class RegexCImpl;
public:
#ifndef U_HIDE_INTERNAL_API
    /** @internal  */
    void resetPreserveRegion();  // Reset matcher state, but preserve any region.
#endif  /* U_HIDE_INTERNAL_API */
private:

    //
    //  MatchAt   This is the internal interface to the match engine itself.
    //            Match status comes back in matcher member variables.
    //
    void                 MatchAt(int64_t startIdx, UBool toEnd, UErrorCode &status);
    inline void          backTrack(int64_t &inputIdx, int32_t &patIdx);
    UBool                isWordBoundary(int64_t pos);         // perform Perl-like  \b test
    UBool                isUWordBoundary(int64_t pos);        // perform RBBI based \b test
    REStackFrame        *resetStack();
    inline REStackFrame *StateSave(REStackFrame *fp, int64_t savePatIdx, UErrorCode &status);
    void                 IncrementTime(UErrorCode &status);

    // Call user find callback function, if set. Return TRUE if operation should be interrupted.
    inline UBool         findProgressInterrupt(int64_t matchIndex, UErrorCode &status);
    
    int64_t              appendGroup(int32_t groupNum, UText *dest, UErrorCode &status) const;
    
    UBool                findUsingChunk(UErrorCode &status);
    void                 MatchChunkAt(int32_t startIdx, UBool toEnd, UErrorCode &status);
    UBool                isChunkWordBoundary(int32_t pos);

    const RegexPattern  *fPattern;
    RegexPattern        *fPatternOwned;    // Non-NULL if this matcher owns the pattern, and
                                           //   should delete it when through.

    const UnicodeString *fInput;           // The string being matched. Only used for input()
    UText               *fInputText;       // The text being matched. Is never NULL.
    UText               *fAltInputText;    // A shallow copy of the text being matched.
                                           //   Only created if the pattern contains backreferences.
    int64_t              fInputLength;     // Full length of the input text.
    int32_t              fFrameSize;       // The size of a frame in the backtrack stack.
    
    int64_t              fRegionStart;     // Start of the input region, default = 0.
    int64_t              fRegionLimit;     // End of input region, default to input.length.
    
    int64_t              fAnchorStart;     // Region bounds for anchoring operations (^ or $).
    int64_t              fAnchorLimit;     //   See useAnchoringBounds
    
    int64_t              fLookStart;       // Region bounds for look-ahead/behind and
    int64_t              fLookLimit;       //   and other boundary tests.  See
                                           //   useTransparentBounds

    int64_t              fActiveStart;     // Currently active bounds for matching.
    int64_t              fActiveLimit;     //   Usually is the same as region, but
                                           //   is changed to fLookStart/Limit when
                                           //   entering look around regions.

    UBool                fTransparentBounds;  // True if using transparent bounds.
    UBool                fAnchoringBounds; // True if using anchoring bounds.

    UBool                fMatch;           // True if the last attempted match was successful.
    int64_t              fMatchStart;      // Position of the start of the most recent match
    int64_t              fMatchEnd;        // First position after the end of the most recent match
                                           //   Zero if no previous match, even when a region
                                           //   is active.
    int64_t              fLastMatchEnd;    // First position after the end of the previous match,
                                           //   or -1 if there was no previous match.
    int64_t              fAppendPosition;  // First position after the end of the previous
                                           //   appendReplacement().  As described by the
                                           //   JavaDoc for Java Matcher, where it is called 
                                           //   "append position"
    UBool                fHitEnd;          // True if the last match touched the end of input.
    UBool                fRequireEnd;      // True if the last match required end-of-input
                                           //    (matched $ or Z)

    UVector64           *fStack;
    REStackFrame        *fFrame;           // After finding a match, the last active stack frame,
                                           //   which will contain the capture group results.
                                           //   NOT valid while match engine is running.

    int64_t             *fData;            // Data area for use by the compiled pattern.
    int64_t             fSmallData[8];     //   Use this for data if it's enough.

    int32_t             fTimeLimit;        // Max time (in arbitrary steps) to let the
                                           //   match engine run.  Zero for unlimited.
    
    int32_t             fTime;             // Match time, accumulates while matching.
    int32_t             fTickCounter;      // Low bits counter for time.  Counts down StateSaves.
                                           //   Kept separately from fTime to keep as much
                                           //   code as possible out of the inline
                                           //   StateSave function.

    int32_t             fStackLimit;       // Maximum memory size to use for the backtrack
                                           //   stack, in bytes.  Zero for unlimited.

    URegexMatchCallback *fCallbackFn;       // Pointer to match progress callback funct.
                                           //   NULL if there is no callback.
    const void         *fCallbackContext;  // User Context ptr for callback function.

    URegexFindProgressCallback  *fFindProgressCallbackFn;  // Pointer to match progress callback funct.
                                                           //   NULL if there is no callback.
    const void         *fFindProgressCallbackContext;      // User Context ptr for callback function.


    UBool               fInputUniStrMaybeMutable;  // Set when fInputText wraps a UnicodeString that may be mutable - compatibility.

    UBool               fTraceDebug;       // Set true for debug tracing of match engine.

    UErrorCode          fDeferredStatus;   // Save error state that cannot be immediately
                                           //   reported, or that permanently disables this matcher.

    RuleBasedBreakIterator  *fWordBreakItr;
};

U_NAMESPACE_END
#endif  // UCONFIG_NO_REGULAR_EXPRESSIONS
#endif
