diff --git a/common/androidmk.go b/common/androidmk.go
index 5dd422d..06aa30c 100644
--- a/common/androidmk.go
+++ b/common/androidmk.go
@@ -37,11 +37,11 @@
 
 type AndroidMkData struct {
 	Class      string
-	OutputFile string
+	OutputFile OptionalPath
 
 	Custom func(w io.Writer, name, prefix string)
 
-	Extra func(name, prefix, outputFile string, arch Arch) []string
+	Extra func(name, prefix string, outputFile Path, arch Arch) []string
 }
 
 func AndroidMkSingleton() blueprint.Singleton {
@@ -55,7 +55,7 @@
 	hasBPDir := make(map[string]bool)
 	bpDirs := []string{}
 
-	ctx.SetNinjaBuildDir(pctx, filepath.Join(ctx.Config().(Config).BuildDir(), ".."))
+	ctx.SetNinjaBuildDir(pctx, filepath.Join(ctx.Config().(Config).buildDir, ".."))
 
 	ctx.VisitAllModules(func(module blueprint.Module) {
 		if _, ok := module.(AndroidModule); ok {
@@ -72,28 +72,13 @@
 
 	// Gather list of eligible Android modules for translation
 	androidMkModules := make(map[blueprint.Module]bool)
-	srcDir := ctx.Config().(Config).SrcDir()
-	intermediatesDir := filepath.Join(ctx.Config().(Config).IntermediatesDir(), "androidmk")
 	sort.Strings(bpDirs)
 	for _, bpDir := range bpDirs {
-		mkFile := filepath.Join(srcDir, bpDir, "Android.mk")
-
-		files, err := Glob(ctx, intermediatesDir, mkFile, nil)
-		if err != nil {
-			ctx.Errorf("glob: %s", err.Error())
-			continue
-		}
-
-		// Existing Android.mk file, use that instead
-		if len(files) > 0 {
-			for _, file := range files {
-				ctx.AddNinjaFileDeps(file)
+		mkFile := OptionalPathForSource(ctx, "androidmk", bpDir, "Android.mk")
+		if !mkFile.Valid() {
+			for _, mod := range dirModules[bpDir] {
+				androidMkModules[mod] = true
 			}
-			continue
-		}
-
-		for _, mod := range dirModules[bpDir] {
-			androidMkModules[mod] = true
 		}
 	}
 
@@ -110,16 +95,19 @@
 		}
 	}
 
-	transMk := filepath.Join(ctx.Config().(Config).BuildDir(), "Android.mk")
+	transMk := PathForOutput(ctx, "Android.mk")
+	if ctx.Failed() {
+		return
+	}
 
-	err := translateAndroidMk(ctx, transMk, androidMkModulesList)
+	err := translateAndroidMk(ctx, transMk.String(), androidMkModulesList)
 	if err != nil {
 		ctx.Errorf(err.Error())
 	}
 
 	ctx.Build(pctx, blueprint.BuildParams{
 		Rule:     blueprint.Phony,
-		Outputs:  []string{transMk},
+		Outputs:  []string{transMk.String()},
 		Optional: true,
 	})
 }
@@ -177,7 +165,7 @@
 
 	type archSrc struct {
 		arch  Arch
-		src   string
+		src   Path
 		extra []string
 	}
 
@@ -211,6 +199,10 @@
 			return
 		}
 
+		if !data.OutputFile.Valid() {
+			return
+		}
+
 		hC := hostClass{
 			host:     amod.HostOrDevice() == Host,
 			class:    data.Class,
@@ -219,7 +211,7 @@
 
 		src := archSrc{
 			arch: arch,
-			src:  data.OutputFile,
+			src:  data.OutputFile.Path(),
 		}
 
 		if data.Extra != nil {
@@ -242,7 +234,7 @@
 
 		printed := make(map[string]bool)
 		for _, src := range archSrcs {
-			io.WriteString(w, "LOCAL_SRC_FILES_"+src.arch.ArchType.String()+" := "+src.src+"\n")
+			io.WriteString(w, "LOCAL_SRC_FILES_"+src.arch.ArchType.String()+" := "+src.src.String()+"\n")
 
 			for _, extra := range src.extra {
 				if !printed[extra] {
diff --git a/common/config.go b/common/config.go
index c67023e..7f6ee65 100644
--- a/common/config.go
+++ b/common/config.go
@@ -20,6 +20,7 @@
 	"os"
 	"path/filepath"
 	"runtime"
+	"strings"
 	"sync"
 )
 
@@ -38,8 +39,6 @@
 
 type Config struct {
 	*config
-
-	dontCreateNinjaFile bool
 }
 
 // A config object represents the entire build configuration for Android.
@@ -142,8 +141,24 @@
 		},
 	}
 
+	// Sanity check the build and source directories. This won't catch strange
+	// configurations with symlinks, but at least checks the obvious cases.
+	absBuildDir, err := filepath.Abs(buildDir)
+	if err != nil {
+		return Config{}, err
+	}
+
+	absSrcDir, err := filepath.Abs(srcDir)
+	if err != nil {
+		return Config{}, err
+	}
+
+	if strings.HasPrefix(absSrcDir, absBuildDir) {
+		return Config{}, fmt.Errorf("Build dir must not contain source directory")
+	}
+
 	// Load any configurable options from the configuration file
-	err := loadConfig(config.config)
+	err = loadConfig(config.config)
 	if err != nil {
 		return Config{}, err
 	}
@@ -159,18 +174,6 @@
 	return config, nil
 }
 
-func (c *config) SrcDir() string {
-	return c.srcDir
-}
-
-func (c *config) BuildDir() string {
-	return c.buildDir
-}
-
-func (c *config) IntermediatesDir() string {
-	return filepath.Join(c.BuildDir(), ".intermediates")
-}
-
 func (c *config) RemoveAbandonedFiles() bool {
 	return false
 }
@@ -238,37 +241,7 @@
 	return false
 }
 
-// DeviceOut returns the path to out directory for device targets
-func (c *config) DeviceOut() string {
-	return filepath.Join(c.BuildDir(), "target/product", c.DeviceName())
-}
-
-// HostOut returns the path to out directory for host targets
-func (c *config) HostOut() string {
-	return filepath.Join(c.BuildDir(), "host", c.PrebuiltOS())
-}
-
-// HostBin returns the path to bin directory for host targets
-func (c *config) HostBin() string {
-	return filepath.Join(c.HostOut(), "bin")
-}
-
-// HostBinTool returns the path to a host tool in the bin directory for host targets
-func (c *config) HostBinTool(tool string) (string, error) {
-	return filepath.Join(c.HostBin(), tool), nil
-}
-
-// HostJavaDir returns the path to framework directory for host targets
-func (c *config) HostJavaDir() string {
-	return filepath.Join(c.HostOut(), "framework")
-}
-
-// HostJavaTool returns the path to a host tool in the frameworks directory for host targets
-func (c *config) HostJavaTool(tool string) (string, error) {
-	return filepath.Join(c.HostJavaDir(), tool), nil
-}
-
-func (c *config) ResourceOverlays() []string {
+func (c *config) ResourceOverlays() []SourcePath {
 	return nil
 }
 
@@ -296,10 +269,10 @@
 	return "nosdcard"
 }
 
-func (c *config) DefaultAppCertificateDir() string {
-	return filepath.Join(c.SrcDir(), "build/target/product/security")
+func (c *config) DefaultAppCertificateDir(ctx PathContext) SourcePath {
+	return PathForSource(ctx, "build/target/product/security")
 }
 
-func (c *config) DefaultAppCertificate() string {
-	return filepath.Join(c.DefaultAppCertificateDir(), "testkey")
+func (c *config) DefaultAppCertificate(ctx PathContext) SourcePath {
+	return c.DefaultAppCertificateDir(ctx).Join(ctx, "testkey")
 }
diff --git a/common/defs.go b/common/defs.go
index 7b2a706..9e185e4 100644
--- a/common/defs.go
+++ b/common/defs.go
@@ -20,13 +20,11 @@
 )
 
 var (
-	pctx = blueprint.NewPackageContext("android/soong/common")
+	pctx = NewPackageContext("android/soong/common")
 
 	cpPreserveSymlinks = pctx.VariableConfigMethod("cpPreserveSymlinks",
 		Config.CpPreserveSymlinksFlags)
 
-	srcDir = pctx.VariableConfigMethod("srcDir", Config.SrcDir)
-
 	// A phony rule that is not the built-in Ninja phony rule.  The built-in
 	// phony rule has special behavior that is sometimes not desired.  See the
 	// Ninja docs for more details.
diff --git a/common/env.go b/common/env.go
index 8694c28..478fffc 100644
--- a/common/env.go
+++ b/common/env.go
@@ -15,8 +15,6 @@
 package common
 
 import (
-	"path/filepath"
-
 	"android/soong"
 	"android/soong/env"
 
@@ -43,12 +41,15 @@
 func (c *envSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
 	envDeps := ctx.Config().(Config).EnvDeps()
 
-	envFile := filepath.Join(ctx.Config().(Config).BuildDir(), ".soong.environment")
+	envFile := PathForOutput(ctx, ".soong.environment")
+	if ctx.Failed() {
+		return
+	}
 
-	err := env.WriteEnvFile(envFile, envDeps)
+	err := env.WriteEnvFile(envFile.String(), envDeps)
 	if err != nil {
 		ctx.Errorf(err.Error())
 	}
 
-	ctx.AddNinjaFileDeps(envFile)
+	ctx.AddNinjaFileDeps(envFile.String())
 }
diff --git a/common/module.go b/common/module.go
index 113768a..36710c5 100644
--- a/common/module.go
+++ b/common/module.go
@@ -32,6 +32,19 @@
 	HostExecutable      = "host_executable"
 )
 
+type ModuleBuildParams struct {
+	Rule      blueprint.Rule
+	Output    WritablePath
+	Outputs   WritablePaths
+	Input     Path
+	Inputs    Paths
+	Implicit  Path
+	Implicits Paths
+	OrderOnly Paths
+	Default   bool
+	Args      map[string]string
+}
+
 type androidBaseContext interface {
 	Arch() Arch
 	HostOrDevice() HostOrDevice
@@ -52,12 +65,16 @@
 	blueprint.ModuleContext
 	androidBaseContext
 
-	ExpandSources(srcFiles, excludes []string) []string
-	Glob(outDir, globPattern string, excludes []string) []string
+	// Similar to Build, but takes Paths instead of []string,
+	// and performs more verification.
+	ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams)
 
-	InstallFile(installPath, srcPath string, deps ...string) string
-	InstallFileName(installPath, name, srcPath string, deps ...string) string
-	CheckbuildFile(srcPath string)
+	ExpandSources(srcFiles, excludes []string) Paths
+	Glob(outDir, globPattern string, excludes []string) Paths
+
+	InstallFile(installPath string, srcPath Path, deps ...Path) Path
+	InstallFileName(installPath, name string, srcPath Path, deps ...Path) Path
+	CheckbuildFile(srcPath Path)
 }
 
 type AndroidModule interface {
@@ -196,8 +213,8 @@
 	archProperties          []*archProperties
 
 	noAddressSanitizer bool
-	installFiles       []string
-	checkbuildFiles    []string
+	installFiles       Paths
+	checkbuildFiles    Paths
 
 	// Used by buildTargetSingleton to create checkbuild and per-directory build targets
 	// Only set on the final variant of each module
@@ -254,9 +271,9 @@
 }
 
 func (a *AndroidModuleBase) computeInstallDeps(
-	ctx blueprint.ModuleContext) []string {
+	ctx blueprint.ModuleContext) Paths {
 
-	result := []string{}
+	result := Paths{}
 	ctx.VisitDepsDepthFirstIf(isFileInstaller,
 		func(m blueprint.Module) {
 			fileInstaller := m.(fileInstaller)
@@ -267,7 +284,7 @@
 	return result
 }
 
-func (a *AndroidModuleBase) filesToInstall() []string {
+func (a *AndroidModuleBase) filesToInstall() Paths {
 	return a.installFiles
 }
 
@@ -280,8 +297,8 @@
 		return
 	}
 
-	allInstalledFiles := []string{}
-	allCheckbuildFiles := []string{}
+	allInstalledFiles := Paths{}
+	allCheckbuildFiles := Paths{}
 	ctx.VisitAllModuleVariants(func(module blueprint.Module) {
 		a := module.(AndroidModule).base()
 		allInstalledFiles = append(allInstalledFiles, a.installFiles...)
@@ -295,7 +312,7 @@
 		ctx.Build(pctx, blueprint.BuildParams{
 			Rule:      blueprint.Phony,
 			Outputs:   []string{name},
-			Implicits: allInstalledFiles,
+			Implicits: allInstalledFiles.Strings(),
 		})
 		deps = append(deps, name)
 		a.installTarget = name
@@ -306,7 +323,7 @@
 		ctx.Build(pctx, blueprint.BuildParams{
 			Rule:      blueprint.Phony,
 			Outputs:   []string{name},
-			Implicits: allCheckbuildFiles,
+			Implicits: allCheckbuildFiles.Strings(),
 			Optional:  true,
 		})
 		deps = append(deps, name)
@@ -371,9 +388,9 @@
 type androidModuleContext struct {
 	blueprint.ModuleContext
 	androidBaseContextImpl
-	installDeps     []string
-	installFiles    []string
-	checkbuildFiles []string
+	installDeps     Paths
+	installFiles    Paths
+	checkbuildFiles Paths
 }
 
 func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
@@ -381,6 +398,30 @@
 	a.ModuleContext.Build(pctx, params)
 }
 
+func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
+	bparams := blueprint.BuildParams{
+		Rule:      params.Rule,
+		Outputs:   params.Outputs.Strings(),
+		Inputs:    params.Inputs.Strings(),
+		Implicits: params.Implicits.Strings(),
+		OrderOnly: params.OrderOnly.Strings(),
+		Args:      params.Args,
+		Optional:  !params.Default,
+	}
+
+	if params.Output != nil {
+		bparams.Outputs = append(bparams.Outputs, params.Output.String())
+	}
+	if params.Input != nil {
+		bparams.Inputs = append(bparams.Inputs, params.Input.String())
+	}
+	if params.Implicit != nil {
+		bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
+	}
+
+	a.ModuleContext.Build(pctx, bparams)
+}
+
 func (a *androidBaseContextImpl) Arch() Arch {
 	return a.arch
 }
@@ -413,31 +454,19 @@
 	return a.config
 }
 
-func (a *androidModuleContext) InstallFileName(installPath, name, srcPath string,
-	deps ...string) string {
+func (a *androidModuleContext) InstallFileName(installPath, name string, srcPath Path,
+	deps ...Path) Path {
 
-	config := a.AConfig()
-	var fullInstallPath string
-	if a.hod.Device() {
-		// TODO: replace unset with a device name once we have device targeting
-		fullInstallPath = filepath.Join(config.DeviceOut(), "system",
-			installPath, name)
-	} else {
-		// TODO
-		if a.ht == Windows {
-			fullInstallPath = filepath.Join(config.BuildDir(), "host", "windows-x86", installPath, name)
-		} else {
-			fullInstallPath = filepath.Join(config.HostOut(), installPath, name)
-		}
-	}
+	fullInstallPath := PathForModuleInstall(a, installPath, name)
 
 	deps = append(deps, a.installDeps...)
 
-	a.ModuleContext.Build(pctx, blueprint.BuildParams{
+	a.ModuleBuild(pctx, ModuleBuildParams{
 		Rule:      Cp,
-		Outputs:   []string{fullInstallPath},
-		Inputs:    []string{srcPath},
-		OrderOnly: deps,
+		Output:    fullInstallPath,
+		Input:     srcPath,
+		OrderOnly: Paths(deps),
+		Default:   true,
 	})
 
 	a.installFiles = append(a.installFiles, fullInstallPath)
@@ -445,16 +474,16 @@
 	return fullInstallPath
 }
 
-func (a *androidModuleContext) InstallFile(installPath, srcPath string, deps ...string) string {
-	return a.InstallFileName(installPath, filepath.Base(srcPath), srcPath, deps...)
+func (a *androidModuleContext) InstallFile(installPath string, srcPath Path, deps ...Path) Path {
+	return a.InstallFileName(installPath, filepath.Base(srcPath.String()), srcPath, deps...)
 }
 
-func (a *androidModuleContext) CheckbuildFile(srcPath string) {
+func (a *androidModuleContext) CheckbuildFile(srcPath Path) {
 	a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
 }
 
 type fileInstaller interface {
-	filesToInstall() []string
+	filesToInstall() Paths
 }
 
 func isFileInstaller(m blueprint.Module) bool {
@@ -476,8 +505,8 @@
 	return -1
 }
 
-func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) []string {
-	prefix := ModuleSrcDir(ctx)
+func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
+	prefix := PathForModuleSrc(ctx).String()
 	for i, e := range excludes {
 		j := findStringInSlice(e, srcFiles)
 		if j != -1 {
@@ -487,32 +516,24 @@
 		excludes[i] = filepath.Join(prefix, e)
 	}
 
-	for i, srcFile := range srcFiles {
-		srcFiles[i] = filepath.Join(prefix, srcFile)
-	}
-
-	if !hasGlob(srcFiles) {
-		return srcFiles
-	}
-
-	globbedSrcFiles := make([]string, 0, len(srcFiles))
+	globbedSrcFiles := make(Paths, 0, len(srcFiles))
 	for _, s := range srcFiles {
 		if glob.IsGlob(s) {
-			globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", s, excludes)...)
+			globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", filepath.Join(prefix, s), excludes)...)
 		} else {
-			globbedSrcFiles = append(globbedSrcFiles, s)
+			globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s))
 		}
 	}
 
 	return globbedSrcFiles
 }
 
-func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) []string {
-	ret, err := Glob(ctx, filepath.Join(ModuleOutDir(ctx), outDir), globPattern, excludes)
+func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) Paths {
+	ret, err := Glob(ctx, PathForModuleOut(ctx, outDir).String(), globPattern, excludes)
 	if err != nil {
 		ctx.ModuleErrorf("glob: %s", err.Error())
 	}
-	return ret
+	return pathsForModuleSrcFromFullPath(ctx, ret)
 }
 
 func init() {
diff --git a/common/package_ctx.go b/common/package_ctx.go
new file mode 100644
index 0000000..cd18b65
--- /dev/null
+++ b/common/package_ctx.go
@@ -0,0 +1,127 @@
+// Copyright 2015 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 common
+
+import (
+	"fmt"
+
+	"github.com/google/blueprint"
+)
+
+// AndroidPackageContext is a wrapper for blueprint.PackageContext that adds
+// some android-specific helper functions.
+type AndroidPackageContext struct {
+	blueprint.PackageContext
+}
+
+func NewPackageContext(pkgPath string) AndroidPackageContext {
+	return AndroidPackageContext{blueprint.NewPackageContext(pkgPath)}
+}
+
+// configErrorWrapper can be used with Path functions when a Context is not
+// available. A Config can be provided, and errors are stored as a list for
+// later retrieval.
+//
+// The most common use here will be with VariableFunc, where only a config is
+// provided, and an error should be returned.
+type configErrorWrapper struct {
+	config Config
+	errors []error
+}
+
+var _ PathContext = &configErrorWrapper{}
+var _ errorfContext = &configErrorWrapper{}
+
+func (e *configErrorWrapper) Config() interface{} {
+	return e.config
+}
+func (e *configErrorWrapper) Errorf(format string, args ...interface{}) {
+	e.errors = append(e.errors, fmt.Errorf(format, args...))
+}
+
+// SourcePathVariable returns a Variable whose value is the source directory
+// appended with the supplied path. It may only be called during a Go package's
+// initialization - either from the init() function or as part of a
+// package-scoped variable's initialization.
+func (p AndroidPackageContext) SourcePathVariable(name, path string) blueprint.Variable {
+	return p.VariableFunc(name, func(config interface{}) (string, error) {
+		ctx := &configErrorWrapper{config.(Config), []error{}}
+		p := safePathForSource(ctx, path)
+		if len(ctx.errors) > 0 {
+			return "", ctx.errors[0]
+		}
+		return p.String(), nil
+	})
+}
+
+// HostBinVariable returns a Variable whose value is the path to a host tool
+// in the bin directory for host targets. It may only be called during a Go
+// package's initialization - either from the init() function or as part of a
+// package-scoped variable's initialization.
+func (p AndroidPackageContext) HostBinToolVariable(name, path string) blueprint.Variable {
+	return p.VariableFunc(name, func(config interface{}) (string, error) {
+		ctx := &configErrorWrapper{config.(Config), []error{}}
+		p := PathForOutput(ctx, "host", ctx.config.PrebuiltOS(), "bin", path)
+		if len(ctx.errors) > 0 {
+			return "", ctx.errors[0]
+		}
+		return p.String(), nil
+	})
+}
+
+// HostJavaToolVariable returns a Variable whose value is the path to a host
+// tool in the frameworks directory for host targets. It may only be called
+// during a Go package's initialization - either from the init() function or as
+// part of a package-scoped variable's initialization.
+func (p AndroidPackageContext) HostJavaToolVariable(name, path string) blueprint.Variable {
+	return p.VariableFunc(name, func(config interface{}) (string, error) {
+		ctx := &configErrorWrapper{config.(Config), []error{}}
+		p := PathForOutput(ctx, "host", ctx.config.PrebuiltOS(), "framework", path)
+		if len(ctx.errors) > 0 {
+			return "", ctx.errors[0]
+		}
+		return p.String(), nil
+	})
+}
+
+// IntermediatesPathVariable returns a Variable whose value is the intermediate
+// directory appended with the supplied path. It may only be called during a Go
+// package's initialization - either from the init() function or as part of a
+// package-scoped variable's initialization.
+func (p AndroidPackageContext) IntermediatesPathVariable(name, path string) blueprint.Variable {
+	return p.VariableFunc(name, func(config interface{}) (string, error) {
+		ctx := &configErrorWrapper{config.(Config), []error{}}
+		p := PathForIntermediates(ctx, path)
+		if len(ctx.errors) > 0 {
+			return "", ctx.errors[0]
+		}
+		return p.String(), nil
+	})
+}
+
+// PrefixedPathsForSourceVariable returns a Variable whose value is the
+// list of source paths prefixed with the supplied prefix. It may only be
+// called during a Go package's initialization - either from the init()
+// function or as part of a package-scoped variable's initialization.
+func (p AndroidPackageContext) PrefixedPathsForSourceVariable(name, prefix string, paths []string) blueprint.Variable {
+	return p.VariableFunc(name, func(config interface{}) (string, error) {
+		ctx := &configErrorWrapper{config.(Config), []error{}}
+		paths := PathsForSource(ctx, paths)
+		if len(ctx.errors) > 0 {
+			return "", ctx.errors[0]
+		}
+		return JoinWithPrefix(paths.Strings(), prefix), nil
+	})
+}
diff --git a/common/paths.go b/common/paths.go
index d92dcf9..8a085ea 100644
--- a/common/paths.go
+++ b/common/paths.go
@@ -18,103 +18,571 @@
 	"fmt"
 	"os"
 	"path/filepath"
+	"reflect"
+	"strings"
+
+	"github.com/google/blueprint"
+	"github.com/google/blueprint/pathtools"
 )
 
-// ModuleOutDir returns the path to the module-specific output directory.
-func ModuleOutDir(ctx AndroidModuleContext) string {
-	return filepath.Join(ctx.AConfig().IntermediatesDir(),
-		ctx.ModuleDir(), ctx.ModuleName(), ctx.ModuleSubDir())
+// PathContext is the subset of a (Module|Singleton)Context required by the
+// Path methods.
+type PathContext interface {
+	Config() interface{}
 }
 
-// ModuleSrcDir returns the path of the directory that all source file paths are
-// specified relative to.
-func ModuleSrcDir(ctx AndroidModuleContext) string {
-	return filepath.Join(ctx.AConfig().SrcDir(), ctx.ModuleDir())
+var _ PathContext = blueprint.SingletonContext(nil)
+var _ PathContext = blueprint.ModuleContext(nil)
+
+// errorfContext is the interface containing the Errorf method matching the
+// Errorf method in blueprint.SingletonContext.
+type errorfContext interface {
+	Errorf(format string, args ...interface{})
 }
 
-// ModuleBinDir returns the path to the module- and architecture-specific binary
-// output directory.
-func ModuleBinDir(ctx AndroidModuleContext) string {
-	return filepath.Join(ModuleOutDir(ctx), "bin")
+var _ errorfContext = blueprint.SingletonContext(nil)
+
+// moduleErrorf is the interface containing the ModuleErrorf method matching
+// the ModuleErrorf method in blueprint.ModuleContext.
+type moduleErrorf interface {
+	ModuleErrorf(format string, args ...interface{})
 }
 
-// ModuleLibDir returns the path to the module- and architecture-specific
-// library output directory.
-func ModuleLibDir(ctx AndroidModuleContext) string {
-	return filepath.Join(ModuleOutDir(ctx), "lib")
+var _ moduleErrorf = blueprint.ModuleContext(nil)
+
+// pathConfig returns the android Config interface associated to the context.
+// Panics if the context isn't affiliated with an android build.
+func pathConfig(ctx PathContext) Config {
+	if ret, ok := ctx.Config().(Config); ok {
+		return ret
+	}
+	panic("Paths may only be used on Soong builds")
 }
 
-// ModuleGenDir returns the module directory for generated files
-// path.
-func ModuleGenDir(ctx AndroidModuleContext) string {
-	return filepath.Join(ModuleOutDir(ctx), "gen")
-}
-
-// ModuleObjDir returns the module- and architecture-specific object directory
-// path.
-func ModuleObjDir(ctx AndroidModuleContext) string {
-	return filepath.Join(ModuleOutDir(ctx), "obj")
-}
-
-// ModuleGoPackageDir returns the module-specific package root directory path.
-// This directory is where the final package .a files are output and where
-// dependent modules search for this package via -I arguments.
-func ModuleGoPackageDir(ctx AndroidModuleContext) string {
-	return filepath.Join(ModuleOutDir(ctx), "pkg")
-}
-
-// ModuleIncludeDir returns the module-specific public include directory path.
-func ModuleIncludeDir(ctx AndroidModuleContext) string {
-	return filepath.Join(ModuleOutDir(ctx), "include")
-}
-
-// ModuleProtoDir returns the module-specific public proto include directory path.
-func ModuleProtoDir(ctx AndroidModuleContext) string {
-	return filepath.Join(ModuleOutDir(ctx), "proto")
-}
-
-func ModuleJSCompiledDir(ctx AndroidModuleContext) string {
-	return filepath.Join(ModuleOutDir(ctx), "js")
-}
-
-// CheckModuleSrcDirsExist logs an error on a property if any of the directories relative to the
-// Blueprints file don't exist.
-func CheckModuleSrcDirsExist(ctx AndroidModuleContext, dirs []string, prop string) {
-	for _, dir := range dirs {
-		fullDir := filepath.Join(ModuleSrcDir(ctx), dir)
-		if _, err := os.Stat(fullDir); err != nil {
-			if os.IsNotExist(err) {
-				ctx.PropertyErrorf(prop, "module source directory %q does not exist", dir)
-			} else {
-				ctx.PropertyErrorf(prop, "%s", err.Error())
-			}
-		}
+// reportPathError will register an error with the attached context. It
+// attempts ctx.ModuleErrorf for a better error message first, then falls
+// back to ctx.Errorf.
+func reportPathError(ctx PathContext, format string, args ...interface{}) {
+	if mctx, ok := ctx.(moduleErrorf); ok {
+		mctx.ModuleErrorf(format, args...)
+	} else if ectx, ok := ctx.(errorfContext); ok {
+		ectx.Errorf(format, args...)
+	} else {
+		panic(fmt.Sprintf(format, args...))
 	}
 }
 
-// CheckModuleSrcDirsExist logs an error on a property if any of the directories relative to the
-// top of the source tree don't exist.
-func CheckSrcDirsExist(ctx AndroidModuleContext, dirs []string, prop string) {
-	for _, dir := range dirs {
-		fullDir := filepath.Join(ctx.AConfig().SrcDir(), dir)
-		if _, err := os.Stat(fullDir); err != nil {
-			if os.IsNotExist(err) {
-				ctx.PropertyErrorf(prop, "top-level source directory %q does not exist", dir)
-			} else {
-				ctx.PropertyErrorf(prop, "%s", err.Error())
-			}
-		}
+type Path interface {
+	// Returns the path in string form
+	String() string
+
+	// Returns the current file extension of the path
+	Ext() string
+}
+
+// WritablePath is a type of path that can be used as an output for build rules.
+type WritablePath interface {
+	Path
+
+	writablePath()
+}
+
+type genPathProvider interface {
+	genPathWithExt(ctx AndroidModuleContext, ext string) ModuleGenPath
+}
+type objPathProvider interface {
+	objPathWithExt(ctx AndroidModuleContext, subdir, ext string) ModuleObjPath
+}
+type resPathProvider interface {
+	resPathWithName(ctx AndroidModuleContext, name string) ModuleResPath
+}
+
+// GenPathWithExt derives a new file path in ctx's generated sources directory
+// from the current path, but with the new extension.
+func GenPathWithExt(ctx AndroidModuleContext, p Path, ext string) ModuleGenPath {
+	if path, ok := p.(genPathProvider); ok {
+		return path.genPathWithExt(ctx, ext)
+	}
+	reportPathError(ctx, "Tried to create generated file from unsupported path: %s(%s)", reflect.TypeOf(p).Name(), p)
+	return PathForModuleGen(ctx)
+}
+
+// ObjPathWithExt derives a new file path in ctx's object directory from the
+// current path, but with the new extension.
+func ObjPathWithExt(ctx AndroidModuleContext, p Path, subdir, ext string) ModuleObjPath {
+	if path, ok := p.(objPathProvider); ok {
+		return path.objPathWithExt(ctx, subdir, ext)
+	}
+	reportPathError(ctx, "Tried to create object file from unsupported path: %s (%s)", reflect.TypeOf(p).Name(), p)
+	return PathForModuleObj(ctx)
+}
+
+// ResPathWithName derives a new path in ctx's output resource directory, using
+// the current path to create the directory name, and the `name` argument for
+// the filename.
+func ResPathWithName(ctx AndroidModuleContext, p Path, name string) ModuleResPath {
+	if path, ok := p.(resPathProvider); ok {
+		return path.resPathWithName(ctx, name)
+	}
+	reportPathError(ctx, "Tried to create object file from unsupported path: %s (%s)", reflect.TypeOf(p).Name(), p)
+	return PathForModuleRes(ctx)
+}
+
+// OptionalPath is a container that may or may not contain a valid Path.
+type OptionalPath struct {
+	valid bool
+	path  Path
+}
+
+// OptionalPathForPath returns an OptionalPath containing the path.
+func OptionalPathForPath(path Path) OptionalPath {
+	if path == nil {
+		return OptionalPath{}
+	}
+	return OptionalPath{valid: true, path: path}
+}
+
+// Valid returns whether there is a valid path
+func (p OptionalPath) Valid() bool {
+	return p.valid
+}
+
+// Path returns the Path embedded in this OptionalPath. You must be sure that
+// there is a valid path, since this method will panic if there is not.
+func (p OptionalPath) Path() Path {
+	if !p.valid {
+		panic("Requesting an invalid path")
+	}
+	return p.path
+}
+
+// String returns the string version of the Path, or "" if it isn't valid.
+func (p OptionalPath) String() string {
+	if p.valid {
+		return p.path.String()
+	} else {
+		return ""
 	}
 }
 
-// Returns a path relative to the top level source directory.  Panics if path is not inside the
-// top level source directory.
-func SrcDirRelPath(ctx AndroidModuleContext, path string) string {
-	srcDir := ctx.AConfig().SrcDir()
-	relPath, err := filepath.Rel(srcDir, path)
+// Paths is a slice of Path objects, with helpers to operate on the collection.
+type Paths []Path
+
+// PathsForSource returns Paths rooted from SrcDir
+func PathsForSource(ctx PathContext, paths []string) Paths {
+	ret := make(Paths, len(paths))
+	for i, path := range paths {
+		ret[i] = PathForSource(ctx, path)
+	}
+	return ret
+}
+
+// PathsForModuleSrc returns Paths rooted from the module's local source
+// directory
+func PathsForModuleSrc(ctx AndroidModuleContext, paths []string) Paths {
+	ret := make(Paths, len(paths))
+	for i, path := range paths {
+		ret[i] = PathForModuleSrc(ctx, path)
+	}
+	return ret
+}
+
+// pathsForModuleSrcFromFullPath returns Paths rooted from the module's local
+// source directory, but strip the local source directory from the beginning of
+// each string.
+func pathsForModuleSrcFromFullPath(ctx AndroidModuleContext, paths []string) Paths {
+	prefix := filepath.Join(ctx.AConfig().srcDir, ctx.ModuleDir()) + "/"
+	ret := make(Paths, 0, len(paths))
+	for _, p := range paths {
+		path := filepath.Clean(p)
+		if !strings.HasPrefix(path, prefix) {
+			reportPathError(ctx, "Path '%s' is not in module source directory '%s'", p, prefix)
+			continue
+		}
+		ret = append(ret, PathForModuleSrc(ctx, path[len(prefix):]))
+	}
+	return ret
+}
+
+// PathsWithOptionalDefaultForModuleSrc returns Paths rooted from the module's
+// local source directory. If none are provided, use the default if it exists.
+func PathsWithOptionalDefaultForModuleSrc(ctx AndroidModuleContext, input []string, def string) Paths {
+	if len(input) > 0 {
+		return PathsForModuleSrc(ctx, input)
+	}
+	// Use Glob so that if the default doesn't exist, a dependency is added so that when it
+	// is created, we're run again.
+	path := filepath.Join(ctx.AConfig().srcDir, ctx.ModuleDir(), def)
+	return ctx.Glob("default", path, []string{})
+}
+
+// Strings returns the Paths in string form
+func (p Paths) Strings() []string {
+	if p == nil {
+		return nil
+	}
+	ret := make([]string, len(p))
+	for i, path := range p {
+		ret[i] = path.String()
+	}
+	return ret
+}
+
+// WritablePaths is a slice of WritablePaths, used for multiple outputs.
+type WritablePaths []WritablePath
+
+// Strings returns the string forms of the writable paths.
+func (p WritablePaths) Strings() []string {
+	if p == nil {
+		return nil
+	}
+	ret := make([]string, len(p))
+	for i, path := range p {
+		ret[i] = path.String()
+	}
+	return ret
+}
+
+type basePath struct {
+	path   string
+	config Config
+}
+
+func (p basePath) Ext() string {
+	return filepath.Ext(p.path)
+}
+
+// SourcePath is a Path representing a file path rooted from SrcDir
+type SourcePath struct {
+	basePath
+}
+
+var _ Path = SourcePath{}
+
+// safePathForSource is for paths that we expect are safe -- only for use by go
+// code that is embedding ninja variables in paths
+func safePathForSource(ctx PathContext, path string) SourcePath {
+	p := validateSafePath(ctx, path)
+	ret := SourcePath{basePath{p, pathConfig(ctx)}}
+
+	abs, err := filepath.Abs(ret.String())
 	if err != nil {
-		panic(fmt.Errorf("%q is not inside %q: %s", path, srcDir, err.Error()))
+		reportPathError(ctx, "%s", err.Error())
+		return ret
+	}
+	buildroot, err := filepath.Abs(pathConfig(ctx).buildDir)
+	if err != nil {
+		reportPathError(ctx, "%s", err.Error())
+		return ret
+	}
+	if strings.HasPrefix(abs, buildroot) {
+		reportPathError(ctx, "source path %s is in output", abs)
+		return ret
 	}
 
-	return relPath
+	return ret
+}
+
+// PathForSource returns a SourcePath for the provided paths... (which are
+// joined together with filepath.Join). This also validates that the path
+// doesn't escape the source dir, or is contained in the build dir. On error, it
+// will return a usable, but invalid SourcePath, and report a ModuleError.
+func PathForSource(ctx PathContext, paths ...string) SourcePath {
+	p := validatePath(ctx, paths...)
+	ret := SourcePath{basePath{p, pathConfig(ctx)}}
+
+	abs, err := filepath.Abs(ret.String())
+	if err != nil {
+		reportPathError(ctx, "%s", err.Error())
+		return ret
+	}
+	buildroot, err := filepath.Abs(pathConfig(ctx).buildDir)
+	if err != nil {
+		reportPathError(ctx, "%s", err.Error())
+		return ret
+	}
+	if strings.HasPrefix(abs, buildroot) {
+		reportPathError(ctx, "source path %s is in output", abs)
+		return ret
+	}
+
+	if _, err = os.Stat(ret.String()); err != nil {
+		if os.IsNotExist(err) {
+			reportPathError(ctx, "source path %s does not exist", ret)
+		} else {
+			reportPathError(ctx, "%s: %s", ret, err.Error())
+		}
+	}
+	return ret
+}
+
+// OptionalPathForSource returns an OptionalPath with the SourcePath if the
+// path exists, or an empty OptionalPath if it doesn't exist. Dependencies are added
+// so that the ninja file will be regenerated if the state of the path changes.
+func OptionalPathForSource(ctx blueprint.SingletonContext, intermediates string, paths ...string) OptionalPath {
+	p := validatePath(ctx, paths...)
+	path := SourcePath{basePath{p, pathConfig(ctx)}}
+
+	abs, err := filepath.Abs(path.String())
+	if err != nil {
+		reportPathError(ctx, "%s", err.Error())
+		return OptionalPath{}
+	}
+	buildroot, err := filepath.Abs(pathConfig(ctx).buildDir)
+	if err != nil {
+		reportPathError(ctx, "%s", err.Error())
+		return OptionalPath{}
+	}
+	if strings.HasPrefix(abs, buildroot) {
+		reportPathError(ctx, "source path %s is in output", abs)
+		return OptionalPath{}
+	}
+
+	// Use glob to produce proper dependencies, even though we only want
+	// a single file.
+	files, err := Glob(ctx, PathForIntermediates(ctx, intermediates).String(), path.String(), nil)
+	if err != nil {
+		reportPathError(ctx, "glob: %s", err.Error())
+		return OptionalPath{}
+	}
+
+	if len(files) == 0 {
+		return OptionalPath{}
+	}
+	return OptionalPathForPath(path)
+}
+
+func (p SourcePath) String() string {
+	return filepath.Join(p.config.srcDir, p.path)
+}
+
+// Join creates a new SourcePath with paths... joined with the current path. The
+// provided paths... may not use '..' to escape from the current path.
+func (p SourcePath) Join(ctx PathContext, paths ...string) SourcePath {
+	path := validatePath(ctx, paths...)
+	return PathForSource(ctx, p.path, path)
+}
+
+// OverlayPath returns the overlay for `path' if it exists. This assumes that the
+// SourcePath is the path to a resource overlay directory.
+func (p SourcePath) OverlayPath(ctx AndroidModuleContext, path Path) OptionalPath {
+	var relDir string
+	if moduleSrcPath, ok := path.(ModuleSrcPath); ok {
+		relDir = moduleSrcPath.sourcePath.path
+	} else if srcPath, ok := path.(SourcePath); ok {
+		relDir = srcPath.path
+	} else {
+		reportPathError(ctx, "Cannot find relative path for %s(%s)", reflect.TypeOf(path).Name(), path)
+		return OptionalPath{}
+	}
+	dir := filepath.Join(p.config.srcDir, p.path, relDir)
+	// Use Glob so that we are run again if the directory is added.
+	paths, err := Glob(ctx, PathForModuleOut(ctx, "overlay").String(), dir, []string{})
+	if err != nil {
+		reportPathError(ctx, "glob: %s", err.Error())
+		return OptionalPath{}
+	}
+	if len(paths) == 0 {
+		return OptionalPath{}
+	}
+	relPath, err := filepath.Rel(p.config.srcDir, paths[0])
+	if err != nil {
+		reportPathError(ctx, "%s", err.Error())
+		return OptionalPath{}
+	}
+	return OptionalPathForPath(PathForSource(ctx, relPath))
+}
+
+// OutputPath is a Path representing a file path rooted from the build directory
+type OutputPath struct {
+	basePath
+}
+
+var _ Path = OutputPath{}
+
+// PathForOutput returns an OutputPath for the provided paths... (which are
+// joined together with filepath.Join). This also validates that the path
+// does not escape the build dir. On error, it will return a usable, but invalid
+// OutputPath, and report a ModuleError.
+func PathForOutput(ctx PathContext, paths ...string) OutputPath {
+	path := validatePath(ctx, paths...)
+	return OutputPath{basePath{path, pathConfig(ctx)}}
+}
+
+func (p OutputPath) writablePath() {}
+
+func (p OutputPath) String() string {
+	return filepath.Join(p.config.buildDir, p.path)
+}
+
+// Join creates a new OutputPath with paths... joined with the current path. The
+// provided paths... may not use '..' to escape from the current path.
+func (p OutputPath) Join(ctx PathContext, paths ...string) OutputPath {
+	path := validatePath(ctx, paths...)
+	return PathForOutput(ctx, p.path, path)
+}
+
+// PathForIntermediates returns an OutputPath representing the top-level
+// intermediates directory.
+func PathForIntermediates(ctx PathContext, paths ...string) OutputPath {
+	path := validatePath(ctx, paths...)
+	return PathForOutput(ctx, ".intermediates", path)
+}
+
+// ModuleSrcPath is a Path representing a file rooted from a module's local source dir
+type ModuleSrcPath struct {
+	basePath
+	sourcePath SourcePath
+	moduleDir  string
+}
+
+var _ Path = ModuleSrcPath{}
+var _ genPathProvider = ModuleSrcPath{}
+var _ objPathProvider = ModuleSrcPath{}
+var _ resPathProvider = ModuleSrcPath{}
+
+// PathForModuleSrc returns a ModuleSrcPath representing the paths... under the
+// module's local source directory.
+func PathForModuleSrc(ctx AndroidModuleContext, paths ...string) ModuleSrcPath {
+	path := validatePath(ctx, paths...)
+	return ModuleSrcPath{basePath{path, ctx.AConfig()}, PathForSource(ctx, ctx.ModuleDir(), path), ctx.ModuleDir()}
+}
+
+// OptionalPathForModuleSrc returns an OptionalPath. The OptionalPath contains a
+// valid path if p is non-nil.
+func OptionalPathForModuleSrc(ctx AndroidModuleContext, p *string) OptionalPath {
+	if p == nil {
+		return OptionalPath{}
+	}
+	return OptionalPathForPath(PathForModuleSrc(ctx, *p))
+}
+
+func (p ModuleSrcPath) String() string {
+	return p.sourcePath.String()
+}
+
+func (p ModuleSrcPath) genPathWithExt(ctx AndroidModuleContext, ext string) ModuleGenPath {
+	return PathForModuleGen(ctx, p.moduleDir, pathtools.ReplaceExtension(p.path, ext))
+}
+
+func (p ModuleSrcPath) objPathWithExt(ctx AndroidModuleContext, subdir, ext string) ModuleObjPath {
+	return PathForModuleObj(ctx, subdir, p.moduleDir, pathtools.ReplaceExtension(p.path, ext))
+}
+
+func (p ModuleSrcPath) resPathWithName(ctx AndroidModuleContext, name string) ModuleResPath {
+	// TODO: Use full directory if the new ctx is not the current ctx?
+	return PathForModuleRes(ctx, p.path, name)
+}
+
+// ModuleOutPath is a Path representing a module's output directory.
+type ModuleOutPath struct {
+	OutputPath
+}
+
+var _ Path = ModuleOutPath{}
+
+// PathForModuleOut returns a Path representing the paths... under the module's
+// output directory.
+func PathForModuleOut(ctx AndroidModuleContext, paths ...string) ModuleOutPath {
+	p := validatePath(ctx, paths...)
+	return ModuleOutPath{PathForOutput(ctx, ".intermediates", ctx.ModuleDir(), ctx.ModuleName(), ctx.ModuleSubDir(), p)}
+}
+
+// ModuleGenPath is a Path representing the 'gen' directory in a module's output
+// directory. Mainly used for generated sources.
+type ModuleGenPath struct {
+	ModuleOutPath
+	path string
+}
+
+var _ Path = ModuleGenPath{}
+var _ genPathProvider = ModuleGenPath{}
+var _ objPathProvider = ModuleGenPath{}
+
+// PathForModuleGen returns a Path representing the paths... under the module's
+// `gen' directory.
+func PathForModuleGen(ctx AndroidModuleContext, paths ...string) ModuleGenPath {
+	p := validatePath(ctx, paths...)
+	return ModuleGenPath{
+		PathForModuleOut(ctx, "gen", p),
+		p,
+	}
+}
+
+func (p ModuleGenPath) genPathWithExt(ctx AndroidModuleContext, ext string) ModuleGenPath {
+	// TODO: make a different path for local vs remote generated files?
+	return PathForModuleGen(ctx, pathtools.ReplaceExtension(p.path, ext))
+}
+
+func (p ModuleGenPath) objPathWithExt(ctx AndroidModuleContext, subdir, ext string) ModuleObjPath {
+	return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
+}
+
+// ModuleObjPath is a Path representing the 'obj' directory in a module's output
+// directory. Used for compiled objects.
+type ModuleObjPath struct {
+	ModuleOutPath
+}
+
+var _ Path = ModuleObjPath{}
+
+// PathForModuleObj returns a Path representing the paths... under the module's
+// 'obj' directory.
+func PathForModuleObj(ctx AndroidModuleContext, paths ...string) ModuleObjPath {
+	p := validatePath(ctx, paths...)
+	return ModuleObjPath{PathForModuleOut(ctx, "obj", p)}
+}
+
+// ModuleResPath is a a Path representing the 'res' directory in a module's
+// output directory.
+type ModuleResPath struct {
+	ModuleOutPath
+}
+
+var _ Path = ModuleResPath{}
+
+// PathForModuleRes returns a Path representing the paths... under the module's
+// 'res' directory.
+func PathForModuleRes(ctx AndroidModuleContext, paths ...string) ModuleResPath {
+	p := validatePath(ctx, paths...)
+	return ModuleResPath{PathForModuleOut(ctx, "res", p)}
+}
+
+// PathForModuleInstall returns a Path representing the install path for the
+// module appended with paths...
+func PathForModuleInstall(ctx AndroidModuleContext, paths ...string) OutputPath {
+	var outPaths []string
+	if ctx.Device() {
+		outPaths = []string{"target", "product", ctx.AConfig().DeviceName(), "system"}
+	} else {
+		outPaths = []string{"host", ctx.HostType().String() + "-x86"}
+	}
+	outPaths = append(outPaths, paths...)
+	return PathForOutput(ctx, outPaths...)
+}
+
+// validateSafePath validates a path that we trust (may contain ninja variables).
+// Ensures that it does not attempt to leave the containing directory.
+func validateSafePath(ctx PathContext, paths ...string) string {
+	// TODO: filepath.Join isn't necessarily correct with embedded ninja
+	// variables. '..' may remove the entire ninja variable, even if it
+	// will be expanded to multiple nested directories.
+	p := filepath.Join(paths...)
+	if p == ".." || strings.HasPrefix(p, "../") || strings.HasPrefix(p, "/") {
+		reportPathError(ctx, "Path is outside directory: %s", p)
+		return ""
+	}
+	return p
+}
+
+// validatePath validates that a path does not include ninja variables, and does
+// not attempt to leave the containing directory.
+func validatePath(ctx PathContext, paths ...string) string {
+	for _, path := range paths {
+		if strings.Contains(path, "$") {
+			reportPathError(ctx, "Path contains invalid character($): %s", path)
+			return ""
+		}
+	}
+	return validateSafePath(ctx, paths...)
 }
diff --git a/common/paths_test.go b/common/paths_test.go
new file mode 100644
index 0000000..16ede0d
--- /dev/null
+++ b/common/paths_test.go
@@ -0,0 +1,167 @@
+// Copyright 2015 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 common
+
+import (
+	"errors"
+	"fmt"
+	"reflect"
+	"strings"
+	"testing"
+)
+
+type strsTestCase struct {
+	in  []string
+	out string
+	err []error
+}
+
+var commonValidatePathTestCases = []strsTestCase{
+	{
+		in:  []string{""},
+		out: "",
+	},
+	{
+		in:  []string{"a/b"},
+		out: "a/b",
+	},
+	{
+		in:  []string{"a/b", "c"},
+		out: "a/b/c",
+	},
+	{
+		in:  []string{"a/.."},
+		out: ".",
+	},
+	{
+		in:  []string{"."},
+		out: ".",
+	},
+	{
+		in:  []string{".."},
+		out: "",
+		err: []error{errors.New("Path is outside directory: ..")},
+	},
+	{
+		in:  []string{"../a"},
+		out: "",
+		err: []error{errors.New("Path is outside directory: ../a")},
+	},
+	{
+		in:  []string{"b/../../a"},
+		out: "",
+		err: []error{errors.New("Path is outside directory: ../a")},
+	},
+	{
+		in:  []string{"/a"},
+		out: "",
+		err: []error{errors.New("Path is outside directory: /a")},
+	},
+}
+
+var validateSafePathTestCases = append(commonValidatePathTestCases, []strsTestCase{
+	{
+		in:  []string{"$host/../$a"},
+		out: "$a",
+	},
+}...)
+
+var validatePathTestCases = append(commonValidatePathTestCases, []strsTestCase{
+	{
+		in:  []string{"$host/../$a"},
+		out: "",
+		err: []error{errors.New("Path contains invalid character($): $host/../$a")},
+	},
+	{
+		in:  []string{"$host/.."},
+		out: "",
+		err: []error{errors.New("Path contains invalid character($): $host/..")},
+	},
+}...)
+
+func TestValidateSafePath(t *testing.T) {
+	for _, testCase := range validateSafePathTestCases {
+		ctx := &configErrorWrapper{}
+		out := validateSafePath(ctx, testCase.in...)
+		check(t, "validateSafePath", p(testCase.in), out, ctx.errors, testCase.out, testCase.err)
+	}
+}
+
+func TestValidatePath(t *testing.T) {
+	for _, testCase := range validatePathTestCases {
+		ctx := &configErrorWrapper{}
+		out := validatePath(ctx, testCase.in...)
+		check(t, "validatePath", p(testCase.in), out, ctx.errors, testCase.out, testCase.err)
+	}
+}
+
+func TestOptionalPath(t *testing.T) {
+	var path OptionalPath
+	checkInvalidOptionalPath(t, path)
+
+	path = OptionalPathForPath(nil)
+	checkInvalidOptionalPath(t, path)
+}
+
+func checkInvalidOptionalPath(t *testing.T, path OptionalPath) {
+	if path.Valid() {
+		t.Errorf("Uninitialized OptionalPath should not be valid")
+	}
+	if path.String() != "" {
+		t.Errorf("Uninitialized OptionalPath String() should return \"\", not %q", path.String())
+	}
+	defer func() {
+		if r := recover(); r == nil {
+			t.Errorf("Expected a panic when calling Path() on an uninitialized OptionalPath")
+		}
+	}()
+	path.Path()
+}
+
+func check(t *testing.T, testType, testString string,
+	got interface{}, err []error,
+	expected interface{}, expectedErr []error) {
+
+	printedTestCase := false
+	e := func(s string, expected, got interface{}) {
+		if !printedTestCase {
+			t.Errorf("test case %s: %s", testType, testString)
+			printedTestCase = true
+		}
+		t.Errorf("incorrect %s", s)
+		t.Errorf("  expected: %s", p(expected))
+		t.Errorf("       got: %s", p(got))
+	}
+
+	if !reflect.DeepEqual(expectedErr, err) {
+		e("errors:", expectedErr, err)
+	}
+
+	if !reflect.DeepEqual(expected, got) {
+		e("output:", expected, got)
+	}
+}
+
+func p(in interface{}) string {
+	if v, ok := in.([]interface{}); ok {
+		s := make([]string, len(v))
+		for i := range v {
+			s[i] = fmt.Sprintf("%#v", v[i])
+		}
+		return "[" + strings.Join(s, ", ") + "]"
+	} else {
+		return fmt.Sprintf("%#v", in)
+	}
+}
