# File lib/chef/cookbook_loader.rb, line 39
    def load_cookbooks
      cookbook_settings = Hash.new
      [Chef::Config.cookbook_path].flatten.each do |cb_path|
        cb_path = File.expand_path(cb_path)
        Dir[File.join(cb_path, "*")].each do |cookbook|
          next unless File.directory?(cookbook)
          cookbook_name = File.basename(cookbook).to_sym
          unless cookbook_settings.has_key?(cookbook_name)
            cookbook_settings[cookbook_name] = { 
              :attribute_filenames  => Hash.new,
              :definition_filenames => Hash.new,
              :recipe_filenames     => Hash.new,
              :template_filenames   => Hash.new,
              :file_filenames       => Hash.new,
              :library_filenames    => Hash.new,
              :resource_filenames   => Hash.new,
              :provider_filenames   => Hash.new,
              :root_filenames       => Hash.new,
              :metadata_filenames   => Array.new
            }
          end
          ignore_regexes = load_ignore_file(File.join(cookbook, "ignore"))
          @ignore_regexes[cookbook_name].concat(ignore_regexes)
          
          load_files_unless_basename(
            File.join(cookbook, "attributes", "*.rb"), 
            cookbook_settings[cookbook_name][:attribute_filenames]
          )
          load_files_unless_basename(
            File.join(cookbook, "definitions", "*.rb"), 
            cookbook_settings[cookbook_name][:definition_filenames]
          )
          load_files_unless_basename(
            File.join(cookbook, "recipes", "*.rb"), 
            cookbook_settings[cookbook_name][:recipe_filenames]
          )
          load_files_unless_basename(
            File.join(cookbook, "libraries", "*.rb"),               
            cookbook_settings[cookbook_name][:library_filenames]
          )
          load_cascading_files(
            "*",
            File.join(cookbook, "templates"),
            cookbook_settings[cookbook_name][:template_filenames]
          )
          load_cascading_files(
            "*",
            File.join(cookbook, "files"),
            cookbook_settings[cookbook_name][:file_filenames]
          )
          load_cascading_files(
            "*.rb",
            File.join(cookbook, "resources"),
            cookbook_settings[cookbook_name][:resource_filenames]
          )
          load_cascading_files(
            "*.rb",
            File.join(cookbook, "providers"),
            cookbook_settings[cookbook_name][:provider_filenames]
          )
          load_files(
            "*",
            cookbook,
            cookbook_settings[cookbook_name][:root_filenames]
          )
          cookbook_settings[cookbook_name][:root_dir] = cookbook
          if File.exists?(File.join(cookbook, "metadata.json"))
            cookbook_settings[cookbook_name][:metadata_filenames] << File.join(cookbook, "metadata.json")
          end

          empty = cookbook_settings[cookbook_name].inject(true) do |all_empty, files|
            all_empty && files.last.empty?
          end

          if empty
            Chef::Log.warn "found a directory #{cookbook_name} in the cookbook path, but it contains no cookbook files. skipping."
            cookbook_settings.delete(cookbook_name)
          end
        end
      end
      remove_ignored_files_from(cookbook_settings)

      cookbook_settings.each_key do |cookbook|
        @cookbooks_by_name[cookbook] = Chef::CookbookVersion.new(cookbook)
        @cookbooks_by_name[cookbook].root_dir = cookbook_settings[cookbook][:root_dir]
        @cookbooks_by_name[cookbook].attribute_filenames = cookbook_settings[cookbook][:attribute_filenames].values
        @cookbooks_by_name[cookbook].definition_filenames = cookbook_settings[cookbook][:definition_filenames].values
        @cookbooks_by_name[cookbook].recipe_filenames = cookbook_settings[cookbook][:recipe_filenames].values
        @cookbooks_by_name[cookbook].template_filenames = cookbook_settings[cookbook][:template_filenames].values
        @cookbooks_by_name[cookbook].file_filenames = cookbook_settings[cookbook][:file_filenames].values
        @cookbooks_by_name[cookbook].library_filenames = cookbook_settings[cookbook][:library_filenames].values
        @cookbooks_by_name[cookbook].resource_filenames = cookbook_settings[cookbook][:resource_filenames].values
        @cookbooks_by_name[cookbook].provider_filenames = cookbook_settings[cookbook][:provider_filenames].values
        @cookbooks_by_name[cookbook].root_filenames = cookbook_settings[cookbook][:root_filenames].values
        @cookbooks_by_name[cookbook].metadata_filenames = cookbook_settings[cookbook][:metadata_filenames]
        @metadata[cookbook] = Chef::Cookbook::Metadata.new(@cookbooks_by_name[cookbook])
        cookbook_settings[cookbook][:metadata_filenames].each do |meta_json|
          begin
            @metadata[cookbook].from_json(IO.read(meta_json))
          rescue JSON::ParserError
            Chef::Log.fatal("Couldn't parse JSON in " + meta_json)
            raise
          end
        end
        @cookbooks_by_name[cookbook].metadata = @metadata[cookbook]
      end
    end