Improvements in Jetifier.

Cleaned up standalone tool API
- We no longer have option for providing multiple files or specifing
  output directory. So the tool now supports only file to file conversion.
  I found the origal approach to be a bit ambiguous and also we never
  actually used it it was just part of the initialdesign.
- DependencyVersionsMap is now part of the config file instead of being
  in the code. This allows more flexibility when providing custom config file
  and enables last minute fixes.

Bug: 64833662
Test: Updated
Change-Id: I475e74a2f6c5e61c3b3dec5d1bcc9c41ff2fee9b
diff --git a/buildSrc/jetify.gradle b/buildSrc/jetify.gradle
index f908c56..2348117 100644
--- a/buildSrc/jetify.gradle
+++ b/buildSrc/jetify.gradle
@@ -75,5 +75,13 @@
 
     outputs.file "${rootProject.ext.distDir}/top-of-tree-m2repository-dejetified-${project.ext.buildNumber}.zip"
 
-    commandLine ("${jetifierBin}", "-s", "-r", "-outputfile", "${outputs.files.singleFile}",  "-i", "${inputs.files.singleFile}", "-l", "error", "-rebuildTopOfTree")
+    commandLine (
+        "${jetifierBin}",
+        "-i", "${inputs.files.singleFile}",
+        "-o", "${outputs.files.singleFile}",
+        "--versions", "inDev",
+        "--log", "warning",
+        "--reversed",
+        "--rebuildTopOfTree"
+    )
 }
diff --git a/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/config/Config.kt b/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/config/Config.kt
index 1f1d918..a59b619 100644
--- a/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/config/Config.kt
+++ b/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/config/Config.kt
@@ -17,6 +17,7 @@
 package com.android.tools.build.jetifier.core.config
 
 import com.android.tools.build.jetifier.core.PackageMap
+import com.android.tools.build.jetifier.core.pom.DependencyVersionsMap
 import com.android.tools.build.jetifier.core.pom.PomRewriteRule
 import com.android.tools.build.jetifier.core.proguard.ProGuardType
 import com.android.tools.build.jetifier.core.proguard.ProGuardTypesMap
@@ -37,6 +38,8 @@
  * ignore packages that don't need rewriting anymore.
  * [pomRewriteRules] Rules to rewrite POM files
  * [typesMap] Map of all java types and fields to be used to rewrite libraries.
+ * [proGuardMap] Proguard types map to be used for ProGuard files rewriting.
+ * [versionsMap] Pre-defined maps of versions to be substituted in pom dependency rules.
  * [packageMap] Package map to be used to rewrite packages, used only during the support library
  * rewrite.
  */
@@ -47,6 +50,7 @@
     val pomRewriteRules: Set<PomRewriteRule>,
     val typesMap: TypesMap,
     val proGuardMap: ProGuardTypesMap,
+    val versionsMap: DependencyVersionsMap,
     val packageMap: PackageMap = PackageMap(PackageMap.DEFAULT_RULES)
 ) {
 
@@ -63,29 +67,43 @@
 
     // Merges all packages prefixes into one regEx pattern
     val packagePrefixPattern = Pattern.compile(
-            "^(" + restrictToPackagePrefixes.map { "($it)" }.joinToString("|") + ").*$")
+        "^(" + restrictToPackagePrefixes.map { "($it)" }.joinToString("|") + ").*$")
 
     val restrictToPackagePrefixesWithDots: List<String> = restrictToPackagePrefixes
