Add support to extend commands bpfix and androidmk

Allows our partners to maintain partner-specific fixes in their repos. Converts most of androidmk into a library similar to bpfix. Makes some methods and types public for use by extended versions.

Bug:140727544
Test: Ran unit test cases &&
  ran test conversions with sample
Change-Id: I7e1fbf3a6a7a8bd47334f43fe3eb68cbbd3426c1
diff --git a/androidmk/cmd/androidmk.go b/androidmk/cmd/androidmk.go
new file mode 100644
index 0000000..00488eb
--- /dev/null
+++ b/androidmk/cmd/androidmk.go
@@ -0,0 +1,56 @@
+// Copyright 2017 Google Inc. All rights reserved.
+//
+// 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 main
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"io/ioutil"
+	"os"
+
+	"android/soong/androidmk/androidmk"
+)
+
+var usage = func() {
+	fmt.Fprintf(os.Stderr, "usage: androidmk [flags] <inputFile>\n"+
+		"\nandroidmk parses <inputFile> as an Android.mk file and attempts to output an analogous Android.bp file (to standard out)\n")
+	flag.PrintDefaults()
+	os.Exit(1)
+}
+
+func main() {
+	flag.Usage = usage
+	flag.Parse()
+	if len(flag.Args()) != 1 {
+		usage()
+	}
+	filePathToRead := flag.Arg(0)
+	b, err := ioutil.ReadFile(filePathToRead)
+	if err != nil {
+		fmt.Println(err.Error())
+		return
+	}
+
+	output, errs := androidmk.ConvertFile(os.Args[1], bytes.NewBuffer(b))
+	if len(errs) > 0 {
+		for _, err := range errs {
+			fmt.Fprintln(os.Stderr, "ERROR: ", err)
+		}
+		os.Exit(1)
+	}
+
+	fmt.Print(output)
+}
diff --git a/androidmk/cmd/androidmk/android.go b/androidmk/cmd/androidmk/android.go
deleted file mode 100644
index fcadd03..0000000
--- a/androidmk/cmd/androidmk/android.go
+++ /dev/null
@@ -1,979 +0,0 @@
-// Copyright 2017 Google Inc. All rights reserved.
-//
-// 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 main
-
-import (
-	"android/soong/android"
-	mkparser "android/soong/androidmk/parser"
-	"fmt"
-	"strings"
-
-	bpparser "github.com/google/blueprint/parser"
-)
-
-const (
-	clear_vars      = "__android_mk_clear_vars"
-	include_ignored = "__android_mk_include_ignored"
-)
-
-type bpVariable struct {
-	name         string
-	variableType bpparser.Type
-}
-
-type variableAssignmentContext struct {
-	file    *bpFile
-	prefix  string
-	mkvalue *mkparser.MakeString
-	append  bool
-}
-
-var rewriteProperties = map[string](func(variableAssignmentContext) error){
-	// custom functions
-	"LOCAL_32_BIT_ONLY":           local32BitOnly,
-	"LOCAL_AIDL_INCLUDES":         localAidlIncludes,
-	"LOCAL_ASSET_DIR":             localizePathList("asset_dirs"),
-	"LOCAL_C_INCLUDES":            localIncludeDirs,
-	"LOCAL_EXPORT_C_INCLUDE_DIRS": exportIncludeDirs,
-	"LOCAL_JARJAR_RULES":          localizePath("jarjar_rules"),
-	"LOCAL_LDFLAGS":               ldflags,
-	"LOCAL_MODULE_CLASS":          prebuiltClass,
-	"LOCAL_MODULE_STEM":           stem,
-	"LOCAL_MODULE_HOST_OS":        hostOs,
-	"LOCAL_RESOURCE_DIR":          localizePathList("resource_dirs"),
-	"LOCAL_SANITIZE":              sanitize(""),
-	"LOCAL_SANITIZE_DIAG":         sanitize("diag."),
-	"LOCAL_STRIP_MODULE":          strip(),
-	"LOCAL_CFLAGS":                cflags,
-	"LOCAL_UNINSTALLABLE_MODULE":  invert("installable"),
-	"LOCAL_PROGUARD_ENABLED":      proguardEnabled,
-	"LOCAL_MODULE_PATH":           prebuiltModulePath,
-
-	// composite functions
-	"LOCAL_MODULE_TAGS": includeVariableIf(bpVariable{"tags", bpparser.ListType}, not(valueDumpEquals("optional"))),
-
-	// skip functions
-	"LOCAL_ADDITIONAL_DEPENDENCIES": skip, // TODO: check for only .mk files?
-	"LOCAL_CPP_EXTENSION":           skip,
-	"LOCAL_MODULE_SUFFIX":           skip, // TODO
-	"LOCAL_PATH":                    skip, // Nothing to do, except maybe avoid the "./" in paths?
-	"LOCAL_PRELINK_MODULE":          skip, // Already phased out
-	"LOCAL_BUILT_MODULE_STEM":       skip,
-	"LOCAL_USE_AAPT2":               skip, // Always enabled in Soong
-	"LOCAL_JAR_EXCLUDE_FILES":       skip, // Soong never excludes files from jars
-
-	"LOCAL_ANNOTATION_PROCESSOR_CLASSES": skip, // Soong gets the processor classes from the plugin
-	"LOCAL_CTS_TEST_PACKAGE":             skip, // Obsolete
-	"LOCAL_JACK_ENABLED":                 skip, // Obselete
-	"LOCAL_JACK_FLAGS":                   skip, // Obselete
-}
-
-// adds a group of properties all having the same type
-func addStandardProperties(propertyType bpparser.Type, properties map[string]string) {
-	for key, val := range properties {
-		rewriteProperties[key] = includeVariable(bpVariable{val, propertyType})
-	}
-}
-
-func init() {
-	addStandardProperties(bpparser.StringType,
-		map[string]string{
-			"LOCAL_MODULE":                  "name",
-			"LOCAL_CXX_STL":                 "stl",
-			"LOCAL_MULTILIB":                "compile_multilib",
-			"LOCAL_ARM_MODE_HACK":           "instruction_set",
-			"LOCAL_SDK_VERSION":             "sdk_version",
-			"LOCAL_MIN_SDK_VERSION":         "min_sdk_version",
-			"LOCAL_NDK_STL_VARIANT":         "stl",
-			"LOCAL_JAR_MANIFEST":            "manifest",
-			"LOCAL_CERTIFICATE":             "certificate",
-			"LOCAL_PACKAGE_NAME":            "name",
-			"LOCAL_MODULE_RELATIVE_PATH":    "relative_install_path",
-			"LOCAL_PROTOC_OPTIMIZE_TYPE":    "proto.type",
-			"LOCAL_MODULE_OWNER":            "owner",
-			"LOCAL_RENDERSCRIPT_TARGET_API": "renderscript.target_api",
-			"LOCAL_NOTICE_FILE":             "notice",
-			"LOCAL_JAVA_LANGUAGE_VERSION":   "java_version",
-			"LOCAL_INSTRUMENTATION_FOR":     "instrumentation_for",
-			"LOCAL_MANIFEST_FILE":           "manifest",
-
-			"LOCAL_DEX_PREOPT_PROFILE_CLASS_LISTING": "dex_preopt.profile",
-			"LOCAL_TEST_CONFIG":                      "test_config",
-		})
-	addStandardProperties(bpparser.ListType,
-		map[string]string{
-			"LOCAL_SRC_FILES":                     "srcs",
-			"LOCAL_SRC_FILES_EXCLUDE":             "exclude_srcs",
-			"LOCAL_HEADER_LIBRARIES":              "header_libs",
-			"LOCAL_SHARED_LIBRARIES":              "shared_libs",
-			"LOCAL_STATIC_LIBRARIES":              "static_libs",
-			"LOCAL_WHOLE_STATIC_LIBRARIES":        "whole_static_libs",
-			"LOCAL_SYSTEM_SHARED_LIBRARIES":       "system_shared_libs",
-			"LOCAL_ASFLAGS":                       "asflags",
-			"LOCAL_CLANG_ASFLAGS":                 "clang_asflags",
-			"LOCAL_COMPATIBILITY_SUPPORT_FILES":   "data",
-			"LOCAL_CONLYFLAGS":                    "conlyflags",
-			"LOCAL_CPPFLAGS":                      "cppflags",
-			"LOCAL_REQUIRED_MODULES":              "required",
-			"LOCAL_HOST_REQUIRED_MODULES":         "host_required",
-			"LOCAL_TARGET_REQUIRED_MODULES":       "target_required",
-			"LOCAL_OVERRIDES_MODULES":             "overrides",
-			"LOCAL_LDLIBS":                        "host_ldlibs",
-			"LOCAL_CLANG_CFLAGS":                  "clang_cflags",
-			"LOCAL_YACCFLAGS":                     "yacc.flags",
-			"LOCAL_SANITIZE_RECOVER":              "sanitize.recover",
-			"LOCAL_LOGTAGS_FILES":                 "logtags",
-			"LOCAL_EXPORT_HEADER_LIBRARY_HEADERS": "export_header_lib_headers",
-			"LOCAL_EXPORT_SHARED_LIBRARY_HEADERS": "export_shared_lib_headers",
-			"LOCAL_EXPORT_STATIC_LIBRARY_HEADERS": "export_static_lib_headers",
-			"LOCAL_INIT_RC":                       "init_rc",
-			"LOCAL_VINTF_FRAGMENTS":               "vintf_fragments",
-			"LOCAL_TIDY_FLAGS":                    "tidy_flags",
-			// TODO: This is comma-separated, not space-separated
-			"LOCAL_TIDY_CHECKS":           "tidy_checks",
-			"LOCAL_RENDERSCRIPT_INCLUDES": "renderscript.include_dirs",
-			"LOCAL_RENDERSCRIPT_FLAGS":    "renderscript.flags",
-
-			"LOCAL_JAVA_RESOURCE_DIRS":    "java_resource_dirs",
-			"LOCAL_JAVA_RESOURCE_FILES":   "java_resources",
-			"LOCAL_JAVACFLAGS":            "javacflags",
-			"LOCAL_ERROR_PRONE_FLAGS":     "errorprone.javacflags",
-			"LOCAL_DX_FLAGS":              "dxflags",
-			"LOCAL_JAVA_LIBRARIES":        "libs",
-			"LOCAL_STATIC_JAVA_LIBRARIES": "static_libs",
-			"LOCAL_JNI_SHARED_LIBRARIES":  "jni_libs",
-			"LOCAL_AAPT_FLAGS":            "aaptflags",
-			"LOCAL_PACKAGE_SPLITS":        "package_splits",
-			"LOCAL_COMPATIBILITY_SUITE":   "test_suites",
-			"LOCAL_OVERRIDES_PACKAGES":    "overrides",
-
-			"LOCAL_ANNOTATION_PROCESSORS": "plugins",
-
-			"LOCAL_PROGUARD_FLAGS":      "optimize.proguard_flags",
-			"LOCAL_PROGUARD_FLAG_FILES": "optimize.proguard_flags_files",
-
-			// These will be rewritten to libs/static_libs by bpfix, after their presence is used to convert
-			// java_library_static to android_library.
-			"LOCAL_SHARED_ANDROID_LIBRARIES": "android_libs",
-			"LOCAL_STATIC_ANDROID_LIBRARIES": "android_static_libs",
-			"LOCAL_ADDITIONAL_CERTIFICATES":  "additional_certificates",
-
-			// Jacoco filters:
-			"LOCAL_JACK_COVERAGE_INCLUDE_FILTER": "jacoco.include_filter",
-			"LOCAL_JACK_COVERAGE_EXCLUDE_FILTER": "jacoco.exclude_filter",
-
-			"LOCAL_FULL_LIBS_MANIFEST_FILES": "additional_manifests",
-		})
-
-	addStandardProperties(bpparser.BoolType,
-		map[string]string{
-			// Bool properties
-			"LOCAL_IS_HOST_MODULE":             "host",
-			"LOCAL_CLANG":                      "clang",
-			"LOCAL_FORCE_STATIC_EXECUTABLE":    "static_executable",
-			"LOCAL_NATIVE_COVERAGE":            "native_coverage",
-			"LOCAL_NO_CRT":                     "nocrt",
-			"LOCAL_ALLOW_UNDEFINED_SYMBOLS":    "allow_undefined_symbols",
-			"LOCAL_RTTI_FLAG":                  "rtti",
-			"LOCAL_PACK_MODULE_RELOCATIONS":    "pack_relocations",
-			"LOCAL_TIDY":                       "tidy",
-			"LOCAL_USE_CLANG_LLD":              "use_clang_lld",
-			"LOCAL_PROPRIETARY_MODULE":         "proprietary",
-			"LOCAL_VENDOR_MODULE":              "vendor",
-			"LOCAL_ODM_MODULE":                 "device_specific",
-			"LOCAL_PRODUCT_MODULE":             "product_specific",
-			"LOCAL_SYSTEM_EXT_MODULE":          "system_ext_specific",
-			"LOCAL_EXPORT_PACKAGE_RESOURCES":   "export_package_resources",
-			"LOCAL_PRIVILEGED_MODULE":          "privileged",
-			"LOCAL_AAPT_INCLUDE_ALL_RESOURCES": "aapt_include_all_resources",
-			"LOCAL_USE_EMBEDDED_NATIVE_LIBS":   "use_embedded_native_libs",
-			"LOCAL_USE_EMBEDDED_DEX":           "use_embedded_dex",
-
-			"LOCAL_DEX_PREOPT":                  "dex_preopt.enabled",
-			"LOCAL_DEX_PREOPT_APP_IMAGE":        "dex_preopt.app_image",
-			"LOCAL_DEX_PREOPT_GENERATE_PROFILE": "dex_preopt.profile_guided",
-
-			"LOCAL_PRIVATE_PLATFORM_APIS": "platform_apis",
-			"LOCAL_JETIFIER_ENABLED":      "jetifier",
-		})
-}
-
-type listSplitFunc func(bpparser.Expression) (string, bpparser.Expression, error)
-
-func emptyList(value bpparser.Expression) bool {
-	if list, ok := value.(*bpparser.List); ok {
-		return len(list.Values) == 0
-	}
-	return false
-}
-
-func splitBpList(val bpparser.Expression, keyFunc listSplitFunc) (lists map[string]bpparser.Expression, err error) {
-	lists = make(map[string]bpparser.Expression)
-
-	switch val := val.(type) {
-	case *bpparser.Operator:
-		listsA, err := splitBpList(val.Args[0], keyFunc)
-		if err != nil {
-			return nil, err
-		}
-
-		listsB, err := splitBpList(val.Args[1], keyFunc)
-		if err != nil {
-			return nil, err
-		}
-
-		for k, v := range listsA {
-			if !emptyList(v) {
-				lists[k] = v
-			}
-		}
-
-		for k, vB := range listsB {
-			if emptyList(vB) {
-				continue
-			}
-
-			if vA, ok := lists[k]; ok {
-				expression := val.Copy().(*bpparser.Operator)
-				expression.Args = [2]bpparser.Expression{vA, vB}
-				lists[k] = expression
-			} else {
-				lists[k] = vB
-			}
-		}
-	case *bpparser.Variable:
-		key, value, err := keyFunc(val)
-		if err != nil {
-			return nil, err
-		}
-		if value.Type() == bpparser.ListType {
-			lists[key] = value
-		} else {
-			lists[key] = &bpparser.List{
-				Values: []bpparser.Expression{value},
-			}
-		}
-	case *bpparser.List:
-		for _, v := range val.Values {
-			key, value, err := keyFunc(v)
-			if err != nil {
-				return nil, err
-			}
-			l := lists[key]
-			if l == nil {
-				l = &bpparser.List{}
-			}
-			l.(*bpparser.List).Values = append(l.(*bpparser.List).Values, value)
-			lists[key] = l
-		}
-	default:
-		panic(fmt.Errorf("unexpected type %t", val))
-	}
-
-	return lists, nil
-}
-
-// classifyLocalOrGlobalPath tells whether a file path should be interpreted relative to the current module (local)
-// or relative to the root of the source checkout (global)
-func classifyLocalOrGlobalPath(value bpparser.Expression) (string, bpparser.Expression, error) {
-	switch v := value.(type) {
-	case *bpparser.Variable:
-		if v.Name == "LOCAL_PATH" {
-			return "local", &bpparser.String{
-				Value: ".",
-			}, nil
-		} else {
-			// TODO: Should we split variables?
-			return "global", value, nil
-		}
-	case *bpparser.Operator:
-		if v.Type() != bpparser.StringType {
-			return "", nil, fmt.Errorf("classifyLocalOrGlobalPath expected a string, got %s", v.Type())
-		}
-
-		if v.Operator != '+' {
-			return "global", value, nil
-		}
-
-		firstOperand := v.Args[0]
-		secondOperand := v.Args[1]
-		if firstOperand.Type() != bpparser.StringType {
-			return "global", value, nil
-		}
-
-		if _, ok := firstOperand.(*bpparser.Operator); ok {
-			return "global", value, nil
-		}
-
-		if variable, ok := firstOperand.(*bpparser.Variable); !ok || variable.Name != "LOCAL_PATH" {
-			return "global", value, nil
-		}
-
-		local := secondOperand
-		if s, ok := secondOperand.(*bpparser.String); ok {
-			if strings.HasPrefix(s.Value, "/") {
-				s.Value = s.Value[1:]
-			}
-		}
-		return "local", local, nil
-	case *bpparser.String:
-		return "global", value, nil
-	default:
-		return "", nil, fmt.Errorf("classifyLocalOrGlobalPath expected a string, got %s", v.Type())
-
-	}
-}
-
-// splitAndAssign splits a Make list into components and then
-// creates the corresponding variable assignments.
-func splitAndAssign(ctx variableAssignmentContext, splitFunc listSplitFunc, namesByClassification map[string]string) error {
-	val, err := makeVariableToBlueprint(ctx.file, ctx.mkvalue, bpparser.ListType)
-	if err != nil {
-		return err
-	}
-
-	lists, err := splitBpList(val, splitFunc)
-	if err != nil {
-		return err
-	}
-
-	for _, nameClassification := range android.SortedStringKeys(namesByClassification) {
-		name := namesByClassification[nameClassification]
-		if component, ok := lists[nameClassification]; ok && !emptyList(component) {
-			err = setVariable(ctx.file, ctx.append, ctx.prefix, name, component, true)
-			if err != nil {
-				return err
-			}
-		}
-	}
-	return nil
-}
-
-func localIncludeDirs(ctx variableAssignmentContext) error {
-	return splitAndAssign(ctx, classifyLocalOrGlobalPath, map[string]string{"global": "include_dirs", "local": "local_include_dirs"})
-}
-
-func exportIncludeDirs(ctx variableAssignmentContext) error {
-	// Add any paths that could not be converted to local relative paths to export_include_dirs
-	// anyways, they will cause an error if they don't exist and can be fixed manually.
-	return splitAndAssign(ctx, classifyLocalOrGlobalPath, map[string]string{"global": "export_include_dirs", "local": "export_include_dirs"})
-}
-
-func local32BitOnly(ctx variableAssignmentContext) error {
-	val, err := makeVariableToBlueprint(ctx.file, ctx.mkvalue, bpparser.BoolType)
-	if err != nil {
-		return err
-	}
-	if val.(*bpparser.Bool).Value {
-		thirtyTwo := &bpparser.String{
-			Value: "32",
-		}
-		setVariable(ctx.file, false, ctx.prefix, "compile_multilib", thirtyTwo, true)
-	}
-	return nil
-}
-
-func localAidlIncludes(ctx variableAssignmentContext) error {
-	return splitAndAssign(ctx, classifyLocalOrGlobalPath, map[string]string{"global": "aidl.include_dirs", "local": "aidl.local_include_dirs"})
-}
-
-func localizePathList(attribute string) func(ctx variableAssignmentContext) error {
-	return func(ctx variableAssignmentContext) error {
-		paths, err := localizePaths(ctx)
-		if err == nil {
-			err = setVariable(ctx.file, ctx.append, ctx.prefix, attribute, paths, true)
-		}
-		return err
-	}
-}
-
-func localizePath(attribute string) func(ctx variableAssignmentContext) error {
-	return func(ctx variableAssignmentContext) error {
-		paths, err := localizePaths(ctx)
-		if err == nil {
-			pathList, ok := paths.(*bpparser.List)
-			if !ok {
-				panic("Expected list")
-			}
-			switch len(pathList.Values) {
-			case 0:
-				err = setVariable(ctx.file, ctx.append, ctx.prefix, attribute, &bpparser.List{}, true)
-			case 1:
-				err = setVariable(ctx.file, ctx.append, ctx.prefix, attribute, pathList.Values[0], true)
-			default:
-				err = fmt.Errorf("Expected single value for %s", attribute)
-			}
-		}
-		return err
-	}
-}
-
-// Convert the "full" paths (that is, from the top of the source tree) to the relative one
-// (from the directory containing the blueprint file) and set given attribute to it.
-// This is needed for some of makefile variables (e.g., LOCAL_RESOURCE_DIR).
-// At the moment only the paths of the `$(LOCAL_PATH)/foo/bar` format can be converted
-// (to `foo/bar` in this case) as we cannot convert a literal path without
-// knowing makefiles's location in the source tree. We just issue a warning in the latter case.
-func localizePaths(ctx variableAssignmentContext) (bpparser.Expression, error) {
-	bpvalue, err := makeVariableToBlueprint(ctx.file, ctx.mkvalue, bpparser.ListType)
-	var result bpparser.Expression
-	if err != nil {
-		return result, err
-	}
-	classifiedPaths, err := splitBpList(bpvalue, classifyLocalOrGlobalPath)
-	if err != nil {
-		return result, err
-	}
-	for pathClass, path := range classifiedPaths {
-		switch pathClass {
-		case "local":
-			result = path
-		default:
-			err = fmt.Errorf("Only $(LOCAL_PATH)/.. values are allowed")
-		}
-	}
-	return result, err
-}
-
-func stem(ctx variableAssignmentContext) error {
-	val, err := makeVariableToBlueprint(ctx.file, ctx.mkvalue, bpparser.StringType)
-	if err != nil {
-		return err
-	}
-	varName := "stem"
-
-	if exp, ok := val.(*bpparser.Operator); ok && exp.Operator == '+' {
-		if variable, ok := exp.Args[0].(*bpparser.Variable); ok && variable.Name == "LOCAL_MODULE" {
-			varName = "suffix"
-			val = exp.Args[1]
-		}
-	}
-
-	return setVariable(ctx.file, ctx.append, ctx.prefix, varName, val, true)
-}
-
-func hostOs(ctx variableAssignmentContext) error {
-	val, err := makeVariableToBlueprint(ctx.file, ctx.mkvalue, bpparser.ListType)
-	if err != nil {
-		return err
-	}
-
-	inList := func(s string) bool {
-		for _, v := range val.(*bpparser.List).Values {
-			if v.(*bpparser.String).Value == s {
-				return true
-			}
-		}
-		return false
-	}
-
-	falseValue := &bpparser.Bool{
-		Value: false,
-	}
-
-	trueValue := &bpparser.Bool{
-		Value: true,
-	}
-
-	if inList("windows") {
-		err = setVariable(ctx.file, ctx.append, "target.windows", "enabled", trueValue, true)
-	}
-
-	if !inList("linux") && err == nil {
-		err = setVariable(ctx.file, ctx.append, "target.linux_glibc", "enabled", falseValue, true)
-	}
-
-	if !inList("darwin") && err == nil {
-		err = setVariable(ctx.file, ctx.append, "target.darwin", "enabled", falseValue, true)
-	}
-
-	return err
-}
-
-func sanitize(sub string) func(ctx variableAssignmentContext) error {
-	return func(ctx variableAssignmentContext) error {
-		val, err := makeVariableToBlueprint(ctx.file, ctx.mkvalue, bpparser.ListType)
-		if err != nil {
-			return err
-		}
-
-		if _, ok := val.(*bpparser.List); !ok {
-			return fmt.Errorf("unsupported sanitize expression")
-		}
-
-		misc := &bpparser.List{}
-
-		for _, v := range val.(*bpparser.List).Values {
-			switch v := v.(type) {
-			case *bpparser.Variable, *bpparser.Operator:
-				ctx.file.errorf(ctx.mkvalue, "unsupported sanitize expression")
-			case *bpparser.String:
-				switch v.Value {
-				case "never", "address", "fuzzer", "thread", "undefined", "cfi":
-					bpTrue := &bpparser.Bool{
-						Value: true,
-					}
-					err = setVariable(ctx.file, false, ctx.prefix, "sanitize."+sub+v.Value, bpTrue, true)
-					if err != nil {
-						return err
-					}
-				default:
-					misc.Values = append(misc.Values, v)
-				}
-			default:
-				return fmt.Errorf("sanitize expected a string, got %s", v.Type())
-			}
-		}
-
-		if len(misc.Values) > 0 {
-			err = setVariable(ctx.file, false, ctx.prefix, "sanitize."+sub+"misc_undefined", misc, true)
-			if err != nil {
-				return err
-			}
-		}
-
-		return err
-	}
-}
-
-func strip() func(ctx variableAssignmentContext) error {
-	return func(ctx variableAssignmentContext) error {
-		val, err := makeVariableToBlueprint(ctx.file, ctx.mkvalue, bpparser.StringType)
-		if err != nil {
-			return err
-		}
-
-		if _, ok := val.(*bpparser.String); !ok {
-			return fmt.Errorf("unsupported strip expression")
-		}
-
-		bpTrue := &bpparser.Bool{
-			Value: true,
-		}
-		v := val.(*bpparser.String).Value
-		sub := (map[string]string{"false": "none", "true": "all", "keep_symbols": "keep_symbols"})[v]
-		if sub == "" {
-			return fmt.Errorf("unexpected strip option: %s", v)
-		}
-		return setVariable(ctx.file, false, ctx.prefix, "strip."+sub, bpTrue, true)
-	}
-}
-
-func prebuiltClass(ctx variableAssignmentContext) error {
-	class := ctx.mkvalue.Value(ctx.file.scope)
-	if _, ok := prebuiltTypes[class]; ok {
-		ctx.file.scope.Set("BUILD_PREBUILT", class)
-	} else {
-		// reset to default
-		ctx.file.scope.Set("BUILD_PREBUILT", "prebuilt")
-	}
-	return nil
-}
-
-func makeBlueprintStringAssignment(file *bpFile, prefix string, suffix string, value string) error {
-	val, err := makeVariableToBlueprint(file, mkparser.SimpleMakeString(value, mkparser.NoPos), bpparser.StringType)
-	if err == nil {
-		err = setVariable(file, false, prefix, suffix, val, true)
-	}
-	return err
-}
-
-// If variable is a literal variable name, return the name, otherwise return ""
-func varLiteralName(variable mkparser.Variable) string {
-	if len(variable.Name.Variables) == 0 {
-		return variable.Name.Strings[0]
-	}
-	return ""
-}
-
-func prebuiltModulePath(ctx variableAssignmentContext) error {
-	// Cannot handle appending
-	if ctx.append {
-		return fmt.Errorf("Cannot handle appending to LOCAL_MODULE_PATH")
-	}
-	// Analyze value in order to set the correct values for the 'device_specific',
-	// 'product_specific', 'system_ext_specific' 'vendor'/'soc_specific',
-	// 'system_ext_specific' attribute. Two cases are allowed:
-	//   $(VAR)/<literal-value>
-	//   $(PRODUCT_OUT)/$(TARGET_COPY_OUT_VENDOR)/<literal-value>
-	// The last case is equivalent to $(TARGET_OUT_VENDOR)/<literal-value>
-	// Map the variable name if present to `local_module_path_var`
-	// Map literal-path to local_module_path_fixed
-	varname := ""
-	fixed := ""
-	val := ctx.mkvalue
-	if len(val.Variables) == 1 && varLiteralName(val.Variables[0]) != "" && len(val.Strings) == 2 && val.Strings[0] == "" {
-		fixed = val.Strings[1]
-		varname = val.Variables[0].Name.Strings[0]
-	} else if len(val.Variables) == 2 && varLiteralName(val.Variables[0]) == "PRODUCT_OUT" && varLiteralName(val.Variables[1]) == "TARGET_COPY_OUT_VENDOR" &&
-		len(val.Strings) == 3 && val.Strings[0] == "" && val.Strings[1] == "/" {
-		fixed = val.Strings[2]
-		varname = "TARGET_OUT_VENDOR"
-	} else {
-		return fmt.Errorf("LOCAL_MODULE_PATH value should start with $(<some-varaible>)/ or $(PRODUCT_OUT)/$(TARGET_COPY_VENDOR)/")
-	}
-	err := makeBlueprintStringAssignment(ctx.file, "local_module_path", "var", varname)
-	if err == nil && fixed != "" {
-		err = makeBlueprintStringAssignment(ctx.file, "local_module_path", "fixed", fixed)
-	}
-	return err
-}
-
-func ldflags(ctx variableAssignmentContext) error {
-	val, err := makeVariableToBlueprint(ctx.file, ctx.mkvalue, bpparser.ListType)
-	if err != nil {
-		return err
-	}
-
-	lists, err := splitBpList(val, func(value bpparser.Expression) (string, bpparser.Expression, error) {
-		// Anything other than "-Wl,--version_script," + LOCAL_PATH + "<path>" matches ldflags
-		exp1, ok := value.(*bpparser.Operator)
-		if !ok {
-			return "ldflags", value, nil
-		}
-
-		exp2, ok := exp1.Args[0].(*bpparser.Operator)
-		if !ok {
-			return "ldflags", value, nil
-		}
-
-		if s, ok := exp2.Args[0].(*bpparser.String); !ok || s.Value != "-Wl,--version-script," {
-			return "ldflags", value, nil
-		}
-
-		if v, ok := exp2.Args[1].(*bpparser.Variable); !ok || v.Name != "LOCAL_PATH" {
-			ctx.file.errorf(ctx.mkvalue, "Unrecognized version-script")
-			return "ldflags", value, nil
-		}
-
-		s, ok := exp1.Args[1].(*bpparser.String)
-		if !ok {
-			ctx.file.errorf(ctx.mkvalue, "Unrecognized version-script")
-			return "ldflags", value, nil
-		}
-
-		s.Value = strings.TrimPrefix(s.Value, "/")
-
-		return "version", s, nil
-	})
-	if err != nil {
-		return err
-	}
-
-	if ldflags, ok := lists["ldflags"]; ok && !emptyList(ldflags) {
-		err = setVariable(ctx.file, ctx.append, ctx.prefix, "ldflags", ldflags, true)
-		if err != nil {
-			return err
-		}
-	}
-
-	if version_script, ok := lists["version"]; ok && !emptyList(version_script) {
-		if len(version_script.(*bpparser.List).Values) > 1 {
-			ctx.file.errorf(ctx.mkvalue, "multiple version scripts found?")
-		}
-		err = setVariable(ctx.file, false, ctx.prefix, "version_script", version_script.(*bpparser.List).Values[0], true)
-		if err != nil {
-			return err
-		}
-	}
-
-	return nil
-}
-
-func cflags(ctx variableAssignmentContext) error {
-	// The Soong replacement for CFLAGS doesn't need the same extra escaped quotes that were present in Make
-	ctx.mkvalue = ctx.mkvalue.Clone()
-	ctx.mkvalue.ReplaceLiteral(`\"`, `"`)
-	return includeVariableNow(bpVariable{"cflags", bpparser.ListType}, ctx)
-}
-
-func proguardEnabled(ctx variableAssignmentContext) error {
-	val, err := makeVariableToBlueprint(ctx.file, ctx.mkvalue, bpparser.ListType)
-	if err != nil {
-		return err
-	}
-
-	list, ok := val.(*bpparser.List)
-	if !ok {
-		return fmt.Errorf("unsupported proguard expression")
-	}
-
-	set := func(prop string, value bool) {
-		bpValue := &bpparser.Bool{
-			Value: value,
-		}
-		setVariable(ctx.file, false, ctx.prefix, prop, bpValue, true)
-	}
-
-	enable := false
-
-	for _, v := range list.Values {
-		s, ok := v.(*bpparser.String)
-		if !ok {
-			return fmt.Errorf("unsupported proguard expression")
-		}
-
-		switch s.Value {
-		case "disabled":
-			set("optimize.enabled", false)
-		case "obfuscation":
-			enable = true
-			set("optimize.obfuscate", true)
-		case "optimization":
-			enable = true
-			set("optimize.optimize", true)
-		case "full":
-			enable = true
-		case "custom":
-			set("optimize.no_aapt_flags", true)
-			enable = true
-		default:
-			return fmt.Errorf("unsupported proguard value %q", s)
-		}
-	}
-
-	if enable {
-		// This is only necessary for libraries which default to false, but we can't
-		// tell the difference between a library and an app here.
-		set("optimize.enabled", true)
-	}
-
-	return nil
-}
-
-func invert(name string) func(ctx variableAssignmentContext) error {
-	return func(ctx variableAssignmentContext) error {
-		val, err := makeVariableToBlueprint(ctx.file, ctx.mkvalue, bpparser.BoolType)
-		if err != nil {
-			return err
-		}
-
-		val.(*bpparser.Bool).Value = !val.(*bpparser.Bool).Value
-
-		return setVariable(ctx.file, ctx.append, ctx.prefix, name, val, true)
-	}
-}
-
-// given a conditional, returns a function that will insert a variable assignment or not, based on the conditional
-func includeVariableIf(bpVar bpVariable, conditional func(ctx variableAssignmentContext) bool) func(ctx variableAssignmentContext) error {
-	return func(ctx variableAssignmentContext) error {
-		var err error
-		if conditional(ctx) {
-			err = includeVariableNow(bpVar, ctx)
-		}
-		return err
-	}
-}
-
-// given a variable, returns a function that will always insert a variable assignment
-func includeVariable(bpVar bpVariable) func(ctx variableAssignmentContext) error {
-	return includeVariableIf(bpVar, always)
-}
-
-func includeVariableNow(bpVar bpVariable, ctx variableAssignmentContext) error {
-	var val bpparser.Expression
-	var err error
-	val, err = makeVariableToBlueprint(ctx.file, ctx.mkvalue, bpVar.variableType)
-	if err == nil {
-		err = setVariable(ctx.file, ctx.append, ctx.prefix, bpVar.name, val, true)
-	}
-	return err
-}
-
-// given a function that returns a bool, returns a function that returns the opposite
-func not(conditional func(ctx variableAssignmentContext) bool) func(ctx variableAssignmentContext) bool {
-	return func(ctx variableAssignmentContext) bool {
-		return !conditional(ctx)
-	}
-}
-
-// returns a function that tells whether mkvalue.Dump equals the given query string
-func valueDumpEquals(textToMatch string) func(ctx variableAssignmentContext) bool {
-	return func(ctx variableAssignmentContext) bool {
-		return (ctx.mkvalue.Dump() == textToMatch)
-	}
-}
-
-func always(ctx variableAssignmentContext) bool {
-	return true
-}
-
-func skip(ctx variableAssignmentContext) error {
-	return nil
-}
-
-// Shorter suffixes of other suffixes must be at the end of the list
-var propertyPrefixes = []struct{ mk, bp string }{
-	{"arm", "arch.arm"},
-	{"arm64", "arch.arm64"},
-	{"mips", "arch.mips"},
-	{"mips64", "arch.mips64"},
-	{"x86", "arch.x86"},
-	{"x86_64", "arch.x86_64"},
-	{"32", "multilib.lib32"},
-	// 64 must be after x86_64
-	{"64", "multilib.lib64"},
-	{"darwin", "target.darwin"},
-	{"linux", "target.linux_glibc"},
-	{"windows", "target.windows"},
-}
-
-var conditionalTranslations = map[string]map[bool]string{
-	"($(HOST_OS),darwin)": {
-		true:  "target.darwin",
-		false: "target.not_darwin"},
-	"($(HOST_OS), darwin)": {
-		true:  "target.darwin",
-		false: "target.not_darwin"},
-	"($(HOST_OS),windows)": {
-		true:  "target.windows",
-		false: "target.not_windows"},
-	"($(HOST_OS), windows)": {
-		true:  "target.windows",
-		false: "target.not_windows"},
-	"($(HOST_OS),linux)": {
-		true:  "target.linux_glibc",
-		false: "target.not_linux_glibc"},
-	"($(HOST_OS), linux)": {
-		true:  "target.linux_glibc",
-		false: "target.not_linux_glibc"},
-	"($(BUILD_OS),darwin)": {
-		true:  "target.darwin",
-		false: "target.not_darwin"},
-	"($(BUILD_OS), darwin)": {
-		true:  "target.darwin",
-		false: "target.not_darwin"},
-	"($(BUILD_OS),linux)": {
-		true:  "target.linux_glibc",
-		false: "target.not_linux_glibc"},
-	"($(BUILD_OS), linux)": {
-		true:  "target.linux_glibc",
-		false: "target.not_linux_glibc"},
-	"(,$(TARGET_BUILD_APPS))": {
-		false: "product_variables.unbundled_build"},
-	"($(TARGET_BUILD_APPS),)": {
-		false: "product_variables.unbundled_build"},
-	"($(TARGET_BUILD_PDK),true)": {
-		true: "product_variables.pdk"},
-	"($(TARGET_BUILD_PDK), true)": {
-		true: "product_variables.pdk"},
-}
-
-func mydir(args []string) []string {
-	return []string{"."}
-}
-
-func allFilesUnder(wildcard string) func(args []string) []string {
-	return func(args []string) []string {
-		dirs := []string{""}
-		if len(args) > 0 {
-			dirs = strings.Fields(args[0])
-		}
-
-		paths := make([]string, len(dirs))
-		for i := range paths {
-			paths[i] = fmt.Sprintf("%s/**/"+wildcard, dirs[i])
-		}
-		return paths
-	}
-}
-
-func allSubdirJavaFiles(args []string) []string {
-	return []string{"**/*.java"}
-}
-
-func includeIgnored(args []string) []string {
-	return []string{include_ignored}
-}
-
-var moduleTypes = map[string]string{
-	"BUILD_SHARED_LIBRARY":        "cc_library_shared",
-	"BUILD_STATIC_LIBRARY":        "cc_library_static",
-	"BUILD_HOST_SHARED_LIBRARY":   "cc_library_host_shared",
-	"BUILD_HOST_STATIC_LIBRARY":   "cc_library_host_static",
-	"BUILD_HEADER_LIBRARY":        "cc_library_headers",
-	"BUILD_EXECUTABLE":            "cc_binary",
-	"BUILD_HOST_EXECUTABLE":       "cc_binary_host",
-	"BUILD_NATIVE_TEST":           "cc_test",
-	"BUILD_HOST_NATIVE_TEST":      "cc_test_host",
-	"BUILD_NATIVE_BENCHMARK":      "cc_benchmark",
-	"BUILD_HOST_NATIVE_BENCHMARK": "cc_benchmark_host",
-
-	"BUILD_JAVA_LIBRARY":             "java_library_installable", // will be rewritten to java_library by bpfix
-	"BUILD_STATIC_JAVA_LIBRARY":      "java_library",
-	"BUILD_HOST_JAVA_LIBRARY":        "java_library_host",
-	"BUILD_HOST_DALVIK_JAVA_LIBRARY": "java_library_host_dalvik",
-	"BUILD_PACKAGE":                  "android_app",
-
-	"BUILD_CTS_EXECUTABLE":          "cc_binary",               // will be further massaged by bpfix depending on the output path
-	"BUILD_CTS_SUPPORT_PACKAGE":     "cts_support_package",     // will be rewritten to android_test by bpfix
-	"BUILD_CTS_PACKAGE":             "cts_package",             // will be rewritten to android_test by bpfix
-	"BUILD_CTS_TARGET_JAVA_LIBRARY": "cts_target_java_library", // will be rewritten to java_library by bpfix
-	"BUILD_CTS_HOST_JAVA_LIBRARY":   "cts_host_java_library",   // will be rewritten to java_library_host by bpfix
-}
-
-var prebuiltTypes = map[string]string{
-	"SHARED_LIBRARIES": "cc_prebuilt_library_shared",
-	"STATIC_LIBRARIES": "cc_prebuilt_library_static",
-	"EXECUTABLES":      "cc_prebuilt_binary",
-	"JAVA_LIBRARIES":   "java_import",
-	"APPS":             "android_app_import",
-	"ETC":              "prebuilt_etc",
-}
-
-var soongModuleTypes = map[string]bool{}
-
-var includePathToModule = map[string]string{
-	"test/vts/tools/build/Android.host_config.mk": "vts_config",
-	// The rest will be populated dynamically in androidScope below
-}
-
-func mapIncludePath(path string) (string, bool) {
-	if path == clear_vars || path == include_ignored {
-		return path, true
-	}
-	module, ok := includePathToModule[path]
-	return module, ok
-}
-
-func androidScope() mkparser.Scope {
-	globalScope := mkparser.NewScope(nil)
-	globalScope.Set("CLEAR_VARS", clear_vars)
-	globalScope.SetFunc("my-dir", mydir)
-	globalScope.SetFunc("all-java-files-under", allFilesUnder("*.java"))
-	globalScope.SetFunc("all-proto-files-under", allFilesUnder("*.proto"))
-	globalScope.SetFunc("all-aidl-files-under", allFilesUnder("*.aidl"))
-	globalScope.SetFunc("all-Iaidl-files-under", allFilesUnder("I*.aidl"))
-	globalScope.SetFunc("all-logtags-files-under", allFilesUnder("*.logtags"))
-	globalScope.SetFunc("all-subdir-java-files", allSubdirJavaFiles)
-	globalScope.SetFunc("all-makefiles-under", includeIgnored)
-	globalScope.SetFunc("first-makefiles-under", includeIgnored)
-	globalScope.SetFunc("all-named-subdir-makefiles", includeIgnored)
-	globalScope.SetFunc("all-subdir-makefiles", includeIgnored)
-
-	// The scope maps each known variable to a path, and then includePathToModule maps a path
-	// to a module. We don't care what the actual path value is so long as the value in scope
-	// is mapped, so we might as well use variable name as key, too.
-	for varName, moduleName := range moduleTypes {
-		path := varName
-		globalScope.Set(varName, path)
-		includePathToModule[path] = moduleName
-	}
-	for varName, moduleName := range prebuiltTypes {
-		includePathToModule[varName] = moduleName
-	}
-
-	return globalScope
-}
diff --git a/androidmk/cmd/androidmk/androidmk.go b/androidmk/cmd/androidmk/androidmk.go
deleted file mode 100644
index d2a84d1..0000000
--- a/androidmk/cmd/androidmk/androidmk.go
+++ /dev/null
@@ -1,474 +0,0 @@
-// Copyright 2017 Google Inc. All rights reserved.
-//
-// 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 main
-
-import (
-	"bytes"
-	"flag"
-	"fmt"
-	"io/ioutil"
-	"os"
-	"strings"
-	"text/scanner"
-
-	"android/soong/bpfix/bpfix"
-
-	mkparser "android/soong/androidmk/parser"
-
-	bpparser "github.com/google/blueprint/parser"
-)
-
-var usage = func() {
-	fmt.Fprintf(os.Stderr, "usage: androidmk [flags] <inputFile>\n"+
-		"\nandroidmk parses <inputFile> as an Android.mk file and attempts to output an analogous Android.bp file (to standard out)\n")
-	flag.PrintDefaults()
-	os.Exit(1)
-}
-
-// TODO: non-expanded variables with expressions
-
-type bpFile struct {
-	comments          []*bpparser.CommentGroup
-	defs              []bpparser.Definition
-	localAssignments  map[string]*bpparser.Property
-	globalAssignments map[string]*bpparser.Expression
-	scope             mkparser.Scope
-	module            *bpparser.Module
-
-	mkPos scanner.Position // Position of the last handled line in the makefile
-	bpPos scanner.Position // Position of the last emitted line to the blueprint file
-
-	inModule bool
-}
-
-func (f *bpFile) insertComment(s string) {
-	f.comments = append(f.comments, &bpparser.CommentGroup{
-		Comments: []*bpparser.Comment{
-			&bpparser.Comment{
-				Comment: []string{s},
-				Slash:   f.bpPos,
-			},
-		},
-	})
-	f.bpPos.Offset += len(s)
-}
-
-func (f *bpFile) insertExtraComment(s string) {
-	f.insertComment(s)
-	f.bpPos.Line++
-}
-
-// records that the given node failed to be converted and includes an explanatory message
-func (f *bpFile) errorf(failedNode mkparser.Node, message string, args ...interface{}) {
-	orig := failedNode.Dump()
-	message = fmt.Sprintf(message, args...)
-	f.addErrorText(fmt.Sprintf("// ANDROIDMK TRANSLATION ERROR: %s", message))
-
-	lines := strings.Split(orig, "\n")
-	for _, l := range lines {
-		f.insertExtraComment("// " + l)
-	}
-}
-
-// records that something unexpected occurred
-func (f *bpFile) warnf(message string, args ...interface{}) {
-	message = fmt.Sprintf(message, args...)
-	f.addErrorText(fmt.Sprintf("// ANDROIDMK TRANSLATION WARNING: %s", message))
-}
-
-// adds the given error message as-is to the bottom of the (in-progress) file
-func (f *bpFile) addErrorText(message string) {
-	f.insertExtraComment(message)
-}
-
-func (f *bpFile) setMkPos(pos, end scanner.Position) {
-	// It is unusual but not forbidden for pos.Line to be smaller than f.mkPos.Line
-	// For example:
-	//
-	// if true                       # this line is emitted 1st
-	// if true                       # this line is emitted 2nd
-	// some-target: some-file        # this line is emitted 3rd
-	//         echo doing something  # this recipe is emitted 6th
-	// endif #some comment           # this endif is emitted 4th; this comment is part of the recipe
-	//         echo doing more stuff # this is part of the recipe
-	// endif                         # this endif is emitted 5th
-	//
-	// However, if pos.Line < f.mkPos.Line, we treat it as though it were equal
-	if pos.Line >= f.mkPos.Line {
-		f.bpPos.Line += (pos.Line - f.mkPos.Line)
-		f.mkPos = end
-	}
-
-}
-
-type conditional struct {
-	cond string
-	eq   bool
-}
-
-func main() {
-	flag.Usage = usage
-	flag.Parse()
-	if len(flag.Args()) != 1 {
-		usage()
-	}
-	filePathToRead := flag.Arg(0)
-	b, err := ioutil.ReadFile(filePathToRead)
-	if err != nil {
-		fmt.Println(err.Error())
-		return
-	}
-
-	output, errs := convertFile(os.Args[1], bytes.NewBuffer(b))
-	if len(errs) > 0 {
-		for _, err := range errs {
-			fmt.Fprintln(os.Stderr, "ERROR: ", err)
-		}
-		os.Exit(1)
-	}
-
-	fmt.Print(output)
-}
-
-func convertFile(filename string, buffer *bytes.Buffer) (string, []error) {
-	p := mkparser.NewParser(filename, buffer)
-
-	nodes, errs := p.Parse()
-	if len(errs) > 0 {
-		return "", errs
-	}
-
-	file := &bpFile{
-		scope:             androidScope(),
-		localAssignments:  make(map[string]*bpparser.Property),
-		globalAssignments: make(map[string]*bpparser.Expression),
-	}
-
-	var conds []*conditional
-	var assignmentCond *conditional
-
-	for _, node := range nodes {
-		file.setMkPos(p.Unpack(node.Pos()), p.Unpack(node.End()))
-
-		switch x := node.(type) {
-		case *mkparser.Comment:
-			file.insertComment("//" + x.Comment)
-		case *mkparser.Assignment:
-			handleAssignment(file, x, assignmentCond)
-		case *mkparser.Directive:
-			switch x.Name {
-			case "include", "-include":
-				module, ok := mapIncludePath(x.Args.Value(file.scope))
-				if !ok {
-					file.errorf(x, "unsupported include")
-					continue
-				}
-				switch module {
-				case clear_vars:
-					resetModule(file)
-				case include_ignored:
-					// subdirs are already automatically included in Soong
-					continue
-				default:
-					handleModuleConditionals(file, x, conds)
-					makeModule(file, module)
-				}
-			case "ifeq", "ifneq", "ifdef", "ifndef":
-				args := x.Args.Dump()
-				eq := x.Name == "ifeq" || x.Name == "ifdef"
-				if _, ok := conditionalTranslations[args]; ok {
-					newCond := conditional{args, eq}
-					conds = append(conds, &newCond)
-					if file.inModule {
-						if assignmentCond == nil {
-							assignmentCond = &newCond
-						} else {
-							file.errorf(x, "unsupported nested conditional in module")
-						}
-					}
-				} else {
-					file.errorf(x, "unsupported conditional")
-					conds = append(conds, nil)
-					continue
-				}
-			case "else":
-				if len(conds) == 0 {
-					file.errorf(x, "missing if before else")
-					continue
-				} else if conds[len(conds)-1] == nil {
-					file.errorf(x, "else from unsupported conditional")
-					continue
-				}
-				conds[len(conds)-1].eq = !conds[len(conds)-1].eq
-			case "endif":
-				if len(conds) == 0 {
-					file.errorf(x, "missing if before endif")
-					continue
-				} else if conds[len(conds)-1] == nil {
-					file.errorf(x, "endif from unsupported conditional")
-					conds = conds[:len(conds)-1]
-				} else {
-					if assignmentCond == conds[len(conds)-1] {
-						assignmentCond = nil
-					}
-					conds = conds[:len(conds)-1]
-				}
-			default:
-				file.errorf(x, "unsupported directive")
-				continue
-			}
-		default:
-			file.errorf(x, "unsupported line")
-		}
-	}
-
-	tree := &bpparser.File{
-		Defs:     file.defs,
-		Comments: file.comments,
-	}
-
-	// check for common supported but undesirable structures and clean them up
-	fixer := bpfix.NewFixer(tree)
-	tree, err := fixer.Fix(bpfix.NewFixRequest().AddAll())
-	if err != nil {
-		return "", []error{err}
-	}
-
-	out, err := bpparser.Print(tree)
-	if err != nil {
-		return "", []error{err}
-	}
-
-	return string(out), nil
-}
-
-func handleAssignment(file *bpFile, assignment *mkparser.Assignment, c *conditional) {
-	if !assignment.Name.Const() {
-		file.errorf(assignment, "unsupported non-const variable name")
-		return
-	}
-
-	if assignment.Target != nil {
-		file.errorf(assignment, "unsupported target assignment")
-		return
-	}
-
-	name := assignment.Name.Value(nil)
-	prefix := ""
-
-	if strings.HasPrefix(name, "LOCAL_") {
-		for _, x := range propertyPrefixes {
-			if strings.HasSuffix(name, "_"+x.mk) {
-				name = strings.TrimSuffix(name, "_"+x.mk)
-				prefix = x.bp
-				break
-			}
-		}
-
-		if c != nil {
-			if prefix != "" {
-				file.errorf(assignment, "prefix assignment inside conditional, skipping conditional")
-			} else {
-				var ok bool
-				if prefix, ok = conditionalTranslations[c.cond][c.eq]; !ok {
-					panic("unknown conditional")
-				}
-			}
-		}
-	} else {
-		if c != nil {
-			eq := "eq"
-			if !c.eq {
-				eq = "neq"
-			}
-			file.errorf(assignment, "conditional %s %s on global assignment", eq, c.cond)
-		}
-	}
-
-	appendVariable := assignment.Type == "+="
-
-	var err error
-	if prop, ok := rewriteProperties[name]; ok {
-		err = prop(variableAssignmentContext{file, prefix, assignment.Value, appendVariable})
-	} else {
-		switch {
-		case name == "LOCAL_ARM_MODE":
-			// This is a hack to get the LOCAL_ARM_MODE value inside
-			// of an arch: { arm: {} } block.
-			armModeAssign := assignment
-			armModeAssign.Name = mkparser.SimpleMakeString("LOCAL_ARM_MODE_HACK_arm", assignment.Name.Pos())
-			handleAssignment(file, armModeAssign, c)
-		case strings.HasPrefix(name, "LOCAL_"):
-			file.errorf(assignment, "unsupported assignment to %s", name)
-			return
-		default:
-			var val bpparser.Expression
-			val, err = makeVariableToBlueprint(file, assignment.Value, bpparser.ListType)
-			if err == nil {
-				err = setVariable(file, appendVariable, prefix, name, val, false)
-			}
-		}
-	}
-	if err != nil {
-		file.errorf(assignment, err.Error())
-	}
-}
-
-func handleModuleConditionals(file *bpFile, directive *mkparser.Directive, conds []*conditional) {
-	for _, c := range conds {
-		if c == nil {
-			continue
-		}
-
-		if _, ok := conditionalTranslations[c.cond]; !ok {
-			panic("unknown conditional " + c.cond)
-		}
-
-		disabledPrefix := conditionalTranslations[c.cond][!c.eq]
-
-		// Create a fake assignment with enabled = false
-		val, err := makeVariableToBlueprint(file, mkparser.SimpleMakeString("false", mkparser.NoPos), bpparser.BoolType)
-		if err == nil {
-			err = setVariable(file, false, disabledPrefix, "enabled", val, true)
-		}
-		if err != nil {
-			file.errorf(directive, err.Error())
-		}
-	}
-}
-
-func makeModule(file *bpFile, t string) {
-	file.module.Type = t
-	file.module.TypePos = file.module.LBracePos
-	file.module.RBracePos = file.bpPos
-	file.defs = append(file.defs, file.module)
-	file.inModule = false
-}
-
-func resetModule(file *bpFile) {
-	file.module = &bpparser.Module{}
-	file.module.LBracePos = file.bpPos
-	file.localAssignments = make(map[string]*bpparser.Property)
-	file.inModule = true
-}
-
-func makeVariableToBlueprint(file *bpFile, val *mkparser.MakeString,
-	typ bpparser.Type) (bpparser.Expression, error) {
-
-	var exp bpparser.Expression
-	var err error
-	switch typ {
-	case bpparser.ListType:
-		exp, err = makeToListExpression(val, file.scope)
-	case bpparser.StringType:
-		exp, err = makeToStringExpression(val, file.scope)
-	case bpparser.BoolType:
-		exp, err = makeToBoolExpression(val)
-	default:
-		panic("unknown type")
-	}
-
-	if err != nil {
-		return nil, err
-	}
-
-	return exp, nil
-}
-
-func setVariable(file *bpFile, plusequals bool, prefix, name string, value bpparser.Expression, local bool) error {
-
-	if prefix != "" {
-		name = prefix + "." + name
-	}
-
-	pos := file.bpPos
-
-	var oldValue *bpparser.Expression
-	if local {
-		oldProp := file.localAssignments[name]
-		if oldProp != nil {
-			oldValue = &oldProp.Value
-		}
-	} else {
-		oldValue = file.globalAssignments[name]
-	}
-
-	if local {
-		if oldValue != nil && plusequals {
-			val, err := addValues(*oldValue, value)
-			if err != nil {
-				return fmt.Errorf("unsupported addition: %s", err.Error())
-			}
-			val.(*bpparser.Operator).OperatorPos = pos
-			*oldValue = val
-		} else {
-			names := strings.Split(name, ".")
-			if file.module == nil {
-				file.warnf("No 'include $(CLEAR_VARS)' detected before first assignment; clearing vars now")
-				resetModule(file)
-			}
-			container := &file.module.Properties
-
-			for i, n := range names[:len(names)-1] {
-				fqn := strings.Join(names[0:i+1], ".")
-				prop := file.localAssignments[fqn]
-				if prop == nil {
-					prop = &bpparser.Property{
-						Name:    n,
-						NamePos: pos,
-						Value: &bpparser.Map{
-							Properties: []*bpparser.Property{},
-						},
-					}
-					file.localAssignments[fqn] = prop
-					*container = append(*container, prop)
-				}
-				container = &prop.Value.(*bpparser.Map).Properties
-			}
-
-			prop := &bpparser.Property{
-				Name:    names[len(names)-1],
-				NamePos: pos,
-				Value:   value,
-			}
-			file.localAssignments[name] = prop
-			*container = append(*container, prop)
-		}
-	} else {
-		if oldValue != nil && plusequals {
-			a := &bpparser.Assignment{
-				Name:      name,
-				NamePos:   pos,
-				Value:     value,
-				OrigValue: value,
-				EqualsPos: pos,
-				Assigner:  "+=",
-			}
-			file.defs = append(file.defs, a)
-		} else {
-			a := &bpparser.Assignment{
-				Name:      name,
-				NamePos:   pos,
-				Value:     value,
-				OrigValue: value,
-				EqualsPos: pos,
-				Assigner:  "=",
-			}
-			file.globalAssignments[name] = &a.Value
-			file.defs = append(file.defs, a)
-		}
-	}
-	return nil
-}
diff --git a/androidmk/cmd/androidmk/androidmk_test.go b/androidmk/cmd/androidmk/androidmk_test.go
deleted file mode 100644
index dbb7fde..0000000
--- a/androidmk/cmd/androidmk/androidmk_test.go
+++ /dev/null
@@ -1,1363 +0,0 @@
-// Copyright 2016 Google Inc. All rights reserved.
-//
-// 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 main
-
-import (
-	"bytes"
-	"fmt"
-	"strings"
-	"testing"
-
-	"android/soong/bpfix/bpfix"
-)
-
-var testCases = []struct {
-	desc     string
-	in       string
-	expected string
-}{
-	{
-		desc: "basic cc_library_shared with comments",
-		in: `
-#
-# Copyright
-#
-
-# Module Comment
-include $(CLEAR_VARS)
-# Name Comment
-LOCAL_MODULE := test
-# Source comment
-LOCAL_SRC_FILES_EXCLUDE := a.c
-# Second source comment
-LOCAL_SRC_FILES_EXCLUDE += b.c
-include $(BUILD_SHARED_LIBRARY)`,
-		expected: `
-//
-// Copyright
-//
-
-// Module Comment
-cc_library_shared {
-    // Name Comment
-    name: "test",
-    // Source comment
-    exclude_srcs: ["a.c"] + ["b.c"], // Second source comment
-
-}`,
-	},
-	{
-		desc: "split local/global include_dirs (1)",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_C_INCLUDES := $(LOCAL_PATH)
-include $(BUILD_SHARED_LIBRARY)`,
-		expected: `
-cc_library_shared {
-    local_include_dirs: ["."],
-}`,
-	},
-	{
-		desc: "split local/global include_dirs (2)",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
-include $(BUILD_SHARED_LIBRARY)`,
-		expected: `
-cc_library_shared {
-    local_include_dirs: ["include"],
-}`,
-	},
-	{
-		desc: "split local/global include_dirs (3)",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_C_INCLUDES := system/core/include
-include $(BUILD_SHARED_LIBRARY)`,
-		expected: `
-cc_library_shared {
-    include_dirs: ["system/core/include"],
-}`,
-	},
-	{
-		desc: "split local/global include_dirs (4)",
-		in: `
-input := testing/include
-include $(CLEAR_VARS)
-# Comment 1
-LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/include system/core/include $(input)
-# Comment 2
-LOCAL_C_INCLUDES += $(TOP)/system/core/include $(LOCAL_PATH)/test/include
-# Comment 3
-include $(BUILD_SHARED_LIBRARY)`,
-		expected: `
-input = ["testing/include"]
-cc_library_shared {
-    // Comment 1
-    include_dirs: ["system/core/include"] + input + ["system/core/include"], // Comment 2
-    local_include_dirs: ["."] + ["include"] + ["test/include"],
-    // Comment 3
-}`,
-	},
-	{
-		desc: "Convert to local path",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res $(LOCAL_PATH)/res2
-LOCAL_ASSET_DIR := $(LOCAL_PATH)/asset
-LOCAL_JARJAR_RULES := $(LOCAL_PATH)/jarjar-rules.txt
-include $(BUILD_PACKAGE)
-	`,
-		expected: `
-android_app {
-	resource_dirs: [
-		"res",
-		"res2",
-	],
-	asset_dirs: ["asset"],
-	jarjar_rules: "jarjar-rules.txt",
-}`,
-	},
-	{
-		desc: "LOCAL_MODULE_STEM",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := libtest
-LOCAL_MODULE_STEM := $(LOCAL_MODULE).so
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libtest2
-LOCAL_MODULE_STEM := testing.so
-include $(BUILD_SHARED_LIBRARY)
-`,
-		expected: `
-cc_library_shared {
-    name: "libtest",
-    suffix: ".so",
-}
-
-cc_library_shared {
-    name: "libtest2",
-    stem: "testing.so",
-}
-`,
-	},
-	{
-		desc: "LOCAL_MODULE_HOST_OS",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := libtest
-LOCAL_MODULE_HOST_OS := linux darwin windows
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libtest2
-LOCAL_MODULE_HOST_OS := linux
-include $(BUILD_SHARED_LIBRARY)
-`,
-		expected: `
-cc_library_shared {
-    name: "libtest",
-    target: {
-        windows: {
-            enabled: true,
-        }
-    }
-}
-
-cc_library_shared {
-    name: "libtest2",
-    target: {
-        darwin: {
-            enabled: false,
-        }
-    }
-}
-`,
-	},
-	{
-		desc: "LOCAL_RTTI_VALUE",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := libtest
-LOCAL_RTTI_FLAG := # Empty flag
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libtest2
-LOCAL_RTTI_FLAG := -frtti
-include $(BUILD_SHARED_LIBRARY)
-`,
-		expected: `
-cc_library_shared {
-    name: "libtest",
-    rtti: false, // Empty flag
-}
-
-cc_library_shared {
-    name: "libtest2",
-    rtti: true,
-}
-`,
-	},
-	{
-		desc: "LOCAL_ARM_MODE",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_ARM_MODE := arm
-include $(BUILD_SHARED_LIBRARY)
-`,
-		expected: `
-cc_library_shared {
-    arch: {
-        arm: {
-            instruction_set: "arm",
-        },
-    },
-}
-`,
-	},
-	{
-		desc: "_<OS> suffixes",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES_darwin := darwin.c
-LOCAL_SRC_FILES_linux := linux.c
-LOCAL_SRC_FILES_windows := windows.c
-include $(BUILD_SHARED_LIBRARY)
-`,
-		expected: `
-cc_library_shared {
-    target: {
-        darwin: {
-            srcs: ["darwin.c"],
-        },
-        linux_glibc: {
-            srcs: ["linux.c"],
-        },
-        windows: {
-            srcs: ["windows.c"],
-        },
-    },
-}
-`,
-	},
-	{
-		desc: "LOCAL_SANITIZE := never",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_SANITIZE := never
-include $(BUILD_SHARED_LIBRARY)
-`,
-		expected: `
-cc_library_shared {
-    sanitize: {
-        never: true,
-    },
-}
-`,
-	},
-	{
-		desc: "LOCAL_SANITIZE unknown parameter",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_SANITIZE := thread cfi asdf
-LOCAL_SANITIZE_DIAG := cfi
-LOCAL_SANITIZE_RECOVER := qwert
-include $(BUILD_SHARED_LIBRARY)
-`,
-		expected: `
-cc_library_shared {
-    sanitize: {
-        thread: true,
-        cfi: true,
-        misc_undefined: ["asdf"],
-        diag: {
-            cfi: true,
-        },
-        recover: ["qwert"],
-    },
-}
-`,
-	},
-	{
-		desc: "LOCAL_SANITIZE_RECOVER",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_SANITIZE_RECOVER := shift-exponent
-include $(BUILD_SHARED_LIBRARY)
-`,
-		expected: `
-cc_library_shared {
-    sanitize: {
-	recover: ["shift-exponent"],
-    },
-}
-`,
-	},
-	{
-		desc: "version_script in LOCAL_LDFLAGS",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_LDFLAGS := -Wl,--link-opt -Wl,--version-script,$(LOCAL_PATH)/exported32.map
-include $(BUILD_SHARED_LIBRARY)
-`,
-		expected: `
-cc_library_shared {
-    ldflags: ["-Wl,--link-opt"],
-    version_script: "exported32.map",
-}
-`,
-	},
-	{
-		desc: "Handle TOP",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_C_INCLUDES := $(TOP)/system/core/include $(TOP)
-include $(BUILD_SHARED_LIBRARY)
-`,
-		expected: `
-cc_library_shared {
-	include_dirs: ["system/core/include", "."],
-}
-`,
-	},
-	{
-		desc: "Remove LOCAL_MODULE_TAGS optional",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_SHARED_LIBRARY)
-`,
-
-		expected: `
-cc_library_shared {
-
-}
-`,
-	},
-	{
-		desc: "Warn for LOCAL_MODULE_TAGS non-optional",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := debug
-include $(BUILD_SHARED_LIBRARY)
-`,
-
-		expected: `
-cc_library_shared {
-	// WARNING: Module tags are not supported in Soong.
-	// Add this module to PRODUCT_PACKAGES_DEBUG in your product file if you want to
-	// force installation for -userdebug and -eng builds.
-}
-`,
-	},
-	{
-		desc: "Custom warning for LOCAL_MODULE_TAGS tests",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := debug tests
-include $(BUILD_SHARED_LIBRARY)
-`,
-
-		expected: `
-cc_library_shared {
-	// WARNING: Module tags are not supported in Soong.
-	// Add this module to PRODUCT_PACKAGES_DEBUG in your product file if you want to
-	// force installation for -userdebug and -eng builds.
-	// WARNING: Module tags are not supported in Soong.
-	// To make a shared library only for tests, use the "cc_test_library" module
-	// type. If you don't use gtest, set "gtest: false".
-}
-`,
-	},
-	{
-		desc: "Ignore LOCAL_MODULE_TAGS tests for cc_test",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := tests
-include $(BUILD_NATIVE_TEST)
-`,
-
-		expected: `
-cc_test {
-}
-`,
-	},
-	{
-		desc: "Convert LOCAL_MODULE_TAGS tests to java_test",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := tests
-include $(BUILD_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := tests
-include $(BUILD_PACKAGE)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := tests
-include $(BUILD_HOST_JAVA_LIBRARY)
-`,
-
-		expected: `
-java_test {
-}
-
-android_test {
-}
-
-java_test_host {
-}
-`,
-	},
-
-	{
-		desc: "Input containing escaped quotes",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE:= libsensorservice
-LOCAL_CFLAGS:= -DLOG_TAG=\"-DDontEscapeMe\"
-LOCAL_SRC_FILES := \"EscapeMe.cc\"
-include $(BUILD_SHARED_LIBRARY)
-`,
-
-		expected: `
-cc_library_shared {
-    name: "libsensorservice",
-    cflags: ["-DLOG_TAG=\"-DDontEscapeMe\""],
-    srcs: ["\\\"EscapeMe.cc\\\""],
-}
-`,
-	},
-	{
-
-		desc: "Don't fail on missing CLEAR_VARS",
-		in: `
-LOCAL_MODULE := iAmAModule
-include $(BUILD_SHARED_LIBRARY)`,
-
-		expected: `
-// ANDROIDMK TRANSLATION WARNING: No 'include $(CLEAR_VARS)' detected before first assignment; clearing vars now
-cc_library_shared {
-  name: "iAmAModule",
-
-}`,
-	},
-	{
-
-		desc: "LOCAL_AIDL_INCLUDES",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := iAmAModule
-LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/src/main/java system/core
-include $(BUILD_SHARED_LIBRARY)`,
-
-		expected: `
-cc_library_shared {
-  name: "iAmAModule",
-  aidl: {
-    include_dirs: ["system/core"],
-    local_include_dirs: ["src/main/java"],
-  }
-}`,
-	},
-	{
-		// the important part of this test case is that it confirms that androidmk doesn't
-		// panic in this case
-		desc: "multiple directives inside recipe",
-		in: `
-ifeq ($(a),true)
-ifeq ($(b),false)
-imABuildStatement: somefile
-	echo begin
-endif # a==true
-	echo middle
-endif # b==false
-	echo end
-`,
-		expected: `
-// ANDROIDMK TRANSLATION ERROR: unsupported conditional
-// ifeq ($(a),true)
-
-// ANDROIDMK TRANSLATION ERROR: unsupported conditional
-// ifeq ($(b),false)
-
-// ANDROIDMK TRANSLATION ERROR: unsupported line
-// rule:       imABuildStatement: somefile
-// echo begin
-//  # a==true
-// echo middle
-//  # b==false
-// echo end
-//
-// ANDROIDMK TRANSLATION ERROR: endif from unsupported conditional
-// endif
-// ANDROIDMK TRANSLATION ERROR: endif from unsupported conditional
-// endif
-		`,
-	},
-	{
-		desc: "ignore all-makefiles-under",
-		in: `
-include $(call all-makefiles-under,$(LOCAL_PATH))
-`,
-		expected: ``,
-	},
-	{
-		desc: "proguard options for java library",
-		in: `
-			include $(CLEAR_VARS)
-			# Empty
-			LOCAL_PROGUARD_ENABLED :=
-			# Disabled
-			LOCAL_PROGUARD_ENABLED := disabled
-			# Full
-			LOCAL_PROGUARD_ENABLED := full
-			# Obfuscation and optimization
-			LOCAL_PROGUARD_ENABLED := obfuscation optimization
-			# Custom
-			LOCAL_PROGUARD_ENABLED := custom
-			include $(BUILD_STATIC_JAVA_LIBRARY)
-		`,
-		expected: `
-			java_library {
-				// Empty
-
-				// Disabled
-				optimize: {
-					enabled: false,
-					// Full
-					enabled: true,
-					// Obfuscation and optimization
-					obfuscate: true,
-					optimize: true,
-					enabled: true,
-					// Custom
-					no_aapt_flags: true,
-					enabled: true,
-				},
-			}
-		`,
-	},
-	{
-		desc: "java library",
-		in: `
-			include $(CLEAR_VARS)
-			LOCAL_SRC_FILES := a.java
-			include $(BUILD_STATIC_JAVA_LIBRARY)
-
-			include $(CLEAR_VARS)
-			LOCAL_SRC_FILES := b.java
-			include $(BUILD_JAVA_LIBRARY)
-
-			include $(CLEAR_VARS)
-			LOCAL_SRC_FILES := c.java
-			LOCAL_UNINSTALLABLE_MODULE := true
-			include $(BUILD_JAVA_LIBRARY)
-
-			include $(CLEAR_VARS)
-			LOCAL_SRC_FILES := d.java
-			LOCAL_UNINSTALLABLE_MODULE := false
-			include $(BUILD_JAVA_LIBRARY)
-
-			include $(CLEAR_VARS)
-			LOCAL_SRC_FILES := $(call all-java-files-under, src gen)
-			include $(BUILD_STATIC_JAVA_LIBRARY)
-
-			include $(CLEAR_VARS)
-			LOCAL_JAVA_RESOURCE_FILES := foo bar
-			include $(BUILD_STATIC_JAVA_LIBRARY)
-		`,
-		expected: `
-			java_library {
-				srcs: ["a.java"],
-			}
-
-			java_library {
-				installable: true,
-				srcs: ["b.java"],
-			}
-
-			java_library {
-				installable: false,
-				srcs: ["c.java"],
-			}
-
-			java_library {
-				installable: true,
-				srcs: ["d.java"],
-			}
-
-			java_library {
-				srcs: [
-					"src/**/*.java",
-					"gen/**/*.java",
-				],
-			}
-
-			java_library {
-				java_resources: [
-					"foo",
-					"bar",
-				],
-			}
-		`,
-	},
-	{
-		desc: "errorprone options for java library",
-		in: `
-			include $(CLEAR_VARS)
-			LOCAL_ERROR_PRONE_FLAGS := -Xep:AsyncCallableReturnsNull:ERROR -Xep:AsyncFunctionReturnsNull:ERROR
-			include $(BUILD_STATIC_JAVA_LIBRARY)
-		`,
-		expected: `
-			java_library {
-				errorprone: {
-					javacflags: [
-						"-Xep:AsyncCallableReturnsNull:ERROR",
-						"-Xep:AsyncFunctionReturnsNull:ERROR",
-					],
-				},
-			}
-		`,
-	},
-	{
-		desc: "java prebuilt",
-		in: `
-			include $(CLEAR_VARS)
-			LOCAL_SRC_FILES := test.jar
-			LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-			LOCAL_STATIC_ANDROID_LIBRARIES :=
-			LOCAL_JETIFIER_ENABLED := true
-			include $(BUILD_PREBUILT)
-		`,
-		expected: `
-			java_import {
-				jars: ["test.jar"],
-
-				jetifier: true,
-			}
-		`,
-	},
-	{
-		desc: "aar prebuilt",
-		in: `
-			include $(CLEAR_VARS)
-			LOCAL_SRC_FILES := test.aar
-			LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-			include $(BUILD_PREBUILT)
-		`,
-		expected: `
-			android_library_import {
-				aars: ["test.aar"],
-
-			}
-		`,
-	},
-
-	{
-		desc: "aar",
-		in: `
-			include $(CLEAR_VARS)
-			LOCAL_SRC_FILES := test.java
-			LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-			LOCAL_JACK_COVERAGE_INCLUDE_FILTER := foo.*
-			include $(BUILD_STATIC_JAVA_LIBRARY)
-
-			include $(CLEAR_VARS)
-			LOCAL_SRC_FILES := test.java
-			LOCAL_STATIC_LIBRARIES := foo
-			LOCAL_STATIC_ANDROID_LIBRARIES := bar
-			LOCAL_JACK_COVERAGE_EXCLUDE_FILTER := bar.*
-			include $(BUILD_STATIC_JAVA_LIBRARY)
-
-			include $(CLEAR_VARS)
-			LOCAL_SRC_FILES := test.java
-			LOCAL_SHARED_LIBRARIES := foo
-			LOCAL_SHARED_ANDROID_LIBRARIES := bar
-			include $(BUILD_STATIC_JAVA_LIBRARY)
-
-			include $(CLEAR_VARS)
-			LOCAL_SRC_FILES := test.java
-			LOCAL_STATIC_ANDROID_LIBRARIES :=
-			include $(BUILD_STATIC_JAVA_LIBRARY)
-		`,
-		expected: `
-			android_library {
-				srcs: ["test.java"],
-				resource_dirs: ["res"],
-				jacoco: {
-					include_filter: ["foo.*"],
-				},
-			}
-
-			android_library {
-				srcs: ["test.java"],
-				static_libs: [
-					"foo",
-					"bar",
-				],
-				jacoco: {
-					exclude_filter: ["bar.*"],
-				},
-			}
-
-			android_library {
-				srcs: ["test.java"],
-				libs: [
-					"foo",
-					"bar",
-				],
-			}
-
-			java_library {
-				srcs: ["test.java"],
-				static_libs: [],
-			}
-		`,
-	},
-	{
-		desc: "cc_library shared_libs",
-		in: `
-			include $(CLEAR_VARS)
-			LOCAL_SHARED_LIBRARIES := libfoo
-			include $(BUILD_SHARED_LIBRARY)
-		`,
-		expected: `
-			cc_library_shared {
-				shared_libs: ["libfoo"],
-			}
-		`,
-	},
-	{
-		desc: "LOCAL_STRIP_MODULE",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := libtest
-LOCAL_STRIP_MODULE := false
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libtest2
-LOCAL_STRIP_MODULE := true
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libtest3
-LOCAL_STRIP_MODULE := keep_symbols
-include $(BUILD_SHARED_LIBRARY)
-`,
-		expected: `
-cc_library_shared {
-    name: "libtest",
-    strip: {
-        none: true,
-    }
-}
-
-cc_library_shared {
-    name: "libtest2",
-    strip: {
-        all: true,
-    }
-}
-
-cc_library_shared {
-    name: "libtest3",
-    strip: {
-        keep_symbols: true,
-    }
-}
-`,
-	},
-	{
-		desc: "BUILD_CTS_SUPPORT_PACKAGE",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := FooTest
-LOCAL_COMPATIBILITY_SUITE := cts
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-include $(BUILD_CTS_SUPPORT_PACKAGE)
-`,
-		expected: `
-android_test {
-    name: "FooTest",
-    defaults: ["cts_support_defaults"],
-    test_suites: ["cts"],
-
-}
-`,
-	},
-	{
-		desc: "BUILD_CTS_PACKAGE",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := FooTest
-LOCAL_COMPATIBILITY_SUITE := cts
-LOCAL_CTS_TEST_PACKAGE := foo.bar
-LOCAL_COMPATIBILITY_SUPPORT_FILES := file1
-include $(BUILD_CTS_PACKAGE)
-`,
-		expected: `
-android_test {
-    name: "FooTest",
-    defaults: ["cts_defaults"],
-    test_suites: ["cts"],
-
-    data: ["file1"],
-}
-`,
-	},
-	{
-		desc: "BUILD_CTS_*_JAVA_LIBRARY",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := foolib
-include $(BUILD_CTS_TARGET_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := foolib-host
-include $(BUILD_CTS_HOST_JAVA_LIBRARY)
-`,
-		expected: `
-java_library {
-    name: "foolib",
-    defaults: ["cts_defaults"],
-}
-
-java_library_host {
-    name: "foolib-host",
-    defaults: ["cts_defaults"],
-}
-`,
-	},
-	{
-		desc: "LOCAL_ANNOTATION_PROCESSORS",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := foolib
-LOCAL_ANNOTATION_PROCESSORS := bar
-LOCAL_ANNOTATION_PROCESSOR_CLASSES := com.bar
-include $(BUILD_STATIC_JAVA_LIBRARY)
-`,
-		expected: `
-java_library {
-    name: "foolib",
-    plugins: ["bar"],
-
-}
-`,
-	},
-	{
-		desc: "prebuilt_etc_TARGET_OUT_ETC",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := etc.test1
-LOCAL_SRC_FILES := mymod
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/foo/bar
-include $(BUILD_PREBUILT)
-`,
-		expected: `
-prebuilt_etc {
-	name: "etc.test1",
-	src: "mymod",
-	sub_dir: "foo/bar",
-
-}
-`,
-	},
-	{
-		desc: "prebuilt_etc_PRODUCT_OUT/system/etc",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := etc.test1
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(PRODUCT_OUT)/system/etc/foo/bar
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-`,
-		expected: `
-prebuilt_etc {
-	name: "etc.test1",
-
-	src: "etc.test1",
-	sub_dir: "foo/bar",
-
-}
-`,
-	},
-	{
-		desc: "prebuilt_etc_TARGET_OUT_ODM/etc",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := etc.test1
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ODM)/etc/foo/bar
-include $(BUILD_PREBUILT)
-`,
-		expected: `
-prebuilt_etc {
-	name: "etc.test1",
-	sub_dir: "foo/bar",
-    device_specific: true,
-
-}
-`,
-	},
-	{
-		desc: "prebuilt_etc_TARGET_OUT_PRODUCT/etc",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := etc.test1
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_PRODUCT)/etc/foo/bar
-include $(BUILD_PREBUILT)
-`,
-		expected: `
-prebuilt_etc {
-	name: "etc.test1",
-	sub_dir: "foo/bar",
-	product_specific: true,
-
-
-}
-`,
-	},
-	{
-		desc: "prebuilt_etc_TARGET_OUT_PRODUCT_ETC",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := etc.test1
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_PRODUCT_ETC)/foo/bar
-include $(BUILD_PREBUILT)
-`,
-		expected: `
-prebuilt_etc {
-	name: "etc.test1",
-	sub_dir: "foo/bar",
-	product_specific: true,
-
-}
-`,
-	},
-	{
-		desc: "prebuilt_etc_TARGET_OUT_SYSTEM_EXT/etc",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := etc.test1
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_SYSTEM_EXT)/etc/foo/bar
-include $(BUILD_PREBUILT)
-`,
-		expected: `
-prebuilt_etc {
-	name: "etc.test1",
-	sub_dir: "foo/bar",
-	system_ext_specific: true,
-
-}
-`,
-	},
-	{
-		desc: "prebuilt_etc_TARGET_OUT_SYSTEM_EXT_ETC",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := etc.test1
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_SYSTEM_EXT_ETC)/foo/bar
-include $(BUILD_PREBUILT)
-`,
-		expected: `
-prebuilt_etc {
-	name: "etc.test1",
-	sub_dir: "foo/bar",
-	system_ext_specific: true,
-
-
-}
-`,
-	},
-	{
-		desc: "prebuilt_etc_TARGET_OUT_VENDOR/etc",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := etc.test1
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/foo/bar
-include $(BUILD_PREBUILT)
-`,
-		expected: `
-prebuilt_etc {
-	name: "etc.test1",
-	sub_dir: "foo/bar",
-	proprietary: true,
-
-}
-`,
-	},
-	{
-		desc: "prebuilt_etc_PRODUCT_OUT/TARGET_COPY_OUT_VENDOR/etc",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := etc.test1
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_VENDOR)/etc/foo/bar
-include $(BUILD_PREBUILT)
-`,
-		expected: `
-prebuilt_etc {
-	name: "etc.test1",
-	sub_dir: "foo/bar",
-	proprietary: true,
-
-}
-`,
-	},
-	{
-		desc: "prebuilt_etc_TARGET_OUT_VENDOR_ETC",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := etc.test1
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/foo/bar
-include $(BUILD_PREBUILT)
-`,
-		expected: `
-prebuilt_etc {
-	name: "etc.test1",
-	sub_dir: "foo/bar",
-	proprietary: true,
-
-}
-`,
-	},
-	{
-		desc: "prebuilt_etc_TARGET_RECOVERY_ROOT_OUT/system/etc",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := etc.test1
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/etc/foo/bar
-include $(BUILD_PREBUILT)
-`,
-		expected: `
-prebuilt_etc {
-	name: "etc.test1",
-	sub_dir: "foo/bar",
-	recovery: true,
-
-}
-`,
-	},
-	{
-		desc: "prebuilt_usr_share",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := foo
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT)/usr/share
-LOCAL_SRC_FILES := foo.txt
-include $(BUILD_PREBUILT)
-`,
-		expected: `
-prebuilt_usr_share {
-	name: "foo",
-
-	src: "foo.txt",
-}
-`,
-	},
-	{
-		desc: "prebuilt_usr_share subdir_bar",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := foo
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT)/usr/share/bar
-LOCAL_SRC_FILES := foo.txt
-include $(BUILD_PREBUILT)
-`,
-		expected: `
-prebuilt_usr_share {
-	name: "foo",
-
-	src: "foo.txt",
-	sub_dir: "bar",
-}
-`,
-	},
-	{
-		desc: "prebuilt_usr_share_host",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := foo
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(HOST_OUT)/usr/share
-LOCAL_SRC_FILES := foo.txt
-include $(BUILD_PREBUILT)
-`,
-		expected: `
-prebuilt_usr_share_host {
-	name: "foo",
-
-	src: "foo.txt",
-}
-`,
-	},
-	{
-		desc: "prebuilt_font",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := font.ttf
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT)/fonts
-include $(BUILD_PREBUILT)
-`,
-		expected: `
-prebuilt_font {
-	name: "font.ttf",
-	src: "font.ttf",
-
-}
-`,
-	},
-	{
-		desc: "prebuilt_font",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := font.ttf
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_PRODUCT)/fonts
-include $(BUILD_PREBUILT)
-`,
-		expected: `
-prebuilt_font {
-	name: "font.ttf",
-	src: "font.ttf",
-	product_specific: true,
-
-}
-`,
-	},
-	{
-		desc: "prebuilt_usr_share_host subdir_bar",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := foo
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(HOST_OUT)/usr/share/bar
-LOCAL_SRC_FILES := foo.txt
-include $(BUILD_PREBUILT)
-`,
-		expected: `
-prebuilt_usr_share_host {
-	name: "foo",
-
-	src: "foo.txt",
-	sub_dir: "bar",
-}
-`,
-	},
-	{
-		desc: "prebuilt_firmware subdir_bar in $(TARGET_OUT_ETC)",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := foo
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/firmware/bar
-LOCAL_SRC_FILES := foo.fw
-include $(BUILD_PREBUILT)
-`,
-		expected: `
-prebuilt_firmware {
-	name: "foo",
-
-	src: "foo.fw",
-	sub_dir: "bar",
-}
-`,
-	},
-	{
-		desc: "prebuilt_firmware subdir_bar in $(TARGET_OUT)",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := foo
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/firmware/bar
-LOCAL_SRC_FILES := foo.fw
-include $(BUILD_PREBUILT)
-`,
-		expected: `
-prebuilt_firmware {
-	name: "foo",
-
-	src: "foo.fw",
-	sub_dir: "bar",
-}
-`,
-	},
-	{
-		desc: "prebuilt_firmware subdir_bar in $(TARGET_OUT_VENDOR)",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := foo
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/firmware/bar
-LOCAL_SRC_FILES := foo.fw
-include $(BUILD_PREBUILT)
-`,
-		expected: `
-prebuilt_firmware {
-	name: "foo",
-
-	src: "foo.fw",
-	sub_dir: "bar",
-	proprietary: true,
-}
-`,
-	},
-	{
-		desc: "prebuilt_firmware subdir_bar in $(TARGET_OUT)/vendor",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := foo
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT)/vendor/firmware/bar
-LOCAL_SRC_FILES := foo.fw
-include $(BUILD_PREBUILT)
-`,
-		expected: `
-prebuilt_firmware {
-	name: "foo",
-
-	src: "foo.fw",
-	sub_dir: "bar",
-	proprietary: true,
-}
-`,
-	},
-	{
-		desc: "vts_config",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := vtsconf
-include test/vts/tools/build/Android.host_config.mk
-`,
-		expected: `
-vts_config {
-	name: "vtsconf",
-}
-`,
-	},
-	{
-		desc: "comment with ESC",
-		in: `
-# Comment line 1 \
-# Comment line 2
-`,
-		expected: `
-// Comment line 1 \
-// Comment line 2
-`,
-	},
-	{
-		desc: "Merge with variable reference",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := foo
-LOCAL_STATIC_ANDROID_LIBRARIES := $(FOO)
-LOCAL_STATIC_JAVA_LIBRARIES := javalib
-LOCAL_JAVA_RESOURCE_DIRS := $(FOO)
-include $(BUILD_PACKAGE)
-`,
-		expected: `
-android_app {
-	name: "foo",
-	static_libs: FOO,
-	static_libs: ["javalib"],
-	java_resource_dirs: FOO,
-}
-`,
-	},
-	{
-		desc: "LOCAL_JACK_ENABLED and LOCAL_JACK_FLAGS skipped",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := foo
-LOCAL_JACK_ENABLED := incremental
-LOCAL_JACK_FLAGS := --multi-dex native
-include $(BUILD_PACKAGE)
-		`,
-		expected: `
-android_app {
-	name: "foo",
-
-}
-		`,
-	},
-	{
-		desc: "android_app_import",
-		in: `
-include $(CLEAR_VARS)
-LOCAL_MODULE := foo
-LOCAL_SRC_FILES := foo.apk
-LOCAL_PRIVILEGED_MODULE := true
-LOCAL_MODULE_CLASS := APPS
-LOCAL_MODULE_TAGS := optional
-LOCAL_DEX_PREOPT := false
-include $(BUILD_PREBUILT)
-`,
-		expected: `
-android_app_import {
-	name: "foo",
-
-	privileged: true,
-
-	dex_preopt: {
-		enabled: false,
-	},
-	apk: "foo.apk",
-
-}
-`,
-	},
-}
-
-func TestEndToEnd(t *testing.T) {
-	for i, test := range testCases {
-		expected, err := bpfix.Reformat(test.expected)
-		if err != nil {
-			t.Error(err)
-		}
-
-		got, errs := convertFile(fmt.Sprintf("<testcase %d>", i), bytes.NewBufferString(test.in))
-		if len(errs) > 0 {
-			t.Errorf("Unexpected errors: %q", errs)
-			continue
-		}
-
-		if got != expected {
-			t.Errorf("failed testcase '%s'\ninput:\n%s\n\nexpected:\n%s\ngot:\n%s\n", test.desc, strings.TrimSpace(test.in), expected, got)
-		}
-	}
-}
diff --git a/androidmk/cmd/androidmk/values.go b/androidmk/cmd/androidmk/values.go
deleted file mode 100644
index 90f2e74..0000000
--- a/androidmk/cmd/androidmk/values.go
+++ /dev/null
@@ -1,228 +0,0 @@
-// Copyright 2017 Google Inc. All rights reserved.
-//
-// 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 main
-
-import (
-	"fmt"
-	"strings"
-
-	mkparser "android/soong/androidmk/parser"
-
-	bpparser "github.com/google/blueprint/parser"
-)
-
-func stringToStringValue(s string) bpparser.Expression {
-	return &bpparser.String{
-		Value: s,
-	}
-}
-
-func stringListToStringValueList(list []string) []bpparser.Expression {
-	valList := make([]bpparser.Expression, len(list))
-	for i, l := range list {
-		valList[i] = stringToStringValue(l)
-	}
-	return valList
-}
-
-func addValues(val1, val2 bpparser.Expression) (bpparser.Expression, error) {
-	if val1 == nil {
-		return val2, nil
-	}
-
-	if val1.Type() == bpparser.StringType && val2.Type() == bpparser.ListType {
-		val1 = &bpparser.List{
-			Values: []bpparser.Expression{val1},
-		}
-	} else if val2.Type() == bpparser.StringType && val1.Type() == bpparser.ListType {
-		val2 = &bpparser.List{
-			Values: []bpparser.Expression{val1},
-		}
-	} else if val1.Type() != val2.Type() {
-		return nil, fmt.Errorf("cannot add mismatched types")
-	}
-
-	return &bpparser.Operator{
-		Operator: '+',
-		Args:     [2]bpparser.Expression{val1, val2},
-	}, nil
-}
-
-func makeToStringExpression(ms *mkparser.MakeString, scope mkparser.Scope) (bpparser.Expression, error) {
-
-	var val bpparser.Expression
-	var err error
-
-	if ms.Strings[0] != "" {
-		val = stringToStringValue(ms.Strings[0])
-	}
-
-	for i, s := range ms.Strings[1:] {
-		if ret, ok := ms.Variables[i].EvalFunction(scope); ok {
-			if len(ret) > 1 {
-				return nil, fmt.Errorf("Unexpected list value %s", ms.Dump())
-			}
-			val, err = addValues(val, stringToStringValue(ret[0]))
-		} else {
-			name := ms.Variables[i].Name
-			if !name.Const() {
-				return nil, fmt.Errorf("Unsupported non-const variable name %s", name.Dump())
-			}
-			tmp := &bpparser.Variable{
-				Name:  name.Value(nil),
-				Value: &bpparser.String{},
-			}
-
-			if tmp.Name == "TOP" {
-				if s[0] == '/' {
-					s = s[1:]
-				} else {
-					s = "." + s
-				}
-			} else {
-				val, err = addValues(val, tmp)
-				if err != nil {
-					return nil, err
-				}
-			}
-		}
-
-		if s != "" {
-			tmp := stringToStringValue(s)
-			val, err = addValues(val, tmp)
-			if err != nil {
-				return nil, err
-			}
-		}
-	}
-
-	return val, nil
-}
-
-func stringToListValue(s string) bpparser.Expression {
-	list := strings.Fields(s)
-	valList := make([]bpparser.Expression, len(list))
-	for i, l := range list {
-		valList[i] = &bpparser.String{
-			Value: l,
-		}
-	}
-	return &bpparser.List{
-		Values: valList,
-	}
-
-}
-
-func makeToListExpression(ms *mkparser.MakeString, scope mkparser.Scope) (bpparser.Expression, error) {
-
-	fields := ms.Split(" \t")
-
-	var listOfListValues []bpparser.Expression
-
-	listValue := &bpparser.List{}
-
-	for _, f := range fields {
-		if len(f.Variables) == 1 && f.Strings[0] == "" && f.Strings[1] == "" {
-			if ret, ok := f.Variables[0].EvalFunction(scope); ok {
-				listValue.Values = append(listValue.Values, stringListToStringValueList(ret)...)
-			} else {
-				// Variable by itself, variable is probably a list
-				if !f.Variables[0].Name.Const() {
-					return nil, fmt.Errorf("unsupported non-const variable name")
-				}
-				if f.Variables[0].Name.Value(nil) == "TOP" {
-					listValue.Values = append(listValue.Values, &bpparser.String{
-						Value: ".",
-					})
-				} else {
-					if len(listValue.Values) > 0 {
-						listOfListValues = append(listOfListValues, listValue)
-					}
-					listOfListValues = append(listOfListValues, &bpparser.Variable{
-						Name:  f.Variables[0].Name.Value(nil),
-						Value: &bpparser.List{},
-					})
-					listValue = &bpparser.List{}
-				}
-			}
-		} else {
-			s, err := makeToStringExpression(f, scope)
-			if err != nil {
-				return nil, err
-			}
-			if s == nil {
-				continue
-			}
-
-			listValue.Values = append(listValue.Values, s)
-		}
-	}
-
-	if len(listValue.Values) > 0 {
-		listOfListValues = append(listOfListValues, listValue)
-	}
-
-	if len(listOfListValues) == 0 {
-		return listValue, nil
-	}
-
-	val := listOfListValues[0]
-	for _, tmp := range listOfListValues[1:] {
-		var err error
-		val, err = addValues(val, tmp)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	return val, nil
-}
-
-func stringToBoolValue(s string) (bpparser.Expression, error) {
-	var b bool
-	s = strings.TrimSpace(s)
-	switch s {
-	case "true":
-		b = true
-	case "false", "":
-		b = false
-	case "-frtti": // HACK for LOCAL_RTTI_VALUE
-		b = true
-	default:
-		return nil, fmt.Errorf("unexpected bool value %s", s)
-	}
-	return &bpparser.Bool{
-		Value: b,
-	}, nil
-}
-
-func makeToBoolExpression(ms *mkparser.MakeString) (bpparser.Expression, error) {
-	if !ms.Const() {
-		if len(ms.Variables) == 1 && ms.Strings[0] == "" && ms.Strings[1] == "" {
-			name := ms.Variables[0].Name
-			if !name.Const() {
-				return nil, fmt.Errorf("unsupported non-const variable name")
-			}
-			return &bpparser.Variable{
-				Name:  name.Value(nil),
-				Value: &bpparser.Bool{},
-			}, nil
-		} else {
-			return nil, fmt.Errorf("non-const bool expression %s", ms.Dump())
-		}
-	}
-
-	return stringToBoolValue(ms.Value(nil))
-}