<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>ext/autotest/Rakefile</filename>
    </added>
    <added>
      <filename>ext/autotest/config</filename>
    </added>
    <added>
      <filename>ext/autotest/readme.rst</filename>
    </added>
    <added>
      <filename>lib/puppet/indirector/certificate/rest.rb</filename>
    </added>
    <added>
      <filename>lib/puppet/indirector/certificate_request/rest.rb</filename>
    </added>
    <added>
      <filename>lib/puppet/indirector/certificate_revocation_list/rest.rb</filename>
    </added>
    <added>
      <filename>lib/puppet/provider/confine.rb</filename>
    </added>
    <added>
      <filename>lib/puppet/provider/confine/exists.rb</filename>
    </added>
    <added>
      <filename>lib/puppet/provider/confine/facter.rb</filename>
    </added>
    <added>
      <filename>lib/puppet/provider/confine/false.rb</filename>
    </added>
    <added>
      <filename>lib/puppet/provider/confine/feature.rb</filename>
    </added>
    <added>
      <filename>lib/puppet/provider/confine/true.rb</filename>
    </added>
    <added>
      <filename>lib/puppet/provider/confine_collection.rb</filename>
    </added>
    <added>
      <filename>lib/puppet/provider/confiner.rb</filename>
    </added>
    <added>
      <filename>lib/puppet/provider/group/ldap.rb</filename>
    </added>
    <added>
      <filename>lib/puppet/provider/ldap.rb</filename>
    </added>
    <added>
      <filename>lib/puppet/provider/ssh_authorized_key/parsed.rb</filename>
    </added>
    <added>
      <filename>lib/puppet/provider/user/ldap.rb</filename>
    </added>
    <added>
      <filename>lib/puppet/ssl/certificate_authority/interface.rb</filename>
    </added>
    <added>
      <filename>lib/puppet/type/ssh_authorized_key.rb</filename>
    </added>
    <added>
      <filename>lib/puppet/util/cacher.rb</filename>
    </added>
    <added>
      <filename>lib/puppet/util/ldap.rb</filename>
    </added>
    <added>
      <filename>lib/puppet/util/ldap/connection.rb</filename>
    </added>
    <added>
      <filename>lib/puppet/util/ldap/generator.rb</filename>
    </added>
    <added>
      <filename>lib/puppet/util/ldap/manager.rb</filename>
    </added>
    <added>
      <filename>spec/integration/bin/puppetmasterd.rb</filename>
    </added>
    <added>
      <filename>spec/integration/defaults.rb</filename>
    </added>
    <added>
      <filename>spec/integration/ssl/certificate_revocation_list.rb</filename>
    </added>
    <added>
      <filename>spec/integration/type/package.rb</filename>
    </added>
    <added>
      <filename>spec/unit/indirector/certificate/rest.rb</filename>
    </added>
    <added>
      <filename>spec/unit/indirector/certificate_request/rest.rb</filename>
    </added>
    <added>
      <filename>spec/unit/indirector/certificate_revocation_list/rest.rb</filename>
    </added>
    <added>
      <filename>spec/unit/parser/templatewrapper.rb</filename>
    </added>
    <added>
      <filename>spec/unit/provider/confine.rb</filename>
    </added>
    <added>
      <filename>spec/unit/provider/confine/exists.rb</filename>
    </added>
    <added>
      <filename>spec/unit/provider/confine/facter.rb</filename>
    </added>
    <added>
      <filename>spec/unit/provider/confine/false.rb</filename>
    </added>
    <added>
      <filename>spec/unit/provider/confine/feature.rb</filename>
    </added>
    <added>
      <filename>spec/unit/provider/confine/true.rb</filename>
    </added>
    <added>
      <filename>spec/unit/provider/confine_collection.rb</filename>
    </added>
    <added>
      <filename>spec/unit/provider/confiner.rb</filename>
    </added>
    <added>
      <filename>spec/unit/provider/group/ldap.rb</filename>
    </added>
    <added>
      <filename>spec/unit/provider/interface/redhat.rb</filename>
    </added>
    <added>
      <filename>spec/unit/provider/interface/sunos.rb</filename>
    </added>
    <added>
      <filename>spec/unit/provider/ldap.rb</filename>
    </added>
    <added>
      <filename>spec/unit/provider/mount.rb</filename>
    </added>
    <added>
      <filename>spec/unit/provider/mount/parsed.rb</filename>
    </added>
    <added>
      <filename>spec/unit/provider/ssh_authorized_key/parsed.rb</filename>
    </added>
    <added>
      <filename>spec/unit/provider/user/ldap.rb</filename>
    </added>
    <added>
      <filename>spec/unit/ssl/certificate_authority/interface.rb</filename>
    </added>
    <added>
      <filename>spec/unit/type.rb</filename>
    </added>
    <added>
      <filename>spec/unit/type/exec.rb</filename>
    </added>
    <added>
      <filename>spec/unit/type/file.rb</filename>
    </added>
    <added>
      <filename>spec/unit/type/interface.rb</filename>
    </added>
    <added>
      <filename>spec/unit/type/mount.rb</filename>
    </added>
    <added>
      <filename>spec/unit/type/nagios.rb</filename>
    </added>
    <added>
      <filename>spec/unit/type/noop_metaparam.rb</filename>
    </added>
    <added>
      <filename>spec/unit/type/package.rb</filename>
    </added>
    <added>
      <filename>spec/unit/type/schedule.rb</filename>
    </added>
    <added>
      <filename>spec/unit/type/service.rb</filename>
    </added>
    <added>
      <filename>spec/unit/type/ssh_authorized_key.rb</filename>
    </added>
    <added>
      <filename>spec/unit/type/user.rb</filename>
    </added>
    <added>
      <filename>spec/unit/util/cacher.rb</filename>
    </added>
    <added>
      <filename>spec/unit/util/ldap/connection.rb</filename>
    </added>
    <added>
      <filename>spec/unit/util/ldap/generator.rb</filename>
    </added>
    <added>
      <filename>spec/unit/util/ldap/manager.rb</filename>
    </added>
    <added>
      <filename>spec/unit/util/storage.rb</filename>
    </added>
    <added>
      <filename>test/data/providers/ssh_authorized_key/parsed/authorized_keys</filename>
    </added>
    <added>
      <filename>test/data/types/ssh_authorized_key/1</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -10,7 +10,7 @@
 #
 #   puppetd  [-D|--daemonize|--no-daemonize] [-d|--debug] [--disable] [--enable]
 #       [-h|--help] [--fqdn &lt;host name&gt;] [-l|--logdest syslog|&lt;file&gt;|console]
-#       [-o|--onetime] [--serve &lt;handler&gt;] [-t|--test]
+#       [-o|--onetime] [--serve &lt;handler&gt;] [-t|--test] [--noop]
 #       [-V|--version] [-v|--verbose] [-w|--waitforcert &lt;seconds&gt;]
 #
 # = Description
@@ -57,7 +57,7 @@
 # parameter, so you can specify '--server &lt;servername&gt;' as an argument.
 #
 # See the configuration file documentation at
-# http://reductivelabs.com/projects/puppet/reference/configref.html for
+# http://reductivelabs.com/trac/puppet/wiki/ConfigurationReference for
 # the full list of acceptable parameters. A commented list of all
 # configuration options can also be generated by running puppetd with
 # '--genconfig'.
@@ -124,6 +124,10 @@
 #   Enable the most common options used for testing.  These are +onetime+,
 #   +verbose+, +ignorecache, and +no-usecacheonfailure+.
 #
+# noop::
+#   Use +noop+ mode where the daemon runs in a no-op or dry-run mode.  This is useful
+#   for seeing what changes Puppet will make without actually executing the changes.
+#
 # verbose::
 #   Turn on verbose reporting.
 #
@@ -317,6 +321,11 @@ if options[:centrallogs]
     Puppet::Util::Log.newdestination(logdest)
 end
 
+# We need to specify a ca location for things to work, but
+# until the REST cert transfers are working, it needs to
+# be local.
+Puppet::SSL::Host.ca_location = :local
+
 # We need tomake the client either way, we just don't start it
 # if --no-client is set.
 client = Puppet::Network::Client.master.new(args)
@@ -338,10 +347,9 @@ if Puppet[:daemonize]
     client.daemonize
 end
 
-unless Puppet::Network::HttpPool.read_cert
-    # If we don't already have the certificate, then create a client to
-    # request one.  Use the special ca stuff, don't use the normal server and port.
-    caclient = Puppet::Network::Client.ca.new()
+caclient = Puppet::Network::Client.ca.new()
+
+unless caclient.read_cert
     if options[:waitforcert] &gt; 0
         begin
             while ! caclient.request_cert do
@@ -360,7 +368,7 @@ unless Puppet::Network::HttpPool.read_cert
     end
 
     # Now read the new cert in.
-    if Puppet::Network::HttpPool.read_cert
+    if caclient.read_cert
         # If we read it in, then get rid of our existing http connection.
         client.recycle_connection
         Puppet.notice &quot;Got signed certificate&quot;</diff>
      <filename>bin/puppetd</filename>
    </modified>
    <modified>
      <diff>@@ -8,8 +8,7 @@
 # = Usage
 #
 #   puppetmasterd [-D|--daemonize|--no-daemonize] [-d|--debug] [-h|--help]
-#       [-l|--logdest &lt;file&gt;|console|syslog] [--nobucket] [--nonodes]
-#       [-v|--verbose] [-V|--version]
+#       [-l|--logdest &lt;file&gt;|console|syslog] [-v|--verbose] [-V|--version]
 #
 # = Description
 #
@@ -22,7 +21,7 @@
 # parameter, so you can specify '--ssldir &lt;directory&gt;' as an argument.
 #
 # See the configuration file documentation at
-# http://reductivelabs.com/projects/puppet/reference/configref.html for
+# http://reductivelabs.com/trac/puppet/wiki/ConfigurationReference for
 # the full list of acceptable parameters. A commented list of all
 # configuration options can also be generated by running puppetmasterdd with
 # '--genconfig'.
@@ -44,16 +43,6 @@
 #   Defaults to sending messages to syslog, or the console
 #   if debugging or verbosity is enabled.
 #
-# nobucket::
-#   Do not function as a file bucket.
-#
-# nonodes::
-#   Do not use individual node designations; each node will receive the result
-#   of evaluating the entire configuration.
-#
-# noreports::
-#   Do not start the reports server.
-#
 # verbose::
 #   Enable verbosity.
 #
@@ -81,16 +70,12 @@ end
 
 require 'getoptlong'
 require 'puppet'
-require 'puppet/network/handler'
-require 'puppet/sslcertificates'
+require 'puppet/network/server'
 
 options = [
 	[ &quot;--debug&quot;,	&quot;-d&quot;,			GetoptLong::NO_ARGUMENT ],
 	[ &quot;--help&quot;,		&quot;-h&quot;,			GetoptLong::NO_ARGUMENT ],
 	[ &quot;--logdest&quot;,	&quot;-l&quot;,			GetoptLong::REQUIRED_ARGUMENT ],
-	[ &quot;--nobucket&quot;,        			GetoptLong::NO_ARGUMENT ],
-	[ &quot;--noreports&quot;,       			GetoptLong::NO_ARGUMENT ],
-	[ &quot;--nonodes&quot;,         			GetoptLong::NO_ARGUMENT ],
 	[ &quot;--verbose&quot;,	&quot;-v&quot;,			GetoptLong::NO_ARGUMENT ],
     [ &quot;--version&quot;,  &quot;-V&quot;,           GetoptLong::NO_ARGUMENT ]
 ]
@@ -100,15 +85,7 @@ Puppet.settings.addargs(options)
 
 result = GetoptLong.new(*options)
 
-master = {}
-ca = {}
-report = {}
-bucket = {}
-
 options = {
-    :havereport =&gt; true,
-    :havebucket =&gt; true,
-    :havemaster =&gt; true,
     :setdest =&gt; false,
     :verbose =&gt; false,
     :debug =&gt; false
@@ -128,14 +105,6 @@ begin
                     puts &quot;No help available unless you have RDoc::usage installed&quot;
                     exit
                 end
-            when &quot;--noreports&quot;
-                options[:havereport] = false
-            when &quot;--nomaster&quot;
-                options[:havemaster] = false
-            when &quot;--nobucket&quot;
-                options[:havebucket] = false
-            when &quot;--nonodes&quot;
-                master[:UseNodes] = false
             when &quot;--logdest&quot;
                 begin
                     Puppet::Util::Log.newdestination(arg)
@@ -191,87 +160,54 @@ Puppet::Node::Facts.terminus_class = :yaml
 # Cache our nodes in yaml.  Currently not configurable.
 Puppet::Node.cache_class = :yaml
 
-require 'etc'
-
-handlers = {
-    :Status =&gt; {},
-    :FileServer =&gt; {}
-}
-
-if options[:havemaster]
-    handlers[:Master] = master
+# Configure all of the SSL stuff.
+if Puppet::SSL::CertificateAuthority.ca?
+    Puppet::SSL::Host.ca_location = :local
+    Puppet.settings.use :main, :ssl, :ca
+    Puppet::SSL::CertificateAuthority.instance
+else
+    Puppet::SSL::Host.ca_location = :none
 end
 
-if options[:havereport]
-    handlers[:Report] = report
-end
-
-if Puppet[:ca]
-    handlers[:CA] = ca
-end
-
-if options[:havebucket]
-    handlers[:FileBucket] = bucket
-end
+require 'etc'
 
 if Puppet[:parseonly]
     begin
-        Puppet::Network::Handler.master.new(master)
+        Puppet::Parser::Interpreter.new.parser(Puppet[:environment])
     rescue =&gt; detail
-        if Puppet[:trace]
-            puts detail.backtrace
-        end
-        $stderr.puts detail
-        exit(32)
+        Puppet.err detail
+        exit 1
     end
-    # we would have already exited if the file weren't syntactically correct
     exit(0)
 end
 
-webserver = server = nil
-begin
-    case Puppet[:servertype]
-    when &quot;webrick&quot;
-        # use the default, um, everything
-        require 'puppet/network/http_server/webrick'
-        webserver = server = Puppet::Network::HTTPServer::WEBrick.new(:Handlers =&gt; handlers)
-    when &quot;mongrel&quot;:
-        require 'puppet/network/http_server/mongrel'
-        server = Puppet::Network::HTTPServer::Mongrel.new(handlers)
-        addr = Puppet[:bindaddress]
-        if addr == &quot;&quot;
-            addr =  &quot;127.0.0.1&quot;
-        end
-        webserver = Mongrel::HttpServer.new(addr, Puppet[:masterport])
-        webserver.register(&quot;/&quot;, server)
-    else
-        Puppet.err &quot;Invalid server type %s&quot; % Puppet[:servertype]
-        exit(45)
-    end
-rescue =&gt; detail
-    if Puppet[:trace]
-        puts detail.backtrace
-    end
-    $stderr.puts detail
-    exit(1)
+require 'puppet/file_serving/content'
+require 'puppet/file_serving/metadata'
+require 'puppet/checksum'
+
+xmlrpc_handlers = [:Status, :FileServer, :Master, :Report, :Filebucket]
+rest_handlers = [:file_content, :file_metadata, :certificate, :facts, :catalog, :report, :checksum]
+
+if Puppet[:ca]
+    xmlrpc_handlers &lt;&lt; :CA
 end
 
+server = Puppet::Network::Server.new(:handlers =&gt; rest_handlers, :xmlrpc_handlers =&gt; xmlrpc_handlers)
+
 if Process.uid == 0
     begin
         Puppet::Util.chuser
     rescue =&gt; detail
-        if Puppet[:debug]
-            puts detail.backtrace
-        end
+        puts detail.backtrace if Puppet[:trace]
         $stderr.puts &quot;Could not change user to %s: %s&quot; % [Puppet[:user], detail]
         exit(39)
     end
 end
 
-# Mongrel doesn't shut down like webrick; we really need to write plugins for it.
-if Puppet[:servertype] == &quot;webrick&quot;
-    Puppet.newservice(server)
-end
+# Tell Puppet to manage this service for us, which has it starting and stopping
+# as appropriate.
+Puppet.newservice(server)
+
 Puppet.settraps
 
 if Puppet[:daemonize]
@@ -279,10 +215,5 @@ if Puppet[:daemonize]
 end
 
 Puppet.notice &quot;Starting Puppet server version %s&quot; % [Puppet.version]
-case Puppet[:servertype]
-when &quot;webrick&quot;
-    Puppet.start
-when &quot;mongrel&quot;:
-    webserver.run.join
-end
 
+Puppet.start</diff>
      <filename>bin/puppetmasterd</filename>
    </modified>
    <modified>
      <diff>@@ -65,7 +65,7 @@
 #
 # This example uses ``ralsh`` to return Puppet configuration for the user ``luke``::
 #   
-# $ ralsh user luke
+#    $ ralsh user luke
 #    user { 'luke':
 #      home =&gt; '/home/luke',
 #      uid =&gt; '100',</diff>
      <filename>bin/ralsh</filename>
    </modified>
    <modified>
      <diff>@@ -2,10 +2,11 @@
 ;;; puppet-mode.el
 ;;; 
 ;;; Author: lutter
-;;; Description: A simple mode for editing puppet manifests
+;;; Author: Russ Allbery &lt;rra@stanford.edu&gt;
 ;;;
+;;; Description: A simple mode for editing puppet manifests
 
-(defconst puppet-mode-version &quot;0.1&quot;)
+(defconst puppet-mode-version &quot;0.2&quot;)
 
 (defvar puppet-mode-abbrev-table nil
   &quot;Abbrev table in use in puppet-mode buffers.&quot;)
@@ -56,11 +57,43 @@
   &quot;*Indentation column of comments.&quot;
   :type 'integer :group 'puppet)
 
+(defun puppet-count-matches (re start end)
+  &quot;The same as Emacs 22 count-matches, for portability to other versions
+of Emacs.&quot;
+  (save-excursion
+    (let ((n 0))
+      (goto-char start)
+      (while (re-search-forward re end t) (setq n (1+ n)))
+      n)))
+
 (defun puppet-comment-line-p ()
   &quot;Return non-nil iff this line is a comment.&quot;
   (save-excursion
-    (beginning-of-line)
-    (looking-at (format &quot;\\s-*%s&quot; comment-start))))
+    (save-match-data
+      (beginning-of-line)
+      (looking-at (format &quot;\\s-*%s&quot; comment-start)))))
+
+(defun puppet-block-indent ()
+  &quot;If point is in a block, return the indentation of the first line of that
+block (the line containing the opening brace).  Used to set the indentation
+of the closing brace of a block.&quot;
+  (save-excursion
+    (save-match-data
+      (let ((opoint (point))
+            (apoint (search-backward &quot;{&quot; nil t)))
+        (when apoint
+          ;; This is a bit of a hack and doesn't allow for strings.  We really
+          ;; want to parse by sexps at some point.
+          (let ((close-braces (puppet-count-matches &quot;}&quot; apoint opoint))
+                (open-braces 0))
+            (while (and apoint (&gt; close-braces open-braces))
+              (setq apoint (search-backward &quot;{&quot; nil t))
+              (when apoint
+                (setq close-braces (puppet-count-matches &quot;}&quot; apoint opoint))
+                (setq open-braces (1+ open-braces)))))
+          (if apoint
+              (current-indentation)
+            nil))))))
 
 (defun puppet-in-array ()
   &quot;If point is in an array, return the position of the opening '[' of
@@ -77,7 +110,7 @@ that array, else return nil.&quot;
           ;; ### steps, baby steps.  A more robust strategy might be
           ;; ### to walk backwards by sexps, until hit a wall, then
           ;; ### inspect the nature of that wall.
-          (if (= (count-matches &quot;\\]&quot; apoint opoint) 0)
+          (if (= (puppet-count-matches &quot;\\]&quot; apoint opoint) 0)
               apoint))))))
 
 (defun puppet-in-include ()
@@ -90,15 +123,14 @@ of the initial include plus puppet-include-indent.&quot;
         (while not-found
           (forward-line -1)
           (cond
-             ((puppet-comment-line-p)
-              (if (bobp)
-                  (setq not-found nil)))
-             ((looking-at &quot;^\\s-*include\\s-+.*,\\s-*$&quot;)
-              (setq include-column
-                    (+ (current-indentation) puppet-include-indent))
-              (setq not-found nil))
-             ((not (looking-at &quot;.*,\\s-*$&quot;))
-              (setq not-found nil))))
+           ((bobp)
+            (setq not-found nil))
+           ((looking-at &quot;^\\s-*include\\s-+.*,\\s-*$&quot;)
+            (setq include-column
+                  (+ (current-indentation) puppet-include-indent))
+            (setq not-found nil))
+           ((not (looking-at &quot;.*,\\s-*$&quot;))
+            (setq not-found nil))))
         include-column))))
 
 (defun puppet-indent-line ()
@@ -110,6 +142,7 @@ of the initial include plus puppet-include-indent.&quot;
     (let ((not-indented t)
           (array-start (puppet-in-array))
           (include-start (puppet-in-include))
+          (block-indent (puppet-block-indent))
           cur-indent)
       (cond
        (array-start
@@ -146,18 +179,11 @@ of the initial include plus puppet-include-indent.&quot;
           (setq cur-indent (current-column))))
        (include-start
         (setq cur-indent include-start))
-       ((looking-at &quot;^[^{\n]*}&quot;)
-        ;; This line contains the end of a block, but the block does
-        ;; not also begin on this line, so decrease the indentation.
-        (save-excursion
-          (forward-line -1)
-          (if (looking-at &quot;^.*}&quot;)
-              (progn
-                (setq cur-indent (- (current-indentation) puppet-indent-level))
-                (setq not-indented nil))
-            (setq cur-indent (- (current-indentation) puppet-indent-level))))
-        (if (&lt; cur-indent 0)     ; We can't indent past the left margin
-            (setq cur-indent 0)))
+       ((and (looking-at &quot;^\\s-*}\\s-*$&quot;) block-indent)
+        ;; This line contains only a closing brace and we're at the inner
+        ;; block, so we should indent it matching the indentation of the
+        ;; opening brace of the block.
+        (setq cur-indent block-indent))
        (t
         ;; Otherwise, we did not start on a block-ending-only line.
         (save-excursion
@@ -165,30 +191,136 @@ of the initial include plus puppet-include-indent.&quot;
           (while not-indented
             (forward-line -1)
             (cond
+             ;; Comment lines are ignored unless we're at the start of the
+             ;; buffer.
              ((puppet-comment-line-p)
               (if (bobp)
-                  (setq not-indented nil)
-                ;; else ignore the line and continue iterating backwards
-                ))
-             ((looking-at &quot;^.*}&quot;) ; indent at the level of the END_ token
+                  (setq not-indented nil)))
+
+             ;; Brace or paren on a line by itself will already be indented to
+             ;; the right level, so we can cheat and stop there.
+             ((looking-at &quot;^\\s-*[\)}]\\s-*&quot;)
               (setq cur-indent (current-indentation))
               (setq not-indented nil))
-             ((looking-at &quot;^.*{&quot;) ; indent an extra level
+
+             ;; Brace or paren not on a line by itself will be indented one
+             ;; level too much, but don't catch cases where the block is
+             ;; started and closed on the same line.
+             ((looking-at &quot;^[^\({]*[\)}]\\s-*$&quot;)
+              (setq cur-indent (- (current-indentation) puppet-indent-level))
+              (setq not-indented nil))
+
+             ;; Indent by one level more than the start of our block.  We lose
+             ;; if there is more than one block opened and closed on the same
+             ;; line but it's still unbalanced; hopefully people don't do that.
+             ((looking-at &quot;^.*{[^}]*$&quot;)
+              (setq cur-indent (+ (current-indentation) puppet-indent-level)) 
+              (setq not-indented nil))
+
+             ;; Indent by one level if the line ends with an open paren.
+             ((looking-at &quot;^.*\(\\s-*$&quot;)
               (setq cur-indent (+ (current-indentation) puppet-indent-level)) 
               (setq not-indented nil))
-             ((looking-at &quot;^.*;\\s-*$&quot;) ; Semicolon ends a nested resource
+
+             ;; Semicolon ends a block for a resource when multiple resources
+             ;; are defined in the same block, but try not to get the case of
+             ;; a complete resource on a single line wrong.
+             ((looking-at &quot;^\\([^'\&quot;:\n]\\|\&quot;[^\&quot;]*\&quot;\\|'[^']'\\)**;\\s-*$&quot;)
               (setq cur-indent (- (current-indentation) puppet-indent-level))
               (setq not-indented nil))
-             ((looking-at &quot;^.*:\\s-*$&quot;) ; indent an extra level after :
+
+             ;; Indent an extra level after : since it introduces a resource.
+             ((looking-at &quot;^.*:\\s-*$&quot;)
               (setq cur-indent (+ (current-indentation) puppet-indent-level))
               (setq not-indented nil))
+
+             ;; Start of buffer.
              ((bobp)
-              (setq not-indented nil))
-             )))))
-      (if cur-indent
+              (setq not-indented nil)))))
+
+        ;; If this line contains only a closing paren, we should lose one
+        ;; level of indentation.
+        (if (looking-at &quot;^\\s-*\)\\s-*$&quot;)
+            (setq cur-indent (- cur-indent puppet-indent-level)))))
+
+      ;; We've figured out the indentation, so do it.
+      (if (and cur-indent (&gt; cur-indent 0))
           (indent-line-to cur-indent)
         (indent-line-to 0)))))
 
