diff --git a/ts_auto_deps/analyze/loader.go b/ts_auto_deps/analyze/loader.go
new file mode 100644
index 0000000..e3a70cb
--- /dev/null
+++ b/ts_auto_deps/analyze/loader.go
@@ -0,0 +1,282 @@
+package analyze
+
+import (
+	"bytes"
+	"fmt"
+	"os/exec"
+	"strings"
+
+	"github.com/bazelbuild/buildtools/edit"
+	"github.com/bazelbuild/rules_typescript/ts_auto_deps/workspace"
+	"github.com/golang/protobuf/proto"
+
+	appb "github.com/bazelbuild/buildtools/build_proto"
+)
+
+var (
+	commonModuleLocations = []string{}
+
+	ts_auto_depsManagedRuleClasses = []string{
+		"ts_library",
+		"ts_declaration",
+		"ng_module",
+		"js_library",
+	}
+)
+
+// QueryBasedTargetLoader uses Bazel query to load targets from BUILD files.
+type QueryBasedTargetLoader struct {
+	workdir     string
+	bazelBinary string
+}
+
+// NewQueryBasedTargetLoader constructs a new QueryBasedTargetLoader rooted
+// in workdir.
+func NewQueryBasedTargetLoader(workdir, bazelBinary string) *QueryBasedTargetLoader {
+	return &QueryBasedTargetLoader{
+		workdir:     workdir,
+		bazelBinary: bazelBinary,
+	}
+}
+
+// LoadLabels uses Bazel query to load targets associated with labels from BUILD
+// files.
+func (q *QueryBasedTargetLoader) LoadLabels(labels []string) (map[string]*appb.Rule, error) {
+	// Ensure the labels are unique to minimize the total number of targets that
+	// need to be loaded.
+	r, err := q.batchQuery(dedupeLabels(labels))
+	if err != nil {
+		return nil, err
+	}
+	labelToRule := make(map[string]*appb.Rule)
+	for _, target := range r.GetTarget() {
+		label, err := q.ruleLabel(target)
+		if err != nil {
+			return nil, err
+		}
+		labelToRule[label] = target.GetRule()
+	}
+	return labelToRule, nil
+}
+
+// LoadImportPaths uses Bazel Query to load targets associated with import
+// paths from BUILD files.
+func (q *QueryBasedTargetLoader) LoadImportPaths(_ string, paths []string) (map[string]*appb.Rule, error) {
+	var remainingImportPaths []string
+	results := make(map[string]*appb.Rule)
+	for _, path := range paths {
+		if trim := strings.TrimPrefix(path, workspace.Name()+"/"); trim != path {
+			// TODO(jdhamlik): Optimize by grouping the queries into one larger query.
+			// TODO(jdhamlik): Handle .d.ts and .tsx files.
+			r, err := q.query(trim + ".ts")
+			if err != nil {
+				return nil, err
+			}
+			targets := r.GetTarget()
+			// Expecting to get one, and only one, target per query.
+			n := len(targets)
+			if n < 1 {
+				return nil, fmt.Errorf("failed to resolved a target for file %q", trim+".ts")
+			}
+			if n > 1 {
+				return nil, fmt.Errorf("got %d targets when only one was expected", n)
+			}
+			t, err := q.loadRuleIncludingFile(targets[0].GetSourceFile().GetName())
+			if err != nil {
+				return nil, err
+			}
+			results[path] = t
+		} else if trim := strings.TrimPrefix(path, "goog:"); trim != path {
+			// There are no current heuristics in this implementation for
+			// 'goog:' imports. That is handled by the ts_auto_deps binary proper.
+			results[path] = nil
+		} else {
+			// The import is not explicitly under google3 or a closure-style
+			// import.
+			remainingImportPaths = append(remainingImportPaths, path)
+		}
+	}
+	var potentialCommonImports []string
+	// Attempt to locate the file rooted in the workspace even though it isn't
+	// prefixed by 'google3/'.
+	for _, imp := range remainingImportPaths {
+		// If the path has a suffix of ".ngfactory" or ".ngsummary", it might
+		// be an Angular AOT generated file. We can infer the target as we
+		// infer its corresponding ngmodule target by simply stripping the
+		// ".ngfactory" / ".ngsummary" suffix
+		path := strings.TrimSuffix(strings.TrimSuffix(imp, ".ngsummary"), ".ngfactory")
+		res, err := q.batchQuery(pathWithExtensions(path))
+		if err != nil {
+			return nil, err
+		}
+		if len(res.GetTarget()) > 0 {
+			target := res.GetTarget()[0]
+			label, err := q.sourceFileLabel(target)
+			if err != nil {
+				return nil, err
+			}
+			rule, err := q.loadRuleIncludingFile(label)
+			if err != nil {
+				return nil, err
+			}
+			results[imp] = rule
+			continue
+		}
+		potentialCommonImports = append(potentialCommonImports, imp)
+	}
+	if err := q.resolveImportsInCommonLocations(results, potentialCommonImports); err != nil {
+		return nil, err
+	}
+	return results, nil
+}
+
+func (q *QueryBasedTargetLoader) ruleLabel(target *appb.Target) (string, error) {
+	if t := target.GetType(); t != appb.Target_RULE {
+		return "", fmt.Errorf("target contains object of type %q instead of type %q", t, appb.Target_RULE)
+	}
+	return target.GetRule().GetName(), nil
+}
+
+func (q *QueryBasedTargetLoader) sourceFileLabel(target *appb.Target) (string, error) {
+	if t := target.GetType(); t != appb.Target_SOURCE_FILE {
+		return "", fmt.Errorf("target contains object of type %q instead of type %q", t, appb.Target_SOURCE_FILE)
+	}
+	return target.GetSourceFile().GetName(), nil
+}
+
+// loadRuleIncludingFile loads the target associated with a file label.
+func (q *QueryBasedTargetLoader) loadRuleIncludingFile(fileLabel string) (*appb.Rule, error) {
+	_, pkg, file := edit.ParseLabel(fileLabel)
+	// Filter the targets in the file label's package to only targets which
+	// include the file in their 'srcs' attribute.
+	r, err := q.query(fmt.Sprintf("attr('srcs', %s, //%s:*)", file, pkg))
+	if err != nil {
+		return nil, err
+	}
+	for _, target := range r.GetTarget() {
+		rule := target.GetRule()
+		for _, src := range listAttribute(rule, "srcs") {
+			_, _, path := edit.ParseLabel(src)
+			// Return the first rule which has a source file exactly matching
+			// the requested file path.
+			if path == file {
+				return rule, nil
+			}
+		}
+	}
+	return nil, fmt.Errorf("failed to resolved a target for file label %q", fileLabel)
+}
+
+// searchCommonLocations searches through common locations like third_party to
+// find a target providing imports which cannot be resolved using other
+// techniques.
+func (q *QueryBasedTargetLoader) resolveImportsInCommonLocations(results map[string]*appb.Rule, paths []string) error {
+	var queries []string
+	labelToPath := make(map[string]string)
+
+	for _, path := range paths {
+		// third_party uses '_' instead of '-' since the latter is not allowed
+		// in target labels
+		underscored := strings.Replace(path, "-", "_", -1)
+		file := underscored
+		module := underscored
+		if i := strings.Index(underscored, "/"); i >= 0 {
+			// Use the slash in the import path as a separator between the
+			// module name and the path under the module.
+			file = underscored[i+1:]
+			module = commonModuleName(underscored[:i])
+		}
+		for _, l := range commonModuleLocations {
+			// Construct the potential target label in the common location.
+			target := fmt.Sprintf("%s:%s", fmt.Sprintf(l, module), file)
+			queries = append(queries, target)
+			labelToPath[target] = path
+		}
+	}
+	r, err := q.batchQuery(queries)
+	if err != nil {
+		return err
+	}
+	for _, target := range r.GetTarget() {
+		r := target.GetRule()
+		// TODO(jdhamlik): Determine if it's required that the alias resolves to
+		// an allowedRuleClass.
+		// Allow alias rules to provide imports. Alias rules should only appear
+		// in this context if they are special-cased above.
+		if c := r.GetRuleClass(); isTazeManagedRuleClass(c) || c == "alias" {
+			results[labelToPath[r.GetName()]] = r
+		}
+	}
+	return nil
+}
+
+// batchQuery runs a set of queries with a single call to Bazel query and the
+// '--keep_going' flag.
+func (q *QueryBasedTargetLoader) batchQuery(queries []string) (*appb.QueryResult, error) {
+	// Join all of the queries with a '+' character according to Bazel's
+	// syntax for running multiple queries.
+	return q.query("--keep_going", strings.Join(queries, "+"))
+}
+
+func (q *QueryBasedTargetLoader) query(args ...string) (*appb.QueryResult, error) {
+	n := len(args)
+	if n < 1 {
+		return nil, fmt.Errorf("expected at least one argument")
+	}
+	if query := args[n-1]; query == "" {
+		// An empty query was provided so return an empty result without
+		// making a call to Bazel.
+		return &appb.QueryResult{}, nil
+	}
+	var stdout, stderr bytes.Buffer
+	args = append([]string{"query", "--output=proto"}, args...)
+	cmd := exec.Command(q.bazelBinary, args...)
+	cmd.Dir = q.workdir
+	cmd.Stdout = &stdout
+	cmd.Stderr = &stderr
+	if err := cmd.Run(); err != nil {
+		// Exit status 3 is a direct result of one or more queries in a set of
+		// queries not returning a result while running with the '--keep_going'
+		// flag. Since one query failing to return a result does not hinder the
+		// other queries from returning a result, ignore these errors.
+		if err.Error() != "exit status 3" {
+			// The error provided as a result is less useful than the contents of
+			// stderr for debugging.
+			return nil, fmt.Errorf(stderr.String())
+		}
+	}
+	var result appb.QueryResult
+	if err := proto.Unmarshal(stdout.Bytes(), &result); err != nil {
+		return nil, err
+	}
+	return &result, nil
+}
+
+// dedupeLabels returns a new set of labels with no duplicates.
+func dedupeLabels(labels []string) []string {
+	addedLabels := make(map[string]bool)
+	var uniqueLabels []string
+	for _, label := range labels {
+		if _, added := addedLabels[label]; !added {
+			addedLabels[label] = true
+			uniqueLabels = append(uniqueLabels, label)
+		}
+	}
+	return uniqueLabels
+}
+
+// commonModuleName maps module names to their common names. If no common name
+// is set for a module, it returns the module's name as is.
+func commonModuleName(path string) string {
+	return path
+}
+
+// isTazeManagedRuleClass checks if a class is a ts_auto_deps-managed rule class.
+func isTazeManagedRuleClass(class string) bool {
+	for _, c := range ts_auto_depsManagedRuleClasses {
+		if c == class {
+			return true
+		}
+	}
+	return false
+}
diff --git a/ts_auto_deps/analyze/query.go b/ts_auto_deps/analyze/query.go
index 402113b..66336a3 100644
--- a/ts_auto_deps/analyze/query.go
+++ b/ts_auto_deps/analyze/query.go
@@ -4,9 +4,7 @@
 
 import (
 	"fmt"
-	"io/ioutil"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"strings"
 
@@ -20,19 +18,6 @@
 )
 
 var (
-	commonModuleLocations = []string{
-		"//third_party/javascript/%s",
-		"//third_party/javascript/node_modules/%s",
-		"//third_party/javascript/typings/%s",
-	}
-
-	ts_auto_depsManagedRuleClasses = []string{
-		"ts_library",
-		"ts_declaration",
-		"ng_module",
-		"js_library",
-	}
-
 	extensions = []string{
 		// '.d.ts' must come before '.ts' to completely remove the '.d.ts'
 		// extension.
@@ -391,7 +376,7 @@
 					}
 				}
 				report.MissingDependencyGroup = append(report.MissingDependencyGroup, &arpb.DependencyGroup{
-					Dependency: []string{i.knownTarget},
+					Dependency: []string{edit.ShortenLabel(i.knownTarget, "")},
 					ImportPath: []string{i.resolvedPath()},
 				})
 			}
