private MeshModel parseMigratedMeshModel(final JsonObject jsonObject) {
        final int modelId = jsonObject.get("mModelId").getAsInt();
        final MeshModel meshModel = getMeshModel(modelId);

        if (meshModel instanceof ConfigurationServerModel) {
            if (jsonObject.has("heartbeatPub")) {
                final JsonObject heartbeatPub = jsonObject.get("heartbeatPub").getAsJsonObject();
                final int destination;
                if (heartbeatPub.has("address") && !heartbeatPub.has("destination")) {
                    destination = heartbeatPub.get("address").getAsInt();
                } else {
                    destination = heartbeatPub.get("destination").getAsInt();
                }
                if (!isValidUnassignedAddress(destination)) {
                    final int countLog = heartbeatPub.get("count").getAsInt();
                    final int period = (heartbeatPub.get("period").getAsInt());
                    final int ttl = heartbeatPub.get("ttl").getAsInt();
                    final int index = heartbeatPub.get("index").getAsInt();

                    final JsonObject featuresJson = heartbeatPub.get("features").getAsJsonObject();
                    final Features features = new Features(featuresJson.get("friend").getAsInt(),
                            featuresJson.get("lowPower").getAsInt(),
                            featuresJson.get("relay").getAsInt(),
                            featuresJson.get("proxy").getAsInt());
                    ((ConfigurationServerModel) meshModel)
                            .setHeartbeatPublication(new HeartbeatPublication(destination, (byte) countLog,
                                    (byte) period, ttl, features, index));
                }
            }
            if (jsonObject.has("heartbeatSub")) {
                final JsonObject heartbeatSub = jsonObject.get("heartbeatSub").getAsJsonObject();
                final int source = heartbeatSub.get("source").getAsInt();
                final int destination;
                if (heartbeatSub.has("address") && !heartbeatSub.has("destination")) {
                    destination = heartbeatSub.get("address").getAsInt();
                } else {
                    destination = heartbeatSub.get("destination").getAsInt();
                }
                if (isValidUnassignedAddress(destination)) {
                    final int period = (heartbeatSub.get("period").getAsInt());
                    final int countLog = heartbeatSub.get("count").getAsInt();
                    final int minHops = heartbeatSub.get("minHops").getAsInt();
                    final int maxHops = heartbeatSub.get("maxHops").getAsInt();
                    ((ConfigurationServerModel) meshModel)
                            .setHeartbeatSubscription(new HeartbeatSubscription(source, destination, (byte) period,
                                    (byte) countLog, minHops, maxHops));
                }
            }
        }

        if (meshModel instanceof SceneServer) {
            if (jsonObject.has("sceneNumbers")) {
                final JsonArray scenesArray = jsonObject.get("sceneNumbers").getAsJsonArray();
                for (JsonElement element : scenesArray) {
                    meshModel.sceneNumbers.add(element.getAsInt());
                }
            }
        }

        final JsonArray jsonArrayBoundKeyIndexes = jsonObject.getAsJsonArray("mBoundAppKeyIndexes");
        for (int i = 0; i < jsonArrayBoundKeyIndexes.size(); i++) {
            final int index = jsonArrayBoundKeyIndexes.get(i).getAsInt();
            meshModel.mBoundAppKeyIndexes.add(index);
        }

        //We check if subscription address is a byte[] or not inorder to migrate the data without losing
        if (jsonObject.has("mSubscriptionAddress")) {
            final JsonArray addresses = jsonObject.getAsJsonArray("mSubscriptionAddress");
            if (addresses.size() > 0) {
                for (int i = 0; i < addresses.size(); i++) {
                    final JsonArray jsonArray = addresses.get(i).getAsJsonArray();
                    final int address = MeshParserUtils.unsignedBytesToInt(jsonArray.get(1).getAsByte(),
                            jsonArray.get(0).getAsByte());
                    meshModel.addSubscriptionAddress(address);
                }
            }
        }

        if (jsonObject.has("labelUuids")) {
            final JsonArray labelUuids = jsonObject.get("labelUuids").getAsJsonArray();
            for (int i = 0; i < labelUuids.size(); i++) {
                final String hexUuid = labelUuids.get(i).getAsString().toUpperCase(Locale.US);
                final UUID uuid = UUID.fromString(hexUuid);
                if (uuid != null)
                    meshModel.labelUuids.add(uuid);
            }
        }

        if (jsonObject.has("subscriptionAddresses")) {
            final JsonArray addresses = jsonObject.get("subscriptionAddresses").getAsJsonArray();
            if (addresses != null) {
                for (int i = 0; i < addresses.size(); i++) {
                    meshModel.addSubscriptionAddress(addresses.get(i).getAsInt());
                }
            }
        }

        if (jsonObject.getAsJsonObject().has("mPublicationSettings")) {
            final JsonObject jsonPublicationSettings = jsonObject.get("mPublicationSettings").getAsJsonObject();
            if (jsonPublicationSettings != null) {
                final int appKeyIndex = jsonPublicationSettings.get("appKeyIndex").getAsInt();
                final boolean credentialFlag = jsonPublicationSettings.get("credentialFlag").getAsBoolean();
                final int publicationResolution = jsonPublicationSettings.get("publicationResolution").getAsInt();
                final int publicationSteps = jsonPublicationSettings.get("publicationSteps").getAsInt();

                if (jsonPublicationSettings.has("publishAddress")) {
                    final int publishAddress;
                    UUID labelUUID = null;
                    final JsonElement jsonElement = jsonPublicationSettings.get("publishAddress");
                    //We check if publish address is a byte[] or not inorder to migrate avoiding data loss
                    if (jsonElement.isJsonArray()) {
                        final JsonArray jsonPublishAddress = jsonElement.getAsJsonArray();
                        final byte[] address = new byte[jsonPublishAddress.size()];
                        for (int i = 0; i < jsonPublishAddress.size(); i++) {
                            address[i] = jsonPublishAddress.get(i).getAsByte();
                        }
                        publishAddress = MeshParserUtils.unsignedBytesToInt(address[1], address[0]);
                    } else {
                        publishAddress = jsonElement.getAsInt();
                    }
                    if (isValidUnassignedAddress(publishAddress))
                        return meshModel;

                    if (jsonPublicationSettings.has("labelUUID")) {
                        final String uuid = jsonPublicationSettings.get("labelUUID").getAsString();
                        labelUUID = UUID.fromString(uuid);
                    }

                    final int publishRetransmitCount = jsonPublicationSettings.get("publishRetransmitCount").getAsInt();
                    final int publishRetransmitIntervalSteps = jsonPublicationSettings.get("publishRetransmitIntervalSteps").getAsInt();
                    final int publishTtl = jsonPublicationSettings.get("publishTtl").getAsByte();
                    meshModel.mPublicationSettings = new PublicationSettings(publishAddress,
                            appKeyIndex, credentialFlag, publishTtl, publicationSteps,
                            publicationResolution, publishRetransmitCount, publishRetransmitIntervalSteps);
                    meshModel.mPublicationSettings.setLabelUUID(labelUUID);
                }
            }
        }
        return meshModel;
    }
Parses migrated mesh model data

@param jsonObject jsonObject
mesh/src/main/java/no/nordicsemi/android/mesh/transport/InternalMeshModelDeserializer.java