+(defvar puppet-font-lock-syntax-table
+  (let* ((tbl (copy-syntax-table puppet-mode-syntax-table)))
+    (modify-syntax-entry ?_ &quot;w&quot; tbl)
+    tbl))
+
+(defvar puppet-font-lock-keywords
+  (list
+   ;; defines, classes, and nodes
+   '(&quot;^\\s *\\(class\\|define\\|node\\)\\s +\\([^( \t\n]+\\)&quot;
+     2 font-lock-function-name-face)
+   ;; inheritence
+   '(&quot;\\s +inherits\\s +\\([^( \t\n]+\\)&quot;
+     1 font-lock-function-name-face)
+   ;; include
+   '(&quot;\\(^\\|\\s +\\)include\\s +\\(\\([a-zA-Z0-9:_-]+\\(,[ \t\n]*\\)?\\)+\\)&quot;
+     2 font-lock-reference-face)
+   ;; keywords
+   (cons (concat
+          &quot;\\b\\(\\(&quot;
+          (mapconcat
+           'identity
+           '(&quot;alert&quot;
+             &quot;case&quot;
+             &quot;class&quot;
+             &quot;crit&quot;
+             &quot;debug&quot;
+             &quot;default&quot;
+             &quot;define&quot;
+             &quot;defined&quot;
+             &quot;else&quot;
+             &quot;emerg&quot;
+             &quot;err&quot;
+             &quot;fail&quot;
+             &quot;false&quot;
+             &quot;file&quot;
+             &quot;filebucket&quot;
+             &quot;generate&quot;
+             &quot;if&quot;
+             &quot;import&quot;
+             &quot;include&quot;
+             &quot;info&quot;
+             &quot;inherits&quot;
+             &quot;node&quot;
+             &quot;notice&quot;
+             &quot;realize&quot;
+             &quot;search&quot;
+             &quot;tag&quot;
+             &quot;tagged&quot;
+             &quot;template&quot;
+             &quot;true&quot;
+             &quot;warning&quot;
+             )
+           &quot;\\|&quot;)
+          &quot;\\)\\&gt;\\)&quot;)
+         1)
+     ;; variables
+     '(&quot;\\(^\\|[^_:.@$]\\)\\b\\(true\\|false\\)\\&gt;&quot;
+       2 font-lock-variable-name-face)
+     ;; variables
+     '(&quot;\\(\\$\\([^a-zA-Z0-9 \n]\\|[0-9]\\)\\)\\W&quot;
+       1 font-lock-variable-name-face)
+     '(&quot;\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\|:\\)+&quot;
+       0 font-lock-variable-name-face)
+     ;; usage of types
+     '(&quot;^\\s *\\([a-zA-Z_-]+\\)\\s +{&quot;
+       1 font-lock-type-face)
+     ;; overrides
+     '(&quot;^\\s +\\([a-zA-Z_-]+\\)\\[&quot;
+       1 font-lock-type-face)
+     ;; general delimited string
+     '(&quot;\\(^\\|[[ \t\n&lt;+(,=]\\)\\(%[xrqQwW]?\\([^&lt;[{(a-zA-Z0-9 \n]\\)[^\n\\\\]*\\(\\\\.[^\n\\\\]*\\)*\\(\\3\\)\\)&quot;
+       (2 font-lock-string-face)))
+  &quot;*Additional expressions to highlight in puppet mode.&quot;)
 
 ;;;###autoload
 (defun puppet-mode ()
@@ -213,97 +345,14 @@ The variable puppet-indent-level controls the amount of indentation.
   (set (make-local-variable 'paragraph-ignore-fill-prefix) t)
   (set (make-local-variable 'paragraph-start) &quot;\f\\|[ 	]*$&quot;)
   (set (make-local-variable 'paragraph-separate) &quot;[ 	\f]*$&quot;)
-  (run-hooks 'puppet-mode-hook))
-
-(cond
- ((featurep 'font-lock)
   (or (boundp 'font-lock-variable-name-face)
       (setq font-lock-variable-name-face font-lock-type-face))
-
-  (setq puppet-font-lock-syntactic-keywords
-        '(
-          (&quot;\\(^\\|[=(,~?:;]\\|\\(^\\|\\s \\)\\(if\\|elsif\\|unless\\|while\\|until\\|when\\|and\\|or\\|&amp;&amp;\\|||\\)\\|g?sub!?\\|scan\\|split!?\\)\\s *\\(/\\)[^/\n\\\\]*\\(\\\\.[^/\n\\\\]*\\)*\\(/\\)&quot;
-           (4 (7 . ?/))
-           (6 (7 . ?/)))
-          (&quot;^\\(=\\)begin\\(\\s \\|$\\)&quot; 1 (7 . nil))
-          (&quot;^\\(=\\)end\\(\\s \\|$\\)&quot; 1 (7 . nil))))
-
-  (cond ((featurep 'xemacs)
-         (put 'puppet-mode 'font-lock-defaults
-              '((puppet-font-lock-keywords)
-                nil nil nil
-                beginning-of-line
-                (font-lock-syntactic-keywords
-                 . puppet-font-lock-syntactic-keywords))))
-        (t
-         (add-hook 'puppet-mode-hook
-            '(lambda ()
-               (make-local-variable 'font-lock-defaults)
-               (make-local-variable 'font-lock-keywords)
-               (make-local-variable 'font-lock-syntax-table)
-               (make-local-variable 'font-lock-syntactic-keywords)
-               (setq font-lock-defaults '((puppet-font-lock-keywords) nil nil))
-               (setq font-lock-keywords puppet-font-lock-keywords)
-               (setq font-lock-syntax-table puppet-font-lock-syntax-table)
-               (setq font-lock-syntactic-keywords puppet-font-lock-syntactic-keywords)))))
-
-  (defvar puppet-font-lock-syntax-table
-    (let* ((tbl (copy-syntax-table puppet-mode-syntax-table)))
-      (modify-syntax-entry ?_ &quot;w&quot; tbl)
-      tbl))
-
-  (defvar puppet-font-lock-keywords
-    (list
-     ;; defines
-     '(&quot;^\\s *\\(define\\|node\\|class\\)\\s +\\([^( \t\n]+\\)&quot;
-       2 font-lock-function-name-face)
-     '(&quot;\\s +inherits\\s +\\([^( \t\n]+\\)&quot;
-       1 font-lock-function-name-face)
-     ;; include
-     '(&quot;^\\s *include\\s +\\([^( \t\n,]+\\)&quot;
-       1 font-lock-reference-face)
-     ;; hack to catch continued includes
-     '(&quot;^\\s *\\([a-zA-Z0-9:_-]+\\),?\\s *$&quot;
-       1 font-lock-reference-face)
-     ;; keywords
-     (cons (concat
-            &quot;\\b\\(\\(&quot;
-            (mapconcat
-             'identity
-             '(&quot;case&quot;
-               &quot;class&quot;
-               &quot;default&quot;
-               &quot;define&quot;
-               &quot;false&quot;
-               &quot;import&quot;
-               &quot;include&quot;
-               &quot;inherits&quot;
-               &quot;node&quot;
-               &quot;realize&quot;
-               &quot;true&quot;
-               )
-             &quot;\\|&quot;)
-            &quot;\\)\\&gt;\\)&quot;)
-           1)
-     ;; variables
-     '(&quot;\\(^\\|[^_:.@$]\\|\\.\\.\\)\\b\\(nil\\|self\\|true\\|false\\)\\&gt;&quot;
-       2 font-lock-variable-name-face)
-     ;; variables
-     '(&quot;\\(\\$\\([^a-zA-Z0-9 \n]\\|[0-9]\\)\\)\\W&quot;
-       1 font-lock-variable-name-face)
-     '(&quot;\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+&quot;
-       0 font-lock-variable-name-face)
-     ;; usage of types
-     '(&quot;^\\s +\\([a-zA-Z_-]+\\)\\s +{&quot; 
-       1 font-lock-type-face)
-     ;; overrides
-     '(&quot;^\\s +\\([a-zA-Z_-]+\\)\\[&quot;
-       1 font-lock-type-face)
-     ;; general delimited string
-     '(&quot;\\(^\\|[[ \t\n&lt;+(,=]\\)\\(%[xrqQwW]?\\([^&lt;[{(a-zA-Z0-9 \n]\\)[^\n\\\\]*\\(\\\\.[^\n\\\\]*\\)*\\(\\3\\)\\)&quot;
-       (2 font-lock-string-face))
-     )
-    &quot;*Additional expressions to highlight in puppet mode.&quot;))
- )
+  (set (make-local-variable 'font-lock-keywords) puppet-font-lock-keywords)
+  (set (make-local-variable 'font-lock-multiline) t)
+  (set (make-local-variable 'font-lock-defaults)
+       '((puppet-font-lock-keywords) nil nil))
+  (set (make-local-variable 'font-lock-syntax-table)
+       puppet-font-lock-syntax-table)
+  (run-hooks 'puppet-mode-hook))
 
 (provide 'puppet-mode)</diff>
      <filename>ext/emacs/puppet-mode.el</filename>
    </modified>
    <modified>
      <diff>@@ -17,6 +17,11 @@ attributetype ( 1.1.3.11 NAME 'environment'
 	EQUALITY caseIgnoreIA5Match
 	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
 
+attributetype ( 1.1.3.12 NAME 'puppetvar'
+	DESC 'A variable setting for puppet'
+	EQUALITY caseIgnoreIA5Match
+	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
 objectclass ( 1.1.1.2 NAME 'puppetClient' SUP top AUXILIARY
 	DESC 'Puppet Client objectclass'
-	MAY ( puppetclass $ parentnode $ environment ))
+	MAY ( puppetclass $ parentnode $ environment $ puppetvar ))</diff>
      <filename>ext/ldap/puppet.schema</filename>
    </modified>
    <modified>
      <diff>@@ -106,7 +106,7 @@ def do_man(man, strip = 'man/')
     File.install(mf, omf, 0644, true)
     gzip = %x{which gzip}
     gzip.chomp!
-    %x{#{gzip} #{omf}}
+    %x{#{gzip} -f #{omf}}
   end
 end
 
@@ -210,6 +210,15 @@ def prepare_installation
     end
   end
 
+  # Mac OS X 10.5 declares bindir and sbindir as
+  # /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin
+  # /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/sbin
+  # which is not generally where people expect executables to be installed
+  if RUBY_PLATFORM == &quot;universal-darwin9.0&quot;
+    Config::CONFIG['bindir'] = &quot;/usr/bin&quot;
+    Config::CONFIG['sbindir'] = &quot;/usr/sbin&quot;
+  end
+
   if (destdir = ENV['DESTDIR'])
     bindir = &quot;#{destdir}#{Config::CONFIG['bindir']}&quot;
     sbindir = &quot;#{destdir}#{Config::CONFIG['sbindir']}&quot;</diff>
      <filename>install.rb</filename>
    </modified>
    <modified>
      <diff>@@ -60,12 +60,6 @@ module Puppet
                 this directory can be removed without causing harm (although it
                 might result in spurious service restarts).&quot;
         },
-        :ssldir =&gt; {
-            :default =&gt; &quot;$confdir/ssl&quot;,
-            :mode =&gt; 0771,
-            :owner =&gt; &quot;root&quot;,
-            :desc =&gt; &quot;Where SSL certificates are kept.&quot;
-        },
         :rundir =&gt; { 
             :default =&gt; rundir,
             :mode =&gt; 01777,
@@ -148,7 +142,20 @@ module Puppet
             but then ship with tools that do not know how to handle signed ints, so the UIDs show up as
             huge numbers that can then not be fed back into the system.  This is a hackish way to fail in a
             slightly more useful way when that happens.&quot;],
-        :node_terminus =&gt; [&quot;plain&quot;, &quot;Where to find information about nodes.&quot;]
+        :node_terminus =&gt; [&quot;plain&quot;, &quot;Where to find information about nodes.&quot;],
+        :httplog =&gt; { :default =&gt; &quot;$logdir/http.log&quot;,
+            :owner =&gt; &quot;root&quot;,
+            :mode =&gt; 0640,
+            :desc =&gt; &quot;Where the puppetd web server logs.&quot;
+        },
+        :http_proxy_host =&gt; [&quot;none&quot;,
+            &quot;The HTTP proxy host to use for outgoing connections.  Note: You
+            may need to use a FQDN for the server hostname when using a proxy.&quot;],
+        :http_proxy_port =&gt; [3128,
+            &quot;The HTTP proxy port to use for outgoing connections&quot;],
+        :http_enable_post_connection_check =&gt; [true,
+            &quot;Boolean; wheter or not puppetd should validate the server
+            SSL certificate against the request hostname.&quot;]
     )
 
     hostname = Facter[&quot;hostname&quot;].value
@@ -159,13 +166,19 @@ module Puppet
         fqdn = hostname
     end
 
-    Puppet.setdefaults(:ssl,
+    Puppet.setdefaults(:main,
         :certname =&gt; [fqdn, &quot;The name to use when handling certificates.  Defaults
             to the fully qualified domain name.&quot;],
         :certdnsnames =&gt; ['', &quot;The DNS names on the Server certificate as a colon-separated list.
             If it's anything other than an empty string, it will be used as an alias in the created
             certificate.  By default, only the server gets an alias set up, and only for 'puppet'.&quot;],
         :certdir =&gt; [&quot;$ssldir/certs&quot;, &quot;The certificate directory.&quot;],
+        :ssldir =&gt; {
+            :default =&gt; &quot;$confdir/ssl&quot;,
+            :mode =&gt; 0771,
+            :owner =&gt; &quot;root&quot;,
+            :desc =&gt; &quot;Where SSL certificates are kept.&quot;
+        },
         :publickeydir =&gt; [&quot;$ssldir/public_keys&quot;, &quot;The public key directory.&quot;],
         :requestdir =&gt; [&quot;$ssldir/certificate_requests&quot;, &quot;Where host certificate requests are stored.&quot;],
         :privatekeydir =&gt; { :default =&gt; &quot;$ssldir/private_keys&quot;,
@@ -236,7 +249,12 @@ module Puppet
             :owner =&gt; &quot;$user&quot;,
             :group =&gt; &quot;$group&quot;,
             :mode =&gt; 0664,
-            :desc =&gt; &quot;The certificate revocation list (CRL) for the CA. Set this to 'false' if you do not want to use a CRL.&quot;
+            :desc =&gt; &quot;The certificate revocation list (CRL) for the CA. Will be used if present but otherwise ignored.&quot;,
+            :hook =&gt; proc do |value|
+                if value == 'false'
+                    Puppet.warning &quot;Setting the :cacrl to 'false' is deprecated; Puppet will just ignore the crl if yours is missing&quot;
+                end
+            end
         },
         :caprivatedir =&gt; { :default =&gt; &quot;$cadir/private&quot;,
             :owner =&gt; &quot;$user&quot;,
@@ -264,7 +282,7 @@ module Puppet
         :serial =&gt; { :default =&gt; &quot;$cadir/serial&quot;,
             :owner =&gt; &quot;$user&quot;,
             :group =&gt; &quot;$group&quot;,
-            :mode =&gt; 0600,
+            :mode =&gt; 0644,
             :desc =&gt; &quot;Where the serial number for certificates is stored.&quot;
         },
         :autosign =&gt; { :default =&gt; &quot;$confdir/autosign.conf&quot;,
@@ -297,7 +315,7 @@ module Puppet
     self.setdefaults(self.settings[:name],
         :config =&gt; [&quot;$confdir/puppet.conf&quot;,
             &quot;The configuration file for #{Puppet[:name]}.&quot;],
-        :pidfile =&gt; [&quot;&quot;, &quot;The pid file&quot;],
+        :pidfile =&gt; [&quot;$rundir/$name.pid&quot;, &quot;The pid file&quot;],
         :bindaddress =&gt; [&quot;&quot;, &quot;The address to bind to.  Mongrel servers
             default to 127.0.0.1 and WEBrick defaults to 0.0.0.0.&quot;],
         :servertype =&gt; [&quot;webrick&quot;, &quot;The type of server to use.  Currently supported
@@ -388,19 +406,6 @@ module Puppet
             :mode =&gt; 0640,
             :desc =&gt; &quot;The log file for puppetd.  This is generally not used.&quot;
         },
-        :httplog =&gt; { :default =&gt; &quot;$logdir/http.log&quot;,
-            :owner =&gt; &quot;root&quot;,
-            :mode =&gt; 0640,
-            :desc =&gt; &quot;Where the puppetd web server logs.&quot;
-        },
-        :http_proxy_host =&gt; [&quot;none&quot;,
-            &quot;The HTTP proxy host to use for outgoing connections.  Note: You
-            may need to use a FQDN for the server hostname when using a proxy.&quot;],
-        :http_proxy_port =&gt; [3128,
-            &quot;The HTTP proxy port to use for outgoing connections&quot;],
-        :http_enable_post_connection_check =&gt; [true,
-            &quot;Boolean; wheter or not puppetd should validate the server
-            SSL certificate against the request hostname.&quot;],
         :server =&gt; [&quot;puppet&quot;,
             &quot;The server to which server puppetd should connect&quot;],
         :ignoreschedules =&gt; [false,
@@ -511,9 +516,11 @@ module Puppet
 
     # Central fact information.
     self.setdefaults(:main,
-        :factpath =&gt; [&quot;$vardir/facts&quot;,
-            &quot;Where Puppet should look for facts.  Multiple directories should
-            be colon-separated, like normal PATH variables.&quot;],
+        :factpath =&gt; {:default =&gt; &quot;$vardir/facts&quot;,
+            :desc =&gt; &quot;Where Puppet should look for facts.  Multiple directories should
+                be colon-separated, like normal PATH variables.&quot;,
+            :call_on_define =&gt; true, # Call our hook with the default value, so we always get the value added to facter.
+            :hook =&gt; proc { |value| Facter.search(value) if Facter.respond_to?(:search) }},
         :factdest =&gt; [&quot;$vardir/facts&quot;,
             &quot;Where Puppet should store facts that it pulls down from the central
             server.&quot;],
@@ -628,6 +635,10 @@ module Puppet
         :ldapclassattrs =&gt; [&quot;puppetclass&quot;,
             &quot;The LDAP attributes to use to define Puppet classes.  Values
             should be comma-separated.&quot;],
+        :ldapstackedattrs =&gt; [&quot;puppetvar&quot;,
+            &quot;The LDAP attributes that should be stacked to arrays by adding
+            the values in all hierarchy elements of the tree.  Values
+            should be comma-separated.&quot;],
         :ldapattrs =&gt; [&quot;all&quot;,
             &quot;The LDAP attributes to include when querying LDAP for nodes.  All
             returned attributes are set as variables in the top-level scope.</diff>
      <filename>lib/puppet/defaults.rb</filename>
    </modified>
    <modified>
      <diff>@@ -5,25 +5,20 @@
 require 'puppet'
 require 'puppet/file_serving'
 require 'puppet/file_serving/mount'
+require 'puppet/util/cacher'
 
 class Puppet::FileServing::Configuration
     require 'puppet/file_serving/configuration/parser'
 
+    extend Puppet::Util::Cacher
+
     @config_fileuration = nil
 
     Mount = Puppet::FileServing::Mount
 
-    # Remove our singleton instance.
-    def self.clear_cache
-        @config_fileuration = nil
-    end
-
     # Create our singleton configuration.
     def self.create
-        unless @config_fileuration
-            @config_fileuration = new()
-        end
-        @config_fileuration
+        attr_cache(:configuration) { new() }
     end
 
     private_class_method  :new</diff>
      <filename>lib/puppet/file_serving/configuration.rb</filename>
    </modified>
    <modified>
      <diff>@@ -4,6 +4,7 @@
 
 require 'puppet/network/authstore'
 require 'puppet/util/logging'
+require 'puppet/util/cacher'
 require 'puppet/file_serving'
 require 'puppet/file_serving/metadata'
 require 'puppet/file_serving/content'
@@ -12,12 +13,16 @@ require 'puppet/file_serving/content'
 # or content objects.
 class Puppet::FileServing::Mount &lt; Puppet::Network::AuthStore
     include Puppet::Util::Logging
+    extend Puppet::Util::Cacher
 
-    @@localmap = nil
-
-    # Clear the cache.  This is only ever used for testing.
-    def self.clear_cache
-        @@localmap = nil
+    def self.localmap
+        attr_cache(:localmap) { 
+            {   &quot;h&quot; =&gt;  Facter.value(&quot;hostname&quot;),
+                &quot;H&quot; =&gt; [Facter.value(&quot;hostname&quot;),
+                        Facter.value(&quot;domain&quot;)].join(&quot;.&quot;),
+                &quot;d&quot; =&gt;  Facter.value(&quot;domain&quot;)
+            }
+        }
     end
 
     attr_reader :name
@@ -173,14 +178,6 @@ class Puppet::FileServing::Mount &lt; Puppet::Network::AuthStore
     # Cache this manufactured map, since if it's used it's likely
     # to get used a lot.
     def localmap
-        unless @@localmap
-            @@localmap = {
-                &quot;h&quot; =&gt;  Facter.value(&quot;hostname&quot;),
-                &quot;H&quot; =&gt; [Facter.value(&quot;hostname&quot;),
-                        Facter.value(&quot;domain&quot;)].join(&quot;.&quot;),
-                &quot;d&quot; =&gt;  Facter.value(&quot;domain&quot;)
-            }
-        end
-        @@localmap
+        self.class.localmap
     end
 end</diff>
      <filename>lib/puppet/file_serving/mount.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,20 +1,17 @@
 require 'puppet/util/docs'
 require 'puppet/indirector/envelope'
 require 'puppet/indirector/request'
+require 'puppet/util/cacher'
 
 # The class that connects functional classes with their different collection
 # back-ends.  Each indirection has a set of associated terminus classes,
 # each of which is a subclass of Puppet::Indirector::Terminus.
 class Puppet::Indirector::Indirection
+    include Puppet::Util::Cacher
     include Puppet::Util::Docs
 
     @@indirections = []
 
-    # Clear all cached termini from all indirections.
-    def self.clear_cache
-        @@indirections.each { |ind| ind.clear_cache }
-    end
-
     # Find an indirection by name.  This is provided so that Terminus classes
     # can specifically hook up with the indirections they are associated with.
     def self.instance(name)
@@ -54,13 +51,6 @@ class Puppet::Indirector::Indirection
         @cache_class = class_name
     end
 
-    # Clear our cached list of termini, and reset the cache name
-    # so it's looked up again.
-    # This is only used for testing.
-    def clear_cache
-        @termini.clear
-    end
-
     # This is only used for testing.
     def delete
         @@indirections.delete(self) if @@indirections.include?(self)
@@ -104,7 +94,6 @@ class Puppet::Indirector::Indirection
         @model = model
         @name = name
 
-        @termini = {}
         @cache_class = nil
         @terminus_class = nil
 
@@ -138,7 +127,7 @@ class Puppet::Indirector::Indirection
             raise Puppet::DevError, &quot;No terminus specified for %s; cannot redirect&quot; % self.name
         end
         
-        return @termini[terminus_name] ||= make_terminus(terminus_name)
+        return termini[terminus_name] ||= make_terminus(terminus_name)
     end
 
     # This can be used to select the terminus class.
@@ -299,4 +288,9 @@ class Puppet::Indirector::Indirection
         end
         return klass.new
     end
+
+    # Use cached termini.
+    def termini
+        attr_cache(:termini) { Hash.new }
+    end
 end</diff>
      <filename>lib/puppet/indirector/indirection.rb</filename>
    </modified>
    <modified>
      <diff>@@ -19,6 +19,8 @@ class Puppet::Node::Ldap &lt; Puppet::Indirector::Ldap
 
         node = Puppet::Node.new(name)
 
+        information[:stacked_parameters] = {}
+
         parent_info = nil
         parent = information[:parent]
         parents = [name]
@@ -34,6 +36,10 @@ class Puppet::Node::Ldap &lt; Puppet::Indirector::Ldap
                 raise Puppet::Error.new(&quot;Could not find parent node '%s'&quot; % parent)
             end
             information[:classes] += parent_info[:classes]
+            parent_info[:stacked].each do |value|
+                param = value.split('=', 2)
+                information[:stacked_parameters][param[0]] = param[1]
+            end
             parent_info[:parameters].each do |param, value|
                 # Specifically test for whether it's set, so false values are handled
                 # correctly.
@@ -45,6 +51,15 @@ class Puppet::Node::Ldap &lt; Puppet::Indirector::Ldap
             parent = parent_info[:parent]
         end
 
+        information[:stacked].each do |value|
+            param = value.split('=', 2)
+            information[:stacked_parameters][param[0]] = param[1]
+        end
+
+        information[:stacked_parameters].each do |param, value|
+            information[:parameters][param] = value unless information[:parameters].include?(param)
+        end
+
         node.classes = information[:classes].uniq unless information[:classes].empty?
         node.parameters = information[:parameters] unless information[:parameters].empty?
         node.environment = information[:environment] if information[:environment]
@@ -62,6 +77,12 @@ class Puppet::Node::Ldap &lt; Puppet::Indirector::Ldap
         end
     end
 
+    # The attributes that Puppet will stack as array over the full
+    # hierarchy.
+    def stacked_attributes
+        Puppet[:ldapstackedattrs].split(/\s*,\s*/)
+    end
+
     # Process the found entry.  We assume that we don't just want the
     # ldap object.
     def process(name, entry)
@@ -85,6 +106,14 @@ class Puppet::Node::Ldap &lt; Puppet::Indirector::Ldap
             end
         }
 
+        result[:stacked] = []
+        stacked_attributes.each { |attr|
+            if values = entry.vals(attr)
+                result[:stacked] = result[:stacked] + values
+            end
+        }
+        
+
         result[:parameters] = entry.to_hash.inject({}) do |hash, ary|
             if ary[1].length == 1
                 hash[ary[0]] = ary[1].shift</diff>
      <filename>lib/puppet/indirector/node/ldap.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,21 +3,20 @@ require 'uri'
 
 # Access objects via REST
 class Puppet::Indirector::REST &lt; Puppet::Indirector::Terminus
-
     def rest_connection_details
         { :host =&gt; Puppet[:server], :port =&gt; Puppet[:masterport].to_i }
     end
 
     def network_fetch(path)
-        network {|conn| conn.get(&quot;/#{path}&quot;).body }
+        network.get(&quot;/#{path}&quot;).body
     end
     
     def network_delete(path)
-        network {|conn| conn.delete(&quot;/#{path}&quot;).body }
+        network.delete(&quot;/#{path}&quot;).body
     end
     
     def network_put(path, data)
-        network {|conn| conn.put(&quot;/#{path}&quot;, data).body }
+        network.put(&quot;/#{path}&quot;, data).body
     end
     
     def find(request)
@@ -46,8 +45,8 @@ class Puppet::Indirector::REST &lt; Puppet::Indirector::Terminus
     
   private
   
-    def network(&amp;block)
-        Net::HTTP.start(rest_connection_details[:host], rest_connection_details[:port]) {|conn| yield(conn) }
+    def network
+        Puppet::Network::HttpPool.http_instance(rest_connection_details[:host], rest_connection_details[:port])
     end
   
     def exception?(yaml_string)</diff>
      <filename>lib/puppet/indirector/rest.rb</filename>
    </modified>
    <modified>
      <diff>@@ -45,7 +45,7 @@ class Puppet::Network::Client::CA &lt; Puppet::Network::Client
         end
 
         unless @cert.check_private_key(key)
-            raise InvalidCertificate, &quot;Certificate does not match private key.  Try 'puppetca --clean %s' on the server.&quot; % Facter.value(:fqdn)
+            raise InvalidCertificate, &quot;Certificate does not match private key.  Try 'puppetca --clean %s' on the server.&quot; % Puppet[:certname]
         end
 
         # Only write the cert out if it passes validating.</diff>
      <filename>lib/puppet/network/client/ca.rb</filename>
    </modified>
    <modified>
      <diff>@@ -20,7 +20,7 @@ module Puppet::Network::HTTP::Handler
   private
 
     def model
-      @model
+        @model
     end
     
     def do_find(request, response)
@@ -53,7 +53,7 @@ module Puppet::Network::HTTP::Handler
     end
     
     def save_object(obj)
-      obj.save
+        obj.save
     end
   
     def do_exception(request, response, exception, status=404)
@@ -85,8 +85,7 @@ module Puppet::Network::HTTP::Handler
         %r{/#{@handler.to_s}s$}.match(path(request))
     end
     
-  # methods to be overridden by the including web server class
-    
+    # methods to be overridden by the including web server class
     def register_handler
         raise NotImplementedError
     end</diff>
      <filename>lib/puppet/network/http/handler.rb</filename>
    </modified>
    <modified>
      <diff>@@ -16,6 +16,7 @@ class Puppet::Network::HTTP::Mongrel
 
         @protocols = args[:protocols]
         @handlers = args[:handlers]
+        @xmlrpc_handlers = args[:xmlrpc_handlers]
         @server = Mongrel::HttpServer.new(args[:address], args[:port]) 
         setup_handlers
 
@@ -38,12 +39,22 @@ class Puppet::Network::HTTP::Mongrel
   
     def setup_handlers
         @protocols.each do |protocol|
+            next if protocol == :xmlrpc
             klass = class_for_protocol(protocol)
             @handlers.each do |handler|
                 @server.register('/' + handler.to_s, klass.new(:server =&gt; @server, :handler =&gt; handler))
                 @server.register('/' + handler.to_s + 's', klass.new(:server =&gt; @server, :handler =&gt; handler))
             end
         end
+
+        if @protocols.include?(:xmlrpc) and ! @xmlrpc_handlers.empty?
+            setup_xmlrpc_handlers
+        end
+    end
+
+    # Use our existing code to provide the xmlrpc backward compatibility.
+    def setup_xmlrpc_handlers
+        @server.register('/RPC2', Puppet::Network::HTTPServer::Mongrel.new(@xmlrpc_handlers))
     end
   
     def class_for_protocol(protocol)</diff>
      <filename>lib/puppet/network/http/mongrel.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,12 +2,12 @@ require 'puppet/network/http/handler'
 
 class Puppet::Network::HTTP::MongrelREST &lt; Mongrel::HttpHandler
 
-  include Puppet::Network::HTTP::Handler
+    include Puppet::Network::HTTP::Handler
   
-  def initialize(args={})
-    super()
-    initialize_for_puppet(args)
-  end
+    def initialize(args={})
+        super()
+        initialize_for_puppet(args)
+    end
 
   private
  </diff>
      <filename>lib/puppet/network/http/mongrel/rest.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,8 +1,12 @@
 require 'webrick'
 require 'webrick/https'
 require 'puppet/network/http/webrick/rest'
+require 'puppet/network/xmlrpc/webrick_servlet'
 require 'thread'
 
+require 'puppet/ssl/certificate'
+require 'puppet/ssl/certificate_revocation_list'
+
 class Puppet::Network::HTTP::WEBrick
     def initialize(args = {})
         @listening = false
@@ -22,6 +26,7 @@ class Puppet::Network::HTTP::WEBrick
         
         @protocols = args[:protocols]
         @handlers = args[:handlers]        
+        @xmlrpc_handlers = args[:xmlrpc_handlers]        
 
         arguments = {:BindAddress =&gt; args[:address], :Port =&gt; args[:port]}
         arguments.merge!(setup_logger)
@@ -54,7 +59,7 @@ class Puppet::Network::HTTP::WEBrick
         end
     end
 
-    # Configure out http log file.
+    # Configure our http log file.
     def setup_logger
         # Make sure the settings are all ready for us.
         Puppet.settings.use(:main, :ssl, Puppet[:name])
@@ -84,51 +89,56 @@ class Puppet::Network::HTTP::WEBrick
     def setup_ssl
         results = {}
 
-        results[:SSLCertificateStore] = setup_crl if Puppet[:cacrl] != 'false'
+        host = Puppet::SSL::Host.new
+
+        host.generate unless host.certificate
+
+        raise Puppet::Error, &quot;Could not retrieve certificate for %s and not running on a valid certificate authority&quot; % host.name unless host.certificate
 
-        results[:SSLCertificate] = self.cert
-        results[:SSLPrivateKey] = self.key
+        results[:SSLPrivateKey] = host.key.content
+        results[:SSLCertificate] = host.certificate.content
         results[:SSLStartImmediately] = true
         results[:SSLEnable] = true
-        results[:SSLCACertificateFile] = Puppet[:localcacert]
-        results[:SSLVerifyClient] = OpenSSL::SSL::VERIFY_PEER
-        results[:SSLCertName] = nil
 
-        results
-    end
-
-    # Create our Certificate revocation list
-    def setup_crl
-        nil
-        if Puppet[:cacrl] == 'false'
-            # No CRL, no store needed
-            return nil
-        end
-        unless File.exist?(Puppet[:cacrl])
-            raise Puppet::Error, &quot;Could not find CRL; set 'cacrl' to 'false' to disable CRL usage&quot;
-        end
-        crl = OpenSSL::X509::CRL.new(File.read(Puppet[:cacrl]))
-        store = OpenSSL::X509::Store.new
-        store.purpose = OpenSSL::X509::PURPOSE_ANY
-        store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK
-        unless self.ca_cert
+        unless Puppet::SSL::Certificate.find(&quot;ca&quot;)
             raise Puppet::Error, &quot;Could not find CA certificate&quot;
         end
 
-        store.add_file(Puppet[:localcacert])
-        store.add_crl(crl)
-        return store
+        results[:SSLCACertificateFile] = Puppet[:localcacert]
+        results[:SSLVerifyClient] = OpenSSL::SSL::VERIFY_PEER
+
+        results[:SSLCertificateStore] = host.ssl_store
+
+        results
     end
 
   private
     
     def setup_handlers
+        # Set up the new-style protocols.
         @protocols.each do |protocol|
+            next if protocol == :xmlrpc
             klass = self.class.class_for_protocol(protocol)
             @handlers.each do |handler|
                 @server.mount('/' + handler.to_s, klass, handler)
                 @server.mount('/' + handler.to_s + 's', klass, handler)
             end
         end
+
+        # And then set up xmlrpc, if configured.
+        if @protocols.include?(:xmlrpc) and ! @xmlrpc_handlers.empty?
+            @server.mount(&quot;/RPC2&quot;, xmlrpc_servlet)
+        end
+    end
+
+    # Create our xmlrpc servlet, which provides backward compatibility.
+    def xmlrpc_servlet
+        handlers = @xmlrpc_handlers.collect { |handler|
+            unless hclass = Puppet::Network::Handler.handler(handler)
+                raise &quot;Invalid xmlrpc handler %s&quot; % handler
+            end
+            hclass.new({})
+        }
+        Puppet::Network::XMLRPC::WEBrickServlet.new handlers
     end
 end</diff>
      <filename>lib/puppet/network/http/webrick.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,11 +1,13 @@
-require 'puppet/sslcertificates/support'
+require 'puppet/ssl/host'
 require 'net/https'
+require 'puppet/util/cacher'
 
-module Puppet::Network
-end
+module Puppet::Network; end
 
 # Manage Net::HTTP instances for keep-alive.
 module Puppet::Network::HttpPool
+    extend Puppet::Util::Cacher
+
     # 2008/03/23
     # LAK:WARNING: Enabling this has a high propability of
     # causing corrupt files and who knows what else.  See #1010.
@@ -15,18 +17,18 @@ module Puppet::Network::HttpPool
         HTTP_KEEP_ALIVE
     end
 
-    # This handles reading in the key and such-like.
-    extend Puppet::SSLCertificates::Support
-    @http_cache = {}
+    # Create an ssl host instance for getting certificate
+    # information.
+    def self.ssl_host
+        attr_cache(:ssl_host) { Puppet::SSL::Host.new }
+    end
 
     # Clear our http cache, closing all connections.
     def self.clear_http_instances
-        @http_cache.each do |name, connection|
+        http_cache.each do |name, connection|
             connection.finish if connection.started?
         end
-        @http_cache.clear
-        @cert = nil
-        @key = nil
+        Puppet::Util::Cacher.invalidate
     end
 
     # Make sure we set the driver up when we read the cert in.
@@ -44,17 +46,13 @@ module Puppet::Network::HttpPool
     # Use cert information from a Puppet client to set up the http object.
     def self.cert_setup(http)
         # Just no-op if we don't have certs.
-        return false unless (defined?(@cert) and @cert) or self.read_cert
+        return false unless FileTest.exist?(Puppet[:hostcert]) # ssl_host.certificate
 
-        store = OpenSSL::X509::Store.new
-        store.add_file Puppet[:localcacert]
-        store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
-
-        http.cert_store = store
+        http.cert_store = ssl_host.ssl_store
         http.ca_file = Puppet[:localcacert]
-        http.cert = self.cert
+        http.cert = ssl_host.certificate.content
         http.verify_mode = OpenSSL::SSL::VERIFY_PEER
-        http.key = self.key
+        http.key = ssl_host.key.content
     end
 
     # Retrieve a cached http instance of caching is enabled, else return
@@ -66,11 +64,11 @@ module Puppet::Network::HttpPool
         # Return our cached instance if we've got a cache, as long as we're not
         # resetting the instance.
         if keep_alive?
-            return @http_cache[key] if ! reset and @http_cache[key]
+            return http_cache[key] if ! reset and http_cache[key]
 
             # Clean up old connections if we have them.
-            if http = @http_cache[key]
-                @http_cache.delete(key)
+            if http = http_cache[key]
+                http_cache.delete(key)
                 http.finish if http.started?
             end
         end
@@ -100,8 +98,15 @@ module Puppet::Network::HttpPool
 
         cert_setup(http)
 
-        @http_cache[key] = http if keep_alive?
+        http_cache[key] = http if keep_alive?
 
         return http
     end
+
+    private
+    
+    def self.http_cache
+        # Default to an empty hash.
+        attr_cache(:http) { Hash.new }
+    end
 end</diff>
      <filename>lib/puppet/network/http_pool.rb</filename>
    </modified>
    <modified>
      <diff>@@ -64,11 +64,11 @@ module Puppet::Network
             # behaviour and we have to subclass Mongrel::HttpHandler so our handler
             # works for Mongrel.
             @xmlrpc_server = Puppet::Network::XMLRPCServer.new
-            handlers.each do |name, args|
+            handlers.each do |name|
                 unless handler = Puppet::Network::Handler.handler(name)
                     raise ArgumentError, &quot;Invalid handler %s&quot; % name
                 end
-                @xmlrpc_server.add_handler(handler.interface, handler.new(args))
+                @xmlrpc_server.add_handler(handler.interface, handler.new({}))
             end
         end
 </diff>
      <filename>lib/puppet/network/http_server/mongrel.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,26 +1,87 @@
 require 'puppet/network/http'
+require 'puppet/util/pidlock'
 
 class Puppet::Network::Server
     attr_reader :server_type, :protocols, :address, :port
 
+    # Put the daemon into the background.
+    def daemonize
+        if pid = fork()
+            Process.detach(pid)
+            exit(0)
+        end
+
+        # Get rid of console logging
+        Puppet::Util::Log.close(:console)
+
+        Process.setsid
+        Dir.chdir(&quot;/&quot;)
+        begin
+            $stdin.reopen &quot;/dev/null&quot;
+            $stdout.reopen &quot;/dev/null&quot;, &quot;a&quot;
+            $stderr.reopen $stdout
+            Puppet::Util::Log.reopen
+        rescue =&gt; detail
+            File.open(&quot;/tmp/daemonout&quot;, &quot;w&quot;) { |f|
+                f.puts &quot;Could not start %s: %s&quot; % [Puppet[:name], detail]
+            }
+            raise &quot;Could not start %s: %s&quot; % [Puppet[:name], detail]
+        end
+    end
+
+    # Create a pidfile for our daemon, so we can be stopped and others
+    # don't try to start.
+    def create_pidfile
+        Puppet::Util.sync(Puppet[:name]).synchronize(Sync::EX) do
+            unless Puppet::Util::Pidlock.new(pidfile).lock
+                raise &quot;Could not create PID file: %s&quot; % [pidfile]
+            end
+        end
+    end
+
+    # Remove the pid file for our daemon.
+    def remove_pidfile
+        Puppet::Util.sync(Puppet[:name]).synchronize(Sync::EX) do
+            locker = Puppet::Util::Pidlock.new(pidfile)
+            if locker.locked?
+                locker.unlock or Puppet.err &quot;Could not remove PID file %s&quot; % [pidfile]
+            end
+        end
+    end
+
+    # Provide the path to our pidfile.
+    def pidfile
+        Puppet[:pidfile]
+    end
+
     def initialize(args = {})
         @server_type = Puppet[:servertype] or raise &quot;No servertype configuration found.&quot;  # e.g.,  WEBrick, Mongrel, etc.
         http_server_class || raise(ArgumentError, &quot;Could not determine HTTP Server class for server type [#{@server_type}]&quot;)
-        @address = args[:address] || Puppet[:bindaddress] || 
-            raise(ArgumentError, &quot;Must specify :address or configure Puppet :bindaddress.&quot;)
-        @port = args[:port] || Puppet[:masterport] ||
-            raise(ArgumentError, &quot;Must specify :port or configure Puppet :masterport&quot;)
-        @protocols = [ :rest ]
+
+        @address = args[:address] || Puppet[:bindaddress] || raise(ArgumentError, &quot;Must specify :address or configure Puppet :bindaddress.&quot;)
+        @port = args[:port] || Puppet[:masterport] || raise(ArgumentError, &quot;Must specify :port or configure Puppet :masterport&quot;)
+
+        @protocols = [ :rest, :xmlrpc ]
         @listening = false
         @routes = {}
+        @xmlrpc_routes = {}
         self.register(args[:handlers]) if args[:handlers]
+        self.register_xmlrpc(args[:xmlrpc_handlers]) if args[:xmlrpc_handlers]
+
+        # Make sure we have all of the directories we need to function.
+        Puppet.settings.use(:main, :ssl, Puppet[:name])
     end
 
+    # Register handlers for REST networking, based on the Indirector.
     def register(*indirections)
         raise ArgumentError, &quot;Indirection names are required.&quot; if indirections.empty?
-        indirections.flatten.each { |i| @routes[i.to_sym] = true }
+        indirections.flatten.each do |name|
+            Puppet::Indirector::Indirection.model(name) || raise(ArgumentError, &quot;Cannot locate indirection '#{name}'.&quot;)
+            @routes[name.to_sym] = true
+        end
     end
   
+    # Unregister Indirector handlers.
     def unregister(*indirections)
         raise &quot;Cannot unregister indirections while server is listening.&quot; if listening?
         indirections = @routes.keys if indirections.empty?
@@ -34,6 +95,29 @@ class Puppet::Network::Server
         end
     end
 
+    # Register xmlrpc handlers for backward compatibility.
+    def register_xmlrpc(*namespaces)
+        raise ArgumentError, &quot;XMLRPC namespaces are required.&quot; if namespaces.empty?
+        namespaces.flatten.each do |name|
+            Puppet::Network::Handler.handler(name) || raise(ArgumentError, &quot;Cannot locate XMLRPC handler for namespace '#{name}'.&quot;)
+            @xmlrpc_routes[name.to_sym] = true
+        end
+    end
+  
+    # Unregister xmlrpc handlers.
+    def unregister_xmlrpc(*namespaces)
+        raise &quot;Cannot unregister xmlrpc handlers while server is listening.&quot; if listening?
+        namespaces = @xmlrpc_routes.keys if namespaces.empty?
+
+        namespaces.flatten.each do |i|
+            raise(ArgumentError, &quot;XMLRPC handler '%s' is unknown.&quot; % i) unless @xmlrpc_routes[i.to_sym]
+        end
+        
+        namespaces.flatten.each do |i|
+            @xmlrpc_routes.delete(i.to_sym)
+        end
+    end
+
     def listening?
         @listening
     end
@@ -41,7 +125,7 @@ class Puppet::Network::Server
     def listen
         raise &quot;Cannot listen -- already listening.&quot; if listening?
         @listening = true
-        http_server.listen(:address =&gt; address, :port =&gt; port, :handlers =&gt; @routes.keys, :protocols =&gt; protocols)
+        http_server.listen(:address =&gt; address, :port =&gt; port, :handlers =&gt; @routes.keys, :xmlrpc_handlers =&gt; @xmlrpc_routes.keys, :protocols =&gt; protocols)
     end
   
     def unlisten
@@ -54,6 +138,16 @@ class Puppet::Network::Server
         http_server_class_by_type(@server_type)
     end
 
+    def start
+        create_pidfile
+        listen
+    end
+
+    def stop
+        unlisten
+        remove_pidfile
+    end
+
   private
   
     def http_server</diff>
      <filename>lib/puppet/network/server.rb</filename>
    </modified>
    <modified>
      <diff>@@ -51,7 +51,8 @@ module Puppet::Network
                         end
                         [&quot;certificate verify failed&quot;, &quot;hostname was not match&quot;, &quot;hostname not match&quot;].each do |str|
                             if detail.message.include?(str)
-                                Puppet.warning &quot;Certificate validation failed; considering using the certname configuration option&quot;
+                                Puppet.warning &quot;Certificate validation failed; consider using the certname configuration option&quot;
+                                break
                             end
                         end 
                         raise XMLRPCClientError,</diff>
      <filename>lib/puppet/network/xmlrpc/client.rb</filename>
    </modified>
    <modified>
      <diff>@@ -332,7 +332,7 @@ class Puppet::Parser::Compiler
 
         unless remaining.empty?
             fail Puppet::ParseError,
-                &quot;Could not find object(s) %s&quot; % remaining.collect { |o|
+                &quot;Could not find resource(s) %s for overriding&quot; % remaining.collect { |o|
                     o.ref
                 }.join(&quot;, &quot;)
         end</diff>
      <filename>lib/puppet/parser/compiler.rb</filename>
    </modified>
    <modified>
      <diff>@@ -165,7 +165,7 @@ module Functions
     type is defined, either as a native type or a defined type, or whether a class is defined.
     This is useful for checking whether a class is defined and only including it if it is.
     This function can also test whether a resource has been defined, using resource references
-    (e.g., ``if defined(File['/tmp/myfile'] { ... }``).  This function is unfortunately
+    (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.&quot;) do |vals|
         result = false
         vals.each do |val|</diff>
      <filename>lib/puppet/parser/functions.rb</filename>
    </modified>
    <modified>
      <diff>@@ -62,7 +62,7 @@ class Puppet::Parser::Interpreter
                 # exception elsewhere and reuse the parser.  If one doesn't
                 # exist, then reraise.
                 if @parsers[environment]
-                    Puppet.err detail
+                    Puppet.err(detail.to_s + &quot;; using previously parsed manifests&quot;)
                 else
                     raise detail
                 end</diff>
      <filename>lib/puppet/parser/interpreter.rb</filename>
    </modified>
    <modified>
      <diff>@@ -20,6 +20,15 @@ class Puppet::Parser::TemplateWrapper
         end
     end
 
+    # Should return true if a variable is defined, false if it is not
+    def has_variable?(name)
+        if @scope.lookupvar(name.to_s, false) != :undefined
+            true
+        else
+            false
+        end
+    end
+
     # Ruby treats variables like methods, so we can cheat here and
     # trap missing vars like they were missing methods.
     def method_missing(name, *args)</diff>
      <filename>lib/puppet/parser/templatewrapper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -5,6 +5,10 @@ class Puppet::Provider
     include Puppet::Util::Warnings
     extend Puppet::Util::Warnings
 
+    require 'puppet/provider/confiner'
+
+    extend Puppet::Provider::Confiner
+
     Puppet::Util.logmethods(self, true)
 
     class &lt;&lt; self
@@ -40,27 +44,13 @@ class Puppet::Provider
                 [name, self.name]
         end
 
-        if command == :missing
-            return nil
-        end
-
-        command
+        return binary(command)
     end
 
     # Define commands that are not optional.
     def self.commands(hash)
         optional_commands(hash) do |name, path|
-            confine :exists =&gt; path
-        end
-    end
-
-    def self.confine(hash)
-        hash.each do |p,v|
-            if v.is_a? Array
-                @confines[p] += v
-            else
-                @confines[p] &lt;&lt; v
-            end
+            confine :exists =&gt; path, :for_binary =&gt; true
         end
     end
 
@@ -108,10 +98,6 @@ class Puppet::Provider
     def self.initvars
         @defaults = {}
         @commands = {}
-        @origcommands = {}
-        @confines = Hash.new do |hash, key|
-            hash[key] = []
-        end
     end
 
     # The method for returning a list of provider instances.  Note that it returns providers, preferably with values already
@@ -180,16 +166,7 @@ class Puppet::Provider
     def self.optional_commands(hash)
         hash.each do |name, path|
             name = symbolize(name)
-            @origcommands[name] = path
-
-            # Try to find the full path (or verify already-full paths); otherwise
-            # store that the command is missing so we know it's defined but absent.
-            if tmp = binary(path)
-                path = tmp
-                @commands[name] = path
-            else
-                @commands[name] = :missing
-            end
+            @commands[name] = path
 
             if block_given?
                 yield(name, path)
@@ -208,69 +185,6 @@ class Puppet::Provider
         @source
     end
 
-    # Check whether this implementation is suitable for our platform.
-    def self.suitable?(short = true)
-        # A single false result is sufficient to turn the whole thing down.
-        # We don't return 'true' until the very end, though, so that every
-        # confine is tested.
-        missing = {}
-        @confines.each do |check, values|
-            case check
-            when :exists:
-                values.each do |value|
-                    unless value and FileTest.exists? value
-                        debug &quot;Not suitable: missing %s&quot; % value
-                        return false if short
-                        missing[:exists] ||= []
-                        missing[:exists] &lt;&lt; value
-                    end
-                end
-            when :true:
-                values.each do |v|
-                    debug &quot;Not suitable: false value&quot;
-                    unless v
-                        return false if short
-                        missing[:true] ||= 0
-                        missing[:true] += 1
-                    end
-                end
-            when :false:
-                values.each do |v|
-                    debug &quot;Not suitable: true value&quot;
-                    if v and short
-                        return false if short
-                        missing[:false] ||= 0
-                        missing[:false] += 1
-                    end
-                end
-            else # Just delegate everything else to facter
-                if result = Facter.value(check)
-                    result = result.to_s.downcase.intern
-
-                    found = values.find do |v|
-                        result == v.to_s.downcase.intern
-                    end
-                    unless found
-                        debug &quot;Not suitable: %s not in %s&quot; % [check, values]
-                        return false if short
-                        missing[:facter] ||= {}
-                        missing[:facter][check] = values
-                    end
-                else
-                    return false if short
-                    missing[:facter] ||= {}
-                    missing[:facter][check] = values
-                end
-            end
-        end
-
-        if short
-            return true
-        else
-            return missing
-        end
-    end
-
     # Does this provider support the specified parameter?
     def self.supports_parameter?(param)
         if param.is_a?(Class)
@@ -309,8 +223,8 @@ class Puppet::Provider
     end
 
     dochook(:commands) do
-        if @origcommands.length &gt; 0
-            return &quot;  Required binaries: &quot; + @origcommands.collect do |n, c|
+        if @commands.length &gt; 0
+            return &quot;  Required binaries: &quot; + @commands.collect do |n, c|
                 &quot;``#{c}``&quot;
             end.join(&quot;, &quot;) + &quot;.&quot;
         end</diff>
      <filename>lib/puppet/provider.rb</filename>
    </modified>
    <modified>
      <diff>@@ -30,7 +30,7 @@ Puppet::Type.type(:cron).provide(:crontab,
         }
 
     crontab = record_line :crontab, :fields =&gt; %w{minute hour monthday month weekday command},
-        :match =&gt; %r{^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.+)$},
+        :match =&gt; %r{^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.+)$},
         :optional =&gt; %w{minute hour weekday month monthday}, :absent =&gt; &quot;*&quot;
 
     class &lt;&lt; crontab</diff>
      <filename>lib/puppet/provider/cron/crontab.rb</filename>
    </modified>
    <modified>
      <diff>@@ -25,7 +25,7 @@ class ObjectAdd &lt; Puppet::Provider::NameService
         cmd = [command(:modify),
             flag(param),
             value]
-        if @resource[:allowdupe]  == :true
+        if @resource[:allowdupe] == :true &amp;&amp; param == :uid
             cmd &lt;&lt; &quot;-o&quot;
         end
         cmd &lt;&lt; @resource[:name]</diff>
      <filename>lib/puppet/provider/nameservice/objectadd.rb</filename>
    </modified>
    <modified>
      <diff>@@ -67,7 +67,7 @@ Puppet::Type.type(:package).provide :rpm, :source =&gt; :rpm, :parent =&gt; Puppet::Pr
         end
         
         cmd = [command(:rpm), &quot;-q&quot;, &quot;--qf&quot;, &quot;#{NEVRAFORMAT}\n&quot;, &quot;-p&quot;, &quot;#{@resource[:source]}&quot;]
-        h = nevra_to_hash(execfail(cmd, Puppet::Error))
+        h = self.class.nevra_to_hash(execfail(cmd, Puppet::Error))
         return h[:ensure]
     end
 </diff>
      <filename>lib/puppet/provider/package/rpm.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,6 @@
 Puppet::Type.type(:package).provide :urpmi, :parent =&gt; :rpm, :source =&gt; :rpm do
     desc &quot;Support via ``urpmi``.&quot;
-    commands :urpmi =&gt; &quot;urpmi&quot;, :rpm =&gt; &quot;rpm&quot;
+    commands :urpmi =&gt; &quot;urpmi&quot;, :urpmq =&gt; &quot;urpmq&quot;, :rpm =&gt; &quot;rpm&quot;
 
     if command('rpm')
         confine :true =&gt; begin
@@ -41,9 +41,9 @@ Puppet::Type.type(:package).provide :urpmi, :parent =&gt; :rpm, :source =&gt; :rpm do
 
     # What's the latest package version available?
     def latest
-        output = urpmi &quot;-S&quot;,  :available, @resource[:name]
+        output = urpmq &quot;-S&quot;, @resource[:name]
 
-        if output =~ /^#{@resource[:name]}\S+\s+(\S+)\s/
+        if output =~ /^#{@resource[:name]}\s+:\s+.*\(\s+(\S+)\s+\)/
             return $1
         else
             # urpmi didn't find updates, pretend the current</diff>
      <filename>lib/puppet/provider/package/urpmi.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,10 +1,10 @@
 Puppet::Type.type(:service).provide :base do
     desc &quot;The simplest form of service support.  You have to specify
         enough about your service for this to work; the minimum you can specify
-        is a binary for starting the process, and this same binary will be searched
-        for in the process table to stop the service.  It is preferable to
-        specify start, stop, and status commands, akin to how you would do
-        so using ``init``.&quot;
+        is a binary for starting the process, and this same binary will be 
+        searched for in the process table to stop the service.  It is 
+        preferable to specify start, stop, and status commands, akin to how you
+        would do so using ``init``.&quot;
 
     commands :kill =&gt; &quot;kill&quot;
 </diff>
      <filename>lib/puppet/provider/service/base.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,9 +2,9 @@
 # customizations of this module.
 Puppet::Type.type(:service).provide :init, :parent =&gt; :base do
     desc &quot;Standard init service management.  This provider assumes that the
-        init script has not ``status`` command, because so few scripts do,
-        so you need to either provide a status command or specify via ``hasstatus``
-        that one already exists in the init script.&quot;
+        init script has no ``status`` command, because so few scripts do,
+        so you need to either provide a status command or specify via 
+        ``hasstatus`` that one already exists in the init script.&quot;
 
     class &lt;&lt; self
         attr_accessor :defpath</diff>
      <filename>lib/puppet/provider/service/init.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,11 +1,11 @@
-# Manage debian services.  Start/stop is the same as InitSvc, but enable/disable
-# is special.
+# Manage Red Hat services.  Start/stop uses /sbin/service and enable/disable uses chkconfig
+
 Puppet::Type.type(:service).provide :redhat, :parent =&gt; :init do
     desc &quot;Red Hat's (and probably many others) form of ``init``-style service
         management; uses ``chkconfig`` for service enabling and disabling.&quot;
 
-    commands :chkconfig =&gt; &quot;/sbin/chkconfig&quot;
-
+    commands :chkconfig =&gt; &quot;/sbin/chkconfig&quot;, :service =&gt; &quot;/sbin/service&quot;
+ 
     defaultfor :operatingsystem =&gt; [:redhat, :fedora, :suse, :centos]
 
     def self.defpath
@@ -16,7 +16,6 @@ Puppet::Type.type(:service).provide :redhat, :parent =&gt; :init do
     def disable
         begin
             output = chkconfig(@resource[:name], :off)
-            output += chkconfig(&quot;--del&quot;, @resource[:name])
         rescue Puppet::ExecutionFailure
             raise Puppet::Error, &quot;Could not disable %s: %s&quot; %
                 [self.name, output]
@@ -43,12 +42,28 @@ Puppet::Type.type(:service).provide :redhat, :parent =&gt; :init do
     # in the init scripts.
     def enable
         begin
-            output = chkconfig(&quot;--add&quot;, @resource[:name])
-            output += chkconfig(@resource[:name], :on)
+            output = chkconfig(@resource[:name], :on)
         rescue Puppet::ExecutionFailure =&gt; detail
             raise Puppet::Error, &quot;Could not enable %s: %s&quot; %
                 [self.name, detail]
         end
     end
+ 
+    def restart
+        if @resource[:hasrestart] == true
+              service(@resource[:name], &quot;restart&quot;)
+        else
+           return false
+        end
+    end
+
+    def start
+        service(@resource[:name], &quot;start&quot;)
+    end
+
+    def stop
+        service(@resource[:name], &quot;stop&quot;)
+    end
+
 end
 </diff>
      <filename>lib/puppet/provider/service/redhat.rb</filename>
    </modified>
    <modified>
      <diff>@@ -71,6 +71,8 @@ providers = Puppet::Util::Reference.newreference :providers, :title =&gt; &quot;Provider
                         details += &quot;  - Got %s true tests that should have been false\n&quot; % values
                     when :false:
                         details += &quot;  - Got %s false tests that should have been true\n&quot; % values
+                    when :feature:
+                        details += &quot;  - Missing features %s\n&quot; % values.collect { |f| f.to_s }.join(&quot;,&quot;)
                     end
                 end
                 notes &lt;&lt; details</diff>
      <filename>lib/puppet/reference/providers.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,6 @@
 require 'puppet/ssl/host'
 require 'puppet/ssl/certificate_request'
+require 'puppet/util/cacher'
 
 # The class that knows how to sign certificates.  It creates
 # a 'special' SSL::Host whose name is 'ca', thus indicating
@@ -14,141 +15,84 @@ class Puppet::SSL::CertificateAuthority
     require 'puppet/ssl/inventory'
     require 'puppet/ssl/certificate_revocation_list'
 
-    # This class is basically a hidden class that knows how to act
-    # on the CA.  It's only used by the 'puppetca' executable, and its
-    # job is to provide a CLI-like interface to the CA class. 
-    class Interface
-        INTERFACE_METHODS = [:destroy, :list, :revoke, :generate, :sign, :print, :verify]
+    require 'puppet/ssl/certificate_authority/interface'
 
-        class InterfaceError &lt; ArgumentError; end
+    extend Puppet::Util::Cacher
 
-        attr_reader :method, :subjects
+    def self.ca?
+        return false unless Puppet[:ca]
+        return false unless Puppet[:name] == &quot;puppetmasterd&quot;
+        return true
+    end
 
-        # Actually perform the work.
-        def apply(ca)
-            unless subjects or method == :list
-                raise ArgumentError, &quot;You must provide hosts or :all when using %s&quot; % method
-            end
+    # If this process can function as a CA, then return a singleton
+    # instance.
+    def self.instance
+        return nil unless ca?
 
-            begin
-                if respond_to?(method)
-                    return send(method, ca)
-                end
-
-                (subjects == :all ? ca.list : subjects).each do |host|
-                    ca.send(method, host)
-                end
-            rescue InterfaceError
-                raise
-            rescue =&gt; detail
-                puts detail.backtrace if Puppet[:trace]
-                Puppet.err &quot;Could not call %s: %s&quot; % [method, detail]
-            end
-        end
-
-        def generate(ca)
-            raise InterfaceError, &quot;It makes no sense to generate all hosts; you must specify a list&quot; if subjects == :all
+        attr_cache(:instance) { new }
+    end
 
-            subjects.each do |host|
-                ca.generate(host)
-            end
-        end
+    attr_reader :name, :host
 
-        def initialize(method, subjects)
-            self.method = method
-            self.subjects = subjects
+    # Create and run an applicator.  I wanted to build an interface where you could do
+    # something like 'ca.apply(:generate).to(:all) but I don't think it's really possible.
+    def apply(method, options)
+        unless options[:to]
+            raise ArgumentError, &quot;You must specify the hosts to apply to; valid values are an array or the symbol :all&quot;
         end
+        applier = Interface.new(method, options[:to])
 
-        # List the hosts.
-        def list(ca)
-            unless subjects
-                puts ca.waiting?.join(&quot;\n&quot;)
-                return nil
-            end
-
-            signed = ca.list
-            requests = ca.waiting?
-
-            if subjects == :all
-                hosts = [signed, requests].flatten
-            else
-                hosts = subjects
-            end
+        applier.apply(self)
+    end
 
-            hosts.uniq.sort.each do |host|
-                if signed.include?(host)
-                    puts &quot;+ &quot; + host
-                else
-                    puts host
-                end
-            end
-        end
+    # If autosign is configured, then autosign all CSRs that match our configuration.
+    def autosign
+        return unless auto = autosign?
 
-        # Set the method to apply.
-        def method=(method)
-            raise ArgumentError, &quot;Invalid method %s to apply&quot; % method unless INTERFACE_METHODS.include?(method)
-            @method = method
+        store = nil
+        if auto != true
+            store = autosign_store(auto)
         end
 
-        # Print certificate information.
-        def print(ca)
-            (subjects == :all ? ca.list : subjects).each do |host|
-                if value = ca.print(host)
-                    puts value
-                else
-                    Puppet.err &quot;Could not find certificate for %s&quot; % host
-                end
-            end
-        end
-
-        # Sign a given certificate.
-        def sign(ca)
-            list = subjects == :all ? ca.waiting? : subjects
-            raise InterfaceError, &quot;No waiting certificate requests to sign&quot; if list.empty?
-            list.each do |host|
-                ca.sign(host)
-            end
+        Puppet::SSL::CertificateRequest.search(&quot;*&quot;).each do |csr|
+            sign(csr.name) if auto == true or store.allowed?(csr.name, &quot;127.1.1.1&quot;)
         end
+    end
 
-        # Set the list of hosts we're operating on.  Also supports keywords.
-        def subjects=(value)
-            unless value == :all or value.is_a?(Array)
-                raise ArgumentError, &quot;Subjects must be an array or :all; not %s&quot; % value
-            end
+    # Do we autosign?  This returns true, false, or a filename.
+    def autosign?
+        auto = Puppet[:autosign]
+        return false if ['false', false].include?(auto)
+        return true if ['true', true].include?(auto)
 
-            if value.is_a?(Array) and value.empty?
-                value = nil
-            end
-
-            @subjects = value
+        raise ArgumentError, &quot;The autosign configuration '%s' must be a fully qualified file&quot; % auto unless auto =~ /^\//
+        if FileTest.exist?(auto)
+            return auto
+        else
+            return false
         end
     end
 
-    attr_reader :name, :host
-
-    # Create and run an applicator.  I wanted to build an interface where you could do
-    # something like 'ca.apply(:generate).to(:all) but I don't think it's really possible.
-    def apply(method, options)
-        unless options[:to]
-            raise ArgumentError, &quot;You must specify the hosts to apply to; valid values are an array or the symbol :all&quot;
+    # Create an AuthStore for autosigning.
+    def autosign_store(file)
+        auth = Puppet::Network::AuthStore.new
+        File.readlines(file).each do |line|
+            next if line =~ /^\s*#/
+            next if line =~ /^\s*$/
+            auth.allow(line.chomp)
         end
-        applier = Interface.new(method, options[:to])
 
-        applier.apply(self)
+        auth
     end
 
     # Retrieve (or create, if necessary) the certificate revocation list.
     def crl
         unless defined?(@crl)
-            # The crl is disabled.
-            if [&quot;false&quot;, false].include?(Puppet[:cacrl])
-                @crl = nil
-                return @crl
-            end
-
-            unless @crl = Puppet::SSL::CertificateRevocationList.find(&quot;whatever&quot;)
-                @crl = Puppet::SSL::CertificateRevocationList.new(&quot;whatever&quot;)
-                @crl.generate(host.certificate.content)
+            unless @crl = Puppet::SSL::CertificateRevocationList.find(&quot;ca&quot;)
+                @crl = Puppet::SSL::CertificateRevocationList.new(&quot;ca&quot;)
+                @crl.generate(host.certificate.content, host.key.content)
+                @crl.save
             end
         end
         @crl
@@ -183,6 +127,9 @@ class Puppet::SSL::CertificateAuthority
 
         # Create a self-signed certificate.
         @certificate = sign(host.name, :ca, request)
+
+        # And make sure we initialize our CRL.
+        crl()
     end
 
     def initialize
@@ -191,6 +138,8 @@ class Puppet::SSL::CertificateAuthority
         @name = Puppet[:certname]
 
         @host = Puppet::SSL::Host.new(Puppet::SSL::Host.ca_name)
+
+        setup()
     end
 
     # Retrieve (or create, if necessary) our inventory manager.
@@ -226,11 +175,17 @@ class Puppet::SSL::CertificateAuthority
     # file so this one is considered used.
     def next_serial
         serial = nil
+
+        # This is slightly odd.  If the file doesn't exist, our readwritelock creates
+        # it, but with a mode we can't actually read in some cases.  So, use
+        # a default before the lock.
+        unless FileTest.exist?(Puppet[:serial])
+            serial = 0x0
+        end
+
         Puppet.settings.readwritelock(:serial) { |f|
             if FileTest.exist?(Puppet[:serial])
-                serial = File.read(Puppet.settings[:serial]).chomp.hex
-            else
-                serial = 0x0
+                serial ||= File.read(Puppet.settings[:serial]).chomp.hex
             end
 
             # We store the next valid serial, not the one we just used.
@@ -266,6 +221,14 @@ class Puppet::SSL::CertificateAuthority
         crl.revoke(serial, host.key.content)
     end
 
+    # This initializes our CA so it actually works.  This should be a private
+    # method, except that you can't any-instance stub private methods, which is
+    # *awesome*.  This method only really exists to provide a stub-point during
+    # testing.
+    def setup
+        generate_ca_certificate unless @host.certificate
+    end
+
     # Sign a given certificate request.
     def sign(hostname, cert_type = :server, self_signing_csr = nil)
         # This is a self-signed certificate
@@ -273,8 +236,6 @@ class Puppet::SSL::CertificateAuthority
             csr = self_signing_csr
             issuer = csr.content
         else
-            generate_ca_certificate unless host.certificate
-
             unless csr = Puppet::SSL::CertificateRequest.find(hostname)
                 raise ArgumentError, &quot;Could not find certificate request for %s&quot; % hostname
             end</diff>
      <filename>lib/puppet/ssl/certificate_authority.rb</filename>
    </modified>
    <modified>
      <diff>@@ -115,7 +115,7 @@ class Puppet::SSL::CertificateFactory
         dnsnames = Puppet[:certdnsnames]
         name = @name.to_s.sub(%r{/CN=},'')
         if dnsnames != &quot;&quot;
-            dnsnames.split(':').each { |d| subject_alt_name &lt;&lt; 'DNS:' + d }
+            dnsnames.split(':').each { |d| @subject_alt_name &lt;&lt; 'DNS:' + d }
             @subject_alt_name &lt;&lt; 'DNS:' + name # Add the fqdn as an alias
         elsif name == Facter.value(:fqdn) # we're a CA server, and thus probably the server
             @subject_alt_name &lt;&lt; 'DNS:' + &quot;puppet&quot; # Add 'puppet' as an alias</diff>
      <filename>lib/puppet/ssl/certificate_factory.rb</filename>
    </modified>
    <modified>
      <diff>@@ -24,4 +24,13 @@ class Puppet::SSL::CertificateRequest &lt; Puppet::SSL::Base
 
         @content = csr
     end
+
+    def save
+        super()
+
+        # Try to autosign the CSR.
+        if ca = Puppet::SSL::CertificateAuthority.instance
+            ca.autosign
+        end
+    end
 end</diff>
      <filename>lib/puppet/ssl/certificate_request.rb</filename>
    </modified>
    <modified>
      <diff>@@ -9,12 +9,23 @@ class Puppet::SSL::CertificateRevocationList &lt; Puppet::SSL::Base
     indirects :certificate_revocation_list, :terminus_class =&gt; :file
 
     # Knows how to create a CRL with our system defaults.
-    def generate(cert)
+    def generate(cert, cakey)
         Puppet.info &quot;Creating a new certificate revocation list&quot;
         @content = wrapped_class.new
         @content.issuer = cert.subject
         @content.version = 1
 
+        # Init the CRL number.
+        crlNum = OpenSSL::ASN1::Integer(0)
+        @content.extensions = [OpenSSL::X509::Extension.new(&quot;crlNumber&quot;, crlNum)]
+
+        # Set last/next update
+        @content.last_update = Time.now
+        # Keep CRL valid for 5 years
+        @content.next_update = Time.now + 5 * 365*24*60*60
+
+        @content.sign(cakey, OpenSSL::Digest::SHA1.new)
+
         @content
     end
 </diff>
      <filename>lib/puppet/ssl/certificate_revocation_list.rb</filename>
    </modified>
    <modified>
      <diff>@@ -141,8 +141,21 @@ class Puppet::SSL::Host
         @certificate
     end
 
-    def initialize(name)
-        @name = name
+    # Generate all necessary parts of our ssl host.
+    def generate
+        generate_key unless key
+        generate_certificate_request unless certificate_request
+
+        # If we can get a CA instance, then we're a valid CA, and we
+        # should use it to sign our request; else, just try to read
+        # the cert.
+        if ! certificate() and ca = Puppet::SSL::CertificateAuthority.instance
+            ca.sign(self.name)
+        end
+    end
+
+    def initialize(name = nil)
+        @name = name || Puppet[:certname]
         @key = @certificate = @certificate_request = nil
         @ca = (name == self.class.ca_name)
     end
@@ -151,4 +164,22 @@ class Puppet::SSL::Host
     def public_key
         key.content.public_key
     end
+
+    # Create/return a store that uses our SSL info to validate
+    # connections.
+    def ssl_store(purpose = OpenSSL::X509::PURPOSE_ANY)
+        store = OpenSSL::X509::Store.new
+        store.purpose = purpose
+
+        store.add_file(Puppet[:localcacert])
+
+        # If there's a CRL, add it to our store.
+        if crl = Puppet::SSL::CertificateRevocationList.find(&quot;ca&quot;)
+            store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK
+            store.add_crl(crl.content)
+        end
+        return store
+    end
 end
+
+require 'puppet/ssl/certificate_authority'</diff>
      <filename>lib/puppet/ssl/host.rb</filename>
    </modified>
    <modified>
      <diff>@@ -796,7 +796,6 @@ module Puppet
         # a wrapper method to make sure the file exists before doing anything
         def retrieve
             unless stat = self.stat(true)
-                self.debug &quot;File does not exist&quot;
                 # If the file doesn't exist but we have a source, then call
                 # retrieve on that property
 </diff>
      <filename>lib/puppet/type/file.rb</filename>
    </modified>
    <modified>
      <diff>@@ -141,7 +141,9 @@ module Puppet
 
         newproperty(:dump) do
             desc &quot;Whether to dump the mount.  Not all platforms
-                support this.&quot;
+                support this. Valid values are ``1`` or ``0``. Default is ``0``.&quot;
+
+             newvalue(%r{(0|1)}) { }
 
             defaultto {
                 if @resource.managed?</diff>
      <filename>lib/puppet/type/mount.rb</filename>
    </modified>
    <modified>
      <diff>@@ -39,6 +39,8 @@ class Puppet::Util::Settings
             end
             @values[:memory][param] = value
             @cache.clear
+
+            clearused
         end
 
         return value
@@ -121,7 +123,7 @@ class Puppet::Util::Settings
             if pval = self.value(varname)
                 pval
             else
-                raise Puppet::DevError, &quot;Could not find value for %s&quot; % parent
+                raise Puppet::DevError, &quot;Could not find value for %s&quot; % value
             end
         end
 
@@ -574,7 +576,7 @@ Generated on #{Time.now}.
                 catalog = bucket.to_catalog
             rescue =&gt; detail
                 puts detail.backtrace if Puppet[:trace]
-                Puppet.err &quot;Could not create resources for managing Puppet's files and directories: %s&quot; % detail
+                Puppet.err &quot;Could not create resources for managing Puppet's files and directories in sections %s: %s&quot; % [sections.inspect, detail]
 
                 # We need some way to get rid of any resources created during the catalog creation
                 # but not cleaned up.
@@ -585,7 +587,12 @@ Generated on #{Time.now}.
                 catalog.host_config = false
                 catalog.apply do |transaction|
                     if failures = transaction.any_failed?
-                        raise &quot;Could not configure for running; got %s failure(s)&quot; % failures
+                        # LAK:NOTE We should do something like this for some cases,
+                        # since it can otherwise be hard to know what failed.
+                        #transaction.report.logs.find_all { |log| log.level == :err }.each do |log|
+                        #    puts log.message
+                        #end
+                        raise &quot;Could not configure myself; got %s failure(s)&quot; % failures
                     end
                 end
             end
@@ -692,13 +699,19 @@ Generated on #{Time.now}.
                             [file]
                     end
 
-                    writesub(default, tmpfile, *args, &amp;bloc)
+                    # If there's a failure, remove our tmpfile
+                    begin
+                        writesub(default, tmpfile, *args, &amp;bloc)
+                    rescue
+                        File.unlink(tmpfile) if FileTest.exist?(tmpfile)
+                        raise
+                    end
 
                     begin
                         File.rename(tmpfile, file)
                     rescue =&gt; detail
-                        Puppet.err &quot;Could not rename %s to %s: %s&quot; %
-                            [file, tmpfile, detail]
+                        Puppet.err &quot;Could not rename %s to %s: %s&quot; % [file, tmpfile, detail]
+                        File.unlink(tmpfile) if FileTest.exist?(tmpfile)
                     end
                 end
             end</diff>
      <filename>lib/puppet/util/settings.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,6 +6,10 @@ class Puppet::Util::Storage
     include Singleton
     include Puppet::Util
 
+    def self.state
+        return @@state
+    end
+
     def initialize
         self.class.load
     end</diff>
      <filename>lib/puppet/util/storage.rb</filename>
    </modified>
    <modified>
      <diff>@@ -112,5 +112,5 @@ Copyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public
 License
 
 
-.\&quot; Generated by docutils manpage writer on 2008-03-22 17:46.
+.\&quot; Generated by docutils manpage writer on 2008-05-05 09:33.
 .\&quot; </diff>
      <filename>man/man8/filebucket.8</filename>
    </modified>
    <modified>
      <diff>@@ -30,5 +30,5 @@ Only list parameters without detail
 Include metaparams
 
 
-.\&quot; Generated by docutils manpage writer on 2008-03-22 17:46.
+.\&quot; Generated by docutils manpage writer on 2008-05-05 09:33.
 .\&quot; </diff>
      <filename>man/man8/pi.8</filename>
    </modified>
    <modified>
      <diff>@@ -73,5 +73,5 @@ Copyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public
 License
 
 
-.\&quot; Generated by docutils manpage writer on 2008-03-22 17:46.
+.\&quot; Generated by docutils manpage writer on 2008-05-05 09:33.
 .\&quot; </diff>
      <filename>man/man8/puppet.8</filename>
    </modified>
    <modified>
      <diff>@@ -4,7 +4,7 @@ Configuration Reference \-
 
 .\&quot; Man page generated from reStructeredText.
 This page is autogenerated; any changes will get overwritten 
-.I (last generated on Sat Mar 22 17:46:15 +1100 2008)
+.I (last generated on Mon May 05 09:33:01 +1000 2008)
 
 
 
@@ -691,7 +691,7 @@ puppetmasterd
 
 .TP 2
 \(bu
-Default: development
+Default: production
 
 
 .SS environments
@@ -1739,9 +1739,9 @@ Default: $vardir/yaml
 .ce 0
 .sp
 
-.I This page autogenerated on Sat Mar 22 17:46:15 +1100 2008
+.I This page autogenerated on Mon May 05 09:33:01 +1000 2008
 
 
 
-.\&quot; Generated by docutils manpage writer on 2008-03-22 17:46.
+.\&quot; Generated by docutils manpage writer on 2008-05-05 09:33.
 .\&quot; </diff>
      <filename>man/man8/puppet.conf.8</filename>
    </modified>
    <modified>
      <diff>@@ -42,8 +42,8 @@ configuration options can also be generated by running puppetca with
 
 
 .TP
-.B all:      Operate on all outstanding requests. Only makes sense with
-\'\-\-sign\', or \'\-\-list\'.
+.B all:      Operate on all items. Currently only makes sense with
+\'\-\-sign\', \'\-\-clean\', or \'\-\-list\'.
 
 
 .TP
@@ -51,7 +51,9 @@ configuration options can also be generated by running puppetca with
 This is useful when rebuilding hosts, since new certificate
 signing requests will only be honored if puppetca does not
 have a copy of a signed certificate for that host. The
-certificate of the host remains valid.
+certificate of the host remains valid. If \'\-\-all\' is specified
+then all host certificates, both signed and unsigned, will be
+removed.
 
 debug:    Enable full debugging.
 
@@ -112,5 +114,5 @@ Copyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public
 License
 
 
-.\&quot; Generated by docutils manpage writer on 2008-03-22 17:46.
+.\&quot; Generated by docutils manpage writer on 2008-05-05 09:33.
 .\&quot; </diff>
      <filename>man/man8/puppetca.8</filename>
    </modified>
    <modified>
      <diff>@@ -180,5 +180,5 @@ Copyright (c) 2005, 2006 Reductive Labs, LLC Licensed under the GNU
 Public License
 
 
-.\&quot; Generated by docutils manpage writer on 2008-03-22 17:46.
+.\&quot; Generated by docutils manpage writer on 2008-05-05 09:33.
 .\&quot; </diff>
      <filename>man/man8/puppetd.8</filename>
    </modified>
    <modified>
      <diff>@@ -58,5 +58,5 @@ Copyright (c) 2005\-2007 Reductive Labs, LLC Licensed under the GNU
 Public License
 
 
-.\&quot; Generated by docutils manpage writer on 2008-03-22 17:46.
+.\&quot; Generated by docutils manpage writer on 2008-05-05 09:33.
 .\&quot; </diff>
      <filename>man/man8/puppetdoc.8</filename>
    </modified>
    <modified>
      <diff>@@ -83,5 +83,5 @@ Copyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public
 License
 
 
-.\&quot; Generated by docutils manpage writer on 2008-03-22 17:46.
+.\&quot; Generated by docutils manpage writer on 2008-05-05 09:33.
 .\&quot; </diff>
      <filename>man/man8/puppetmasterd.8</filename>
    </modified>
    <modified>
      <diff>@@ -147,5 +147,5 @@ Copyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public
 License
 
 
-.\&quot; Generated by docutils manpage writer on 2008-03-22 17:46.
+.\&quot; Generated by docutils manpage writer on 2008-05-05 09:33.
 .\&quot; </diff>
      <filename>man/man8/puppetrun.8</filename>
    </modified>
    <modified>
      <diff>@@ -111,29 +111,16 @@ luke
 
 .nf
 $ ralsh user luke
-.fi
-
-.\&quot; visit_block_quote
-
-.TP
-.B user { \'luke\':
-home =&gt; \'/home/luke\',
-uid =&gt; \'100\',
-ensure =&gt; \'present\',
-comment =&gt; \'Luke Kanies,,,\',
-gid =&gt; \'1000\',
-shell =&gt; \'/bin/bash\',
-groups =&gt; [\'sysadmin\',\'audio\',\'video\',\'puppet\']
-
-\.SH system-message
-System Message: WARNING/2 (./ralsh.rst:, line 87)
-Definition list ends without a blank line; unexpected unindent.
-
-
+user { \'luke\':
+  home =&gt; \'/home/luke\',
+  uid =&gt; \'100\',
+  ensure =&gt; \'present\',
+  comment =&gt; \'Luke Kanies,,,\',
+  gid =&gt; \'1000\',
+  shell =&gt; \'/bin/bash\',
+  groups =&gt; [\'sysadmin\',\'audio\',\'video\',\'puppet\']
 }
-
-
-.\&quot; depart_block_quote
+.fi
 
 .SH AUTHOR
 Luke Kanies
@@ -144,5 +131,5 @@ Copyright (c) 2005\-2007 Reductive Labs, LLC Licensed under the GNU
 Public License
 
 
-.\&quot; Generated by docutils manpage writer on 2008-03-22 17:46.
+.\&quot; Generated by docutils manpage writer on 2008-05-05 09:33.
 .\&quot; </diff>
      <filename>man/man8/ralsh.8</filename>
    </modified>
    <modified>
      <diff>@@ -10,7 +10,7 @@ require 'puppet/file_serving/configuration'
 describe Puppet::FileServing::Configuration, &quot; when finding files with Puppet::FileServing::Mount&quot; do
     before do
         # Just in case it already exists.
-        Puppet::FileServing::Configuration.clear_cache
+        Puppet::Util::Cacher.invalidate
 
         @mount = Puppet::FileServing::Mount.new(&quot;mymount&quot;)
         FileTest.stubs(:exists?).with(&quot;/my/path&quot;).returns(true)
@@ -38,6 +38,6 @@ describe Puppet::FileServing::Configuration, &quot; when finding files with Puppet::F
     end
 
     after do
-        Puppet::FileServing::Configuration.clear_cache
+        Puppet::Util::Cacher.invalidate
     end
 end</diff>
      <filename>spec/integration/file_serving/configuration.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,3 +1,5 @@
+#!/usr/bin/env ruby
+
 require File.dirname(__FILE__) + '/../../spec_helper'
 require 'puppet/network/server'
 require 'puppet/indirector'
@@ -5,460 +7,476 @@ require 'puppet/indirector/rest'
 
 # a fake class that will be indirected via REST
 class Puppet::TestIndirectedFoo
-  extend Puppet::Indirector  
-  indirects :test_indirected_foo, :terminus_setting =&gt; :test_indirected_foo_terminus
-  
-  attr_reader :value
-  
-  def initialize(value = 0)
-    @value = value
-  end
-  
-  def self.from_yaml(yaml)
-    YAML.load(yaml)
-  end
-  
-  def name
-    &quot;bob&quot;
-  end
+    extend Puppet::Indirector    
+    indirects :test_indirected_foo, :terminus_setting =&gt; :test_indirected_foo_terminus
+    
+    attr_reader :value
+    
+    def initialize(value = 0)
+        @value = value
+    end
+    
+    def self.from_yaml(yaml)
+        YAML.load(yaml)
+    end
+    
+    def name
+        &quot;bob&quot;
+    end
 end
 
 # empty Terminus class -- this would normally have to be in a directory findable by the autoloader, but we short-circuit that below
 class Puppet::TestIndirectedFoo::Rest &lt; Puppet::Indirector::REST
 end
 
+# This way the retrieval of the class by name works.
+Puppet::Indirector::Terminus.register_terminus_class(Puppet::TestIndirectedFoo::Rest)
 
 describe Puppet::Indirector::REST do
-  describe &quot;when using webrick&quot; do
-    before :each do
-      Puppet[:servertype] = 'webrick'
-      @params = { :address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 34343, :handlers =&gt; [ :test_indirected_foo ] }
-      @server = Puppet::Network::Server.new(@params)
-      
-      # LAK:NOTE For now, stub out the certificate setup.  This will need to be undone when the client side expects
-      # to speak ssl, also.
-      Puppet::Network::HTTP::WEBrick.any_instance.stubs(:setup_ssl).returns({})
+    before do
+        Puppet[:masterport] = 34343
+        Puppet[:server] = &quot;localhost&quot;
+
+        # Get a safe temporary file
+        @tmpfile = Tempfile.new(&quot;webrick_integration_testing&quot;)
+        @dir = @tmpfile.path + &quot;_dir&quot;
 
-      @server.listen
+        Puppet.settings[:confdir] = @dir
+        Puppet.settings[:vardir] = @dir
+        Puppet.settings[:http_enable_post_connection_check] = false
 
-      Puppet::Indirector::Terminus.stubs(:terminus_class).returns(Puppet::TestIndirectedFoo::Rest)
-      Puppet::TestIndirectedFoo.indirection.stubs(:terminus_class).returns :rest
+        Puppet::SSL::Host.ca_location = :local
 
-      # Stub the connection information.
-      Puppet::TestIndirectedFoo.indirection.terminus(:rest).stubs(:rest_connection_details).returns(:host =&gt; &quot;localhost&quot;, :port =&gt; 34343)
+        Puppet::TestIndirectedFoo.terminus_class = :rest
+        Puppet::TestIndirectedFoo.indirection.terminus.stubs(:rest_connection_details).returns(:host =&gt; &quot;127.0.0.1&quot;, :port =&gt; &quot;34343&quot;)
     end
-  
-    describe &quot;when finding a model instance over REST&quot; do
-      describe &quot;when a matching model instance can be found&quot; do
-        before :each do
-          @model_instance = Puppet::TestIndirectedFoo.new(23)
-          @mock_model = stub('faked model', :find =&gt; @model_instance)
-          Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:model).returns(@mock_model)        
-        end
-      
-        it &quot;should not fail&quot; do
-          Puppet::TestIndirectedFoo.find('bar')
-          lambda { Puppet::TestIndirectedFoo.find('bar') }.should_not raise_error
-        end
-  
-        it 'should return an instance of the model class' do
-          Puppet::TestIndirectedFoo.find('bar').class.should == Puppet::TestIndirectedFoo
-        end
-  
-        it 'should return the instance of the model class associated with the provided lookup key' do
-          Puppet::TestIndirectedFoo.find('bar').value.should == @model_instance.value
-        end
-  
-        it 'should set an expiration on model instance' do
-          Puppet::TestIndirectedFoo.find('bar').expiration.should_not be_nil
-        end
-      end
-    
-      describe &quot;when no matching model instance can be found&quot; do
-        before :each do
-          @mock_model = stub('faked model', :find =&gt; nil)
-          Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:model).returns(@mock_model)
-        end
-      
-        it &quot;should return nil&quot; do
-          Puppet::TestIndirectedFoo.find('bar').should be_nil
-        end
-      end
-    
-      describe &quot;when an exception is encountered in looking up a model instance&quot; do
-        before :each do
-          @mock_model = stub('faked model')
-          @mock_model.stubs(:find).raises(RuntimeError)
-          Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:model).returns(@mock_model)        
-        end
-      
-        it &quot;should raise an exception&quot; do
-          lambda { Puppet::TestIndirectedFoo.find('bar') }.should raise_error(RuntimeError) 
-        end
-      end
+
+    after do
+        Puppet::Network::HttpPool.instance_variable_set(&quot;@ssl_host&quot;, nil)
     end
 
-    describe &quot;when searching for model instances over REST&quot; do
-      describe &quot;when matching model instances can be found&quot; do
+    describe &quot;when using webrick&quot; do
         before :each do
-          @model_instances = [ Puppet::TestIndirectedFoo.new(23), Puppet::TestIndirectedFoo.new(24) ]
-          @mock_model = stub('faked model', :search =&gt; @model_instances)
-          Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:model).returns(@mock_model)        
-        end
-      
-        it &quot;should not fail&quot; do
-          lambda { Puppet::TestIndirectedFoo.search('bar') }.should_not raise_error
-        end
-  
-        it 'should return all matching results' do
-          Puppet::TestIndirectedFoo.search('bar').length.should == @model_instances.length
-        end
-  
-        it 'should return model instances' do
-          Puppet::TestIndirectedFoo.search('bar').each do |result| 
-            result.class.should == Puppet::TestIndirectedFoo
-          end
+            Puppet::Util::Cacher.invalidate
+
+            Puppet[:servertype] = 'webrick'
+            Puppet[:server] = '127.0.0.1'
+            Puppet[:certname] = '127.0.0.1'
+
+            ca = Puppet::SSL::CertificateAuthority.new
+            ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
+            
+            @params = { :address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 34343, :handlers =&gt; [ :test_indirected_foo ], :xmlrpc_handlers =&gt; [ :status ] }
+            @server = Puppet::Network::Server.new(@params)
+            @server.listen
         end
-  
-        it 'should return the instance of the model class associated with the provided lookup key' do
-          Puppet::TestIndirectedFoo.search('bar').collect(&amp;:value).should == @model_instances.collect(&amp;:value)
+
+        after do
+            @server.unlisten
+            @tmpfile.delete
+            Puppet.settings.clear
+            Puppet::Util::Cacher.invalidate
         end
-  
-        it 'should set a version timestamp on model instances' do
-          pending(&quot;Luke looking at why this version magic might not be working&quot;) do
-            Puppet::TestIndirectedFoo.search('bar').each do |result|
-              result.version.should_not be_nil
+    
+        describe &quot;when finding a model instance over REST&quot; do
+            describe &quot;when a matching model instance can be found&quot; do
+                before :each do
+                    @model_instance = Puppet::TestIndirectedFoo.new(23)
+                    @mock_model = stub('faked model', :find =&gt; @model_instance)
+                    Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:model).returns(@mock_model)                
+                end
+            
+                it &quot;should not fail&quot; do
+                    Puppet::TestIndirectedFoo.find('bar')
+                    lambda { Puppet::TestIndirectedFoo.find('bar') }.should_not raise_error
+                end
+    
+                it 'should return an instance of the model class' do
+                    Puppet::TestIndirectedFoo.find('bar').class.should == Puppet::TestIndirectedFoo
+                end
+    
+                it 'should return the instance of the model class associated with the provided lookup key' do
+                    Puppet::TestIndirectedFoo.find('bar').value.should == @model_instance.value
+                end
+    
+                it 'should set an expiration on model instance' do
+                    Puppet::TestIndirectedFoo.find('bar').expiration.should_not be_nil
+                end
+            end
+        
+            describe &quot;when no matching model instance can be found&quot; do
+                before :each do
+                    @mock_model = stub('faked model', :find =&gt; nil)
+                    Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:model).returns(@mock_model)
+                end
+            
+                it &quot;should return nil&quot; do
+                    Puppet::TestIndirectedFoo.find('bar').should be_nil
+                end
+            end
+        
+            describe &quot;when an exception is encountered in looking up a model instance&quot; do
+                before :each do
+                    @mock_model = stub('faked model')
+                    @mock_model.stubs(:find).raises(RuntimeError)
+                    Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:model).returns(@mock_model)                
+                end
+            
+                it &quot;should raise an exception&quot; do
+                    lambda { Puppet::TestIndirectedFoo.find('bar') }.should raise_error(RuntimeError) 
+                end
             end
-          end
         end
-      end
+
+        describe &quot;when searching for model instances over REST&quot; do
+            describe &quot;when matching model instances can be found&quot; do
+                before :each do
+                    @model_instances = [ Puppet::TestIndirectedFoo.new(23), Puppet::TestIndirectedFoo.new(24) ]
+                    @mock_model = stub('faked model', :search =&gt; @model_instances)
+                    Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:model).returns(@mock_model)                
+                end
+            
+                it &quot;should not fail&quot; do
+                    lambda { Puppet::TestIndirectedFoo.search('bar') }.should_not raise_error
+                end
     
-      describe &quot;when no matching model instance can be found&quot; do
-        before :each do
-          @mock_model = stub('faked model', :find =&gt; nil)
-          Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:model).returns(@mock_model)
-        end
-      
-        it &quot;should return nil&quot; do
-          Puppet::TestIndirectedFoo.find('bar').should be_nil
-        end
-      end
+                it 'should return all matching results' do
+                    Puppet::TestIndirectedFoo.search('bar').length.should == @model_instances.length
+                end
     
-      describe &quot;when an exception is encountered in looking up a model instance&quot; do
-        before :each do
-          @mock_model = stub('faked model')
-          @mock_model.stubs(:find).raises(RuntimeError)
-          Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:model).returns(@mock_model)        
-        end
-      
-        it &quot;should raise an exception&quot; do
-          lambda { Puppet::TestIndirectedFoo.find('bar') }.should raise_error(RuntimeError) 
+                it 'should return model instances' do
+                    Puppet::TestIndirectedFoo.search('bar').each do |result| 
+                        result.class.should == Puppet::TestIndirectedFoo
+                    end
+                end
+    
+                it 'should return the instance of the model class associated with the provided lookup key' do
+                    Puppet::TestIndirectedFoo.search('bar').collect(&amp;:value).should == @model_instances.collect(&amp;:value)
+                end
+            end
+        
+            describe &quot;when no matching model instance can be found&quot; do
+                before :each do
+                    @mock_model = stub('faked model', :find =&gt; nil)
+                    Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:model).returns(@mock_model)
+                end
+            
+                it &quot;should return nil&quot; do
+                    Puppet::TestIndirectedFoo.find('bar').should be_nil
+                end
+            end
+        
+            describe &quot;when an exception is encountered in looking up a model instance&quot; do
+                before :each do
+                    @mock_model = stub('faked model')
+                    @mock_model.stubs(:find).raises(RuntimeError)
+                    Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:model).returns(@mock_model)                
+                end
+            
+                it &quot;should raise an exception&quot; do
+                    lambda { Puppet::TestIndirectedFoo.find('bar') }.should raise_error(RuntimeError) 
+                end
+            end
         end
-      end
-    end
 
-    describe &quot;when destroying a model instance over REST&quot; do
-      describe &quot;when a matching model instance can be found&quot; do
-        before :each do
-          @mock_model = stub('faked model', :destroy =&gt; true)
-          Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:model).returns(@mock_model)        
-        end
-      
-        it &quot;should not fail&quot; do
-          lambda { Puppet::TestIndirectedFoo.destroy('bar') }.should_not raise_error
-        end
-  
-        it 'should return success' do
-          Puppet::TestIndirectedFoo.destroy('bar').should == true
-        end
-      end
+        describe &quot;when destroying a model instance over REST&quot; do
+            describe &quot;when a matching model instance can be found&quot; do
+                before :each do
+                    @mock_model = stub('faked model', :destroy =&gt; true)
+                    Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:model).returns(@mock_model)                
+                end
+            
+                it &quot;should not fail&quot; do
+                    lambda { Puppet::TestIndirectedFoo.destroy('bar') }.should_not raise_error
+                end
     
-      describe &quot;when no matching model instance can be found&quot; do
-        before :each do
-          @mock_model = stub('faked model', :destroy =&gt; false)
-          Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:model).returns(@mock_model)
-        end
-      
-        it &quot;should return failure&quot; do
-          Puppet::TestIndirectedFoo.destroy('bar').should == false
+                it 'should return success' do
+                    Puppet::TestIndirectedFoo.destroy('bar').should == true
+                end
+            end
+        
+            describe &quot;when no matching model instance can be found&quot; do
+                before :each do
+                    @mock_model = stub('faked model', :destroy =&gt; false)
+                    Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:model).returns(@mock_model)
+                end
+            
+                it &quot;should return failure&quot; do
+                    Puppet::TestIndirectedFoo.destroy('bar').should == false
+                end
+            end
+        
+            describe &quot;when an exception is encountered in destroying a model instance&quot; do
+                before :each do
+                    @mock_model = stub('faked model')
+                    @mock_model.stubs(:destroy).raises(RuntimeError)
+                    Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:model).returns(@mock_model)                
+                end
+            
+                it &quot;should raise an exception&quot; do
+                    lambda { Puppet::TestIndirectedFoo.destroy('bar') }.should raise_error(RuntimeError) 
+                end
+            end
         end
-      end
+
+        describe &quot;when saving a model instance over REST&quot; do
+            before :each do
+                @instance = Puppet::TestIndirectedFoo.new(42)
+                @mock_model = stub('faked model', :from_yaml =&gt; @instance)
+                Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:model).returns(@mock_model)                
+                Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:save_object).returns(@instance)                
+            end
+            
+            describe &quot;when a successful save can be performed&quot; do
+                before :each do
+                end
+            
+                it &quot;should not fail&quot; do
+                    lambda { @instance.save }.should_not raise_error
+                end
     
-      describe &quot;when an exception is encountered in destroying a model instance&quot; do
-        before :each do
-          @mock_model = stub('faked model')
-          @mock_model.stubs(:destroy).raises(RuntimeError)
-          Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:model).returns(@mock_model)        
-        end
-      
-        it &quot;should raise an exception&quot; do
-          lambda { Puppet::TestIndirectedFoo.destroy('bar') }.should raise_error(RuntimeError) 
+                it 'should return an instance of the model class' do
+                    @instance.save.class.should == Puppet::TestIndirectedFoo
+                end
+                 
+                it 'should return a matching instance of the model class' do
+                    @instance.save.value.should == @instance.value
+                end
+            end
+                    
+            describe &quot;when a save cannot be completed&quot; do
+                before :each do
+                    Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:save_object).returns(false)
+                end
+                            
+                it &quot;should return failure&quot; do
+                    @instance.save.should == false
+                end
+            end
+                    
+            describe &quot;when an exception is encountered in performing a save&quot; do
+                before :each do
+                    Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:save_object).raises(RuntimeError)             
+                end
+            
+                it &quot;should raise an exception&quot; do
+                    lambda { @instance.save }.should raise_error(RuntimeError) 
+                end
+            end
         end
-      end
     end
 
-    describe &quot;when saving a model instance over REST&quot; do
-      before :each do
-        @instance = Puppet::TestIndirectedFoo.new(42)
-        @mock_model = stub('faked model', :from_yaml =&gt; @instance)
-        Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:model).returns(@mock_model)        
-        Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:save_object).returns(@instance)        
-      end
-      
-      describe &quot;when a successful save can be performed&quot; do
+    describe &quot;when using mongrel&quot; do
+        confine &quot;Mongrel is not available&quot; =&gt; Puppet.features.mongrel?
+        
         before :each do
-        end
-      
-        it &quot;should not fail&quot; do
-          lambda { @instance.save }.should_not raise_error
-        end
-  
-        it 'should return an instance of the model class' do
-          @instance.save.class.should == Puppet::TestIndirectedFoo
-        end
-         
-        it 'should return a matching instance of the model class' do
-          @instance.save.value.should == @instance.value
-        end
-      end
-          
-      describe &quot;when a save cannot be completed&quot; do
-        before :each do
-          Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:save_object).returns(false)
-        end
-              
-        it &quot;should return failure&quot; do
-          @instance.save.should == false
-        end
-      end
-          
-      describe &quot;when an exception is encountered in performing a save&quot; do
-        before :each do
-          Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:save_object).raises(RuntimeError)       
-        end
-      
-        it &quot;should raise an exception&quot; do
-          lambda { @instance.save }.should raise_error(RuntimeError) 
-        end
-      end
-    end
+            Puppet[:servertype] = 'mongrel'
+            @params = { :address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 34343, :handlers =&gt; [ :test_indirected_foo ] }
 
-    after :each do
-      @server.unlisten
-    end
-  end
-
-  describe &quot;when using mongrel&quot; do
-    confine &quot;Mongrel is not available&quot; =&gt; Puppet.features.mongrel?
-    
-    before :each do
-      Puppet[:servertype] = 'mongrel'
-      @params = { :address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 34343, :handlers =&gt; [ :test_indirected_foo ] }
-      @server = Puppet::Network::Server.new(@params)
-      @server.listen
+            # Make sure we never get a cert, since mongrel can't speak ssl
+            Puppet::SSL::Certificate.stubs(:find).returns nil
 
-      # the autoloader was clearly not written test-first.  We subvert the integration test to get around its bullshit.
-      Puppet::Indirector::Terminus.stubs(:terminus_class).returns(Puppet::TestIndirectedFoo::Rest)
-      Puppet::TestIndirectedFoo.indirection.stubs(:terminus_class).returns :rest
+            # We stub ssl to be off, since mongrel can't speak ssl
+            Net::HTTP.any_instance.stubs(:use_ssl?).returns false
 
-      # Stub the connection information.
-      Puppet::TestIndirectedFoo.indirection.terminus(:rest).stubs(:rest_connection_details).returns(:host =&gt; &quot;localhost&quot;, :port =&gt; 34343)
-    end
-  
-    describe &quot;when finding a model instance over REST&quot; do
-      describe &quot;when a matching model instance can be found&quot; do
-        before :each do
-          @model_instance = Puppet::TestIndirectedFoo.new(23)
-          @mock_model = stub('faked model', :find =&gt; @model_instance)
-          Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:model).returns(@mock_model)        
-        end
-      
-        it &quot;should not fail&quot; do
-          lambda { Puppet::TestIndirectedFoo.find('bar') }.should_not raise_error
-        end
-  
-        it 'should return an instance of the model class' do
-          Puppet::TestIndirectedFoo.find('bar').class.should == Puppet::TestIndirectedFoo
+            @server = Puppet::Network::Server.new(@params)
+            @server.listen
         end
-  
-        it 'should return the instance of the model class associated with the provided lookup key' do
-          Puppet::TestIndirectedFoo.find('bar').value.should == @model_instance.value
-        end
-  
-        it 'should set an expiration on model instance' do
-          Puppet::TestIndirectedFoo.find('bar').expiration.should_not be_nil
+
+        after :each do
+            @server.unlisten
         end
-      end
     
-      describe &quot;when no matching model instance can be found&quot; do
-        before :each do
-          @mock_model = stub('faked model', :find =&gt; nil)
-          Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:model).returns(@mock_model)
-        end
-      
-        it &quot;should return nil&quot; do
-          Puppet::TestIndirectedFoo.find('bar').should be_nil
-        end
-      end
+        describe &quot;when finding a model instance over REST&quot; do
+            describe &quot;when a matching model instance can be found&quot; do
+                before :each do
+                    @model_instance = Puppet::TestIndirectedFoo.new(23)
+                    @mock_model = stub('faked model', :find =&gt; @model_instance)
+                    Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:model).returns(@mock_model)                
+                end
+            
+                it &quot;should not fail&quot; do
+                    lambda { Puppet::TestIndirectedFoo.find('bar') }.should_not raise_error
+                end
     
-      describe &quot;when an exception is encountered in looking up a model instance&quot; do
-        before :each do
-          @mock_model = stub('faked model')
-          @mock_model.stubs(:find).raises(RuntimeError)
-          Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:model).returns(@mock_model)        
-        end
-      
-        it &quot;should raise an exception&quot; do
-          lambda { Puppet::TestIndirectedFoo.find('bar') }.should raise_error(RuntimeError) 
-        end
-      end
-    end
-
-    describe &quot;when searching for model instances over REST&quot; do
-      describe &quot;when matching model instances can be found&quot; do
-        before :each do
-          @model_instances = [ Puppet::TestIndirectedFoo.new(23), Puppet::TestIndirectedFoo.new(24) ]
-          @mock_model = stub('faked model', :search =&gt; @model_instances)
-          Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:model).returns(@mock_model)        
-        end
-      
-        it &quot;should not fail&quot; do
-          lambda { Puppet::TestIndirectedFoo.search('bar') }.should_not raise_error
-        end
-  
-        it 'should return all matching results' do
-          Puppet::TestIndirectedFoo.search('bar').length.should == @model_instances.length
-        end
-  
-        it 'should return model instances' do
-          Puppet::TestIndirectedFoo.search('bar').each do |result| 
-            result.class.should == Puppet::TestIndirectedFoo
-          end
-        end
-  
-        it 'should return the instance of the model class associated with the provided lookup key' do
-          Puppet::TestIndirectedFoo.search('bar').collect(&amp;:value).should == @model_instances.collect(&amp;:value)
-        end
-  
-        it 'should set an expiration on model instances' do
-          Puppet::TestIndirectedFoo.search('bar').each do |result|
-            result.expiration.should_not be_nil
-          end
-        end
-      end
+                it 'should return an instance of the model class' do
+                    Puppet::TestIndirectedFoo.find('bar').class.should == Puppet::TestIndirectedFoo
+                end
     
-      describe &quot;when no matching model instance can be found&quot; do
-        before :each do
-          @mock_model = stub('faked model', :find =&gt; nil)
-          Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:model).returns(@mock_model)
-        end
-      
-        it &quot;should return nil&quot; do
-          Puppet::TestIndirectedFoo.find('bar').should be_nil
-        end
-      end
+                it 'should return the instance of the model class associated with the provided lookup key' do
+                    Puppet::TestIndirectedFoo.find('bar').value.should == @model_instance.value
+                end
     
-      describe &quot;when an exception is encountered in looking up a model instance&quot; do
-        before :each do
-          @mock_model = stub('faked model')
-          @mock_model.stubs(:find).raises(RuntimeError)
-          Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:model).returns(@mock_model)        
-        end
-      
-        it &quot;should raise an exception&quot; do
-          lambda { Puppet::TestIndirectedFoo.find('bar') }.should raise_error(RuntimeError) 
+                it 'should set an expiration on model instance' do
+                    Puppet::TestIndirectedFoo.find('bar').expiration.should_not be_nil
+                end
+            end
+        
+            describe &quot;when no matching model instance can be found&quot; do
+                before :each do
+                    @mock_model = stub('faked model', :find =&gt; nil)
+                    Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:model).returns(@mock_model)
+                end
+            
+                it &quot;should return nil&quot; do
+                    Puppet::TestIndirectedFoo.find('bar').should be_nil
+                end
+            end
+        
+            describe &quot;when an exception is encountered in looking up a model instance&quot; do
+                before :each do
+                    @mock_model = stub('faked model')
+                    @mock_model.stubs(:find).raises(RuntimeError)
+                    Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:model).returns(@mock_model)                
+                end
+            
+                it &quot;should raise an exception&quot; do
+                    lambda { Puppet::TestIndirectedFoo.find('bar') }.should raise_error(RuntimeError) 
+                end
+            end
         end
-      end
-    end
 
-    describe &quot;when destroying a model instance over REST&quot; do
-      describe &quot;when a matching model instance can be found&quot; do
-        before :each do
-          @mock_model = stub('faked model', :destroy =&gt; true)
-          Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:model).returns(@mock_model)        
-        end
-      
-        it &quot;should not fail&quot; do
-          lambda { Puppet::TestIndirectedFoo.destroy('bar') }.should_not raise_error
-        end
-  
-        it 'should return success' do
-          Puppet::TestIndirectedFoo.destroy('bar').should == true
-        end
-      end
+        describe &quot;when searching for model instances over REST&quot; do
+            describe &quot;when matching model instances can be found&quot; do
+                before :each do
+                    @model_instances = [ Puppet::TestIndirectedFoo.new(23), Puppet::TestIndirectedFoo.new(24) ]
+                    @mock_model = stub('faked model', :search =&gt; @model_instances)
+                    Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:model).returns(@mock_model)                
+                end
+            
+                it &quot;should not fail&quot; do
+                    lambda { Puppet::TestIndirectedFoo.search('bar') }.should_not raise_error
+                end
     
-      describe &quot;when no matching model instance can be found&quot; do
-        before :each do
-          @mock_model = stub('faked model', :destroy =&gt; false)
-          Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:model).returns(@mock_model)
-        end
-      
-        it &quot;should return failure&quot; do
-          Puppet::TestIndirectedFoo.destroy('bar').should == false
-        end
-      end
+                it 'should return all matching results' do
+                    Puppet::TestIndirectedFoo.search('bar').length.should == @model_instances.length
+                end
     
-      describe &quot;when an exception is encountered in destroying a model instance&quot; do
-        before :each do
-          @mock_model = stub('faked model')
-          @mock_model.stubs(:destroy).raises(RuntimeError)
-          Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:model).returns(@mock_model)        
-        end
-      
-        it &quot;should raise an exception&quot; do
-          lambda { Puppet::TestIndirectedFoo.destroy('bar') }.should raise_error(RuntimeError) 
+                it 'should return model instances' do
+                    Puppet::TestIndirectedFoo.search('bar').each do |result| 
+                        result.class.should == Puppet::TestIndirectedFoo
+                    end
+                end
+    
+                it 'should return the instance of the model class associated with the provided lookup key' do
+                    Puppet::TestIndirectedFoo.search('bar').collect(&amp;:value).should == @model_instances.collect(&amp;:value)
+                end
+    
+                it 'should set an expiration on model instances' do
+                    Puppet::TestIndirectedFoo.search('bar').each do |result|
+                        result.expiration.should_not be_nil
+                    end
+                end
+            end
+        
+            describe &quot;when no matching model instance can be found&quot; do
+                before :each do
+                    @mock_model = stub('faked model', :find =&gt; nil)
+                    Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:model).returns(@mock_model)
+                end
+            
+                it &quot;should return nil&quot; do
+                    Puppet::TestIndirectedFoo.find('bar').should be_nil
+                end
+            end
+        
+            describe &quot;when an exception is encountered in looking up a model instance&quot; do
+                before :each do
+                    @mock_model = stub('faked model')
+                    @mock_model.stubs(:find).raises(RuntimeError)
+                    Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:model).returns(@mock_model)                
+                end
+            
+                it &quot;should raise an exception&quot; do
+                    lambda { Puppet::TestIndirectedFoo.find('bar') }.should raise_error(RuntimeError) 
+                end
+            end
         end
