If a char sequence is adjacent to an index of matcher, then append the sequence to
the pattern of the index of matcher.
9315
static Matcher combineCharSeqAfterIndexOf(Matcher matcher) {
    if (matcher instanceof IndexOfMatcher) {
      IndexOfMatcher m = matcher.as();
      Matcher next = PatternUtils.head(m.next());
      if (next instanceof CharSeqMatcher) {
        String pattern = m.pattern() + next.<CharSeqMatcher>as().pattern();
        return new IndexOfMatcher(pattern, PatternUtils.tail(m.next()));
      }
    }
    return matcher;
  }
1168107
private static boolean matchesPatternList(final String str, final List<Pattern> patterns) {
        if (patterns != null) {
            for (final Pattern pattern : patterns) {
                if (pattern.matcher(str).matches()) {
                    return true;
                }
            }
        }
        return false;
    }
495231
def including(self, sequence) -> Generator:
        """"""
        return (element for element in sequence
                if self.indexer(element) in self.predicates)
606818
protected void chunkString(
            final List<CharacterEvent> characterEvents,
            final CharSequence buffer,
            int patternIndex) {
        // Iterate over the chunking patterns
        for (; patternIndex < this.chunkingPatterns.length; patternIndex++) {
            final Pattern pattern = this.chunkingPatterns[patternIndex];

            final Matcher matcher = pattern.matcher(buffer);
            if (matcher.find()) {
                final CharacterEventSource eventSource =
                        this.chunkingPatternEventSources.get(pattern);
                int prevMatchEnd = 0;

                do {
                    // Add all of the text up to the match as a new chunk, use subSequence to avoid
                    // extra string alloc
                    this.chunkString(
                            characterEvents,
                            buffer.subSequence(prevMatchEnd, matcher.start()),
                            patternIndex + 1);

                    // Get the generated CharacterEvents for the match
                    final MatchResult matchResult = matcher.toMatchResult();
                    eventSource.generateCharacterEvents(this.request, matchResult, characterEvents);

                    prevMatchEnd = matcher.end();
                } while (matcher.find());

                // Add any remaining text from the original CharacterDataEvent
                if (prevMatchEnd < buffer.length()) {
                    this.chunkString(
                            characterEvents,
                            buffer.subSequence(prevMatchEnd, buffer.length()),
                            patternIndex + 1);
                }

                return;
            }
        }

        // Buffer didn't match anything, just append the string data

        // de-duplication of the event string data
        final String eventString = buffer.toString();
        characterEvents.add(CharacterDataEventImpl.create(eventString));
    }
1024331
protected void appendPattern(StringBuilder sb, QPathEntry entry, boolean indexConstraint)
   {
      String pattern = entry.getAsString(false);
      sb.append("(I.NAME");
      if (pattern.contains("*"))
      {
         sb.append(" LIKE '");
         sb.append(escapeSpecialChars(pattern));
         sb.append("' ESCAPE '");
         sb.append(getLikeExpressionEscape());
         sb.append("'");
      }
      else
      {
         sb.append("='");
         sb.append(escape(pattern));
         sb.append("'");
      }

      if (indexConstraint && entry.getIndex() != -1)
      {
         sb.append(" and I.I_INDEX=");
         sb.append(entry.getIndex());
      }
      sb.append(")");
   }
1019094
static Matcher combineCharSeqAfterStartsWith(Matcher matcher) {
    if (matcher instanceof SeqMatcher) {
      List<Matcher> matchers = matcher.<SeqMatcher>as().matchers();
      if (matchers.size() >= 2
          && matchers.get(0) instanceof StartsWithMatcher
          && matchers.get(1) instanceof CharSeqMatcher) {
        List<Matcher> ms = new ArrayList<>();
        String prefix = matchers.get(0).<StartsWithMatcher>as().pattern()
            + matchers.get(1).<CharSeqMatcher>as().pattern();
        ms.add(new StartsWithMatcher(prefix));
        ms.addAll(matchers.subList(2, matchers.size()));
        return SeqMatcher.create(ms);
      } else {
        return matcher;
      }
    }
    return matcher;
  }
