diff --git a/src/base/api.lua b/src/base/api.lua
index 73ea4dbd..3d5e1b69 100755
--- a/src/base/api.lua
+++ b/src/base/api.lua
@@ -17,6 +17,9 @@
 -- scope (e.g. solutions, projects, groups, and configurations). Initialize
 -- it with a "root" container to contain the other containers, as well as the
 -- global configuration settings which should apply to all of them.
+--
+-- TODO: this should be hidden, with a perhaps a read-only accessor to fetch
+-- individual scopes for testing.
 ---
 
 	api.scope = {}
@@ -78,6 +81,22 @@
 
 
 
+---
+-- Recursively clear any child scopes for a container class. For example,
+-- if a solution is being activated, clear the project and group scopes,
+-- as those are children of solutions. If the root scope is made active,
+-- all child scopes will be cleared.
+---
+
+	function api._clearChildScopes(cc)
+		for ch in cc:eachChildClass() do
+			api.scope[ch.name] = nil
+			api._clearChildScopes(ch)
+		end
+	end
+
+
+
 ---
 -- Activate a new configuration container, making it the target for all
 -- subsequent configuration settings. When you call solution() or project()
@@ -89,28 +108,54 @@
 -- @param name
 --    The name of the container instance to be activated. If a container
 --    (e.g. project) with this name does not already exist it will be
---    created.
+--    created. If name is not set, the last activated container of this
+--    class will be made current again.
 -- @return
 --    The container instance.
 ---
 
 	function api._setScope(cc, name)
-		local instance
+		-- for backward compatibility, "*" activates the parent container
+		if name == "*" then
+			return api._setScope(cc.parent)
+		end
 
-		-- << handle (name == nil) >>
+		-- if name is not set, use whatever was last made current
+		local container
+		if not name then
+			container = api.scope[cc.name]
+			if not container then
+				error("no " .. cc.name .. " in scope", 3)
+			end
+		end
 
-		-- << handle "*" >>
+		if not container then
+			-- all containers should be contained within a parent
+			local parent = api.scope[cc.parent.name]
+			if not parent then
+				error("no active " .. cc.parent.name, 3)
+			end
 
-		-- Fetch (creating if necessary) the container
-		local parentContainer = api._target(cc.parent)
-		local container = parentContainer:fetchContainer(cc, name)
+			-- fetch (creating if necessary) the container
+			container = parent:fetchChild(cc, name)
+			if not container then
+				container = parent:createChild(cc, name, parent)
+			else
+				configset.addFilter(container, {}, os.getcwd())
+			end
+		end
 
-		-- << start a new settings block >>
+		-- clear out any active child container types
+		api._clearChildScopes(cc)
 
-		-- Activate the container
-		api.scope[cc.name] = container  -- TODO: do I still need this?
+		-- activate the container, as well as its ancestors
 		api.scope.current = container
-		return container
+		while container.parent do
+			api.scope[container.class.name] = container
+			container = container.parent
+		end
+
+		return api.scope.current
 	end
 
 
@@ -630,6 +675,9 @@
 ---
 
 	function api.reset()
+		-- Clear out all top level objects
+		api.scope.root.solutions = {}
+
 		-- Remove all custom variables
 		local vars = api.getCustomVars()
 		for i, var in ipairs(vars) do
@@ -1034,6 +1082,23 @@
 
 
 
+
+	local _slnContainerClass = api.container {
+		name = "solution",
+	}
+
+	api.container {
+		name = "group",
+		parent = "solution",
+	}
+
+	api.container {
+		name = "project",
+		parent = "solution",
+	}
+
+
+
 ---
 -- Begin a new solution group, which will contain any subsequent projects.
 ---
@@ -1056,15 +1121,6 @@
 --    The active project object.
 --
 
-	api.container {
-		name = "solution",
-	}
-
-	api.container {
-		name = "project",
-		parent = "solution",
-	}
-
   	function project(name)
 		if not name then
 			if api.scope.project then
@@ -1081,6 +1137,7 @@
 
 		local prj
 		if name ~= "*" then
+			sln.projects = sln.projects or {}
 			prj = sln.projects[name]
 			if not prj then
 				prj = premake.project.new(sln, name)
@@ -1120,44 +1177,6 @@
 
 
 
