[Pkg-puppet-devel] [SCM] Puppet packaging for Debian branch, upstream, updated. 0.25.5-639-g8f94f35

test branch puppet-dev at googlegroups.com
Wed Jul 14 10:31:58 UTC 2010


The following commit has been merged in the upstream branch:
commit 7089446697ad550c22012bc2b5572030727d67e1
Author: Luke Kanies <luke at reductivelabs.com>
Date:   Fri Jan 29 20:57:21 2010 -0600

    Removing Resource::Reference classes
    
    This commit is hopefully less messy than it
    first appears, but it's certainly cross-cutting.
    
    The reason for all of this is that we previously only
    looked up builtin resource types from outside the parser,
    but now that the defined resource types are available globally
    via environments, we can push that lookup code to Resource.
    
    Once we do that, however, we have to have environment and
    namespace information in every resource.
    
    Here I remove the Resource::Reference classes (except
    the AST class), and use Resource instances instead. I
    did this because the shared code between the two classes
    got incredibly complicated, such that they should have had
    a hierarchical relationship disallowed by their constants.
    This complexity convinced me just to get rid of References
    entirely.
    
    I also make Puppet::Parser::Resource a subclass
    of Puppet::Resource.
    
    There are still broken tests in test/, but this was a big
    enough commit I wanted to get it in.
    
    Signed-off-by: Luke Kanies <luke at reductivelabs.com>

diff --git a/lib/puppet.rb b/lib/puppet.rb
index 2e531ad..09ae531 100644
--- a/lib/puppet.rb
+++ b/lib/puppet.rb
@@ -153,7 +153,6 @@ end
 require 'puppet/type'
 require 'puppet/parser'
 require 'puppet/resource'
-require 'puppet/resource/reference'
 require 'puppet/network'
 require 'puppet/ssl'
 require 'puppet/module'
diff --git a/lib/puppet/parser/ast/resource.rb b/lib/puppet/parser/ast/resource.rb
index d222893..5da40b3 100644
--- a/lib/puppet/parser/ast/resource.rb
+++ b/lib/puppet/parser/ast/resource.rb
@@ -14,7 +14,7 @@ class Resource < AST::ResourceReference
     # in the current scope.
     def evaluate(scope)
         # Evaluate all of the specified params.
