// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*****************************************************************************
* Copyright (C) 2001-2016, International Business Machines orporation  
* and others. All Rights Reserved.
****************************************************************************/

#include "unicode/utypes.h"

#if !UCONFIG_NO_COLLATION

#include "srchtest.h"
#if !UCONFIG_NO_BREAK_ITERATION
#include "../cintltst/usrchdat.c"
#endif
#include "unicode/stsearch.h"
#include "unicode/ustring.h"
#include "unicode/schriter.h"
#include "cmemory.h"
#include <string.h>
#include <stdio.h>

// private definitions -----------------------------------------------------

#define CASE(id,test)                 \
    case id:                          \
        name = #test;                 \
        if (exec) {                   \
            logln(#test "---");       \
            logln((UnicodeString)""); \
            if(areBroken) {           \
                  dataerrln(__FILE__ " cannot test - failed to create collator.");  \
            } else {                  \
                test();               \
            }                         \
        }                             \
        break;

// public contructors and destructors --------------------------------------

StringSearchTest::StringSearchTest() 
#if !UCONFIG_NO_BREAK_ITERATION
:
    m_en_wordbreaker_(NULL), m_en_characterbreaker_(NULL)
#endif
{
#if !UCONFIG_NO_BREAK_ITERATION
    UErrorCode    status = U_ZERO_ERROR;
    
    m_en_us_ = (RuleBasedCollator *)Collator::createInstance("en_US", status);
    m_fr_fr_ = (RuleBasedCollator *)Collator::createInstance("fr_FR", status);
    m_de_    = (RuleBasedCollator *)Collator::createInstance("de_DE", status);
    m_es_    = (RuleBasedCollator *)Collator::createInstance("es_ES", status);
    if(U_FAILURE(status)) {
      delete m_en_us_;
      delete m_fr_fr_;
      delete m_de_;
      delete m_es_;
      m_en_us_ = 0;
      m_fr_fr_ = 0;
      m_de_ = 0;
      m_es_ = 0;
      errln("Collator creation failed with %s", u_errorName(status));
      return;
    }

    
    UnicodeString rules;
    rules.setTo(((RuleBasedCollator *)m_de_)->getRules());
    UChar extrarules[128];
    u_unescape(EXTRACOLLATIONRULE, extrarules, 128);
    rules.append(extrarules, u_strlen(extrarules));
    delete m_de_;

    m_de_ = new RuleBasedCollator(rules, status);

    rules.setTo(((RuleBasedCollator *)m_es_)->getRules());
    rules.append(extrarules, u_strlen(extrarules));
        
    delete m_es_;

    m_es_ = new RuleBasedCollator(rules, status); 
        
#if !UCONFIG_NO_BREAK_ITERATION
    m_en_wordbreaker_      = BreakIterator::createWordInstance(
                                                    Locale::getEnglish(), status);
    m_en_characterbreaker_ = BreakIterator::createCharacterInstance(
                                                    Locale::getEnglish(), status);
#endif
#endif
}

StringSearchTest::~StringSearchTest() 
{
#if !UCONFIG_NO_BREAK_ITERATION
    delete m_en_us_;
    delete m_fr_fr_;
    delete m_de_;
    delete m_es_;
#if !UCONFIG_NO_BREAK_ITERATION
    delete m_en_wordbreaker_;
    delete m_en_characterbreaker_;
#endif
#endif
}

// public methods ----------------------------------------------------------

void StringSearchTest::runIndexedTest(int32_t index, UBool exec, 
                                      const char* &name, char* ) 
{
#if !UCONFIG_NO_BREAK_ITERATION
    UBool areBroken = FALSE;
    if (m_en_us_ == NULL && m_fr_fr_ == NULL && m_de_ == NULL &&
        m_es_ == NULL && m_en_wordbreaker_ == NULL &&
        m_en_characterbreaker_ == NULL && exec) {
        areBroken = TRUE;
    }

    switch (index) {
#if !UCONFIG_NO_FILE_IO
        CASE(0, TestOpenClose)
#endif
        CASE(1, TestInitialization)
        CASE(2, TestBasic)
        CASE(3, TestNormExact)
        CASE(4, TestStrength)
#if UCONFIG_NO_BREAK_ITERATION
    case 5:
        name = "TestBreakIterator";
        break;
#else
        CASE(5, TestBreakIterator)
#endif
        CASE(6, TestVariable)
        CASE(7, TestOverlap)
        CASE(8, TestCollator)
        CASE(9, TestPattern)
        CASE(10, TestText)
        CASE(11, TestCompositeBoundaries)
        CASE(12, TestGetSetOffset)
        CASE(13, TestGetSetAttribute)
        CASE(14, TestGetMatch)
        CASE(15, TestSetMatch)
        CASE(16, TestReset)
        CASE(17, TestSupplementary)
        CASE(18, TestContraction)
        CASE(19, TestIgnorable)
        CASE(20, TestCanonical)
        CASE(21, TestNormCanonical)
        CASE(22, TestStrengthCanonical)
#if UCONFIG_NO_BREAK_ITERATION
    case 23:
        name = "TestBreakIteratorCanonical";
        break;
#else
        CASE(23, TestBreakIteratorCanonical)
#endif
        CASE(24, TestVariableCanonical)
        CASE(25, TestOverlapCanonical)
        CASE(26, TestCollatorCanonical)
        CASE(27, TestPatternCanonical)
        CASE(28, TestTextCanonical)
        CASE(29, TestCompositeBoundariesCanonical)
        CASE(30, TestGetSetOffsetCanonical)
        CASE(31, TestSupplementaryCanonical)
        CASE(32, TestContractionCanonical)
        CASE(33, TestUClassID)
        CASE(34, TestSubclass)
        CASE(35, TestCoverage)
        CASE(36, TestDiacriticMatch)
        default: name = ""; break;
    }
#else
    name="";
#endif
}

#if !UCONFIG_NO_BREAK_ITERATION
// private methods ------------------------------------------------------

RuleBasedCollator * StringSearchTest::getCollator(const char *collator)
{
    if (collator == NULL) {
        return m_en_us_;
    }
    if (strcmp(collator, "fr") == 0) {
        return m_fr_fr_;
    }
    else if (strcmp(collator, "de") == 0) {
        return m_de_;
    }
    else if (strcmp(collator, "es") == 0) {
        return m_es_;
    }
    else {
        return m_en_us_;
    }
}
 
BreakIterator * StringSearchTest::getBreakIterator(const char *breaker)
{
#if UCONFIG_NO_BREAK_ITERATION
    return NULL;
#else
    if (breaker == NULL) {
        return NULL;
    }
    if (strcmp(breaker, "wordbreaker") == 0) {
        return m_en_wordbreaker_;
    }
    else {
        return m_en_characterbreaker_;
    }
#endif
}

char * StringSearchTest::toCharString(const UnicodeString &text)
{
    static char   result[1024];
           int    index  = 0;
           int    count  = 0;
           int    length = text.length();

    for (; count < length; count ++) {
        UChar ch = text[count];
        if (ch >= 0x20 && ch <= 0x7e) {
            result[index ++] = (char)ch;
        }
        else {
            sprintf(result+index, "\\u%04x", ch);
            index += 6; /* \uxxxx */
        }
    }
    result[index] = 0;

    return result;
}

Collator::ECollationStrength StringSearchTest::getECollationStrength(
                                    const UCollationStrength &strength) const
{
  switch (strength)
  {
  case UCOL_PRIMARY :
    return Collator::PRIMARY;
  case UCOL_SECONDARY :
    return Collator::SECONDARY;
  case UCOL_TERTIARY :
    return Collator::TERTIARY;
  default :
    return Collator::IDENTICAL;
  }
}

UBool StringSearchTest::assertEqualWithStringSearch(StringSearch *strsrch,
                                                    const SearchData *search)
{
    int32_t         count       = 0;
    UErrorCode      status      = U_ZERO_ERROR;
    int32_t         matchindex  = search->offset[count];
    UnicodeString   matchtext;
    int32_t         matchlength;

    strsrch->setAttribute(USEARCH_ELEMENT_COMPARISON, search->elemCompare, status);
    if (U_FAILURE(status)) {
        errln("Error setting USEARCH_ELEMENT_COMPARISON attribute %s", u_errorName(status));
        return FALSE;
    }   

    if (strsrch->getMatchedStart() != USEARCH_DONE ||
        strsrch->getMatchedLength() != 0) {
        errln("Error with the initialization of match start and length");
    }

    // start of next matches
    while (U_SUCCESS(status) && matchindex >= 0) {
        matchlength = search->size[count];
        strsrch->next(status);
        if (matchindex != strsrch->getMatchedStart() || 
            matchlength != strsrch->getMatchedLength()) {
            char *str = toCharString(strsrch->getText());
            errln("Text: %s", str);
            str = toCharString(strsrch->getPattern());
            errln("Pattern: %s", str);
            errln("Error next match found at %d (len:%d); expected %d (len:%d)", 
                    strsrch->getMatchedStart(), strsrch->getMatchedLength(),
                    matchindex, matchlength);
            return FALSE;
        }
        count ++;
        
        strsrch->getMatchedText(matchtext);

        if (U_FAILURE(status) ||
            strsrch->getText().compareBetween(matchindex, 
                                              matchindex + matchlength,
                                              matchtext, 0, 
                                              matchtext.length())) {
            errln("Error getting next matched text");
        }

        matchindex = search->offset[count];
    }
    strsrch->next(status);
    if (strsrch->getMatchedStart() != USEARCH_DONE ||
        strsrch->getMatchedLength() != 0) {
        char *str = toCharString(strsrch->getText());
            errln("Text: %s", str);
            str = toCharString(strsrch->getPattern());
            errln("Pattern: %s", str);
            errln("Error next match found at %d (len:%d); expected <NO MATCH>", 
                    strsrch->getMatchedStart(), strsrch->getMatchedLength());
            return FALSE;
    }

    // start of previous matches
    count = count == 0 ? 0 : count - 1;
    matchindex = search->offset[count];
    while (U_SUCCESS(status) && matchindex >= 0) {
        matchlength = search->size[count];
        strsrch->previous(status);
        if (matchindex != strsrch->getMatchedStart() || 
            matchlength != strsrch->getMatchedLength()) {
            char *str = toCharString(strsrch->getText());
            errln("Text: %s", str);
            str = toCharString(strsrch->getPattern());
            errln("Pattern: %s", str);
            errln("Error previous match found at %d (len:%d); expected %d (len:%d)",
                    strsrch->getMatchedStart(), strsrch->getMatchedLength(),
                    matchindex, matchlength);
            return FALSE;
        }
        
        strsrch->getMatchedText(matchtext);

        if (U_FAILURE(status) ||
            strsrch->getText().compareBetween(matchindex, 
                                              matchindex + matchlength,
                                              matchtext, 0, 
                                              matchtext.length())) {
            errln("Error getting previous matched text");
        }

        matchindex = count > 0 ? search->offset[count - 1] : -1;
        count --;
    }
    strsrch->previous(status);
    if (strsrch->getMatchedStart() != USEARCH_DONE ||
        strsrch->getMatchedLength() != 0) {
        char *str = toCharString(strsrch->getText());
        errln("Text: %s", str);
        str = toCharString(strsrch->getPattern());
        errln("Pattern: %s", str);
        errln("Error previous match found at %d (len:%d); expected <NO MATCH>", 
                strsrch->getMatchedStart(), strsrch->getMatchedLength());
        return FALSE;
    }

    int32_t nextStart;
    UBool isOverlap = (strsrch->getAttribute(USEARCH_OVERLAP) == USEARCH_ON);

    // start of following matches
    count = 0;
    matchindex = search->offset[count];
    nextStart = 0;

    while (TRUE) {
        strsrch->following(nextStart, status);

        if (matchindex < 0) {
            if (strsrch->getMatchedStart() != USEARCH_DONE ||
                    strsrch->getMatchedLength() != 0) {
                char *str = toCharString(strsrch->getText());
                errln("Text: %s", str);
                str = toCharString(strsrch->getPattern());
                errln("Pattern: %s", str);
                errln("Error following match starting at %d (overlap:%d) found at %d (len:%d); expected <NO MATCH>",
                        nextStart, isOverlap,
                        strsrch->getMatchedStart(), strsrch->getMatchedLength());
                return FALSE;
            }
            // no more matches
            break;
        }

        matchlength = search->size[count];
        if (strsrch->getMatchedStart() != matchindex
                || strsrch->getMatchedLength() != matchlength
                || U_FAILURE(status)) {
            char *str = toCharString(strsrch->getText());
            errln("Text: %s\n", str);
            str = toCharString(strsrch->getPattern());
            errln("Pattern: %s\n", str);
            errln("Error following match starting at %d (overlap: %d) found at %d (len:%d); expected %d (len:%d)\n",
                        nextStart, isOverlap,
                        strsrch->getMatchedStart(), strsrch->getMatchedLength(),
                        matchindex, matchlength);
            return FALSE;
        }

        if (isOverlap || strsrch->getMatchedLength() == 0) {
            nextStart = strsrch->getMatchedStart() + 1;
        } else {
            nextStart = strsrch->getMatchedStart() + strsrch->getMatchedLength();
        }

        count++;
        matchindex = search->offset[count];
    }

    // start preceding matches
    count = -1; // last non-negative offset index, could be -1 if no match
    while (search->offset[count + 1] >= 0) {
        count++;
    }
    nextStart = strsrch->getText().length();

    while (TRUE) {
        strsrch->preceding(nextStart, status);

        if (count < 0) {
            if (strsrch->getMatchedStart() != USEARCH_DONE || strsrch->getMatchedLength() != 0) {
                char *str = toCharString(strsrch->getText());
                errln("Text: %s\n", str);
                str = toCharString(strsrch->getPattern());
                errln("Pattern: %s\n", str);
                errln("Error preceding match starting at %d (overlap: %d) found at %d (len:%d); expected <NO MATCH>\n",
                            nextStart, isOverlap,
                            strsrch->getMatchedStart(), 
                            strsrch->getMatchedLength());
                return FALSE;
            }
            // no more matches
            break;
        }

        matchindex = search->offset[count];
        matchlength = search->size[count];
        if (strsrch->getMatchedStart() != matchindex
                || strsrch->getMatchedLength() != matchlength
                || U_FAILURE(status)) {
            char *str = toCharString(strsrch->getText());
            errln("Text: %s\n", str);
            str = toCharString(strsrch->getPattern());
            errln("Pattern: %s\n", str);
            errln("Error preceding match starting at %d (overlap: %d) found at %d (len:%d); expected %d (len:%d)\n",
                        nextStart, isOverlap,
                        strsrch->getMatchedStart(), strsrch->getMatchedLength(),
                        matchindex, matchlength);
            return FALSE;
        }

        nextStart = matchindex;
        count--;
    }

    strsrch->setAttribute(USEARCH_ELEMENT_COMPARISON, USEARCH_STANDARD_ELEMENT_COMPARISON, status);
    return TRUE;
}
    
UBool StringSearchTest::assertEqual(const SearchData *search)
{
    UErrorCode     status   = U_ZERO_ERROR;
    
    Collator      *collator = getCollator(search->collator);
    BreakIterator *breaker  = getBreakIterator(search->breaker);
    StringSearch  *strsrch, *strsrch2;
    UChar          temp[128];
    
#if UCONFIG_NO_BREAK_ITERATION
    if(search->breaker) {
      return TRUE; /* skip test */
    }
#endif
    u_unescape(search->text, temp, 128);
    UnicodeString text;
    text.setTo(temp);
    u_unescape(search->pattern, temp, 128);
    UnicodeString  pattern;
    pattern.setTo(temp);

#if !UCONFIG_NO_BREAK_ITERATION
    if (breaker != NULL) {
        breaker->setText(text);
    }
#endif
    collator->setStrength(getECollationStrength(search->strength));
    strsrch = new StringSearch(pattern, text, (RuleBasedCollator *)collator, 
                               breaker, status);
    if (U_FAILURE(status)) {
        errln("Error opening string search %s", u_errorName(status));
        return FALSE;
    }   
    
    if (!assertEqualWithStringSearch(strsrch, search)) {
        collator->setStrength(getECollationStrength(UCOL_TERTIARY));
        delete strsrch;
        return FALSE;
    }


    strsrch2 = strsrch->clone();
    if( strsrch2 == strsrch || *strsrch2 != *strsrch ||
        !assertEqualWithStringSearch(strsrch2, search)
    ) {
        infoln("failure with StringSearch.clone()");
        collator->setStrength(getECollationStrength(UCOL_TERTIARY));
        delete strsrch;
        delete strsrch2;
        return FALSE;
    }
    delete strsrch2;

    collator->setStrength(getECollationStrength(UCOL_TERTIARY));
    delete strsrch;
    return TRUE;
}
 
UBool StringSearchTest::assertCanonicalEqual(const SearchData *search)
{
    UErrorCode     status   = U_ZERO_ERROR;
    Collator      *collator = getCollator(search->collator);
    BreakIterator *breaker  = getBreakIterator(search->breaker);
    StringSearch  *strsrch; 
    UChar          temp[128];
    UBool          result = TRUE;
    
#if UCONFIG_NO_BREAK_ITERATION
    if(search->breaker) {
      return TRUE; /* skip test */
    }
#endif

    u_unescape(search->text, temp, 128);
    UnicodeString text;
    text.setTo(temp);
    u_unescape(search->pattern, temp, 128);
    UnicodeString  pattern;
    pattern.setTo(temp);

#if !UCONFIG_NO_BREAK_ITERATION
    if (breaker != NULL) {
        breaker->setText(text);
    }
#endif
    collator->setStrength(getECollationStrength(search->strength));
    collator->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status);
    strsrch = new StringSearch(pattern, text, (RuleBasedCollator *)collator, 
                               breaker, status);
    strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
    if (U_FAILURE(status)) {
        errln("Error opening string search %s", u_errorName(status));
        result = FALSE;
        goto bail;
    }   
    
    if (!assertEqualWithStringSearch(strsrch, search)) {
        result = FALSE;
        goto bail;
    }

bail:
    collator->setStrength(getECollationStrength(UCOL_TERTIARY));
    collator->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_OFF, status);
    delete strsrch;

    return result;
}
   
