Remove crostool migration tools

The migration to .bzl configured toolchains happened a long time ago and the conversion tools from proto files are not needed anymore.

This also cleans up rules_cc dependencies to build those tools. And unblock me around the import of py_proto_library, which is not needed anymore.

PiperOrigin-RevId: 683582749
Change-Id: I9a56d9e3f9089f7434708a2cfefdd4f12d186658
diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml
index 8d7899d..9fbb3ed 100644
--- a/.bazelci/presubmit.yml
+++ b/.bazelci/presubmit.yml
@@ -16,7 +16,6 @@
     - "//examples/my_c_archive:all"
     - "//examples/my_c_compile:all"
     - "//examples/write_cc_toolchain_cpu:all"
-    - "//tools/migration:all"
     - "//tests/..."
     test_flags:
     - "--test_timeout=120"
@@ -29,7 +28,6 @@
     - "//examples/my_c_archive:all"
     - "//examples/my_c_compile:all"
     - "//examples/write_cc_toolchain_cpu:all"
-    - "//tools/migration:all"
     - "//tests/..."
 
 buildifier:
diff --git a/WORKSPACE b/WORKSPACE
index a4587d5..9501829 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -12,34 +12,6 @@
 )
 
 http_archive(
-    name = "com_google_googletest",
-    sha256 = "81964fe578e9bd7c94dfdb09c8e4d6e6759e19967e397dbea48d1c10e45d0df2",
-    strip_prefix = "googletest-release-1.12.1",
-    urls = [
-        "https://mirror.bazel.build/github.com/google/googletest/archive/refs/tags/release-1.12.1.tar.gz",
-        "https://github.com/google/googletest/archive/refs/tags/release-1.12.1.tar.gz",
-    ],
-)
-
-http_archive(
-    name = "io_abseil_py",
-    sha256 = "0fb3a4916a157eb48124ef309231cecdfdd96ff54adf1660b39c0d4a9790a2c0",
-    strip_prefix = "abseil-py-1.4.0",
-    urls = [
-        "https://github.com/abseil/abseil-py/archive/refs/tags/v1.4.0.tar.gz",
-    ],
-)
-
-http_archive(
-    name = "io_bazel_rules_go",
-    sha256 = "91585017debb61982f7054c9688857a2ad1fd823fc3f9cb05048b0025c47d023",
-    urls = [
-        "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.42.0/rules_go-v0.42.0.zip",
-        "https://github.com/bazelbuild/rules_go/releases/download/v0.42.0/rules_go-v0.42.0.zip",
-    ],
-)
-
-http_archive(
     name = "platforms",
     sha256 = "218efe8ee736d26a3572663b374a253c012b716d8af0c07e842e82f238a0a7ee",
     urls = [
@@ -48,49 +20,10 @@
     ],
 )
 
-http_archive(
-    name = "py_mock",
-    patch_cmds = [
-        "mkdir -p py/mock",
-        "mv mock.py py/mock/__init__.py",
-        """echo 'licenses(["notice"])' > BUILD""",
-        "touch py/BUILD",
-        """echo 'py_library(name = "mock", srcs = ["__init__.py"], visibility = ["//visibility:public"],)' > py/mock/BUILD""",
-    ],
-    sha256 = "b839dd2d9c117c701430c149956918a423a9863b48b09c90e30a6013e7d2f44f",
-    strip_prefix = "mock-1.0.1",
-    urls = [
-        "https://mirror.bazel.build/pypi.python.org/packages/source/m/mock/mock-1.0.1.tar.gz",
-        "https://pypi.python.org/packages/source/m/mock/mock-1.0.1.tar.gz",
-    ],
-)
-
-http_archive(
-    name = "rules_proto",
-    sha256 = "9a0503631679e9ab4e27d891ea60fee3e86a85654ea2048cae25516171dd260e",
-    strip_prefix = "rules_proto-e51f588e5932966ab9e63e0b0f6de6f740cf04c4",
-    urls = [
-        "https://mirror.bazel.build/github.com/bazelbuild/rules_proto/archive/e51f588e5932966ab9e63e0b0f6de6f740cf04c4.tar.gz",
-        "https://github.com/bazelbuild/rules_proto/archive/e51f588e5932966ab9e63e0b0f6de6f740cf04c4.tar.gz",
-    ],
-)
-
 load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
 
 bazel_skylib_workspace()
 