-        paramobjects = @params.collect { |param|
+        paramobjects = params.collect { |param|
             param.safeevaluate(scope)
         }
 
@@ -25,8 +25,6 @@ class Resource < AST::ResourceReference
             resource_titles = [resource_titles]
         end
 
-        resource_type = qualified_type(scope)
-
         # We want virtual to be true if exported is true.  We can't
         # just set :virtual => self.virtual in the initialization,
         # because sometimes the :virtual attribute is set *after*
@@ -39,9 +37,7 @@ class Resource < AST::ResourceReference
         # many times.
         resource_titles.flatten.collect { |resource_title|
             exceptwrap :type => Puppet::ParseError do
-                resource = Puppet::Parser::Resource.new(
-                    :type => resource_type,
-                    :title => resource_title,
+                resource = Puppet::Parser::Resource.new(type, resource_title,
                     :params => paramobjects,
                     :file => self.file,
                     :line => self.line,
diff --git a/lib/puppet/parser/ast/resource_defaults.rb b/lib/puppet/parser/ast/resource_defaults.rb
index 3fde7ad..f0746ec 100644
--- a/lib/puppet/parser/ast/resource_defaults.rb
+++ b/lib/puppet/parser/ast/resource_defaults.rb
@@ -12,7 +12,7 @@ class Puppet::Parser::AST
         # object type.
         def evaluate(scope)
             # Use a resource reference to canonize the type
-            ref = Puppet::Resource::Reference.new(@type, "whatever")
+            ref = Puppet::Resource.new(@type, "whatever")
             type = ref.type
             params = @params.safeevaluate(scope)
 
diff --git a/lib/puppet/parser/ast/resource_override.rb b/lib/puppet/parser/ast/resource_override.rb
index 5eac509..2d4f7a8 100644
--- a/lib/puppet/parser/ast/resource_override.rb
+++ b/lib/puppet/parser/ast/resource_override.rb
@@ -36,9 +36,7 @@ class Puppet::Parser::AST
             resource = [resource] unless resource.is_a?(Array)
 
             resource = resource.collect do |r|
-                res = Puppet::Parser::Resource.new(
-                    :type => r.type,
-                    :title => r.title,
+                res = Puppet::Parser::Resource.new(r.type, r.title,
                     :params => params,
                     :file => file,
                     :line => line,
diff --git a/lib/puppet/parser/ast/resource_reference.rb b/lib/puppet/parser/ast/resource_reference.rb
index 794e505..8e09a8e 100644
--- a/lib/puppet/parser/ast/resource_reference.rb
+++ b/lib/puppet/parser/ast/resource_reference.rb
@@ -1,76 +1,23 @@
+require 'puppet/parser/ast'
 require 'puppet/parser/ast/branch'
+require 'puppet/resource'
 
-class Puppet::Parser::AST
-    # A reference to an object.  Only valid as an rvalue.
-    class ResourceReference < AST::Branch
-        attr_accessor :title, :type
-        # Is the type a builtin type?
-        def builtintype?(type)
-            if typeklass = Puppet::Type.type(type)
-                return typeklass
-            else
-                return false
-            end
-        end
-
-        def each
-            [@type, at title].flatten.each { |param|
-                #Puppet.debug("yielding param %s" % param)
-                yield param
-            }
-        end
+class Puppet::Parser::AST::ResourceReference < Puppet::Parser::AST::Branch
+    attr_accessor :title, :type
 
-        # Evaluate our object, but just return a simple array of the type
-        # and name.
-        def evaluate(scope)
-            title = @title.safeevaluate(scope)
-            title = [title] unless title.is_a?(Array)
-
-            if @type.to_s.downcase == "class"
-                resource_type = "class"
-                title = title.collect { |t| qualified_class(scope, t) }
-            else
-                resource_type = qualified_type(scope)
-            end
-
-            title = title.collect { |t| Puppet::Parser::Resource::Reference.new(
-                :type => resource_type, :title => t
-            ) }
-            return title.pop if title.length == 1
-            return title
-        end
-
-        # Look up a fully qualified class name.
-        def qualified_class(scope, title)
-            # Look up the full path to the class
-            if classobj = scope.find_hostclass(title)
-                title = classobj.name
-            else
-                raise Puppet::ParseError, "Could not find class %s" % title
-            end
-        end
-
-        # Look up a fully-qualified type.  This method is
-        # also used in AST::Resource.
-        def qualified_type(scope, title = nil)
-            # We want a lower-case type.  For some reason.
-            objtype = @type.downcase
-            unless builtintype?(objtype)
-                if dtype = scope.find_definition(objtype)
-                    objtype = dtype.name
-                else
-                    raise Puppet::ParseError, "Could not find resource type %s" % objtype
-                end
-            end
-            return objtype
-        end
+    # Evaluate our object, but just return a simple array of the type
+    # and name.
+    def evaluate(scope)
+        titles = Array(title.safeevaluate(scope)).collect { |t| Puppet::Resource.new(type, t, :namespaces => scope.namespaces) }
+        return titles.pop if titles.length == 1
+        return titles
+    end
 
-        def to_s
-            if title.is_a?(ASTArray)
-                "#{type.to_s.capitalize}#{title}"
-            else
-                "#{type.to_s.capitalize}[#{title}]"
-            end
+    def to_s
+        if title.is_a?(Puppet::Parser::AST::ASTArray)
+            "#{type.to_s.capitalize}#{title}"
+        else
+            "#{type.to_s.capitalize}[#{title}]"
         end
     end
 end
diff --git a/lib/puppet/parser/collector.rb b/lib/puppet/parser/collector.rb
index a6763c4..0445187 100644
--- a/lib/puppet/parser/collector.rb
+++ b/lib/puppet/parser/collector.rb
@@ -75,7 +75,7 @@ class Puppet::Parser::Collector
         @collected = {}
 
         # Canonize the type
-        @type = Puppet::Resource::Reference.new(type, "whatever").type
+        @type = Puppet::Resource.new(type, "whatever").type
         @equery = equery
         @vquery = vquery
 
diff --git a/lib/puppet/parser/compiler.rb b/lib/puppet/parser/compiler.rb
index c669076..8e84f5a 100644
--- a/lib/puppet/parser/compiler.rb
+++ b/lib/puppet/parser/compiler.rb
@@ -275,9 +275,9 @@ class Puppet::Parser::Compiler
 
     # Find and evaluate our main object, if possible.
     def evaluate_main
-        @main = known_resource_types.find_hostclass("", "") || known_resource_types.add(Puppet::Resource::Type.new(:hostclass, ""))
+        @main = known_resource_types.find_hostclass([""], "") || known_resource_types.add(Puppet::Resource::Type.new(:hostclass, ""))
         @topscope.source = @main
-        @main_resource = Puppet::Parser::Resource.new(:type => "class", :title => :main, :scope => @topscope, :source => @main)
+        @main_resource = Puppet::Parser::Resource.new("class", :main, :scope => @topscope, :source => @main)
         @topscope.resource = @main_resource
 
         @resources << @main_resource
diff --git a/lib/puppet/parser/functions/defined.rb b/lib/puppet/parser/functions/defined.rb
index 5ad74a7..4d1d8c6 100644
--- a/lib/puppet/parser/functions/defined.rb
+++ b/lib/puppet/parser/functions/defined.rb
@@ -6,21 +6,21 @@ Puppet::Parser::Functions::newfunction(:defined, :type => :rvalue, :doc => "Dete
     (e.g., ``if defined(File['/tmp/myfile']) { ... }``).  This function is unfortunately
     dependent on the parse order of the configuration when testing whether a resource is defined.") do |vals|
         result = false
+        vals = [vals] unless vals.is_a?(Array)
         vals.each do |val|
             case val
             when String
-                # For some reason, it doesn't want me to return from here.
                 if Puppet::Type.type(val) or find_definition(val) or find_hostclass(val)
                     result = true
                     break
                 end
-            when Puppet::Parser::Resource::Reference
+            when Puppet::Resource
                 if findresource(val.to_s)
                     result = true
                     break
                 end
             else
-                raise ArgumentError, "Invalid argument of type %s to 'defined'" % val.class
+                raise ArgumentError, "Invalid argument of type '#{val.class}' to 'defined'"
             end
         end
         result
diff --git a/lib/puppet/parser/functions/require.rb b/lib/puppet/parser/functions/require.rb
index 66d60b9..294484a 100644
--- a/lib/puppet/parser/functions/require.rb
+++ b/lib/puppet/parser/functions/require.rb
@@ -49,7 +49,7 @@ fail if used with earlier clients.
             # The 'obvious' way is just to add an edge in the catalog,
             # but that is considered a containment edge, not a dependency
             # edge, so it usually gets lost on the client.
-            ref = Puppet::Parser::Resource::Reference.new(:type => :class, :title => klass)
+            ref = Puppet::Resource.new(:class, klass)
             resource.set_parameter(:require, [resource[:require]].flatten.compact << ref)
         end
     end
diff --git a/lib/puppet/parser/parser_support.rb b/lib/puppet/parser/parser_support.rb
index e6bc46b..d43b0d3 100644
--- a/lib/puppet/parser/parser_support.rb
+++ b/lib/puppet/parser/parser_support.rb
@@ -388,15 +388,4 @@ class Puppet::Parser::Parser
     def watch_file(filename)
         known_resource_types.watch_file(filename)
     end
-
-    private
-
-    def check_and_add_to_watched_files(filename)
-        unless @files.include?(filename)
-            @files[filename] = Puppet::Util::LoadedFile.new(filename)
-            return true
-        else
-            return false
-        end
-    end
 end
diff --git a/lib/puppet/parser/resource.rb b/lib/puppet/parser/resource.rb
index 428b9df..36f1fbe 100644
--- a/lib/puppet/parser/resource.rb
+++ b/lib/puppet/parser/resource.rb
@@ -1,8 +1,11 @@
-# A resource that we're managing.  This handles making sure that only subclasses
-# can set parameters.
-class Puppet::Parser::Resource
+require 'puppet/resource'
+
+# The primary difference between this class and its
+# parent is that this class has rules on who can set
+# parameters
+class Puppet::Parser::Resource < Puppet::Resource
     require 'puppet/parser/resource/param'
-    require 'puppet/parser/resource/reference'
+    require 'puppet/resource'
     require 'puppet/util/tagging'
     require 'puppet/file_collection/lookup'
     require 'puppet/parser/yaml_trimmer'
@@ -29,15 +32,8 @@ class Puppet::Parser::Resource
         @relationship_names.include?(name)
     end
 
-    # Proxy a few methods to our @ref object.
-    [:builtin?, :type, :title].each do |method|
-        define_method(method) do
-            @ref.send(method)
-        end
-    end
-
     # Set up some boolean test methods
-    [:exported, :translated, :override, :virtual, :evaluated].each do |method|
+    [:translated, :override, :evaluated].each do |method|
         newmeth = (method.to_s + "?").intern
         define_method(newmeth) do
             self.send(method)
@@ -60,25 +56,25 @@ class Puppet::Parser::Resource
         set_parameter(param, value)
     end
 
-    def builtin=(bool)
-        @ref.builtin = bool
-    end
-
     def eachparam
         @params.each do |name, param|
             yield param
         end
     end
 
+    def environment
+        scope.environment
+    end
+
     # Retrieve the associated definition and evaluate it.
     def evaluate
-        if klass = @ref.definedtype
+        if klass = resource_type and ! builtin_type?
             finish()
             return klass.evaluate_code(self)
         elsif builtin?
-            devfail "Cannot evaluate a builtin type"
+            devfail "Cannot evaluate a builtin type (#{type})"
         else
-            self.fail "Cannot find definition %s" % self.type
+            self.fail "Cannot find definition #{type}"
         end
     ensure
         @evaluated = true
@@ -111,61 +107,41 @@ class Puppet::Parser::Resource
         defined?(@finished) and @finished
     end
 
-    def initialize(options)
+    def initialize(type, title, options)
+        self.type = type
+        self.title = title
+
+        @params = {}
+        # Define all of the parameters
+        if params = options[:params]
+            extract_parameters(params)
+            options.delete(:params)
+        end
+
         # Set all of the options we can.
         options.each do |option, value|
             if respond_to?(option.to_s + "=")
                 send(option.to_s + "=", value)
                 options.delete(option)
+            else
+                raise ArgumentError, "Resources do not accept #{option}"
             end
         end
 
         unless self.scope
             raise ArgumentError, "Resources require a scope"
         end
-        @source ||= scope.source
-
-        options = symbolize_options(options)
-
-        # Set up our reference.
-        if type = options[:type] and title = options[:title]
-            options.delete(:type)
-            options.delete(:title)
-        else
-            raise ArgumentError, "Resources require a type and title"
-        end
-
-        @ref = Reference.new(:type => type, :title => title, :scope => self.scope)
-
-        @params = {}
-
-        # Define all of the parameters
-        if params = options[:params]
-            options.delete(:params)
-            params.each do |param|
-                # Don't set the same parameter twice
-                if @params[param.name]
-                    self.fail Puppet::ParseError, "Duplicate parameter '%s' for on %s" %
-                        [param.name, self.to_s]
-                end
-
-                set_parameter(param)
-            end
-        end
 
-        # Throw an exception if we've got any arguments left to set.
-        unless options.empty?
-            raise ArgumentError, "Resources do not accept %s" % options.keys.collect { |k| k.to_s }.join(", ")
-        end
+        @source ||= scope.source
 
-        tag(@ref.type)
-        tag(@ref.title) if valid_tag?(@ref.title.to_s)
+        tag(self.type)
+        tag(self.title) if valid_tag?(self.title.to_s)
     end
 
     # Is this resource modeling an isomorphic resource type?
     def isomorphic?
-        if builtin?
-            return @ref.builtintype.isomorphic?
+        if builtin_type?
+            return resource_type.isomorphic?
         else
             return true
         end
@@ -199,12 +175,8 @@ class Puppet::Parser::Resource
         @name
     end
 
-    # This *significantly* reduces the number of calls to Puppet.[].
-    def paramcheck?
-        unless defined? @@paramcheck
-            @@paramcheck = Puppet[:paramcheck]
-        end
-        @@paramcheck
+    def namespaces
+        scope.namespaces
     end
 
     # A temporary occasion, until I get paths in the scopes figured out.
@@ -212,11 +184,6 @@ class Puppet::Parser::Resource
         to_s
     end
 
-    # Return the short version of our name.
-    def ref
-        @ref.to_s
-    end
-
     # Define a parameter in our resource.
     # if we ever receive a parameter named 'tag', set
     # the resource tags with its value.
@@ -254,16 +221,16 @@ class Puppet::Parser::Resource
         result = Puppet::Resource.new(type, title)
 
         to_hash.each do |p, v|
-            if v.is_a?(Puppet::Parser::Resource::Reference)
-                v = Puppet::Resource::Reference.new(v.type, v.title)
+            if v.is_a?(Puppet::Resource)
+                v = Puppet::Resource.new(v.type, v.title)
             elsif v.is_a?(Array)
                 # flatten resource references arrays
-                if v.flatten.find { |av| av.is_a?(Puppet::Parser::Resource::Reference) }
+                if v.flatten.find { |av| av.is_a?(Puppet::Resource) }
                     v = v.flatten
                 end
                 v = v.collect do |av|
-                    if av.is_a?(Puppet::Parser::Resource::Reference)
-                        av = Puppet::Resource::Reference.new(av.type, av.title)
+                    if av.is_a?(Puppet::Resource)
+                        av = Puppet::Resource.new(av.type, av.title)
                     end
                     av
                 end
@@ -289,10 +256,6 @@ class Puppet::Parser::Resource
         return result
     end
 
-    def to_s
-        self.ref
-    end
-
     # Translate our object to a transportable object.
     def to_trans
         return nil if virtual?
@@ -389,28 +352,26 @@ class Puppet::Parser::Resource
         set_parameter(param)
     end
 
-    # Verify that all passed parameters are valid.  This throws an error if
-    #  there's a problem, so we don't have to worry about the return value.
-    def paramcheck(param)
-        param = param.to_s
-        # Now make sure it's a valid argument to our class.  These checks
-        # are organized in order of commonhood -- most types, it's a valid
-        # argument and paramcheck is enabled.
-        if @ref.typeclass.valid_parameter?(param)
-            true
-        elsif %w{name title}.include?(param) # always allow these
-            true
-        elsif paramcheck?
-            self.fail Puppet::ParseError, "Invalid parameter '%s' for type '%s'" %
-                    [param, @ref.type]
-        end
-    end
-
     # Make sure the resource's parameters are all valid for the type.
     def validate
         @params.each do |name, param|
-            # Make sure it's a valid parameter.
-            paramcheck(name)
+            validate_parameter(name)
+        end
+    rescue => detail
+        fail Puppet::ParseError, detail.to_s
+    end
+
+    private
+
+    def extract_parameters(params)
+        params.each do |param|
+            # Don't set the same parameter twice
+            if @params[param.name]
+                self.fail Puppet::ParseError, "Duplicate parameter '%s' for on %s" %
+                    [param.name, self.to_s]
+            end
+
+            set_parameter(param)
         end
     end
 end
diff --git a/lib/puppet/parser/resource/reference.rb b/lib/puppet/parser/resource/reference.rb
deleted file mode 100644
index ac1c79a..0000000
--- a/lib/puppet/parser/resource/reference.rb
+++ /dev/null
@@ -1,103 +0,0 @@
-# A reference to a resource.  Mostly just the type and title.
-require 'puppet/resource/reference'
-require 'puppet/file_collection/lookup'
-require 'puppet/parser/yaml_trimmer'
-
-require 'puppet/resource/type_collection_helper'
-
-# A reference to a resource.  Mostly just the type and title.
-class Puppet::Parser::Resource::Reference < Puppet::Resource::Reference
-    include Puppet::Parser::YamlTrimmer
-    include Puppet::FileCollection::Lookup
-    include Puppet::Util::MethodHelper
-    include Puppet::Util::Errors
-    include Puppet::Resource::TypeCollectionHelper
-
-    attr_accessor :builtin, :file, :line, :scope
-
-    # Are we a builtin type?
-    def builtin?
-        unless defined? @builtin
-            if builtintype()
-                @builtin = true
-            else
-                @builtin = false
-            end
-        end
-
-        @builtin
-    end
-
-    def builtintype
-        if t = Puppet::Type.type(self.type.downcase) and t.name != :component
-            t
-        else
-            nil
-        end
-    end
-
-    # Return the defined type for our obj.  This can return classes,
-    # definitions or nodes.
-    def definedtype
-        unless defined? @definedtype
-            case self.type
-            when "Class" # look for host classes
-                name = self.title == :main ? "" : self.title
-                unless tmp = known_resource_types.find_hostclass("", name)
-                    fail Puppet::ParseError, "Could not find '#{title}' class"
-                end
-            when "Node" # look for node definitions
-                unless tmp = known_resource_types.node(self.title)
-                    fail Puppet::ParseError, "Could not find node '%s'" % self.title
-                end
-            else # normal definitions
-                # The resource type is capitalized, so we have to downcase.  Really,
-                # we should have a better interface for finding these, but eh.
-                tmp = known_resource_types.definition(self.type.downcase)
-            end
-
-            if tmp
-                @definedtype = tmp
-            else
-                fail Puppet::ParseError, "Could not find resource type '%s'" % self.type
-            end
-        end
-
-        @definedtype
-    end
-
-    def environment
-        scope.environment
-    end
-
-    def initialize(hash)
-        set_options(hash)
-        requiredopts(:type, :title)
-    end
-
-    def skip_for_yaml
-        %w{@typeclass @definedtype}
-    end
-
-    def to_ref
-        # We have to return different cases to provide backward compatibility
-        # from 0.24.x to 0.23.x.
-        if builtin?
-            return [type.to_s.downcase, title.to_s]
-        else
-            return [type.to_s, title.to_s]
-        end
-    end
-
-    def typeclass
-        unless defined? @typeclass
-            if tmp = builtintype || definedtype
-                @typeclass = tmp
-            else
-                fail Puppet::ParseError, "Could not find type %s" % self.type
-            end
-        end
-
-        @typeclass
-    end
-end
diff --git a/lib/puppet/rails/param_value.rb b/lib/puppet/rails/param_value.rb
index b298924..d0bb8d7 100644
--- a/lib/puppet/rails/param_value.rb
+++ b/lib/puppet/rails/param_value.rb
@@ -23,7 +23,7 @@ class Puppet::Rails::ParamValue < ActiveRecord::Base
     def self.munge_parser_values(value)
         values = value.is_a?(Array) ? value : [value]
         values.map do |v|
-            if v.is_a?(Puppet::Resource::Reference)
+            if v.is_a?(Puppet::Resource)
                 v
             else
                 v.to_s
diff --git a/lib/puppet/resource.rb b/lib/puppet/resource.rb
index 010cd95..ec1fd2e 100644
--- a/lib/puppet/resource.rb
+++ b/lib/puppet/resource.rb
@@ -5,7 +5,6 @@ require 'puppet/util/pson'
 # The simplest resource class.  Eventually it will function as the
 # base class for all resource-like behaviour.
 class Puppet::Resource
-    require 'puppet/resource/reference'
     include Puppet::Util::Tagging
 
     require 'puppet/resource/type_collection_helper'
@@ -13,8 +12,8 @@ class Puppet::Resource
 
     extend Puppet::Util::Pson
     include Enumerable
-    attr_accessor :file, :line, :catalog, :exported, :virtual, :namespace, :validate_parameters
-    attr_writer :type, :title, :environment
+    attr_accessor :file, :line, :catalog, :exported, :virtual, :validate_parameters
+    attr_reader :type, :title, :namespaces
 
     require 'puppet/indirector'
     extend Puppet::Indirector
@@ -95,6 +94,13 @@ class Puppet::Resource
         @parameters[parameter_name(param)]
     end
 
+    def ==(other)
+        return false unless other.respond_to?(:title) and self.type == other.type and self.title == other.title
+
+        return false unless to_hash == other.to_hash
+        true
+    end
+
     # Compatibility method.
     def builtin?
         builtin_type?
@@ -102,7 +108,7 @@ class Puppet::Resource
 
     # Is this a builtin resource type?
     def builtin_type?
-        @reference.builtin_type?
+        resource_type.is_a?(Class)
     end
 
     # Iterate over each param/value pair, as required for Enumerable.
@@ -114,6 +120,23 @@ class Puppet::Resource
         super || @parameters.keys.include?( parameter_name(parameter) )
     end
 
+    # These two methods are extracted into a Helper
+    # module, but file load order prevents me
+    # from including them in the class, and I had weird
+    # behaviour (i.e., sometimes it didn't work) when
+    # I directly extended each resource with the helper.
+    def environment
+        Puppet::Node::Environment.new(@environment)
+    end
+
+    def environment=(env)
+        if env.is_a?(String) or env.is_a?(Symbol)
+            @environment = env
+        else
+            @environment = env.name
+        end
+    end
+
     %w{exported virtual}.each do |m|
         define_method(m+"?") do
             self.send(m)
@@ -121,14 +144,11 @@ class Puppet::Resource
     end
 
     # Create our resource.
-    def initialize(type, title, attributes = {})
-        # Doing this, instead of including it in the class,
-        # is the only way I could get the load order to work
-        # here.
-        extend Puppet::Node::Environment::Helper
+    def initialize(type, title = nil, attributes = {})
+        self.type, self.title = extract_type_and_title(type, title)
 
         @parameters = {}
-        @namespace = ""
+        @namespaces = [""]
 
         (attributes[:parameters] || {}).each do |param, value|
             self[param] = value
@@ -139,15 +159,25 @@ class Puppet::Resource
             send(attr.to_s + "=", value)
         end
 
-        @reference = Puppet::Resource::Reference.new(type, title)
-
-        tag(@reference.type)
-        tag(@reference.title) if valid_tag?(@reference.title)
+        tag(self.type)
+        tag(self.title) if valid_tag?(self.title)
     end
 
-    # Provide a reference to our resource in the canonical form.
     def ref
-        @reference.to_s
+        to_s
+    end
+
+    # Find our resource.
+    def resolve
+        return catalog.resource(to_s) if catalog
+        return nil
+    end
+
+    def title=(value)
+        if @type and klass = Puppet::Type.type(@type.to_s.downcase)
+            value = klass.canonicalize_ref(value)
+        end
+        @title = value
     end
 
     def resource_type
@@ -159,16 +189,6 @@ class Puppet::Resource
         end
     end
 
-    # Get our title information from the reference, since it will canonize it for us.
-    def title
-        @reference.title
-    end
-
-    # Get our type information from the reference, since it will canonize it for us.
-    def type
-        @reference.type
-    end
-
     # Produce a simple hash of our parameters.
     def to_hash
         result = @parameters.dup
@@ -179,7 +199,7 @@ class Puppet::Resource
     end
 
     def to_s
-        return ref
+        "#{type}[#{title}]"
     end
 
     # Convert our resource to Puppet code.
@@ -211,7 +231,7 @@ class Puppet::Resource
 
     # Translate our object to a backward-compatible transportable object.
     def to_trans
-        if @reference.builtin_type?
+        if builtin_type?
             result = to_transobject
         else
             result = to_transbucket
@@ -223,16 +243,20 @@ class Puppet::Resource
         return result
     end
 
+    def to_trans_ref
+        [type.to_s, title.to_s]
+    end
+
     # Create an old-style TransObject instance, for builtin resource types.
     def to_transobject
         # Now convert to a transobject
-        result = Puppet::TransObject.new(@reference.title, @reference.type)
+        result = Puppet::TransObject.new(title, type)
         to_hash.each do |p, v|
-            if v.is_a?(Puppet::Resource::Reference)
+            if v.is_a?(Puppet::Resource)
                 v = v.to_trans_ref
             elsif v.is_a?(Array)
                 v = v.collect { |av|
-                    if av.is_a?(Puppet::Resource::Reference)
+                    if av.is_a?(Puppet::Resource)
                         av = av.to_trans_ref
                     end
                     av
@@ -266,6 +290,15 @@ class Puppet::Resource
         self
     end
 
+    # Canonize the type so we know it's always consistent.
+    def type=(value)
+        if value.nil? or value.to_s.downcase == "component"
+            @type = "Class"
+        else
+            @type = value.to_s.split("::").collect { |s| s.capitalize }.join("::")
+        end
+    end
+
     def valid_parameter?(name)
         resource_type.valid_parameter?(name)
     end
@@ -282,7 +315,7 @@ class Puppet::Resource
 
     def find_hostclass
         name = title == :main ? "" : title
-        known_resource_types.find_hostclass(namespace, name)
+        known_resource_types.find_hostclass(namespaces, name)
     end
 
     def find_builtin_resource_type
@@ -290,7 +323,7 @@ class Puppet::Resource
     end
 
     def find_defined_resource_type
-        known_resource_types.find_definition(namespace, type.to_s.downcase)
+        known_resource_types.find_definition(namespaces, type.to_s.downcase)
     end
 
     # Produce a canonical method name.
@@ -302,10 +335,14 @@ class Puppet::Resource
         param
     end
 
+    def namespaces=(ns)
+        @namespaces = Array(ns)
+    end
+
     # The namevar for our resource type. If the type doesn't exist,
     # always use :name.
     def namevar
-        if t = resource_type
+        if builtin_type? and t = resource_type
             t.namevar
         else
             :name
@@ -322,4 +359,14 @@ class Puppet::Resource
         # TransBuckets don't support parameters, which is why they're being deprecated.
         return bucket
     end
+
+    private
+
+    def extract_type_and_title(argtype, argtitle)
+	    if    (argtitle || argtype) =~ /^([^\[\]]+)\[(.+)\]$/m then [ $1,                 $2            ]
+	    elsif argtitle                                         then [ argtype,            argtitle      ]
+	    elsif argtype.is_a?(Puppet::Type)                      then [ argtype.class.name, argtype.title ]
+	    else raise ArgumentError, "No title provided and #{argtype.inspect} is not a valid resource reference"
+	    end
+    end
 end
diff --git a/lib/puppet/resource/catalog.rb b/lib/puppet/resource/catalog.rb
index 6e064a9..e63c00c 100644
--- a/lib/puppet/resource/catalog.rb
+++ b/lib/puppet/resource/catalog.rb
@@ -376,12 +376,12 @@ class Puppet::Resource::Catalog < Puppet::SimpleGraph
         # Always create a resource reference, so that it always canonizes how we
         # are referring to them.
         if title
-            ref = Puppet::Resource::Reference.new(type, title).to_s
+            ref = Puppet::Resource.new(type, title).to_s
         else
             # If they didn't provide a title, then we expect the first
             # argument to be of the form 'Class[name]', which our
             # Reference class canonizes for us.
-            ref = Puppet::Resource::Reference.new(nil, type).to_s
+            ref = Puppet::Resource.new(nil, type).to_s
         end
         @resource_table[ref]
     end
diff --git a/lib/puppet/resource/reference.rb b/lib/puppet/resource/reference.rb
deleted file mode 100644
index eddb2d9..0000000
--- a/lib/puppet/resource/reference.rb
+++ /dev/null
@@ -1,90 +0,0 @@
-#
-#  Created by Luke Kanies on 2007-11-28.
-#  Copyright (c) 2007. All rights reserved.
-
-require 'puppet'
-require 'puppet/resource'
-
-# A simple class to canonize how we refer to and retrieve
-# resources.
-class Puppet::Resource::Reference
-    attr_reader :type, :title
-    attr_accessor :catalog
-
-    def ==(other)
-        other.respond_to?(:title) and self.type == other.type and self.title == other.title
-    end
-
-    def builtin_type?
-        builtin_type ? true : false
-    end
-
-    def initialize(argtype, argtitle = nil)
-        self.type,self.title = 
-	    if    (argtitle || argtype) =~ /^([^\[\]]+)\[(.+)\]$/m then [ $1,                 $2            ]
-	    elsif argtitle                                         then [ argtype,            argtitle      ]
-	    elsif argtype.is_a?(Puppet::Type)                      then [ argtype.class.name, argtype.title ]
-	    else raise ArgumentError, "No title provided and #{argtype.inspect} is not a valid resource reference"
-	    end
-        @builtin_type = nil
-    end
-
-    # Find our resource.
-    def resolve
-        return catalog.resource(to_s) if catalog
-        return nil
-    end
-
-    def title=(value)
-        if @type and klass = Puppet::Type.type(@type.to_s.downcase)
-            value = klass.canonicalize_ref(value)
-        end
-        @title = value
-    end
-
-    # Canonize the type so we know it's always consistent.
-    def type=(value)
-        if value.nil? or value.to_s.downcase == "component"
-            @type = "Class"
-        else
-            # LAK:NOTE See http://snurl.com/21zf8  [groups_google_com]
-            x = @type = value.to_s.split("::").collect { |s| s.capitalize }.join("::")
-        end
-
-        if @title
-            self.title = @title
-        end
-    end
-
-    # Convert to the reference format that TransObject uses.  Yay backward
-    # compatibility.
-    def to_trans_ref
-        # We have to return different cases to provide backward compatibility
-        # from 0.24.x to 0.23.x.
-        if builtin_type?
-            return [type.to_s.downcase, title.to_s]
-        else
-            return [type.to_s, title.to_s]
-        end
-    end
-
-    # Convert to the standard way of referring to resources.
-    def to_s
-        "%s[%s]" % [@type, @title]
-    end
-
-    private
-
-    def builtin_type
-        if @builtin_type.nil?
-            if @type =~ /::/
-                @builtin_type = false
-            elsif klass = Puppet::Type.type(@type.to_s.downcase)
-                @builtin_type = true
-            else
-                @builtin_type = false
-            end
-        end
-        @builtin_type
-    end
-end
diff --git a/lib/puppet/resource/type.rb b/lib/puppet/resource/type.rb
index d476582..c615a2c 100644
--- a/lib/puppet/resource/type.rb
+++ b/lib/puppet/resource/type.rb
@@ -60,11 +60,11 @@ class Puppet::Resource::Type
 
     # Add code from a new instance to our code.
     def merge(other)
-        fail ArgumentError, "#{name} is not a class; cannot add code to it" unless type == :hostclass
-        fail ArgumentError, "#{other.name} is not a class; cannot add code from it" unless other.type == :hostclass
+        fail "#{name} is not a class; cannot add code to it" unless type == :hostclass
+        fail "#{other.name} is not a class; cannot add code from it" unless other.type == :hostclass
 
         if parent and other.parent and parent != other.parent
-            fail ArgumentError, "Cannot merge classes with different parent classes"
+            fail "Cannot merge classes with different parent classes (#{name} => #{parent} vs. #{other.name} => #{other.parent})"
         end
 
         # We know they're either equal or only one is set, so keep whichever parent is specified.
@@ -114,7 +114,7 @@ class Puppet::Resource::Type
             return resource
         end
 
-        resource = Puppet::Parser::Resource.new(:type => resource_type, :title => name, :scope => scope, :source => self)
+        resource = Puppet::Parser::Resource.new(resource_type, name, :scope => scope, :source => self)
         scope.compiler.add_resource(scope, resource)
         scope.catalog.tag(*resource.tags)
         resource
diff --git a/lib/puppet/resource/type_collection.rb b/lib/puppet/resource/type_collection.rb
index a0bd2dd..e2ca562 100644
--- a/lib/puppet/resource/type_collection.rb
+++ b/lib/puppet/resource/type_collection.rb
@@ -1,6 +1,12 @@
 class Puppet::Resource::TypeCollection
     attr_reader :environment
 
+    def clear
+        @hostclasses.clear
+        @definitions.clear
+        @nodes.clear
+    end
+
     def initialize(env)
         @environment = env.is_a?(String) ? Puppet::Node::Environment.new(env) : env
         @hostclasses = {}
@@ -19,6 +25,10 @@ class Puppet::Resource::TypeCollection
     end
 
     def add(instance)
+        if instance.type == :hostclass and other = @hostclasses[instance.name] and other.type == :hostclass
+            other.merge(instance)
+            return other
+        end
         method = "add_#{instance.type}"
         send(method, instance)
         instance.code_collection = self
@@ -26,8 +36,8 @@ class Puppet::Resource::TypeCollection
     end
 
     def add_hostclass(instance)
-        dupe_check(instance, @hostclasses) { |dupe| "Class #{instance.name} is already defined#{dupe.error_context}; cannot redefine" }
-        dupe_check(instance, @definitions) { |dupe| "Definition #{instance.name} is already defined#{dupe.error_context}; cannot be redefined as a class" }
+        dupe_check(instance, @hostclasses) { |dupe| "Class '#{instance.name}' is already defined#{dupe.error_context}; cannot redefine" }
+        dupe_check(instance, @definitions) { |dupe| "Definition '#{instance.name}' is already defined#{dupe.error_context}; cannot be redefined as a class" }
 
         @hostclasses[instance.name] = instance
         instance
@@ -38,7 +48,7 @@ class Puppet::Resource::TypeCollection
     end
 
     def add_node(instance)
-        dupe_check(instance, @nodes) { |dupe| "Node #{instance.name} is already defined#{dupe.error_context}; cannot redefine" }
+        dupe_check(instance, @nodes) { |dupe| "Node '#{instance.name}' is already defined#{dupe.error_context}; cannot redefine" }
 
         @node_list << instance
         @nodes[instance.name] = instance
@@ -67,8 +77,10 @@ class Puppet::Resource::TypeCollection
         @nodes.length > 0
     end
 
-    def add_definition(code)
-        @definitions[code.name] = code
+    def add_definition(instance)
+        dupe_check(instance, @hostclasses) { |dupe| "'#{instance.name}' is already defined#{dupe.error_context} as a class; cannot redefine as a definition" }
+        dupe_check(instance, @definitions) { |dupe| "Definition '#{instance.name}' is already defined#{dupe.error_context}; cannot be redefined" }
+        @definitions[instance.name] = instance
     end
 
     def definition(name)
@@ -76,12 +88,13 @@ class Puppet::Resource::TypeCollection
     end
 
     def find(namespaces, name, type)
+        #Array("") == [] for some reason
+        namespaces = [namespaces] unless namespaces.is_a?(Array)
+
         if r = find_fully_qualified(name, type)
             return r
         end
 
-        namespaces = Array(namespaces)
-
         namespaces.each do |namespace|
             ary = namespace.split("::")
 
diff --git a/lib/puppet/transportable.rb b/lib/puppet/transportable.rb
index 1970d9f..c488170 100644
--- a/lib/puppet/transportable.rb
+++ b/lib/puppet/transportable.rb
@@ -1,5 +1,5 @@
 require 'puppet'
-require 'puppet/resource/reference'
+require 'puppet/resource'
 require 'yaml'
 
 module Puppet
@@ -36,7 +36,7 @@ module Puppet
 
         def ref
             unless defined? @ref
-                @ref = Puppet::Resource::Reference.new(@type, @name)
+                @ref = Puppet::Resource.new(@type, @name)
             end
             @ref.to_s
         end
@@ -225,11 +225,11 @@ module Puppet
         def to_ref
             unless defined? @ref
                 if self.type and self.name
-                    @ref = Puppet::Resource::Reference.new(self.type, self.name)
+                    @ref = Puppet::Resource.new(self.type, self.name)
                 elsif self.type and ! self.name # This is old-school node types
-                    @ref = Puppet::Resource::Reference.new("node", self.type)
+                    @ref = Puppet::Resource.new("node", self.type)
                 elsif ! self.type and self.name
-                    @ref = Puppet::Resource::Reference.new("component", self.name)
+                    @ref = Puppet::Resource.new("component", self.name)
                 else
                     @ref = nil
                 end
@@ -244,7 +244,7 @@ module Puppet
         # Create a normalized resource from our TransObject.
         def to_resource
             params = defined?(@parameters) ? @parameters.dup : {}
-            Puppet::Resource.new(type, name, params)
+            Puppet::Resource.new(type, name, :parameters => params)
         end
 
         def param(param,value)
diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb
index 31728c3..ee545a9 100644
--- a/lib/puppet/type.rb
+++ b/lib/puppet/type.rb
@@ -9,7 +9,7 @@ require 'puppet/metatype/manager'
 require 'puppet/util/errors'
 require 'puppet/util/log_paths'
 require 'puppet/util/logging'
-require 'puppet/resource/reference'
+require 'puppet/resource'
 require 'puppet/util/cacher'
 require 'puppet/file_collection/lookup'
 require 'puppet/util/tagging'
@@ -1231,10 +1231,10 @@ class Type
         def munge(references)
             references = [references] unless references.is_a?(Array)
             references.collect do |ref|
-                if ref.is_a?(Puppet::Resource::Reference)
+                if ref.is_a?(Puppet::Resource)
                     ref
                 else
-                    Puppet::Resource::Reference.new(ref)
+                    Puppet::Resource.new(ref)
                 end
             end
         end
diff --git a/lib/puppet/type/component.rb b/lib/puppet/type/component.rb
index bf9007a..d16cdda 100644
--- a/lib/puppet/type/component.rb
+++ b/lib/puppet/type/component.rb
@@ -65,7 +65,7 @@ Puppet::Type.newtype(:component) do
     end
 
     def title=(str)
-        @reference = Puppet::Resource::Reference.new(str)
+        @reference = Puppet::Resource.new(str)
     end
 
     def refresh
diff --git a/lib/puppet/type/tidy.rb b/lib/puppet/type/tidy.rb
index 830f476..c912ad3 100755
--- a/lib/puppet/type/tidy.rb
+++ b/lib/puppet/type/tidy.rb
@@ -275,9 +275,9 @@ Puppet::Type.newtype(:tidy) do
             dir = File.dirname(path)
             next unless resource = files_by_name[dir]
             if resource[:require]
-                resource[:require] << Puppet::Resource::Reference.new(:file, path)
+                resource[:require] << Puppet::Resource.new(:file, path)
             else
-                resource[:require] = [Puppet::Resource::Reference.new(:file, path)]
+                resource[:require] = [Puppet::Resource.new(:file, path)]
             end
         end
 
diff --git a/lib/puppet/util/settings.rb b/lib/puppet/util/settings.rb
index f50d466..e3f95d8 100644
--- a/lib/puppet/util/settings.rb
+++ b/lib/puppet/util/settings.rb
@@ -5,7 +5,6 @@ require 'puppet/external/event-loop'
 require 'puppet/util/cacher'
 require 'puppet/util/loadedfile'
 require 'puppet/resource'
-require 'puppet/resource/reference'
 
 # The class for handling configuration files.
 class Puppet::Util::Settings
diff --git a/spec/integration/application/puppet.rb b/spec/integration/application/puppet.rb
index 1342f3c..cfafc9c 100755
--- a/spec/integration/application/puppet.rb
+++ b/spec/integration/application/puppet.rb
@@ -14,7 +14,7 @@ describe "Puppet" do
         it "should be able to apply catalogs provided in a file in pson" do
             file_to_create = tmpfile("pson_catalog")
             catalog = Puppet::Resource::Catalog.new
-            resource = Puppet::Resource.new(:file, file_to_create, :content => "my stuff")
+            resource = Puppet::Resource.new(:file, file_to_create, :parameters => {:content => "my stuff"})
             catalog.add_resource resource
 
             manifest = tmpfile("manifest")
diff --git a/spec/integration/indirector/catalog/compiler.rb b/spec/integration/indirector/catalog/compiler.rb
index 16102ca..b4067a6 100755
--- a/spec/integration/indirector/catalog/compiler.rb
+++ b/spec/integration/indirector/catalog/compiler.rb
@@ -8,6 +8,7 @@ Puppet::Resource::Catalog.indirection.terminus(:compiler)
 
 describe Puppet::Resource::Catalog::Compiler do
     before do
+        Facter.stubs(:value).returns "something"
         @catalog = Puppet::Resource::Catalog.new
 
         @one = Puppet::Resource.new(:file, "/one")
diff --git a/spec/unit/configurer.rb b/spec/unit/configurer.rb
index 9fc46af..48a197a 100755
--- a/spec/unit/configurer.rb
+++ b/spec/unit/configurer.rb
@@ -84,6 +84,7 @@ describe Puppet::Configurer, "when executing a catalog run" do
     before do
         Puppet.settings.stubs(:use).returns(true)
         @agent = Puppet::Configurer.new
+        @agent.stubs(:prepare)
         @agent.stubs(:facts_for_uploading).returns({})
         @agent.stubs(:retrieve_catalog).returns Puppet::Resource::Catalog.new
 
@@ -122,7 +123,7 @@ describe Puppet::Configurer, "when executing a catalog run" do
     it "should log a failure and do nothing if no catalog can be retrieved" do
         @agent.expects(:retrieve_catalog).returns nil
 
-        Puppet.expects(:err)
+        Puppet.expects(:err).with "Could not retrieve catalog; skipping run"
 
         @agent.run
     end
diff --git a/spec/unit/indirector/catalog/compiler.rb b/spec/unit/indirector/catalog/compiler.rb
index d11daaa..8339d18 100755
--- a/spec/unit/indirector/catalog/compiler.rb
+++ b/spec/unit/indirector/catalog/compiler.rb
@@ -11,7 +11,7 @@ describe Puppet::Resource::Catalog::Compiler do
     before do
         Puppet::Rails.stubs(:init)
         Facter.stubs(:to_hash).returns({})
-        Facter.stubs(:[]).returns(Facter::Util::Fact.new("something"))
+        Facter.stubs(:value).returns(Facter::Util::Fact.new("something"))
     end
 
     describe "when initializing" do
@@ -44,7 +44,7 @@ describe Puppet::Resource::Catalog::Compiler do
 
         describe "and storeconfigs is enabled" do
             before do
-                Puppet.settings[:storeconfigs] = true
+                Puppet.settings.expects(:value).with(:storeconfigs).returns true
             end
 
             it "should initialize Rails if it is available" do
@@ -141,11 +141,11 @@ describe Puppet::Resource::Catalog::Compiler do
 
     describe "when extracting facts from the request" do
         before do
+            Facter.stubs(:value).returns "something"
             @compiler = Puppet::Resource::Catalog::Compiler.new
             @request = stub 'request', :options => {}
 
             @facts = stub 'facts', :save => nil
-            Facter.stubs(:value).returns "something"
         end
 
         it "should do nothing if no facts are provided" do
diff --git a/spec/unit/parser/ast/resource.rb b/spec/unit/parser/ast/resource.rb
index b257cb1..391f4c7 100755
--- a/spec/unit/parser/ast/resource.rb
+++ b/spec/unit/parser/ast/resource.rb
@@ -9,16 +9,15 @@ describe Puppet::Parser::AST::Resource do
         @title = stub_everything 'title'
         @compiler = stub_everything 'compiler'
         @scope = Puppet::Parser::Scope.new(:compiler => @compiler)
-        @param1 = stub_everything 'parameter', :is_a? => true
         @scope.stubs(:resource).returns(stub_everything)
-        @params = ast::ASTArray.new( :children => [@param1])
-        @resource = ast::Resource.new(:title => @title, :type => "Resource", :params => @params )
+        @resource = ast::Resource.new(:title => @title, :type => "Resource", :params => ast::ASTArray.new(:children => []) )
         @resource.stubs(:qualified_type).returns("Resource")
-        Puppet::Parser::Resource.stubs(:new).returns(stub_everything)
     end
 
     it "should evaluate all its parameters" do
-        @param1.expects(:safeevaluate).with(@scope)
+        param = stub 'param'
+        param.expects(:safeevaluate).with(@scope).returns Puppet::Parser::Resource::Param.new(:name => "myparam", :value => "myvalue", :source => stub("source"))
+        @resource.stubs(:params).returns [param]
 
         @resource.evaluate(@scope)
     end
@@ -49,10 +48,10 @@ describe Puppet::Parser::AST::Resource do
         title_array.stubs(:flatten).returns([@title])
         titles.stubs(:safeevaluate).with(@scope).returns(title_array)
 
-        Puppet::Parser::Resource.expects(:new).with { |hash| hash[:title] == @title }
-
         @resource.title = titles
-        @resource.evaluate(@scope)
+        result = @resource.evaluate(@scope)
+        result[0].should be_instance_of(Puppet::Parser::Resource)
+        result[0].title.should == @title
     end
 
     it "should handover resources to the compiler" do
@@ -77,18 +76,18 @@ describe Puppet::Parser::AST::Resource do
 
         title_array.stubs(:flatten).returns([@title])
         titles.stubs(:safeevaluate).with(@scope).returns(title_array)
-        Puppet::Parser::Resource.stubs(:new).returns(resource)
 
-        @compiler.stubs(:add_resource).with(resource)
+        @compiler.stubs(:add_resource)
 
         @resource.title = titles
-        @resource.evaluate(@scope).should == [resource]
+        @resource.evaluate(@scope)[0].should be_instance_of(Puppet::Parser::Resource)
     end
 
     it "should generate virtual resources if it is virtual" do
         @resource.virtual = true
 
-        Puppet::Parser::Resource.expects(:new).with { |hash| hash[:virtual] == true }
+        result = @resource.evaluate(@scope)
+        result[0].should be_virtual
 
         @resource.evaluate(@scope)
     end
@@ -96,8 +95,8 @@ describe Puppet::Parser::AST::Resource do
     it "should generate virtual and exported resources if it is exported" do
         @resource.exported = true
 
-        Puppet::Parser::Resource.expects(:new).with { |hash| hash[:virtual] == true and hash[:exported] == true }
-
-        @resource.evaluate(@scope)
+        result = @resource.evaluate(@scope)
+        result[0].should be_virtual
+        result[0].should be_exported
     end
 end
diff --git a/spec/unit/parser/ast/resource_reference.rb b/spec/unit/parser/ast/resource_reference.rb
index 10d9678..ee42694 100755
--- a/spec/unit/parser/ast/resource_reference.rb
+++ b/spec/unit/parser/ast/resource_reference.rb
@@ -10,54 +10,31 @@ describe Puppet::Parser::AST::ResourceReference do
         @scope = Puppet::Parser::Scope.new()
     end
 
-    def newref(title, type)
+    def newref(type, title)
         title = stub 'title', :safeevaluate => title
         ref = Puppet::Parser::AST::ResourceReference.new(:type => type, :title => title)
     end
 
-    it "should evaluate correctly reference to builtin types" do
-        newref("/tmp/yay", "File").evaluate(@scope).to_s.should == "File[/tmp/yay]"
+    it "should correctly produce reference strings" do
+        newref("File", "/tmp/yay").evaluate(@scope).to_s.should == "File[/tmp/yay]"
     end
 
-    %{ "one::two" "one-two"}.each do |type|
-        it "should evaluate correctly reference to define" do
-            klass = stub 'klass', :title => "three", :name => type
-            @scope.stubs(:find_definition).returns(klass)
-        
-            newref("three", type).evaluate(@scope).to_ref.should == Puppet::Parser::Resource::Reference.new( :type => type, :title => "three" ).to_ref
-        end
+    it "should produce a single resource when the title evaluates to a string" do
+        newref("File", "/tmp/yay").evaluate(@scope).should == Puppet::Resource.new("file", "/tmp/yay")
     end
 
-    it "should be able to call qualified_class" do
-        klass = stub 'klass', :title => "three", :name => "one"
-        @scope.expects(:find_hostclass).with("one").returns(klass)
-        newref("three","class").qualified_class(@scope,"one").should == "one" 
-    end
-
-    it "should be able to find qualified classes when evaluating" do
-        klass = stub 'klass', :title => "one", :name => "one"
-        @scope.stubs(:find_hostclass).returns(klass)
-        
-        evaled = newref("one", "class").evaluate(@scope)
-        evaled.type.should == "Class"
-        evaled.title.should == "one"
-    end
-
-    it "should return an array of reference if given an array of titles" do
+    it "should return an array of resources if given an array of titles" do
         titles = mock 'titles', :safeevaluate => ["title1","title2"]
-        ref = ast::ResourceReference.new( :title => titles, :type => "Resource" )
-        ref.stubs(:qualified_type).with(@scope).returns("Resource")
-
-        ref.evaluate(@scope).should have(2).elements
+        ref = ast::ResourceReference.new( :title => titles, :type => "File" )
+        ref.evaluate(@scope).should == [
+            Puppet::Resource.new("file", "title1"),
+            Puppet::Resource.new("file", "title2")
+        ]
     end
 
-    it "should qualify class of all titles for Class resource references" do
-        titles = mock 'titles', :safeevaluate => ["title1","title2"]
-        ref = ast::ResourceReference.new( :title => titles, :type => "Class" )
-        ref.expects(:qualified_class).with(@scope,"title1").returns("class")
-        ref.expects(:qualified_class).with(@scope,"title2").returns("class")
-
-        ref.evaluate(@scope)
+    it "should pass its scope's namespaces to all created resource references" do
+        @scope.add_namespace "foo"
+        newref("File", "/tmp/yay").evaluate(@scope).namespaces.should == ["foo"]
     end
 
     it "should return a correct representation when converting to string" do
diff --git a/spec/unit/parser/collector.rb b/spec/unit/parser/collector.rb
index 7f88bf7..9c2d722 100755
--- a/spec/unit/parser/collector.rb
+++ b/spec/unit/parser/collector.rb
@@ -52,11 +52,10 @@ end
 describe Puppet::Parser::Collector, "when collecting specific virtual resources" do
     before do
         @scope = mock 'scope'
-        @resource_type = mock 'resource_type'
         @vquery = mock 'vquery'
         @equery = mock 'equery'
 
-        @collector = Puppet::Parser::Collector.new(@scope, @resource_type, @equery, @vquery, :virtual)
+        @collector = Puppet::Parser::Collector.new(@scope, "resource_type", @equery, @vquery, :virtual)
     end
 
     it "should not fail when it does not find any resources to collect" do
diff --git a/spec/unit/parser/compiler.rb b/spec/unit/parser/compiler.rb
index 333046c..6fd4d1f 100755
--- a/spec/unit/parser/compiler.rb
+++ b/spec/unit/parser/compiler.rb
@@ -174,10 +174,9 @@ describe Puppet::Parser::Compiler do
 
         it "should evaluate the main class if it exists" do
             compile_stub(:evaluate_main)
-            main_class = mock 'main_class'
+            main_class = @known_resource_types.add Puppet::Resource::Type.new(:hostclass, "")
             main_class.expects(:evaluate_code).with { |r| r.is_a?(Puppet::Parser::Resource) }
             @compiler.topscope.expects(:source=).with(main_class)
-            @known_resource_types.stubs(:find_hostclass).with("", "").returns(main_class)
 
             @compiler.compile
         end
@@ -185,7 +184,7 @@ describe Puppet::Parser::Compiler do
         it "should create a new, empty 'main' if no main class exists" do
             compile_stub(:evaluate_main)
             @compiler.compile
-            @known_resource_types.find_hostclass("", "").should be_instance_of(Puppet::Resource::Type)
+            @known_resource_types.find_hostclass([""], "").should be_instance_of(Puppet::Resource::Type)
         end
 
         it "should evaluate any node classes" do
@@ -252,7 +251,7 @@ describe Puppet::Parser::Compiler do
 
         it "should call finish() on all resources" do
             # Add a resource that does respond to :finish
-            resource = Puppet::Parser::Resource.new :scope => @scope, :type => "file", :title => "finish"
+            resource = Puppet::Parser::Resource.new "file", "finish", :scope => @scope
             resource.expects(:finish)
 
             @compiler.add_resource(@scope, resource)
@@ -268,12 +267,12 @@ describe Puppet::Parser::Compiler do
         it "should call finish() in add_resource order" do
             resources = sequence('resources')
 
-            resource1 = Puppet::Parser::Resource.new :scope => @scope, :type => "file", :title => "finish1"
+            resource1 = Puppet::Parser::Resource.new "file", "finish1", :scope => @scope
             resource1.expects(:finish).in_sequence(resources)
 
             @compiler.add_resource(@scope, resource1)
 
-            resource2 = Puppet::Parser::Resource.new :scope => @scope, :type => "file", :title => "finish2"
+            resource2 = Puppet::Parser::Resource.new "file", "finish2", :scope => @scope
             resource2.expects(:finish).in_sequence(resources)
 
             @compiler.add_resource(@scope, resource2)
diff --git a/spec/unit/parser/functions/defined.rb b/spec/unit/parser/functions/defined.rb
new file mode 100755
index 0000000..0da8c4a
--- /dev/null
+++ b/spec/unit/parser/functions/defined.rb
@@ -0,0 +1,50 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe "the 'defined' function" do
+
+    before :each do
+        @scope = Puppet::Parser::Scope.new()
+        @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foo"))
+        @scope.compiler = @compiler
+    end
+
+    it "should exist" do
+        Puppet::Parser::Functions.function("defined").should == "function_defined"
+    end
+
+    it "should be true when the name is defined as a class" do
+        @scope.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "yayness")
+        @scope.function_defined("yayness").should be_true
+    end
+    
+    it "should be true when the name is defined as a definition" do
+        @scope.known_resource_types.add Puppet::Resource::Type.new(:definition, "yayness")
+        @scope.function_defined("yayness").should be_true
+    end
+
+    it "should be true when the name is defined as a builtin type" do
+        @scope.function_defined("file").should be_true
+    end
+
+
+    it "should be true when any of the provided names are defined" do
+        @scope.known_resource_types.add Puppet::Resource::Type.new(:definition, "yayness")
+        @scope.function_defined(["meh", "yayness", "booness"]).should be_true
+    end
+
+    it "should be false when a single given name is not defined" do
+        @scope.function_defined("meh").should be_false
+    end
+
+    it "should be false when none of the names are defined" do
+        @scope.function_defined(["meh", "yayness", "booness"]).should be_false
+    end
+
+    it "should be true when a resource reference is provided and the resource is in the catalog" do
+        resource = Puppet::Resource.new("file", "/my/file")
+        @compiler.add_resource(@scope, resource)
+        @scope.function_defined(resource).should be_true
+    end
+end
diff --git a/spec/unit/parser/functions/require.rb b/spec/unit/parser/functions/require.rb
index 924990a..1d9ce93 100755
--- a/spec/unit/parser/functions/require.rb
+++ b/spec/unit/parser/functions/require.rb
@@ -28,7 +28,7 @@ describe "the require function" do
     end
 
     it "should set the 'require' prarameter on the resource to a resource reference" do
-        @resource.expects(:set_parameter).with { |name, value| name == :require and value[0].is_a?(Puppet::Parser::Resource::Reference) }
+        @resource.expects(:set_parameter).with { |name, value| name == :require and value[0].is_a?(Puppet::Resource) }
         @scope.stubs(:function_include)
         @scope.function_require("myclass")
     end
diff --git a/spec/unit/parser/functions/tag.rb b/spec/unit/parser/functions/tag.rb
new file mode 100755
index 0000000..5fb467e
--- /dev/null
+++ b/spec/unit/parser/functions/tag.rb
@@ -0,0 +1,24 @@
+#! /usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe "the 'tag' function" do
+
+    before :each do
+        @scope = Puppet::Parser::Scope.new()
+    end
+
+    it "should exist" do
+        Puppet::Parser::Functions.function(:tag).should == "function_tag"
+    end
+
+    it "should tag the resource with any provided tags" do
+        resource = Puppet::Parser::Resource.new(:file, "/file", :scope => @scope)
+        @scope.expects(:resource).returns resource
+
+        @scope.function_tag ["one", "two"]
+
+        resource.should be_tagged("one")
+        resource.should be_tagged("two")
+    end
+end
diff --git a/spec/unit/parser/parser.rb b/spec/unit/parser/parser.rb
index 84749c3..8cc29c9 100755
--- a/spec/unit/parser/parser.rb
+++ b/spec/unit/parser/parser.rb
@@ -429,6 +429,12 @@ describe Puppet::Parser do
             @krt.hostclass("foobar").parent.should == "yayness"
         end
 
+        it "should correctly set the parent class for multiple classes at a time" do
+            @parser.parse("class foobar inherits yayness {}\nclass boo inherits bar {}")
+            @krt.hostclass("foobar").parent.should == "yayness"
+            @krt.hostclass("boo").parent.should == "bar"
+        end
+
         it "should define the code when some is provided" do
             @parser.parse("class foobar { $var = val }")
             @krt.hostclass("foobar").code.should_not be_nil
@@ -451,5 +457,15 @@ describe Puppet::Parser do
             @krt.add(Puppet::Resource::Type.new(:hostclass, "foobar", :arguments => {"biz" => nil}))
             lambda { @parser.parse("class { foobar: biz => stuff }") }.should_not raise_error
         end
+        
+        it "should correctly mark exported resources as exported" do
+            @parser.parse("@@file { '/file': }")
+            @krt.hostclass("").code[0].exported.should be_true
+        end
+        
+        it "should correctly mark virtual resources as virtual" do
+            @parser.parse("@file { '/file': }")
+            @krt.hostclass("").code[0].virtual.should be_true
+        end
     end
 end
diff --git a/spec/unit/parser/resource.rb b/spec/unit/parser/resource.rb
index bb3001c..0c70c81 100755
--- a/spec/unit/parser/resource.rb
+++ b/spec/unit/parser/resource.rb
@@ -19,7 +19,7 @@ describe Puppet::Parser::Resource do
         args[:source] ||= "source"
         args[:scope] ||= stub('scope', :source => mock('source'))
 
-        {:type => "resource", :title => "testing", :source => "source", :scope => "scope"}.each do |param, value|
+        {:source => "source", :scope => "scope"}.each do |param, value|
             args[param] ||= value
         end
 
@@ -30,7 +30,7 @@ describe Puppet::Parser::Resource do
             args[:params] = paramify(args[:source], params)
         end
 
-        Puppet::Parser::Resource.new(args)
+        Puppet::Parser::Resource.new("resource", "testing", args)
     end
 
     def param(name, value, source)
@@ -61,19 +61,31 @@ describe Puppet::Parser::Resource do
         Puppet::Parser::Resource.ancestors.should be_include(Puppet::FileCollection::Lookup)
     end
 
+    it "should get its environment from its scope" do
+        scope = stub 'scope', :source => stub("source")
+        scope.expects(:environment).returns "foo"
+        Puppet::Parser::Resource.new("file", "whatever", :scope => scope).environment.should == "foo"
+    end
+
+    it "should get its namespaces from its scope" do
+        scope = stub 'scope', :source => stub("source")
+        scope.expects(:namespaces).returns %w{one two}
+        Puppet::Parser::Resource.new("file", "whatever", :scope => scope).namespaces.should == %w{one two}
+    end
+
     it "should be isomorphic if it is builtin and models an isomorphic type" do
         Puppet::Type.type(:file).expects(:isomorphic?).returns(true)
-        @resource = Puppet::Parser::Resource.new(:type => "file", :title => "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true
+        @resource = Puppet::Parser::Resource.new("file", "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true
     end
 
     it "should not be isomorphic if it is builtin and models a non-isomorphic type" do
         Puppet::Type.type(:file).expects(:isomorphic?).returns(false)
-        @resource = Puppet::Parser::Resource.new(:type => "file", :title => "whatever", :scope => @scope, :source => @source).isomorphic?.should be_false
+        @resource = Puppet::Parser::Resource.new("file", "whatever", :scope => @scope, :source => @source).isomorphic?.should be_false
     end
 
     it "should be isomorphic if it is not builtin" do
         newdefine "whatever"
-        @resource = Puppet::Parser::Resource.new(:type => "whatever", :title => "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true
+        @resource = Puppet::Parser::Resource.new("whatever", "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true
     end
 
     it "should have a array-indexing method for retrieving parameter values" do
@@ -89,77 +101,68 @@ describe Puppet::Parser::Resource do
     end
 
     it "should be able to use the indexing operator to access parameters" do
-        resource = Puppet::Parser::Resource.new(:type => "resource", :title => "testing", :source => "source", :scope => "scope")
+        resource = Puppet::Parser::Resource.new("resource", "testing", :source => "source", :scope => "scope")
         resource["foo"] = "bar"
         resource["foo"].should == "bar"
     end
 
     it "should return the title when asked for a parameter named 'title'" do
-        Puppet::Parser::Resource.new(:type => "resource", :title => "testing", :source => "source", :scope => "scope")[:title].should == "testing"
+        Puppet::Parser::Resource.new("resource", "testing", :source => "source", :scope => "scope")[:title].should == "testing"
     end
 
     describe "when initializing" do
         before do
-            @arguments = {:type => "resource", :title => "testing", :scope => stub('scope', :source => mock('source'))}
+            @arguments = {:scope => stub('scope', :source => mock('source'))}
         end
 
-        [:type, :title, :scope].each do |name|
-            it "should fail unless #{name.to_s} is specified" do
-                try = @arguments.dup
-                try.delete(name)
-                lambda { Puppet::Parser::Resource.new(try) }.should raise_error(ArgumentError)
-            end
+        it "should fail unless #{name.to_s} is specified" do
+            lambda { Puppet::Parser::Resource.new('file', '/my/file') }.should raise_error(ArgumentError)
         end
 
         it "should set the reference correctly" do
-            res = Puppet::Parser::Resource.new(@arguments)
+            res = Puppet::Parser::Resource.new("resource", "testing", @arguments)
             res.ref.should == "Resource[testing]"
         end
 
         it "should be tagged with user tags" do
             tags = [ "tag1", "tag2" ]
             @arguments[:params] = [ param(:tag, tags , :source) ]
-            res = Puppet::Parser::Resource.new(@arguments)
+            res = Puppet::Parser::Resource.new("resource", "testing", @arguments)
             (res.tags & tags).should == tags
         end
     end
 
     describe "when refering to a resource with name canonicalization" do
         before do
-            @arguments = {:type => "file", :title => "/path/", :scope => stub('scope', :source => mock('source'))}
+            @arguments = {:scope => stub('scope', :source => mock('source'))}
         end
 
         it "should canonicalize its own name" do
-            res = Puppet::Parser::Resource.new(@arguments)
+            res = Puppet::Parser::Resource.new("file", "/path/", @arguments)
             res.ref.should == "File[/path]"
         end
     end
 
     describe "when evaluating" do
-        before do
-            @type = Puppet::Parser::Resource
-
-            @definition = newdefine "mydefine"
-            @class = newclass "myclass"
-            @nodedef = newnode("mynode")
-        end
-
         it "should evaluate the associated AST definition" do
-            res = @type.new(:type => "mydefine", :title => "whatever", :scope => @scope, :source => @source)
-            @definition.expects(:evaluate_code).with(res)
+            definition = newdefine "mydefine"
+            res = Puppet::Parser::Resource.new("mydefine", "whatever", :scope => @scope, :source => @source)
+            definition.expects(:evaluate_code).with(res)
 
             res.evaluate
         end
 
         it "should evaluate the associated AST class" do
-            res = @type.new(:type => "class", :title => "myclass", :scope => @scope, :source => @source)
+            @class = newclass "myclass"
+            res = Puppet::Parser::Resource.new("class", "myclass", :scope => @scope, :source => @source)
             @class.expects(:evaluate_code).with(res)
             res.evaluate
         end
 
         it "should evaluate the associated AST node" do
-            res = @type.new(:type => "node", :title => "mynode", :scope => @scope, :source => @source)
-            @nodedef.expects(:evaluate_code).with(res)
+            nodedef = newnode("mynode")
+            res = Puppet::Parser::Resource.new("node", "mynode", :scope => @scope, :source => @source)
+            nodedef.expects(:evaluate_code).with(res)
             res.evaluate
         end
     end
@@ -169,7 +172,7 @@ describe Puppet::Parser::Resource do
             @class = newclass "myclass"
             @nodedef = newnode("mynode")
 
-            @resource = Puppet::Parser::Resource.new(:type => "file", :title => "whatever", :scope => @scope, :source => @source)
+            @resource = Puppet::Parser::Resource.new("file", "whatever", :scope => @scope, :source => @source)
         end
 
         it "should do nothing if it has already been finished" do
@@ -292,7 +295,7 @@ describe Puppet::Parser::Resource do
         before do
             @scope_resource = stub 'scope_resource', :tags => %w{srone srtwo}
             @scope = stub 'scope', :resource => @scope_resource
-            @resource = Puppet::Parser::Resource.new(:type => "file", :title => "yay", :scope => @scope, :source => mock('source'))
+            @resource = Puppet::Parser::Resource.new("file", "yay", :scope => @scope, :source => mock('source'))
         end
 
         it "should get tagged with the resource type" do
@@ -304,19 +307,19 @@ describe Puppet::Parser::Resource do
         end
 
         it "should get tagged with each name in the title if the title is a qualified class name" do
-            resource = Puppet::Parser::Resource.new(:type => "file", :title => "one::two", :scope => @scope, :source => mock('source'))
+            resource = Puppet::Parser::Resource.new("file", "one::two", :scope => @scope, :source => mock('source'))
             resource.tags.should be_include("one")
             resource.tags.should be_include("two")
         end
 
         it "should get tagged with each name in the type if the type is a qualified class name" do
-            resource = Puppet::Parser::Resource.new(:type => "one::two", :title => "whatever", :scope => @scope, :source => mock('source'))
+            resource = Puppet::Parser::Resource.new("one::two", "whatever", :scope => @scope, :source => mock('source'))
             resource.tags.should be_include("one")
             resource.tags.should be_include("two")
         end
 
         it "should not get tagged with non-alphanumeric titles" do
-            resource = Puppet::Parser::Resource.new(:type => "file", :title => "this is a test", :scope => @scope, :source => mock('source'))
+            resource = Puppet::Parser::Resource.new("file", "this is a test", :scope => @scope, :source => mock('source'))
             resource.tags.should_not be_include("this is a test")
         end
 
@@ -496,26 +499,26 @@ describe Puppet::Parser::Resource do
             @parser_resource.to_resource.virtual.should be_true
         end
 
-        it "should convert any parser resource references to Puppet::Resource::Reference instances" do
-            ref = Puppet::Parser::Resource::Reference.new(:title => "/my/file", :type => "file")
+        it "should convert any parser resource references to Puppet::Resource instances" do
+            ref = Puppet::Resource.new("file", "/my/file")
             @parser_resource = mkresource :source => @source, :params => {:foo => "bar", :fee => ref}
             result = @parser_resource.to_resource
-            result[:fee].should == Puppet::Resource::Reference.new(:file, "/my/file")
+            result[:fee].should == Puppet::Resource.new(:file, "/my/file")
         end
 
-        it "should convert any parser resource references to Puppet::Resource::Reference instances even if they are in an array" do
-            ref = Puppet::Parser::Resource::Reference.new(:title => "/my/file", :type => "file")
+        it "should convert any parser resource references to Puppet::Resource instances even if they are in an array" do
+            ref = Puppet::Resource.new("file", "/my/file")
             @parser_resource = mkresource :source => @source, :params => {:foo => "bar", :fee => ["a", ref]}
             result = @parser_resource.to_resource
-            result[:fee].should == ["a", Puppet::Resource::Reference.new(:file, "/my/file")]
+            result[:fee].should == ["a", Puppet::Resource.new(:file, "/my/file")]
         end
 
-        it "should convert any parser resource references to Puppet::Resource::Reference instances even if they are in an array of array, and even deeper" do
-            ref1 = Puppet::Parser::Resource::Reference.new(:title => "/my/file1", :type => "file")
-            ref2 = Puppet::Parser::Resource::Reference.new(:title => "/my/file2", :type => "file")
+        it "should convert any parser resource references to Puppet::Resource instances even if they are in an array of array, and even deeper" do
+            ref1 = Puppet::Resource.new("file", "/my/file1")
+            ref2 = Puppet::Resource.new("file", "/my/file2")
             @parser_resource = mkresource :source => @source, :params => {:foo => "bar", :fee => ["a", [ref1,ref2]]}
             result = @parser_resource.to_resource
-            result[:fee].should == ["a", Puppet::Resource::Reference.new(:file, "/my/file1"), Puppet::Resource::Reference.new(:file, "/my/file2")]
+            result[:fee].should == ["a", Puppet::Resource.new(:file, "/my/file1"), Puppet::Resource.new(:file, "/my/file2")]
         end
 
         it "should fail if the same param is declared twice" do
@@ -531,4 +534,52 @@ describe Puppet::Parser::Resource do
             end.should raise_error(Puppet::ParseError)
         end
     end
+
+    describe "when validating" do
+        it "should check each parameter" do
+            resource = Puppet::Parser::Resource.new :foo, "bar", :scope => stub("scope"), :source => stub("source")
+            resource[:one] = :two
+            resource[:three] = :four
+            resource.expects(:validate_parameter).with(:one)
+            resource.expects(:validate_parameter).with(:three)
+            resource.send(:validate)
+        end
+
+        it "should raise a parse error when there's a failure" do
+            resource = Puppet::Parser::Resource.new :foo, "bar", :scope => stub("scope"), :source => stub("source")
+            resource[:one] = :two
+            resource.expects(:validate_parameter).with(:one).raises ArgumentError
+            lambda { resource.send(:validate) }.should raise_error(Puppet::ParseError)
+        end
+    end
+
+    describe "when setting parameters" do
+        before do
+            @source = newclass "foobar"
+            @resource = Puppet::Parser::Resource.new :foo, "bar", :scope => stub("scope"), :source => @source
+        end
+
+        it "should accept Param instances and add them to the parameter list" do
+            param = Puppet::Parser::Resource::Param.new :name => "foo", :value => "bar", :source => @source
+            @resource.set_parameter(param)
+            @resource["foo"].should == "bar"
+        end
+
+        it "should fail when provided a parameter name but no value" do
+            lambda { @resource.set_parameter("myparam") }.should raise_error(ArgumentError)
+        end
+
+        it "should use its source when provided a parameter name and value" do
+            @resource.set_parameter("myparam", "myvalue")
+            @resource["myparam"].should == "myvalue"
+        end
+    end
+
+    # part of #629 -- the undef keyword.  Make sure 'undef' params get skipped.
+    it "should not include 'undef' parameters when converting itself to a hash" do
+        resource = Puppet::Parser::Resource.new "file", "/tmp/testing", :source => mock("source"), :scope => mock("scope")
+        resource[:owner] = :undef
+        resource[:mode] = "755"
+        resource.to_hash[:owner].should be_nil
+    end
 end
diff --git a/spec/unit/parser/resource/reference.rb b/spec/unit/parser/resource/reference.rb
deleted file mode 100755
index a386042..0000000
--- a/spec/unit/parser/resource/reference.rb
+++ /dev/null
@@ -1,134 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../../spec_helper'
-
-describe Puppet::Parser::Resource::Reference do
-    before do
-        @type = Puppet::Parser::Resource::Reference
-    end
-
-    it "should get its environment from its scope" do
-        env = stub 'environment'
-        scope = stub 'scope', :environment => env
-        @type.new(:title => "foo", :type => "bar", :scope => scope).environment.should equal(env)
-    end
-
-    it "should use the resource type collection helper to find its known resource types" do
-        Puppet::Parser::Resource::Reference.ancestors.should include(Puppet::Resource::TypeCollectionHelper)
-    end
-
-    it "should use the file lookup module" do
-        Puppet::Parser::Resource::Reference.ancestors.should be_include(Puppet::FileCollection::Lookup)
-    end
-
-    it "should require a type" do
-        proc { @type.new(:title => "yay") }.should raise_error(Puppet::DevError)
-    end
-
-    it "should require a title" do
-        proc { @type.new(:type => "file") }.should raise_error(Puppet::DevError)
-    end
-
-    it "should know when it refers to a builtin type" do
-        ref = @type.new(:type => "file", :title => "/tmp/yay")
-        ref.builtin?.should be_true
-        ref.builtintype.should equal(Puppet::Type.type(:file))
-    end
-
-    it "should return a downcased relationship-style resource reference for defined types" do
-        ref = @type.new(:type => "file", :title => "/tmp/yay")
-        ref.to_ref.should == ["file", "/tmp/yay"]
-    end
-
-    it "should return a capitalized relationship-style resource reference for defined types" do
-        ref = @type.new(:type => "whatever", :title => "/tmp/yay")
-        ref.to_ref.should == ["Whatever", "/tmp/yay"]
-    end
-
-    it "should return a resource reference string when asked" do
-        ref = @type.new(:type => "file", :title => "/tmp/yay")
-        ref.to_s.should == "File[/tmp/yay]"
-    end
-
-    it "should canonize resource reference types" do
-        ref = @type.new(:type => "foo::bar", :title => "/tmp/yay")
-        ref.to_s.should == "Foo::Bar[/tmp/yay]"
-    end
-
-    it "should canonize resource reference values" do
-        ref = @type.new(:type => "file", :title => "/tmp/yay/")
-        ref.to_s.should == "File[/tmp/yay]"
-    end
-
-    it "should canonize resource reference values without order dependencies" do
-        args = [[:title, "/tmp/yay/"], [:type, "file"]]
-        ref = @type.new(args)
-        ref.to_s.should == "File[/tmp/yay]"
-    end
-
-end
-
-describe Puppet::Parser::Resource::Reference, " when modeling defined types" do
-    def newclass(name)
-        @known_resource_types.add Puppet::Resource::Type.new(:hostclass, name)
-    end
-
-    def newdefine(name)
-        @known_resource_types.add Puppet::Resource::Type.new(:definition, name)
-    end
-
-    def newnode(name)
-        @known_resource_types.add Puppet::Resource::Type.new(:node, name)
-    end
-
-    before do
-        @type = Puppet::Parser::Resource::Reference
-
-        @known_resource_types = Puppet::Resource::TypeCollection.new("myenv")
-        @definition = newdefine("mydefine")
-        @class = newclass("myclass")
-        @nodedef = newnode("mynode")
-        @node = Puppet::Node.new("yaynode")
-
-        @compiler = Puppet::Parser::Compiler.new(@node)
-        @compiler.environment.stubs(:known_resource_types).returns @known_resource_types
-    end
-
-    it "should be able to find defined types" do
-        ref = @type.new(:type => "mydefine", :title => "/tmp/yay", :scope => @compiler.topscope)
-        ref.builtin?.should be_false
-        ref.definedtype.should equal(@definition)
-    end
-
-    it "should be able to find classes" do
-        ref = @type.new(:type => "class", :title => "myclass", :scope => @compiler.topscope)
-        ref.builtin?.should be_false
-        ref.definedtype.should equal(@class)
-    end
-
-    it "should be able to find nodes" do
-        ref = @type.new(:type => "node", :title => "mynode", :scope => @compiler.topscope)
-        ref.builtin?.should be_false
-        ref.definedtype.object_id.should  == @nodedef.object_id
-    end
-
-    it "should only look for fully qualified classes" do
-        top = newclass "top"
-        sub = newclass "other::top"
-
-        scope = @compiler.topscope.class.new(:parent => @compiler.topscope, :namespace => "other", :compiler => @compiler)
-
-        ref = @type.new(:type => "class", :title => "top", :scope => scope)
-        ref.definedtype.name.should equal(top.name)
-    end
-
-    it "should only look for fully qualified definitions" do
-        top = newdefine "top"
-        sub = newdefine "other::top"
-
-        scope = @compiler.topscope.class.new(:parent => @compiler.topscope, :namespace => "other", :compiler => @compiler)
-
-        ref = @type.new(:type => "top", :title => "foo", :scope => scope)
-        ref.definedtype.name.should equal(top.name)
-    end
-end
diff --git a/spec/unit/parser/scope.rb b/spec/unit/parser/scope.rb
index 799d057..3d648fe 100755
--- a/spec/unit/parser/scope.rb
+++ b/spec/unit/parser/scope.rb
@@ -8,6 +8,7 @@ describe Puppet::Parser::Scope do
         # This is necessary so we don't try to use the compiler to discover our parent.
         @topscope.parent = nil
         @scope = Puppet::Parser::Scope.new()
+        @scope.compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foo"))
         @scope.parent = @topscope
     end
  
@@ -104,7 +105,7 @@ describe Puppet::Parser::Scope do
 
             def create_class_scope(name)
                 klass = newclass(name)
-                Puppet::Parser::Resource.new(:type => "class", :title => name, :scope => @scope, :source => mock('source')).evaluate
+                Puppet::Parser::Resource.new("class", name, :scope => @scope, :source => mock('source')).evaluate
 
                 return @scope.class_scope(klass)
             end
@@ -315,6 +316,114 @@ describe Puppet::Parser::Scope do
 
             @scope.strinterp('==${10}==').should == "==value=="
         end
+
+        describe "with qualified variables" do
+            before do
+                @scopes = {}
+                klass = @scope.known_resource_types.add(Puppet::Resource::Type.new(:hostclass, ""))
+                Puppet::Parser::Resource.new("class", :main, :scope => @scope, :source => mock('source')).evaluate
+                @scopes[""] = @scope.compiler.class_scope(klass)
+                @scopes[""].setvar("test", "value")
+
+                %w{one one::two one::two::three}.each do |name|
+                    klass = @scope.known_resource_types.add(Puppet::Resource::Type.new(:hostclass, name))
+                    Puppet::Parser::Resource.new("class", name, :scope => @scope, :source => mock('source')).evaluate
+                    @scopes[name] = @scope.compiler.class_scope(klass)
+                    @scopes[name].setvar("test", "value-#{name.sub(/.+::/,'')}")
+                end
+            end
+            {
+                "===${one::two::three::test}===" => "===value-three===",
+                "===$one::two::three::test===" => "===value-three===",
+                "===${one::two::test}===" => "===value-two===",
+                "===$one::two::test===" => "===value-two===",
+                "===${one::test}===" => "===value-one===",
+                "===$one::test===" => "===value-one===",
+                "===${::test}===" => "===value===",
+                "===$::test===" => "===value==="
+            }.each do |input, output|
+                it "should parse '#{input}' correctly" do
+                    @scope.strinterp(input).should == output
+                end
+            end
+        end
+
+        tests = {
+            "===${test}===" => "===value===",
+            "===${test} ${test} ${test}===" => "===value value value===",
+            "===$test ${test} $test===" => "===value value value===",
+            "===\\$test===" => "===$test===",
+            '===\\$test string===' => "===$test string===",
+            '===$test string===' => "===value string===",
+            '===a testing $===' => "===a testing $===",
+            '===a testing \$===' => "===a testing $===",
+            "===an escaped \\\n carriage return===" => "===an escaped  carriage return===",
+            '\$' => "$",
+            '\s' => "\s",
+            '\t' => "\t",
+            '\n' => "\n"
+        }
+
+        tests.each do |input, output|
+            it "should parse '#{input}' correctly" do
+                @scope.setvar("test", "value")
+                @scope.strinterp(input).should == output
+            end
+        end
+
+        # #523
+        %w{d f h l w z}.each do |l|
+            it "should parse '#{l}' when escaped" do
+                string = "\\" + l
+                @scope.strinterp(string).should == string
+            end
+        end
+    end
+
+    def test_strinterp
+        # Make and evaluate our classes so the qualified lookups work
+        parser = mkparser
+        klass = parser.newclass("")
+        scope = mkscope(:parser => parser)
+        Puppet::Parser::Resource.new(:type => "class", :title => :main, :scope => scope, :source => mock('source')).evaluate
+
+        assert_nothing_raised {
+            scope.setvar("test","value")
+        }
+
+        scopes = {"" => scope}
+
+        %w{one one::two one::two::three}.each do |name|
+            klass = parser.newclass(name)
+            Puppet::Parser::Resource.new(:type => "class", :title => name, :scope => scope, :source => mock('source')).evaluate
+            scopes[name] = scope.compiler.class_scope(klass)
+            scopes[name].setvar("test", "value-%s" % name.sub(/.+::/,''))
+        end
+
+        assert_equal("value", scope.lookupvar("::test"), "did not look up qualified value correctly")
+        tests.each do |input, output|
+            assert_nothing_raised("Failed to scan %s" % input.inspect) do
+                assert_equal(output, scope.strinterp(input),
+                    'did not parserret %s correctly' % input.inspect)
+            end
+        end
+
+        logs = []
+        Puppet::Util::Log.close
+        Puppet::Util::Log.newdestination(logs)
+
+        # #523
+        %w{d f h l w z}.each do |l|
+            string = "\\" + l
+            assert_nothing_raised do
+                assert_equal(string, scope.strinterp(string),
+                    'did not parserret %s correctly' % string)
+            end
+
+            assert(logs.detect { |m| m.message =~ /Unrecognised escape/ },
+                "Did not get warning about escape sequence with %s" % string)
+            logs.clear
+        end
     end
 
     describe "when setting ephemeral vars from matches" do
@@ -357,4 +466,50 @@ describe Puppet::Parser::Scope do
             @scope.lookupvar("foo").should == ""
         end
     end
+
+    it "should use its namespaces to find hostclasses" do
+        klass = @scope.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "a::b::c")
+        @scope.add_namespace "a::b"
+        @scope.find_hostclass("c").should equal(klass)
+    end
+
+    it "should use its namespaces to find definitions" do
+        define = @scope.known_resource_types.add Puppet::Resource::Type.new(:definition, "a::b::c")
+        @scope.add_namespace "a::b"
+        @scope.find_definition("c").should equal(define)
+    end
+
+    describe "when managing defaults" do
+        it "should be able to set and lookup defaults" do
+            param = Puppet::Parser::Resource::Param.new(:name => :myparam, :value => "myvalue", :source => stub("source"))
+            @scope.setdefaults(:mytype, param)
+            @scope.lookupdefaults(:mytype).should == {:myparam => param}
+        end
+
+        it "should fail if a default is already defined and a new default is being defined" do
+            param = Puppet::Parser::Resource::Param.new(:name => :myparam, :value => "myvalue", :source => stub("source"))
+            @scope.setdefaults(:mytype, param)
+            lambda { @scope.setdefaults(:mytype, param) }.should raise_error(Puppet::ParseError)
+        end
+
+        it "should return multiple defaults at once" do
+            param1 = Puppet::Parser::Resource::Param.new(:name => :myparam, :value => "myvalue", :source => stub("source"))
+            @scope.setdefaults(:mytype, param1)
+            param2 = Puppet::Parser::Resource::Param.new(:name => :other, :value => "myvalue", :source => stub("source"))
+            @scope.setdefaults(:mytype, param2)
+
+            @scope.lookupdefaults(:mytype).should == {:myparam => param1, :other => param2}
+        end
+
+        it "should look up defaults defined in parent scopes" do
+            param1 = Puppet::Parser::Resource::Param.new(:name => :myparam, :value => "myvalue", :source => stub("source"))
+            @scope.setdefaults(:mytype, param1)
+
+            child_scope = @scope.newscope
+            param2 = Puppet::Parser::Resource::Param.new(:name => :other, :value => "myvalue", :source => stub("source"))
+            child_scope.setdefaults(:mytype, param2)
+
+            child_scope.lookupdefaults(:mytype).should == {:myparam => param1, :other => param2}
+        end
+    end
 end
diff --git a/spec/unit/rails/param_value.rb b/spec/unit/rails/param_value.rb
index 26e87fe..070ac82 100755
--- a/spec/unit/rails/param_value.rb
+++ b/spec/unit/rails/param_value.rb
@@ -42,7 +42,7 @@ describe "Puppet::Rails::ParamValue" do
         end
 
         it "should not convert Resource References into strings" do
-            ref = Puppet::Resource::Reference.new(:file, "/file")
+            ref = Puppet::Resource.new(:file, "/file")
             Puppet::Rails::ParamValue.from_parser_param(:myparam, ref)[0][:value].should == ref
         end
     end
diff --git a/spec/unit/resource.rb b/spec/unit/resource.rb
index 73bbfd8..c97cd63 100755
--- a/spec/unit/resource.rb
+++ b/spec/unit/resource.rb
@@ -12,71 +12,89 @@ describe Puppet::Resource do
         end
     end
 
-    describe "when initializing" do
-        it "should require the type and title" do
-            lambda { Puppet::Resource.new }.should raise_error(ArgumentError)
-        end
+    it "should have a :title attribute" do
+        Puppet::Resource.new(:file, "foo").title.should == "foo"
+    end
 
-        it "should create a resource reference with its type and title" do
-            ref = Puppet::Resource::Reference.new("file", "/f")
-            Puppet::Resource::Reference.expects(:new).with("file", "/f").returns ref
-            Puppet::Resource.new("file", "/f")
-        end
+    it "should require the type and title" do
+        lambda { Puppet::Resource.new }.should raise_error(ArgumentError)
+    end
 
-        it "should tag itself with its type" do
-            Puppet::Resource.new("file", "/f").should be_tagged("file")
-        end
+    it "should canonize types to capitalized strings" do
+        Puppet::Resource.new(:file, "foo").type.should == "File"
+    end
 
-        it "should tag itself with its title if the title is a valid tag" do
-            Puppet::Resource.new("file", "bar").should be_tagged("bar")
-        end
+    it "should canonize qualified types so all strings are capitalized" do
+        Puppet::Resource.new("foo::bar", "foo").type.should == "Foo::Bar"
+    end
 
-        it "should not tag itself with its title if the title is a not valid tag" do
-            Puppet::Resource.new("file", "/bar").should_not be_tagged("/bar")
-        end
+    it "should tag itself with its type" do
+        Puppet::Resource.new("file", "/f").should be_tagged("file")
+    end
 
-        it "should allow setting of attributes" do
-            Puppet::Resource.new("file", "/bar", :file => "/foo").file.should == "/foo"
-            Puppet::Resource.new("file", "/bar", :exported => true).should be_exported
-        end
+    it "should tag itself with its title if the title is a valid tag" do
+        Puppet::Resource.new("file", "bar").should be_tagged("bar")
     end
 
-    it "should use the resource reference to determine its type" do
-        ref = Puppet::Resource::Reference.new("file", "/f")
-        Puppet::Resource::Reference.expects(:new).returns ref
-        resource = Puppet::Resource.new("file", "/f")
-        ref.expects(:type).returns "mytype"
-        resource.type.should == "mytype"
+    it "should not tag itself with its title if the title is a not valid tag" do
+        Puppet::Resource.new("file", "/bar").should_not be_tagged("/bar")
     end
 
-    it "should use its resource reference to determine its title" do
-        ref = Puppet::Resource::Reference.new("file", "/f")
-        Puppet::Resource::Reference.expects(:new).returns ref
-        resource = Puppet::Resource.new("file", "/f")
-        ref.expects(:title).returns "mytitle"
-        resource.title.should == "mytitle"
+    it "should allow setting of attributes" do
+        Puppet::Resource.new("file", "/bar", :file => "/foo").file.should == "/foo"
+        Puppet::Resource.new("file", "/bar", :exported => true).should be_exported
     end
 
-    it "should use its resource reference to determine whether it is builtin" do
-        ref = Puppet::Resource::Reference.new("file", "/f")
-        Puppet::Resource::Reference.expects(:new).returns ref
-        resource = Puppet::Resource.new("file", "/f")
-        ref.expects(:builtin_type?).returns "yep"
-        resource.builtin_type?.should == "yep"
+    it "should set its type to 'Class' and its title to the passed title if the passed type is :component and the title has no square brackets in it" do
+        ref = Puppet::Resource.new(:component, "foo")
+        ref.type.should == "Class"
+        ref.title.should == "foo"
     end
 
-    it "should call its builtin_type? method when 'builtin?' is called" do
-        resource = Puppet::Resource.new("file", "/f")
-        resource.expects(:builtin_type?).returns "foo"
-        resource.builtin?.should == "foo"
+    it "should interpret the title as a reference and assign appropriately if the type is :component and the title contains square brackets" do
+        ref = Puppet::Resource.new(:component, "foo::bar[yay]")
+        ref.type.should == "Foo::Bar"
+        ref.title.should == "yay"
     end
 
-    it "should use its resource reference to produce its canonical reference string" do
-        ref = Puppet::Resource::Reference.new("file", "/f")
-        Puppet::Resource::Reference.expects(:new).returns ref
-        resource = Puppet::Resource.new("file", "/f")
-        ref.expects(:to_s).returns "Foo[bar]"
-        resource.ref.should == "Foo[bar]"
+    it "should set the type to 'Class' if it is nil and the title contains no square brackets" do
+        ref = Puppet::Resource.new(nil, "yay")
+        ref.type.should == "Class"
+        ref.title.should == "yay"
+    end
+
+    it "should interpret the title as a reference and assign appropriately if the type is nil and the title contains square brackets" do
+        ref = Puppet::Resource.new(nil, "foo::bar[yay]")
+        ref.type.should == "Foo::Bar"
+        ref.title.should == "yay"
+    end
+
+    it "should interpret the title as a reference and assign appropriately if the type is nil and the title contains nested square brackets" do
+        ref = Puppet::Resource.new(nil, "foo::bar[baz[yay]]")
+        ref.type.should == "Foo::Bar"
+        ref.title.should =="baz[yay]"
+    end
+
+    it "should interpret the type as a reference and assign appropriately if the title is nil and the type contains square brackets" do
+        ref = Puppet::Resource.new("foo::bar[baz]")
+        ref.type.should == "Foo::Bar"
+        ref.title.should =="baz"
+    end
+
+    it "should be able to extract its information from a Puppet::Type instance" do
+        ral = Puppet::Type.type(:file).new :path => "/foo"
+        ref = Puppet::Resource.new(ral)
+        ref.type.should == "File"
+        ref.title.should == "/foo"
+    end
+
+
+    it "should fail if the title is nil and the type is not a valid resource reference string" do
+        lambda { Puppet::Resource.new("foo") }.should raise_error(ArgumentError)
+    end
+
+    it "should be able to produce a backward-compatible reference array" do
+        Puppet::Resource.new("foobar", "/f").to_trans_ref.should == %w{Foobar /f}
     end
 
     it "should be taggable" do
@@ -94,12 +112,16 @@ describe Puppet::Resource do
         Puppet::Resource.new("file", "/my/file", :environment => :foo).environment.name.should == :foo
     end
 
-    it "should support a namespace attribute" do
-        Puppet::Resource.new("file", "/my/file", :namespace => :foo).namespace.should == :foo
+    it "should support specifying namespaces" do
+        Puppet::Resource.new("file", "/my/file", :namespaces => [:foo]).namespaces.should == [:foo]
+    end
+
+    it "should convert namespaces to an array if not specified as one" do
+        Puppet::Resource.new("file", "/my/file", :namespaces => :foo).namespaces.should == [:foo]
     end
 
-    it "should default to a namespace of an empty string" do
-        Puppet::Resource.new("file", "/my/file").namespace.should == ""
+    it "should default to a single amespace of an empty string" do
+        Puppet::Resource.new("file", "/my/file").namespaces.should == [""]
     end
 
     it "should be able to look up its resource type when the type is a builtin resource" do
@@ -130,16 +152,16 @@ describe Puppet::Resource do
         resource.resource_type.should equal(klass)
     end
 
-    it "should use its namespace when looking up defined resource types" do
-        resource = Puppet::Resource.new("bar", "/my/file", :namespace => "foo")
+    it "should use its namespaces when looking up defined resource types" do
+        resource = Puppet::Resource.new("bar", "/my/file", :namespaces => ["foo"])
         type = Puppet::Resource::Type.new(:definition, "foo::bar")
         resource.environment.known_resource_types.add type
 
         resource.resource_type.should equal(type)
     end
 
-    it "should use its namespace when looking up host classes" do
-        resource = Puppet::Resource.new("class", "bar", :namespace => "foo")
+    it "should use its namespaces when looking up host classes" do
+        resource = Puppet::Resource.new("class", "bar", :namespaces => ["foo"])
         type = Puppet::Resource::Type.new(:hostclass, "foo::bar")
         resource.environment.known_resource_types.add type
 
@@ -171,6 +193,30 @@ describe Puppet::Resource do
         resource[:yay] = true
     end
 
+    it "should be considered equivalent to another resource if their type and title match and no parameters are set" do
+        Puppet::Resource.new("file", "/f").should == Puppet::Resource.new("file", "/f")
+    end
+
+    it "should be considered equivalent to another resource if their type, title, and parameters are equal" do
+        Puppet::Resource.new("file", "/f", :parameters => {:foo => "bar"}).should == Puppet::Resource.new("file", "/f", :parameters => {:foo => "bar"})
+    end
+
+    it "should not be considered equivalent to another resource if their type and title match but parameters are different" do
+        Puppet::Resource.new("file", "/f", :parameters => {:fee => "baz"}).should_not == Puppet::Resource.new("file", "/f", :parameters => {:foo => "bar"})
+    end
+
+    it "should not be considered equivalent to a non-resource" do
+        Puppet::Resource.new("file", "/f").should_not == "foo"
+    end
+
+    it "should not be considered equivalent to another resource if their types do not match" do
+        Puppet::Resource.new("file", "/f").should_not == Puppet::Resource.new("exec", "/f")
+    end
+
+    it "should not be considered equivalent to another resource if their titles do not match" do
+        Puppet::Resource.new("file", "/foo").should_not == Puppet::Resource.new("file", "/f")
+    end
+
     describe "when managing parameters" do
         before do
             @resource = Puppet::Resource.new("file", "/my/file")
@@ -305,7 +351,10 @@ describe Puppet::Resource do
         end
 
         it "should set :name to the title if :name is not present for non-builtin types" do
+            krt = Puppet::Resource::TypeCollection.new("myenv")
+            krt.add Puppet::Resource::Type.new(:definition, :foo)
             resource = Puppet::Resource.new :foo, "bar"
+            resource.stubs(:known_resource_types).returns krt
             resource.to_hash[:name].should == "bar"
         end
     end
@@ -334,25 +383,19 @@ describe Puppet::Resource do
     end
 
     describe "when converting to a RAL resource" do
-        before do
-            @resource = Puppet::Resource.new("file", "/my/file")
-            @resource["one"] = "test"
-            @resource["two"] = "other"
-        end
-
-        it "should use the resource type's :create method to create the resource if the resource is of a builtin type" do
-            type = mock 'resource type'
-            type.expects(:new).with(@resource).returns(:myresource)
-            Puppet::Type.expects(:type).with(@resource.type).returns(type)
-            @resource.to_ral.should == :myresource
+        it "should use the resource type's :new method to create the resource if the resource is of a builtin type" do
+            resource = Puppet::Resource.new("file", "/my/file")
+            result = resource.to_ral
+            result.should be_instance_of(Puppet::Type.type(:file))
+            result[:path].should == "/my/file"
         end
 
         it "should convert to a component instance if the resource type is not of a builtin type" do
-            component = mock 'component type'
-            Puppet::Type::Component.expects(:new).with(@resource).returns "meh"
+            resource = Puppet::Resource.new("foobar", "somename")
+            result = resource.to_ral
 
-            Puppet::Type.expects(:type).with(@resource.type).returns(nil)
-            @resource.to_ral.should == "meh"
+            result.should be_instance_of(Puppet::Type.type(:component))
+            result.title.should == "Foobar[somename]"
         end
     end
 
@@ -450,13 +493,13 @@ describe Puppet::Resource do
             end
 
             it "should convert resource references into the backward-compatible form" do
-                @resource[:foo] = Puppet::Resource::Reference.new(:file, "/f")
-                @resource.to_trans["foo"].should == %w{file /f}
+                @resource[:foo] = Puppet::Resource.new(:file, "/f")
+                @resource.to_trans["foo"].should == %w{File /f}
             end
 
             it "should convert resource references into the backward-compatible form even when within arrays" do
-                @resource[:foo] = ["a", Puppet::Resource::Reference.new(:file, "/f")]
-                @resource.to_trans["foo"].should == ["a", %w{file /f}]
+                @resource[:foo] = ["a", Puppet::Resource.new(:file, "/f")]
+                @resource.to_trans["foo"].should == ["a", %w{File /f}]
             end
         end
     end
@@ -618,4 +661,16 @@ describe Puppet::Resource do
             Puppet::Resource.new("file", "/my/file").name.should == "File//my/file"
         end
     end
+
+    describe "when resolving resources with a catalog" do
+        it "should resolve all resources using the catalog" do
+            catalog = mock 'catalog'
+            resource = Puppet::Resource.new("foo::bar", "yay")
+            resource.catalog = catalog
+
+            catalog.expects(:resource).with("Foo::Bar[yay]").returns(:myresource)
+
+            resource.resolve.should == :myresource
+        end
+    end
 end
diff --git a/spec/unit/resource/catalog.rb b/spec/unit/resource/catalog.rb
index e2fe724..6c6af24 100755
--- a/spec/unit/resource/catalog.rb
+++ b/spec/unit/resource/catalog.rb
@@ -109,7 +109,7 @@ describe Puppet::Resource::Catalog, "when compiling" do
         end
 
         def mkresource(type, name)
-            Puppet::Parser::Resource.new(:type => type, :title => name, :source => @source, :scope => @scope)
+            Puppet::Parser::Resource.new(type, name, :source => @source, :scope => @scope)
         end
 
         it "should always create a TransBucket for the 'main' class" do
diff --git a/spec/unit/resource/reference.rb b/spec/unit/resource/reference.rb
deleted file mode 100755
index 7a97045..0000000
--- a/spec/unit/resource/reference.rb
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../spec_helper'
-
-require 'puppet/resource/reference'
-
-describe Puppet::Resource::Reference do
-    it "should have a :title attribute" do
-        Puppet::Resource::Reference.new(:file, "foo").title.should == "foo"
-    end
-
-    it "should canonize types to capitalized strings" do
-        Puppet::Resource::Reference.new(:file, "foo").type.should == "File"
-    end
-
-    it "should canonize qualified types so all strings are capitalized" do
-        Puppet::Resource::Reference.new("foo::bar", "foo").type.should == "Foo::Bar"
-    end
-
-    it "should set its type to 'Class' and its title to the passed title if the passed type is :component and the title has no square brackets in it" do
-        ref = Puppet::Resource::Reference.new(:component, "foo")
-        ref.type.should == "Class"
-        ref.title.should == "foo"
-    end
-
-    it "should interpret the title as a reference and assign appropriately if the type is :component and the title contains square brackets" do
-        ref = Puppet::Resource::Reference.new(:component, "foo::bar[yay]")
-        ref.type.should == "Foo::Bar"
-        ref.title.should == "yay"
-    end
-
-    it "should set the type to 'Class' if it is nil and the title contains no square brackets" do
-        ref = Puppet::Resource::Reference.new(nil, "yay")
-        ref.type.should == "Class"
-        ref.title.should == "yay"
-    end
-
-    it "should interpret the title as a reference and assign appropriately if the type is nil and the title contains square brackets" do
-        ref = Puppet::Resource::Reference.new(nil, "foo::bar[yay]")
-        ref.type.should == "Foo::Bar"
-        ref.title.should == "yay"
-    end
-
-    it "should interpret the title as a reference and assign appropriately if the type is nil and the title contains nested square brackets" do
-        ref = Puppet::Resource::Reference.new(nil, "foo::bar[baz[yay]]")
-        ref.type.should == "Foo::Bar"
-        ref.title.should =="baz[yay]"
-    end
-
-    it "should interpret the type as a reference and assign appropriately if the title is nil and the type contains square brackets" do
-        ref = Puppet::Resource::Reference.new("foo::bar[baz]")
-        ref.type.should == "Foo::Bar"
-        ref.title.should =="baz"
-    end
-
-    it "should be able to extract its information from a Puppet::Type instance" do
-        ral = Puppet::Type.type(:file).new :path => "/foo"
-        ref = Puppet::Resource::Reference.new(ral)
-        ref.type.should == "File"
-        ref.title.should == "/foo"
-    end
-
-
-    it "should fail if the title is nil and the type is not a valid resource reference string" do
-        lambda { Puppet::Resource::Reference.new("foo") }.should raise_error(ArgumentError)
-    end
-
-    it "should be considered builtin if an existing resource type matches the type" do
-        Puppet::Resource::Reference.new("file", "/f").should be_builtin_type
-    end
-
-    it "should be not considered builtin if an existing resource type does not match the type" do
-        Puppet::Resource::Reference.new("foobar", "/f").should_not be_builtin_type
-    end
-
-    it "should be able to produce a backward-compatible reference array" do
-        Puppet::Resource::Reference.new("foobar", "/f").to_trans_ref.should == %w{Foobar /f}
-    end
-
-    it "should downcase resource types when producing a backward-compatible reference array for builtin resource types" do
-        Puppet::Resource::Reference.new("file", "/f").to_trans_ref.should == %w{file /f}
-    end
-
-    it "should be considered equivalent to another reference if their type and title match" do
-        Puppet::Resource::Reference.new("file", "/f").should == Puppet::Resource::Reference.new("file", "/f")
-    end
-
-    it "should not be considered equivalent to a non-reference" do
-        Puppet::Resource::Reference.new("file", "/f").should_not == "foo"
-    end
-
-    it "should not be considered equivalent to another reference if their types do not match" do
-        Puppet::Resource::Reference.new("file", "/f").should_not == Puppet::Resource::Reference.new("exec", "/f")
-    end
-
-    it "should not be considered equivalent to another reference if their titles do not match" do
-        Puppet::Resource::Reference.new("file", "/foo").should_not == Puppet::Resource::Reference.new("file", "/f")
-    end
-
-    describe "when resolving resources with a catalog" do
-        it "should resolve all resources using the catalog" do
-            config = mock 'catalog'
-            ref = Puppet::Resource::Reference.new("foo::bar", "yay")
-            ref.catalog = config
-
-            config.expects(:resource).with("Foo::Bar[yay]").returns(:myresource)
-
-            ref.resolve.should == :myresource
-        end
-    end
-end
diff --git a/spec/unit/resource/type.rb b/spec/unit/resource/type.rb
index 0a2f447..1a19cf4 100755
--- a/spec/unit/resource/type.rb
+++ b/spec/unit/resource/type.rb
@@ -456,13 +456,13 @@ describe Puppet::Resource::Type do
         end
 
         it "should fail unless it is a class" do
-            lambda { Puppet::Resource::Type.new(:node, "bar").merge("foo") }.should raise_error(ArgumentError)
+            lambda { Puppet::Resource::Type.new(:node, "bar").merge("foo") }.should raise_error(Puppet::Error)
         end
 
         it "should fail unless the source instance is a class" do
             dest = Puppet::Resource::Type.new(:hostclass, "bar")
             source = Puppet::Resource::Type.new(:node, "foo")
-            lambda { dest.merge(source) }.should raise_error(ArgumentError)
+            lambda { dest.merge(source) }.should raise_error(Puppet::Error)
         end
 
         it "should fail if both classes have different parent classes" do
@@ -471,7 +471,7 @@ describe Puppet::Resource::Type do
                 code.add Puppet::Resource::Type.new(:hostclass, parent)
                 code.add Puppet::Resource::Type.new(:hostclass, child, :parent => parent)
             end
-            lambda { code.hostclass("b").merge(code.hostclass("d")) }.should raise_error(ArgumentError)
+            lambda { code.hostclass("b").merge(code.hostclass("d")) }.should raise_error(Puppet::Error)
         end
 
         it "should copy the other class's parent if it has not parent" do
diff --git a/spec/unit/resource/type_collection.rb b/spec/unit/resource/type_collection.rb
index 3de5e50..a2a213f 100644
--- a/spec/unit/resource/type_collection.rb
+++ b/spec/unit/resource/type_collection.rb
@@ -64,7 +64,32 @@ describe Puppet::Resource::TypeCollection do
         @code.definition("foo").should equal(define)
     end
 
+    it "should merge new classes with existing classes of the same name" do
+        loader = Puppet::Resource::TypeCollection.new("env")
+        first = Puppet::Resource::Type.new(:hostclass, "foo")
+        second = Puppet::Resource::Type.new(:hostclass, "foo")
+        loader.add first
+        first.expects(:merge).with(second)
+        loader.add(second)
+    end
+
+    it "should remove all nodes, classes, and definitions when cleared" do
+        loader = Puppet::Resource::TypeCollection.new("env")
+        loader.add Puppet::Resource::Type.new(:hostclass, "class")
+        loader.add Puppet::Resource::Type.new(:definition, "define")
+        loader.add Puppet::Resource::Type.new(:node, "node")
+
+        loader.clear
+        loader.hostclass("class").should be_nil
+        loader.definition("define").should be_nil
+        loader.node("node").should be_nil
+    end
+
     %w{hostclass node definition}.each do |data|
+        before do
+            @instance = Puppet::Resource::Type.new(data, "foo")
+        end
+
         it "should have a method for adding a #{data}" do
             Puppet::Resource::TypeCollection.new("env").should respond_to("add_" + data)
         end
@@ -75,10 +100,12 @@ describe Puppet::Resource::TypeCollection do
             loader.send(data, @instance.name).should equal(@instance)
         end
 
-        it "should fail to add a #{data} when one already exists" do
-            loader = Puppet::Resource::TypeCollection.new("env")
-            loader.add @instance
-            lambda { loader.add(@instance) }.should raise_error(Puppet::ParseError)
+        unless data == "hostclass"
+            it "should fail to add a #{data} when one already exists" do
+                loader = Puppet::Resource::TypeCollection.new("env")
+                loader.add @instance
+                lambda { loader.add(@instance) }.should raise_error(Puppet::ParseError)
+            end
         end
 
         it "should return the added #{data}" do
@@ -127,6 +154,13 @@ describe Puppet::Resource::TypeCollection do
             loader.find("namespace", "::foo::bar", :hostclass).should be_nil
         end
 
+        it "should be able to find classes in the base namespace" do
+            loader = Puppet::Resource::TypeCollection.new("env")
+            instance = Puppet::Resource::Type.new(:hostclass, "foo")
+            loader.add instance
+            loader.find("", "foo", :hostclass).should equal(instance)
+        end
+
         it "should return the partially qualified object if it exists in a provided namespace" do
             loader = Puppet::Resource::TypeCollection.new("env")
             instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz")
diff --git a/examples/etc/otherfile b/spec/unit/transportable.rb
similarity index 100%
copy from examples/etc/otherfile
copy to spec/unit/transportable.rb
diff --git a/spec/unit/type.rb b/spec/unit/type.rb
index 73f249f..b2f4bcb 100755
--- a/spec/unit/type.rb
+++ b/spec/unit/type.rb
@@ -464,13 +464,13 @@ describe Puppet::Type::RelationshipMetaparam do
             @metaparam = Puppet::Type.metaparamclass(:require).new :resource => @resource
         end
 
-        it "should accept Puppet::Resource::Reference instances" do
-            ref = Puppet::Resource::Reference.new(:file, "/foo")
+        it "should accept Puppet::Resource instances" do
+            ref = Puppet::Resource.new(:file, "/foo")
             @metaparam.munge(ref)[0].should equal(ref)
         end
 
-        it "should turn any string into a Puppet::Resource::Reference" do
-            @metaparam.munge("File[/ref]")[0].should be_instance_of(Puppet::Resource::Reference)
+        it "should turn any string into a Puppet::Resource" do
+            @metaparam.munge("File[/ref]")[0].should be_instance_of(Puppet::Resource)
         end
     end
 
diff --git a/spec/unit/type/tidy.rb b/spec/unit/type/tidy.rb
index ccec9ed..9bee7d7 100755
--- a/spec/unit/type/tidy.rb
+++ b/spec/unit/type/tidy.rb
@@ -390,7 +390,7 @@ describe tidy do
                 "/what/ever/one/subone" => ["/what/ever/one/subone/ssone"]
             }.each do |parent, children|
                 children.each do |child|
-                    ref = Puppet::Resource::Reference.new(:file, child)
+                    ref = Puppet::Resource.new(:file, child)
                     result[parent][:require].find { |req| req.to_s == ref.to_s }.should_not be_nil
                 end
             end
diff --git a/test/language/functions.rb b/test/language/functions.rb
index af07325..70605f8 100755
--- a/test/language/functions.rb
+++ b/test/language/functions.rb
@@ -289,16 +289,12 @@ class TestLangFunctions < Test::Unit::TestCase
 
         Puppet[:code] = %{file { "#{file}": content => template("#{template}") }}
         Puppet[:environment] = "yay"
-        interp = Puppet::Parser::Interpreter.new
         node = mknode
-        node.stubs(:environment).returns("yay")
+        node.stubs(:environment).returns Puppet::Node::Environment.new
 
         Puppet[:environment] = "yay"
 
-        catalog = nil
-        assert_nothing_raised {
-            catalog = interp.compile(node)
-        }
+        catalog = Puppet::Parser::Compiler.new(node).compile
 
         version = catalog.version
 
@@ -317,7 +313,7 @@ class TestLangFunctions < Test::Unit::TestCase
             f.puts "new text"
         end
 
-        newversion = interp.compile(node).version
+        newversion = Puppet::Parser::Compiler.new(node).compile.version
 
         assert(version != newversion, "Parse date did not change")
     end
@@ -385,100 +381,6 @@ class TestLangFunctions < Test::Unit::TestCase
             "Did not set function correctly")
     end
 
-    def test_realize
-        scope = mkscope
-        parser = scope.compiler.parser
-
-        realize = Puppet::Parser::Functions.function(:realize)
-
-        # Make a definition
-        parser.newdefine("mytype")
-
-        [%w{file /tmp/virtual}, %w{mytype yay}].each do |type, title|
-            # Make a virtual resource
-            virtual = mkresource(:type => type, :title => title,
-                :virtual => true, :params => {}, :scope => scope)
-
-            scope.compiler.add_resource(scope, virtual)
-
-            ref = Puppet::Parser::Resource::Reference.new(
-                :type => type, :title => title,
-                :scope => scope
-            )
-            # Now call the realize function
-            assert_nothing_raised do
-                scope.function_realize(ref)
-            end
-
-            # Make sure it created a collection
-            assert_equal(1, scope.compiler.collections.length,
-                "Did not set collection")
-
-            assert_nothing_raised do
-                scope.compiler.collections.each do |coll| coll.evaluate end
-            end
-            scope.compiler.collections.clear
-
-            # Now make sure the virtual resource is no longer virtual
-            assert(! virtual.virtual?, "Did not make virtual resource real")
-        end
-
-        # Make sure we puke on any resource that doesn't exist
-        none = Puppet::Parser::Resource::Reference.new(
-            :type => "file", :title => "/tmp/nosuchfile",
-            :scope => scope
-        )
-
-        # The function works
-        assert_nothing_raised do
-            scope.function_realize(none.to_s)
-        end
-
-        # Make sure it created a collection
-        assert_equal(1, scope.compiler.collections.length,
-            "Did not set collection")
-
-        # And the collection has our resource in it
-        assert_equal([none.to_s], scope.compiler.collections[0].resources,
-            "Did not set resources in collection")
-    end
-
-    def test_defined
-        scope = mkscope
-        parser = scope.compiler.parser
-
-        defined = Puppet::Parser::Functions.function(:defined)
-
-        parser.newclass("yayness")
-        parser.newdefine("rahness")
-
-        assert_nothing_raised do
-            assert(scope.function_defined("yayness"), "yayness class was not considered defined")
-            assert(scope.function_defined("rahness"), "rahness definition was not considered defined")
-            assert(scope.function_defined("service"), "service type was not considered defined")
-            assert(! scope.function_defined("fakness"), "fakeness was considered defined")
-        end
-
-        # Now make sure any match in a list will work
-        assert(scope.function_defined(["booness", "yayness", "fakeness"]),
-            "A single answer was not sufficient to return true")
-
-        # and make sure multiple falses are still false
-        assert(! scope.function_defined(%w{no otherno stillno}),
-            "Multiple falses were somehow true")
-
-        # Now make sure we can test resources
-        scope.compiler.add_resource(scope, mkresource(:type => "file", :title => "/tmp/rahness",
-            :scope => scope, :source => scope.source,
-            :params => {:owner => "root"}))
-
-        yep = Puppet::Parser::Resource::Reference.new(:type => "file", :title => "/tmp/rahness")
-        nope = Puppet::Parser::Resource::Reference.new(:type => "file", :title => "/tmp/fooness")
-
-        assert(scope.function_defined([yep]), "valid resource was not considered defined")
-        assert(! scope.function_defined([nope]), "invalid resource was considered defined")
-    end
-
     def test_search
         parser = mkparser
         scope = mkscope(:parser => parser)
@@ -503,7 +405,7 @@ class TestLangFunctions < Test::Unit::TestCase
 
     def test_include
         scope = mkscope
-        parser = scope.compiler.parser
+        parser = mkparser
 
         include = Puppet::Parser::Functions.function(:include)
 
@@ -569,7 +471,7 @@ class TestLangFunctions < Test::Unit::TestCase
         generate = Puppet::Parser::Functions.function(:generate)
 
         scope = mkscope
-        parser = scope.compiler.parser
+        parser = mkparser
 
         val = nil
         assert_nothing_raised("Could not call generator with no args") do
diff --git a/test/language/parser.rb b/test/language/parser.rb
index a3311f4..b721490 100755
--- a/test/language/parser.rb
+++ b/test/language/parser.rb
@@ -18,8 +18,14 @@ class TestParser < Test::Unit::TestCase
         #@lexer = Puppet::Parser::Lexer.new()
     end
 
+    def teardown
+        super
+        Puppet::Node::Environment.clear
+    end
+
     def test_each_file
         textfiles { |file|
+            Puppet::Node::Environment.clear
             parser = mkparser
             Puppet.debug("parsing %s" % file) if __FILE__ == $0
             assert_nothing_raised() {
@@ -379,9 +385,7 @@ file { "/tmp/yayness":
         assert_instance_of(Puppet::Parser::AST::IfStatement, ret)
         parser = mkparser
         str2 = %{if true { #{exec.call("true")} } else { #{exec.call("false")} }}
-        assert_nothing_raised {
-            ret = parser.parse(str2).hostclass("").code[0]
-        }
+        ret = parser.parse(str2).hostclass("").code[0]
         assert_instance_of(Puppet::Parser::AST::IfStatement, ret)
         assert_instance_of(Puppet::Parser::AST::Else, ret.else)
     end
@@ -410,7 +414,7 @@ file { "/tmp/yayness":
         }
         sub = parser.hostclass("container::one")
         assert(sub, "Could not find one")
-        assert_equal("container::deep::sub", sub.parentclass)
+        assert_equal("container::deep::sub", sub.parent)
 
         # Finally, try including a qualified class
         assert_nothing_raised("Could not include fully qualified class") {
@@ -435,7 +439,7 @@ file { "/tmp/yayness":
         assert_nothing_raised do
             out = parser.parse "Exec { path => '/usr/bin:/usr/sbin' }"
             assert_instance_of(Puppet::Resource::TypeCollection, out)
-            assert_equal("", parser.hostclass("").classname)
+            assert_equal("", parser.hostclass("").name)
             assert_equal("", parser.hostclass("").namespace)
         end
     end
@@ -520,6 +524,7 @@ file { "/tmp/yayness":
         end
 
         tests.each do |form|
+            Puppet::Node::Environment.clear
             parser = mkparser
 
             if form == :virtual
@@ -549,6 +554,7 @@ file { "/tmp/yayness":
 
     def test_collectionexpressions
         %w{== !=}.each do |oper|
+            Puppet::Node::Environment.clear
             str = "File <| title #{oper} '/tmp/testing' |>"
 
             parser = mkparser
@@ -616,30 +622,6 @@ file { "/tmp/yayness":
         end
     end
 
-    # We've had problems with files other than site.pp importing into main.
-    def test_importing_into_main
-        top = tempfile()
-        other = tempfile()
-        File.open(top, "w") do |f|
-            f.puts "import '#{other}'"
-        end
-
-        file = tempfile()
-        File.open(other, "w") do |f|
-            f.puts "file { '#{file}': ensure => present }"
-        end
-
-        Puppet[:manifest] = top
-        interp = Puppet::Parser::Interpreter.new
-
-        code = nil
-        assert_nothing_raised do
-            code = interp.compile(mknode).extract.flatten
-        end
-        assert(code.length == 1, "Did not get the file")
-        assert_instance_of(Puppet::TransObject, code[0])
-    end
-
     def test_fully_qualified_definitions
         parser = mkparser
 
@@ -803,196 +785,10 @@ file { "/tmp/yayness":
         end
         assert_instance_of(Puppet::Resource::TypeCollection, result, "Did not get a ASTSet back from parsing")
 
-        assert_instance_of(AST::HostClass, result.hostclass("yay"), "Did not create 'yay' class")
-        assert_instance_of(AST::HostClass, result.hostclass(""), "Did not create main class")
-        assert_instance_of(AST::Definition, result.definition("bar"), "Did not create 'bar' definition")
-        assert_instance_of(AST::Node, result.node("foo"), "Did not create 'foo' node")
-    end
-
-    # Make sure our node gets added to the node table.
-    def test_newnode
-        parser = mkparser
-
-        # First just try calling it directly
-        assert_nothing_raised {
-            parser.newnode("mynode", :code => :yay)
-        }
-
-        assert_equal(:yay, parser.node("mynode").code)
-
-        # Now make sure that trying to redefine it throws an error.
-        assert_raise(Puppet::ParseError) {
-            parser.newnode("mynode", {})
-        }
-
-        # Now try one with no code
-        assert_nothing_raised {
-            parser.newnode("simplenode", :parent => :foo)
-        }
-
-        # Now define the parent node
-        parser.newnode(:foo)
-
-        # And make sure we get things back correctly
-        assert_equal(:foo, parser.node("simplenode").parentclass)
-        assert_nil(parser.node("simplenode").code)
-
-        # Now make sure that trying to redefine it throws an error.
-        assert_raise(Puppet::ParseError) {
-            parser.newnode("mynode", {})
-        }
-
-        # Test multiple names
-        names = ["one", "two", "three"]
-        assert_nothing_raised {
-            parser.newnode(names, {:code => :yay, :parent => :foo})
-        }
-
-        names.each do |name|
-            assert_equal(:yay, parser.node(name).code)
-            assert_equal(:foo, parser.node(name).parentclass)
-            # Now make sure that trying to redefine it throws an error.
-            assert_raise(Puppet::ParseError) {
-                parser.newnode(name, {})
-            }
-        end
-    end
-
-    def test_newdefine
-        parser = mkparser
-
-        assert_nothing_raised {
-            parser.newdefine("mydefine", :code => :yay,
-                :arguments => ["a", stringobj("b")])
-        }
-
-        mydefine = parser.definition("mydefine")
-        assert(mydefine, "Could not find definition")
-        assert_equal("", mydefine.namespace)
-        assert_equal("mydefine", mydefine.classname)
-
-        assert_raise(Puppet::ParseError) do
-            parser.newdefine("mydefine", :code => :yay,
-                :arguments => ["a", stringobj("b")])
-        end
-
-        # Now define the same thing in a different scope
-        assert_nothing_raised {
-            parser.newdefine("other::mydefine", :code => :other,
-                :arguments => ["a", stringobj("b")])
-        }
-        other = parser.definition("other::mydefine")
-        assert(other, "Could not find definition")
-        assert(parser.definition("other::mydefine"),
-            "Could not find other::mydefine")
-        assert_equal(:other, other.code)
-        assert_equal("other", other.namespace)
-        assert_equal("other::mydefine", other.classname)
-    end
-
-    def test_newclass
-        scope = mkscope
-        parser = scope.compiler.parser
-
-        mkcode = proc do |ary|
-            classes = ary.collect do |string|
-                AST::FlatString.new(:value => string)
-            end
-            AST::ASTArray.new(:children => classes)
-        end
-
-
-        # First make sure that code is being appended
-        code = mkcode.call(%w{original code})
-
-        klass = nil
-        assert_nothing_raised {
-            klass = parser.newclass("myclass", :code => code)
-        }
-
-        assert(klass, "Did not return class")
-
-        assert(parser.hostclass("myclass"), "Could not find definition")
-        assert_equal("myclass", parser.hostclass("myclass").classname)
-        assert_equal(%w{original code},
-             parser.hostclass("myclass").code.evaluate(scope))
-
-        # Newclass behaves differently than the others -- it just appends
-        # the code to the existing class.
-        code = mkcode.call(%w{something new})
-        assert_nothing_raised do
-            klass = parser.newclass("myclass", :code => code)
-        end
-        assert(klass, "Did not return class when appending")
-        assert_equal(%w{original code something new},
-            parser.hostclass("myclass").code.evaluate(scope))
-
-        # Now create the same class name in a different scope
-        assert_nothing_raised {
-            klass = parser.newclass("other::myclass",
-                            :code => mkcode.call(%w{something diff}))
-        }
-        assert(klass, "Did not return class")
-        other = parser.hostclass("other::myclass")
-        assert(other, "Could not find class")
-        assert_equal("other::myclass", other.classname)
-        assert_equal("other::myclass", other.namespace)
-        assert_equal(%w{something diff},
-             other.code.evaluate(scope))
-
-        # Make sure newclass deals correctly with nodes with no code
-        klass = parser.newclass("nocode")
-        assert(klass, "Did not return class")
-
-        assert_nothing_raised do
-            klass = parser.newclass("nocode", :code => mkcode.call(%w{yay test}))
-        end
-        assert(klass, "Did not return class with no code")
-        assert_equal(%w{yay test},
-            parser.hostclass("nocode").code.evaluate(scope))
-
-        # Then try merging something into nothing
-        parser.newclass("nocode2", :code => mkcode.call(%w{foo test}))
-        assert(klass, "Did not return class with no code")
-
-        assert_nothing_raised do
-            klass = parser.newclass("nocode2")
-        end
-        assert(klass, "Did not return class with no code")
-        assert_equal(%w{foo test},
-            parser.hostclass("nocode2").code.evaluate(scope))
-
-        # And lastly, nothing and nothing
-        klass = parser.newclass("nocode3")
-        assert(klass, "Did not return class with no code")
-
-        assert_nothing_raised do
-            klass = parser.newclass("nocode3")
-        end
-        assert(klass, "Did not return class with no code")
-        assert_nil(parser.hostclass("nocode3").code)
-    end
-
-    # Make sure you can't have classes and defines with the same name in the
-    # same scope.
-    def test_classes_beat_defines
-        parser = mkparser
-
-        assert_nothing_raised {
-            parser.newclass("yay::funtest")
-        }
-
-        assert_raise(Puppet::ParseError) do
-            parser.newdefine("yay::funtest")
-        end
-
-        assert_nothing_raised {
-            parser.newdefine("yay::yaytest")
-        }
-
-        assert_raise(Puppet::ParseError) do
-            parser.newclass("yay::yaytest")
-        end
+        assert_instance_of(Puppet::Resource::Type, result.hostclass("yay"), "Did not create 'yay' class")
+        assert_instance_of(Puppet::Resource::Type, result.hostclass(""), "Did not create main class")
+        assert_instance_of(Puppet::Resource::Type, result.definition("bar"), "Did not create 'bar' definition")
+        assert_instance_of(Puppet::Resource::Type, result.node("foo"), "Did not create 'foo' node")
     end
 
     def test_namesplit
@@ -1009,50 +805,6 @@ file { "/tmp/yayness":
         end
     end
 
-    # Now make sure we get appropriate behaviour with parent class conflicts.
-    def test_newclass_parentage
-        parser = mkparser
-        parser.newclass("base1")
-        parser.newclass("one::two::three")
-
-        # First create it with no parentclass.
-        assert_nothing_raised {
-            parser.newclass("sub")
-        }
-        assert(parser.hostclass("sub"), "Could not find definition")
-        assert_nil(parser.hostclass("sub").parentclass)
-
-        # Make sure we can't set the parent class to ourself.
-        assert_raise(Puppet::ParseError) {
-            parser.newclass("sub", :parent => "sub")
-        }
-
-        # Now create another one, with a parentclass.
-        assert_nothing_raised {
-            parser.newclass("sub", :parent => "base1")
-        }
-
-        # Make sure we get the right parent class, and make sure it's not an object.
-        assert_equal("base1",
-                    parser.hostclass("sub").parentclass)
-
-        # Now make sure we get a failure if we try to conflict.
-        assert_raise(Puppet::ParseError) {
-            parser.newclass("sub", :parent => "one::two::three")
-        }
-
-        # Make sure that failure didn't screw us up in any way.
-        assert_equal("base1",
-                    parser.hostclass("sub").parentclass)
-        # But make sure we can create a class with a fq parent
-        assert_nothing_raised {
-            parser.newclass("another", :parent => "one::two::three")
-        }
-        assert_equal("one::two::three",
-                    parser.hostclass("another").parentclass)
-
-    end
-
     # Setup a module.
     def mk_module(name, files = {})
         mdir = File.join(@dir, name)
@@ -1095,22 +847,22 @@ file { "/tmp/yayness":
 
         # Try to load the module automatically now
         klass = parser.find_hostclass("", name)
-        assert_instance_of(AST::HostClass, klass, "Did not autoload class from module init file")
-        assert_equal(name, klass.classname, "Incorrect class was returned")
+        assert_instance_of(Puppet::Resource::Type, klass, "Did not autoload class from module init file")
+        assert_equal(name, klass.name, "Incorrect class was returned")
 
         # Try loading the simple module when we're in something other than the base namespace.
         parser = mkparser
         klass = parser.find_hostclass("something::else", name)
-        assert_instance_of(AST::HostClass, klass, "Did not autoload class from module init file")
-        assert_equal(name, klass.classname, "Incorrect class was returned")
+        assert_instance_of(Puppet::Resource::Type, klass, "Did not autoload class from module init file")
+        assert_equal(name, klass.name, "Incorrect class was returned")
 
         # Now try it with a definition as the base file
         name = "simpdef"
         mk_module(name, :define => true, :init => [name])
 
         klass = parser.find_definition("", name)
-        assert_instance_of(AST::Definition, klass, "Did not autoload class from module init file")
-        assert_equal(name, klass.classname, "Incorrect class was returned")
+        assert_instance_of(Puppet::Resource::Type, klass, "Did not autoload class from module init file")
+        assert_equal(name, klass.name, "Incorrect class was returned")
 
         # Now try it with namespace classes where both classes are in the init file
         parser = mkparser
@@ -1120,14 +872,14 @@ file { "/tmp/yayness":
 
         # First try it with a namespace
         klass = parser.find_hostclass("both", name)
-        assert_instance_of(AST::HostClass, klass, "Did not autoload sub class from module init file with a namespace")
-        assert_equal("both::sub", klass.classname, "Incorrect class was returned")
+        assert_instance_of(Puppet::Resource::Type, klass, "Did not autoload sub class from module init file with a namespace")
+        assert_equal("both::sub", klass.name, "Incorrect class was returned")
 
         # Now try it using the fully qualified name
         parser = mkparser
         klass = parser.find_hostclass("", "both::sub")
-        assert_instance_of(AST::HostClass, klass, "Did not autoload sub class from module init file with no namespace")
-        assert_equal("both::sub", klass.classname, "Incorrect class was returned")
+        assert_instance_of(Puppet::Resource::Type, klass, "Did not autoload sub class from module init file with no namespace")
+        assert_equal("both::sub", klass.name, "Incorrect class was returned")
 
 
         # Now try it with the class in a different file
@@ -1138,14 +890,14 @@ file { "/tmp/yayness":
 
         # First try it with a namespace
         klass = parser.find_hostclass("separate", name)
-        assert_instance_of(AST::HostClass, klass, "Did not autoload sub class from separate file with a namespace")
-        assert_equal("separate::sub", klass.classname, "Incorrect class was returned")
+        assert_instance_of(Puppet::Resource::Type, klass, "Did not autoload sub class from separate file with a namespace")
+        assert_equal("separate::sub", klass.name, "Incorrect class was returned")
 
         # Now try it using the fully qualified name
         parser = mkparser
         klass = parser.find_hostclass("", "separate::sub")
-        assert_instance_of(AST::HostClass, klass, "Did not autoload sub class from separate file with no namespace")
-        assert_equal("separate::sub", klass.classname, "Incorrect class was returned")
+        assert_instance_of(Puppet::Resource::Type, klass, "Did not autoload sub class from separate file with no namespace")
+        assert_equal("separate::sub", klass.name, "Incorrect class was returned")
 
         # Now make sure we don't get a failure when there's no module file
         parser = mkparser
@@ -1157,22 +909,22 @@ file { "/tmp/yayness":
         assert_nothing_raised("Could not autoload file when module file is missing") do
             klass = parser.find_hostclass("alone", name)
         end
-        assert_instance_of(AST::HostClass, klass, "Did not autoload sub class from alone file with a namespace")
-        assert_equal("alone::sub", klass.classname, "Incorrect class was returned")
+        assert_instance_of(Puppet::Resource::Type, klass, "Did not autoload sub class from alone file with a namespace")
+        assert_equal("alone::sub", klass.name, "Incorrect class was returned")
 
         # Now try it using the fully qualified name
         parser = mkparser
         klass = parser.find_hostclass("", "alone::sub")
-        assert_instance_of(AST::HostClass, klass, "Did not autoload sub class from alone file with no namespace")
-        assert_equal("alone::sub", klass.classname, "Incorrect class was returned")
+        assert_instance_of(Puppet::Resource::Type, klass, "Did not autoload sub class from alone file with no namespace")
+        assert_equal("alone::sub", klass.name, "Incorrect class was returned")
 
         # and with the definition in its own file
         name = "mymod"
         mk_module(name, :define => true, :mydefine => ["mymod::mydefine"])
 
         klass = parser.find_definition("", "mymod::mydefine")
-        assert_instance_of(AST::Definition, klass, "Did not autoload definition from its own file")
-        assert_equal("mymod::mydefine", klass.classname, "Incorrect definition was returned")
+        assert_instance_of(Puppet::Resource::Type, klass, "Did not autoload definition from its own file")
+        assert_equal("mymod::mydefine", klass.name, "Incorrect definition was returned")
     end
 
     # Make sure class, node, and define methods are case-insensitive
@@ -1191,25 +943,4 @@ file { "/tmp/yayness":
         assert_equal(result, parser.find_definition("", "fUntEst"),
             "%s was not matched" % "fUntEst")
     end
-
-    def test_manifests_with_multiple_environments
-        parser = mkparser :environment => "something"
-
-        # We use an exception to cut short the processing to simplify our stubbing
-        #Puppet::Module.expects(:find_manifests).with("test", {:cwd => ".", :environment => "something"}).raises(Puppet::ParseError)
-        Puppet::Parser::Files.expects(:find_manifests).with("test", {:cwd => ".", :environment => "something"}).returns([])
-
-        assert_raise(Puppet::ImportError) do
-            parser.import("test")
-        end
-    end
-
-    def test_watch_file_only_once
-        FileTest.stubs(:exists?).returns(true)
-        parser = mkparser
-        parser.watch_file("doh")
-        parser.watch_file("doh")
-        assert_equal(1, parser.files.select { |name, file| file.file == "doh" }.length, "Length of watched 'doh' files was not 1")
-    end
 end
-
diff --git a/test/language/resource.rb b/test/language/resource.rb
deleted file mode 100755
index c1d116f..0000000
--- a/test/language/resource.rb
+++ /dev/null
@@ -1,172 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../lib/puppettest'
-
-require 'puppettest'
-require 'puppettest/resourcetesting'
-
-class TestResource < PuppetTest::TestCase
-    include PuppetTest
-    include PuppetTest::ParserTesting
-    include PuppetTest::ResourceTesting
-    Parser = Puppet::Parser
-    AST = Parser::AST
-    Resource = Puppet::Parser::Resource
-    Reference = Puppet::Parser::Resource::Reference
-
-    def setup
-        super
-        Puppet[:trace] = false
-    end
-
-    def teardown
-        mocha_verify
-    end
-
-    # Make sure we paramcheck our params
-    def test_validate
-        res = mkresource
-        params = res.instance_variable_get("@params")
-        params[:one] = :two
-        params[:three] = :four
-        res.expects(:paramcheck).with(:one)
-        res.expects(:paramcheck).with(:three)
-        res.send(:validate)
-    end
-
-    def test_set_parameter
-        res = mkresource
-        params = res.instance_variable_get("@params")
-
-        # First test the simple case:  It's already a parameter
-        param = stub('param', :name => "pname")
-        param.expects(:is_a?).with(Resource::Param).returns(true)
-        res.send(:set_parameter, param)
-        assert_equal(param, params["pname"], "Parameter was not added to hash")
-
-        # Now the case where there's no value but it's not a param
-        param = mock('param')
-        param.expects(:is_a?).with(Resource::Param).returns(false)
-        assert_raise(ArgumentError, "Did not fail when a non-param was passed") do
-            res.send(:set_parameter, param)
-        end
-
-        # and the case where a value is passed in
-        param = stub :name => "pname", :value => "whatever"
-        Resource::Param.expects(:new).with(:name => "pname", :value => "myvalue", :source => res.source).returns(param)
-        res.send(:set_parameter, "pname", "myvalue")
-        assert_equal(param, params["pname"], "Did not put param in hash")
-    end
-
-    def test_paramcheck
-        # There are three cases here:
-
-        # It's a valid parameter
-        res = mkresource
-        ref = mock('ref')
-        res.instance_variable_set("@ref", ref)
-        klass = mock("class")
-        ref.expects(:typeclass).returns(klass).times(4)
-        klass.expects(:valid_parameter?).with("good").returns(true)
-        assert(res.send(:paramcheck, :good), "Did not allow valid param")
-
-        # It's name or title
-        klass.expects(:valid_parameter?).with("name").returns(false)
-        assert(res.send(:paramcheck, :name), "Did not allow name")
-        klass.expects(:valid_parameter?).with("title").returns(false)
-        assert(res.send(:paramcheck, :title), "Did not allow title")
-
-        # It's not actually allowed
-        klass.expects(:valid_parameter?).with("other").returns(false)
-        res.expects(:fail)
-        ref.expects(:type)
-        res.send(:paramcheck, :other)
-    end
-
-    def test_evaluate
-        # First try the most common case, we're not a builtin type.
-        res = mkresource
-        ref = res.instance_variable_get("@ref")
-        type = mock("type")
-        ref.expects(:definedtype).returns(type)
-        res.expects(:finish)
-        res.scope = mock("scope")
-
-        type.expects(:evaluate_code).with(res)
-
-        res.evaluate
-    end
-
-    def test_proxymethods
-        res = Parser::Resource.new :type => "evaltest", :title => "yay",
-            :source => mock("source"), :scope => mkscope
-
-        assert_equal("Evaltest", res.type)
-        assert_equal("yay", res.title)
-        assert_equal(false, res.builtin?)
-    end
-
-    # This is a bit of a weird one -- the user should not actually know
-    # that components exist, so we want references to act like they're not
-    # builtin
-    def test_components_are_not_builtin
-        ref = Parser::Resource::Reference.new(:type => "component", :title => "yay")
-
-        assert_nil(ref.builtintype, "Definition was considered builtin")
-    end
-
-    # The second part of #539 - make sure resources pass the arguments
-    # correctly.
-    def test_title_with_definitions
-        parser = mkparser
-        define = parser.newdefine "yayness",
-            :code => resourcedef("file", "/tmp",
-                "owner" => varref("name"), "mode" => varref("title"))
-
-
-        klass = parser.find_hostclass("", "")
-        should = {:name => :owner, :title => :mode}
-        [
-        {:name => "one", :title => "two"},
-        {:title => "three"},
-        ].each do |hash|
-            config = mkcompiler parser
-            args = {:type => "yayness", :title => hash[:title],
-                :source => klass, :scope => config.topscope}
-            if hash[:name]
-                args[:params] = {:name => hash[:name]}
-            else
-                args[:params] = {} # override the defaults
-            end
-
-            res = nil
-            assert_nothing_raised("Could not create res with %s" % hash.inspect) do
-                res = mkresource(args)
-            end
-            assert_nothing_raised("Could not eval res with %s" % hash.inspect) do
-                res.evaluate
-            end
-
-            made = config.topscope.findresource("File[/tmp]")
-            assert(made, "Did not create resource with %s" % hash.inspect)
-            should.each do |orig, param|
-                assert_equal(hash[orig] || hash[:title], made[param],
-                    "%s was not set correctly with %s" % [param, hash.inspect])
-            end
-        end
-    end
-
-    # part of #629 -- the undef keyword.  Make sure 'undef' params get skipped.
-    def test_undef_and_to_hash
-        res = mkresource :type => "file", :title => "/tmp/testing",
-            :source => mock("source"), :scope => mkscope,
-            :params => {:owner => :undef, :mode => "755"}
-
-        hash = nil
-        assert_nothing_raised("Could not convert resource with undef to hash") do
-            hash = res.to_hash
-        end
-
-        assert_nil(hash[:owner], "got a value for an undef parameter")
-    end
-end
diff --git a/test/language/scope.rb b/test/language/scope.rb
index 8819de6..b1ba63d 100755
--- a/test/language/scope.rb
+++ b/test/language/scope.rb
@@ -20,6 +20,11 @@ class TestScope < Test::Unit::TestCase
     include PuppetTest::ParserTesting
     include PuppetTest::ResourceTesting
 
+    def setup
+        Puppet::Node::Environment.clear
+        super
+    end
+
     def to_ary(hash)
         hash.collect { |key,value|
             [key,value]
@@ -102,60 +107,6 @@ class TestScope < Test::Unit::TestCase
         }
     end
 
-    def test_setdefaults
-        config = mkcompiler
-
-        scope = config.topscope
-
-        defaults = scope.instance_variable_get("@defaults")
-
-        # First the case where there are no defaults and we pass a single param
-        param = stub :name => "myparam", :file => "f", :line => "l"
-        scope.setdefaults(:mytype, param)
-        assert_equal({"myparam" => param}, defaults[:mytype], "Did not set default correctly")
-
-        # Now the case where we pass in multiple parameters
-        param1 = stub :name => "one", :file => "f", :line => "l"
-        param2 = stub :name => "two", :file => "f", :line => "l"
-        scope.setdefaults(:newtype, [param1, param2])
-        assert_equal({"one" => param1, "two" => param2}, defaults[:newtype], "Did not set multiple defaults correctly")
-
-        # And the case where there's actually a conflict.  Use the first default for this.
-        newparam = stub :name => "myparam", :file => "f", :line => "l"
-        assert_raise(Puppet::ParseError, "Allowed resetting of defaults") do
-            scope.setdefaults(:mytype, param)
-        end
-        assert_equal({"myparam" => param}, defaults[:mytype], "Replaced default even though there was a failure")
-    end
-
-    def test_lookupdefaults
-        config = mkcompiler
-        top = config.topscope
-
-        # Make a subscope
-        sub = config.newscope(top)
-
-        topdefs = top.instance_variable_get("@defaults")
-        subdefs = sub.instance_variable_get("@defaults")
-
-        # First add some defaults to our top scope
-        topdefs[:t1] = {:p1 => :p2, :p3 => :p4}
-        topdefs[:t2] = {:p5 => :p6}
-
-        # Then the sub scope
-        subdefs[:t1] = {:p1 => :p7, :p8 => :p9}
-        subdefs[:t2] = {:p5 => :p10, :p11 => :p12}
-
-        # Now make sure we get the correct list back
-        result = nil
-        assert_nothing_raised("Could not get defaults") do
-            result = sub.lookupdefaults(:t1)
-        end
-        assert_equal(:p9, result[:p8], "Did not get child defaults")
-        assert_equal(:p4, result[:p3], "Did not override parent defaults with child default")
-        assert_equal(:p7, result[:p1], "Did not get parent defaults")
-    end
-
     def test_parent
         config = mkcompiler
         top = config.topscope
@@ -167,86 +118,6 @@ class TestScope < Test::Unit::TestCase
         assert_equal(top, sub.parent, "Did not find parent scope on second call")
     end
 
-    def test_strinterp
-        # Make and evaluate our classes so the qualified lookups work
-        parser = mkparser
-        klass = parser.newclass("")
-        scope = mkscope(:parser => parser)
-        Puppet::Parser::Resource.new(:type => "class", :title => :main, :scope => scope, :source => mock('source')).evaluate
-
-        assert_nothing_raised {
-            scope.setvar("test","value")
-        }
-
-        scopes = {"" => scope}
-
-        %w{one one::two one::two::three}.each do |name|
-            klass = parser.newclass(name)
-            Puppet::Parser::Resource.new(:type => "class", :title => name, :scope => scope, :source => mock('source')).evaluate
-            scopes[name] = scope.compiler.class_scope(klass)
-            scopes[name].setvar("test", "value-%s" % name.sub(/.+::/,''))
-        end
-
-        assert_equal("value", scope.lookupvar("::test"), "did not look up qualified value correctly")
-        tests = {
-            "string ${test}" => "string value",
-            "string ${one::two::three::test}" => "string value-three",
-            "string $one::two::three::test" => "string value-three",
-            "string ${one::two::test}" => "string value-two",
-            "string $one::two::test" => "string value-two",
-            "string ${one::test}" => "string value-one",
-            "string $one::test" => "string value-one",
-            "string ${::test}" => "string value",
-            "string $::test" => "string value",
-            "string ${test} ${test} ${test}" => "string value value value",
-            "string $test ${test} $test" => "string value value value",
-            "string \\$test" => "string $test",
-            '\\$test string' => "$test string",
-            '$test string' => "value string",
-            'a testing $' => "a testing $",
-            'a testing \$' => "a testing $",
-            "an escaped \\\n carriage return" => "an escaped  carriage return",
-            '\$' => "$",
-            '\s' => "\s",
-            '\t' => "\t",
-            '\n' => "\n"
-        }
-
-        tests.each do |input, output|
-            assert_nothing_raised("Failed to scan %s" % input.inspect) do
-                assert_equal(output, scope.strinterp(input),
-                    'did not parserret %s correctly' % input.inspect)
-            end
-        end
-
-        logs = []
-        Puppet::Util::Log.close
-        Puppet::Util::Log.newdestination(logs)
-
-        # #523
-        %w{d f h l w z}.each do |l|
-            string = "\\" + l
-            assert_nothing_raised do
-                assert_equal(string, scope.strinterp(string),
-                    'did not parserret %s correctly' % string)
-            end
-
-            assert(logs.detect { |m| m.message =~ /Unrecognised escape/ },
-                "Did not get warning about escape sequence with %s" % string)
-            logs.clear
-        end
-    end
-
-    def test_tagfunction
-        Puppet::Parser::Functions.function(:tag)
-        scope = mkscope
-        resource = mock 'resource'
-        scope.resource = resource
-        resource.expects(:tag).with("yayness", "booness")
-
-        scope.function_tag(%w{yayness booness})
-    end
-
     def test_includefunction
         parser = mkparser
         scope = mkscope :parser => parser
@@ -270,7 +141,7 @@ class TestScope < Test::Unit::TestCase
 
         [myclass, otherclass].each do |klass|
             assert(scope.compiler.class_scope(klass),
-                "%s was not set" % klass.classname)
+                "%s was not set" % klass.name)
         end
     end
 
@@ -312,13 +183,14 @@ class TestScope < Test::Unit::TestCase
     # components.
     def test_virtual_definitions_do_not_get_evaluated
         config = mkcompiler
-        parser = config.parser
+        parser = mkparser
 
         # Create a default source
-        config.topscope.source = parser.newclass ""
+        parser.newclass("")
+        config.topscope.source = parser.known_resource_types.hostclass("")
 
         # And a scope resource
-        scope_res = stub 'scope_resource', :virtual? => true, :exported? => false, :tags => [], :builtin? => true, :type => "eh", :title => "bee"
+        scope_res = Puppet::Parser::Resource.new(:file, "/file", :scope => "scope", :source => "source")
         config.topscope.resource = scope_res
 
         args = AST::ASTArray.new(
@@ -374,20 +246,13 @@ include yay
 @@host { puppet: ip => \"192.168.0.3\" }
 Host <<||>>"
 
-        interp = nil
-        assert_nothing_raised {
-            interp = Puppet::Parser::Interpreter.new
-        }
-
         config = nil
         # We run it twice because we want to make sure there's no conflict
         # if we pull it up from the database.
         node = mknode
-        node.parameters = {"hostname" => node.name}
+        node.merge "hostname" => node.name
         2.times { |i|
-            assert_nothing_raised {
-                config = interp.compile(node)
-            }
+            config = Puppet::Parser::Compiler.new(node).compile
 
             flat = config.extract.flatten
 
@@ -418,54 +283,6 @@ Host <<||>>"
             "Did not add extra namespace correctly")
     end
 
-    def test_find_hostclass_and_find_definition
-        parser = mkparser
-
-        # Make sure our scope calls the parser find_hostclass method with
-        # the right namespaces
-        scope = mkscope :parser => parser
-
-        parser.metaclass.send(:attr_accessor, :last)
-
-        methods = [:find_hostclass, :find_definition]
-        methods.each do |m|
-            parser.meta_def(m) do |namespace, name|
-                @checked ||= []
-                @checked << [namespace, name]
-
-                # Only return a value on the last call.
-                if @last == namespace
-                    ret = @checked.dup
-                    @checked.clear
-                    return ret
-                else
-                    return nil
-                end
-            end
-        end
-
-        test = proc do |should|
-            parser.last = scope.namespaces[-1]
-            methods.each do |method|
-                result = scope.send(method, "testing")
-                assert_equal(should, result,
-                    "did not get correct value from %s with namespaces %s" %
-                    [method, scope.namespaces.inspect])
-            end
-        end
-
-        # Start with the empty namespace
-        assert_nothing_raised { test.call([["", "testing"]]) }
-
-        # Now add a namespace
-        scope.add_namespace("a")
-        assert_nothing_raised { test.call([["a", "testing"]]) }
-
-        # And another
-        scope.add_namespace("b")
-        assert_nothing_raised { test.call([["a", "testing"], ["b", "testing"]]) }
-    end
-
     # #629 - undef should be "" or :undef
     def test_lookupvar_with_undef
         scope = mkscope
diff --git a/test/lib/puppettest/parsertesting.rb b/test/lib/puppettest/parsertesting.rb
index dee38eb..44c78f2 100644
--- a/test/lib/puppettest/parsertesting.rb
+++ b/test/lib/puppettest/parsertesting.rb
@@ -47,9 +47,8 @@ module PuppetTest::ParserTesting
     end
 
     def mkcompiler(parser = nil)
-        parser ||= mkparser
         node = mknode
-        return Compiler.new(node, parser)
+        return Compiler.new(node)
     end
 
     def mknode(name = nil)
@@ -59,12 +58,9 @@ module PuppetTest::ParserTesting
         Puppet::Node.new(name)
     end
 
-    def mkinterp
-        Puppet::Parser::Interpreter.new
-    end
-
-    def mkparser(args = {})
-        Puppet::Parser::Parser.new(args)
+    def mkparser
+        Puppet::Node::Environment.clear
+        Puppet::Parser::Parser.new(Puppet::Node::Environment.new)
     end
 
     def mkscope(hash = {})
@@ -306,13 +302,10 @@ module PuppetTest::ParserTesting
         interp = nil
         oldmanifest = Puppet[:manifest]
         Puppet[:manifest] = manifest
-        assert_nothing_raised {
-            interp = Puppet::Parser::Interpreter.new
-        }
 
         trans = nil
         assert_nothing_raised {
-            trans = interp.compile(mknode)
+            trans = Puppet::Parser::Compiler.new(mknode).compile
         }
 
         config = nil
diff --git a/test/lib/puppettest/resourcetesting.rb b/test/lib/puppettest/resourcetesting.rb
index d4469a2..95fe5bc 100644
--- a/test/lib/puppettest/resourcetesting.rb
+++ b/test/lib/puppettest/resourcetesting.rb
@@ -15,9 +15,12 @@ module PuppetTest::ResourceTesting
         args[:source] ||= "source"
         args[:scope] ||= mkscope
 
-        {:type => "resource", :title => "testing",
-            :source => "source", :scope => "scope"}.each do |param, value|
-                args[param] ||= value
+        type = args[:type] || "resource"
+        title = args[:title] || "testing"
+        args.delete(:type)
+        args.delete(:title)
+        {:source => "source", :scope => "scope"}.each do |param, value|
+            args[param] ||= value
         end
 
         params = args[:params] || {:one => "yay", :three => "rah"}
@@ -27,7 +30,7 @@ module PuppetTest::ResourceTesting
             args[:params] = paramify args[:source], params
         end
 
-        Parser::Resource.new(args)
+        Parser::Resource.new(type, title, args)
     end
 
     def param(name, value, source)
diff --git a/test/other/relationships.rb b/test/other/relationships.rb
index b15ff50..e9d3a93 100755
--- a/test/other/relationships.rb
+++ b/test/other/relationships.rb
@@ -80,7 +80,7 @@ class TestRelationships < Test::Unit::TestCase
 
     # Testing #411.  It was a problem with builddepends.
     def test_missing_deps
-        file = Puppet::Type.type(:file).new :path => tempfile, :require => Puppet::Resource::Reference.new("file", "/no/such/file")
+        file = Puppet::Type.type(:file).new :path => tempfile, :require => Puppet::Resource.new("file", "/no/such/file")
 
         assert_raise(Puppet::Error) do
             file.builddepends
diff --git a/test/other/transactions.rb b/test/other/transactions.rb
index 94deeab..6f4f5d9 100755
--- a/test/other/transactions.rb
+++ b/test/other/transactions.rb
@@ -125,12 +125,12 @@ class TestTransactions < Test::Unit::TestCase
         file = Puppet::Type.type(:file).new(:title => "file", :path => path, :content => "yayness")
         first = Puppet::Type.type(:exec).new(:title => "first",
                                      :command => "/bin/echo first > #{firstpath}",
-                                     :subscribe => Puppet::Resource::Reference.new(:file, path),
+                                     :subscribe => Puppet::Resource.new(:file, path),
                                      :refreshonly => true
         )
         second = Puppet::Type.type(:exec).new(:title => "second",
                                      :command => "/bin/echo second > #{secondpath}",
-                                     :subscribe => Puppet::Resource::Reference.new(:exec, "first"),
+                                     :subscribe => Puppet::Resource.new(:exec, "first"),
                                      :refreshonly => true
         )
 
@@ -218,7 +218,7 @@ class TestTransactions < Test::Unit::TestCase
         @@tmpfiles << execfile
 
         # 'subscribe' expects an array of arrays
-        exec[:subscribe] = Puppet::Resource::Reference.new(file.class.name,file.name)
+        exec[:subscribe] = Puppet::Resource.new(file.class.name,file.name)
         exec[:refreshonly] = true
 
         assert_nothing_raised() {
@@ -302,13 +302,13 @@ class TestTransactions < Test::Unit::TestCase
             :path => ENV["PATH"],
             :command => "touch %s" % file1,
             :refreshonly => true,
-            :subscribe => Puppet::Resource::Reference.new(:file, path)
+            :subscribe => Puppet::Resource.new(:file, path)
         )
         exec2 = Puppet::Type.type(:exec).new(
             :path => ENV["PATH"],
             :command => "touch %s" % file2,
             :refreshonly => true,
-            :subscribe => Puppet::Resource::Reference.new(:file, path)
+            :subscribe => Puppet::Resource.new(:file, path)
         )
 
         assert_apply(file, exec1, exec2)
@@ -361,7 +361,7 @@ class TestTransactions < Test::Unit::TestCase
             :name => "touch %s" % fname,
             :path => "/usr/bin:/bin",
             :schedule => "monthly",
-            :subscribe => Puppet::Resource::Reference.new("file", file.name)
+            :subscribe => Puppet::Resource.new("file", file.name)
         )
 
         config = mk_catalog(file, exec)
diff --git a/test/ral/type/exec.rb b/test/ral/type/exec.rb
index c533aff..27a3de4 100755
--- a/test/ral/type/exec.rb
+++ b/test/ral/type/exec.rb
@@ -181,7 +181,7 @@ class TestExec < Test::Unit::TestCase
 
         exec = Puppet::Type.type(:exec).new(
             :command => oexe,
-            :require => Puppet::Resource::Reference.new(:file, oexe)
+            :require => Puppet::Resource.new(:file, oexe)
         )
 
         comp = mk_catalog("Testing", file, exec)
@@ -404,7 +404,7 @@ class TestExec < Test::Unit::TestCase
                 :path => basedir,
                 :recurse => true,
                 :mode => "755",
-                :require => Puppet::Resource::Reference.new("exec", "mkdir")
+                :require => Puppet::Resource.new("exec", "mkdir")
             )
         }
 

-- 
Puppet packaging for Debian



More information about the Pkg-puppet-devel mailing list