UBool StringSearchTest::assertEqualWithAttribute(const SearchData *search, 
                                            USearchAttributeValue canonical,
                                            USearchAttributeValue overlap)
{
    UErrorCode     status   = U_ZERO_ERROR;
    Collator      *collator = getCollator(search->collator);
    BreakIterator *breaker  = getBreakIterator(search->breaker);
    StringSearch  *strsrch; 
    UChar          temp[128];
    

#if UCONFIG_NO_BREAK_ITERATION
    if(search->breaker) {
      return TRUE; /* skip test */
    }
#endif

    u_unescape(search->text, temp, 128);
    UnicodeString text;
    text.setTo(temp);
    u_unescape(search->pattern, temp, 128);
    UnicodeString  pattern;
    pattern.setTo(temp);

#if !UCONFIG_NO_BREAK_ITERATION
    if (breaker != NULL) {
        breaker->setText(text);
    }
#endif
    collator->setStrength(getECollationStrength(search->strength));
    strsrch = new StringSearch(pattern, text, (RuleBasedCollator *)collator, 
                               breaker, status);
    strsrch->setAttribute(USEARCH_CANONICAL_MATCH, canonical, status);
    strsrch->setAttribute(USEARCH_OVERLAP, overlap, status);
    
    if (U_FAILURE(status)) {
        errln("Error opening string search %s", u_errorName(status));
        return FALSE;
    }   
    
    if (!assertEqualWithStringSearch(strsrch, search)) {
        collator->setStrength(getECollationStrength(UCOL_TERTIARY));
        delete strsrch;
        return FALSE;
    }
    collator->setStrength(getECollationStrength(UCOL_TERTIARY));
    delete strsrch;
    return TRUE;
}

