diff --git a/.sdk-version b/.sdk-version index da7a7c5..85a92c4 100644 --- a/.sdk-version +++ b/.sdk-version @@ -1 +1 @@ -v3.101.0 +v3.102.0 diff --git a/README.md b/README.md index 953caa4..0fd89b1 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Add this dependency to your project's POM: ai.reveng sdk - 3.101.0 + 3.102.0 compile ``` @@ -31,7 +31,7 @@ repositories { } dependencies { - implementation "ai.reveng:sdk:3.101.0" + implementation "ai.reveng:sdk:3.102.0" } ``` diff --git a/build.gradle b/build.gradle index 355f2db..515edaf 100644 --- a/build.gradle +++ b/build.gradle @@ -19,7 +19,7 @@ apply plugin: 'java' apply plugin: 'com.diffplug.spotless' group = 'ai.reveng' -version = '3.101.0' +version = '3.102.0' @@ -171,7 +171,7 @@ mavenPublishing { publishToMavenCentral(true) signAllPublications() - coordinates("ai.reveng", "sdk", "3.101.0") + coordinates("ai.reveng", "sdk", "3.102.0") pom { name = "sdk" diff --git a/build.sbt b/build.sbt index 010d56c..8953656 100644 --- a/build.sbt +++ b/build.sbt @@ -2,7 +2,7 @@ lazy val root = (project in file(".")). settings( organization := "ai.reveng", name := "sdk", - version := "3.101.0", + version := "3.102.0", scalaVersion := "2.11.12", scalacOptions ++= Seq("-feature"), compile / javacOptions ++= Seq("-Xlint:deprecation"), diff --git a/docs/AnalysisBasicInfoOutputBody.md b/docs/AnalysisBasicInfoOutputBody.md index 08c00bc..4f1845e 100644 --- a/docs/AnalysisBasicInfoOutputBody.md +++ b/docs/AnalysisBasicInfoOutputBody.md @@ -12,7 +12,7 @@ |**binaryId** | **Long** | Binary ID | | |**binaryName** | **String** | Binary filename | | |**binarySize** | **Long** | Binary size in bytes | | -|**binaryUuid** | **String** | UUID of the binary, omitted when not set | [optional] | +|**binaryUuid** | **String** | UUID of the binary, omitted when not set | | |**creation** | **OffsetDateTime** | When the binary was uploaded | | |**debug** | **Boolean** | True when the binary was analysed with debug symbols | | |**functionCount** | **Long** | Number of functions in the binary | | diff --git a/docs/DataTypesEntry.md b/docs/DataTypesEntry.md index 97c0e98..490a6e7 100644 --- a/docs/DataTypesEntry.md +++ b/docs/DataTypesEntry.md @@ -8,6 +8,7 @@ | Name | Type | Description | Notes | |------------ | ------------- | ------------- | -------------| |**dataTypes** | [**FunctionInfo**](FunctionInfo.md) | | [optional] | +|**dataTypesVersion** | **Long** | Current version of the function data types. Pass this back on the next write to satisfy the CAS check. | | |**functionId** | **Long** | | | diff --git a/docs/FunctionDetailsOutputBody.md b/docs/FunctionDetailsOutputBody.md index 94c23be..95849a3 100644 --- a/docs/FunctionDetailsOutputBody.md +++ b/docs/FunctionDetailsOutputBody.md @@ -7,6 +7,7 @@ | Name | Type | Description | Notes | |------------ | ------------- | ------------- | -------------| +|**analysisId** | **Long** | | | |**binaryId** | **Long** | | | |**creation** | **OffsetDateTime** | | | |**debug** | **Boolean** | | | diff --git a/docs/StartMatchingForFunctionsInputBody.md b/docs/StartMatchingForFunctionsInputBody.md index 300062c..f933e30 100644 --- a/docs/StartMatchingForFunctionsInputBody.md +++ b/docs/StartMatchingForFunctionsInputBody.md @@ -11,6 +11,7 @@ |**functionIds** | **List<Long>** | Source function IDs to match against the rest of the corpus. | | |**minSimilarity** | **Double** | Similarity floor as a percentage. Defaults to 90. | [optional] | |**resultsPerFunction** | **Long** | Max matches returned per source function. Defaults to 1. | [optional] | +|**useCanonicalNames** | **Boolean** | Collapse near-duplicate candidate names into canonical buckets and return per-name confidences (the response 'confidences' array). Adds a canonicalisation step; defaults to false. | [optional] | diff --git a/pom.xml b/pom.xml index 80d2cb3..b7ecb84 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ sdk jar sdk - 3.101.0 + 3.102.0 https://github.com/RevEngAI/sdk-java Java SDK for the RevEng.AI API diff --git a/src/main/java/ai/reveng/invoker/ApiClient.java b/src/main/java/ai/reveng/invoker/ApiClient.java index c918f7f..51fad5a 100644 --- a/src/main/java/ai/reveng/invoker/ApiClient.java +++ b/src/main/java/ai/reveng/invoker/ApiClient.java @@ -148,7 +148,7 @@ protected void init() { json = new JSON(); // Set default User-Agent. - setUserAgent("OpenAPI-Generator/3.101.0/java"); + setUserAgent("OpenAPI-Generator/3.102.0/java"); authentications = new HashMap(); } diff --git a/src/main/java/ai/reveng/invoker/Configuration.java b/src/main/java/ai/reveng/invoker/Configuration.java index 4ff7141..f87e3b4 100644 --- a/src/main/java/ai/reveng/invoker/Configuration.java +++ b/src/main/java/ai/reveng/invoker/Configuration.java @@ -18,7 +18,7 @@ @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") public class Configuration { - public static final String VERSION = "3.101.0"; + public static final String VERSION = "3.102.0"; private static final AtomicReference defaultApiClient = new AtomicReference<>(); private static volatile Supplier apiClientFactory = ApiClient::new; diff --git a/src/main/java/ai/reveng/model/AnalysisBasicInfoOutputBody.java b/src/main/java/ai/reveng/model/AnalysisBasicInfoOutputBody.java index d993ee1..cae5437 100644 --- a/src/main/java/ai/reveng/model/AnalysisBasicInfoOutputBody.java +++ b/src/main/java/ai/reveng/model/AnalysisBasicInfoOutputBody.java @@ -133,7 +133,7 @@ public static void validateJsonElement(JsonElement jsonElement) throws IOExcepti public static final String SERIALIZED_NAME_BINARY_UUID = "binary_uuid"; @SerializedName(SERIALIZED_NAME_BINARY_UUID) - @javax.annotation.Nullable + @javax.annotation.Nonnull private String binaryUuid; public static final String SERIALIZED_NAME_CREATION = "creation"; @@ -294,7 +294,7 @@ public void setBinarySize(@javax.annotation.Nonnull Long binarySize) { } - public AnalysisBasicInfoOutputBody binaryUuid(@javax.annotation.Nullable String binaryUuid) { + public AnalysisBasicInfoOutputBody binaryUuid(@javax.annotation.Nonnull String binaryUuid) { this.binaryUuid = binaryUuid; return this; } @@ -303,12 +303,12 @@ public AnalysisBasicInfoOutputBody binaryUuid(@javax.annotation.Nullable String * UUID of the binary, omitted when not set * @return binaryUuid */ - @javax.annotation.Nullable + @javax.annotation.Nonnull public String getBinaryUuid() { return binaryUuid; } - public void setBinaryUuid(@javax.annotation.Nullable String binaryUuid) { + public void setBinaryUuid(@javax.annotation.Nonnull String binaryUuid) { this.binaryUuid = binaryUuid; } @@ -619,7 +619,7 @@ private String toIndentedString(Object o) { openapiFields = new HashSet(Arrays.asList("analysis_scope", "base_address", "binary_id", "binary_name", "binary_size", "binary_uuid", "creation", "debug", "function_count", "is_advanced", "is_owner", "is_system", "model_id", "model_name", "owner_username", "sequencer_version", "sha_256_hash", "team_id")); // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(Arrays.asList("analysis_scope", "base_address", "binary_id", "binary_name", "binary_size", "creation", "debug", "function_count", "is_advanced", "is_owner", "is_system", "model_id", "model_name", "owner_username", "sha_256_hash", "team_id")); + openapiRequiredFields = new HashSet(Arrays.asList("analysis_scope", "base_address", "binary_id", "binary_name", "binary_size", "binary_uuid", "creation", "debug", "function_count", "is_advanced", "is_owner", "is_system", "model_id", "model_name", "owner_username", "sha_256_hash", "team_id")); } /** @@ -658,7 +658,7 @@ public static void validateJsonElement(JsonElement jsonElement) throws IOExcepti if (!jsonObj.get("binary_name").isJsonPrimitive()) { throw new IllegalArgumentException(String.format(java.util.Locale.ROOT, "Expected the field `binary_name` to be a primitive type in the JSON string but got `%s`", jsonObj.get("binary_name").toString())); } - if ((jsonObj.get("binary_uuid") != null && !jsonObj.get("binary_uuid").isJsonNull()) && !jsonObj.get("binary_uuid").isJsonPrimitive()) { + if (!jsonObj.get("binary_uuid").isJsonPrimitive()) { throw new IllegalArgumentException(String.format(java.util.Locale.ROOT, "Expected the field `binary_uuid` to be a primitive type in the JSON string but got `%s`", jsonObj.get("binary_uuid").toString())); } if (!jsonObj.get("model_name").isJsonPrimitive()) { diff --git a/src/main/java/ai/reveng/model/DataTypesEntry.java b/src/main/java/ai/reveng/model/DataTypesEntry.java index 78e6aaf..a00c345 100644 --- a/src/main/java/ai/reveng/model/DataTypesEntry.java +++ b/src/main/java/ai/reveng/model/DataTypesEntry.java @@ -55,6 +55,11 @@ public class DataTypesEntry { @javax.annotation.Nullable private FunctionInfo dataTypes; + public static final String SERIALIZED_NAME_DATA_TYPES_VERSION = "data_types_version"; + @SerializedName(SERIALIZED_NAME_DATA_TYPES_VERSION) + @javax.annotation.Nonnull + private Long dataTypesVersion; + public static final String SERIALIZED_NAME_FUNCTION_ID = "function_id"; @SerializedName(SERIALIZED_NAME_FUNCTION_ID) @javax.annotation.Nonnull @@ -82,6 +87,25 @@ public void setDataTypes(@javax.annotation.Nullable FunctionInfo dataTypes) { } + public DataTypesEntry dataTypesVersion(@javax.annotation.Nonnull Long dataTypesVersion) { + this.dataTypesVersion = dataTypesVersion; + return this; + } + + /** + * Current version of the function data types. Pass this back on the next write to satisfy the CAS check. + * @return dataTypesVersion + */ + @javax.annotation.Nonnull + public Long getDataTypesVersion() { + return dataTypesVersion; + } + + public void setDataTypesVersion(@javax.annotation.Nonnull Long dataTypesVersion) { + this.dataTypesVersion = dataTypesVersion; + } + + public DataTypesEntry functionId(@javax.annotation.Nonnull Long functionId) { this.functionId = functionId; return this; @@ -112,12 +136,13 @@ public boolean equals(Object o) { } DataTypesEntry dataTypesEntry = (DataTypesEntry) o; return Objects.equals(this.dataTypes, dataTypesEntry.dataTypes) && + Objects.equals(this.dataTypesVersion, dataTypesEntry.dataTypesVersion) && Objects.equals(this.functionId, dataTypesEntry.functionId); } @Override public int hashCode() { - return Objects.hash(dataTypes, functionId); + return Objects.hash(dataTypes, dataTypesVersion, functionId); } @Override @@ -125,6 +150,7 @@ public String toString() { StringBuilder sb = new StringBuilder(); sb.append("class DataTypesEntry {\n"); sb.append(" dataTypes: ").append(toIndentedString(dataTypes)).append("\n"); + sb.append(" dataTypesVersion: ").append(toIndentedString(dataTypesVersion)).append("\n"); sb.append(" functionId: ").append(toIndentedString(functionId)).append("\n"); sb.append("}"); return sb.toString(); @@ -144,10 +170,10 @@ private String toIndentedString(Object o) { static { // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(Arrays.asList("data_types", "function_id")); + openapiFields = new HashSet(Arrays.asList("data_types", "data_types_version", "function_id")); // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(Arrays.asList("function_id")); + openapiRequiredFields = new HashSet(Arrays.asList("data_types_version", "function_id")); } /** diff --git a/src/main/java/ai/reveng/model/FunctionDetailsOutputBody.java b/src/main/java/ai/reveng/model/FunctionDetailsOutputBody.java index 557b807..fbd830e 100644 --- a/src/main/java/ai/reveng/model/FunctionDetailsOutputBody.java +++ b/src/main/java/ai/reveng/model/FunctionDetailsOutputBody.java @@ -50,6 +50,11 @@ */ @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") public class FunctionDetailsOutputBody { + public static final String SERIALIZED_NAME_ANALYSIS_ID = "analysis_id"; + @SerializedName(SERIALIZED_NAME_ANALYSIS_ID) + @javax.annotation.Nonnull + private Long analysisId; + public static final String SERIALIZED_NAME_BINARY_ID = "binary_id"; @SerializedName(SERIALIZED_NAME_BINARY_ID) @javax.annotation.Nonnull @@ -98,6 +103,25 @@ public class FunctionDetailsOutputBody { public FunctionDetailsOutputBody() { } + public FunctionDetailsOutputBody analysisId(@javax.annotation.Nonnull Long analysisId) { + this.analysisId = analysisId; + return this; + } + + /** + * Get analysisId + * @return analysisId + */ + @javax.annotation.Nonnull + public Long getAnalysisId() { + return analysisId; + } + + public void setAnalysisId(@javax.annotation.Nonnull Long analysisId) { + this.analysisId = analysisId; + } + + public FunctionDetailsOutputBody binaryId(@javax.annotation.Nonnull Long binaryId) { this.binaryId = binaryId; return this; @@ -279,7 +303,8 @@ public boolean equals(Object o) { return false; } FunctionDetailsOutputBody functionDetailsOutputBody = (FunctionDetailsOutputBody) o; - return Objects.equals(this.binaryId, functionDetailsOutputBody.binaryId) && + return Objects.equals(this.analysisId, functionDetailsOutputBody.analysisId) && + Objects.equals(this.binaryId, functionDetailsOutputBody.binaryId) && Objects.equals(this.creation, functionDetailsOutputBody.creation) && Objects.equals(this.debug, functionDetailsOutputBody.debug) && Objects.equals(this.functionId, functionDetailsOutputBody.functionId) && @@ -292,13 +317,14 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(binaryId, creation, debug, functionId, functionName, functionSize, functionVaddr, mangledName, sourceFunctionId); + return Objects.hash(analysisId, binaryId, creation, debug, functionId, functionName, functionSize, functionVaddr, mangledName, sourceFunctionId); } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("class FunctionDetailsOutputBody {\n"); + sb.append(" analysisId: ").append(toIndentedString(analysisId)).append("\n"); sb.append(" binaryId: ").append(toIndentedString(binaryId)).append("\n"); sb.append(" creation: ").append(toIndentedString(creation)).append("\n"); sb.append(" debug: ").append(toIndentedString(debug)).append("\n"); @@ -326,10 +352,10 @@ private String toIndentedString(Object o) { static { // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(Arrays.asList("binary_id", "creation", "debug", "function_id", "function_name", "function_size", "function_vaddr", "mangled_name", "source_function_id")); + openapiFields = new HashSet(Arrays.asList("analysis_id", "binary_id", "creation", "debug", "function_id", "function_name", "function_size", "function_vaddr", "mangled_name", "source_function_id")); // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(Arrays.asList("binary_id", "creation", "debug", "function_id", "function_name", "function_size", "function_vaddr")); + openapiRequiredFields = new HashSet(Arrays.asList("analysis_id", "binary_id", "creation", "debug", "function_id", "function_name", "function_size", "function_vaddr")); } /** diff --git a/src/main/java/ai/reveng/model/StartMatchingForFunctionsInputBody.java b/src/main/java/ai/reveng/model/StartMatchingForFunctionsInputBody.java index 36dbeca..780f757 100644 --- a/src/main/java/ai/reveng/model/StartMatchingForFunctionsInputBody.java +++ b/src/main/java/ai/reveng/model/StartMatchingForFunctionsInputBody.java @@ -72,6 +72,11 @@ public class StartMatchingForFunctionsInputBody { @javax.annotation.Nullable private Long resultsPerFunction; + public static final String SERIALIZED_NAME_USE_CANONICAL_NAMES = "use_canonical_names"; + @SerializedName(SERIALIZED_NAME_USE_CANONICAL_NAMES) + @javax.annotation.Nullable + private Boolean useCanonicalNames; + public StartMatchingForFunctionsInputBody() { } @@ -163,6 +168,69 @@ public void setResultsPerFunction(@javax.annotation.Nullable Long resultsPerFunc } + public StartMatchingForFunctionsInputBody useCanonicalNames(@javax.annotation.Nullable Boolean useCanonicalNames) { + this.useCanonicalNames = useCanonicalNames; + return this; + } + + /** + * Collapse near-duplicate candidate names into canonical buckets and return per-name confidences (the response 'confidences' array). Adds a canonicalisation step; defaults to false. + * @return useCanonicalNames + */ + @javax.annotation.Nullable + public Boolean getUseCanonicalNames() { + return useCanonicalNames; + } + + public void setUseCanonicalNames(@javax.annotation.Nullable Boolean useCanonicalNames) { + this.useCanonicalNames = useCanonicalNames; + } + + /** + * A container for additional, undeclared properties. + * This is a holder for any undeclared properties as specified with + * the 'additionalProperties' keyword in the OAS document. + */ + private Map additionalProperties; + + /** + * Set the additional (undeclared) property with the specified name and value. + * If the property does not already exist, create it otherwise replace it. + * + * @param key name of the property + * @param value value of the property + * @return the StartMatchingForFunctionsInputBody instance itself + */ + public StartMatchingForFunctionsInputBody putAdditionalProperty(String key, Object value) { + if (this.additionalProperties == null) { + this.additionalProperties = new HashMap(); + } + this.additionalProperties.put(key, value); + return this; + } + + /** + * Return the additional (undeclared) property. + * + * @return a map of objects + */ + public Map getAdditionalProperties() { + return additionalProperties; + } + + /** + * Return the additional (undeclared) property with the specified name. + * + * @param key name of the property + * @return an object + */ + public Object getAdditionalProperty(String key) { + if (this.additionalProperties == null) { + return null; + } + return this.additionalProperties.get(key); + } + @Override public boolean equals(Object o) { @@ -176,12 +244,14 @@ public boolean equals(Object o) { return Objects.equals(this.filters, startMatchingForFunctionsInputBody.filters) && Objects.equals(this.functionIds, startMatchingForFunctionsInputBody.functionIds) && Objects.equals(this.minSimilarity, startMatchingForFunctionsInputBody.minSimilarity) && - Objects.equals(this.resultsPerFunction, startMatchingForFunctionsInputBody.resultsPerFunction); + Objects.equals(this.resultsPerFunction, startMatchingForFunctionsInputBody.resultsPerFunction) && + Objects.equals(this.useCanonicalNames, startMatchingForFunctionsInputBody.useCanonicalNames)&& + Objects.equals(this.additionalProperties, startMatchingForFunctionsInputBody.additionalProperties); } @Override public int hashCode() { - return Objects.hash(filters, functionIds, minSimilarity, resultsPerFunction); + return Objects.hash(filters, functionIds, minSimilarity, resultsPerFunction, useCanonicalNames, additionalProperties); } @Override @@ -192,6 +262,8 @@ public String toString() { sb.append(" functionIds: ").append(toIndentedString(functionIds)).append("\n"); sb.append(" minSimilarity: ").append(toIndentedString(minSimilarity)).append("\n"); sb.append(" resultsPerFunction: ").append(toIndentedString(resultsPerFunction)).append("\n"); + sb.append(" useCanonicalNames: ").append(toIndentedString(useCanonicalNames)).append("\n"); + sb.append(" additionalProperties: ").append(toIndentedString(additionalProperties)).append("\n"); sb.append("}"); return sb.toString(); } @@ -210,7 +282,7 @@ private String toIndentedString(Object o) { static { // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(Arrays.asList("filters", "function_ids", "min_similarity", "results_per_function")); + openapiFields = new HashSet(Arrays.asList("filters", "function_ids", "min_similarity", "results_per_function", "use_canonical_names")); // a set of required properties/fields (JSON key names) openapiRequiredFields = new HashSet(Arrays.asList("function_ids")); @@ -229,14 +301,6 @@ public static void validateJsonElement(JsonElement jsonElement) throws IOExcepti } } - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Map.Entry entry : entries) { - if (!StartMatchingForFunctionsInputBody.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format(java.util.Locale.ROOT, "The field `%s` in the JSON string is not defined in the `StartMatchingForFunctionsInputBody` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - // check to make sure all required properties/fields are present in the JSON string for (String requiredField : StartMatchingForFunctionsInputBody.openapiRequiredFields) { if (jsonElement.getAsJsonObject().get(requiredField) == null) { @@ -271,6 +335,28 @@ public TypeAdapter create(Gson gson, TypeToken type) { @Override public void write(JsonWriter out, StartMatchingForFunctionsInputBody value) throws IOException { JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); + obj.remove("additionalProperties"); + // serialize additional properties + if (value.getAdditionalProperties() != null) { + for (Map.Entry entry : value.getAdditionalProperties().entrySet()) { + if (entry.getValue() instanceof String) + obj.addProperty(entry.getKey(), (String) entry.getValue()); + else if (entry.getValue() instanceof Number) + obj.addProperty(entry.getKey(), (Number) entry.getValue()); + else if (entry.getValue() instanceof Boolean) + obj.addProperty(entry.getKey(), (Boolean) entry.getValue()); + else if (entry.getValue() instanceof Character) + obj.addProperty(entry.getKey(), (Character) entry.getValue()); + else { + JsonElement jsonElement = gson.toJsonTree(entry.getValue()); + if (jsonElement.isJsonArray()) { + obj.add(entry.getKey(), jsonElement.getAsJsonArray()); + } else { + obj.add(entry.getKey(), jsonElement.getAsJsonObject()); + } + } + } + } elementAdapter.write(out, obj); } @@ -278,7 +364,28 @@ public void write(JsonWriter out, StartMatchingForFunctionsInputBody value) thro public StartMatchingForFunctionsInputBody read(JsonReader in) throws IOException { JsonElement jsonElement = elementAdapter.read(in); validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); + JsonObject jsonObj = jsonElement.getAsJsonObject(); + // store additional fields in the deserialized instance + StartMatchingForFunctionsInputBody instance = thisAdapter.fromJsonTree(jsonObj); + for (Map.Entry entry : jsonObj.entrySet()) { + if (!openapiFields.contains(entry.getKey())) { + if (entry.getValue().isJsonPrimitive()) { // primitive type + if (entry.getValue().getAsJsonPrimitive().isString()) + instance.putAdditionalProperty(entry.getKey(), entry.getValue().getAsString()); + else if (entry.getValue().getAsJsonPrimitive().isNumber()) + instance.putAdditionalProperty(entry.getKey(), entry.getValue().getAsNumber()); + else if (entry.getValue().getAsJsonPrimitive().isBoolean()) + instance.putAdditionalProperty(entry.getKey(), entry.getValue().getAsBoolean()); + else + throw new IllegalArgumentException(String.format(java.util.Locale.ROOT, "The field `%s` has unknown primitive type. Value: %s", entry.getKey(), entry.getValue().toString())); + } else if (entry.getValue().isJsonArray()) { + instance.putAdditionalProperty(entry.getKey(), gson.fromJson(entry.getValue(), List.class)); + } else { // JSON object + instance.putAdditionalProperty(entry.getKey(), gson.fromJson(entry.getValue(), HashMap.class)); + } + } + } + return instance; } }.nullSafe();