60941
@Override
    public int matches(Replaceable text,
                       int[] offset,
                       int limit,
                       boolean incremental) {
        // Note (1): We process text in 16-bit code units, rather than
        // 32-bit code points.  This works because stand-ins are
        // always in the BMP and because we are doing a literal match
        // operation, which can be done 16-bits at a time.
        int i;
        int[] cursor = new int[] { offset[0] };
        if (limit < cursor[0]) {
            // Match in the reverse direction
            for (i=pattern.length()-1; i>=0; --i) {
                char keyChar = pattern.charAt(i); // OK; see note (1) above
                UnicodeMatcher subm = data.lookupMatcher(keyChar);
                if (subm == null) {
                    if (cursor[0] > limit &&
                        keyChar == text.charAt(cursor[0])) { // OK; see note (1) above
                        --cursor[0];
                    } else {
                        return U_MISMATCH;
                    }
                } else {
                    int m =
                        subm.matches(text, cursor, limit, incremental);
                    if (m != U_MATCH) {
                        return m;
                    }
                }
            }
            // Record the match position, but adjust for a normal
            // forward start, limit, and only if a prior match does not
            // exist -- we want the rightmost match.
            if (matchStart < 0) {
                matchStart = cursor[0]+1;
                matchLimit = offset[0]+1;
            }
        } else {
            for (i=0; i<pattern.length(); ++i) {
                if (incremental && cursor[0] == limit) {
                    // We've reached the context limit without a mismatch and
                    // without completing our match.
                    return U_PARTIAL_MATCH;
                }
                char keyChar = pattern.charAt(i); // OK; see note (1) above
                UnicodeMatcher subm = data.lookupMatcher(keyChar);
                if (subm == null) {
                    // Don't need the cursor < limit check if
                    // incremental is true (because it's done above); do need
                    // it otherwise.
                    if (cursor[0] < limit &&
                        keyChar == text.charAt(cursor[0])) { // OK; see note (1) above
                        ++cursor[0];
                    } else {
                        return U_MISMATCH;
                    }
                } else {
                    int m =
                        subm.matches(text, cursor, limit, incremental);
                    if (m != U_MATCH) {
                        return m;
                    }
                }
            }
            // Record the match position
            matchStart = offset[0];
            matchLimit = cursor[0];
        }

        offset[0] = cursor[0];
        return U_MATCH;
    }
276526
def _sequence(self, i):
        """"""

        result = ['[']
        end_range = 0
        escape_hyphen = -1
        removed = False
        last_posix = False

        c = next(i)
        if c in ('!', '^'):
            # Handle negate char
            result.append('^')
            c = next(i)
        if c == '[':
            last_posix = self._handle_posix(i, result, 0)
            if not last_posix:
                result.append(re.escape(c))
            c = next(i)
        elif c in ('-', ']'):
            result.append(re.escape(c))
            c = next(i)

        while c != ']':
            if c == '-':
                if last_posix:
                    result.append('\\' + c)
                    last_posix = False
                elif i.index - 1 > escape_hyphen:
                    # Found a range delimiter.
                    # Mark the next two characters as needing to be escaped if hyphens.
                    # The next character would be the end char range (s-e),
                    # and the one after that would be the potential start char range
                    # of a new range (s-es-e), so neither can be legitimate range delimiters.
                    result.append(c)
                    escape_hyphen = i.index + 1
                    end_range = i.index
                elif end_range and i.index - 1 >= end_range:
                    if self._sequence_range_check(result, '\\' + c):
                        removed = True
                    end_range = 0
                else:
                    result.append('\\' + c)
                c = next(i)
                continue
            last_posix = False

            if c == '[':
                last_posix = self._handle_posix(i, result, end_range)
                if last_posix:
                    c = next(i)
                    continue

            if c == '\\':
                # Handle escapes
                subindex = i.index
                try:
                    value = self._references(i, True)
                except PathNameException:
                    raise StopIteration
                except StopIteration:
                    i.rewind(i.index - subindex)
                    value = r'\\'
            elif c == '/':
                if self.pathname:
                    raise StopIteration
                value = c
            elif c in SET_OPERATORS:
                # Escape &, |, and ~ to avoid &&, ||, and ~~
                value = '\\' + c
            else:
                # Anything else
                value = c

            if end_range and i.index - 1 >= end_range:
                if self._sequence_range_check(result, value):
                    removed = True
                end_range = 0
            else:
                result.append(value)

            c = next(i)

        result.append(']')
        # Bad range removed.
        if removed:
            value = "".join(result)
            if value == '[]':
                # We specified some ranges, but they are all
                # out of reach.  Create an impossible sequence to match.
                result = ['[^%s]' % ('\x00-\xff' if self.is_bytes else uniprops.UNICODE_RANGE)]
            elif value == '[^]':
                # We specified some range, but hey are all
                # out of reach. Since this is exclusive
                # that means we can match *anything*.
                result = ['[%s]' % ('\x00-\xff' if self.is_bytes else uniprops.UNICODE_RANGE)]
            else:
                result = [value]

        if self.pathname or self.after_start:
            return self._restrict_sequence() + ''.join(result)

        return ''.join(result)