-      end
-    end
 
-    describe &quot;when saving a model instance over REST&quot; do
-      before :each do
-        @instance = Puppet::TestIndirectedFoo.new(42)
-        @mock_model = stub('faked model', :from_yaml =&gt; @instance)
-        Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:model).returns(@mock_model)        
-        Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:save_object).returns(@instance)        
-      end
-      
-      describe &quot;when a successful save can be performed&quot; do
-        before :each do
-        end
-      
-        it &quot;should not fail&quot; do
-          lambda { @instance.save }.should_not raise_error
-        end
-  
-        it 'should return an instance of the model class' do
-          @instance.save.class.should == Puppet::TestIndirectedFoo
-        end
-         
-        it 'should return a matching instance of the model class' do
-          @instance.save.value.should == @instance.value
-        end
-      end
-          
-      describe &quot;when a save cannot be completed&quot; do
-        before :each do
-          Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:save_object).returns(false)
-        end
-              
-        it &quot;should return failure&quot; do
-          @instance.save.should == false
-        end
-      end
-          
-      describe &quot;when an exception is encountered in performing a save&quot; do
-        before :each do
-          Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:save_object).raises(RuntimeError)       
-        end
-      
-        it &quot;should raise an exception&quot; do
-          lambda { @instance.save }.should raise_error(RuntimeError) 
+        describe &quot;when destroying a model instance over REST&quot; do
+            describe &quot;when a matching model instance can be found&quot; do
+                before :each do
+                    @mock_model = stub('faked model', :destroy =&gt; true)
+                    Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:model).returns(@mock_model)                
+                end
+            
+                it &quot;should not fail&quot; do
+                    lambda { Puppet::TestIndirectedFoo.destroy('bar') }.should_not raise_error
+                end
+    
+                it 'should return success' do
+                    Puppet::TestIndirectedFoo.destroy('bar').should == true
+                end
+            end
+        
+            describe &quot;when no matching model instance can be found&quot; do
+                before :each do
+                    @mock_model = stub('faked model', :destroy =&gt; false)
+                    Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:model).returns(@mock_model)
+                end
+            
+                it &quot;should return failure&quot; do
+                    Puppet::TestIndirectedFoo.destroy('bar').should == false
+                end
+            end
+        
+            describe &quot;when an exception is encountered in destroying a model instance&quot; do
+                before :each do
+                    @mock_model = stub('faked model')
+                    @mock_model.stubs(:destroy).raises(RuntimeError)
+                    Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:model).returns(@mock_model)                
+                end
+            
+                it &quot;should raise an exception&quot; do
+                    lambda { Puppet::TestIndirectedFoo.destroy('bar') }.should raise_error(RuntimeError) 
+                end
+            end
         end