void StringSearchTest::TestOpenClose()
{
    UErrorCode               status    = U_ZERO_ERROR;
    StringSearch            *result;
    BreakIterator           *breakiter = m_en_wordbreaker_;
    UnicodeString            pattern;
    UnicodeString            text;
    UnicodeString            temp("a");
    StringCharacterIterator  chariter(text);

    /* testing null arguments */
    result = new StringSearch(pattern, text, NULL, NULL, status);
    if (U_SUCCESS(status)) {
        errln("Error: NULL arguments should produce an error");
    }
    delete result;

    chariter.setText(text);
    status = U_ZERO_ERROR;
    result = new StringSearch(pattern, chariter, NULL, NULL, status);
    if (U_SUCCESS(status)) {
        errln("Error: NULL arguments should produce an error");
    }
    delete result;

    // No-op: text.append(0, 0x1); -- what was intended here?
    status = U_ZERO_ERROR;
    result = new StringSearch(pattern, text, NULL, NULL, status);
    if (U_SUCCESS(status)) {
        errln("Error: Empty pattern should produce an error");
    }
    delete result;

    chariter.setText(text);
    status = U_ZERO_ERROR;
    result = new StringSearch(pattern, chariter, NULL, NULL, status);
    if (U_SUCCESS(status)) {
        errln("Error: Empty pattern should produce an error");
    }
    delete result;

    text.remove();
    pattern.append(temp);
    status = U_ZERO_ERROR;
    result = new StringSearch(pattern, text, NULL, NULL, status);
    if (U_SUCCESS(status)) {
        errln("Error: Empty text should produce an error");
    }
    delete result;

    chariter.setText(text);
    status = U_ZERO_ERROR;
    result = new StringSearch(pattern, chariter, NULL, NULL, status);
    if (U_SUCCESS(status)) {
        errln("Error: Empty text should produce an error");
    }
    delete result;

    text.append(temp);
    status = U_ZERO_ERROR;
    result = new StringSearch(pattern, text, NULL, NULL, status);
    if (U_SUCCESS(status)) {
        errln("Error: NULL arguments should produce an error");
    }
    delete result;

    chariter.setText(text);
    status = U_ZERO_ERROR;
    result = new StringSearch(pattern, chariter, NULL, NULL, status);
    if (U_SUCCESS(status)) {
        errln("Error: NULL arguments should produce an error");
    }
    delete result;

    status = U_ZERO_ERROR;
    result = new StringSearch(pattern, text, m_en_us_, NULL, status);
    if (U_FAILURE(status)) {
        errln("Error: NULL break iterator is valid for opening search");
    }
    delete result;

    status = U_ZERO_ERROR;
    result = new StringSearch(pattern, chariter, m_en_us_, NULL, status);
    if (U_FAILURE(status)) {
        errln("Error: NULL break iterator is valid for opening search");
    }
    delete result;

    status = U_ZERO_ERROR;
    result = new StringSearch(pattern, text, Locale::getEnglish(), NULL, status);
    if (U_FAILURE(status) || result == NULL) {
        errln("Error: NULL break iterator is valid for opening search");
    }
    delete result;

    status = U_ZERO_ERROR;
    result = new StringSearch(pattern, chariter, Locale::getEnglish(), NULL, status);
    if (U_FAILURE(status)) {
        errln("Error: NULL break iterator is valid for opening search");
    }
    delete result;

    status = U_ZERO_ERROR;
    result = new StringSearch(pattern, text, m_en_us_, breakiter, status);
    if (U_FAILURE(status)) {
        errln("Error: Break iterator is valid for opening search");
    }
    delete result;

    status = U_ZERO_ERROR;
    result = new StringSearch(pattern, chariter, m_en_us_, NULL, status);
    if (U_FAILURE(status)) {
        errln("Error: Break iterator is valid for opening search");
    }
    delete result;
}
 
void StringSearchTest::TestInitialization()
{
    UErrorCode     status = U_ZERO_ERROR;
    UnicodeString  pattern;
    UnicodeString  text;
    UnicodeString  temp("a");
    StringSearch  *result;
    int count;

    /* simple test on the pattern ce construction */
    pattern.append(temp);
    pattern.append(temp);
    text.append(temp);
    text.append(temp);
    text.append(temp);
    result = new StringSearch(pattern, text, m_en_us_, NULL, status);
    if (U_FAILURE(status)) {
        errln("Error opening search %s", u_errorName(status));
    }
    StringSearch *copy = new StringSearch(*result);
    if (*(copy->getCollator()) != *(result->getCollator()) ||
        copy->getBreakIterator() != result->getBreakIterator() ||
        copy->getMatchedLength() != result->getMatchedLength() ||
        copy->getMatchedStart() != result->getMatchedStart() ||
        copy->getOffset() != result->getOffset() ||
        copy->getPattern() != result->getPattern() ||
        copy->getText() != result->getText() ||
        *(copy) != *(result))
    {
        errln("Error copying StringSearch");
    }
    delete copy;

    copy = result->safeClone();
    if (*(copy->getCollator()) != *(result->getCollator()) ||
        copy->getBreakIterator() != result->getBreakIterator() ||
        copy->getMatchedLength() != result->getMatchedLength() ||
        copy->getMatchedStart() != result->getMatchedStart() ||
        copy->getOffset() != result->getOffset() ||
        copy->getPattern() != result->getPattern() ||
        copy->getText() != result->getText() ||
        *(copy) != *(result)) {
        errln("Error copying StringSearch");
    }
    delete result;
    
    /* testing if an extremely large pattern will fail the initialization */
    for (count = 0; count < 512; count ++) {
        pattern.append(temp);
    }
    result = new StringSearch(pattern, text, m_en_us_, NULL, status);
    if (*result != *result) {
        errln("Error: string search object expected to match itself");
    }
    if (*result == *copy) {
        errln("Error: string search objects are not expected to match");
    }
    *copy  = *result;
    if (*(copy->getCollator()) != *(result->getCollator()) ||
        copy->getBreakIterator() != result->getBreakIterator() ||
        copy->getMatchedLength() != result->getMatchedLength() ||
        copy->getMatchedStart() != result->getMatchedStart() ||
        copy->getOffset() != result->getOffset() ||
        copy->getPattern() != result->getPattern() ||
        copy->getText() != result->getText() ||
        *(copy) != *(result)) {
        errln("Error copying StringSearch");
    }
    if (U_FAILURE(status)) {
        errln("Error opening search %s", u_errorName(status));
    }
    delete result;
    delete copy;
}

void StringSearchTest::TestBasic()
{
    int count = 0;
    while (BASIC[count].text != NULL) {
        //printf("count %d", count);
        if (!assertEqual(&BASIC[count])) {
            infoln("Error at test number %d", count);
        }
        count ++;
    }
}

void StringSearchTest::TestNormExact()
{
    int count = 0;
    UErrorCode status = U_ZERO_ERROR;
    m_en_us_->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status);
    if (U_FAILURE(status)) {
        errln("Error setting collation normalization %s", 
              u_errorName(status));
    }
    while (BASIC[count].text != NULL) {
        if (!assertEqual(&BASIC[count])) {
            infoln("Error at test number %d", count);
        }
        count ++;
    }
    count = 0;
    while (NORMEXACT[count].text != NULL) {
        if (!assertEqual(&NORMEXACT[count])) {
            infoln("Error at test number %d", count);
        }
        count ++;
    }
    m_en_us_->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_OFF, status);
    count = 0;
    while (NONNORMEXACT[count].text != NULL) {
        if (!assertEqual(&NONNORMEXACT[count])) {
            infoln("Error at test number %d", count);
        }
        count ++;
    }
}
 
void StringSearchTest::TestStrength()
{
    int count = 0;
    while (STRENGTH[count].text != NULL) {
        if (!assertEqual(&STRENGTH[count])) {
            infoln("Error at test number %d", count);
        }
        count ++;
    }
}
 
#if !UCONFIG_NO_BREAK_ITERATION

void StringSearchTest::TestBreakIterator()
{
    UChar temp[128];
    u_unescape(BREAKITERATOREXACT[0].text, temp, 128);
    UnicodeString text;
    text.setTo(temp, u_strlen(temp));
    u_unescape(BREAKITERATOREXACT[0].pattern, temp, 128);
    UnicodeString pattern;
    pattern.setTo(temp, u_strlen(temp));

    UErrorCode status = U_ZERO_ERROR;
    StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, 
                                             status);
    if (U_FAILURE(status)) {
        errln("Error opening string search %s", u_errorName(status));
    }
    
    strsrch->setBreakIterator(NULL, status);
    if (U_FAILURE(status) || strsrch->getBreakIterator() != NULL) {
        errln("Error usearch_getBreakIterator returned wrong object");
    }

    strsrch->setBreakIterator(m_en_characterbreaker_, status);
    if (U_FAILURE(status) || 
        strsrch->getBreakIterator() != m_en_characterbreaker_) {
        errln("Error usearch_getBreakIterator returned wrong object");
    }
    
    strsrch->setBreakIterator(m_en_wordbreaker_, status);
    if (U_FAILURE(status) || 
        strsrch->getBreakIterator() != m_en_wordbreaker_) {
        errln("Error usearch_getBreakIterator returned wrong object");
    }

    delete strsrch;

    int count = 0;
    while (count < 4) {
        // special purposes for tests numbers 0-3
        const SearchData        *search   = &(BREAKITERATOREXACT[count]);     
              RuleBasedCollator *collator = getCollator(search->collator);
              BreakIterator     *breaker  = getBreakIterator(search->breaker);
              StringSearch      *strsrch; 
    
        u_unescape(search->text, temp, 128);
        text.setTo(temp, u_strlen(temp));
        u_unescape(search->pattern, temp, 128);
        pattern.setTo(temp, u_strlen(temp));
        if (breaker != NULL) {
            breaker->setText(text);
        }
        collator->setStrength(getECollationStrength(search->strength));
        
        strsrch = new StringSearch(pattern, text, collator, breaker, status);
        if (U_FAILURE(status) || 
            strsrch->getBreakIterator() != breaker) {
            errln("Error setting break iterator");
            if (strsrch != NULL) {
                delete strsrch;
            }
        }
        if (!assertEqualWithStringSearch(strsrch, search)) {
            collator->setStrength(getECollationStrength(UCOL_TERTIARY));
            delete strsrch;
        }
        search   = &(BREAKITERATOREXACT[count + 1]);
        breaker  = getBreakIterator(search->breaker);
        if (breaker != NULL) {
            breaker->setText(text);
        }
        strsrch->setBreakIterator(breaker, status);
        if (U_FAILURE(status) || 
            strsrch->getBreakIterator() != breaker) {
            errln("Error setting break iterator");
            delete strsrch;
        }
        strsrch->reset();
        if (!assertEqualWithStringSearch(strsrch, search)) {
             infoln("Error at test number %d", count);
        }
        delete strsrch;
        count += 2;
    }
    count = 0;
    while (BREAKITERATOREXACT[count].text != NULL) {
         if (!assertEqual(&BREAKITERATOREXACT[count])) {
             infoln("Error at test number %d", count);
         }
         count ++;
    }
}

