<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>chef-server-api/LICENSE</filename>
    </added>
    <added>
      <filename>chef-server-api/README.rdoc</filename>
    </added>
    <added>
      <filename>chef-server-api/Rakefile</filename>
    </added>
    <added>
      <filename>chef-server-api/app/controllers/application.rb</filename>
    </added>
    <added>
      <filename>chef-server-api/app/controllers/cookbooks.rb</filename>
    </added>
    <added>
      <filename>chef-server-api/app/controllers/data.rb</filename>
    </added>
    <added>
      <filename>chef-server-api/app/controllers/data_item.rb</filename>
    </added>
    <added>
      <filename>chef-server-api/app/controllers/exceptions.rb</filename>
    </added>
    <added>
      <filename>chef-server-api/app/controllers/main.rb</filename>
    </added>
    <added>
      <filename>chef-server-api/app/controllers/nodes.rb</filename>
    </added>
    <added>
      <filename>chef-server-api/app/controllers/roles.rb</filename>
    </added>
    <added>
      <filename>chef-server-api/app/controllers/search.rb</filename>
    </added>
    <added>
      <filename>chef-server-api/app/helpers/application_helper.rb</filename>
    </added>
    <added>
      <filename>chef-server-api/app/helpers/exceptions_helper.rb</filename>
    </added>
    <added>
      <filename>chef-server-api/app/helpers/global_helpers.rb</filename>
    </added>
    <added>
      <filename>chef-server-api/app/helpers/nodes_helper.rb</filename>
    </added>
    <added>
      <filename>chef-server-api/app/helpers/roles_helper.rb</filename>
    </added>
    <added>
      <filename>chef-server-api/app/views/exceptions/bad_request.json.erb</filename>
    </added>
    <added>
      <filename>chef-server-api/app/views/exceptions/internal_server_error.html.erb</filename>
    </added>
    <added>
      <filename>chef-server-api/app/views/exceptions/not_acceptable.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-api/app/views/exceptions/not_found.html.erb</filename>
    </added>
    <added>
      <filename>chef-server-api/app/views/exceptions/standard_error.html.erb</filename>
    </added>
    <added>
      <filename>chef-server-api/app/views/layout/chef_server_api.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-api/app/views/main/index.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-api/config/init.rb</filename>
    </added>
    <added>
      <filename>chef-server-api/config/router.rb</filename>
    </added>
    <added>
      <filename>chef-server-api/lib/chef-server-api.rb</filename>
    </added>
    <added>
      <filename>chef-server-api/lib/chef-server-api/merbtasks.rb</filename>
    </added>
    <added>
      <filename>chef-server-api/lib/chef-server-api/slicetasks.rb</filename>
    </added>
    <added>
      <filename>chef-server-api/lib/chef-server-api/spectasks.rb</filename>
    </added>
    <added>
      <filename>chef-server-api/public/images/avatar.png</filename>
    </added>
    <added>
      <filename>chef-server-api/public/images/indicator.gif</filename>
    </added>
    <added>
      <filename>chef-server-api/public/images/merb.jpg</filename>
    </added>
    <added>
      <filename>chef-server-api/public/stylesheets/base.css</filename>
    </added>
    <added>
      <filename>chef-server-api/public/stylesheets/chef.css</filename>
    </added>
    <added>
      <filename>chef-server-api/public/stylesheets/themes/bec-green/style.css</filename>
    </added>
    <added>
      <filename>chef-server-api/public/stylesheets/themes/bec/style.css</filename>
    </added>
    <added>
      <filename>chef-server-api/public/stylesheets/themes/blue/style.css</filename>
    </added>
    <added>
      <filename>chef-server-api/public/stylesheets/themes/default/style.css</filename>
    </added>
    <added>
      <filename>chef-server-api/public/stylesheets/themes/djime-cerulean/style.css</filename>
    </added>
    <added>
      <filename>chef-server-api/public/stylesheets/themes/kathleene/style.css</filename>
    </added>
    <added>
      <filename>chef-server-api/public/stylesheets/themes/orange/style.css</filename>
    </added>
    <added>
      <filename>chef-server-api/public/stylesheets/themes/reidb-greenish/style.css</filename>
    </added>
    <added>
      <filename>chef-server-api/stubs/app/controllers/application.rb</filename>
    </added>
    <added>
      <filename>chef-server-api/stubs/app/controllers/main.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/LICENSE</filename>
    </added>
    <added>
      <filename>chef-server-webui/NOTICE</filename>
    </added>
    <added>
      <filename>chef-server-webui/README.rdoc</filename>
    </added>
    <added>
      <filename>chef-server-webui/Rakefile</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/controllers/application.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/controllers/cookbook_attributes.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/controllers/cookbook_definitions.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/controllers/cookbook_files.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/controllers/cookbook_libraries.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/controllers/cookbook_recipes.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/controllers/cookbook_templates.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/controllers/cookbooks.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/controllers/exceptions.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/controllers/main.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/controllers/nodes.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/controllers/openid_consumer.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/controllers/roles.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/controllers/search.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/controllers/search_entries.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/controllers/status.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/helpers/application_helper.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/helpers/cookbook_attributes_helper.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/helpers/cookbook_definitions_helper.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/helpers/cookbook_files_helper.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/helpers/cookbook_libraries_helper.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/helpers/cookbook_recipes_helper.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/helpers/cookbook_templates_helper.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/helpers/cookbooks_helper.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/helpers/exceptions_helper.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/helpers/global_helpers.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/helpers/nodes_helper.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/helpers/openid_consumer_helper.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/helpers/openid_register_helper.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/helpers/openid_server_helper.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/helpers/openid_server_helpers.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/helpers/roles_helper.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/helpers/search_entries_helper.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/helpers/search_helper.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/helpers/status_helper.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/cookbook_templates/index.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/cookbooks/index.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/cookbooks/show.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/exceptions/bad_request.json.erb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/exceptions/internal_server_error.html.erb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/exceptions/not_acceptable.html.erb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/exceptions/not_found.html.erb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/exceptions/standard_error.html.erb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/layout/chef_server_webui.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/layout/login.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/main/index.html.erb</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/nodes/_action.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/nodes/_form.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/nodes/_navigation.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/nodes/_resource.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/nodes/edit.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/nodes/index.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/nodes/new.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/nodes/show.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/openid_consumer/index.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/openid_consumer/start.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/openid_login/index.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/openid_register/index.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/openid_register/show.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/openid_server/decide.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/roles/_form.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/roles/_navigation.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/roles/edit.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/roles/index.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/roles/new.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/roles/show.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/search/_search_form.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/search/index.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/search/show.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/search_entries/index.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/search_entries/show.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/app/views/status/index.html.haml</filename>
    </added>
    <added>
      <filename>chef-server-webui/config/init.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/config/router.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/lib/chef-server-webui.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/lib/chef-server-webui/merbtasks.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/lib/chef-server-webui/slicetasks.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/lib/chef-server-webui/spectasks.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/facebox/README.txt</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/facebox/b.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/facebox/bl.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/facebox/br.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/facebox/closelabel.gif</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/facebox/facebox.css</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/facebox/facebox.js</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/facebox/loading.gif</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/facebox/tl.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/facebox/tr.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/avatar.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/black_big.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/indicator.gif</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/merb.jpg</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/toggle-collapse-dark.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/toggle-collapse-light.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/toggle-collapse.gif</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/toggle-expand-dark.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/toggle-expand-light.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/toggle-expand.gif</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/treeBuilderImages/Thumbs.db</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/treeBuilderImages/doc.gif</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/treeBuilderImages/docNode.gif</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/treeBuilderImages/docNodeLast.gif</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/treeBuilderImages/docNodeLastFirst.gif</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/treeBuilderImages/folder.gif</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/treeBuilderImages/folderNode.gif</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/treeBuilderImages/folderNodeFirst.gif</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/treeBuilderImages/folderNodeLast.gif</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/treeBuilderImages/folderNodeLastFirst.gif</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/treeBuilderImages/folderNodeOpen.gif</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/treeBuilderImages/folderNodeOpenFirst.gif</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/treeBuilderImages/folderNodeOpenLast.gif</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/treeBuilderImages/folderNodeOpenLastFirst.gif</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/treeBuilderImages/folderOpen.gif</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/images/treeBuilderImages/vertLine.gif</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/javascripts/JSONeditor.js</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/javascripts/chef.js</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/javascripts/jquery-1.3.2.min.js</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/javascripts/jquery-ui-1.7.1.custom.min.js</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/javascripts/jquery.editinline.js</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/javascripts/jquery.jeditable.mini.js</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/javascripts/jquery.livequery.js</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/javascripts/jquery.localscroll.js</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/javascripts/jquery.scrollTo.js</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/javascripts/jquery.tools.min.js</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/javascripts/jquery.treeTable.min.js</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/base.css</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/chef.css</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/images/ui-bg_diagonals-small_0_aaaaaa_40x40.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/images/ui-bg_diagonals-thick_15_444444_40x40.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/images/ui-bg_glass_100_f0f0f0_1x400.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/images/ui-bg_glass_50_99c2ff_1x400.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/images/ui-bg_glass_55_fbf5d0_1x400.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/images/ui-bg_glass_80_e6e6e6_1x400.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/images/ui-bg_glass_95_fef1ec_1x400.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/images/ui-bg_highlight-hard_100_f9f9f9_1x100.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/images/ui-bg_highlight-soft_100_e7eef3_1x100.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/images/ui-icons_222222_256x240.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/images/ui-icons_2694e8_256x240.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/images/ui-icons_2e83ff_256x240.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/images/ui-icons_72a7cf_256x240.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/images/ui-icons_888888_256x240.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/images/ui-icons_cd0a0a_256x240.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/images/ui-icons_ffffff_256x240.png</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/jquery-ui-1.7.1.custom.css</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/jquery.treeTable.css</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/themes/bec-green/style.css</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/themes/bec/style.css</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/themes/blue/style.css</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/themes/default/style.css</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/themes/djime-cerulean/style.css</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/themes/kathleene/style.css</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/themes/orange/style.css</filename>
    </added>
    <added>
      <filename>chef-server-webui/public/stylesheets/themes/reidb-greenish/style.css</filename>
    </added>
    <added>
      <filename>chef-server-webui/stubs/app/controllers/application.rb</filename>
    </added>
    <added>
      <filename>chef-server-webui/stubs/app/controllers/main.rb</filename>
    </added>
    <added>
      <filename>chef-solr/.document</filename>
    </added>
    <added>
      <filename>chef-solr/.gitignore</filename>
    </added>
    <added>
      <filename>chef-solr/README.rdoc</filename>
    </added>
    <added>
      <filename>chef-solr/Rakefile</filename>
    </added>
    <added>
      <filename>chef-solr/VERSION</filename>
    </added>
    <added>
      <filename>chef-solr/bin/chef-solr</filename>
    </added>
    <added>
      <filename>chef-solr/bin/chef-solr-indexer</filename>
    </added>
    <added>
      <filename>chef-solr/bin/chef-solr-rebuild</filename>
    </added>
    <added>
      <filename>chef-solr/chef-solr.gemspec</filename>
    </added>
    <added>
      <filename>chef-solr/lib/chef/solr.rb</filename>
    </added>
    <added>
      <filename>chef-solr/lib/chef/solr/application/indexer.rb</filename>
    </added>
    <added>
      <filename>chef-solr/lib/chef/solr/application/rebuild.rb</filename>
    </added>
    <added>
      <filename>chef-solr/lib/chef/solr/application/solr.rb</filename>
    </added>
    <added>
      <filename>chef-solr/lib/chef/solr/index.rb</filename>
    </added>
    <added>
      <filename>chef-solr/lib/chef/solr/index_actor.rb</filename>
    </added>
    <added>
      <filename>chef-solr/lib/chef/solr/query.rb</filename>
    </added>
    <added>
      <filename>chef-solr/solr/solr-home.tar.gz</filename>
    </added>
    <added>
      <filename>chef-solr/solr/solr-jetty.tar.gz</filename>
    </added>
    <added>
      <filename>chef-solr/spec/chef/solr/index_spec.rb</filename>
    </added>
    <added>
      <filename>chef-solr/spec/chef/solr/query_spec.rb</filename>
    </added>
    <added>
      <filename>chef-solr/spec/chef/solr_spec.rb</filename>
    </added>
    <added>
      <filename>chef-solr/spec/spec_helper.rb</filename>
    </added>
    <added>
      <filename>chef/lib/chef/cookbook_helper.rb</filename>
    </added>
    <added>
      <filename>chef/lib/chef/data_bag.rb</filename>
    </added>
    <added>
      <filename>chef/lib/chef/data_bag_item.rb</filename>
    </added>
    <added>
      <filename>chef/lib/chef/nanite.rb</filename>
    </added>
    <added>
      <filename>chef/lib/chef/search/query.rb</filename>
    </added>
    <added>
      <filename>chef/lib/chef/streaming_cookbook_uploader.rb</filename>
    </added>
    <added>
      <filename>chef/spec/unit/data_bag_item_spec.rb</filename>
    </added>
    <added>
      <filename>chef/spec/unit/data_bag_spec.rb</filename>
    </added>
    <added>
      <filename>chef/spec/unit/search/query_spec.rb</filename>
    </added>
    <added>
      <filename>features/api/cookbooks/list_cookbooks_api.feature</filename>
    </added>
    <added>
      <filename>features/api/cookbooks/show_cookbook_api.feature</filename>
    </added>
    <added>
      <filename>features/api/cookbooks/show_cookbook_attributes_api.feature</filename>
    </added>
    <added>
      <filename>features/api/data/create_data_bag_api.feature</filename>
    </added>
    <added>
      <filename>features/api/data/create_data_bag_item_api.feature</filename>
    </added>
    <added>
      <filename>features/api/data/delete_data_bag_api.feature</filename>
    </added>
    <added>
      <filename>features/api/data/delete_data_bag_item.feature</filename>
    </added>
    <added>
      <filename>features/api/data/list_data_bags.feature</filename>
    </added>
    <added>
      <filename>features/api/data/show_data_bag_api.feature</filename>
    </added>
    <added>
      <filename>features/api/data/show_data_bag_item_api.feature</filename>
    </added>
    <added>
      <filename>features/api/nodes/cookbook_sync_api.feature</filename>
    </added>
    <added>
      <filename>features/api/search/list_search.feature</filename>
    </added>
    <added>
      <filename>features/api/search/show_search.feature</filename>
    </added>
    <added>
      <filename>features/data/cookbooks/node_cookbook_sync/README.rdoc</filename>
    </added>
    <added>
      <filename>features/data/cookbooks/node_cookbook_sync/attributes/attr_file.rb</filename>
    </added>
    <added>
      <filename>features/data/cookbooks/node_cookbook_sync/definitions/def_file.rb</filename>
    </added>
    <added>
      <filename>features/data/cookbooks/node_cookbook_sync/libraries/lib_file.rb</filename>
    </added>
    <added>
      <filename>features/data/cookbooks/node_cookbook_sync/metadata.rb</filename>
    </added>
    <added>
      <filename>features/data/cookbooks/node_cookbook_sync/recipes/default.rb</filename>
    </added>
    <added>
      <filename>features/data/cookbooks/search/recipes/search_data_noblock.rb</filename>
    </added>
    <added>
      <filename>features/data/cookbooks/show_cookbook/README.rdoc</filename>
    </added>
    <added>
      <filename>features/data/cookbooks/show_cookbook/attributes/attr_file.rb</filename>
    </added>
    <added>
      <filename>features/data/cookbooks/show_cookbook/definitions/def_file.rb</filename>
    </added>
    <added>
      <filename>features/data/cookbooks/show_cookbook/files/default/prime_time.txt</filename>
    </added>
    <added>
      <filename>features/data/cookbooks/show_cookbook/files/host-latte/prime_time.txt</filename>
    </added>
    <added>
      <filename>features/data/cookbooks/show_cookbook/files/mac_os_x-10.5/prime_time.txt</filename>
    </added>
    <added>
      <filename>features/data/cookbooks/show_cookbook/files/mac_os_x/prime_time.txt</filename>
    </added>
    <added>
      <filename>features/data/cookbooks/show_cookbook/libraries/lib_file.rb</filename>
    </added>
    <added>
      <filename>features/data/cookbooks/show_cookbook/metadata.rb</filename>
    </added>
    <added>
      <filename>features/data/cookbooks/show_cookbook/recipes/default.rb</filename>
    </added>
    <added>
      <filename>features/data/cookbooks/show_cookbook/templates/default/prime_time.txt.erb</filename>
    </added>
    <added>
      <filename>features/data/cookbooks/show_cookbook/templates/host-latte/prime_time.txt.erb</filename>
    </added>
    <added>
      <filename>features/data/cookbooks/show_cookbook/templates/mac_os_x-10.5/prime_time.txt.erb</filename>
    </added>
    <added>
      <filename>features/data/cookbooks/show_cookbook/templates/mac_os_x/prime_time.txt.erb</filename>
    </added>
    <added>
      <filename>opscode-start</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -9,7 +9,8 @@ examples/openid-cstore
 examples/openid-db
 chef/pkg
 chef-server/pkg
-chef-server-slice/pkg
+chef-server-webui/pkg
+chef-server-api/pkg
 chef/log
 chef-server/log
 log
@@ -18,3 +19,5 @@ couchdb.stdout
 features/data/tmp/**
 *.swp
 features/data/cookbooks/**/metadata.json
+features/data/solr/**
+erl_crash.dump</diff>
      <filename>.gitignore</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-gems = %w[chef chef-server-slice chef-server]
+gems = %w[chef chef-server-api chef-server-webui chef-server chef-solr]
 require 'rubygems'
 require 'cucumber/rake/task'
 
@@ -26,71 +26,111 @@ end
 desc &quot;Run the rspec tests&quot;
 task :spec do
   Dir.chdir(&quot;chef&quot;) { sh &quot;rake spec&quot; }
+  Dir.chdir(&quot;chef-solr&quot;) { sh &quot;rake spec&quot; }
 end
 
 task :default =&gt; :spec
 
-def start_dev_environment(type=&quot;normal&quot;)
-  @couchdb_server_pid = nil
-  @chef_server_pid    = nil
-  @chef_indexer_pid   = nil
-  @stompserver_pid    = nil
-  
-  ccid = fork
-  if ccid
-    @couchdb_server_pid = ccid
+def start_couchdb(type=&quot;normal&quot;)
+  @couchdb_server_pid  = nil
+  cid = fork
+  if cid
+    @couchdb_server_pid = cid
   else
     exec(&quot;couchdb&quot;)
   end
+end
 
-  scid = fork
-  if scid
-    @stompserver_pid = scid
+def start_rabbitmq(type=&quot;normal&quot;)
+  @rabbitmq_server_pid = nil
+  cid = fork
+  if cid
+    @rabbitmq_server_pid = cid
   else
-    exec(&quot;stompserver&quot;)
+    exec(&quot;rabbitmq-server&quot;)
   end
+end
 
-  mcid = fork
-  if mcid # parent
-    @chef_indexer_pid = mcid
-  else # child
+def start_chef_solr(type=&quot;normal&quot;)
+  @chef_solr_pid = nil
+  cid = fork
+  if cid
+    @chef_solr_pid = cid
+  else
     case type
     when &quot;normal&quot;
-      exec(&quot;chef-indexer -l debug&quot;)
+      exec(&quot;./chef-solr/bin/chef-solr -l debug&quot;)
     when &quot;features&quot;
-      exec(&quot;chef-indexer -c #{File.join(File.dirname(__FILE__), &quot;features&quot;, &quot;data&quot;, &quot;config&quot;, &quot;server.rb&quot;)} -l debug&quot;)
+      exec(&quot;./chef-solr/bin/chef-solr -c #{File.join(File.dirname(__FILE__), &quot;features&quot;, &quot;data&quot;, &quot;config&quot;, &quot;server.rb&quot;)} -l debug&quot;)
     end
   end
+end
 
+def start_chef_solr_indexer(type=&quot;normal&quot;)
+  @chef_solr_indexer   = nil
+  cid = fork
+  if cid
+    @chef_solr_indexer_pid = cid
+  else
+    case type
+    when &quot;normal&quot;
+      exec(&quot;./chef-solr/bin/chef-solr-indexer -l debug&quot;)
+    when &quot;features&quot;
+      exec(&quot;./chef-solr/bin/chef-solr-indexer -c #{File.join(File.dirname(__FILE__), &quot;features&quot;, &quot;data&quot;, &quot;config&quot;, &quot;server.rb&quot;)} -l debug&quot;)
+    end
+  end
+end
+
+def start_chef_server(type=&quot;normal&quot;)
+  @chef_server_pid     = nil
   mcid = fork
   if mcid # parent
     @chef_server_pid = mcid
   else # child
     case type
     when &quot;normal&quot;
-      exec(&quot;chef-server -l debug -N -c 2&quot;)
+      exec(&quot;./chef-server/bin/chef-server -a thin -l debug -N&quot;)
     when &quot;features&quot;
-      exec(&quot;chef-server -C #{File.join(File.dirname(__FILE__), &quot;features&quot;, &quot;data&quot;, &quot;config&quot;, &quot;server.rb&quot;)} -l debug -N -c 2&quot;)
-      
+      exec(&quot;./chef-server/bin/chef-server -a thin -C #{File.join(File.dirname(__FILE__), &quot;features&quot;, &quot;data&quot;, &quot;config&quot;, &quot;server.rb&quot;)} -l debug -N&quot;)
     end
   end
+end
 
-  puts &quot;Running Chef at #{@chef_server_pid}&quot;
-  puts &quot;Running Chef Indexer at #{@chef_indexer_pid}&quot;
+def start_dev_environment(type=&quot;normal&quot;)
+  start_couchdb(type)
+  start_rabbitmq(type)
+  start_chef_solr(type)
+  start_chef_solr_indexer(type)
+  start_chef_server(type)
   puts &quot;Running CouchDB at #{@couchdb_server_pid}&quot;
-  puts &quot;Running Stompserver at #{@stompserver_pid}&quot;
+  puts &quot;Running RabbitMQ at #{@rabbitmq_server_pid}&quot;
+  puts &quot;Running Chef Solr at #{@chef_solr_pid}&quot;
+  puts &quot;Running Chef Solr Indexer at #{@chef_solr_indexer_pid}&quot;
+  puts &quot;Running Chef at #{@chef_server_pid}&quot;
 end
 
 def stop_dev_environment
-  puts &quot;Stopping CouchDB&quot;
-  Process.kill(&quot;KILL&quot;, @couchdb_server_pid) 
-  puts &quot;Stopping Stomp server&quot;
-  Process.kill(&quot;KILL&quot;, @stompserver_pid) 
-  puts &quot;Stopping Chef Server&quot;
-  Process.kill(&quot;INT&quot;, @chef_server_pid)
-  puts &quot;Stopping Chef Indexer&quot;
-  Process.kill(&quot;INT&quot;, @chef_indexer_pid)
-  puts &quot;\nCouchDB, Stomp, Chef Server and Chef Indexer killed - have a nice day!&quot;
+  if @chef_server_pid
+    puts &quot;Stopping Chef&quot;
+    Process.kill(&quot;KILL&quot;, @chef_server_pid)
+  end
+  if @chef_solr_pid
+    puts &quot;Stopping Chef Solr&quot;
+    Process.kill(&quot;INT&quot;, @chef_solr_pid)
+  end
+  if @chef_solr_indexer_pid
+    puts &quot;Stopping Chef Solr Indexer&quot;
+    Process.kill(&quot;INT&quot;, @chef_solr_indexer_pid)
+  end
+  if @couchdb_server_pid
+    puts &quot;Stopping CouchDB&quot;
+    Process.kill(&quot;KILL&quot;, @couchdb_server_pid) 
+  end
+  if @rabbitmq_server_pid
+    puts &quot;Stopping RabbitMQ&quot;
+    Process.kill(&quot;KILL&quot;, @rabbitmq_server_pid) 
+  end
+  puts &quot;Have a nice day!&quot;
 end
 
 def wait_for_ctrlc
@@ -106,7 +146,7 @@ def wait_for_ctrlc
 end
 
 desc &quot;Run a Devel instance of Chef&quot;
-task :dev =&gt; &quot;dev:install&quot; do
+task :dev do
   start_dev_environment
   wait_for_ctrlc
 end
@@ -114,12 +154,77 @@ end
 namespace :dev do  
   desc &quot;Install a test instance of Chef for doing features against&quot;
   task :features do
-    gems.each do |dir|
-      Dir.chdir(dir) { sh &quot;rake install&quot; }
-    end
     start_dev_environment(&quot;features&quot;)
     wait_for_ctrlc
   end
+
+  namespace :features do
+    
+    namespace :start do
+      desc &quot;Start CouchDB for testing&quot;
+      task :couchdb do
+        start_couchdb(&quot;features&quot;)
+        wait_for_ctrlc
+      end
+
+      desc &quot;Start RabbitMQ for testing&quot;
+      task :rabbitmq do
+        start_rabbitmq(&quot;features&quot;)
+        wait_for_ctrlc
+      end
+
+      desc &quot;Start Chef Solr for testing&quot;
+      task :chef_solr do
+        start_chef_solr(&quot;features&quot;)
+        wait_for_ctrlc
+      end
+
+      desc &quot;Start Chef Solr Indexer for testing&quot;
+      task :chef_solr_indexer do
+        start_chef_solr_indexer(&quot;features&quot;)
+        wait_for_ctrlc
+      end
+
+      desc &quot;Start Chef Server for testing&quot;
+      task :chef_server do
+        start_chef_server(&quot;features&quot;)
+        wait_for_ctrlc
+      end
+
+    end
+  end
+
+  namespace :start do
+    desc &quot;Start CouchDB&quot;
+    task :couchdb do
+      start_couchdb
+      wait_for_ctrlc
+    end
+
+    desc &quot;Start RabbitMQ&quot;
+    task :rabbitmq do
+      start_rabbitmq
+      wait_for_ctrlc
+    end
+
+    desc &quot;Start Chef Solr&quot;
+    task :chef_solr do
+      start_chef_solr
+      wait_for_ctrlc
+    end
+
+    desc &quot;Start Chef Solr Indexer&quot;
+    task :chef_solr_indexer do
+      start_chef_solr_indexer
+      wait_for_ctrlc
+    end
+
+    desc &quot;Start Chef Server&quot;
+    task :chef_server do
+      start_chef_server
+      wait_for_ctrlc
+    end
+  end
 end
 
 Cucumber::Rake::Task.new(:features) do |t|
@@ -127,12 +232,13 @@ Cucumber::Rake::Task.new(:features) do |t|
 end
 
 namespace :features do
+  desc &quot;Run cucumber tests for the REST API&quot;
   Cucumber::Rake::Task.new(:api) do |t|
     t.profile = &quot;api&quot;
   end
 
   namespace :api do
-    [ :nodes, :roles].each do |api|
+    [ :nodes, :roles ].each do |api|
         Cucumber::Rake::Task.new(api) do |apitask|
           apitask.profile = &quot;api_#{api.to_s}&quot;
         end
@@ -144,8 +250,52 @@ namespace :features do
         end
       end
     end
+
+    namespace :cookbooks do    
+      desc &quot;Run cucumber tests for the cookbooks portion of the REST API&quot;
+      Cucumber::Rake::Task.new(:cookbooks) do |t|
+        t.profile = &quot;api_cookbooks&quot;
+      end
+      
+      Cucumber::Rake::Task.new(:cookbook_tarballs) do |t|
+        t.profile = &quot;api_cookbooks_tarballs&quot;
+      end
+    end
+    
+    namespace :data do    
+      desc &quot;Run cucumber tests for the data portion of the REST API&quot;
+      Cucumber::Rake::Task.new(:data) do |t|
+        t.profile = &quot;api_data&quot;
+      end
+      
+      desc &quot;Run cucumber tests for deleting data via the REST API&quot;
+      Cucumber::Rake::Task.new(:delete) do |t|
+        t.profile = &quot;api_data_delete&quot;
+      end
+      desc &quot;Run cucumber tests for adding items via the REST API&quot;
+      Cucumber::Rake::Task.new(:item) do |t|
+        t.profile = &quot;api_data_item&quot;
+      end
+    end
+    
+    namespace :search do
+      desc &quot;Run cucumber tests for searching via the REST API&quot;
+      Cucumber::Rake::Task.new(:search) do |t|
+        t.profile = &quot;api_search&quot;
+      end
+      
+      desc &quot;Run cucumber tests for listing search endpoints via the REST API&quot;
+      Cucumber::Rake::Task.new(:list) do |t|
+        t.profile = &quot;api_search_list&quot;
+      end
+      desc &quot;Run cucumber tests for searching via the REST API&quot;
+      Cucumber::Rake::Task.new(:show) do |t|
+        t.profile = &quot;api_search_show&quot;
+      end
+    end
   end
 
+  desc &quot;Run cucumber tests for the chef client&quot;
   Cucumber::Rake::Task.new(:client) do |t|
     t.profile = &quot;client&quot;
   end
@@ -156,6 +306,17 @@ namespace :features do
     end
   end
 
+  desc &quot;Run cucumber tests for the cookbooks&quot;
+  Cucumber::Rake::Task.new(:cookbooks) do |t|
+    t.profile = &quot;cookbooks&quot;
+  end
+
+  desc &quot;Run cucumber tests for the recipe language&quot;
+  Cucumber::Rake::Task.new(:language) do |t|
+    t.profile = &quot;language&quot;
+  end
+
+  desc &quot;Run cucumber tests for searching in recipes&quot;
   Cucumber::Rake::Task.new(:search) do |t|
     t.profile = &quot;search&quot;
   end
@@ -170,12 +331,34 @@ namespace :features do
     end
   end
 
+  desc &quot;Run cucumber tests for providers&quot; 
+  Cucumber::Rake::Task.new(:provider) do |t|
+    t.profile = &quot;provider&quot;
+  end
+
   namespace :provider do
+    desc &quot;Run cucumber tests for directory resources&quot;
+    Cucumber::Rake::Task.new(:directory) do |t|
+      t.profile = &quot;provider_directory&quot;
+    end
+
+    desc &quot;Run cucumber tests for execute resources&quot;
+    Cucumber::Rake::Task.new(:execute) do |t|
+      t.profile = &quot;provider_execute&quot;
+    end
+
+    desc &quot;Run cucumber tests for file resources&quot;
+    Cucumber::Rake::Task.new(:execute) do |t|
+      t.profile = &quot;provider_file&quot;
+    end
+
+    desc &quot;Run cucumber tests for remote_file resources&quot;
     Cucumber::Rake::Task.new(:remote_file) do |t|
       t.profile = &quot;provider_remote_file&quot;
     end
     
     namespace :package do
+      desc &quot;Run cucumber tests for macports packages&quot;
       Cucumber::Rake::Task.new(:macports) do |t|
         t.profile = &quot;provider_package_macports&quot;
       end</diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -18,7 +18,7 @@ require 'chef' unless defined?(Chef)
 include FileUtils
 
 GEM = &quot;chef-server&quot;
-CHEF_SERVER_VERSION = &quot;0.7.9&quot;
+CHEF_SERVER_VERSION = &quot;0.8.0&quot;
 AUTHOR = &quot;Opscode&quot;
 EMAIL = &quot;chef@opscode.com&quot;
 HOMEPAGE = &quot;http://wiki.opscode.com/display/chef&quot;</diff>
      <filename>chef-server/Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -26,7 +26,8 @@
 require &quot;rubygems&quot;
 require &quot;merb-core&quot;
 
-[ 'chef', 'chef-server-slice' ].each do |lib|
+[ 'chef', 'chef-server-api' ].each do |lib|
+  $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), &quot;..&quot;, &quot;..&quot;, &quot;lib&quot;)))
   library = File.join(File.dirname(__FILE__), &quot;..&quot;, &quot;..&quot;, lib, &quot;lib&quot;, &quot;#{lib}.rb&quot;)
   require library if File.exists?(library)
 end
@@ -50,7 +51,7 @@ if ARGV[0] &amp;&amp; ARGV[0] =~ /^[^-]/
   ARGV.push &quot;-H&quot;
 end 
 unless %w[-a --adapter -i --irb-console -r --script-runner].any? { |o| ARGV.index(o) }
-  ARGV.push *%w[-a mongrel]
+  ARGV.push *%w[-a thin]
 end
 ARGV.push *[ &quot;-I&quot;, File.join(__DIR__, &quot;config&quot;, &quot;init.rb&quot;) ]
 ARGV.push *[ &quot;-m&quot;, __DIR__]</diff>
      <filename>chef-server/bin/chef-server</filename>
    </modified>
    <modified>
      <diff>@@ -1,13 +1,24 @@
 # dependencies are generated using a strict version, don't forget to edit the dependency versions when upgrading.
 merb_gems_version = &quot;&gt; 1.0&quot;
 
+%w{chef chef-server-api chef-solr}.each do |dep|
+  $: &lt;&lt; File.join(File.dirname(__FILE__), &quot;..&quot;, &quot;..&quot;, dep, &quot;lib&quot;)
+end
+
+begin
+  require 'chef'
+  require 'chef-server-api'
+rescue
+end
+  
 # For more information about each component, please read http://wiki.merbivore.com/faqs/merb_components
 dependency &quot;merb-core&quot;, merb_gems_version 
 dependency &quot;merb-assets&quot;, merb_gems_version  
 dependency &quot;merb-helpers&quot;, merb_gems_version 
 dependency &quot;merb-slices&quot;, merb_gems_version  
 if defined?(CHEF_SERVER_VERSION)
-  dependency &quot;chef-server-slice&quot;, CHEF_SERVER_VERSION unless defined?(ChefServerSlice)
+  dependency &quot;chef-server-api&quot;, CHEF_SERVER_VERSION unless defined?(ChefServerApi)
 else
-  dependency &quot;chef-server-slice&quot; unless defined?(ChefServerSlice)
+  dependency &quot;chef-server-api&quot; unless defined?(ChefServerSlice)
 end
+</diff>
      <filename>chef-server/config/dependencies.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,5 @@
 # Go to http://wiki.merbivore.com/pages/init-rb
- 
+
 require 'config/dependencies.rb'
 unless defined?(Chef)
   gem &quot;chef&quot;, &quot;=&quot; + CHEF_SERVER_VERSION if CHEF_SERVER_VERSION
@@ -17,7 +17,9 @@ Merb::Config.use do |c|
   c[:exception_details] = true
   c[:reload_classes] = false
   c[:log_level] = Chef::Config[:log_level]
-  c[:log_stream] = Chef::Config[:log_location]
+  if Chef::Config[:log_location].kind_of?(String)
+    c[:log_file] = Chef::Config[:log_location]
+  end
 end
  
 Merb::BootLoader.before_app_loads do
@@ -25,6 +27,6 @@ Merb::BootLoader.before_app_loads do
 end
  
 Merb::BootLoader.after_app_loads do
-  # This will get executed after your app's classes have been loaded.
-  OpenID::Util.logger = Merb.logger
+  # This will get executed after your app's classes have been loaded.  OpenID::Util.logger = Merb.logger
 end
+</diff>
      <filename>chef-server/config/init.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,3 +1,5 @@
+$: &lt;&lt; File.join(File.dirname(__FILE__))
+
 # use PathPrefix Middleware if :path_prefix is set in Merb::Config
 if prefix = ::Merb::Config[:path_prefix]
   use Merb::Rack::PathPrefix, prefix</diff>
      <filename>chef-server/config/rack.rb</filename>
    </modified>
    <modified>
      <diff>@@ -29,16 +29,11 @@ Merb.logger.info(&quot;Compiling routes...&quot;)
 Merb::Router.prepare do
   # RESTful routes
   # resources :posts
-  
+ 
   # Adds the required routes for merb-auth using the password slice
   # slice(:merb_auth_slice_password, :name_prefix =&gt; nil, :path_prefix =&gt; &quot;&quot;)
-  slice(:chef_server_slice)
-  # This is the default route for /:controller/:action/:id
-  # This is fine for most cases.  If you're heavily using resource-based
-  # routes, you may want to comment/remove this line to prevent
-  # clients from calling your create or destroy actions with a GET
-  default_routes
-  
-  # Change this for your home page to be available at /
-  # match('/').to(:controller =&gt; 'whatever', :action =&gt;'index')
+
+  slice(:chef_server_api)
+  # slice(:chef_server_webui, :path_prefix =&gt; &quot;html&quot;)
+
 end</diff>
      <filename>chef-server/config/router.rb</filename>
    </modified>
    <modified>
      <diff>@@ -4,7 +4,7 @@ require 'rake/rdoctask'
 require './tasks/rspec.rb'
 
 GEM = &quot;chef&quot;
-CHEF_VERSION = &quot;0.7.9&quot;
+CHEF_VERSION = &quot;0.8.0&quot;
 AUTHOR = &quot;Adam Jacob&quot;
 EMAIL = &quot;adam@opscode.com&quot;
 HOMEPAGE = &quot;http://wiki.opscode.com/display/chef&quot;</diff>
      <filename>chef/Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -27,7 +27,7 @@ require 'chef/config'
 Dir[File.join(File.dirname(__FILE__), 'chef/mixin/**/*.rb')].sort.each { |lib| require lib }
 
 class Chef