-      end
-    end
 
-    after :each do
-      @server.unlisten
+        describe &quot;when saving a model instance over REST&quot; do
+            before :each do
+                @instance = Puppet::TestIndirectedFoo.new(42)
+                @mock_model = stub('faked model', :from_yaml =&gt; @instance)
+                Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:model).returns(@mock_model)                
+                Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:save_object).returns(@instance)                
+            end
+            
+            describe &quot;when a successful save can be performed&quot; do
+                before :each do
+                end
+            
+                it &quot;should not fail&quot; do
+                    lambda { @instance.save }.should_not raise_error
+                end
+    
+                it 'should return an instance of the model class' do
+                    @instance.save.class.should == Puppet::TestIndirectedFoo
+                end
+                 
+                it 'should return a matching instance of the model class' do
+                    @instance.save.value.should == @instance.value
+                end
+            end
+                    
+            describe &quot;when a save cannot be completed&quot; do
+                before :each do
+                    Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:save_object).returns(false)
+                end
+                            
+                it &quot;should return failure&quot; do
+                    @instance.save.should == false
+                end
+            end
+                    
+            describe &quot;when an exception is encountered in performing a save&quot; do
+                before :each do
+                    Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:save_object).raises(RuntimeError)             
+                end
+            
+                it &quot;should raise an exception&quot; do
+                    lambda { @instance.save }.should raise_error(RuntimeError) 
+                end
+            end
+        end
     end
-  end
 end</diff>
      <filename>spec/integration/indirector/rest.rb</filename>
    </modified>
    <modified>
      <diff>@@ -8,7 +8,7 @@ describe Puppet::Network::Server do
     
     before :each do
       Puppet[:servertype] = 'mongrel'
-      @params = { :address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 34346, :handlers =&gt; [ :node ] }
+      @params = { :address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 34346, :handlers =&gt; [ :node ], :xmlrpc_handlers =&gt; [ :status ] }
       @server = Puppet::Network::Server.new(@params)      
     end
 </diff>
      <filename>spec/integration/network/server/mongrel.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,50 +1,70 @@
+#!/usr/bin/env ruby
+
 require File.dirname(__FILE__) + '/../../../spec_helper'
 require 'puppet/network/server'
+require 'puppet/ssl/certificate_authority'
 require 'socket'
 
 describe Puppet::Network::Server do
-  describe &quot;when using webrick&quot; do
-    before :each do
-      Puppet[:servertype] = 'webrick'
-      @params = { :address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 34343, :handlers =&gt; [ :node ] }
-
-      # LAK:NOTE (4/08) Stub the ssl support for now; we'll remove it once it's actually 
-      # functional.
-      Puppet::Network::HTTP::WEBrick.any_instance.stubs(:setup_ssl).returns({})
-    end
-    
-    describe &quot;before listening&quot; do
-      it &quot;should not be reachable at the specified address and port&quot; do
-        lambda { TCPSocket.new('127.0.0.1', 34343) }.should raise_error
-      end
-    end
-    
-    describe &quot;when listening&quot; do
-      it &quot;should be reachable on the specified address and port&quot; do
-        @server = Puppet::Network::Server.new(@params.merge(:port =&gt; 34343))      
-        @server.listen
-        lambda { TCPSocket.new('127.0.0.1', 34343) }.should_not raise_error      
-      end
-            
-      it &quot;should not allow multiple servers to listen on the same address and port&quot; do
-        @server = Puppet::Network::Server.new(@params.merge(:port =&gt; 34343))      
-        @server.listen
-        @server2 = Puppet::Network::Server.new(@params.merge(:port =&gt; 34343))
-        lambda { @server2.listen }.should raise_error
-      end
-      
-      after :each do
-        @server.unlisten if @server.listening?
-      end
-    end
-    
-    describe &quot;after unlistening&quot; do
-      it &quot;should not be reachable on the port and address assigned&quot; do
-        @server = Puppet::Network::Server.new(@params.merge(:port =&gt; 34343))      
-        @server.listen
-        @server.unlisten
-        lambda { TCPSocket.new('127.0.0.1', 34343) }.should raise_error(Errno::ECONNREFUSED)        
-      end
+    describe &quot;when using webrick&quot; do
+        before :each do
+            Puppet[:servertype] = 'webrick'
+            @params = { :address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 34343, :handlers =&gt; [ :node ], :xmlrpc_handlers =&gt; [ :status ] }
+
+            # Get a safe temporary file
+            @tmpfile = Tempfile.new(&quot;webrick_integration_testing&quot;)
+            @dir = @tmpfile.path + &quot;_dir&quot;
+
+            Puppet.settings[:confdir] = @dir
+            Puppet.settings[:vardir] = @dir
+
+            Puppet::SSL::Host.ca_location = :local
+
+            ca = Puppet::SSL::CertificateAuthority.new
+            ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname])
+        end
+
+        after do
+            @tmpfile.delete
+            Puppet.settings.clear
+
+            system(&quot;rm -rf %s&quot; % @dir)
+
+            Puppet::Util::Cacher.invalidate
+        end
+
+        describe &quot;before listening&quot; do
+            it &quot;should not be reachable at the specified address and port&quot; do
+                lambda { TCPSocket.new('127.0.0.1', 34343) }.should raise_error
+            end
+        end
+
+        describe &quot;when listening&quot; do
+            it &quot;should be reachable on the specified address and port&quot; do
+                @server = Puppet::Network::Server.new(@params.merge(:port =&gt; 34343))      
+                @server.listen
+                lambda { TCPSocket.new('127.0.0.1', 34343) }.should_not raise_error      
+            end
+
+            it &quot;should not allow multiple servers to listen on the same address and port&quot; do
+                @server = Puppet::Network::Server.new(@params.merge(:port =&gt; 34343))      
+                @server.listen
+                @server2 = Puppet::Network::Server.new(@params.merge(:port =&gt; 34343))
+                lambda { @server2.listen }.should raise_error
+            end
+
+            after :each do
+                @server.unlisten if @server.listening?
+            end
+        end
+
+        describe &quot;after unlistening&quot; do
+            it &quot;should not be reachable on the port and address assigned&quot; do
+                @server = Puppet::Network::Server.new(@params.merge(:port =&gt; 34343))      
+                @server.listen
+                @server.unlisten
+                lambda { TCPSocket.new('127.0.0.1', 34343) }.should raise_error(Errno::ECONNREFUSED)        
+            end
+        end
     end
-  end
 end</diff>
      <filename>spec/integration/network/server/webrick.rb</filename>
    </modified>
    <modified>
      <diff>@@ -7,7 +7,13 @@ require File.dirname(__FILE__) + '/../../spec_helper'
 
 describe Puppet::Node::Catalog do
     describe &quot;when using the indirector&quot; do
-        after { Puppet::Node::Catalog.indirection.clear_cache }
+        after { Puppet::Util::Cacher.invalidate }
+        before do
+            # This is so the tests work w/out networking.
+            Facter.stubs(:to_hash).returns({&quot;hostname&quot; =&gt; &quot;foo.domain.com&quot;})
+            Facter.stubs(:value).returns(&quot;eh&quot;)
+        end
+
 
         it &quot;should be able to delegate to the :yaml terminus&quot; do
             Puppet::Node::Catalog.indirection.stubs(:terminus_class).returns :yaml</diff>
      <filename>spec/integration/node/catalog.rb</filename>
    </modified>
    <modified>
      <diff>@@ -7,13 +7,15 @@ require File.dirname(__FILE__) + '/../../spec_helper'
 
 describe Puppet::Node::Facts do
     describe &quot;when using the indirector&quot; do
-        after { Puppet::Node::Facts.indirection.clear_cache }
+        after { Puppet::Util::Cacher.invalidate }
 
         it &quot;should expire any cached node instances when it is saved&quot; do
             Puppet::Node::Facts.indirection.stubs(:terminus_class).returns :yaml
+
+            Puppet::Node::Facts.indirection.terminus(:yaml).should equal(Puppet::Node::Facts.indirection.terminus(:yaml))
             terminus = Puppet::Node::Facts.indirection.terminus(:yaml)
+            terminus.stubs :save
 
-            terminus.expects(:save)
             Puppet::Node.expects(:expire).with(&quot;me&quot;)
 
             facts = Puppet::Node::Facts.new(&quot;me&quot;)</diff>
      <filename>spec/integration/node/facts.rb</filename>
    </modified>
    <modified>
      <diff>@@ -11,7 +11,7 @@ require 'tempfile'
 describe Puppet::SSL::CertificateAuthority do
     before do
         # Get a safe temporary file
-        file = Tempfile.new(&quot;host_integration_testing&quot;)
+        file = Tempfile.new(&quot;ca_integration_testing&quot;)
         @dir = file.path
         file.delete
 
@@ -28,10 +28,9 @@ describe Puppet::SSL::CertificateAuthority do
         system(&quot;rm -rf %s&quot; % @dir)
         Puppet.settings.clear
 
-        # This is necessary so the terminus instances don't lie around.
-        Puppet::SSL::Key.indirection.clear_cache
-        Puppet::SSL::Certificate.indirection.clear_cache
-        Puppet::SSL::CertificateRequest.indirection.clear_cache
+        Puppet::Util::Cacher.invalidate
+
+        Puppet::SSL::CertificateAuthority.instance_variable_set(&quot;@instance&quot;, nil)
     }
 
     it &quot;should create a CA host&quot; do
@@ -60,6 +59,20 @@ describe Puppet::SSL::CertificateAuthority do
         end
     end
 
+    it &quot;should have a CRL&quot; do
+        @ca.generate_ca_certificate
+        @ca.crl.should_not be_nil
+    end
+
+    it &quot;should be able to read in a previously created CRL&quot; do
+        @ca.generate_ca_certificate
+
+        # Create it to start with.
+        @ca.crl
+
+        Puppet::SSL::CertificateAuthority.new.crl.should_not be_nil
+    end
+
     describe &quot;when signing certificates&quot; do
         before do
             @host = Puppet::SSL::Host.new(&quot;luke.madstop.com&quot;)</diff>
      <filename>spec/integration/ssl/certificate_authority.rb</filename>
    </modified>
    <modified>
      <diff>@@ -8,13 +8,15 @@ require File.dirname(__FILE__) + '/../../spec_helper'
 require 'puppet/ssl/certificate_request'
 require 'tempfile'
 
-describe Puppet::SSL::Host do
+describe Puppet::SSL::CertificateRequest do
     before do
         # Get a safe temporary file
         file = Tempfile.new(&quot;csr_integration_testing&quot;)
         @dir = file.path
         file.delete
 
+        Puppet.settings.clear
+
         Puppet.settings[:confdir] = @dir
         Puppet.settings[:vardir] = @dir
 
@@ -23,13 +25,13 @@ describe Puppet::SSL::Host do
         @key = OpenSSL::PKey::RSA.new(512)
     end
 
-    after {
+    after do
         system(&quot;rm -rf %s&quot; % @dir)
         Puppet.settings.clear
 
         # This is necessary so the terminus instances don't lie around.
-        Puppet::SSL::CertificateRequest.indirection.clear_cache
-    }
+        Puppet::Util::Cacher.invalidate
+    end
 
     it &quot;should be able to generate CSRs&quot; do
         @csr.generate(@key)</diff>
      <filename>spec/integration/ssl/certificate_request.rb</filename>
    </modified>
    <modified>
      <diff>@@ -18,16 +18,18 @@ describe Puppet::SSL::Host do
         Puppet.settings[:confdir] = @dir
         Puppet.settings[:vardir] = @dir
 
+        Puppet::SSL::Host.ca_location = :local
+
         @host = Puppet::SSL::Host.new(&quot;luke.madstop.com&quot;)
