private static void handleOption(@NotNull MatchVariableConstraint constraint, @NotNull String option, @NotNull String argument,
                                   boolean invert) {
    argument = argument.trim();
    if (option.equals(REF)) {
      constraint.setReferenceConstraint(argument);
      constraint.setInvertReference(invert);
    }
    else if (option.equals(REGEX) || option.equals(REGEXW)) {
      if (argument.charAt(0) == '*') {
        argument = argument.substring(1);
        constraint.setWithinHierarchy(true);
      }
      checkRegex(argument);
      constraint.setRegExp(argument);
      constraint.setInvertRegExp(invert);
      if (option.equals(REGEXW)) {
        constraint.setWholeWordsOnly(true);
      }
    }
    else if (option.equals(EXPRTYPE)) {
      if (argument.charAt(0) == '*') {
        argument = argument.substring(1);
        constraint.setExprTypeWithinHierarchy(true);
      }
      boolean regex = false;
      if (argument.charAt(0) == '~') {
        argument = argument.substring(1);
        regex = true;
      }
      argument = unescape(argument);
      if (regex) constraint.setNameOfExprType(argument);
      else constraint.setExpressionTypes(argument);
      constraint.setInvertExprType(invert);
    }
    else if (option.equals(FORMAL)) {
      if (argument.charAt(0) == '*') {
        argument = argument.substring(1);
        constraint.setFormalArgTypeWithinHierarchy(true);
      }
      argument = unescape(argument);
      constraint.setExpectedTypes(argument);
      constraint.setInvertFormalType(invert);
    }
    else if (option.equals(SCRIPT)) {
      if (invert) throw new MalformedPatternException(SSRBundle.message("error.cannot.invert", option));
      constraint.setScriptCodeConstraint(argument);
    }
    else if (option.equals(CONTAINS)) {
      constraint.setContainsConstraint(argument);
      constraint.setInvertContainsConstraint(invert);
    }
    else if (option.equals(WITHIN)) {
      if (!Configuration.CONTEXT_VAR_NAME.equals(constraint.getName())) {
        throw new MalformedPatternException(SSRBundle.message("error.only.applicable.to.complete.match", option));
      }
      constraint.setWithinConstraint(argument);
      constraint.setInvertWithinConstraint(invert);
    }
    else if (option.equals(CONTEXT)) {
      if (invert) throw new MalformedPatternException(SSRBundle.message("error.cannot.invert", option));
      if (!Configuration.CONTEXT_VAR_NAME.equals(constraint.getName())) {
        throw new MalformedPatternException(SSRBundle.message("error.only.applicable.to.complete.match", option));
      }
      constraint.setContextConstraint(argument);
    }
    else if (option.startsWith("_")) {
      if (invert) throw new MalformedPatternException(SSRBundle.message("error.cannot.invert", option));
      constraint.putAdditionalConstraint(option.substring(1), argument);
    }
    else {
      assert false;
    }
  }
private static void handleOption(@NotNull MatchVariableConstraint constraint, @NotNull String option, @NotNull String argument,
                                   boolean invert)