-  VERSION = '0.7.9'
+  VERSION = '0.8.0'
 end
 
 # Adds a Dir.glob to Ruby 1.8.5, for compat</diff>
      <filename>chef/lib/chef.rb</filename>
    </modified>
    <modified>
      <diff>@@ -46,9 +46,14 @@ class Chef
       @json_attribs = nil
       @node_name = nil
       @node_exists = true 
-      Ohai::Log.logger = Chef::Log.logger
+      Mixlib::Auth::Log.logger = Ohai::Log.logger = Chef::Log.logger
       @ohai = Ohai::System.new
-      @rest = Chef::REST.new(Chef::Config[:registration_url])
+      @ohai_has_run = false
+      if File.exists?(Chef::Config[:client_key])
+        @rest = Chef::REST.new(Chef::Config[:chef_server_url])
+      else
+        @rest = Chef::REST.new(Chef::Config[:chef_server_url], nil, nil)
+      end
     end
     
     # Do a full run for this Chef::Client.  Calls:
@@ -71,13 +76,9 @@ class Chef
       
       determine_node_name
       register
-      authenticate
       build_node(@node_name)
       save_node
-      sync_library_files
-      sync_attribute_files
-      sync_definitions
-      sync_recipes
+      sync_cookbooks
       save_node
       converge
       save_node
@@ -116,9 +117,14 @@ class Chef
     end
 
     def determine_node_name
-      run_ohai
       unless @safe_name &amp;&amp; @node_name
-        @node_name ||= @ohai[:fqdn] ? @ohai[:fqdn] : @ohai[:hostname]
+        run_ohai
+        if Chef::Config[:node_name]
+          @node_name = Chef::Config[:node_name]
+        else
+          @node_name ||= @ohai[:fqdn] ? @ohai[:fqdn] : @ohai[:hostname]
+          Chef::Config[:node_name] = @node_name
+        end
         @safe_name = @node_name.gsub(/\./, '_')
       end
       @node_name
@@ -177,68 +183,22 @@ class Chef
       @node[:tags] = Array.new unless @node.attribute?(:tags)
       @node
     end
-    
-    # If this node has been registered before, this method will fetch the current registration
-    # data.
-    #
-    # If it has not, we register it by calling create_registration.
-    #
+   
+    # 
     # === Returns
     # true:: Always returns true
     def register
