private boolean charEquals(int patternIndex, int nameIndex, boolean isIgnoreCase, boolean allowTypos, @NotNull ErrorState errorState) {
      char patternChar = charAt(patternIndex, errorState);
      char nameChar = myName.charAt(nameIndex);
      int length = myName.length();

      if (patternChar == nameChar || isIgnoreCase && equalsIgnoreCase(patternIndex, errorState, nameChar)) {
        return true;
      }

      if (!myAllowTypos || !allowTypos) return false;

      if (errorState.countErrors(0, patternIndex) > 0) return false;
      Error prevError = errorState.getError(patternIndex - 1);
      if (prevError == SwapError.instance) {
        return false;
      }

      char leftMiss = leftMiss(patternChar);
      if (leftMiss != 0) {
        if (leftMiss == nameChar ||
            isIgnoreCase && (AsciiUtils.toLowerAscii(leftMiss) == nameChar || AsciiUtils.toUpperAscii(leftMiss) == nameChar)) {
          errorState.addError(patternIndex, new TypoError(leftMiss));
          return true;
        }
      }

      char rightMiss = rightMiss(patternChar);
      if (rightMiss != 0) {
        if (rightMiss == nameChar ||
            isIgnoreCase && (AsciiUtils.toLowerAscii(rightMiss) == nameChar || AsciiUtils.toUpperAscii(rightMiss) == nameChar)) {
          errorState.addError(patternIndex, new TypoError(rightMiss));
          return true;
        }
      }

      if (patternLength(errorState) > patternIndex + 1 && length > nameIndex + 1) {
        char nextNameChar = myName.charAt(nameIndex + 1);
        char nextPatternChar = charAt(patternIndex + 1, errorState);

        if ((patternChar == nextNameChar || isIgnoreCase && equalsIgnoreCase(patternIndex, errorState, nextNameChar)) &&
            (nextPatternChar == nameChar || isIgnoreCase && equalsIgnoreCase(patternIndex + 1, errorState, nameChar))) {
          errorState.addError(patternIndex, SwapError.instance);
          return true;
        }
      }

      if (length > nameIndex + 1) {
        char nextNameChar = myName.charAt(nameIndex + 1);

        if (patternChar == nextNameChar || isIgnoreCase && equalsIgnoreCase(patternIndex, errorState, nextNameChar)) {
          errorState.addError(patternIndex, new MissError(nameChar));
          return true;
        }
      }

      return false;
    }
private boolean charEquals(int patternIndex, int nameIndex, boolean isIgnoreCase, boolean allowTypos, @NotNull ErrorState errorState)