---
--- Set the current configuration scope to a solution.
---
--- @param name
---    The name of the solution. If a solution with this name already
---    exists, it is made current, otherwise a new solution is created
---    with this name. If no name is provided, the most recently defined
---    solution is made active.
--- @return
---    The active solution object.
---
-
-	function solution(name)
-		if not name then
-			if api.scope.solution then
-				name = api.scope.solution.name
-			else
-				return nil
-			end
-		end
-
-		local sln
-		if name ~= "*" then
-			sln = premake.solution.get(name) or premake.solution.new(name)
-			sln.class = p.containerClass.get("solution")
-		end
-
-		api.scope.solution = sln
-		api.scope.project = nil
-		api.scope.group = nil
-		api.scope.current = sln
-
-		configuration {}
-
-		return sln
-	end
-
-
 --
 -- Define a new action.
 --
diff --git a/src/base/container.lua b/src/base/container.lua
index e3bdfdd3..695eef9f 100644
--- a/src/base/container.lua
+++ b/src/base/container.lua
@@ -73,6 +73,8 @@
 --       An initializer function to call for new instances of this class.
 --       Should accept the new instance object as its only argument.
 --
+--    Other keys are allowed and will be left intact.
+--
 -- @return
 --    A new container class object if successful, else nil and an
 --    error message.
@@ -102,8 +104,8 @@
 
 		-- Looks good, set myself up and add to master list
 
-		def.children = {}
-		def.listKey = def.name:plural()
+		def._children = {}
+		def._listKey = def.name:plural()
 		setmetatable(def, p.containerClass)
 		container._classes[def.name] = def
 
@@ -111,7 +113,7 @@
 
 		def.parent = container._classes[def.parent]
 		if def.parent then
-			table.insert(def.parent.children, def)
+			table.insert(def.parent._children, def)
 		end
 
 		return def
@@ -119,6 +121,23 @@
 
 
 
+---
+-- Enumerate the child container class of a given class.
+---
+
+	function p.containerClass:eachChildClass()
+		local children = self._children
+		local i = 0
+		return function ()
+			i = i + 1
+			if i <= #children then
+				return children[i]
+			end
+		end
+	end
+
+
+
 ---
 -- Retrieve a container class by name.
 --
@@ -158,6 +177,32 @@
 
 
 
+---
+-- Create a new child container of the given class, with the specified name.
+--
+-- @param cc
+--    The class of child container to be fetched.
+-- @param key
+--    A string key or array index for the container.
+-- @param parent
+--    The parent container instance.
+-- @return
+--    The child container instance.
+---
+
+	function container:createChild(cc, key, parent)
+		self[cc._listKey] = self[cc._listKey] or {}
+		local list = self[cc._listKey]
+
+		local child = cc:new(key, parent)
+		table.insert(list, child)
+		list[key] = child
+
+		return child
+	end
+
+
+
 ---
 -- Return an iterator for the child containers of a particular class.
 --
@@ -165,8 +210,8 @@
 --    The class of child container to be enumerated.
 ---
 
-	function container:eachContainer(cc)
-		local children = self[cc.listKey] or {}
+	function container:eachChild(cc)
+		local children = self[cc._listKey] or {}
 		local i = 0
 		return function ()
 			i = i + 1
@@ -180,28 +225,16 @@
 
 ---
 -- Fetch the child container with the given container class and instance name.
--- If it doesn't exist, a new container is created.
 --
 -- @param cc
 --    The class of child container to be fetched.
 -- @param key
---    A string key or array index for the container. If a string key is
---    provided, the container will be created if it doesn't exist. If an
---    array index is provided, nil will be returned if it does not exist.
+--    A string key or array index for the container.
 -- @return
 --    The child container instance.
 ---
 
-	function container:fetchContainer(cc, key)
-		self[cc.listKey] = self[cc.listKey] or {}
-		local children = self[cc.listKey]
-		local c = children[key]
-
-		if not c and type(key) == "string" then
-			c = cc:new(key, parent)
-			table.insert(children, c)
-			children[key] = c
-		end
-
-		return c
+	function container:fetchChild(cc, key)
+		self[cc._listKey] = self[cc._listKey] or {}
+		return self[cc._listKey][key]
 	end