#endif
    
void StringSearchTest::TestVariable()
{
    int count = 0;
    UErrorCode status = U_ZERO_ERROR;
    m_en_us_->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, status);
    if (U_FAILURE(status)) {
        errln("Error setting collation alternate attribute %s", 
              u_errorName(status));
    }
    while (VARIABLE[count].text != NULL) {
        logln("variable %d", count);
        if (!assertEqual(&VARIABLE[count])) {
            infoln("Error at test number %d", count);
        }
        count ++;
    }
    m_en_us_->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, 
                           status);
}
  
void StringSearchTest::TestOverlap()
{
    int count = 0;
    while (OVERLAP[count].text != NULL) {
        if (!assertEqualWithAttribute(&OVERLAP[count], USEARCH_OFF, 
                                      USEARCH_ON)) {
            errln("Error at overlap test number %d", count);
        }
        count ++;
    }    
    count = 0;
    while (NONOVERLAP[count].text != NULL) {
        if (!assertEqual(&NONOVERLAP[count])) {
            errln("Error at non overlap test number %d", count);
        }
        count ++;
    }

    count = 0;
    while (count < 1) {
        const SearchData *search = &(OVERLAP[count]);     
              UChar       temp[128];
        u_unescape(search->text, temp, 128);
        UnicodeString text;
        text.setTo(temp, u_strlen(temp));
        u_unescape(search->pattern, temp, 128);
        UnicodeString pattern;
        pattern.setTo(temp, u_strlen(temp));

        RuleBasedCollator *collator = getCollator(search->collator);
        UErrorCode         status   = U_ZERO_ERROR;
        StringSearch      *strsrch  = new StringSearch(pattern, text, 
                                                       collator, NULL, 
                                                       status);

        strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_ON, status);
        if (U_FAILURE(status) ||
            strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_ON) {
            errln("Error setting overlap option");
        }
        if (!assertEqualWithStringSearch(strsrch, search)) {
            delete strsrch;
            return;
        }
        
        search = &(NONOVERLAP[count]);
        strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_OFF, status);
        if (U_FAILURE(status) ||
            strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_OFF) {
            errln("Error setting overlap option");
        }
        strsrch->reset();
        if (!assertEqualWithStringSearch(strsrch, search)) {
            delete strsrch;
            errln("Error at test number %d", count);
         }

        count ++;
        delete strsrch;
    }
}
 
void StringSearchTest::TestCollator()
{
    // test collator that thinks "o" and "p" are the same thing
    UChar         temp[128];
    u_unescape(COLLATOR[0].text, temp, 128);
    UnicodeString text;
    text.setTo(temp, u_strlen(temp));
    u_unescape(COLLATOR[0].pattern, temp, 128);
    UnicodeString pattern;
    pattern.setTo(temp, u_strlen(temp));

    UErrorCode    status = U_ZERO_ERROR;
    StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, 
                                             status);    
    if (U_FAILURE(status)) {
        errln("Error opening string search %s", u_errorName(status));
        delete strsrch;
        return;
    }
    if (!assertEqualWithStringSearch(strsrch, &COLLATOR[0])) {
        delete strsrch;
        return;
    }
    
    u_unescape(TESTCOLLATORRULE, temp, 128);
    UnicodeString rules;
    rules.setTo(temp, u_strlen(temp));
    RuleBasedCollator *tailored = new RuleBasedCollator(rules, status);
    tailored->setStrength(getECollationStrength(COLLATOR[1].strength)); 

    if (U_FAILURE(status)) {
        errln("Error opening rule based collator %s", u_errorName(status));
        delete strsrch;
        delete tailored;
        return;
    }

    strsrch->setCollator(tailored, status);
    if (U_FAILURE(status) || (*strsrch->getCollator()) != (*tailored)) {
        errln("Error setting rule based collator");
        delete strsrch;
        delete tailored;
    }
    strsrch->reset();
    if (!assertEqualWithStringSearch(strsrch, &COLLATOR[1])) {
        delete strsrch;
        delete tailored;
        return;
    }
        
    strsrch->setCollator(m_en_us_, status);
    strsrch->reset();
    if (U_FAILURE(status) || (*strsrch->getCollator()) != (*m_en_us_)) {
        errln("Error setting rule based collator");
        delete strsrch;
        delete tailored;
    }
    if (!assertEqualWithStringSearch(strsrch, &COLLATOR[0])) {
       errln("Error searching collator test");
    }
    delete strsrch;
    delete tailored;
}

void StringSearchTest::TestPattern()
{
          
    UChar temp[512];
    int templength;
    u_unescape(PATTERN[0].text, temp, 512);
    UnicodeString text;
    text.setTo(temp, u_strlen(temp));
    u_unescape(PATTERN[0].pattern, temp, 512);
    UnicodeString pattern;
    pattern.setTo(temp, u_strlen(temp));

    m_en_us_->setStrength(getECollationStrength(PATTERN[0].strength));
    UErrorCode    status = U_ZERO_ERROR;
    StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, 
                                             status);

    if (U_FAILURE(status)) {
        errln("Error opening string search %s", u_errorName(status));
        m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY));
        if (strsrch != NULL) {
            delete strsrch;
        }
        return;
    }
    if (strsrch->getPattern() != pattern) {
        errln("Error setting pattern");
    }
    if (!assertEqualWithStringSearch(strsrch, &PATTERN[0])) {
        m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY));
        if (strsrch != NULL) {
            delete strsrch;
        }
        return;
    }

    u_unescape(PATTERN[1].pattern, temp, 512);
    pattern.setTo(temp, u_strlen(temp));
    strsrch->setPattern(pattern, status);
    if (pattern != strsrch->getPattern()) {
        errln("Error setting pattern");
        m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY));
        if (strsrch != NULL) {
            delete strsrch;
        }
        return;
    }
    strsrch->reset();
    if (U_FAILURE(status)) {
        errln("Error setting pattern %s", u_errorName(status));
    }
    if (!assertEqualWithStringSearch(strsrch, &PATTERN[1])) {
        m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY));
        if (strsrch != NULL) {
            delete strsrch;
        }
        return;
    }

    u_unescape(PATTERN[0].pattern, temp, 512);
    pattern.setTo(temp, u_strlen(temp));
    strsrch->setPattern(pattern, status);
    if (pattern != strsrch->getPattern()) {
        errln("Error setting pattern");
        m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY));
        if (strsrch != NULL) {
            delete strsrch;
        }
        return;
    }
    strsrch->reset();
    if (U_FAILURE(status)) {
        errln("Error setting pattern %s", u_errorName(status));
    }
    if (!assertEqualWithStringSearch(strsrch, &PATTERN[0])) {
        m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY));
        if (strsrch != NULL) {
            delete strsrch;
        }
        return;
    }
    /* enormous pattern size to see if this crashes */
    for (templength = 0; templength != 512; templength ++) {
        temp[templength] = 0x61;
    }
    temp[511] = 0;
    pattern.setTo(temp, 511);
    strsrch->setPattern(pattern, status);
    if (U_FAILURE(status)) {
        errln("Error setting pattern with size 512, %s", u_errorName(status));
    }
    m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY));
    if (strsrch != NULL) {
        delete strsrch;
    }
}
 
void StringSearchTest::TestText()
{
    UChar temp[128];
    u_unescape(TEXT[0].text, temp, 128);
    UnicodeString text;
    text.setTo(temp, u_strlen(temp));
    u_unescape(TEXT[0].pattern, temp, 128);
    UnicodeString pattern;
    pattern.setTo(temp, u_strlen(temp));

    UErrorCode status = U_ZERO_ERROR;
    StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, 
                                             status);
    if (U_FAILURE(status)) {
        errln("Error opening string search %s", u_errorName(status));
        return;
    }
    if (text != strsrch->getText()) {
        errln("Error setting text");
    }
    if (!assertEqualWithStringSearch(strsrch, &TEXT[0])) {
        delete strsrch;
        return;
    }

    u_unescape(TEXT[1].text, temp, 128);
    text.setTo(temp, u_strlen(temp));
    strsrch->setText(text, status);
    if (text != strsrch->getText()) {
        errln("Error setting text");
        delete strsrch;
        return;
    }
    if (U_FAILURE(status)) {
        errln("Error setting text %s", u_errorName(status));
    }
    if (!assertEqualWithStringSearch(strsrch, &TEXT[1])) {
        delete strsrch;
        return;
    }

    u_unescape(TEXT[0].text, temp, 128);
    text.setTo(temp, u_strlen(temp));
    StringCharacterIterator chariter(text);
    strsrch->setText(chariter, status);
    if (text != strsrch->getText()) {
        errln("Error setting text");
        delete strsrch;
        return;
    }
    if (U_FAILURE(status)) {
        errln("Error setting pattern %s", u_errorName(status));
    }
    if (!assertEqualWithStringSearch(strsrch, &TEXT[0])) {
        errln("Error searching within set text");
    }
    delete strsrch;
}
 