-      determine_node_name unless @node_name
-      Chef::Log.debug(&quot;Registering #{@safe_name} for an openid&quot;) 
-      
-      begin
-        if @rest.get_rest(&quot;registrations/#{@safe_name}&quot;)
-          @secret = Chef::FileCache.load(File.join(&quot;registration&quot;, @safe_name))
-        end
-      rescue Net::HTTPServerException =&gt; e
-        case e.message
-        when /^404/
-          create_registration
-        else
-          raise
-        end
-      rescue Chef::Exceptions::FileNotFound
-        Chef::Application.fatal! &quot;A remote registration already exists for #{@safe_name}, however the local shared secret does not exist.&quot; +
-          &quot; To remedy this, you could delete the registration via webUI/REST, change the node_name option in config.rb&quot; +
-          &quot; (or use the -N/--node-name option to the CLI) or&quot; +
-          &quot; copy the old shared secret to #{File.join(Chef::Config[:file_cache_path], 'registration', @safe_name)}&quot;, 3
+      if File.exists?(Chef::Config[:validation_key])
+        @vr = Chef::REST.new(Chef::Config[:client_url], Chef::Config[:validation_client_name], Chef::Config[:validation_key])
+        @vr.register(@node_name, Chef::Config[:client_key])
+      else
+        Chef::Log.debug(&quot;Validation key #{Chef::Config[:validation_key]} is not present - skipping registration&quot;)
       end
-
+      # We now have the client key, and should use it from now on.
+      @rest = Chef::REST.new(Chef::Config[:chef_server_url])
       true
     end
     
-    # Generates a random secret, stores it in the Chef::Filestore with the &quot;registration&quot; key,
-    # and posts our nodes registration information to the server.
-    #
-    # === Returns
-    # true:: Always returns true
-    def create_registration
-      @secret = random_password(500)
-      Chef::FileCache.store(File.join(&quot;registration&quot;, @safe_name), @secret)
-      @rest.post_rest(&quot;registrations&quot;, { :id =&gt; @safe_name, :password =&gt; @secret, :validation_token =&gt; @validation_token })
-      true
-    end
-    
-    # Authenticates the node via OpenID.
-    #
-    # === Returns
-    # true:: Always returns true
-    def authenticate
-      determine_node_name unless @node_name
-      Chef::Log.debug(&quot;Authenticating #{@safe_name} via openid&quot;) 
-      response = @rest.post_rest('openid/consumer/start', { 
-        &quot;openid_identifier&quot; =&gt; &quot;#{Chef::Config[:openid_url]}/openid/server/node/#{@safe_name}&quot;,
-        &quot;submit&quot; =&gt; &quot;Verify&quot;
-      })
-      @rest.post_rest(
-        &quot;#{Chef::Config[:openid_url]}#{response[&quot;action&quot;]}&quot;,
-        { &quot;password&quot; =&gt; @secret }
-      )
-    end
-    
     # Update the file caches for a given cache segment.  Takes a segment name
     # and a hash that matches one of the cookbooks/_attribute_files style
     # remote file listings.
@@ -246,103 +206,81 @@ class Chef
     # === Parameters
     # segment&lt;String&gt;:: The cache segment to update
     # remote_list&lt;Hash&gt;:: A cookbooks/_attribute_files style remote file listing
-    def update_file_cache(segment, remote_list)  
-      # We need the list of known good attribute files, so we can delete any that are
-      # just laying about.
+    def update_file_cache(cookbook_name, parts)  
+      Chef::Log.debug(&quot;Synchronizing cookbook #{cookbook_name}&quot;)
+
       file_canonical = Hash.new
-      
-      remote_list.each do |rf|
-        cache_file = File.join(&quot;cookbooks&quot;, rf['cookbook'], segment, rf['name'])
-        file_canonical[cache_file] = true
 
-        # For back-compat between older clients and new chef servers
-        rf['checksum'] ||= nil 
-      
-        current_checksum = nil
-        if Chef::FileCache.has_key?(cache_file)
-          current_checksum = checksum(Chef::FileCache.load(cache_file, false))
-        end
+      parts.each do |segment, remote_list|
+        # segement = cookbook segment
+        # remote_list = list of file hashes
+        #
+        # We need the list of known good attribute files, so we can delete any that are
+        # just laying about.
+       
+        
+        remote_list.each do |rf|
+          cache_file = File.join(&quot;cookbooks&quot;, cookbook_name, segment, rf['name'])
+          file_canonical[cache_file] = true
 
-        rf_url = generate_cookbook_url(
-          rf['name'], 
-          rf['cookbook'], 
-          segment, 
-          @node, 
-          current_checksum ? { 'checksum' =&gt; current_checksum } : nil
-        )
-        Chef::Log.debug(rf_url)
+          # For back-compat between older clients and new chef servers
+          rf['checksum'] ||= nil 
+        
+          current_checksum = nil
+          if Chef::FileCache.has_key?(cache_file)
+            current_checksum = checksum(Chef::FileCache.load(cache_file, false))
+          end
 
-        if current_checksum != rf['checksum']
-          changed = true
-          begin
-            raw_file = @rest.get_rest(rf_url, true)
-          rescue Net::HTTPRetriableError =&gt; e
-            if e.response.kind_of?(Net::HTTPNotModified)
-              changed = false
-              Chef::Log.debug(&quot;Cache file #{cache_file} is unchanged&quot;)
-            else
-              raise e
+          rf_url = generate_cookbook_url(
+            rf['name'], 
+            cookbook_name, 
+            segment, 
+            @node, 
+            current_checksum ? { 'checksum' =&gt; current_checksum } : nil
+          )
+          if current_checksum != rf['checksum']
+            changed = true
+            begin
+              raw_file = @rest.get_rest(rf_url, true)
+            rescue Net::HTTPRetriableError =&gt; e
+              if e.response.kind_of?(Net::HTTPNotModified)
+                changed = false
+                Chef::Log.debug(&quot;Cache file #{cache_file} is unchanged&quot;)
+              else
+                raise e
+              end
             end
-          end
 
-          if changed
-            Chef::Log.info(&quot;Storing updated #{cache_file} in the cache.&quot;)
-            Chef::FileCache.move_to(raw_file.path, cache_file)
+            if changed
+              Chef::Log.info(&quot;Storing updated #{cache_file} in the cache.&quot;)
+              Chef::FileCache.move_to(raw_file.path, cache_file)
+            end
           end
         end
-      end
-      
-      Chef::FileCache.list.each do |cache_file|
-        if cache_file.match(&quot;cookbooks/.+?/#{segment}&quot;)
-          unless file_canonical[cache_file]
-            Chef::Log.info(&quot;Removing #{cache_file} from the cache; it is no longer on the server.&quot;)
-            Chef::FileCache.delete(cache_file)
+
+        Chef::FileCache.list.each do |cache_file|
+          if cache_file =~ /^cookbooks\/(recipes|attributes|definitions|libraries)\//
+            unless file_canonical[cache_file]
+              Chef::Log.info(&quot;Removing #{cache_file} from the cache; it is no longer on the server.&quot;)
+              Chef::FileCache.delete(cache_file)
+            end
           end
         end
+
       end
       
     end
-    
-    # Gets all the attribute files included in all the cookbooks available on the server,
-    # and executes them.
-    #
-    # === Returns
-    # true:: Always returns true
-    def sync_attribute_files
-      Chef::Log.debug(&quot;Synchronizing attributes&quot;)
-      update_file_cache(&quot;attributes&quot;, @rest.get_rest(&quot;cookbooks/_attribute_files?node=#{@node.name}&quot;))
-      true
-    end
-    
-    # Gets all the library files included in all the cookbooks available on the server,
-    # and loads them.
-    #
-    # === Returns
-    # true:: Always returns true
-    def sync_library_files
-      Chef::Log.debug(&quot;Synchronizing libraries&quot;)
-      update_file_cache(&quot;libraries&quot;, @rest.get_rest(&quot;cookbooks/_library_files?node=#{@node.name}&quot;))
-      true
-    end
-    
-    # Gets all the definition files included in all the cookbooks available on the server,
-    # and loads them.
-    #
-    # === Returns
-    # true:: Always returns true
-    def sync_definitions
-      Chef::Log.debug(&quot;Synchronizing definitions&quot;) 
-      update_file_cache(&quot;definitions&quot;, @rest.get_rest(&quot;cookbooks/_definition_files?node=#{@node.name}&quot;))
-    end
-    
-    # Gets all the recipe files included in all the cookbooks available on the server,
-    # and loads them.
+
+    # Synchronizes all the cookbooks from the chef-server.
     #
     # === Returns
     # true:: Always returns true
-    def sync_recipes
-      Chef::Log.debug(&quot;Synchronizing recipes&quot;)
-      update_file_cache(&quot;recipes&quot;, @rest.get_rest(&quot;cookbooks/_recipe_files?node=#{@node.name}&quot;))
+    def sync_cookbooks
+      Chef::Log.debug(&quot;Synchronizing cookbooks&quot;)
+      cookbook_hash = @rest.get_rest(&quot;nodes/#{@safe_name}/cookbooks&quot;)
+      cookbook_hash.each do |cookbook_name, parts|
+        update_file_cache(cookbook_name, parts)
+      end
     end
     
     # Updates the current node configuration on the server.
@@ -382,15 +320,6 @@ class Chef
       cr.converge
       true
     end
-        
-    protected
-      # Generates a random password of &quot;len&quot; length.
-      def random_password(len)
-        chars = (&quot;a&quot;..&quot;z&quot;).to_a + (&quot;A&quot;..&quot;Z&quot;).to_a + (&quot;0&quot;..&quot;9&quot;).to_a
-        newpass = &quot;&quot;
-        1.upto(len) { |i| newpass &lt;&lt; chars[rand(chars.size-1)] }
-        newpass
-      end
 
   end
 end</diff>
      <filename>chef/lib/chef/client.rb</filename>
    </modified>
    <modified>
      <diff>@@ -17,6 +17,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+require 'chef/log'
 require 'mixlib/config'
 
 class Chef
@@ -54,11 +55,13 @@ class Chef
           :template_url,
           :remotefile_url,
           :search_url,
+          :chef_server_url,
           :role_url ].each do |u| 
             c[u] = url
         end
       end
     end
+
     # Override the config dispatch to set the value of log_location configuration option
     #
     # === Parameters
@@ -79,7 +82,7 @@ class Chef
 
     authorized_openid_identifiers nil
     authorized_openid_providers nil
-    chef_server_url nil
+    chef_server_url &quot;http://localhost:4000&quot;
     cookbook_path [ &quot;/var/chef/site-cookbooks&quot;, &quot;/var/chef/cookbooks&quot; ]
     couchdb_database &quot;chef&quot;
     couchdb_url &quot;http://localhost:5984&quot;
@@ -105,14 +108,9 @@ class Chef
     openid_store_path &quot;/var/chef/openid/db&quot;
     openid_url &quot;http://localhost:4001&quot;
     pid_file nil
-    queue_host &quot;localhost&quot;
-    queue_password &quot;&quot;
-    queue_port 61613
-    queue_retry_count 5
-    queue_retry_delay 5
-    queue_user &quot;&quot;
-    queue_prefix nil
     registration_url &quot;http://localhost:4000&quot;
+    certificate_url &quot;http://localhost:4000&quot;
+    client_url &quot;http://localhost:4042&quot;
     remotefile_url &quot;http://localhost:4000&quot;
     rest_timeout 60
     run_command_stderr_timeout 120
@@ -130,5 +128,22 @@ class Chef
     role_path &quot;/var/chef/roles&quot;
     role_url &quot;http://localhost:4000&quot;
     recipe_url nil
+    solr_url &quot;http://localhost:8983&quot;
+    solr_jetty_path &quot;/var/chef/solr-jetty&quot;
+    solr_data_path &quot;/var/chef/solr/data&quot;
+    solr_home_path &quot;/var/chef/solr&quot;
+    solr_heap_size &quot;256M&quot;
+    solr_java_opts nil
+    nanite_host '0.0.0.0'
+    nanite_port '5672'
+    nanite_user 'nanite'
+    nanite_pass 'testing'
+    nanite_vhost '/nanite'
+    nanite_identity nil
+
+    client_key &quot;/etc/chef/client.pem&quot;
+    validation_key &quot;/etc/chef/validation.pem&quot;
+    validation_client_name &quot;chef-validator&quot;
+
   end
 end</diff>
      <filename>chef/lib/chef/config.rb</filename>
    </modified>
    <modified>
      <diff>@@ -21,40 +21,77 @@ require 'chef/rest'
 require 'chef/log'
 require 'digest/sha2'
 require 'json'
+require 'uuidtools'
+require 'chef/nanite'
 
 class Chef
   class CouchDB
     include Chef::Mixin::ParamsValidate
 
-    def initialize(url=nil)
+    def initialize(url=nil, db=Chef::Config[:couchdb_database])
       url ||= Chef::Config[:couchdb_url]
-      @rest = Chef::REST.new(url)
+      @db = db
+      @rest = Chef::REST.new(url, nil, nil)
+    end
+
+    def couchdb_database(args=nil)
+      if args
+        @db = args
+      else
+        @db
+      end
+    end
+
+    def create_id_map
+      create_design_document(
+        &quot;id_map&quot;, 
+        {
+          &quot;version&quot; =&gt; 1,
+          &quot;language&quot; =&gt; &quot;javascript&quot;,
+          &quot;views&quot; =&gt; {
+            &quot;name_to_id&quot; =&gt; {
+              &quot;map&quot; =&gt; &lt;&lt;-EOJS
+                function(doc) {
+                  emit([ doc.chef_type, doc.name], doc._id);
+                }
+              EOJS
+            },
+            &quot;id_to_name&quot; =&gt; {
+              &quot;map&quot; =&gt; &lt;&lt;-EOJS
+                function(doc) { 
+                  emit(doc._id, [ doc.chef_type, doc.name ]);
+                }
+              EOJS
+            }
+          }
+        }
+      )
     end
     
     def create_db
       @database_list = @rest.get_rest(&quot;_all_dbs&quot;)
-      unless @database_list.detect { |db| db == Chef::Config[:couchdb_database] }
-        response = @rest.put_rest(Chef::Config[:couchdb_database], Hash.new)
+      unless @database_list.detect { |db| db == couchdb_database }
+        response = @rest.put_rest(couchdb_database, Hash.new)
       end
-      Chef::Config[:couchdb_database]
+      couchdb_database
     end
     
     def create_design_document(name, data)
       create_db
       to_update = true
       begin
-        old_doc = @rest.get_rest(&quot;#{Chef::Config[:couchdb_database]}/_design%2F#{name}&quot;)
+        old_doc = @rest.get_rest(&quot;#{couchdb_database}/_design/#{name}&quot;)
         if data[&quot;version&quot;] != old_doc[&quot;version&quot;]
           data[&quot;_rev&quot;] = old_doc[&quot;_rev&quot;]
           Chef::Log.debug(&quot;Updating #{name} views&quot;)
         else
           to_update = false
         end
-      rescue
-        Chef::Log.debug(&quot;Creating #{name} views for the first time&quot;)
+      rescue 
+        Chef::Log.debug(&quot;Creating #{name} views for the first time because: #{$!}&quot;)
       end
       if to_update
-        @rest.put_rest(&quot;#{Chef::Config[:couchdb_database]}/_design%2F#{name}&quot;, data)
+        @rest.put_rest(&quot;#{couchdb_database}/_design%2F#{name}&quot;, data)
       end
       true
     end
@@ -70,7 +107,29 @@ class Chef
           :object =&gt; { :respond_to =&gt; :to_json },
         }
       )
-      @rest.put_rest(&quot;#{Chef::Config[:couchdb_database]}/#{obj_type}_#{safe_name(name)}&quot;, object)
+      r = get_view(&quot;id_map&quot;, &quot;name_to_id&quot;, :key =&gt; [ obj_type, name ])
+      uuid = nil
+      if r[&quot;rows&quot;].length == 1
+        uuid = r[&quot;rows&quot;][0][&quot;id&quot;]
+      else
+        uuid = UUIDTools::UUID.random_create.to_s
+      end
+        
+      r = @rest.put_rest(&quot;#{couchdb_database}/#{uuid}&quot;, object)
+      Chef::Log.info(&quot;Sending #{uuid} to Nanite for indexing..&quot;)
+      n = Chef::Nanite.request(
+        &quot;/index/add&quot;,
+        { 
+          :id =&gt; uuid,
+          :database =&gt; couchdb_database,
+          :type =&gt; obj_type,
+          :item =&gt; object
+        },
+        :persistent =&gt; true
+      ) do |response_full|
+        Chef::Log.debug(&quot;Finished indexing #{obj_type} #{uuid} in #{couchdb_database}&quot;);
+      end
+      r
     end
 
     def load(obj_type, name)
@@ -84,7 +143,9 @@ class Chef
           :name =&gt; { :kind_of =&gt; String },
         }
       )
-      @rest.get_rest(&quot;#{Chef::Config[:couchdb_database]}/#{obj_type}_#{safe_name(name)}&quot;)
+      doc = find_by_name(obj_type, name)
+      doc.couchdb = self if doc.respond_to?(:couchdb)
+      doc 
     end
   
     def delete(obj_type, name, rev=nil)
@@ -98,15 +159,30 @@ class Chef
           :name =&gt; { :kind_of =&gt; String },
         }
       )
+      del_id = nil 
+      last_obj, obj_id = find_by_name(obj_type, name, true)
       unless rev
-        last_obj = @rest.get_rest(&quot;#{Chef::Config[:couchdb_database]}/#{obj_type}_#{safe_name(name)}&quot;)
         if last_obj.respond_to?(:couchdb_rev)
           rev = last_obj.couchdb_rev
         else
           rev = last_obj['_rev']
         end
       end
-      @rest.delete_rest(&quot;#{Chef::Config[:couchdb_database]}/#{obj_type}_#{safe_name(name)}?rev=#{rev}&quot;)
+      r = @rest.delete_rest(&quot;#{couchdb_database}/#{obj_id}?rev=#{rev}&quot;)
+      r.couchdb = self if r.respond_to?(:couchdb)
+      Chef::Log.info(&quot;Sending #{obj_id} to Nanite for deletion..&quot;)
+      n = Chef::Nanite.request(
+        &quot;/index/delete&quot;,
+        { 
+          :id =&gt; obj_id,
+          :database =&gt; couchdb_database,
+          :type =&gt; obj_type
+        },
+        :persistent =&gt; true
+      ) do |response_full|
+        Chef::Log.debug(&quot;Finished Deleting #{obj_type} #{obj_id} in #{couchdb_database}&quot;);
+      end
+      r
     end
   
     def list(view, inflate=false)
@@ -119,10 +195,13 @@ class Chef
         }
       )
       if inflate
-        @rest.get_rest(view_uri(view, &quot;all&quot;))
+        r = @rest.get_rest(view_uri(view, &quot;all&quot;))
+        r[&quot;rows&quot;].each { |i| i[&quot;value&quot;].couchdb = self if i[&quot;value&quot;].respond_to?(:couchdb=) }
+        r
       else
-        @rest.get_rest(view_uri(view, &quot;all_id&quot;))
+        r = @rest.get_rest(view_uri(view, &quot;all_id&quot;))
       end
+      r
     end
   
     def has_key?(obj_type, name)
@@ -137,13 +216,25 @@ class Chef
         }
       )
       begin
-        @rest.get_rest(&quot;#{Chef::Config[:couchdb_database]}/#{obj_type}_#{safe_name(name)}&quot;)
+        find_by_name(obj_type, name)
         true
       rescue
         false
       end
     end
 
+    def find_by_name(obj_type, name, with_id=false)
+      r = get_view(&quot;id_map&quot;, &quot;name_to_id&quot;, :key =&gt; [ obj_type, name ], :include_docs =&gt; true)
+      if r[&quot;rows&quot;].length == 0
+        raise Chef::Exceptions::CouchDBNotFound, &quot;Cannot find #{obj_type} #{name} in CouchDB!&quot;
+      end
+      if with_id
+        [ r[&quot;rows&quot;][0][&quot;doc&quot;], r[&quot;rows&quot;][0][&quot;id&quot;] ]
+      else
+        r[&quot;rows&quot;][0][&quot;doc&quot;] 
+      end
+    end
+
     def get_view(design, view, options={})
       view_string = view_uri(design, view)
       view_string &lt;&lt; &quot;?&quot; if options.length != 0
@@ -151,14 +242,21 @@ class Chef
       options.each { |k,v| view_string &lt;&lt; &quot;#{first ? '' : '&amp;'}#{k}=#{URI.escape(v.to_json)}&quot;; first = false }
       @rest.get_rest(view_string)
     end
+
+    def bulk_get(*to_fetch)
+      response = @rest.post_rest(&quot;#{couchdb_database}/_all_docs?include_docs=true&quot;, { &quot;keys&quot; =&gt; to_fetch.flatten })
+      response[&quot;rows&quot;].collect { |r| r[&quot;doc&quot;].couchdb = self; r[&quot;doc&quot;] }
+    end
     
     def view_uri(design, view)
-      Chef::Config[:couchdb_version] ||= @rest.run_request(:GET, URI.parse(@rest.url + &quot;/&quot;), false, 10, false)[&quot;version&quot;].gsub(/-.+/,&quot;&quot;).to_f
+      Chef::Config[:couchdb_version] ||= @rest.run_request(:GET, URI.parse(@rest.url + &quot;/&quot;), {}, false, 10, false)[&quot;version&quot;].gsub(/-.+/,&quot;&quot;).to_f
       case Chef::Config[:couchdb_version]
       when 0.9
-        &quot;#{Chef::Config[:couchdb_database]}/_design/#{design}/_view/#{view}&quot;
+        &quot;#{couchdb_database}/_design/#{design}/_view/#{view}&quot;
       when 0.8
-        &quot;#{Chef::Config[:couchdb_database]}/_view/#{design}/#{view}&quot;
+        &quot;#{couchdb_database}/_view/#{design}/#{view}&quot;
+      else
+        &quot;#{couchdb_database}/_design/#{design}/_view/#{view}&quot;
       end
     end
     
@@ -167,6 +265,6 @@ class Chef
       def safe_name(name)
         name.gsub(/\./, &quot;_&quot;)
       end
-      
+
   end
 end</diff>
      <filename>chef/lib/chef/couchdb.rb</filename>
    </modified>
    <modified>
      <diff>@@ -32,5 +32,8 @@ class Chef
     class Group &lt; RuntimeError; end
     class Link &lt; RuntimeError; end
     class Mount &lt; RuntimeError; end
+    class CouchDBNotFound &lt; RuntimeError; end
+    class PrivateKeyMissing &lt; RuntimeError; end
+    class CannotWritePrivateKey &lt; RuntimeError; end
   end
 end</diff>
      <filename>chef/lib/chef/exceptions.rb</filename>
    </modified>
    <modified>
      <diff>@@ -29,19 +29,28 @@ class Chef
         else
           new_url = &quot;cookbooks/#{cookbook}/#{type}?&quot;
           new_url += &quot;id=#{url}&quot;
-          platform, version = Chef::Platform.find_platform_and_version(node)
-          if type == &quot;files&quot; || type == &quot;templates&quot;
-            new_url += &quot;&amp;platform=#{platform}&amp;version=#{version}&amp;fqdn=#{node[:fqdn]}&amp;node_name=#{node.name}&quot;
-          end
-          if args
-            args.each do |key, value|
-              new_url += &quot;&amp;#{key}=#{value}&quot;
-            end
-          end
+          new_url = generate_cookbook_url_from_uri(new_url, node, args)
         end
 
         return new_url
       end
+
+      def generate_cookbook_url_from_uri(uri, node, args=nil)
+        platform, version = Chef::Platform.find_platform_and_version(node)
+        uri =~ /cookbooks\/(.+?)\/(.+)\?/
+        cookbook = $1
+        type = $2
+        if type == &quot;files&quot; || type == &quot;templates&quot;
+          uri += &quot;&amp;platform=#{platform}&amp;version=#{version}&amp;fqdn=#{node[:fqdn]}&amp;node_name=#{node.name}&quot;
+        end
+        if args
+          args.each do |key, value|
+            uri += &quot;&amp;#{key}=#{value}&quot;
+          end
+        end
+
+        uri
+      end
       
     end
   end</diff>
      <filename>chef/lib/chef/mixin/generate_url.rb</filename>
    </modified>
    <modified>
      <diff>@@ -16,6 +16,8 @@
 # limitations under the License.
 #
 
+require 'chef/search/query'
+
 class Chef
   module Mixin
     module Language
@@ -73,6 +75,10 @@ class Chef
   
         has_platform
       end
+
+      def search(*args, &amp;block)
+        Chef::Search::Query.new.search(*args, &amp;block)
+      end
       
     end
   end</diff>
      <filename>chef/lib/chef/mixin/language.rb</filename>
    </modified>
    <modified>
      <diff>@@ -21,7 +21,6 @@ require 'chef/mixin/check_helper'
 require 'chef/mixin/params_validate'
 require 'chef/mixin/from_file'
 require 'chef/couchdb'
-require 'chef/queue'
 require 'chef/run_list'
 require 'chef/node/attribute'
 require 'extlib'
@@ -30,14 +29,14 @@ require 'json'
 class Chef
   class Node
     
-    attr_accessor :attribute, :recipe_list, :couchdb_rev, :run_state, :run_list, :override, :default
+    attr_accessor :attribute, :recipe_list, :couchdb_rev, :couchdb_id, :run_state, :run_list, :override, :default
     
     include Chef::Mixin::CheckHelper
     include Chef::Mixin::FromFile
     include Chef::Mixin::ParamsValidate
     
     DESIGN_DOCUMENT = {
-      &quot;version&quot; =&gt; 8,
+      &quot;version&quot; =&gt; 9,
       &quot;language&quot; =&gt; &quot;javascript&quot;,
       &quot;views&quot; =&gt; {
         &quot;all&quot; =&gt; {
@@ -120,7 +119,7 @@ class Chef
     }
     
     # Create a new Chef::Node object.
-    def initialize()
+    def initialize
       @name = nil
 
       @attribute = Mash.new
@@ -129,6 +128,7 @@ class Chef
       @run_list = Chef::RunList.new 
 
       @couchdb_rev = nil
+      @couchdb_id = nil
       @couchdb = Chef::CouchDB.new
       @run_state = {
         :template_cache =&gt; Hash.new,
@@ -279,53 +279,32 @@ class Chef
       @run_list.detect { |r| r == item } ? true : false
     end
     
-    # Turns the node into an object that we can index.  I apologize up front for the
-    # super confusion that is the recursive index_flatten hash, which comes up next.
-    # Faith, young one, faith.
-    #
-    # === Returns
-    # index_hash&lt;Hash&gt;:: A flattened hash of all the nodes attributes, suitable for indexing.
-    def to_index
-      index_hash = {
-        &quot;index_name&quot; =&gt; &quot;node&quot;,
-        &quot;id&quot; =&gt; &quot;node_#{@name}&quot;,
-        &quot;name&quot; =&gt; @name,
-      }
-      @attribute.each do |key, value|
-        if value.kind_of?(Hash) || value.kind_of?(Mash)
-          index_flatten_hash(key, value).each do |to_index|
-            to_index.each do |nk, nv|
-              index_hash[nk] = nv
-            end
-          end
+    # Set an attribute based on the missing method.  If you pass an argument, we'll use that
+    # to set the attribute values.  Otherwise, we'll wind up just returning the attributes
+    # value.
+    def method_missing(symbol, *args)
+      if args.length != 0
+        @attribute[symbol] = args.length == 1 ? args[0] : args
+      else
+        if @attribute.has_key?(symbol)
+          @attribute[symbol]
         else
-          index_hash[key] = value
+          raise ArgumentError, &quot;Attribute #{symbol.to_s} is not defined!&quot;
         end
       end
-      index_hash[&quot;recipe&quot;] = @run_list.recipes if @run_list.recipes.length &gt; 0
+    end
+ 
+    # Transform the node to a Hash
+    def to_hash
+      index_hash = @attribute
+      index_hash[&quot;chef_type&quot;] = &quot;node&quot;
+      index_hash[&quot;name&quot;] = @name
+      index_hash[&quot;recipes&quot;] = @run_list.recipes if @run_list.recipes.length &gt; 0
       index_hash[&quot;roles&quot;] = @run_list.roles if @run_list.roles.length &gt; 0
       index_hash[&quot;run_list&quot;] = @run_list.run_list if @run_list.run_list.length &gt; 0
       index_hash
     end
     
-    # Ah, song of my heart, index_flatten_hash.  This method flattens a hash in preparation
-    # for indexing, by appending the name of it's parent to a current key with an _.  Hence,
-    # node[:bar][:baz] = 'monkey' becomes bar_baz:monkey.
-    #
-    # === Returns
-    # results&lt;Array&gt;:: An array of hashes with one element.
-    def index_flatten_hash(parent_name, hash)
-      results = Array.new
-      hash.each do |k, v|
-        if v.kind_of?(Hash) || v.kind_of?(Mash)
-          results &lt;&lt; index_flatten_hash(&quot;#{parent_name}_#{k}&quot;, v)
-        else
-          results &lt;&lt; { &quot;#{parent_name}_#{k}&quot;, v }
-        end
-      end
-      results.flatten
-    end
-    
     # Serialize this object as a hash 
     def to_json(*a)
       result = {
@@ -358,13 +337,15 @@ class Chef
         o[&quot;recipes&quot;].each { |r| node.recipes &lt;&lt; r }
       end
       node.couchdb_rev = o[&quot;_rev&quot;] if o.has_key?(&quot;_rev&quot;)
+      node.couchdb_id = o[&quot;_id&quot;] if o.has_key?(&quot;_id&quot;)
       node
     end
     
     # List all the Chef::Node objects in the CouchDB.  If inflate is set to true, you will get
     # the full list of all Nodes, fully inflated.
     def self.list(inflate=false)
-      rs = Chef::CouchDB.new.list(&quot;nodes&quot;, inflate)
+      couchdb = Chef::CouchDB.new
+      rs = couchdb.list(&quot;nodes&quot;, inflate)
       if inflate
         rs[&quot;rows&quot;].collect { |r| r[&quot;value&quot;] }
       else
@@ -374,25 +355,25 @@ class Chef
     
     # Load a node by name from CouchDB
     def self.load(name)
-      Chef::CouchDB.new.load(&quot;node&quot;, name)
+      couchdb = Chef::CouchDB.new
+      couchdb.load(&quot;node&quot;, name)
     end
     
     # Remove this node from the CouchDB
     def destroy
-      Chef::Queue.send_msg(:queue, :remove, self)
       @couchdb.delete(&quot;node&quot;, @name, @couchdb_rev)
     end
     
     # Save this node to the CouchDB
     def save
-      Chef::Queue.send_msg(:queue, :index, self)
       results = @couchdb.store(&quot;node&quot;, @name, self)
       @couchdb_rev = results[&quot;rev&quot;]
     end
-    
+
     # Set up our CouchDB design document
     def self.create_design_document
-      Chef::CouchDB.new.create_design_document(&quot;nodes&quot;, DESIGN_DOCUMENT)
+      couchdb = Chef::CouchDB.new
+      couchdb.create_design_document(&quot;nodes&quot;, DESIGN_DOCUMENT)
     end
     
     # As a string</diff>
      <filename>chef/lib/chef/node.rb</filename>
    </modified>
    <modified>
      <diff>@@ -178,4 +178,4 @@ class Chef
       end
     
   end
-end
\ No newline at end of file
+end</diff>
      <filename>chef/lib/chef/openid_registration.rb</filename>
    </modified>
    <modified>
      <diff>@@ -142,7 +142,6 @@ class Chef
         if pmap.has_key?(rtkey)
           pmap[rtkey]
         else
-          Chef::Log.error(&quot;#{rtkey.inspect} #{pmap.inspect}&quot;)
           raise(
             ArgumentError, 
             &quot;Cannot find a provider for #{resource_type} on #{platform} version #{version}&quot;</diff>
      <filename>chef/lib/chef/platform.rb</filename>
    </modified>
    <modified>
      <diff>@@ -25,7 +25,7 @@ class Chef
       attr_accessor :rest
       
       def load_current_resource
-        @rest = Chef::REST.new(@new_resource.url)
+        @rest = Chef::REST.new(@new_resource.url, nil, nil)
       end
       
       # Send a GET request to @new_resource.url, with ?message=@new_resource.message
@@ -99,4 +99,4 @@ class Chef
       
     end
   end
-end
\ No newline at end of file
+end</diff>
      <filename>chef/lib/chef/provider/http_request.rb</filename>
    </modified>
    <modified>
      <diff>@@ -95,7 +95,7 @@ class Chef
         begin
           uri = URI.parse(source)
           if uri.absolute
-            r = Chef::REST.new(source)
+            r = Chef::REST.new(source, nil, nil)
             Chef::Log.debug(&quot;Downloading from absolute URI: #{source}&quot;)
             r.get_rest(source, true).open
           end</diff>
      <filename>chef/lib/chef/provider/remote_file.rb</filename>
    </modified>
    <modified>
      <diff>@@ -34,7 +34,6 @@ class Chef
       include Chef::Mixin::FindPreferredFile
       
       def action_create
-        Chef::Log.debug(@node.run_state.inspect)
         raw_template_file = nil
         
         cookbook_name = @new_resource.cookbook || @new_resource.cookbook_name
@@ -137,4 +136,4 @@ class Chef
       
     end
   end
-end
\ No newline at end of file
+end</diff>
      <filename>chef/lib/chef/provider/template.rb</filename>
    </modified>
    <modified>
      <diff>@@ -23,7 +23,6 @@ require 'chef/mixin/language'
 require 'chef/resource_collection'
 require 'chef/cookbook_loader'
 require 'chef/rest'
-require 'chef/search/result'
 
 class Chef
   class Recipe
@@ -89,21 +88,6 @@ class Chef
       @collection.resources(*args)
     end
     
-    def search(type, query, attributes=[], &amp;block)
-      Chef::Log.debug(&quot;Searching #{type} index with #{query}&quot;)
-      r = Chef::REST.new(Chef::Config[:search_url])
-
-      results = r.get_rest(&quot;search/#{type}?q=#{query}&amp;a=#{attributes.join(',')}&quot;)
-      Chef::Log.debug(&quot;Searching #{type} index with #{query} returned #{results.length} entries&quot;)
-      if block
-        results.each do |sr|
-          block.call(sr)
-        end
-      else
-        results
-      end
-    end
-    
     # Sets a tag, or list of tags, for this node.  Syntactic sugar for
     # @node[:tags].  
     #</diff>
      <filename>chef/lib/chef/recipe.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,8 @@
 #
 # Author:: Adam Jacob (&lt;adam@opscode.com&gt;)
 # Author:: Thom May (&lt;thom@clearairturbulence.org&gt;)
-# Copyright:: Copyright (c) 2008 Opscode, Inc.
+# Author:: Nuo Yan (&lt;nuo@opscode.com&gt;)
+# Copyright:: Copyright (c) 2009 Opscode, Inc.
 # License:: Apache License, Version 2.0
 #
 # Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
@@ -24,6 +25,9 @@ require 'uri'
 require 'json'
 require 'tempfile'
 require 'singleton'
+require 'mixlib/auth/signedheaderauth'
+
+include Mixlib::Auth::SignedHeaderAuth
 
 class Chef
   class REST
@@ -32,47 +36,57 @@ class Chef
       include Singleton
     end
     
-    attr_accessor :url, :cookies
+    attr_accessor :url, :cookies, :signing_key
     
-    def initialize(url)
+    def initialize(url, client_name=Chef::Config[:node_name], signing_key=Chef::Config[:client_key])
       @url = url
       @cookies = CookieJar.instance
+      @client_name = client_name
+      if signing_key
+        @signing_key = load_signing_key(signing_key) 
+      else
+        @signing_key = nil
+      end
+    end
+
+    def load_signing_key(key)
+      if File.exists?(key) &amp;&amp; File.readable?(key)
+        IO.read(key)
+      else
+        raise Chef::Exceptions::PrivateKeyMissing, &quot;I cannot find #{key}, which you told me to use to sign requests!&quot;
+      end
     end
     
-    # Register for an OpenID
-    def register(user, pass, validation_token=nil)
-      Chef::Log.debug(&quot;Registering #{user} for an openid&quot;) 
-      registration = nil
+    # Register the client 
+    def register(name=Chef::Config[:node_name], destination=Chef::Config[:client_key])
+
+      if File.exists?(destination)
+        raise Chef::Exceptions::CannotWritePrivateKey, &quot;I cannot write your private key to #{destination} - check permissions?&quot; unless File.writable?(destination)
+      end
+
+      # First, try and create a new registration
       begin
-        registration = get_rest(&quot;registrations/#{user}&quot;)
-      rescue Net::HTTPServerException =&gt; e
-        unless e.message =~ /^404/
-          raise e
-        end
+        Chef::Log.info(&quot;Registering API Client #{name}&quot;)
+        response = post_rest(&quot;clients&quot;, {:clientname =&gt; name})
+      rescue Net::HTTPServerException 
+        # If that fails, go ahead and try and update it
+        response = put_rest(&quot;clients/#{name}&quot;, { :clientname =&gt; name, :private_key =&gt; true }) 
       end
-      unless registration
-        post_rest(
-          &quot;registrations&quot;, 
-          { 
-            :id =&gt; user, 
-            :password =&gt; pass, 
-            :validation_token =&gt; validation_token 
-          }
-        )
+
+      Chef::Log.debug(&quot;Registration response: #{response.inspect}&quot;)
+
+      raise Chef::Exceptions::CannotWritePrivateKey, &quot;The response from the server did not include a private key!&quot; unless response.has_key?(&quot;private_key&quot;)
+
+      begin
+        # Write out the private key
+        file = File.open(destination, &quot;w&quot;)
+        file.print(response[&quot;private_key&quot;])
+        file.close
+      rescue 
+        raise Chef::Exceptions::CannotWritePrivateKey, &quot;I cannot write your private key to #{destination}&quot;
       end
-    end
-    
-    # Authenticate 
-    def authenticate(user, pass)
-      Chef::Log.debug(&quot;Authenticating #{user} via openid&quot;) 
-      response = post_rest('openid/consumer/start', { 
-        &quot;openid_identifier&quot; =&gt; &quot;#{Chef::Config[:openid_url]}/openid/server/node/#{user}&quot;,
-        &quot;submit&quot; =&gt; &quot;Verify&quot;
-      })
-      post_rest(
-        &quot;#{Chef::Config[:openid_url]}#{response[&quot;action&quot;]}&quot;,
-        { &quot;password&quot; =&gt; pass }
-      )
+
+      true
     end
 
     # Send an HTTP GET request to the path
@@ -81,23 +95,23 @@ class Chef
     # path:: The path to GET
     # raw:: Whether you want the raw body returned, or JSON inflated.  Defaults 
     #   to JSON inflated.
-    def get_rest(path, raw=false)
-      run_request(:GET, create_url(path), false, 10, raw)    
+    def get_rest(path, raw=false, headers={})
+      run_request(:GET, create_url(path), headers, false, 10, raw)    
     end                               
                           
     # Send an HTTP DELETE request to the path
-    def delete_rest(path)             
-      run_request(:DELETE, create_url(path))       
+    def delete_rest(path, headers={}) 
+      run_request(:DELETE, create_url(path), headers)       
     end                               
     
     # Send an HTTP POST request to the path                                  
-    def post_rest(path, json)          
-      run_request(:POST, create_url(path), json)    
+    def post_rest(path, json, headers={})
+      run_request(:POST, create_url(path), headers, json)    
     end                               
                                       
     # Send an HTTP PUT request to the path
-    def put_rest(path, json)           
-      run_request(:PUT, create_url(path), json)
+    def put_rest(path, json, headers={})
+      run_request(:PUT, create_url(path), headers, json)
     end
     
     def create_url(path)
@@ -108,6 +122,18 @@ class Chef
       end
     end
     
+    def sign_request(http_method, private_key, user_id, body = &quot;&quot;, host=&quot;localhost&quot;)
+      #body = &quot;&quot; if body == false
+      timestamp = Time.now.utc.iso8601
+      sign_obj = Mixlib::Auth::SignedHeaderAuth.signing_object(
+                                                         :http_method=&gt;http_method,
+                                                         :body=&gt;body,
+                                                         :user_id=&gt;user_id,
+                                                         :timestamp=&gt;timestamp)
+      signed =  sign_obj.sign(private_key).merge({:host =&gt; host})
+      signed.inject({}){|memo, kv| memo[&quot;#{kv[0].to_s.upcase}&quot;] = kv[1];memo}
+    end
+    
     # Actually run an HTTP request.  First argument is the HTTP method,
     # which should be one of :GET, :PUT, :POST or :DELETE.  Next is the
     # URL, then an object to include in the body (which will be converted with
@@ -117,7 +143,8 @@ class Chef
     # the helper methods (get_rest, post_rest, etc.)
     #
     # Will return the body of the response on success.
-    def run_request(method, url, data=false, limit=10, raw=false)
+    def run_request(method, url, headers={}, data=false, limit=10, raw=false)
+      
       http_retry_delay = Chef::Config[:http_retry_delay] 
       http_retry_count = Chef::Config[:http_retry_count]
 
@@ -129,21 +156,35 @@ class Chef
         if Chef::Config[:ssl_verify_mode] == :verify_none
           http.verify_mode = OpenSSL::SSL::VERIFY_NONE
         end
-        if File.exists?(Chef::Config[:ssl_client_cert])
+        if Chef::Config[:ssl_client_cert] &amp;&amp; File.exists?(Chef::Config[:ssl_client_cert])
           http.cert = OpenSSL::X509::Certificate.new(File.read(Chef::Config[:ssl_client_cert]))
           http.key = OpenSSL::PKey::RSA.new(File.read(Chef::Config[:ssl_client_key]))
         end
       end
+
       http.read_timeout = Chef::Config[:rest_timeout]
-      headers = Hash.new
+
       unless raw
-        headers = { 
+        headers = headers.merge({ 
           'Accept' =&gt; &quot;application/json&quot;,
-        }
+        })
       end
+      
       if @cookies.has_key?(&quot;#{url.host}:#{url.port}&quot;)
         headers['Cookie'] = @cookies[&quot;#{url.host}:#{url.port}&quot;]
       end
+
+      json_body = data ? data.to_json : nil 
+
+      if @signing_key
+        Chef::Log.debug(&quot;Signing the request as #{@client_name}&quot;)
+        if json_body
+          headers.merge!(sign_request(method, OpenSSL::PKey::RSA.new(@signing_key), @client_name, json_body, &quot;#{url.host}:#{url.port}&quot;))
+        else
+          headers.merge!(sign_request(method, OpenSSL::PKey::RSA.new(@signing_key), @client_name, &quot;&quot;, &quot;#{url.host}:#{url.port}&quot;))
+        end
+      end
+     
       req = nil
       case method
       when :GET
@@ -152,12 +193,16 @@ class Chef
         req = Net::HTTP::Get.new(req_path, headers)
       when :POST
         headers[&quot;Content-Type&quot;] = 'application/json' if data
-        req = Net::HTTP::Post.new(url.path, headers)          
-        req.body = data.to_json if data
+        req_path = &quot;#{url.path}&quot;
+        req_path &lt;&lt; &quot;?#{url.query}&quot; if url.query
+        req = Net::HTTP::Post.new(req_path, headers)          
+        req.body = json_body if json_body 
       when :PUT
         headers[&quot;Content-Type&quot;] = 'application/json' if data
-        req = Net::HTTP::Put.new(url.path, headers)
-        req.body = data.to_json if data
+        req_path = &quot;#{url.path}&quot;
+        req_path &lt;&lt; &quot;?#{url.query}&quot; if url.query
+        req = Net::HTTP::Put.new(req_path, headers)
+        req.body = json_body if json_body 
       when :DELETE
         req_path = &quot;#{url.path}&quot;
         req_path &lt;&lt; &quot;?#{url.query}&quot; if url.query
@@ -165,6 +210,8 @@ class Chef
       else
         raise ArgumentError, &quot;You must provide :GET, :PUT, :POST or :DELETE as the method&quot;
       end
+
+      Chef::Log.debug(&quot;Sending HTTP Request via #{req.method} to #{url.host}:#{url.port}/#{req.path}&quot;)
       
       # Optionally handle HTTP Basic Authentication
       req.basic_auth(url.user, url.password) if url.user
@@ -199,7 +246,8 @@ class Chef
           end
           response
         end
-      rescue Errno::ECONNREFUSED
+
+      rescue Errno::ECONNREFUSED =&gt; e
         Chef::Log.error(&quot;Connection refused connecting to #{url.host}:#{url.port} for #{req.path} #{http_retries}/#{http_retry_count}&quot;)
         sleep(http_retry_delay)
         retry if (http_retries += 1) &lt; http_retry_count
@@ -216,7 +264,8 @@ class Chef
           @cookies[&quot;#{url.host}:#{url.port}&quot;] = res['set-cookie']
         end
         if res['content-type'] =~ /json/
-          JSON.parse(res.body)
+          response_body = res.body.chomp
+          JSON.parse(response_body)
         else
           if raw
             tf
@@ -228,11 +277,11 @@ class Chef
         if res['set-cookie']
           @cookies[&quot;#{url.host}:#{url.port}&quot;] = res['set-cookie']
         end
-        run_request(:GET, create_url(res['location']), false, limit - 1, raw)
+        run_request(:GET, create_url(res['location']), {}, false, limit - 1, raw)
       else
         res.error!
       end
     end
- 
+    
   end
 end</diff>
      <filename>chef/lib/chef/rest.rb</filename>
    </modified>
    <modified>
      <diff>@@ -30,7 +30,7 @@ class Chef
     include Chef::Mixin::ParamsValidate
     
     DESIGN_DOCUMENT = {
-      &quot;version&quot; =&gt; 3,
+      &quot;version&quot; =&gt; 6,
       &quot;language&quot; =&gt; &quot;javascript&quot;,
       &quot;views&quot; =&gt; {
         &quot;all&quot; =&gt; {
@@ -50,21 +50,22 @@ class Chef
             }
           }
           EOJS
-        },
-      },
+        }
+      }
     }
 
-    attr_accessor :couchdb_rev
+    attr_accessor :couchdb_rev, :couchdb_id
     
     # Create a new Chef::Role object.
-    def initialize()
+    def initialize
       @name = '' 
       @description = '' 
       @default_attributes = Mash.new
       @override_attributes = Mash.new
       @recipes = Array.new 
       @couchdb_rev = nil
-      @couchdb = Chef::CouchDB.new
+      @couchdb_id = nil
+      @couchdb = Chef::CouchDB.new 
     end
 
     def name(arg=nil) 
@@ -139,13 +140,15 @@ class Chef
       role.override_attributes(o[&quot;override_attributes&quot;])
       role.recipes(o[&quot;recipes&quot;])
       role.couchdb_rev = o[&quot;_rev&quot;] if o.has_key?(&quot;_rev&quot;)
+      role.couchdb_id = o[&quot;_id&quot;] if o.has_key?(&quot;_id&quot;)
       role 
     end
     
     # List all the Chef::Role objects in the CouchDB.  If inflate is set to true, you will get
     # the full list of all Roles, fully inflated.
     def self.list(inflate=false)
-      rs = Chef::CouchDB.new.list(&quot;roles&quot;, inflate)
+      couchdb = Chef::CouchDB.new
+      rs = couchdb.list(&quot;roles&quot;, inflate)
       if inflate
         rs[&quot;rows&quot;].collect { |r| r[&quot;value&quot;] }
       else
@@ -155,7 +158,8 @@ class Chef
     
     # Load a role by name from CouchDB
     def self.load(name)
-      Chef::CouchDB.new.load(&quot;role&quot;, name)
+      couchdb = Chef::CouchDB.new
+      couchdb.load(&quot;role&quot;, name)
     end
     
     # Remove this role from the CouchDB
@@ -186,7 +190,8 @@ class Chef
     
     # Set up our CouchDB design document
     def self.create_design_document
-      Chef::CouchDB.new.create_design_document(&quot;roles&quot;, DESIGN_DOCUMENT)
+      couchdb = Chef::CouchDB.new
+      couchdb.create_design_document(&quot;roles&quot;, DESIGN_DOCUMENT)
     end
     
     # As a string
@@ -212,6 +217,7 @@ class Chef
 
     # Sync all the json roles with couchdb from disk
     def self.sync_from_disk_to_couchdb
+      couchdb = Chef::CouchDB.new
       Dir[File.join(Chef::Config[:role_path], &quot;*.json&quot;)].each do |role_file|
         short_name = File.basename(role_file, &quot;.json&quot;) 
         Chef::Log.warn(&quot;Loading #{short_name}&quot;)
@@ -220,7 +226,7 @@ class Chef
           couch_role = Chef::Role.load(short_name)
           r.couchdb_rev = couch_role.couchdb_rev
           Chef::Log.debug(&quot;Replacing role #{short_name} with data from #{role_file}&quot;)
-        rescue Net::HTTPServerException
+        rescue Chef::Exceptions::CouchDBNotFound 
           Chef::Log.debug(&quot;Creating role #{short_name} with data from #{role_file}&quot;)
         end
         r.save</diff>
      <filename>chef/lib/chef/role.rb</filename>
    </modified>
    <modified>
      <diff>@@ -111,7 +111,8 @@ class Chef
       self
     end
 
-    def expand(from='server')
+    def expand(from='server', couchdb=nil)
+      couchdb = couchdb ? couchdb : Chef::CouchDB.new
       recipes = Array.new
       default_attrs = Mash.new
       override_attrs = Mash.new
@@ -132,7 +133,7 @@ class Chef
             role = r.get_rest(&quot;roles/#{name}&quot;)
           elsif from == 'couchdb'
             # Load the role from couchdb
-            role = Chef::Role.load(name)
+            role = Chef::Role.load(name, couchdb)
           end
           role.recipes.each { |r| recipes &lt;&lt;  r unless recipes.include?(r) }
           default_attrs = Chef::Mixin::DeepMerge.merge(default_attrs, role.default_attributes)</diff>
      <filename>chef/lib/chef/run_list.rb</filename>
    </modified>
    <modified>
      <diff>@@ -30,13 +30,9 @@ describe Chef::Client, &quot;run&quot; do
     to_stub = [
       :build_node,
       :register,
-      :authenticate,
-      :sync_library_files,
-      :sync_attribute_files,
-      :sync_definitions,
-      :sync_recipes,
+      :sync_cookbooks,
       :save_node,
-      :save_node
+      :converge
     ]
     to_stub.each do |method|
       @client.stub!(method).and_return(true)
@@ -58,37 +54,17 @@ describe Chef::Client, &quot;run&quot; do
     @client.run
   end
   
-  it &quot;should register for an openid&quot; do
+  it &quot;should register for a client&quot; do
     @client.should_receive(:register).and_return(true)
     @client.run
   end
   
-  it &quot;should authenticate with the server&quot; do
-    @client.should_receive(:authenticate).and_return(true)
+  it &quot;should synchronize the cookbooks from the server&quot; do
+    @client.should_receive(:sync_cookbooks).and_return(true)
     @client.run
   end
   
-  it &quot;should synchronize definitions from the server&quot; do
-    @client.should_receive(:sync_definitions).and_return(true)
-    @client.run
-  end
-  
-  it &quot;should synchronize recipes from the server&quot; do
-    @client.should_receive(:sync_recipes).and_return(true)
-    @client.run
-  end
-  
-  it &quot;should synchronize and load library files from the server&quot; do
-    @client.should_receive(:sync_library_files).and_return(true)
-    @client.run
-  end
-  
-  it &quot;should synchronize and load attribute files from the server&quot; do
-    @client.should_receive(:sync_attribute_files).and_return(true)
-    @client.run
-  end
-  
-  it &quot;should save the nodes state on the server (twice!)&quot; do
+  it &quot;should save the nodes state on the server (thrice!)&quot; do
     @client.should_receive(:save_node).exactly(3).times.and_return(true)
     @client.run
   end
@@ -98,11 +74,6 @@ describe Chef::Client, &quot;run&quot; do
     @client.run
   end
 
-  it &quot;should set the cookbook_path&quot; do
-    Chef::Config.should_receive('[]').with(:file_cache_path).
-      and_return('/var/chef/cache/cookbooks')
-    @client.run
-  end
 end
 
 describe Chef::Client, &quot;run_solo&quot; do
@@ -149,6 +120,7 @@ describe Chef::Client, &quot;build_node&quot; do
     Chef::REST.stub!(:new).and_return(@mock_rest)
     @client = Chef::Client.new
     Chef::Platform.stub!(:find_platform_and_version).and_return([&quot;FooOS&quot;, &quot;1.3.3.7&quot;])
+    Chef::Config[:node_name] = nil
   end
   
   it &quot;should set the name equal to the FQDN&quot; do
@@ -208,35 +180,34 @@ describe Chef::Client, &quot;register&quot; do
   before do
     @mock_rest = mock(&quot;Chef::REST&quot;, :null_object =&gt; true)
     @mock_rest.stub!(:get_rest).and_return(true)
+    @mock_rest.stub!(:register).and_return(true)
     Chef::REST.stub!(:new).and_return(@mock_rest)
     @chef_client = Chef::Client.new
     @chef_client.safe_name = &quot;testnode&quot;
+    @chef_client.node_name = &quot;testnode&quot;
     @chef_client.stub!(:determine_node_name).and_return(true)
-    @chef_client.stub!(:create_registration).and_return(true)
-    Chef::Application.stub!(:fatal!).and_return(true)
-    Chef::FileCache.stub!(:create_cache_path).and_return(&quot;/tmp&quot;)
-    Chef::FileCache.stub!(:load).and_return(&quot;/tmp/testnode&quot;)
-  end
-
-  it &quot;should log an appropriate debug message regarding registering an openid&quot; do
-    Chef::Log.should_receive(:debug).with(&quot;Registering testnode for an openid&quot;).and_return(true)
-    @chef_client.register
+    File.stub!(:exists?).and_return(false)
   end
+  
+  describe &quot;when the validation key is present&quot; do
+    before(:each) do
+      File.stub!(:exists?).with(Chef::Config[:validation_key]).and_return(true)
+    end
 
-  it &quot;should fetch the registration based on safe_name from the chef server&quot; do
-    @mock_rest.should_receive(:get_rest).with(&quot;registrations/testnode&quot;).and_return(true)
-    @chef_client.register
-  end
+    it &quot;should sign requests with the validation key&quot; do
+      Chef::REST.should_receive(:new).with(Chef::Config[:client_url], Chef::Config[:validation_client_name], Chef::Config[:validation_key]).and_return(@mock_rest)
+      @chef_client.register
+    end
 
-  it &quot;should load the secret from disk&quot; do
-    Chef::FileCache.should_receive(:load).with(File.join(&quot;registration&quot;, &quot;testnode&quot;)).and_return(&quot;/tmp/testnode&quot;)
-    @chef_client.register
+    it &quot;should register for a new key-pair&quot; do
+      @mock_rest.should_receive(:register).with(&quot;testnode&quot;, Chef::Config[:client_key])
+      @chef_client.register
+    end
   end
 
-  it &quot;should cause chef to die fatally if the filecache cannot find the registration&quot; do
-    Chef::FileCache.stub!(:load).with(File.join(&quot;registration&quot;, &quot;testnode&quot;)).and_raise(Chef::Exceptions::FileNotFound)
-    Chef::Application.should_receive(:fatal!).with(/^.*$/, 3).and_return(true) 
-    @chef_client.register
+  it &quot;should setup the rest client to use the client key-pair&quot; do
+    Chef::REST.should_receive(:new).with(Chef::Config[:chef_server_url]).and_return(@mock_rest)
+    @chef_client.register 
   end
 
 end
@@ -256,3 +227,4 @@ describe Chef::Client, &quot;run_ohai&quot; do
     @chef_client.run_ohai
   end
 end
+</diff>
      <filename>chef/spec/unit/client_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -18,236 +18,245 @@
 
 require File.expand_path(File.join(File.dirname(__FILE__), &quot;..&quot;, &quot;spec_helper&quot;))
 
-describe Chef::CouchDB, &quot;new&quot; do
-  before do
+describe Chef::CouchDB do
+  before(:each) do
     @mock_rest = mock(&quot;Chef::REST&quot;, :null_object =&gt; true)
     @mock_rest.stub!(:run_request).and_return({&quot;couchdb&quot; =&gt; &quot;Welcome&quot;, &quot;version&quot; =&gt;&quot;0.9.0&quot;})
     @mock_rest.stub!(:url).and_return(&quot;http://localhost:5984&quot;)
     Chef::REST.stub!(:new).and_return(@mock_rest)
-  end
-  
-  it &quot;should create a new Chef::REST object from the default url&quot; do
-    Chef::Config[:couchdb_url] = &quot;http://monkey&quot;
-    Chef::REST.should_receive(:new).with(&quot;http://monkey&quot;)
-    Chef::CouchDB.new
+    @couchdb = Chef::CouchDB.new
+    Chef::Nanite.stub!(:request).and_return(true)
+    Chef::Nanite.stub!(:in_event).and_return(true)
+    Chef::Nanite.stub!(:start_mapper).and_return(true)
   end
 
-  it &quot;should create a new Chef::REST object from a provided url&quot; do
-    Chef::REST.should_receive(:new).with(&quot;http://monkeypants&quot;)
-    Chef::CouchDB.new(&quot;http://monkeypants&quot;)
-  end  
-end
+  describe &quot;new&quot; do
+    it &quot;should create a new Chef::REST object from the default url&quot; do
+      old_url = Chef::Config[:couchdb_url]
+      Chef::Config[:couchdb_url] = &quot;http://monkey&quot;
+      Chef::REST.should_receive(:new).with(&quot;http://monkey&quot;, nil, nil)
+      Chef::CouchDB.new
+      Chef::Config[:couchdb_url] = old_url
+    end
 
-describe Chef::CouchDB, &quot;create_db&quot; do
-  before(:each) do
-    @mock_rest = mock(&quot;Chef::REST&quot;, :null_object =&gt; true)
-    @mock_rest.stub!(:get_rest).and_return([ &quot;chef&quot; ])
-    @mock_rest.stub!(:put_rest).and_return(true)
-    Chef::REST.stub!(:new).and_return(@mock_rest)
-  end
-  
-  def do_create_db
-    couch = Chef::CouchDB.new
-    couch.create_db
-  end
-  
-  it &quot;should get a list of current databases&quot; do
-    @mock_rest.should_receive(:get_rest).and_return([&quot;chef&quot;])
-    do_create_db
-  end
-  
-  it &quot;should create the chef database if it does not exist&quot; do
-    @mock_rest.stub!(:get_rest).and_return([])
-    @mock_rest.should_receive(:put_rest).with(&quot;chef&quot;, {}).and_return(true)
-    do_create_db
+    it &quot;should create a new Chef::REST object from a provided url&quot; do
+      Chef::REST.should_receive(:new).with(&quot;http://monkeypants&quot;, nil, nil)
+      Chef::CouchDB.new(&quot;http://monkeypants&quot;)
+    end 
   end
-  
-  it &quot;should not create the chef database if it does exist&quot; do
-    @mock_rest.stub!(:get_rest).and_return([&quot;chef&quot;])
-    @mock_rest.should_not_receive(:put_rest)
-    do_create_db
-  end
-  
-  it &quot;should return 'chef'&quot; do
-    do_create_db.should eql(&quot;chef&quot;)
+
+  describe &quot;create_db&quot; do
+    before(:each) do
+      @couchdb.stub!(:create_design_document).and_return(true)
+    end
+    
+    it &quot;should get a list of current databases&quot; do
+      @mock_rest.should_receive(:get_rest).and_return([&quot;chef&quot;])
+      @couchdb.create_db
+    end
+    
+    it &quot;should create the chef database if it does not exist&quot; do
+      @mock_rest.stub!(:get_rest).and_return([])
+      @mock_rest.should_receive(:put_rest).with(&quot;chef&quot;, {}).and_return(true)
+      @couchdb.create_db
+    end
+    
+    it &quot;should not create the chef database if it does exist&quot; do
+      @mock_rest.stub!(:get_rest).and_return([&quot;chef&quot;])
+      @mock_rest.should_not_receive(:put_rest)
+      @couchdb.create_db
+    end
+    
+    it &quot;should return 'chef'&quot; do
+      @couchdb.create_db.should eql(&quot;chef&quot;)
+    end
   end
-end
 
-describe Chef::CouchDB, &quot;create_design_document&quot; do
-  before(:each) do
-    @mock_rest = mock(&quot;Chef::REST&quot;, :null_object =&gt; true)
-    @mock_design = {
-      &quot;version&quot; =&gt; 1,
-      &quot;_rev&quot; =&gt; 1
-    }
-    @mock_data = {
-      &quot;version&quot; =&gt; 1,
-      &quot;language&quot; =&gt; &quot;javascript&quot;,
-      &quot;views&quot; =&gt; {
-        &quot;all&quot; =&gt; {
-          &quot;map&quot; =&gt; &lt;&lt;-EOJS
-          function(doc) { 
-            if (doc.chef_type == &quot;node&quot;) {
-              emit(doc.name, doc);
+  describe &quot;create_design_document&quot; do
+    before(:each) do
+      @mock_design = {
+        &quot;version&quot; =&gt; 1,
+        &quot;_rev&quot; =&gt; 1
+      }
+      @mock_data = {
+        &quot;version&quot; =&gt; 1,
+        &quot;language&quot; =&gt; &quot;javascript&quot;,
+        &quot;views&quot; =&gt; {
+          &quot;all&quot; =&gt; {
+            &quot;map&quot; =&gt; &lt;&lt;-EOJS
+            function(doc) { 
+              if (doc.chef_type == &quot;node&quot;) {
+                emit(doc.name, doc);
+              }
             }
-          }
-          EOJS
-        },
+            EOJS
+          },
+        }
       }
-    }
-    @mock_rest.stub!(:get_rest).and_return(@mock_design)
-    @mock_rest.stub!(:put_rest).and_return(true)
-    Chef::REST.stub!(:new).and_return(@mock_rest)
-    @couchdb = Chef::CouchDB.new
-    @couchdb.stub!(:create_db).and_return(true)
-  end
-  
-  def do_create_design_document
-    @couchdb.create_design_document(&quot;bob&quot;, @mock_data)
-  end
-  
-  it &quot;should create the database if it does not exist&quot; do
-    @couchdb.should_receive(:create_db).and_return(true)
-    do_create_design_document
-  end
-  
-  it &quot;should fetch the existing design document&quot; do
-    @mock_rest.should_receive(:get_rest).with(&quot;chef/_design%2Fbob&quot;)
-    do_create_design_document
-  end
-  
-  it &quot;should populate the _rev in the new design if the versions dont match&quot; do
-    @mock_data[&quot;version&quot;] = 2
-    do_create_design_document
-    @mock_data[&quot;_rev&quot;].should eql(1)
-  end
-  
-  it &quot;should create the view if it requires updating&quot; do
-    @mock_data[&quot;version&quot;] = 2
-    @mock_rest.should_receive(:put_rest).with(&quot;chef/_design%2Fbob&quot;, @mock_data)
-    do_create_design_document
-  end
-  
-  it &quot;should not create the view if it does not require updating&quot; do
-    @mock_data[&quot;version&quot;] = 1
-    @mock_rest.should_not_receive(:put_rest)
-    do_create_design_document
+      @mock_rest.stub!(:get_rest).and_return(@mock_design)
+      @mock_rest.stub!(:put_rest).and_return(true)
+      @couchdb.stub!(:create_db).and_return(true)
+    end
+    
+    def do_create_design_document
+      @couchdb.create_design_document(&quot;bob&quot;, @mock_data)
+    end
+    
+    it &quot;should create the database if it does not exist&quot; do
+      @couchdb.should_receive(:create_db).and_return(true)
+      do_create_design_document
+    end
+    
+    it &quot;should fetch the existing design document&quot; do
+      @mock_rest.should_receive(:get_rest).with(&quot;chef/_design/bob&quot;)
+      do_create_design_document
+    end
+    
+    it &quot;should populate the _rev in the new design if the versions dont match&quot; do
+      @mock_data[&quot;version&quot;] = 2
+      do_create_design_document
+      @mock_data[&quot;_rev&quot;].should eql(1)
+    end
+    
+    it &quot;should create the view if it requires updating&quot; do
+      @mock_data[&quot;version&quot;] = 2
+      @mock_rest.should_receive(:put_rest).with(&quot;chef/_design%2Fbob&quot;, @mock_data)
+      do_create_design_document
+    end
+    
+    it &quot;should not create the view if it does not require updating&quot; do
+      @mock_data[&quot;version&quot;] = 1
+      @mock_rest.should_not_receive(:put_rest)
+      do_create_design_document
+    end
   end
-end
 
-describe Chef::CouchDB, &quot;store&quot; do
-  it &quot;should put the object into couchdb&quot; do
-    @mock_rest = mock(&quot;Chef::REST&quot;, :null_object =&gt; true)
-    @mock_rest.should_receive(:put_rest).with(&quot;chef/node_bob&quot;, {}).and_return(true)
-    Chef::REST.stub!(:new).and_return(@mock_rest)
-    Chef::CouchDB.new.store(&quot;node&quot;, &quot;bob&quot;, {})
-  end
-end
+  describe &quot;store&quot; do
+    before(:each) do 
+      @mock_results = {
+        &quot;rows&quot; =&gt; [
+          &quot;id&quot; =&gt; 'a0934635-e111-45d9-8223-cb58e1c9434c'
+        ]
+      }
+      @couchdb.stub!(:get_view).with(&quot;id_map&quot;, &quot;name_to_id&quot;, :key =&gt; [ &quot;node&quot;, &quot;bob&quot; ]).and_return(@mock_results)
+    end
 
-describe Chef::CouchDB, &quot;load&quot; do
-  it &quot;should load the object from couchdb&quot; do
-    @mock_rest = mock(&quot;Chef::REST&quot;, :null_object =&gt; true)
-    @mock_rest.should_receive(:get_rest).with(&quot;chef/node_bob&quot;).and_return(true)
-    Chef::REST.stub!(:new).and_return(@mock_rest)
-    Chef::CouchDB.new.load(&quot;node&quot;, &quot;bob&quot;).should eql(true)
-  end
-end
+    it &quot;should put the object into couchdb with a pre-existing GUID&quot; do
+      @mock_rest.should_receive(:put_rest).with(&quot;chef/#{@mock_results[&quot;rows&quot;][0][&quot;id&quot;]}&quot;, {}).and_return(true)
+      @couchdb.store(&quot;node&quot;, &quot;bob&quot;, {})
+    end
 
-describe Chef::CouchDB, &quot;delete&quot; do
-  before(:each) do
-    @mock_current = {
-      &quot;version&quot; =&gt; 1,
-      &quot;_rev&quot; =&gt; 1
-    }
-    @mock_rest = mock(&quot;Chef::REST&quot;, :null_object =&gt; true)
-    @mock_rest.stub!(:get_rest).and_return(@mock_current)
-    @mock_rest.stub!(:delete_rest).and_return(true)
-    Chef::REST.stub!(:new).and_return(@mock_rest)
-  end
-  
-  def do_delete(rev=nil)
-    Chef::REST.stub!(:new).and_return(@mock_rest)
-    Chef::CouchDB.new.delete(&quot;node&quot;, &quot;bob&quot;, rev)
-  end
-  
-  it &quot;should remove the object from couchdb with a specific revision&quot; do
-    @mock_rest.should_receive(:delete_rest).with(&quot;chef/node_bob?rev=1&quot;)
-    do_delete(1)  
-  end
-  
-  it &quot;should remove the object from couchdb based on the couchdb_rev of the current obj&quot; do
-    mock_real = mock(&quot;Inflated Object&quot;)
-    mock_real.stub!(:respond_to?).and_return(true)
-    mock_real.stub!(:couchdb_rev).and_return(2)
-    @mock_rest.should_receive(:get_rest).with(&quot;chef/node_bob&quot;).and_return(mock_real)
-    @mock_rest.should_receive(:delete_rest).with(&quot;chef/node_bob?rev=2&quot;)
-    do_delete
-  end
-  
-  it &quot;should remove the object from couchdb based on the current objects rev&quot; do
-    @mock_rest.should_receive(:delete_rest).with(&quot;chef/node_bob?rev=1&quot;)
-    do_delete
+    it &quot;should put the object into couchdb with a new GUID&quot; do
+      @mock_results = { &quot;rows&quot; =&gt; [] }
+      @couchdb.stub!(:get_view).with(&quot;id_map&quot;, &quot;name_to_id&quot;, :key =&gt; [ &quot;node&quot;, &quot;bob&quot; ]).and_return(@mock_results)
+      UUIDTools::UUID.stub!(:random_create).and_return(&quot;aaaaaaaa-xxxx-xxxx-xxxx-xxxxxxxxxxx&quot;)
+      @mock_rest.should_receive(:put_rest).with(&quot;chef/aaaaaaaa-xxxx-xxxx-xxxx-xxxxxxxxxxx&quot;, {}).and_return(true)
+      @couchdb.store(&quot;node&quot;, &quot;bob&quot;, {})
+    end
+
+    it &quot;should send the object to nanite for indexing&quot; do
+      Chef::Nanite.should_receive(:request)
+      @couchdb.store(&quot;node&quot;, &quot;bob&quot;, {})
+    end
   end
-end
 
-describe Chef::CouchDB, &quot;list&quot; do
-  before(:each) do
-    @mock_rest = mock(&quot;Chef::REST&quot;, :null_object =&gt; true, :url =&gt; &quot;http://monkeypants&quot;)
-    Chef::REST.stub!(:new).and_return(@mock_rest)
-    @couch = Chef::CouchDB.new(&quot;http://monkeypants&quot;)
-    Chef::Config.stub!(:[]).with(:couchdb_database).and_return(&quot;chef&quot;)
+  describe &quot;load&quot; do
+    before(:each) do 
+      @mock_node = Chef::Node.new()
+      @mock_node.name(&quot;bob&quot;)
+      @couchdb.stub!(:find_by_name).with(&quot;node&quot;, &quot;bob&quot;).and_return(@mock_node)
+    end
+
+    it &quot;should load the object from couchdb&quot; do
+      @couchdb.load(&quot;node&quot;, &quot;bob&quot;).should eql(@mock_node)
+    end
   end
-  
-  describe &quot;on couchdb 0.8&quot; do
-    before do
-      Chef::Config.stub!(:[]).with(:couchdb_version).and_return(0.8)
+
+  describe &quot;delete&quot; do
+    before(:each) do
+      @mock_current = {
+        &quot;version&quot; =&gt; 1,
+        &quot;_rev&quot; =&gt; 1
+      }
+      @mock_rest.stub!(:get_rest).and_return(@mock_current)
+      @mock_rest.stub!(:delete_rest).and_return(true)
+      @mock_node = Chef::Node.new()
+      @mock_node.name(&quot;bob&quot;)
+      @mock_node.couchdb_rev = 15
+      @couchdb.stub!(:find_by_name).with(&quot;node&quot;, &quot;bob&quot;, true).and_return([ @mock_node, &quot;ax&quot; ])
     end
     
-    it &quot;should get the view for all objects if inflate is true&quot; do
-      @mock_rest.should_receive(:get_rest).with(&quot;chef/_view/node/all&quot;).and_return(true)
-      @couch.list(&quot;node&quot;, true)
+    def do_delete(rev=nil)
+      @couchdb.delete(&quot;node&quot;, &quot;bob&quot;, rev)
     end
-
-    it &quot;should get the view for just the object id's if inflate is false&quot; do
-      @mock_rest.should_receive(:get_rest).with(&quot;chef/_view/node/all_id&quot;).and_return(true)
-      @couch.list(&quot;node&quot;, false)
+    
+    it &quot;should remove the object from couchdb with a specific revision&quot; do
+      @mock_rest.should_receive(:delete_rest).with(&quot;chef/ax?rev=1&quot;)
+      do_delete(1)  
+    end
+    
+    it &quot;should remove the object from couchdb based on the couchdb_rev of the current obj&quot; do
+      @mock_rest.should_receive(:delete_rest).with(&quot;chef/ax?rev=15&quot;)
+      do_delete
     end
   end
 
-  describe &quot;on couchdb 0.9&quot; do
-    before do
-      Chef::Config.stub!(:[]).with(:couchdb_version).and_return(0.9)
+  describe &quot;list&quot; do
+    before(:each) do
+      Chef::Config.stub!(:[]).with(:couchdb_database).and_return(&quot;chef&quot;)
+      @mock_response = mock(&quot;Chef::CouchDB::Response&quot;, :null_object =&gt; true)
     end
     
-    it &quot;should get the view for all objects if inflate is true&quot; do
-      @mock_rest.should_receive(:get_rest).with(&quot;chef/_design/node/_view/all&quot;).and_return(true)
-      @couch.list(&quot;node&quot;, true)
+    describe &quot;on couchdb 0.8&quot; do
+      before(:each) do
+        Chef::Config.stub!(:[]).with(:couchdb_version).and_return(0.8)
+      end
+      
+      it &quot;should get the view for all objects if inflate is true&quot; do
+        @mock_rest.should_receive(:get_rest).with(&quot;chef/_view/node/all&quot;).and_return(@mock_response)
+        @couchdb.list(&quot;node&quot;, true)
+      end
+
+      it &quot;should get the view for just the object id's if inflate is false&quot; do
+        @mock_rest.should_receive(:get_rest).with(&quot;chef/_view/node/all_id&quot;).and_return(@mock_response)
+        @couchdb.list(&quot;node&quot;, false)
+      end
     end
 
-    it &quot;should get the view for just the object id's if inflate is false&quot; do
-      @mock_rest.should_receive(:get_rest).with(&quot;chef/_design/node/_view/all_id&quot;).and_return(true)
-      @couch.list(&quot;node&quot;, false)
+    describe &quot;on couchdb 0.9&quot; do
+      before do
+        Chef::Config.stub!(:[]).with(:couchdb_version).and_return(0.9)
+      end
+      
+      it &quot;should get the view for all objects if inflate is true&quot; do
+        @mock_rest.should_receive(:get_rest).with(&quot;chef/_design/node/_view/all&quot;).and_return(@mock_response)
+        @couchdb.list(&quot;node&quot;, true)
+      end
+
+      it &quot;should get the view for just the object id's if inflate is false&quot; do
+        @mock_rest.should_receive(:get_rest).with(&quot;chef/_design/node/_view/all_id&quot;).and_return(@mock_response)
+        @couchdb.list(&quot;node&quot;, false)
+      end
     end
   end
-end
 
-describe Chef::CouchDB, &quot;has_key?&quot; do
-  before(:each) do
-    @mock_rest = mock(&quot;Chef::REST&quot;, :null_object =&gt; true)
-    Chef::REST.stub!(:new).and_return(@mock_rest)
-  end
-  
-  it &quot;should return true if the object exists&quot; do
-    @mock_rest.should_receive(:get_rest).and_return(true)
-    Chef::CouchDB.new.has_key?(&quot;node&quot;, &quot;bob&quot;).should eql(true)
-  end
-  
-  it &quot;should return false if the object does not exist&quot; do
-    @mock_rest.should_receive(:get_rest).and_raise(ArgumentError)
-    Chef::CouchDB.new.has_key?(&quot;node&quot;, &quot;bob&quot;).should eql(false)
+  describe &quot;has_key?&quot; do
+    it &quot;should return true if the object exists&quot; do
+      @couchdb.stub!(:find_by_name).with(&quot;node&quot;, &quot;bob&quot;).and_return(true)
+      @couchdb.has_key?(&quot;node&quot;, &quot;bob&quot;).should eql(true)
+    end
+    
+    it &quot;should return false if the object does not exist&quot; do
+      @couchdb.stub!(:find_by_name).and_raise(Chef::Exceptions::CouchDBNotFound)
+      @couchdb.has_key?(&quot;node&quot;, &quot;bob&quot;).should eql(false)
+    end
   end
+
 end
 
+
+
+
 describe Chef::CouchDB, &quot;get_view&quot; do
   before do
     @mock_rest = mock(&quot;Chef::REST&quot;, :null_object =&gt; true, :url =&gt; &quot;http://monkeypants&quot;)
@@ -287,6 +296,7 @@ describe Chef::CouchDB, &quot;view_uri&quot; do
       @mock_rest.should_receive(:run_request).with(
         :GET, 
         URI.parse(&quot;http://monkeypants/&quot;), 
+        {},
         false, 
         10, 
         false</diff>
      <filename>chef/spec/unit/couchdb_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -21,6 +21,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), &quot;..&quot;, &quot;spec_helper&quot;))
 describe Chef::Node do
   before(:each) do
     Chef::Config.node_path(File.join(File.dirname(__FILE__), &quot;..&quot;, &quot;data&quot;, &quot;nodes&quot;))
+    Nanite.stub!(:request).and_return(true)
     @node = Chef::Node.new()
   end
  
@@ -252,17 +253,6 @@ describe Chef::Node do
     end
   end
 
-  describe &quot;to_index&quot; do
-    before(:each) do
-      @node.foo(&quot;bar&quot;)
-    end
-    
-    it &quot;should return a hash with :index attributes&quot; do
-      @node.name(&quot;airplane&quot;)
-      @node.to_index.should == { &quot;foo&quot; =&gt; &quot;bar&quot;, &quot;index_name&quot; =&gt; &quot;node&quot;, &quot;id&quot; =&gt; &quot;node_airplane&quot;, &quot;name&quot; =&gt; &quot;airplane&quot; }
-    end
-  end
-
   describe &quot;to_s&quot; do
     it &quot;should turn into a string like node[name]&quot; do
       @node.name(&quot;airplane&quot;)
@@ -311,7 +301,6 @@ describe Chef::Node do
         node = Chef::Node.new
         node.name &quot;bob&quot;
         node.couchdb_rev = 1
-        Chef::Queue.should_receive(:send_msg).with(:queue, :remove, node)
         node.destroy
       end
     end
@@ -320,14 +309,12 @@ describe Chef::Node do
       before(:each) do
         @mock_couch.stub!(:store).and_return({ &quot;rev&quot; =&gt; 33 })
         Chef::CouchDB.stub!(:new).and_return(@mock_couch)
-        Chef::Queue.stub!(:send_msg).and_return(true)
         @node = Chef::Node.new
         @node.name &quot;bob&quot;
         @node.couchdb_rev = 1
       end
 
       it &quot;should save the node to couchdb&quot; do
-        Chef::Queue.should_receive(:send_msg).with(:queue, :index, @node)
         @mock_couch.should_receive(:store).with(&quot;node&quot;, &quot;bob&quot;, @node).and_return({ &quot;rev&quot; =&gt; 33 })
         @node.save
       end</diff>
      <filename>chef/spec/unit/node_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -177,6 +177,7 @@ end
 describe Chef::Provider::Group::Groupadd, &quot;load_current_resource&quot; do
   before do
     @node = mock(&quot;Chef::Node&quot;, :null_object =&gt; true)
+    Chef::Node.stub!(:new).and_return(@node)
     @new_resource = mock(&quot;Chef::Resource::Group&quot;, :null_object =&gt; true, :group_name =&gt; &quot;aj&quot;)
     @provider = Chef::Provider::Group::Groupadd.new(@node, @new_resource)
     File.stub!(:exists?).and_return(false)</diff>
      <filename>chef/spec/unit/provider/group/groupadd_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -47,8 +47,8 @@ describe Chef::Provider::HttpRequest, &quot;load_current_resource&quot; do
     @provider = Chef::Provider::HttpRequest.new(@node, @new_resource)
   end
   
-  it &quot;should set up a Chef::REST client&quot; do
-    Chef::REST.should_receive(:new).with(@new_resource.url)
+  it &quot;should set up a Chef::REST client, with no authentication&quot; do
+    Chef::REST.should_receive(:new).with(@new_resource.url, nil, nil)
     @provider.load_current_resource
   end
 end
@@ -205,4 +205,4 @@ describe Chef::Provider::HttpRequest, &quot;action_delete&quot; do
     @new_resource.should_receive(:updated=).with(true)
     @provider.action_delete
   end
-end
\ No newline at end of file
+end</diff>
      <filename>chef/spec/unit/provider/http_request_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -20,333 +20,365 @@ require File.expand_path(File.join(File.dirname(__FILE__), &quot;..&quot;, &quot;spec_helper&quot;))
 require 'uri'
 require 'net/https'
 
-describe Chef::REST, &quot;initialize method&quot; do
-  it &quot;should create a new Chef::REST&quot; do
-    Chef::REST.new(&quot;url&quot;).should be_kind_of(Chef::REST)
+describe Chef::REST do
+  before(:each) do
+    Chef::REST::CookieJar.stub!(:instance).and_return({})
+    @rest = Chef::REST.new(&quot;url&quot;, nil, nil)
   end
-end
 
-describe Chef::REST, &quot;get_rest method&quot; do
-  it &quot;should create a url from the path and base url&quot; do
-    URI.should_receive(:parse).with(&quot;url/monkey&quot;)
-    r = Chef::REST.new(&quot;url&quot;)
-    r.stub!(:run_request)
-    r.get_rest(&quot;monkey&quot;)
-  end
-  
-  it &quot;should call run_request :GET with the composed url object&quot; do
-    URI.stub!(:parse).and_return(true)
-    r = Chef::REST.new(&quot;url&quot;)
-    r.should_receive(:run_request).with(:GET, true, false, 10, false).and_return(true)
-    r.get_rest(&quot;monkey&quot;)
+  describe &quot;initialize&quot; do
+    it &quot;should create a new Chef::REST&quot; do
+      @rest.should be_kind_of(Chef::REST)
+    end
   end
-end
 
-describe Chef::REST, &quot;delete_rest method&quot; do
-  it &quot;should create a url from the path and base url&quot; do
-    URI.should_receive(:parse).with(&quot;url/monkey&quot;)
-    r = Chef::REST.new(&quot;url&quot;)
-    r.stub!(:run_request)
-    r.delete_rest(&quot;monkey&quot;)
-  end
-  
-  it &quot;should call run_request :DELETE with the composed url object&quot; do
-    URI.stub!(:parse).and_return(true)
-    r = Chef::REST.new(&quot;url&quot;)
-    r.should_receive(:run_request).with(:DELETE, true).and_return(true)
-    r.delete_rest(&quot;monkey&quot;)
-  end
-end
+  describe &quot;load_signing_key&quot; do
+    before(:each) do
+      @private_key = &lt;&lt;EOH
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAx8xAfO2BO8kUughpjWwHPN2rgDcES15PbMEGe6OdJgjFARkt
+FMdEusbGxmXKpk51Ggxi2P6ZYEoZfniZWt4qSt4i1vanDayRlJ1qoRCOaYj5cQS7
+gpHspHWqkY3HfGvx4svdutQ06o/gypx2QYfi68YrIUQexPiTUhsnP9FlgNt40Rl1
+YgBiIlJUk7d3q+1b/+POTNKPeyjGK9hoTloplbSx+cYdZgc4/YpU0eLBoHPuPv5l
+QD+Y8VNS39bvY2NWbCqhV508gExAK26FxXTDNpi2mTZmbRZ8U0PKrCgF6gBSeod5
+EdQnNgoZHmA2fzfPHWfJd2OEuMcNM7DWpPDizQIDAQABAoIBAAGVDYGvw9E8Y2yh
+umxDSb9ipgQK637JTWm4EZwTDKCLezvp/iBm/5VXE6XoknVEs8q0BGhhg8dubstA
+mz5L+hvDrJT1ORdzoWeC46BI6EfPrOIHPpDnJO+cevBSJh1HIZBBOw1KtuyQnSAd
+oxYbxGFHnXnS90dqDIie7G2l897UWoiQWNMLY+A+l5H4GLC+4Phq02pLd4OQwXA3
+Nd+3Nq69aOeccyfSDeeG7u35TKrjQPIxU210aR18d/0trR20BKsKbT30GPE1tQQd
+jm4uReSPttTQ+NjwBQKKYmO2F9b9MPzmQ7c+KycBRmf+IOgZeZ54JN0GzUXsDTjJ
++ZSgdgUCgYEA41aetBJwsKkF973gL54QCB5vFhRw3TdUgYhQgz04B5JGouGTSALy
+u1XtO6il65Zf6FwFSzXiggYYxTKyP/zwL88CQAVA7rleyhoZrw2bD6R2RZLivRba
+50rstltUbjevd96TagFY7i9gVHL9E6DKJH4unZfIM0Bl2IZQraqCR8MCgYEA4PzC
+FfUwiLa5drN6OVWZZfwxOeMbQUsYVeq7pHyeuvIe0euhcCLabBqfVt0pxqf1hem+
+l2+PnSKtvbI9siwt6WvJCtB3e/3aHOA3d6Y9TYxoyJAK007mRlQbbgqLzG83tZH2
+twO2tjo+h1+nv5yjE7aF9ItszegwTWsupvR+Ei8CgYAy0nt6MCEnLTIbV0RWANT+
+q6cT3Y/5tFPc/Vdab4YmEypdYWZmk9olzSjSzHoDN8PLEz9PuAUiIjDJbPLyYR5k
+4bdUDpicha5OKhWRz83Zal/SX+r2cLSRPmu6vKIcXbCJcKWt7g0uekLjvi0bhTeL
+fvX23yavZnceN7Czkkm7twKBgEFTgrNHdykrDRzXLhT5ssm2+UAani5ONKm1t3gi
+KyCS7rn7FevuYsdiz4M0Qk4JNLQGU6262dNBX3smBt32D/qnrj8ymo7o/WzG+bQH
+E+OxcjdSA6KpVRl0kGZaL49Td7SDxkQLkwDEVqWN87IiNAOkSq7f0N7UnTnNdkVJ
+1lVHAoGBANYgMoEj7gIJdch7hMdQcFfq9+4ntAAbsl3JFW+T9ChATn0XHAylP9ha
+ZaGlRrC7vxcF06vMe0HXyH1XVK3J9186zliTa4oDjkQ0D5X7Ga7KktLXAmQTysUH
+V3jwIQbAF6LqLUnGOq6rJzQxrWKvFt0mVDyuJzIJGSbnN/Sl5J6P
+-----END RSA PRIVATE KEY-----
+EOH
+      IO.stub!(:read).and_return(@private_key)
+    end
 
-describe Chef::REST, &quot;post_rest method&quot; do
-  it &quot;should create a url from the path and base url&quot; do
-    URI.should_receive(:parse).with(&quot;url/monkey&quot;)
-    r = Chef::REST.new(&quot;url&quot;)
-    r.stub!(:run_request)
-    r.post_rest(&quot;monkey&quot;, &quot;data&quot;)
-  end
-  
-  it &quot;should call run_request :POST with the composed url object and data&quot; do
-    URI.stub!(:parse).and_return(true)
-    r = Chef::REST.new(&quot;url&quot;)
-    r.should_receive(:run_request).with(:POST, true, &quot;data&quot;).and_return(true)
-    r.post_rest(&quot;monkey&quot;, &quot;data&quot;)
-  end
-end
+    it &quot;should return the contents of the key file&quot; do
+      File.stub!(:exists?).and_return(true)
+      File.stub!(:readable?).and_return(true)
+      @rest.load_signing_key(&quot;/tmp/keyfile.pem&quot;).should be(@private_key)
+    end
 
-describe Chef::REST, &quot;put_rest method&quot; do
-  it &quot;should create a url from the path and base url&quot; do
-    URI.should_receive(:parse).with(&quot;url/monkey&quot;)
-    r = Chef::REST.new(&quot;url&quot;)
-    r.stub!(:run_request)
-    r.put_rest(&quot;monkey&quot;, &quot;data&quot;)
-  end
-  
-  it &quot;should call run_request :PUT with the composed url object and data&quot; do
-    URI.stub!(:parse).and_return(true)
-    r = Chef::REST.new(&quot;url&quot;)
-    r.should_receive(:run_request).with(:PUT, true, &quot;data&quot;).and_return(true)
-    r.put_rest(&quot;monkey&quot;, &quot;data&quot;)
-  end
-end
+    it &quot;should raise a Chef::Exceptions::PrivateKeyMissing exception if the key cannot be found&quot; do
+      File.stub!(:exists?).and_return(false)
+      File.stub!(:readable?).and_return(true) #42!
+      lambda {
+        @rest.load_signing_key(&quot;/tmp/keyfile.pem&quot;)
+      }.should raise_error(Chef::Exceptions::PrivateKeyMissing)
+    end
 
-describe Chef::REST, &quot;run_request method&quot; do
-  before(:each) do
-    Chef::REST::CookieJar.stub!(:instance).and_return({})
-    @r = Chef::REST.new(&quot;url&quot;)
-    @url_mock = mock(&quot;URI&quot;, :null_object =&gt; true)
-    @url_mock.stub!(:host).and_return(&quot;one&quot;)
-    @url_mock.stub!(:port).and_return(&quot;80&quot;)
-    @url_mock.stub!(:path).and_return(&quot;/&quot;)
-    @url_mock.stub!(:query).and_return(&quot;foo=bar&quot;)
-    @url_mock.stub!(:scheme).and_return(&quot;https&quot;)
-    @url_mock.stub!(:user).and_return(nil)
-    @url_mock.stub!(:password).and_return(nil)
-    @url_mock.stub!(:to_s).and_return(&quot;https://one:80/?foo=bar&quot;)
-    @http_response_mock = mock(&quot;Net::HTTPSuccess&quot;, :null_object =&gt; true)
-    @http_response_mock.stub!(:kind_of?).with(Net::HTTPSuccess).and_return(true)
-    @http_response_mock.stub!(:body).and_return(&quot;ninja&quot;)
-    @http_response_mock.stub!(:error!).and_return(true)
-    @http_response_mock.stub!(:header).and_return({ 'Content-Length' =&gt; &quot;5&quot; })
-    @http_mock = mock(&quot;Net::HTTP&quot;, :null_object =&gt; true)
-    @http_mock.stub!(:verify_mode=).and_return(true)
-    @http_mock.stub!(:read_timeout=).and_return(true)
-    @http_mock.stub!(:use_ssl=).with(true).and_return(true)
-    @data_mock = mock(&quot;Data&quot;, :null_object =&gt; true)
-    @data_mock.stub!(:to_json).and_return('{ &quot;one&quot;: &quot;two&quot; }')
-    @request_mock = mock(&quot;Request&quot;, :null_object =&gt; true)
-    @request_mock.stub!(:body=).and_return(true)
-    @request_mock.stub!(:method).and_return(true)
-    @request_mock.stub!(:path).and_return(true)
-    @http_mock.stub!(:request).and_return(@http_response_mock)
-    @tf_mock = mock(Tempfile, { :print =&gt; true, :close =&gt; true, :write =&gt; true })
-    Tempfile.stub!(:new).with(&quot;chef-rest&quot;).and_return(@tf_mock)
-  end
-  
-  def do_run_request(method=:GET, data=false, limit=10, raw=false)
-    Net::HTTP.stub!(:new).and_return(@http_mock)
-    @r.run_request(method, @url_mock, data, limit, raw)
+    it &quot;should raise a Chef::Exceptions::PrivateKeyMissing exception if the key cannot be read&quot; do
+      File.stub!(:exists?).and_return(true)
+      File.stub!(:readable?).and_return(false)
+      lambda {
+        @rest.load_signing_key(&quot;/tmp/keyfile.pem&quot;)
+      }.should raise_error(Chef::Exceptions::PrivateKeyMissing)
+    end
   end
-  
-  it &quot;should raise an exception if the redirect limit is 0&quot; do
-    lambda { @r.run_request(:GET, &quot;/&quot;, false, 0)}.should raise_error(ArgumentError)
+
+  describe &quot;get_rest&quot; do
+    it &quot;should create a url from the path and base url&quot; do
+      URI.should_receive(:parse).with(&quot;url/monkey&quot;)
+      @rest.stub!(:run_request)
+      @rest.get_rest(&quot;monkey&quot;)
+    end
+    
+    it &quot;should call run_request :GET with the composed url object&quot; do
+      URI.stub!(:parse).and_return(true)
+      @rest.should_receive(:run_request).with(:GET, true, {}, false, 10, false).and_return(true)
+      @rest.get_rest(&quot;monkey&quot;)
+    end
   end
 
-  it &quot;should not fail if URI contains %d characters&quot; do
-    @http_response_mock.stub!(:read_body).and_yield(&quot;ninja&quot;)
-    @url_mock.stub!(:path).and_return(&quot;/myfile?Expires=1247484042&amp;Signature=hpK%2BbHchAmUCErdz1yCBPazzGRQ%3D&quot;)
-    @http_mock.stub!(:request).and_yield(@http_response_mock).and_return(@http_response_mock)
-    @http_response_mock.should_receive(:read_body).and_return(true)
-    do_run_request(:GET, false, 10, true)
+  describe &quot;delete_rest&quot; do
+    it &quot;should create a url from the path and base url&quot; do
+      URI.should_receive(:parse).with(&quot;url/monkey&quot;)
+      @rest.stub!(:run_request)
+      @rest.delete_rest(&quot;monkey&quot;)
+    end
+    
+    it &quot;should call run_request :DELETE with the composed url object&quot; do
+      URI.stub!(:parse).and_return(true)
+      @rest.should_receive(:run_request).with(:DELETE, true, {}).and_return(true)
+      @rest.delete_rest(&quot;monkey&quot;)
+    end
   end
-  
-  it &quot;should use SSL if the url starts with https&quot; do
-    @url_mock.should_receive(:scheme).and_return(&quot;https&quot;)
-    @http_mock.should_receive(:use_ssl=).with(true).and_return(true)
-    do_run_request
+
+  describe &quot;post_rest&quot; do
+    it &quot;should create a url from the path and base url&quot; do
+      URI.should_receive(:parse).with(&quot;url/monkey&quot;)
+      @rest.stub!(:run_request)
+      @rest.post_rest(&quot;monkey&quot;, &quot;data&quot;)
+    end
+    
+    it &quot;should call run_request :POST with the composed url object and data&quot; do
+      URI.stub!(:parse).and_return(true)
+      @rest.should_receive(:run_request).with(:POST, true, {}, &quot;data&quot;).and_return(true)
+      @rest.post_rest(&quot;monkey&quot;, &quot;data&quot;)
+    end
   end
-  
-  it &quot;should set the OpenSSL Verify Mode to verify_none if requested&quot; do
-    @http_mock.should_receive(:verify_mode=).and_return(true)
-    do_run_request
+
+  describe &quot;put_rest&quot; do
+    it &quot;should create a url from the path and base url&quot; do
+      URI.should_receive(:parse).with(&quot;url/monkey&quot;)
+      @rest.stub!(:run_request)
+      @rest.put_rest(&quot;monkey&quot;, &quot;data&quot;)
+    end
+    
+    it &quot;should call run_request :PUT with the composed url object and data&quot; do
+      URI.stub!(:parse).and_return(true)
+      @rest.should_receive(:run_request).with(:PUT, true, {}, &quot;data&quot;).and_return(true)
+      @rest.put_rest(&quot;monkey&quot;, &quot;data&quot;)
+    end
   end
-  
-  describe &quot;with a client SSL cert&quot; do
+
+  describe Chef::REST, &quot;run_request method&quot; do
     before(:each) do
-      Chef::Config[:ssl_client_cert] = &quot;/etc/chef/client-cert.pem&quot;
-      Chef::Config[:ssl_client_key] = &quot;/etc/chef/client-cert.key&quot;
-      File.stub!(:exists?).with(&quot;/etc/chef/client-cert.pem&quot;).and_return(true)
-      File.stub!(:exists?).with(&quot;/etc/chef/client-cert.key&quot;).and_return(true)
-      File.stub!(:read).with(&quot;/etc/chef/client-cert.pem&quot;).and_return(&quot;monkey magic client&quot;)
-      File.stub!(:read).with(&quot;/etc/chef/client-cert.key&quot;).and_return(&quot;monkey magic key&quot;)
-      OpenSSL::X509::Certificate.stub!(:new).and_return(&quot;monkey magic client data&quot;)
-      OpenSSL::PKey::RSA.stub!(:new).and_return(&quot;monkey magic key data&quot;)
+      @url_mock = mock(&quot;URI&quot;, :null_object =&gt; true)
+      @url_mock.stub!(:host).and_return(&quot;one&quot;)
+      @url_mock.stub!(:port).and_return(&quot;80&quot;)
+      @url_mock.stub!(:path).and_return(&quot;/&quot;)
+      @url_mock.stub!(:query).and_return(&quot;foo=bar&quot;)
+      @url_mock.stub!(:scheme).and_return(&quot;https&quot;)
+      @url_mock.stub!(:to_s).and_return(&quot;https://one:80/?foo=bar&quot;)
+      @http_response_mock = mock(&quot;Net::HTTPSuccess&quot;, :null_object =&gt; true)
+      @http_response_mock.stub!(:kind_of?).with(Net::HTTPSuccess).and_return(true)
+      @http_response_mock.stub!(:body).and_return(&quot;ninja&quot;)
+      @http_response_mock.stub!(:error!).and_return(true)
+      @http_response_mock.stub!(:header).and_return({ 'Content-Length' =&gt; &quot;5&quot; })
+      @http_mock = mock(&quot;Net::HTTP&quot;, :null_object =&gt; true)
+      @http_mock.stub!(:verify_mode=).and_return(true)
+      @http_mock.stub!(:read_timeout=).and_return(true)
+      @http_mock.stub!(:use_ssl=).with(true).and_return(true)
+      @data_mock = mock(&quot;Data&quot;, :null_object =&gt; true)
+      @data_mock.stub!(:to_json).and_return('{ &quot;one&quot;: &quot;two&quot; }')
+      @request_mock = mock(&quot;Request&quot;, :null_object =&gt; true)
+      @request_mock.stub!(:body=).and_return(true)
+      @request_mock.stub!(:method).and_return(true)
+      @request_mock.stub!(:path).and_return(true)
+      @http_mock.stub!(:request).and_return(@http_response_mock)
+      @tf_mock = mock(Tempfile, { :print =&gt; true, :close =&gt; true, :write =&gt; true })
+      Tempfile.stub!(:new).with(&quot;chef-rest&quot;).and_return(@tf_mock)
     end
-
-    it &quot;should check that the client cert file exists&quot; do
-      File.should_receive(:exists?).with(&quot;/etc/chef/client-cert.pem&quot;).and_return(true)
+    
+    def do_run_request(method=:GET, data=false, limit=10, raw=false)
+      Net::HTTP.stub!(:new).and_return(@http_mock)
+      @rest.run_request(method, @url_mock, {}, data, limit, raw)
+    end
+    
+    it &quot;should raise an exception if the redirect limit is 0&quot; do
+      lambda { @rest.run_request(:GET, &quot;/&quot;, {}, false, 0)}.should raise_error(ArgumentError)
+    end
+    
+    it &quot;should use SSL if the url starts with https&quot; do
+      @url_mock.should_receive(:scheme).and_return(&quot;https&quot;)
+      @http_mock.should_receive(:use_ssl=).with(true).and_return(true)
       do_run_request
     end
-
-    it &quot;should read the cert file&quot; do
-      File.should_receive(:read).with(&quot;/etc/chef/client-cert.pem&quot;).and_return(&quot;monkey magic client&quot;)
+    
+    it &quot;should set the OpenSSL Verify Mode to verify_none if requested&quot; do
+      @http_mock.should_receive(:verify_mode=).and_return(true)
       do_run_request
     end
+    
+    describe &quot;with a client SSL cert&quot; do
+      before(:each) do
+        Chef::Config[:ssl_client_cert] = &quot;/etc/chef/client-cert.pem&quot;
+        Chef::Config[:ssl_client_key] = &quot;/etc/chef/client-cert.key&quot;
+        File.stub!(:exists?).with(&quot;/etc/chef/client-cert.pem&quot;).and_return(true)
+        File.stub!(:exists?).with(&quot;/etc/chef/client-cert.key&quot;).and_return(true)
+        File.stub!(:read).with(&quot;/etc/chef/client-cert.pem&quot;).and_return(&quot;monkey magic client&quot;)
+        File.stub!(:read).with(&quot;/etc/chef/client-cert.key&quot;).and_return(&quot;monkey magic key&quot;)
+        OpenSSL::X509::Certificate.stub!(:new).and_return(&quot;monkey magic client data&quot;)
+        OpenSSL::PKey::RSA.stub!(:new).and_return(&quot;monkey magic key data&quot;)
+      end
+
+      it &quot;should check that the client cert file exists&quot; do
+        File.should_receive(:exists?).with(&quot;/etc/chef/client-cert.pem&quot;).and_return(true)
+        do_run_request
+      end
+
+      it &quot;should read the cert file&quot; do
+        File.should_receive(:read).with(&quot;/etc/chef/client-cert.pem&quot;).and_return(&quot;monkey magic client&quot;)
+        do_run_request
+      end
+
+      it &quot;should read the cert into OpenSSL&quot; do
+        OpenSSL::X509::Certificate.should_receive(:new).and_return(&quot;monkey magic client data&quot;)
+        do_run_request
+      end
+
+      it &quot;should set the cert&quot; do
+        @http_mock.should_receive(:cert=).and_return(true)
+        do_run_request
+      end
+
+      it &quot;should read the key file&quot; do
+        File.should_receive(:read).with(&quot;/etc/chef/client-cert.key&quot;).and_return(&quot;monkey magic key&quot;)
+        do_run_request
+      end
+
+      it &quot;should read the key into OpenSSL&quot; do
+        OpenSSL::PKey::RSA.should_receive(:new).and_return(&quot;monkey magic key data&quot;)
+        do_run_request
+      end
+
+      it &quot;should set the key&quot; do
+        @http_mock.should_receive(:key=).and_return(true)
+        do_run_request
+      end
 
-    it &quot;should read the cert into OpenSSL&quot; do
-      OpenSSL::X509::Certificate.should_receive(:new).and_return(&quot;monkey magic client data&quot;)
-      do_run_request
     end
 
-    it &quot;should set the cert&quot; do
-      @http_mock.should_receive(:cert=).and_return(true)
+    it &quot;should set a read timeout based on the rest_timeout config option&quot; do
+      Chef::Config[:rest_timeout] = 10
+      @http_mock.should_receive(:read_timeout=).with(10).and_return(true)
       do_run_request
     end
-
-    it &quot;should read the key file&quot; do
-      File.should_receive(:read).with(&quot;/etc/chef/client-cert.key&quot;).and_return(&quot;monkey magic key&quot;)
+    
+    it &quot;should set the cookie for this request if one exists for the given host:port&quot; do
+      @rest.cookies = { &quot;#{@url_mock.host}:#{@url_mock.port}&quot; =&gt; &quot;cookie monster&quot; }
+      Net::HTTP::Get.should_receive(:new).with(&quot;/?foo=bar&quot;, 
+        { 'Accept' =&gt; 'application/json', 'Cookie' =&gt; 'cookie monster' }
+      ).and_return(@request_mock)
       do_run_request
+      @rest.cookies = Hash.new
     end
-
-    it &quot;should read the key into OpenSSL&quot; do
-      OpenSSL::PKey::RSA.should_receive(:new).and_return(&quot;monkey magic key data&quot;)
+    
+    it &quot;should build a new HTTP GET request&quot; do
+      Net::HTTP::Get.should_receive(:new).with(&quot;/?foo=bar&quot;, 
+        { 'Accept' =&gt; 'application/json' }
+      ).and_return(@request_mock)
       do_run_request
     end
-
-    it &quot;should set the key&quot; do
-      @http_mock.should_receive(:key=).and_return(true)
+    
+    it &quot;should build a new HTTP POST request&quot; do
+      Net::HTTP::Post.should_receive(:new).with(&quot;/?foo=bar&quot;, 
+        { 'Accept' =&gt; 'application/json', &quot;Content-Type&quot; =&gt; 'application/json' }
+      ).and_return(@request_mock)
+      do_run_request(:POST, @data_mock)
+    end
+    
+    it &quot;should build a new HTTP PUT request&quot; do
+      Net::HTTP::Put.should_receive(:new).with(&quot;/?foo=bar&quot;, 
+        { 'Accept' =&gt; 'application/json', &quot;Content-Type&quot; =&gt; 'application/json' }
+      ).and_return(@request_mock)
+      do_run_request(:PUT, @data_mock)
+    end
+    
+    it &quot;should build a new HTTP DELETE request&quot; do
+      Net::HTTP::Delete.should_receive(:new).with(&quot;/?foo=bar&quot;, 
+        { 'Accept' =&gt; 'application/json' }
+      ).and_return(@request_mock)
+      do_run_request(:DELETE)
+    end
+    
+    it &quot;should raise an error if the method is not GET/PUT/POST/DELETE&quot; do
+      lambda { do_run_request(:MONKEY) }.should raise_error(ArgumentError)
+    end
+    
+    it &quot;should run an http request&quot; do
+      @http_mock.should_receive(:request).and_return(@http_response_mock)
       do_run_request
     end
-
-  end
-
-  it &quot;should set a read timeout based on the rest_timeout config option&quot; do
-    Chef::Config[:rest_timeout] = 10
-    @http_mock.should_receive(:read_timeout=).with(10).and_return(true)
-    do_run_request
-  end
-  
-  it &quot;should set the cookie for this request if one exists for the given host:port&quot; do
-    @r.cookies = { &quot;#{@url_mock.host}:#{@url_mock.port}&quot; =&gt; &quot;cookie monster&quot; }
-    Net::HTTP::Get.should_receive(:new).with(&quot;/?foo=bar&quot;, 
-      { 'Accept' =&gt; 'application/json', 'Cookie' =&gt; 'cookie monster' }
-    ).and_return(@request_mock)
-    do_run_request
-  end
-  
-  it &quot;should build a new HTTP GET request&quot; do
-    Net::HTTP::Get.should_receive(:new).with(&quot;/?foo=bar&quot;, 
-      { 'Accept' =&gt; 'application/json' }
-    ).and_return(@request_mock)
-    do_run_request
-  end
-  
-  it &quot;should build a new HTTP POST request&quot; do
-    Net::HTTP::Post.should_receive(:new).with(&quot;/&quot;, 
-      { 'Accept' =&gt; 'application/json', &quot;Content-Type&quot; =&gt; 'application/json' }
-    ).and_return(@request_mock)
-    do_run_request(:POST, @data_mock)
-  end
-  
-  it &quot;should build a new HTTP PUT request&quot; do
-    Net::HTTP::Put.should_receive(:new).with(&quot;/&quot;, 
-      { 'Accept' =&gt; 'application/json', &quot;Content-Type&quot; =&gt; 'application/json' }
-    ).and_return(@request_mock)
-    do_run_request(:PUT, @data_mock)
-  end
-  
-  it &quot;should build a new HTTP DELETE request&quot; do
-    Net::HTTP::Delete.should_receive(:new).with(&quot;/?foo=bar&quot;, 
-      { 'Accept' =&gt; 'application/json' }
-    ).and_return(@request_mock)
-    do_run_request(:DELETE)
-  end
-  
-  describe &quot;with HTTP Basic Authentication info in the URL&quot; do
-    before(:each) do
-      @url_mock.stub!(:user).and_return('frodo')
-      @url_mock.stub!(:password).and_return('odorf')
+    
+    it &quot;should return the body of the response on success&quot; do
+      do_run_request.should eql(&quot;ninja&quot;)
     end
-
-    %w(Get Post Put Delete).each do |verb|
-      it &quot;should authenticate HTTP #{verb.upcase} requests&quot; do
-        Net::HTTP::const_get(verb).stub!(:new).and_return(@request_mock)
-        @request_mock.should_receive(:basic_auth).with('frodo', 'odorf')
-        do_run_request(verb.upcase.to_sym)
-      end
+    
+    it &quot;should inflate the body as to an object if JSON is returned&quot; do
+      @http_response_mock.stub!(:[]).with('content-type').and_return(&quot;application/json&quot;)
+      JSON.should_receive(:parse).with(&quot;ninja&quot;).and_return(true)
+      do_run_request
+    end
+    
+    it &quot;should call run_request again on a Redirect response&quot; do
+      @http_response_mock.stub!(:kind_of?).with(Net::HTTPSuccess).and_return(false)
+      @http_response_mock.stub!(:kind_of?).with(Net::HTTPFound).and_return(true)
+      @http_response_mock.stub!(:[]).with('location').and_return(@url_mock.path)
+      lambda { do_run_request(method=:GET, data=false, limit=1) }.should raise_error(ArgumentError)
     end
-  end
 
-  it &quot;should raise an error if the method is not GET/PUT/POST/DELETE&quot; do
-    lambda { do_run_request(:MONKEY) }.should raise_error(ArgumentError)
-  end
-  
-  it &quot;should run an http request&quot; do
-    @http_mock.should_receive(:request).and_return(@http_response_mock)
-    do_run_request
-  end
-  
-  it &quot;should return the body of the response on success&quot; do
-    do_run_request.should eql(&quot;ninja&quot;)
-  end
-  
-  it &quot;should inflate the body as to an object if JSON is returned&quot; do
-    @http_response_mock.stub!(:[]).with('content-type').and_return(&quot;application/json&quot;)
-    JSON.should_receive(:parse).with(&quot;ninja&quot;).and_return(true)
-    do_run_request
-  end
-  
-  it &quot;should call run_request again on a Redirect response&quot; do
-    @http_response_mock.stub!(:kind_of?).with(Net::HTTPSuccess).and_return(false)
-    @http_response_mock.stub!(:kind_of?).with(Net::HTTPFound).and_return(true)
-    @http_response_mock.stub!(:[]).with('location').and_return(@url_mock.path)
-    lambda { do_run_request(method=:GET, data=false, limit=1) }.should raise_error(ArgumentError)
-  end
+    it &quot;should call run_request again on a Permanent Redirect response&quot; do
+      @http_response_mock.stub!(:kind_of?).with(Net::HTTPSuccess).and_return(false)
+      @http_response_mock.stub!(:kind_of?).with(Net::HTTPFound).and_return(false)
+      @http_response_mock.stub!(:kind_of?).with(Net::HTTPMovedPermanently).and_return(true)
+      @http_response_mock.stub!(:[]).with('location').and_return(@url_mock.path)
+      lambda { do_run_request(method=:GET, data=false, limit=1) }.should raise_error(ArgumentError)
+    end
+    
+    it &quot;should raise an exception on an unsuccessful request&quot; do
+      @http_response_mock.stub!(:kind_of?).with(Net::HTTPSuccess).and_return(false)
+      @http_response_mock.stub!(:kind_of?).with(Net::HTTPFound).and_return(false)
+      @http_response_mock.stub!(:kind_of?).with(Net::HTTPMovedPermanently).and_return(false)
+      @http_response_mock.should_receive(:error!)
+      do_run_request
+    end
+    
+    it &quot;should build a new HTTP GET request without the application/json accept header for raw reqs&quot; do
+      Net::HTTP::Get.should_receive(:new).with(&quot;/?foo=bar&quot;, {}).and_return(@request_mock)
+      do_run_request(:GET, false, 10, true)
+    end
+    
+    it &quot;should create a tempfile for the output of a raw request&quot; do
+      @http_mock.stub!(:request).and_yield(@http_response_mock).and_return(@http_response_mock)
+      Tempfile.should_receive(:new).with(&quot;chef-rest&quot;).and_return(@tf_mock)
+      do_run_request(:GET, false, 10, true).should eql(@tf_mock)    
+    end
+    
+    it &quot;should read the body of the response in chunks on a raw request&quot; do
+      @http_mock.stub!(:request).and_yield(@http_response_mock).and_return(@http_response_mock)
+      @http_response_mock.should_receive(:read_body).and_return(true)
+      do_run_request(:GET, false, 10, true)
+    end
+    
+    it &quot;should populate the tempfile with the value of the raw request&quot; do
+      @http_mock.stub!(:request).and_yield(@http_response_mock).and_return(@http_response_mock)
+      @http_response_mock.stub!(:read_body).and_yield(&quot;ninja&quot;)
+      @tf_mock.should_receive(:write, &quot;ninja&quot;).once.and_return(true)
+      do_run_request(:GET, false, 10, true)
+    end
+    
+    it &quot;should close the tempfile if we're doing a raw request&quot; do
+      @http_mock.stub!(:request).and_yield(@http_response_mock).and_return(@http_response_mock)
+      @tf_mock.should_receive(:close).once.and_return(true)
+      do_run_request(:GET, false, 10, true)
+    end
+    
+    it &quot;should not raise a divide by zero exception if the size is 0&quot; do
+      @http_mock.stub!(:request).and_yield(@http_response_mock).and_return(@http_response_mock)
+      @http_response_mock.stub!(:header).and_return({ 'Content-Length' =&gt; &quot;5&quot; })
+      @http_response_mock.stub!(:read_body).and_yield('')
+      lambda { do_run_request(:GET, false, 10, true) }.should_not raise_error(ZeroDivisionError)
+    end
+    
+    it &quot;should not raise a divide by zero exception if the Content-Length is 0&quot; do
+      @http_mock.stub!(:request).and_yield(@http_response_mock).and_return(@http_response_mock)
+      @http_response_mock.stub!(:header).and_return({ 'Content-Length' =&gt; &quot;0&quot; })
+      @http_response_mock.stub!(:read_body).and_yield(&quot;ninja&quot;)
+      lambda { do_run_request(:GET, false, 10, true) }.should_not raise_error(ZeroDivisionError)
+    end
+    
+    it &quot;should call read_body without a block if the request is not raw&quot; do
+      @http_mock.stub!(:request).and_yield(@http_response_mock).and_return(@http_response_mock)
+      @http_response_mock.should_receive(:read_body)
+      do_run_request(:GET, false, 10, false)
+    end
 
-  it &quot;should call run_request again on a Permanent Redirect response&quot; do
-    @http_response_mock.stub!(:kind_of?).with(Net::HTTPSuccess).and_return(false)
-    @http_response_mock.stub!(:kind_of?).with(Net::HTTPFound).and_return(false)
-    @http_response_mock.stub!(:kind_of?).with(Net::HTTPMovedPermanently).and_return(true)
-    @http_response_mock.stub!(:[]).with('location').and_return(@url_mock.path)
-    lambda { do_run_request(method=:GET, data=false, limit=1) }.should raise_error(ArgumentError)
-  end
-  
-  it &quot;should raise an exception on an unsuccessful request&quot; do
-    @http_response_mock.stub!(:kind_of?).with(Net::HTTPSuccess).and_return(false)
-    @http_response_mock.stub!(:kind_of?).with(Net::HTTPFound).and_return(false)
-    @http_response_mock.stub!(:kind_of?).with(Net::HTTPMovedPermanently).and_return(false)
-    @http_response_mock.should_receive(:error!)
-    do_run_request
-  end
-  
-  it &quot;should build a new HTTP GET request without the application/json accept header for raw reqs&quot; do
-    Net::HTTP::Get.should_receive(:new).with(&quot;/?foo=bar&quot;, {}).and_return(@request_mock)
-    do_run_request(:GET, false, 10, true)
-  end
-  
-  it &quot;should create a tempfile for the output of a raw request&quot; do
-    @http_mock.stub!(:request).and_yield(@http_response_mock).and_return(@http_response_mock)
-    Tempfile.should_receive(:new).with(&quot;chef-rest&quot;).and_return(@tf_mock)
-    do_run_request(:GET, false, 10, true).should eql(@tf_mock)    
-  end
-  
-  it &quot;should read the body of the response in chunks on a raw request&quot; do
-    @http_mock.stub!(:request).and_yield(@http_response_mock).and_return(@http_response_mock)
-    @http_response_mock.should_receive(:read_body).and_return(true)
-    do_run_request(:GET, false, 10, true)
-  end
-  
-  it &quot;should populate the tempfile with the value of the raw request&quot; do
-    @http_mock.stub!(:request).and_yield(@http_response_mock).and_return(@http_response_mock)
-    @http_response_mock.stub!(:read_body).and_yield(&quot;ninja&quot;)
-    @tf_mock.should_receive(:write, &quot;ninja&quot;).once.and_return(true)
-    do_run_request(:GET, false, 10, true)
-  end
-  
-  it &quot;should close the tempfile if we're doing a raw request&quot; do
-    @http_mock.stub!(:request).and_yield(@http_response_mock).and_return(@http_response_mock)
-    @tf_mock.should_receive(:close).once.and_return(true)
-    do_run_request(:GET, false, 10, true)
-  end
-  
-  it &quot;should not raise a divide by zero exception if the size is 0&quot; do
-    @http_mock.stub!(:request).and_yield(@http_response_mock).and_return(@http_response_mock)
-    @http_response_mock.stub!(:header).and_return({ 'Content-Length' =&gt; &quot;5&quot; })
-    @http_response_mock.stub!(:read_body).and_yield('')
-    lambda { do_run_request(:GET, false, 10, true) }.should_not raise_error(ZeroDivisionError)
-  end
-  
-  it &quot;should not raise a divide by zero exception if the Content-Length is 0&quot; do
-    @http_mock.stub!(:request).and_yield(@http_response_mock).and_return(@http_response_mock)
-    @http_response_mock.stub!(:header).and_return({ 'Content-Length' =&gt; &quot;0&quot; })
-    @http_response_mock.stub!(:read_body).and_yield(&quot;ninja&quot;)
-    lambda { do_run_request(:GET, false, 10, true) }.should_not raise_error(ZeroDivisionError)
-  end
-  
-  it &quot;should call read_body without a block if the request is not raw&quot; do
-    @http_mock.stub!(:request).and_yield(@http_response_mock).and_return(@http_response_mock)
-    @http_response_mock.should_receive(:read_body)
-    do_run_request(:GET, false, 10, false)
   end
 
 end
+</diff>
      <filename>chef/spec/unit/rest_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -175,7 +175,7 @@ describe Chef::RunList do
 
     describe &quot;from couchdb&quot; do
       it &quot;should load the role from couchdb&quot; do
-        Chef::Role.should_receive(:load).with(&quot;stubby&quot;)
+        Chef::Role.should_receive(:load)
         @run_list.expand(&quot;couchdb&quot;)
       end
     end</diff>
      <filename>chef/spec/unit/run_list_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -8,7 +8,7 @@ task :default =&gt; :spec
 
 desc &quot;Run all specs in spec directory&quot;
 Spec::Rake::SpecTask.new(:spec) do |t|
-  t.spec_opts = ['--options', &quot;\&quot;#{CHEF_ROOT}/spec/spec.opts\&quot;&quot;]
+  t.spec_opts = ['--format', 'specdoc', '--options', &quot;\&quot;#{CHEF_ROOT}/spec/spec.opts\&quot;&quot;]
   t.spec_files = FileList['spec/**/*_spec.rb']
 end
 </diff>
      <filename>chef/tasks/rspec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,22 +1,34 @@
 default: -f pretty features -r features/steps -r features/support 
-api: --tags api --format pretty -r features/steps -r features/support features 
-api_roles: --tags roles --format pretty -r features/steps -r features/support features
+api: --tags @api --format pretty -r features/steps -r features/support features 
+api_cookbooks: --tags @api,@cookbooks --format pretty -r features/steps -r features/support features 
+api_cookbooks_tarballs: --tags @api,@cookbooks,@tarballs --format pretty -r features/steps -r features/support features 
+api_roles: --tags @api_roles --format pretty -r features/steps -r features/support features
 api_roles_create: --tags roles_create --format pretty -r features/steps -r features/support features
 api_roles_delete: --tags roles_delete --format pretty -r features/steps -r features/support features
 api_roles_list: --tags roles_list --format pretty -r features/steps -r features/support features
 api_roles_show: --tags roles_show --format pretty -r features/steps -r features/support features
 api_roles_update: --tags roles_update --format pretty -r features/steps -r features/support features
-api_nodes: --tags nodes --format pretty -r features/steps -r features/support features
+api_nodes: --tags @api_nodes --format pretty -r features/steps -r features/support features
 api_nodes_create: --tags nodes_create --format pretty -r features/steps -r features/support features
 api_nodes_delete: --tags nodes_delete --format pretty -r features/steps -r features/support features
 api_nodes_list: --tags nodes_list --format pretty -r features/steps -r features/support features
 api_nodes_show: --tags nodes_show --format pretty -r features/steps -r features/support features
 api_nodes_update: --tags nodes_update --format pretty -r features/steps -r features/support features
-client: --tags client --format pretty -r features/steps -r features/support features 
+api_data: --tags @api_data --format pretty -r features/steps -r features/support features 
+api_data_delete: --tags @api_data_delete --format pretty -r features/steps -r features/support features 
+api_data_item: --tags @api_data_item --format pretty -r features/steps -r features/support features 
+api_search: --tags @api_search --format pretty -r features/steps -r features/support features 
+api_search_list: --tags @api_search_list --format pretty -r features/steps -r features/support features 
+api_search_show: --tags @api_search_show --format pretty -r features/steps -r features/support features 
+client: --tags @client --format pretty -r features/steps -r features/support features 
 client_roles: --tags client_roles --format pretty -r features/steps -r features/support features 
-search: --tags search --format pretty -r features/steps -r features/support features 
-language: --tags language --format pretty -r features/steps -r features/support features 
-recipe_inclusion: --tags recipe_inclusion --format pretty -r features/steps -r features/support features 
-provider_remote_file: --tags provider,remote_file --format pretty -r features/steps -r features/support features 
-provider_package_macports: --tags macports --format pretty -r features/steps -r features/support features 
+search: --tags @search --format pretty -r features/steps -r features/support features 
+provider: --tags @provider --format pretty -r features/steps -r features/support features 
+provider_directory: --tags @provider_directory --format pretty -r features/steps -r features/support features 
+provider_execute: --tags @provider_execute --format pretty -r features/steps -r features/support features 
+provider_file: --tags @provider_file --format pretty -r features/steps -r features/support features 
+provider_remote_file: --tags @remote_file --format pretty -r features/steps -r features/support features 
+provider_package_macports: --tags @macports --format pretty -r features/steps -r features/support features 
+language: --tags @language --format pretty -r features/steps -r features/support features 
+cookbooks: --tags @cookbooks --format pretty -r features/steps -r features/support features 
 </diff>
      <filename>cucumber.yml</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-@api @nodes @nodes_create
+@api @api_nodes @nodes_create
 Feature: Create a node via the REST API
   In order to create nodes programatically 
   As a Devleoper
@@ -7,19 +7,19 @@ Feature: Create a node via the REST API
   Scenario: Create a new node 
     Given a 'registration' named 'bobo' exists
       And a 'node' named 'webserver'
-     When I authenticate as 'bobo'
-      And I 'POST' the 'node' to the path '/nodes' 
+     When I 'POST' the 'node' to the path '/nodes' 
       And the inflated responses key 'uri' should match '^http://.+/nodes/webserver$'
 
   Scenario: Create a node that already exists
     Given a 'registration' named 'bobo' exists
       And an 'node' named 'webserver'
-     When I authenticate as 'bobo'
-      And I 'POST' the 'node' to the path '/nodes' 
+     When I 'POST' the 'node' to the path '/nodes' 
       And I 'POST' the 'node' to the path '/nodes' 
      Then I should get a '403 &quot;Forbidden&quot;' exception
-
-  Scenario: Create a new node without authenticating
-    Given a 'node' named 'webserver'
-     When I 'POST' the 'node' to the path '/nodes' 
+  
+  Scenario: Create a node with a wrong private key
+    Given a 'registration' named 'bobo' exists
+      And an 'node' named 'webserver'
+     When I 'POST' the 'node' to the path '/nodes' using a wrong private key
      Then I should get a '401 &quot;Unauthorized&quot;' exception
+     </diff>
      <filename>features/api/nodes/create_node_api.feature</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-@api @nodes @nodes_delete
+@api @api_nodes @nodes_delete
 Feature: Delete a node via the REST API 
   In order to remove a node 
   As a Developer 
@@ -7,19 +7,18 @@ Feature: Delete a node via the REST API
   Scenario: Delete a node 
     Given a 'registration' named 'bobo' exists
       And a 'node' named 'webserver' exists
-     When I authenticate as 'bobo'
-      And I 'DELETE' the path '/nodes/webserver'
+     When I 'DELETE' the path '/nodes/webserver'
      Then the inflated response should respond to 'name' with 'webserver' 
 
   Scenario: Delete a node that does not exist
     Given a 'registration' named 'bobo' exists
       And there are no nodes 
-     When I authenticate as 'bobo'
      When I 'DELETE' the path '/nodes/webserver'
      Then I should get a '404 &quot;Not Found&quot;' exception
 
-  Scenario: Delete a node without authenticating 
-    Given a 'node' named 'webserver'
-     When I 'DELETE' the path '/nodes/webserver'
+  Scenario: Delete a node with a wrong private key
+    Given a 'registration' named 'bobo' exists
+      And a 'node' named 'webserver' exists
+     When I 'DELETE' the path '/nodes/webserver' using a wrong private key
      Then I should get a '401 &quot;Unauthorized&quot;' exception
 </diff>
      <filename>features/api/nodes/delete_node_api.feature</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-@api @nodes @nodes_list
+@api @api_nodes @nodes_list
 Feature: List nodes via the REST API
   In order to know what nodes exists programatically
   As a Developer
@@ -7,28 +7,26 @@ Feature: List nodes via the REST API
   Scenario: List nodes when none have been created
     Given a 'registration' named 'bobo' exists
       And there are no nodes 
-     When I authenticate as 'bobo'
-      And I 'GET' the path '/nodes' 
+     When I 'GET' the path '/nodes' 
      Then the inflated response should be an empty array
 
   Scenario: List nodes when one has been created
     Given a 'registration' named 'bobo' exists
     Given a 'node' named 'webserver' exists
-     When I authenticate as 'bobo'
-      And I 'GET' the path '/nodes'
+     When I 'GET' the path '/nodes'
      Then the inflated response should include '^http://.+/nodes/webserver$'
-
+  
   Scenario: List nodes when two have been created
     Given a 'registration' named 'bobo' exists
       And a 'node' named 'webserver' exists
       And a 'node' named 'dbserver' exists
-     When I authenticate as 'bobo'
-      And I 'GET' the path '/nodes'
+     When I 'GET' the path '/nodes'
      Then the inflated response should be '2' items long
       And the inflated response should include '^http://.+/nodes/webserver$'
       And the inflated response should include '^http://.+/nodes/dbserver$'
 
-  Scenario: List nodes when you are not authenticated 
-     When I 'GET' the path '/nodes' 
+  Scenario: List nodes none have been created with a wrong private key
+    Given a 'registration' named 'bobo' exists
+      And there are no cookbooks
+     When I 'GET' the path '/nodes' using a wrong private key
      Then I should get a '401 &quot;Unauthorized&quot;' exception
-</diff>
      <filename>features/api/nodes/list_nodes_api.feature</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-@api @nodes @nodes_show
+@api @api_nodes @nodes_show
 Feature: Show a node via the REST API 
   In order to know what the details are for a node 
   As a Developer
@@ -7,19 +7,18 @@ Feature: Show a node via the REST API
   Scenario: Show a node
     Given a 'registration' named 'bobo' exists
       And a 'node' named 'webserver' exists
-     When I authenticate as 'bobo'
-      And I 'GET' the path '/nodes/webserver'
+     When I 'GET' the path '/nodes/webserver'
      Then the inflated response should respond to 'name' with 'webserver'
 
   Scenario: Show a missing node
     Given a 'registration' named 'bobo' exists
       And there are no nodes 
-     When I authenticate as 'bobo'
-      And I 'GET' the path '/nodes/bobo'
+     When I 'GET' the path '/nodes/bobo'
      Then I should get a '404 &quot;Not Found&quot;' exception
 
-  Scenario: Show a node without authenticating
-    Given a 'node' named 'webserver' exists
-      And I 'GET' the path '/nodes/webserver'
+  Scenario: Show a node with a wrong private key
+    Given a 'registration' named 'bobo' exists
+      And a 'node' named 'webserver' exists
+     When I 'GET' the path '/nodes/webserver' using a wrong private key
      Then I should get a '401 &quot;Unauthorized&quot;' exception
 </diff>
      <filename>features/api/nodes/show_node_api.feature</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-@api @nodes @nodes_update
+@api @api_nodes @nodes_update
 Feature: Update a node
   In order to keep my node data up-to-date
   As a Developer
@@ -8,7 +8,6 @@ Feature: Update a node
     Given a 'registration' named 'bobo' exists
       And a 'node' named 'webserver' exists
       And sending the method '&lt;method&gt;' to the 'node' with '&lt;updated_value&gt;'
-     When I authenticate as 'bobo'
      When I 'PUT' the 'node' to the path '/nodes/webserver' 
      Then the inflated response should respond to '&lt;method&gt;' with '&lt;updated_value&gt;' 
      When I 'GET' the path '/nodes/webserver'
@@ -19,9 +18,10 @@ Feature: Update a node
       | run_list     | [ &quot;recipe[one]&quot;, &quot;recipe[two]&quot; ] |
       | snakes       | really arent so bad | 
       
-  Scenario: Update a node without authenticating
-    Given a 'node' named 'webserver'
-      And sending the method 'snakes' to the 'node' with 'night train'
-     When I 'PUT' the 'node' to the path '/nodes/webserver' 
-     Then I should get a '401 &quot;Unauthorized&quot;' exception
 
+  Scenario Outline: Update a node with a wrong private key
+    Given a 'registration' named 'bobo' exists
+      And a 'node' named 'webserver' exists
+      And sending the method 'run_list' to the 'node' with '[ &quot;recipe[one]&quot;, &quot;recipe[two]&quot; ]'
+     When I 'PUT' the 'node' to the path '/nodes/webserver' using a wrong private key
+     Then I should get a '401 &quot;Unauthorized&quot;' exception</diff>
      <filename>features/api/nodes/update_node_api.feature</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-@api @roles @roles_create
+@api @api_roles @roles_create
 Feature: Create a role via the REST API
   In order to create roles programatically 
   As a Devleoper
@@ -7,20 +7,18 @@ Feature: Create a role via the REST API
   Scenario: Create a new role 
     Given a 'registration' named 'bobo' exists
       And a 'role' named 'webserver'
-     When I authenticate as 'bobo'
-      And I 'POST' the 'role' to the path '/roles' 
+     When I 'POST' the 'role' to the path '/roles' 
       And the inflated responses key 'uri' should match '^http://.+/roles/webserver$'
 
   Scenario: Create a role that already exists
     Given a 'registration' named 'bobo' exists
       And an 'role' named 'webserver'
-     When I authenticate as 'bobo'
-      And I 'POST' the 'role' to the path '/roles' 
+     When I 'POST' the 'role' to the path '/roles' 
       And I 'POST' the 'role' to the path '/roles' 
      Then I should get a '403 &quot;Forbidden&quot;' exception
 
-  Scenario: Create a new role without authenticating
-    Given a 'role' named 'webserver'
-     When I 'POST' the 'role' to the path '/roles' 
+  Scenario: Create a new role with a wrong private key
+    Given a 'registration' named 'bobo' exists
+      And a 'role' named 'webserver'
+     When I 'POST' the 'role' to the path '/roles' using a wrong private key
      Then I should get a '401 &quot;Unauthorized&quot;' exception
-</diff>
      <filename>features/api/roles/create_role_api.feature</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-@api @roles @roles_delete
+@api @api_roles @roles_delete
 Feature: Delete a Role via the REST API 
   In order to remove a role 
   As a Developer 
@@ -7,19 +7,18 @@ Feature: Delete a Role via the REST API
   Scenario: Delete a Role 
     Given a 'registration' named 'bobo' exists
       And a 'role' named 'webserver' exists
-     When I authenticate as 'bobo'
-      And I 'DELETE' the path '/roles/webserver'
+     When I 'DELETE' the path '/roles/webserver'
      Then the inflated response should respond to 'name' with 'webserver' 
 
   Scenario: Delete a Role that does not exist
     Given a 'registration' named 'bobo' exists
       And there are no roles 
-     When I authenticate as 'bobo'
      When I 'DELETE' the path '/roles/webserver'
      Then I should get a '404 &quot;Not Found&quot;' exception
-
-  Scenario: Delete a Role without authenticating 
-    Given a 'role' named 'webserver'
-     When I 'DELETE' the path '/roles/webserver'
+    
+  Scenario: Delete a Role with a wrong private key
+    Given a 'registration' named 'bobo' exists
+      And a 'role' named 'webserver' exists
+     When I 'DELETE' the path '/roles/webserver' using a wrong private key
      Then I should get a '401 &quot;Unauthorized&quot;' exception
 </diff>
      <filename>features/api/roles/delete_role_api.feature</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-@api @roles @roles_list
+@api @api_roles @roles_list
 Feature: List roles via the REST API
   In order to know what roles exists programatically
   As a Developer
@@ -6,30 +6,29 @@ Feature: List roles via the REST API
 
   Scenario: List roles when none have been created
     Given a 'registration' named 'bobo' exists
-      And there are no roles
-     When I authenticate as 'bobo'
-      And I 'GET' the path '/roles' 
-     Then the inflated response should be an empty array
+      And there are no roles 
+     When I 'GET' the path '/roles' 
+     Then the inflated response should be '1' items long 
 
   Scenario: List roles when one has been created
     Given a 'registration' named 'bobo' exists
     Given a 'role' named 'webserver' exists
-     When I authenticate as 'bobo'
-      And I 'GET' the path '/roles'
+     When I 'GET' the path '/roles'
      Then the inflated response should include '^http://.+/roles/webserver$'
 
   Scenario: List roles when two have been created
     Given a 'registration' named 'bobo' exists
       And a 'role' named 'webserver' exists
       And a 'role' named 'db' exists
-     When I authenticate as 'bobo'
-      And I 'GET' the path '/roles'
+     When I 'GET' the path '/roles'
      Then the inflated response should be '3' items long
       And the inflated response should include '^http://.+/roles/role_test$'
       And the inflated response should include '^http://.+/roles/webserver$'
       And the inflated response should include '^http://.+/roles/db$'
 
-  Scenario: List roles when you are not authenticated 
-     When I 'GET' the path '/roles' 
+  Scenario: List roles when none have been created with a wrong private key
+    Given a 'registration' named 'bobo' exists
+      And there are no roles 
+     When I 'GET' the path '/roles' using a wrong private key
      Then I should get a '401 &quot;Unauthorized&quot;' exception
 </diff>
      <filename>features/api/roles/list_roles_api.feature</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-@api @roles @roles_show
+@api @api_roles @roles_show
 Feature: Show a role via the REST API 
   In order to know what the details are for a Role 
   As a Developer
@@ -7,20 +7,18 @@ Feature: Show a role via the REST API
   Scenario: Show a role
     Given a 'registration' named 'bobo' exists
       And a 'role' named 'webserver' exists
-     When I authenticate as 'bobo'
-      And I 'GET' the path '/roles/webserver'
+     When I 'GET' the path '/roles/webserver'
      Then the inflated response should respond to 'name' with 'webserver'
 
   Scenario: Show a missing role
     Given a 'registration' named 'bobo' exists
       And there are no roles 
-     When I authenticate as 'bobo'
-      And I 'GET' the path '/roles/bobo'
+     When I 'GET' the path '/roles/bobo'
      Then I should get a '404 &quot;Not Found&quot;' exception
 
-  Scenario: Show a role without authenticating
-    Given a 'role' named 'webserver' exists
-      And I 'GET' the path '/roles/webserver'
+  Scenario: Show a role with a wrong private key
+    Given a 'registration' named 'bobo' exists
+      And a 'role' named 'webserver' exists
+     When I 'GET' the path '/roles/webserver' using a wrong private key
      Then I should get a '401 &quot;Unauthorized&quot;' exception
 
-</diff>
      <filename>features/api/roles/show_roles_api.feature</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-@api @roles @roles_update
+@api @api_roles @roles_update
 Feature: Update a role
   In order to keep my role data up-to-date
   As a Developer
@@ -8,7 +8,6 @@ Feature: Update a role
     Given a 'registration' named 'bobo' exists
       And a 'role' named 'webserver' exists
       And sending the method '&lt;method&gt;' to the 'role' with '&lt;updated_value&gt;'
-     When I authenticate as 'bobo'
      When I 'PUT' the 'role' to the path '/roles/webserver' 
      Then the inflated response should respond to '&lt;method&gt;' with '&lt;updated_value&gt;' 
      When I 'GET' the path '/roles/webserver'
@@ -21,9 +20,9 @@ Feature: Update a role
       | default_attributes | { &quot;a&quot;: &quot;d&quot; } |
       | override_attributes | { &quot;c&quot;: &quot;e&quot; } |
       
-  Scenario: Update a role without authenticating
-    Given a 'role' named 'webserver'
-      And sending the method 'description' to the 'role' with 'Is easy'
-     When I 'PUT' the 'role' to the path '/roles/webserver' 
+  Scenario Outline: Update a role with a wrong private key
+    Given a 'registration' named 'bobo' exists
+      And a 'role' named 'webserver' exists
+      And sending the method '&lt;method&gt;' to the 'role' with '&lt;updated_value&gt;'
+     When I 'PUT' the 'role' to the path '/roles/webserver' using a wrong private key
      Then I should get a '401 &quot;Unauthorized&quot;' exception
-</diff>
      <filename>features/api/roles/update_roles_api.feature</filename>
    </modified>
    <modified>
      <diff>@@ -6,9 +6,15 @@ log_location     STDOUT
 file_cache_path  File.join(tmpdir, &quot;cache&quot;)
 ssl_verify_mode  :verify_none
 registration_url &quot;http://127.0.0.1:4000&quot;
-openid_url       &quot;http://127.0.0.1:4001&quot;
+openid_url       &quot;http://127.0.0.1:4000&quot;
 template_url     &quot;http://127.0.0.1:4000&quot;
 remotefile_url   &quot;http://127.0.0.1:4000&quot;
 search_url       &quot;http://127.0.0.1:4000&quot;
-role_url          &quot;http://127.0.0.1:4000&quot;
-couchdb_database   'chef_integration'
+role_url         &quot;http://127.0.0.1:4000&quot;
+client_url       &quot;http://127.0.0.1:4000&quot;
+chef_server_url  &quot;http://127.0.0.1:4000&quot;
+validation_client_name &quot;validator&quot;
+systmpdir = File.expand_path(File.join(Dir.tmpdir, &quot;chef_integration&quot;))
+validation_key   File.join(systmpdir, &quot;validation.pem&quot;)
+client_key       File.join(systmpdir, &quot;client.pem&quot;)
+</diff>
      <filename>features/data/config/client.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,17 +6,30 @@ log_location       STDOUT
 file_cache_path    File.join(tmpdir, &quot;cache&quot;)
 ssl_verify_mode    :verify_none
 registration_url   &quot;http://127.0.0.1:4000&quot;
-openid_url         &quot;http://127.0.0.1:4001&quot;
+openid_url         &quot;http://127.0.0.1:4000&quot;
 template_url       &quot;http://127.0.0.1:4000&quot;
 remotefile_url     &quot;http://127.0.0.1:4000&quot;
 search_url         &quot;http://127.0.0.1:4000&quot;
-role_url          &quot;http://127.0.0.1:4000&quot;
+role_url           &quot;http://127.0.0.1:4000&quot;
+chef_server_url    &quot;http://127.0.0.1:4000&quot;
+client_url         &quot;http://127.0.0.1:4000&quot;
 cookbook_path      File.join(supportdir, &quot;cookbooks&quot;)
 openid_store_path  File.join(tmpdir, &quot;openid&quot;, &quot;store&quot;)
 openid_cstore_path File.join(tmpdir, &quot;openid&quot;, &quot;cstore&quot;)
 search_index_path  File.join(tmpdir, &quot;search_index&quot;)
 role_path          File.join(supportdir, &quot;roles&quot;)
-validation_token   'ceelo'
 couchdb_database   'chef_integration'
 
+systmpdir = File.expand_path(File.join(Dir.tmpdir, &quot;chef_integration&quot;))
+
+validation_client_name &quot;validator&quot;
+validation_key   File.join(systmpdir, &quot;validation.pem&quot;)
+client_key       File.join(systmpdir, &quot;client.pem&quot;)
+
+solr_jetty_path File.join(supportdir, &quot;solr&quot;, &quot;jetty&quot;)
+solr_heap_size &quot;250M&quot;
+solr_data_path File.join(supportdir, &quot;solr&quot;, &quot;data&quot;)
+solr_home_path File.join(supportdir, &quot;solr&quot;, &quot;home&quot;)
+solr_heap_size &quot;256M&quot;
+
 Chef::Log::Formatter.show_time = true</diff>
      <filename>features/data/config/server.rb</filename>
    </modified>
    <modified>
      <diff>@@ -19,7 +19,7 @@
 
 directory node[:int][:tmpdir] do
   owner &quot;root&quot;
-  mode 1777
+  mode &quot;1777&quot;
   action :create
 end
 </diff>
      <filename>features/data/cookbooks/integration_setup/recipes/default.rb</filename>
    </modified>
    <modified>
      <diff>@@ -17,11 +17,12 @@
 # limitations under the License.
 #
 
-node.save
-sleep 5
-search(:node, &quot;*&quot;) do |entry|
-  Chef::Log.error(entry.inspect)
-  entry[&quot;search_files&quot;].each do |filename|
-    file &quot;#{node[:tmpdir]}/#{filename}&quot; 
-  end
+# We have to sleep at least 10 seconds to confirm that the data has made it 
+# into the index.  We can only rely on this because we are in a test environment
+# in real-land Chef, the index is only eventually consistent.. and may take a
+# variable amount of time.
+sleep 10
+search(:users, &quot;*:*&quot;) do |entry|
+  file &quot;#{node[:tmpdir]}/#{entry[&quot;id&quot;]}&quot;
 end
+</diff>
      <filename>features/data/cookbooks/search/recipes/search_data.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,3 +1,4 @@
+@language
 Feature: Delayed Notifications
   In order to not impact the system we are configuring unduly
   As a developer</diff>
      <filename>features/language/delayed_notifications.feature</filename>
    </modified>
    <modified>
      <diff>@@ -1,3 +1,4 @@
+@provider @provider_directory
 Feature: Create Directories 
   In order to save time
   As a Developer</diff>
      <filename>features/provider/directory/create_directories.feature</filename>
    </modified>
    <modified>
      <diff>@@ -1,3 +1,4 @@
+@provider @provider_directory
 Feature: Delete Directories 
   In order to save time 
   As a Developer</diff>
      <filename>features/provider/directory/delete_directories.feature</filename>
    </modified>
    <modified>
      <diff>@@ -1,3 +1,4 @@
+@provider @provider_execute
 Feature: Run Commands 
   In order to utilize the plethora of useful command line utilities 
   As a Developer</diff>
      <filename>features/provider/execute/run_commands.feature</filename>
    </modified>
    <modified>
      <diff>@@ -1,3 +1,4 @@
+@provider @provider_file
 Feature: Manage Files
   In order to save time
   As a Developer</diff>
      <filename>features/provider/file/manage_files.feature</filename>
    </modified>
    <modified>
      <diff>@@ -4,11 +4,25 @@ Feature: Search Data
   As a Developer
   I want to search the data 
 
-  Scenario: Search the node index
+  Scenario: Search the user index
     Given a validated node
       And it includes the recipe 'search::search_data'
+      And a 'data_bag' named 'users' exists
+      And a 'data_bag_item' named 'francis' exists
+      And a 'data_bag_item' named 'axl_rose' exists
      When I run the chef-client
      Then the run should exit '0'
-      And a file named 'search_one.txt' should exist
-      And a file named 'search_two.txt' should exist
+      And a file named 'francis' should exist
+      And a file named 'axl_rose' should exist
+
+  Scenario: Search the user index without a block
+    Given a validated node
+      And it includes the recipe 'search::search_data_noblock'
+      And a 'data_bag' named 'users' exists
+      And a 'data_bag_item' named 'francis' exists
+      And a 'data_bag_item' named 'axl_rose' exists
+     When I run the chef-client
+     Then the run should exit '0'
+      And a file named 'francis' should exist
+      And a file named 'axl_rose' should exist
 </diff>
      <filename>features/search/search_data.feature</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,6 @@
 #
 # Author:: Adam Jacob (&lt;adam@opscode.com&gt;)
+# Author:: Chris Walters (&lt;cw@opscode.com&gt;)
 # Copyright:: Copyright (c) 2008 Opscode, Inc.
 # License:: Apache License, Version 2.0
 #
@@ -51,3 +52,4 @@ When /^I run the rake task to generate cookbook metadata$/ do
     end
   end
 end
+</diff>
      <filename>features/steps/cookbook_steps.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,19 +1,53 @@
 
+require 'ostruct'
+
 Before do
   @fixtures = {
+    'signing_caller' =&gt;{ 
+      :user_id=&gt;'bobo', :secret_key =&gt; &quot;/tmp/poop.pem&quot;
+    },
     'registration' =&gt; { 
       'bobo' =&gt; Proc.new do
-        r = Chef::OpenIDRegistration.new
-        r.name = &quot;bobo&quot;
-        r.set_password('tclown')
-        r.validated = true
-        r.admin = true
-        r
+
+        OpenStruct.new({ :save =&gt; true })
+     #Chef::CouchDB.new(Chef::Config[:couchdb_url], &quot;chef_integration&quot;))
+      end
+    },
+    'data_bag' =&gt; {
+      'users' =&gt; Proc.new do
+        b = Chef::DataBag.new(Chef::CouchDB.new(nil, &quot;chef_integration&quot;))
+        b.name &quot;users&quot;
+        b
+      end,
+      'rubies' =&gt; Proc.new do
+        b = Chef::DataBag.new(Chef::CouchDB.new(nil, &quot;chef_integration&quot;))
+        b.name &quot;rubies&quot;
+        b
+      end
+    },
+    'data_bag_item' =&gt; {
+      'francis' =&gt; Proc.new do
+        i = Chef::DataBagItem.new(Chef::CouchDB.new(nil, &quot;chef_integration&quot;))
+        i.data_bag &quot;users&quot;
+        i.raw_data = { &quot;id&quot; =&gt; &quot;francis&quot; }
+        i
+      end,
+      'francis_extra' =&gt; Proc.new do
+        i = Chef::DataBagItem.new(Chef::CouchDB.new(nil, &quot;chef_integration&quot;))
+        i.data_bag &quot;users&quot;
+        i.raw_data = { &quot;id&quot; =&gt; &quot;francis&quot;, &quot;extra&quot; =&gt; &quot;majority&quot; }
+        i
+      end,
+      'axl_rose' =&gt; Proc.new do
+        i = Chef::DataBagItem.new(Chef::CouchDB.new(nil, &quot;chef_integration&quot;))
+        i.data_bag &quot;users&quot;
+        i.raw_data = { &quot;id&quot; =&gt; &quot;axl_rose&quot; }
+        i
       end
     },
     'role' =&gt; {
       'webserver' =&gt; Proc.new do
-        r = Chef::Role.new
+        r = Chef::Role.new(Chef::CouchDB.new(nil, &quot;chef_integration&quot;))
         r.name &quot;webserver&quot;
         r.description &quot;monkey&quot;
         r.recipes(&quot;role::webserver&quot;, &quot;role::base&quot;)
@@ -22,7 +56,7 @@ Before do
         r 
       end,
       'db' =&gt; Proc.new do
-        r = Chef::Role.new
+        r = Chef::Role.new(Chef::CouchDB.new(nil, &quot;chef_integration&quot;))
         r.name &quot;db&quot;
         r.description &quot;monkey&quot;
         r.recipes(&quot;role::db&quot;, &quot;role::base&quot;)
@@ -33,7 +67,7 @@ Before do
     },
     'node' =&gt; {
       'webserver' =&gt; Proc.new do
-        n = Chef::Node.new
+        n = Chef::Node.new(Chef::CouchDB.new(nil, &quot;chef_integration&quot;))
         n.name 'webserver'
         n.run_list &lt;&lt; &quot;tacos&quot;
         n.snakes &quot;on a plane&quot;
@@ -41,17 +75,34 @@ Before do
         n
       end,
       'dbserver' =&gt; Proc.new do
-        n = Chef::Node.new
+        n = Chef::Node.new(Chef::CouchDB.new(nil, &quot;chef_integration&quot;))
         n.name 'dbserver'
         n.run_list &lt;&lt; &quot;oracle&quot;
         n.just &quot;kidding - who uses oracle?&quot;
         n
+      end,
+      'sync' =&gt; Proc.new do
+        n = Chef::Node.new(Chef::CouchDB.new(nil, &quot;chef_integration&quot;))
+        n.name 'sync'
+        n.run_list &lt;&lt; &quot;node_cookbook_sync&quot;
+        n
       end
     }
   }
   @stash = {}
 end
 
+def sign_request(http_method, private_key, user_id, body = &quot;&quot;)
+  timestamp = Time.now.utc.iso8601
+  sign_obj = Mixlib::Auth::SignedHeaderAuth.signing_object(
+                                                     :http_method=&gt;http_method,
+                                                     :body=&gt;body,
+                                                     :user_id=&gt;user_id,
+                                                     :timestamp=&gt;timestamp)
+  signed =  sign_obj.sign(private_key).merge({:host =&gt; &quot;localhost&quot;})
+  signed.inject({}){|memo, kv| memo[&quot;#{kv[0].to_s.upcase}&quot;] = kv[1];memo}
+end
+
 def get_fixture(stash_name, stash_key)
   fixy = @fixtures[stash_name][stash_key]
   if fixy.kind_of?(Proc)
@@ -62,20 +113,35 @@ def get_fixture(stash_name, stash_key)
 end
 
 Given /^an? '(.+)' named '(.+)'$/ do |stash_name, stash_key|
-  @stash[stash_name] = get_fixture(stash_name, stash_key)
+  # BUGBUG: I need to reference fixtures individually, but the fixtures, as written, store under the type, not the fixture's identifier and I don't currently have time to re-write the tests
+
+  key = case stash_name
+        when 'file','hash'
+          stash_key
+        else
+          stash_name
+        end
+  @stash[key] = get_fixture(stash_name, stash_key)
 end
 
-Given /^an? '(.+)' named '(.+)' exists$/ do |stash_name, stash_key|
+Given /^an? '(.+)' named '(.+)' exists$/ do |stash_name, stash_key|  
   @stash[stash_name] = get_fixture(stash_name, stash_key) 
-  if @stash[stash_name].respond_to?(:save)
-    @stash[stash_name].save
-  else
-    request(&quot;/#{stash_name.pluralize}&quot;, { 
-      :method =&gt; &quot;POST&quot;, 
-      &quot;HTTP_ACCEPT&quot; =&gt; 'application/json',
-      &quot;CONTENT_TYPE&quot; =&gt; 'application/json',
-      :input =&gt; @stash[stash_name].to_json 
-    })
+    
+  if stash_name == 'registration'
+    r = Chef::REST.new(Chef::Config[:registration_url], Chef::Config[:validation_user], Chef::Config[:validation_key])
+    r.register(&quot;bobo&quot;, &quot;#{tmpdir}/bobo.pem&quot;)
+    @rest = Chef::REST.new(Chef::Config[:registration_url], 'bobo', &quot;#{tmpdir}/bobo.pem&quot;)
+  else 
+    if @stash[stash_name].respond_to?(:save)#stash_name == &quot;registration&quot; 
+      @stash[stash_name].save
+    else
+      request(&quot;#{stash_name.pluralize}&quot;, { 
+        :method =&gt; &quot;POST&quot;, 
+        &quot;HTTP_ACCEPT&quot; =&gt; 'application/json',
+        &quot;CONTENT_TYPE&quot; =&gt; 'application/json',
+        :input =&gt; @stash[stash_name].to_json 
+      }.merge(sign_request(&quot;POST&quot;, OpenSSL::PKey::RSA.new(IO.read(&quot;#{tmpdir}/client.pem&quot;)), &quot;bobo&quot;)))
+    end
   end
 end
 
@@ -98,3 +164,7 @@ Given /^there are no (.+)$/ do |stash_name|
     Chef::Role.list(true).each { |r| r.destroy }
   end
 end
+
+Given /^I wait for '(\d+)' seconds$/ do |time|
+  sleep time.to_i
+end</diff>
      <filename>features/steps/fixture_steps.rb</filename>
    </modified>
    <modified>
      <diff>@@ -20,15 +20,15 @@
 # Given
 ###
 Given /^a validated node$/ do
-  client.validation_token = Chef::Config[:validation_token] = 'ceelo'
+  client.determine_node_name
   client.register
-  client.authenticate
   client.build_node
   client.node.recipes &lt;&lt; &quot;integration_setup&quot;
 end
 
 Given /^it includes the recipe '(.+)'$/ do |recipe|
   self.recipe = recipe
+  Chef::Log.error(&quot;It's like this we have: #{Chef::Config[:chef_server_url]}&quot;)
   client.node.recipes &lt;&lt; recipe
   client.save_node
 end</diff>
      <filename>features/steps/node_steps.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,21 +1,55 @@
-When /^I '(.+)' the path '(.+)'$/ do |http_method, request_uri|
+When /^I '([^']*)' (?:to )?the path '([^']*)'$/ do |http_method, request_uri|
   begin
     self.response = rest.send(&quot;#{http_method}_rest&quot;.downcase.to_sym, request_uri)
-    self.inflated_response = self.response 
+    self.inflated_response = self.response
   rescue
+    Chef::Log.debug(&quot;Caught exception in request: #{$!.message}&quot;)
     self.exception = $!
   end
 end
 
+When /^I '([^']*)' to the path '(.+)'$/ do |http_method, request_uri|
+  When &quot;I '#{http_method}' the path '#{request_uri}'&quot;
+end
+
+When /^I '(.+)' the path '(.+)' using a wrong private key$/ do |http_method, request_uri|
+  key = OpenSSL::PKey::RSA.generate(2048)
+  File.open(File.join(tmpdir, 'false_key.pem'), &quot;w&quot;) { |f| f.print key }
+  @rest = Chef::REST.new(Chef::Config[:chef_server_url], 'snakebite' , File.join(tmpdir, 'false_key.pem'))
+
+  When &quot;I '#{http_method}' the path '#{request_uri}'&quot;
+end
+
 When /^I '(.+)' the '(.+)' to the path '(.+)'$/ do |http_method, stash_key, request_uri|
   begin
-    self.response = rest.send(&quot;#{http_method}_rest&quot;.downcase.to_sym, request_uri, stash[stash_key])
+    self.response = rest.send(&quot;#{http_method.to_s.downcase}_rest&quot;.downcase.to_sym, request_uri, stash[stash_key])
     self.inflated_response = response
   rescue
     self.exception = $!
   end
 end
 
+When /^I '(.+)' the '(.+)' to the path '(.+)' using a wrong private key$/ do |http_method, stash_key, request_uri|
+  key = OpenSSL::PKey::RSA.generate(2048)
+  File.open(File.join(tmpdir, 'false_key.pem'), &quot;w&quot;) { |f| f.print key }
+  @rest = Chef::REST.new(Chef::Config[:chef_server_url], 'snakebite' , File.join(tmpdir, 'false_key.pem'))
+
+  When &quot;I '#{http_method}' the '#{stash_key}' to the path '#{request_uri}'&quot;
+end
+
+When /^I delete local private key/ do
+  Chef::FileCache.delete(&quot;private_key.pem&quot;)
+end
+
+When /^I register '(.+)'$/ do |user|
+  begin
+    rest = Chef::REST.new(Chef::Config[:registration_url])
+    rest.register(&quot;bobo&quot;)
+  rescue
+    self.exception = $!
+  end
+end
+
 When /^I authenticate as '(.+)'$/ do |reg|
   begin
     rest.authenticate(reg, 'tclown')
@@ -24,3 +58,59 @@ When /^I authenticate as '(.+)'$/ do |reg|
   end
 end
 
+
+
+
+# When /^I '(.+)' the path '(.+)'$/ do |http_method, request_uri|
+#   begin
+#     #if http_method.downcase == 'get'
+#     #  self.response = @rest.get_rest(request_uri)
+#     #else
+#       #puts &quot;test test test \n\n\n\n\n\n\n&quot;
+#       @response = @rest.send(&quot;#{http_method}_rest&quot;.downcase.to_sym, request_uri)
+#     #end
+#     puts &quot;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&quot;
+#     puts @response
+#     puts @response['content-type']
+#     #puts self.response
+#     #puts self.response.inspect
+#     #self.inflated_response = self.response
+#     @inflated_response = @response#JSON.parse(response.body.to_s) 
+#     puts &quot;~~~~~~~~INFLATED RESPONSE~~~~~~~~~~~~&quot;
+#     puts @inflated_response
+#   rescue
+#     self.exception = $!
+#   end
+# end
+# 
+# When /^I '(.+)' the '(.+)' to the path '(.+)'$/ do |http_method, stash_key, request_uri|
+#   begin
+#     #if http_method.downcase == 'post'
+#     #  puts &quot;post request&quot;
+#     #  self.response = @rest.post_rest(request_uri, @stash[stash_key])
+#     #  puts self.response
+#     #else
+#     puts &quot;This is the request -- @stash[stash_key]:&quot; 
+#     puts @stash[stash_key].to_s
+#     @response = @rest.send(&quot;#{http_method}_rest&quot;.downcase.to_sym, request_uri, @stash[stash_key])
+#     #end
+#     puts &quot;This is the response:&quot;
+#     #puts self.response.body.to_s
+#     puts @response
+#     #self.inflated_response = response
+#     @inflated_response = @response#JSON.parse(self.response.body.to_s)
+#     puts &quot;~~~~~~~~INFLATED RESPONSE~~~~~~~~~~~~&quot;
+#     puts @inflated_response
+#   rescue
+#     self.exception = $!
+#   end
+# end
+# 
+# When /^I authenticate as '(.+)'$/ do |reg|
+#   begin
+#     rest.authenticate(reg, 'tclown')
+#   rescue
+#     self.exception = $!
+#   end
+# end
+# </diff>
      <filename>features/steps/request_steps.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,70 +3,101 @@ Then /^I should get a '(.+)' exception$/ do |exception|
 end
 
 Then /^the response code should be '(.+)'$/ do |response_code|
-  response.status.should == response_code.to_i
+  self.response.status.should == response_code.to_i
+end
+
+Then /^the inflated responses key '(.+)' should be the integer '(\d+)'$/ do |key, int|
+  inflated_response[key].should == int.to_i
 end
 
 Then /^the inflated responses key '(.+)' should match '(.+)'$/ do |key, regex|
-  inflated_response[key].should =~ /#{regex}/
+  puts self.inflated_response.inspect if ENV['DEBUG']
+  self.inflated_response[key].should =~ /#{regex}/m  
+end
+
+Then /^the inflated responses key '(.+)' should match '(.+)' as json$/ do |key, regex|
+  puts self.inflated_response.inspect if ENV[&quot;DEBUG&quot;]
+  self.inflated_response[key].to_json.should =~ /#{regex}/m
+end
+
+Then /^the inflated responses key '(.+)' item '(\d+)' should be a kind of '(.+)'$/ do |key, index, constant|
+  inflated_response[key][index.to_i].should be_a_kind_of(eval(constant))
+end
+
+Then /^the inflated responses key '(.+)' item '(\d+)' key '(.+)' should be '(.+)'$/ do |key, index, sub_key, to_equal|
+  inflated_response[key][index.to_i][sub_key].should == to_equal
+end
+
+Then /^the inflated responses key '(.+)' should be '(\d+)' items long$/ do |key, length| 
+  inflated_response[key].length.should == length.to_i
 end
 
 Then /^the inflated responses key '(.+)' should not exist$/ do |key|
-  inflated_response.has_key?(key).should == false
+  self.inflated_response.has_key?(key).should == false
 end
 
 Then /^the inflated responses key '(.+)' should exist$/ do |key|
-  inflated_response.has_key?(key).should == true 
+  self.inflated_response.has_key?(key).should == true 
 end
 
 Then /^the inflated response should be an empty array$/ do
-  inflated_response.should == []
+  self.inflated_response.should == []
 end
 
 Then /^the inflated response should include '(.+)'$/ do |entry|
-  inflated_response.detect { |n| n =~ /#{entry}/ }.should be(true)
+  self.inflated_response.detect { |n| n =~ /#{entry}/ }.should be(true)
 end
 
 Then /^the inflated response should be '(.+)' items long$/ do |length|
-  inflated_response.length.should == length.to_i
+  self.inflated_response.length.should == length.to_i
 end
 
 Then /^the '(.+)' header should match '(.+)'$/ do |header, regex|
-  response.headers[header].should =~ /#{regex}/
+  self.response.headers[header].should =~ /#{regex}/
 end
 
 Then /^the inflated responses key '(.+)' should include '(.+)'$/ do |key, regex|
-  inflated_response[key].detect { |n| n =~ /#{regex}/ }.should be(true)
+  self.inflated_response[key].detect { |n| n =~ /#{regex}/ }.should be(true)
 end
 
 Then /^the inflated response should match the '(.+)'$/ do |stash_name|
   stash[stash_name].each do |k,v|
-    inflated_response[k.to_s].should == v
+    self.inflated_response[k.to_s].should == v
   end
 end
 
 Then /^the inflated response should be the '(.+)'$/ do |stash_key|
-  stash[stash_key].should == inflated_response
+  stash[stash_key].should == self.inflated_response
 end
 
 Then /^the inflated response should be a kind of '(.+)'$/ do |thing|
-  inflated_response.should be_a_kind_of(thing)
+  self.inflated_response.should be_a_kind_of(thing)
 end
 
 Then /^the inflated response should respond to '(.+)' with '(.+)'$/ do |method, to_match|
   to_match = JSON.parse(to_match) if to_match =~ /^\[|\{/
-  inflated_response.send(method.to_sym).should == to_match 
+  self.inflated_response.send(method.to_sym).should == to_match 
 end
 
 Then /^the inflated response should respond to '(.+)' and match '(.+)'$/ do |method, to_match|
-  inflated_response.send(method.to_sym).should == to_match 
+  self.inflated_response.send(method.to_sym).should == to_match 
 end
 
 
 Then /^the fields in the inflated response should match the '(.+)'$/ do |stash_name|
-  inflated_response.each do |k,v|
+  self.inflated_response.each do |k,v|
     unless k =~ /^_/ || k == 'couchrest-type'
       stash[stash_name][k.to_sym].should == v
     end
   end
 end
 
+Then /^the data_bag named '(.+)' should not have an item named '(.+)'$/ do |data_bag, item|
+  exists = true
+  begin
+    Chef::DataBagItem.load(data_bag, item, @couchdb)
+  rescue
+    exists = false
+  end
+  exists.should == false
+end</diff>
      <filename>features/steps/response_steps.rb</filename>
    </modified>
    <modified>
      <diff>@@ -24,7 +24,7 @@ When /^I run the chef\-client$/ do
   @chef_args ||= &quot;&quot;
   @config_file ||= File.expand_path(File.join(File.dirname(__FILE__), '..', 'data', 'config', 'client.rb'))
   status = Chef::Mixin::Command.popen4(
-    &quot;chef-client -l #{@log_level} -c #{@config_file} #{@chef_args}&quot;) do |p, i, o, e|
+    &quot;#{File.join(File.dirname(__FILE__), &quot;..&quot;, &quot;..&quot;, &quot;chef&quot;, &quot;bin&quot;, &quot;chef-client&quot;)} -l #{@log_level} -c #{@config_file} #{@chef_args}&quot;) do |p, i, o, e|
     @stdout = o.gets(nil)
     @stderr = e.gets(nil)
   end
@@ -76,7 +76,7 @@ openid_url       &quot;http://127.0.0.1:4001&quot;
 template_url     &quot;http://127.0.0.1:4000&quot;
 remotefile_url   &quot;http://127.0.0.1:4000&quot;
 search_url       &quot;http://127.0.0.1:4000&quot;
-couchdb_database   'chef_integration'
+couchdb_database   'chef'
 CONFIG
   
   @config_file = File.expand_path(File.join(File.dirname(__FILE__), '..', 'data', 'config', 'client-with-logging.rb'))  
@@ -86,12 +86,11 @@ CONFIG
 
   self.cleanup_files &lt;&lt; @config_file
   
-  @status = Chef::Mixin::Command.popen4(&quot;chef-client -c #{@config_file}&quot;) do |p, i, o, e|
+  
+  @status = Chef::Mixin::Command.popen4(&quot;#{File.join(File.dirname(__FILE__), &quot;..&quot;, &quot;..&quot;, &quot;chef&quot;, &quot;bin&quot;, &quot;chef-client&quot;)} -l #{@log_level} -c #{@config_file} #{@chef_args}&quot;) do |p, i, o, e|
     @stdout = o.gets(nil)
     @stderr = e.gets(nil)
   end
-
-  
 end
 
 ###</diff>
      <filename>features/steps/run_client_steps.rb</filename>
    </modified>
    <modified>
      <diff>@@ -26,7 +26,7 @@ When /^I run chef-solo with the '(.+)' recipe$/ do |recipe_name|
   cleanup_files &lt;&lt; config_file
 
   binary_path = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'chef', 'bin', 'chef-solo'))
-  command = &quot;chef-solo -c #{config_file} -j #{dna_file}&quot;
+  command = &quot;#{binary_path} -c #{config_file} -j #{dna_file}&quot;
   command += &quot; -l debug&quot; if ENV['LOG_LEVEL'] == 'debug'
 
   # Run it</diff>
      <filename>features/steps/run_solo.rb</filename>
    </modified>
    <modified>
      <diff>@@ -36,4 +36,4 @@ end
 When /^I attach the file at &quot;(.*)&quot; to &quot;(.*)&quot; $/ do |path, field|
   attach_file(field, path)
 end
- 
\ No newline at end of file
+ </diff>
      <filename>features/steps/webrat_steps.rb</filename>
    </modified>
    <modified>
      <diff>@@ -16,7 +16,7 @@
 # limitations under the License.
 #
 
-%w{chef chef-server chef-server-slice}.each do |inc_dir|
+%w{chef chef-server chef-server-slice chef-solr}.each do |inc_dir|
   $: &lt;&lt; File.join(File.dirname(__FILE__), '..', '..', inc_dir, 'lib')
 end
 
@@ -25,22 +25,92 @@ require 'spec'
 require 'chef'
 require 'chef/config'
 require 'chef/client'
+require 'chef/data_bag'
+require 'chef/data_bag_item'
+require 'chef/solr'
 require 'tmpdir'
 require 'merb-core'
 require 'merb_cucumber/world/webrat'
+require 'opscode/audit'
+require 'chef/streaming_cookbook_uploader'
 
 def Spec.run? ; true; end
 
-Chef::Config.from_file(File.join(File.dirname(__FILE__), '..', 'data', 'config', 'server.rb'))
-Chef::Config[:log_level] = :error
-Ohai::Config[:log_level] = :error
+ENV['LOG_LEVEL'] ||= 'error'
+
+def setup_logging
+  Chef::Config.from_file(File.join(File.dirname(__FILE__), '..', 'data', 'config', 'server.rb'))
+  Merb.logger.auto_flush = true
+  if ENV['DEBUG'] == 'true' || ENV['LOG_LEVEL'] == 'debug'
+    Chef::Config[:log_level] = :debug
+    Chef::Log.level(:debug)
+    Merb.logger.set_log(STDOUT, :debug) 
+  else
+    Chef::Config[:log_level] = ENV['LOG_LEVEL'].to_sym 
+    Chef::Log.level(ENV['LOG_LEVEL'].to_sym)
+    Merb.logger.set_log(STDOUT, ENV['LOG_LEVEL'].to_sym)
+  end
+  Nanite::Log.logger = Mixlib::Auth::Log.logger = Ohai::Log.logger = Chef::Log.logger 
+end
+
+def setup_nanite
+  Chef::Config[:nanite_identity] = &quot;chef-integration-test&quot;
+  Chef::Nanite.in_event { Chef::Log.debug(&quot;Nanite is up!&quot;) } 
+  Chef::Log.debug(&quot;Waiting for Nanites to register with us as a mapper&quot;)
+  sleep 10
+end
+
+def delete_databases
+  c = Chef::REST.new(Chef::Config[:couchdb_url], nil, nil)
+  %w{chef_integration}.each do |db|
+    begin
+      c.delete_rest(&quot;#{db}/&quot;)
+    rescue
+    end
+  end
+end
 
-if ENV['DEBUG'] = 'true'
-  Merb.logger.set_log(STDOUT, :debug) if ENV['DEBUG'] = 'true'
-else
-  Merb.logger.set_log(STDOUT, :error)
+def create_databases
+  Chef::Log.info(&quot;Creating bootstrap databases&quot;)
+  cdb = Chef::CouchDB.new(Chef::Config[:couchdb_url], &quot;chef_integration&quot;)
+  cdb.create_db
+  Chef::Node.create_design_document
+  Chef::Role.create_design_document
+  Chef::DataBag.create_design_document
+  Chef::Role.sync_from_disk_to_couchdb
 end
 
+
+def create_validation
+# TODO: Create the validation certificate here
+  File.open(&quot;#{Dir.tmpdir}/validation.pem&quot;, &quot;w&quot;) do |f|
+    f.print response[&quot;private_key&quot;]
+  end
+end
+
+def prepare_replicas
+  c = Chef::REST.new(Chef::Config[:couchdb_url], nil, nil)
+  c.put_rest(&quot;chef_integration_safe/&quot;, nil)
+  c.post_rest(&quot;_replicate&quot;, { &quot;source&quot; =&gt; &quot;#{Chef::Config[:couchdb_url]}/chef_integration&quot;, &quot;target&quot; =&gt; &quot;#{Chef::Config[:couchdb_url]}/chef_integration_safe&quot; })
+  c.delete_rest(&quot;chef_integration&quot;)
+end
+
+at_exit do
+  c = Chef::REST.new(Chef::Config[:couchdb_url], nil, nil)
+  c.delete_rest(&quot;chef_integration_safe&quot;)
+  File.unlink(File.join(Dir.tmpdir, &quot;validation.pem&quot;))
+end
+
+###
+# Pre-testing setup
+###
+setup_logging
+setup_nanite
+delete_databases
+create_databases
+create_validation
+prepare_replicas
+
 Merb.start_environment(
   :merb_root =&gt; File.join(File.dirname(__FILE__), &quot;..&quot;, &quot;..&quot;, &quot;chef-server&quot;), 
   :testing =&gt; true, 
@@ -55,6 +125,11 @@ Spec::Runner.configure do |config|
   config.include(Merb::Test::ControllerHelper)
 end
 
+Chef::Log.info(&quot;Ready to run tests&quot;)
+
+###
+# The Cucumber World
+###
 module ChefWorld
 
   attr_accessor :recipe, :cookbook, :response, :inflated_response, :log_level, :chef_args, :config_file, :stdout, :stderr, :status, :exception
@@ -64,7 +139,7 @@ module ChefWorld
   end
 
   def rest
-    @rest ||= Chef::REST.new('http://localhost:4000')
+    @rest ||= Chef::REST.new('http://localhost:4000/organizations/clownco', nil, nil)
   end
 
   def tmpdir
@@ -91,7 +166,23 @@ end
 
 World(ChefWorld)
 
+Before do
+  system(&quot;mkdir -p #{tmpdir}&quot;)
+  system(&quot;cp -r #{File.join(Dir.tmpdir, &quot;validation.pem&quot;)} #{File.join(tmpdir, &quot;validation.pem&quot;)}&quot;)
+  Chef::CouchDB.new(Chef::Config[:couchdb_url], &quot;chef_integration&quot;).create_db
+  c = Chef::REST.new(Chef::Config[:couchdb_url], nil, nil)
+  c.post_rest(&quot;_replicate&quot;, { 
+    &quot;source&quot; =&gt; &quot;#{Chef::Config[:couchdb_url]}/chef_integration_safe&quot;,
+    &quot;target&quot; =&gt; &quot;#{Chef::Config[:couchdb_url]}/chef_integration&quot; 
+  })
+end
+
 After do
+  r = Chef::REST.new(Chef::Config[:couchdb_url], nil, nil)
+  r.delete_rest(&quot;chef_integration/&quot;)
+  s = Chef::Solr.new
+  s.solr_delete_by_query(&quot;*:*&quot;)
+  s.solr_commit
   cleanup_files.each do |file|
     system(&quot;rm #{file}&quot;)
   end
@@ -104,5 +195,6 @@ After do
   end
   data_tmp = File.join(File.dirname(__FILE__), &quot;..&quot;, &quot;data&quot;, &quot;tmp&quot;)
   system(&quot;rm -rf #{data_tmp}/*&quot;)
+  system(&quot;rm -rf #{tmpdir}&quot;)
 end
 </diff>
      <filename>features/support/env.rb</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>chef-server-slice/LICENSE</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/NOTICE</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/README.rdoc</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/Rakefile</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/controllers/application.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/controllers/cookbook_attributes.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/controllers/cookbook_definitions.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/controllers/cookbook_files.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/controllers/cookbook_libraries.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/controllers/cookbook_recipes.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/controllers/cookbook_templates.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/controllers/cookbooks.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/controllers/exceptions.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/controllers/main.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/controllers/nodes.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/controllers/openid_consumer.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/controllers/openid_register.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/controllers/openid_server.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/controllers/roles.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/controllers/search.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/controllers/search_entries.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/controllers/status.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/helpers/application_helper.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/helpers/cookbook_attributes_helper.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/helpers/cookbook_definitions_helper.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/helpers/cookbook_files_helper.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/helpers/cookbook_libraries_helper.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/helpers/cookbook_recipes_helper.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/helpers/cookbook_templates_helper.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/helpers/cookbooks_helper.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/helpers/exceptions_helper.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/helpers/global_helpers.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/helpers/nodes_helper.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/helpers/openid_consumer_helper.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/helpers/openid_register_helper.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/helpers/openid_server_helper.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/helpers/openid_server_helpers.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/helpers/roles_helper.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/helpers/search_entries_helper.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/helpers/search_helper.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/helpers/status_helper.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/cookbook_templates/index.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/cookbooks/index.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/cookbooks/show.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/exceptions/bad_request.json.erb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/exceptions/internal_server_error.html.erb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/exceptions/not_acceptable.html.erb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/exceptions/not_found.html.erb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/exceptions/standard_error.html.erb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/layout/chef_server_slice.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/layout/login.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/main/index.html.erb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/nodes/_action.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/nodes/_form.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/nodes/_navigation.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/nodes/_resource.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/nodes/edit.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/nodes/index.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/nodes/new.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/nodes/show.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/openid_consumer/index.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/openid_consumer/start.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/openid_login/index.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/openid_register/index.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/openid_register/show.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/openid_server/decide.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/roles/_form.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/roles/_navigation.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/roles/edit.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/roles/index.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/roles/new.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/roles/show.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/search/_search_form.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/search/index.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/search/show.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/search_entries/index.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/search_entries/show.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/app/views/status/index.html.haml</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/config/init.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/config/router.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/lib/chef-server-slice.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/lib/chef-server-slice/merbtasks.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/lib/chef-server-slice/slicetasks.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/lib/chef-server-slice/spectasks.rb</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/facebox/README.txt</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/facebox/b.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/facebox/bl.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/facebox/br.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/facebox/closelabel.gif</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/facebox/facebox.css</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/facebox/facebox.js</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/facebox/loading.gif</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/facebox/tl.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/facebox/tr.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/avatar.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/black_big.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/indicator.gif</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/merb.jpg</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/toggle-collapse-dark.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/toggle-collapse-light.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/toggle-collapse.gif</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/toggle-expand-dark.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/toggle-expand-light.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/toggle-expand.gif</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/treeBuilderImages/Thumbs.db</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/treeBuilderImages/doc.gif</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/treeBuilderImages/docNode.gif</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/treeBuilderImages/docNodeLast.gif</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/treeBuilderImages/docNodeLastFirst.gif</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/treeBuilderImages/folder.gif</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/treeBuilderImages/folderNode.gif</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/treeBuilderImages/folderNodeFirst.gif</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/treeBuilderImages/folderNodeLast.gif</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/treeBuilderImages/folderNodeLastFirst.gif</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/treeBuilderImages/folderNodeOpen.gif</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/treeBuilderImages/folderNodeOpenFirst.gif</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/treeBuilderImages/folderNodeOpenLast.gif</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/treeBuilderImages/folderNodeOpenLastFirst.gif</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/treeBuilderImages/folderOpen.gif</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/images/treeBuilderImages/vertLine.gif</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/javascripts/JSONeditor.js</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/javascripts/chef.js</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/javascripts/jquery-1.3.2.min.js</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/javascripts/jquery-ui-1.7.1.custom.min.js</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/javascripts/jquery.editinline.js</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/javascripts/jquery.jeditable.mini.js</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/javascripts/jquery.livequery.js</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/javascripts/jquery.localscroll.js</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/javascripts/jquery.scrollTo.js</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/javascripts/jquery.tools.min.js</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/javascripts/jquery.treeTable.min.js</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/base.css</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/chef.css</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/images/ui-bg_diagonals-small_0_aaaaaa_40x40.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/images/ui-bg_diagonals-thick_15_444444_40x40.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/images/ui-bg_glass_100_f0f0f0_1x400.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/images/ui-bg_glass_50_99c2ff_1x400.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/images/ui-bg_glass_55_fbf5d0_1x400.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/images/ui-bg_glass_80_e6e6e6_1x400.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/images/ui-bg_glass_95_fef1ec_1x400.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/images/ui-bg_highlight-hard_100_f9f9f9_1x100.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/images/ui-bg_highlight-soft_100_e7eef3_1x100.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/images/ui-icons_222222_256x240.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/images/ui-icons_2694e8_256x240.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/images/ui-icons_2e83ff_256x240.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/images/ui-icons_72a7cf_256x240.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/images/ui-icons_888888_256x240.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/images/ui-icons_cd0a0a_256x240.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/images/ui-icons_ffffff_256x240.png</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/jquery-ui-1.7.1.custom.css</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/jquery.treeTable.css</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/themes/bec-green/style.css</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/themes/bec/style.css</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/themes/blue/style.css</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/themes/default/style.css</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/themes/djime-cerulean/style.css</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/themes/kathleene/style.css</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/themes/orange/style.css</filename>
    </removed>
    <removed>
      <filename>chef-server-slice/public/stylesheets/themes/reidb-greenish/style.css</filename>
    </removed>
    <removed>
      <filename>chef/lib/chef/application/indexer.rb</filename>
    </removed>
    <removed>
      <filename>chef/lib/chef/queue.rb</filename>
    </removed>
    <removed>
      <filename>chef/lib/chef/search.rb</filename>
    </removed>
    <removed>
      <filename>chef/lib/chef/search/result.rb</filename>
    </removed>
    <removed>
      <filename>chef/lib/chef/search_index.rb</filename>
    </removed>
    <removed>
      <filename>chef/spec/unit/application/indexer_spec.rb</filename>
    </removed>
    <removed>
      <filename>chef/spec/unit/queue_spec.rb</filename>
    </removed>
    <removed>
      <filename>chef/spec/unit/search/result_spec.rb</filename>
    </removed>
    <removed>
      <filename>features/steps/couchdb_steps.rb</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>89a2609242a63d6bc85e0ddfed078319b4d4a81b</id>
    </parent>
  </parents>
  <author>
    <name>Adam Jacob</name>
    <email>adam@opscode.com</email>
  </author>
  <url>http://github.com/opscode/chef/commit/89779a4d487ac7dd313e16eb68732835bd13d4e4</url>
  <id>89779a4d487ac7dd313e16eb68732835bd13d4e4</id>
  <committed-date>2009-08-20T13:31:58-07:00</committed-date>
  <authored-date>2009-08-01T21:26:21-07:00</authored-date>
  <message>Initial pass at a Chef 0.8.0 alpha

Conflicts:

	Rakefile
	chef-server-slice/Rakefile
	chef-server-slice/app/controllers/application.rb
	chef-server-slice/app/controllers/exceptions.rb
	chef-server-slice/app/controllers/nodes.rb
	chef-server-slice/app/controllers/openid_consumer.rb
	chef-server-slice/app/controllers/openid_server.rb
	chef-server-slice/app/helpers/nodes_helper.rb
	chef-server/Rakefile
	chef-server/config/dependencies.rb
	chef-server/config/init.rb
	chef/Rakefile
	chef/lib/chef.rb
	chef/lib/chef/application/indexer.rb
	chef/lib/chef/client.rb
	chef/lib/chef/config.rb
	chef/lib/chef/node.rb
	chef/lib/chef/queue.rb
	chef/spec/unit/application/indexer_spec.rb
	chef/spec/unit/client_spec.rb
	chef/spec/unit/config_spec.rb
	cucumber.yml
	features/api/nodes/create_node_api.feature
	features/api/nodes/delete_node_api.feature
	features/api/nodes/list_nodes_api.feature
	features/api/nodes/show_node_api.feature
	features/api/nodes/update_node_api.feature
	features/api/roles/list_roles_api.feature
	features/steps/fixture_steps.rb</message>
  <tree>d8b867f3a5610ed39bd864149152085af05a1c3d</tree>
  <committer>
    <name>Adam Jacob</name>
    <email>adam@opscode.com</email>
  </committer>
</commit>