1179743
@Deprecated
    public static int matchAfter(CharSequence a, CharSequence b, int aIndex, int bIndex) {
        int i = aIndex, j = bIndex;
        int alen = a.length();
        int blen = b.length();
        for (; i < alen && j < blen; ++i, ++j) {
            char ca = a.charAt(i);
            char cb = b.charAt(j);
            if (ca != cb) {
                break;
            }
        }
        // if we failed a match make sure that we didn't match half a character
        int result = i - aIndex;
        if (result != 0 && !onCharacterBoundary(a, i) && !onCharacterBoundary(b, j)) {
            --result; // backup
        }
        return result;
    }
426842
def nth_char(char_map, index):
    """"""
    for char in char_map:
        if index < char_map[char]:
            return char
        index = index - char_map[char]
    return None
1363595
@Override
    public int matches(Replaceable text,
            int[] offset,
            int limit,
            boolean incremental) {

        if (offset[0] == limit) {
            // Strings, if any, have length != 0, so we don't worry
            // about them here.  If we ever allow zero-length strings
            // we much check for them here.
            if (contains(UnicodeMatcher.ETHER)) {
                return incremental ? U_PARTIAL_MATCH : U_MATCH;
            } else {
                return U_MISMATCH;
            }
        } else {
            if (strings.size() != 0) { // try strings first

                // might separate forward and backward loops later
                // for now they are combined

                // TODO Improve efficiency of this, at least in the forward
                // direction, if not in both.  In the forward direction we
                // can assume the strings are sorted.

                boolean forward = offset[0] < limit;

                // firstChar is the leftmost char to match in the
                // forward direction or the rightmost char to match in
                // the reverse direction.
                char firstChar = text.charAt(offset[0]);

                // If there are multiple strings that can match we
                // return the longest match.
                int highWaterLength = 0;

                for (String trial : strings) {
                    //if (trial.length() == 0) {
                    //    return U_MATCH; // null-string always matches
                    //}
                    // assert(trial.length() != 0); // We ensure this elsewhere

                    char c = trial.charAt(forward ? 0 : trial.length() - 1);

                    // Strings are sorted, so we can optimize in the
                    // forward direction.
                    if (forward && c > firstChar) break;
                    if (c != firstChar) continue;

                    int length = matchRest(text, offset[0], limit, trial);

                    if (incremental) {
                        int maxLen = forward ? limit-offset[0] : offset[0]-limit;
                        if (length == maxLen) {
                            // We have successfully matched but only up to limit.
                            return U_PARTIAL_MATCH;
                        }
                    }

                    if (length == trial.length()) {
                        // We have successfully matched the whole string.
                        if (length > highWaterLength) {
                            highWaterLength = length;
                        }
                        // In the forward direction we know strings
                        // are sorted so we can bail early.
                        if (forward && length < highWaterLength) {
                            break;
                        }
                        continue;
                    }
                }

                // We've checked all strings without a partial match.
                // If we have full matches, return the longest one.
                if (highWaterLength != 0) {
                    offset[0] += forward ? highWaterLength : -highWaterLength;
                    return U_MATCH;
                }
            }
            return super.matches(text, offset, limit, incremental);
        }
    }
1148833
static Matcher sequenceWithFalseIsFalse(Matcher matcher) {
    if (matcher instanceof SeqMatcher) {
      for (Matcher m : matcher.<SeqMatcher>as().matchers()) {
        if (m instanceof FalseMatcher) {
          return FalseMatcher.INSTANCE;
        }
      }
    }
    return matcher;
  }
1005073
def _join_sequence(seq, last_separator=''):
    """"""
    count = len(seq)
    return ', '.join(_format_element(element, count, i, last_separator)
                     for i, element in enumerate(seq))
751682
public Matcher matcher(CharSequence s) {
        Matcher m = new Matcher(this);
        m.setTarget(s);
        return m;
    }
457524
public static boolean endsWith(CharSequence seq, CharSequence pattern)
    {
        return endsWith(seq, pattern, Funcs::same);
    }
1339156
function Matcher (patternFn, successFn, next) {
    this.patternFn = patternFn;
    this.successFn = successFn;
    this.next = next;
  }
757883
static Matcher removeTrueInSequence(Matcher matcher) {
    if (matcher instanceof SeqMatcher) {
      List<Matcher> matchers = matcher.<SeqMatcher>as().matchers();
      List<Matcher> ms = new ArrayList<>();
      for (Matcher m : matchers) {
        if (!(m instanceof TrueMatcher)) {
          ms.add(m);
        }
      }
      return SeqMatcher.create(ms);
    }
    return matcher;
  }