@@ -451,303 +436,3 @@
 	}
 	return nil
 }
-
-// QueryBasedTargetLoader uses Bazel query to load targets from BUILD files.
-type QueryBasedTargetLoader struct {
-	workdir     string
-	bazelBinary string
-}
-
-// NewQueryBasedTargetLoader constructs a new QueryBasedTargetLoader rooted
-// in workdir.
-func NewQueryBasedTargetLoader(workdir, bazelBinary string) *QueryBasedTargetLoader {
-	return &QueryBasedTargetLoader{
-		workdir:     workdir,
-		bazelBinary: bazelBinary,
-	}
-}
-
-// LoadLabels uses Bazel query to load targets associated with labels from BUILD
-// files.
-func (q *QueryBasedTargetLoader) LoadLabels(labels []string) (map[string]*appb.Rule, error) {
-	// Ensure the labels are unique to minimize the total number of targets that
-	// need to be loaded.
-	r, err := q.batchQuery(dedupeLabels(labels))
-	if err != nil {
-		return nil, err
-	}
-	targets := make(map[string]*appb.Rule)
-	for _, target := range r.GetTarget() {
-		t, o, err := q.resultObject(target)
-		if err != nil {
-			return nil, err
-		}
-		if desired := appb.Target_RULE; t != desired {
-			return nil, fmt.Errorf("label %q included object of type %q instead of %q", o.GetName(), t, desired)
-		}
-		targets[o.GetName()] = o.(*appb.Rule)
-	}
-	return targets, nil
-}
-
-// dedupeLabels returns a new set of labels with no duplicates.
-func dedupeLabels(labels []string) []string {
-	m := make(map[string]bool)
-	var u []string
-	for _, label := range labels {
-		if _, ok := m[label]; !ok {
-			m[label] = true
-			u = append(u, label)
-		}
-	}
-	return u
-}
-
-// target is the object of an appb.Target instance. This can be any of:
-// source file, generated file, environment group, rule, or package group.
-//
-// Methods which are shared between all of the possible objects are added
-// here.
-type target interface {
-	GetName() string
-}
-
-// resultObject retrieves the object included in target. Uses the discriminator
-// present on the target to determine which object to return.
-func (q *QueryBasedTargetLoader) resultObject(target *appb.Target) (appb.Target_Discriminator, target, error) {
-	switch t := target.GetType(); t {
-	case appb.Target_ENVIRONMENT_GROUP:
-		return t, target.GetEnvironmentGroup(), nil
-	case appb.Target_GENERATED_FILE:
-		return t, target.GetGeneratedFile(), nil
-	case appb.Target_PACKAGE_GROUP:
-		return t, target.GetPackageGroup(), nil
-	case appb.Target_RULE:
-		return t, target.GetRule(), nil
-	case appb.Target_SOURCE_FILE:
-		return t, target.GetSourceFile(), nil
-	default:
-		// Unfortunately we cannot get the label of the target which caused
-		// the issue.
-		return t, nil, fmt.Errorf("target has object of unknown type %q", t)
-	}
-}
-
-// LoadImportPaths uses Bazel Query to load targets associated with import
-// paths from BUILD files.
-func (q *QueryBasedTargetLoader) LoadImportPaths(root string, paths []string) (map[string]*appb.Rule, error) {
-	var remainingImportPaths []string
-	results := make(map[string]*appb.Rule)
-	for _, path := range paths {
-		if trim := strings.TrimPrefix(path, workspace.Name()+"/"); trim != path {
-			// TODO(jdhamlik): Optimize by grouping the queries into one larger query.
-			// TODO(jdhamlik): Handle .d.ts and .tsx files.
-			r, err := q.query(trim + ".ts")
-			if err != nil {
-				return nil, err
-			}
-			targets := r.GetTarget()
-			// Expecting to get one, and only one, target per query.
-			n := len(targets)
-			if n < 1 {
-				return nil, fmt.Errorf("failed to resolved a target for file %q", trim+".ts")
-			}
-			if n > 1 {
-				return nil, fmt.Errorf("got %d targets when only one was expected", n)
-			}
-			t, err := q.loadRuleIncludingFile(targets[0].GetSourceFile().GetName())
-			if err != nil {
-				return nil, err
-			}
-			results[path] = t
-		} else if trim := strings.TrimPrefix(path, "goog:"); trim != path {
-			// There are no current heuristics in this implementation for
-			// 'goog:' imports. That is handled by the ts_auto_deps binary proper.
-			results[path] = nil
-		} else {
-			// The import is not explicitly under google3 or a closure-style
-			// import.
-			remainingImportPaths = append(remainingImportPaths, path)
-		}
-	}
-	var potentialCommonImports []string
-	// Attempt to locate the file rooted in the workspace even though it isn't
-	// prefixed by 'google3/'.
-	for _, imp := range remainingImportPaths {
-		// If the path has a suffix of ".ngfactory" or ".ngsummary", it might
-		// be an Angular AOT generated file. We can infer the target as we
-		// infer its corresponding ngmodule target by simply stripping the
-		// ".ngfactory" / ".ngsummary" suffix
-		path := strings.TrimSuffix(strings.TrimSuffix(imp, ".ngsummary"), ".ngfactory")
-		res, err := q.batchQuery(pathWithExtensions(path))
-		if err != nil {
-			return nil, err
-		}
-		if len(res.GetTarget()) > 0 {
-			t, obj, err := q.resultObject(res.GetTarget()[0])
-			if err != nil {
-				return nil, err
-			}
-			if desired := appb.Target_SOURCE_FILE; t != desired {
-				return nil, fmt.Errorf("label %q included object of type %q instead of %q", obj.GetName(), t, desired)
-			}
-			target, err := q.loadRuleIncludingFile(obj.GetName())
-			if err != nil {
-				return nil, err
-			}
-			results[imp] = target
-			continue
-		}
-		potentialCommonImports = append(potentialCommonImports, imp)
-	}
-	if err := q.resolveImportsInCommonLocations(results, potentialCommonImports); err != nil {
-		return nil, err
-	}
-	return results, nil
-}
-
-// loadRuleIncludingFile loads the target associated with a file label.
-func (q *QueryBasedTargetLoader) loadRuleIncludingFile(fileLabel string) (*appb.Rule, error) {
-	_, pkg, file := edit.ParseLabel(fileLabel)
-	// Filter the targets in the file label's package to only targets which
-	// include the file in their 'srcs' attribute.
-	r, err := q.query(fmt.Sprintf("attr('srcs', %s, //%s:*)", file, pkg))
-	if err != nil {
-		return nil, err
-	}
-	for _, target := range r.GetTarget() {
-		rule := target.GetRule()
-		for _, src := range listAttribute(rule, "srcs") {
-			_, _, path := edit.ParseLabel(src)
-			// Return the first rule which has a source file exactly matching
-			// the requested file path.
-			if path == file {
-				return rule, nil
-			}
-		}
-	}
-	return nil, fmt.Errorf("failed to resolved a target for file label %q", fileLabel)
-}
-
-// searchCommonLocations searches through common locations like third_party to
-// find a target providing imports which cannot be resolved using other
-// techniques.
-func (q *QueryBasedTargetLoader) resolveImportsInCommonLocations(results map[string]*appb.Rule, paths []string) error {
-	var queries []string
-	labelToPath := make(map[string]string)
-	// TODO(jdhamlik): Determine how to resolve this target. Whether alias
-	// support should be dropped entirely, this "platform_browser_safe" import
-	// should be special cased, or alias resolution should be implemented.
-
-	for _, path := range paths {
-		// third_party uses '_' instead of '-' since the latter is not allowed
-		// in target labels
-		underscored := strings.Replace(path, "-", "_", -1)
-		file := underscored
-		module := underscored
-		if i := strings.Index(underscored, "/"); i >= 0 {
-			// Use the slash in the import path as a separator between the
-			// module name and the path under the module.
-			file = underscored[i+1:]
-			module = commonModuleName(underscored[:i])
-		}
-		for _, l := range commonModuleLocations {
-			// Construct the potential target label in the common location.
-			target := fmt.Sprintf("%s:%s", fmt.Sprintf(l, module), file)
-			queries = append(queries, target)
-			labelToPath[target] = path
-		}
-	}
-	r, err := q.batchQuery(queries)
-	if err != nil {
-		return err
-	}
-	for _, target := range r.GetTarget() {
-		r := target.GetRule()
-		// TODO(jdhamlik): Determine if it's required that the alias resolves to
-		// an allowedRuleClass.
-		// Allow alias rules to provide imports. Alias rules should only appear
-		// in this context if they are special-cased above.
-		if c := r.GetRuleClass(); isTazeManagedRuleClass(c) || c == "alias" {
-			results[labelToPath[r.GetName()]] = r
-		}
-	}
-	return nil
-}
-
-// commonModuleName maps module names to their common names. If no common name
-// is set for a module, it returns the module's name as is.
-func commonModuleName(path string) string {
-	return path
-}
-
-// isTazeManagedRuleClass checks if a class is a ts_auto_deps-managed rule class.
-func isTazeManagedRuleClass(class string) bool {
-	for _, c := range ts_auto_depsManagedRuleClasses {
-		if c == class {
-			return true
-		}
-	}
-	return false
-}
-
-// batchQuery runs a set of queries with a single call to Bazel query and the
-// '--keep_going' flag.
-func (q *QueryBasedTargetLoader) batchQuery(queries []string) (*appb.QueryResult, error) {
-	// Join all of the queries with a '+' character according to Bazel's
-	// syntax for running multiple queries.
-	return q.query("--keep_going", strings.Join(queries, "+"))
-}
-
-func (q *QueryBasedTargetLoader) query(args ...string) (*appb.QueryResult, error) {
-	n := len(args)
-	if n < 1 {
-		return nil, fmt.Errorf("expected at least one argument")
-	}
-	if query := args[n-1]; query == "" {
-		// An empty query was provided so return an empty result without
-		// making a call to Bazel.
-		return &appb.QueryResult{}, nil
-	}
-	args = append([]string{"query", "--output=proto"}, args...)
-	cmd := exec.Command(q.bazelBinary, args...)
-	cmd.Dir = q.workdir
-	stdoutPipe, err := cmd.StdoutPipe()
-	if err != nil {
-		return nil, err
-	}
-	stderrPipe, err := cmd.StderrPipe()
-	if err != nil {
-		return nil, err
-	}
-	if err := cmd.Start(); err != nil {
-		return nil, err
-	}
-	// Collect all of stdout and stderr. Stdout will contain the QueryResult,
-	// if any, and stderr will contain any potential errors either as a result
-	// of the '--keep_going' flag or other, more problematic, errors.
-	stdout, err := ioutil.ReadAll(stdoutPipe)
-	if err != nil {
-		return nil, err
-	}
-	stderr, err := ioutil.ReadAll(stderrPipe)
-	if err != nil {
-		return nil, err
-	}
-	if err := cmd.Wait(); err != nil {
-		// Exit status 3 is a direct result of one or more queries in a set of
-		// queries not returning a result while running with the '--keep_going'
-		// flag. Since one query failing to return a result does not hinder the
-		// other queries from returning a result, ignore these errors.
-		if err.Error() != "exit status 3" {
-			// The error provided as a result is less useful than the contents of
-			// stderr for debugging.
-			return nil, fmt.Errorf(string(stderr))
-		}
-	}
-	var result appb.QueryResult
-	if err := proto.Unmarshal(stdout, &result); err != nil {
-		return nil, err
-	}
-	return &result, nil
-}
