       return matched.contains(where: { $0.typedFullID == resource.typedFullID }) ? nil : resource
     }
 
-    var wrapperPackages: [Package] = []
+    // Temporary:  this method may be called after the initial migration to 'migrate'
+    //             freshly-downloaded resources.  We should double-check our wrapper
+    //             kmp.jsons and reuse them if appropriate.
+    //
+    //             Once the cloud-JS => KMP conversion is done, a simple `[]` initialization
+    //             will suffice.
+    var wrapperPackages: [Package] = localPackages.compactMap { package in
+      // We only consider appending resources to existing kmp.jsons if the kmp.jsons were
+      // produced during resource migration.  We don't alter Developer-compiled kmp.jsons.
+      if package.metadata.isAutogeneratedWrapper {
+        return package
+      } else {
+        return nil
+      }
+    }
+
     for resource in unmatched {
       // Did we already build a matching wrapper package?
       let packageMatches = wrapperPackages.compactMap { package in
         return package.findMetadataMatchFor(resource: resource, ignoreLanguage: true)
       }
+
       if packageMatches.count > 0 {
         // We did!  Add this resource to the existing metadata object.
         var resourceMetadata = packageMatches[0]

      let dstLocation = Storage.active.resourceURL(for: resource)!

      do {
        try FileManager.default.moveItem(at: srcLocation, to: dstLocation)
      } catch {
        log.error("Could not remove version number from filename for resource \(resource.packageID ?? "<no package>").\(resource.id)")
        log.error("Source: \(srcLocation)")

  }

  static func migrateCloudResourcesToKMPFormat() throws {
    let userDefaults = Storage.active.userDefaults

    if var userKeyboards = userDefaults.userKeyboards {
      userKeyboards = migrateToKMPFormat(userKeyboards)
      userDefaults.userKeyboards = userKeyboards
    }

    if var userLexicalModels = userDefaults.userLexicalModels {
      userLexicalModels = migrateToKMPFormat(userLexicalModels)
      userDefaults.userLexicalModels = userLexicalModels
    }
  }

  static func migrateToKMPFormat<Resource, Package: TypedKeymanPackage<Resource>>(
        _ resources: [Resource]) -> [Resource]
        where Resource: KMPInitializableLanguageResource,
              Resource == Resource.Metadata.LanguageResourceType {
    // Step 1 - analyze all locally-cached KMPs for possible resource sources.
    var allLocalPackages: [KeymanPackage] = []
    do {
      let cachedKMPsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
      let files = try FileManager.default.contentsOfDirectory(atPath: cachedKMPsDirectory.path)
      let kmpFiles = files.filter { $0.suffix(4) == ".kmp" }

      allLocalPackages = kmpFiles.compactMap { file in
        let filePath = cachedKMPsDirectory.appendingPathComponent(file)
        do {
          return try ResourceFileManager.shared.prepareKMPInstall(from: filePath)
        } catch {
          log.error("Error occurred when processing existing packages during cloud -> KMP migration: \(String(describing: error))")
          return nil as KeymanPackage?
        }
      }
    } catch {
      log.error("Could not check contents of Documents directory for resource-migration assist")
    }

    // Filters out Packages that don't contain the matching resource type.
    let localPackages = allLocalPackages.compactMap { return $0 as? Package }

    // Step 2 - drop version numbers from all filenames.  KMP installations don't include them, and
    // the version numbered filenames will actually interfere with migration.
    resources.forEach { resource in
