diff --git a/android/androidmk.go b/android/androidmk.go
index d88ba8f..12aa5fa 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -157,6 +157,12 @@
 		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 c728487..e6766a3 100644
--- a/android/module.go
+++ b/android/module.go
@@ -151,6 +151,7 @@
 	VisitAllModuleVariants(visit func(Module))
 
 	GetMissingDependencies() []string
+	Namespace() blueprint.Namespace
 }
 
 type Module interface {
@@ -235,6 +236,8 @@
 	ArchSpecific          bool                  `blueprint:"mutated"`
 
 	SkipInstall bool `blueprint:"mutated"`
+
+	NamespaceExportedToMake bool `blueprint:"mutated"`
 }
 
 type hostAndDeviceProperties struct {
@@ -500,8 +503,13 @@
 
 	var deps Paths
 
+	namespacePrefix := ctx.Namespace().(*Namespace).id
+	if namespacePrefix != "" {
+		namespacePrefix = namespacePrefix + "-"
+	}
+
 	if len(allInstalledFiles) > 0 {
-		name := PathForPhony(ctx, ctx.ModuleName()+"-install")
+		name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install")
 		ctx.Build(pctx, BuildParams{
 			Rule:      blueprint.Phony,
 			Output:    name,
@@ -513,7 +521,7 @@
 	}
 
 	if len(allCheckbuildFiles) > 0 {
-		name := PathForPhony(ctx, ctx.ModuleName()+"-checkbuild")
+		name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild")
 		ctx.Build(pctx, BuildParams{
 			Rule:      blueprint.Phony,
 			Output:    name,
@@ -529,9 +537,10 @@
 			suffix = "-soong"
 		}
 
+		name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix)
 		ctx.Build(pctx, BuildParams{
 			Rule:      blueprint.Phony,
-			Output:    PathForPhony(ctx, ctx.ModuleName()+suffix),
+			Outputs:   []WritablePath{name},
 			Implicits: deps,
 		})
 
diff --git a/android/mutator.go b/android/mutator.go
index db3eaa3..876d161 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -86,6 +86,7 @@
 }
 
 var preDeps = []RegisterMutatorFunc{
+	RegisterNamespaceMutator,
 	registerArchMutator,
 }
 
diff --git a/android/namespace.go b/android/namespace.go
new file mode 100644
index 0000000..a2ff1a6
--- /dev/null
+++ b/android/namespace.go
@@ -0,0 +1,398 @@
+// 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
+
+	// 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
new file mode 100644
index 0000000..b10b528
--- /dev/null
+++ b/android/namespace_test.go
@@ -0,0 +1,652 @@
+// 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 fc58cec..4f2a2da 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -23,9 +23,16 @@
 )
 
 func NewTestContext() *TestContext {
-	return &TestContext{
+	ctx := &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 a3920a1..ab8103a 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -194,6 +194,8 @@
 	DistDir             *string  `json:",omitempty"`
 
 	ExtraVndkVersions []string `json:",omitempty"`
+
+	NamespacesToExport []string `json:",omitempty"`
 }
 
 func boolPtr(v bool) *bool {