void StringSearchTest::TestCompositeBoundaries()
{
    int count = 0;
    while (COMPOSITEBOUNDARIES[count].text != NULL) { 
        logln("composite %d", count);
        if (!assertEqual(&COMPOSITEBOUNDARIES[count])) {
            errln("Error at test number %d", count);
        }
        count ++;
    } 
}
 
void StringSearchTest::TestGetSetOffset()
{
    UErrorCode     status  = U_ZERO_ERROR;
    UnicodeString  pattern("1234567890123456");
    UnicodeString  text("12345678901234567890123456789012");
    StringSearch  *strsrch = new StringSearch(pattern, text, m_en_us_, 
                                              NULL, status);
    /* testing out of bounds error */
    strsrch->setOffset(-1, status);
    if (U_SUCCESS(status)) {
        errln("Error expecting set offset error");
    }
    strsrch->setOffset(128, status);
    if (U_SUCCESS(status)) {
        errln("Error expecting set offset error");
    }
    int index   = 0;
    while (BASIC[index].text != NULL) {
        UErrorCode  status      = U_ZERO_ERROR;
        SearchData  search      = BASIC[index ++];
        UChar       temp[128];
    
        u_unescape(search.text, temp, 128);
        text.setTo(temp, u_strlen(temp));
        u_unescape(search.pattern, temp, 128);
        pattern.setTo(temp, u_strlen(temp));
        strsrch->setText(text, status);
        strsrch->setPattern(pattern, status);
        strsrch->getCollator()->setStrength(getECollationStrength(
                                                          search.strength));
        strsrch->reset();

        int count = 0;
        int32_t matchindex  = search.offset[count];
        while (U_SUCCESS(status) && matchindex >= 0) {
            int32_t matchlength = search.size[count];
            strsrch->next(status);
            if (matchindex != strsrch->getMatchedStart() || 
                matchlength != strsrch->getMatchedLength()) {
                char *str = toCharString(strsrch->getText());
                errln("Text: %s", str);
                str = toCharString(strsrch->getPattern());
                errln("Pattern: %s", str);
                errln("Error match found at %d %d", 
                        strsrch->getMatchedStart(), 
                        strsrch->getMatchedLength());
                return;
            }
            matchindex = search.offset[count + 1] == -1 ? -1 : 
                         search.offset[count + 2];
            if (search.offset[count + 1] != -1) {
                strsrch->setOffset(search.offset[count + 1] + 1, status);
                if (strsrch->getOffset() != search.offset[count + 1] + 1) {
                    errln("Error setting offset\n");
                    return;
                }
            }
            
            count += 2;
        }
        strsrch->next(status);
        if (strsrch->getMatchedStart() != USEARCH_DONE) {
            char *str = toCharString(strsrch->getText());
            errln("Text: %s", str);
            str = toCharString(strsrch->getPattern());
            errln("Pattern: %s", str);
            errln("Error match found at %d %d", 
                        strsrch->getMatchedStart(), 
                        strsrch->getMatchedLength());
            return;
        }
    }
    strsrch->getCollator()->setStrength(getECollationStrength(
                                                             UCOL_TERTIARY));
    delete strsrch;
}
 
void StringSearchTest::TestGetSetAttribute()
{
    UErrorCode     status    = U_ZERO_ERROR;
    UnicodeString  pattern("pattern");
    UnicodeString  text("text");
    StringSearch  *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, 
                                              status);
    if (U_FAILURE(status)) {
        errln("Error opening search %s", u_errorName(status));
        return;
    }

    strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_DEFAULT, status);
    if (U_FAILURE(status) || 
        strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_OFF) {
        errln("Error setting overlap to the default");
    }
    strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_ON, status);
    if (U_FAILURE(status) || 
        strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_ON) {
        errln("Error setting overlap true");
    }
    strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_OFF, status);
    if (U_FAILURE(status) || 
        strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_OFF) {
        errln("Error setting overlap false");
    }
    strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_ATTRIBUTE_VALUE_COUNT, 
                          status);
    if (U_SUCCESS(status)) {
        errln("Error setting overlap to illegal value");
    }
    status = U_ZERO_ERROR;
    strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_DEFAULT, status);
    if (U_FAILURE(status) || 
        strsrch->getAttribute(USEARCH_CANONICAL_MATCH) != USEARCH_OFF) {
        errln("Error setting canonical match to the default");
    }
    strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
    if (U_FAILURE(status) || 
        strsrch->getAttribute(USEARCH_CANONICAL_MATCH) != USEARCH_ON) {
        errln("Error setting canonical match true");
    }
    strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_OFF, status);
    if (U_FAILURE(status) || 
        strsrch->getAttribute(USEARCH_CANONICAL_MATCH) != USEARCH_OFF) {
        errln("Error setting canonical match false");
    }
    strsrch->setAttribute(USEARCH_CANONICAL_MATCH, 
                          USEARCH_ATTRIBUTE_VALUE_COUNT, status);
    if (U_SUCCESS(status)) {
        errln("Error setting canonical match to illegal value");
    }
    status = U_ZERO_ERROR;
    strsrch->setAttribute(USEARCH_ATTRIBUTE_COUNT, USEARCH_DEFAULT, status);
    if (U_SUCCESS(status)) {
        errln("Error setting illegal attribute success");
    }

    delete strsrch;
}
 
void StringSearchTest::TestGetMatch()
{
    UChar      temp[128];
    SearchData search = MATCH[0];
    u_unescape(search.text, temp, 128);
    UnicodeString text;
    text.setTo(temp, u_strlen(temp));
    u_unescape(search.pattern, temp, 128);
    UnicodeString pattern;
    pattern.setTo(temp, u_strlen(temp));

    UErrorCode    status  = U_ZERO_ERROR;
    StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, 
                                             status);
    if (U_FAILURE(status)) {
        errln("Error opening string search %s", u_errorName(status));
        if (strsrch != NULL) {
            delete strsrch;
        }
        return;
    }
    
    int           count      = 0;
    int32_t   matchindex = search.offset[count];
    UnicodeString matchtext;
    while (U_SUCCESS(status) && matchindex >= 0) {
        int32_t matchlength = search.size[count];
        strsrch->next(status);
        if (matchindex != strsrch->getMatchedStart() || 
            matchlength != strsrch->getMatchedLength()) {
            char *str = toCharString(strsrch->getText());
            errln("Text: %s", str);
            str = toCharString(strsrch->getPattern());
            errln("Pattern: %s", str);
            errln("Error match found at %d %d", strsrch->getMatchedStart(), 
                  strsrch->getMatchedLength());
            return;
        }
        count ++;
        
        status = U_ZERO_ERROR;
        strsrch->getMatchedText(matchtext);
        if (matchtext.length() != matchlength || U_FAILURE(status)){
            errln("Error getting match text");
        }
        matchindex = search.offset[count];
    }
    status = U_ZERO_ERROR;
    strsrch->next(status);
    if (strsrch->getMatchedStart()  != USEARCH_DONE || 
        strsrch->getMatchedLength() != 0) {
        errln("Error end of match not found");
    }
    status = U_ZERO_ERROR;
    strsrch->getMatchedText(matchtext);
    if (matchtext.length() != 0) {
        errln("Error getting null matches");
    }
    delete strsrch;
}
 
void StringSearchTest::TestSetMatch()
{
    int count = 0;
    while (MATCH[count].text != NULL) {
        SearchData     search = MATCH[count];
        UChar          temp[128];
        UErrorCode status = U_ZERO_ERROR;
        u_unescape(search.text, temp, 128);
        UnicodeString text;
        text.setTo(temp, u_strlen(temp));
        u_unescape(search.pattern, temp, 128);
        UnicodeString pattern;
        pattern.setTo(temp, u_strlen(temp));

        StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, 
                                                 NULL, status);
        if (U_FAILURE(status)) {
            errln("Error opening string search %s", u_errorName(status));
            if (strsrch != NULL) {
                delete strsrch;
            }
            return;
        }

        int size = 0;
        while (search.offset[size] != -1) {
            size ++;
        }

        if (strsrch->first(status) != search.offset[0] || U_FAILURE(status)) {
            errln("Error getting first match");
        }
        if (strsrch->last(status) != search.offset[size -1] ||
            U_FAILURE(status)) {
            errln("Error getting last match");
        }
        
        int index = 0;
        while (index < size) {
            if (index + 2 < size) {
                if (strsrch->following(search.offset[index + 2] - 1, status) 
                         != search.offset[index + 2] || U_FAILURE(status)) {
                    errln("Error getting following match at index %d", 
                          search.offset[index + 2] - 1);
                }
            }
            if (index + 1 < size) {
                if (strsrch->preceding(search.offset[index + 1] + 
                                                search.size[index + 1] + 1, 
                                       status) != search.offset[index + 1] ||
                    U_FAILURE(status)) {
                    errln("Error getting preceeding match at index %d", 
                          search.offset[index + 1] + 1);
                }
            }
            index += 2;
        }
        status = U_ZERO_ERROR;
        if (strsrch->following(text.length(), status) != USEARCH_DONE) {
            errln("Error expecting out of bounds match");
        }
        if (strsrch->preceding(0, status) != USEARCH_DONE) {
            errln("Error expecting out of bounds match");
        }
        count ++;
        delete strsrch;
    }
}
    
