@Override
  public @NotNull DfaValue eval(@NotNull DfaValueFactory factory,
                                @NotNull DfaMemoryState state,
                                @NotNull DfaValue @NotNull ... arguments) {
    DfaValue left = arguments[0];
    DfaValue right = arguments[1];
    String leftString = getString(state, left);
    String rightString = getString(state, right);
    if (leftString != null && rightString != null &&
        leftString.length() + rightString.length() <= CustomMethodHandlers.MAX_STRING_CONSTANT_LENGTH_TO_TRACK) {
      return factory.fromDfType(concatenationResult(leftString + rightString, myStringType));
    }
    DfIntType leftRange = getLength(factory, state, left, leftString);
    DfIntType rightRange = getLength(factory, state, right, rightString);
    DfType resultRange = leftRange.eval(rightRange, LongRangeBinOp.PLUS);
    DfType result = resultRange.isConst(0)
                    ? referenceConstant("", myStringType)
                    : SpecialField.STRING_LENGTH.asDfType(resultRange).meet(myStringType.asDfType());
    return factory.fromDfType(result);
  }
@Override
  public @NotNull DfaValue eval(@NotNull DfaValueFactory factory,
                                @NotNull DfaMemoryState state,
                                @NotNull DfaValue @NotNull ... arguments)