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...)
 }
