private static void mergeValues(@NotNull JsonSchemaObjectImpl base, @NotNull JsonSchemaObjectImpl other) {
    // we do not copy id, schema
    base.myProperties = mergeProperties(base.getProperties(), other.getProperties());
    base.myDefinitionsMap = mergeMaps(base.getDefinitionsMap(), other.getDefinitionsMap());

    var baseProperties = base.getPatternProperties() == null ? null : base.getPatternProperties().getSchemasMap();
    var otherProperties = other.getPatternProperties() == null ? null : other.getPatternProperties().getSchemasMap();
    var patternPropertiesOrNull = mergeMaps(baseProperties, otherProperties);
    base.myPatternProperties = patternPropertiesOrNull == null ? null : new PatternProperties(patternPropertiesOrNull);

    if (!StringUtil.isEmptyOrSpaces(other.getTitle())) base.setTitle(other.getTitle());
    if (!StringUtil.isEmptyOrSpaces(other.getDescription())) base.setDescription(other.getDescription());
    if (!StringUtil.isEmptyOrSpaces(other.getHtmlDescription())) base.setHtmlDescription(other.getHtmlDescription());
    if (!StringUtil.isEmptyOrSpaces(other.getDeprecationMessage())) base.setDeprecationMessage(other.getDeprecationMessage());

    base.setExclusiveMaximum(base.isExclusiveMaximum() || other.isExclusiveMaximum());
    base.setExclusiveMinimum(base.isExclusiveMinimum() || other.isExclusiveMinimum());

    if (other.myUniqueItems != null) base.setUniqueItems(other.myUniqueItems);

    base.setShouldValidateAgainstJSType(base.isShouldValidateAgainstJSType() || other.isShouldValidateAgainstJSType());

    base.setForceCaseInsensitive(base.isForceCaseInsensitive() || other.isForceCaseInsensitive());

    var mergedRequired = mergeSets(base.getRequired(), other.getRequired());
    base.setRequired(mergedRequired);

    base.setPropertyDependencies(mergeMaps(base.getPropertyDependencies(), other.getPropertyDependencies()));
    base.setSchemaDependencies(mergeMaps(base.getSchemaDependencies(), other.getSchemaDependencies()));
    base.setEnumMetadata(mergeMaps(base.getEnumMetadata(), other.getEnumMetadata()));
    base.setAllOf(mergeLists(base.getAllOf(), other.getAllOf()));
    base.setAnyOf(mergeLists(base.getAnyOf(), other.getAnyOf()));
    base.setOneOf(mergeLists(base.getOneOf(), other.getOneOf()));
    base.setIfThenElse(mergeLists(base.getIfThenElse(), other.getIfThenElse()));

    if (other.myDefault != null) base.setDefault(other.myDefault);
    if (other.getExample() != null) base.setExample(other.getExample());
    if (other.getFormat() != null) base.setFormat(other.getFormat());
    if (other.getMultipleOf() != null) base.setMultipleOf(other.getMultipleOf());
    if (other.getMaximum() != null) base.setMaximum(other.getMaximum());
    if (other.getMinimum() != null) base.setMinimum(other.getMinimum());
    if (other.getExclusiveMaximumNumber() != null) base.setExclusiveMaximumNumber(other.getExclusiveMaximumNumber());
    if (other.getExclusiveMinimumNumber() != null) base.setExclusiveMinimumNumber(other.getExclusiveMinimumNumber());
    if (other.getMaxLength() != null) base.setMaxLength(other.getMaxLength());
    if (other.getMinLength() != null) base.setMinLength(other.getMinLength());
    if (other.myPattern != null) base.myPattern = other.myPattern;
    if (other.getAdditionalPropertiesSchema() != null) base.setAdditionalPropertiesSchema(other.getAdditionalPropertiesSchema());
    if (other.getPropertyNamesSchema() != null) base.setPropertyNamesSchema(other.getPropertyNamesSchema());
    if (other.myAdditionalItemsAllowed != null) base.setAdditionalItemsAllowed(other.myAdditionalItemsAllowed);
    if (other.getAdditionalItemsSchema() != null) base.setAdditionalItemsSchema(other.getAdditionalItemsSchema());
    if (other.getItemsSchema() != null) base.setItemsSchema(other.getItemsSchema());
    if (other.getContainsSchema() != null) base.setContainsSchema(other.getContainsSchema());
    if (other.getItemsSchemaList() != null) base.setItemsSchemaList(mergeLists(base.getItemsSchemaList(), other.getItemsSchemaList()));
    if (other.getMaxItems() != null) base.setMaxItems(other.getMaxItems());
    if (other.getMinItems() != null) base.setMinItems(other.getMinItems());
    if (other.getMaxProperties() != null) base.setMaxProperties(other.getMaxProperties());
    if (other.getMinProperties() != null) base.setMinProperties(other.getMinProperties());
    if (other.getEnum() != null) base.setEnum(other.getEnum());
    if (other.getNot() != null) base.setNot(other.getNot());
    if (other.getLanguageInjection() != null) base.setLanguageInjection(other.getLanguageInjection());
    if (other.getMetadata() != null) base.setMetadata(other.getMetadata());

    //computed together because influence each other
    var mergedExclusionAndType = computeMergedExclusionAndType(base.getType(), other.getType(), other.getTypeVariants());
    if (mergedExclusionAndType != null) base.setType(mergedExclusionAndType.type);
    if (mergedExclusionAndType != null && mergedExclusionAndType.isValidByExclusion != null) {
      base.setValidByExclusion(mergedExclusionAndType.isValidByExclusion);
    }

    var exclusionAndTypesInfo = mergeTypeVariantSets(base.getTypeVariants(), other.getTypeVariants());
    if (exclusionAndTypesInfo.types != null) base.setTypeVariants(exclusionAndTypesInfo.types);
    if (exclusionAndTypesInfo.isValidByExclusion != null) base.setValidByExclusion(exclusionAndTypesInfo.isValidByExclusion);

    if (other.myAdditionalPropertiesAllowed != null) {
      base.setAdditionalPropertiesAllowed(other.myAdditionalPropertiesAllowed);
      if (other.myAdditionalPropertiesAllowed == Boolean.FALSE) {
        base.addAdditionalPropsNotAllowedFor(other.getFileUrl(), other.getPointer());
      }
    }
  }
private static void mergeValues(@NotNull JsonSchemaObjectImpl base, @NotNull JsonSchemaObjectImpl other)