merge in oc-release history after reset to master
diff --git a/bootstrap/bootstrap.go b/bootstrap/bootstrap.go
index 410790e..4396579 100644
--- a/bootstrap/bootstrap.go
+++ b/bootstrap/bootstrap.go
@@ -294,11 +294,6 @@
 	g.pkgRoot = packageRoot(ctx)
 	g.archiveFile = filepath.Join(g.pkgRoot,
 		filepath.FromSlash(g.properties.PkgPath)+".a")
-	var testArchiveFile string
-	if len(g.properties.TestSrcs) > 0 && g.config.runGoTests {
-		testArchiveFile = filepath.Join(testRoot(ctx),
-			filepath.FromSlash(g.properties.PkgPath)+".a")
-	}
 
 	ctx.VisitDepsDepthFirstIf(isGoPluginFor(name),
 		func(module blueprint.Module) { hasPlugins = true })
@@ -327,6 +322,8 @@
 		}
 
 		if g.config.runGoTests {
+			testArchiveFile := filepath.Join(testRoot(ctx),
+				filepath.FromSlash(g.properties.PkgPath)+".a")
 			g.testResultFile = buildGoTest(ctx, testRoot(ctx), testArchiveFile,
 				g.properties.PkgPath, srcs, genSrcs,
 				testSrcs)
diff --git a/context.go b/context.go
index f63b1af..989711f 100644
--- a/context.go
+++ b/context.go
@@ -1191,6 +1191,10 @@
 }
 
 func (c *Context) addDependency(module *moduleInfo, tag DependencyTag, depName string) []error {
+	if _, ok := tag.(BaseDependencyTag); ok {
+		panic("BaseDependencyTag is not allowed to be used directly!")
+	}
+
 	if depName == module.Name() {
 		return []error{&BlueprintError{
 			Err: fmt.Errorf("%q depends on itself", depName),
@@ -1262,6 +1266,9 @@
 
 func (c *Context) addVariationDependency(module *moduleInfo, variations []Variation,
 	tag DependencyTag, depName string, far bool) []error {
+	if _, ok := tag.(BaseDependencyTag); ok {
+		panic("BaseDependencyTag is not allowed to be used directly!")
+	}
 
 	possibleDeps := c.modulesFromName(depName)
 	if possibleDeps == nil {
@@ -1328,6 +1335,9 @@
 
 func (c *Context) addInterVariantDependency(origModule *moduleInfo, tag DependencyTag,
 	from, to Module) {
+	if _, ok := tag.(BaseDependencyTag); ok {
+		panic("BaseDependencyTag is not allowed to be used directly!")
+	}
 
 	var fromInfo, toInfo *moduleInfo
 	for _, m := range origModule.splitModules {
@@ -2534,9 +2544,45 @@
 	c.visitAllModulesIf(pred, visit)
 }
 
-func (c *Context) VisitDepsDepthFirst(module Module,
-	visit func(Module)) {
+func (c *Context) VisitDirectDeps(module Module, visit func(Module)) {
+	topModule := c.moduleInfo[module]
 
+	var visiting *moduleInfo
+
+	defer func() {
+		if r := recover(); r != nil {
+			panic(newPanicErrorf(r, "VisitDirectDeps(%s, %s) for dependency %s",
+				topModule, funcName(visit), visiting))
+		}
+	}()
+
+	for _, dep := range topModule.directDeps {
+		visiting = dep.module
+		visit(dep.module.logicModule)
+	}
+}
+
+func (c *Context) VisitDirectDepsIf(module Module, pred func(Module) bool, visit func(Module)) {
+	topModule := c.moduleInfo[module]
+
+	var visiting *moduleInfo
+
+	defer func() {
+		if r := recover(); r != nil {
+			panic(newPanicErrorf(r, "VisitDirectDepsIf(%s, %s, %s) for dependency %s",
+				topModule, funcName(pred), funcName(visit), visiting))
+		}
+	}()
+
+	for _, dep := range topModule.directDeps {
+		visiting = dep.module
+		if pred(dep.module.logicModule) {
+			visit(dep.module.logicModule)
+		}
+	}
+}
+
+func (c *Context) VisitDepsDepthFirst(module Module, visit func(Module)) {
 	topModule := c.moduleInfo[module]
 
 	var visiting *moduleInfo
@@ -2554,9 +2600,7 @@
 	})
 }
 
-func (c *Context) VisitDepsDepthFirstIf(module Module,
-	pred func(Module) bool, visit func(Module)) {
-
+func (c *Context) VisitDepsDepthFirstIf(module Module, pred func(Module) bool, visit func(Module)) {
 	topModule := c.moduleInfo[module]
 
 	var visiting *moduleInfo
diff --git a/module_ctx.go b/module_ctx.go
index a2fd9c9..e23caac 100644
--- a/module_ctx.go
+++ b/module_ctx.go
@@ -660,6 +660,10 @@
 // collected until the end of the mutator pass, sorted by name, and then appended to the destination
 // module's dependency list.
 func (mctx *mutatorContext) AddReverseDependency(module Module, tag DependencyTag, destName string) {
+	if _, ok := tag.(BaseDependencyTag); ok {
+		panic("BaseDependencyTag is not allowed to be used directly!")
+	}
+
 	destModule, errs := mctx.context.findReverseDependency(mctx.context.moduleInfo[module], destName)
 	if len(errs) > 0 {
 		mctx.errs = append(mctx.errs, errs...)