diff --git a/src/base/oven.lua b/src/base/oven.lua
index 86e4b490..ce169f0a 100644
--- a/src/base/oven.lua
+++ b/src/base/oven.lua
@@ -10,14 +10,16 @@
 --
 
 	premake.oven = {}
-
 	local oven = premake.oven
-	local solution = premake.solution
-	local project = premake.project
-	local config = premake.config
-	local fileconfig = premake.fileconfig
-	local configset = premake.configset
-	local context = premake.context
+
+	local p = premake
+	local solution = p.solution
+	local project = p.project
+	local config = p.config
+	local fileconfig = p.fileconfig
+	local configset = p.configset
+	local context = p.context
+
 
 
 ---
@@ -34,15 +36,15 @@
 ---
 
 	function oven.bake(root)
-		-- I haven't yet ported the project objects to containers
 		local result = {}
-		for i, sln in ipairs(solution.list) do
+
+		local root = p.api.rootContainer()
+		root.solutions = root.solutions or {}
+		for i, sln in ipairs(root.solutions) do
 			result[i] = oven.bakeSolution(sln)
 		end
-		solution.list = result
-
-		-- Start container implementation
 
+		root.solutions = result
 	end
 
 
@@ -104,6 +106,7 @@
 		-- store that for future reference
 
 		local projects = {}
+		sln.projects = sln.projects or {}
 		for i, prj in ipairs(sln.projects) do
 			projects[i] = oven.bakeProject(prj, ctx)
 			projects[prj.name] = projects[i]
diff --git a/src/base/rules.lua b/src/base/rules.lua
index a7e38de7..c8bddba4 100644
--- a/src/base/rules.lua
+++ b/src/base/rules.lua
@@ -31,7 +31,7 @@
 ---
 
 	function rules.each()
-		return p.api.rootContainer():eachContainer(_ruleContainerClass)
+		return p.api.rootContainer():eachChild(_ruleContainerClass)
 	end
 
 
@@ -46,5 +46,5 @@
 ---
 
 	function rules.fetch(key)
-		return p.api.rootContaiiner():fetchContainer(_ruleContainerClass, key)
+		return p.api.rootContainer():fetchChild(_ruleContainerClass, key)
 	end
diff --git a/src/base/solution.lua b/src/base/solution.lua
index b956de2e..513fdb72 100644
--- a/src/base/solution.lua
+++ b/src/base/solution.lua
@@ -6,41 +6,12 @@
 
 	premake.solution = {}
 	local solution = premake.solution
-	local project = premake.project
-	local configset = premake.configset
-	local context = premake.context
-	local tree = premake.tree
 
+	local p = premake
+	local project = p.project
+	local context = p.context
+	local tree = p.tree
 
--- The list of defined solutions (which contain projects, etc.)
-
-	solution.list = {}
-
-
---
--- Create a new solution and add it to the session.
---
--- @param name
---    The new solution's name.
--- @return
---    A new solution object.
---
-
-	function solution.new(name)
-		sln = configset.new(premake.api.rootContainer())
-		setmetatable(sln, configset.metatable(sln))
-
-		sln.name = name
-		sln.projects = {}
-		sln.basedir = os.getcwd()
-		sln.filename = name
-
-		-- Add to master list keyed by both name and index
-		table.insert(premake.solution.list, sln)
-		premake.solution.list[name] = sln
-
-		return sln
-	end
 
 
 --
@@ -67,11 +38,13 @@
 --
 
 	function solution.each()
+		local root = p.api.rootContainer()
+
 		local i = 0
 		return function ()
 			i = i + 1
-			if i <= #premake.solution.list then
-				return premake.solution.list[i]
+			if i <= #root.solutions then
+				return root.solutions[i]
 			end
 		end
 	end
@@ -153,7 +126,10 @@
 --
 
 	function solution.get(key)
-		return premake.solution.list[key]
+		local root = p.api.rootContainer()
+		if root.solutions then
+			return root.solutions[key]
+		end
 	end
 
 
diff --git a/tests/testfx.lua b/tests/testfx.lua
index ff9a8316..3c04b8dc 100644
--- a/tests/testfx.lua
+++ b/tests/testfx.lua
@@ -339,7 +339,6 @@
 
 		stderr_capture = nil
 
-		premake.solution.list = { }
 		premake.clearWarnings()
 		premake.eol("\n")
 		premake.escaper(nil)