+        @ca = Puppet::SSL::CertificateAuthority.new
     end
 
     after {
+        Puppet::SSL::Host.ca_location = :none
+
         system(&quot;rm -rf %s&quot; % @dir)
         Puppet.settings.clear
-
-        # This is necessary so the terminus instances don't lie around.
-        Puppet::SSL::Key.indirection.clear_cache
-        Puppet::SSL::CertificateRequest.indirection.clear_cache
+        Puppet::Util::Cacher.invalidate
     }
 
     it &quot;should be considered a CA host if its name is equal to 'ca'&quot; do
@@ -77,4 +79,12 @@ describe Puppet::SSL::Host do
             FileTest.should_not be_exist(File.join(Puppet[:privatekeydir], &quot;ca.pem&quot;))
         end
     end
+
+    it &quot;should pass the verification of its own SSL store&quot; do
+        @host.generate
+        @ca = Puppet::SSL::CertificateAuthority.new
+        @ca.sign(@host.name)
+
+        @host.ssl_store.verify(@host.certificate.content).should be_true
+    end
 end</diff>
      <filename>spec/integration/ssl/host.rb</filename>
    </modified>
    <modified>
      <diff>@@ -7,7 +7,7 @@ require File.dirname(__FILE__) + '/../../spec_helper'
 
 describe Puppet::Transaction::Report do
     describe &quot;when using the indirector&quot; do
-        after { Puppet::Transaction::Report.indirection.clear_cache }
+        after { Puppet::Util::Cacher.invalidate }
 
         it &quot;should be able to delegate to the :processor terminus&quot; do
             Puppet::Transaction::Report.indirection.stubs(:terminus_class).returns :processor</diff>
      <filename>spec/integration/transaction/report.rb</filename>
    </modified>
    <modified>
      <diff>@@ -7,7 +7,7 @@ describe &quot;Puppet::Indirector::FileServerTerminus&quot;, :shared =&gt; true do
     # This only works if the shared behaviour is included before
     # the 'before' block in the including context.
     before do
-        Puppet::FileServing::Configuration.clear_cache
+        Puppet::Util::Cacher.invalidate
         FileTest.stubs(:exists?).with(Puppet[:fileserverconfig]).returns(true)
         FileTest.stubs(:exists?).with(&quot;/my/mount/path&quot;).returns(true)
         FileTest.stubs(:directory?).with(&quot;/my/mount/path&quot;).returns(true)</diff>
      <filename>spec/shared_behaviours/file_server_terminus.rb</filename>
    </modified>
    <modified>
      <diff>@@ -15,12 +15,12 @@ describe Puppet::FileServing::Configuration do
 
     it &quot;should have a method for removing the current configuration instance&quot; do
         old = Puppet::FileServing::Configuration.create
-        Puppet::FileServing::Configuration.clear_cache
+        Puppet::Util::Cacher.invalidate
         Puppet::FileServing::Configuration.create.should_not equal(old)
     end
 
     after do
-        Puppet::FileServing::Configuration.clear_cache
+        Puppet::Util::Cacher.invalidate
     end
 end
 
@@ -32,7 +32,7 @@ describe Puppet::FileServing::Configuration do
     end
 
     after :each do
-        Puppet::FileServing::Configuration.clear_cache
+        Puppet::Util::Cacher.invalidate
     end
 
     describe Puppet::FileServing::Configuration, &quot; when initializing&quot; do</diff>
      <filename>spec/unit/file_serving/configuration.rb</filename>
    </modified>
    <modified>
      <diff>@@ -12,9 +12,9 @@ end
 
 describe Puppet::FileServing::Mount do
     it &quot;should provide a method for clearing its cached host information&quot; do
-        Puppet::FileServing::Mount.new(&quot;whatever&quot;).send(:localmap)
-        Puppet::FileServing::Mount.clear_cache
-        Puppet::FileServing::Mount.send(:class_variable_get, &quot;@@localmap&quot;).should be_nil
+        old = Puppet::FileServing::Mount.localmap
+        Puppet::Util::Cacher.invalidate
+        Puppet::FileServing::Mount.localmap.should_not equal(old)
     end
 end
 
@@ -106,7 +106,7 @@ describe Puppet::FileServing::Mount, &quot; when finding files&quot; do
     end
 
     after do
-        Puppet::FileServing::Mount.clear_cache
+        Puppet::Util::Cacher.invalidate
     end
 end
 </diff>
      <filename>spec/unit/file_serving/mount.rb</filename>
    </modified>
    <modified>
      <diff>@@ -87,6 +87,9 @@ describe &quot;Delegation Authorizer&quot;, :shared =&gt; true do
 end
 
 describe Puppet::Indirector::Indirection do
+    after do
+        Puppet::Util::Cacher.invalidate
+    end
     describe &quot;when initializing&quot; do
         # (LAK) I've no idea how to test this, really.
         it &quot;should store a reference to itself before it consumes its options&quot; do
@@ -494,7 +497,7 @@ describe Puppet::Indirector::Indirection do
 
         after :each do
             @indirection.delete
-            Puppet::Indirector::Indirection.clear_cache
+            Puppet::Util::Cacher.invalidate
         end
     end
 
@@ -615,15 +618,6 @@ describe Puppet::Indirector::Indirection do
             @indirection.terminus(:foo).should equal(@terminus)
         end
 
-        it &quot;should allow the clearance of cached terminus instances&quot; do
-            terminus1 = mock 'terminus1'
-            terminus2 = mock 'terminus2'
-            @terminus_class.stubs(:new).returns(terminus1, terminus2, ArgumentError)
-            @indirection.terminus(:foo).should equal(terminus1)
-            @indirection.class.clear_cache
-            @indirection.terminus(:foo).should equal(terminus2)
-        end
-
         # Make sure it caches the terminus.
         it &quot;should return the same terminus instance each time for a given name&quot; do
             @terminus_class.stubs(:new).returns(@terminus)
@@ -638,7 +632,6 @@ describe Puppet::Indirector::Indirection do
 
         after do
             @indirection.delete
-            Puppet::Indirector::Indirection.clear_cache
         end
     end
 
@@ -675,7 +668,6 @@ describe Puppet::Indirector::Indirection do
 
         after do
             @indirection.delete
-            Puppet::Indirector::Indirection.clear_cache
         end
     end
 
@@ -706,15 +698,6 @@ describe Puppet::Indirector::Indirection do
                 @indirection.cache.should equal(@cache)
                 @indirection.cache.should equal(@cache)
             end
-
-            it &quot;should remove the cache terminus when all other terminus instances are cleared&quot; do
-                cache2 = mock 'cache2'
-                @cache_class.stubs(:new).returns(@cache, cache2)
-                @indirection.cache_class = :cache_terminus
-                @indirection.cache.should equal(@cache)
-                @indirection.clear_cache
-                @indirection.cache.should equal(cache2)
-            end
         end
 
         describe &quot;and saving&quot; do
@@ -725,7 +708,6 @@ describe Puppet::Indirector::Indirection do
         
         after :each do
             @indirection.delete
-            Puppet::Indirector::Indirection.clear_cache
         end
     end
 end</diff>
      <filename>spec/unit/indirector/indirection.rb</filename>
    </modified>
    <modified>
      <diff>@@ -17,6 +17,7 @@ describe Puppet::Node::Ldap do
             @searcher.stubs(:connection).returns(@connection)
             @searcher.stubs(:class_attributes).returns([])
             @searcher.stubs(:parent_attribute).returns(nil)
+            @searcher.stubs(:stacked_attributes).returns([])
             @searcher.stubs(:search_base).returns(:yay)
             @searcher.stubs(:search_filter).returns(:filter)
 
@@ -195,6 +196,96 @@ describe Puppet::Node::Ldap do
                 proc { @searcher.find(@request) }.should raise_error(ArgumentError)
             end
         end
+
+        describe &quot;and a puppet variable is specified&quot; do
+            before do
+                @searcher.stubs(:stacked_attributes).returns(['puppetvar'])
+            end
+
+            it &quot;should add the variable to the node parameters&quot; do
+                @entry.stubs(:vals).with(&quot;puppetvar&quot;).returns(%w{one=two})
+                @entry.stubs(:to_hash).returns({})
+                @node.expects(:parameters=).with(&quot;one&quot; =&gt; &quot;two&quot;)
+                @searcher.find(@request)
+            end
+
+            it &quot;should not overwrite node parameters specified as ldap object attribute&quot; do
+                @entry.stubs(:vals).with(&quot;puppetvar&quot;).returns(%w{one=two})
+                @entry.stubs(:to_hash).returns(&quot;one&quot; =&gt; &quot;three&quot;)
+                @node.expects(:parameters=).with(&quot;one&quot; =&gt; &quot;three&quot;)
+                @searcher.find(@request)
+            end
+
+            it &quot;should set entries without an equal sign to nil&quot; do
+                @entry.stubs(:vals).with(&quot;puppetvar&quot;).returns(%w{one})
+                @entry.stubs(:to_hash).returns({})
+                @node.expects(:parameters=).with(&quot;one&quot; =&gt; nil)
+                @searcher.find(@request)
+            end
+
+            it &quot;should ignore empty entries&quot; do
+                @entry.stubs(:vals).with(&quot;puppetvar&quot;).returns(%w{})
+                @entry.stubs(:to_hash).returns({})
+                @searcher.find(@request)
+            end
+        end
+        describe &quot;and a puppet variable as well as a parent node are specified&quot; do
+            before do
+                @parent = mock 'parent'
+
+                @searcher.meta_def(:search_filter) do |name|
+                    return name
+                end
+                @connection.stubs(:search).with { |*args| args[2] == @name              }.yields(@entry)
+                @connection.stubs(:search).with { |*args| args[2] == 'parent'           }.yields(@parent)
+
+                @searcher.stubs(:stacked_attributes).returns(['puppetvar'])
+                @searcher.stubs(:parent_attribute).returns(:parent)
+            end
+
+            it &quot;should add parent node variables to the child node parameters&quot; do
+                @parent.stubs(:to_hash).returns({})
+                @parent.stubs(:vals).with(&quot;puppetvar&quot;).returns(%w{one=two})
+                @parent.stubs(:vals).with(:parent).returns(nil)
+
+                @entry.stubs(:to_hash).returns({})
+                @entry.stubs(:vals).with(&quot;puppetvar&quot;).returns(%w{})
+                @entry.stubs(:vals).with(:parent).returns(%w{parent})
+
+                @node.expects(:parameters=).with(&quot;one&quot; =&gt; &quot;two&quot;)
+
+                @searcher.find(@request)
+            end
+
+            it &quot;should overwrite parent node variables with child node parameters&quot; do
+                @parent.stubs(:to_hash).returns({})
+                @parent.stubs(:vals).with(&quot;puppetvar&quot;).returns(%w{one=two})
+                @parent.stubs(:vals).with(:parent).returns(nil)
+
+                @entry.stubs(:to_hash).returns({})
+                @entry.stubs(:vals).with(&quot;puppetvar&quot;).returns(%w{one=three})
+                @entry.stubs(:vals).with(:parent).returns(%w{parent})
+
+                @node.expects(:parameters=).with(&quot;one&quot; =&gt; &quot;three&quot;)
+
+                @searcher.find(@request)
+            end
+
+            it &quot;should not overwrite parent node parameters specified as ldap object attribute&quot; do
+                @parent.stubs(:to_hash).returns(&quot;one&quot; =&gt; &quot;three&quot;)
+                @parent.stubs(:vals).with(&quot;puppetvar&quot;).returns(%w{})
+                @parent.stubs(:vals).with(:parent).returns(nil)
+
+                @entry.stubs(:vals).with(&quot;puppetvar&quot;).returns(%w{one=two})
+                @entry.stubs(:to_hash).returns({})
+                @entry.stubs(:vals).with(:parent).returns(%w{parent})
+
+                @node.expects(:parameters=).with(&quot;one&quot; =&gt; &quot;three&quot;)
+
+                @searcher.find(@request)
+            end
+
+        end
     end
 end
 </diff>
      <filename>spec/unit/indirector/node/ldap.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,6 +3,39 @@
 require File.dirname(__FILE__) + '/../../spec_helper'
 require 'puppet/indirector/rest'
 
+describe &quot;a REST http call&quot;, :shared =&gt; true do
+    it &quot;should accept a path&quot; do
+        lambda { @search.send(@method, *@arguments) }.should_not raise_error(ArgumentError)
+    end
+
+    it &quot;should require a path&quot; do
+        lambda { @searcher.send(@method) }.should raise_error(ArgumentError)
+    end
+
+    it &quot;should use the Http Pool with the remote server and port looked up from the REST terminus&quot; do
+        @searcher.expects(:rest_connection_details).returns(@details)
+
+        conn = mock 'connection'
+        result = stub 'result', :body =&gt; &quot;body&quot;
+        conn.stubs(:put).returns result
+        conn.stubs(:delete).returns result
+        conn.stubs(:get).returns result
+        Puppet::Network::HttpPool.expects(:http_instance).with(@details[:host], @details[:port]).returns conn
+        @searcher.send(@method, *@arguments)
+    end
+
+    it &quot;should return the results of the request&quot; do
+        conn = mock 'connection'
+        result = stub 'result', :body =&gt; &quot;result&quot;
+        conn.stubs(:put).returns result
+        conn.stubs(:delete).returns result
+        conn.stubs(:get).returns result
+        Puppet::Network::HttpPool.stubs(:http_instance).returns conn
+
+        @searcher.send(@method, *@arguments).should == 'result'                
+    end        
+end
+
 describe Puppet::Indirector::REST do
     before do
         Puppet::Indirector::Terminus.stubs(:register_terminus_class)
@@ -19,354 +52,280 @@ describe Puppet::Indirector::REST do
 
         @searcher = @rest_class.new
     end
-    
-    describe &quot;when locating the REST connection&quot; do
-      before do
-        Puppet.settings.stubs(:value).returns(&quot;whatever&quot;)
-      end
-
-      it &quot;should return the :server setting as the host&quot; do
-        Puppet.settings.expects(:value).with(:server).returns &quot;myserver&quot;
-        @searcher.rest_connection_details[:host].should == &quot;myserver&quot;
-      end
-      
-      it &quot;should return the :masterport (as an Integer) as the port&quot; do
-        Puppet.settings.expects(:value).with(:masterport).returns &quot;1234&quot;
-        @searcher.rest_connection_details[:port].should == 1234
-      end
+
+    describe &quot;when configuring the REST http call&quot; do
+        before do
+            Puppet.settings.stubs(:value).returns(&quot;rest_testing&quot;)
+        end
+
+        it &quot;should return the :server setting as the host&quot; do
+            Puppet.settings.expects(:value).with(:server).returns &quot;myserver&quot;
+            @searcher.rest_connection_details[:host].should == &quot;myserver&quot;
+        end
+
+        it &quot;should return the :masterport (as an Integer) as the port&quot; do
+            Puppet.settings.expects(:value).with(:masterport).returns &quot;1234&quot;
+            @searcher.rest_connection_details[:port].should == 1234
+        end
     end
-    
+
     describe &quot;when doing a network fetch&quot; do
-      before :each do
-        Net::HTTP.stubs(:start).returns('result')
-        @details = { :host =&gt; '127.0.0.1', :port =&gt; 34343 }
-        @searcher.stubs(:rest_connection_details).returns(@details)
-      end
-      
-      it &quot;should accept a path&quot; do
-        lambda { @search.network_fetch('foo') }.should_not raise_error(ArgumentError)
-      end
-      
-      it &quot;should require a path&quot; do
-        lambda { @searcher.network_fetch }.should raise_error(ArgumentError)
-      end
-            
-      it &quot;should look up connection details&quot; do
-        @searcher.expects(:rest_connection_details).returns(@details)
-        @searcher.network_fetch('foo')
-      end
-      
-      it &quot;should use the GET http method&quot; do
-        @mock_result = stub('mock result', :body =&gt; 'result')
-        @mock_connection = mock('mock http connection', :get =&gt; @mock_result)
-        @searcher.stubs(:network).yields(@mock_connection)
-        @searcher.network_fetch('foo')
-      end
-      
-      it &quot;should use the appropriate remote server&quot; do
-        Net::HTTP.expects(:start).with {|host, port| host == @details[:host] }
-        @searcher.network_fetch('foo')
-      end
-      
-      it &quot;should use the appropriate remote port&quot; do
-        Net::HTTP.expects(:start).with {|host, port| port == @details[:port] }
-        @searcher.network_fetch('foo')
-      end
-      
-      it &quot;should use the provided path&quot; do
-        @mock_result = stub('mock result', :body =&gt; 'result')
-        @mock_connection = stub('mock http connection')
-        @mock_connection.expects(:get).with('/foo').returns(@mock_result)
-        @searcher.stubs(:network).yields(@mock_connection)
-        @searcher.network_fetch('foo')
-      end
-                
-      it &quot;should return the results of the GET request&quot; do
-        @searcher.network_fetch('foo').should == 'result'        
-      end
+        before :each do
+            Net::HTTP.stubs(:start).returns('result')
+            @details = { :host =&gt; '127.0.0.1', :port =&gt; 34343 }
+            @searcher.stubs(:rest_connection_details).returns(@details)
+
+            @method = :network_fetch
+            @arguments = &quot;foo&quot;
+        end
+
+        it_should_behave_like &quot;a REST http call&quot;
+
+        it &quot;should use the GET http method&quot; do
+            @mock_result = stub('mock result', :body =&gt; 'result')
+            @mock_connection = mock('mock http connection', :get =&gt; @mock_result)
+            @searcher.stubs(:network).returns(@mock_connection)
+            @searcher.network_fetch('foo')
+        end
+
+        it &quot;should use the provided path&quot; do
+            @mock_result = stub('mock result', :body =&gt; 'result')
+            @mock_connection = stub('mock http connection')
+            @mock_connection.expects(:get).with('/foo').returns(@mock_result)
+            @searcher.stubs(:network).returns(@mock_connection)
+            @searcher.network_fetch('foo')
+        end
     end
 
     describe &quot;when doing a network delete&quot; do
-      before :each do
-        Net::HTTP.stubs(:start).returns('result')
-        @details = { :host =&gt; '127.0.0.1', :port =&gt; 34343 }
-        @searcher.stubs(:rest_connection_details).returns(@details)
-      end
-      
-      it &quot;should accept a path&quot; do
-        lambda { @search.network_delete('foo') }.should_not raise_error(ArgumentError)
-      end
-      
-      it &quot;should require a path&quot; do
-        lambda { @searcher.network_delete }.should raise_error(ArgumentError)
-      end
-            
-      it &quot;should look up connection details&quot; do
-        @searcher.expects(:rest_connection_details).returns(@details)
-        @searcher.network_delete('foo')
-      end
-      
-      it &quot;should use the DELETE http method&quot; do
-        @mock_result = stub('mock result', :body =&gt; 'result')
-        @mock_connection = mock('mock http connection', :delete =&gt; @mock_result)
-        @searcher.stubs(:network).yields(@mock_connection)
-        @searcher.network_delete('foo')
-      end
-      
-      it &quot;should use the appropriate remote server&quot; do
-        Net::HTTP.expects(:start).with {|host, port| host == @details[:host] }
-        @searcher.network_delete('foo')
-      end
-      
-      it &quot;should use the appropriate remote port&quot; do
-        Net::HTTP.expects(:start).with {|host, port| port == @details[:port] }
-        @searcher.network_delete('foo')
-      end
-      
-      it &quot;should use the provided path&quot; do
-        @mock_result = stub('mock result', :body =&gt; 'result')
-        @mock_connection = stub('mock http connection')
-        @mock_connection.expects(:delete).with('/foo').returns(@mock_result)
-        @searcher.stubs(:network).yields(@mock_connection)
-        @searcher.network_delete('foo')
-      end
-            
-      it &quot;should return the results of the DELETE request&quot; do
-        @searcher.network_delete('foo').should == 'result'        
-      end    
+        before :each do
+            Net::HTTP.stubs(:start).returns('result')
+            @details = { :host =&gt; '127.0.0.1', :port =&gt; 34343 }
+            @searcher.stubs(:rest_connection_details).returns(@details)
+
+            @method = :network_delete
+            @arguments = &quot;foo&quot;
+        end
+
+        it_should_behave_like &quot;a REST http call&quot;
+
+        it &quot;should use the DELETE http method&quot; do
+            @mock_result = stub('mock result', :body =&gt; 'result')
+            @mock_connection = mock('mock http connection', :delete =&gt; @mock_result)
+            @searcher.stubs(:network).returns(@mock_connection)
+            @searcher.network_delete('foo')
+        end
     end
-    
+
     describe &quot;when doing a network put&quot; do
-      before :each do
-        Net::HTTP.stubs(:start).returns('result')
-        @details = { :host =&gt; '127.0.0.1', :port =&gt; 34343 }
-        @data = { :foo =&gt; 'bar' }
-        @searcher.stubs(:rest_connection_details).returns(@details)
-      end
-      
-      it &quot;should accept a path and data&quot; do
-        lambda { @search.network_put('foo', @data) }.should_not raise_error(ArgumentError)
-      end
-      
-      it &quot;should require a path and data&quot; do
-        lambda { @searcher.network_put('foo') }.should raise_error(ArgumentError)
-      end
-      
-      it &quot;should look up connection details&quot; do
-        @searcher.expects(:rest_connection_details).returns(@details)
-        @searcher.network_put('foo', @data)
-      end
-      
-      it &quot;should use the appropriate remote server&quot; do
-        Net::HTTP.expects(:start).with {|host, port| host == @details[:host] }
-        @searcher.network_put('foo', @data)
-      end
-      
-      it &quot;should use the appropriate remote port&quot; do
-        Net::HTTP.expects(:start).with {|host, port| port == @details[:port] }
-        @searcher.network_put('foo', @data)
-      end
-      
-      it &quot;should use the PUT http method&quot; do
-        @mock_result = stub('mock result', :body =&gt; 'result')
-        @mock_connection = mock('mock http connection', :put =&gt; @mock_result)
-        @searcher.stubs(:network).yields(@mock_connection)
-        @searcher.network_put('foo', @data)
-      end
-      
-      it &quot;should use the provided path&quot; do
-        @mock_result = stub('mock result', :body =&gt; 'result')
-        @mock_connection = stub('mock http connection')
-        @mock_connection.expects(:put).with {|path, data| path == '/foo' }.returns(@mock_result)
-        @searcher.stubs(:network).yields(@mock_connection)
-        @searcher.network_put('foo', @data)        
-      end
-      
-      it &quot;should use the provided data&quot; do
-        @mock_result = stub('mock result', :body =&gt; 'result')
-        @mock_connection = stub('mock http connection')
-        @mock_connection.expects(:put).with {|path, data| data == @data }.returns(@mock_result)
-        @searcher.stubs(:network).yields(@mock_connection)
-        @searcher.network_put('foo', @data)                
-      end
-      
-      it &quot;should return the results of the PUT request&quot; do
-        @searcher.network_put('foo', @data).should == 'result'        
-      end    
+        before :each do
+            Net::HTTP.stubs(:start).returns('result')
+            @details = { :host =&gt; '127.0.0.1', :port =&gt; 34343 }
+            @data = { :foo =&gt; 'bar' }
+            @searcher.stubs(:rest_connection_details).returns(@details)
+
+            @method = :network_put
+            @arguments = [&quot;foo&quot;, @data]
+        end
+
+        it_should_behave_like &quot;a REST http call&quot;
+
+        it &quot;should use the PUT http method&quot; do
+            @mock_result = stub('mock result', :body =&gt; 'result')
+            @mock_connection = mock('mock http connection', :put =&gt; @mock_result)
+            @searcher.stubs(:network).returns(@mock_connection)
+            @searcher.network_put('foo', @data)
+        end
+
+        it &quot;should use the provided path&quot; do
+            @mock_result = stub('mock result', :body =&gt; 'result')
+            @mock_connection = stub('mock http connection')
+            @mock_connection.expects(:put).with {|path, data| path == '/foo' }.returns(@mock_result)
+            @searcher.stubs(:network).returns(@mock_connection)
+            @searcher.network_put('foo', @data)                
+        end
+
+        it &quot;should use the provided data&quot; do
+            @mock_result = stub('mock result', :body =&gt; 'result')
+            @mock_connection = stub('mock http connection')
+            @mock_connection.expects(:put).with {|path, data| data == @data }.returns(@mock_result)
+            @searcher.stubs(:network).returns(@mock_connection)
+            @searcher.network_put('foo', @data)                                
+        end
     end
 
     describe &quot;when doing a find&quot; do