void StringSearchTest::TestReset()
{
    UErrorCode     status  = U_ZERO_ERROR;
    UnicodeString  text("fish fish");
    UnicodeString  pattern("s");
    StringSearch  *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, 
                                              status);
    if (U_FAILURE(status)) {
        errln("Error opening string search %s", u_errorName(status));
        if (strsrch != NULL) {
            delete strsrch;
        }
        return;
    }
    strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_ON, status);
    strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
    strsrch->setOffset(9, status);
    if (U_FAILURE(status)) {
        errln("Error setting attributes and offsets");
    }
    else {
        strsrch->reset();
        if (strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_OFF ||
            strsrch->getAttribute(USEARCH_CANONICAL_MATCH) != USEARCH_OFF ||
            strsrch->getOffset() != 0 || strsrch->getMatchedLength() != 0 ||
            strsrch->getMatchedStart() != USEARCH_DONE) {
            errln("Error resetting string search");
        }
        strsrch->previous(status);
        if (strsrch->getMatchedStart() != 7 ||
            strsrch->getMatchedLength() != 1) {
            errln("Error resetting string search\n");
        }
    }
    delete strsrch;
}
 
void StringSearchTest::TestSupplementary()
{
    int count = 0;
    while (SUPPLEMENTARY[count].text != NULL) {
        if (!assertEqual(&SUPPLEMENTARY[count])) {
            errln("Error at test number %d", count);
        }
        count ++;
    }
}
 
void StringSearchTest::TestContraction()
{
    UChar      temp[128];
    UErrorCode status = U_ZERO_ERROR;
    
    u_unescape(CONTRACTIONRULE, temp, 128);
    UnicodeString rules;
    rules.setTo(temp, u_strlen(temp));
    RuleBasedCollator *collator = new RuleBasedCollator(rules, 
        getECollationStrength(UCOL_TERTIARY), UCOL_ON, status); 
    if (U_FAILURE(status)) {
        errln("Error opening collator %s", u_errorName(status));
    }
    UnicodeString text("text");
    UnicodeString pattern("pattern");
    StringSearch *strsrch = new StringSearch(pattern, text, collator, NULL, 
                                             status);
    if (U_FAILURE(status)) {
        errln("Error opening string search %s", u_errorName(status));
    }   
    
    int count = 0;
    while (CONTRACTION[count].text != NULL) {
        u_unescape(CONTRACTION[count].text, temp, 128);
        text.setTo(temp, u_strlen(temp));
        u_unescape(CONTRACTION[count].pattern, temp, 128);
        pattern.setTo(temp, u_strlen(temp));
        strsrch->setText(text, status);
        strsrch->setPattern(pattern, status);
        if (!assertEqualWithStringSearch(strsrch, &CONTRACTION[count])) {
            errln("Error at test number %d", count);
        }
        count ++;
    }
    delete strsrch;
    delete collator;
}
    
void StringSearchTest::TestIgnorable()
{
    UChar temp[128];
    u_unescape(IGNORABLERULE, temp, 128);
    UnicodeString rules;
    rules.setTo(temp, u_strlen(temp));
    UErrorCode status = U_ZERO_ERROR;
    int        count  = 0;
    RuleBasedCollator *collator = new RuleBasedCollator(rules,  
                            getECollationStrength(IGNORABLE[count].strength), 
                            UCOL_ON, status);  
    if (U_FAILURE(status)) {
        errln("Error opening collator %s", u_errorName(status));
        return;
    }
    UnicodeString pattern("pattern");
    UnicodeString text("text");
    StringSearch *strsrch = new StringSearch(pattern, text, collator, NULL, 
                                             status);
    if (U_FAILURE(status)) {
        errln("Error opening string search %s", u_errorName(status));
        delete collator;
        return;
    }   
    
    while (IGNORABLE[count].text != NULL) {
        u_unescape(IGNORABLE[count].text, temp, 128);
        text.setTo(temp, u_strlen(temp));
        u_unescape(IGNORABLE[count].pattern, temp, 128);
        pattern.setTo(temp, u_strlen(temp));
        strsrch->setText(text, status);
        strsrch->setPattern(pattern, status);
        if (!assertEqualWithStringSearch(strsrch, &IGNORABLE[count])) {
            errln("Error at test number %d", count);
        }
        count ++;
    }
    delete strsrch;
    delete collator;
}

void StringSearchTest::TestDiacriticMatch()
{
	UChar temp[128];
    UErrorCode status = U_ZERO_ERROR;
    int        count  = 0;
    RuleBasedCollator* coll = NULL;
    StringSearch *strsrch = NULL;

    UnicodeString pattern("pattern");
    UnicodeString text("text");
    
    const SearchData *search; 
    
    search = &(DIACRITICMATCH[count]);
    while (search->text != NULL) {
   		coll = getCollator(search->collator);
    	coll->setStrength(getECollationStrength(search->strength));
    	strsrch = new StringSearch(pattern, text, coll, getBreakIterator(search->breaker), status);
    	if (U_FAILURE(status)) {
	        errln("Error opening string search %s", u_errorName(status));
	        return;
	    }  
        u_unescape(search->text, temp, 128);
        text.setTo(temp, u_strlen(temp));
        u_unescape(search->pattern, temp, 128);
        pattern.setTo(temp, u_strlen(temp));
        strsrch->setText(text, status);
        strsrch->setPattern(pattern, status);
        if (!assertEqualWithStringSearch(strsrch, search)) {
            errln("Error at test number %d", count);
        }
        search = &(DIACRITICMATCH[++count]);
        delete strsrch;
    }
    
}
 
void StringSearchTest::TestCanonical()
{
    int count = 0;
    while (BASICCANONICAL[count].text != NULL) {
        if (!assertCanonicalEqual(&BASICCANONICAL[count])) {
            errln("Error at test number %d", count);
        }
        count ++;
    }
}
 
void StringSearchTest::TestNormCanonical()
{
    UErrorCode status = U_ZERO_ERROR;
    m_en_us_->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status);
    int count = 0;
    while (NORMCANONICAL[count].text != NULL) {
        if (!assertCanonicalEqual(&NORMCANONICAL[count])) {
            errln("Error at test number %d", count);
        }
        count ++;
    }
    m_en_us_->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_OFF, status);
}
 
void StringSearchTest::TestStrengthCanonical()
{
    int count = 0;
    while (STRENGTHCANONICAL[count].text != NULL) {
        if (!assertCanonicalEqual(&STRENGTHCANONICAL[count])) {
            errln("Error at test number %d", count);
        }
        count ++;
    }
}
    
#if !UCONFIG_NO_BREAK_ITERATION

void StringSearchTest::TestBreakIteratorCanonical()
{
    UErrorCode status = U_ZERO_ERROR;
    int        count  = 0;

    while (count < 4) {
        // special purposes for tests numbers 0-3
              UChar           temp[128];
        const SearchData     *search   = &(BREAKITERATORCANONICAL[count]);     
    
        u_unescape(search->text, temp, 128);
        UnicodeString text;
        text.setTo(temp, u_strlen(temp));
        u_unescape(search->pattern, temp, 128);
        UnicodeString pattern;
        pattern.setTo(temp, u_strlen(temp));
        RuleBasedCollator *collator = getCollator(search->collator);
        collator->setStrength(getECollationStrength(search->strength));

        BreakIterator *breaker = getBreakIterator(search->breaker);
        StringSearch  *strsrch = new StringSearch(pattern, text, collator, 
                                                  breaker, status);
        if (U_FAILURE(status)) {
            errln("Error creating string search data");
            return;
        }
        strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
        if (U_FAILURE(status) || 
            strsrch->getBreakIterator() != breaker) {
            errln("Error setting break iterator");
            delete strsrch;
            return;
        }
        if (!assertEqualWithStringSearch(strsrch, search)) {
            collator->setStrength(getECollationStrength(UCOL_TERTIARY));
            delete strsrch;
            return;
        }
        search  = &(BREAKITERATOREXACT[count + 1]);
        breaker = getBreakIterator(search->breaker);
        if (breaker == NULL) {
            errln("Error creating BreakIterator");
            return;
        }
        breaker->setText(strsrch->getText());
        strsrch->setBreakIterator(breaker, status);
        if (U_FAILURE(status) || strsrch->getBreakIterator() != breaker) {
            errln("Error setting break iterator");
            delete strsrch;
            return;
        }
        strsrch->reset();
        strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
        if (!assertEqualWithStringSearch(strsrch, search)) {
             errln("Error at test number %d", count);
             return;
        }
        delete strsrch;
        count += 2;
    }
    count = 0;
    while (BREAKITERATORCANONICAL[count].text != NULL) {
         if (!assertEqual(&BREAKITERATORCANONICAL[count])) {
             errln("Error at test number %d", count);
             return;
         }
         count ++;
    }
}

#endif
    
void StringSearchTest::TestVariableCanonical()
{
    int count = 0;
    UErrorCode status = U_ZERO_ERROR;
    m_en_us_->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, status);
    if (U_FAILURE(status)) {
        errln("Error setting collation alternate attribute %s", 
              u_errorName(status));
    }
    while (VARIABLE[count].text != NULL) {
        logln("variable %d", count);
        if (!assertCanonicalEqual(&VARIABLE[count])) {
            errln("Error at test number %d", count);
        }
        count ++;
    }
    m_en_us_->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, 
                           status);
}
    