-            .map { it.replace("/", ".") }
+        .map { it.replace("/", ".") }
 
     companion object {
         /** Path to the default config file located within the jar file. */
         const val DEFAULT_CONFIG_RES_PATH = "/default.generated.config"
 
-        val EMPTY = Config(
-            restrictToPackagePrefixes = emptySet(),
-            rulesMap = RewriteRulesMap.EMPTY,
-            slRules = emptyList(),
-            pomRewriteRules = emptySet(),
-            typesMap = TypesMap.EMPTY,
-            proGuardMap = ProGuardTypesMap.EMPTY,
-            packageMap = PackageMap.EMPTY
-        )
+        val EMPTY = fromOptional()
+
+        fun fromOptional(
+            restrictToPackagePrefixes: Set<String> = emptySet(),
+            rulesMap: RewriteRulesMap = RewriteRulesMap.EMPTY,
+            slRules: List<RewriteRule> = emptyList(),
+            pomRewriteRules: Set<PomRewriteRule> = emptySet(),
+            typesMap: TypesMap = TypesMap.EMPTY,
+            proGuardMap: ProGuardTypesMap = ProGuardTypesMap.EMPTY,
+            versionsMap: DependencyVersionsMap = DependencyVersionsMap.EMPTY,
+            packageMap: PackageMap = PackageMap.EMPTY
+        ): Config {
+            return Config(
+                restrictToPackagePrefixes = restrictToPackagePrefixes,
+                rulesMap = rulesMap,
+                slRules = slRules,
+                pomRewriteRules = pomRewriteRules,
+                typesMap = typesMap,
+                proGuardMap = proGuardMap,
+                versionsMap = versionsMap,
+                packageMap = packageMap
+            )
+        }
     }
 
     fun setNewMap(mappings: TypesMap): Config {
         return Config(restrictToPackagePrefixes, rulesMap, slRules, pomRewriteRules,
-            mappings, proGuardMap)
+            mappings, proGuardMap, versionsMap, packageMap)
     }
 
     /**
@@ -148,6 +166,7 @@
             rulesMap.toJson().rules.toList(),
             slRules.map { it.toJson() }.toList(),
             pomRewriteRules.map { it.toJson() }.toList(),
+            versionsMap.data,
             typesMap.toJson(),
             proGuardMap.toJson()
         )
@@ -157,33 +176,41 @@
      * JSON data model for [Config].
      */
     data class JsonData(
-            @SerializedName("restrictToPackagePrefixes")
-            val restrictToPackages: List<String?>,
+        @SerializedName("restrictToPackagePrefixes")
+        val restrictToPackages: List<String?>,
 
-            @SerializedName("rules")
-            val rules: List<RewriteRule.JsonData?>?,
+        @SerializedName("rules")
+        val rules: List<RewriteRule.JsonData?>?,
 
-            @SerializedName("slRules")
-            val slRules: List<RewriteRule.JsonData?>?,
+        @SerializedName("slRules")
+        val slRules: List<RewriteRule.JsonData?>?,
 
-            @SerializedName("pomRules")
-            val pomRules: List<PomRewriteRule.JsonData?>,
+        @SerializedName("pomRules")
+        val pomRules: List<PomRewriteRule.JsonData?>,
 
-            @SerializedName("map")
-            val mappings: TypesMap.JsonData? = null,
+        @SerializedName("versions")
+        val versions: Map<String, Map<String, String>>? = null,
 
-            @SerializedName("proGuardMap")
-            val proGuardMap: ProGuardTypesMap.JsonData? = null
+        @SerializedName("map")
+        val mappings: TypesMap.JsonData? = null,
+
+        @SerializedName("proGuardMap")
+        val proGuardMap: ProGuardTypesMap.JsonData? = null
     ) {
         /** Creates instance of [Config] */
         fun toConfig(): Config {
-
             return Config(
                 restrictToPackagePrefixes = restrictToPackages.filterNotNull().toSet(),
-                rulesMap = RewriteRulesMap(
-                    rules?.filterNotNull()?.map { it.toRule() }?.toList() ?: emptyList()),
-                slRules = slRules?.filterNotNull()?.map { it.toRule() }?.toList() ?: emptyList(),
+                rulesMap = rules
+                    ?.let { RewriteRulesMap(it.filterNotNull().map { it.toRule() }.toList()) }
+                    ?: RewriteRulesMap.EMPTY,
+                slRules = slRules
+                    ?.let { it.filterNotNull().map { it.toRule() }.toList() }
+                    ?: emptyList(),
                 pomRewriteRules = pomRules.filterNotNull().map { it.toRule() }.toSet(),
+                versionsMap = versions
+                    ?.let { DependencyVersionsMap(versions) }
+                    ?: DependencyVersionsMap.EMPTY,
                 typesMap = mappings?.toMappings() ?: TypesMap.EMPTY,
                 proGuardMap = proGuardMap?.toMappings() ?: ProGuardTypesMap.EMPTY
             )
diff --git a/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/pom/DependencyVersions.kt b/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/pom/DependencyVersions.kt
new file mode 100644
index 0000000..a1e6fa8
--- /dev/null
+++ b/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/pom/DependencyVersions.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.build.jetifier.core.pom
+
+/**
+ * Map that provides extra configuration for versions of dependencies generated by Jetifier.
+ */
+data class DependencyVersions(private val currentSet: Map<String, String>) {
+
+    companion object {
+
+        val EMPTY = DependencyVersions(emptyMap())
+
+        const val DATA_BINDING_VAR_NAME = "newDataBindingVersion"
+
+        private const val DEFAULT_DEPENDENCY_SET = "latestReleased"
+
+        fun parseFromVersionSetTypeId(
+            versionsMap: DependencyVersionsMap,
+            versionSetType: String?
+        ): DependencyVersions {
+            val name = versionSetType ?: DEFAULT_DEPENDENCY_SET
+
+            if (versionsMap.data.isEmpty()) {
+                return DependencyVersions(emptyMap())
+            }
+
+            val map = versionsMap.data[name]
+            if (map == null) {
+                throw IllegalArgumentException("The given versions map is invalid as it does not " +
+                    "contain version set called '$name' or maybe you passed incorrect version " +
+                    "set identifier?")
+            }
+
+            return DependencyVersions(map)
+        }
+    }
+
+    /**
+     * Puts the given version into the map to be referred to using the given variable name.
+     *
+     * Ignored if null is given.
+     *
+     * @param newVersion New version to be put into the map
+     * @param forVariable Then name of the variable to be used to refer to the version
+     */
+    fun replaceVersionIfAny(forVariable: String, newVersion: String?): DependencyVersions {
+        newVersion ?: return this
+
+        val temp = currentSet.toMutableMap()
+        temp[forVariable] = newVersion
+        return DependencyVersions(temp)
+    }
+
+    /** Takes a version from a configuration file and rewrites any variables related to the map. */
+    fun applyOnVersionRef(version: String): String {
+        if (version.matches(Regex("^\\{[a-zA-Z0-9]+\\}$"))) {
+            val variableName = version.removePrefix("{").removeSuffix("}")
+            return currentSet[variableName]
+                ?: throw IllegalArgumentException(
+                    "The version variable '$variableName' was not found")
+        }
+
+        return version
+    }
+
+    fun applyOnConfigPomDep(dep: PomDependency): PomDependency {
+        return PomDependency(
+            groupId = dep.groupId,
+            artifactId = dep.artifactId,
+            version = applyOnVersionRef(dep.version!!))
+    }
+}
\ No newline at end of file
diff --git a/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/pom/DependencyVersionsMap.kt b/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/pom/DependencyVersionsMap.kt
index 99f1024..e8e8d4e 100644
--- a/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/pom/DependencyVersionsMap.kt
+++ b/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/pom/DependencyVersionsMap.kt
@@ -17,104 +17,13 @@
 package com.android.tools.build.jetifier.core.pom
 
 /**
- * Map that provides extra configuration for versions of dependencies generated by Jetifier.
+ * Contains sets of mappings for dependency version variables.
+ *
+ * E.g. alpha1 => { newSlVersion: 1.0.0-alpha1, newArchVersion: 2.0.0-alpha1 }
  */
-data class DependencyVersionsMap(
-        private val oldSlVersion: String = "",
-        private val oldMaterialVersion: String = "",
-        private val oldRoomVersion: String = "",
-        private val newSlVersion: String = "",
-        private val newMaterialVersion: String = "",
-        private val newArchCoreVersion: String = "",
-        private val newLifecycleVersion: String = "",
-        private val newPagingVersion: String = "",
-        private val newRoomVersion: String = "",
-        private val newEspressoVersion: String = "",
-        private val newTestsVersion: String = "",
-        private val newJankTestHelperVersion: String = "",
-        private val newUiAutomatorVersion: String = "",
-        private var newDataBindingVersion: String = ""
-    ) {
+data class DependencyVersionsMap(val data: Map<String, Map<String, String>>) {
 
     companion object {
-
-        val LATEST = DependencyVersionsMap(
-            oldSlVersion = "28.0.0",
-            oldMaterialVersion = "28.0.0-alpha1",
-            oldRoomVersion = "1.1.0",
-            newSlVersion="1.0.0",
-            newMaterialVersion = "1.0.0-alpha1",
-            newArchCoreVersion = "2.0.0",
-            newLifecycleVersion = "2.0.0",
-            newPagingVersion = "2.0.0",
-            newRoomVersion = "2.0.0",
-            newEspressoVersion = "3.1.0-alpha2",
-            newTestsVersion = "1.1.0-alpha2",
-            newJankTestHelperVersion = "1.0.1-alpha1",
-            newUiAutomatorVersion = "2.2.0-alpha1",
-            newDataBindingVersion = "undefined"
-        )
-
-        val ALPHA1 = DependencyVersionsMap(
-            oldSlVersion = "28.0.0-alpha1",
-            oldMaterialVersion = "28.0.0-alpha1",
-            oldRoomVersion = "1.1.0",
-            newSlVersion="1.0.0-alpha1",
-            newMaterialVersion = "1.0.0-alpha1",
-            newArchCoreVersion = "2.0.0-alpha1",
-            newLifecycleVersion = "2.0.0-alpha1",
-            newPagingVersion = "2.0.0-alpha1",
-            newRoomVersion = "2.0.0-alpha1",
-            newEspressoVersion = "3.1.0-alpha2",
-            newTestsVersion = "1.1.0-alpha2",
-            newJankTestHelperVersion = "1.0.1-alpha1",
-            newUiAutomatorVersion = "2.2.0-alpha1",
-            newDataBindingVersion = "undefined"
-        )
-
-        val LATEST_RELEASED = ALPHA1
-
-        fun parseFromVersionSetTypeId(versionSetType: String?): DependencyVersionsMap {
-            versionSetType ?: return DependencyVersionsMap.LATEST
-
-            return when (versionSetType) {
-                "alpha1" -> DependencyVersionsMap.ALPHA1
-                "latest" -> DependencyVersionsMap.LATEST
-                else -> throw IllegalArgumentException(
-                    "Version set type contains unsupported version set '$versionSetType'")
-            }
-        }
-    }
-
-    fun setDataBindingVersion(dataBindingVersion: String) {
-        newDataBindingVersion = dataBindingVersion
-    }
-
-    /** Takes a version from a configuration file and rewrites any variables related to the map. */
-    fun applyOnVersionRef(version: String): String {
-        return when (version) {
-            "{oldSlVersion}" -> oldSlVersion
-            "{oldMaterialVersion}" -> oldMaterialVersion
-            "{oldRoomVersion}" -> oldRoomVersion
-            "{newSlVersion}" -> newSlVersion
-            "{newMaterialVersion}" -> newMaterialVersion
-            "{newArchCoreVersion}" -> newArchCoreVersion
-            "{newLifecycleVersion}" -> newLifecycleVersion
-            "{newPagingVersion}" -> newPagingVersion
-            "{newRoomVersion}" -> newRoomVersion
-            "{newEspressoVersion}" -> newEspressoVersion
-            "{newTestsVersion}" -> newTestsVersion
-            "{newJankTestHelperVersion}" -> newJankTestHelperVersion
-            "{newUiAutomatorVersion}" -> newUiAutomatorVersion
-            "{newDataBindingVersion}" -> newDataBindingVersion
-            else -> version
-        }
-    }
-
-    fun applyOnConfigPomDep(dep: PomDependency): PomDependency {
-        return PomDependency(
-            groupId = dep.groupId,
-            artifactId = dep.artifactId,
-            version = applyOnVersionRef(dep.version!!))
+        val EMPTY = DependencyVersionsMap(emptyMap())
     }
 }
\ No newline at end of file
diff --git a/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/pom/PomDependency.kt b/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/pom/PomDependency.kt
index 403961c..56e0f29 100644
--- a/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/pom/PomDependency.kt
+++ b/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/pom/PomDependency.kt
@@ -52,10 +52,10 @@
      * Returns a new dependency created by taking all the items from the [input] dependency and then
      * overwriting these with all of its non-null items.
      */
-    fun rewrite(input: PomDependency, versionsMap: DependencyVersionsMap): PomDependency {
+    fun rewrite(input: PomDependency, versions: DependencyVersions): PomDependency {
         var newVersion = input.version
         if (version != null) {
-            newVersion = versionsMap.applyOnVersionRef(version!!)
+            newVersion = versions.applyOnVersionRef(version!!)
         }
 
         return PomDependency(
diff --git a/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/utils/LogLevel.kt b/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/utils/LogLevel.kt
index 053e77a..bb63dbf 100644
--- a/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/utils/LogLevel.kt
+++ b/jetifier/jetifier/core/src/main/kotlin/com/android/tools/build/jetifier/core/utils/LogLevel.kt
@@ -20,6 +20,5 @@
     ERROR(0),
     WARNING(1),
     INFO(2),
-    VERBOSE(3),
-    DEBUG(4),
+    VERBOSE(3)
 }
\ No newline at end of file
diff --git a/jetifier/jetifier/core/src/main/resources/default.config b/jetifier/jetifier/core/src/main/resources/default.config
index fdf8633..eb7409f 100644
--- a/jetifier/jetifier/core/src/main/resources/default.config
+++ b/jetifier/jetifier/core/src/main/resources/default.config
@@ -1428,8 +1428,43 @@
         {
             "from": { "groupId": "com.google.dagger", "artifactId": "dagger-android-processor", "version": "2.16" },
             "to": { "groupId": "com.google.dagger", "artifactId": "dagger-android-processor", "version": "2.16" }
-        }
+        },
     ],
+    "versions": {
+        "inDev": {
+            "oldSlVersion": "28.0.0",
+            "oldMaterialVersion": "28.0.0-alpha1",
+            "oldRoomVersion": "1.1.0",
+            "newSlVersion": "1.0.0",
+            "newMaterialVersion": "1.0.0-alpha1",
+            "newArchCoreVersion": "2.0.0",
+            "newLifecycleVersion": "2.0.0",
+            "newPagingVersion": "2.0.0",
+            "newRoomVersion": "2.0.0",
+            "newEspressoVersion": "3.1.0-alpha2",
+            "newTestsVersion": "1.1.0-alpha2",
+            "newJankTestHelperVersion": "1.0.1-alpha1",
+            "newUiAutomatorVersion": "2.2.0-alpha1",
+            "newDataBindingVersion": "undefined"
+        },
+        "latestReleased": {
+            "oldSlVersion": "28.0.0-alpha1",
+            "oldMaterialVersion": "28.0.0-alpha1",
+            "oldRoomVersion": "1.1.0",
+            "newSlVersion": "1.0.0-alpha1",
+            "newMaterialVersion": "1.0.0-alpha1",
+            "newArchCoreVersion": "2.0.0-alpha1",
+            "newLifecycleVersion": "2.0.0-alpha1",
+            "newPagingVersion": "2.0.0-alpha1",
+            "newRoomVersion": "2.0.0-alpha1",
+            "newEspressoVersion": "3.1.0-alpha2",
+            "newTestsVersion": "1.1.0-alpha2",
+            "newJankTestHelperVersion": "1.0.1-alpha1",
+            "newUiAutomatorVersion": "2.2.0-alpha1",
+            "newDataBindingVersion": "undefined"
+        }
+    },
+    # Manual fallback types map
     "map": {
         # Types added in 28.0.0 (missing in 27.1.0)
         "types": {
diff --git a/jetifier/jetifier/core/src/main/resources/default.generated.config b/jetifier/jetifier/core/src/main/resources/default.generated.config
index fd91886..9377a61 100644
--- a/jetifier/jetifier/core/src/main/resources/default.generated.config
+++ b/jetifier/jetifier/core/src/main/resources/default.generated.config
@@ -2224,6 +2224,40 @@
       }
     }
   ],
+  "versions": {
+    "inDev": {
+      "oldSlVersion": "28.0.0",
+      "oldMaterialVersion": "28.0.0-alpha1",
+      "oldRoomVersion": "1.1.0",
+      "newSlVersion": "1.0.0",
+      "newMaterialVersion": "1.0.0-alpha1",
+      "newArchCoreVersion": "2.0.0",
+      "newLifecycleVersion": "2.0.0",
+      "newPagingVersion": "2.0.0",
+      "newRoomVersion": "2.0.0",
+      "newEspressoVersion": "3.1.0-alpha2",
+      "newTestsVersion": "1.1.0-alpha2",
+      "newJankTestHelperVersion": "1.0.1-alpha1",
+      "newUiAutomatorVersion": "2.2.0-alpha1",
+      "newDataBindingVersion": "undefined"
+    },
+    "latestReleased": {
+      "oldSlVersion": "28.0.0-alpha1",
+      "oldMaterialVersion": "28.0.0-alpha1",
+      "oldRoomVersion": "1.1.0",
+      "newSlVersion": "1.0.0-alpha1",
+      "newMaterialVersion": "1.0.0-alpha1",
+      "newArchCoreVersion": "2.0.0-alpha1",
+      "newLifecycleVersion": "2.0.0-alpha1",
+      "newPagingVersion": "2.0.0-alpha1",
+      "newRoomVersion": "2.0.0-alpha1",
+      "newEspressoVersion": "3.1.0-alpha2",
+      "newTestsVersion": "1.1.0-alpha2",
+      "newJankTestHelperVersion": "1.0.1-alpha1",
+      "newUiAutomatorVersion": "2.2.0-alpha1",
+      "newDataBindingVersion": "undefined"
+    }
+  },
   "map": {
     "types": {
       "android/arch/core/executor/ArchTaskExecutor": "androidx/arch/core/executor/ArchTaskExecutor",
diff --git a/jetifier/jetifier/core/src/test/kotlin/com/android/tools/build/jetifier/core/TypeRewriterTest.kt b/jetifier/jetifier/core/src/test/kotlin/com/android/tools/build/jetifier/core/TypeRewriterTest.kt
index 36aca0a..2f5813f 100644
--- a/jetifier/jetifier/core/src/test/kotlin/com/android/tools/build/jetifier/core/TypeRewriterTest.kt
+++ b/jetifier/jetifier/core/src/test/kotlin/com/android/tools/build/jetifier/core/TypeRewriterTest.kt
@@ -17,7 +17,6 @@
 package com.android.tools.build.jetifier.core
 
 import com.android.tools.build.jetifier.core.config.Config
-import com.android.tools.build.jetifier.core.proguard.ProGuardTypesMap
 import com.android.tools.build.jetifier.core.rule.RewriteRule
 import com.android.tools.build.jetifier.core.rule.RewriteRulesMap
 import com.android.tools.build.jetifier.core.type.JavaType
@@ -131,14 +130,10 @@
             typesMap: TypesMap = TypesMap.EMPTY,
             rewriteRulesMap: RewriteRulesMap = RewriteRulesMap.EMPTY,
             useFallback: Boolean = false) {
-        val config = Config(
+        val config = Config.fromOptional(
             restrictToPackagePrefixes = setOf(packagePrefix),
             rulesMap = rewriteRulesMap,
-            slRules = emptyList(),
-            pomRewriteRules = emptySet(),
-            typesMap = typesMap,
-            proGuardMap = ProGuardTypesMap.EMPTY,
-            packageMap = PackageMap.EMPTY
+            typesMap = typesMap
         )
 
         val rewriter = TypeRewriter(config, useFallback)
diff --git a/jetifier/jetifier/core/src/test/kotlin/com/android/tools/build/jetifier/core/config/ConfigParserTest.kt b/jetifier/jetifier/core/src/test/kotlin/com/android/tools/build/jetifier/core/config/ConfigParserTest.kt
index 2018185..37826b7 100644
--- a/jetifier/jetifier/core/src/test/kotlin/com/android/tools/build/jetifier/core/config/ConfigParserTest.kt
+++ b/jetifier/jetifier/core/src/test/kotlin/com/android/tools/build/jetifier/core/config/ConfigParserTest.kt
@@ -43,7 +43,12 @@
             "            to: {groupId: \"g\", artifactId: \"a\", version: \"2.0\"} \n" +
             "        }\n" +
             "    ],\n" +
-            "   proGuardMap: {\n" +
+            "    versions: {\n" +
+            "        \"latestReleased\": {\n" +
+            "            \"something\": \"1.0.0\"\n" +
+            "        }\n" +
+            "    }," +
+            "    proGuardMap: {\n" +
             "       rules: {\n" +
             "           \"android/support/**\": [\"androidx/**\"]\n" +
             "       }\n" +
@@ -51,11 +56,19 @@
             "}"
 
         val config = ConfigParser.parseFromString(confStr)
+        val jsonConfig = config!!.toJson()
 
         Truth.assertThat(config).isNotNull()
         Truth.assertThat(config!!.restrictToPackagePrefixes.first()).isEqualTo("android/support/")
         Truth.assertThat(config.rulesMap.rewriteRules.size).isEqualTo(2)
+        Truth.assertThat(config.versionsMap.data.size).isEqualTo(1)
+        Truth.assertThat(config.versionsMap.data["latestReleased"])
+            .containsExactly("something", "1.0.0")
         Truth.assertThat(config.proGuardMap.toJson().rules.size).isEqualTo(1)
+
+        Truth.assertThat(jsonConfig.versions!!.size).isEqualTo(1)
+        Truth.assertThat(jsonConfig.versions!!["latestReleased"])
+            .containsExactly("something", "1.0.0")
     }
 
     @Test(expected = IllegalArgumentException::class)
diff --git a/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/Processor.kt b/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/Processor.kt
index 0006a15..2b8bbd5f 100644
--- a/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/Processor.kt
+++ b/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/Processor.kt
@@ -17,7 +17,7 @@
 package com.android.tools.build.jetifier.processor
 
 import com.android.tools.build.jetifier.core.config.Config
-import com.android.tools.build.jetifier.core.pom.DependencyVersionsMap
+import com.android.tools.build.jetifier.core.pom.DependencyVersions
 import com.android.tools.build.jetifier.core.pom.PomDependency
 import com.android.tools.build.jetifier.core.utils.Log
 import com.android.tools.build.jetifier.processor.archive.Archive
@@ -91,14 +91,20 @@
             reversedMode: Boolean = false,
             rewritingSupportLib: Boolean = false,
             useFallbackIfTypeIsMissing: Boolean = true,
-            versionsMap: DependencyVersionsMap = DependencyVersionsMap.LATEST_RELEASED,
+            versionSetName: String? = null,
             dataBindingVersion: String? = null
         ): Processor {
             var newConfig = config
 
-            if (dataBindingVersion != null) {
-                versionsMap.setDataBindingVersion(dataBindingVersion)
-            }
+            val versionsMap = DependencyVersions
+                .parseFromVersionSetTypeId(
+                    versionsMap = config.versionsMap,
+                    versionSetType = versionSetName
+                )
+                .replaceVersionIfAny(
+                    forVariable = DependencyVersions.DATA_BINDING_VAR_NAME,
+                    newVersion = dataBindingVersion
+                )
 
             if (reversedMode) {
                 newConfig = Config(
@@ -108,6 +114,7 @@
                     pomRewriteRules = config.pomRewriteRules.map { it.getReversed() }.toSet(),
                     typesMap = config.typesMap.reverseMapOrDie(),
                     proGuardMap = config.proGuardMap.reverseMap(),
+                    versionsMap = config.versionsMap,
                     packageMap = config.packageMap.reverse()
                 )
             }
@@ -117,7 +124,7 @@
                 rewritingSupportLib = rewritingSupportLib,
                 isInReversedMode = reversedMode,
                 useFallbackIfTypeIsMissing = useFallbackIfTypeIsMissing,
-                versionsMap = versionsMap)
+                versions = versionsMap)
             val transformers = if (rewritingSupportLib) {
                 createSLTransformers(context)
             } else {
@@ -234,7 +241,7 @@
             .firstOrNull { it.matches(inputDependency) } ?: return null
 
         return resultRule.to
-            .rewrite(inputDependency, context.versionsMap)
+            .rewrite(inputDependency, context.versions)
             .toStringNotation()
     }
 
@@ -251,8 +258,8 @@
             .filter { !filterOutBaseLibrary || !(it.from.artifactId == "baseLibrary"
                     && it.from.groupId == "com.android.databinding") }
             .map {
-                (context.versionsMap.applyOnConfigPomDep(it.from).toStringNotationWithoutVersion()
-                    to context.versionsMap.applyOnConfigPomDep(it.to).toStringNotation()) }
+                (context.versions.applyOnConfigPomDep(it.from).toStringNotationWithoutVersion()
+                    to context.versions.applyOnConfigPomDep(it.to).toStringNotation()) }
             .toMap()
     }
 
