@Override
  public void handleSubstitution(@NotNull ParameterInfo info, @NotNull MatchResult match, @NotNull StringBuilder result, @NotNull ReplacementInfo replacementInfo) {
    if (info.getName().equals(match.getName())) {
      final String replacementString;
      boolean forceAddingNewLine = false;
      int offset = 0;

      final PsiElement element = info.getElement();
      final Map<String, ParameterInfo> typeInfos = info.getUserData(PARAMETER_CONTEXT);
      if (typeInfos != null) {
        if (element instanceof PsiParameter) {
          final int parameterEnd = info.getStartIndex();
          final Integer length = info.getUserData(PARAMETER_LENGTH);
          assert length != null;
          final int parameterStart = parameterEnd - length;
          final String template = result.substring(parameterStart, parameterEnd);
          replacementString = handleParameter(info, replacementInfo, -parameterStart, template);
          result.delete(parameterStart, parameterEnd);
          offset -= template.length();
        }
        else if (element instanceof PsiNameValuePair) {
          final int parameterStart = info.getStartIndex();
          final Integer length = info.getUserData(PARAMETER_LENGTH);
          assert length != null;
          final int parameterEnd = parameterStart + length;
          final String template = result.substring(parameterStart, parameterEnd);
          replacementString = handleParameter(info, replacementInfo, -parameterStart, template);
          result.delete(parameterStart, parameterEnd);
        }
        else {
          return;
        }
      }
      else if (match.hasChildren() && !match.isScopeMatch()) {
        // compound matches
        final StringBuilder buf = new StringBuilder();

        PsiElement previous = null;
        boolean stripSemicolon = false;
        for (MatchResult matchResult : match.getChildren()) {
          final PsiElement currentElement = matchResult.getMatch();
          stripSemicolon = !(currentElement instanceof PsiField);

          if (previous != null) {
            final PsiElement parent = currentElement.getParent();
            if (parent instanceof PsiVariable || parent instanceof PsiTypeElement || parent instanceof PsiTypeParameter) {
              addSeparatorText(previous.getParent(), parent, buf);
            }
            else if (parent instanceof PsiClass || parent instanceof PsiReferenceList) {
              addSeparatorTextMatchedInAnyOrder(currentElement,
                                                parent instanceof PsiClass ? PsiMember.class : PsiJavaCodeReferenceElement.class, buf);
            }
            else if (info.isStatementContext() ||
                     info.isArgumentContext() ||
                     parent instanceof PsiPolyadicExpression ||
                     parent instanceof PsiArrayInitializerExpression) {
              addSeparatorText(previous, currentElement, buf);
            }
            else {
              buf.append(" "); // fallback, but shouldn't happen
            }
          }

          buf.append(matchResult.getMatchImage());
          forceAddingNewLine = currentElement instanceof PsiComment;
          previous = matchResult.getMatch();
        }

        replacementString = stripSemicolon ? StringUtil.trimEnd(buf.toString(), ';') : buf.toString();
      } else {
        final PsiElement matchElement = match.getMatch();
        if (info.isStatementContext()) {
          forceAddingNewLine = matchElement instanceof PsiComment;
        }
        final String matchImage = match.getMatchImage();
        replacementString = !(matchElement instanceof PsiField) ? StringUtil.trimEnd(matchImage, ';') : matchImage;
      }

      offset = Replacer.insertSubstitution(result, offset, info, replacementString);
      offset = removeExtraSemicolon(info, offset, result, match);
      if (forceAddingNewLine && info.isStatementContext()) {
        result.insert(info.getStartIndex() + offset + 1, '\n');
      }
    }
  }
@Override
  public void handleSubstitution(@NotNull ParameterInfo info, @NotNull MatchResult match, @NotNull StringBuilder result, @NotNull ReplacementInfo replacementInfo)