-load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
-
-go_rules_dependencies()
-
-go_register_toolchains(version = "1.20.5")
-
-load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")
-
-rules_proto_dependencies()
-
-rules_proto_toolchains()
-
 http_archive(
     name = "rules_testing",
     sha256 = "02c62574631876a4e3b02a1820cb51167bb9cdcdea2381b2fa9d9b8b11c407c4",
diff --git a/third_party/BUILD b/third_party/BUILD
deleted file mode 100644
index 0c41157..0000000
--- a/third_party/BUILD
+++ /dev/null
@@ -1 +0,0 @@
-# Intentionally empty, only there to make //third_party a package.
diff --git a/third_party/com/github/bazelbuild/bazel/src/main/protobuf/BUILD b/third_party/com/github/bazelbuild/bazel/src/main/protobuf/BUILD
deleted file mode 100644
index c08e13b..0000000
--- a/third_party/com/github/bazelbuild/bazel/src/main/protobuf/BUILD
+++ /dev/null
@@ -1,30 +0,0 @@
-load("@com_google_protobuf//:protobuf.bzl", "py_proto_library")
-load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
-load("@rules_proto//proto:defs.bzl", "proto_library")
-
-licenses(["notice"])  # Apache 2.0
-
-py_proto_library(
-    name = "crosstool_config_py_pb2",
-    srcs = ["crosstool_config.proto"],
-    visibility = [
-        "//tools/migration:__pkg__",
-    ],
-)
-
-proto_library(
-    name = "crosstool_config_pb2",
-    srcs = ["crosstool_config.proto"],
-    visibility = [
-        "//tools/migration:__pkg__",
-    ],
-)
-
-go_proto_library(
-    name = "crosstool_config_go_proto",
-    importpath = "third_party/com/github/bazelbuild/bazel/src/main/protobuf/crosstool_config_go_proto",
-    proto = ":crosstool_config_pb2",
-    visibility = [
-        "//tools/migration:__pkg__",
-    ],
-)
diff --git a/third_party/com/github/bazelbuild/bazel/src/main/protobuf/crosstool_config.proto b/third_party/com/github/bazelbuild/bazel/src/main/protobuf/crosstool_config.proto
deleted file mode 100644
index 45ad1e5..0000000
--- a/third_party/com/github/bazelbuild/bazel/src/main/protobuf/crosstool_config.proto
+++ /dev/null
@@ -1,548 +0,0 @@
-// Copyright 2014 The Bazel Authors. 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.
-//
-// File format for Blaze to configure Crosstool releases.
-
-syntax = "proto2";
-
-package com.google.devtools.build.lib.view.config.crosstool;
-
-// option java_api_version = 2;  // copybara-comment-this-out-please
-option java_package = "com.google.devtools.build.lib.view.config.crosstool";
-
-// A description of a toolchain, which includes all the tools generally expected
-// to be available for building C/C++ targets, based on the GNU C compiler.
-//
-// System and cpu names are two overlapping concepts, which need to be both
-// supported at this time. The cpu name is the blaze command-line name for the
-// target system. The most common values are 'k8' and 'piii'. The system name is
-// a more generic identification of the executable system, based on the names
-// used by the GNU C compiler.
-//
-// Typically, the system name contains an identifier for the cpu (e.g. x86_64 or
-// alpha), an identifier for the machine (e.g. pc, or unknown), and an
-// identifier for the operating system (e.g. cygwin or linux-gnu). Typical
-// examples are 'x86_64-unknown-linux-gnu' and 'i686-unknown-cygwin'.
-//
-// The system name is used to determine if a given machine can execute a given
-// executable. In particular, it is used to check if the compilation products of
-// a toolchain can run on the host machine.
-message CToolchain {
-  // A group of correlated flags. Supports parametrization via variable
-  // expansion.
-  //
-  // To expand a variable of list type, flag_group has to be annotated with
-  // `iterate_over` message. Then all nested flags or flag_groups will be
-  // expanded repeatedly for each element of the list.
-  //
-  // For example:
-  // flag_group {
-  //   iterate_over: 'include_path'
-  //   flag: '-I'
-  //   flag: '%{include_path}'
-  // }
-  // ... will get expanded to -I /to/path1 -I /to/path2 ... for each
-  // include_path /to/pathN.
-  //
-  // To expand a variable of structure type, use dot-notation, e.g.:
-  //    flag_group {
-  //      iterate_over: "libraries_to_link"
-  //      flag_group {
-  //        iterate_over: "libraries_to_link.libraries"
-  //        flag: "-L%{libraries_to_link.libraries.directory}"
-  //      }
-  //    }
-  //
-  // Flag groups can be nested; if they are, the flag group must only contain
-  // other flag groups (no flags) so the order is unambiguously specified.
-  // In order to expand a variable of nested lists, 'iterate_over' can be used.
-  //
-  // For example:
-  // flag_group {
-  //   iterate_over: 'object_files'
-  //   flag_group { flag: '--start-lib' }
-  //   flag_group {
-  //     iterate_over: 'object_files'
-  //     flag: '%{object_files}'
-  //   }
-  //   flag_group { flag: '--end-lib' }
-  // }
-  // ... will get expanded to
-  //   --start-lib a1.o a2.o ... --end-lib --start-lib b1.o b2.o .. --end-lib
-  //   with %{object_files} being a variable of nested list type
-  //   [['a1.o', 'a2.o', ...], ['b1.o', 'b2.o', ...], ...].
-  //
-  // TODO(bazel-team): Write more elaborate documentation and add a link to it.
-  message FlagGroup {
-    repeated string flag = 1;
-
-    repeated FlagGroup flag_group = 2;
-
-    optional string iterate_over = 3;
-
-    repeated string expand_if_all_available = 4;
-
-    repeated string expand_if_none_available = 5;
-
-    optional string expand_if_true = 6;
-
-    optional string expand_if_false = 7;
-
-    optional VariableWithValue expand_if_equal = 8;
-  }
-
-  message VariableWithValue {
-    required string variable = 1;
-
-    required string value = 2;
-  }
-
-  // A key/value pair to be added as an environment variable. The value of
-  // this pair is expanded in the same way as is described in FlagGroup.
-  // The key remains an unexpanded string literal.
-  message EnvEntry {
-    required string key = 1;
-    required string value = 2;
-    repeated string expand_if_all_available = 3;
-  }
-
-  // A set of features; used to support logical 'and' when specifying feature
-  // requirements in Feature.
-  message FeatureSet {
-    repeated string feature = 1;
-  }
-
-  // A set of positive and negative features. This stanza will
-  // evaluate to true when every 'feature' is enabled, and every
-  // 'not_feature' is not enabled.
-  message WithFeatureSet {
-    repeated string feature = 1;
-    repeated string not_feature = 2;
-  }
-
-  // A set of flags that are expanded in the command line for specific actions.
-  message FlagSet {
-    // The actions this flag set applies to; each flag set must specify at
-    // least one action.
-    repeated string action = 1;
-
-    // The flags applied via this flag set.
-    repeated FlagGroup flag_group = 2;
-
-    // A list of feature sets defining when this flag set gets applied.  The
-    // flag set will be applied when any one of the feature sets evaluate to
-    // true. (That is, when when every 'feature' is enabled, and every
-    // 'not_feature' is not enabled.)
-    //
-    // If 'with_feature' is omitted, the flag set will be applied
-    // unconditionally for every action specified.
-    repeated WithFeatureSet with_feature = 3;
-
-    // Deprecated (https://github.com/bazelbuild/bazel/issues/7008) - use
-    // expand_if_all_available in flag_group
-    //
-    // A list of build variables that this feature set needs, but which are
-    // allowed to not be set. If any of the build variables listed is not
-    // set, the feature set will not be expanded.
-    //
-    // NOTE: Consider alternatives before using this; usually tools should
-    // consistently create the same set of files, even if empty; use this
-    // only for backwards compatibility with already existing behavior in tools
-    // that are currently not worth changing.
-    repeated string expand_if_all_available = 4;
-  }
-
-  // A set of environment variables that are expanded in the command line for
-  // specific actions.
-  message EnvSet {
-    // The actions this env set applies to; each env set must specify at
-    // least one action.
-    repeated string action = 1;
-
-    // The environment variables applied via this env set.
-    repeated EnvEntry env_entry = 2;
-
-    // A list of feature sets defining when this env set gets applied.  The
-    // env set will be applied when any one of the feature sets evaluate to
-    // true. (That is, when when every 'feature' is enabled, and every
-    // 'not_feature' is not enabled.)
-    //
-    // If 'with_feature' is omitted, the env set will be applied
-    // unconditionally for every action specified.
-    repeated WithFeatureSet with_feature = 3;
-  }
-
-  // Contains all flag specifications for one feature.
-  // Next ID: 8
-  message Feature {
-    // The feature's name. Feature names are generally defined by Bazel; it is
-    // possible to introduce a feature without a change to Bazel by adding a
-    // 'feature' section to the toolchain and adding the corresponding string as
-    // feature in the BUILD file.
-    optional string name = 1;
-
-    // If 'true', this feature is enabled unless a rule type explicitly marks it
-    // as unsupported. Such features cannot be turned off from within a BUILD
-    // file or the command line.
-    optional bool enabled = 7;
-
-    // If the given feature is enabled, the flag sets will be applied for the
-    // actions in the modes that they are specified for.
-    repeated FlagSet flag_set = 2;
-
-    // If the given feature is enabled, the env sets will be applied for the
-    // actions in the modes that they are specified for.
-    repeated EnvSet env_set = 6;
-
-    // A list of feature sets defining when this feature is supported by the
-    // toolchain. The feature is supported if any of the feature sets fully
-    // apply, that is, when all features of a feature set are enabled.
-    //
-    // If 'requires' is omitted, the feature is supported independently of which
-    // other features are enabled.
-    //
-    // Use this for example to filter flags depending on the build mode
-    // enabled (opt / fastbuild / dbg).
-    repeated FeatureSet requires = 3;
-
-    // A list of features or action configs that are automatically enabled when
-    // this feature is enabled. If any of the implied features or action configs
-    // cannot be enabled, this feature will (silently) not be enabled either.
-    repeated string implies = 4;
-
-    // A list of names this feature conflicts with.
-    // A feature cannot be enabled if:
-    // - 'provides' contains the name of a different feature or action config
-    //  that we want to enable.
-    // - 'provides' contains the same value as a 'provides' in a different
-    //   feature or action config that we want to enable.
-    //
-    // Use this in order to ensure that incompatible features cannot be
-    // accidentally activated at the same time, leading to hard to diagnose
-    // compiler errors.
-    repeated string provides = 5;
-  }
-
-  // Describes a tool associated with a crosstool action config.
-  message Tool {
-    // Describes the origin of a path.
-    enum PathOrigin {
-      // Indicates that `tool_path` is relative to the location of the
-      // crosstool. For legacy reasons, absolute paths are als0 allowed here.
-      CROSSTOOL_PACKAGE = 0;
-
-      // Indicates that `tool_path` is an absolute path.
-      // This is enforced by Bazel.
-      FILESYSTEM_ROOT = 1;
-
-      // Indicates that `tool_path` is relative to the current workspace's
-      // exec root.
-      WORKSPACE_ROOT = 2;
-    }
-
-    // Path to the tool, relative to the location of the crosstool.
-    required string tool_path = 1;
-
-    // Origin of `tool_path`.
-    // Optional only for legacy reasons. New crosstools should set this value!
-    optional PathOrigin tool_path_origin = 4 [default = CROSSTOOL_PACKAGE];
-
-    // A list of feature sets defining when this tool is applicable.  The tool
-    // will used when any one of the feature sets evaluate to true. (That is,
-    // when when every 'feature' is enabled, and every 'not_feature' is not
-    // enabled.)
-    //
-    // If 'with_feature' is omitted, the tool will apply for any feature
-    // configuration.
-    repeated WithFeatureSet with_feature = 2;
-
-    // Requirements on the execution environment for the execution of this tool,
-    // to be passed as out-of-band "hints" to the execution backend.
-    // Ex. "requires-darwin"
-    repeated string execution_requirement = 3;
-  }
-
-  // The name for an artifact of a given category of input or output artifacts
-  // to an action.
-  message ArtifactNamePattern {
-    // The category of artifacts that this selection applies to.  This field
-    // is compared against a list of categories defined in bazel. Example
-    // categories include "linked_output" or "debug_symbols". An error is thrown
-    // if no category is matched.
-    required string category_name = 1;
-    // The prefix and extension for creating the artifact for this selection.
-    // They are used to create an artifact name based on the target name.
-    required string prefix = 2;
-    required string extension = 3;
-  }
-
-  // An action config corresponds to a blaze action, and allows selection of
-  // a tool based on activated features.  Action configs come in two varieties:
-  // automatic (the blaze action will exist whether or not the action config
-  // is activated) and attachable (the blaze action will be added to the
-  // action graph only if the action config is activated).
-  //
-  // Action config activation occurs by the same semantics as features: a
-  // feature can 'require' or 'imply' an action config in the same way that it
-  // would another feature.
-  // Next ID: 9
-  message ActionConfig {
-    // The name other features will use to activate this action config.  Can
-    // be the same as action_name.
-    required string config_name = 1;
-
-    // The name of the blaze action that this config applies to, ex. 'c-compile'
-    // or 'c-module-compile'.
-    required string action_name = 2;
-
-    // If 'true', this feature is enabled unless a rule type explicitly marks it
-    // as unsupported.  Such action_configs cannot be turned off from within a
-    // BUILD file or the command line.
-    optional bool enabled = 8;
-
-    // The tool applied to the action will be the first Tool with a feature
-    // set that matches the feature configuration.  An error will be thrown
-    // if no tool matches a provided feature configuration - for that reason,
-    // it's a good idea to provide a default tool with an empty feature set.
-    repeated Tool tool = 3;
-
-    // If the given action config is enabled, the flag sets will be applied
-    // to the corresponding action.
-    repeated FlagSet flag_set = 4;
-
-    // If the given action config is enabled, the env sets will be applied
-    // to the corresponding action.
-    repeated EnvSet env_set = 5;
-
-    // A list of feature sets defining when this action config
-    // is supported by the toolchain. The action config is supported if any of
-    // the feature sets fully apply, that is, when all features of a
-    // feature set are enabled.
-    //
-    // If 'requires' is omitted, the action config is supported independently
-    // of which other features are enabled.
-    //
-    // Use this for example to filter actions depending on the build
-    // mode enabled (opt / fastbuild / dbg).
-    repeated FeatureSet requires = 6;
-
-    // A list of features or action configs that are automatically enabled when
-    // this action config is enabled. If any of the implied features or action
-    // configs cannot be enabled, this action config will (silently)
-    // not be enabled either.
-    repeated string implies = 7;
-  }
-
-  repeated Feature feature = 50;
-  repeated ActionConfig action_config = 53;
-  repeated ArtifactNamePattern artifact_name_pattern = 54;
-
-  // The unique identifier of the toolchain within the crosstool release. It
-  // must be possible to use this as a directory name in a path.
-  // It has to match the following regex: [a-zA-Z_][\.\- \w]*
-  required string toolchain_identifier = 1;
-
-  // A basic toolchain description.
-  required string host_system_name = 2;
-  required string target_system_name = 3;
-  required string target_cpu = 4;
-  required string target_libc = 5;
-  required string compiler = 6;
-
-  required string abi_version = 7;
-  required string abi_libc_version = 8;
-
-  // Tool locations. Relative paths are resolved relative to the configuration
-  // file directory.
-  // NOTE: DEPRECATED. Prefer specifying an ActionConfig for the action that
-  // needs the tool.
-  // TODO(b/27903698) migrate to ActionConfig.
-  repeated ToolPath tool_path = 9;
-
-  // Feature flags.
-  // TODO(bazel-team): Sink those into 'Feature' instances.
-  // Legacy field, ignored by Bazel.
-  optional bool supports_gold_linker = 10 [default = false];
-  // Legacy field, ignored by Bazel.
-  optional bool supports_thin_archives = 11 [default = false];
-  // Legacy field, use 'supports_start_end_lib' feature instead.
-  optional bool supports_start_end_lib = 28 [default = false];
-  // Legacy field, use 'supports_interface_shared_libraries' instead.
-  optional bool supports_interface_shared_objects = 32 [default = false];
-  // Legacy field, use 'static_link_cpp_runtimes' feature instead.
-  optional bool supports_embedded_runtimes = 40 [default = false];
-  // If specified, Blaze finds statically linked / dynamically linked runtime
-  // libraries in the declared crosstool filegroup. Otherwise, Blaze
-  // looks in "[static|dynamic]-runtime-libs-$TARGET_CPU".
-  // Deprecated, see https://github.com/bazelbuild/bazel/issues/6942
-  optional string static_runtimes_filegroup = 45;
-  // Deprecated, see https://github.com/bazelbuild/bazel/issues/6942
-  optional string dynamic_runtimes_filegroup = 46;
-  // Legacy field, ignored by Bazel.
-  optional bool supports_incremental_linker = 41 [default = false];
-  // Legacy field, ignored by Bazel.
-  optional bool supports_normalizing_ar = 26 [default = false];
-  // Legacy field, use 'per_object_debug_info' feature instead.
-  optional bool supports_fission = 43 [default = false];
-  // Legacy field, ignored by Bazel.
-  optional bool supports_dsym = 51 [default = false];
-  // Legacy field, use 'supports_pic' feature instead
-  optional bool needsPic = 12 [default = false];
-
-  // Compiler flags for C/C++/Asm compilation.
-  repeated string compiler_flag = 13;
-  // Additional compiler flags for C++ compilation.
-  repeated string cxx_flag = 14;
-  // Additional unfiltered compiler flags for C/C++/Asm compilation.
-  // These are not subject to nocopt filtering in cc_* rules.
-  // Note: These flags are *not* applied to objc/objc++ compiles.
-  repeated string unfiltered_cxx_flag = 25;
-  // Linker flags.
-  repeated string linker_flag = 15;
-  // Additional linker flags when linking dynamic libraries.
-  repeated string dynamic_library_linker_flag = 27;
-  // Additional test-only linker flags.
-  repeated string test_only_linker_flag = 49;
-  // Objcopy flags for embedding files into binaries.
-  repeated string objcopy_embed_flag = 16;
-  // Ld flags for embedding files into binaries. This is used by filewrapper
-  // since it calls ld directly and needs to know what -m flag to pass.
-  repeated string ld_embed_flag = 23;
-  // Ar flags for combining object files into archives. If this is not set, it
-  // defaults to "rcsD".
-  // TODO(b/37271982): Remove after blaze with ar action_config release
-  repeated string ar_flag = 47;
-  // Legacy field, ignored by Bazel.
-  repeated string ar_thin_archives_flag = 48;
-  // Legacy field, ignored by Bazel.
-  repeated string gcc_plugin_compiler_flag = 34;
-
-  // Additional compiler and linker flags depending on the compilation mode.
-  repeated CompilationModeFlags compilation_mode_flags = 17;
-
-  // Additional linker flags depending on the linking mode.
-  repeated LinkingModeFlags linking_mode_flags = 18;
-
-  // Legacy field, ignored by Bazel.
-  repeated string gcc_plugin_header_directory = 19;
-  // Legacy field, ignored by Bazel.
-  repeated string mao_plugin_header_directory = 20;
-
-  // Make variables that are made accessible to rules.
-  repeated MakeVariable make_variable = 21;
-
-  // Built-in include directories for C++ compilation. These should be the exact
-  // paths used by the compiler, and are generally relative to the exec root.
-  // The paths used by the compiler can be determined by 'gcc -Wp,-v some.c'.
-  // We currently use the C++ paths also for C compilation, which is safe as
-  // long as there are no name clashes between C++ and C header files.
-  //
-  // Relative paths are resolved relative to the configuration file directory.
-  //
-  // If the compiler has --sysroot support, then these paths should use
-  // %sysroot% rather than the include path, and specify the sysroot attribute
-  // in order to give blaze the information necessary to make the correct
-  // replacements.
-  repeated string cxx_builtin_include_directory = 22;
-
-  // The built-in sysroot. If this attribute is not present, blaze does not
-  // allow using a different sysroot, i.e. through the --grte_top option. Also
-  // see the documentation above.
-  optional string builtin_sysroot = 24;
-
-  // Legacy field, ignored by Bazel.
-  optional string default_python_top = 29;
-  // Legacy field, ignored by Bazel.
-  optional string default_python_version = 30;
-  // Legacy field, ignored by Bazel.
-  optional bool python_preload_swigdeps = 42;
-
-  // The default GRTE to use. This should be a label, and gets the same
-  // treatment from Blaze as the --grte_top option. This setting is only used in
-  // the absence of an explicit --grte_top option. If unset, Blaze will not pass
-  // -sysroot by default. The local part must be 'everything', i.e.,
-  // '//some/label:everything'. There can only be one GRTE library per package,
-  // because the compiler expects the directory as a parameter of the -sysroot
-  // option.
-  // This may only be set to a non-empty value if builtin_sysroot is also set!
-  optional string default_grte_top = 31;
-
-  // Legacy field, ignored by Bazel.
-  repeated string debian_extra_requires = 33;
-
-  // Legacy field, ignored by Bazel. Only there for compatibility with
-  // things internal to Google.
-  optional string cc_target_os = 55;
-
-  // Next free id: 56
-}
-
-message ToolPath {
-  required string name = 1;
-  required string path = 2;
-}
-
-enum CompilationMode {
-  FASTBUILD = 1;
-  DBG = 2;
-  OPT = 3;
-  // This value is ignored and should not be used in new files.
-  COVERAGE = 4;
-}
-
-message CompilationModeFlags {
-  required CompilationMode mode = 1;
-  repeated string compiler_flag = 2;
-  repeated string cxx_flag = 3;
-  // Linker flags that are added when compiling in a certain mode.
-  repeated string linker_flag = 4;
-}
-
-enum LinkingMode {
-  FULLY_STATIC = 1;
-  MOSTLY_STATIC = 2;
-  DYNAMIC = 3;
-  MOSTLY_STATIC_LIBRARIES = 4;
-}
-
-message LinkingModeFlags {
-  required LinkingMode mode = 1;
-  repeated string linker_flag = 2;
-}
-
-message MakeVariable {
-  required string name = 1;
-  required string value = 2;
-}
-
-message DefaultCpuToolchain {
-  required string cpu = 1;
-  required string toolchain_identifier = 2;
-}
-
-// An entire crosstool release, containing the version number, and a set of
-// toolchains.
-message CrosstoolRelease {
-  // The major and minor version of the crosstool release.
-  required string major_version = 1;
-  required string minor_version = 2;
-
-  // Legacy field, ignored by Bazel.
-  optional string default_target_cpu = 3;
-  // Legacy field, ignored by Bazel.
-  repeated DefaultCpuToolchain default_toolchain = 4;
-
-  // All the toolchains in this release.
-  repeated CToolchain toolchain = 5;
-}
diff --git a/third_party/six.BUILD b/third_party/six.BUILD
deleted file mode 100644
index 19433c2..0000000
--- a/third_party/six.BUILD
+++ /dev/null
@@ -1,16 +0,0 @@
-# Description:
-#   Six provides simple utilities for wrapping over differences between Python 2
-#   and Python 3.
-
-load("@rules_python//python:defs.bzl", "py_library")
-
-licenses(["notice"])  # MIT
-
-exports_files(["LICENSE"])
-
-py_library(
-    name = "six",
-    srcs = ["six.py"],
-    srcs_version = "PY2AND3",
-    visibility = ["//visibility:public"],
-)
diff --git a/tools/migration/BUILD b/tools/migration/BUILD
deleted file mode 100644
index 1550c15..0000000
--- a/tools/migration/BUILD
+++ /dev/null
@@ -1,144 +0,0 @@
-# Copyright 2018 The Bazel Authors. 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.
-
-load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
-load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test")
-load("@rules_python//python:defs.bzl", "py_binary", "py_library", "py_test")
-
-package(default_visibility = ["//visibility:public"])
-
-licenses(["notice"])
-
-py_binary(
-    name = "legacy_fields_migrator",
-    srcs = ["legacy_fields_migrator.py"],
-    python_version = "PY3",
-    deps = [
-        ":legacy_fields_migration_lib",
-        "//third_party/com/github/bazelbuild/bazel/src/main/protobuf:crosstool_config_py_pb2",
-        "@io_abseil_py//absl:app",
-        "@io_abseil_py//absl/flags",
-        #internal proto upb dep,
-    ],
-)
-
-py_library(
-    name = "legacy_fields_migration_lib",
-    srcs = ["legacy_fields_migration_lib.py"],
-    deps = [
-        "//third_party/com/github/bazelbuild/bazel/src/main/protobuf:crosstool_config_py_pb2",
-    ],
-)
-
-py_test(
-    name = "legacy_fields_migration_lib_test",
-    srcs = ["legacy_fields_migration_lib_test.py"],
-    python_version = "PY3",
-    deps = [
-        ":legacy_fields_migration_lib",
-        "//third_party/com/github/bazelbuild/bazel/src/main/protobuf:crosstool_config_py_pb2",
-    ],
-)
-
-py_binary(
-    name = "crosstool_query",
-    srcs = ["crosstool_query.py"],
-    python_version = "PY3",
-    deps = [
-        "//third_party/com/github/bazelbuild/bazel/src/main/protobuf:crosstool_config_py_pb2",
-        "@io_abseil_py//absl:app",
-        "@io_abseil_py//absl/flags",
-        #internal proto upb dep,
-    ],
-)
-
-py_binary(
-    name = "ctoolchain_comparator",
-    srcs = ["ctoolchain_comparator.py"],
-    python_version = "PY3",
-    deps = [
-        ":ctoolchain_comparator_lib",
-        "//third_party/com/github/bazelbuild/bazel/src/main/protobuf:crosstool_config_py_pb2",
-        "@io_abseil_py//absl:app",
-        "@io_abseil_py//absl/flags",
-        #internal proto upb dep,
-    ],
-)
-
-py_library(
-    name = "ctoolchain_comparator_lib",
-    srcs = ["ctoolchain_comparator_lib.py"],
-    deps = [
-        "//third_party/com/github/bazelbuild/bazel/src/main/protobuf:crosstool_config_py_pb2",
-    ],
-)
-
-py_test(
-    name = "ctoolchain_comparator_lib_test",
-    srcs = ["ctoolchain_comparator_lib_test.py"],
-    python_version = "PY3",
-    deps = [
-        ":ctoolchain_comparator_lib",
-        "//third_party/com/github/bazelbuild/bazel/src/main/protobuf:crosstool_config_py_pb2",
-        "@py_mock//py/mock",
-    ],
-)
-
-go_binary(
-    name = "convert_crosstool_to_starlark",
-    srcs = ["convert_crosstool_to_starlark.go"],
-    deps = [
-        ":crosstooltostarlarklib",
-        "//third_party/com/github/bazelbuild/bazel/src/main/protobuf:crosstool_config_go_proto",
-        "@com_github_golang_protobuf//proto:go_default_library",
-    ],
-)
-
-go_library(
-    name = "crosstooltostarlarklib",
-    srcs = ["crosstool_to_starlark_lib.go"],
-    importpath = "tools/migration/crosstooltostarlarklib",
-    deps = ["//third_party/com/github/bazelbuild/bazel/src/main/protobuf:crosstool_config_go_proto"],
-)
-
-go_test(
-    name = "crosstooltostarlarklib_test",
-    size = "small",
-    srcs = ["crosstool_to_starlark_lib_test.go"],
-    embed = [":crosstooltostarlarklib"],
-    deps = [
-        "//third_party/com/github/bazelbuild/bazel/src/main/protobuf:crosstool_config_go_proto",
-        "@com_github_golang_protobuf//proto:go_default_library",
-    ],
-)
-
-filegroup(
-    name = "bazel_osx_p4deps",
-    srcs = [
-        "BUILD",
-        "ctoolchain_compare.bzl",
-    ],
-)
-
-bzl_library(
-    name = "ctoolchain_compare_bzl",
-    srcs = ["ctoolchain_compare.bzl"],
-    visibility = ["//visibility:private"],
-)
-
-bzl_library(
-    name = "cc_toolchain_config_comparator_bzl",
-    srcs = ["cc_toolchain_config_comparator.bzl"],
-    visibility = ["//visibility:private"],
-)
diff --git a/tools/migration/cc_toolchain_config_comparator.bzl b/tools/migration/cc_toolchain_config_comparator.bzl
deleted file mode 100644
index 66746b3..0000000
--- a/tools/migration/cc_toolchain_config_comparator.bzl
+++ /dev/null
@@ -1,53 +0,0 @@
-"""A test rule that compares two C++ toolchain configuration rules in proto format."""
-
-def _impl(ctx):
-    first_toolchain_config_proto = ctx.actions.declare_file(
-        ctx.label.name + "_first_toolchain_config.proto",
-    )
-    ctx.actions.write(
-        first_toolchain_config_proto,
-        ctx.attr.first[CcToolchainConfigInfo].proto,
-    )
-
-    second_toolchain_config_proto = ctx.actions.declare_file(
-        ctx.label.name + "_second_toolchain_config.proto",
-    )
-    ctx.actions.write(
-        second_toolchain_config_proto,
-        ctx.attr.second[CcToolchainConfigInfo].proto,
-    )
-
-    script = ("%s --before='%s' --after='%s'" % (
-        ctx.executable._comparator.short_path,
-        first_toolchain_config_proto.short_path,
-        second_toolchain_config_proto.short_path,
-    ))
-    test_executable = ctx.actions.declare_file(ctx.label.name)
-    ctx.actions.write(test_executable, script, is_executable = True)
-
-    runfiles = ctx.runfiles(files = [first_toolchain_config_proto, second_toolchain_config_proto])
-    runfiles = runfiles.merge(ctx.attr._comparator[DefaultInfo].default_runfiles)
-
-    return DefaultInfo(runfiles = runfiles, executable = test_executable)
-
-cc_toolchain_config_compare_test = rule(
-    implementation = _impl,
-    attrs = {
-        "first": attr.label(
-            mandatory = True,
-            providers = [CcToolchainConfigInfo],
-            doc = "A C++ toolchain config rule",
-        ),
-        "second": attr.label(
-            mandatory = True,
-            providers = [CcToolchainConfigInfo],
-            doc = "A C++ toolchain config rule",
-        ),
-        "_comparator": attr.label(
-            default = ":ctoolchain_comparator",
-            executable = True,
-            cfg = "exec",
-        ),
-    },
-    test = True,
-)
diff --git a/tools/migration/convert_crosstool_to_starlark.go b/tools/migration/convert_crosstool_to_starlark.go
deleted file mode 100644
index 2c31456..0000000
--- a/tools/migration/convert_crosstool_to_starlark.go
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-The convert_crosstool_to_starlark script takes in a CROSSTOOL file and
-generates a Starlark rule.
-
-See https://github.com/bazelbuild/bazel/issues/5380
-
-Example usage:
-bazel run \
-@rules_cc//tools/migration:convert_crosstool_to_starlark -- \
---crosstool=/path/to/CROSSTOOL \
---output_location=/path/to/cc_config.bzl
-*/
-package main
-
-import (
-	"flag"
-	"fmt"
-	"io/ioutil"
-	"os"
-	"os/user"
-	"path"
-	"strings"
-
-	// Google internal base/go package, commented out by copybara
-	"log"
-	crosstoolpb "third_party/com/github/bazelbuild/bazel/src/main/protobuf/crosstool_config_go_proto"
-	"github.com/golang/protobuf/proto"
-
-	"tools/migration/crosstooltostarlarklib"
-)
-
-var (
-	crosstoolLocation = flag.String(
-		"crosstool", "", "Location of the CROSSTOOL file")
-	outputLocation = flag.String(
-		"output_location", "", "Location of the output .bzl file")
-)
-
-func toAbsolutePath(pathString string) (string, error) {
-	usr, err := user.Current()
-	if err != nil {
-		return "", err
-	}
-	homeDir := usr.HomeDir
-
-	if strings.HasPrefix(pathString, "~") {
-		return path.Join(homeDir, pathString[1:]), nil
-	}
-
-	if path.IsAbs(pathString) {
-		return pathString, nil
-	}
-
-	workingDirectory := os.Getenv("BUILD_WORKING_DIRECTORY")
-	return path.Join(workingDirectory, pathString), nil
-}
-
-func main() {
-	flag.Parse()
-
-	if *crosstoolLocation == "" {
-		log.Fatalf("Missing mandatory argument 'crosstool'")
-	}
-	crosstoolPath, err := toAbsolutePath(*crosstoolLocation)
-	if err != nil {
-		log.Fatalf("Error while resolving CROSSTOOL location:", err)
-	}
-
-	if *outputLocation == "" {
-		log.Fatalf("Missing mandatory argument 'output_location'")
-	}
-	outputPath, err := toAbsolutePath(*outputLocation)
-	if err != nil {
-		log.Fatalf("Error resolving output location:", err)
-	}
-
-	in, err := ioutil.ReadFile(crosstoolPath)
-	if err != nil {
-		log.Fatalf("Error reading CROSSTOOL file:", err)
-	}
-	crosstool := &crosstoolpb.CrosstoolRelease{}
-	if err := proto.UnmarshalText(string(in), crosstool); err != nil {
-		log.Fatalf("Failed to parse CROSSTOOL:", err)
-	}
-
-	file, err := os.Create(outputPath)
-	if err != nil {
-		log.Fatalf("Error creating output file:", err)
-	}
-	defer file.Close()
-
-	rule, err := crosstooltostarlarklib.Transform(crosstool)
-	if err != nil {
-		log.Fatalf("Error converting CROSSTOOL to a Starlark rule:", err)
-	}
-
-	if _, err := file.WriteString(rule); err != nil {
-		log.Fatalf("Error converting CROSSTOOL to a Starlark rule:", err)
-	}
-	fmt.Println("Success!")
-}
diff --git a/tools/migration/crosstool_query.py b/tools/migration/crosstool_query.py
deleted file mode 100644
index af3f7fa..0000000
--- a/tools/migration/crosstool_query.py
+++ /dev/null
@@ -1,53 +0,0 @@
-"""Script to make automated CROSSTOOL refactorings easier.
-
-This script reads the CROSSTOOL file and allows for querying of its fields.
-"""
-
-from absl import app
-from absl import flags
-from google.protobuf import text_format
-from third_party.com.github.bazelbuild.bazel.src.main.protobuf import crosstool_config_pb2
-
-flags.DEFINE_string("crosstool", None, "CROSSTOOL file path to be queried")
-flags.DEFINE_string("identifier", None,
-                    "Toolchain identifier to specify toolchain.")
-flags.DEFINE_string("print_field", None, "Field to be printed to stdout.")
-
-
-def main(unused_argv):
-  crosstool = crosstool_config_pb2.CrosstoolRelease()
-
-  crosstool_filename = flags.FLAGS.crosstool
-  identifier = flags.FLAGS.identifier
-  print_field = flags.FLAGS.print_field
-
-  if not crosstool_filename:
-    raise app.UsageError("ERROR crosstool unspecified")
-  if not identifier:
-    raise app.UsageError("ERROR identifier unspecified")
-
-  if not print_field:
-    raise app.UsageError("ERROR print_field unspecified")
-
-  with open(crosstool_filename, "r") as f:
-    text = f.read()
-    text_format.Merge(text, crosstool)
-
-  toolchain_found = False
-  for toolchain in crosstool.toolchain:
-    if toolchain.toolchain_identifier == identifier:
-      toolchain_found = True
-      if not print_field:
-        continue
-      for field, value in toolchain.ListFields():
-        if print_field == field.name:
-          print value
-
-  if not toolchain_found:
-    print "toolchain_identifier %s not found, valid values are:" % identifier
-    for toolchain in crosstool.toolchain:
-      print "  " + toolchain.toolchain_identifier
-
-
-if __name__ == "__main__":
-  app.run(main)
diff --git a/tools/migration/crosstool_to_starlark_lib.go b/tools/migration/crosstool_to_starlark_lib.go
deleted file mode 100644
index 15f5c12..0000000
--- a/tools/migration/crosstool_to_starlark_lib.go
+++ /dev/null
@@ -1,1419 +0,0 @@
-/*
-Package crosstooltostarlarklib provides the Transform method
-for conversion of a CROSSTOOL file to a Starlark rule.
-
-https://github.com/bazelbuild/bazel/issues/5380
-*/
-package crosstooltostarlarklib
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-	"sort"
-	"strings"
-
-	crosstoolpb "third_party/com/github/bazelbuild/bazel/src/main/protobuf/crosstool_config_go_proto"
-)
-
-// CToolchainIdentifier is what we'll use to differ between CToolchains
-// If a CToolchain can be distinguished from the other CToolchains
-// by only one of the fields (eg if cpu is different for each CToolchain
-// then only that field will be set.
-type CToolchainIdentifier struct {
-	cpu      string
-	compiler string
-}
-
-// Writes the load statement for the cc_toolchain_config_lib
-func getCcToolchainConfigHeader() string {
-	return `load("@rules_cc//cc:cc_toolchain_config_lib.bzl",
-    "action_config",
-    "artifact_name_pattern",
-    "env_entry",
-    "env_set",
-    "feature",
-    "feature_set",
-    "flag_group",
-    "flag_set",
-    "make_variable",
-    "tool",
-    "tool_path",
-    "variable_with_value",
-    "with_feature_set",
-)
-`
-}
-
-var allCompileActions = []string{
-	"c-compile",
-	"c++-compile",
-	"linkstamp-compile",
-	"assemble",
-	"preprocess-assemble",
-	"c++-header-parsing",
-	"c++-module-compile",
-	"c++-module-codegen",
-	"clif-match",
-	"lto-backend",
-}
-
-var allCppCompileActions = []string{
-	"c++-compile",
-	"linkstamp-compile",
-	"c++-header-parsing",
-	"c++-module-compile",
-	"c++-module-codegen",
-	"clif-match",
-}
-
-var preprocessorCompileActions = []string{
-	"c-compile",
-	"c++-compile",
-	"linkstamp-compile",
-	"preprocess-assemble",
-	"c++-header-parsing",
-	"c++-module-compile",
-	"clif-match",
-}
-
-var codegenCompileActions = []string{
-	"c-compile",
-	"c++-compile",
-	"linkstamp-compile",
-	"assemble",
-	"preprocess-assemble",
-	"c++-module-codegen",
-	"lto-backend",
-}
-
-var allLinkActions = []string{
-	"c++-link-executable",
-	"c++-link-dynamic-library",
-	"c++-link-nodeps-dynamic-library",
-}
-
-var actionNames = map[string]string{
-	"c-compile":                       "ACTION_NAMES.c_compile",
-	"c++-compile":                     "ACTION_NAMES.cpp_compile",
-	"linkstamp-compile":               "ACTION_NAMES.linkstamp_compile",
-	"cc-flags-make-variable":          "ACTION_NAMES.cc_flags_make_variable",
-	"c++-module-codegen":              "ACTION_NAMES.cpp_module_codegen",
-	"c++-header-parsing":              "ACTION_NAMES.cpp_header_parsing",
-	"c++-module-compile":              "ACTION_NAMES.cpp_module_compile",
-	"assemble":                        "ACTION_NAMES.assemble",
-	"preprocess-assemble":             "ACTION_NAMES.preprocess_assemble",
-	"lto-indexing":                    "ACTION_NAMES.lto_indexing",
-	"lto-backend":                     "ACTION_NAMES.lto_backend",
-	"c++-link-executable":             "ACTION_NAMES.cpp_link_executable",
-	"c++-link-dynamic-library":        "ACTION_NAMES.cpp_link_dynamic_library",
-	"c++-link-nodeps-dynamic-library": "ACTION_NAMES.cpp_link_nodeps_dynamic_library",
-	"c++-link-static-library":         "ACTION_NAMES.cpp_link_static_library",
-	"strip":                           "ACTION_NAMES.strip",
-	"objc-compile":                    "ACTION_NAMES.objc_compile",
-	"objc++-compile":                  "ACTION_NAMES.objcpp_compile",
-	"clif-match":                      "ACTION_NAMES.clif_match",
-// 	"objcopy_embed_data":              "ACTION_NAMES.objcopy_embed_data", // copybara-comment-this-out-please
-// 	"ld_embed_data":                   "ACTION_NAMES.ld_embed_data",      // copybara-comment-this-out-please
-}
-
-func getLoadActionsStmt() string {
-	return "load(\"@rules_cc//cc:action_names.bzl\", \"ACTION_NAMES\")\n\n"
-}
-
-// Returns a map {toolchain_identifier : CToolchainIdentifier}
-func toolchainToCToolchainIdentifier(
-	crosstool *crosstoolpb.CrosstoolRelease) map[string]CToolchainIdentifier {
-	cpuToCompiler := make(map[string][]string)
-	compilerToCPU := make(map[string][]string)
-	var cpus []string
-	var compilers []string
-	var identifiers []string
-	res := make(map[string]CToolchainIdentifier)
-	for _, cToolchain := range crosstool.GetToolchain() {
-		cpu := cToolchain.GetTargetCpu()
-		compiler := cToolchain.GetCompiler()
-
-		cpuToCompiler[cpu] = append(cpuToCompiler[cpu], compiler)
-		compilerToCPU[compiler] = append(compilerToCPU[compiler], cpu)
-
-		cpus = append(cpus, cToolchain.GetTargetCpu())
-		compilers = append(compilers, cToolchain.GetCompiler())
-		identifiers = append(identifiers, cToolchain.GetToolchainIdentifier())
-	}
-
-	for i := range cpus {
-		if len(cpuToCompiler[cpus[i]]) == 1 {
-			// if cpu is unique among CToolchains, we don't need the compiler field
-			res[identifiers[i]] = CToolchainIdentifier{cpu: cpus[i], compiler: ""}
-		} else {
-			res[identifiers[i]] = CToolchainIdentifier{
-				cpu:      cpus[i],
-				compiler: compilers[i],
-			}
-		}
-	}
-	return res
-}
-
-func getConditionStatementForCToolchainIdentifier(identifier CToolchainIdentifier) string {
-	if identifier.compiler != "" {
-		return fmt.Sprintf(
-			"ctx.attr.cpu == \"%s\" and ctx.attr.compiler == \"%s\"",
-			identifier.cpu,
-			identifier.compiler)
-	}
-	return fmt.Sprintf("ctx.attr.cpu == \"%s\"", identifier.cpu)
-}
-
-func isArrayPrefix(prefix []string, arr []string) bool {
-	if len(prefix) > len(arr) {
-		return false
-	}
-	for i := 0; i < len(prefix); i++ {
-		if arr[i] != prefix[i] {
-			return false
-		}
-	}
-	return true
-}
-
-func isAllCompileActions(actions []string) (bool, []string) {
-	if isArrayPrefix(allCompileActions, actions) {
-		return true, actions[len(allCompileActions):]
-	}
-	return false, actions
-}
-
-func isAllCppCompileActions(actions []string) (bool, []string) {
-	if isArrayPrefix(allCppCompileActions, actions) {
-		return true, actions[len(allCppCompileActions):]
-	}
-	return false, actions
-}
-
-func isPreprocessorCompileActions(actions []string) (bool, []string) {
-	if isArrayPrefix(preprocessorCompileActions, actions) {
-		return true, actions[len(preprocessorCompileActions):]
-	}
-	return false, actions
-}
-
-func isCodegenCompileActions(actions []string) (bool, []string) {
-	if isArrayPrefix(codegenCompileActions, actions) {
-		return true, actions[len(codegenCompileActions):]
-	}
-	return false, actions
-}
-
-func isAllLinkActions(actions []string) (bool, []string) {
-	if isArrayPrefix(allLinkActions, actions) {
-		return true, actions[len(allLinkActions):]
-	}
-	return false, actions
-}
-
-func getActionNames(actions []string) []string {
-	var res []string
-	for _, el := range actions {
-		if name, ok := actionNames[el]; ok {
-			res = append(res, name)
-		} else {
-			res = append(res, "\""+el+"\"")
-		}
-	}
-	return res
-}
-
-func getListOfActions(name string, depth int) string {
-	var res []string
-	if name == "all_compile_actions" {
-		res = getActionNames(allCompileActions)
-	} else if name == "all_cpp_compile_actions" {
-		res = getActionNames(allCppCompileActions)
-	} else if name == "preprocessor_compile_actions" {
-		res = getActionNames(preprocessorCompileActions)
-	} else if name == "codegen_compile_actions" {
-		res = getActionNames(codegenCompileActions)
-	} else if name == "all_link_actions" {
-		res = getActionNames(allLinkActions)
-	}
-	stmt := fmt.Sprintf("%s%s = %s\n\n", getTabs(depth),
-		name, makeStringArr(res, depth /* isPlainString= */, false))
-	return stmt
-}
-
-func processActions(actions []string, depth int) []string {
-	var res []string
-	var ok bool
-	initLen := len(actions)
-	if ok, actions = isAllCompileActions(actions); ok {
-		res = append(res, "all_compile_actions")
-	}
-	if ok, actions = isAllCppCompileActions(actions); ok {
-		res = append(res, "all_cpp_compile_actions")
-	}
-	if ok, actions = isPreprocessorCompileActions(actions); ok {
-		res = append(res, "preprocessor_compile_actions")
-	}
-	if ok, actions = isCodegenCompileActions(actions); ok {
-		res = append(res, "codegen_actions")
-	}
-	if ok, actions = isAllLinkActions(actions); ok {
-		res = append(res, "all_link_actions")
-	}
-	if len(actions) != 0 {
-		actions = getActionNames(actions)
-		newDepth := depth + 1
-		if len(actions) != initLen {
-			newDepth++
-		}
-		res = append(res, makeStringArr(actions, newDepth /* isPlainString= */, false))
-	}
-	return res
-}
-
-func getUniqueValues(arr []string) []string {
-	valuesSet := make(map[string]bool)
-	for _, val := range arr {
-		valuesSet[val] = true
-	}
-	var uniques []string
-	for val, _ := range valuesSet {
-		uniques = append(uniques, val)
-	}
-	sort.Strings(uniques)
-	return uniques
-}
-
-func getRule(cToolchainIdentifiers map[string]CToolchainIdentifier,
-	allowedCompilers []string) string {
-	cpus := make(map[string]bool)
-	shouldUseCompilerAttribute := false
-	for _, val := range cToolchainIdentifiers {
-		cpus[val.cpu] = true
-		if val.compiler != "" {
-			shouldUseCompilerAttribute = true
-		}
-	}
-
-	var cpuValues []string
-	for cpu := range cpus {
-		cpuValues = append(cpuValues, cpu)
-	}
-
-	var args []string
-	sort.Strings(cpuValues)
-	args = append(args,
-		fmt.Sprintf(
-			`"cpu": attr.string(mandatory=True, values=["%s"]),`,
-			strings.Join(cpuValues, "\", \"")))
-	if shouldUseCompilerAttribute {
-		// If there are two CToolchains that share the cpu we need the compiler attribute
-		// for our cc_toolchain_config rule.
-		allowedCompilers = getUniqueValues(allowedCompilers)
-		args = append(args,
-			fmt.Sprintf(`"compiler": attr.string(mandatory=True, values=["%s"]),`,
-				strings.Join(allowedCompilers, "\", \"")))
-	}
-	return fmt.Sprintf(`cc_toolchain_config =  rule(
-    implementation = _impl,
-    attrs = {
-        %s
-    },
-    provides = [CcToolchainConfigInfo],
-    executable = True,
-)
-`, strings.Join(args, "\n        "))
-}
-
-func getImplHeader() string {
-	return "def _impl(ctx):\n"
-}
-
-func getStringStatement(crosstool *crosstoolpb.CrosstoolRelease,
-	cToolchainIdentifiers map[string]CToolchainIdentifier, field string,
-	depth int) string {
-
-	identifiers := getToolchainIdentifiers(crosstool)
-	var fieldValues []string
-	if field == "toolchain_identifier" {
-		fieldValues = getToolchainIdentifiers(crosstool)
-	} else if field == "host_system_name" {
-		fieldValues = getHostSystemNames(crosstool)
-	} else if field == "target_system_name" {
-		fieldValues = getTargetSystemNames(crosstool)
-	} else if field == "target_cpu" {
-		fieldValues = getTargetCpus(crosstool)
-	} else if field == "target_libc" {
-		fieldValues = getTargetLibcs(crosstool)
-	} else if field == "compiler" {
-		fieldValues = getCompilers(crosstool)
-	} else if field == "abi_version" {
-		fieldValues = getAbiVersions(crosstool)
-	} else if field == "abi_libc_version" {
-		fieldValues = getAbiLibcVersions(crosstool)
-	} else if field == "cc_target_os" {
-		fieldValues = getCcTargetOss(crosstool)
-	} else if field == "builtin_sysroot" {
-		fieldValues = getBuiltinSysroots(crosstool)
-	}
-
-	mappedValuesToIds := getMappedStringValuesToIdentifiers(identifiers, fieldValues)
-	return getAssignmentStatement(field, mappedValuesToIds, crosstool,
-		cToolchainIdentifiers, depth /* isPlainString= */, true /* shouldFail= */, true)
-}
-
-func getFeatures(crosstool *crosstoolpb.CrosstoolRelease) (
-	map[string][]string, map[string]map[string][]string, error) {
-	featureNameToFeature := make(map[string]map[string][]string)
-	toolchainToFeatures := make(map[string][]string)
-	for _, toolchain := range crosstool.GetToolchain() {
-		id := toolchain.GetToolchainIdentifier()
-		if len(toolchain.GetFeature()) == 0 {
-			toolchainToFeatures[id] = []string{}
-		}
-		for _, feature := range toolchain.GetFeature() {
-			featureName := strings.ToLower(feature.GetName()) + "_feature"
-			featureName = strings.Replace(featureName, "+", "p", -1)
-			featureName = strings.Replace(featureName, ".", "_", -1)
-			featureName = strings.Replace(featureName, "-", "_", -1)
-			stringFeature, err := parseFeature(feature, 1)
-			if err != nil {
-				return nil, nil, fmt.Errorf(
-					"Error in feature '%s': %v", feature.GetName(), err)
-			}
-			if _, ok := featureNameToFeature[featureName]; !ok {
-				featureNameToFeature[featureName] = make(map[string][]string)
-			}
-			featureNameToFeature[featureName][stringFeature] = append(
-				featureNameToFeature[featureName][stringFeature], id)
-			toolchainToFeatures[id] = append(toolchainToFeatures[id], featureName)
-		}
-	}
-	return toolchainToFeatures, featureNameToFeature, nil
-}
-
-func getFeaturesDeclaration(crosstool *crosstoolpb.CrosstoolRelease,
-	cToolchainIdentifiers map[string]CToolchainIdentifier,
-	featureNameToFeature map[string]map[string][]string, depth int) string {
-	var res []string
-	for featureName, featureStringToID := range featureNameToFeature {
-		res = append(res,
-			getAssignmentStatement(
-				featureName,
-				featureStringToID,
-				crosstool,
-				cToolchainIdentifiers,
-				depth,
-				/* isPlainString= */ false,
-				/* shouldFail= */ false))
-	}
-	return strings.Join(res, "")
-}
-
-func getFeaturesStmt(cToolchainIdentifiers map[string]CToolchainIdentifier,
-	toolchainToFeatures map[string][]string, depth int) string {
-	var res []string
-	arrToIdentifier := make(map[string][]string)
-	for id, features := range toolchainToFeatures {
-		arrayString := strings.Join(features, "{arrayFieldDelimiter}")
-		arrToIdentifier[arrayString] = append(arrToIdentifier[arrayString], id)
-	}
-	res = append(res,
-		getStringArrStatement(
-			"features",
-			arrToIdentifier,
-			cToolchainIdentifiers,
-			depth,
-			/* isPlainString= */ false))
-	return strings.Join(res, "\n")
-}
-
-func getActions(crosstool *crosstoolpb.CrosstoolRelease) (
-	map[string][]string, map[string]map[string][]string, error) {
-	actionNameToAction := make(map[string]map[string][]string)
-	toolchainToActions := make(map[string][]string)
-	for _, toolchain := range crosstool.GetToolchain() {
-		id := toolchain.GetToolchainIdentifier()
-		var actionName string
-		if len(toolchain.GetActionConfig()) == 0 {
-			toolchainToActions[id] = []string{}
-		}
-		for _, action := range toolchain.GetActionConfig() {
-			if aName, ok := actionNames[action.GetActionName()]; ok {
-				actionName = aName
-			} else {
-				actionName = strings.ToLower(action.GetActionName())
-				actionName = strings.Replace(actionName, "+", "p", -1)
-				actionName = strings.Replace(actionName, ".", "_", -1)
-				actionName = strings.Replace(actionName, "-", "_", -1)
-			}
-			stringAction, err := parseAction(action, 1)
-			if err != nil {
-				return nil, nil, fmt.Errorf(
-					"Error in action_config '%s': %v", action.GetActionName(), err)
-			}
-			if _, ok := actionNameToAction[actionName]; !ok {
-				actionNameToAction[actionName] = make(map[string][]string)
-			}
-			actionNameToAction[actionName][stringAction] = append(
-				actionNameToAction[actionName][stringAction], id)
-			toolchainToActions[id] = append(
-				toolchainToActions[id],
-				strings.TrimPrefix(strings.ToLower(actionName), "action_names.")+"_action")
-		}
-	}
-	return toolchainToActions, actionNameToAction, nil
-}
-
-func getActionConfigsDeclaration(
-	crosstool *crosstoolpb.CrosstoolRelease,
-	cToolchainIdentifiers map[string]CToolchainIdentifier,
-	actionNameToAction map[string]map[string][]string, depth int) string {
-	var res []string
-	for actionName, actionStringToID := range actionNameToAction {
-		variableName := strings.TrimPrefix(strings.ToLower(actionName), "action_names.") + "_action"
-		res = append(res,
-			getAssignmentStatement(
-				variableName,
-				actionStringToID,
-				crosstool,
-				cToolchainIdentifiers,
-				depth,
-				/* isPlainString= */ false,
-				/* shouldFail= */ false))
-	}
-	return strings.Join(res, "")
-}
-
-func getActionConfigsStmt(
-	cToolchainIdentifiers map[string]CToolchainIdentifier,
-	toolchainToActions map[string][]string, depth int) string {
-	var res []string
-	arrToIdentifier := make(map[string][]string)
-	for id, actions := range toolchainToActions {
-		var arrayString string
-		arrayString = strings.Join(actions, "{arrayFieldDelimiter}")
-		arrToIdentifier[arrayString] = append(arrToIdentifier[arrayString], id)
-	}
-	res = append(res,
-		getStringArrStatement(
-			"action_configs",
-			arrToIdentifier,
-			cToolchainIdentifiers,
-			depth,
-			/* isPlainString= */ false))
-	return strings.Join(res, "\n")
-}
-
-func parseAction(action *crosstoolpb.CToolchain_ActionConfig, depth int) (string, error) {
-	actionName := action.GetActionName()
-	aName := ""
-	if val, ok := actionNames[actionName]; ok {
-		aName = val
-	} else {
-		aName = "\"" + action.GetActionName() + "\""
-	}
-	name := fmt.Sprintf("action_name = %s", aName)
-	fields := []string{name}
-	if action.GetEnabled() {
-		fields = append(fields, "enabled = True")
-	}
-	if len(action.GetFlagSet()) != 0 {
-		flagSets, err := parseFlagSets(action.GetFlagSet(), depth+1)
-		if err != nil {
-			return "", err
-		}
-		fields = append(fields, "flag_sets = "+flagSets)
-	}
-	if len(action.GetImplies()) != 0 {
-		implies := "implies = " +
-			makeStringArr(action.GetImplies(), depth+1 /* isPlainString= */, true)
-		fields = append(fields, implies)
-	}
-	if len(action.GetTool()) != 0 {
-		tools := "tools = " + parseTools(action.GetTool(), depth+1)
-		fields = append(fields, tools)
-	}
-	return createObject("action_config", fields, depth), nil
-}
-
-func getStringArrStatement(attr string, arrValToIds map[string][]string,
-	cToolchainIdentifiers map[string]CToolchainIdentifier, depth int, plainString bool) string {
-	var b bytes.Buffer
-	if len(arrValToIds) == 0 {
-		b.WriteString(fmt.Sprintf("%s%s = []\n", getTabs(depth), attr))
-	} else if len(arrValToIds) == 1 {
-		for value := range arrValToIds {
-			var arr []string
-			if value == "" {
-				arr = []string{}
-			} else if value == "None" {
-				b.WriteString(fmt.Sprintf("%s%s = None\n", getTabs(depth), attr))
-				break
-			} else {
-				arr = strings.Split(value, "{arrayFieldDelimiter}")
-			}
-			b.WriteString(
-				fmt.Sprintf(
-					"%s%s = %s\n",
-					getTabs(depth),
-					attr,
-					makeStringArr(arr, depth+1, plainString)))
-			break
-		}
-	} else {
-		first := true
-		var keys []string
-		for k := range arrValToIds {
-			keys = append(keys, k)
-		}
-		sort.Strings(keys)
-		for _, value := range keys {
-			ids := arrValToIds[value]
-			branch := "elif"
-			if first {
-				branch = "if"
-			}
-			first = false
-			var arr []string
-			if value == "" {
-				arr = []string{}
-			} else if value == "None" {
-				b.WriteString(
-					getIfStatement(
-						branch, ids, attr, "None", cToolchainIdentifiers,
-						depth /* isPlainString= */, true))
-				continue
-			} else {
-				arr = strings.Split(value, "{arrayFieldDelimiter}")
-			}
-			b.WriteString(
-				getIfStatement(branch, ids, attr,
-					makeStringArr(arr, depth+1, plainString),
-					cToolchainIdentifiers, depth /* isPlainString= */, false))
-		}
-		b.WriteString(fmt.Sprintf("%selse:\n%sfail(\"Unreachable\")\n", getTabs(depth), getTabs(depth+1)))
-	}
-	b.WriteString("\n")
-	return b.String()
-}
-
-func getStringArr(crosstool *crosstoolpb.CrosstoolRelease,
-	cToolchainIdentifiers map[string]CToolchainIdentifier, attr string, depth int) string {
-	var res []string
-	arrToIdentifier := make(map[string][]string)
-	for _, toolchain := range crosstool.GetToolchain() {
-		id := toolchain.GetToolchainIdentifier()
-		arrayString := strings.Join(getArrField(attr, toolchain), "{arrayFieldDelimiter}")
-		arrToIdentifier[arrayString] = append(arrToIdentifier[arrayString], id)
-	}
-	statement := getStringArrStatement(attr, arrToIdentifier, cToolchainIdentifiers, depth /* isPlainString= */, true)
-	res = append(res, statement)
-	return strings.Join(res, "\n")
-}
-
-func getArrField(attr string, toolchain *crosstoolpb.CToolchain) []string {
-	var arr []string
-	if attr == "cxx_builtin_include_directories" {
-		arr = toolchain.GetCxxBuiltinIncludeDirectory()
-	}
-	return arr
-}
-
-func getTabs(depth int) string {
-	var res string
-	for i := 0; i < depth; i++ {
-		res = res + "    "
-	}
-	return res
-}
-
-func createObject(objtype string, fields []string, depth int) string {
-	if len(fields) == 0 {
-		return objtype + "()"
-	}
-	singleLine := objtype + "(" + strings.Join(fields, ", ") + ")"
-	if len(singleLine) < 60 {
-		return singleLine
-	}
-	return objtype +
-		"(\n" +
-		getTabs(depth+1) +
-		strings.Join(fields, ",\n"+getTabs(depth+1)) +
-		",\n" + getTabs(depth) +
-		")"
-}
-
-func getArtifactNamePatterns(crosstool *crosstoolpb.CrosstoolRelease,
-	cToolchainIdentifiers map[string]CToolchainIdentifier, depth int) string {
-	var res []string
-	artifactToIds := make(map[string][]string)
-	for _, toolchain := range crosstool.GetToolchain() {
-		artifactNamePatterns := parseArtifactNamePatterns(
-			toolchain.GetArtifactNamePattern(),
-			depth)
-		artifactToIds[artifactNamePatterns] = append(
-			artifactToIds[artifactNamePatterns],
-			toolchain.GetToolchainIdentifier())
-	}
-	res = append(res,
-		getAssignmentStatement(
-			"artifact_name_patterns",
-			artifactToIds,
-			crosstool,
-			cToolchainIdentifiers,
-			depth,
-			/* isPlainString= */ false,
-			/* shouldFail= */ true))
-	return strings.Join(res, "\n")
-}
-
-func parseArtifactNamePatterns(
-	artifactNamePatterns []*crosstoolpb.CToolchain_ArtifactNamePattern, depth int) string {
-	var res []string
-	for _, pattern := range artifactNamePatterns {
-		res = append(res, parseArtifactNamePattern(pattern, depth+1))
-	}
-	return makeStringArr(res, depth /* isPlainString= */, false)
-}
-
-func parseArtifactNamePattern(
-	artifactNamePattern *crosstoolpb.CToolchain_ArtifactNamePattern, depth int) string {
-	categoryName := fmt.Sprintf("category_name = \"%s\"", artifactNamePattern.GetCategoryName())
-	prefix := fmt.Sprintf("prefix = \"%s\"", artifactNamePattern.GetPrefix())
-	extension := fmt.Sprintf("extension = \"%s\"", artifactNamePattern.GetExtension())
-	fields := []string{categoryName, prefix, extension}
-	return createObject("artifact_name_pattern", fields, depth)
-}
-
-func parseFeature(feature *crosstoolpb.CToolchain_Feature, depth int) (string, error) {
-	name := fmt.Sprintf("name = \"%s\"", feature.GetName())
-
-	fields := []string{name}
-	if feature.GetEnabled() {
-		fields = append(fields, "enabled = True")
-	}
-
-	if len(feature.GetFlagSet()) > 0 {
-		flagSets, err := parseFlagSets(feature.GetFlagSet(), depth+1)
-		if err != nil {
-			return "", err
-		}
-		fields = append(fields, "flag_sets = "+flagSets)
-	}
-	if len(feature.GetEnvSet()) > 0 {
-		envSets := "env_sets = " + parseEnvSets(feature.GetEnvSet(), depth+1)
-		fields = append(fields, envSets)
-	}
-	if len(feature.GetRequires()) > 0 {
-		requires := "requires = " + parseFeatureSets(feature.GetRequires(), depth+1)
-		fields = append(fields, requires)
-	}
-	if len(feature.GetImplies()) > 0 {
-		implies := "implies = " +
-			makeStringArr(feature.GetImplies(), depth+1 /* isPlainString= */, true)
-		fields = append(fields, implies)
-	}
-	if len(feature.GetProvides()) > 0 {
-		provides := "provides = " +
-			makeStringArr(feature.GetProvides(), depth+1 /* isPlainString= */, true)
-		fields = append(fields, provides)
-	}
-	return createObject("feature", fields, depth), nil
-}
-
-func parseFlagSets(flagSets []*crosstoolpb.CToolchain_FlagSet, depth int) (string, error) {
-	var res []string
-	for _, flagSet := range flagSets {
-		parsedFlagset, err := parseFlagSet(flagSet, depth+1)
-		if err != nil {
-			return "", err
-		}
-		res = append(res, parsedFlagset)
-	}
-	return makeStringArr(res, depth /* isPlainString= */, false), nil
-}
-
-func parseFlagSet(flagSet *crosstoolpb.CToolchain_FlagSet, depth int) (string, error) {
-	var fields []string
-	if len(flagSet.GetAction()) > 0 {
-		actionArr := processActions(flagSet.GetAction(), depth)
-		actions := "actions = " + strings.Join(actionArr, " +\n"+getTabs(depth+2))
-		fields = append(fields, actions)
-	}
-	if len(flagSet.GetFlagGroup()) > 0 {
-		flagGroups, err := parseFlagGroups(flagSet.GetFlagGroup(), depth+1)
-		if err != nil {
-			return "", err
-		}
-		fields = append(fields, "flag_groups = "+flagGroups)
-	}
-	if len(flagSet.GetWithFeature()) > 0 {
-		withFeatures := "with_features = " +
-			parseWithFeatureSets(flagSet.GetWithFeature(), depth+1)
-		fields = append(fields, withFeatures)
-	}
-	return createObject("flag_set", fields, depth), nil
-}
-
-func parseFlagGroups(flagGroups []*crosstoolpb.CToolchain_FlagGroup, depth int) (string, error) {
-	var res []string
-	for _, flagGroup := range flagGroups {
-		flagGroupString, err := parseFlagGroup(flagGroup, depth+1)
-		if err != nil {
-			return "", err
-		}
-		res = append(res, flagGroupString)
-	}
-	return makeStringArr(res, depth /* isPlainString= */, false), nil
-}
-
-func parseFlagGroup(flagGroup *crosstoolpb.CToolchain_FlagGroup, depth int) (string, error) {
-	var res []string
-	if len(flagGroup.GetFlag()) != 0 {
-		res = append(res, "flags = "+makeStringArr(flagGroup.GetFlag(), depth+1, true))
-	}
-	if flagGroup.GetIterateOver() != "" {
-		res = append(res, fmt.Sprintf("iterate_over = \"%s\"", flagGroup.GetIterateOver()))
-	}
-	if len(flagGroup.GetFlagGroup()) != 0 {
-		flagGroupString, err := parseFlagGroups(flagGroup.GetFlagGroup(), depth+1)
-		if err != nil {
-			return "", err
-		}
-		res = append(res, "flag_groups = "+flagGroupString)
-	}
-	if len(flagGroup.GetExpandIfAllAvailable()) > 1 {
-		return "", errors.New("Flag group must not have more than one 'expand_if_all_available' field")
-	}
-	if len(flagGroup.GetExpandIfAllAvailable()) != 0 {
-		res = append(res,
-			fmt.Sprintf(
-				"expand_if_available = \"%s\"",
-				flagGroup.GetExpandIfAllAvailable()[0]))
-	}
-	if len(flagGroup.GetExpandIfNoneAvailable()) > 1 {
-		return "", errors.New("Flag group must not have more than one 'expand_if_none_available' field")
-	}
-	if len(flagGroup.GetExpandIfNoneAvailable()) != 0 {
-		res = append(res,
-			fmt.Sprintf(
-				"expand_if_not_available = \"%s\"",
-				flagGroup.GetExpandIfNoneAvailable()[0]))
-	}
-	if flagGroup.GetExpandIfTrue() != "" {
-		res = append(res, fmt.Sprintf("expand_if_true = \"%s\"",
-			flagGroup.GetExpandIfTrue()))
-	}
-	if flagGroup.GetExpandIfFalse() != "" {
-		res = append(res, fmt.Sprintf("expand_if_false = \"%s\"",
-			flagGroup.GetExpandIfFalse()))
-	}
-	if flagGroup.GetExpandIfEqual() != nil {
-		res = append(res,
-			"expand_if_equal = "+parseVariableWithValue(
-				flagGroup.GetExpandIfEqual(), depth+1))
-	}
-	return createObject("flag_group", res, depth), nil
-}
-
-func parseVariableWithValue(variable *crosstoolpb.CToolchain_VariableWithValue, depth int) string {
-	variableName := fmt.Sprintf("name = \"%s\"", variable.GetVariable())
-	value := fmt.Sprintf("value = \"%s\"", variable.GetValue())
-	return createObject("variable_with_value", []string{variableName, value}, depth)
-}
-
-func getToolPaths(crosstool *crosstoolpb.CrosstoolRelease,
-	cToolchainIdentifiers map[string]CToolchainIdentifier, depth int) string {
-	var res []string
-	toolPathsToIds := make(map[string][]string)
-	for _, toolchain := range crosstool.GetToolchain() {
-		toolPaths := parseToolPaths(toolchain.GetToolPath(), depth)
-		toolPathsToIds[toolPaths] = append(
-			toolPathsToIds[toolPaths],
-			toolchain.GetToolchainIdentifier())
-	}
-	res = append(res,
-		getAssignmentStatement(
-			"tool_paths",
-			toolPathsToIds,
-			crosstool,
-			cToolchainIdentifiers,
-			depth,
-			/* isPlainString= */ false,
-			/* shouldFail= */ true))
-	return strings.Join(res, "\n")
-}
-
-func parseToolPaths(toolPaths []*crosstoolpb.ToolPath, depth int) string {
-	var res []string
-	for _, toolPath := range toolPaths {
-		res = append(res, parseToolPath(toolPath, depth+1))
-	}
-	return makeStringArr(res, depth /* isPlainString= */, false)
-}
-
-func parseToolPath(toolPath *crosstoolpb.ToolPath, depth int) string {
-	name := fmt.Sprintf("name = \"%s\"", toolPath.GetName())
-	path := toolPath.GetPath()
-	if path == "" {
-		path = "NOT_USED"
-	}
-	path = fmt.Sprintf("path = \"%s\"", path)
-	return createObject("tool_path", []string{name, path}, depth)
-}
-
-func getMakeVariables(crosstool *crosstoolpb.CrosstoolRelease,
-	cToolchainIdentifiers map[string]CToolchainIdentifier, depth int) string {
-	var res []string
-	makeVariablesToIds := make(map[string][]string)
-	for _, toolchain := range crosstool.GetToolchain() {
-		makeVariables := parseMakeVariables(toolchain.GetMakeVariable(), depth)
-		makeVariablesToIds[makeVariables] = append(
-			makeVariablesToIds[makeVariables],
-			toolchain.GetToolchainIdentifier())
-	}
-	res = append(res,
-		getAssignmentStatement(
-			"make_variables",
-			makeVariablesToIds,
-			crosstool,
-			cToolchainIdentifiers,
-			depth,
-			/* isPlainString= */ false,
-			/* shouldFail= */ true))
-	return strings.Join(res, "\n")
-}
-
-func parseMakeVariables(makeVariables []*crosstoolpb.MakeVariable, depth int) string {
-	var res []string
-	for _, makeVariable := range makeVariables {
-		res = append(res, parseMakeVariable(makeVariable, depth+1))
-	}
-	return makeStringArr(res, depth /* isPlainString= */, false)
-}
-
-func parseMakeVariable(makeVariable *crosstoolpb.MakeVariable, depth int) string {
-	name := fmt.Sprintf("name = \"%s\"", makeVariable.GetName())
-	value := fmt.Sprintf("value = \"%s\"", makeVariable.GetValue())
-	return createObject("make_variable", []string{name, value}, depth)
-}
-
-func parseTools(tools []*crosstoolpb.CToolchain_Tool, depth int) string {
-	var res []string
-	for _, tool := range tools {
-		res = append(res, parseTool(tool, depth+1))
-	}
-	return makeStringArr(res, depth /* isPlainString= */, false)
-}
-
-func parseTool(tool *crosstoolpb.CToolchain_Tool, depth int) string {
-	toolPath := "path = \"NOT_USED\""
-	if tool.GetToolPath() != "" {
-		toolPath = fmt.Sprintf("path = \"%s\"", tool.GetToolPath())
-	}
-	fields := []string{toolPath}
-	if len(tool.GetWithFeature()) != 0 {
-		withFeatures := "with_features = " + parseWithFeatureSets(tool.GetWithFeature(), depth+1)
-		fields = append(fields, withFeatures)
-	}
-	if len(tool.GetExecutionRequirement()) != 0 {
-		executionRequirements := "execution_requirements = " +
-			makeStringArr(tool.GetExecutionRequirement(), depth+1 /* isPlainString= */, true)
-		fields = append(fields, executionRequirements)
-	}
-	return createObject("tool", fields, depth)
-}
-
-func parseEnvEntries(envEntries []*crosstoolpb.CToolchain_EnvEntry, depth int) string {
-	var res []string
-	for _, envEntry := range envEntries {
-		res = append(res, parseEnvEntry(envEntry, depth+1))
-	}
-	return makeStringArr(res, depth /* isPlainString= */, false)
-}
-
-func parseEnvEntry(envEntry *crosstoolpb.CToolchain_EnvEntry, depth int) string {
-	key := fmt.Sprintf("key = \"%s\"", envEntry.GetKey())
-	value := fmt.Sprintf("value = \"%s\"", envEntry.GetValue())
-	return createObject("env_entry", []string{key, value}, depth)
-}
-
-func parseWithFeatureSets(withFeatureSets []*crosstoolpb.CToolchain_WithFeatureSet,
-	depth int) string {
-	var res []string
-	for _, withFeature := range withFeatureSets {
-		res = append(res, parseWithFeatureSet(withFeature, depth+1))
-	}
-	return makeStringArr(res, depth /* isPlainString= */, false)
-}
-
-func parseWithFeatureSet(withFeature *crosstoolpb.CToolchain_WithFeatureSet,
-	depth int) string {
-	var fields []string
-	if len(withFeature.GetFeature()) != 0 {
-		features := "features = " +
-			makeStringArr(withFeature.GetFeature(), depth+1 /* isPlainString= */, true)
-		fields = append(fields, features)
-	}
-	if len(withFeature.GetNotFeature()) != 0 {
-		notFeatures := "not_features = " +
-			makeStringArr(withFeature.GetNotFeature(), depth+1 /* isPlainString= */, true)
-		fields = append(fields, notFeatures)
-	}
-	return createObject("with_feature_set", fields, depth)
-}
-
-func parseEnvSets(envSets []*crosstoolpb.CToolchain_EnvSet, depth int) string {
-	var res []string
-	for _, envSet := range envSets {
-		envSetString := parseEnvSet(envSet, depth+1)
-		res = append(res, envSetString)
-	}
-	return makeStringArr(res, depth /* isPlainString= */, false)
-}
-
-func parseEnvSet(envSet *crosstoolpb.CToolchain_EnvSet, depth int) string {
-	actionsStatement := processActions(envSet.GetAction(), depth)
-	actions := "actions = " + strings.Join(actionsStatement, " +\n"+getTabs(depth+2))
-	fields := []string{actions}
-	if len(envSet.GetEnvEntry()) != 0 {
-		envEntries := "env_entries = " + parseEnvEntries(envSet.GetEnvEntry(), depth+1)
-		fields = append(fields, envEntries)
-	}
-	if len(envSet.GetWithFeature()) != 0 {
-		withFeatures := "with_features = " + parseWithFeatureSets(envSet.GetWithFeature(), depth+1)
-		fields = append(fields, withFeatures)
-	}
-	return createObject("env_set", fields, depth)
-}
-
-func parseFeatureSets(featureSets []*crosstoolpb.CToolchain_FeatureSet, depth int) string {
-	var res []string
-	for _, featureSet := range featureSets {
-		res = append(res, parseFeatureSet(featureSet, depth+1))
-	}
-	return makeStringArr(res, depth /* isPlainString= */, false)
-}
-
-func parseFeatureSet(featureSet *crosstoolpb.CToolchain_FeatureSet, depth int) string {
-	features := "features = " +
-		makeStringArr(featureSet.GetFeature(), depth+1 /* isPlainString= */, true)
-	return createObject("feature_set", []string{features}, depth)
-}
-
-// Takes in a list of string elements and returns a string that represents
-// an array :
-//     [
-//         "element1",
-//         "element2",
-//     ]
-// The isPlainString argument tells us whether the input elements should be
-// treated as string (eg, flags), or not (eg, variable names)
-func makeStringArr(arr []string, depth int, isPlainString bool) string {
-	if len(arr) == 0 {
-		return "[]"
-	}
-	var escapedArr []string
-	for _, el := range arr {
-		if isPlainString {
-			escapedArr = append(escapedArr, strings.Replace(el, "\"", "\\\"", -1))
-		} else {
-			escapedArr = append(escapedArr, el)
-		}
-	}
-	addQuote := ""
-	if isPlainString {
-		addQuote = "\""
-	}
-	singleLine := "[" + addQuote + strings.Join(escapedArr, addQuote+", "+addQuote) + addQuote + "]"
-	if len(singleLine) < 60 {
-		return singleLine
-	}
-	return "[\n" +
-		getTabs(depth+1) +
-		addQuote +
-		strings.Join(escapedArr, addQuote+",\n"+getTabs(depth+1)+addQuote) +
-		addQuote +
-		",\n" +
-		getTabs(depth) +
-		"]"
-}
-
-// Returns a string that represents a value assignment
-// (eg if ctx.attr.cpu == "linux":
-//         compiler = "llvm"
-//     elif ctx.attr.cpu == "windows":
-//         compiler = "mingw"
-//     else:
-//         fail("Unreachable")
-func getAssignmentStatement(field string, valToIds map[string][]string,
-	crosstool *crosstoolpb.CrosstoolRelease,
-	toCToolchainIdentifier map[string]CToolchainIdentifier,
-	depth int, isPlainString, shouldFail bool) string {
-	var b bytes.Buffer
-	if len(valToIds) <= 1 {
-		// if there is only one possible value for this field, we don't need if statements
-		for val := range valToIds {
-			if val != "None" && isPlainString {
-				val = "\"" + val + "\""
-			}
-			b.WriteString(fmt.Sprintf("%s%s = %s\n", getTabs(depth), field, val))
-			break
-		}
-	} else {
-		first := true
-		var keys []string
-		for k := range valToIds {
-			keys = append(keys, k)
-		}
-		sort.Strings(keys)
-		for _, value := range keys {
-			ids := valToIds[value]
-			branch := "elif"
-			if first {
-				branch = "if"
-			}
-			b.WriteString(
-				getIfStatement(branch, ids, field, value,
-					toCToolchainIdentifier, depth, isPlainString))
-			first = false
-		}
-		if shouldFail {
-			b.WriteString(
-				fmt.Sprintf(
-					"%selse:\n%sfail(\"Unreachable\")\n",
-					getTabs(depth), getTabs(depth+1)))
-		} else {
-			b.WriteString(
-				fmt.Sprintf(
-					"%selse:\n%s%s = None\n",
-					getTabs(depth), getTabs(depth+1), field))
-		}
-	}
-	b.WriteString("\n")
-	return b.String()
-}
-
-func getCPUToCompilers(identifiers []CToolchainIdentifier) map[string][]string {
-	res := make(map[string][]string)
-	for _, identifier := range identifiers {
-		if identifier.compiler != "" {
-			res[identifier.cpu] = append(res[identifier.cpu], identifier.compiler)
-		}
-	}
-	return res
-}
-
-func getIfStatement(ifOrElseIf string, identifiers []string, field, val string,
-	toCToolchainIdentifier map[string]CToolchainIdentifier, depth int,
-	isPlainString bool) string {
-	usedStmts := make(map[string]bool)
-	if val != "None" && isPlainString {
-		val = "\"" + val + "\""
-	}
-	var cToolchainIdentifiers []CToolchainIdentifier
-	for _, value := range toCToolchainIdentifier {
-		cToolchainIdentifiers = append(cToolchainIdentifiers, value)
-	}
-	cpuToCompilers := getCPUToCompilers(cToolchainIdentifiers)
-	countCpus := make(map[string]int)
-	var conditions []string
-	for _, id := range identifiers {
-		identifier := toCToolchainIdentifier[id]
-		stmt := getConditionStatementForCToolchainIdentifier(identifier)
-		if _, ok := usedStmts[stmt]; !ok {
-			conditions = append(conditions, stmt)
-			usedStmts[stmt] = true
-			if identifier.compiler != "" {
-				countCpus[identifier.cpu]++
-			}
-		}
-	}
-
-	var compressedConditions []string
-	usedStmtsOptimized := make(map[string]bool)
-	for _, id := range identifiers {
-		identifier := toCToolchainIdentifier[id]
-		var stmt string
-		if _, ok := countCpus[identifier.cpu]; ok {
-			if countCpus[identifier.cpu] == len(cpuToCompilers[identifier.cpu]) {
-				stmt = getConditionStatementForCToolchainIdentifier(
-					CToolchainIdentifier{cpu: identifier.cpu, compiler: ""})
-			} else {
-				stmt = getConditionStatementForCToolchainIdentifier(identifier)
-			}
-		} else {
-			stmt = getConditionStatementForCToolchainIdentifier(identifier)
-		}
-		if _, ok := usedStmtsOptimized[stmt]; !ok {
-			compressedConditions = append(compressedConditions, stmt)
-			usedStmtsOptimized[stmt] = true
-		}
-	}
-
-	sort.Strings(compressedConditions)
-	val = strings.Join(strings.Split(val, "\n"+getTabs(depth)), "\n"+getTabs(depth+1))
-	return fmt.Sprintf(`%s%s %s:
-%s%s = %s
-`, getTabs(depth),
-		ifOrElseIf,
-		"("+strings.Join(compressedConditions, "\n"+getTabs(depth+1)+"or ")+")",
-		getTabs(depth+1),
-		field,
-		val)
-}
-
-func getToolchainIdentifiers(crosstool *crosstoolpb.CrosstoolRelease) []string {
-	var res []string
-	for _, toolchain := range crosstool.GetToolchain() {
-		res = append(res, toolchain.GetToolchainIdentifier())
-	}
-	return res
-}
-
-func getHostSystemNames(crosstool *crosstoolpb.CrosstoolRelease) []string {
-	var res []string
-	for _, toolchain := range crosstool.GetToolchain() {
-		res = append(res, toolchain.GetHostSystemName())
-	}
-	return res
-}
-
-func getTargetSystemNames(crosstool *crosstoolpb.CrosstoolRelease) []string {
-	var res []string
-	for _, toolchain := range crosstool.GetToolchain() {
-		res = append(res, toolchain.GetTargetSystemName())
-	}
-	return res
-}
-
-func getTargetCpus(crosstool *crosstoolpb.CrosstoolRelease) []string {
-	var res []string
-	for _, toolchain := range crosstool.GetToolchain() {
-		res = append(res, toolchain.GetTargetCpu())
-	}
-	return res
-}
-
-func getTargetLibcs(crosstool *crosstoolpb.CrosstoolRelease) []string {
-	var res []string
-	for _, toolchain := range crosstool.GetToolchain() {
-		res = append(res, toolchain.GetTargetLibc())
-	}
-	return res
-}
-
-func getCompilers(crosstool *crosstoolpb.CrosstoolRelease) []string {
-	var res []string
-	for _, toolchain := range crosstool.GetToolchain() {
-		res = append(res, toolchain.GetCompiler())
-	}
-	return res
-}
-
-func getAbiVersions(crosstool *crosstoolpb.CrosstoolRelease) []string {
-	var res []string
-	for _, toolchain := range crosstool.GetToolchain() {
-		res = append(res, toolchain.GetAbiVersion())
-	}
-	return res
-}
-
-func getAbiLibcVersions(crosstool *crosstoolpb.CrosstoolRelease) []string {
-	var res []string
-	for _, toolchain := range crosstool.GetToolchain() {
-		res = append(res, toolchain.GetAbiLibcVersion())
-	}
-	return res
-}
-
-func getCcTargetOss(crosstool *crosstoolpb.CrosstoolRelease) []string {
-	var res []string
-	for _, toolchain := range crosstool.GetToolchain() {
-		targetOS := "None"
-		if toolchain.GetCcTargetOs() != "" {
-			targetOS = toolchain.GetCcTargetOs()
-		}
-		res = append(res, targetOS)
-	}
-	return res
-}
-
-func getBuiltinSysroots(crosstool *crosstoolpb.CrosstoolRelease) []string {
-	var res []string
-	for _, toolchain := range crosstool.GetToolchain() {
-		sysroot := "None"
-		if toolchain.GetBuiltinSysroot() != "" {
-			sysroot = toolchain.GetBuiltinSysroot()
-		}
-		res = append(res, sysroot)
-	}
-	return res
-}
-
-func getMappedStringValuesToIdentifiers(identifiers, fields []string) map[string][]string {
-	res := make(map[string][]string)
-	for i := range identifiers {
-		res[fields[i]] = append(res[fields[i]], identifiers[i])
-	}
-	return res
-}
-
-func getReturnStatement() string {
-	return `
-    out = ctx.actions.declare_file(ctx.label.name)
-    ctx.actions.write(out, "Fake executable")
-    return [
-        cc_common.create_cc_toolchain_config_info(
-            ctx = ctx,
-            features = features,
-            action_configs = action_configs,
-            artifact_name_patterns = artifact_name_patterns,
-            cxx_builtin_include_directories = cxx_builtin_include_directories,
-            toolchain_identifier = toolchain_identifier,
-            host_system_name = host_system_name,
-            target_system_name = target_system_name,
-            target_cpu = target_cpu,
-            target_libc = target_libc,
-            compiler = compiler,
-            abi_version = abi_version,
-            abi_libc_version = abi_libc_version,
-            tool_paths = tool_paths,
-            make_variables = make_variables,
-            builtin_sysroot = builtin_sysroot,
-            cc_target_os = cc_target_os
-        ),
-        DefaultInfo(
-            executable = out,
-        ),
-    ]
-`
-}
-
-// Transform writes a cc_toolchain_config rule functionally equivalent to the
-// CROSSTOOL file.
-func Transform(crosstool *crosstoolpb.CrosstoolRelease) (string, error) {
-	var b bytes.Buffer
-
-	cToolchainIdentifiers := toolchainToCToolchainIdentifier(crosstool)
-
-	toolchainToFeatures, featureNameToFeature, err := getFeatures(crosstool)
-	if err != nil {
-		return "", err
-	}
-
-	toolchainToActions, actionNameToAction, err := getActions(crosstool)
-	if err != nil {
-		return "", err
-	}
-
-	header := getCcToolchainConfigHeader()
-	if _, err := b.WriteString(header); err != nil {
-		return "", err
-	}
-
-	loadActionsStmt := getLoadActionsStmt()
-	if _, err := b.WriteString(loadActionsStmt); err != nil {
-		return "", err
-	}
-
-	implHeader := getImplHeader()
-	if _, err := b.WriteString(implHeader); err != nil {
-		return "", err
-	}
-
-	stringFields := []string{
-		"toolchain_identifier",
-		"host_system_name",
-		"target_system_name",
-		"target_cpu",
-		"target_libc",
-		"compiler",
-		"abi_version",
-		"abi_libc_version",
-		"cc_target_os",
-		"builtin_sysroot",
-	}
-
-	for _, stringField := range stringFields {
-		stmt := getStringStatement(crosstool, cToolchainIdentifiers, stringField, 1)
-		if _, err := b.WriteString(stmt); err != nil {
-			return "", err
-		}
-	}
-
-	listsOfActions := []string{
-		"all_compile_actions",
-		"all_cpp_compile_actions",
-		"preprocessor_compile_actions",
-		"codegen_compile_actions",
-		"all_link_actions",
-	}
-
-	for _, listOfActions := range listsOfActions {
-		actions := getListOfActions(listOfActions, 1)
-		if _, err := b.WriteString(actions); err != nil {
-			return "", err
-		}
-	}
-
-	actionConfigDeclaration := getActionConfigsDeclaration(
-		crosstool, cToolchainIdentifiers, actionNameToAction, 1)
-	if _, err := b.WriteString(actionConfigDeclaration); err != nil {
-		return "", err
-	}
-
-	actionConfigStatement := getActionConfigsStmt(
-		cToolchainIdentifiers, toolchainToActions, 1)
-	if _, err := b.WriteString(actionConfigStatement); err != nil {
-		return "", err
-	}
-
-	featureDeclaration := getFeaturesDeclaration(
-		crosstool, cToolchainIdentifiers, featureNameToFeature, 1)
-	if _, err := b.WriteString(featureDeclaration); err != nil {
-		return "", err
-	}
-
-	featuresStatement := getFeaturesStmt(
-		cToolchainIdentifiers, toolchainToFeatures, 1)
-	if _, err := b.WriteString(featuresStatement); err != nil {
-		return "", err
-	}
-
-	includeDirectories := getStringArr(
-		crosstool, cToolchainIdentifiers, "cxx_builtin_include_directories", 1)
-	if _, err := b.WriteString(includeDirectories); err != nil {
-		return "", err
-	}
-
-	artifactNamePatterns := getArtifactNamePatterns(
-		crosstool, cToolchainIdentifiers, 1)
-	if _, err := b.WriteString(artifactNamePatterns); err != nil {
-		return "", err
-	}
-
-	makeVariables := getMakeVariables(crosstool, cToolchainIdentifiers, 1)
-	if _, err := b.WriteString(makeVariables); err != nil {
-		return "", err
-	}
-
-	toolPaths := getToolPaths(crosstool, cToolchainIdentifiers, 1)
-	if _, err := b.WriteString(toolPaths); err != nil {
-		return "", err
-	}
-
-	if _, err := b.WriteString(getReturnStatement()); err != nil {
-		return "", err
-	}
-
-	rule := getRule(cToolchainIdentifiers, getCompilers(crosstool))
-	if _, err := b.WriteString(rule); err != nil {
-		return "", err
-	}
-
-	return b.String(), nil
-}
diff --git a/tools/migration/crosstool_to_starlark_lib_test.go b/tools/migration/crosstool_to_starlark_lib_test.go
deleted file mode 100644
index 63d9736..0000000
--- a/tools/migration/crosstool_to_starlark_lib_test.go
+++ /dev/null
@@ -1,1756 +0,0 @@
-package crosstooltostarlarklib
-
-import (
-	"fmt"
-	"strings"
-	"testing"
-
-	"log"
-	crosstoolpb "third_party/com/github/bazelbuild/bazel/src/main/protobuf/crosstool_config_go_proto"
-	"github.com/golang/protobuf/proto"
-)
-
-func makeCToolchainString(lines []string) string {
-	return fmt.Sprintf(`toolchain {
-  %s
-}`, strings.Join(lines, "\n  "))
-}
-
-func makeCrosstool(CToolchains []string) *crosstoolpb.CrosstoolRelease {
-	crosstool := &crosstoolpb.CrosstoolRelease{}
-	requiredFields := []string{
-		"major_version: '0'",
-		"minor_version: '0'",
-		"default_target_cpu: 'cpu'",
-	}
-	CToolchains = append(CToolchains, requiredFields...)
-	if err := proto.UnmarshalText(strings.Join(CToolchains, "\n"), crosstool); err != nil {
-		log.Fatalf("Failed to parse CROSSTOOL:", err)
-	}
-	return crosstool
-}
-
-func getSimpleCToolchain(id string) string {
-	lines := []string{
-		"toolchain_identifier: 'id-" + id + "'",
-		"host_system_name: 'host-" + id + "'",
-		"target_system_name: 'target-" + id + "'",
-		"target_cpu: 'cpu-" + id + "'",
-		"compiler: 'compiler-" + id + "'",
-		"target_libc: 'libc-" + id + "'",
-		"abi_version: 'version-" + id + "'",
-		"abi_libc_version: 'libc_version-" + id + "'",
-	}
-	return makeCToolchainString(lines)
-}
-
-func getCToolchain(id, cpu, compiler string, extraLines []string) string {
-	lines := []string{
-		"toolchain_identifier: '" + id + "'",
-		"host_system_name: 'host'",
-		"target_system_name: 'target'",
-		"target_cpu: '" + cpu + "'",
-		"compiler: '" + compiler + "'",
-		"target_libc: 'libc'",
-		"abi_version: 'version'",
-		"abi_libc_version: 'libc_version'",
-	}
-	lines = append(lines, extraLines...)
-	return makeCToolchainString(lines)
-}
-
-func TestStringFieldsConditionStatement(t *testing.T) {
-	toolchain1 := getSimpleCToolchain("1")
-	toolchain2 := getSimpleCToolchain("2")
-	toolchains := []string{toolchain1, toolchain2}
-	crosstool := makeCrosstool(toolchains)
-
-	testCases := []struct {
-		field        string
-		expectedText string
-	}{
-		{field: "toolchain_identifier",
-			expectedText: `
-    if (ctx.attr.cpu == "cpu-1"):
-        toolchain_identifier = "id-1"
-    elif (ctx.attr.cpu == "cpu-2"):
-        toolchain_identifier = "id-2"
-    else:
-        fail("Unreachable")`},
-		{field: "host_system_name",
-			expectedText: `
-    if (ctx.attr.cpu == "cpu-1"):
-        host_system_name = "host-1"
-    elif (ctx.attr.cpu == "cpu-2"):
-        host_system_name = "host-2"
-    else:
-        fail("Unreachable")`},
-		{field: "target_system_name",
-			expectedText: `
-    if (ctx.attr.cpu == "cpu-1"):
-        target_system_name = "target-1"
-    elif (ctx.attr.cpu == "cpu-2"):
-        target_system_name = "target-2"
-    else:
-        fail("Unreachable")`},
-		{field: "target_cpu",
-			expectedText: `
-    if (ctx.attr.cpu == "cpu-1"):
-        target_cpu = "cpu-1"
-    elif (ctx.attr.cpu == "cpu-2"):
-        target_cpu = "cpu-2"
-    else:
-        fail("Unreachable")`},
-		{field: "target_libc",
-			expectedText: `
-    if (ctx.attr.cpu == "cpu-1"):
-        target_libc = "libc-1"
-    elif (ctx.attr.cpu == "cpu-2"):
-        target_libc = "libc-2"
-    else:
-        fail("Unreachable")`},
-		{field: "compiler",
-			expectedText: `
-    if (ctx.attr.cpu == "cpu-1"):
-        compiler = "compiler-1"
-    elif (ctx.attr.cpu == "cpu-2"):
-        compiler = "compiler-2"
-    else:
-        fail("Unreachable")`},
-		{field: "abi_version",
-			expectedText: `
-    if (ctx.attr.cpu == "cpu-1"):
-        abi_version = "version-1"
-    elif (ctx.attr.cpu == "cpu-2"):
-        abi_version = "version-2"
-    else:
-        fail("Unreachable")`},
-		{field: "abi_libc_version",
-			expectedText: `
-    if (ctx.attr.cpu == "cpu-1"):
-        abi_libc_version = "libc_version-1"
-    elif (ctx.attr.cpu == "cpu-2"):
-        abi_libc_version = "libc_version-2"
-    else:
-        fail("Unreachable")`}}
-
-	got, err := Transform(crosstool)
-	if err != nil {
-		t.Fatalf("CROSSTOOL conversion failed: %v", err)
-	}
-
-	failed := false
-	for _, tc := range testCases {
-		if !strings.Contains(got, tc.expectedText) {
-			t.Errorf("Failed to correctly convert '%s' field, expected to contain:\n%v\n",
-				tc.field, tc.expectedText)
-			failed = true
-		}
-	}
-	if failed {
-		t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
-			strings.Join(toolchains, "\n"), got)
-	}
-}
-
-func TestConditionsSameCpu(t *testing.T) {
-	toolchainAA := getCToolchain("1", "cpuA", "compilerA", []string{})
-	toolchainAB := getCToolchain("2", "cpuA", "compilerB", []string{})
-	toolchains := []string{toolchainAA, toolchainAB}
-	crosstool := makeCrosstool(toolchains)
-
-	testCases := []struct {
-		field        string
-		expectedText string
-	}{
-		{field: "toolchain_identifier",
-			expectedText: `
-    if (ctx.attr.cpu == "cpuA" and ctx.attr.compiler == "compilerA"):
-        toolchain_identifier = "1"
-    elif (ctx.attr.cpu == "cpuA" and ctx.attr.compiler == "compilerB"):
-        toolchain_identifier = "2"
-    else:
-        fail("Unreachable")`},
-		{field: "host_system_name",
-			expectedText: `
-    host_system_name = "host"`},
-		{field: "target_system_name",
-			expectedText: `
-    target_system_name = "target"`},
-		{field: "target_cpu",
-			expectedText: `
-    target_cpu = "cpuA"`},
-		{field: "target_libc",
-			expectedText: `
-    target_libc = "libc"`},
-		{field: "compiler",
-			expectedText: `
-    if (ctx.attr.cpu == "cpuA" and ctx.attr.compiler == "compilerA"):
-        compiler = "compilerA"
-    elif (ctx.attr.cpu == "cpuA" and ctx.attr.compiler == "compilerB"):
-        compiler = "compilerB"
-    else:
-        fail("Unreachable")`},
-		{field: "abi_version",
-			expectedText: `
-    abi_version = "version"`},
-		{field: "abi_libc_version",
-			expectedText: `
-    abi_libc_version = "libc_version"`}}
-
-	got, err := Transform(crosstool)
-	if err != nil {
-		t.Fatalf("CROSSTOOL conversion failed: %v", err)
-	}
-
-	failed := false
-	for _, tc := range testCases {
-		if !strings.Contains(got, tc.expectedText) {
-			t.Errorf("Failed to correctly convert '%s' field, expected to contain:\n%v\n",
-				tc.field, tc.expectedText)
-			failed = true
-		}
-	}
-	if failed {
-		t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
-			strings.Join(toolchains, "\n"), got)
-	}
-}
-
-func TestConditionsSameCompiler(t *testing.T) {
-	toolchainAA := getCToolchain("1", "cpuA", "compilerA", []string{})
-	toolchainBA := getCToolchain("2", "cpuB", "compilerA", []string{})
-	toolchains := []string{toolchainAA, toolchainBA}
-	crosstool := makeCrosstool(toolchains)
-
-	testCases := []struct {
-		field        string
-		expectedText string
-	}{
-		{field: "toolchain_identifier",
-			expectedText: `
-    if (ctx.attr.cpu == "cpuA"):
-        toolchain_identifier = "1"
-    elif (ctx.attr.cpu == "cpuB"):
-        toolchain_identifier = "2"
-    else:
-        fail("Unreachable")`},
-		{field: "target_cpu",
-			expectedText: `
-    if (ctx.attr.cpu == "cpuA"):
-        target_cpu = "cpuA"
-    elif (ctx.attr.cpu == "cpuB"):
-        target_cpu = "cpuB"
-    else:
-        fail("Unreachable")`},
-		{field: "compiler",
-			expectedText: `
-    compiler = "compilerA"`}}
-
-	got, err := Transform(crosstool)
-	if err != nil {
-		t.Fatalf("CROSSTOOL conversion failed: %v", err)
-	}
-
-	failed := false
-	for _, tc := range testCases {
-		if !strings.Contains(got, tc.expectedText) {
-			t.Errorf("Failed to correctly convert '%s' field, expected to contain:\n%v\n",
-				tc.field, tc.expectedText)
-			failed = true
-		}
-	}
-	if failed {
-		t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
-			strings.Join(toolchains, "\n"), got)
-	}
-}
-
-func TestNonMandatoryStrings(t *testing.T) {
-	toolchainAA := getCToolchain("1", "cpuA", "compilerA", []string{"cc_target_os: 'osA'"})
-	toolchainBB := getCToolchain("2", "cpuB", "compilerB", []string{})
-	toolchains := []string{toolchainAA, toolchainBB}
-	crosstool := makeCrosstool(toolchains)
-
-	testCases := []struct {
-		field        string
-		expectedText string
-	}{
-		{field: "cc_target_os",
-			expectedText: `
-    if (ctx.attr.cpu == "cpuB"):
-        cc_target_os = None
-    elif (ctx.attr.cpu == "cpuA"):
-        cc_target_os = "osA"
-    else:
-        fail("Unreachable")`},
-		{field: "builtin_sysroot",
-			expectedText: `
-    builtin_sysroot = None`}}
-
-	got, err := Transform(crosstool)
-	if err != nil {
-		t.Fatalf("CROSSTOOL conversion failed: %v", err)
-	}
-
-	failed := false
-	for _, tc := range testCases {
-		if !strings.Contains(got, tc.expectedText) {
-			t.Errorf("Failed to correctly convert '%s' field, expected to contain:\n%v\n",
-				tc.field, tc.expectedText)
-			failed = true
-		}
-	}
-	if failed {
-		t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
-			strings.Join(toolchains, "\n"), got)
-	}
-}
-
-func TestBuiltinIncludeDirectories(t *testing.T) {
-	toolchainAA := getCToolchain("1", "cpuA", "compilerA", []string{})
-	toolchainBA := getCToolchain("2", "cpuB", "compilerA", []string{})
-	toolchainCA := getCToolchain("3", "cpuC", "compilerA",
-		[]string{"cxx_builtin_include_directory: 'dirC'"})
-	toolchainCB := getCToolchain("4", "cpuC", "compilerB",
-		[]string{"cxx_builtin_include_directory: 'dirC'",
-			"cxx_builtin_include_directory: 'dirB'"})
-	toolchainDA := getCToolchain("5", "cpuD", "compilerA",
-		[]string{"cxx_builtin_include_directory: 'dirC'"})
-
-	toolchainsEmpty := []string{toolchainAA, toolchainBA}
-
-	toolchainsOneNonempty := []string{toolchainAA, toolchainBA, toolchainCA}
-
-	toolchainsSameNonempty := []string{toolchainCA, toolchainDA}
-
-	allToolchains := []string{toolchainAA, toolchainBA, toolchainCA, toolchainCB, toolchainDA}
-
-	testCases := []struct {
-		field        string
-		toolchains   []string
-		expectedText string
-	}{
-		{field: "cxx_builtin_include_directories",
-			toolchains: toolchainsEmpty,
-			expectedText: `
-    cxx_builtin_include_directories = []`},
-		{field: "cxx_builtin_include_directories",
-			toolchains: toolchainsOneNonempty,
-			expectedText: `
-    if (ctx.attr.cpu == "cpuA"
-        or ctx.attr.cpu == "cpuB"):
-        cxx_builtin_include_directories = []
-    elif (ctx.attr.cpu == "cpuC"):
-        cxx_builtin_include_directories = ["dirC"]
-    else:
-        fail("Unreachable")`},
-		{field: "cxx_builtin_include_directories",
-			toolchains: toolchainsSameNonempty,
-			expectedText: `
-    cxx_builtin_include_directories = ["dirC"]`},
-		{field: "cxx_builtin_include_directories",
-			toolchains: allToolchains,
-			expectedText: `
-    if (ctx.attr.cpu == "cpuA"
-        or ctx.attr.cpu == "cpuB"):
-        cxx_builtin_include_directories = []
-    elif (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerA"
-        or ctx.attr.cpu == "cpuD"):
-        cxx_builtin_include_directories = ["dirC"]
-    elif (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerB"):
-        cxx_builtin_include_directories = ["dirC", "dirB"]`}}
-
-	for _, tc := range testCases {
-		crosstool := makeCrosstool(tc.toolchains)
-		got, err := Transform(crosstool)
-		if err != nil {
-			t.Fatalf("CROSSTOOL conversion failed: %v", err)
-		}
-		if !strings.Contains(got, tc.expectedText) {
-			t.Errorf("Failed to correctly convert '%s' field, expected to contain:\n%v\n",
-				tc.field, tc.expectedText)
-			t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
-				strings.Join(tc.toolchains, "\n"), got)
-		}
-	}
-}
-
-func TestMakeVariables(t *testing.T) {
-	toolchainEmpty1 := getCToolchain("1", "cpuA", "compilerA", []string{})
-	toolchainEmpty2 := getCToolchain("2", "cpuB", "compilerA", []string{})
-	toolchainA1 := getCToolchain("3", "cpuC", "compilerA",
-		[]string{"make_variable {name: 'A', value: 'a/b/c'}"})
-	toolchainA2 := getCToolchain("4", "cpuC", "compilerB",
-		[]string{"make_variable {name: 'A', value: 'a/b/c'}"})
-	toolchainAB := getCToolchain("5", "cpuC", "compilerC",
-		[]string{"make_variable {name: 'A', value: 'a/b/c'}",
-			"make_variable {name: 'B', value: 'a/b/c'}"})
-	toolchainBA := getCToolchain("6", "cpuD", "compilerA",
-		[]string{"make_variable {name: 'B', value: 'a/b/c'}",
-			"make_variable {name: 'A', value: 'a b c'}"})
-
-	toolchainsEmpty := []string{toolchainEmpty1, toolchainEmpty2}
-
-	toolchainsOneNonempty := []string{toolchainEmpty1, toolchainA1}
-
-	toolchainsSameNonempty := []string{toolchainA1, toolchainA2}
-
-	toolchainsDifferentOrder := []string{toolchainAB, toolchainBA}
-
-	allToolchains := []string{
-		toolchainEmpty1,
-		toolchainEmpty2,
-		toolchainA1,
-		toolchainA2,
-		toolchainAB,
-		toolchainBA,
-	}
-
-	testCases := []struct {
-		field        string
-		toolchains   []string
-		expectedText string
-	}{
-		{field: "make_variables",
-			toolchains: toolchainsEmpty,
-			expectedText: `
-    make_variables = []`},
-		{field: "make_variables",
-			toolchains: toolchainsOneNonempty,
-			expectedText: `
-    if (ctx.attr.cpu == "cpuA"):
-        make_variables = []
-    elif (ctx.attr.cpu == "cpuC"):
-        make_variables = [make_variable(name = "A", value = "a/b/c")]
-    else:
-        fail("Unreachable")`},
-		{field: "make_variables",
-			toolchains: toolchainsSameNonempty,
-			expectedText: `
-    make_variables = [make_variable(name = "A", value = "a/b/c")]`},
-		{field: "make_variables",
-			toolchains: toolchainsDifferentOrder,
-			expectedText: `
-    if (ctx.attr.cpu == "cpuC"):
-        make_variables = [
-            make_variable(name = "A", value = "a/b/c"),
-            make_variable(name = "B", value = "a/b/c"),
-        ]
-    elif (ctx.attr.cpu == "cpuD"):
-        make_variables = [
-            make_variable(name = "B", value = "a/b/c"),
-            make_variable(name = "A", value = "a b c"),
-        ]
-    else:
-        fail("Unreachable")`},
-		{field: "make_variables",
-			toolchains: allToolchains,
-			expectedText: `
-    if (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerC"):
-        make_variables = [
-            make_variable(name = "A", value = "a/b/c"),
-            make_variable(name = "B", value = "a/b/c"),
-        ]
-    elif (ctx.attr.cpu == "cpuD"):
-        make_variables = [
-            make_variable(name = "B", value = "a/b/c"),
-            make_variable(name = "A", value = "a b c"),
-        ]
-    elif (ctx.attr.cpu == "cpuA"
-        or ctx.attr.cpu == "cpuB"):
-        make_variables = []
-    elif (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerA"
-        or ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerB"):
-        make_variables = [make_variable(name = "A", value = "a/b/c")]
-    else:
-        fail("Unreachable")`}}
-
-	for _, tc := range testCases {
-		crosstool := makeCrosstool(tc.toolchains)
-		got, err := Transform(crosstool)
-		if err != nil {
-			t.Fatalf("CROSSTOOL conversion failed: %v", err)
-		}
-		if !strings.Contains(got, tc.expectedText) {
-			t.Errorf("Failed to correctly convert '%s' field, expected to contain:\n%v\n",
-				tc.field, tc.expectedText)
-			t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
-				strings.Join(tc.toolchains, "\n"), got)
-		}
-	}
-}
-
-func TestToolPaths(t *testing.T) {
-	toolchainEmpty1 := getCToolchain("1", "cpuA", "compilerA", []string{})
-	toolchainEmpty2 := getCToolchain("2", "cpuB", "compilerA", []string{})
-	toolchainA1 := getCToolchain("3", "cpuC", "compilerA",
-		[]string{"tool_path {name: 'A', path: 'a/b/c'}"})
-	toolchainA2 := getCToolchain("4", "cpuC", "compilerB",
-		[]string{"tool_path {name: 'A', path: 'a/b/c'}"})
-	toolchainAB := getCToolchain("5", "cpuC", "compilerC",
-		[]string{"tool_path {name: 'A', path: 'a/b/c'}",
-			"tool_path {name: 'B', path: 'a/b/c'}"})
-	toolchainBA := getCToolchain("6", "cpuD", "compilerA",
-		[]string{"tool_path {name: 'B', path: 'a/b/c'}",
-			"tool_path {name: 'A', path: 'a/b/c'}"})
-
-	toolchainsEmpty := []string{toolchainEmpty1, toolchainEmpty2}
-
-	toolchainsOneNonempty := []string{toolchainEmpty1, toolchainA1}
-
-	toolchainsSameNonempty := []string{toolchainA1, toolchainA2}
-
-	toolchainsDifferentOrder := []string{toolchainAB, toolchainBA}
-
-	allToolchains := []string{
-		toolchainEmpty1,
-		toolchainEmpty2,
-		toolchainA1,
-		toolchainA2,
-		toolchainAB,
-		toolchainBA,
-	}
-
-	testCases := []struct {
-		field        string
-		toolchains   []string
-		expectedText string
-	}{
-		{field: "tool_paths",
-			toolchains: toolchainsEmpty,
-			expectedText: `
-    tool_paths = []`},
-		{field: "tool_paths",
-			toolchains: toolchainsOneNonempty,
-			expectedText: `
-    if (ctx.attr.cpu == "cpuA"):
-        tool_paths = []
-    elif (ctx.attr.cpu == "cpuC"):
-        tool_paths = [tool_path(name = "A", path = "a/b/c")]
-    else:
-        fail("Unreachable")`},
-		{field: "tool_paths",
-			toolchains: toolchainsSameNonempty,
-			expectedText: `
-    tool_paths = [tool_path(name = "A", path = "a/b/c")]`},
-		{field: "tool_paths",
-			toolchains: toolchainsDifferentOrder,
-			expectedText: `
-    if (ctx.attr.cpu == "cpuC"):
-        tool_paths = [
-            tool_path(name = "A", path = "a/b/c"),
-            tool_path(name = "B", path = "a/b/c"),
-        ]
-    elif (ctx.attr.cpu == "cpuD"):
-        tool_paths = [
-            tool_path(name = "B", path = "a/b/c"),
-            tool_path(name = "A", path = "a/b/c"),
-        ]
-    else:
-        fail("Unreachable")`},
-		{field: "tool_paths",
-			toolchains: allToolchains,
-			expectedText: `
-    if (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerC"):
-        tool_paths = [
-            tool_path(name = "A", path = "a/b/c"),
-            tool_path(name = "B", path = "a/b/c"),
-        ]
-    elif (ctx.attr.cpu == "cpuD"):
-        tool_paths = [
-            tool_path(name = "B", path = "a/b/c"),
-            tool_path(name = "A", path = "a/b/c"),
-        ]
-    elif (ctx.attr.cpu == "cpuA"
-        or ctx.attr.cpu == "cpuB"):
-        tool_paths = []
-    elif (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerA"
-        or ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerB"):
-        tool_paths = [tool_path(name = "A", path = "a/b/c")]
-    else:
-        fail("Unreachable")`}}
-
-	for _, tc := range testCases {
-		crosstool := makeCrosstool(tc.toolchains)
-		got, err := Transform(crosstool)
-		if err != nil {
-			t.Fatalf("CROSSTOOL conversion failed: %v", err)
-		}
-		if !strings.Contains(got, tc.expectedText) {
-			t.Errorf("Failed to correctly convert '%s' field, expected to contain:\n%v\n",
-				tc.field, tc.expectedText)
-			t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
-				strings.Join(tc.toolchains, "\n"), got)
-		}
-	}
-}
-
-func getArtifactNamePattern(lines []string) string {
-	return fmt.Sprintf(`artifact_name_pattern {
-  %s
-}`, strings.Join(lines, "\n  "))
-}
-
-func TestArtifactNamePatterns(t *testing.T) {
-	toolchainEmpty1 := getCToolchain("1", "cpuA", "compilerA", []string{})
-	toolchainEmpty2 := getCToolchain("2", "cpuB", "compilerA", []string{})
-	toolchainA1 := getCToolchain("3", "cpuC", "compilerA",
-		[]string{
-			getArtifactNamePattern([]string{
-				"category_name: 'A'",
-				"prefix: 'p'",
-				"extension: '.exe'"}),
-		},
-	)
-	toolchainA2 := getCToolchain("4", "cpuC", "compilerB",
-		[]string{
-			getArtifactNamePattern([]string{
-				"category_name: 'A'",
-				"prefix: 'p'",
-				"extension: '.exe'"}),
-		},
-	)
-	toolchainAB := getCToolchain("5", "cpuC", "compilerC",
-		[]string{
-			getArtifactNamePattern([]string{
-				"category_name: 'A'",
-				"prefix: 'p'",
-				"extension: '.exe'"}),
-			getArtifactNamePattern([]string{
-				"category_name: 'B'",
-				"prefix: 'p'",
-				"extension: '.exe'"}),
-		},
-	)
-	toolchainBA := getCToolchain("6", "cpuD", "compilerA",
-		[]string{
-			getArtifactNamePattern([]string{
-				"category_name: 'B'",
-				"prefix: 'p'",
-				"extension: '.exe'"}),
-			getArtifactNamePattern([]string{
-				"category_name: 'A'",
-				"prefix: 'p'",
-				"extension: '.exe'"}),
-		},
-	)
-	toolchainsEmpty := []string{toolchainEmpty1, toolchainEmpty2}
-
-	toolchainsOneNonempty := []string{toolchainEmpty1, toolchainA1}
-
-	toolchainsSameNonempty := []string{toolchainA1, toolchainA2}
-
-	toolchainsDifferentOrder := []string{toolchainAB, toolchainBA}
-
-	allToolchains := []string{
-		toolchainEmpty1,
-		toolchainEmpty2,
-		toolchainA1,
-		toolchainA2,
-		toolchainAB,
-		toolchainBA,
-	}
-
-	testCases := []struct {
-		field        string
-		toolchains   []string
-		expectedText string
-	}{
-		{field: "artifact_name_patterns",
-			toolchains: toolchainsEmpty,
-			expectedText: `
-    artifact_name_patterns = []`},
-		{field: "artifact_name_patterns",
-			toolchains: toolchainsOneNonempty,
-			expectedText: `
-    if (ctx.attr.cpu == "cpuC"):
-        artifact_name_patterns = [
-            artifact_name_pattern(
-                category_name = "A",
-                prefix = "p",
-                extension = ".exe",
-            ),
-        ]
-    elif (ctx.attr.cpu == "cpuA"):
-        artifact_name_patterns = []
-    else:
-        fail("Unreachable")`},
-		{field: "artifact_name_patterns",
-			toolchains: toolchainsSameNonempty,
-			expectedText: `
-    artifact_name_patterns = [
-        artifact_name_pattern(
-            category_name = "A",
-            prefix = "p",
-            extension = ".exe",
-        ),
-    ]`},
-		{field: "artifact_name_patterns",
-			toolchains: toolchainsDifferentOrder,
-			expectedText: `
-    if (ctx.attr.cpu == "cpuC"):
-        artifact_name_patterns = [
-            artifact_name_pattern(
-                category_name = "A",
-                prefix = "p",
-                extension = ".exe",
-            ),
-            artifact_name_pattern(
-                category_name = "B",
-                prefix = "p",
-                extension = ".exe",
-            ),
-        ]
-    elif (ctx.attr.cpu == "cpuD"):
-        artifact_name_patterns = [
-            artifact_name_pattern(
-                category_name = "B",
-                prefix = "p",
-                extension = ".exe",
-            ),
-            artifact_name_pattern(
-                category_name = "A",
-                prefix = "p",
-                extension = ".exe",
-            ),
-        ]
-    else:
-        fail("Unreachable")`},
-		{field: "artifact_name_patterns",
-			toolchains: allToolchains,
-			expectedText: `
-    if (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerC"):
-        artifact_name_patterns = [
-            artifact_name_pattern(
-                category_name = "A",
-                prefix = "p",
-                extension = ".exe",
-            ),
-            artifact_name_pattern(
-                category_name = "B",
-                prefix = "p",
-                extension = ".exe",
-            ),
-        ]
-    elif (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerA"
-        or ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerB"):
-        artifact_name_patterns = [
-            artifact_name_pattern(
-                category_name = "A",
-                prefix = "p",
-                extension = ".exe",
-            ),
-        ]
-    elif (ctx.attr.cpu == "cpuD"):
-        artifact_name_patterns = [
-            artifact_name_pattern(
-                category_name = "B",
-                prefix = "p",
-                extension = ".exe",
-            ),
-            artifact_name_pattern(
-                category_name = "A",
-                prefix = "p",
-                extension = ".exe",
-            ),
-        ]
-    elif (ctx.attr.cpu == "cpuA"
-        or ctx.attr.cpu == "cpuB"):
-        artifact_name_patterns = []
-    else:
-        fail("Unreachable")`}}
-
-	for _, tc := range testCases {
-		crosstool := makeCrosstool(tc.toolchains)
-		got, err := Transform(crosstool)
-		if err != nil {
-			t.Fatalf("CROSSTOOL conversion failed: %v", err)
-		}
-		if !strings.Contains(got, tc.expectedText) {
-			t.Errorf("Failed to correctly convert '%s' field, expected to contain:\n%v\n",
-				tc.field, tc.expectedText)
-			t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
-				strings.Join(tc.toolchains, "\n"), got)
-		}
-	}
-}
-
-func getFeature(lines []string) string {
-	return fmt.Sprintf(`feature {
-  %s
-}`, strings.Join(lines, "\n  "))
-}
-
-func TestFeatureListAssignment(t *testing.T) {
-	toolchainEmpty1 := getCToolchain("1", "cpuA", "compilerA", []string{})
-	toolchainEmpty2 := getCToolchain("2", "cpuB", "compilerA", []string{})
-	toolchainA1 := getCToolchain("3", "cpuC", "compilerA",
-		[]string{getFeature([]string{"name: 'A'"})},
-	)
-	toolchainA2 := getCToolchain("4", "cpuC", "compilerB",
-		[]string{getFeature([]string{"name: 'A'"})},
-	)
-	toolchainAB := getCToolchain("5", "cpuC", "compilerC",
-		[]string{
-			getFeature([]string{"name: 'A'"}),
-			getFeature([]string{"name: 'B'"}),
-		},
-	)
-	toolchainBA := getCToolchain("6", "cpuD", "compilerA",
-		[]string{
-			getFeature([]string{"name: 'B'"}),
-			getFeature([]string{"name: 'A'"}),
-		},
-	)
-	toolchainsEmpty := []string{toolchainEmpty1, toolchainEmpty2}
-
-	toolchainsOneNonempty := []string{toolchainEmpty1, toolchainA1}
-
-	toolchainsSameNonempty := []string{toolchainA1, toolchainA2}
-
-	toolchainsDifferentOrder := []string{toolchainAB, toolchainBA}
-
-	allToolchains := []string{
-		toolchainEmpty1,
-		toolchainEmpty2,
-		toolchainA1,
-		toolchainA2,
-		toolchainAB,
-		toolchainBA,
-	}
-
-	testCases := []struct {
-		field        string
-		toolchains   []string
-		expectedText string
-	}{
-		{field: "features",
-			toolchains: toolchainsEmpty,
-			expectedText: `
-    features = []`},
-		{field: "features",
-			toolchains: toolchainsOneNonempty,
-			expectedText: `
-    if (ctx.attr.cpu == "cpuA"):
-        features = []
-    elif (ctx.attr.cpu == "cpuC"):
-        features = [a_feature]
-    else:
-        fail("Unreachable")`},
-		{field: "features",
-			toolchains: toolchainsSameNonempty,
-			expectedText: `
-    features = [a_feature]`},
-		{field: "features",
-			toolchains: toolchainsDifferentOrder,
-			expectedText: `
-    if (ctx.attr.cpu == "cpuC"):
-        features = [a_feature, b_feature]
-    elif (ctx.attr.cpu == "cpuD"):
-        features = [b_feature, a_feature]
-    else:
-        fail("Unreachable")`},
-		{field: "features",
-			toolchains: allToolchains,
-			expectedText: `
-    if (ctx.attr.cpu == "cpuA"
-        or ctx.attr.cpu == "cpuB"):
-        features = []
-    elif (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerA"
-        or ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerB"):
-        features = [a_feature]
-    elif (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerC"):
-        features = [a_feature, b_feature]
-    elif (ctx.attr.cpu == "cpuD"):
-        features = [b_feature, a_feature]
-    else:
-        fail("Unreachable")`}}
-
-	for _, tc := range testCases {
-		crosstool := makeCrosstool(tc.toolchains)
-		got, err := Transform(crosstool)
-		if err != nil {
-			t.Fatalf("CROSSTOOL conversion failed: %v", err)
-		}
-		if !strings.Contains(got, tc.expectedText) {
-			t.Errorf("Failed to correctly convert '%s' field, expected to contain:\n%v\n",
-				tc.field, tc.expectedText)
-			t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
-				strings.Join(tc.toolchains, "\n"), got)
-		}
-	}
-}
-
-func getActionConfig(lines []string) string {
-	return fmt.Sprintf(`action_config {
-  %s
-}`, strings.Join(lines, "\n  "))
-}
-
-func TestActionConfigListAssignment(t *testing.T) {
-	toolchainEmpty1 := getCToolchain("1", "cpuA", "compilerA", []string{})
-	toolchainEmpty2 := getCToolchain("2", "cpuB", "compilerA", []string{})
-	toolchainA1 := getCToolchain("3", "cpuC", "compilerA",
-		[]string{
-			getActionConfig([]string{"action_name: 'A'", "config_name: 'A'"}),
-		},
-	)
-	toolchainA2 := getCToolchain("4", "cpuC", "compilerB",
-		[]string{
-			getActionConfig([]string{"action_name: 'A'", "config_name: 'A'"}),
-		},
-	)
-	toolchainAB := getCToolchain("5", "cpuC", "compilerC",
-		[]string{
-			getActionConfig([]string{"action_name: 'A'", "config_name: 'A'"}),
-			getActionConfig([]string{"action_name: 'B'", "config_name: 'B'"}),
-		},
-	)
-	toolchainBA := getCToolchain("6", "cpuD", "compilerA",
-		[]string{
-			getActionConfig([]string{"action_name: 'B'", "config_name: 'B'"}),
-			getActionConfig([]string{"action_name: 'A'", "config_name: 'A'"}),
-		},
-	)
-	toolchainsEmpty := []string{toolchainEmpty1, toolchainEmpty2}
-
-	toolchainsOneNonempty := []string{toolchainEmpty1, toolchainA1}
-
-	toolchainsSameNonempty := []string{toolchainA1, toolchainA2}
-
-	toolchainsDifferentOrder := []string{toolchainAB, toolchainBA}
-
-	allToolchains := []string{
-		toolchainEmpty1,
-		toolchainEmpty2,
-		toolchainA1,
-		toolchainA2,
-		toolchainAB,
-		toolchainBA,
-	}
-
-	testCases := []struct {
-		field        string
-		toolchains   []string
-		expectedText string
-	}{
-		{field: "action_configs",
-			toolchains: toolchainsEmpty,
-			expectedText: `
-    action_configs = []`},
-		{field: "action_configs",
-			toolchains: toolchainsOneNonempty,
-			expectedText: `
-    if (ctx.attr.cpu == "cpuA"):
-        action_configs = []
-    elif (ctx.attr.cpu == "cpuC"):
-        action_configs = [a_action]
-    else:
-        fail("Unreachable")`},
-		{field: "action_configs",
-			toolchains: toolchainsSameNonempty,
-			expectedText: `
-    action_configs = [a_action]`},
-		{field: "action_configs",
-			toolchains: toolchainsDifferentOrder,
-			expectedText: `
-    if (ctx.attr.cpu == "cpuC"):
-        action_configs = [a_action, b_action]
-    elif (ctx.attr.cpu == "cpuD"):
-        action_configs = [b_action, a_action]
-    else:
-        fail("Unreachable")`},
-		{field: "action_configs",
-			toolchains: allToolchains,
-			expectedText: `
-    if (ctx.attr.cpu == "cpuA"
-        or ctx.attr.cpu == "cpuB"):
-        action_configs = []
-    elif (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerA"
-        or ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerB"):
-        action_configs = [a_action]
-    elif (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerC"):
-        action_configs = [a_action, b_action]
-    elif (ctx.attr.cpu == "cpuD"):
-        action_configs = [b_action, a_action]
-    else:
-        fail("Unreachable")`}}
-
-	for _, tc := range testCases {
-		crosstool := makeCrosstool(tc.toolchains)
-		got, err := Transform(crosstool)
-		if err != nil {
-			t.Fatalf("CROSSTOOL conversion failed: %v", err)
-		}
-		if !strings.Contains(got, tc.expectedText) {
-			t.Errorf("Failed to correctly convert '%s' field, expected to contain:\n%v\n",
-				tc.field, tc.expectedText)
-			t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
-				strings.Join(tc.toolchains, "\n"), got)
-		}
-	}
-}
-
-func TestAllAndNoneAvailableErrorsWhenMoreThanOneElement(t *testing.T) {
-	toolchainFeatureAllAvailable := getCToolchain("1", "cpu", "compiler",
-		[]string{getFeature([]string{
-			"name: 'A'",
-			"flag_set {",
-			"  action: 'A'",
-			"  flag_group {",
-			"    flag: 'f'",
-			"    expand_if_all_available: 'e1'",
-			"    expand_if_all_available: 'e2'",
-			"  }",
-			"}",
-		})},
-	)
-	toolchainFeatureNoneAvailable := getCToolchain("1", "cpu", "compiler",
-		[]string{getFeature([]string{
-			"name: 'A'",
-			"flag_set {",
-			"  action: 'A'",
-			"  flag_group {",
-			"    flag: 'f'",
-			"    expand_if_none_available: 'e1'",
-			"    expand_if_none_available: 'e2'",
-			"  }",
-			"}",
-		})},
-	)
-	toolchainActionConfigAllAvailable := getCToolchain("1", "cpu", "compiler",
-		[]string{getActionConfig([]string{
-			"config_name: 'A'",
-			"action_name: 'A'",
-			"flag_set {",
-			"  action: 'A'",
-			"  flag_group {",
-			"    flag: 'f'",
-			"    expand_if_all_available: 'e1'",
-			"    expand_if_all_available: 'e2'",
-			"  }",
-			"}",
-		})},
-	)
-	toolchainActionConfigNoneAvailable := getCToolchain("1", "cpu", "compiler",
-		[]string{getActionConfig([]string{
-			"config_name: 'A'",
-			"action_name: 'A'",
-			"flag_set {",
-			"  action: 'A'",
-			"  flag_group {",
-			"    flag: 'f'",
-			"    expand_if_none_available: 'e1'",
-			"    expand_if_none_available: 'e2'",
-			"  }",
-			"}",
-		})},
-	)
-
-	testCases := []struct {
-		field        string
-		toolchain    string
-		expectedText string
-	}{
-		{field: "features",
-			toolchain: toolchainFeatureAllAvailable,
-			expectedText: "Error in feature 'A': Flag group must not have more " +
-				"than one 'expand_if_all_available' field"},
-		{field: "features",
-			toolchain: toolchainFeatureNoneAvailable,
-			expectedText: "Error in feature 'A': Flag group must not have more " +
-				"than one 'expand_if_none_available' field"},
-		{field: "action_configs",
-			toolchain: toolchainActionConfigAllAvailable,
-			expectedText: "Error in action_config 'A': Flag group must not have more " +
-				"than one 'expand_if_all_available' field"},
-		{field: "action_configs",
-			toolchain: toolchainActionConfigNoneAvailable,
-			expectedText: "Error in action_config 'A': Flag group must not have more " +
-				"than one 'expand_if_none_available' field"},
-	}
-
-	for _, tc := range testCases {
-		crosstool := makeCrosstool([]string{tc.toolchain})
-		_, err := Transform(crosstool)
-		if err == nil || !strings.Contains(err.Error(), tc.expectedText) {
-			t.Errorf("Expected error: %s, got: %v", tc.expectedText, err)
-		}
-	}
-}
-
-func TestFeaturesAndActionConfigsSetToNoneWhenAllOptionsAreExausted(t *testing.T) {
-	toolchainFeatureAEnabled := getCToolchain("1", "cpuA", "compilerA",
-		[]string{getFeature([]string{"name: 'A'", "enabled: true"})},
-	)
-	toolchainFeatureADisabled := getCToolchain("2", "cpuA", "compilerB",
-		[]string{getFeature([]string{"name: 'A'", "enabled: false"})},
-	)
-
-	toolchainWithoutFeatureA := getCToolchain("3", "cpuA", "compilerC", []string{})
-
-	toolchainActionConfigAEnabled := getCToolchain("4", "cpuA", "compilerD",
-		[]string{getActionConfig([]string{
-			"config_name: 'A'",
-			"action_name: 'A'",
-			"enabled: true",
-		})})
-
-	toolchainActionConfigADisabled := getCToolchain("5", "cpuA", "compilerE",
-		[]string{getActionConfig([]string{
-			"config_name: 'A'",
-			"action_name: 'A'",
-		})})
-
-	toolchainWithoutActionConfigA := getCToolchain("6", "cpuA", "compilerF", []string{})
-
-	testCases := []struct {
-		field        string
-		toolchains   []string
-		expectedText string
-	}{
-		{field: "features",
-			toolchains: []string{
-				toolchainFeatureAEnabled, toolchainFeatureADisabled, toolchainWithoutFeatureA},
-			expectedText: `
-    if (ctx.attr.cpu == "cpuA" and ctx.attr.compiler == "compilerB"):
-        a_feature = feature(name = "A")
-    elif (ctx.attr.cpu == "cpuA" and ctx.attr.compiler == "compilerA"):
-        a_feature = feature(name = "A", enabled = True)
-    else:
-        a_feature = None
-`},
-		{field: "action_config",
-			toolchains: []string{
-				toolchainActionConfigAEnabled, toolchainActionConfigADisabled, toolchainWithoutActionConfigA},
-			expectedText: `
-    if (ctx.attr.cpu == "cpuA" and ctx.attr.compiler == "compilerE"):
-        a_action = action_config(action_name = "A")
-    elif (ctx.attr.cpu == "cpuA" and ctx.attr.compiler == "compilerD"):
-        a_action = action_config(action_name = "A", enabled = True)
-    else:
-        a_action = None
-`},
-	}
-
-	for _, tc := range testCases {
-		crosstool := makeCrosstool(tc.toolchains)
-		got, err := Transform(crosstool)
-		if err != nil {
-			t.Fatalf("CROSSTOOL conversion failed: %v", err)
-		}
-		if !strings.Contains(got, tc.expectedText) {
-			t.Errorf("Failed to correctly convert '%s' field, expected to contain:\n%v\n",
-				tc.field, tc.expectedText)
-			t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
-				strings.Join(tc.toolchains, "\n"), got)
-		}
-	}
-}
-
-func TestActionConfigDeclaration(t *testing.T) {
-	toolchainEmpty1 := getCToolchain("1", "cpuA", "compilerA", []string{})
-	toolchainEmpty2 := getCToolchain("2", "cpuB", "compilerA", []string{})
-
-	toolchainNameNotInDict := getCToolchain("3", "cpBC", "compilerB",
-		[]string{
-			getActionConfig([]string{"action_name: 'A-B.C'", "config_name: 'A-B.C'"}),
-		},
-	)
-	toolchainNameInDictA := getCToolchain("4", "cpuC", "compilerA",
-		[]string{
-			getActionConfig([]string{"action_name: 'c++-compile'", "config_name: 'c++-compile'"}),
-		},
-	)
-	toolchainNameInDictB := getCToolchain("5", "cpuC", "compilerB",
-		[]string{
-			getActionConfig([]string{
-				"action_name: 'c++-compile'",
-				"config_name: 'c++-compile'",
-				"tool {",
-				"  tool_path: '/a/b/c'",
-				"}",
-			}),
-		},
-	)
-	toolchainComplexActionConfig := getCToolchain("6", "cpuC", "compilerC",
-		[]string{
-			getActionConfig([]string{
-				"action_name: 'action-complex'",
-				"config_name: 'action-complex'",
-				"enabled: true",
-				"tool {",
-				"  tool_path: '/a/b/c'",
-				"  with_feature {",
-				"    feature: 'a'",
-				"    feature: 'b'",
-				"    not_feature: 'c'",
-				"    not_feature: 'd'",
-				"  }",
-				"  with_feature{",
-				"    feature: 'e'",
-				"  }",
-				"  execution_requirement: 'a'",
-				"}",
-				"tool {",
-				"  tool_path: ''",
-				"}",
-				"flag_set {",
-				"  flag_group {",
-				"    flag: 'a'",
-				"    flag: '%b'",
-				"    iterate_over: 'c'",
-				"    expand_if_all_available: 'd'",
-				"    expand_if_none_available: 'e'",
-				"    expand_if_true: 'f'",
-				"    expand_if_false: 'g'",
-				"    expand_if_equal {",
-				"      variable: 'var'",
-				"      value: 'val'",
-				"    }",
-				"  }",
-				"  flag_group {",
-				"    flag_group {",
-				"      flag: 'a'",
-				"    }",
-				"  }",
-				"}",
-				"flag_set {",
-				"  with_feature {",
-				"    feature: 'a'",
-				"    feature: 'b'",
-				"    not_feature: 'c'",
-				"    not_feature: 'd'",
-				"  }",
-				"}",
-				"env_set {",
-				"  action: 'a'",
-				"  env_entry {",
-				"    key: 'k'",
-				"    value: 'v'",
-				"  }",
-				"  with_feature {",
-				"    feature: 'a'",
-				"  }",
-				"}",
-				"requires {",
-				"  feature: 'a'",
-				"  feature: 'b'",
-				"}",
-				"implies: 'a'",
-				"implies: 'b'",
-			}),
-		},
-	)
-
-	testCases := []struct {
-		toolchains   []string
-		expectedText string
-	}{
-		{
-			toolchains: []string{toolchainEmpty1, toolchainEmpty2},
-			expectedText: `
-    action_configs = []`},
-		{
-			toolchains: []string{toolchainEmpty1, toolchainNameNotInDict},
-			expectedText: `
-    a_b_c_action = action_config(action_name = "A-B.C")`},
-		{
-			toolchains: []string{toolchainNameInDictA, toolchainNameInDictB},
-			expectedText: `
-    if (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerB"):
-        cpp_compile_action = action_config(
-            action_name = ACTION_NAMES.cpp_compile,
-            tools = [tool(path = "/a/b/c")],
-        )
-    elif (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerA"):
-        cpp_compile_action = action_config(action_name = ACTION_NAMES.cpp_compile)`},
-		{
-			toolchains: []string{toolchainComplexActionConfig},
-			expectedText: `
-    action_complex_action = action_config(
-        action_name = "action-complex",
-        enabled = True,
-        flag_sets = [
-            flag_set(
-                flag_groups = [
-                    flag_group(
-                        flags = ["a", "%b"],
-                        iterate_over = "c",
-                        expand_if_available = "d",
-                        expand_if_not_available = "e",
-                        expand_if_true = "f",
-                        expand_if_false = "g",
-                        expand_if_equal = variable_with_value(name = "var", value = "val"),
-                    ),
-                    flag_group(flag_groups = [flag_group(flags = ["a"])]),
-                ],
-            ),
-            flag_set(
-                with_features = [
-                    with_feature_set(
-                        features = ["a", "b"],
-                        not_features = ["c", "d"],
-                    ),
-                ],
-            ),
-        ],
-        implies = ["a", "b"],
-        tools = [
-            tool(
-                path = "/a/b/c",
-                with_features = [
-                    with_feature_set(
-                        features = ["a", "b"],
-                        not_features = ["c", "d"],
-                    ),
-                    with_feature_set(features = ["e"]),
-                ],
-                execution_requirements = ["a"],
-            ),
-            tool(path = "NOT_USED"),
-        ],
-    )`}}
-
-	for _, tc := range testCases {
-		crosstool := makeCrosstool(tc.toolchains)
-		got, err := Transform(crosstool)
-		if err != nil {
-			t.Fatalf("CROSSTOOL conversion failed: %v", err)
-		}
-		if !strings.Contains(got, tc.expectedText) {
-			t.Errorf("Failed to correctly declare an action_config, expected to contain:\n%v\n",
-				tc.expectedText)
-			t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
-				strings.Join(tc.toolchains, "\n"), got)
-		}
-	}
-}
-
-func TestFeatureDeclaration(t *testing.T) {
-	toolchainEmpty1 := getCToolchain("1", "cpuA", "compilerA", []string{})
-	toolchainEmpty2 := getCToolchain("2", "cpuB", "compilerA", []string{})
-
-	toolchainSimpleFeatureA1 := getCToolchain("3", "cpuB", "compilerB",
-		[]string{
-			getFeature([]string{"name: 'Feature-c++.a'", "enabled: true"}),
-		},
-	)
-	toolchainSimpleFeatureA2 := getCToolchain("4", "cpuC", "compilerA",
-		[]string{
-			getFeature([]string{"name: 'Feature-c++.a'"}),
-		},
-	)
-	toolchainComplexFeature := getCToolchain("5", "cpuC", "compilerC",
-		[]string{
-			getFeature([]string{
-				"name: 'complex-feature'",
-				"enabled: true",
-				"flag_set {",
-				"  action: 'c++-compile'",    // in ACTION_NAMES
-				"  action: 'something-else'", // not in ACTION_NAMES
-				"  flag_group {",
-				"    flag: 'a'",
-				"    flag: '%b'",
-				"    iterate_over: 'c'",
-				"    expand_if_all_available: 'd'",
-				"    expand_if_none_available: 'e'",
-				"    expand_if_true: 'f'",
-				"    expand_if_false: 'g'",
-				"    expand_if_equal {",
-				"      variable: 'var'",
-				"      value: 'val'",
-				"    }",
-				"  }",
-				"  flag_group {",
-				"    flag_group {",
-				"      flag: 'a'",
-				"    }",
-				"  }",
-				"}",
-				"flag_set {", // all_compile_actions
-				"  action: 'c-compile'",
-				"  action: 'c++-compile'",
-				"  action: 'linkstamp-compile'",
-				"  action: 'assemble'",
-				"  action: 'preprocess-assemble'",
-				"  action: 'c++-header-parsing'",
-				"  action: 'c++-module-compile'",
-				"  action: 'c++-module-codegen'",
-				"  action: 'clif-match'",
-				"  action: 'lto-backend'",
-				"}",
-				"flag_set {", // all_cpp_compile_actions
-				"  action: 'c++-compile'",
-				"  action: 'linkstamp-compile'",
-				"  action: 'c++-header-parsing'",
-				"  action: 'c++-module-compile'",
-				"  action: 'c++-module-codegen'",
-				"  action: 'clif-match'",
-				"}",
-				"flag_set {", // all_link_actions
-				"  action: 'c++-link-executable'",
-				"  action: 'c++-link-dynamic-library'",
-				"  action: 'c++-link-nodeps-dynamic-library'",
-				"}",
-				"flag_set {", // all_cpp_compile_actions + all_link_actions
-				"  action: 'c++-compile'",
-				"  action: 'linkstamp-compile'",
-				"  action: 'c++-header-parsing'",
-				"  action: 'c++-module-compile'",
-				"  action: 'c++-module-codegen'",
-				"  action: 'clif-match'",
-				"  action: 'c++-link-executable'",
-				"  action: 'c++-link-dynamic-library'",
-				"  action: 'c++-link-nodeps-dynamic-library'",
-				"}",
-				"flag_set {", // all_link_actions + something else
-				"  action: 'c++-link-executable'",
-				"  action: 'c++-link-dynamic-library'",
-				"  action: 'c++-link-nodeps-dynamic-library'",
-				"  action: 'some.unknown-c++.action'",
-				"}",
-				"env_set {",
-				"  action: 'a'",
-				"  env_entry {",
-				"    key: 'k'",
-				"    value: 'v'",
-				"  }",
-				"  with_feature {",
-				"    feature: 'a'",
-				"  }",
-				"}",
-				"env_set {",
-				"  action: 'c-compile'",
-				"}",
-				"env_set {", // all_compile_actions
-				"  action: 'c-compile'",
-				"  action: 'c++-compile'",
-				"  action: 'linkstamp-compile'",
-				"  action: 'assemble'",
-				"  action: 'preprocess-assemble'",
-				"  action: 'c++-header-parsing'",
-				"  action: 'c++-module-compile'",
-				"  action: 'c++-module-codegen'",
-				"  action: 'clif-match'",
-				"  action: 'lto-backend'",
-				"}",
-				"requires {",
-				"  feature: 'a'",
-				"  feature: 'b'",
-				"}",
-				"implies: 'a'",
-				"implies: 'b'",
-				"provides: 'c'",
-				"provides: 'd'",
-			}),
-		},
-	)
-
-	testCases := []struct {
-		toolchains   []string
-		expectedText string
-	}{
-		{
-			toolchains: []string{toolchainEmpty1, toolchainEmpty2},
-			expectedText: `
-    features = []
-`},
-		{
-			toolchains: []string{toolchainEmpty1, toolchainSimpleFeatureA1},
-			expectedText: `
-    feature_cpp_a_feature = feature(name = "Feature-c++.a", enabled = True)`},
-		{
-			toolchains: []string{toolchainSimpleFeatureA1, toolchainSimpleFeatureA2},
-			expectedText: `
-    if (ctx.attr.cpu == "cpuC"):
-        feature_cpp_a_feature = feature(name = "Feature-c++.a")
-    elif (ctx.attr.cpu == "cpuB"):
-        feature_cpp_a_feature = feature(name = "Feature-c++.a", enabled = True)`},
-		{
-			toolchains: []string{toolchainComplexFeature},
-			expectedText: `
-    complex_feature_feature = feature(
-        name = "complex-feature",
-        enabled = True,
-        flag_sets = [
-            flag_set(
-                actions = [ACTION_NAMES.cpp_compile, "something-else"],
-                flag_groups = [
-                    flag_group(
-                        flags = ["a", "%b"],
-                        iterate_over = "c",
-                        expand_if_available = "d",
-                        expand_if_not_available = "e",
-                        expand_if_true = "f",
-                        expand_if_false = "g",
-                        expand_if_equal = variable_with_value(name = "var", value = "val"),
-                    ),
-                    flag_group(flag_groups = [flag_group(flags = ["a"])]),
-                ],
-            ),
-            flag_set(actions = all_compile_actions),
-            flag_set(actions = all_cpp_compile_actions),
-            flag_set(actions = all_link_actions),
-            flag_set(
-                actions = all_cpp_compile_actions +
-                    all_link_actions,
-            ),
-            flag_set(
-                actions = all_link_actions +
-                    ["some.unknown-c++.action"],
-            ),
-        ],
-        env_sets = [
-            env_set(
-                actions = ["a"],
-                env_entries = [env_entry(key = "k", value = "v")],
-                with_features = [with_feature_set(features = ["a"])],
-            ),
-            env_set(actions = [ACTION_NAMES.c_compile]),
-            env_set(actions = all_compile_actions),
-        ],
-        requires = [feature_set(features = ["a", "b"])],
-        implies = ["a", "b"],
-        provides = ["c", "d"],
-    )`}}
-
-	for _, tc := range testCases {
-		crosstool := makeCrosstool(tc.toolchains)
-		got, err := Transform(crosstool)
-		if err != nil {
-			t.Fatalf("CROSSTOOL conversion failed: %v", err)
-		}
-		if !strings.Contains(got, tc.expectedText) {
-			t.Errorf("Failed to correctly declare a feature, expected to contain:\n%v\n",
-				tc.expectedText)
-			t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
-				strings.Join(tc.toolchains, "\n"), got)
-		}
-	}
-}
-
-func TestRule(t *testing.T) {
-	simpleToolchain := getSimpleCToolchain("simple")
-	expected := `load("@rules_cc//cc:cc_toolchain_config_lib.bzl",
-    "action_config",
-    "artifact_name_pattern",
-    "env_entry",
-    "env_set",
-    "feature",
-    "feature_set",
-    "flag_group",
-    "flag_set",
-    "make_variable",
-    "tool",
-    "tool_path",
-    "variable_with_value",
-    "with_feature_set",
-)
-load("@rules_cc//cc:action_names.bzl", "ACTION_NAMES")
-
-def _impl(ctx):
-    toolchain_identifier = "id-simple"
-
-    host_system_name = "host-simple"
-
-    target_system_name = "target-simple"
-
-    target_cpu = "cpu-simple"
-
-    target_libc = "libc-simple"
-
-    compiler = "compiler-simple"
-
-    abi_version = "version-simple"
-
-    abi_libc_version = "libc_version-simple"
-
-    cc_target_os = None
-
-    builtin_sysroot = None
-
-    all_compile_actions = [
-        ACTION_NAMES.c_compile,
-        ACTION_NAMES.cpp_compile,
-        ACTION_NAMES.linkstamp_compile,
-        ACTION_NAMES.assemble,
-        ACTION_NAMES.preprocess_assemble,
-        ACTION_NAMES.cpp_header_parsing,
-        ACTION_NAMES.cpp_module_compile,
-        ACTION_NAMES.cpp_module_codegen,
-        ACTION_NAMES.clif_match,
-        ACTION_NAMES.lto_backend,
-    ]
-
-    all_cpp_compile_actions = [
-        ACTION_NAMES.cpp_compile,
-        ACTION_NAMES.linkstamp_compile,
-        ACTION_NAMES.cpp_header_parsing,
-        ACTION_NAMES.cpp_module_compile,
-        ACTION_NAMES.cpp_module_codegen,
-        ACTION_NAMES.clif_match,
-    ]
-
-    preprocessor_compile_actions = [
-        ACTION_NAMES.c_compile,
-        ACTION_NAMES.cpp_compile,
-        ACTION_NAMES.linkstamp_compile,
-        ACTION_NAMES.preprocess_assemble,
-        ACTION_NAMES.cpp_header_parsing,
-        ACTION_NAMES.cpp_module_compile,
-        ACTION_NAMES.clif_match,
-    ]
-
-    codegen_compile_actions = [
-        ACTION_NAMES.c_compile,
-        ACTION_NAMES.cpp_compile,
-        ACTION_NAMES.linkstamp_compile,
-        ACTION_NAMES.assemble,
-        ACTION_NAMES.preprocess_assemble,
-        ACTION_NAMES.cpp_module_codegen,
-        ACTION_NAMES.lto_backend,
-    ]
-
-    all_link_actions = [
-        ACTION_NAMES.cpp_link_executable,
-        ACTION_NAMES.cpp_link_dynamic_library,
-        ACTION_NAMES.cpp_link_nodeps_dynamic_library,
-    ]
-
-    action_configs = []
-
-    features = []
-
-    cxx_builtin_include_directories = []
-
-    artifact_name_patterns = []
-
-    make_variables = []
-
-    tool_paths = []
-
-
-    out = ctx.actions.declare_file(ctx.label.name)
-    ctx.actions.write(out, "Fake executable")
-    return [
-        cc_common.create_cc_toolchain_config_info(
-            ctx = ctx,
-            features = features,
-            action_configs = action_configs,
-            artifact_name_patterns = artifact_name_patterns,
-            cxx_builtin_include_directories = cxx_builtin_include_directories,
-            toolchain_identifier = toolchain_identifier,
-            host_system_name = host_system_name,
-            target_system_name = target_system_name,
-            target_cpu = target_cpu,
-            target_libc = target_libc,
-            compiler = compiler,
-            abi_version = abi_version,
-            abi_libc_version = abi_libc_version,
-            tool_paths = tool_paths,
-            make_variables = make_variables,
-            builtin_sysroot = builtin_sysroot,
-            cc_target_os = cc_target_os
-        ),
-        DefaultInfo(
-            executable = out,
-        ),
-    ]
-cc_toolchain_config =  rule(
-    implementation = _impl,
-    attrs = {
-        "cpu": attr.string(mandatory=True, values=["cpu-simple"]),
-    },
-    provides = [CcToolchainConfigInfo],
-    executable = True,
-)
-`
-	crosstool := makeCrosstool([]string{simpleToolchain})
-	got, err := Transform(crosstool)
-	if err != nil {
-		t.Fatalf("CROSSTOOL conversion failed: %v", err)
-	}
-	if got != expected {
-		t.Fatalf("Expected:\n%v\nGot:\n%v\nTested CROSSTOOL:\n%v",
-			expected, got, simpleToolchain)
-	}
-}
-
-func TestAllowedCompilerValues(t *testing.T) {
-	toolchainAA := getCToolchain("1", "cpuA", "compilerA", []string{})
-	toolchainBA := getCToolchain("2", "cpuB", "compilerA", []string{})
-	toolchainBB := getCToolchain("3", "cpuB", "compilerB", []string{})
-	toolchainCC := getCToolchain("4", "cpuC", "compilerC", []string{})
-
-	testCases := []struct {
-		toolchains   []string
-		expectedText string
-	}{
-		{
-			toolchains: []string{toolchainAA, toolchainBA},
-			expectedText: `
-cc_toolchain_config =  rule(
-    implementation = _impl,
-    attrs = {
-        "cpu": attr.string(mandatory=True, values=["cpuA", "cpuB"]),
-    },
-    provides = [CcToolchainConfigInfo],
-    executable = True,
-)
-`},
-		{
-			toolchains: []string{toolchainBA, toolchainBB},
-			expectedText: `
-cc_toolchain_config =  rule(
-    implementation = _impl,
-    attrs = {
-        "cpu": attr.string(mandatory=True, values=["cpuB"]),
-        "compiler": attr.string(mandatory=True, values=["compilerA", "compilerB"]),
-    },
-    provides = [CcToolchainConfigInfo],
-    executable = True,
-)
-`},
-		{
-			toolchains: []string{toolchainAA, toolchainBA, toolchainBB},
-			expectedText: `
-cc_toolchain_config =  rule(
-    implementation = _impl,
-    attrs = {
-        "cpu": attr.string(mandatory=True, values=["cpuA", "cpuB"]),
-        "compiler": attr.string(mandatory=True, values=["compilerA", "compilerB"]),
-    },
-    provides = [CcToolchainConfigInfo],
-    executable = True,
-)
-`},
-		{
-			toolchains: []string{toolchainAA, toolchainBA, toolchainBB, toolchainCC},
-			expectedText: `
-cc_toolchain_config =  rule(
-    implementation = _impl,
-    attrs = {
-        "cpu": attr.string(mandatory=True, values=["cpuA", "cpuB", "cpuC"]),
-        "compiler": attr.string(mandatory=True, values=["compilerA", "compilerB", "compilerC"]),
-    },
-    provides = [CcToolchainConfigInfo],
-    executable = True,
-)
-`}}
-
-	for _, tc := range testCases {
-		crosstool := makeCrosstool(tc.toolchains)
-		got, err := Transform(crosstool)
-		if err != nil {
-			t.Fatalf("CROSSTOOL conversion failed: %v", err)
-		}
-		if !strings.Contains(got, tc.expectedText) {
-			t.Errorf("Failed to correctly declare the rule, expected to contain:\n%v\n",
-				tc.expectedText)
-			t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
-				strings.Join(tc.toolchains, "\n"), got)
-		}
-	}
-}
diff --git a/tools/migration/ctoolchain_comparator.py b/tools/migration/ctoolchain_comparator.py
deleted file mode 100644
index 5143e02..0000000
--- a/tools/migration/ctoolchain_comparator.py
+++ /dev/null
@@ -1,127 +0,0 @@
-# Copyright 2018 The Bazel Authors. 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.
-r"""A script that compares 2 CToolchains from proto format.
-
-This script accepts two files in either a CROSSTOOL proto text format or a
-CToolchain proto text format. It then locates the CToolchains with the given
-toolchain_identifier and checks if the resulting CToolchain objects in Java
-are the same.
-
-Example usage:
-
-bazel run \
-@rules_cc//tools/migration:ctoolchain_comparator -- \
---before=/path/to/CROSSTOOL1 \
---after=/path/to/CROSSTOOL2 \
---toolchain_identifier=id
-"""
-
-import os
-from absl import app
-from absl import flags
-from google.protobuf import text_format
-from third_party.com.github.bazelbuild.bazel.src.main.protobuf import crosstool_config_pb2
-from tools.migration.ctoolchain_comparator_lib import compare_ctoolchains
-
-flags.DEFINE_string(
-    "before", None,
-    ("A text proto file containing the relevant CTooclchain before the change, "
-     "either a CROSSTOOL file or a single CToolchain proto text"))
-flags.DEFINE_string(
-    "after", None,
-    ("A text proto file containing the relevant CToolchain after the change, "
-     "either a CROSSTOOL file or a single CToolchain proto text"))
-flags.DEFINE_string("toolchain_identifier", None,
-                    "The identifier of the CToolchain that is being compared.")
-flags.mark_flag_as_required("before")
-flags.mark_flag_as_required("after")
-
-
-def _to_absolute_path(path):
-  path = os.path.expanduser(path)
-  if os.path.isabs(path):
-    return path
-  else:
-    if "BUILD_WORKING_DIRECTORY" in os.environ:
-      return os.path.join(os.environ["BUILD_WORKING_DIRECTORY"], path)
-    else:
-      return path
-
-
-def _find_toolchain(crosstool, toolchain_identifier):
-  for toolchain in crosstool.toolchain:
-    if toolchain.toolchain_identifier == toolchain_identifier:
-      return toolchain
-  return None
-
-
-def _read_crosstool_or_ctoolchain_proto(input_file, toolchain_identifier=None):
-  """Reads a proto file and finds the CToolchain with the given identifier."""
-  with open(input_file, "r") as f:
-    text = f.read()
-  crosstool_release = crosstool_config_pb2.CrosstoolRelease()
-  c_toolchain = crosstool_config_pb2.CToolchain()
-  try:
-    text_format.Merge(text, crosstool_release)
-    if toolchain_identifier is None:
-      print("CROSSTOOL proto needs a 'toolchain_identifier' specified in "
-            "order to be able to select the right toolchain for comparison.")
-      return None
-    toolchain = _find_toolchain(crosstool_release, toolchain_identifier)
-    if toolchain is None:
-      print(("Cannot find a CToolchain with an identifier '%s' in CROSSTOOL "
-             "file") % toolchain_identifier)
-      return None
-    return toolchain
-  except text_format.ParseError as crosstool_error:
-    try:
-      text_format.Merge(text, c_toolchain)
-      if (toolchain_identifier is not None and
-          c_toolchain.toolchain_identifier != toolchain_identifier):
-        print(("Expected CToolchain with identifier '%s', got CToolchain with "
-               "identifier '%s'" % (toolchain_identifier,
-                                    c_toolchain.toolchain_identifier)))
-        return None
-      return c_toolchain
-    except text_format.ParseError as toolchain_error:
-      print(("Error parsing file '%s':" % input_file))  # pylint: disable=superfluous-parens
-      print("Attempt to parse it as a CROSSTOOL proto:")  # pylint: disable=superfluous-parens
-      print(crosstool_error)  # pylint: disable=superfluous-parens
-      print("Attempt to parse it as a CToolchain proto:")  # pylint: disable=superfluous-parens
-      print(toolchain_error)  # pylint: disable=superfluous-parens
-      return None
-
-
-def main(unused_argv):
-
-  before_file = _to_absolute_path(flags.FLAGS.before)
-  after_file = _to_absolute_path(flags.FLAGS.after)
-  toolchain_identifier = flags.FLAGS.toolchain_identifier
-
-  toolchain_before = _read_crosstool_or_ctoolchain_proto(
-      before_file, toolchain_identifier)
-  toolchain_after = _read_crosstool_or_ctoolchain_proto(after_file,
-                                                        toolchain_identifier)
-
-  if not toolchain_before or not toolchain_after:
-    print("There was an error getting the required toolchains.")
-    exit(1)
-
-  found_difference = compare_ctoolchains(toolchain_before, toolchain_after)
-  if found_difference:
-    exit(1)
-
-
-if __name__ == "__main__":
-  app.run(main)
diff --git a/tools/migration/ctoolchain_comparator_lib.py b/tools/migration/ctoolchain_comparator_lib.py
deleted file mode 100644
index eb47305..0000000
--- a/tools/migration/ctoolchain_comparator_lib.py
+++ /dev/null
@@ -1,523 +0,0 @@
-# Copyright 2018 The Bazel Authors. 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.
-"""Module providing compare_ctoolchains function.
-
-compare_ctoolchains takes in two parsed CToolchains and compares them
-"""
-
-
-def _print_difference(field_name, before_value, after_value):
-  if not before_value and after_value:
-    print(("Difference in '%s' field:\nValue before change is not set\n"
-           "Value after change is set to '%s'") % (field_name, after_value))
-  elif before_value and not after_value:
-    print(("Difference in '%s' field:\nValue before change is set to '%s'\n"
-           "Value after change is not set") % (field_name, before_value))
-  else:
-    print(("Difference in '%s' field:\nValue before change:\t'%s'\n"
-           "Value after change:\t'%s'\n") % (field_name, before_value,
-                                             after_value))
-
-
-def _array_to_string(arr, ordered=False):
-  if not arr:
-    return "[]"
-  elif len(arr) == 1:
-    return "[" + list(arr)[0] + "]"
-  if not ordered:
-    return "[\n\t%s\n]" % "\n\t".join(arr)
-  else:
-    return "[\n\t%s\n]" % "\n\t".join(sorted(list(arr)))
-
-
-def _check_with_feature_set_equivalence(before, after):
-  before_set = set()
-  after_set = set()
-  for el in before:
-    before_set.add((str(set(el.feature)), str(set(el.not_feature))))
-  for el in after:
-    after_set.add((str(set(el.feature)), str(set(el.not_feature))))
-  return before_set == after_set
-
-
-def _check_tool_equivalence(before, after):
-  """Compares two "CToolchain.Tool"s."""
-  if before.tool_path == "NOT_USED":
-    before.tool_path = ""
-  if after.tool_path == "NOT_USED":
-    after.tool_path = ""
-  if before.tool_path != after.tool_path:
-    return False
-  if set(before.execution_requirement) != set(after.execution_requirement):
-    return False
-  if not _check_with_feature_set_equivalence(before.with_feature,
-                                             after.with_feature):
-    return False
-  return True
-
-
-def _check_flag_group_equivalence(before, after):
-  """Compares two "CToolchain.FlagGroup"s."""
-  if before.flag != after.flag:
-    return False
-  if before.expand_if_true != after.expand_if_true:
-    return False
-  if before.expand_if_false != after.expand_if_false:
-    return False
-  if set(before.expand_if_all_available) != set(after.expand_if_all_available):
-    return False
-  if set(before.expand_if_none_available) != set(
-      after.expand_if_none_available):
-    return False
-  if before.iterate_over != after.iterate_over:
-    return False
-  if before.expand_if_equal != after.expand_if_equal:
-    return False
-  if len(before.flag_group) != len(after.flag_group):
-    return False
-  for (flag_group_before, flag_group_after) in zip(before.flag_group,
-                                                   after.flag_group):
-    if not _check_flag_group_equivalence(flag_group_before, flag_group_after):
-      return False
-  return True
-
-
-def _check_flag_set_equivalence(before, after, in_action_config=False):
-  """Compares two "CToolchain.FlagSet"s."""
-  # ActionConfigs in proto format do not have a 'FlagSet.action' field set.
-  # Instead, when construction the Java ActionConfig object, we set the
-  # flag_set.action field to the action name. This currently causes the
-  # CcToolchainConfigInfo.proto to generate a CToolchain.ActionConfig that still
-  # has the action name in the FlagSet.action field, therefore we don't compare
-  # the FlagSet.action field when comparing flag_sets that belong to an
-  # ActionConfig.
-  if not in_action_config and set(before.action) != set(after.action):
-    return False
-  if not _check_with_feature_set_equivalence(before.with_feature,
-                                             after.with_feature):
-    return False
-  if len(before.flag_group) != len(after.flag_group):
-    return False
-  for (flag_group_before, flag_group_after) in zip(before.flag_group,
-                                                   after.flag_group):
-    if not _check_flag_group_equivalence(flag_group_before, flag_group_after):
-      return False
-  return True
-
-
-def _check_action_config_equivalence(before, after):
-  """Compares two "CToolchain.ActionConfig"s."""
-  if before.config_name != after.config_name:
-    return False
-  if before.action_name != after.action_name:
-    return False
-  if before.enabled != after.enabled:
-    return False
-  if len(before.tool) != len(after.tool):
-    return False
-  for (tool_before, tool_after) in zip(before.tool, after.tool):
-    if not _check_tool_equivalence(tool_before, tool_after):
-      return False
-  if before.implies != after.implies:
-    return False
-  if len(before.flag_set) != len(after.flag_set):
-    return False
-  for (flag_set_before, flag_set_after) in zip(before.flag_set, after.flag_set):
-    if not _check_flag_set_equivalence(flag_set_before, flag_set_after, True):
-      return False
-  return True
-
-
-def _check_env_set_equivalence(before, after):
-  """Compares two "CToolchain.EnvSet"s."""
-  if set(before.action) != set(after.action):
-    return False
-  if not _check_with_feature_set_equivalence(before.with_feature,
-                                             after.with_feature):
-    return False
-  if before.env_entry != after.env_entry:
-    return False
-  return True
-
-
-def _check_feature_equivalence(before, after):
-  """Compares two "CToolchain.Feature"s."""
-  if before.name != after.name:
-    return False
-  if before.enabled != after.enabled:
-    return False
-  if len(before.flag_set) != len(after.flag_set):
-    return False
-  for (flag_set_before, flag_set_after) in zip(before.flag_set, after.flag_set):
-    if not _check_flag_set_equivalence(flag_set_before, flag_set_after):
-      return False
-  if len(before.env_set) != len(after.env_set):
-    return False
-  for (env_set_before, env_set_after) in zip(before.env_set, after.env_set):
-    if not _check_env_set_equivalence(env_set_before, env_set_after):
-      return False
-  if len(before.requires) != len(after.requires):
-    return False
-  for (requires_before, requires_after) in zip(before.requires, after.requires):
-    if set(requires_before.feature) != set(requires_after.feature):
-      return False
-  if before.implies != after.implies:
-    return False
-  if before.provides != after.provides:
-    return False
-  return True
-
-
-def _compare_features(features_before, features_after):
-  """Compares two "CToolchain.FlagFeature" lists."""
-  feature_name_to_feature_before = {}
-  feature_name_to_feature_after = {}
-  for feature in features_before:
-    feature_name_to_feature_before[feature.name] = feature
-  for feature in features_after:
-    feature_name_to_feature_after[feature.name] = feature
-
-  feature_names_before = set(feature_name_to_feature_before.keys())
-  feature_names_after = set(feature_name_to_feature_after.keys())
-
-  before_after_diff = feature_names_before - feature_names_after
-  after_before_diff = feature_names_after - feature_names_before
-
-  diff_string = "Difference in 'feature' field:"
-  found_difference = False
-  if before_after_diff:
-    if not found_difference:
-      print(diff_string)  # pylint: disable=superfluous-parens
-      found_difference = True
-    print(("* List before change contains entries for the following features "
-           "that the list after the change doesn't:\n%s") % _array_to_string(
-               before_after_diff, ordered=True))
-  if after_before_diff:
-    if not found_difference:
-      print(diff_string)  # pylint: disable=superfluous-parens
-      found_difference = True
-    print(("* List after change contains entries for the following features "
-           "that the list before the change doesn't:\n%s") % _array_to_string(
-               after_before_diff, ordered=True))
-
-  names_before = [feature.name for feature in features_before]
-  names_after = [feature.name for feature in features_after]
-  if names_before != names_after:
-    if not found_difference:
-      print(diff_string)  # pylint: disable=superfluous-parens
-      found_difference = True
-    print(("Features not in right order:\n"
-           "* List of features before change:\t%s"
-           "* List of features before change:\t%s") %
-          (_array_to_string(names_before), _array_to_string(names_after)))
-  for name in feature_name_to_feature_before:
-    feature_before = feature_name_to_feature_before[name]
-    feature_after = feature_name_to_feature_after.get(name, None)
-    if feature_after and not _check_feature_equivalence(feature_before,
-                                                        feature_after):
-      if not found_difference:
-        print(diff_string)  # pylint: disable=superfluous-parens
-        found_difference = True
-      print(("* Feature '%s' differs before and after the change:\n"
-             "Value before change:\n%s\n"
-             "Value after change:\n%s") % (name, str(feature_before),
-                                           str(feature_after)))
-  if found_difference:
-    print("")  # pylint: disable=superfluous-parens
-  return found_difference
-
-
-def _compare_action_configs(action_configs_before, action_configs_after):
-  """Compares two "CToolchain.ActionConfig" lists."""
-  action_name_to_action_before = {}
-  action_name_to_action_after = {}
-  for action_config in action_configs_before:
-    action_name_to_action_before[action_config.config_name] = action_config
-  for action_config in action_configs_after:
-    action_name_to_action_after[action_config.config_name] = action_config
-
-  config_names_before = set(action_name_to_action_before.keys())
-  config_names_after = set(action_name_to_action_after.keys())
-
-  before_after_diff = config_names_before - config_names_after
-  after_before_diff = config_names_after - config_names_before
-
-  diff_string = "Difference in 'action_config' field:"
-  found_difference = False
-  if before_after_diff:
-    if not found_difference:
-      print(diff_string)  # pylint: disable=superfluous-parens
-      found_difference = True
-    print(("* List before change contains entries for the following "
-           "action_configs that the list after the change doesn't:\n%s") %
-          _array_to_string(before_after_diff, ordered=True))
-  if after_before_diff:
-    if not found_difference:
-      print(diff_string)  # pylint: disable=superfluous-parens
-      found_difference = True
-    print(("* List after change contains entries for the following "
-           "action_configs that the list before the change doesn't:\n%s") %
-          _array_to_string(after_before_diff, ordered=True))
-
-  names_before = [config.config_name for config in action_configs_before]
-  names_after = [config.config_name for config in action_configs_after]
-  if names_before != names_after:
-    if not found_difference:
-      print(diff_string)  # pylint: disable=superfluous-parens
-      found_difference = True
-    print(("Action configs not in right order:\n"
-           "* List of action configs before change:\t%s"
-           "* List of action_configs before change:\t%s") %
-          (_array_to_string(names_before), _array_to_string(names_after)))
-  for name in config_names_before:
-    action_config_before = action_name_to_action_before[name]
-    action_config_after = action_name_to_action_after.get(name, None)
-    if action_config_after and not _check_action_config_equivalence(
-        action_config_before, action_config_after):
-      if not found_difference:
-        print(diff_string)  # pylint: disable=superfluous-parens
-        found_difference = True
-      print(("* Action config '%s' differs before and after the change:\n"
-             "Value before change:\n%s\n"
-             "Value after change:\n%s") % (name, str(action_config_before),
-                                           str(action_config_after)))
-  if found_difference:
-    print("")  # pylint: disable=superfluous-parens
-  return found_difference
-
-
-def _compare_tool_paths(tool_paths_before, tool_paths_after):
-  """Compares two "CToolchain.ToolPath" lists."""
-  tool_to_path_before = {}
-  tool_to_path_after = {}
-  for tool_path in tool_paths_before:
-    tool_to_path_before[tool_path.name] = (
-        tool_path.path if tool_path.path != "NOT_USED" else "")
-  for tool_path in tool_paths_after:
-    tool_to_path_after[tool_path.name] = (
-        tool_path.path if tool_path.path != "NOT_USED" else "")
-
-  tool_names_before = set(tool_to_path_before.keys())
-  tool_names_after = set(tool_to_path_after.keys())
-
-  before_after_diff = tool_names_before - tool_names_after
-  after_before_diff = tool_names_after - tool_names_before
-
-  diff_string = "Difference in 'tool_path' field:"
-  found_difference = False
-  if before_after_diff:
-    if not found_difference:
-      print(diff_string)  # pylint: disable=superfluous-parens
-      found_difference = True
-    print(("* List before change contains entries for the following tools "
-           "that the list after the change doesn't:\n%s") % _array_to_string(
-               before_after_diff, ordered=True))
-  if after_before_diff:
-    if not found_difference:
-      print(diff_string)  # pylint: disable=superfluous-parens
-      found_difference = True
-    print(("* List after change contains entries for the following tools that "
-           "the list before the change doesn't:\n%s") % _array_to_string(
-               after_before_diff, ordered=True))
-
-  for tool in tool_to_path_before:
-    path_before = tool_to_path_before[tool]
-    path_after = tool_to_path_after.get(tool, None)
-    if path_after and path_after != path_before:
-      if not found_difference:
-        print(diff_string)  # pylint: disable=superfluous-parens
-        found_difference = True
-      print(("* Path for tool '%s' differs before and after the change:\n"
-             "Value before change:\t'%s'\n"
-             "Value after change:\t'%s'") % (tool, path_before, path_after))
-  if found_difference:
-    print("")  # pylint: disable=superfluous-parens
-  return found_difference
-
-
-def _compare_make_variables(make_variables_before, make_variables_after):
-  """Compares two "CToolchain.MakeVariable" lists."""
-  name_to_variable_before = {}
-  name_to_variable_after = {}
-  for variable in make_variables_before:
-    name_to_variable_before[variable.name] = variable.value
-  for variable in make_variables_after:
-    name_to_variable_after[variable.name] = variable.value
-
-  variable_names_before = set(name_to_variable_before.keys())
-  variable_names_after = set(name_to_variable_after.keys())
-
-  before_after_diff = variable_names_before - variable_names_after
-  after_before_diff = variable_names_after - variable_names_before
-
-  diff_string = "Difference in 'make_variable' field:"
-  found_difference = False
-  if before_after_diff:
-    if not found_difference:
-      print(diff_string)  # pylint: disable=superfluous-parens
-      found_difference = True
-    print(("* List before change contains entries for the following variables "
-           "that the list after the change doesn't:\n%s") % _array_to_string(
-               before_after_diff, ordered=True))
-  if after_before_diff:
-    if not found_difference:
-      print(diff_string)  # pylint: disable=superfluous-parens
-      found_difference = True
-    print(("* List after change contains entries for the following variables "
-           "that the list before the change doesn't:\n%s") % _array_to_string(
-               after_before_diff, ordered=True))
-
-  for variable in name_to_variable_before:
-    value_before = name_to_variable_before[variable]
-    value_after = name_to_variable_after.get(variable, None)
-    if value_after and value_after != value_before:
-      if not found_difference:
-        print(diff_string)  # pylint: disable=superfluous-parens
-        found_difference = True
-      print(
-          ("* Value for variable '%s' differs before and after the change:\n"
-           "Value before change:\t'%s'\n"
-           "Value after change:\t'%s'") % (variable, value_before, value_after))
-  if found_difference:
-    print("")  # pylint: disable=superfluous-parens
-  return found_difference
-
-
-def _compare_cxx_builtin_include_directories(directories_before,
-                                             directories_after):
-  if directories_before != directories_after:
-    print(("Difference in 'cxx_builtin_include_directory' field:\n"
-           "List of elements before change:\n%s\n"
-           "List of elements after change:\n%s\n") %
-          (_array_to_string(directories_before),
-           _array_to_string(directories_after)))
-    return True
-  return False
-
-
-def _compare_artifact_name_patterns(artifact_name_patterns_before,
-                                    artifact_name_patterns_after):
-  """Compares two "CToolchain.ArtifactNamePattern" lists."""
-  category_to_values_before = {}
-  category_to_values_after = {}
-  for name_pattern in artifact_name_patterns_before:
-    category_to_values_before[name_pattern.category_name] = (
-        name_pattern.prefix, name_pattern.extension)
-  for name_pattern in artifact_name_patterns_after:
-    category_to_values_after[name_pattern.category_name] = (
-        name_pattern.prefix, name_pattern.extension)
-
-  category_names_before = set(category_to_values_before.keys())
-  category_names_after = set(category_to_values_after.keys())
-
-  before_after_diff = category_names_before - category_names_after
-  after_before_diff = category_names_after - category_names_before
-
-  diff_string = "Difference in 'artifact_name_pattern' field:"
-  found_difference = False
-  if before_after_diff:
-    if not found_difference:
-      print(diff_string)  # pylint: disable=superfluous-parens
-      found_difference = True
-    print(("* List before change contains entries for the following categories "
-           "that the list after the change doesn't:\n%s") % _array_to_string(
-               before_after_diff, ordered=True))
-  if after_before_diff:
-    if not found_difference:
-      print(diff_string)  # pylint: disable=superfluous-parens
-      found_difference = True
-    print(("* List after change contains entries for the following categories "
-           "that the list before the change doesn't:\n%s") % _array_to_string(
-               after_before_diff, ordered=True))
-
-  for category in category_to_values_before:
-    value_before = category_to_values_before[category]
-    value_after = category_to_values_after.get(category, None)
-    if value_after and value_after != value_before:
-      if not found_difference:
-        print(diff_string)  # pylint: disable=superfluous-parens
-        found_difference = True
-      print(("* Value for category '%s' differs before and after the change:\n"
-             "Value before change:\tprefix:'%s'\textension:'%s'\n"
-             "Value after change:\tprefix:'%s'\textension:'%s'") %
-            (category, value_before[0], value_before[1], value_after[0],
-             value_after[1]))
-  if found_difference:
-    print("")  # pylint: disable=superfluous-parens
-  return found_difference
-
-
-def compare_ctoolchains(toolchain_before, toolchain_after):
-  """Compares two CToolchains."""
-  found_difference = False
-  if (toolchain_before.toolchain_identifier !=
-      toolchain_after.toolchain_identifier):
-    _print_difference("toolchain_identifier",
-                      toolchain_before.toolchain_identifier,
-                      toolchain_after.toolchain_identifier)
-  if toolchain_before.host_system_name != toolchain_after.host_system_name:
-    _print_difference("host_system_name", toolchain_before.host_system_name,
-                      toolchain_after.host_system_name)
-    found_difference = True
-  if toolchain_before.target_system_name != toolchain_after.target_system_name:
-    _print_difference("target_system_name", toolchain_before.target_system_name,
-                      toolchain_after.target_system_name)
-    found_difference = True
-  if toolchain_before.target_cpu != toolchain_after.target_cpu:
-    _print_difference("target_cpu", toolchain_before.target_cpu,
-                      toolchain_after.target_cpu)
-    found_difference = True
-  if toolchain_before.target_libc != toolchain_after.target_libc:
-    _print_difference("target_libc", toolchain_before.target_libc,
-                      toolchain_after.target_libc)
-    found_difference = True
-  if toolchain_before.compiler != toolchain_after.compiler:
-    _print_difference("compiler", toolchain_before.compiler,
-                      toolchain_after.compiler)
-    found_difference = True
-  if toolchain_before.abi_version != toolchain_after.abi_version:
-    _print_difference("abi_version", toolchain_before.abi_version,
-                      toolchain_after.abi_version)
-    found_difference = True
-  if toolchain_before.abi_libc_version != toolchain_after.abi_libc_version:
-    _print_difference("abi_libc_version", toolchain_before.abi_libc_version,
-                      toolchain_after.abi_libc_version)
-    found_difference = True
-  if toolchain_before.cc_target_os != toolchain_after.cc_target_os:
-    _print_difference("cc_target_os", toolchain_before.cc_target_os,
-                      toolchain_after.cc_target_os)
-    found_difference = True
-  if toolchain_before.builtin_sysroot != toolchain_after.builtin_sysroot:
-    _print_difference("builtin_sysroot", toolchain_before.builtin_sysroot,
-                      toolchain_after.builtin_sysroot)
-    found_difference = True
-  found_difference = _compare_features(
-      toolchain_before.feature, toolchain_after.feature) or found_difference
-  found_difference = _compare_action_configs(
-      toolchain_before.action_config,
-      toolchain_after.action_config) or found_difference
-  found_difference = _compare_tool_paths(
-      toolchain_before.tool_path, toolchain_after.tool_path) or found_difference
-  found_difference = _compare_cxx_builtin_include_directories(
-      toolchain_before.cxx_builtin_include_directory,
-      toolchain_after.cxx_builtin_include_directory) or found_difference
-  found_difference = _compare_make_variables(
-      toolchain_before.make_variable,
-      toolchain_after.make_variable) or found_difference
-  found_difference = _compare_artifact_name_patterns(
-      toolchain_before.artifact_name_pattern,
-      toolchain_after.artifact_name_pattern) or found_difference
-  if not found_difference:
-    print("No difference")  # pylint: disable=superfluous-parens
-  return found_difference
diff --git a/tools/migration/ctoolchain_comparator_lib_test.py b/tools/migration/ctoolchain_comparator_lib_test.py
deleted file mode 100644
index 1a3a270..0000000
--- a/tools/migration/ctoolchain_comparator_lib_test.py
+++ /dev/null
@@ -1,1821 +0,0 @@
-# Copyright 2018 The Bazel Authors. 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.
-
-import unittest
-
-from py import mock
-
-from google.protobuf import text_format
-from third_party.com.github.bazelbuild.bazel.src.main.protobuf import crosstool_config_pb2
-from tools.migration.ctoolchain_comparator_lib import compare_ctoolchains
-
-try:
-  # Python 2
-  from cStringIO import StringIO
-except ImportError:
-  # Python 3
-  from io import StringIO
-
-
-def make_toolchain(toolchain_proto):
-  toolchain = crosstool_config_pb2.CToolchain()
-  text_format.Merge(toolchain_proto, toolchain)
-  return toolchain
-
-
-class CtoolchainComparatorLibTest(unittest.TestCase):
-
-  def test_string_fields(self):
-    first = make_toolchain("""
-          toolchain_identifier: "first-id"
-          host_system_name: "first-host"
-          target_system_name: "first-target"
-          target_cpu: "first-cpu"
-          target_libc: "first-libc"
-          compiler: "first-compiler"
-          abi_version: "first-abi"
-          abi_libc_version: "first-abi-libc"
-          builtin_sysroot: "sysroot"
-        """)
-    second = make_toolchain("""
-          toolchain_identifier: "second-id"
-          host_system_name: "second-host"
-          target_system_name: "second-target"
-          target_cpu: "second-cpu"
-          target_libc: "second-libc"
-          compiler: "second-compiler"
-          abi_version: "second-abi"
-          abi_libc_version: "second-abi-libc"
-          cc_target_os: "os"
-        """)
-    error_toolchain_identifier = (
-        "Difference in 'toolchain_identifier' field:\n"
-        "Value before change:\t'first-id'\n"
-        "Value after change:\t'second-id'\n"
-    )
-    error_host_system_name = (
-        "Difference in 'host_system_name' field:\n"
-        "Value before change:\t'first-host'\n"
-        "Value after change:\t'second-host'\n"
-    )
-    error_target_system_name = (
-        "Difference in 'target_system_name' field:\n"
-        "Value before change:\t'first-target'\n"
-        "Value after change:\t'second-target'\n"
-    )
-    error_target_cpu = (
-        "Difference in 'target_cpu' field:\n"
-        "Value before change:\t'first-cpu'\n"
-        "Value after change:\t'second-cpu'\n"
-    )
-    error_target_libc = (
-        "Difference in 'target_libc' field:\n"
-        "Value before change:\t'first-libc'\n"
-        "Value after change:\t'second-libc'\n"
-    )
-    error_compiler = (
-        "Difference in 'compiler' field:\n"
-        "Value before change:\t'first-compiler'\n"
-        "Value after change:\t'second-compiler'\n"
-    )
-    error_abi_version = (
-        "Difference in 'abi_version' field:\n"
-        "Value before change:\t'first-abi'\n"
-        "Value after change:\t'second-abi'\n"
-    )
-    error_abi_libc_version = (
-        "Difference in 'abi_libc_version' field:\n"
-        "Value before change:\t'first-abi-libc'\n"
-        "Value after change:\t'second-abi-libc'\n"
-    )
-    error_builtin_sysroot = (
-        "Difference in 'builtin_sysroot' field:\n"
-        "Value before change is set to 'sysroot'\n"
-        "Value after change is not set\n"
-    )
-    error_cc_target_os = (
-        "Difference in 'cc_target_os' field:\n"
-        "Value before change is not set\n"
-        "Value after change is set to 'os'\n"
-    )
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(error_toolchain_identifier, mock_stdout.getvalue())
-      self.assertIn(error_host_system_name, mock_stdout.getvalue())
-      self.assertIn(error_target_system_name, mock_stdout.getvalue())
-      self.assertIn(error_target_cpu, mock_stdout.getvalue())
-      self.assertIn(error_target_libc, mock_stdout.getvalue())
-      self.assertIn(error_compiler, mock_stdout.getvalue())
-      self.assertIn(error_abi_version, mock_stdout.getvalue())
-      self.assertIn(error_abi_libc_version, mock_stdout.getvalue())
-      self.assertIn(error_builtin_sysroot, mock_stdout.getvalue())
-      self.assertIn(error_cc_target_os, mock_stdout.getvalue())
-
-  def test_tool_path(self):
-    first = make_toolchain("""
-        tool_path {
-          name: "only_first"
-          path: "/a/b/c"
-        }
-        tool_path {
-          name: "paths_differ"
-          path: "/path/first"
-        }
-    """)
-    second = make_toolchain("""
-        tool_path {
-          name: "paths_differ"
-          path: "/path/second"
-        }
-        tool_path {
-          name: "only_second_1"
-          path: "/a/b/c"
-        }
-        tool_path {
-          name: "only_second_2"
-          path: "/a/b/c"
-        }
-    """)
-    error_only_first = (
-        "* List before change contains entries for the "
-        "following tools that the list after the change "
-        "doesn't:\n[only_first]\n"
-    )
-    error_only_second = (
-        "* List after change contains entries for the "
-        "following tools that the list before the change "
-        "doesn't:\n"
-        "[\n"
-        "\tonly_second_1\n"
-        "\tonly_second_2\n"
-        "]\n"
-    )
-    error_paths_differ = (
-        "* Path for tool 'paths_differ' differs before and "
-        "after the change:\n"
-        "Value before change:\t'/path/first'\n"
-        "Value after change:\t'/path/second'\n"
-    )
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(error_only_first, mock_stdout.getvalue())
-      self.assertIn(error_only_second, mock_stdout.getvalue())
-      self.assertIn(error_paths_differ, mock_stdout.getvalue())
-
-  def test_make_variable(self):
-    first = make_toolchain("""
-        make_variable {
-          name: "only_first"
-          value: "val"
-        }
-        make_variable {
-          name: "value_differs"
-          value: "first_value"
-        }
-    """)
-    second = make_toolchain("""
-        make_variable {
-          name: "value_differs"
-          value: "second_value"
-        }
-        make_variable {
-          name: "only_second_1"
-          value: "val"
-        }
-        make_variable {
-          name: "only_second_2"
-          value: "val"
-        }
-    """)
-    error_only_first = (
-        "* List before change contains entries for the "
-        "following variables that the list after the "
-        "change doesn't:\n[only_first]\n"
-    )
-    error_only_second = (
-        "* List after change contains entries for the "
-        "following variables that the list before the "
-        "change doesn't:\n"
-        "[\n"
-        "\tonly_second_1\n"
-        "\tonly_second_2\n"
-        "]\n"
-    )
-    error_value_differs = (
-        "* Value for variable 'value_differs' differs before"
-        " and after the change:\n"
-        "Value before change:\t'first_value'\n"
-        "Value after change:\t'second_value'\n"
-    )
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(error_only_first, mock_stdout.getvalue())
-      self.assertIn(error_only_second, mock_stdout.getvalue())
-      self.assertIn(error_value_differs, mock_stdout.getvalue())
-
-  def test_cxx_builtin_include_directories(self):
-    first = make_toolchain("""
-        cxx_builtin_include_directory: "a/b/c"
-        cxx_builtin_include_directory: "d/e/f"
-    """)
-    second = make_toolchain("""
-        cxx_builtin_include_directory: "d/e/f"
-        cxx_builtin_include_directory: "a/b/c"
-    """)
-    expect_error = (
-        "Difference in 'cxx_builtin_include_directory' field:\n"
-        "List of elements before change:\n"
-        "[\n"
-        "\ta/b/c\n"
-        "\td/e/f\n"
-        "]\n"
-        "List of elements after change:\n"
-        "[\n"
-        "\td/e/f\n"
-        "\ta/b/c\n"
-        "]\n"
-    )
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(expect_error, mock_stdout.getvalue())
-
-  def test_artifact_name_pattern(self):
-    first = make_toolchain("""
-        artifact_name_pattern {
-          category_name: 'object_file'
-          prefix: ''
-          extension: '.obj1'
-        }
-        artifact_name_pattern {
-          category_name: 'executable'
-          prefix: 'first'
-          extension: '.exe'
-        }
-        artifact_name_pattern {
-          category_name: 'dynamic_library'
-          prefix: ''
-          extension: '.dll'
-        }
-    """)
-    second = make_toolchain("""
-        artifact_name_pattern {
-          category_name: 'object_file'
-          prefix: ''
-          extension: '.obj2'
-        }
-        artifact_name_pattern {
-          category_name: 'static_library'
-          prefix: ''
-          extension: '.lib'
-        }
-        artifact_name_pattern {
-          category_name: 'executable'
-          prefix: 'second'
-          extension: '.exe'
-        }
-        artifact_name_pattern {
-          category_name: 'interface_library'
-          prefix: ''
-          extension: '.if.lib'
-        }
-    """)
-    error_only_first = (
-        "* List before change contains entries for the "
-        "following categories that the list after the "
-        "change doesn't:\n[dynamic_library]\n"
-    )
-    error_only_second = (
-        "* List after change contains entries for the "
-        "following categories that the list before the "
-        "change doesn't:\n"
-        "[\n"
-        "\tinterface_library\n"
-        "\tstatic_library\n"
-        "]\n"
-    )
-    error_extension_differs = (
-        "* Value for category 'object_file' differs "
-        "before and after the change:\n"
-        "Value before change:"
-        "\tprefix:''"
-        "\textension:'.obj1'\n"
-        "Value after change:"
-        "\tprefix:''"
-        "\textension:'.obj2'\n"
-    )
-    error_prefix_differs = (
-        "* Value for category 'executable' differs "
-        "before and after the change:\n"
-        "Value before change:"
-        "\tprefix:'first'"
-        "\textension:'.exe'\n"
-        "Value after change:"
-        "\tprefix:'second'"
-        "\textension:'.exe'\n"
-    )
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(error_only_first, mock_stdout.getvalue())
-      self.assertIn(error_only_second, mock_stdout.getvalue())
-      self.assertIn(error_extension_differs, mock_stdout.getvalue())
-      self.assertIn(error_prefix_differs, mock_stdout.getvalue())
-
-  def test_features_not_ordered(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature1'
-        }
-        feature {
-          name: 'feature2'
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature2'
-        }
-        feature {
-          name: 'feature1'
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn("Features not in right order", mock_stdout.getvalue())
-
-  def test_features_missing(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature1'
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature2'
-        }
-    """)
-    error_only_first = (
-        "* List before change contains entries for the "
-        "following features that the list after the "
-        "change doesn't:\n[feature1]\n"
-    )
-    error_only_second = (
-        "* List after change contains entries for the "
-        "following features that the list before the "
-        "change doesn't:\n[feature2]\n"
-    )
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(error_only_first, mock_stdout.getvalue())
-      self.assertIn(error_only_second, mock_stdout.getvalue())
-
-  def test_feature_enabled(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          enabled: true
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          enabled: false
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Feature 'feature' differs before and after", mock_stdout.getvalue()
-      )
-
-  def test_feature_provides(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          provides: 'a'
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          provides: 'b'
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Feature 'feature' differs before and after the change:",
-          mock_stdout.getvalue(),
-      )
-
-  def test_feature_provides_preserves_order(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          provides: 'a'
-          provides: 'b'
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          provides: 'b'
-          provides: 'a'
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Feature 'feature' differs before and after the change:",
-          mock_stdout.getvalue(),
-      )
-
-  def test_feature_implies(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          implies: 'a'
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Feature 'feature' differs before and after the change:",
-          mock_stdout.getvalue(),
-      )
-
-  def test_feature_implies_preserves_order(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          implies: 'a'
-          implies: 'b'
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          implies: 'b'
-          implies: 'a'
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Feature 'feature' differs before and after the change:",
-          mock_stdout.getvalue(),
-      )
-
-  def test_feature_requires_preserves_list_order(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          requires: {
-            feature: 'feature1'
-          }
-          requires: {
-            feature: 'feature2'
-          }
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          requires: {
-            feature: 'feature2'
-          }
-          requires: {
-            feature: 'feature1'
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Feature 'feature' differs before and after the change:",
-          mock_stdout.getvalue(),
-      )
-
-  def test_feature_requires_ignores_required_features_order(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          requires: {
-            feature: 'feature1'
-            feature: 'feature2'
-          }
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          requires: {
-            feature: 'feature2'
-            feature: 'feature1'
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn("No difference", mock_stdout.getvalue())
-
-  def test_feature_requires_differs(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          requires: {
-            feature: 'feature1'
-          }
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          requires: {
-            feature: 'feature2'
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Feature 'feature' differs before and after the change:",
-          mock_stdout.getvalue(),
-      )
-
-  def test_action_config_ignores_requires(self):
-    first = make_toolchain("""
-        action_config {
-          config_name: 'config'
-          requires: {
-            feature: 'feature1'
-          }
-        }
-    """)
-    second = make_toolchain("""
-        action_config {
-          config_name: 'config'
-          requires: {
-            feature: 'feature2'
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn("No difference", mock_stdout.getvalue())
-
-  def test_env_set_actions_differ(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          env_set {
-            action: 'a1'
-          }
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          env_set: {
-            action: 'a1'
-            action: 'a2'
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Feature 'feature' differs before and after the change:",
-          mock_stdout.getvalue(),
-      )
-
-  def test_env_set_ignores_actions_order(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          env_set {
-            action: 'a2'
-            action: 'a1'
-          }
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          env_set: {
-            action: 'a1'
-            action: 'a2'
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn("No difference", mock_stdout.getvalue())
-
-  def test_env_set_env_entries_not_ordered(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          env_set {
-            env_entry {
-              key: 'k1'
-              value: 'v1'
-            }
-            env_entry {
-              key: 'k2'
-              value: 'v2'
-            }
-          }
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          env_set {
-            env_entry {
-              key: 'k2'
-              value: 'v2'
-            }
-            env_entry {
-              key: 'k1'
-              value: 'v1'
-            }
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Feature 'feature' differs before and after the change:",
-          mock_stdout.getvalue(),
-      )
-
-  def test_env_set_env_entries_differ(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          env_set {
-            env_entry {
-              key: 'k1'
-              value: 'value_first'
-            }
-          }
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          env_set {
-            env_entry {
-              key: 'k1'
-              value: 'value_second'
-            }
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Feature 'feature' differs before and after the change:",
-          mock_stdout.getvalue(),
-      )
-
-  def test_feature_preserves_env_set_order(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          env_set {
-            env_entry {
-              key: 'first'
-              value: 'first'
-            }
-          }
-          env_set {
-            env_entry {
-              key: 'second'
-              value: 'second'
-            }
-          }
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          env_set {
-            env_entry {
-              key: 'second'
-              value: 'second'
-            }
-          }
-          env_set {
-            env_entry {
-              key: 'first'
-              value: 'first'
-            }
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Feature 'feature' differs before and after the change:",
-          mock_stdout.getvalue(),
-      )
-
-  def test_action_config_ignores_env_set(self):
-    first = make_toolchain("""
-        action_config {
-          config_name: 'config'
-          env_set {
-            env_entry {
-              key: 'k1'
-              value: 'value_first'
-            }
-          }
-        }
-    """)
-    second = make_toolchain("""
-        action_config {
-          config_name: 'config'
-          env_set {
-            env_entry {
-              key: 'k1'
-              value: 'value_second'
-            }
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn("No difference", mock_stdout.getvalue())
-
-  def test_env_set_ignores_with_feature_set_order(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          env_set{
-            with_feature {
-              feature: 'feature1'
-            }
-            with_feature {
-              not_feature: 'feature2'
-            }
-          }
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          env_set {
-            with_feature {
-              not_feature: 'feature2'
-            }
-            with_feature {
-              feature: 'feature1'
-            }
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn("No difference", mock_stdout.getvalue())
-
-  def test_env_set_ignores_with_feature_set_lists_order(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          env_set{
-            with_feature {
-              feature: 'feature1'
-              feature: 'feature2'
-              not_feature: 'not_feature1'
-              not_feature: 'not_feature2'
-            }
-          }
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          env_set{
-            with_feature {
-              feature: 'feature2'
-              feature: 'feature1'
-              not_feature: 'not_feature2'
-              not_feature: 'not_feature1'
-            }
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn("No difference", mock_stdout.getvalue())
-
-  def test_flag_set_ignores_actions_order(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set {
-             action: 'a1'
-             action: 'a2'
-          }
-        }
-    """)
-    second = make_toolchain("""
-       feature {
-          name: 'feature'
-          flag_set {
-             action: 'a2'
-             action: 'a1'
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn("No difference", mock_stdout.getvalue())
-
-  def test_action_config_flag_set_actions_ignored(self):
-    first = make_toolchain("""
-      action_config {
-          config_name: 'config'
-          flag_set {
-            action: 'a1'
-          }
-        }
-    """)
-    second = make_toolchain("""
-      action_config {
-          config_name: 'config'
-          flag_set {
-            action: 'a2'
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn("No difference", mock_stdout.getvalue())
-
-  def test_flag_set_ignores_with_feature_set_order(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set {
-            with_feature {
-              feature: 'feature1'
-            }
-            with_feature {
-              not_feature: 'feature2'
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set {
-            with_feature {
-              feature: 'feature1'
-            }
-            with_feature {
-              not_feature: 'feature2'
-            }
-          }
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set {
-            with_feature {
-              not_feature: 'feature2'
-            }
-            with_feature {
-              feature: 'feature1'
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set {
-            with_feature {
-              not_feature: 'feature2'
-            }
-            with_feature {
-              feature: 'feature1'
-            }
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn("No difference", mock_stdout.getvalue())
-
-  def test_flag_set_ignores_with_feature_set_lists_order(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set{
-            with_feature {
-              feature: 'feature1'
-              feature: 'feature2'
-              not_feature: 'not_feature1'
-              not_feature: 'not_feature2'
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set{
-            with_feature {
-              feature: 'feature1'
-              feature: 'feature2'
-              not_feature: 'not_feature1'
-              not_feature: 'not_feature2'
-            }
-          }
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set{
-            with_feature {
-              feature: 'feature2'
-              feature: 'feature1'
-              not_feature: 'not_feature2'
-              not_feature: 'not_feature1'
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set{
-            with_feature {
-              feature: 'feature2'
-              feature: 'feature1'
-              not_feature: 'not_feature2'
-              not_feature: 'not_feature1'
-            }
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn("No difference", mock_stdout.getvalue())
-
-  def test_flag_set_preserves_flag_group_order(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set {
-            flag_group {
-              flag: 'a'
-            }
-            flag_group {
-              flag: 'b'
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set {
-             flag_group {
-               flag: 'a'
-             }
-             flag_group {
-               flag: 'b'
-             }
-          }
-        }
-    """)
-    second = make_toolchain("""
-       feature {
-          name: 'feature'
-          flag_set {
-            flag_group {
-              flag: 'b'
-            }
-            flag_group {
-              flag: 'a'
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set {
-            flag_group {
-              flag: 'b'
-            }
-            flag_group {
-              flag: 'a'
-            }
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Feature 'feature' differs before and after", mock_stdout.getvalue()
-      )
-      self.assertIn(
-          "* Action config 'config' differs before and after",
-          mock_stdout.getvalue(),
-      )
-
-  def test_flag_group_preserves_flags_order(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set{
-            flag_group {
-              flag: 'flag1'
-              flag: 'flag2'
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set{
-            flag_group {
-              flag: 'flag1'
-              flag: 'flag2'
-            }
-          }
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set{
-            flag_group {
-              flag: 'flag2'
-              flag: 'flag1'
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set{
-            flag_group {
-              flag: 'flag2'
-              flag: 'flag1'
-            }
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Feature 'feature' differs before and after", mock_stdout.getvalue()
-      )
-      self.assertIn(
-          "* Action config 'config' differs before and after",
-          mock_stdout.getvalue(),
-      )
-
-  def test_flag_group_iterate_over_differs(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set{
-            flag_group {
-              iterate_over: 'a'
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set{
-            flag_group {
-              iterate_over: 'a'
-            }
-          }
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set{
-            flag_group {
-              iterate_over: 'b'
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set{
-            flag_group {
-              iterate_over: 'b'
-            }
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Feature 'feature' differs before and after", mock_stdout.getvalue()
-      )
-      self.assertIn(
-          "* Action config 'config' differs before and after",
-          mock_stdout.getvalue(),
-      )
-
-  def test_flag_group_expand_if_true_differs(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set{
-            flag_group {
-              expand_if_true: 'a'
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set{
-            flag_group {
-              expand_if_true: 'a'
-            }
-          }
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set{
-            flag_group {
-              expand_if_true: 'b'
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set{
-            flag_group {
-              expand_if_true: 'b'
-            }
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Feature 'feature' differs before and after", mock_stdout.getvalue()
-      )
-      self.assertIn(
-          "* Action config 'config' differs before and after",
-          mock_stdout.getvalue(),
-      )
-
-  def test_flag_group_expand_if_false_differs(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set{
-            flag_group {
-              expand_if_false: 'a'
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set{
-            flag_group {
-              expand_if_false: 'a'
-            }
-          }
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set{
-            flag_group {
-              expand_if_false: 'b'
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set{
-            flag_group {
-              expand_if_false: 'b'
-            }
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Feature 'feature' differs before and after", mock_stdout.getvalue()
-      )
-      self.assertIn(
-          "* Action config 'config' differs before and after",
-          mock_stdout.getvalue(),
-      )
-
-  def test_flag_group_expand_if_all_available_differs(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set{
-            flag_group {
-              expand_if_all_available: 'a'
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set{
-            flag_group {
-              expand_if_all_available: 'a'
-            }
-          }
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set{
-            flag_group {
-              expand_if_all_available: 'b'
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set{
-            flag_group {
-              expand_if_all_available: 'b'
-            }
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Feature 'feature' differs before and after", mock_stdout.getvalue()
-      )
-      self.assertIn(
-          "* Action config 'config' differs before and after",
-          mock_stdout.getvalue(),
-      )
-
-  def test_flag_group_expand_if_none_available_differs(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set{
-            flag_group {
-              expand_if_none_available: 'a'
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set{
-            flag_group {
-              expand_if_none_available: 'a'
-            }
-          }
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set{
-            flag_group {
-              expand_if_none_available: 'b'
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set{
-            flag_group {
-              expand_if_none_available: 'b'
-            }
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Feature 'feature' differs before and after", mock_stdout.getvalue()
-      )
-      self.assertIn(
-          "* Action config 'config' differs before and after",
-          mock_stdout.getvalue(),
-      )
-
-  def test_flag_group_expand_if_all_available_ignores_order(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set{
-            flag_group {
-              expand_if_all_available: 'a'
-              expand_if_all_available: 'b'
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set{
-            flag_group {
-              expand_if_all_available: 'a'
-              expand_if_all_available: 'b'
-            }
-          }
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set{
-            flag_group {
-              expand_if_all_available: 'b'
-              expand_if_all_available: 'a'
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set{
-            flag_group {
-              expand_if_all_available: 'b'
-              expand_if_all_available: 'a'
-            }
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn("No difference", mock_stdout.getvalue())
-
-  def test_flag_group_expand_if_none_available_ignores_order(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set{
-            flag_group {
-              expand_if_none_available: 'a'
-              expand_if_none_available: 'b'
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set{
-            flag_group {
-              expand_if_none_available: 'a'
-              expand_if_none_available: 'b'
-            }
-          }
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set{
-            flag_group {
-              expand_if_none_available: 'b'
-              expand_if_none_available: 'a'
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set{
-            flag_group {
-              expand_if_none_available: 'b'
-              expand_if_none_available: 'a'
-            }
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn("No difference", mock_stdout.getvalue())
-
-  def test_flag_group_expand_if_equal_differs(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set{
-            flag_group {
-              expand_if_equal {
-                variable: 'first'
-                value: 'val'
-              }
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set{
-            flag_group {
-              expand_if_equal {
-                variable: 'first'
-                value: 'val'
-              }
-            }
-          }
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set{
-            flag_group {
-              expand_if_equal {
-                variable: 'second'
-                value: 'val'
-              }
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set{
-            flag_group {
-              expand_if_equal {
-                variable: 'second'
-                value: 'val'
-              }
-            }
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Feature 'feature' differs before and after", mock_stdout.getvalue()
-      )
-      self.assertIn(
-          "* Action config 'config' differs before and after",
-          mock_stdout.getvalue(),
-      )
-
-  def test_flag_group_flag_groups_differ(self):
-    first = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set{
-            flag_group {
-              flag_group {
-                flag: 'a'
-                flag: 'b'
-              }
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set{
-            flag_group {
-              flag_group {
-                flag: 'a'
-                flag: 'b'
-              }
-            }
-          }
-        }
-    """)
-    second = make_toolchain("""
-        feature {
-          name: 'feature'
-          flag_set{
-            flag_group {
-              flag_group {
-                flag: 'b'
-                flag: 'a'
-              }
-            }
-          }
-        }
-        action_config {
-          config_name: 'config'
-          flag_set{
-            flag_group {
-              flag_group {
-                flag: 'b'
-                flag: 'a'
-              }
-            }
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Feature 'feature' differs before and after", mock_stdout.getvalue()
-      )
-      self.assertIn(
-          "* Action config 'config' differs before and after",
-          mock_stdout.getvalue(),
-      )
-
-  def test_action_configs_not_ordered(self):
-    first = make_toolchain("""
-        action_config {
-          config_name: 'action1'
-        }
-        action_config {
-          config_name: 'action2'
-        }
-    """)
-    second = make_toolchain("""
-        action_config {
-          config_name: 'action2'
-        }
-        action_config {
-          config_name: 'action1'
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn("Action configs not in right order", mock_stdout.getvalue())
-
-  def test_action_configs_missing(self):
-    first = make_toolchain("""
-        action_config {
-          config_name: 'action1'
-        }
-    """)
-    second = make_toolchain("""
-        action_config {
-          config_name: 'action2'
-        }
-    """)
-    error_only_first = (
-        "* List before change contains entries for the "
-        "following action_configs that the list after the "
-        "change doesn't:\n[action1]\n"
-    )
-    error_only_second = (
-        "* List after change contains entries for the "
-        "following action_configs that the list before the "
-        "change doesn't:\n[action2]\n"
-    )
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(error_only_first, mock_stdout.getvalue())
-      self.assertIn(error_only_second, mock_stdout.getvalue())
-
-  def test_action_config_enabled(self):
-    first = make_toolchain("""
-        action_config {
-          config_name: 'config'
-          enabled: true
-        }
-    """)
-    second = make_toolchain("""
-        action_config {
-          config_name: 'config'
-          enabled: false
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Action config 'config' differs before and after",
-          mock_stdout.getvalue(),
-      )
-
-  def test_action_config_action_name(self):
-    first = make_toolchain("""
-        action_config {
-          config_name: 'config'
-          action_name: 'config1'
-        }
-    """)
-    second = make_toolchain("""
-        action_config {
-          config_name: 'config'
-          action_name: 'config2'
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Action config 'config' differs before and after",
-          mock_stdout.getvalue(),
-      )
-
-  def test_action_config_tool_tool_path_differs(self):
-    first = make_toolchain("""
-        action_config {
-          config_name: 'config'
-          tool {
-            tool_path: 'path1'
-          }
-        }
-    """)
-    second = make_toolchain("""
-        action_config {
-          config_name: 'config'
-          tool {
-            tool_path: 'path2'
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Action config 'config' differs before and after",
-          mock_stdout.getvalue(),
-      )
-
-  def test_action_config_tool_execution_requirements_differ(self):
-    first = make_toolchain("""
-        action_config {
-          config_name: 'config'
-          tool {
-            execution_requirement: 'a'
-          }
-        }
-    """)
-    second = make_toolchain("""
-        action_config {
-          config_name: 'config'
-          tool {
-            execution_requirement: 'b'
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Action config 'config' differs before and after",
-          mock_stdout.getvalue(),
-      )
-
-  def test_action_config_tool_execution_requirements_ignores_order(self):
-    first = make_toolchain("""
-        action_config {
-          config_name: 'config'
-          tool {
-            execution_requirement: 'a'
-            execution_requirement: 'b'
-          }
-        }
-    """)
-    second = make_toolchain("""
-        action_config {
-          config_name: 'config'
-          tool {
-            execution_requirement: 'b'
-            execution_requirement: 'a'
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn("No difference", mock_stdout.getvalue())
-
-  def test_action_config_implies_differs(self):
-    first = make_toolchain("""
-        action_config {
-          config_name: 'config'
-          implies: 'a'
-        }
-    """)
-    second = make_toolchain("""
-        action_config {
-          config_name: 'config'
-          implies: 'b'
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Action config 'config' differs before and after",
-          mock_stdout.getvalue(),
-      )
-
-  def test_action_config_implies_preserves_order(self):
-    first = make_toolchain("""
-        action_config {
-          config_name: 'config'
-          implies: 'a'
-          implies: 'b'
-        }
-    """)
-    second = make_toolchain("""
-        action_config {
-          config_name: 'config'
-          implies: 'b'
-          implies: 'a'
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn(
-          "* Action config 'config' differs before and after",
-          mock_stdout.getvalue(),
-      )
-
-  def test_unused_tool_path(self):
-    first = make_toolchain("""
-        tool_path {
-          name: "empty"
-          path: ""
-        }
-    """)
-    second = make_toolchain("""
-        tool_path {
-          name: "empty"
-          path: "NOT_USED"
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn("No difference", mock_stdout.getvalue())
-
-  def test_unused_tool_path_in_tool(self):
-    first = make_toolchain("""
-        action_config {
-          config_name: 'config'
-          tool {
-            tool_path: ''
-          }
-        }
-    """)
-    second = make_toolchain("""
-        action_config {
-          config_name: 'config'
-          tool {
-            tool_path: 'NOT_USED'
-          }
-        }
-    """)
-    mock_stdout = StringIO()
-    with mock.patch("sys.stdout", mock_stdout):
-      compare_ctoolchains(first, second)
-      self.assertIn("No difference", mock_stdout.getvalue())
-
-
-if __name__ == "__main__":
-  unittest.main()
diff --git a/tools/migration/ctoolchain_compare.bzl b/tools/migration/ctoolchain_compare.bzl
deleted file mode 100644
index a9632af..0000000
--- a/tools/migration/ctoolchain_compare.bzl
+++ /dev/null
@@ -1,49 +0,0 @@
-"""A test rule that compares two CToolchains in proto format."""
-
-def _impl(ctx):
-    toolchain_config_proto = ctx.actions.declare_file(ctx.label.name + "_toolchain_config.proto")
-    ctx.actions.write(
-        toolchain_config_proto,
-        ctx.attr.toolchain_config[CcToolchainConfigInfo].proto,
-    )
-
-    script = ("%s --before='%s' --after='%s' --toolchain_identifier='%s'" % (
-        ctx.executable._comparator.short_path,
-        ctx.file.crosstool.short_path,
-        toolchain_config_proto.short_path,
-        ctx.attr.toolchain_identifier,
-    ))
-    test_executable = ctx.actions.declare_file(ctx.label.name)
-    ctx.actions.write(test_executable, script, is_executable = True)
-
-    runfiles = ctx.runfiles(files = [toolchain_config_proto, ctx.file.crosstool])
-    runfiles = runfiles.merge(ctx.attr._comparator[DefaultInfo].default_runfiles)
-
-    return DefaultInfo(runfiles = runfiles, executable = test_executable)
-
-cc_toolchains_compare_test = rule(
-    implementation = _impl,
-    attrs = {
-        "crosstool": attr.label(
-            mandatory = True,
-            allow_single_file = True,
-            doc = "Location of the CROSSTOOL file",
-        ),
-        "toolchain_config": attr.label(
-            mandatory = True,
-            providers = [CcToolchainConfigInfo],
-            doc = ("Starlark rule that replaces the CROSSTOOL file functionality " +
-                   "for the CToolchain with the given identifier"),
-        ),
-        "toolchain_identifier": attr.string(
-            mandatory = True,
-            doc = "identifier of the CToolchain that is being compared",
-        ),
-        "_comparator": attr.label(
-            default = ":ctoolchain_comparator",
-            executable = True,
-            cfg = "exec",
-        ),
-    },
-    test = True,
-)
diff --git a/tools/migration/legacy_fields_migration_lib.py b/tools/migration/legacy_fields_migration_lib.py
deleted file mode 100644
index 6107f92..0000000
--- a/tools/migration/legacy_fields_migration_lib.py
+++ /dev/null
@@ -1,564 +0,0 @@
-"""Module providing migrate_legacy_fields function.
-
-migrate_legacy_fields takes parsed CROSSTOOL proto and migrates it (inplace) to
-use only the features.
-
-Tracking issue: https://github.com/bazelbuild/bazel/issues/5187
-
-Since C++ rules team is working on migrating CROSSTOOL from text proto into
-Starlark, we advise CROSSTOOL owners to wait for the CROSSTOOL -> Starlark
-migrator before they invest too much time into fixing their pipeline. Tracking
-issue for the Starlark effort is
-https://github.com/bazelbuild/bazel/issues/5380.
-"""
-
-from third_party.com.github.bazelbuild.bazel.src.main.protobuf import crosstool_config_pb2
-
-ALL_CC_COMPILE_ACTIONS = [
-    "assemble", "preprocess-assemble", "linkstamp-compile", "c-compile",
-    "c++-compile", "c++-header-parsing", "c++-module-compile",
-    "c++-module-codegen", "lto-backend", "clif-match"
-]
-
-ALL_OBJC_COMPILE_ACTIONS = [
-    "objc-compile", "objc++-compile"
-]
-
-ALL_CXX_COMPILE_ACTIONS = [
-    action for action in ALL_CC_COMPILE_ACTIONS
-    if action not in ["c-compile", "preprocess-assemble", "assemble"]
-]
-
-ALL_CC_LINK_ACTIONS = [
-    "c++-link-executable", "c++-link-dynamic-library",
-    "c++-link-nodeps-dynamic-library"
-]
-
-ALL_OBJC_LINK_ACTIONS = [
-    "objc-executable", "objc++-executable",
-]
-
-DYNAMIC_LIBRARY_LINK_ACTIONS = [
-    "c++-link-dynamic-library", "c++-link-nodeps-dynamic-library"
-]
-
-NODEPS_DYNAMIC_LIBRARY_LINK_ACTIONS = ["c++-link-nodeps-dynamic-library"]
-
-TRANSITIVE_DYNAMIC_LIBRARY_LINK_ACTIONS = ["c++-link-dynamic-library"]
-
-TRANSITIVE_LINK_ACTIONS = ["c++-link-executable", "c++-link-dynamic-library"]
-
-CC_LINK_EXECUTABLE = ["c++-link-executable"]
-
-
-def compile_actions(toolchain):
-  """Returns compile actions for cc or objc rules."""
-  if _is_objc_toolchain(toolchain):
-    return ALL_CC_COMPILE_ACTIONS + ALL_OBJC_COMPILE_ACTIONS
-  else:
-    return ALL_CC_COMPILE_ACTIONS
-
-def link_actions(toolchain):
-  """Returns link actions for cc or objc rules."""
-  if _is_objc_toolchain(toolchain):
-    return ALL_CC_LINK_ACTIONS + ALL_OBJC_LINK_ACTIONS
-  else:
-    return ALL_CC_LINK_ACTIONS
-
-
-def executable_link_actions(toolchain):
-  """Returns transitive link actions for cc or objc rules."""
-  if _is_objc_toolchain(toolchain):
-    return CC_LINK_EXECUTABLE + ALL_OBJC_LINK_ACTIONS
-  else:
-    return CC_LINK_EXECUTABLE
-
-
-def _is_objc_toolchain(toolchain):
-  return any(ac.action_name == "objc-compile" for ac in toolchain.action_config)
-
-# Map converting from LinkingMode to corresponding feature name
-LINKING_MODE_TO_FEATURE_NAME = {
-    "FULLY_STATIC": "fully_static_link",
-    "MOSTLY_STATIC": "static_linking_mode",
-    "DYNAMIC": "dynamic_linking_mode",
-    "MOSTLY_STATIC_LIBRARIES": "static_linking_mode_nodeps_library",
-}
-
-def migrate_legacy_fields(crosstool):
-  """Migrates parsed crosstool (inplace) to not use legacy fields."""
-  crosstool.ClearField("default_toolchain")
-  for toolchain in crosstool.toolchain:
-    _ = [_migrate_expand_if_all_available(f) for f in toolchain.feature]
-    _ = [_migrate_expand_if_all_available(ac) for ac in toolchain.action_config]
-    _ = [_migrate_repeated_expands(f) for f in toolchain.feature]
-    _ = [_migrate_repeated_expands(ac) for ac in toolchain.action_config]
-
-    if (toolchain.dynamic_library_linker_flag or
-        _contains_dynamic_flags(toolchain)) and not _get_feature(
-            toolchain, "supports_dynamic_linker"):
-      feature = toolchain.feature.add()
-      feature.name = "supports_dynamic_linker"
-      feature.enabled = True
-
-    if toolchain.supports_start_end_lib and not _get_feature(
-        toolchain, "supports_start_end_lib"):
-      feature = toolchain.feature.add()
-      feature.name = "supports_start_end_lib"
-      feature.enabled = True
-
-    if toolchain.supports_interface_shared_objects and not _get_feature(
-        toolchain, "supports_interface_shared_libraries"):
-      feature = toolchain.feature.add()
-      feature.name = "supports_interface_shared_libraries"
-      feature.enabled = True
-
-    if toolchain.supports_embedded_runtimes and not _get_feature(
-        toolchain, "static_link_cpp_runtimes"):
-      feature = toolchain.feature.add()
-      feature.name = "static_link_cpp_runtimes"
-      feature.enabled = True
-
-    if toolchain.needsPic and not _get_feature(toolchain, "supports_pic"):
-      feature = toolchain.feature.add()
-      feature.name = "supports_pic"
-      feature.enabled = True
-
-    if toolchain.supports_fission and not _get_feature(
-        toolchain, "per_object_debug_info"):
-      # feature {
-      #   name: "per_object_debug_info"
-      #   enabled: true
-      #   flag_set {
-      #     action: "assemble"
-      #     action: "preprocess-assemble"
-      #     action: "c-compile"
-      #     action: "c++-compile"
-      #     action: "c++-module-codegen"
-      #     action: "lto-backend"
-      #     flag_group {
-      #       expand_if_all_available: 'is_using_fission'",
-      #       flag: "-gsplit-dwarf"
-      #     }
-      #   }
-      # }
-      feature = toolchain.feature.add()
-      feature.name = "per_object_debug_info"
-      feature.enabled = True
-      flag_set = feature.flag_set.add()
-      flag_set.action[:] = [
-          "c-compile", "c++-compile", "c++-module-codegen", "assemble",
-          "preprocess-assemble", "lto-backend"
-      ]
-      flag_group = flag_set.flag_group.add()
-      flag_group.expand_if_all_available[:] = ["is_using_fission"]
-      flag_group.flag[:] = ["-gsplit-dwarf"]
-
-    if toolchain.objcopy_embed_flag and not _get_feature(
-        toolchain, "objcopy_embed_flags"):
-      feature = toolchain.feature.add()
-      feature.name = "objcopy_embed_flags"
-      feature.enabled = True
-      flag_set = feature.flag_set.add()
-      flag_set.action[:] = ["objcopy_embed_data"]
-      flag_group = flag_set.flag_group.add()
-      flag_group.flag[:] = toolchain.objcopy_embed_flag
-
-      action_config = toolchain.action_config.add()
-      action_config.action_name = "objcopy_embed_data"
-      action_config.config_name = "objcopy_embed_data"
-      action_config.enabled = True
-      tool = action_config.tool.add()
-      tool.tool_path = _find_tool_path(toolchain, "objcopy")
-
-    if toolchain.ld_embed_flag and not _get_feature(
-        toolchain, "ld_embed_flags"):
-      feature = toolchain.feature.add()
-      feature.name = "ld_embed_flags"
-      feature.enabled = True
-      flag_set = feature.flag_set.add()
-      flag_set.action[:] = ["ld_embed_data"]
-      flag_group = flag_set.flag_group.add()
-      flag_group.flag[:] = toolchain.ld_embed_flag
-
-      action_config = toolchain.action_config.add()
-      action_config.action_name = "ld_embed_data"
-      action_config.config_name = "ld_embed_data"
-      action_config.enabled = True
-      tool = action_config.tool.add()
-      tool.tool_path = _find_tool_path(toolchain, "ld")
-
-
-    # Create default_link_flags feature for linker_flag
-    flag_sets = _extract_legacy_link_flag_sets_for(toolchain)
-    if flag_sets:
-      if _get_feature(toolchain, "default_link_flags"):
-        continue
-      if _get_feature(toolchain, "legacy_link_flags"):
-        for f in toolchain.feature:
-          if f.name == "legacy_link_flags":
-            f.ClearField("flag_set")
-            feature = f
-            _rename_feature_in_toolchain(toolchain, "legacy_link_flags",
-                                         "default_link_flags")
-            break
-      else:
-        feature = _prepend_feature(toolchain)
-      feature.name = "default_link_flags"
-      feature.enabled = True
-      _add_flag_sets(feature, flag_sets)
-
-    # Create default_compile_flags feature for compiler_flag, cxx_flag
-    flag_sets = _extract_legacy_compile_flag_sets_for(toolchain)
-    if flag_sets and not _get_feature(toolchain, "default_compile_flags"):
-      if _get_feature(toolchain, "legacy_compile_flags"):
-        for f in toolchain.feature:
-          if f.name == "legacy_compile_flags":
-            f.ClearField("flag_set")
-            feature = f
-            _rename_feature_in_toolchain(toolchain, "legacy_compile_flags",
-                                         "default_compile_flags")
-            break
-      else:
-        feature = _prepend_feature(toolchain)
-      feature.enabled = True
-      feature.name = "default_compile_flags"
-      _add_flag_sets(feature, flag_sets)
-
-    # Unfiltered cxx flags have to have their own special feature.
-    # "unfiltered_compile_flags" is a well-known (by Bazel) feature name that is
-    # excluded from nocopts filtering.
-    if toolchain.unfiltered_cxx_flag:
-      # If there already is a feature named unfiltered_compile_flags, the
-      # crosstool is already migrated for unfiltered_compile_flags
-      if _get_feature(toolchain, "unfiltered_compile_flags"):
-        for f in toolchain.feature:
-          if f.name == "unfiltered_compile_flags":
-            for flag_set in f.flag_set:
-              for flag_group in flag_set.flag_group:
-                if flag_group.iterate_over == "unfiltered_compile_flags":
-                  flag_group.ClearField("iterate_over")
-                  flag_group.ClearField("expand_if_all_available")
-                  flag_group.ClearField("flag")
-                  flag_group.flag[:] = toolchain.unfiltered_cxx_flag
-      else:
-        if not _get_feature(toolchain, "user_compile_flags"):
-          feature = toolchain.feature.add()
-          feature.name = "user_compile_flags"
-          feature.enabled = True
-          flag_set = feature.flag_set.add()
-          flag_set.action[:] = compile_actions(toolchain)
-          flag_group = flag_set.flag_group.add()
-          flag_group.expand_if_all_available[:] = ["user_compile_flags"]
-          flag_group.iterate_over = "user_compile_flags"
-          flag_group.flag[:] = ["%{user_compile_flags}"]
-
-        if not _get_feature(toolchain, "sysroot"):
-          sysroot_actions = compile_actions(toolchain) + link_actions(toolchain)
-          sysroot_actions.remove("assemble")
-          feature = toolchain.feature.add()
-          feature.name = "sysroot"
-          feature.enabled = True
-          flag_set = feature.flag_set.add()
-          flag_set.action[:] = sysroot_actions
-          flag_group = flag_set.flag_group.add()
-          flag_group.expand_if_all_available[:] = ["sysroot"]
-          flag_group.flag[:] = ["--sysroot=%{sysroot}"]
-
-        feature = toolchain.feature.add()
-        feature.name = "unfiltered_compile_flags"
-        feature.enabled = True
-        flag_set = feature.flag_set.add()
-        flag_set.action[:] = compile_actions(toolchain)
-        flag_group = flag_set.flag_group.add()
-        flag_group.flag[:] = toolchain.unfiltered_cxx_flag
-
-    # clear fields
-    toolchain.ClearField("debian_extra_requires")
-    toolchain.ClearField("gcc_plugin_compiler_flag")
-    toolchain.ClearField("ar_flag")
-    toolchain.ClearField("ar_thin_archives_flag")
-    toolchain.ClearField("gcc_plugin_header_directory")
-    toolchain.ClearField("mao_plugin_header_directory")
-    toolchain.ClearField("supports_normalizing_ar")
-    toolchain.ClearField("supports_thin_archives")
-    toolchain.ClearField("supports_incremental_linker")
-    toolchain.ClearField("supports_dsym")
-    toolchain.ClearField("supports_gold_linker")
-    toolchain.ClearField("default_python_top")
-    toolchain.ClearField("default_python_version")
-    toolchain.ClearField("python_preload_swigdeps")
-    toolchain.ClearField("needsPic")
-    toolchain.ClearField("compilation_mode_flags")
-    toolchain.ClearField("linking_mode_flags")
-    toolchain.ClearField("unfiltered_cxx_flag")
-    toolchain.ClearField("ld_embed_flag")
-    toolchain.ClearField("objcopy_embed_flag")
-    toolchain.ClearField("supports_start_end_lib")
-    toolchain.ClearField("supports_interface_shared_objects")
-    toolchain.ClearField("supports_fission")
-    toolchain.ClearField("supports_embedded_runtimes")
-    toolchain.ClearField("compiler_flag")
-    toolchain.ClearField("cxx_flag")
-    toolchain.ClearField("linker_flag")
-    toolchain.ClearField("dynamic_library_linker_flag")
-    toolchain.ClearField("static_runtimes_filegroup")
-    toolchain.ClearField("dynamic_runtimes_filegroup")
-
-    # Enable features that were previously enabled by Bazel
-    default_features = [
-        "dependency_file", "random_seed", "module_maps", "module_map_home_cwd",
-        "header_module_compile", "include_paths", "pic", "preprocessor_define"
-    ]
-    for feature_name in default_features:
-      feature = _get_feature(toolchain, feature_name)
-      if feature:
-        feature.enabled = True
-
-
-def _find_tool_path(toolchain, tool_name):
-  """Returns the tool path of the tool with the given name."""
-  for tool in toolchain.tool_path:
-    if tool.name == tool_name:
-      return tool.path
-  return None
-
-
-def _add_flag_sets(feature, flag_sets):
-  """Add flag sets into a feature."""
-  for flag_set in flag_sets:
-    with_feature = flag_set[0]
-    actions = flag_set[1]
-    flags = flag_set[2]
-    expand_if_all_available = flag_set[3]
-    not_feature = None
-    if len(flag_set) >= 5:
-      not_feature = flag_set[4]
-    flag_set = feature.flag_set.add()
-    if with_feature is not None:
-      flag_set.with_feature.add().feature[:] = [with_feature]
-    if not_feature is not None:
-      flag_set.with_feature.add().not_feature[:] = [not_feature]
-    flag_set.action[:] = actions
-    flag_group = flag_set.flag_group.add()
-    flag_group.expand_if_all_available[:] = expand_if_all_available
-    flag_group.flag[:] = flags
-  return feature
-
-
-def _extract_legacy_compile_flag_sets_for(toolchain):
-  """Get flag sets for default_compile_flags feature."""
-  result = []
-  if toolchain.compiler_flag:
-    result.append(
-        [None, compile_actions(toolchain), toolchain.compiler_flag, []])
-
-  # Migrate compiler_flag from compilation_mode_flags
-  for cmf in toolchain.compilation_mode_flags:
-    mode = crosstool_config_pb2.CompilationMode.Name(cmf.mode).lower()
-    # coverage mode has been a noop since a while
-    if mode == "coverage":
-      continue
-
-    if (cmf.compiler_flag or
-        cmf.cxx_flag) and not _get_feature(toolchain, mode):
-      feature = toolchain.feature.add()
-      feature.name = mode
-
-    if cmf.compiler_flag:
-      result.append([mode, compile_actions(toolchain), cmf.compiler_flag, []])
-
-  if toolchain.cxx_flag:
-    result.append([None, ALL_CXX_COMPILE_ACTIONS, toolchain.cxx_flag, []])
-
-  # Migrate compiler_flag/cxx_flag from compilation_mode_flags
-  for cmf in toolchain.compilation_mode_flags:
-    mode = crosstool_config_pb2.CompilationMode.Name(cmf.mode).lower()
-    # coverage mode has been a noop since a while
-    if mode == "coverage":
-      continue
-
-    if cmf.cxx_flag:
-      result.append([mode, ALL_CXX_COMPILE_ACTIONS, cmf.cxx_flag, []])
-
-  return result
-
-
-def _extract_legacy_link_flag_sets_for(toolchain):
-  """Get flag sets for default_link_flags feature."""
-  result = []
-
-  # Migrate linker_flag
-  if toolchain.linker_flag:
-    result.append([None, link_actions(toolchain), toolchain.linker_flag, []])
-
-  # Migrate linker_flags from compilation_mode_flags
-  for cmf in toolchain.compilation_mode_flags:
-    mode = crosstool_config_pb2.CompilationMode.Name(cmf.mode).lower()
-    # coverage mode has beed a noop since a while
-    if mode == "coverage":
-      continue
-
-    if cmf.linker_flag and not _get_feature(toolchain, mode):
-      feature = toolchain.feature.add()
-      feature.name = mode
-
-    if cmf.linker_flag:
-      result.append([mode, link_actions(toolchain), cmf.linker_flag, []])
-
-  # Migrate linker_flags from linking_mode_flags
-  for lmf in toolchain.linking_mode_flags:
-    mode = crosstool_config_pb2.LinkingMode.Name(lmf.mode)
-    feature_name = LINKING_MODE_TO_FEATURE_NAME.get(mode)
-    # if the feature is already there, we don't migrate, lmf is not used
-    if _get_feature(toolchain, feature_name):
-      continue
-
-    if lmf.linker_flag:
-      feature = toolchain.feature.add()
-      feature.name = feature_name
-      if mode == "DYNAMIC":
-        result.append(
-            [None, NODEPS_DYNAMIC_LIBRARY_LINK_ACTIONS, lmf.linker_flag, []])
-        result.append([
-            None,
-            TRANSITIVE_DYNAMIC_LIBRARY_LINK_ACTIONS,
-            lmf.linker_flag,
-            [],
-            "static_link_cpp_runtimes",
-        ])
-        result.append([
-            feature_name,
-            executable_link_actions(toolchain), lmf.linker_flag, []
-        ])
-      elif mode == "MOSTLY_STATIC":
-        result.append(
-            [feature_name,
-             CC_LINK_EXECUTABLE, lmf.linker_flag, []])
-      else:
-        result.append(
-           [feature_name,
-            link_actions(toolchain), lmf.linker_flag, []])
-
-  if toolchain.dynamic_library_linker_flag:
-    result.append([
-        None, DYNAMIC_LIBRARY_LINK_ACTIONS,
-        toolchain.dynamic_library_linker_flag, []
-    ])
-
-  if toolchain.test_only_linker_flag:
-    result.append([
-        None,
-        link_actions(toolchain), toolchain.test_only_linker_flag,
-        ["is_cc_test"]
-    ])
-
-  return result
-
-
-def _prepend_feature(toolchain):
-  """Create a new feature and make it be the first in the toolchain."""
-  features = toolchain.feature
-  toolchain.ClearField("feature")
-  new_feature = toolchain.feature.add()
-  toolchain.feature.extend(features)
-  return new_feature
-
-
-def _get_feature(toolchain, name):
-  """Returns feature with a given name or None."""
-  for feature in toolchain.feature:
-    if feature.name == name:
-      return feature
-  return None
-
-
-def _migrate_expand_if_all_available(message):
-  """Move expand_if_all_available field to flag_groups."""
-  for flag_set in message.flag_set:
-    if flag_set.expand_if_all_available:
-      for flag_group in flag_set.flag_group:
-        new_vars = (
-            flag_group.expand_if_all_available[:] +
-            flag_set.expand_if_all_available[:])
-        flag_group.expand_if_all_available[:] = new_vars
-      flag_set.ClearField("expand_if_all_available")
-
-
-def _migrate_repeated_expands(message):
-  """Replace repeated legacy fields with nesting."""
-  todo_queue = []
-  for flag_set in message.flag_set:
-    todo_queue.extend(flag_set.flag_group)
-  while todo_queue:
-    flag_group = todo_queue.pop()
-    todo_queue.extend(flag_group.flag_group)
-    if len(flag_group.expand_if_all_available) <= 1 and len(
-        flag_group.expand_if_none_available) <= 1:
-      continue
-
-    current_children = flag_group.flag_group
-    current_flags = flag_group.flag
-    flag_group.ClearField("flag_group")
-    flag_group.ClearField("flag")
-
-    new_flag_group = flag_group.flag_group.add()
-    new_flag_group.flag_group.extend(current_children)
-    new_flag_group.flag.extend(current_flags)
-
-    if len(flag_group.expand_if_all_available) > 1:
-      expands_to_move = flag_group.expand_if_all_available[1:]
-      flag_group.expand_if_all_available[:] = [
-          flag_group.expand_if_all_available[0]
-      ]
-      new_flag_group.expand_if_all_available.extend(expands_to_move)
-
-    if len(flag_group.expand_if_none_available) > 1:
-      expands_to_move = flag_group.expand_if_none_available[1:]
-      flag_group.expand_if_none_available[:] = [
-          flag_group.expand_if_none_available[0]
-      ]
-      new_flag_group.expand_if_none_available.extend(expands_to_move)
-
-    todo_queue.append(new_flag_group)
-    todo_queue.append(flag_group)
-
-
-def _contains_dynamic_flags(toolchain):
-  for lmf in toolchain.linking_mode_flags:
-    mode = crosstool_config_pb2.LinkingMode.Name(lmf.mode)
-    if mode == "DYNAMIC":
-      return True
-  return False
-
-
-def _rename_feature_in_toolchain(toolchain, from_name, to_name):
-  for f in toolchain.feature:
-    _rename_feature_in(f, from_name, to_name)
-  for a in toolchain.action_config:
-    _rename_feature_in(a, from_name, to_name)
-
-
-def _rename_feature_in(msg, from_name, to_name):
-  if from_name in msg.implies:
-    msg.implies.remove(from_name)
-  for requires in msg.requires:
-    if from_name in requires.feature:
-      requires.feature.remove(from_name)
-      requires.feature.extend([to_name])
-    for flag_set in msg.flag_set:
-      for with_feature in flag_set.with_feature:
-        if from_name in with_feature.feature:
-          with_feature.feature.remove(from_name)
-          with_feature.feature.extend([to_name])
-        if from_name in with_feature.not_feature:
-          with_feature.not_feature.remove(from_name)
-          with_feature.not_feature.extend([to_name])
-    for env_set in msg.env_set:
-      for with_feature in env_set.with_feature:
-        if from_name in with_feature.feature:
-          with_feature.feature.remove(from_name)
-          with_feature.feature.extend([to_name])
-        if from_name in with_feature.not_feature:
-          with_feature.not_feature.remove(from_name)
-          with_feature.not_feature.extend([to_name])
diff --git a/tools/migration/legacy_fields_migration_lib_test.py b/tools/migration/legacy_fields_migration_lib_test.py
deleted file mode 100644
index 93972cc..0000000
--- a/tools/migration/legacy_fields_migration_lib_test.py
+++ /dev/null
@@ -1,1240 +0,0 @@
-import unittest
-from google.protobuf import text_format
-from third_party.com.github.bazelbuild.bazel.src.main.protobuf import crosstool_config_pb2
-from tools.migration.legacy_fields_migration_lib import ALL_CC_COMPILE_ACTIONS
-from tools.migration.legacy_fields_migration_lib import ALL_OBJC_COMPILE_ACTIONS
-from tools.migration.legacy_fields_migration_lib import ALL_CXX_COMPILE_ACTIONS
-from tools.migration.legacy_fields_migration_lib import ALL_CC_LINK_ACTIONS
-from tools.migration.legacy_fields_migration_lib import ALL_OBJC_LINK_ACTIONS
-from tools.migration.legacy_fields_migration_lib import DYNAMIC_LIBRARY_LINK_ACTIONS
-from tools.migration.legacy_fields_migration_lib import NODEPS_DYNAMIC_LIBRARY_LINK_ACTIONS
-from tools.migration.legacy_fields_migration_lib import TRANSITIVE_LINK_ACTIONS
-from tools.migration.legacy_fields_migration_lib import TRANSITIVE_DYNAMIC_LIBRARY_LINK_ACTIONS
-from tools.migration.legacy_fields_migration_lib import CC_LINK_EXECUTABLE
-from tools.migration.legacy_fields_migration_lib import migrate_legacy_fields
-
-
-def assert_has_feature(self, toolchain, name):
-  self.assertTrue(any(feature.name == name for feature in toolchain.feature))
-
-
-def make_crosstool(string):
-  crosstool = crosstool_config_pb2.CrosstoolRelease()
-  text_format.Merge("major_version: '123' minor_version: '456'", crosstool)
-  toolchain = crosstool.toolchain.add()
-  text_format.Merge(string, toolchain)
-  return crosstool
-
-
-def migrate_to_string(crosstool):
-  migrate_legacy_fields(crosstool)
-  return to_string(crosstool)
-
-
-def to_string(crosstool):
-  return text_format.MessageToString(crosstool)
-
-
-class LegacyFieldsMigrationLibTest(unittest.TestCase):
-
-  def test_deletes_fields(self):
-    crosstool = make_crosstool("""
-          debian_extra_requires: 'debian-1'
-          gcc_plugin_compiler_flag: 'gcc_plugin_compiler_flag-1'
-          ar_flag: 'ar_flag-1'
-          ar_thin_archives_flag: 'ar_thin_archives_flag-1'
-          gcc_plugin_header_directory: 'gcc_plugin_header_directory-1'
-          mao_plugin_header_directory: 'mao_plugin_header_directory-1'
-          default_python_top: 'default_python_top-1'
-          default_python_version: 'default_python_version-1'
-          python_preload_swigdeps: false
-          supports_normalizing_ar: false
-          supports_thin_archives: false
-          supports_incremental_linker: false
-          supports_dsym: false
-          supports_gold_linker: false
-          needsPic: false
-          supports_start_end_lib: false
-          supports_interface_shared_objects: false
-          supports_fission: false
-          supports_embedded_runtimes: false
-          static_runtimes_filegroup: 'yolo'
-          dynamic_runtimes_filegroup: 'yolo'
-      """)
-    output = migrate_to_string(crosstool)
-    self.assertNotIn("debian_extra_requires", output)
-    self.assertNotIn("gcc_plugin_compiler_flag", output)
-    self.assertNotIn("ar_flag", output)
-    self.assertNotIn("ar_thin_archives_flag", output)
-    self.assertNotIn("gcc_plugin_header_directory", output)
-    self.assertNotIn("mao_plugin_header_directory", output)
-    self.assertNotIn("supports_normalizing_ar", output)
-    self.assertNotIn("supports_thin_archives", output)
-    self.assertNotIn("supports_incremental_linker", output)
-    self.assertNotIn("supports_dsym", output)
-    self.assertNotIn("default_python_top", output)
-    self.assertNotIn("default_python_version", output)
-    self.assertNotIn("python_preload_swigdeps", output)
-    self.assertNotIn("supports_gold_linker", output)
-    self.assertNotIn("needsPic", output)
-    self.assertNotIn("supports_start_end_lib", output)
-    self.assertNotIn("supports_interface_shared_objects", output)
-    self.assertNotIn("supports_fission", output)
-    self.assertNotIn("supports_embedded_runtimes", output)
-    self.assertNotIn("static_runtimes_filegroup", output)
-    self.assertNotIn("dynamic_runtimes_filegroup", output)
-
-  def test_deletes_default_toolchains(self):
-    crosstool = make_crosstool("")
-    crosstool.default_toolchain.add()
-    self.assertEqual(len(crosstool.default_toolchain), 1)
-    migrate_legacy_fields(crosstool)
-    self.assertEqual(len(crosstool.default_toolchain), 0)
-
-  def test_replace_legacy_compile_flags(self):
-    crosstool = make_crosstool("""
-        feature { name: 'foo' }
-        feature { name: 'legacy_compile_flags' }
-        compiler_flag: 'clang-flag-1'
-    """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(len(output.compiler_flag), 0)
-    self.assertEqual(output.feature[0].name, "foo")
-    self.assertEqual(output.feature[1].name, "default_compile_flags")
-    self.assertEqual(output.feature[1].flag_set[0].action,
-                     ALL_CC_COMPILE_ACTIONS)
-    self.assertEqual(output.feature[1].flag_set[0].flag_group[0].flag,
-                     ["clang-flag-1"])
-
-  def test_replace_legacy_compile_flags_in_action_configs(self):
-    crosstool = make_crosstool("""
-        feature {
-          name: 'foo'
-          implies: 'legacy_compile_flags'
-          requires: { feature: 'legacy_compile_flags' }
-          flag_set {
-            with_feature { feature: 'legacy_compile_flags' }
-            with_feature { not_feature: 'legacy_compile_flags' }
-          }
-          env_set {
-            with_feature { feature: 'legacy_compile_flags' }
-            with_feature { not_feature: 'legacy_compile_flags' }
-          }
-        }
-        feature { name: 'legacy_compile_flags' }
-        action_config {
-          action_name: 'foo'
-          config_name: 'foo'
-          implies: 'legacy_compile_flags'
-          requires: { feature: 'legacy_compile_flags' }
-          flag_set {
-            with_feature { feature: 'legacy_compile_flags' }
-            with_feature { not_feature: 'legacy_compile_flags' }
-          }
-          env_set {
-            with_feature { feature: 'legacy_compile_flags' }
-            with_feature { not_feature: 'legacy_compile_flags' }
-          }
-        }
-        compiler_flag: 'clang-flag-1'
-    """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.action_config[0].action_name, "foo")
-    self.assertEqual(output.action_config[0].implies, [])
-    self.assertEqual(output.action_config[0].requires[0].feature,
-                     ["default_compile_flags"])
-    self.assertEqual(
-        output.action_config[0].flag_set[0].with_feature[0].feature,
-        ["default_compile_flags"])
-    self.assertEqual(
-        output.action_config[0].flag_set[0].with_feature[1].not_feature,
-        ["default_compile_flags"])
-    self.assertEqual(output.action_config[0].env_set[0].with_feature[0].feature,
-                     ["default_compile_flags"])
-    self.assertEqual(
-        output.action_config[0].env_set[0].with_feature[1].not_feature,
-        ["default_compile_flags"])
-    self.assertEqual(output.feature[0].name, "foo")
-    self.assertEqual(output.feature[0].implies, [])
-    self.assertEqual(output.feature[0].requires[0].feature,
-                     ["default_compile_flags"])
-    self.assertEqual(output.feature[0].flag_set[0].with_feature[0].feature,
-                     ["default_compile_flags"])
-    self.assertEqual(output.feature[0].flag_set[0].with_feature[1].not_feature,
-                     ["default_compile_flags"])
-    self.assertEqual(output.feature[0].env_set[0].with_feature[0].feature,
-                     ["default_compile_flags"])
-    self.assertEqual(output.feature[0].env_set[0].with_feature[1].not_feature,
-                     ["default_compile_flags"])
-
-  def test_replace_legacy_link_flags(self):
-    crosstool = make_crosstool("""
-        feature { name: 'foo' }
-        feature { name: 'legacy_link_flags' }
-        linker_flag: 'ld-flag-1'
-    """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(len(output.compiler_flag), 0)
-    self.assertEqual(output.feature[0].name, "foo")
-    self.assertEqual(output.feature[1].name, "default_link_flags")
-    self.assertEqual(output.feature[1].flag_set[0].action, ALL_CC_LINK_ACTIONS)
-    self.assertEqual(output.feature[1].flag_set[0].flag_group[0].flag,
-                     ["ld-flag-1"])
-
-  def test_replace_legacy_link_flags_in_action_configs(self):
-    crosstool = make_crosstool("""
-        feature {
-          name: 'foo'
-          implies: 'legacy_link_flags'
-          requires: { feature: 'legacy_link_flags' }
-          flag_set {
-            with_feature { feature: 'legacy_link_flags' }
-            with_feature { not_feature: 'legacy_link_flags' }
-          }
-          env_set {
-            with_feature { feature: 'legacy_link_flags' }
-            with_feature { not_feature: 'legacy_link_flags' }
-          }
-        }
-        feature { name: 'legacy_link_flags' }
-        action_config {
-          action_name: 'foo'
-          config_name: 'foo'
-          implies: 'legacy_link_flags'
-          requires: { feature: 'legacy_link_flags' }
-          flag_set {
-            with_feature { feature: 'legacy_link_flags' }
-            with_feature { not_feature: 'legacy_link_flags' }
-          }
-          env_set {
-            with_feature { feature: 'legacy_link_flags' }
-            with_feature { not_feature: 'legacy_link_flags' }
-          }
-        }
-        linker_flag: 'clang-flag-1'
-    """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.action_config[0].action_name, "foo")
-    self.assertEqual(output.action_config[0].implies, [])
-    self.assertEqual(output.action_config[0].requires[0].feature,
-                     ["default_link_flags"])
-    self.assertEqual(
-        output.action_config[0].flag_set[0].with_feature[0].feature,
-        ["default_link_flags"])
-    self.assertEqual(
-        output.action_config[0].flag_set[0].with_feature[1].not_feature,
-        ["default_link_flags"])
-    self.assertEqual(output.action_config[0].env_set[0].with_feature[0].feature,
-                     ["default_link_flags"])
-    self.assertEqual(
-        output.action_config[0].env_set[0].with_feature[1].not_feature,
-        ["default_link_flags"])
-    self.assertEqual(output.feature[0].name, "foo")
-    self.assertEqual(output.feature[0].implies, [])
-    self.assertEqual(output.feature[0].requires[0].feature,
-                     ["default_link_flags"])
-    self.assertEqual(output.feature[0].flag_set[0].with_feature[0].feature,
-                     ["default_link_flags"])
-    self.assertEqual(output.feature[0].flag_set[0].with_feature[1].not_feature,
-                     ["default_link_flags"])
-    self.assertEqual(output.feature[0].env_set[0].with_feature[0].feature,
-                     ["default_link_flags"])
-    self.assertEqual(output.feature[0].env_set[0].with_feature[1].not_feature,
-                     ["default_link_flags"])
-
-
-  def test_migrate_compiler_flags(self):
-    crosstool = make_crosstool("""
-        compiler_flag: 'clang-flag-1'
-    """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(len(output.compiler_flag), 0)
-    self.assertEqual(output.feature[0].name, "default_compile_flags")
-    self.assertEqual(output.feature[0].flag_set[0].action, ALL_CC_COMPILE_ACTIONS)
-    self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
-                     ["clang-flag-1"])
-
-  def test_migrate_compiler_flags_for_objc(self):
-    crosstool = make_crosstool("""
-        action_config { action_name: "objc-compile" }
-        compiler_flag: 'clang-flag-1'
-    """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(len(output.compiler_flag), 0)
-    self.assertEqual(output.feature[0].name, "default_compile_flags")
-    self.assertEqual(output.feature[0].flag_set[0].action, ALL_CC_COMPILE_ACTIONS + ALL_OBJC_COMPILE_ACTIONS)
-    self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
-                     ["clang-flag-1"])
-
-  def test_migrate_cxx_flags(self):
-    crosstool = make_crosstool("""
-        cxx_flag: 'clang-flag-1'
-    """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(len(output.cxx_flag), 0)
-    self.assertEqual(output.feature[0].name, "default_compile_flags")
-    self.assertEqual(output.feature[0].flag_set[0].action,
-                     ALL_CXX_COMPILE_ACTIONS)
-    self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
-                     ["clang-flag-1"])
-
-  def test_compiler_flag_come_before_cxx_flags(self):
-    crosstool = make_crosstool("""
-        compiler_flag: 'clang-flag-1'
-        cxx_flag: 'clang-flag-2'
-    """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "default_compile_flags")
-    self.assertEqual(output.feature[0].flag_set[0].action, ALL_CC_COMPILE_ACTIONS)
-    self.assertEqual(output.feature[0].flag_set[1].action,
-                     ALL_CXX_COMPILE_ACTIONS)
-    self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
-                     ["clang-flag-1"])
-    self.assertEqual(output.feature[0].flag_set[1].flag_group[0].flag,
-                     ["clang-flag-2"])
-
-  def test_migrate_linker_flags(self):
-    crosstool = make_crosstool("""
-        linker_flag: 'linker-flag-1'
-    """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(len(output.linker_flag), 0)
-    self.assertEqual(output.feature[0].name, "default_link_flags")
-    self.assertEqual(output.feature[0].flag_set[0].action, ALL_CC_LINK_ACTIONS)
-    self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
-                     ["linker-flag-1"])
-
-  def test_migrate_dynamic_library_linker_flags(self):
-    crosstool = make_crosstool("""
-        dynamic_library_linker_flag: 'linker-flag-1'
-    """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(len(output.dynamic_library_linker_flag), 0)
-    self.assertEqual(output.feature[0].name, "default_link_flags")
-    self.assertEqual(output.feature[0].flag_set[0].action,
-                     DYNAMIC_LIBRARY_LINK_ACTIONS)
-    self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
-                     ["linker-flag-1"])
-
-  def test_compilation_mode_flags(self):
-    crosstool = make_crosstool("""
-        compiler_flag: "compile-flag-1"
-        cxx_flag: "cxx-flag-1"
-        linker_flag: "linker-flag-1"
-        compilation_mode_flags {
-          mode: OPT
-          compiler_flag: "opt-flag-1"
-          cxx_flag: "opt-flag-2"
-          linker_flag: "opt-flag-3"
-        }
-    """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(len(output.compilation_mode_flags), 0)
-    assert_has_feature(self, output, "opt")
-
-    self.assertEqual(output.feature[0].name, "default_compile_flags")
-    self.assertEqual(output.feature[1].name, "default_link_flags")
-
-    # flag set for compiler_flag fields
-    self.assertEqual(len(output.feature[0].flag_set[0].with_feature), 0)
-    self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
-                     ["compile-flag-1"])
-
-    # flag set for compiler_flag from compilation_mode_flags
-    self.assertEqual(len(output.feature[0].flag_set[1].with_feature), 1)
-    self.assertEqual(output.feature[0].flag_set[1].with_feature[0].feature[0],
-                     "opt")
-    self.assertEqual(output.feature[0].flag_set[1].flag_group[0].flag,
-                     ["opt-flag-1"])
-
-    # flag set for cxx_flag fields
-    self.assertEqual(len(output.feature[0].flag_set[2].with_feature), 0)
-    self.assertEqual(output.feature[0].flag_set[2].flag_group[0].flag,
-                     ["cxx-flag-1"])
-
-    # flag set for cxx_flag from compilation_mode_flags
-    self.assertEqual(len(output.feature[0].flag_set[3].with_feature), 1)
-    self.assertEqual(output.feature[0].flag_set[3].with_feature[0].feature[0],
-                     "opt")
-    self.assertEqual(output.feature[0].flag_set[3].flag_group[0].flag,
-                     ["opt-flag-2"])
-
-    # default_link_flags, flag set for linker_flag
-    self.assertEqual(len(output.feature[1].flag_set[0].with_feature), 0)
-    self.assertEqual(output.feature[1].flag_set[0].flag_group[0].flag,
-                     ["linker-flag-1"])
-
-    # default_link_flags, flag set for linker_flag from
-    # compilation_mode_flags
-    self.assertEqual(len(output.feature[1].flag_set[1].with_feature), 1)
-    self.assertEqual(output.feature[1].flag_set[1].with_feature[0].feature[0],
-                     "opt")
-    self.assertEqual(output.feature[1].flag_set[1].flag_group[0].flag,
-                     ["opt-flag-3"])
-
-  def test_linking_mode_flags(self):
-    crosstool = make_crosstool("""
-        linker_flag: "linker-flag-1"
-        compilation_mode_flags {
-          mode: DBG
-          linker_flag: "dbg-flag-1"
-        }
-        linking_mode_flags {
-          mode: MOSTLY_STATIC
-          linker_flag: "mostly-static-flag-1"
-        }
-        """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(len(output.compilation_mode_flags), 0)
-    self.assertEqual(len(output.linking_mode_flags), 0)
-
-    # flag set for linker_flag
-    self.assertEqual(len(output.feature[0].flag_set[0].with_feature), 0)
-    self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
-                     ["linker-flag-1"])
-
-    # flag set for compilation_mode_flags
-    self.assertEqual(len(output.feature[0].flag_set[1].with_feature), 1)
-    self.assertEqual(output.feature[0].flag_set[1].with_feature[0].feature[0],
-                     "dbg")
-    self.assertEqual(output.feature[0].flag_set[1].flag_group[0].flag,
-                     ["dbg-flag-1"])
-
-    # flag set for linking_mode_flags
-    self.assertEqual(len(output.feature[0].flag_set[2].with_feature), 1)
-    self.assertEqual(output.feature[0].flag_set[2].action, CC_LINK_EXECUTABLE)
-    self.assertEqual(output.feature[0].flag_set[2].with_feature[0].feature[0],
-                     "static_linking_mode")
-    self.assertEqual(output.feature[0].flag_set[2].flag_group[0].flag,
-                     ["mostly-static-flag-1"])
-
-  def test_coverage_compilation_mode_ignored(self):
-    crosstool = make_crosstool("""
-    compilation_mode_flags {
-      mode: COVERAGE
-      compiler_flag: "coverage-flag-1"
-      cxx_flag: "coverage-flag-2"
-      linker_flag: "coverage-flag-3"
-    }
-    """)
-    output = migrate_to_string(crosstool)
-    self.assertNotIn("compilation_mode_flags", output)
-    self.assertNotIn("coverage-flag-1", output)
-    self.assertNotIn("coverage-flag-2", output)
-    self.assertNotIn("coverage-flag-3", output)
-    self.assertNotIn("COVERAGE", output)
-
-  def test_supports_dynamic_linker_when_dynamic_library_linker_flag_is_used(
-      self):
-    crosstool = make_crosstool("""
-        dynamic_library_linker_flag: "foo"
-    """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "default_link_flags")
-    self.assertEqual(output.feature[1].name, "supports_dynamic_linker")
-    self.assertEqual(output.feature[1].enabled, True)
-
-  def test_supports_dynamic_linker_is_added_when_DYNAMIC_present(self):
-    crosstool = make_crosstool("""
-    linking_mode_flags {
-      mode: DYNAMIC
-    }
-    """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "supports_dynamic_linker")
-    self.assertEqual(output.feature[0].enabled, True)
-
-  def test_supports_dynamic_linker_is_not_added_when_present(self):
-    crosstool = make_crosstool("""
-    feature { name: "supports_dynamic_linker" enabled: false }
-    """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "supports_dynamic_linker")
-    self.assertEqual(output.feature[0].enabled, False)
-
-  def test_all_linker_flag_ordering(self):
-    crosstool = make_crosstool("""
-    linker_flag: 'linker-flag-1'
-    compilation_mode_flags {
-        mode: OPT
-        linker_flag: 'cmf-flag-2'
-    }
-    linking_mode_flags {
-      mode: MOSTLY_STATIC
-      linker_flag: 'lmf-flag-3'
-    }
-    linking_mode_flags {
-      mode: DYNAMIC
-      linker_flag: 'lmf-dynamic-flag-4'
-    }
-    dynamic_library_linker_flag: 'dl-flag-5'
-    test_only_linker_flag: 'to-flag-6'
-    """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "default_link_flags")
-    self.assertEqual(output.feature[0].enabled, True)
-    self.assertEqual(output.feature[0].flag_set[0].action[:], ALL_CC_LINK_ACTIONS)
-    self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag[:],
-                     ["linker-flag-1"])
-
-    self.assertEqual(output.feature[0].flag_set[1].action[:], ALL_CC_LINK_ACTIONS)
-    self.assertEqual(output.feature[0].flag_set[1].with_feature[0].feature[0],
-                     "opt")
-    self.assertEqual(output.feature[0].flag_set[1].flag_group[0].flag,
-                     ["cmf-flag-2"])
-
-    self.assertEqual(output.feature[0].flag_set[2].action, CC_LINK_EXECUTABLE)
-    self.assertEqual(output.feature[0].flag_set[2].with_feature[0].feature[0],
-                     "static_linking_mode")
-    self.assertEqual(output.feature[0].flag_set[2].flag_group[0].flag,
-                     ["lmf-flag-3"])
-
-    self.assertEqual(len(output.feature[0].flag_set[3].with_feature), 0)
-    self.assertEqual(output.feature[0].flag_set[3].flag_group[0].flag,
-                     ["lmf-dynamic-flag-4"])
-    self.assertEqual(output.feature[0].flag_set[3].action,
-                     NODEPS_DYNAMIC_LIBRARY_LINK_ACTIONS)
-
-    self.assertEqual(
-        output.feature[0].flag_set[4].with_feature[0].not_feature[0],
-        "static_link_cpp_runtimes")
-    self.assertEqual(output.feature[0].flag_set[4].flag_group[0].flag,
-                     ["lmf-dynamic-flag-4"])
-    self.assertEqual(output.feature[0].flag_set[4].action,
-                     TRANSITIVE_DYNAMIC_LIBRARY_LINK_ACTIONS)
-
-    self.assertEqual(output.feature[0].flag_set[5].with_feature[0].feature[0],
-                     "dynamic_linking_mode")
-    self.assertEqual(output.feature[0].flag_set[5].flag_group[0].flag,
-                     ["lmf-dynamic-flag-4"])
-    self.assertEqual(output.feature[0].flag_set[5].action,
-                     CC_LINK_EXECUTABLE)
-
-    self.assertEqual(output.feature[0].flag_set[6].flag_group[0].flag,
-                     ["dl-flag-5"])
-    self.assertEqual(output.feature[0].flag_set[6].action,
-                     DYNAMIC_LIBRARY_LINK_ACTIONS)
-
-    self.assertEqual(output.feature[0].flag_set[7].flag_group[0].flag,
-                     ["to-flag-6"])
-    self.assertEqual(output.feature[0].flag_set[7].action, ALL_CC_LINK_ACTIONS)
-    self.assertEqual(
-        output.feature[0].flag_set[7].flag_group[0].expand_if_all_available,
-        ["is_cc_test"])
-
-  def test_all_linker_flag_objc_actions(self):
-    crosstool = make_crosstool("""
-    action_config { action_name: "objc-compile" }
-    linker_flag: 'linker-flag-1'
-    compilation_mode_flags {
-        mode: OPT
-        linker_flag: 'cmf-flag-2'
-    }
-    linking_mode_flags {
-      mode: MOSTLY_STATIC
-      linker_flag: 'lmf-flag-3'
-    }
-    dynamic_library_linker_flag: 'dl-flag-5'
-    test_only_linker_flag: 'to-flag-6'
-    """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "default_link_flags")
-    self.assertEqual(output.feature[0].flag_set[0].action[:],
-                     ALL_CC_LINK_ACTIONS + ALL_OBJC_LINK_ACTIONS)
-    self.assertEqual(output.feature[0].flag_set[1].action[:],
-                     ALL_CC_LINK_ACTIONS + ALL_OBJC_LINK_ACTIONS)
-    self.assertEqual(output.feature[0].flag_set[2].action[:],
-                     CC_LINK_EXECUTABLE)
-    self.assertEqual(output.feature[0].flag_set[3].action[:],
-                     DYNAMIC_LIBRARY_LINK_ACTIONS)
-    self.assertEqual(output.feature[0].flag_set[4].action[:],
-                     ALL_CC_LINK_ACTIONS + ALL_OBJC_LINK_ACTIONS)
-
-  def test_linking_mode_features_are_not_added_when_present(self):
-    crosstool = make_crosstool("""
-    linking_mode_flags {
-      mode: DYNAMIC
-      linker_flag: 'dynamic-flag'
-    }
-    linking_mode_flags {
-      mode: FULLY_STATIC
-      linker_flag: 'fully-static-flag'
-    }
-    linking_mode_flags {
-      mode: MOSTLY_STATIC
-      linker_flag: 'mostly-static-flag'
-    }
-    linking_mode_flags {
-      mode: MOSTLY_STATIC_LIBRARIES
-      linker_flag: 'mostly-static-libraries-flag'
-    }
-    feature { name: "static_linking_mode" }
-    feature { name: "dynamic_linking_mode" }
-    feature { name: "static_linking_mode_nodeps_library" }
-    feature { name: "fully_static_link" }
-    """)
-    output = migrate_to_string(crosstool)
-    self.assertNotIn("linking_mode_flags", output)
-    self.assertNotIn("DYNAMIC", output)
-    self.assertNotIn("MOSTLY_STATIC", output)
-    self.assertNotIn("MOSTLY_STATIC_LIBRARIES", output)
-    self.assertNotIn("MOSTLY_STATIC_LIBRARIES", output)
-    self.assertNotIn("dynamic-flag", output)
-    self.assertNotIn("fully-static-flag", output)
-    self.assertNotIn("mostly-static-flag", output)
-    self.assertNotIn("mostly-static-libraries-flag", output)
-
-  def test_unfiltered_require_user_compile_flags_and_sysroot(self):
-    crosstool = make_crosstool("""
-      feature { name: 'preexisting_feature' }
-      unfiltered_cxx_flag: 'unfiltered-flag-1'
-    """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    # all these features are added after features that are already present in
-    # the crosstool
-    self.assertEqual(output.feature[0].name, "preexisting_feature")
-    self.assertEqual(output.feature[1].name, "user_compile_flags")
-    self.assertEqual(output.feature[2].name, "sysroot")
-    self.assertEqual(output.feature[3].name, "unfiltered_compile_flags")
-
-  def test_user_compile_flags_not_migrated_when_present(self):
-    crosstool = make_crosstool("""
-      unfiltered_cxx_flag: 'unfiltered-flag-1'
-      feature { name: 'user_compile_flags' }
-      feature { name: 'preexisting_feature' }
-    """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "user_compile_flags")
-    self.assertEqual(output.feature[1].name, "preexisting_feature")
-    self.assertEqual(output.feature[2].name, "sysroot")
-    self.assertEqual(output.feature[3].name, "unfiltered_compile_flags")
-
-  def test_sysroot_not_migrated_when_present(self):
-    crosstool = make_crosstool("""
-      unfiltered_cxx_flag: 'unfiltered-flag-1'
-      feature { name: 'sysroot' }
-      feature { name: 'preexisting_feature' }
-    """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "sysroot")
-    self.assertEqual(output.feature[1].name, "preexisting_feature")
-    self.assertEqual(output.feature[2].name, "user_compile_flags")
-    self.assertEqual(output.feature[3].name, "unfiltered_compile_flags")
-
-  def test_user_compile_flags(self):
-    crosstool = make_crosstool("""
-      unfiltered_cxx_flag: 'unfiltered-flag-1'
-    """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "user_compile_flags")
-    self.assertEqual(output.feature[0].enabled, True)
-    self.assertEqual(output.feature[0].flag_set[0].action,
-                     ALL_CC_COMPILE_ACTIONS)
-    self.assertEqual(
-        output.feature[0].flag_set[0].flag_group[0].expand_if_all_available,
-        ["user_compile_flags"])
-    self.assertEqual(output.feature[0].flag_set[0].flag_group[0].iterate_over,
-                     "user_compile_flags")
-    self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
-                     ["%{user_compile_flags}"])
-
-  def test_sysroot(self):
-    sysroot_actions = ALL_CC_COMPILE_ACTIONS + ALL_CC_LINK_ACTIONS
-    sysroot_actions.remove("assemble")
-    self.assertTrue("assemble" not in sysroot_actions)
-    crosstool = make_crosstool("""
-      unfiltered_cxx_flag: 'unfiltered-flag-1'
-    """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[1].name, "sysroot")
-    self.assertEqual(output.feature[1].enabled, True)
-    self.assertEqual(output.feature[1].flag_set[0].action, sysroot_actions)
-    self.assertEqual(
-        output.feature[1].flag_set[0].flag_group[0].expand_if_all_available,
-        ["sysroot"])
-    self.assertEqual(output.feature[1].flag_set[0].flag_group[0].flag,
-                     ["--sysroot=%{sysroot}"])
-
-  def test_unfiltered_compile_flags_is_not_added_when_already_present(self):
-    crosstool = make_crosstool("""
-            unfiltered_cxx_flag: 'unfiltered-flag-1'
-            feature { name: 'something_else' }
-            feature { name: 'unfiltered_compile_flags' }
-            feature { name: 'something_else_2' }
-        """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "something_else")
-    self.assertEqual(output.feature[1].name, "unfiltered_compile_flags")
-    self.assertEqual(len(output.feature[1].flag_set), 0)
-    self.assertEqual(output.feature[2].name, "something_else_2")
-
-  def test_unfiltered_compile_flags_is_not_edited_if_old_variant_present(self):
-    crosstool = make_crosstool("""
-            unfiltered_cxx_flag: 'unfiltered-flag-1'
-            feature {
-              name: 'unfiltered_compile_flags'
-              flag_set {
-                action: 'c-compile'
-                flag_group {
-                  flag: 'foo-flag-1'
-                }
-              }
-            }
-        """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "unfiltered_compile_flags")
-    self.assertEqual(len(output.feature[0].flag_set), 1)
-    self.assertEqual(output.feature[0].flag_set[0].action, ["c-compile"])
-    self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
-                     ["foo-flag-1"])
-
-  def test_use_of_unfiltered_compile_flags_var_is_removed_and_replaced(self):
-    crosstool = make_crosstool("""
-            unfiltered_cxx_flag: 'unfiltered-flag-1'
-            feature {
-              name: 'unfiltered_compile_flags'
-              flag_set {
-                action: 'c-compile'
-                flag_group {
-                  flag: 'foo-flag-1'
-                }
-              }
-              flag_set {
-                action: 'c++-compile'
-                flag_group {
-                  flag: 'bar-flag-1'
-                }
-                flag_group {
-                  expand_if_all_available: 'unfiltered_compile_flags'
-                  iterate_over: 'unfiltered_compile_flags'
-                  flag: '%{unfiltered_compile_flags}'
-                }
-                flag_group {
-                  flag: 'bar-flag-2'
-                }
-              }
-              flag_set {
-                action: 'c-compile'
-                flag_group {
-                  flag: 'foo-flag-2'
-                }
-              }
-            }
-        """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "unfiltered_compile_flags")
-    self.assertEqual(output.feature[0].flag_set[0].action, ["c-compile"])
-    self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
-                     ["foo-flag-1"])
-    self.assertEqual(output.feature[0].flag_set[1].action, ["c++-compile"])
-    self.assertEqual(output.feature[0].flag_set[1].flag_group[0].flag,
-                     ["bar-flag-1"])
-    self.assertEqual(output.feature[0].flag_set[1].flag_group[1].flag,
-                     ["unfiltered-flag-1"])
-    self.assertEqual(output.feature[0].flag_set[1].flag_group[2].flag,
-                     ["bar-flag-2"])
-    self.assertEqual(output.feature[0].flag_set[2].action, ["c-compile"])
-    self.assertEqual(output.feature[0].flag_set[2].flag_group[0].flag,
-                     ["foo-flag-2"])
-
-  def test_unfiltered_compile_flags_is_added_at_the_end(self):
-    crosstool = make_crosstool("""
-            feature { name: 'something_else' }
-            unfiltered_cxx_flag: 'unfiltered-flag-1'
-        """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "something_else")
-    self.assertEqual(output.feature[1].name, "user_compile_flags")
-    self.assertEqual(output.feature[2].name, "sysroot")
-    self.assertEqual(output.feature[3].name, "unfiltered_compile_flags")
-    self.assertEqual(output.feature[3].flag_set[0].action,
-                     ALL_CC_COMPILE_ACTIONS)
-    self.assertEqual(output.feature[3].flag_set[0].flag_group[0].flag,
-                     ["unfiltered-flag-1"])
-
-  def test_unfiltered_compile_flags_are_not_added_for_objc(self):
-    crosstool = make_crosstool("""
-        action_config { action_name: "obc-compile" }
-        feature { name: 'something_else' }
-        unfiltered_cxx_flag: 'unfiltered-flag-1'
-    """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[3].name, "unfiltered_compile_flags")
-    self.assertEqual(output.feature[3].flag_set[0].action,
-                     ALL_CC_COMPILE_ACTIONS)
-    self.assertEqual(output.feature[3].flag_set[0].flag_group[0].flag,
-                     ["unfiltered-flag-1"])
-
-  def test_default_link_flags_is_added_first(self):
-    crosstool = make_crosstool("""
-          linker_flag: 'linker-flag-1'
-          feature { name: 'something_else' }
-        """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "default_link_flags")
-    self.assertEqual(output.feature[0].enabled, True)
-    self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
-                     ["linker-flag-1"])
-
-  def test_default_link_flags_is_not_added_when_already_present(self):
-    crosstool = make_crosstool("""
-            linker_flag: 'linker-flag-1'
-            feature { name: 'something_else' }
-            feature { name: 'default_link_flags' }
-        """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "something_else")
-    self.assertEqual(output.feature[1].name, "default_link_flags")
-
-  def test_default_compile_flags_is_not_added_when_no_reason_to(self):
-    crosstool = make_crosstool("""
-          feature { name: 'something_else' }
-        """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "something_else")
-    self.assertEqual(len(output.feature), 1)
-
-  def test_default_compile_flags_is_first(self):
-    crosstool = make_crosstool("""
-          compiler_flag: 'compiler-flag-1'
-          feature { name: 'something_else' }
-        """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "default_compile_flags")
-    self.assertEqual(output.feature[0].enabled, True)
-    self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
-                     ["compiler-flag-1"])
-
-  def test_default_compile_flags_not_added_when_present(self):
-    crosstool = make_crosstool("""
-          compiler_flag: 'compiler-flag-1'
-          feature { name: 'something_else' }
-          feature { name: 'default_compile_flags' }
-        """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "something_else")
-    self.assertEqual(output.feature[1].name, "default_compile_flags")
-    self.assertEqual(len(output.feature[1].flag_set), 0)
-
-  def test_supports_start_end_lib_migrated(self):
-    crosstool = make_crosstool("supports_start_end_lib: true")
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "supports_start_end_lib")
-    self.assertEqual(output.feature[0].enabled, True)
-
-  def test_supports_start_end_lib_not_migrated_on_false(self):
-    crosstool = make_crosstool("supports_start_end_lib: false")
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(len(output.feature), 0)
-
-  def test_supports_start_end_lib_not_migrated_when_already_present(self):
-    crosstool = make_crosstool("""
-            supports_start_end_lib: true
-            feature { name: "supports_start_end_lib" enabled: false }
-        """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "supports_start_end_lib")
-    self.assertEqual(output.feature[0].enabled, False)
-
-  def test_supports_interface_shared_libraries_migrated(self):
-    crosstool = make_crosstool("supports_interface_shared_objects: true")
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name,
-                     "supports_interface_shared_libraries")
-    self.assertEqual(output.feature[0].enabled, True)
-
-  def test_supports_interface_shared_libraries_not_migrated_on_false(self):
-    crosstool = make_crosstool("supports_interface_shared_objects: false")
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(len(output.feature), 0)
-
-  def test_supports_interface_shared_libraries_not_migrated_when_present(self):
-    crosstool = make_crosstool("""
-            supports_interface_shared_objects: true
-            feature {
-              name: "supports_interface_shared_libraries"
-              enabled: false }
-        """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name,
-                     "supports_interface_shared_libraries")
-    self.assertEqual(output.feature[0].enabled, False)
-
-  def test_supports_embedded_runtimes_migrated(self):
-    crosstool = make_crosstool("supports_embedded_runtimes: true")
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "static_link_cpp_runtimes")
-    self.assertEqual(output.feature[0].enabled, True)
-
-  def test_supports_embedded_runtimes_not_migrated_on_false(self):
-    crosstool = make_crosstool("supports_embedded_runtimes: false")
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(len(output.feature), 0)
-
-  def test_supports_embedded_runtimes_not_migrated_when_already_present(self):
-    crosstool = make_crosstool("""
-            supports_embedded_runtimes: true
-            feature { name: "static_link_cpp_runtimes" enabled: false }
-        """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "static_link_cpp_runtimes")
-    self.assertEqual(output.feature[0].enabled, False)
-
-  def test_needs_pic_migrated(self):
-    crosstool = make_crosstool("needsPic: true")
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "supports_pic")
-    self.assertEqual(output.feature[0].enabled, True)
-
-  def test_needs_pic_not_migrated_on_false(self):
-    crosstool = make_crosstool("needsPic: false")
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(len(output.feature), 0)
-
-  def test_needs_pic_not_migrated_when_already_present(self):
-    crosstool = make_crosstool("""
-            needsPic: true
-            feature { name: "supports_pic" enabled: false }
-        """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "supports_pic")
-    self.assertEqual(output.feature[0].enabled, False)
-
-  def test_supports_fission_migrated(self):
-    crosstool = make_crosstool("supports_fission: true")
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "per_object_debug_info")
-    self.assertEqual(output.feature[0].enabled, True)
-    self.assertEqual(
-        output.feature[0].flag_set[0].flag_group[0].expand_if_all_available,
-        ["is_using_fission"])
-
-  def test_supports_fission_not_migrated_on_false(self):
-    crosstool = make_crosstool("supports_fission: false")
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(len(output.feature), 0)
-
-  def test_supports_fission_not_migrated_when_already_present(self):
-    crosstool = make_crosstool("""
-            supports_fission: true
-            feature { name: "per_object_debug_info" enabled: false }
-        """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "per_object_debug_info")
-    self.assertEqual(output.feature[0].enabled, False)
-
-  def test_migrating_objcopy_embed_flag(self):
-    crosstool = make_crosstool("""
-            tool_path { name: "objcopy" path: "foo/objcopy" }
-            objcopy_embed_flag: "a"
-            objcopy_embed_flag: "b"
-        """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "objcopy_embed_flags")
-    self.assertEqual(output.feature[0].enabled, True)
-    self.assertEqual(output.feature[0].flag_set[0].action[:],
-                     ["objcopy_embed_data"])
-    self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag[:],
-                     ["a", "b"])
-    self.assertEqual(len(output.objcopy_embed_flag), 0)
-    self.assertEqual(output.action_config[0].action_name, "objcopy_embed_data")
-    self.assertEqual(output.action_config[0].tool[0].tool_path, "foo/objcopy")
-
-  def test_not_migrating_objcopy_embed_flag_when_feature_present(self):
-    crosstool = make_crosstool("""
-            objcopy_embed_flag: "a"
-            objcopy_embed_flag: "b"
-            feature { name: "objcopy_embed_flags" }
-        """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "objcopy_embed_flags")
-    self.assertEqual(output.feature[0].enabled, False)
-
-  def test_migrating_ld_embed_flag(self):
-    crosstool = make_crosstool("""
-            tool_path { name: "ld" path: "foo/ld" }
-            ld_embed_flag: "a"
-            ld_embed_flag: "b"
-        """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "ld_embed_flags")
-    self.assertEqual(output.feature[0].enabled, True)
-    self.assertEqual(output.feature[0].flag_set[0].action[:], ["ld_embed_data"])
-    self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag[:],
-                     ["a", "b"])
-    self.assertEqual(len(output.ld_embed_flag), 0)
-    self.assertEqual(output.action_config[0].action_name, "ld_embed_data")
-    self.assertEqual(output.action_config[0].tool[0].tool_path, "foo/ld")
-
-  def test_not_migrating_objcopy_embed_flag_when_feature_present(self):
-    crosstool = make_crosstool("""
-            objcopy_embed_flag: "a"
-            objcopy_embed_flag: "b"
-            feature { name: "objcopy_embed_flags" }
-        """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.feature[0].name, "objcopy_embed_flags")
-    self.assertEqual(output.feature[0].enabled, False)
-
-  def test_migrate_expand_if_all_available_from_flag_sets(self):
-    crosstool = make_crosstool("""
-        action_config {
-          action_name: 'something'
-          config_name: 'something'
-          flag_set {
-            expand_if_all_available: 'foo'
-            flag_group {
-              flag: '%{foo}'
-            }
-            flag_group {
-              flag: 'bar'
-            }
-          }
-        }
-        feature {
-          name: 'something_else'
-          flag_set {
-            action: 'c-compile'
-            expand_if_all_available: 'foo'
-            flag_group {
-              flag: '%{foo}'
-            }
-            flag_group {
-              flag: 'bar'
-            }
-          }
-        }
-        """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.action_config[0].action_name, "something")
-    self.assertEqual(len(output.action_config[0].flag_set), 1)
-    self.assertEqual(
-        len(output.action_config[0].flag_set[0].expand_if_all_available), 0)
-    self.assertEqual(len(output.action_config[0].flag_set[0].flag_group), 2)
-    self.assertEqual(
-        output.action_config[0].flag_set[0].flag_group[0]
-        .expand_if_all_available, ["foo"])
-    self.assertEqual(
-        output.action_config[0].flag_set[0].flag_group[1]
-        .expand_if_all_available, ["foo"])
-
-    self.assertEqual(output.feature[0].name, "something_else")
-    self.assertEqual(len(output.feature[0].flag_set), 1)
-    self.assertEqual(
-        len(output.feature[0].flag_set[0].expand_if_all_available), 0)
-    self.assertEqual(len(output.feature[0].flag_set[0].flag_group), 2)
-    self.assertEqual(
-        output.feature[0].flag_set[0].flag_group[0].expand_if_all_available,
-        ["foo"])
-    self.assertEqual(
-        output.feature[0].flag_set[0].flag_group[1].expand_if_all_available,
-        ["foo"])
-
-  def test_enable_previously_default_features(self):
-    default_features = [
-        "dependency_file", "random_seed", "module_maps", "module_map_home_cwd",
-        "header_module_compile", "include_paths", "pic", "preprocessor_define"
-    ]
-    crosstool = make_crosstool("""
-          feature { name: "dependency_file" }
-          feature { name: "random_seed" }
-          feature { name: "module_maps" }
-          feature { name: "module_map_home_cwd" }
-          feature { name: "header_module_compile" }
-          feature { name: "include_paths" }
-          feature { name: "pic" }
-          feature { name: "preprocessor_define" }
-          """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    for i in range(0, 8):
-      self.assertEqual(output.feature[i].name, default_features[i])
-      self.assertTrue(output.feature[i].enabled)
-
-  def test_migrate_repeated_expand_if_all_available_from_flag_groups(self):
-    crosstool = make_crosstool("""
-          action_config {
-            action_name: 'something'
-            config_name: 'something'
-            flag_set {
-              flag_group {
-                expand_if_all_available: 'foo'
-                expand_if_all_available: 'bar'
-                flag: '%{foo}'
-              }
-              flag_group {
-                expand_if_none_available: 'foo'
-                expand_if_none_available: 'bar'
-                flag: 'bar'
-              }
-            }
-          }
-          feature {
-            name: 'something_else'
-            flag_set {
-              action: 'c-compile'
-              flag_group {
-                expand_if_all_available: 'foo'
-                expand_if_all_available: 'bar'
-                flag: '%{foo}'
-              }
-              flag_group {
-                expand_if_none_available: 'foo'
-                expand_if_none_available: 'bar'
-                flag: 'bar'
-              }
-            }
-          }
-          """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-    self.assertEqual(output.action_config[0].action_name, "something")
-    self.assertEqual(len(output.action_config[0].flag_set), 1)
-    self.assertEqual(
-        len(output.action_config[0].flag_set[0].expand_if_all_available), 0)
-    self.assertEqual(len(output.action_config[0].flag_set[0].flag_group), 2)
-    self.assertEqual(
-        output.action_config[0].flag_set[0].flag_group[0]
-        .expand_if_all_available, ["foo"])
-    self.assertEqual(
-        output.action_config[0].flag_set[0].flag_group[0].flag_group[0]
-        .expand_if_all_available, ["bar"])
-    self.assertEqual(
-        output.action_config[0].flag_set[0].flag_group[1]
-        .expand_if_none_available, ["foo"])
-    self.assertEqual(
-        output.action_config[0].flag_set[0].flag_group[1].flag_group[0]
-        .expand_if_none_available, ["bar"])
-
-    self.assertEqual(output.feature[0].name, "something_else")
-    self.assertEqual(len(output.feature[0].flag_set), 1)
-    self.assertEqual(
-        len(output.feature[0].flag_set[0].expand_if_all_available), 0)
-    self.assertEqual(len(output.feature[0].flag_set[0].flag_group), 2)
-    self.assertEqual(
-        output.feature[0].flag_set[0].flag_group[0].expand_if_all_available,
-        ["foo"])
-    self.assertEqual(
-        output.feature[0].flag_set[0].flag_group[0].flag_group[0]
-        .expand_if_all_available, ["bar"])
-    self.assertEqual(
-        output.feature[0].flag_set[0].flag_group[1].expand_if_none_available,
-        ["foo"])
-    self.assertEqual(
-        output.feature[0].flag_set[0].flag_group[1].flag_group[0]
-        .expand_if_none_available, ["bar"])
-
-  def test_migrate_repeated_expands_from_nested_flag_groups(self):
-    crosstool = make_crosstool("""
-          feature {
-            name: 'something'
-            flag_set {
-              action: 'c-compile'
-              flag_group {
-                flag_group {
-                  expand_if_all_available: 'foo'
-                  expand_if_all_available: 'bar'
-                  flag: '%{foo}'
-                }
-              }
-              flag_group {
-                flag_group {
-                  expand_if_all_available: 'foo'
-                  expand_if_all_available: 'bar'
-                  expand_if_none_available: 'foo'
-                  expand_if_none_available: 'bar'
-                  flag: '%{foo}'
-                }
-              }
-            }
-          }
-          """)
-    migrate_legacy_fields(crosstool)
-    output = crosstool.toolchain[0]
-
-    self.assertEqual(output.feature[0].name, "something")
-    self.assertEqual(len(output.feature[0].flag_set[0].flag_group), 2)
-    self.assertEqual(
-        len(output.feature[0].flag_set[0].flag_group[0].expand_if_all_available
-           ), 0)
-    self.assertEqual(
-        output.feature[0].flag_set[0].flag_group[0].flag_group[0]
-        .expand_if_all_available, ["foo"])
-    self.assertEqual(
-        output.feature[0].flag_set[0].flag_group[0].flag_group[0].flag_group[0]
-        .expand_if_all_available, ["bar"])
-    self.assertEqual(
-        output.feature[0].flag_set[0].flag_group[0].flag_group[0].flag_group[0]
-        .flag, ["%{foo}"])
-
-    self.assertEqual(
-        output.feature[0].flag_set[0].flag_group[1].flag_group[0]
-        .expand_if_all_available, ["foo"])
-    self.assertEqual(
-        output.feature[0].flag_set[0].flag_group[1].flag_group[0]
-        .expand_if_none_available, ["foo"])
-    self.assertEqual(
-        output.feature[0].flag_set[0].flag_group[1].flag_group[0].flag_group[0]
-        .expand_if_none_available, ["bar"])
-    self.assertEqual(
-        output.feature[0].flag_set[0].flag_group[1].flag_group[0].flag_group[0]
-        .expand_if_all_available, ["bar"])
-    self.assertEqual(
-        output.feature[0].flag_set[0].flag_group[1].flag_group[0].flag_group[0]
-        .flag, ["%{foo}"])
-
-
-if __name__ == "__main__":
-  unittest.main()
diff --git a/tools/migration/legacy_fields_migrator.py b/tools/migration/legacy_fields_migrator.py
deleted file mode 100644
index cc1bb41..0000000
--- a/tools/migration/legacy_fields_migrator.py
+++ /dev/null
@@ -1,69 +0,0 @@
-"""Script migrating legacy CROSSTOOL fields into features.
-
-This script migrates the CROSSTOOL to use only the features to describe C++
-command lines. It is intended to be added as a last step of CROSSTOOL generation
-pipeline. Since it doesn't retain comments, we assume CROSSTOOL owners will want
-to migrate their pipeline manually.
-"""
-
-# Tracking issue: https://github.com/bazelbuild/bazel/issues/5187
-#
-# Since C++ rules team is working on migrating CROSSTOOL from text proto into
-# Starlark, we advise CROSSTOOL owners to wait for the CROSSTOOL -> Starlark
-# migrator before they invest too much time into fixing their pipeline. Tracking
-# issue for the Starlark effort is
-# https://github.com/bazelbuild/bazel/issues/5380.
-
-from absl import app
-from absl import flags
-from google.protobuf import text_format
-from third_party.com.github.bazelbuild.bazel.src.main.protobuf import crosstool_config_pb2
-from tools.migration.legacy_fields_migration_lib import migrate_legacy_fields
-import os
-
-flags.DEFINE_string("input", None, "Input CROSSTOOL file to be migrated")
-flags.DEFINE_string("output", None,
-                    "Output path where to write migrated CROSSTOOL.")
-flags.DEFINE_boolean("inline", None, "Overwrite --input file")
-
-
-def main(unused_argv):
-  crosstool = crosstool_config_pb2.CrosstoolRelease()
-
-  input_filename = flags.FLAGS.input
-  output_filename = flags.FLAGS.output
-  inline = flags.FLAGS.inline
-
-  if not input_filename:
-    raise app.UsageError("ERROR --input unspecified")
-  if not output_filename and not inline:
-    raise app.UsageError("ERROR --output unspecified and --inline not passed")
-  if output_filename and inline:
-    raise app.UsageError("ERROR both --output and --inline passed")
-
-  with open(to_absolute_path(input_filename), "r") as f:
-    input_text = f.read()
-
-  text_format.Merge(input_text, crosstool)
-
-  migrate_legacy_fields(crosstool)
-  output_text = text_format.MessageToString(crosstool)
-
-  resolved_output_filename = to_absolute_path(
-      input_filename if inline else output_filename)
-  with open(resolved_output_filename, "w") as f:
-    f.write(output_text)
-
-def to_absolute_path(path):
-  path = os.path.expanduser(path)
-  if os.path.isabs(path):
-    return path
-  else:
-    if "BUILD_WORKING_DIRECTORY" in os.environ:
-      return os.path.join(os.environ["BUILD_WORKING_DIRECTORY"], path)
-    else:
-      return path
-
-
-if __name__ == "__main__":
-  app.run(main)