@Nullable
  public MatchingHandler processPatternStringWithFragments(@NotNull String pattern, @NotNull OccurenceKind kind,
                                                           @NotNull Pattern substitutionPattern) {
    String content;

    if (kind == OccurenceKind.LITERAL) {
      content = pattern.substring(1, pattern.length() - 1);
    }
    else if (kind == OccurenceKind.COMMENT || kind == OccurenceKind.TEXT) {
      content = pattern;
    }
    else {
      assert false;
      return null;
    }

    @NonNls StringBuilder buf = new StringBuilder(content.length());
    Matcher matcher = substitutionPattern.matcher(content);
    List<SubstitutionHandler> handlers = new SmartList<>();
    int start = 0;
    String word;
    boolean hasLiteralContent = false;

    SubstitutionHandler handler = null;
    while (matcher.find()) {
      word = content.substring(start, matcher.start());
      if (!word.isEmpty()) {
        hasLiteralContent = true;
        buf.append(MatchUtil.makeExtremeSpacesOptional(MatchUtil.shieldRegExpMetaChars(word)));

        processTokenizedName(word, kind);
      }

      handler = (SubstitutionHandler)getContext().getPattern().getHandler(matcher.group(1));
      if (handler == null) throw new MalformedPatternException();

      handlers.add(handler);
      RegExpPredicate predicate = handler.findPredicate(RegExpPredicate.class);

      if (predicate == null || !predicate.isWholeWords()) {
        buf.append("(.*?)");
      }
      else {
        buf.append(".*?\\b(").append(predicate.getRegExp()).append(")\\b.*?");
      }

      if (isSuitablePredicate(predicate, handler)) {
        processTokenizedName(predicate.getRegExp(), kind);
      }

      start = matcher.end();
    }

    word = content.substring(start);

    if (!word.isEmpty()) {
      hasLiteralContent = true;
      buf.append(MatchUtil.makeExtremeSpacesOptional(MatchUtil.shieldRegExpMetaChars(word)));

      processTokenizedName(word, kind);
    }

    if (hasLiteralContent) {
      if (kind == OccurenceKind.LITERAL) {
        buf.insert(0, "[\"']");
        buf.append("[\"']");
      }
    }

    if (!handlers.isEmpty()) {
      return hasLiteralContent
             ? new LiteralWithSubstitutionHandler(buf.toString(), handlers, context.getOptions().isCaseSensitiveMatch())
             : handler;
    }

    return null;
  }
@Nullable
  public MatchingHandler processPatternStringWithFragments(@NotNull String pattern, @NotNull OccurenceKind kind,
                                                           @NotNull Pattern substitutionPattern)