void StringSearchTest::TestOverlapCanonical()
{
    int count = 0;
    while (OVERLAPCANONICAL[count].text != NULL) {
        if (!assertEqualWithAttribute(&OVERLAPCANONICAL[count], USEARCH_ON, 
                                      USEARCH_ON)) {
            errln("Error at overlap test number %d", count);
        }
        count ++;
    }    
    count = 0;
    while (NONOVERLAP[count].text != NULL) {
        if (!assertCanonicalEqual(&NONOVERLAPCANONICAL[count])) {
            errln("Error at non overlap test number %d", count);
        }
        count ++;
    }

    count = 0;
    while (count < 1) {
              UChar       temp[128];
        const SearchData *search = &(OVERLAPCANONICAL[count]);     
              UErrorCode  status = U_ZERO_ERROR;
    
        u_unescape(search->text, temp, 128);
        UnicodeString text;
        text.setTo(temp, u_strlen(temp));
        u_unescape(search->pattern, temp, 128);
        UnicodeString pattern;
        pattern.setTo(temp, u_strlen(temp));
        RuleBasedCollator *collator = getCollator(search->collator);
        StringSearch *strsrch = new StringSearch(pattern, text, collator, 
                                                 NULL, status);
        strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
        strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_ON, status);
        if (U_FAILURE(status) ||
            strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_ON) {
            errln("Error setting overlap option");
        }
        if (!assertEqualWithStringSearch(strsrch, search)) {
            delete strsrch;
            return;
        }
        search = &(NONOVERLAPCANONICAL[count]);
        strsrch->setAttribute(USEARCH_OVERLAP, USEARCH_OFF, status);
        if (U_FAILURE(status) ||
            strsrch->getAttribute(USEARCH_OVERLAP) != USEARCH_OFF) {
            errln("Error setting overlap option");
        }
        strsrch->reset();
        if (!assertEqualWithStringSearch(strsrch, search)) {
            delete strsrch;
            errln("Error at test number %d", count);
         }

        count ++;
        delete strsrch;
    }
}
    
void StringSearchTest::TestCollatorCanonical()
{
    /* test collator that thinks "o" and "p" are the same thing */
    UChar temp[128];
    u_unescape(COLLATORCANONICAL[0].text, temp, 128);
    UnicodeString text;
    text.setTo(temp, u_strlen(temp));
    u_unescape(COLLATORCANONICAL[0].pattern, temp, 128);
    UnicodeString pattern;
    pattern.setTo(temp, u_strlen(temp));

    UErrorCode    status  = U_ZERO_ERROR;
    StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, 
                                             NULL, status);
    strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
    if (U_FAILURE(status)) {
        errln("Error opening string search %s", u_errorName(status));
    }
    if (!assertEqualWithStringSearch(strsrch, &COLLATORCANONICAL[0])) {
        delete strsrch;
        return;
    }
    
    u_unescape(TESTCOLLATORRULE, temp, 128);
    UnicodeString rules;
    rules.setTo(temp, u_strlen(temp));
    RuleBasedCollator *tailored = new RuleBasedCollator(rules, 
        getECollationStrength(COLLATORCANONICAL[1].strength), 
        UCOL_ON, status);

    if (U_FAILURE(status)) {
        errln("Error opening rule based collator %s", u_errorName(status));
    }

    strsrch->setCollator(tailored, status);
    if (U_FAILURE(status) || *(strsrch->getCollator()) != *tailored) {
        errln("Error setting rule based collator");
    }
    strsrch->reset();
    strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
    if (!assertEqualWithStringSearch(strsrch, &COLLATORCANONICAL[1])) {
        delete strsrch;
        if (tailored != NULL) {
            delete tailored;
        }

        return;
    }
        
    strsrch->setCollator(m_en_us_, status);
    strsrch->reset();
    if (U_FAILURE(status) || *(strsrch->getCollator()) != *m_en_us_) {
        errln("Error setting rule based collator");
    }
    if (!assertEqualWithStringSearch(strsrch, &COLLATORCANONICAL[0])) {
    }
    delete strsrch;
    if (tailored != NULL) {
        delete tailored;
    }
}
    
void StringSearchTest::TestPatternCanonical()
{
    
    UChar temp[128];
    
    u_unescape(PATTERNCANONICAL[0].text, temp, 128);
    UnicodeString text;
    text.setTo(temp, u_strlen(temp));
    u_unescape(PATTERNCANONICAL[0].pattern, temp, 128);
    UnicodeString pattern;
    pattern.setTo(temp, u_strlen(temp));

    m_en_us_->setStrength(
                      getECollationStrength(PATTERNCANONICAL[0].strength));

    UErrorCode    status  = U_ZERO_ERROR;
    StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, 
                                             status);
    strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
    if (U_FAILURE(status)) {
        errln("Error opening string search %s", u_errorName(status));
        goto ENDTESTPATTERN;
    }
    if (pattern != strsrch->getPattern()) {
        errln("Error setting pattern");
    }
    if (!assertEqualWithStringSearch(strsrch, &PATTERNCANONICAL[0])) {
        goto ENDTESTPATTERN;
    }

    u_unescape(PATTERNCANONICAL[1].pattern, temp, 128);
    pattern.setTo(temp, u_strlen(temp));
    strsrch->setPattern(pattern, status);
    if (pattern != strsrch->getPattern()) {
        errln("Error setting pattern");
        goto ENDTESTPATTERN;
    }
    strsrch->reset();
    strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
    if (U_FAILURE(status)) {
        errln("Error setting pattern %s", u_errorName(status));
    }
    if (!assertEqualWithStringSearch(strsrch, &PATTERNCANONICAL[1])) {
        goto ENDTESTPATTERN;
    }

    u_unescape(PATTERNCANONICAL[0].pattern, temp, 128);
    pattern.setTo(temp, u_strlen(temp));
    strsrch->setPattern(pattern, status);
    if (pattern != strsrch->getPattern()) {
        errln("Error setting pattern");
        goto ENDTESTPATTERN;
    }
    strsrch->reset();
    strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
    if (U_FAILURE(status)) {
        errln("Error setting pattern %s", u_errorName(status));
    }
    if (!assertEqualWithStringSearch(strsrch, &PATTERNCANONICAL[0])) {
        goto ENDTESTPATTERN;
    }
ENDTESTPATTERN:
    m_en_us_->setStrength(getECollationStrength(UCOL_TERTIARY));
    if (strsrch != NULL) {
        delete strsrch;
    }
}
    
void StringSearchTest::TestTextCanonical()
{
    UChar temp[128];
    u_unescape(TEXTCANONICAL[0].text, temp, 128);
    UnicodeString text;
    text.setTo(temp, u_strlen(temp));
    u_unescape(TEXTCANONICAL[0].pattern, temp, 128);
    UnicodeString pattern;
    pattern.setTo(temp, u_strlen(temp));

    UErrorCode    status  = U_ZERO_ERROR;
    StringSearch *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, 
                                             status);
    strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);

    if (U_FAILURE(status)) {
        errln("Error opening string search %s", u_errorName(status));
        goto ENDTESTPATTERN;
    }
    if (text != strsrch->getText()) {
        errln("Error setting text");
    }
    if (!assertEqualWithStringSearch(strsrch, &TEXTCANONICAL[0])) {
        goto ENDTESTPATTERN;
    }

    u_unescape(TEXTCANONICAL[1].text, temp, 128);
    text.setTo(temp, u_strlen(temp));
    strsrch->setText(text, status);
    if (text != strsrch->getText()) {
        errln("Error setting text");
        goto ENDTESTPATTERN;
    }
    if (U_FAILURE(status)) {
        errln("Error setting text %s", u_errorName(status));
    }
    if (!assertEqualWithStringSearch(strsrch, &TEXTCANONICAL[1])) {
        goto ENDTESTPATTERN;
    }

    u_unescape(TEXTCANONICAL[0].text, temp, 128);
    text.setTo(temp, u_strlen(temp));
    strsrch->setText(text, status);
    if (text != strsrch->getText()) {
        errln("Error setting text");
        goto ENDTESTPATTERN;
    }
    if (U_FAILURE(status)) {
        errln("Error setting pattern %s", u_errorName(status));
    }
    if (!assertEqualWithStringSearch(strsrch, &TEXTCANONICAL[0])) {
        goto ENDTESTPATTERN;
    }
ENDTESTPATTERN:
    if (strsrch != NULL) {
        delete strsrch;
    }
}
    
void StringSearchTest::TestCompositeBoundariesCanonical()
{
    int count = 0;
    while (COMPOSITEBOUNDARIESCANONICAL[count].text != NULL) { 
        logln("composite %d", count);
        if (!assertCanonicalEqual(&COMPOSITEBOUNDARIESCANONICAL[count])) {
            errln("Error at test number %d", count);
        }
        count ++;
    } 
}
    
void StringSearchTest::TestGetSetOffsetCanonical()
{
    
    UErrorCode     status  = U_ZERO_ERROR;
    UnicodeString  text("text");
    UnicodeString  pattern("pattern");
    StringSearch  *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, 
                                              status);
    Collator *collator = strsrch->getCollator();

    collator->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status);

    strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
    /* testing out of bounds error */
    strsrch->setOffset(-1, status);
    if (U_SUCCESS(status)) {
        errln("Error expecting set offset error");
    }
    strsrch->setOffset(128, status);
    if (U_SUCCESS(status)) {
        errln("Error expecting set offset error");
    }
    int   index   = 0;
    UChar temp[128];
    while (BASICCANONICAL[index].text != NULL) {
        SearchData  search      = BASICCANONICAL[index ++];
        if (BASICCANONICAL[index].text == NULL) {
            /* skip the last one */
            break;
        }
        
        u_unescape(search.text, temp, 128);
        text.setTo(temp, u_strlen(temp));
        u_unescape(search.pattern, temp, 128);
        pattern.setTo(temp, u_strlen(temp));

        UErrorCode  status      = U_ZERO_ERROR;
        strsrch->setText(text, status);

        strsrch->setPattern(pattern, status);

        int         count       = 0;
        int32_t matchindex  = search.offset[count];
        while (U_SUCCESS(status) && matchindex >= 0) {
            int32_t matchlength = search.size[count];
            strsrch->next(status);
            if (matchindex != strsrch->getMatchedStart() || 
                matchlength != strsrch->getMatchedLength()) {
                char *str = toCharString(strsrch->getText());
                errln("Text: %s", str);
                str = toCharString(strsrch->getPattern());
                errln("Pattern: %s", str);
                errln("Error match found at %d %d", 
                      strsrch->getMatchedStart(), 
                      strsrch->getMatchedLength());
                goto bail;
            }
            matchindex = search.offset[count + 1] == -1 ? -1 : 
                         search.offset[count + 2];
            if (search.offset[count + 1] != -1) {
                strsrch->setOffset(search.offset[count + 1] + 1, status);
                if (strsrch->getOffset() != search.offset[count + 1] + 1) {
                    errln("Error setting offset");
                    goto bail;
                }
            }
            
            count += 2;
        }
        strsrch->next(status);
        if (strsrch->getMatchedStart() != USEARCH_DONE) {
            char *str = toCharString(strsrch->getText());
            errln("Text: %s", str);
            str = toCharString(strsrch->getPattern());
            errln("Pattern: %s", str);
            errln("Error match found at %d %d", strsrch->getMatchedStart(), 
                   strsrch->getMatchedLength());
            goto bail;
        }
    }

