public void checkUpgrade(Context context, NetworkParameters params) {
    if (checkDone) {
      // skip if already done
      return;
    }

    String appVersion = SharedPrefUtils.getAppVersion(context);
    if (appVersion == null) {
      // first start - no app version yet.
      Log.d(TAG, "No appVersion yet - first launch");
    } else if (appVersion.equals(BuildConfig.VERSION_NAME)) {
      Log.d(TAG, "appVersion '" + appVersion + "' equals current version - no action required");
    } else {
      // add upgrade instructions as needed.
    }

    if (migrateFrom_v1_0_262(context)) {
      Log.d(TAG, "Migrate from v1.0.262 / 2of2 multisig (CeBIT) to CLTV");
      /* special case: migrate from objectstore and 2of2 multisig wallet
       * - migrate from early version v1.0.262 (CeBIT)
       * - enable transfer of funds to new address (2of2 multisig to cltv)
       */
      try {
        // migration is done for mainnet and testnet regardless of the current network setting of
        // the app!
        NetworkParameters[] cltvMigrationParams =
            new NetworkParameters[] {MainNetParams.get(), TestNet3Params.get()};
        for (NetworkParameters migrationParams : cltvMigrationParams) {
          doMigrateFrom_v1_0_262(context, migrationParams);
        }
      } catch (Exception e) {
        Log.e(TAG, "Migration failed: ", e);
      }
    }

    SharedPrefUtils.setAppVersion(context, BuildConfig.VERSION_NAME);
    checkDone = true;
  }
  private void doMigrateFrom_v1_0_262(Context context, NetworkParameters migrationParams)
      throws IOException {
    Log.d(TAG, "********* MIGRATION FROM v1.0.262 - " + migrationParams.getId() + "*********");

    final File rootDir = context.getFilesDir();
    final File storageDir;
    final File archiveDir = new File(rootDir, "archive_" + System.currentTimeMillis());
    final File walletFile;
    final File chainFile;

    final File newWalletFile;
    final File newChainFile;

    if (ClientUtils.isMainNet(migrationParams)) {
      String walletFilesPrefix = AppConfig.MainNetConfig.get().getWalletFilesPrefix();
      storageDir = new File(rootDir, "mainnet_wallet__uuid_object_storage");
      walletFile = new File(rootDir, "mainnet_wallet_.wallet");
      newWalletFile = new File(rootDir, walletFilesPrefix + ".wallet");
      chainFile = new File(rootDir, "mainnet_wallet_.spvchain");
      newChainFile = new File(rootDir, walletFilesPrefix + ".spvchain");
    } else if (ClientUtils.isTestNet(migrationParams)) {
      String walletFilesPrefix = AppConfig.TestNetConfig.get().getWalletFilesPrefix();
      storageDir = new File(rootDir, "testnet_wallet__uuid_object_storage");
      walletFile = new File(rootDir, "testnet_wallet_.wallet");
      newWalletFile = new File(rootDir, walletFilesPrefix + ".wallet");
      chainFile = new File(rootDir, "testnet_wallet_.spvchain");
      newChainFile = new File(rootDir, walletFilesPrefix + ".spvchain");
    } else {
      throw new RuntimeException(
          "Network params not supported (unknown): " + migrationParams.toString());
    }

    final File keyFile = new File(storageDir, "ECKeyWrapper.json");

    if (keyFile.exists() && walletFile.exists()) {

      // Keys: stored in ECKeyWrapper.json
      /* Key format (JSON):
        {
          "...uuid1...": {
              "isPublicOnly": true,
              "keyPayload": [...bytes (integers)...],
              "name": "remote_server_public_key",
              "uuid": "...uuid1..."
          },
          "...uuid2...": {
              "isPublicOnly": false,
              "keyPayload": [...bytes (integers)...],
              "name": "remote_client_public_key",
              "uuid": "...uuid2..."
          }
        }
      */

      Log.d(TAG, "Key file found: " + keyFile);
      String keyFileJson = FileUtils.readFileToString(keyFile);
      Type type = new TypeToken<Map<String, ECKeyWrapper>>() {}.getType();
      // Note: do not use gson from serializeutils (key is not stored in base64).
      Map<String, ECKeyWrapper> keys = new Gson().fromJson(keyFileJson, type);
      ECKey serverKey = null;
      ECKey clientKey = null;
      for (ECKeyWrapper key : keys.values()) {
        if (key.isPublicOnly && key.name.equals("remote_server_public_key")) {
          serverKey = ECKey.fromPublicOnly(key.keyPayload);
        } else if (!key.isPublicOnly && key.name.equals("remote_client_public_key")) {
          clientKey = ECKey.fromPrivate(key.keyPayload);
        } else {
          Log.d(TAG, "Unknown key name: " + key.name);
        }
      }

      if (clientKey != null && serverKey != null) {
        Log.d(TAG, "Found client and server keys - store in shared preferences.");
        try {

          /** ******** Actual Migration Code ********* */
          SharedPrefUtils.setClientKey(context, migrationParams, clientKey);
          SharedPrefUtils.setServerKey(context, migrationParams, serverKey, "n/a - migration");
          Log.d(
              TAG,
              "Migrated keys:"
                  + " clientPubKey="
                  + clientKey.getPublicKeyAsHex()
                  + ", serverPubKey="
                  + serverKey.getPublicKeyAsHex());

          // move wallet file
          Log.d(
              TAG,
              "Migrate wallet file: " + walletFile.toString() + " -> " + newWalletFile.toString());
          FileUtils.copyFile(walletFile, newWalletFile);
          Log.d(
              TAG,
              "Migrate chain file: " + chainFile.toString() + " -> " + newChainFile.toString());
          FileUtils.copyFile(chainFile, newChainFile);

          SharedPrefUtils.enableMultisig2of2ToCltvForwarder(context);

          // move everything to an archive file.
          Log.d(TAG, "Move old files to archive dir: " + archiveDir.toString());
          FileUtils.moveToDirectory(storageDir, archiveDir, true);
          FileUtils.moveToDirectory(walletFile, archiveDir, true);
          FileUtils.moveToDirectory(chainFile, archiveDir, true);

        } catch (Exception e) {
          Log.d(TAG, "Exception: ", e);
          // clear the changes made.
          SharedPrefUtils.setClientKey(context, migrationParams, null);
          SharedPrefUtils.setServerKey(context, migrationParams, null, "");
          if (newWalletFile.exists()) {
            newWalletFile.delete();
          }
        }
      }
    } else {
      Log.d(
          TAG,
          "Key file or wallet file not found - no migration required - "
              + String.format(
                  "keyFile: %s (exists: %s), walletFile: %s (exists: %s)",
                  keyFile.toString(),
                  keyFile.exists(),
                  walletFile.toString(),
                  walletFile.exists()));
    }

    Log.d(TAG, "********* MIGRATION FROM v1.0.262 FINISHED *********");
  }