diff --git a/android/androidmk.go b/android/androidmk.go
index dd412d7..aff43fa 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -159,12 +159,6 @@
 		return nil
 	}
 
-	if !amod.commonProperties.NamespaceExportedToMake {
-		// TODO(jeffrygaston) do we want to validate that there are no modules being
-		// exported to Kati that depend on this module?
-		return nil
-	}
-
 	data := provider.AndroidMk()
 
 	if data.Include == "" {
diff --git a/android/module.go b/android/module.go
index 1608f4b..0eb4820 100644
--- a/android/module.go
+++ b/android/module.go
@@ -211,8 +211,6 @@
 	ArchSpecific          bool                  `blueprint:"mutated"`
 
 	SkipInstall bool `blueprint:"mutated"`
-
-	NamespaceExportedToMake bool `blueprint:"mutated"`
 }
 
 type hostAndDeviceProperties struct {
@@ -478,13 +476,8 @@
 
 	var deps Paths
 
-	namespacePrefix := ctx.Namespace().(*Namespace).id
-	if namespacePrefix != "" {
-		namespacePrefix = namespacePrefix + "-"
-	}
-
 	if len(allInstalledFiles) > 0 {
-		name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install")
+		name := PathForPhony(ctx, ctx.ModuleName()+"-install")
 		ctx.Build(pctx, BuildParams{
 			Rule:      blueprint.Phony,
 			Output:    name,
@@ -496,7 +489,7 @@
 	}
 
 	if len(allCheckbuildFiles) > 0 {
-		name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild")
+		name := PathForPhony(ctx, ctx.ModuleName()+"-checkbuild")
 		ctx.Build(pctx, BuildParams{
 			Rule:      blueprint.Phony,
 			Output:    name,
@@ -512,10 +505,9 @@
 			suffix = "-soong"
 		}
 
-		name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix)
 		ctx.Build(pctx, BuildParams{
 			Rule:      blueprint.Phony,
-			Outputs:   []WritablePath{name},
+			Output:    PathForPhony(ctx, ctx.ModuleName()+suffix),
 			Implicits: deps,
 		})
 
diff --git a/android/mutator.go b/android/mutator.go
index 3c6e3e3..cc3f1f3 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -86,7 +86,6 @@
 }
 
 var preDeps = []RegisterMutatorFunc{
-	RegisterNamespaceMutator,
 	registerArchMutator,
 }
 
diff --git a/android/namespace.go b/android/namespace.go
deleted file mode 100644
index 5f7e962..0000000
--- a/android/namespace.go
+++ /dev/null
@@ -1,402 +0,0 @@
-// Copyright 2017 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package android
-
-import (
-	"fmt"
-	"path/filepath"
-	"sort"
-	"strconv"
-	"strings"
-	"sync"
-	"sync/atomic"
-
-	"github.com/google/blueprint"
-)
-
-// This file implements namespaces
-const (
-	namespacePrefix = "//"
-	modulePrefix    = ":"
-)
-
-func init() {
-	RegisterModuleType("soong_namespace", NamespaceFactory)
-}
-
-// threadsafe sorted list
-type sortedNamespaces struct {
-	lock   sync.Mutex
-	items  []*Namespace
-	sorted bool
-}
-
-func (s *sortedNamespaces) add(namespace *Namespace) {
-	s.lock.Lock()
-	defer s.lock.Unlock()
-	if s.sorted {
-		panic("It is not supported to call sortedNamespaces.add() after sortedNamespaces.sortedItems()")
-	}
-	s.items = append(s.items, namespace)
-}
-
-func (s *sortedNamespaces) sortedItems() []*Namespace {
-	s.lock.Lock()
-	defer s.lock.Unlock()
-	if !s.sorted {
-		less := func(i int, j int) bool {
-			return s.items[i].Path < s.items[j].Path
-		}
-		sort.Slice(s.items, less)
-		s.sorted = true
-	}
-	return s.items
-}
-
-// A NameResolver implements blueprint.NameInterface, and implements the logic to
-// find a module from namespaces based on a query string.
-// A query string can be a module name or can be be "//namespace_path:module_path"
-type NameResolver struct {
-	rootNamespace *Namespace
-
-	// id counter for atomic.AddInt32
-	numNamespaces int32
-
-	// All namespaces, without duplicates.
-	sortedNamespaces sortedNamespaces
-
-	// Map from dir to namespace. Will have duplicates if two dirs are part of the same namespace.
-	namespacesByDir sync.Map // if generics were supported, this would be sync.Map[string]*Namespace
-
-	// func telling whether to export a namespace to Kati
-	namespaceExportFilter func(*Namespace) bool
-}
-
-func NewNameResolver(namespaceExportFilter func(*Namespace) bool) *NameResolver {
-	namespacesByDir := sync.Map{}
-
-	r := &NameResolver{
-		namespacesByDir:       namespacesByDir,
-		namespaceExportFilter: namespaceExportFilter,
-	}
-	r.rootNamespace = r.newNamespace(".")
-	r.rootNamespace.visibleNamespaces = []*Namespace{r.rootNamespace}
-	r.addNamespace(r.rootNamespace)
-
-	return r
-}
-
-func (r *NameResolver) newNamespace(path string) *Namespace {
-	namespace := NewNamespace(path)
-
-	namespace.exportToKati = r.namespaceExportFilter(namespace)
-
-	nextId := atomic.AddInt32(&r.numNamespaces, 1)
-	id := nextId - 1
-	stringId := ""
-	if id > 0 {
-		stringId = strconv.Itoa(int(id))
-	}
-	namespace.id = stringId
-
-	return namespace
-}
-
-func (r *NameResolver) addNewNamespaceForModule(module *NamespaceModule, dir string) error {
-	namespace := r.newNamespace(dir)
-	module.namespace = namespace
-	module.resolver = r
-	namespace.importedNamespaceNames = module.properties.Imports
-	return r.addNamespace(namespace)
-}
-
-func (r *NameResolver) addNamespace(namespace *Namespace) (err error) {
-	existingNamespace, exists := r.namespaceAt(namespace.Path)
-	if exists {
-		if existingNamespace.Path == namespace.Path {
-			return fmt.Errorf("namespace %v already exists", namespace.Path)
-		} else {
-			// It would probably confuse readers if namespaces were declared anywhere but
-			// the top of the file, so we forbid declaring namespaces after anything else.
-			return fmt.Errorf("a namespace must be the first module in the file")
-		}
-	}
-	r.sortedNamespaces.add(namespace)
-
-	r.namespacesByDir.Store(namespace.Path, namespace)
-	return nil
-}
-
-// non-recursive check for namespace
-func (r *NameResolver) namespaceAt(path string) (namespace *Namespace, found bool) {
-	mapVal, found := r.namespacesByDir.Load(path)
-	if !found {
-		return nil, false
-	}
-	return mapVal.(*Namespace), true
-}
-
-// recursive search upward for a namespace
-func (r *NameResolver) findNamespace(path string) (namespace *Namespace) {
-	namespace, found := r.namespaceAt(path)
-	if found {
-		return namespace
-	}
-	parentDir := filepath.Dir(path)
-	if parentDir == path {
-		return nil
-	}
-	namespace = r.findNamespace(parentDir)
-	r.namespacesByDir.Store(path, namespace)
-	return namespace
-}
-
-func (r *NameResolver) NewModule(ctx blueprint.NamespaceContext, moduleGroup blueprint.ModuleGroup, module blueprint.Module) (namespace blueprint.Namespace, errs []error) {
-	// if this module is a namespace, then save it to our list of namespaces
-	newNamespace, ok := module.(*NamespaceModule)
-	if ok {
-		err := r.addNewNamespaceForModule(newNamespace, ctx.ModuleDir())
-		if err != nil {
-			return nil, []error{err}
-		}
-		return nil, nil
-	}
-
-	// if this module is not a namespace, then save it into the appropriate namespace
-	ns := r.findNamespaceFromCtx(ctx)
-
-	_, errs = ns.moduleContainer.NewModule(ctx, moduleGroup, module)
-	if len(errs) > 0 {
-		return nil, errs
-	}
-
-	amod, ok := module.(Module)
-	if ok {
-		// inform the module whether its namespace is one that we want to export to Make
-		amod.base().commonProperties.NamespaceExportedToMake = ns.exportToKati
-	}
-
-	return ns, nil
-}
-
-func (r *NameResolver) AllModules() []blueprint.ModuleGroup {
-	childLists := [][]blueprint.ModuleGroup{}
-	totalCount := 0
-	for _, namespace := range r.sortedNamespaces.sortedItems() {
-		newModules := namespace.moduleContainer.AllModules()
-		totalCount += len(newModules)
-		childLists = append(childLists, newModules)
-	}
-
-	allModules := make([]blueprint.ModuleGroup, 0, totalCount)
-	for _, childList := range childLists {
-		allModules = append(allModules, childList...)
-	}
-	return allModules
-}
-
-// parses a fully-qualified path (like "//namespace_path:module_name") into a namespace name and a
-// module name
-func (r *NameResolver) parseFullyQualifiedName(name string) (namespaceName string, moduleName string, ok bool) {
-	if !strings.HasPrefix(name, namespacePrefix) {
-		return "", "", false
-	}
-	name = strings.TrimPrefix(name, namespacePrefix)
-	components := strings.Split(name, modulePrefix)
-	if len(components) != 2 {
-		return "", "", false
-	}
-	return components[0], components[1], true
-
-}
-
-func (r *NameResolver) getNamespacesToSearchForModule(sourceNamespace *Namespace) (searchOrder []*Namespace) {
-	return sourceNamespace.visibleNamespaces
-}
-
-func (r *NameResolver) ModuleFromName(name string, namespace blueprint.Namespace) (group blueprint.ModuleGroup, found bool) {
-	// handle fully qualified references like "//namespace_path:module_name"
-	nsName, moduleName, isAbs := r.parseFullyQualifiedName(name)
-	if isAbs {
-		namespace, found := r.namespaceAt(nsName)
-		if !found {
-			return blueprint.ModuleGroup{}, false
-		}
-		container := namespace.moduleContainer
-		return container.ModuleFromName(moduleName, nil)
-	}
-	for _, candidate := range r.getNamespacesToSearchForModule(namespace.(*Namespace)) {
-		group, found = candidate.moduleContainer.ModuleFromName(name, nil)
-		if found {
-			return group, true
-		}
-	}
-	return blueprint.ModuleGroup{}, false
-
-}
-
-func (r *NameResolver) Rename(oldName string, newName string, namespace blueprint.Namespace) []error {
-	oldNs := r.findNamespace(oldName)
-	newNs := r.findNamespace(newName)
-	if oldNs != newNs {
-		return []error{fmt.Errorf("cannot rename %v to %v because the destination is outside namespace %v", oldName, newName, oldNs.Path)}
-	}
-
-	oldName, err := filepath.Rel(oldNs.Path, oldName)
-	if err != nil {
-		panic(err)
-	}
-	newName, err = filepath.Rel(newNs.Path, newName)
-	if err != nil {
-		panic(err)
-	}
-
-	return oldNs.moduleContainer.Rename(oldName, newName, nil)
-}
-
-// resolve each element of namespace.importedNamespaceNames and put the result in namespace.visibleNamespaces
-func (r *NameResolver) FindNamespaceImports(namespace *Namespace) (err error) {
-	namespace.visibleNamespaces = make([]*Namespace, 0, 2+len(namespace.importedNamespaceNames))
-	// search itself first
-	namespace.visibleNamespaces = append(namespace.visibleNamespaces, namespace)
-	// search its imports next
-	for _, name := range namespace.importedNamespaceNames {
-		imp, ok := r.namespaceAt(name)
-		if !ok {
-			return fmt.Errorf("namespace %v does not exist", name)
-		}
-		namespace.visibleNamespaces = append(namespace.visibleNamespaces, imp)
-	}
-	// search the root namespace last
-	namespace.visibleNamespaces = append(namespace.visibleNamespaces, r.rootNamespace)
-	return nil
-}
-
-func (r *NameResolver) MissingDependencyError(depender string, dependerNamespace blueprint.Namespace, depName string) (err error) {
-	text := fmt.Sprintf("%q depends on undefined module %q", depender, depName)
-
-	_, _, isAbs := r.parseFullyQualifiedName(depName)
-	if isAbs {
-		// if the user gave a fully-qualified name, we don't need to look for other
-		// modules that they might have been referring to
-		return fmt.Errorf(text)
-	}
-
-	// determine which namespaces the module can be found in
-	foundInNamespaces := []string{}
-	for _, namespace := range r.sortedNamespaces.sortedItems() {
-		_, found := namespace.moduleContainer.ModuleFromName(depName, nil)
-		if found {
-			foundInNamespaces = append(foundInNamespaces, namespace.Path)
-		}
-	}
-	if len(foundInNamespaces) > 0 {
-		// determine which namespaces are visible to dependerNamespace
-		dependerNs := dependerNamespace.(*Namespace)
-		searched := r.getNamespacesToSearchForModule(dependerNs)
-		importedNames := []string{}
-		for _, ns := range searched {
-			importedNames = append(importedNames, ns.Path)
-		}
-		text += fmt.Sprintf("\nModule %q is defined in namespace %q which can read these %v namespaces: %q", depender, dependerNs.Path, len(importedNames), importedNames)
-		text += fmt.Sprintf("\nModule %q can be found in these namespaces: %q", depName, foundInNamespaces)
-	}
-
-	return fmt.Errorf(text)
-}
-
-func (r *NameResolver) GetNamespace(ctx blueprint.NamespaceContext) blueprint.Namespace {
-	return r.findNamespaceFromCtx(ctx)
-}
-
-func (r *NameResolver) findNamespaceFromCtx(ctx blueprint.NamespaceContext) *Namespace {
-	return r.findNamespace(ctx.ModuleDir())
-}
-
-var _ blueprint.NameInterface = (*NameResolver)(nil)
-
-type Namespace struct {
-	blueprint.NamespaceMarker
-	Path string
-
-	// a unique name (derived from the path), to be used in generating unique module names without
-	// repeating the entire module path
-	Shortname string
-
-	// names of namespaces listed as imports by this namespace
-	importedNamespaceNames []string
-	// all namespaces that should be searched when a module in this namespace declares a dependency
-	visibleNamespaces []*Namespace
-
-	id string
-
-	exportToKati bool
-
-	moduleContainer blueprint.NameInterface
-}
-
-func NewNamespace(path string) *Namespace {
-	return &Namespace{Path: path, moduleContainer: blueprint.NewSimpleNameInterface()}
-}
-
-var _ blueprint.Namespace = (*Namespace)(nil)
-
-type NamespaceModule struct {
-	ModuleBase
-
-	namespace *Namespace
-	resolver  *NameResolver
-
-	properties struct {
-		Imports []string
-	}
-}
-
-func (n *NamespaceModule) DepsMutator(context BottomUpMutatorContext) {
-}
-
-func (n *NamespaceModule) GenerateAndroidBuildActions(ctx ModuleContext) {
-}
-
-func (n *NamespaceModule) GenerateBuildActions(ctx blueprint.ModuleContext) {
-}
-
-func (n *NamespaceModule) Name() (name string) {
-	return *n.nameProperties.Name
-}
-
-func NamespaceFactory() Module {
-	module := &NamespaceModule{}
-
-	name := "soong_namespace"
-	module.nameProperties.Name = &name
-
-	module.AddProperties(&module.properties)
-	return module
-}
-
-func RegisterNamespaceMutator(ctx RegisterMutatorsContext) {
-	ctx.BottomUp("namespace_deps", namespaceDeps)
-}
-
-func namespaceDeps(ctx BottomUpMutatorContext) {
-	module, ok := ctx.Module().(*NamespaceModule)
-	if ok {
-		err := module.resolver.FindNamespaceImports(module.namespace)
-		if err != nil {
-			ctx.ModuleErrorf(err.Error())
-		}
-	}
-}
diff --git a/android/namespace_test.go b/android/namespace_test.go
deleted file mode 100644
index b10b528..0000000
--- a/android/namespace_test.go
+++ /dev/null
@@ -1,652 +0,0 @@
-// Copyright 2017 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package android
-
-import (
-	"errors"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"testing"
-
-	"github.com/google/blueprint"
-)
-
-func TestDependingOnModuleInSameNamespace(t *testing.T) {
-	ctx := setupTest(t,
-		map[string]string{
-			"dir1": `
-			soong_namespace {
-			}
-			test_module {
-				name: "a",
-			}
-			test_module {
-				name: "b",
-				deps: ["a"],
-			}
-			`,
-		},
-	)
-
-	a := getModule(ctx, "a")
-	b := getModule(ctx, "b")
-	if !dependsOn(ctx, b, a) {
-		t.Errorf("module b does not depend on module a in the same namespace")
-	}
-}
-
-func TestDependingOnModuleInRootNamespace(t *testing.T) {
-	ctx := setupTest(t,
-		map[string]string{
-			".": `
-			test_module {
-				name: "b",
-				deps: ["a"],
-			}
-			test_module {
-				name: "a",
-			}
-			`,
-		},
-	)
-
-	a := getModule(ctx, "a")
-	b := getModule(ctx, "b")
-	if !dependsOn(ctx, b, a) {
-		t.Errorf("module b in root namespace does not depend on module a in the root namespace")
-	}
-}
-
-func TestImplicitlyImportRootNamespace(t *testing.T) {
-	_ = setupTest(t,
-		map[string]string{
-			".": `
-			test_module {
-				name: "a",
-			}
-			`,
-			"dir1": `
-			soong_namespace {
-			}
-			test_module {
-				name: "b",
-				deps: ["a"],
-			}
-			`,
-		},
-	)
-
-	// setupTest will report any errors
-}
-
-func TestDependingOnModuleInImportedNamespace(t *testing.T) {
-	ctx := setupTest(t,
-		map[string]string{
-			"dir1": `
-			soong_namespace {
-			}
-			test_module {
-				name: "a",
-			}
-			`,
-			"dir2": `
-			soong_namespace {
-				imports: ["dir1"],
-			}
-			test_module {
-				name: "b",
-				deps: ["a"],
-			}
-			`,
-		},
-	)
-
-	a := getModule(ctx, "a")
-	b := getModule(ctx, "b")
-	if !dependsOn(ctx, b, a) {
-		t.Errorf("module b does not depend on module a in the same namespace")
-	}
-}
-
-func TestDependingOnModuleInNonImportedNamespace(t *testing.T) {
-	_, errs := setupTestExpectErrs(
-		map[string]string{
-			"dir1": `
-			soong_namespace {
-			}
-			test_module {
-				name: "a",
-			}
-			`,
-			"dir2": `
-			soong_namespace {
-			}
-			test_module {
-				name: "a",
-			}
-			`,
-			"dir3": `
-			soong_namespace {
-			}
-			test_module {
-				name: "b",
-				deps: ["a"],
-			}
-			`,
-		},
-	)
-
-	expectedErrors := []error{
-		errors.New(
-			`dir3/Blueprints:4:4: "b" depends on undefined module "a"
-Module "b" is defined in namespace "dir3" which can read these 2 namespaces: ["dir3" "."]
-Module "a" can be found in these namespaces: ["dir1" "dir2"]`),
-	}
-
-	if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
-		t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
-	}
-}
-
-func TestDependingOnModuleByFullyQualifiedReference(t *testing.T) {
-	ctx := setupTest(t,
-		map[string]string{
-			"dir1": `
-			soong_namespace {
-			}
-			test_module {
-				name: "a",
-			}
-			`,
-			"dir2": `
-			soong_namespace {
-			}
-			test_module {
-				name: "b",
-				deps: ["//dir1:a"],
-			}
-			`,
-		},
-	)
-	a := getModule(ctx, "a")
-	b := getModule(ctx, "b")
-	if !dependsOn(ctx, b, a) {
-		t.Errorf("module b does not depend on module a")
-	}
-}
-
-func TestSameNameInTwoNamespaces(t *testing.T) {
-	ctx := setupTest(t,
-		map[string]string{
-			"dir1": `
-			soong_namespace {
-			}
-			test_module {
-				name: "a",
-				id: "1",
-			}
-			test_module {
-				name: "b",
-				deps: ["a"],
-				id: "2",
-			}
-			`,
-			"dir2": `
-			soong_namespace {
-			}
-			test_module {
-				name: "a",
-				id:"3",
-			}
-			test_module {
-				name: "b",
-				deps: ["a"],
-				id:"4",
-			}
-			`,
-		},
-	)
-
-	one := findModuleById(ctx, "1")
-	two := findModuleById(ctx, "2")
-	three := findModuleById(ctx, "3")
-	four := findModuleById(ctx, "4")
-	if !dependsOn(ctx, two, one) {
-		t.Fatalf("Module 2 does not depend on module 1 in its namespace")
-	}
-	if dependsOn(ctx, two, three) {
-		t.Fatalf("Module 2 depends on module 3 in another namespace")
-	}
-	if !dependsOn(ctx, four, three) {
-		t.Fatalf("Module 4 does not depend on module 3 in its namespace")
-	}
-	if dependsOn(ctx, four, one) {
-		t.Fatalf("Module 4 depends on module 1 in another namespace")
-	}
-}
-
-func TestSearchOrder(t *testing.T) {
-	ctx := setupTest(t,
-		map[string]string{
-			"dir1": `
-			soong_namespace {
-			}
-			test_module {
-				name: "a",
-				id: "1",
-			}
-			`,
-			"dir2": `
-			soong_namespace {
-			}
-			test_module {
-				name: "a",
-				id:"2",
-			}
-			test_module {
-				name: "b",
-				id:"3",
-			}
-			`,
-			"dir3": `
-			soong_namespace {
-			}
-			test_module {
-				name: "a",
-				id:"4",
-			}
-			test_module {
-				name: "b",
-				id:"5",
-			}
-			test_module {
-				name: "c",
-				id:"6",
-			}
-			`,
-			".": `
-			test_module {
-				name: "a",
-				id: "7",
-			}
-			test_module {
-				name: "b",
-				id: "8",
-			}
-			test_module {
-				name: "c",
-				id: "9",
-			}
-			test_module {
-				name: "d",
-				id: "10",
-			}
-			`,
-			"dir4": `
-			soong_namespace {
-				imports: ["dir1", "dir2", "dir3"]
-			}
-			test_module {
-				name: "test_me",
-				id:"0",
-				deps: ["a", "b", "c", "d"],
-			}
-			`,
-		},
-	)
-
-	testMe := findModuleById(ctx, "0")
-	if !dependsOn(ctx, testMe, findModuleById(ctx, "1")) {
-		t.Errorf("test_me doesn't depend on id 1")
-	}
-	if !dependsOn(ctx, testMe, findModuleById(ctx, "3")) {
-		t.Errorf("test_me doesn't depend on id 3")
-	}
-	if !dependsOn(ctx, testMe, findModuleById(ctx, "6")) {
-		t.Errorf("test_me doesn't depend on id 6")
-	}
-	if !dependsOn(ctx, testMe, findModuleById(ctx, "10")) {
-		t.Errorf("test_me doesn't depend on id 10")
-	}
-	if numDeps(ctx, testMe) != 4 {
-		t.Errorf("num dependencies of test_me = %v, not 4\n", numDeps(ctx, testMe))
-	}
-}
-
-func TestTwoNamespacesCanImportEachOther(t *testing.T) {
-	_ = setupTest(t,
-		map[string]string{
-			"dir1": `
-			soong_namespace {
-				imports: ["dir2"]
-			}
-			test_module {
-				name: "a",
-			}
-			test_module {
-				name: "c",
-				deps: ["b"],
-			}
-			`,
-			"dir2": `
-			soong_namespace {
-				imports: ["dir1"],
-			}
-			test_module {
-				name: "b",
-				deps: ["a"],
-			}
-			`,
-		},
-	)
-
-	// setupTest will report any errors
-}
-
-func TestImportingNonexistentNamespace(t *testing.T) {
-	_, errs := setupTestExpectErrs(
-		map[string]string{
-			"dir1": `
-			soong_namespace {
-				imports: ["a_nonexistent_namespace"]
-			}
-			test_module {
-				name: "a",
-				deps: ["a_nonexistent_module"]
-			}
-			`,
-		},
-	)
-
-	// should complain about the missing namespace and not complain about the unresolvable dependency
-	expectedErrors := []error{
-		errors.New(`dir1/Blueprints:2:4: module "soong_namespace": namespace a_nonexistent_namespace does not exist`),
-	}
-	if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
-		t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
-	}
-}
-
-func TestNamespacesDontInheritParentNamespaces(t *testing.T) {
-	_, errs := setupTestExpectErrs(
-		map[string]string{
-			"dir1": `
-			soong_namespace {
-			}
-			test_module {
-				name: "a",
-			}
-			`,
-			"dir1/subdir1": `
-			soong_namespace {
-			}
-			test_module {
-				name: "b",
-				deps: ["a"],
-			}
-			`,
-		},
-	)
-
-	expectedErrors := []error{
-		errors.New(`dir1/subdir1/Blueprints:4:4: "b" depends on undefined module "a"
-Module "b" is defined in namespace "dir1/subdir1" which can read these 2 namespaces: ["dir1/subdir1" "."]
-Module "a" can be found in these namespaces: ["dir1"]`),
-	}
-	if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
-		t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
-	}
-}
-
-func TestModulesDoReceiveParentNamespace(t *testing.T) {
-	_ = setupTest(t,
-		map[string]string{
-			"dir1": `
-			soong_namespace {
-			}
-			test_module {
-				name: "a",
-			}
-			`,
-			"dir1/subdir": `
-			test_module {
-				name: "b",
-				deps: ["a"],
-			}
-			`,
-		},
-	)
-
-	// setupTest will report any errors
-}
-
-func TestNamespaceImportsNotTransitive(t *testing.T) {
-	_, errs := setupTestExpectErrs(
-		map[string]string{
-			"dir1": `
-			soong_namespace {
-			}
-			test_module {
-				name: "a",
-			}
-			`,
-			"dir2": `
-			soong_namespace {
-				imports: ["dir1"],
-			}
-			test_module {
-				name: "b",
-				deps: ["a"],
-			}
-			`,
-			"dir3": `
-			soong_namespace {
-				imports: ["dir2"],
-			}
-			test_module {
-				name: "c",
-				deps: ["a"],
-			}
-			`,
-		},
-	)
-
-	expectedErrors := []error{
-		errors.New(`dir3/Blueprints:5:4: "c" depends on undefined module "a"
-Module "c" is defined in namespace "dir3" which can read these 3 namespaces: ["dir3" "dir2" "."]
-Module "a" can be found in these namespaces: ["dir1"]`),
-	}
-	if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
-		t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
-	}
-}
-
-func TestTwoNamepacesInSameDir(t *testing.T) {
-	_, errs := setupTestExpectErrs(
-		map[string]string{
-			"dir1": `
-			soong_namespace {
-			}
-			soong_namespace {
-			}
-			`,
-		},
-	)
-
-	expectedErrors := []error{
-		errors.New(`dir1/Blueprints:4:4: namespace dir1 already exists`),
-	}
-	if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
-		t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
-	}
-}
-
-func TestNamespaceNotAtTopOfFile(t *testing.T) {
-	_, errs := setupTestExpectErrs(
-		map[string]string{
-			"dir1": `
-			test_module {
-				name: "a"
-			}
-			soong_namespace {
-			}
-			`,
-		},
-	)
-
-	expectedErrors := []error{
-		errors.New(`dir1/Blueprints:5:4: a namespace must be the first module in the file`),
-	}
-	if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
-		t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
-	}
-}
-
-func TestTwoModulesWithSameNameInSameNamespace(t *testing.T) {
-	_, errs := setupTestExpectErrs(
-		map[string]string{
-			"dir1": `
-			soong_namespace {
-			}
-			test_module {
-				name: "a"
-			}
-			test_module {
-				name: "a"
-			}
-			`,
-		},
-	)
-
-	expectedErrors := []error{
-		errors.New(`dir1/Blueprints:7:4: module "a" already defined
-       dir1/Blueprints:4:4 <-- previous definition here`),
-	}
-	if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
-		t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
-	}
-}
-
-// some utils to support the tests
-
-func mockFiles(bps map[string]string) (files map[string][]byte) {
-	files = make(map[string][]byte, len(bps))
-	files["Blueprints"] = []byte("")
-	for dir, text := range bps {
-		files[filepath.Join(dir, "Blueprints")] = []byte(text)
-	}
-	return files
-}
-
-func setupTestExpectErrs(bps map[string]string) (ctx *TestContext, errs []error) {
-	buildDir, err := ioutil.TempDir("", "soong_namespace_test")
-	if err != nil {
-		return nil, []error{err}
-	}
-	defer os.RemoveAll(buildDir)
-
-	config := TestConfig(buildDir, nil)
-
-	ctx = NewTestContext()
-	ctx.MockFileSystem(mockFiles(bps))
-	ctx.RegisterModuleType("test_module", ModuleFactoryAdaptor(newTestModule))
-	ctx.RegisterModuleType("soong_namespace", ModuleFactoryAdaptor(NamespaceFactory))
-	ctx.PreDepsMutators(RegisterNamespaceMutator)
-	ctx.Register()
-
-	_, errs = ctx.ParseBlueprintsFiles("Blueprints")
-	if len(errs) > 0 {
-		return ctx, errs
-	}
-	_, errs = ctx.PrepareBuildActions(config)
-	return ctx, errs
-}
-
-func setupTest(t *testing.T, bps map[string]string) (ctx *TestContext) {
-	ctx, errs := setupTestExpectErrs(bps)
-	failIfErrored(t, errs)
-	return ctx
-}
-
-func dependsOn(ctx *TestContext, module TestingModule, possibleDependency TestingModule) bool {
-	depends := false
-	visit := func(dependency blueprint.Module) {
-		if dependency == possibleDependency.module {
-			depends = true
-		}
-	}
-	ctx.VisitDirectDeps(module.module, visit)
-	return depends
-}
-
-func numDeps(ctx *TestContext, module TestingModule) int {
-	count := 0
-	visit := func(dependency blueprint.Module) {
-		count++
-	}
-	ctx.VisitDirectDeps(module.module, visit)
-	return count
-}
-
-func getModule(ctx *TestContext, moduleName string) TestingModule {
-	return ctx.ModuleForTests(moduleName, "")
-}
-
-func findModuleById(ctx *TestContext, id string) (module TestingModule) {
-	visit := func(candidate blueprint.Module) {
-		testModule, ok := candidate.(*testModule)
-		if ok {
-			if testModule.properties.Id == id {
-				module = TestingModule{testModule}
-			}
-		}
-	}
-	ctx.VisitAllModules(visit)
-	return module
-}
-
-type testModule struct {
-	ModuleBase
-	properties struct {
-		Deps []string
-		Id   string
-	}
-}
-
-func (m *testModule) DepsMutator(ctx BottomUpMutatorContext) {
-	for _, d := range m.properties.Deps {
-		ctx.AddDependency(ctx.Module(), nil, d)
-	}
-}
-
-func (m *testModule) GenerateAndroidBuildActions(ModuleContext) {
-}
-
-func newTestModule() Module {
-	m := &testModule{}
-	m.AddProperties(&m.properties)
-	InitAndroidModule(m)
-	return m
-}
-
-func failIfErrored(t *testing.T, errs []error) {
-	if len(errs) > 0 {
-		for _, err := range errs {
-			t.Error(err)
-		}
-		t.FailNow()
-	}
-}
diff --git a/android/testing.go b/android/testing.go
index 60189d3..03572b3 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -23,16 +23,9 @@
 )
 
 func NewTestContext() *TestContext {
-	ctx := &TestContext{
+	return &TestContext{
 		Context: blueprint.NewContext(),
 	}
-
-	namespaceExportFilter := func(namespace *Namespace) bool {
-		return true
-	}
-	ctx.SetNameInterface(NewNameResolver(namespaceExportFilter))
-
-	return ctx
 }
 
 func NewTestArchContext() *TestContext {
diff --git a/android/variable.go b/android/variable.go
index dc24c1b..13b5abf 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -190,8 +190,6 @@
 
 	DeviceKernelHeaders []string `json:",omitempty"`
 	DistDir             *string  `json:",omitempty"`
-
-	NamespacesToExport []string `json:",omitempty"`
 }
 
 func boolPtr(v bool) *bool {