bail:
    collator->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_OFF, status);
    delete strsrch;
}
    
void StringSearchTest::TestSupplementaryCanonical()
{
    int count = 0;
    while (SUPPLEMENTARYCANONICAL[count].text != NULL) {
        if (!assertCanonicalEqual(&SUPPLEMENTARYCANONICAL[count])) {
            errln("Error at test number %d", count);
        }
        count ++;
    }
}
    
void StringSearchTest::TestContractionCanonical()
{
    UChar          temp[128];
    
    u_unescape(CONTRACTIONRULE, temp, 128);
    UnicodeString rules;
    rules.setTo(temp, u_strlen(temp));

    UErrorCode         status   = U_ZERO_ERROR;
    RuleBasedCollator *collator = new RuleBasedCollator(rules, 
        getECollationStrength(UCOL_TERTIARY), UCOL_ON, status); 
    if (U_FAILURE(status)) {
        errln("Error opening collator %s", u_errorName(status));
    }
    UnicodeString text("text");
    UnicodeString pattern("pattern");
    StringSearch *strsrch = new StringSearch(pattern, text, collator, NULL, 
                                             status);
    strsrch->setAttribute(USEARCH_CANONICAL_MATCH, USEARCH_ON, status);
    if (U_FAILURE(status)) {
        errln("Error opening string search %s", u_errorName(status));
    }   
    
    int count = 0;
    while (CONTRACTIONCANONICAL[count].text != NULL) {
        u_unescape(CONTRACTIONCANONICAL[count].text, temp, 128);
        text.setTo(temp, u_strlen(temp));
        u_unescape(CONTRACTIONCANONICAL[count].pattern, temp, 128);
        pattern.setTo(temp, u_strlen(temp));
        strsrch->setText(text, status);
        strsrch->setPattern(pattern, status);
        if (!assertEqualWithStringSearch(strsrch, 
                                             &CONTRACTIONCANONICAL[count])) {
            errln("Error at test number %d", count);
        }
        count ++;
    }
    delete strsrch;
    delete collator;
}

void StringSearchTest::TestUClassID()
{
    char id = *((char *)StringSearch::getStaticClassID());
    if (id != 0) {
        errln("Static class id for StringSearch should be 0");
    }
    UErrorCode     status    = U_ZERO_ERROR;
    UnicodeString  text("text");
    UnicodeString  pattern("pattern");
    StringSearch  *strsrch = new StringSearch(pattern, text, m_en_us_, NULL, 
                                              status);
    id = *((char *)strsrch->getDynamicClassID());
    if (id != 0) {
        errln("Dynamic class id for StringSearch should be 0");
    }
    delete strsrch;
}

class TestSearch : public SearchIterator
{
public:
    TestSearch(const TestSearch &obj);
    TestSearch(const UnicodeString &text, 
               BreakIterator *breakiter,
               const UnicodeString &pattern);
    ~TestSearch();

    void        setOffset(int32_t position, UErrorCode &status);
    int32_t     getOffset() const;
    SearchIterator* safeClone() const;


    /**
     * ICU "poor man's RTTI", returns a UClassID for the actual class.
     *
     * @draft ICU 2.2
     */
    virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }

    /**
     * ICU "poor man's RTTI", returns a UClassID for this class.
     *
     * @draft ICU 2.2
     */
    static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }

    UBool operator!=(const TestSearch &that) const;

    UnicodeString m_pattern_;

protected:
    int32_t      handleNext(int32_t position, UErrorCode &status);
    int32_t      handlePrev(int32_t position, UErrorCode &status);
    TestSearch & operator=(const TestSearch &that);

private:

    /**
     * The address of this static class variable serves as this class's ID
     * for ICU "poor man's RTTI".
     */
    static const char fgClassID;
    uint32_t m_offset_;
};

const char TestSearch::fgClassID=0;

TestSearch::TestSearch(const TestSearch &obj) : SearchIterator(obj)
{
    m_offset_ = obj.m_offset_;
    m_pattern_ = obj.m_pattern_;
}

TestSearch::TestSearch(const UnicodeString &text, 
                       BreakIterator *breakiter,
                       const UnicodeString &pattern) : SearchIterator()
{
    m_breakiterator_ = breakiter;
    m_pattern_ = pattern;
    m_text_ = text;
    m_offset_ = 0;
    m_pattern_ = pattern;
}

TestSearch::~TestSearch()
{
}


void TestSearch::setOffset(int32_t position, UErrorCode &status)
{
    if (position >= 0 && position <= m_text_.length()) {
        m_offset_ = position;
    }
    else {
        status = U_INDEX_OUTOFBOUNDS_ERROR;
    }
}

int32_t TestSearch::getOffset() const
{
    return m_offset_;
}

SearchIterator * TestSearch::safeClone() const 
{
    return new TestSearch(m_text_, m_breakiterator_, m_pattern_);
}

UBool TestSearch::operator!=(const TestSearch &that) const
{
    if (SearchIterator::operator !=(that)) {
        return FALSE;
    }
    return m_offset_ != that.m_offset_ || m_pattern_ != that.m_pattern_;
}

int32_t TestSearch::handleNext(int32_t start, UErrorCode &status)
{
  if(U_SUCCESS(status)) {
    int match = m_text_.indexOf(m_pattern_, start);
    if (match < 0) {
        m_offset_ = m_text_.length();
        setMatchStart(m_offset_);
        setMatchLength(0);
        return USEARCH_DONE;
    }
    setMatchStart(match);
    m_offset_ = match;
    setMatchLength(m_pattern_.length());
    return match;
  } else {
    return USEARCH_DONE;
  }
}

int32_t TestSearch::handlePrev(int32_t start, UErrorCode &status)
{
  if(U_SUCCESS(status)) {
    int match = m_text_.lastIndexOf(m_pattern_, 0, start);
    if (match < 0) {
        m_offset_ = 0;
        setMatchStart(m_offset_);
        setMatchLength(0);
        return USEARCH_DONE;
    }
    setMatchStart(match);
    m_offset_ = match;
    setMatchLength(m_pattern_.length());
    return match;
  } else {
    return USEARCH_DONE;
  }
}

TestSearch & TestSearch::operator=(const TestSearch &that)
{
    SearchIterator::operator=(that);
    m_offset_ = that.m_offset_;
    m_pattern_ = that.m_pattern_;
    return *this;
}

void StringSearchTest::TestSubclass()
{
    UnicodeString text("abc abcd abc");
    UnicodeString pattern("abc");
    TestSearch search(text, NULL, pattern);
    TestSearch search2(search);
    int expected[] = {0, 4, 9};
    UErrorCode status = U_ZERO_ERROR; 
    int i;
    StringCharacterIterator chariter(text);

    search.setText(text, status);
    if (search.getText() != search2.getText()) {
        errln("Error setting text");
    }

    search.setText(chariter, status);
    if (search.getText() != search2.getText()) {
        errln("Error setting text");
    }

    search.reset();
    // comparing constructors
 
    for (i = 0; i < UPRV_LENGTHOF(expected); i ++) {
        if (search.next(status) != expected[i]) {
            errln("Error getting next match");
        }
        if (search.getMatchedLength() != search.m_pattern_.length()) {
            errln("Error getting next match length");
        }
    }
    if (search.next(status) != USEARCH_DONE) {
        errln("Error should have reached the end of the iteration");
    }
    for (i = UPRV_LENGTHOF(expected) - 1; i >= 0; i --) {
        if (search.previous(status) != expected[i]) {
            errln("Error getting previous match");
        }
        if (search.getMatchedLength() != search.m_pattern_.length()) {
            errln("Error getting previous match length");
        }
    }
    if (search.previous(status) != USEARCH_DONE) {
        errln("Error should have reached the start of the iteration");
    }
}

class StubSearchIterator:public SearchIterator{
public:
    StubSearchIterator(){}
    virtual void setOffset(int32_t , UErrorCode &) {}
    virtual int32_t getOffset(void) const {return 0;}
    virtual SearchIterator* safeClone(void) const {return NULL;}
    virtual int32_t handleNext(int32_t , UErrorCode &){return 0;}
    virtual int32_t handlePrev(int32_t , UErrorCode &) {return 0;}
    virtual UClassID getDynamicClassID() const {
        static char classID = 0;
        return (UClassID)&classID; 
    }
};

void StringSearchTest::TestCoverage(){
    StubSearchIterator stub1, stub2;
    UErrorCode status = U_ZERO_ERROR;

    if (stub1 != stub2){
        errln("new StubSearchIterator should be equal");
    }

    stub2.setText(UnicodeString("ABC"), status);
    if (U_FAILURE(status)) {
        errln("Error: SearchIterator::SetText");
    }

    stub1 = stub2;
    if (stub1 != stub2){
        errln("SearchIterator::operator =  assigned object should be equal");
    }
}

#endif /* !UCONFIG_NO_BREAK_ITERATION */

#endif /* #if !UCONFIG_NO_COLLATION */