-      before :each do
-        @result = { :foo =&gt; 'bar'}.to_yaml
-        @searcher.stubs(:network_fetch).returns(@result)  # neuter the network connection
-        @model.stubs(:from_yaml).returns(@instance)
-
-        @request = stub 'request', :key =&gt; 'foo'
-      end
-      
-      it &quot;should look up the model instance over the network&quot; do
-        @searcher.expects(:network_fetch).returns(@result)
-        @searcher.find(@request)
-      end
-      
-      it &quot;should look up the model instance using the named indirection&quot; do
-        @searcher.expects(:network_fetch).with {|path| path =~ %r{^#{@indirection.name.to_s}/} }.returns(@result)
-        @searcher.find(@request)
-      end
-      
-      it &quot;should look up the model instance using the provided key&quot; do
-        @searcher.expects(:network_fetch).with {|path| path =~ %r{/foo$} }.returns(@result)
-        @searcher.find(@request)
-      end
-      
-      it &quot;should deserialize result data to a Model instance&quot; do
-        @model.expects(:from_yaml)
-        @searcher.find(@request)
-      end
-      
-      it &quot;should return the deserialized Model instance&quot; do
-        @searcher.find(@request).should == @instance     
-      end
-      
-      it &quot;should return nil when deserialized model instance is nil&quot; do
-        @model.stubs(:from_yaml).returns(nil)
-        @searcher.find(@request).should be_nil
-      end
-      
-      it &quot;should generate an error when result data deserializes improperly&quot; do
-        @model.stubs(:from_yaml).raises(ArgumentError)
-        lambda { @searcher.find(@request) }.should raise_error(ArgumentError)
-      end
-      
-      it &quot;should generate an error when result data specifies an error&quot; do
-        @searcher.stubs(:network_fetch).returns(RuntimeError.new(&quot;bogus&quot;).to_yaml)
-        lambda { @searcher.find(@request) }.should raise_error(RuntimeError)        
-      end      
+        before :each do
+            @result = { :foo =&gt; 'bar'}.to_yaml
+            @searcher.stubs(:network_fetch).returns(@result)    # neuter the network connection
+            @model.stubs(:from_yaml).returns(@instance)
+
+            @request = stub 'request', :key =&gt; 'foo'
+        end
+
+        it &quot;should look up the model instance over the network&quot; do
+            @searcher.expects(:network_fetch).returns(@result)
+            @searcher.find(@request)
+        end
+
+        it &quot;should look up the model instance using the named indirection&quot; do
+            @searcher.expects(:network_fetch).with {|path| path =~ %r{^#{@indirection.name.to_s}/} }.returns(@result)
+            @searcher.find(@request)
+        end
+
+        it &quot;should look up the model instance using the provided key&quot; do
+            @searcher.expects(:network_fetch).with {|path| path =~ %r{/foo$} }.returns(@result)
+            @searcher.find(@request)
+        end
+
+        it &quot;should deserialize result data to a Model instance&quot; do
+            @model.expects(:from_yaml)
+            @searcher.find(@request)
+        end
+
+        it &quot;should return the deserialized Model instance&quot; do
+            @searcher.find(@request).should == @instance         
+        end
+
+        it &quot;should return nil when deserialized model instance is nil&quot; do
+            @model.stubs(:from_yaml).returns(nil)
+            @searcher.find(@request).should be_nil
+        end
+
+        it &quot;should generate an error when result data deserializes improperly&quot; do
+            @model.stubs(:from_yaml).raises(ArgumentError)
+            lambda { @searcher.find(@request) }.should raise_error(ArgumentError)
+        end
+
+        it &quot;should generate an error when result data specifies an error&quot; do
+            @searcher.stubs(:network_fetch).returns(RuntimeError.new(&quot;bogus&quot;).to_yaml)
+            lambda { @searcher.find(@request) }.should raise_error(RuntimeError)                
+        end            
     end
 
     describe &quot;when doing a search&quot; do
-      before :each do
-        @result = [1, 2].to_yaml
-        @searcher.stubs(:network_fetch).returns(@result)
-        @model.stubs(:from_yaml).returns(@instance)
-
-        @request = stub 'request', :key =&gt; 'foo'
-      end
-      
-      it &quot;should look up the model data over the network&quot; do
-        @searcher.expects(:network_fetch).returns(@result)
-        @searcher.search(@request)
-      end
-      
-      it &quot;should look up the model instance using the named indirection&quot; do
-        @searcher.expects(:network_fetch).with {|path| path =~ %r{^#{@indirection.name.to_s}s/} }.returns(@result)
-        @searcher.search(@request)
-      end
-      
-      it &quot;should look up the model instance using the provided key&quot; do
-        @searcher.expects(:network_fetch).with {|path| path =~ %r{/foo$} }.returns(@result)
-        @searcher.search(@request)
-      end
-      
-      it &quot;should deserialize result data into a list of Model instances&quot; do
-        @model.expects(:from_yaml).at_least(2)
-        @searcher.search(@request)
-      end
-      
-      it &quot;should generate an error when result data deserializes improperly&quot; do
-        @model.stubs(:from_yaml).raises(ArgumentError)
-        lambda { @searcher.search(@request) }.should raise_error(ArgumentError)        
-      end
-      
-      it &quot;should generate an error when result data specifies an error&quot; do
-        @searcher.stubs(:network_fetch).returns(RuntimeError.new(&quot;bogus&quot;).to_yaml)
-        lambda { @searcher.search(@request) }.should raise_error(RuntimeError)        
-      end     
-    end    
-    
+        before :each do
+            @result = [1, 2].to_yaml
+            @searcher.stubs(:network_fetch).returns(@result)
+            @model.stubs(:from_yaml).returns(@instance)
+
+            @request = stub 'request', :key =&gt; 'foo'
+        end
+
+        it &quot;should look up the model data over the network&quot; do
+            @searcher.expects(:network_fetch).returns(@result)
+            @searcher.search(@request)
+        end
+
+        it &quot;should look up the model instance using the plural of the named indirection&quot; do
+            @searcher.expects(:network_fetch).with {|path| path =~ %r{^#{@indirection.name.to_s}s/} }.returns(@result)
+            @searcher.search(@request)
+        end
+
+        it &quot;should look up the model instance using the provided key&quot; do
+            @searcher.expects(:network_fetch).with {|path| path =~ %r{/foo$} }.returns(@result)
+            @searcher.search(@request)
+        end
+
+        it &quot;should deserialize result data into a list of Model instances&quot; do
+            @model.expects(:from_yaml).at_least(2)
+            @searcher.search(@request)
+        end
+
+        it &quot;should generate an error when result data deserializes improperly&quot; do
+            @model.stubs(:from_yaml).raises(ArgumentError)
+            lambda { @searcher.search(@request) }.should raise_error(ArgumentError)                
+        end
+
+        it &quot;should generate an error when result data specifies an error&quot; do
+            @searcher.stubs(:network_fetch).returns(RuntimeError.new(&quot;bogus&quot;).to_yaml)
+            lambda { @searcher.search(@request) }.should raise_error(RuntimeError)                
+        end         
+    end        
+
     describe &quot;when doing a destroy&quot; do
-      before :each do
-        @result = true.to_yaml
-        @searcher.stubs(:network_delete).returns(@result)  # neuter the network connection
-        @model.stubs(:from_yaml).returns(@instance)
-
-        @request = stub 'request', :key =&gt; 'foo'
-      end
-      
-      it &quot;should look up the model instance over the network&quot; do
-        @searcher.expects(:network_delete).returns(@result)
-        @searcher.destroy(@request)
-      end
-      
-      it &quot;should look up the model instance using the named indirection&quot; do
-        @searcher.expects(:network_delete).with {|path| path =~ %r{^#{@indirection.name.to_s}/} }.returns(@result)
-        @searcher.destroy(@request)
-      end
-      
-      it &quot;should look up the model instance using the provided key&quot; do
-        @searcher.expects(:network_delete).with {|path| path =~ %r{/foo$} }.returns(@result)
-        @searcher.destroy(@request)
-      end
-      
-      it &quot;should deserialize result data&quot; do
-        YAML.expects(:load).with(@result)
-        @searcher.destroy(@request)
-      end
-      
-      it &quot;should return deserialized result data&quot; do
-        @searcher.destroy(@request).should == true
-      end
-      
-      it &quot;should generate an error when result data specifies an error&quot; do
-        @searcher.stubs(:network_delete).returns(RuntimeError.new(&quot;bogus&quot;).to_yaml)
-        lambda { @searcher.destroy(@request) }.should raise_error(RuntimeError)        
-      end      
+        before :each do
+            @result = true.to_yaml
+            @searcher.stubs(:network_delete).returns(@result)    # neuter the network connection
+            @model.stubs(:from_yaml).returns(@instance)
+
+            @request = stub 'request', :key =&gt; 'foo'
+        end
+
+        it &quot;should look up the model instance over the network&quot; do
+            @searcher.expects(:network_delete).returns(@result)
+            @searcher.destroy(@request)
+        end
+
+        it &quot;should look up the model instance using the named indirection&quot; do
+            @searcher.expects(:network_delete).with {|path| path =~ %r{^#{@indirection.name.to_s}/} }.returns(@result)
+            @searcher.destroy(@request)
+        end
+
+        it &quot;should look up the model instance using the provided key&quot; do
+            @searcher.expects(:network_delete).with {|path| path =~ %r{/foo$} }.returns(@result)
+            @searcher.destroy(@request)
+        end
+
+        it &quot;should deserialize result data&quot; do
+            YAML.expects(:load).with(@result)
+            @searcher.destroy(@request)
+        end
+
+        it &quot;should return deserialized result data&quot; do
+            @searcher.destroy(@request).should == true
+        end
+
+        it &quot;should generate an error when result data specifies an error&quot; do
+            @searcher.stubs(:network_delete).returns(RuntimeError.new(&quot;bogus&quot;).to_yaml)
+            lambda { @searcher.destroy(@request) }.should raise_error(RuntimeError)                
+        end            
     end
 
     describe &quot;when doing a save&quot; do
-      before :each do
-        @result = { :foo =&gt; 'bar'}.to_yaml
-        @searcher.stubs(:network_put).returns(@result)  # neuter the network connection
-        @model.stubs(:from_yaml).returns(@instance)
-
-        @request = stub 'request', :instance =&gt; @instance
-      end
-      
-      it &quot;should save the model instance over the network&quot; do
-        @searcher.expects(:network_put).returns(@result)
-        @searcher.save(@request)
-      end
-      
-      it &quot;should save the model instance using the named indirection&quot; do
-        @searcher.expects(:network_put).with do |path, data| 
-          path =~ %r{^#{@indirection.name.to_s}/} and 
-          data == @instance.to_yaml 
-        end.returns(@result)
-        @searcher.save(@request)
-      end
-      
-      it &quot;should deserialize result data to a Model instance&quot; do
-        @model.expects(:from_yaml)
-        @searcher.save(@request)
-      end
-      
-      it &quot;should return the resulting deserialized Model instance&quot; do
-        @searcher.save(@request).should == @instance     
-      end
-      
-      it &quot;should return nil when deserialized model instance is nil&quot; do
-        @model.stubs(:from_yaml).returns(nil)
-        @searcher.save(@request).should be_nil
-      end
-      
-      it &quot;should generate an error when result data deserializes improperly&quot; do
-        @model.stubs(:from_yaml).raises(ArgumentError)
-        lambda { @searcher.save(@request) }.should raise_error(ArgumentError)
-      end
-      
-      it &quot;should generate an error when result data specifies an error&quot; do
-        @searcher.stubs(:network_put).returns(RuntimeError.new(&quot;bogus&quot;).to_yaml)
-        lambda { @searcher.save(@request) }.should raise_error(RuntimeError)        
-      end      
+        before :each do
+            @result = { :foo =&gt; 'bar'}.to_yaml
+            @searcher.stubs(:network_put).returns(@result)    # neuter the network connection
+            @model.stubs(:from_yaml).returns(@instance)
+
+            @request = stub 'request', :instance =&gt; @instance
+        end
+
+        it &quot;should save the model instance over the network&quot; do
+            @searcher.expects(:network_put).returns(@result)
+            @searcher.save(@request)
+        end
+
+        it &quot;should save the model instance using the named indirection&quot; do
+            @searcher.expects(:network_put).with do |path, data| 
+                path =~ %r{^#{@indirection.name.to_s}/} and 
+                data == @instance.to_yaml 
+            end.returns(@result)
+            @searcher.save(@request)
+        end
+
+        it &quot;should deserialize result data to a Model instance&quot; do
+            @model.expects(:from_yaml)
+            @searcher.save(@request)
+        end
+
+        it &quot;should return the resulting deserialized Model instance&quot; do
+            @searcher.save(@request).should == @instance         
+        end
+
+        it &quot;should return nil when deserialized model instance is nil&quot; do
+            @model.stubs(:from_yaml).returns(nil)
+            @searcher.save(@request).should be_nil
+        end
+
+        it &quot;should generate an error when result data deserializes improperly&quot; do
+            @model.stubs(:from_yaml).raises(ArgumentError)
+            lambda { @searcher.save(@request) }.should raise_error(ArgumentError)
+        end
+
+        it &quot;should generate an error when result data specifies an error&quot; do
+            @searcher.stubs(:network_put).returns(RuntimeError.new(&quot;bogus&quot;).to_yaml)
+            lambda { @searcher.save(@request) }.should raise_error(RuntimeError)                
+        end            
     end
 end</diff>
      <filename>spec/unit/indirector/rest.rb</filename>
    </modified>
    <modified>
      <diff>@@ -23,7 +23,14 @@ describe Puppet::Network::HTTP::Mongrel, &quot;when turning on listening&quot; do
         @mock_mongrel.stubs(:run)
         @mock_mongrel.stubs(:register)
         Mongrel::HttpServer.stubs(:new).returns(@mock_mongrel)
-        @listen_params = { :address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337, :handlers =&gt; [ :node, :catalog ], :protocols =&gt; [ :rest ] }
+
+        @mock_puppet_mongrel = mock('puppet_mongrel')
+        Puppet::Network::HTTPServer::Mongrel.stubs(:new).returns(@mock_puppet_mongrel)
+
+        @listen_params = { :address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337,
+            :handlers =&gt; [ :node, :catalog ], :protocols =&gt; [ :rest, :xmlrpc ],
+            :xmlrpc_handlers =&gt; [ :status, :fileserver ]
+        }
     end
     
     it &quot;should fail if already listening&quot; do
@@ -63,18 +70,38 @@ describe Puppet::Network::HTTP::Mongrel, &quot;when turning on listening&quot; do
         @server.should be_listening
     end
 
-    it &quot;should instantiate a handler for each protocol+handler pair to configure web server routing&quot; do
-        @listen_params[:protocols].each do |protocol|
-            @listen_params[:handlers].each do |handler|
-                @mock_mongrel.expects(:register)
+    describe &quot;when providing REST services&quot; do
+        it &quot;should instantiate a handler for each protocol+handler pair to configure web server routing&quot; do
+            @listen_params[:protocols].each do |protocol|
+                @listen_params[:handlers].each do |handler|
+                    @mock_mongrel.expects(:register)
+                end
             end
+            @server.listen(@listen_params)        
+        end
+        
+        it &quot;should use a Mongrel + REST class to configure Mongrel when REST services are requested&quot; do
+            @server.expects(:class_for_protocol).with(:rest).at_least_once.returns(Puppet::Network::HTTP::MongrelREST)
+            @server.listen(@listen_params)
         end
-        @server.listen(@listen_params)        
     end
-    
-    it &quot;should use a Mongrel + REST class to configure Mongrel when REST services are requested&quot; do
-        @server.expects(:class_for_protocol).with(:rest).at_least_once.returns(Puppet::Network::HTTP::MongrelREST)
-        @server.listen(@listen_params)
+
+    describe &quot;when providing XMLRPC services&quot; do
+        it &quot;should do nothing if no xmlrpc handlers have been provided&quot; do
+            Puppet::Network::HTTPServer::Mongrel.expects(:new).never
+            @server.listen(@listen_params.merge(:xmlrpc_handlers =&gt; []))
+        end
+
+        it &quot;should create an instance of the existing Mongrel http server with the right handlers&quot; do
+            Puppet::Network::HTTPServer::Mongrel.expects(:new).with([:status, :master]).returns(@mock_puppet_mongrel)
+            @server.listen(@listen_params.merge(:xmlrpc_handlers =&gt; [:status, :master]))
+        end
+
+        it &quot;should register the Mongrel server instance at /RPC2&quot; do
+            @mock_mongrel.expects(:register).with(&quot;/RPC2&quot;, @mock_puppet_mongrel)
+
+            @server.listen(@listen_params.merge(:xmlrpc_handlers =&gt; [:status, :master]))
+        end
     end
     
     it &quot;should fail if services from an unknown protocol are requested&quot; do</diff>
      <filename>spec/unit/network/http/mongrel.rb</filename>
    </modified>
    <modified>
      <diff>@@ -19,18 +19,20 @@ describe Puppet::Network::HTTP::WEBrick, &quot;when turning on listening&quot; do
         WEBrick::HTTPServer.stubs(:new).returns(@mock_webrick)
         @server = Puppet::Network::HTTP::WEBrick.new
         [:setup_logger, :setup_ssl].each {|meth| @server.stubs(meth).returns({})} # the empty hash is required because of how we're merging
-        @listen_params = { :address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337, :handlers =&gt; [ :node, :catalog ], :protocols =&gt; [ :rest ] }
+        @listen_params = { :address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337,
+            :handlers =&gt; [ :node, :catalog ], :xmlrpc_handlers =&gt; [], :protocols =&gt; [ :rest ]
+        }
     end
-    
+
     it &quot;should fail if already listening&quot; do
         @server.listen(@listen_params)
         Proc.new { @server.listen(@listen_params) }.should raise_error(RuntimeError)
     end
-    
+
     it &quot;should require at least one handler&quot; do
         Proc.new { @server.listen(@listen_params.delete_if {|k,v| :handlers == k}) }.should raise_error(ArgumentError)
     end
-    
+
     it &quot;should require at least one protocol&quot; do
         Proc.new { @server.listen(@listen_params.delete_if {|k,v| :protocols == k}) }.should raise_error(ArgumentError)
     end
@@ -38,7 +40,7 @@ describe Puppet::Network::HTTP::WEBrick, &quot;when turning on listening&quot; do
     it &quot;should require a listening address to be specified&quot; do
         Proc.new { @server.listen(@listen_params.delete_if {|k,v| :address == k})}.should raise_error(ArgumentError)
     end
-    
+
     it &quot;should require a listening port to be specified&quot; do
         Proc.new { @server.listen(@listen_params.delete_if {|k,v| :port == k})}.should raise_error(ArgumentError)        
     end
@@ -47,7 +49,7 @@ describe Puppet::Network::HTTP::WEBrick, &quot;when turning on listening&quot; do
         @mock_webrick.expects(:start)
         @server.listen(@listen_params)
     end
-    
+
     it &quot;should tell webrick to listen on the specified address and port&quot; do
         WEBrick::HTTPServer.expects(:new).with {|args|
             args[:Port] == 31337 and args[:BindAddress] == &quot;127.0.0.1&quot;
@@ -74,28 +76,80 @@ describe Puppet::Network::HTTP::WEBrick, &quot;when turning on listening&quot; do
 
         @server.listen(@listen_params)
     end
-    
+
     it &quot;should be listening&quot; do
         @server.listen(@listen_params)
         @server.should be_listening
     end
-    
-    it &quot;should instantiate a handler for each protocol+handler pair to configure web server routing&quot; do
-        @listen_params[:protocols].each do |protocol|
-            mock_handler = mock(&quot;handler instance for [#{protocol}]&quot;)
-            mock_handler_class = mock(&quot;handler class for [#{protocol}]&quot;)
-            @listen_params[:handlers].each do |handler|
-                @mock_webrick.expects(:mount)
+
+    describe &quot;when the REST protocol is requested&quot; do
+        it &quot;should use a WEBrick + REST class to configure WEBrick&quot; do
+            Puppet::Network::HTTP::WEBrick.expects(:class_for_protocol).with(:rest).at_least_once
+            @server.listen(@listen_params.merge(:protocols =&gt; [:rest]))
+        end
+
+        it &quot;should instantiate a handler for each protocol+handler pair to configure web server routing&quot; do
+            @listen_params[:protocols].each do |protocol|
+                @listen_params[:handlers].each do |handler|
+                    @mock_webrick.expects(:mount)
+                end
             end
+            @server.listen(@listen_params)        
         end
-        @server.listen(@listen_params)        
     end
 
-    it &quot;should use a WEBrick + REST class to configure WEBrick when REST services are requested&quot; do
-        Puppet::Network::HTTP::WEBrick.expects(:class_for_protocol).with(:rest).at_least_once
-        @server.listen(@listen_params.merge(:protocols =&gt; [:rest]))
+    describe &quot;when the XMLRPC protocol is requested&quot; do
+        before do
+            @servlet = mock 'servlet'
+
+            Puppet::Network::XMLRPC::WEBrickServlet.stubs(:new).returns @servlet
+
+            @master_handler = mock('master_handler')
+            @file_handler = mock('file_handler')
+
+            @master = mock 'master'
+            @file = mock 'file'
+            @master_handler.stubs(:new).returns @master
+            @file_handler.stubs(:new).returns @file
+
+            Puppet::Network::Handler.stubs(:handler).with(:master).returns @master_handler
+            Puppet::Network::Handler.stubs(:handler).with(:fileserver).returns @file_handler
+        end
+
+        it &quot;should do nothing if no xmlrpc handlers have been specified&quot; do
+            Puppet::Network::Handler.expects(:handler).never
+
+            @server.listen(@listen_params.merge(:protocols =&gt; [:xmlrpc], :xmlrpc_handlers =&gt; []))
+        end
+
+        it &quot;should look the handler classes up via their base class&quot; do
+            Puppet::Network::Handler.expects(:handler).with(:master).returns @master_handler
+            Puppet::Network::Handler.expects(:handler).with(:fileserver).returns @file_handler
+
+            @server.listen(@listen_params.merge(:protocols =&gt; [:xmlrpc], :xmlrpc_handlers =&gt; [:master, :fileserver]))
+        end
+
+        it &quot;should create an instance for each requested xmlrpc handler&quot; do
+            @master_handler.expects(:new).returns @master
+            @file_handler.expects(:new).returns @file
+
+            @server.listen(@listen_params.merge(:protocols =&gt; [:xmlrpc], :xmlrpc_handlers =&gt; [:master, :fileserver]))
+        end
+
+        it &quot;should create a webrick servlet with the xmlrpc handler instances&quot; do
+            Puppet::Network::XMLRPC::WEBrickServlet.expects(:new).with([@master, @file]).returns @servlet
+
+            @server.listen(@listen_params.merge(:protocols =&gt; [:xmlrpc], :xmlrpc_handlers =&gt; [:master, :fileserver]))
+        end
+
+        it &quot;should mount the webrick servlet at /RPC2&quot; do
+            @mock_webrick.stubs(:mount)
+            @mock_webrick.expects(:mount).with(&quot;/RPC2&quot;, @servlet)
+
+            @server.listen(@listen_params.merge(:protocols =&gt; [:xmlrpc], :xmlrpc_handlers =&gt; [:master, :fileserver]))
+        end
     end
-    
+
     it &quot;should fail if services from an unknown protocol are requested&quot; do
         Proc.new { @server.listen(@listen_params.merge(:protocols =&gt; [ :foo ]))}.should raise_error
     end
@@ -103,21 +157,21 @@ end
 
 
 describe Puppet::Network::HTTP::WEBrick, &quot;when looking up the class to handle a protocol&quot; do
-  it &quot;should require a protocol&quot; do
-    lambda { Puppet::Network::HTTP::WEBrick.class_for_protocol }.should raise_error(ArgumentError)
-  end
-  
-  it &quot;should accept a protocol&quot; do
-    lambda { Puppet::Network::HTTP::WEBrick.class_for_protocol(&quot;bob&quot;) }.should_not raise_error(ArgumentError)    
-  end
-  
-  it &quot;should use a WEBrick + REST class when a REST protocol is specified&quot; do
-    Puppet::Network::HTTP::WEBrick.class_for_protocol(&quot;rest&quot;).should == Puppet::Network::HTTP::WEBrickREST
-  end
-  
-  it &quot;should fail when an unknown protocol is specified&quot; do
-    lambda { Puppet::Network::HTTP::WEBrick.class_for_protocol(&quot;abcdefg&quot;) }.should raise_error
-  end
+    it &quot;should require a protocol&quot; do
+        lambda { Puppet::Network::HTTP::WEBrick.class_for_protocol }.should raise_error(ArgumentError)
+    end
+
+    it &quot;should accept a protocol&quot; do
+        lambda { Puppet::Network::HTTP::WEBrick.class_for_protocol(&quot;bob&quot;) }.should_not raise_error(ArgumentError)    
+    end
+
+    it &quot;should use a WEBrick + REST class when a REST protocol is specified&quot; do
+        Puppet::Network::HTTP::WEBrick.class_for_protocol(&quot;rest&quot;).should == Puppet::Network::HTTP::WEBrickREST
+    end
+
+    it &quot;should fail when an unknown protocol is specified&quot; do
+        lambda { Puppet::Network::HTTP::WEBrick.class_for_protocol(&quot;abcdefg&quot;) }.should raise_error
+    end
 end
 
 describe Puppet::Network::HTTP::WEBrick, &quot;when turning off listening&quot; do
@@ -129,17 +183,17 @@ describe Puppet::Network::HTTP::WEBrick, &quot;when turning off listening&quot; do
         [:setup_logger, :setup_ssl].each {|meth| @server.stubs(meth).returns({})} # the empty hash is required because of how we're merging
         @listen_params = { :address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337, :handlers =&gt; [ :node, :catalog ], :protocols =&gt; [ :rest ] }
     end
-    
+
     it &quot;should fail unless listening&quot; do
         Proc.new { @server.unlisten }.should raise_error(RuntimeError)
     end
-    
+
     it &quot;should order webrick server to stop&quot; do
         @mock_webrick.expects(:shutdown)
         @server.listen(@listen_params)
         @server.unlisten
     end
-    
+
     it &quot;should no longer be listening&quot; do
         @server.listen(@listen_params)
         @server.unlisten
@@ -154,20 +208,6 @@ describe Puppet::Network::HTTP::WEBrick do
         WEBrick::HTTPServer.stubs(:new).returns(@mock_webrick)
         @server = Puppet::Network::HTTP::WEBrick.new
     end
-    
-    describe &quot;when configuring an x509 store&quot; do
-        it &quot;should add the CRL to the store&quot;
-
-        it &quot;should create a new x509 store&quot;
-
-        it &quot;should add the CA certificate to the store&quot;
-
-        it &quot;should set the store's flags to 'OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK'&quot;
-
-        it &quot;should set the store's purpose to 'OpenSSL::X509::PURPOSE_ANY'&quot;
-
-        it &quot;should return the store&quot;
-    end
 
     describe &quot;when configuring an http logger&quot; do
         before do
@@ -250,22 +290,72 @@ describe Puppet::Network::HTTP::WEBrick do
     end
 
     describe &quot;when configuring ssl&quot; do
-        it &quot;should add an x509 store if the CRL is enabled&quot;
+        before do
+            @key = stub 'key', :content =&gt; &quot;mykey&quot;
+            @cert = stub 'cert', :content =&gt; &quot;mycert&quot;
+            @host = stub 'host', :key =&gt; @key, :certificate =&gt; @cert, :name =&gt; &quot;yay&quot;, :ssl_store =&gt; &quot;mystore&quot;
 
-        it &quot;should not add an x509 store if the CRL is disabled&quot;
+            Puppet::SSL::Certificate.stubs(:find).with('ca').returns @cert
 
-        it &quot;should configure the certificate&quot;
+            Puppet::SSL::Host.stubs(:new).returns @host
+        end
 
-        it &quot;should configure the private key&quot;
+        it &quot;should use the key from an SSL::Host instance created with the default name&quot; do
+            Puppet::SSL::Host.expects(:new).returns @host
+            @host.expects(:key).returns @key
 
-        it &quot;should start ssl immediately&quot;
+            @server.setup_ssl[:SSLPrivateKey].should == &quot;mykey&quot;
+        end
+
+        it &quot;should generate its files if no certificate can be found&quot; do
+            @host.expects(:certificate).times(2).returns(nil).then.returns(@cert)
 
-        it &quot;should enable ssl&quot;
+            @host.expects(:generate)
 
-        it &quot;should specify the path to the CA certificate&quot;
+            @server.setup_ssl
+        end
 
-        it &quot;should configure the verification method as 'OpenSSL::SSL::VERIFY_PEER'&quot;
+        it &quot;should configure the certificate&quot; do
+            @server.setup_ssl[:SSLCertificate].should == &quot;mycert&quot;
+        end
 
-        it &quot;should set the certificate name to 'nil'&quot;
+        it &quot;should fail if no CA certificate can be found&quot; do
+            Puppet::SSL::Certificate.stubs(:find).with('ca').returns nil
+
+            lambda { @server.setup_ssl }.should raise_error(Puppet::Error)
+        end
+
+        it &quot;should specify the path to the CA certificate&quot; do
+            Puppet.settings.stubs(:value).returns &quot;whatever&quot;
+            Puppet.settings.stubs(:value).with(:hostcrl).returns 'false'
+            Puppet.settings.stubs(:value).with(:localcacert).returns '/ca/crt'
+
+            @server.setup_ssl[:SSLCACertificateFile].should == &quot;/ca/crt&quot;
+        end
+
+        it &quot;should start ssl immediately&quot; do
+            @server.setup_ssl[:SSLStartImmediately].should be_true
+        end
+
+        it &quot;should enable ssl&quot; do
+            @server.setup_ssl[:SSLEnable].should be_true
+        end
+
+        it &quot;should configure the verification method as 'OpenSSL::SSL::VERIFY_PEER'&quot; do
+            @server.setup_ssl[:SSLVerifyClient].should == OpenSSL::SSL::VERIFY_PEER
+        end
+
+        it &quot;should add an x509 store&quot; do
+            Puppet.settings.stubs(:value).returns &quot;whatever&quot;
+            Puppet.settings.stubs(:value).with(:hostcrl).returns '/my/crl'
+
+            @host.expects(:ssl_store).returns &quot;mystore&quot;
+
+            @server.setup_ssl[:SSLCertificateStore].should == &quot;mystore&quot;
+        end
+
+        it &quot;should set the certificate name to 'nil'&quot; do
+            @server.setup_ssl[:SSLCertName].should be_nil
+        end
     end
 end</diff>
      <filename>spec/unit/network/http/webrick.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,105 +6,28 @@
 require File.dirname(__FILE__) + '/../../spec_helper'
 require 'puppet/network/http_pool'
 
-describe Puppet::Network::HttpPool, &quot; when adding certificate information to http instances&quot; do
-    before do
-        @http = mock 'http'
-        [:cert_store=, :verify_mode=, :ca_file=, :cert=, :key=].each { |m| @http.stubs(m) }
-        @store = stub 'store'
-        [:add_file,:purpose=].each { |m| @store.stubs(m) }
+describe Puppet::Network::HttpPool do
+    after do
+        Puppet::Util::Cacher.invalidate
+        Puppet::Network::HttpPool.clear_http_instances
+        Puppet::Network::HttpPool.instance_variable_set(&quot;@ssl_host&quot;, nil)
     end
 
     it &quot;should have keep-alive disabled&quot; do
         Puppet::Network::HttpPool::HTTP_KEEP_ALIVE.should be_false
     end
 
-    it &quot;should do nothing if no certificate is available&quot; do
-        Puppet::Network::HttpPool.expects(:read_cert).returns(false)
-        @http.expects(:cert=).never
-        Puppet::Network::HttpPool.cert_setup(@http)
-    end
-
-    it &quot;should add a certificate store&quot; do
-        Puppet::Network::HttpPool.stubs(:read_cert).returns(true)
-        Puppet::Network::HttpPool.stubs(:key).returns(:mykey)
-        OpenSSL::X509::Store.expects(:new).returns(@store)
-        @http.expects(:cert_store=).with(@store)
-
-        Puppet::Network::HttpPool.cert_setup(@http)
-    end
-
-    it &quot;should add the local CA cert to the certificate store&quot; do
-        Puppet::Network::HttpPool.stubs(:read_cert).returns(true)
-        OpenSSL::X509::Store.expects(:new).returns(@store)
-        Puppet.settings.stubs(:value).with(:localcacert).returns(&quot;/some/file&quot;)
-        Puppet.settings.stubs(:value).with(:localcacert).returns(&quot;/some/file&quot;)
-        @store.expects(:add_file).with(&quot;/some/file&quot;)
-
-        Puppet::Network::HttpPool.stubs(:key).returns(:whatever)
-
-        Puppet::Network::HttpPool.cert_setup(@http)
-    end
-
-    it &quot;should set the purpose of the cert store to OpenSSL::X509::PURPOSE_SSL_CLIENT&quot; do
-        Puppet::Network::HttpPool.stubs(:read_cert).returns(true)
-        Puppet::Network::HttpPool.stubs(:key).returns(:mykey)
-        OpenSSL::X509::Store.expects(:new).returns(@store)
-
-        @store.expects(:purpose=).with(OpenSSL::X509::PURPOSE_SSL_CLIENT)
-
-        Puppet::Network::HttpPool.cert_setup(@http)
-    end
-
-    it &quot;should add the client certificate&quot; do
-        Puppet::Network::HttpPool.stubs(:read_cert).returns(true)
-        Puppet::Network::HttpPool.stubs(:cert).returns(:mycert)
-        Puppet::Network::HttpPool.stubs(:key).returns(:mykey)
-        OpenSSL::X509::Store.expects(:new).returns(@store)
-
-        @http.expects(:cert=).with(:mycert)
-
-        Puppet::Network::HttpPool.cert_setup(@http)
-    end
-
-    it &quot;should add the client key&quot; do
-        Puppet::Network::HttpPool.stubs(:read_cert).returns(true)
-        Puppet::Network::HttpPool.stubs(:key).returns(:mykey)
-        OpenSSL::X509::Store.expects(:new).returns(@store)
-
-        @http.expects(:key=).with(:mykey)
-
-        Puppet::Network::HttpPool.cert_setup(@http)
+    it &quot;should use an SSL::Host instance to get its certificate information&quot; do
+        host = mock 'host'
+        Puppet::SSL::Host.expects(:new).with().returns host
+        Puppet::Network::HttpPool.ssl_host.should equal(host)
     end
 
-    it &quot;should set the verify mode to OpenSSL::SSL::VERIFY_PEER&quot; do
-        Puppet::Network::HttpPool.stubs(:read_cert).returns(true)
-        Puppet::Network::HttpPool.stubs(:key).returns(:mykey)
-        OpenSSL::X509::Store.expects(:new).returns(@store)
-
-        @http.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
-
-        Puppet::Network::HttpPool.cert_setup(@http)
-    end
-
-    it &quot;should set the ca file&quot; do
-        Puppet::Network::HttpPool.stubs(:read_cert).returns(true)
-        Puppet.settings.stubs(:value).with(:localcacert).returns(&quot;/some/file&quot;)
-        OpenSSL::X509::Store.expects(:new).returns(@store)
-
-        @http.expects(:ca_file=).with(&quot;/some/file&quot;)
-
-        Puppet::Network::HttpPool.stubs(:key).returns(:whatever)
-
-        Puppet::Network::HttpPool.cert_setup(@http)
-    end
-
-    it &quot;should set up certificate information when creating http instances&quot; do
-        Puppet::Network::HttpPool.expects(:cert_setup).with { |i| i.is_a?(Net::HTTP) }
-        Puppet::Network::HttpPool.http_instance(&quot;one&quot;, &quot;two&quot;)
-    end
-
-    after do
-        Puppet::Network::HttpPool.clear_http_instances
+    it &quot;should reuse the same host instance&quot; do
+        host = mock 'host'
+        Puppet::SSL::Host.expects(:new).with().once.returns host
+        Puppet::Network::HttpPool.ssl_host.should equal(host)
+        Puppet::Network::HttpPool.ssl_host.should equal(host)
     end
 
     describe &quot;when managing http instances&quot; do
@@ -115,7 +38,7 @@ describe Puppet::Network::HttpPool, &quot; when adding certificate information to htt
         end
 
         before do
-            # All of hte cert stuff is tested elsewhere
+            # All of the cert stuff is tested elsewhere
             Puppet::Network::HttpPool.stubs(:cert_setup)
         end
 
@@ -152,7 +75,7 @@ describe Puppet::Network::HttpPool, &quot; when adding certificate information to htt
             Puppet::Network::HttpPool.http_instance(&quot;me&quot;, 54321).open_timeout.should == 120
         end
 
-        describe &quot;when http keep-alive is enabled&quot; do
+        describe &quot;and http keep-alive is enabled&quot; do
             before do
                 Puppet::Network::HttpPool.stubs(:keep_alive?).returns true
             end
@@ -201,9 +124,19 @@ describe Puppet::Network::HttpPool, &quot; when adding certificate information to htt
                 one.expects(:finish).never
                 Puppet::Network::HttpPool.clear_http_instances
             end
+
+            it &quot;should reset its ssl host when clearing the cache&quot; do
+                stub_settings :http_proxy_host =&gt; &quot;myhost&quot;, :http_proxy_port =&gt; 432, :configtimeout =&gt; 120, :http_enable_post_connection_check =&gt; true, :certname =&gt; &quot;a&quot;
+                one = Puppet::Network::HttpPool.http_instance(&quot;me&quot;, 54321)
+                one.expects(:started?).returns(false)
+                one.expects(:finish).never
+                id = Puppet::Network::HttpPool.ssl_host.object_id
+                Puppet::Network::HttpPool.clear_http_instances
+                Puppet::Network::HttpPool.ssl_host.object_id.should_not == id
+            end
         end
 
-        describe &quot;when http keep-alive is disabled&quot; do
+        describe &quot;and http keep-alive is disabled&quot; do
             before do
                 Puppet::Network::HttpPool.stubs(:keep_alive?).returns false
             end
@@ -215,26 +148,73 @@ describe Puppet::Network::HttpPool, &quot; when adding certificate information to htt
             end
         end
 
-        # We mostly have to do this for testing, since in real life people
-        # won't change certs within a single process.
-        it &quot;should remove its loaded certificate when clearing the cache&quot; do
-            Puppet::Network::HttpPool.instance_variable_set(&quot;@cert&quot;, :yay)
+        after do
             Puppet::Network::HttpPool.clear_http_instances
-            # Can't use the accessor, because it will read the cert in
-            Puppet::Network::HttpPool.instance_variable_get(&quot;@cert&quot;).should be_nil
         end
+    end
 
-        # We mostly have to do this for testing, since in real life people
-        # won't change certs within a single process.
-        it &quot;should remove its loaded key when clearing the cache&quot; do
-            Puppet::Network::HttpPool.instance_variable_set(&quot;@key&quot;, :yay)
-            Puppet::Network::HttpPool.clear_http_instances
-            # Can't use the accessor, because it will read the cert in
-            Puppet::Network::HttpPool.instance_variable_get(&quot;@key&quot;).should be_nil
+    describe &quot;when adding certificate information to http instances&quot; do
+        before do
+            @http = mock 'http'
+            [:cert_store=, :verify_mode=, :ca_file=, :cert=, :key=].each { |m| @http.stubs(m) }
+            @store = stub 'store'
+
+            @cert = stub 'cert', :content =&gt; &quot;real_cert&quot;
+            @key = stub 'key', :content =&gt; &quot;real_key&quot;
+            @host = stub 'host', :certificate =&gt; @cert, :key =&gt; @key, :ssl_store =&gt; @store
+
+            Puppet[:confdir] = &quot;/sometthing/else&quot;
+            Puppet.settings.stubs(:value).returns &quot;/some/file&quot;
+            Puppet.settings.stubs(:value).with(:hostcert).returns &quot;/host/cert&quot;
+
+            FileTest.stubs(:exist?).with(&quot;/host/cert&quot;).returns true
+
+            Puppet::Network::HttpPool.stubs(:ssl_host).returns @host
         end
 
-        after do
-            Puppet::Network::HttpPool.clear_http_instances
+        it &quot;should do nothing if no certificate is on disk&quot; do
+            FileTest.expects(:exist?).with(&quot;/host/cert&quot;).returns false
+            @http.expects(:cert=).never
+            Puppet::Network::HttpPool.cert_setup(@http)
+        end
+
+        it &quot;should add a certificate store from the ssl host&quot; do
+            @http.expects(:cert_store=).with(@store)
+
+            Puppet::Network::HttpPool.cert_setup(@http)
+        end
+
+        it &quot;should add the client certificate&quot; do
+            @http.expects(:cert=).with(&quot;real_cert&quot;)
+
+            Puppet::Network::HttpPool.cert_setup(@http)
+        end
+
+        it &quot;should add the client key&quot; do
+            @http.expects(:key=).with(&quot;real_key&quot;)
+
+            Puppet::Network::HttpPool.cert_setup(@http)
+        end
+
+        it &quot;should set the verify mode to OpenSSL::SSL::VERIFY_PEER&quot; do
+            @http.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
+
+            Puppet::Network::HttpPool.cert_setup(@http)
+        end
+
+        it &quot;should set the ca file&quot; do
+            Puppet.settings.stubs(:value).returns &quot;/some/file&quot;
+            FileTest.stubs(:exist?).with(Puppet[:hostcert]).returns true
+
+            Puppet.settings.stubs(:value).with(:localcacert).returns &quot;/ca/cert/file&quot;
+            @http.expects(:ca_file=).with(&quot;/ca/cert/file&quot;)
+
+            Puppet::Network::HttpPool.cert_setup(@http)
+        end
+
+        it &quot;should set up certificate information when creating http instances&quot; do
+            Puppet::Network::HttpPool.expects(:cert_setup).with { |i| i.is_a?(Net::HTTP) }
+            Puppet::Network::HttpPool.http_instance(&quot;one&quot;, &quot;two&quot;)
         end
     end
 end</diff>
      <filename>spec/unit/network/http_pool.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,311 +6,527 @@
 require File.dirname(__FILE__) + '/../../spec_helper'
 require 'puppet/network/server'
 
-describe Puppet::Network::Server, &quot;when initializing&quot; do
+describe Puppet::Network::Server do
     before do
         @mock_http_server_class = mock('http server class')
-        Puppet.stubs(:[]).with(:servertype).returns(:suparserver)
+        Puppet.settings.stubs(:use)
+        Puppet.settings.stubs(:value).with(:name).returns(&quot;me&quot;)
+        Puppet.settings.stubs(:value).with(:servertype).returns(:suparserver)
         Puppet::Network::HTTP.stubs(:server_class_by_type).returns(@mock_http_server_class)
-    end
-    
-    it &quot;should allow specifying a listening address&quot; do
-        Puppet.stubs(:[]).with(:masterport).returns('')
-        @server = Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;)
-        @server.address.should == &quot;127.0.0.1&quot;
+        Puppet.settings.stubs(:value).with(:servertype).returns(:suparserver)
+        @server = Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337)
     end
 
-    it &quot;should allow specifying a listening port&quot; do
-        Puppet.stubs(:[]).with(:bindaddress).returns('')
-        @server = Puppet::Network::Server.new(:port =&gt; 31337)
-        @server.port.should == 31337
-    end
-    
-    it &quot;should use the Puppet configurator to find a default listening address&quot; do
-        Puppet.stubs(:[]).with(:masterport).returns('')
-        Puppet.expects(:[]).with(:bindaddress).returns(&quot;10.0.0.1&quot;)
-        @server = Puppet::Network::Server.new
-        @server.address.should == &quot;10.0.0.1&quot;
-    end
+    describe &quot;when initializing&quot; do
+        before do
+            Puppet::Indirector::Indirection.stubs(:model).returns mock('indirection')
+            Puppet::Network::Handler.stubs(:handler).returns mock('xmlrpc_handler')
+        end
 
-    it &quot;should use the Puppet configurator to find a default listening port&quot; do
-        Puppet.stubs(:[]).with(:bindaddress).returns('')
-        Puppet.expects(:[]).with(:masterport).returns(6667)
-        @server = Puppet::Network::Server.new
-        @server.port.should == 6667
-    end
+        it &quot;should allow specifying a listening address&quot; do
+            Puppet.settings.stubs(:value).with(:masterport).returns('')
+            @server = Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;)
+            @server.address.should == &quot;127.0.0.1&quot;
+        end
 
-    it &quot;should fail to initialize if no listening address can be found&quot; do
-        Puppet.stubs(:[]).with(:masterport).returns(6667)
-        Puppet.stubs(:[]).with(:bindaddress).returns(nil)
-        Proc.new { Puppet::Network::Server.new }.should raise_error(ArgumentError)
-    end
-    
-    it &quot;should fail to initialize if no listening port can be found&quot; do
-        Puppet.stubs(:[]).with(:bindaddress).returns(&quot;127.0.0.1&quot;)
-        Puppet.stubs(:[]).with(:masterport).returns(nil)
-        Proc.new { Puppet::Network::Server.new }.should raise_error(ArgumentError)        
-    end
+        it &quot;should allow specifying a listening port&quot; do
+            Puppet.settings.stubs(:value).with(:bindaddress).returns('')
+            @server = Puppet::Network::Server.new(:port =&gt; 31337)
+            @server.port.should == 31337
+        end
 
-    it &quot;should use the Puppet configurator to determine which HTTP server will be used to provide access to clients&quot; do
-        Puppet.expects(:[]).with(:servertype).returns(:suparserver)
-        @server = Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337)
-        @server.server_type.should == :suparserver
-    end
-  
-    it &quot;should fail to initialize if there is no HTTP server known to the Puppet configurator&quot; do
-        Puppet.expects(:[]).with(:servertype).returns(nil)
-        Proc.new { Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337) }.should raise_error
-    end
- 
-    it &quot;should ask the Puppet::Network::HTTP class to fetch the proper HTTP server class&quot; do
-        Puppet::Network::HTTP.expects(:server_class_by_type).with(:suparserver).returns(@mock_http_server_class)
-        @server = Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337)
-    end
-    
-    it &quot;should fail if the HTTP server class is unknown&quot; do
-        Puppet::Network::HTTP.stubs(:server_class_by_type).returns(nil)
-        Proc.new { Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337) }.should raise_error(ArgumentError)
-    end
-  
-    it &quot;should allow registering indirections&quot; do
-        @server = Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337, :handlers =&gt; [ :foo, :bar, :baz])
-        Proc.new { @server.unregister(:foo, :bar, :baz) }.should_not raise_error
-    end
-  
-    it &quot;should not be listening after initialization&quot; do
-        Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337).should_not be_listening
-    end
-end
+        it &quot;should use the Puppet configurator to find a default listening address&quot; do
+            Puppet.settings.stubs(:value).with(:masterport).returns('')
+            Puppet.settings.expects(:value).with(:bindaddress).returns(&quot;10.0.0.1&quot;)
+            @server = Puppet::Network::Server.new
+            @server.address.should == &quot;10.0.0.1&quot;
+        end
 
-describe Puppet::Network::Server, &quot;in general&quot; do
-    before do
-        @mock_http_server_class = mock('http server class')
-        Puppet::Network::HTTP.stubs(:server_class_by_type).returns(@mock_http_server_class)
-        Puppet.stubs(:[]).with(:servertype).returns(:suparserver)
-        @server = Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337)
-    end
-  
-    it &quot;should allow registering an indirection for client access by specifying its indirection name&quot; do
-        Proc.new { @server.register(:foo) }.should_not raise_error
-    end
-  
-    it &quot;should require at least one indirection name when registering indirections for client access&quot; do
-        Proc.new { @server.register }.should raise_error(ArgumentError)
-    end
-  
-    it &quot;should allow for numerous indirections to be registered at once for client access&quot; do
-        Proc.new { @server.register(:foo, :bar, :baz) }.should_not raise_error
-    end
+        it &quot;should use the Puppet configurator to find a default listening port&quot; do
+            Puppet.settings.stubs(:value).with(:bindaddress).returns('')
+            Puppet.settings.expects(:value).with(:masterport).returns(6667)
+            @server = Puppet::Network::Server.new
+            @server.port.should == 6667
+        end
+
+        it &quot;should fail to initialize if no listening address can be found&quot; do
+            Puppet.settings.stubs(:value).with(:masterport).returns(6667)
+            Puppet.settings.stubs(:value).with(:bindaddress).returns(nil)
+            lambda { Puppet::Network::Server.new }.should raise_error(ArgumentError)
+        end
+
+        it &quot;should fail to initialize if no listening port can be found&quot; do
+            Puppet.settings.stubs(:value).with(:bindaddress).returns(&quot;127.0.0.1&quot;)
+            Puppet.settings.stubs(:value).with(:masterport).returns(nil)
+            lambda { Puppet::Network::Server.new }.should raise_error(ArgumentError)        
+        end
+
+        it &quot;should use the Puppet configurator to determine which HTTP server will be used to provide access to clients&quot; do
+            Puppet.settings.expects(:value).with(:servertype).returns(:suparserver)
+            @server = Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337)
+            @server.server_type.should == :suparserver
+        end
 
-    it &quot;should allow the use of indirection names to specify which indirections are to be no longer accessible to clients&quot; do
-        @server.register(:foo)
-        Proc.new { @server.unregister(:foo) }.should_not raise_error    
+        it &quot;should fail to initialize if there is no HTTP server known to the Puppet configurator&quot; do
+            Puppet.settings.expects(:value).with(:servertype).returns(nil)
+            lambda { Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337) }.should raise_error
+        end
+
+        it &quot;should ask the Puppet::Network::HTTP class to fetch the proper HTTP server class&quot; do
+            Puppet::Network::HTTP.expects(:server_class_by_type).with(:suparserver).returns(@mock_http_server_class)
+            @server = Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337)
+        end
+
+        it &quot;should fail if the HTTP server class is unknown&quot; do
+            Puppet::Network::HTTP.stubs(:server_class_by_type).returns(nil)
+            lambda { Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337) }.should raise_error(ArgumentError)
+        end
+
+        it &quot;should allow registering REST handlers&quot; do
+            @server = Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337, :handlers =&gt; [ :foo, :bar, :baz])
+            lambda { @server.unregister(:foo, :bar, :baz) }.should_not raise_error
+        end
+
+        it &quot;should allow registering XMLRPC handlers&quot; do
+            @server = Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337, :xmlrpc_handlers =&gt; [ :foo, :bar, :baz])
+            lambda { @server.unregister_xmlrpc(:foo, :bar, :baz) }.should_not raise_error
+        end
+
+        it &quot;should not be listening after initialization&quot; do
+            Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337).should_not be_listening
+        end
+
+        it &quot;should use the :main setting section&quot; do
+            Puppet.settings.expects(:use).with { |args| args.include?(:main) }
+            @server = Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337, :xmlrpc_handlers =&gt; [ :foo, :bar, :baz])
+        end
+
+        it &quot;should use the Puppet[:name] setting section&quot; do
+            Puppet.settings.expects(:value).with(:name).returns &quot;me&quot;
+            Puppet.settings.expects(:use).with { |args| args.include?(&quot;me&quot;) }
+
+            @server = Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337, :xmlrpc_handlers =&gt; [ :foo, :bar, :baz])
+        end
     end
 