diff --git a/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/transform/TransformationContext.kt b/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/transform/TransformationContext.kt
index c667b0d..951a79b 100644
--- a/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/transform/TransformationContext.kt
+++ b/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/transform/TransformationContext.kt
@@ -18,7 +18,7 @@
 
 import com.android.tools.build.jetifier.core.TypeRewriter
 import com.android.tools.build.jetifier.core.config.Config
-import com.android.tools.build.jetifier.core.pom.DependencyVersionsMap
+import com.android.tools.build.jetifier.core.pom.DependencyVersions
 import com.android.tools.build.jetifier.core.type.JavaType
 import com.android.tools.build.jetifier.core.utils.Log
 import java.util.regex.Pattern
@@ -34,7 +34,7 @@
      * Whether to use fallback if type in our scope is missing instead of throwing an exception.
      */
     val useFallbackIfTypeIsMissing: Boolean = true,
-    val versionsMap: DependencyVersionsMap = DependencyVersionsMap.LATEST_RELEASED
+    val versions: DependencyVersions = DependencyVersions.EMPTY
 ) {
 
     // Merges all packages prefixes into one regEx pattern
diff --git a/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/transform/pom/PomDocument.kt b/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/transform/pom/PomDocument.kt
index f2c817c..31a376c 100644
--- a/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/transform/pom/PomDocument.kt
+++ b/jetifier/jetifier/processor/src/main/kotlin/com/android/tools/build/jetifier/processor/transform/pom/PomDocument.kt
@@ -146,7 +146,7 @@
         val rule = context.config.pomRewriteRules.firstOrNull { it.matches(dependency) }
         if (rule != null) {
             // Replace with new dependencies
-            return rule.to.rewrite(dependency, context.versionsMap)
+            return rule.to.rewrite(dependency, context.versions)
         }
 
         val matchesPrefix = context.config.restrictToPackagePrefixesWithDots.any {
diff --git a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/ChangeDetectionTest.kt b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/ChangeDetectionTest.kt
index d2a224f..297935f 100644
--- a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/ChangeDetectionTest.kt
+++ b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/ChangeDetectionTest.kt
@@ -16,11 +16,9 @@
 
 package com.android.tools.build.jetifier.processor
 
-import com.android.tools.build.jetifier.core.PackageMap
 import com.android.tools.build.jetifier.core.config.Config
 import com.android.tools.build.jetifier.core.pom.PomDependency
 import com.android.tools.build.jetifier.core.pom.PomRewriteRule
-import com.android.tools.build.jetifier.core.proguard.ProGuardTypesMap
 import com.android.tools.build.jetifier.core.rule.RewriteRule
 import com.android.tools.build.jetifier.core.rule.RewriteRulesMap
 import com.android.tools.build.jetifier.core.type.JavaType
@@ -39,13 +37,13 @@
  */
 class ChangeDetectionTest {
 
-    private val prefRewriteConfig = Config(
+    private val prefRewriteConfig = Config.fromOptional(
         restrictToPackagePrefixes = setOf("android/support/v7/preference"),
         rulesMap =
-        RewriteRulesMap(
-            RewriteRule(from = "android/support/v7/preference/Preference(.+)", to = "ignore"),
-            RewriteRule(from = "(.*)/R(.*)", to = "ignore")
-        ),
+            RewriteRulesMap(
+                RewriteRule(from = "android/support/v7/preference/Preference(.+)", to = "ignore"),
+                RewriteRule(from = "(.*)/R(.*)", to = "ignore")
+            ),
         slRules = listOf(),
         pomRewriteRules = setOf(
             PomRewriteRule(
@@ -56,10 +54,8 @@
             )),
         typesMap = TypesMap(
             JavaType("android/support/v7/preference/Preference")
-                    to JavaType("android/test/pref/Preference")
-        ),
-        proGuardMap = ProGuardTypesMap.EMPTY,
-        packageMap = PackageMap.EMPTY
+                to JavaType("android/test/pref/Preference")
+        )
     )
 
     @Test
diff --git a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/ProcessorTest.kt b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/ProcessorTest.kt
index 54df7ec..b0641cb 100644
--- a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/ProcessorTest.kt
+++ b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/ProcessorTest.kt
@@ -20,9 +20,6 @@
 import com.android.tools.build.jetifier.core.config.ConfigParser
 import com.android.tools.build.jetifier.core.pom.PomDependency
 import com.android.tools.build.jetifier.core.pom.PomRewriteRule
-import com.android.tools.build.jetifier.core.proguard.ProGuardTypesMap
-import com.android.tools.build.jetifier.core.rule.RewriteRulesMap
-import com.android.tools.build.jetifier.core.type.TypesMap
 import com.google.common.truth.Truth
 import org.junit.Test
 import java.io.File
@@ -65,15 +62,11 @@
     fun processor_isOldOrNewDependencyFile_shouldDetectProperly() {
 
         val processor = Processor.createProcessor(
-            Config(
-                restrictToPackagePrefixes = emptySet(),
-                rulesMap = RewriteRulesMap.EMPTY,
-                slRules = emptyList(),
+            Config.fromOptional(
                 pomRewriteRules = setOf(PomRewriteRule(
                     from = PomDependency("test.group", "artifactTest", "1.0.0"),
-                    to = PomDependency("test2.group2", "artifactTest2", "1.0.0"))),
-                typesMap = TypesMap.EMPTY,
-                proGuardMap = ProGuardTypesMap.EMPTY
+                    to = PomDependency("test2.group2", "artifactTest2", "1.0.0")
+                ))
             )
         )
 
diff --git a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/map/MapGenerationTest.kt b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/map/MapGenerationTest.kt
index 0bab05c..010afb1 100644
--- a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/map/MapGenerationTest.kt
+++ b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/map/MapGenerationTest.kt
@@ -17,11 +17,9 @@
 package com.android.tools.build.jetifier.processor.map
 
 import com.android.tools.build.jetifier.core.config.Config
-import com.android.tools.build.jetifier.core.proguard.ProGuardTypesMap
 import com.android.tools.build.jetifier.core.rule.RewriteRule
 import com.android.tools.build.jetifier.core.rule.RewriteRulesMap
 import com.android.tools.build.jetifier.core.type.JavaType
-import com.android.tools.build.jetifier.core.type.TypesMap
 import com.android.tools.build.jetifier.processor.type.MapGeneratorRemapper
 import com.google.common.truth.Truth
 import org.junit.Test
@@ -156,13 +154,9 @@
                 }
 
                 fun mapInto(types: Map<String, String>): Step2 {
-                    val config = Config(
+                    val config = Config.fromOptional(
                         restrictToPackagePrefixes = prefixes,
-                        rulesMap = RewriteRulesMap(rules),
-                        slRules = emptyList(),
-                        pomRewriteRules = emptySet(),
-                        typesMap = TypesMap.EMPTY,
-                        proGuardMap = ProGuardTypesMap.EMPTY)
+                        rulesMap = RewriteRulesMap(rules))
                     val scanner = MapGeneratorRemapper(config)
 
                     allTypes.forEach { scanner.rewriteType(it) }
diff --git a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/DependencyMappingTest.kt b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/DependencyMappingTest.kt
index a2843cd..ebf5747 100644
--- a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/DependencyMappingTest.kt
+++ b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/DependencyMappingTest.kt
@@ -16,13 +16,9 @@
 
 package com.android.tools.build.jetifier.processor.transform
 
-import com.android.tools.build.jetifier.core.PackageMap
 import com.android.tools.build.jetifier.core.config.Config
 import com.android.tools.build.jetifier.core.pom.PomDependency
 import com.android.tools.build.jetifier.core.pom.PomRewriteRule
-import com.android.tools.build.jetifier.core.proguard.ProGuardTypesMap
-import com.android.tools.build.jetifier.core.rule.RewriteRulesMap
-import com.android.tools.build.jetifier.core.type.TypesMap
 import com.android.tools.build.jetifier.processor.Processor
 import com.google.common.truth.Truth
 import org.junit.Test
@@ -44,14 +40,8 @@
     object MappingTester {
 
         fun testRewrite(from: String, to: String?, rules: Set<PomRewriteRule>) {
-            val config = Config(
-                restrictToPackagePrefixes = emptySet(),
-                rulesMap = RewriteRulesMap.EMPTY,
-                slRules = emptyList(),
-                pomRewriteRules = rules,
-                typesMap = TypesMap.EMPTY,
-                proGuardMap = ProGuardTypesMap.EMPTY,
-                packageMap = PackageMap.EMPTY
+            val config = Config.fromOptional(
+                pomRewriteRules = rules
             )
 
             val processor = Processor.createProcessor(config)
diff --git a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/bytecode/ClassFilesMoveTest.kt b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/bytecode/ClassFilesMoveTest.kt
index 958d00a..484042d 100644
--- a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/bytecode/ClassFilesMoveTest.kt
+++ b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/bytecode/ClassFilesMoveTest.kt
@@ -17,7 +17,6 @@
 package com.android.tools.build.jetifier.processor.transform.bytecode
 
 import com.android.tools.build.jetifier.core.config.Config
-import com.android.tools.build.jetifier.core.proguard.ProGuardTypesMap
 import com.android.tools.build.jetifier.core.rule.RewriteRule
 import com.android.tools.build.jetifier.core.rule.RewriteRulesMap
 import com.android.tools.build.jetifier.core.type.JavaType
@@ -37,7 +36,7 @@
 class ClassFilesMoveTest {
 
     companion object {
-        private val TEST_CONFIG = Config(
+        private val TEST_CONFIG = Config.fromOptional(
             restrictToPackagePrefixes = setOf("android/support"),
             rulesMap = RewriteRulesMap(
                 RewriteRule("android/support/annotation/(.*)", "ignore"),
@@ -49,7 +48,6 @@
                 RewriteRule("android/support/v7/preference/R(.*)", "ignore"),
                 RewriteRule("android/support/v4/(.*)", "ignore")
             ),
-            pomRewriteRules = emptySet(),
             typesMap = TypesMap(mapOf(
                 "android/support/v7/preference/Preference"
                         to "androidx/support/preference/Preference",
@@ -65,8 +63,7 @@
                         to "androidx/support/preference/SwitchPreference",
                 "android/support/v7/preference/PreferenceDataStore"
                         to "androidx/support/preference/PreferenceDataStore"
-            ).map { JavaType(it.key) to JavaType(it.value) }.toMap()),
-            proGuardMap = ProGuardTypesMap.EMPTY
+            ).map { JavaType(it.key) to JavaType(it.value) }.toMap())
         )
     }
 
diff --git a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/bytecode/CoreRemapperImplTest.kt b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/bytecode/CoreRemapperImplTest.kt
index 881260b..cf69fb2 100644
--- a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/bytecode/CoreRemapperImplTest.kt
+++ b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/bytecode/CoreRemapperImplTest.kt
@@ -16,10 +16,7 @@
 
 package com.android.tools.build.jetifier.processor.transform.bytecode
 
-import com.android.tools.build.jetifier.core.PackageMap
 import com.android.tools.build.jetifier.core.config.Config
-import com.android.tools.build.jetifier.core.proguard.ProGuardTypesMap
-import com.android.tools.build.jetifier.core.rule.RewriteRulesMap
 import com.android.tools.build.jetifier.core.type.JavaType
 import com.android.tools.build.jetifier.core.type.TypesMap
 import com.android.tools.build.jetifier.processor.transform.TransformationContext
@@ -55,14 +52,9 @@
             setOf(restrictToPackagePrefix)
         }
 
-        val config = Config(
+        val config = Config.fromOptional(
             restrictToPackagePrefixes = prefixes,
-            rulesMap = RewriteRulesMap.EMPTY,
-            typesMap = typesMap,
-            slRules = emptyList(),
-            pomRewriteRules = emptySet(),
-            proGuardMap = ProGuardTypesMap.EMPTY,
-            packageMap = PackageMap.EMPTY)
+            typesMap = typesMap)
 
         val context = TransformationContext(config, isInReversedMode = true)
 
diff --git a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/pom/PomDocumentTest.kt b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/pom/PomDocumentTest.kt
index 93b1fb7..efaac53 100644
--- a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/pom/PomDocumentTest.kt
+++ b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/pom/PomDocumentTest.kt
@@ -16,14 +16,10 @@
 
 package com.android.tools.build.jetifier.processor.transform.pom
 
-import com.android.tools.build.jetifier.core.PackageMap
 import com.android.tools.build.jetifier.core.config.Config
-import com.android.tools.build.jetifier.core.pom.DependencyVersionsMap
+import com.android.tools.build.jetifier.core.pom.DependencyVersions
 import com.android.tools.build.jetifier.core.pom.PomDependency
 import com.android.tools.build.jetifier.core.pom.PomRewriteRule
-import com.android.tools.build.jetifier.core.proguard.ProGuardTypesMap
-import com.android.tools.build.jetifier.core.rule.RewriteRulesMap
-import com.android.tools.build.jetifier.core.type.TypesMap
 import com.android.tools.build.jetifier.processor.archive.ArchiveFile
 import com.android.tools.build.jetifier.processor.transform.TransformationContext
 import com.google.common.truth.Truth
@@ -115,7 +111,7 @@
                         version = "{newSlVersion}")
                 )
             ),
-            versionsMap = DependencyVersionsMap(newSlVersion = "1.0.0-test")
+            versions = DependencyVersions(mapOf("newSlVersion" to "1.0.0-test"))
         )
     }
 
@@ -273,7 +269,7 @@
         givenXml: String,
         expectedXml: String,
         rules: Set<PomRewriteRule>,
-        versionsMap: DependencyVersionsMap = DependencyVersionsMap.LATEST
+        versions: DependencyVersions = DependencyVersions.EMPTY
     ) {
         val given =
             "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
@@ -303,15 +299,10 @@
 
         val file = ArchiveFile(Paths.get("pom.xml"), given.toByteArray())
         val pomDocument = PomDocument.loadFrom(file)
-        val config = Config(
+        val config = Config.fromOptional(
             restrictToPackagePrefixes = emptySet(),
-            rulesMap = RewriteRulesMap.EMPTY,
-            typesMap = TypesMap.EMPTY,
-            slRules = emptyList(),
-            pomRewriteRules = rules,
-            proGuardMap = ProGuardTypesMap.EMPTY,
-            packageMap = PackageMap.EMPTY)
-        val context = TransformationContext(config, versionsMap = versionsMap)
+            pomRewriteRules = rules)
+        val context = TransformationContext(config, versions = versions)
         pomDocument.applyRules(context)
         pomDocument.saveBackToFileIfNeeded()
         var strResult = file.data.toString(StandardCharsets.UTF_8)
diff --git a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/pom/PomRewriteInZipTest.kt b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/pom/PomRewriteInZipTest.kt
index 29e37a4..39d8ae1 100644
--- a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/pom/PomRewriteInZipTest.kt
+++ b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/pom/PomRewriteInZipTest.kt
@@ -19,9 +19,6 @@
 import com.android.tools.build.jetifier.core.config.Config
 import com.android.tools.build.jetifier.core.pom.PomDependency
 import com.android.tools.build.jetifier.core.pom.PomRewriteRule
-import com.android.tools.build.jetifier.core.proguard.ProGuardTypesMap
-import com.android.tools.build.jetifier.core.rule.RewriteRulesMap
-import com.android.tools.build.jetifier.core.type.TypesMap
 import com.android.tools.build.jetifier.processor.FileMapping
 import com.android.tools.build.jetifier.processor.Processor
 import com.android.tools.build.jetifier.processor.archive.Archive
@@ -36,10 +33,8 @@
 class PomRewriteInZipTest {
 
     companion object {
-        private val TEST_CONFIG = Config(
+        private val TEST_CONFIG = Config.fromOptional(
             restrictToPackagePrefixes = setOf("com/sample"),
-            rulesMap = RewriteRulesMap.EMPTY,
-            slRules = listOf(),
             pomRewriteRules = setOf(
                 PomRewriteRule(
                     from = PomDependency(
@@ -51,9 +46,7 @@
                         artifactId = "myArtifact",
                         version = "1.0.0"
                     )
-                )),
-            typesMap = TypesMap.EMPTY,
-            proGuardMap = ProGuardTypesMap.EMPTY
+            ))
         )
     }
 
diff --git a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/proguard/ProGuardTester.kt b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/proguard/ProGuardTester.kt
index beb18f7..44ca50b 100644
--- a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/proguard/ProGuardTester.kt
+++ b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/proguard/ProGuardTester.kt
@@ -79,13 +79,11 @@
     }
 
     private fun createConfig(): Config {
-        return Config(
+        return Config.fromOptional(
             restrictToPackagePrefixes = prefixes,
             rulesMap = RewriteRulesMap(rewriteRules
                 .map { RewriteRule(it.first, it.second) }
                 .toList()),
-            slRules = emptyList(),
-            pomRewriteRules = emptySet(),
             typesMap = TypesMap(
                 types = javaTypes.map { JavaType(it.first) to JavaType(it.second) }.toMap()
             ),
diff --git a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/resource/XmlResourcesTransformerTest.kt b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/resource/XmlResourcesTransformerTest.kt
index 3186ee9..34b519a 100644
--- a/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/resource/XmlResourcesTransformerTest.kt
+++ b/jetifier/jetifier/processor/src/test/kotlin/com/android/tools/build/jetifier/processor/transform/resource/XmlResourcesTransformerTest.kt
@@ -18,7 +18,6 @@
 
 import com.android.tools.build.jetifier.core.PackageMap
 import com.android.tools.build.jetifier.core.config.Config
-import com.android.tools.build.jetifier.core.proguard.ProGuardTypesMap
 import com.android.tools.build.jetifier.core.rule.RewriteRule
 import com.android.tools.build.jetifier.core.rule.RewriteRulesMap
 import com.android.tools.build.jetifier.core.type.JavaType
@@ -389,13 +388,10 @@
             "$expectedXml\n"
 
         val typeMap = TypesMap(typesMap.map { JavaType(it.key) to JavaType(it.value) }.toMap())
-        val config = Config(
+        val config = Config.fromOptional(
             restrictToPackagePrefixes = prefixes,
             rulesMap = rulesMap,
-            slRules = emptyList(),
-            pomRewriteRules = emptySet(),
             typesMap = typeMap,
-            proGuardMap = ProGuardTypesMap.EMPTY,
             packageMap = packageMap
         )
         val context = TransformationContext(
diff --git a/jetifier/jetifier/standalone/src/main/kotlin/com/android/tools/build/jetifier/standalone/Main.kt b/jetifier/jetifier/standalone/src/main/kotlin/com/android/tools/build/jetifier/standalone/Main.kt
index dec948f..7172111 100644
--- a/jetifier/jetifier/standalone/src/main/kotlin/com/android/tools/build/jetifier/standalone/Main.kt
+++ b/jetifier/jetifier/standalone/src/main/kotlin/com/android/tools/build/jetifier/standalone/Main.kt
@@ -16,9 +16,7 @@
 
 package com.android.tools.build.jetifier.standalone
 
-import com.android.tools.build.jetifier.core.config.Config
 import com.android.tools.build.jetifier.core.config.ConfigParser
-import com.android.tools.build.jetifier.core.pom.DependencyVersionsMap
 import com.android.tools.build.jetifier.core.utils.Log
 import com.android.tools.build.jetifier.processor.FileMapping
 import com.android.tools.build.jetifier.processor.Processor
@@ -35,42 +33,75 @@
 
     companion object {
         const val TAG = "Main"
-        const val TOOL_NAME = "standalone"
+        const val TOOL_NAME = "Jetifier (standalone)"
 
         val OPTIONS = Options()
-        val OPTION_INPUT = createOption("i", "Input libraries paths", multiple = true)
-        val OPTION_OUTPUT_DIR = createOption("outputdir", "Output directory path",
-            isRequired = false)
-        val OPTION_OUTPUT_FILE = createOption("outputfile", "Output file", isRequired = false)
-        val OPTION_CONFIG = createOption("c", "Input config path", isRequired = false)
-        val OPTION_LOG_LEVEL = createOption("l", "Logging level. debug, verbose, error, info " +
-            "(default)", isRequired = false)
-        val OPTION_REVERSED = createOption("r", "Run reversed process", hasArgs = false,
-            isRequired = false)
-        val OPTION_REWRITE_SUPPORT_LIB = createOption("s", "If set, all libraries being rewritten" +
-            " are assumed to be part of Support Library. Otherwise only general dependencies " +
-            " are expected.", hasArgs = false, isRequired = false)
-        val OPTION_STRICT = createOption("strict",
-            "Don't fallback in case rules are missing", hasArgs = false, isRequired = false)
-        val OPTION_REBUILD_TOP_OF_TREE = createOption("rebuildTopOfTree",
-            "Rebuild the zip of maven distribution according to the generated pom file",
-            hasArgs = false, isRequired = false)
-        val OPTION_VERSIONS = createOption("versions",
-                "Versions to be used with jetifier (latest or alpha1)",
-                hasArgs = true, isRequired = false)
+        val OPTION_INPUT = createOption(
+            argName = "i",
+            argNameLong = "input",
+            desc = "Input library path (jar, aar, zip)",
+            isRequired = true
+        )
+        val OPTION_OUTPUT = createOption(
+            argName = "o",
+            argNameLong = "output",
+            desc = "Output file path",
+            isRequired = true
+        )
+        val OPTION_CONFIG = createOption(
+            argName = "c",
+            argNameLong = "config",
+            desc = "Input config path (otherwise default is used)",
+            isRequired = false
+        )
+        val OPTION_LOG_LEVEL = createOption(
+            argName = "l",
+            argNameLong = "log",
+            desc = "Logging level. Values: error, warning (default), info, verbose",
+            isRequired = false
+        )
+        val OPTION_REVERSED = createOption(
+            argName = "r",
+            argNameLong = "reversed",
+            desc = "Run reversed process (de-jetification)",
+            hasArgs = false,
+            isRequired = false
+        )
+        val OPTION_STRICT = createOption(
+            argName = "s",
+            argNameLong = "strict",
+            desc = "Don't fallback in case rules are missing and throw errors instead",
+            hasArgs = false,
+            isRequired = false
+        )
+        val OPTION_REBUILD_TOP_OF_TREE = createOption(
+            argName = "rebuildTopOfTree",
+            argNameLong = "rebuildTopOfTree",
+            desc = "Rebuild the zip of maven distribution according to the generated pom file." +
+                "If set, all libraries being rewritten are assumed to be part of Support " +
+                "Library. Not needed for jetification.",
+            hasArgs = false,
+            isRequired = false
+        )
+        val OPTION_VERSIONS = createOption(
+            argName = "v",
+            argNameLong = "versions",
+            desc = "Versions of dependencies to be substituted by Jetifier. In most cases you " +
+                "want to leave the default which is 'latestReleased'. Check Jetifier's config " +
+                "file for more types of configurations.",
+            hasArgs = true,
+            isRequired = false
+        )
 
         private fun createOption(
             argName: String,
+            argNameLong: String,
             desc: String,
             hasArgs: Boolean = true,
-            isRequired: Boolean = true,
-            multiple: Boolean = false
+            isRequired: Boolean = true
         ): Option {
-            val op = Option(argName, hasArgs, desc)
+            val op = Option(argName, argNameLong, hasArgs, desc)
             op.isRequired = isRequired
-            if (multiple) {
-                op.args = Option.UNLIMITED_VALUES
-            }
             OPTIONS.addOption(op)
             return op
         }
@@ -89,43 +120,23 @@
 
         Log.setLevel(cmd.getOptionValue(OPTION_LOG_LEVEL.opt))
 
-        val inputLibraries = cmd.getOptionValues(OPTION_INPUT.opt).map { File(it) }.toSet()
-        val outputDir = cmd.getOptionValue(OPTION_OUTPUT_DIR.opt)
-        val outputFile = cmd.getOptionValue(OPTION_OUTPUT_FILE.opt)
+        val inputLibrary = File(cmd.getOptionValue(OPTION_INPUT.opt))
+        val output = cmd.getOptionValue(OPTION_OUTPUT.opt)
         val rebuildTopOfTree = cmd.hasOption(OPTION_REBUILD_TOP_OF_TREE.opt)
 
-        if (outputDir == null && outputFile == null) {
-            throw IllegalArgumentException("Must specify -outputdir or -outputfile")
-        }
-        if (outputDir != null && outputFile != null) {
-            throw IllegalArgumentException("Cannot specify both -outputdir and -outputfile")
-        }
-        if (inputLibraries.size > 1 && outputFile != null) {
-            throw IllegalArgumentException(
-                    "Cannot specify -outputfile when multiple input libraries are given")
-        }
-
         val fileMappings = mutableSetOf<FileMapping>()
-        if (outputFile != null) {
-            if (rebuildTopOfTree) {
-                val tempFile = createTempFile(suffix = "zip")
-                fileMappings.add(FileMapping(inputLibraries.first(), tempFile))
-            } else {
-                fileMappings.add(FileMapping(inputLibraries.first(), File(outputFile)))
-            }
+        if (rebuildTopOfTree) {
+            val tempFile = createTempFile(suffix = "zip")
+            fileMappings.add(FileMapping(inputLibrary, tempFile))
         } else {
-            inputLibraries.forEach {
-                val newFileName = File(Paths.get(outputDir).toString(), it.name)
-                fileMappings.add(FileMapping(it, newFileName))
-            }
+            fileMappings.add(FileMapping(inputLibrary, File(output)))
         }
 
-        val config: Config?
-        if (cmd.hasOption(OPTION_CONFIG.opt)) {
+        val config = if (cmd.hasOption(OPTION_CONFIG.opt)) {
             val configPath = Paths.get(cmd.getOptionValue(OPTION_CONFIG.opt))
-            config = ConfigParser.loadFromFile(configPath)
+            ConfigParser.loadFromFile(configPath)
         } else {
-            config = ConfigParser.loadDefaultConfig()
+            ConfigParser.loadDefaultConfig()
         }
 
         if (config == null) {
@@ -134,29 +145,21 @@
             return
         }
 
-        val versionsMap = DependencyVersionsMap.parseFromVersionSetTypeId(
-            if (cmd.hasOption(OPTION_VERSIONS.opt)) {
-                cmd.getOptionValue(OPTION_VERSIONS.opt)
-            } else {
-                null
-            })
-
+        val versionSetName = cmd.getOptionValue(OPTION_VERSIONS.opt)
         val isReversed = cmd.hasOption(OPTION_REVERSED.opt)
-        val rewriteSupportLib = cmd.hasOption(OPTION_REWRITE_SUPPORT_LIB.opt)
         val isStrict = cmd.hasOption(OPTION_STRICT.opt)
+
         val processor = Processor.createProcessor(
             config = config,
             reversedMode = isReversed,
-            rewritingSupportLib = rewriteSupportLib,
+            rewritingSupportLib = rebuildTopOfTree,
             useFallbackIfTypeIsMissing = !isStrict,
-            versionsMap = versionsMap)
+            versionSetName = versionSetName)
         processor.transform(fileMappings)
 
         if (rebuildTopOfTree) {
             val tempFile = fileMappings.first().to
-            TopOfTreeBuilder().rebuildFrom(
-                inputZip = tempFile,
-                outputZip = File(outputFile))
+            TopOfTreeBuilder().rebuildFrom(inputZip = tempFile, outputZip = File(output))
             tempFile.delete()
         }
     }