-    it &quot;should leave other indirections accessible to clients when turning off indirections&quot; do
-        @server.register(:foo, :bar)
-        @server.unregister(:foo)
-        Proc.new { @server.unregister(:bar)}.should_not raise_error
+    # We don't test the method, because it's too much of a Unix-y pain.
+    it &quot;should be able to daemonize&quot; do
+        @server.should respond_to(:daemonize)
     end
-  
-    it &quot;should allow specifying numerous indirections which are to be no longer accessible to clients&quot; do
-        @server.register(:foo, :bar)
-        Proc.new { @server.unregister(:foo, :bar) }.should_not raise_error
+
+    describe &quot;when being started&quot; do
+        before do
+            @server.stubs(:listen)
+            @server.stubs(:create_pidfile)
+        end
+
+        it &quot;should listen&quot; do
+            @server.expects(:listen)
+            @server.start
+        end
+
+        it &quot;should create its PID file&quot; do
+            @server.expects(:create_pidfile)
+            @server.start
+        end
     end
-    
-    it &quot;should not turn off any indirections if given unknown indirection names to turn off&quot; do
-        @server.register(:foo, :bar)
-        Proc.new { @server.unregister(:foo, :bar, :baz) }.should raise_error(ArgumentError)
-        Proc.new { @server.unregister(:foo, :bar) }.should_not raise_error
+
+    describe &quot;when being stopped&quot; do
+        before do
+            @server.stubs(:unlisten)
+            @server.stubs(:remove_pidfile)
+        end
+
+        it &quot;should unlisten&quot; do
+            @server.expects(:unlisten)
+            @server.stop
+        end
+
+        it &quot;should remove its PID file&quot; do
+            @server.expects(:remove_pidfile)
+            @server.stop
+        end
     end
-  
-    it &quot;should not allow turning off unknown indirection names&quot; do
-        @server.register(:foo, :bar)
-        Proc.new { @server.unregister(:baz) }.should raise_error(ArgumentError)
+
+    describe &quot;when creating its pidfile&quot; do
+        it &quot;should use an exclusive mutex&quot; do
+            Puppet.settings.expects(:value).with(:name).returns &quot;me&quot;
+
+            sync = mock 'sync'
+            Puppet::Util.expects(:sync).with(&quot;me&quot;).returns sync
+            
+            sync.expects(:synchronize).with(Sync::EX)
+            @server.create_pidfile
+        end
+
+        it &quot;should lock the pidfile using the Pidlock class&quot; do
+            pidfile = mock 'pidfile'
+
+            Puppet.settings.stubs(:value).with(:name).returns &quot;eh&quot;
+            Puppet.settings.expects(:value).with(:pidfile).returns &quot;/my/file&quot;
+
+            Puppet::Util::Pidlock.expects(:new).with(&quot;/my/file&quot;).returns pidfile
+
+            pidfile.expects(:lock).returns true
+            @server.create_pidfile
+        end
+
+        it &quot;should fail if it cannot lock&quot; do
+            pidfile = mock 'pidfile'
+
+            Puppet.settings.stubs(:value).with(:name).returns &quot;eh&quot;
+            Puppet.settings.stubs(:value).with(:pidfile).returns &quot;/my/file&quot;
+
+            Puppet::Util::Pidlock.expects(:new).with(&quot;/my/file&quot;).returns pidfile
+
+            pidfile.expects(:lock).returns false
+
+            lambda { @server.create_pidfile }.should raise_error
+        end
     end
-  
-    it &quot;should disable client access immediately when turning off indirections&quot; do
-        @server.register(:foo, :bar)
-        @server.unregister(:foo)    
-        Proc.new { @server.unregister(:foo) }.should raise_error(ArgumentError)
+
+    describe &quot;when removing its pidfile&quot; do
+        it &quot;should use an exclusive mutex&quot; do
+            Puppet.settings.expects(:value).with(:name).returns &quot;me&quot;
+
+            sync = mock 'sync'
+            Puppet::Util.expects(:sync).with(&quot;me&quot;).returns sync
+            
+            sync.expects(:synchronize).with(Sync::EX)
+            @server.remove_pidfile
+        end
+
+        it &quot;should do nothing if the pidfile is not present&quot; do
+            pidfile = mock 'pidfile', :locked? =&gt; false
+            Puppet::Util::Pidlock.expects(:new).with(&quot;/my/file&quot;).returns pidfile
+
+            Puppet.settings.stubs(:value).with(:name).returns &quot;eh&quot;
+            Puppet.settings.stubs(:value).with(:pidfile).returns &quot;/my/file&quot;
+
+            pidfile.expects(:unlock).never
+            @server.remove_pidfile
+        end
+
+        it &quot;should unlock the pidfile using the Pidlock class&quot; do
+            pidfile = mock 'pidfile', :locked? =&gt; true
+            Puppet::Util::Pidlock.expects(:new).with(&quot;/my/file&quot;).returns pidfile
+            pidfile.expects(:unlock).returns true
+
+            Puppet.settings.stubs(:value).with(:name).returns &quot;eh&quot;
+            Puppet.settings.stubs(:value).with(:pidfile).returns &quot;/my/file&quot;
+
+            @server.remove_pidfile
+        end
+
+        it &quot;should warn if it cannot remove the pidfile&quot; do
+            pidfile = mock 'pidfile', :locked? =&gt; true
+            Puppet::Util::Pidlock.expects(:new).with(&quot;/my/file&quot;).returns pidfile
+            pidfile.expects(:unlock).returns false
+
+            Puppet.settings.stubs(:value).with(:name).returns &quot;eh&quot;
+            Puppet.settings.stubs(:value).with(:pidfile).returns &quot;/my/file&quot;
+
+            Puppet.expects :err
+            @server.remove_pidfile
+        end
     end
-  
-    it &quot;should allow turning off all indirections at once&quot; do
-        @server.register(:foo, :bar)
-        @server.unregister
-        [ :foo, :bar, :baz].each do |indirection|
-            Proc.new { @server.unregister(indirection) }.should raise_error(ArgumentError)
+
+    describe &quot;when managing indirection registrations&quot; do
+        before do
+            Puppet::Indirector::Indirection.stubs(:model).returns mock('indirection')
+        end
+
+        it &quot;should allow registering an indirection for client access by specifying its indirection name&quot; do
+            lambda { @server.register(:foo) }.should_not raise_error
+        end
+
+        it &quot;should require that the indirection be valid&quot; do
+            Puppet::Indirector::Indirection.expects(:model).with(:foo).returns nil
+            lambda { @server.register(:foo) }.should raise_error(ArgumentError)
+        end
+
+        it &quot;should require at least one indirection name when registering indirections for client access&quot; do
+            lambda { @server.register }.should raise_error(ArgumentError)
+        end
+
+        it &quot;should allow for numerous indirections to be registered at once for client access&quot; do
+            lambda { @server.register(:foo, :bar, :baz) }.should_not raise_error
+        end
+
+        it &quot;should allow the use of indirection names to specify which indirections are to be no longer accessible to clients&quot; do
+            @server.register(:foo)
+            lambda { @server.unregister(:foo) }.should_not raise_error    
+        end
+
+        it &quot;should leave other indirections accessible to clients when turning off indirections&quot; do
+            @server.register(:foo, :bar)
+            @server.unregister(:foo)
+            lambda { @server.unregister(:bar)}.should_not raise_error
+        end
+
+        it &quot;should allow specifying numerous indirections which are to be no longer accessible to clients&quot; do
+            @server.register(:foo, :bar)
+            lambda { @server.unregister(:foo, :bar) }.should_not raise_error
+        end
+
+        it &quot;should not turn off any indirections if given unknown indirection names to turn off&quot; do
+            @server.register(:foo, :bar)
+            lambda { @server.unregister(:foo, :bar, :baz) }.should raise_error(ArgumentError)
+            lambda { @server.unregister(:foo, :bar) }.should_not raise_error
+        end
+
+        it &quot;should not allow turning off unknown indirection names&quot; do
+            @server.register(:foo, :bar)
+            lambda { @server.unregister(:baz) }.should raise_error(ArgumentError)
+        end
+
+        it &quot;should disable client access immediately when turning off indirections&quot; do
+            @server.register(:foo, :bar)
+            @server.unregister(:foo)    
+            lambda { @server.unregister(:foo) }.should raise_error(ArgumentError)
+        end
+
+        it &quot;should allow turning off all indirections at once&quot; do
+            @server.register(:foo, :bar)
+            @server.unregister
+            [ :foo, :bar, :baz].each do |indirection|
+                lambda { @server.unregister(indirection) }.should raise_error(ArgumentError)
+            end
         end
     end
-  
+
     it &quot;should provide a means of determining whether it is listening&quot; do
         @server.should respond_to(:listening?)
     end
-  
+
     it &quot;should provide a means of determining which HTTP server will be used to provide access to clients&quot; do
         @server.server_type.should == :suparserver
     end
-    
-    it &quot;should allow for multiple configurations, each handling different indirections&quot; do
-        @server2 = Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337)
-        @server.register(:foo, :bar)
-        @server2.register(:foo, :xyzzy)
-        @server.unregister(:foo, :bar)
-        @server2.unregister(:foo, :xyzzy)
-        Proc.new { @server.unregister(:xyzzy) }.should raise_error(ArgumentError)
-        Proc.new { @server2.unregister(:bar) }.should raise_error(ArgumentError)
-    end  
 
     it &quot;should provide a means of determining which protocols are in use&quot; do
         @server.should respond_to(:protocols)
     end
-    
-    it &quot;should only support the REST protocol at this time&quot; do
-        @server.protocols.should == [ :rest ]
+
+    it &quot;should set the protocols to :rest and :xmlrpc&quot; do
+        @server.protocols.should == [ :rest, :xmlrpc ]
     end
-    
+
     it &quot;should provide a means of determining the listening address&quot; do
         @server.address.should == &quot;127.0.0.1&quot;
     end
-    
+
     it &quot;should provide a means of determining the listening port&quot; do
         @server.port.should == 31337
     end
-end
 
-describe Puppet::Network::Server, &quot;when listening is off&quot; do
-    before do
-        @mock_http_server_class = mock('http server class')
-        Puppet::Network::HTTP.stubs(:server_class_by_type).returns(@mock_http_server_class)
-        Puppet.stubs(:[]).with(:servertype).returns(:suparserver)
-        @server = Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337)
-        @mock_http_server = mock('http server')
-        @mock_http_server.stubs(:listen)
-        @server.stubs(:http_server).returns(@mock_http_server)
-    end
+    it &quot;should allow for multiple configurations, each handling different indirections&quot; do
+        Puppet::Indirector::Indirection.stubs(:model).returns mock('indirection')
 
-    it &quot;should indicate that it is not listening&quot; do
-        @server.should_not be_listening
+        @server2 = Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337)
+        @server.register(:foo, :bar)
+        @server2.register(:foo, :xyzzy)
+        @server.unregister(:foo, :bar)
+        @server2.unregister(:foo, :xyzzy)
+        lambda { @server.unregister(:xyzzy) }.should raise_error(ArgumentError)
+        lambda { @server2.unregister(:bar) }.should raise_error(ArgumentError)
     end  
-  
-    it &quot;should not allow listening to be turned off&quot; do
-        Proc.new { @server.unlisten }.should raise_error(RuntimeError)
-    end
-  
-    it &quot;should allow listening to be turned on&quot; do
-        Proc.new { @server.listen }.should_not raise_error
-    end
-    
-end
 
-describe Puppet::Network::Server, &quot;when listening is on&quot; do
-    before do
-        @mock_http_server_class = mock('http server class')
-        Puppet::Network::HTTP.stubs(:server_class_by_type).returns(@mock_http_server_class)
-        Puppet.stubs(:[]).with(:servertype).returns(:suparserver)
-        @server = Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337)
-        @mock_http_server = mock('http server')
-        @mock_http_server.stubs(:listen)
-        @mock_http_server.stubs(:unlisten)
-        @server.stubs(:http_server).returns(@mock_http_server)
-        @server.listen
-    end
-  
-    it &quot;should indicate that it is listening&quot; do
-        @server.should be_listening
-    end
-    
-    it &quot;should not allow listening to be turned on&quot; do
-        Proc.new { @server.listen }.should raise_error(RuntimeError)
-    end
-  
-    it &quot;should allow listening to be turned off&quot; do
-        Proc.new { @server.unlisten }.should_not raise_error
-    end
-end
- 
-describe Puppet::Network::Server, &quot;when listening is being turned on&quot; do
-    before do
-        @mock_http_server_class = mock('http server class')
-        Puppet::Network::HTTP.stubs(:server_class_by_type).returns(@mock_http_server_class)
-        Puppet.stubs(:[]).with(:servertype).returns(:suparserver)
-        @server = Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337, :handlers =&gt; [:node])
-        @mock_http_server = mock('http server')
-        @mock_http_server.stubs(:listen)
-    end
+    describe &quot;when managing xmlrpc registrations&quot; do
+        before do
+            Puppet::Network::Handler.stubs(:handler).returns mock('xmlrpc_handler')
+        end
 
-    it &quot;should fetch an instance of an HTTP server&quot; do
-        @server.stubs(:http_server_class).returns(@mock_http_server_class)
-        @mock_http_server_class.expects(:new).returns(@mock_http_server)
-        @server.listen        
-    end
+        it &quot;should allow registering an xmlrpc handler by specifying its namespace&quot; do
+            lambda { @server.register_xmlrpc(:foo) }.should_not raise_error
+        end
 
-    it &quot;should cause the HTTP server to listen&quot; do
-        @server.stubs(:http_server).returns(@mock_http_server)
-        @mock_http_server.expects(:listen)
-        @server.listen
-    end
-    
-    it &quot;should pass the listening address to the HTTP server&quot; do
-       @server.stubs(:http_server).returns(@mock_http_server)
-       @mock_http_server.expects(:listen).with do |args|
-            args[:address] == '127.0.0.1'
-       end
-       @server.listen
-    end
-    
-    it &quot;should pass the listening port to the HTTP server&quot; do
-      @server.stubs(:http_server).returns(@mock_http_server)
-      @mock_http_server.expects(:listen).with do |args|
-           args[:port] == 31337
-      end
-      @server.listen
-    end
-    
-    it &quot;should pass a list of handlers to the HTTP server&quot; do
-      @server.stubs(:http_server).returns(@mock_http_server)
-      @mock_http_server.expects(:listen).with do |args|
-           args[:handlers] == [ :node ]
-      end
-      @server.listen
+        it &quot;should require that the xmlrpc namespace be valid&quot; do
+            Puppet::Network::Handler.stubs(:handler).returns nil
+
+            lambda { @server.register_xmlrpc(:foo) }.should raise_error(ArgumentError)
+        end
+
+        it &quot;should require at least one namespace&quot; do
+            lambda { @server.register_xmlrpc() }.should raise_error(ArgumentError)
+        end
+
+        it &quot;should allow multiple namespaces to be registered at once&quot; do
+            lambda { @server.register_xmlrpc(:foo, :bar) }.should_not raise_error
+        end
+
+        it &quot;should allow the use of namespaces to specify which are no longer accessible to clients&quot; do
+            @server.register_xmlrpc(:foo, :bar)
+        end
+
+        it &quot;should leave other namespaces accessible to clients when turning off xmlrpc namespaces&quot; do
+            @server.register_xmlrpc(:foo, :bar)
+            @server.unregister_xmlrpc(:foo)
+            lambda { @server.unregister_xmlrpc(:bar)}.should_not raise_error
+        end
+
+        it &quot;should allow specifying numerous namespaces which are to be no longer accessible to clients&quot; do
+            @server.register_xmlrpc(:foo, :bar)
+            lambda { @server.unregister_xmlrpc(:foo, :bar) }.should_not raise_error
+        end
+
+        it &quot;should not turn off any indirections if given unknown namespaces to turn off&quot; do
+            @server.register_xmlrpc(:foo, :bar)
+            lambda { @server.unregister_xmlrpc(:foo, :bar, :baz) }.should raise_error(ArgumentError)
+            lambda { @server.unregister_xmlrpc(:foo, :bar) }.should_not raise_error
+        end
+
+        it &quot;should not allow turning off unknown namespaces&quot; do
+            @server.register_xmlrpc(:foo, :bar)
+            lambda { @server.unregister_xmlrpc(:baz) }.should raise_error(ArgumentError)
+        end
+
+        it &quot;should disable client access immediately when turning off namespaces&quot; do
+            @server.register_xmlrpc(:foo, :bar)
+            @server.unregister_xmlrpc(:foo)    
+            lambda { @server.unregister_xmlrpc(:foo) }.should raise_error(ArgumentError)
+        end
+
+        it &quot;should allow turning off all namespaces at once&quot; do
+            @server.register_xmlrpc(:foo, :bar)
+            @server.unregister_xmlrpc
+            [ :foo, :bar, :baz].each do |indirection|
+                lambda { @server.unregister_xmlrpc(indirection) }.should raise_error(ArgumentError)
+            end
+        end
     end
-    
-    it &quot;should pass a list of protocols to the HTTP server&quot; do
-      @server.stubs(:http_server).returns(@mock_http_server)
-      @mock_http_server.expects(:listen).with do |args|
-           args[:protocols] == [ :rest ]
-      end
-      @server.listen      
+
+    describe &quot;when listening is off&quot; do
+        before do
+            @mock_http_server = mock('http server')
+            @mock_http_server.stubs(:listen)
+            @server.stubs(:http_server).returns(@mock_http_server)
+        end
+
+        it &quot;should indicate that it is not listening&quot; do
+            @server.should_not be_listening
+        end  
+
+        it &quot;should not allow listening to be turned off&quot; do
+            lambda { @server.unlisten }.should raise_error(RuntimeError)
+        end
+
+        it &quot;should allow listening to be turned on&quot; do
+            lambda { @server.listen }.should_not raise_error
+        end
+
     end
-end
 
-describe Puppet::Network::Server, &quot;when listening is being turned off&quot; do
-    before do
-        @mock_http_server_class = mock('http server class')
-        Puppet::Network::HTTP.stubs(:server_class_by_type).returns(@mock_http_server_class)
-        Puppet.stubs(:[]).with(:servertype).returns(:suparserver)
-        @server = Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337)
-        @mock_http_server = mock('http server')
-        @mock_http_server.stubs(:listen)
-        @server.stubs(:http_server).returns(@mock_http_server)
-        @server.listen
+    describe &quot;when listening is on&quot; do
+        before do
+            @mock_http_server = mock('http server')
+            @mock_http_server.stubs(:listen)
+            @mock_http_server.stubs(:unlisten)
+            @server.stubs(:http_server).returns(@mock_http_server)
+            @server.listen
+        end
+
+        it &quot;should indicate that it is listening&quot; do
+            @server.should be_listening
+        end
+
+        it &quot;should not allow listening to be turned on&quot; do
+            lambda { @server.listen }.should raise_error(RuntimeError)
+        end
+
+        it &quot;should allow listening to be turned off&quot; do
+            lambda { @server.unlisten }.should_not raise_error
+        end
     end
 
-    it &quot;should cause the HTTP server to stop listening&quot; do
-        @mock_http_server.expects(:unlisten)
-        @server.unlisten
+    describe &quot;when listening is being turned on&quot; do
+        before do
+            Puppet::Indirector::Indirection.stubs(:model).returns mock('indirection')
+            Puppet::Network::Handler.stubs(:handler).returns mock('xmlrpc_handler')
+
+            @server = Puppet::Network::Server.new(:address =&gt; &quot;127.0.0.1&quot;, :port =&gt; 31337, :handlers =&gt; [:node], :xmlrpc_handlers =&gt; [:master])
+            @mock_http_server = mock('http server')
+            @mock_http_server.stubs(:listen)
+        end
+
+        it &quot;should fetch an instance of an HTTP server&quot; do
+            @server.stubs(:http_server_class).returns(@mock_http_server_class)
+            @mock_http_server_class.expects(:new).returns(@mock_http_server)
+            @server.listen        
+        end
+
+        it &quot;should cause the HTTP server to listen&quot; do
+            @server.stubs(:http_server).returns(@mock_http_server)
+            @mock_http_server.expects(:listen)
+            @server.listen
+        end
+
+        it &quot;should pass the listening address to the HTTP server&quot; do
+           @server.stubs(:http_server).returns(@mock_http_server)
+           @mock_http_server.expects(:listen).with do |args|
+               args[:address] == '127.0.0.1'
+           end
+           @server.listen
+        end
+
+        it &quot;should pass the listening port to the HTTP server&quot; do
+            @server.stubs(:http_server).returns(@mock_http_server)
+            @mock_http_server.expects(:listen).with do |args|
+                args[:port] == 31337
+            end
+            @server.listen
+        end
+
+        it &quot;should pass a list of REST handlers to the HTTP server&quot; do
+            @server.stubs(:http_server).returns(@mock_http_server)
+            @mock_http_server.expects(:listen).with do |args|
+                args[:handlers] == [ :node ]
+            end
+            @server.listen
+        end
+
+        it &quot;should pass a list of XMLRPC handlers to the HTTP server&quot; do
+            @server.stubs(:http_server).returns(@mock_http_server)
+            @mock_http_server.expects(:listen).with do |args|
+                args[:xmlrpc_handlers] == [ :master ]
+            end
+            @server.listen
+        end
+
+        it &quot;should pass a list of protocols to the HTTP server&quot; do
+            @server.stubs(:http_server).returns(@mock_http_server)
+            @mock_http_server.expects(:listen).with do |args|
+               args[:protocols] == [ :rest, :xmlrpc ]
+            end
+            @server.listen      
+        end
     end
 
-    it &quot;should not allow for indirections to be turned off&quot; do
-        @server.register(:foo)
-        Proc.new { @server.unregister(:foo) }.should raise_error(RuntimeError) 
+    describe &quot;when listening is being turned off&quot; do
+        before do
+            @mock_http_server = mock('http server')
+            @mock_http_server.stubs(:listen)
+            @server.stubs(:http_server).returns(@mock_http_server)
+            @server.listen
+        end
+
+        it &quot;should cause the HTTP server to stop listening&quot; do
+            @mock_http_server.expects(:unlisten)
+            @server.unlisten
+        end
+
+        it &quot;should not allow for indirections to be turned off&quot; do
+            Puppet::Indirector::Indirection.stubs(:model).returns mock('indirection')
+
+            @server.register(:foo)
+            lambda { @server.unregister(:foo) }.should raise_error(RuntimeError) 
+        end
     end
-end
 
-                
-describe Class.new, &quot;put these somewhere&quot; do
-    it &quot;should have the ability to use a class-level from_ hook (from_yaml, from_text, etc.) that can be called, based on content-type header, to allow for different deserializations of an object&quot; 
-    it &quot;should allow from_* on the inbound :data packet (look at its content_type) when doing a PUT/.new.save&quot;
-    it &quot;should prepend a rest version number on the path (w00t)&quot;
-    it &quot;should ... on server side, .save should from_yaml, then foo.save(args) instead of just Foo.new.save(args)&quot;
+
+    describe Class.new, &quot;put these somewhere&quot; do
+        it &quot;should have the ability to use a class-level from_ hook (from_yaml, from_text, etc.) that can be called, based on content-type header, to allow for different deserializations of an object&quot; 
+        it &quot;should allow from_* on the inbound :data packet (look at its content_type) when doing a PUT/.new.save&quot;
+        it &quot;should prepend a rest version number on the path (w00t)&quot;
+        it &quot;should ... on server side, .save should from_yaml, then foo.save(args) instead of just Foo.new.save(args)&quot;
+    end
 end</diff>
      <filename>spec/unit/network/server.rb</filename>
    </modified>
    <modified>
      <diff>@@ -148,7 +148,7 @@ describe Puppet::Node, &quot; when indirecting&quot; do
     end
 
     after do
-        Puppet::Indirector::Indirection.clear_cache
+        Puppet::Util::Cacher.invalidate
     end
 end
 </diff>
      <filename>spec/unit/node.rb</filename>
    </modified>
    <modified>
      <diff>@@ -578,6 +578,7 @@ describe Puppet::Node::Catalog do
         # super() doesn't work in the setup method for some reason
         before do
             @catalog.host_config = true
+            Puppet::Util::Storage.stubs(:store)
         end
 
         it &quot;should send a report if reporting is enabled&quot; do
@@ -796,7 +797,7 @@ describe Puppet::Node::Catalog, &quot; when indirecting&quot; do
     before do
         @indirection = stub 'indirection', :name =&gt; :catalog
 
-        Puppet::Indirector::Indirection.clear_cache
+        Puppet::Util::Cacher.invalidate
     end
 
     it &quot;should redirect to the indirection for retrieval&quot; do
@@ -810,8 +811,7 @@ describe Puppet::Node::Catalog, &quot; when indirecting&quot; do
     end
 
     after do
-        mocha_verify
-        Puppet::Indirector::Indirection.clear_cache
+        Puppet::Util::Cacher.invalidate
     end
 end
 </diff>
      <filename>spec/unit/node/catalog.rb</filename>
    </modified>
    <modified>
      <diff>@@ -10,7 +10,8 @@ describe Puppet::Node::Facts, &quot; when indirecting&quot; do
 
         # We have to clear the cache so that the facts ask for our indirection stub,
         # instead of anything that might be cached.
-        Puppet::Indirector::Indirection.clear_cache
+        Puppet::Util::Cacher.invalidate
+
         @facts = Puppet::Node::Facts.new(&quot;me&quot;, &quot;one&quot; =&gt; &quot;two&quot;)
     end
 
@@ -29,11 +30,6 @@ describe Puppet::Node::Facts, &quot; when indirecting&quot; do
     it &quot;should default to the 'facter' terminus&quot; do
         Puppet::Node::Facts.indirection.terminus_class.should == :facter
     end
-
-    after do
-        mocha_verify
-        Puppet::Indirector::Indirection.clear_cache
-    end
 end
 
 describe Puppet::Node::Facts, &quot; when storing and retrieving&quot; do</diff>
      <filename>spec/unit/node/facts.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,6 +6,14 @@ require 'puppet/rails'
 describe Puppet::Rails, &quot;when initializing any connection&quot; do
     confine Puppet.features.rails? =&gt; &quot;Cannot test without ActiveRecord&quot; 
 
+    before do
+        @logger = stub 'logger', :level= =&gt; nil
+        @logger.stub_everything
+        Logger.stubs(:new).returns(@logger)
+
+        ActiveRecord::Base.stubs(:logger).returns(@logger)
+    end
+
     it &quot;should use settings&quot; do
         Puppet.settings.expects(:use).with(:main, :rails, :puppetmasterd)
         </diff>
      <filename>spec/unit/rails.rb</filename>
    </modified>
    <modified>
      <diff>@@ -4,41 +4,76 @@ require File.dirname(__FILE__) + '/../../spec_helper'
 
 require 'puppet/ssl/certificate_authority'
 
-describe &quot;a normal interface method&quot;, :shared =&gt; true do
-    it &quot;should call the method on the CA for each host specified if an array was provided&quot; do
-        @ca.expects(@method).with(&quot;host1&quot;)
-        @ca.expects(@method).with(&quot;host2&quot;)
-
-        @applier = Puppet::SSL::CertificateAuthority::Interface.new(@method, %w{host1 host2})
+describe Puppet::SSL::CertificateAuthority do
+    after do
+        # Clear out the var, yay unit tests.
+        Puppet::SSL::CertificateAuthority.instance_variable_set(&quot;@instance&quot;, nil)
+        Puppet.settings.clearused
+    end
 
-        @applier.apply(@ca)
+    it &quot;should have a class method for returning a singleton instance&quot; do
+        Puppet::SSL::CertificateAuthority.should respond_to(:instance)
     end
 
-    it &quot;should call the method on the CA for all existing certificates if :all was provided&quot; do
-        @ca.expects(:list).returns %w{host1 host2}
+    describe &quot;when finding an existing instance&quot; do
+        describe &quot;and the host is a CA host and the proces name is 'puppetmasterd'&quot; do
+            before do
+                Puppet.settings.stubs(:value).with(:ca).returns true
+                Puppet.settings.stubs(:value).with(:name).returns &quot;puppetmasterd&quot;
+
+                @ca = mock('ca')
+                Puppet::SSL::CertificateAuthority.stubs(:new).returns @ca
+            end
+
+            after do
+                # Clear out the var, yay unit tests.
+                Puppet::SSL::CertificateAuthority.instance_variable_set(&quot;@instance&quot;, nil)
+            end
 
-        @ca.expects(@method).with(&quot;host1&quot;)
-        @ca.expects(@method).with(&quot;host2&quot;)
+            it &quot;should return an instance&quot; do
+                Puppet::SSL::CertificateAuthority.instance.should equal(@ca)
+            end
 
-        @applier = Puppet::SSL::CertificateAuthority::Interface.new(@method, :all)
+            it &quot;should always return the same instance&quot; do
+                Puppet::SSL::CertificateAuthority.instance.should equal(Puppet::SSL::CertificateAuthority.instance)
+            end
+        end
 
-        @applier.apply(@ca)
+        describe &quot;and the host is not a CA host&quot; do
+            it &quot;should return nil&quot; do
+                Puppet.settings.stubs(:value).with(:ca).returns false
+                Puppet.settings.stubs(:value).with(:name).returns &quot;puppetmasterd&quot;
+
+                ca = mock('ca')
+                Puppet::SSL::CertificateAuthority.expects(:new).never
+                Puppet::SSL::CertificateAuthority.instance.should be_nil
+            end
+        end
+
+        describe &quot;and the process name is not 'puppetmasterd'&quot; do
+            it &quot;should return nil&quot; do
+                Puppet.settings.stubs(:value).with(:ca).returns true
+                Puppet.settings.stubs(:value).with(:name).returns &quot;puppetd&quot;
+
+                ca = mock('ca')
+                Puppet::SSL::CertificateAuthority.expects(:new).never
+                Puppet::SSL::CertificateAuthority.instance.should be_nil
+            end
+        end
     end
-end
 
-describe Puppet::SSL::CertificateAuthority do
     describe &quot;when initializing&quot; do
         before do
             Puppet.settings.stubs(:use)
-            Puppet.settings.stubs(:value).returns &quot;whatever&quot;
+            Puppet.settings.stubs(:value).returns &quot;ca_testing&quot;
 
-            Puppet::SSL::CertificateAuthority.any_instance.stubs(:generate_ca_certificate)
+            Puppet::SSL::CertificateAuthority.any_instance.stubs(:setup)
         end
 
         it &quot;should always set its name to the value of :certname&quot; do
-            Puppet.settings.expects(:value).with(:certname).returns &quot;whatever&quot;
+            Puppet.settings.expects(:value).with(:certname).returns &quot;ca_testing&quot;
 
-            Puppet::SSL::CertificateAuthority.new.name.should == &quot;whatever&quot;
+            Puppet::SSL::CertificateAuthority.new.name.should == &quot;ca_testing&quot;
         end
 
         it &quot;should create an SSL::Host instance whose name is the 'ca_name'&quot; do
@@ -60,72 +95,73 @@ describe Puppet::SSL::CertificateAuthority do
 
             Puppet::SSL::CertificateAuthority.new.inventory.should == &quot;inventory&quot;
         end
-    end
 
-    describe &quot;when retrieving the certificate revocation list&quot; do
-        before do
-            Puppet.settings.stubs(:use)
-            Puppet.settings.stubs(:value).returns &quot;whatever&quot;
+        it &quot;should make sure the CA is set up&quot; do
+            Puppet::SSL::CertificateAuthority.any_instance.expects(:setup)
 
-            Puppet::SSL::CertificateAuthority.any_instance.stubs(:generate_ca_certificate)
-            @ca = Puppet::SSL::CertificateAuthority.new
+            Puppet::SSL::CertificateAuthority.new
         end
+    end
 
-        describe &quot;and the CRL is disabled&quot; do
-            it &quot;should return nil when the :cacrl is false&quot; do
-                Puppet.settings.stubs(:value).with(:cacrl).returns false
-
-                Puppet::SSL::CertificateRevocationList.expects(:new).never
-
-                @ca.crl.should be_nil
-            end
+    describe &quot;when setting itself up&quot; do
+        it &quot;should generate the CA certificate if it does not have one&quot; do
+            Puppet.settings.stubs :use
 
-            it &quot;should return nil when the :cacrl is 'false'&quot; do
-                Puppet.settings.stubs(:value).with(:cacrl).returns 'false'
+            host = stub 'host'
+            Puppet::SSL::Host.stubs(:new).returns host
 
-                Puppet::SSL::CertificateRevocationList.expects(:new).never
+            host.expects(:certificate).returns nil
 
-                @ca.crl.should be_nil
-            end
+            Puppet::SSL::CertificateAuthority.any_instance.expects(:generate_ca_certificate)
+            Puppet::SSL::CertificateAuthority.new
         end
+    end
 
-        describe &quot;and the CRL is enabled&quot; do
-            before do
-                Puppet.settings.stubs(:value).with(:cacrl).returns &quot;/my/crl&quot;
+    describe &quot;when retrieving the certificate revocation list&quot; do
+        before do
+            Puppet.settings.stubs(:use)
+            Puppet.settings.stubs(:value).returns &quot;ca_testing&quot;
+            Puppet.settings.stubs(:value).with(:cacrl).returns &quot;/my/crl&quot;
 
-                cert = stub(&quot;certificate&quot;, :content =&gt; &quot;real_cert&quot;)
-                @host = stub 'host', :certificate =&gt; cert, :name =&gt; &quot;hostname&quot;
+            cert = stub(&quot;certificate&quot;, :content =&gt; &quot;real_cert&quot;)
+            key = stub(&quot;key&quot;, :content =&gt; &quot;real_key&quot;)
+            @host = stub 'host', :certificate =&gt; cert, :name =&gt; &quot;hostname&quot;, :key =&gt; key
 
-                @ca.stubs(:host).returns @host
-            end
+            Puppet::SSL::CertificateAuthority.any_instance.stubs(:setup)
+            @ca = Puppet::SSL::CertificateAuthority.new
 
-            it &quot;should return any found CRL instance&quot; do
-                crl = mock 'crl'
-                Puppet::SSL::CertificateRevocationList.expects(:find).returns crl
-                @ca.crl.should equal(crl)
-            end
+            @ca.stubs(:host).returns @host
+        end
 
-            it &quot;should create and generate a new CRL instance of no CRL can be found&quot; do
-                crl = mock 'crl'
-                Puppet::SSL::CertificateRevocationList.expects(:find).returns nil
+        it &quot;should return any found CRL instance&quot; do
+            crl = mock 'crl'
+            Puppet::SSL::CertificateRevocationList.expects(:find).returns crl
+            @ca.crl.should equal(crl)
+        end
 
-                Puppet::SSL::CertificateRevocationList.expects(:new).returns crl
+        it &quot;should create, generate, and save a new CRL instance of no CRL can be found&quot; do
+            crl = mock 'crl'
+            Puppet::SSL::CertificateRevocationList.expects(:find).returns nil
 
-                crl.expects(:generate).with(@ca.host.certificate.content)
+            Puppet::SSL::CertificateRevocationList.expects(:new).returns crl
 
-                @ca.crl.should equal(crl)
-            end
+            crl.expects(:generate).with(@ca.host.certificate.content, @ca.host.key.content)
+            crl.expects(:save)
+
+            @ca.crl.should equal(crl)
         end
     end
 
     describe &quot;when generating a self-signed CA certificate&quot; do
         before do
             Puppet.settings.stubs(:use)
-            Puppet.settings.stubs(:value).returns &quot;whatever&quot;
+            Puppet.settings.stubs(:value).returns &quot;ca_testing&quot;
 
+            Puppet::SSL::CertificateAuthority.any_instance.stubs(:setup)
+            Puppet::SSL::CertificateAuthority.any_instance.stubs(:crl)
             @ca = Puppet::SSL::CertificateAuthority.new
 
-            @host = stub 'host', :key =&gt; mock(&quot;key&quot;), :name =&gt; &quot;hostname&quot;
+            @host = stub 'host', :key =&gt; mock(&quot;key&quot;), :name =&gt; &quot;hostname&quot;, :certificate =&gt; mock('certificate')
 
             Puppet::SSL::CertificateRequest.any_instance.stubs(:generate)
 
@@ -168,6 +204,18 @@ describe Puppet::SSL::CertificateAuthority do
 
             @ca.generate_ca_certificate
         end
+
+        it &quot;should generate its CRL&quot; do
+            @ca.stubs :generate_password
+            @ca.stubs :sign
+
+            @ca.host.expects(:key).returns nil
+            @ca.host.expects(:generate_key)
+
+            @ca.expects(:crl)
+
+            @ca.generate_ca_certificate
+        end
     end
 
     describe &quot;when signing&quot; do
@@ -222,7 +270,7 @@ describe Puppet::SSL::CertificateAuthority do
             end
 
             it &quot;should return the current content of the serial file&quot; do
-                FileTest.expects(:exist?).with(@path).returns true
+                FileTest.stubs(:exist?).with(@path).returns true
                 File.expects(:read).with(@path).returns &quot;0002&quot;
 
                 @ca.next_serial.should == 2
@@ -297,15 +345,6 @@ describe Puppet::SSL::CertificateAuthority do
                 @cert.stubs :save
             end
 
-            it &quot;should generate a self-signed certificate if its Host instance has no certificate&quot; do
-                cert = stub 'ca_certificate', :content =&gt; &quot;mock_cert&quot;
-
-                @ca.host.expects(:certificate).times(2).returns(nil).then.returns cert
-                @ca.expects(:generate_ca_certificate)
-
-                @ca.sign(@name)
-            end
-
             it &quot;should use a certificate type of :server&quot; do
                 Puppet::SSL::CertificateFactory.expects(:new).with do |*args|
                     args[0] == :server
@@ -375,18 +414,98 @@ describe Puppet::SSL::CertificateAuthority do
         end
 
         it &quot;should return the certificate instance&quot; do
+            @ca.stubs(:next_serial).returns @serial
             Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request
             @cert.stubs :save
             @ca.sign(@name).should equal(@cert)
         end
 
         it &quot;should add the certificate to its inventory&quot; do
+            @ca.stubs(:next_serial).returns @serial
             @inventory.expects(:add).with(@cert)
 
             Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request
             @cert.stubs :save
             @ca.sign(@name)
         end
+
+        it &quot;should have a method for triggering autosigning of available CSRs&quot; do
+            @ca.should respond_to(:autosign)
+        end
+
+        describe &quot;when autosigning certificates&quot; do
+            it &quot;should do nothing if autosign is disabled&quot; do
+                Puppet.settings.expects(:value).with(:autosign).returns 'false'
+
+                Puppet::SSL::CertificateRequest.expects(:search).never
+                @ca.autosign
+            end
+
+            it &quot;should do nothing if no autosign.conf exists&quot; do
+                Puppet.settings.expects(:value).with(:autosign).returns '/auto/sign'
+                FileTest.expects(:exist?).with(&quot;/auto/sign&quot;).returns false
+
+                Puppet::SSL::CertificateRequest.expects(:search).never
+                @ca.autosign
+            end
+
+            describe &quot;and autosign is enabled and the autosign.conf file exists&quot; do
+                before do
+                    Puppet.settings.stubs(:value).with(:autosign).returns '/auto/sign'
+                    FileTest.stubs(:exist?).with(&quot;/auto/sign&quot;).returns true
+                    File.stubs(:readlines).with(&quot;/auto/sign&quot;).returns [&quot;one\n&quot;, &quot;two\n&quot;]
+
+                    Puppet::SSL::CertificateRequest.stubs(:search).returns []
+
+                    @store = stub 'store', :allow =&gt; nil
+                    Puppet::Network::AuthStore.stubs(:new).returns @store
+                end
+
+                describe &quot;when creating the AuthStore instance to verify autosigning&quot; do
+                    it &quot;should create an AuthStore with each line in the configuration file allowed to be autosigned&quot; do
+                        Puppet::Network::AuthStore.expects(:new).returns @store
+
+                        @store.expects(:allow).with(&quot;one&quot;)
+                        @store.expects(:allow).with(&quot;two&quot;)
+
+                        @ca.autosign
+                    end
+
+                    it &quot;should reparse the autosign configuration on each call&quot; do
+                        Puppet::Network::AuthStore.expects(:new).times(2).returns @store
+
+                        @ca.autosign
+                        @ca.autosign
+                    end
+
+                    it &quot;should ignore comments&quot; do
+                        File.stubs(:readlines).with(&quot;/auto/sign&quot;).returns [&quot;one\n&quot;, &quot;#two\n&quot;]
+
+                        @store.expects(:allow).with(&quot;one&quot;)
+                        @ca.autosign
+                    end
+
+                    it &quot;should ignore blank lines&quot; do
+                        File.stubs(:readlines).with(&quot;/auto/sign&quot;).returns [&quot;one\n&quot;, &quot;\n&quot;]
+
+                        @store.expects(:allow).with(&quot;one&quot;)
+                        @ca.autosign
+                    end
+                end
+
+                it &quot;should sign all CSRs whose hostname matches the autosign configuration&quot; do
+                    csr1 = mock 'csr1'
+                    csr2 = mock 'csr2'
+                    Puppet::SSL::CertificateRequest.stubs(:search).returns [csr1, csr2]
+                end
+
+                it &quot;should not sign CSRs whose hostname does not match the autosign configuration&quot; do
+                    csr1 = mock 'csr1'
+                    csr2 = mock 'csr2'
+                    Puppet::SSL::CertificateRequest.stubs(:search).returns [csr1, csr2]
+                end
+            end
+        end
     end
 
     describe &quot;when managing certificate clients&quot; do
@@ -398,7 +517,9 @@ describe Puppet::SSL::CertificateAuthority do
             # Set up the CA
             @key = mock 'key'
             @key.stubs(:content).returns &quot;cakey&quot;
-            Puppet::SSL::CertificateAuthority.any_instance.stubs(:key).returns @key
+            @host = stub 'host', :key =&gt; @key
+            Puppet::SSL::CertificateAuthority.any_instance.stubs(:host).returns @host
+
             @cacert = mock 'certificate'
             @cacert.stubs(:content).returns &quot;cacertificate&quot;
             @ca = Puppet::SSL::CertificateAuthority.new
@@ -422,7 +543,7 @@ describe Puppet::SSL::CertificateAuthority do
                 applier = stub('applier')
                 applier.expects(:apply).with(@ca)
                 Puppet::SSL::CertificateAuthority::Interface.expects(:new).returns applier
-                @ca.apply(:generate, :to =&gt; :whatever)
+                @ca.apply(:generate, :to =&gt; :ca_testing)
             end
         end
 
@@ -533,12 +654,19 @@ describe Puppet::SSL::CertificateAuthority do
             before do
                 @crl = mock 'crl'
                 @ca.stubs(:crl).returns @crl
+
+                @ca.stubs(:next_serial).returns 10
+
+                @real_cert = stub 'real_cert', :serial =&gt; 15
+                @cert = stub 'cert', :content =&gt; @real_cert
+                Puppet::SSL::Certificate.stubs(:find).returns @cert
+
             end
 
             it &quot;should fail if the certificate revocation list is disabled&quot; do
                 @ca.stubs(:crl).returns false
 
-                lambda { @ca.revoke('whatever') }.should raise_error(ArgumentError)
+                lambda { @ca.revoke('ca_testing') }.should raise_error(ArgumentError)
 
             end
 
@@ -549,12 +677,10 @@ describe Puppet::SSL::CertificateAuthority do
             end
 
             it &quot;should get the serial number from the local certificate if it exists&quot; do
-                real_cert = stub 'real_cert', :serial =&gt; 15
-                cert = stub 'cert', :content =&gt; real_cert
-                Puppet::SSL::Certificate.expects(:find).with(&quot;host&quot;).returns cert
-
                 @ca.crl.expects(:revoke).with { |serial, key| serial == 15 }
 
+                Puppet::SSL::Certificate.expects(:find).with(&quot;host&quot;).returns @cert
+
                 @ca.revoke('host')
             end
 
@@ -609,241 +735,3 @@ describe Puppet::SSL::CertificateAuthority do
         end
     end
 end
-
-describe Puppet::SSL::CertificateAuthority::Interface do
-    before do
-        @class = Puppet::SSL::CertificateAuthority::Interface
-    end
-    describe &quot;when initializing&quot; do
-        it &quot;should set its method using its settor&quot; do
-            @class.any_instance.expects(:method=).with(:generate)
-            @class.new(:generate, :all)
-        end
-
-        it &quot;should set its subjects using the settor&quot; do
-            @class.any_instance.expects(:subjects=).with(:all)
-            @class.new(:generate, :all)
-        end
-    end
-
-    describe &quot;when setting the method&quot; do
-        it &quot;should set the method&quot; do
-            @class.new(:generate, :all).method.should == :generate
-        end
-
-        it &quot;should fail if the method isn't a member of the INTERFACE_METHODS array&quot; do
-            Puppet::SSL::CertificateAuthority::Interface::INTERFACE_METHODS.expects(:include?).with(:thing).returns false
-
-            lambda { @class.new(:thing, :all) }.should raise_error(ArgumentError)
-        end
-    end
-
-    describe &quot;when setting the subjects&quot; do
-        it &quot;should set the subjects&quot; do
-            @class.new(:generate, :all).subjects.should == :all
-        end
-
-        it &quot;should fail if the subjects setting isn't :all or an array&quot; do
-            lambda { @class.new(:generate, &quot;other&quot;) }.should raise_error(ArgumentError)
-        end
-    end
-
-    it &quot;should have a method for triggering the application&quot; do
-        @class.new(:generate, :all).should respond_to(:apply)
-    end
-
-    describe &quot;when applying&quot; do
-        before do
-            # We use a real object here, because :verify can't be stubbed, apparently.
-            @ca = Object.new
-        end
-
-        it &quot;should raise InterfaceErrors&quot; do
-            @applier = @class.new(:revoke, :all)
-
-            @ca.expects(:list).raises Puppet::SSL::CertificateAuthority::Interface::InterfaceError
-
-            lambda { @applier.apply(@ca) }.should raise_error(Puppet::SSL::CertificateAuthority::Interface::InterfaceError)
-        end
-
-        it &quot;should log non-Interface failures rather than failing&quot; do
-            @applier = @class.new(:revoke, :all)
-
-            @ca.expects(:list).raises ArgumentError
-
-            Puppet.expects(:err)
-
-            lambda { @applier.apply(@ca) }.should_not raise_error
-        end
-
-        describe &quot;with an empty array specified and the method is not list&quot; do
-            it &quot;should fail&quot; do
-                @applier = @class.new(:sign, [])
-                lambda { @applier.apply(@ca) }.should raise_error(ArgumentError)
-            end
-        end
-
-        describe &quot;:generate&quot; do
-            it &quot;should fail if :all was specified&quot; do
-                @applier = @class.new(:generate, :all)
-                lambda { @applier.apply(@ca) }.should raise_error(ArgumentError)
-            end
-
-            it &quot;should call :generate on the CA for each host specified&quot; do
-                @applier = @class.new(:generate, %w{host1 host2})
-                
-                @ca.expects(:generate).with(&quot;host1&quot;)
-                @ca.expects(:generate).with(&quot;host2&quot;)
-
-                @applier.apply(@ca)
-            end
-        end
-
-        describe &quot;:verify&quot; do
-            before { @method = :verify }
-            #it_should_behave_like &quot;a normal interface method&quot;
-
-            it &quot;should call the method on the CA for each host specified if an array was provided&quot; do
-                # LAK:NOTE Mocha apparently doesn't allow you to mock :verify, but I'm confident this works in real life.
-            end
-
-            it &quot;should call the method on the CA for all existing certificates if :all was provided&quot; do
-                # LAK:NOTE Mocha apparently doesn't allow you to mock :verify, but I'm confident this works in real life.
-            end
-        end
-
-        describe &quot;:destroy&quot; do
-            before { @method = :destroy }
-            it_should_behave_like &quot;a normal interface method&quot;
-        end
-
-        describe &quot;:revoke&quot; do
-            before { @method = :revoke }
-            it_should_behave_like &quot;a normal interface method&quot;
-        end
-
-        describe &quot;:sign&quot; do
-            describe &quot;and an array of names was provided&quot; do
-                before do
-                    @applier = @class.new(:sign, %w{host1 host2})
-                end
-
-                it &quot;should sign the specified waiting certificate requests&quot; do
-                    @ca.expects(:sign).with(&quot;host1&quot;)
-                    @ca.expects(:sign).with(&quot;host2&quot;)
-
-                    @applier.apply(@ca)
-                end
-            end
-
-            describe &quot;and :all was provided&quot; do
-                it &quot;should sign all waiting certificate requests&quot; do
-                    @ca.stubs(:waiting?).returns(%w{cert1 cert2})
-
-                    @ca.expects(:sign).with(&quot;cert1&quot;)
-                    @ca.expects(:sign).with(&quot;cert2&quot;)
-
-                    @applier = @class.new(:sign, :all)
-                    @applier.apply(@ca)
-                end
-
-                it &quot;should fail if there are no waiting certificate requests&quot; do
-                    @ca.stubs(:waiting?).returns([])
-
-                    @applier = @class.new(:sign, :all)
-                    lambda { @applier.apply(@ca) }.should raise_error(Puppet::SSL::CertificateAuthority::Interface::InterfaceError)
-                end
-            end
-        end
-
-        describe &quot;:list&quot; do
-            describe &quot;and an empty array was provided&quot; do
-                it &quot;should print a string containing all certificate requests&quot; do
-                    @ca.expects(:waiting?).returns %w{host1 host2}
-
-                    @applier = @class.new(:list, [])
-
-                    @applier.expects(:puts).with &quot;host1\nhost2&quot;
-
-                    @applier.apply(@ca)
-                end
-            end
-
-            describe &quot;and :all was provided&quot; do
-                it &quot;should print a string containing all certificate requests and certificates&quot; do
-                    @ca.expects(:waiting?).returns %w{host1 host2}
-                    @ca.expects(:list).returns %w{host3 host4}
-
-                    @applier = @class.new(:list, :all)
-
-                    @applier.expects(:puts).with &quot;host1&quot;
-                    @applier.expects(:puts).with &quot;host2&quot;
-                    @applier.expects(:puts).with &quot;+ host3&quot;
-                    @applier.expects(:puts).with &quot;+ host4&quot;
-
-                    @applier.apply(@ca)
-                end
-            end
-
-            describe &quot;and an array of names was provided&quot; do
-                it &quot;should print a string of all named hosts that have a waiting request&quot; do
-                    @ca.expects(:waiting?).returns %w{host1 host2}
-                    @ca.expects(:list).returns %w{host3 host4}
-
-                    @applier = @class.new(:list, %w{host1 host2 host3 host4})
-
-                    @applier.expects(:puts).with &quot;host1&quot;
-                    @applier.expects(:puts).with &quot;host2&quot;
-                    @applier.expects(:puts).with &quot;+ host3&quot;
-                    @applier.expects(:puts).with &quot;+ host4&quot;
-
-                    @applier.apply(@ca)
-                end
-            end
-        end
-
-        describe &quot;:print&quot; do
-            describe &quot;and :all was provided&quot; do
-                it &quot;should print all certificates&quot; do
-                    @ca.expects(:list).returns %w{host1 host2}
-
-                    @applier = @class.new(:print, :all)
-
-                    @ca.expects(:print).with(&quot;host1&quot;).returns &quot;h1&quot;
-                    @applier.expects(:puts).with &quot;h1&quot;
-
-                    @ca.expects(:print).with(&quot;host2&quot;).returns &quot;h2&quot;
-                    @applier.expects(:puts).with &quot;h2&quot;
-
-                    @applier.apply(@ca)
-                end
-            end
-
-            describe &quot;and an array of names was provided&quot; do
-                it &quot;should print each named certificate if found&quot; do
-                    @applier = @class.new(:print, %w{host1 host2})
-
-                    @ca.expects(:print).with(&quot;host1&quot;).returns &quot;h1&quot;
-                    @applier.expects(:puts).with &quot;h1&quot;
-
-                    @ca.expects(:print).with(&quot;host2&quot;).returns &quot;h2&quot;
-                    @applier.expects(:puts).with &quot;h2&quot;
-
-                    @applier.apply(@ca)
-                end
-
-                it &quot;should log any named but not found certificates&quot; do
-                    @applier = @class.new(:print, %w{host1 host2})
-
-                    @ca.expects(:print).with(&quot;host1&quot;).returns &quot;h1&quot;
-                    @applier.expects(:puts).with &quot;h1&quot;
-
-                    @ca.expects(:print).with(&quot;host2&quot;).returns nil
-                    Puppet.expects(:err).with { |msg| msg.include?(&quot;host2&quot;) }
-
-                    @applier.apply(@ca)
-                end
-            end
-        end
-    end
-end</diff>
      <filename>spec/unit/ssl/certificate_authority.rb</filename>
    </modified>
    <modified>
      <diff>@@ -139,4 +139,29 @@ describe Puppet::SSL::CertificateRequest do
             @instance.content.should equal(@request)
         end
     end
+
+    describe &quot;when a CSR is saved&quot; do
+        describe &quot;and a CA is available&quot; do
+            it &quot;should save the CSR and trigger autosigning&quot; do
+                ca = mock 'ca', :autosign
+                Puppet::SSL::CertificateAuthority.expects(:instance).returns ca
+
+                csr = Puppet::SSL::CertificateRequest.new(&quot;me&quot;)
+                Puppet::SSL::CertificateRequest.indirection.expects(:save).with(csr)
+
+                csr.save
+            end
+        end
+
+        describe &quot;and a CA is not available&quot; do
+            it &quot;should save the CSR&quot; do
+                Puppet::SSL::CertificateAuthority.expects(:instance).returns nil
+
+                csr = Puppet::SSL::CertificateRequest.new(&quot;me&quot;)
+                Puppet::SSL::CertificateRequest.indirection.expects(:save).with(csr)
+
+                csr.save
+            end
+        end
+    end
 end</diff>
      <filename>spec/unit/ssl/certificate_request.rb</filename>
    </modified>
    <modified>
      <diff>@@ -7,6 +7,7 @@ require 'puppet/ssl/certificate_revocation_list'
 describe Puppet::SSL::CertificateRevocationList do
     before do
         @cert = stub 'cert', :subject =&gt; &quot;mysubject&quot;
+        @key = stub 'key', :private? =&gt; true
 
         @class = Puppet::SSL::CertificateRevocationList
     end
@@ -58,28 +59,50 @@ describe Puppet::SSL::CertificateRevocationList do
         it &quot;should set its issuer to the subject of the passed certificate&quot; do
             @real_crl.expects(:issuer=).with(@cert.subject)
 
-            @crl.generate(@cert)
+            @crl.generate(@cert, @key)
         end
 
         it &quot;should set its version to 1&quot; do
             @real_crl.expects(:version=).with(1)
 
-            @crl.generate(@cert)
+            @crl.generate(@cert, @key)
         end
 
         it &quot;should create an instance of OpenSSL::X509::CRL&quot; do
             OpenSSL::X509::CRL.expects(:new).returns(@real_crl)
 
-            @crl.generate(@cert)
+            @crl.generate(@cert, @key)
+        end
+
+        # The next three tests aren't good, but at least they
+        # specify the behaviour.
+        it &quot;should add an extension for the CRL number&quot; do
+            @real_crl.expects(:extensions=)
+            @crl.generate(@cert, @key)
+        end
+
+        it &quot;should set the last update time&quot; do
+            @real_crl.expects(:last_update=)
+            @crl.generate(@cert, @key)
+        end
+
+        it &quot;should set the next update time&quot; do
+            @real_crl.expects(:next_update=)
+            @crl.generate(@cert, @key)
+        end
+
+        it &quot;should sign the CRL&quot; do
+            @real_crl.expects(:sign).with { |key, digest| key == @key }
+            @crl.generate(@cert, @key)
         end
 
         it &quot;should set the content to the generated crl&quot; do
-            @crl.generate(@cert)
+            @crl.generate(@cert, @key)
             @crl.content.should equal(@real_crl)
         end
 
         it &quot;should return the generated crl&quot; do
-            @crl.generate(@cert).should equal(@real_crl)
+            @crl.generate(@cert, @key).should equal(@real_crl)
         end
     end
 
@@ -88,9 +111,10 @@ describe Puppet::SSL::CertificateRevocationList do
     describe &quot;when revoking a certificate&quot; do
         before do
             @class.wrapped_class.any_instance.stubs(:issuer=)
+            @class.wrapped_class.any_instance.stubs(:sign)
 
             @crl = @class.new(&quot;crl&quot;)
-            @crl.generate(@cert)
+            @crl.generate(@cert, @key)
             @crl.content.stubs(:sign)
 
             @crl.stubs :save</diff>
      <filename>spec/unit/ssl/certificate_revocation_list.rb</filename>
    </modified>
    <modified>
      <diff>@@ -155,6 +155,19 @@ describe Puppet::SSL::Host do
         end
     end
 
+    describe &quot;when initializing&quot; do
+        it &quot;should default its name to the :certname setting&quot; do
+            Puppet.settings.expects(:value).with(:certname).returns &quot;myname&quot;
+
+            Puppet::SSL::Host.new.name.should == &quot;myname&quot;
+        end
+
+        it &quot;should indicate that it is a CA host if its name matches the ca_name constant&quot; do
+            Puppet::SSL::Host.stubs(:ca_name).returns &quot;myca&quot;
+            Puppet::SSL::Host.new(&quot;myca&quot;).should be_ca
+        end
+    end
+
     describe &quot;when managing its private key&quot; do
         before do
             @realkey = &quot;mykey&quot;
@@ -314,4 +327,105 @@ describe Puppet::SSL::Host do
             end
         end
     end
+
+    it &quot;should have a method for generating all necessary files&quot; do
+        Puppet::SSL::Host.new(&quot;me&quot;).should respond_to(:generate)
+    end
+
+    describe &quot;when generating files&quot; do
+        before do
+            @host = Puppet::SSL::Host.new(&quot;me&quot;)
+            @host.stubs(:generate_key)
+            @host.stubs(:generate_certificate_request)
+        end
+
+        it &quot;should generate a key if one is not present&quot; do
+            @host.expects(:key).returns nil
+            @host.expects(:generate_key)
+
+            @host.generate
+        end
+
+        it &quot;should generate a certificate request if one is not present&quot; do
+            @host.expects(:certificate_request).returns nil
+            @host.expects(:generate_certificate_request)
+
+            @host.generate
+        end
+
+        describe &quot;and it can create a certificate authority&quot; do
+            before do
+                @ca = mock 'ca'
+                Puppet::SSL::CertificateAuthority.stubs(:instance).returns @ca
+            end
+
+            it &quot;should use the CA to sign its certificate request if it does not have a certificate&quot; do
+                @host.expects(:certificate).returns nil
+
+                @ca.expects(:sign).with(@host.name)
+
+                @host.generate
+            end
+        end
+
+        describe &quot;and it cannot create a certificate authority&quot; do
+            before do
+                Puppet::SSL::CertificateAuthority.stubs(:instance).returns nil
+            end
+
+            it &quot;should seek its certificate&quot; do
+                @host.expects(:certificate)
+
+                @host.generate
+            end
+        end
+    end
+
+    it &quot;should have a method for creating an SSL store&quot; do
+        Puppet::SSL::Host.new(&quot;me&quot;).should respond_to(:ssl_store)
+    end
+
+    describe &quot;when creating an SSL store&quot; do
+        before do
+            @host = Puppet::SSL::Host.new(&quot;me&quot;)
+            @store = mock 'store'
+            @store.stub_everything
+            OpenSSL::X509::Store.stubs(:new).returns @store
+
+            Puppet.settings.stubs(:value).returns &quot;ssl_host_testing&quot;
+        end
+
+        it &quot;should accept a purpose&quot; do
+            @store.expects(:purpose=).with &quot;my special purpose&quot;
+            @host.ssl_store(&quot;my special purpose&quot;)
+        end
+
+        it &quot;should default to OpenSSL::X509::PURPOSE_ANY as the purpose&quot; do
+            @store.expects(:purpose=).with OpenSSL::X509::PURPOSE_ANY
+            @host.ssl_store
+        end
+
+        it &quot;should add the local CA cert file&quot; do
+            Puppet.settings.stubs(:value).with(:localcacert).returns &quot;/ca/cert/file&quot;
+            @store.expects(:add_file).with &quot;/ca/cert/file&quot;
+            @host.ssl_store
+        end
+
+        describe &quot;and a CRL is available&quot; do
+            before do
+                @crl = stub 'crl', :content =&gt; &quot;real_crl&quot;
+                Puppet::SSL::CertificateRevocationList.stubs(:find).returns @crl
+            end
+
+            it &quot;should add the CRL&quot; do
+                @store.expects(:add_crl).with &quot;real_crl&quot;
+                @host.ssl_store
+            end
+
+            it &quot;should set the flags to OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK&quot; do
+                @store.expects(:flags=).with OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK
+                @host.ssl_store
+            end
+        end
+    end
 end</diff>
      <filename>spec/unit/ssl/host.rb</filename>
    </modified>
    <modified>
      <diff>@@ -35,6 +35,6 @@ describe Puppet::Transaction::Report, &quot; when being indirect&quot; do
     end
 
     after do
-        Puppet::Indirector::Indirection.clear_cache
+        Puppet::Util::Cacher.invalidate
     end
 end</diff>
      <filename>spec/unit/transaction/report.rb</filename>
    </modified>
    <modified>
      <diff>@@ -93,6 +93,11 @@ describe Puppet::Util::Settings, &quot; when setting values&quot; do
         @settings[:myval].should == &quot;yay&quot;
     end
 
+    it &quot;should clear the list of used sections&quot; do
+        @settings.expects(:clearused)
+        @settings[:myval] = &quot;yay&quot;
+    end
+
     it &quot;should call passed blocks when values are set&quot; do
         values = []
         @settings.setdefaults(:section, :hooker =&gt; {:default =&gt; &quot;yay&quot;, :desc =&gt; &quot;boo&quot;, :hook =&gt; lambda { |v| values &lt;&lt; v }})</diff>
      <filename>spec/unit/util/settings.rb</filename>
    </modified>
    <modified>
      <diff>@@ -58,7 +58,6 @@ module PuppetTest::ExeTest
         args += &quot; --masterport %s&quot; % @@port
         args += &quot; --user %s&quot; % Puppet::Util::SUIDManager.uid
         args += &quot; --group %s&quot; % Puppet::Util::SUIDManager.gid
-        args += &quot; --nonodes&quot;
         args += &quot; --autosign true&quot;
 
         #if Puppet[:debug]</diff>
      <filename>test/lib/puppettest/exetest.rb</filename>
    </modified>
    <modified>
      <diff>@@ -35,6 +35,7 @@ class TestClientCA &lt; Test::Unit::TestCase
         Puppet.settings.stubs(:value).with(:http_proxy_host).returns(nil)
         Puppet.settings.stubs(:value).with(:http_proxy_port).returns(nil)
         Puppet.settings.stubs(:value).with(:http_keepalive).returns(false)
+        Puppet.settings.stubs(:value).with(:configtimeout).returns(180)
 
         # Just throw an error; the important thing is the values, not what happens next.
         Net::HTTP.stubs(:new).with(&quot;myca&quot;, 321, nil, nil).raises(ArgumentError)</diff>
      <filename>test/network/client/ca.rb</filename>
    </modified>
    <modified>
      <diff>@@ -67,7 +67,7 @@ class TestWebrickServer &lt; Test::Unit::TestCase
     end
 
     # Test that a client whose cert has been revoked really can't connect
-    def test_certificate_revocation
+    def test_xcertificate_revocation
         Puppet[:autosign] = true
 
         serverpid, server = mk_status_server</diff>
      <filename>test/network/server/webrick.rb</filename>
    </modified>
    <modified>
      <diff>@@ -599,5 +599,33 @@ class TestCronParsedProvider &lt; Test::Unit::TestCase
         result = target.read
         assert_equal(&quot;# Puppet Name: test\n* 4 * * * /bin/echo yay\n&quot;, result, &quot;Did not write out environment setting&quot;)
     end
+
+    # Testing #1216
+    def test_strange_lines
+        @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
+        text = &quot; 5 \t\t 1,2 * 1 0 /bin/echo funtest&quot;
+
+        records = nil
+        assert_nothing_raised {
+            records = @provider.parse(text)
+        }
+
+        should = {
+            :minute =&gt; %w{5},
+            :hour =&gt; %w{1 2},
+            :monthday =&gt; :absent,
+            :month =&gt; %w{1},
+            :weekday =&gt; %w{0},
+            :command =&gt; &quot;/bin/echo funtest&quot;
+        }
+
+        is = records.shift
+        assert(is, &quot;Did not get record&quot;)
+
+        should.each do |p, v|
+            assert_equal(v, is[p], &quot;did not parse %s correctly&quot; % p)
+        end
+    end
+
 end
 </diff>
      <filename>test/ral/providers/cron/crontab.rb</filename>
    </modified>
    <modified>
      <diff>@@ -37,12 +37,13 @@ class TestProvider &lt; Test::Unit::TestCase
         cleanup { Puppet::Type.rmtype(:provider_test) }
     end
 
-    def test_confine
-        provider = newprovider
+    def test_confine_defaults_to_suitable
 
-        assert(provider.suitable?,
-            &quot;Marked unsuitable with no confines&quot;)
+        provider = newprovider
+        assert(provider.suitable?, &quot;Marked unsuitable with no confines&quot;)
+    end
 
+    def test_confine_results
         {
             {:true =&gt; true} =&gt; true,
             {:true =&gt; false} =&gt; false,
@@ -54,6 +55,8 @@ class TestProvider &lt; Test::Unit::TestCase
             {:exists =&gt; echo} =&gt; true,
             {:exists =&gt; &quot;/this/file/does/not/exist&quot;} =&gt; false,
         }.each do |hash, result|
+            provider = newprovider
+
             # First test :true
             hash.each do |test, val|
                 assert_nothing_raised do
@@ -61,19 +64,25 @@ class TestProvider &lt; Test::Unit::TestCase
                 end
             end
 
-            assert_equal(result, provider.suitable?,
-                &quot;Failed for %s&quot; % [hash.inspect])
+            assert_equal(result, provider.suitable?, &quot;Failed for %s&quot; % [hash.inspect])
 
             provider.initvars
         end
+    end
+
+    def test_multiple_confines_do_not_override
+        provider = newprovider
 
         # Make sure multiple confines don't overwrite each other
         provider.confine :true =&gt; false
         assert(! provider.suitable?)
         provider.confine :true =&gt; true
         assert(! provider.suitable?)
+    end
 
-        provider.initvars
+    def test_one_failed_confine_is_sufficient
+
+        provider = newprovider
 
         # Make sure we test multiple of them, and that a single false wins
         provider.confine :true =&gt; true, :false =&gt; false
@@ -82,6 +91,18 @@ class TestProvider &lt; Test::Unit::TestCase
         assert(! provider.suitable?)
     end
 
+    # #1197 - the binary should not be
+    def test_command_checks_for_binaries_each_time
+        provider = newprovider
+
+        provider.commands :testing =&gt; &quot;/no/such/path&quot;
+
+        provider.stubs(:binary).returns &quot;/no/such/path&quot;
+
+        provider.command(:testing)
+        assert_equal(&quot;/no/such/path&quot;, provider.command(:testing), &quot;Did not return correct binary path&quot;)
+    end
+
     def test_command
         {:echo =&gt; &quot;echo&quot;, :echo_with_path =&gt; echo, :missing =&gt; &quot;nosuchcommand&quot;, :missing_qualified =&gt; &quot;/path/to/nosuchcommand&quot;}.each do |name, command|
             provider = newprovider</diff>
      <filename>test/ral/providers/provider.rb</filename>
    </modified>
    <modified>
      <diff>@@ -525,107 +525,6 @@ class TestFileSources &lt; Test::Unit::TestCase
         return file
     end
 
-    def test_NetworkSources
-        server = nil
-        mounts = {
-            &quot;/&quot; =&gt; &quot;root&quot;
-        }
-
-        fileserverconf = mkfileserverconf(mounts)
-
-        Puppet[:autosign] = true
-
-        Puppet[:masterport] = 8762
-        Puppet[:name] = &quot;puppetmasterd&quot;
-        Puppet[:certdnsnames] = &quot;localhost&quot;
-
-        serverpid = nil
-        assert_nothing_raised() {
-            server = Puppet::Network::HTTPServer::WEBrick.new(
-                :Handlers =&gt; {
-                    :CA =&gt; {}, # so that certs autogenerate
-                    :FileServer =&gt; {
-                        :Config =&gt; fileserverconf
-                    }
-                }
-            )
-
-        }
-        serverpid = fork {
-            assert_nothing_raised() {
-                #trap(:INT) { server.shutdown; Kernel.exit! }
-                trap(:INT) { server.shutdown }
-                server.start
-            }
-        }
-        @@tmppids &lt;&lt; serverpid
-
-        sleep(1)
-
-        fromdir, todir = run_complex_sources(&quot;root&quot;)
-        assert_trees_equal(fromdir,todir)
-        recursive_source_test(fromdir, todir)
-        assert_trees_equal(fromdir,todir)
-
-        assert_nothing_raised {
-            system(&quot;kill -INT %s&quot; % serverpid)
-        }
-    end
-
-    def test_unmountedNetworkSources
-        server = nil
-        mounts = {
-            &quot;/&quot; =&gt; &quot;root&quot;,
-            &quot;/noexistokay&quot; =&gt; &quot;noexist&quot;
-        }
-
-        fileserverconf = mkfileserverconf(mounts)
-
-        Puppet[:autosign] = true
-        Puppet[:masterport] = @port
-        Puppet[:certdnsnames] = &quot;localhost&quot;
-
-        serverpid = nil
-        assert_nothing_raised(&quot;Could not start on port %s&quot; % @port) {
-            server = Puppet::Network::HTTPServer::WEBrick.new(
-                :Port =&gt; @port,
-                :Handlers =&gt; {
-                    :CA =&gt; {}, # so that certs autogenerate
-                    :FileServer =&gt; {
-                        :Config =&gt; fileserverconf
-                    }
-                }
-            )
-
-        }
-
-        serverpid = fork {
-            assert_nothing_raised() {
-                #trap(:INT) { server.shutdown; Kernel.exit! }
-                trap(:INT) { server.shutdown }
-                server.start
-            }
-        }
-        @@tmppids &lt;&lt; serverpid
-
-        sleep(1)
-
-        name = File.join(tmpdir(), &quot;nosourcefile&quot;)
-        file = Puppet.type(:file).create(
-            :source =&gt; &quot;puppet://localhost/noexist/file&quot;,
-            :name =&gt; name
-        )
-
-        assert_nothing_raised {
-            file.retrieve
-        }
-
-        comp = mk_catalog(file)
-        comp.apply
-
-        assert(!FileTest.exists?(name), &quot;File with no source exists anyway&quot;)
-    end
-
     def test_alwayschecksum
         from = tempfile()
         to = tempfile()</diff>
      <filename>test/ral/type/filesources.rb</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>lib/puppet/util/variables.rb</filename>
    </removed>
    <removed>
      <filename>spec/integration/ral/types/package.rb</filename>
    </removed>
    <removed>
      <filename>spec/unit/ral/provider/interface/redhat.rb</filename>
    </removed>
    <removed>
      <filename>spec/unit/ral/provider/interface/sunos.rb</filename>
    </removed>
    <removed>
      <filename>spec/unit/ral/provider/mount.rb</filename>
    </removed>
    <removed>
      <filename>spec/unit/ral/provider/mount/parsed.rb</filename>
    </removed>
    <removed>
      <filename>spec/unit/ral/type.rb</filename>
    </removed>
    <removed>
      <filename>spec/unit/ral/type/exec.rb</filename>
    </removed>
    <removed>
      <filename>spec/unit/ral/type/file.rb</filename>
    </removed>
    <removed>
      <filename>spec/unit/ral/type/interface.rb</filename>
    </removed>
    <removed>
      <filename>spec/unit/ral/type/mount.rb</filename>
    </removed>
    <removed>
      <filename>spec/unit/ral/type/nagios.rb</filename>
    </removed>
    <removed>
      <filename>spec/unit/ral/type/noop_metaparam.rb</filename>
    </removed>
    <removed>
      <filename>spec/unit/ral/type/package.rb</filename>
    </removed>
    <removed>
      <filename>spec/unit/ral/type/schedule.rb</filename>
    </removed>
    <removed>
      <filename>spec/unit/ral/type/service.rb</filename>
    </removed>
    <removed>
      <filename>spec/unit/ral/type/user.rb</filename>
    </removed>
    <removed>
      <filename>test/executables/puppetmasterd.rb</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>46785b34f3f662d660f2135a7c3256da059e5094</id>
    </parent>
    <parent>
      <id>fe157f239a301abb52f81c62719355c8e50c970c</id>
    </parent>
  </parents>
  <author>
    <name>Blake Barnett</name>
    <email>shadoi@dre.gs</email>
  </author>
  <url>http://github.com/shadoi/puppet/commit/e3ffa70b9c2ca838ec4c9b62ecb60ba1848c2bfc</url>
  <id>e3ffa70b9c2ca838ec4c9b62ecb60ba1848c2bfc</id>
  <committed-date>2008-05-21T15:37:26-07:00</committed-date>
  <authored-date>2008-05-21T15:37:26-07:00</authored-date>
  <message>Merge branch 'master' of git://reductivelabs.com/puppet</message>
  <tree>818ffff40fa204bc7931b915c4f69c88838d34f4</tree>
  <committer>
    <name>Blake Barnett</name>
    <email>shadoi@dre.gs</email>
  </committer>
</commit>
