[DRE-commits] [ruby-elasticsearch-api] 01/04: Imported Upstream version 1.0.4

Tim Potter tpot-guest at moszumanska.debian.org
Mon Sep 8 04:35:55 UTC 2014


This is an automated email from the git hooks/post-receive script.

tpot-guest pushed a commit to branch master
in repository ruby-elasticsearch-api.

commit 8459555ddd781bd19d19cc32e9c50b65f292cf96
Author: Tim Potter <tpot at hp.com>
Date:   Wed Aug 6 17:04:41 2014 +1000

    Imported Upstream version 1.0.4
---
 .gitignore                                         |  17 +
 Gemfile                                            |  16 +
 LICENSE.txt                                        |  13 +
 README.md                                          | 174 +++++
 Rakefile                                           | 158 +++++
 checksums.yaml.gz                                  | Bin 0 -> 427 bytes
 elasticsearch-api.gemspec                          |  69 ++
 lib/elasticsearch-api.rb                           |   1 +
 lib/elasticsearch/api.rb                           |  41 ++
 lib/elasticsearch/api/actions/abort_benchmark.rb   |  27 +
 lib/elasticsearch/api/actions/benchmark.rb         |  62 ++
 lib/elasticsearch/api/actions/bulk.rb              |  85 +++
 lib/elasticsearch/api/actions/cat/aliases.rb       |  67 ++
 lib/elasticsearch/api/actions/cat/allocation.rb    |  69 ++
 lib/elasticsearch/api/actions/cat/count.rb         |  63 ++
 lib/elasticsearch/api/actions/cat/fielddata.rb     |  49 ++
 lib/elasticsearch/api/actions/cat/health.rb        |  51 ++
 lib/elasticsearch/api/actions/cat/help.rb          |  25 +
 lib/elasticsearch/api/actions/cat/indices.rb       |  77 +++
 lib/elasticsearch/api/actions/cat/master.rb        |  48 ++
 lib/elasticsearch/api/actions/cat/nodes.rb         |  59 ++
 lib/elasticsearch/api/actions/cat/pending_tasks.rb |  49 ++
 lib/elasticsearch/api/actions/cat/recovery.rb      |  73 +++
 lib/elasticsearch/api/actions/cat/shards.rb        |  72 +++
 lib/elasticsearch/api/actions/cat/thread_pool.rb   |  56 ++
 lib/elasticsearch/api/actions/clear_scroll.rb      |  24 +
 .../api/actions/cluster/get_settings.rb            |  31 +
 lib/elasticsearch/api/actions/cluster/health.rb    |  54 ++
 .../api/actions/cluster/pending_tasks.rb           |  33 +
 .../api/actions/cluster/put_settings.rb            |  30 +
 lib/elasticsearch/api/actions/cluster/reroute.rb   |  43 ++
 lib/elasticsearch/api/actions/cluster/state.rb     |  57 ++
 lib/elasticsearch/api/actions/count.rb             |  58 ++
 lib/elasticsearch/api/actions/count_percolate.rb   |  78 +++
 lib/elasticsearch/api/actions/create.rb            |  34 +
 lib/elasticsearch/api/actions/delete.rb            |  64 ++
 lib/elasticsearch/api/actions/delete_by_query.rb   |  75 +++
 lib/elasticsearch/api/actions/exists.rb            |  53 ++
 lib/elasticsearch/api/actions/explain.rb           |  82 +++
 lib/elasticsearch/api/actions/get.rb               |  72 +++
 lib/elasticsearch/api/actions/get_source.rb        |  71 +++
 lib/elasticsearch/api/actions/index.rb             | 103 +++
 lib/elasticsearch/api/actions/indices/analyze.rb   |  62 ++
 .../api/actions/indices/clear_cache.rb             |  79 +++
 lib/elasticsearch/api/actions/indices/close.rb     |  50 ++
 lib/elasticsearch/api/actions/indices/create.rb    |  82 +++
 lib/elasticsearch/api/actions/indices/delete.rb    |  47 ++
 .../api/actions/indices/delete_alias.rb            |  36 ++
 .../api/actions/indices/delete_mapping.rb          |  26 +
 .../api/actions/indices/delete_template.rb         |  42 ++
 .../api/actions/indices/delete_warmer.rb           |  32 +
 lib/elasticsearch/api/actions/indices/exists.rb    |  56 ++
 .../api/actions/indices/exists_alias.rb            |  54 ++
 .../api/actions/indices/exists_template.rb         |  34 +
 .../api/actions/indices/exists_type.rb             |  53 ++
 lib/elasticsearch/api/actions/indices/flush.rb     |  52 ++
 lib/elasticsearch/api/actions/indices/get_alias.rb |  52 ++
 .../api/actions/indices/get_aliases.rb             |  34 +
 .../api/actions/indices/get_field_mapping.rb       |  62 ++
 .../api/actions/indices/get_mapping.rb             |  57 ++
 .../api/actions/indices/get_settings.rb            |  68 ++
 .../api/actions/indices/get_template.rb            |  33 +
 .../api/actions/indices/get_warmer.rb              |  59 ++
 lib/elasticsearch/api/actions/indices/open.rb      |  48 ++
 lib/elasticsearch/api/actions/indices/optimize.rb  |  72 +++
 lib/elasticsearch/api/actions/indices/put_alias.rb |  41 ++
 .../api/actions/indices/put_mapping.rb             |  73 +++
 .../api/actions/indices/put_settings.rb            |  66 ++
 .../api/actions/indices/put_template.rb            |  40 ++
 .../api/actions/indices/put_warmer.rb              |  64 ++
 lib/elasticsearch/api/actions/indices/recovery.rb  |  42 ++
 lib/elasticsearch/api/actions/indices/refresh.rb   |  54 ++
 lib/elasticsearch/api/actions/indices/segments.rb  |  44 ++
 .../api/actions/indices/snapshot_index.rb          |  43 ++
 lib/elasticsearch/api/actions/indices/stats.rb     | 120 ++++
 lib/elasticsearch/api/actions/indices/status.rb    |  56 ++
 .../api/actions/indices/update_aliases.rb          |  48 ++
 .../api/actions/indices/validate_query.rb          |  80 +++
 lib/elasticsearch/api/actions/info.rb              |  19 +
 lib/elasticsearch/api/actions/list_benchmarks.rb   |  29 +
 lib/elasticsearch/api/actions/mget.rb              |  74 +++
 lib/elasticsearch/api/actions/mlt.rb               | 128 ++++
 lib/elasticsearch/api/actions/mpercolate.rb        |  58 ++
 lib/elasticsearch/api/actions/msearch.rb           |  74 +++
 lib/elasticsearch/api/actions/mtermvectors.rb      |  67 ++
 lib/elasticsearch/api/actions/nodes/hot_threads.rb |  46 ++
 lib/elasticsearch/api/actions/nodes/info.rb        |  61 ++
 lib/elasticsearch/api/actions/nodes/shutdown.rb    |  36 ++
 lib/elasticsearch/api/actions/nodes/stats.rb       |  79 +++
 lib/elasticsearch/api/actions/percolate.rb         | 107 ++++
 lib/elasticsearch/api/actions/ping.rb              |  29 +
 lib/elasticsearch/api/actions/scroll.rb            |  61 ++
 lib/elasticsearch/api/actions/search.rb            | 153 +++++
 lib/elasticsearch/api/actions/search_shards.rb     |  41 ++
 lib/elasticsearch/api/actions/search_template.rb   |  61 ++
 lib/elasticsearch/api/actions/snapshot/create.rb   |  48 ++
 .../api/actions/snapshot/create_repository.rb      |  44 ++
 lib/elasticsearch/api/actions/snapshot/delete.rb   |  41 ++
 .../api/actions/snapshot/delete_repository.rb      |  38 ++
 lib/elasticsearch/api/actions/snapshot/get.rb      |  47 ++
 .../api/actions/snapshot/get_repository.rb         |  42 ++
 lib/elasticsearch/api/actions/snapshot/restore.rb  |  53 ++
 lib/elasticsearch/api/actions/snapshot/status.rb   |  40 ++
 lib/elasticsearch/api/actions/suggest.rb           |  46 ++
 lib/elasticsearch/api/actions/termvector.rb        |  77 +++
 lib/elasticsearch/api/actions/update.rb            | 107 ++++
 lib/elasticsearch/api/namespace/cat.rb             |  20 +
 lib/elasticsearch/api/namespace/cluster.rb         |  20 +
 lib/elasticsearch/api/namespace/common.rb          |  27 +
 lib/elasticsearch/api/namespace/indices.rb         |  20 +
 lib/elasticsearch/api/namespace/nodes.rb           |  20 +
 lib/elasticsearch/api/namespace/snapshot.rb        |  20 +
 lib/elasticsearch/api/utils.rb                     | 163 +++++
 lib/elasticsearch/api/version.rb                   |   5 +
 metadata.yml                                       | 705 +++++++++++++++++++++
 test/integration/yaml_test_runner.rb               | 439 +++++++++++++
 test/test_helper.rb                                |  69 ++
 test/unit/abort_benchmark_test.rb                  |  26 +
 test/unit/benchmark_test.rb                        |  26 +
 test/unit/bulk_test.rb                             |  94 +++
 test/unit/cat/aliases_test.rb                      |  26 +
 test/unit/cat/allocation_test.rb                   |  26 +
 test/unit/cat/count_test.rb                        |  26 +
 test/unit/cat/fielddata_test.rb                    |  38 ++
 test/unit/cat/health_test.rb                       |  26 +
 test/unit/cat/help_test.rb                         |  26 +
 test/unit/cat/indices_test.rb                      |  26 +
 test/unit/cat/master_test.rb                       |  26 +
 test/unit/cat/nodes_test.rb                        |  26 +
 test/unit/cat/pending_tasks_test.rb                |  26 +
 test/unit/cat/recovery_test.rb                     |  26 +
 test/unit/cat/shards_test.rb                       |  26 +
 test/unit/cat/thread_pool_test.rb                  |  26 +
 test/unit/clear_scroll_test.rb                     |  38 ++
 test/unit/client_test.rb                           |  31 +
 test/unit/cluster/get_settings_test.rb             |  26 +
 test/unit/cluster/health_test.rb                   |  38 ++
 test/unit/cluster/pending_tasks_test.rb            |  26 +
 test/unit/cluster/put_settings_test.rb             |  26 +
 test/unit/cluster/reroute_test.rb                  |  38 ++
 test/unit/cluster/state_test.rb                    |  46 ++
 test/unit/count_percolate_test.rb                  |  26 +
 test/unit/count_test.rb                            |  46 ++
 test/unit/create_document_test.rb                  |  47 ++
 test/unit/delete_by_query_test.rb                  |  51 ++
 test/unit/delete_document_test.rb                  |  77 +++
 test/unit/exists_document_test.rb                  |  85 +++
 test/unit/explain_document_test.rb                 |  73 +++
 test/unit/get_document_source_test.rb              |  71 +++
 test/unit/get_document_test.rb                     |  77 +++
 test/unit/hashie_test.rb                           |  78 +++
 test/unit/index_document_test.rb                   |  92 +++
 test/unit/indices/analyze_test.rb                  |  76 +++
 test/unit/indices/clear_cache_test.rb              |  54 ++
 test/unit/indices/close_test.rb                    |  51 ++
 test/unit/indices/create_test.rb                   |  51 ++
 test/unit/indices/delete_alias_test.rb             |  47 ++
 test/unit/indices/delete_mapping_test.rb           |  56 ++
 test/unit/indices/delete_template_test.rb          |  43 ++
 test/unit/indices/delete_test.rb                   |  54 ++
 test/unit/indices/delete_warmer_test.rb            |  68 ++
 test/unit/indices/exists_alias_test.rb             |  68 ++
 test/unit/indices/exists_template_test.rb          |  59 ++
 test/unit/indices/exists_test.rb                   |  66 ++
 test/unit/indices/exists_type_test.rb              |  68 ++
 test/unit/indices/flush_test.rb                    |  54 ++
 test/unit/indices/get_alias_test.rb                |  44 ++
 test/unit/indices/get_aliases_test.rb              |  54 ++
 test/unit/indices/get_field_mapping_test.rb        |  44 ++
 test/unit/indices/get_mapping_test.rb              |  62 ++
 test/unit/indices/get_settings_test.rb             |  54 ++
 test/unit/indices/get_template_test.rb             |  36 ++
 test/unit/indices/get_warmer_test.rb               |  44 ++
 test/unit/indices/open_test.rb                     |  51 ++
 test/unit/indices/optimize_test.rb                 |  54 ++
 test/unit/indices/put_alias_test.rb                |  50 ++
 test/unit/indices/put_mapping_test.rb              |  60 ++
 test/unit/indices/put_settings_test.rb             |  68 ++
 test/unit/indices/put_template_test.rb             |  57 ++
 test/unit/indices/put_warmer_test.rb               |  65 ++
 test/unit/indices/recovery_test.rb                 |  26 +
 test/unit/indices/refresh_test.rb                  |  64 ++
 test/unit/indices/segments_test.rb                 |  64 ++
 test/unit/indices/snapshot_index_test.rb           |  64 ++
 test/unit/indices/stats_test.rb                    |  76 +++
 test/unit/indices/status_test.rb                   |  64 ++
 test/unit/indices/update_aliases_test.rb           |  42 ++
 test/unit/indices/validate_query_test.rb           |  84 +++
 test/unit/info_test.rb                             |  26 +
 test/unit/json_builders_test.rb                    |  64 ++
 test/unit/list_benchmarks_test.rb                  |  26 +
 test/unit/mget_test.rb                             |  79 +++
 test/unit/mlt_test.rb                              |  89 +++
 test/unit/mpercolate_test.rb                       |  51 ++
 test/unit/msearch_test.rb                          | 129 ++++
 test/unit/mtermvectors_test.rb                     |  38 ++
 test/unit/nodes/hot_threads_test.rb                |  44 ++
 test/unit/nodes/info_test.rb                       |  66 ++
 test/unit/nodes/shutdown_test.rb                   |  45 ++
 test/unit/nodes/stats_test.rb                      |  65 ++
 test/unit/percolate_test.rb                        |  47 ++
 test/unit/ping_test.rb                             |  48 ++
 test/unit/scroll_test.rb                           |  26 +
 test/unit/search_shards_test.rb                    |  26 +
 test/unit/search_template_test.rb                  |  26 +
 test/unit/search_test.rb                           | 108 ++++
 test/unit/snapshot/create_repository_test.rb       |  38 ++
 test/unit/snapshot/create_test.rb                  |  38 ++
 test/unit/snapshot/delete_repository_test.rb       |  35 +
 test/unit/snapshot/delete_test.rb                  |  38 ++
 test/unit/snapshot/get_repository_test.rb          |  26 +
 test/unit/snapshot/get_test.rb                     |  38 ++
 test/unit/snapshot/restore_test.rb                 |  38 ++
 test/unit/snapshot/status_test.rb                  |  38 ++
 test/unit/suggest_test.rb                          |  64 ++
 test/unit/termvector_test.rb                       |  44 ++
 test/unit/update_document_test.rb                  |  77 +++
 test/unit/utils_test.rb                            | 184 ++++++
 218 files changed, 12749 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d87d4be
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,17 @@
+*.gem
+*.rbc
+.bundle
+.config
+.yardoc
+Gemfile.lock
+InstalledFiles
+_yardoc
+coverage
+doc/
+lib/bundler/man
+pkg
+rdoc
+spec/reports
+test/tmp
+test/version_tmp
+tmp
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..899446d
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,16 @@
+source 'https://rubygems.org'
+
+# Specify your gem's dependencies in elasticsearch-api.gemspec
+gemspec
+
+if File.exists? File.expand_path("../../elasticsearch/elasticsearch.gemspec", __FILE__)
+  gem 'elasticsearch', :path => File.expand_path("../../elasticsearch", __FILE__), :require => false
+end
+
+if File.exists? File.expand_path("../../elasticsearch-transport", __FILE__)
+  gem 'elasticsearch-transport', :path => File.expand_path("../../elasticsearch-transport", __FILE__), :require => true
+end
+
+if File.exists? File.expand_path("../../elasticsearch-extensions", __FILE__)
+  gem 'elasticsearch-extensions', :path => File.expand_path("../../elasticsearch-extensions", __FILE__), :require => false
+end
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..7b9fbe3
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,13 @@
+Copyright (c) 2013 Elasticsearch
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..ab9825d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,174 @@
+# Elasticsearch::API
+
+**This library is part of the [`elasticsearch-ruby`](https://github.com/elasticsearch/elasticsearch-ruby/) package;
+please refer to it, unless you want to use this library standalone.**
+
+----
+
+The `elasticsearch-api` library provides a Ruby implementation of
+the [Elasticsearch](http://elasticsearch.org) REST API.
+
+It does not provide an Elasticsearch client; see the
+[`elasticsearch-transport`](https://github.com/elasticsearch/elasticsearch-ruby/tree/master/elasticsearch-transport)
+library.
+
+The library is compatible with Ruby 1.8.7 or higher.
+
+The library is compatible with Elasticsearch 0.90 and 1.0 -- you have to install and use a matching version, though.
+
+The 1.x versions and the master branch are compatible with **Elasticsearch 1.0** API.
+
+To use the **Elasticsearch 0.90** API, install the **0.4.x** gem version or use the corresponding
+[`0.4`](https://github.com/elasticsearch/elasticsearch-ruby/tree/0.4) branch.
+
+## Installation
+
+Install the package from [Rubygems](https://rubygems.org):
+
+    gem install elasticsearch-api
+
+To use an unreleased version, either add it to your `Gemfile` for [Bundler](http://gembundler.com):
+
+    gem 'elasticsearch-api', git: 'git://github.com/elasticsearch/elasticsearch-ruby.git'
+
+or install it from a source code checkout:
+
+    git clone https://github.com/elasticsearch/elasticsearch-ruby.git
+    cd elasticsearch-ruby/elasticsearch-api
+    bundle install
+    rake install
+
+## Usage
+
+The library is designed as a group of standalone Ruby modules, which can be mixed into a class
+providing connection to Elasticsearch -- an Elasticsearch client.
+
+### Usage with the `elasticsearch` gem
+
+**When you use the client from the [`elasticsearch-ruby`](https://github.com/elasticsearch/elasticsearch-ruby/) package,
+the library modules have been already included**, so you just call the API methods:
+
+```ruby
+require 'elasticsearch'
+
+client = Elasticsearch::Client.new log: true
+
+client.index  index: 'myindex', type: 'mytype', id: 1, body: { title: 'Test' }
+# => {"_index"=>"myindex", ... "created"=>true}
+
+client.search index: 'myindex', body: { query: { match: { title: 'test' } } }
+# => {"took"=>2, ..., "hits"=>{"total":5, ...}}
+```
+
+Full documentation and examples are included as RDoc annotations in the source code
+and available online at <http://rubydoc.info/gems/elasticsearch-api>.
+
+### Usage with a custom client
+
+When you want to mix the library into your own client, it must conform to a following _contract_:
+
+* It responds to a `perform_request(method, path, params, body)` method,
+* the method returns an object with `status`, `body` and `headers` methods.
+
+A simple client could look like this:
+
+```ruby
+require 'multi_json'
+require 'faraday'
+require 'elasticsearch/api'
+
+class MySimpleClient
+  include Elasticsearch::API
+
+  CONNECTION = ::Faraday::Connection.new url: 'http://localhost:9200'
+
+  def perform_request(method, path, params, body)
+    puts "--> #{method.upcase} #{path} #{params} #{body}"
+
+    CONNECTION.run_request \
+      method.downcase.to_sym,
+      path,
+      ( body ? MultiJson.dump(body): nil ),
+      {'Content-Type' => 'application/json'}
+  end
+end
+
+client = MySimpleClient.new
+
+p client.cluster.health
+# --> GET _cluster/health {}
+# => "{"cluster_name":"elasticsearch" ... }"
+
+p client.index index: 'myindex', type: 'mytype', id: 'custom', body: { title: "Indexing from my client" }
+# --> PUT myindex/mytype/custom {} {:title=>"Indexing from my client"}
+# => "{"ok":true, ... }"
+```
+
+### Using JSON Builders
+
+Instead of passing the `:body` argument as a Ruby _Hash_, you can pass it as a _String_, potentially
+taking advantage of JSON builders such as [JBuilder](https://github.com/rails/jbuilder) or
+[Jsonify](https://github.com/bsiggelkow/jsonify):
+
+```ruby
+require 'jbuilder'
+
+query = Jbuilder.encode do |json|
+  json.query do
+    json.match do
+      json.title do
+        json.query    'test 1'
+        json.operator 'and'
+      end
+    end
+  end
+end
+
+client.search index: 'myindex', body: query
+
+# 2013-06-25 09:56:05 +0200: GET http://localhost:9200/myindex/_search [status:200, request:0.015s, query:0.011s]
+# 2013-06-25 09:56:05 +0200: > {"query":{"match":{"title":{"query":"test 1","operator":"and"}}}}
+# ...
+# => {"took"=>21, ..., "hits"=>{"total"=>1, "hits"=>[{ "_source"=>{"title"=>"Test 1", ...}}]}}
+```
+
+### Using Hash Wrappers
+
+For a more comfortable access to response properties, you may wrap it in one of the _Hash_ "object access"
+wrappers, such as [`Hashie::Mash`](https://github.com/intridea/hashie):
+
+```ruby
+require 'hashie'
+
+response = client.search index: 'myindex',
+                         body: {
+                           query: { match: { title: 'test' } },
+                           facets: { tags: { terms: { field: 'tags' } } }
+                         }
+
+mash = Hashie::Mash.new response
+
+mash.hits.hits.first._source.title
+# => 'Test'
+
+mash.facets.tags.terms.first
+# => #<Hashie::Mash count=3 term="z">
+```
+
+## License
+
+This software is licensed under the Apache 2 license, quoted below.
+
+    Copyright (c) 2013 Elasticsearch <http://www.elasticsearch.org>
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
diff --git a/Rakefile b/Rakefile
new file mode 100644
index 0000000..9bc79e0
--- /dev/null
+++ b/Rakefile
@@ -0,0 +1,158 @@
+require "bundler/gem_tasks"
+
+def __current__
+  Pathname( File.expand_path('..', __FILE__) )
+end
+
+def git_specs(command, options={})
+  sh "git --git-dir=#{__current__.join('../support/elasticsearch/.git')} --work-tree=#{__current__.join('../support/elasticsearch')} #{command}", options
+end
+
+task(:default) { system "rake --tasks" }
+task  :test    => 'test:unit'
+
+# ----- Test tasks ------------------------------------------------------------
+
+require 'rake/testtask'
+namespace :test do
+
+  desc "Update the repository with YAML tests"
+  task :update do
+    git_specs "fetch origin --verbose", :verbose => true
+  end
+
+  task :ci_reporter do
+    ENV['CI_REPORTS'] ||= 'tmp/reports'
+    if defined?(RUBY_VERSION) && RUBY_VERSION < '1.9'
+      require 'ci/reporter/rake/test_unit'
+      Rake::Task['ci:setup:testunit'].invoke
+    else
+      require 'ci/reporter/rake/minitest'
+      Rake::Task['ci:setup:minitest'].invoke
+    end
+  end
+
+  Rake::TestTask.new(:unit) do |test|
+    Rake::Task['test:ci_reporter'].invoke if ENV['CI']
+    test.libs << 'lib' << 'test'
+    test.test_files = FileList["test/unit/**/*_test.rb"]
+    # test.verbose = true
+    # test.warning = true
+  end
+
+  desc "Run integration tests"
+  task :integration do
+    require 'elasticsearch'
+
+    branches = `git --git-dir=#{__current__.join('../support/elasticsearch/.git')} --work-tree=#{__current__.join('../support/elasticsearch')} branch --no-color`
+
+    current_branch = branches.
+      split("\n").
+      select { |b| b =~ /^\*/ }.
+      reject { |b| b =~ /no branch|detached/ }.
+      map    { |b| b.gsub(/^\*\s*/, '') }.
+      first
+
+    unless current_branch
+      STDERR.puts "[!] Unable to determine current branch, defaulting to 'master'"
+      current_branch = 'master'
+    end
+
+    # Define the task
+    t = Rake::TestTask.new(:integration) do |test|
+      Rake::Task['test:ci_reporter'].invoke if ENV['CI']
+      test.libs << 'lib' << 'test'
+      test.test_files = FileList["test/integration/yaml_test_runner.rb", "test/integration/**/*_test.rb"]
+    end
+
+    # Check if a test cluster is running
+    begin
+      client = Elasticsearch::Client.new :host => "localhost:#{ENV['TEST_CLUSTER_PORT'] || 9250}"
+      es_version_info = client.info['version']
+      build_hash      = es_version_info['build_hash']
+      cluster_running = true
+    rescue Faraday::Error::ConnectionFailed => e
+      STDERR.puts "[!] Test cluster not running?"
+      cluster_running = false
+    end
+
+    checkout_specs_version = ENV['TEST_NO_CHECKOUT'].nil? ? true : false
+    checkout_build_hash    = ENV['TEST_BUILD_REF'] || build_hash
+    ENV['TEST_BUILD_REF']  = checkout_build_hash
+
+    begin
+      unless checkout_specs_version
+        STDERR.puts '-'*80, "YAML tests: Not switching, TEST_NO_CHECKOUT=y", '-'*80
+      end
+
+      if checkout_specs_version && !checkout_build_hash
+        STDERR.puts "[!] Cannot determine checkout build hash -- server not running or TEST_BUILD_REF not specified"
+        exit(1)
+      end
+
+      if checkout_specs_version && checkout_build_hash
+        # Checkout the commit corresponding to the running server build, or passed TEST_BUILD_REF
+        name = ENV['CI'] ? checkout_build_hash : "[\e[1m#{checkout_build_hash}\e[0m]"
+        STDERR.puts '-'*80, "YAML tests: Switching to #{name} from #{current_branch}", '-'*80
+        git_specs "checkout #{checkout_build_hash} --force --quiet"
+      end
+
+      # Path to the API specs
+      ENV['TEST_REST_API_SPEC'] = __current__.join('../support/elasticsearch/rest-api-spec/test/').to_s
+
+      # Run the task
+      args = [t.ruby_opts_string, t.run_code, t.file_list_string, t.option_list].join(' ')
+
+      ruby args do |ok, status|
+        if !ok && status.respond_to?(:signaled?) && status.signaled?
+          raise SignalException.new(status.termsig)
+        elsif !ok
+          fail "Command failed with status (#{status.exitstatus}): " + "[ruby #{args}]"
+        end
+      end
+
+    ensure
+      git_specs "checkout #{current_branch} --force --quiet" if checkout_specs_version && current_branch
+    end
+  end
+
+  desc "Run unit and integration tests"
+  task :all do
+    Rake::Task['test:ci_reporter'].invoke if ENV['CI']
+    Rake::Task['test:unit'].invoke
+    Rake::Task['test:integration'].invoke
+  end
+
+  namespace :cluster do
+    desc "Start Elasticsearch nodes for tests"
+    task :start do
+      $LOAD_PATH << File.expand_path('../../elasticsearch-transport/lib', __FILE__) << File.expand_path('../test', __FILE__)
+      require 'elasticsearch/extensions/test/cluster'
+      Elasticsearch::Extensions::Test::Cluster.start
+    end
+
+    desc "Stop Elasticsearch nodes for tests"
+    task :stop do
+      $LOAD_PATH << File.expand_path('../../elasticsearch-transport/lib', __FILE__) << File.expand_path('../test', __FILE__)
+      require 'elasticsearch/extensions/test/cluster'
+      Elasticsearch::Extensions::Test::Cluster.stop
+    end
+  end
+end
+
+# ----- Documentation tasks ---------------------------------------------------
+
+require 'yard'
+YARD::Rake::YardocTask.new(:doc) do |t|
+  t.options = %w| --embed-mixins --markup=markdown |
+end
+
+# ----- Code analysis tasks ---------------------------------------------------
+
+if defined?(RUBY_VERSION) && RUBY_VERSION > '1.9'
+  require 'cane/rake_task'
+  Cane::RakeTask.new(:quality) do |cane|
+    cane.abc_max = 15
+    cane.no_style = true
+  end
+end
diff --git a/checksums.yaml.gz b/checksums.yaml.gz
new file mode 100644
index 0000000..1125cb1
Binary files /dev/null and b/checksums.yaml.gz differ
diff --git a/elasticsearch-api.gemspec b/elasticsearch-api.gemspec
new file mode 100644
index 0000000..cd82496
--- /dev/null
+++ b/elasticsearch-api.gemspec
@@ -0,0 +1,69 @@
+# coding: utf-8
+lib = File.expand_path('../lib', __FILE__)
+$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
+require 'elasticsearch/api/version'
+
+Gem::Specification.new do |s|
+  s.name          = "elasticsearch-api"
+  s.version       = Elasticsearch::API::VERSION
+  s.authors       = ["Karel Minarik"]
+  s.email         = ["karel.minarik at elasticsearch.org"]
+  s.summary       = "Ruby API for Elasticsearch."
+  s.homepage      = "https://github.com/elasticsearch/elasticsearch-ruby/tree/master/elasticsearch-api"
+  s.license       = "Apache 2"
+
+  s.files         = `git ls-files`.split($/)
+  s.executables   = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
+  s.test_files    = s.files.grep(%r{^(test|spec|features)/})
+  s.require_paths = ["lib"]
+
+  s.extra_rdoc_files  = [ "README.md", "LICENSE.txt" ]
+  s.rdoc_options      = [ "--charset=UTF-8" ]
+
+  s.add_dependency "multi_json"
+
+  s.add_development_dependency "bundler", "> 1"
+  s.add_development_dependency "rake"
+
+  s.add_development_dependency "elasticsearch"
+  s.add_development_dependency "elasticsearch-transport"
+
+  if defined?(RUBY_VERSION) && RUBY_VERSION > '1.9'
+    s.add_development_dependency "minitest", "~> 4.0"
+    s.add_development_dependency "elasticsearch-extensions"
+  end
+
+  s.add_development_dependency "ansi"
+  s.add_development_dependency "shoulda-context"
+  s.add_development_dependency "mocha"
+  s.add_development_dependency "turn"
+  s.add_development_dependency "yard"
+  s.add_development_dependency "pry"
+  s.add_development_dependency "ci_reporter"
+
+  # Gems for testing integrations
+  s.add_development_dependency "jsonify"
+  s.add_development_dependency "hashie"
+
+  # Prevent unit test failures on Ruby 1.8
+  if defined?(RUBY_VERSION) && RUBY_VERSION < '1.9'
+    s.add_development_dependency "test-unit", '~> 2'
+    s.add_development_dependency "activesupport", '~> 3'
+    s.add_development_dependency "json"
+  end
+
+  if defined?(RUBY_VERSION) && RUBY_VERSION > '1.9'
+    s.add_development_dependency "ruby-prof" unless defined?(JRUBY_VERSION) || defined?(Rubinius)
+    s.add_development_dependency "jbuilder"
+    s.add_development_dependency "escape_utils" unless defined? JRUBY_VERSION
+    s.add_development_dependency "simplecov"
+    s.add_development_dependency "simplecov-rcov"
+    s.add_development_dependency "cane"
+    s.add_development_dependency "require-prof" unless defined?(JRUBY_VERSION) || defined?(Rubinius)
+    s.add_development_dependency "coveralls"
+  end
+
+  s.description = <<-DESC.gsub(/^    /, '')
+    Ruby API for Elasticsearch. See the `elasticsearch` gem for full integration.
+  DESC
+end
diff --git a/lib/elasticsearch-api.rb b/lib/elasticsearch-api.rb
new file mode 100644
index 0000000..df02c43
--- /dev/null
+++ b/lib/elasticsearch-api.rb
@@ -0,0 +1 @@
+require 'elasticsearch/api'
diff --git a/lib/elasticsearch/api.rb b/lib/elasticsearch/api.rb
new file mode 100644
index 0000000..536b17c
--- /dev/null
+++ b/lib/elasticsearch/api.rb
@@ -0,0 +1,41 @@
+require "cgi"
+require "multi_json"
+
+require "elasticsearch/api/version"
+require "elasticsearch/api/namespace/common"
+require "elasticsearch/api/utils"
+
+Dir[ File.expand_path('../api/actions/**/*.rb', __FILE__) ].each   { |f| require f }
+Dir[ File.expand_path('../api/namespace/**/*.rb', __FILE__) ].each { |f| require f }
+
+module Elasticsearch
+  module API
+    COMMON_PARAMS = [
+      :ignore,                        # Client specific parameters
+      :index, :type, :id,             # :index/:type/:id
+      :body,                          # Request body
+      :node_id,                       # Cluster
+      :name,                          # Alias, template, settings, warmer, ...
+      :field                          # Get field mapping
+    ]
+
+    COMMON_QUERY_PARAMS = [
+      :format,                        # Search, Cat, ...
+      :pretty,                        # Pretty-print the response
+      :human                          # Return numeric values in human readable format
+    ]
+
+    # Auto-include all namespaces in the receiver
+    #
+    def self.included(base)
+      base.send :include,
+                Elasticsearch::API::Common,
+                Elasticsearch::API::Actions,
+                Elasticsearch::API::Cluster,
+                Elasticsearch::API::Nodes,
+                Elasticsearch::API::Indices,
+                Elasticsearch::API::Snapshot,
+                Elasticsearch::API::Cat
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/abort_benchmark.rb b/lib/elasticsearch/api/actions/abort_benchmark.rb
new file mode 100644
index 0000000..480875c
--- /dev/null
+++ b/lib/elasticsearch/api/actions/abort_benchmark.rb
@@ -0,0 +1,27 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Abort a running benchmark
+      #
+      # @example
+      #
+      #     client.abort_benchmark name: 'my_benchmark'
+      #
+      # @option arguments [String] :name A benchmark name
+      #
+      # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/search-benchmark.html
+      #
+      def abort_benchmark(arguments={})
+        valid_params = [
+           ]
+        method = 'POST'
+        path   = "_bench/abort/#{arguments[:name]}"
+        params = {}
+        body   = nil
+
+        perform_request(method, path, params, body).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/benchmark.rb b/lib/elasticsearch/api/actions/benchmark.rb
new file mode 100644
index 0000000..76a0fc4
--- /dev/null
+++ b/lib/elasticsearch/api/actions/benchmark.rb
@@ -0,0 +1,62 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Run a single query, or a set of queries, and return statistics on their performance
+      #
+      # @example Return statistics for a single query
+      #
+      #     client.benchmark body: {
+      #       name: 'my_benchmark',
+      #       competitors: [
+      #         {
+      #           name: 'query_1',
+      #           requests: [
+      #             { query: { match: { _all: 'a*' } } }
+      #           ]
+      #         }
+      #       ]
+      #     }
+      #
+      # @example Return statistics for a set of "competing" queries
+      #
+      #     client.benchmark body: {
+      #       name: 'my_benchmark',
+      #       competitors: [
+      #         {
+      #           name: 'query_a',
+      #           requests: [
+      #             { query: { match: { _all: 'a*' } } }
+      #           ]
+      #         },
+      #         {
+      #           name: 'query_b',
+      #           requests: [
+      #             { query: { match: { _all: 'b*' } } }
+      #           ]
+      #         }
+      #       ]
+      #     }
+      #
+      # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string
+      #                                 to perform the operation on all indices
+      # @option arguments [String] :type The name of the document type
+      # @option arguments [Hash] :body The search definition using the Query DSL
+      # @option arguments [Boolean] :verbose Specify whether to return verbose statistics about each iteration
+      #                                      (default: false)
+      #
+      # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/search-benchmark.html
+      #
+      def benchmark(arguments={})
+        valid_params = [
+          :verbose ]
+        method = 'PUT'
+        path   = "_bench"
+        params = Utils.__validate_and_extract_params arguments, valid_params
+        body   = arguments[:body]
+
+        perform_request(method, path, params, body).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/bulk.rb b/lib/elasticsearch/api/actions/bulk.rb
new file mode 100644
index 0000000..c3c4718
--- /dev/null
+++ b/lib/elasticsearch/api/actions/bulk.rb
@@ -0,0 +1,85 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Perform multiple index, delete or update operations in a single request.
+      #
+      # Pass the operations in the `:body` option as an array of hashes, following Elasticsearch conventions.
+      # For operations which take data, pass them as the `:data` option in the operation hash.
+      #
+      # @example Perform three operations in a single request, passing actions and data as an array of hashes
+      #
+      #     client.bulk body: [
+      #       { index: { _index: 'myindex', _type: 'mytype', _id: 1 } },
+      #       { title: 'foo' },
+      #
+      #       { index: { _index: 'myindex', _type: 'mytype', _id: 2 } },
+      #       { title: 'foo' },
+      #
+      #       { delete: { _index: 'myindex', _type: 'mytype', _id: 3  } }
+      #     ]
+      # @example Perform three operations in a single request, passing data in the `:data` option
+      #
+      #     client.bulk body: [
+      #       { index:  { _index: 'myindex', _type: 'mytype', _id: 1, data: { title: 'foo' } } },
+      #       { update: { _index: 'myindex', _type: 'mytype', _id: 2, data: { doc: { title: 'foo' } } } },
+      #       { delete: { _index: 'myindex', _type: 'mytype', _id: 3  } }
+      #     ]
+      #
+      # @example Perform a script-based bulk update, passing scripts in the `:data` option
+      #
+      #     client.bulk body: [
+      #       { update: { _index: 'myindex', _type: 'mytype', _id: 1,
+      #                  data: {
+      #                   script: "ctx._source.counter += value",
+      #                   lang: 'js',
+      #                   params: { value: 1 }, upsert: { counter: 0 } }
+      #                 }},
+      #       { update: { _index: 'myindex', _type: 'mytype', _id: 2,
+      #                  data: {
+      #                   script: "ctx._source.counter += value",
+      #                   lang: 'js',
+      #                   params: { value: 42 }, upsert: { counter: 0 } }
+      #                  }}
+      #
+      #     ]
+      #
+      # @option arguments [String]      :index Default index for items which don't provide one
+      # @option arguments [String]      :type Default document type for items which don't provide one
+      # @option arguments [Array<Hash>] :body An array of operations to perform, each operation is a Hash
+      # @option arguments [String]  :consistency Explicit write consistency setting for the operation
+      #                             (options: one, quorum, all)
+      # @option arguments [Boolean] :refresh Refresh the index after performing the operation
+      # @option arguments [String]  :replication Explicitely set the replication type (options: sync, async)
+      # @option arguments [String]  :type Default document type for items which don't provide one
+      # @option arguments [Time]    :timeout Explicit operation timeout
+      #
+      # @return [Hash] Deserialized Elasticsearch response
+      #
+      # @see http://elasticsearch.org/guide/reference/api/bulk/
+      #
+      def bulk(arguments={})
+        valid_params = [
+          :consistency,
+          :refresh,
+          :replication,
+          :type,
+          :timeout ]
+
+        method = 'POST'
+        path   = Utils.__pathify Utils.__escape(arguments[:index]), Utils.__escape(arguments[:type]), '_bulk'
+
+        params = Utils.__validate_and_extract_params arguments, valid_params
+        body   = arguments[:body]
+
+        if body.is_a? Array
+          payload = Utils.__bulkify(body)
+        else
+          payload = body
+        end
+
+        perform_request(method, path, params, payload).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/cat/aliases.rb b/lib/elasticsearch/api/actions/cat/aliases.rb
new file mode 100644
index 0000000..97f677e
--- /dev/null
+++ b/lib/elasticsearch/api/actions/cat/aliases.rb
@@ -0,0 +1,67 @@
+module Elasticsearch
+  module API
+    module Cat
+      module Actions
+
+        # Returns information about aliases, including associated routing values and filters.
+        #
+        # @example Display all aliases in the cluster
+        #
+        #     puts client.cat.aliases
+        #
+        # @example Display indices for the 'year-2013' alias
+        #
+        #     puts client.cat.aliases name: 'year-2013'
+        #
+        # @example Display header names in the output
+        #
+        #     puts client.cat.aliases v: true
+        #
+        # @example Return only the 'alias' and 'index' columns
+        #
+        #     puts client.cat.aliases h: ['alias', 'index']
+        #
+        # @example Return only the 'alias' and 'index' columns, using short names
+        #
+        #     puts client.cat.aliases h: 'a,i'
+        #
+        # @example Return the information as Ruby objects
+        #
+        #     client.cat.aliases format: 'json'
+        #
+        # @option arguments [List] :name A comma-separated list of alias names to return
+        # @option arguments [List] :h Comma-separated list of column names to display -- see the `help` argument
+        # @option arguments [Boolean] :v Display column headers as part of the output
+        # @option arguments [String] :format The output format. Options: 'text', 'json'; default: 'text'
+        # @option arguments [Boolean] :help Return information about headers
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+        #                                    (default: false)
+        # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/cat-aliases.html
+        #
+        def aliases(arguments={})
+          valid_params = [
+            :local,
+            :master_timeout,
+            :h,
+            :help,
+            :v ]
+
+          name = arguments.delete(:name)
+
+          method = 'GET'
+
+          path   = Utils.__pathify '_cat/aliases', Utils.__listify(name)
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          params[:h] = Utils.__listify(params[:h]) if params[:h]
+
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/cat/allocation.rb b/lib/elasticsearch/api/actions/cat/allocation.rb
new file mode 100644
index 0000000..1e8814c
--- /dev/null
+++ b/lib/elasticsearch/api/actions/cat/allocation.rb
@@ -0,0 +1,69 @@
+module Elasticsearch
+  module API
+    module Cat
+      module Actions
+
+        # Return shard allocation information
+        #
+        # @example Display allocation for all nodes in the cluster
+        #
+        #     puts client.cat.allocation
+        #
+        # @example Display allocation for node with name 'node-1'
+        #
+        #     puts client.cat.allocation node_id: 'node-1'
+        #
+        # @example Display header names in the output
+        #
+        #     puts client.cat.allocation v: true
+        #
+        # @example Display only specific columns in the output (see the `help` parameter)
+        #
+        #     puts client.cat.allocation h: ['node', 'shards', 'disk.percent']
+        #
+        # @example Display only specific columns in the output, using the short names
+        #
+        #     puts client.cat.allocation h: 'n,s,dp'
+        #
+        # @example Return the information as Ruby objects
+        #
+        #     client.cat.allocation format: 'json'
+        #
+        # @option arguments [List] :node_id A comma-separated list of node IDs or names to limit the returned information
+        # @option arguments [String] :bytes The unit in which to display byte values (options: b, k, m, g)
+        # @option arguments [List] :h Comma-separated list of column names to display -- see the `help` argument
+        # @option arguments [Boolean] :v Display column headers as part of the output
+        # @option arguments [String] :format The output format. Options: 'text', 'json'; default: 'text'
+        # @option arguments [Boolean] :help Return information about headers
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+        #                                    (default: false)
+        # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/cat-allocation.html
+        #
+        def allocation(arguments={})
+          valid_params = [
+            :bytes,
+            :local,
+            :master_timeout,
+            :h,
+            :help,
+            :v ]
+
+          node_id = arguments.delete(:node_id)
+
+          method = 'GET'
+
+          path   = Utils.__pathify '_cat/allocation', Utils.__listify(node_id)
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          params[:h] = Utils.__listify(params[:h]) if params[:h]
+
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/cat/count.rb b/lib/elasticsearch/api/actions/cat/count.rb
new file mode 100644
index 0000000..c46b8c2
--- /dev/null
+++ b/lib/elasticsearch/api/actions/cat/count.rb
@@ -0,0 +1,63 @@
+module Elasticsearch
+  module API
+    module Cat
+      module Actions
+
+        # Return document counts for the entire cluster or specific indices
+        #
+        # @example Display number of documents in the cluster
+        #
+        #     puts client.cat.count
+        #
+        # @example Display number of documents in an index
+        #
+        #     puts client.cat.count index: 'index-a'
+        #
+        # @example Display number of documents in a list of indices
+        #
+        #     puts client.cat.count index: ['index-a', 'index-b']
+        #
+        # @example Display header names in the output
+        #
+        #     puts client.cat.count v: true
+        #
+        # @example Return the information as Ruby objects
+        #
+        #     client.cat.count format: 'json'
+        #
+        # @option arguments [List] :index A comma-separated list of index names to limit the returned information
+        # @option arguments [List] :h Comma-separated list of column names to display -- see the `help` argument
+        # @option arguments [Boolean] :v Display column headers as part of the output
+        # @option arguments [String] :format The output format. Options: 'text', 'json'; default: 'text'
+        # @option arguments [Boolean] :help Return information about headers
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+        #                                    (default: false)
+        # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/cat-count.html
+        #
+        def count(arguments={})
+          valid_params = [
+            :local,
+            :master_timeout,
+            :h,
+            :help,
+            :v ]
+
+          index = arguments.delete(:index)
+
+          method = 'GET'
+
+          path   = Utils.__pathify '_cat/count', Utils.__listify(index)
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          params[:h] = Utils.__listify(params[:h]) if params[:h]
+
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/cat/fielddata.rb b/lib/elasticsearch/api/actions/cat/fielddata.rb
new file mode 100644
index 0000000..d63a46e
--- /dev/null
+++ b/lib/elasticsearch/api/actions/cat/fielddata.rb
@@ -0,0 +1,49 @@
+module Elasticsearch
+  module API
+    module Cat
+      module Actions
+
+        # Return information about field data usage across the cluster
+        #
+        # @example Return the total size of field data
+        #
+        #     client.cat.fielddata
+        #
+        # @example Return both the total size and size for specific fields
+        #
+        #     client.cat.fielddata fields: 'title,body'
+        #
+        # @option arguments [List] :fields A comma-separated list of fields to include in the output
+        # @option arguments [String] :bytes The unit in which to display byte values (options: b, k, m, g)
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+        #                                   (default: false)
+        # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node
+        # @option arguments [List] :h Comma-separated list of column names to display
+        # @option arguments [Boolean] :help Return help information
+        # @option arguments [Boolean] :v Verbose mode. Display column headers
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/cat-fielddata.html
+        #
+        def fielddata(arguments={})
+          valid_params = [
+            :bytes,
+            :local,
+            :master_timeout,
+            :h,
+            :help,
+            :v,
+            :fields ]
+
+          fields = arguments.delete(:fields)
+
+          method = 'GET'
+          path   = Utils.__pathify "_cat/fielddata", Utils.__listify(fields)
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/cat/health.rb b/lib/elasticsearch/api/actions/cat/health.rb
new file mode 100644
index 0000000..95170fd
--- /dev/null
+++ b/lib/elasticsearch/api/actions/cat/health.rb
@@ -0,0 +1,51 @@
+module Elasticsearch
+  module API
+    module Cat
+      module Actions
+
+        # Display a terse version of the {Elasticsearch::API::Cluster::Actions#health} API output
+        #
+        # @example Display cluster health
+        #
+        #     puts client.cat.health
+        #
+        # @example Display header names in the output
+        #
+        #     puts client.cat.health v: true
+        #
+        # @example Return the information as Ruby objects
+        #
+        #     client.cat.health format: 'json'
+        #
+        # @option arguments [Boolean] :ts Whether to display timestamp information
+        # @option arguments [List] :h Comma-separated list of column names to display -- see the `help` argument
+        # @option arguments [Boolean] :v Display column headers as part of the output
+        # @option arguments [String] :format The output format. Options: 'text', 'json'; default: 'text'
+        # @option arguments [Boolean] :help Return information about headers
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+        #                                    (default: false)
+        # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/cat-health.html
+        #
+        def health(arguments={})
+          valid_params = [
+            :local,
+            :master_timeout,
+            :h,
+            :help,
+            :ts,
+            :v ]
+
+          method = 'GET'
+          path   = "_cat/health"
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          params[:h] = Utils.__listify(params[:h]) if params[:h]
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/cat/help.rb b/lib/elasticsearch/api/actions/cat/help.rb
new file mode 100644
index 0000000..04a448e
--- /dev/null
+++ b/lib/elasticsearch/api/actions/cat/help.rb
@@ -0,0 +1,25 @@
+module Elasticsearch
+  module API
+    module Cat
+      module Actions
+
+        # Help information for the Cat API
+        #
+        # @option arguments [Boolean] :help Return help information
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/cat.html
+        #
+        def help(arguments={})
+          valid_params = [
+            :help ]
+          method = 'GET'
+          path   = "_cat"
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/cat/indices.rb b/lib/elasticsearch/api/actions/cat/indices.rb
new file mode 100644
index 0000000..2a6ce33
--- /dev/null
+++ b/lib/elasticsearch/api/actions/cat/indices.rb
@@ -0,0 +1,77 @@
+module Elasticsearch
+  module API
+    module Cat
+      module Actions
+
+        # Return the most important statistics about indices, across the cluster nodes
+        #
+        # Use the `help` parameter to display available statistics.
+        #
+        # @example Display information for all indices
+        #
+        #     puts client.cat.indices
+        #
+        # @example Display information for a specific index
+        #
+        #     puts client.cat.indices index: 'index-a'
+        #
+        # @example Display information for indices matching a pattern
+        #
+        #     puts client.cat.indices index: 'index-*'
+        #
+        # @example Display header names in the output
+        #
+        #     puts client.cat.indices v: true
+        #
+        # @example Display only specific columns in the output (see the `help` parameter)
+        #
+        #     puts client.cat.indices h: ['index', 'docs.count', 'fielddata.memory_size', 'filter_cache.memory_size']
+        #
+        # @example Display only specific columns in the output, using the short names
+        #
+        #     puts client.cat.indices h: 'i,dc,ss,mt', v: true
+        #
+        # @example Return the information as Ruby objects
+        #
+        #     client.cat.indices format: 'json'
+        #
+        # @option arguments [List] :index A comma-separated list of index names to limit the returned information
+        # @option arguments [String] :bytes The unit in which to display byte values (options: b, k, m, g)
+        # @option arguments [Boolean] :pri Limit the returned information on primary shards only (default: false)
+        # @option arguments [List] :h Comma-separated list of column names to display -- see the `help` argument
+        # @option arguments [Boolean] :v Display column headers as part of the output
+        # @option arguments [String] :format The output format. Options: 'text', 'json'; default: 'text'
+        # @option arguments [Boolean] :help Return information about headers
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+        #                                    (default: false)
+        # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/cat-indices.html
+        #
+        def indices(arguments={})
+          valid_params = [
+            :bytes,
+            :local,
+            :master_timeout,
+            :h,
+            :help,
+            :pri,
+            :v ]
+
+          index = arguments.delete(:index)
+
+          method = 'GET'
+
+          path   = Utils.__pathify '_cat/indices', Utils.__listify(index)
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          params[:h] = Utils.__listify(params[:h]) if params[:h]
+
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/cat/master.rb b/lib/elasticsearch/api/actions/cat/master.rb
new file mode 100644
index 0000000..6a2ec35
--- /dev/null
+++ b/lib/elasticsearch/api/actions/cat/master.rb
@@ -0,0 +1,48 @@
+module Elasticsearch
+  module API
+    module Cat
+      module Actions
+
+        # Display basic information about the master node
+        #
+        # @example
+        #
+        #     puts client.cat.master
+        #
+        # @example Display header names in the output
+        #
+        #     puts client.cat.master v: true
+        #
+        # @example Return the information as Ruby objects
+        #
+        #     client.cat.master format: 'json'
+        #
+        # @option arguments [List] :h Comma-separated list of column names to display -- see the `help` argument
+        # @option arguments [Boolean] :v Display column headers as part of the output
+        # @option arguments [String] :format The output format. Options: 'text', 'json'; default: 'text'
+        # @option arguments [Boolean] :help Return information about headers
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+        #                                    (default: false)
+        # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/cat-master.html
+        #
+        def master(arguments={})
+          valid_params = [
+            :local,
+            :master_timeout,
+            :h,
+            :help,
+            :v ]
+
+          method = 'GET'
+          path   = "_cat/master"
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/cat/nodes.rb b/lib/elasticsearch/api/actions/cat/nodes.rb
new file mode 100644
index 0000000..df197fa
--- /dev/null
+++ b/lib/elasticsearch/api/actions/cat/nodes.rb
@@ -0,0 +1,59 @@
+module Elasticsearch
+  module API
+    module Cat
+      module Actions
+
+        # Display information about cluster topology and nodes statistics
+        #
+        # @example Display basic information about nodes in the cluster (host, node name, memory usage, master, etc.)
+        #
+        #     puts client.cat.nodes
+        #
+        # @example Display header names in the output
+        #
+        #     puts client.cat.nodes v: true
+        #
+        # @example Display only specific columns in the output (see the `help` parameter)
+        #
+        #     puts client.cat.nodes h: %w(name version jdk disk.avail heap.percent load merges.total_time), v: true
+        #
+        # @example Display only specific columns in the output, using the short names
+        #
+        #     puts client.cat.nodes h: 'n,v,j,d,hp,l,mtt', v: true
+        #
+        # @example Return the information as Ruby objects
+        #
+        #     client.cat.nodes format: 'json'
+        #
+        # @option arguments [List] :h Comma-separated list of column names to display -- see the `help` argument
+        # @option arguments [Boolean] :v Display column headers as part of the output
+        # @option arguments [String] :format The output format. Options: 'text', 'json'; default: 'text'
+        # @option arguments [Boolean] :help Return information about headers
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+        #                                    (default: false)
+        # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/cat-nodes.html
+        #
+        def nodes(arguments={})
+          valid_params = [
+            :local,
+            :master_timeout,
+            :h,
+            :help,
+            :v ]
+
+          method = 'GET'
+          path   = "_cat/nodes"
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          params[:h] = Utils.__listify(params[:h]) if params[:h]
+
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/cat/pending_tasks.rb b/lib/elasticsearch/api/actions/cat/pending_tasks.rb
new file mode 100644
index 0000000..d8c8e34
--- /dev/null
+++ b/lib/elasticsearch/api/actions/cat/pending_tasks.rb
@@ -0,0 +1,49 @@
+module Elasticsearch
+  module API
+    module Cat
+      module Actions
+
+        # Display the information from the {Cluster::Actions#pending_tasks} API in a tabular format
+        #
+        # @example
+        #
+        #     puts client.cat.pending_tasks
+        #
+        # @example Display header names in the output
+        #
+        #     puts client.cat.pending_tasks v: true
+        #
+        # @example Return the information as Ruby objects
+        #
+        #     client.cat.pending_tasks format: 'json'
+        #
+        # @option arguments [List] :h Comma-separated list of column names to display -- see the `help` argument
+        # @option arguments [Boolean] :v Display column headers as part of the output
+        # @option arguments [String] :format The output format. Options: 'text', 'json'; default: 'text'
+        # @option arguments [Boolean] :help Return information about headers
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+        #                                    (default: false)
+        # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/cat-pending-tasks.html
+        #
+        def pending_tasks(arguments={})
+          valid_params = [
+            :local,
+            :master_timeout,
+            :h,
+            :help,
+            :v ]
+
+          method = 'GET'
+          path   = "_cat/pending_tasks"
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          params[:h] = Utils.__listify(params[:h]) if params[:h]
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/cat/recovery.rb b/lib/elasticsearch/api/actions/cat/recovery.rb
new file mode 100644
index 0000000..11b08f5
--- /dev/null
+++ b/lib/elasticsearch/api/actions/cat/recovery.rb
@@ -0,0 +1,73 @@
+module Elasticsearch
+  module API
+    module Cat
+      module Actions
+
+        # Display information about the recovery process (allocating shards)
+        #
+        # @example Display information for all indices
+        #
+        #     puts client.cat.recovery
+        #
+        # @example Display information for a specific index
+        #
+        #     puts client.cat.recovery index: 'index-a'
+        #
+        # @example Display information for indices matching a pattern
+        #
+        #     puts client.cat.recovery index: 'index-*'
+        #
+        # @example Display header names in the output
+        #
+        #     puts client.cat.recovery v: true
+        #
+        # @example Display only specific columns in the output (see the `help` parameter)
+        #
+        #     puts client.cat.recovery h: ['node', 'index', 'shard', 'percent']
+        #
+        # @example Display only specific columns in the output, using the short names
+        #
+        #     puts client.cat.recovery h: 'n,i,s,per'
+        #
+        # @example Return the information as Ruby objects
+        #
+        #     client.cat.recovery format: 'json'
+        #
+        # @option arguments [List] :index A comma-separated list of index names to limit the returned information
+        # @option arguments [String] :bytes The unit in which to display byte values (options: b, k, m, g)
+        # @option arguments [List] :h Comma-separated list of column names to display -- see the `help` argument
+        # @option arguments [Boolean] :v Display column headers as part of the output
+        # @option arguments [String] :format The output format. Options: 'text', 'json'; default: 'text'
+        # @option arguments [Boolean] :help Return information about headers
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+        #                                    (default: false)
+        # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/cat-recovery.html
+        #
+        def recovery(arguments={})
+          valid_params = [
+            :bytes,
+            :local,
+            :master_timeout,
+            :h,
+            :help,
+            :v ]
+
+          index = arguments.delete(:index)
+
+          method = 'GET'
+
+          path   = Utils.__pathify '_cat/recovery', Utils.__listify(index)
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          params[:h] = Utils.__listify(params[:h]) if params[:h]
+
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/cat/shards.rb b/lib/elasticsearch/api/actions/cat/shards.rb
new file mode 100644
index 0000000..f7e72b3
--- /dev/null
+++ b/lib/elasticsearch/api/actions/cat/shards.rb
@@ -0,0 +1,72 @@
+module Elasticsearch
+  module API
+    module Cat
+      module Actions
+
+        # Display shard allocation across nodes
+        #
+        # @example Display information for all indices
+        #
+        #     puts client.cat.shards
+        #
+        # @example Display information for a specific index
+        #
+        #     puts client.cat.shards index: 'index-a'
+        #
+        # @example Display information for a list of indices
+        #
+        #     puts client.cat.shards index: ['index-a', 'index-b']
+        #
+        # @example Display header names in the output
+        #
+        #     puts client.cat.shards v: true
+        #
+        # @example Display only specific columns in the output (see the `help` parameter)
+        #
+        #     puts client.cat.shards h: ['node', 'index', 'shard', 'prirep', 'docs', 'store', 'merges.total']
+        #
+        # @example Display only specific columns in the output, using the short names
+        #
+        #     puts client.cat.shards h: 'n,i,s,p,d,sto,mt'
+        #
+        # @example Return the information as Ruby objects
+        #
+        #     client.cat.shards format: 'json'
+        #
+        # @option arguments [List] :index A comma-separated list of index names to limit the returned information
+        # @option arguments [String] :bytes The unit in which to display byte values (options: b, k, m, g)
+        # @option arguments [List] :h Comma-separated list of column names to display -- see the `help` argument
+        # @option arguments [Boolean] :v Display column headers as part of the output
+        # @option arguments [String] :format The output format. Options: 'text', 'json'; default: 'text'
+        # @option arguments [Boolean] :help Return information about headers
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+        #                                    (default: false)
+        # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/cat-shards.html
+        #
+        def shards(arguments={})
+          valid_params = [
+            :local,
+            :master_timeout,
+            :h,
+            :help,
+            :v ]
+
+          index = arguments.delete(:index)
+
+          method = 'GET'
+
+          path   = Utils.__pathify '_cat/shards', Utils.__listify(index)
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          params[:h] = Utils.__listify(params[:h]) if params[:h]
+
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/cat/thread_pool.rb b/lib/elasticsearch/api/actions/cat/thread_pool.rb
new file mode 100644
index 0000000..fdf2e2e
--- /dev/null
+++ b/lib/elasticsearch/api/actions/cat/thread_pool.rb
@@ -0,0 +1,56 @@
+module Elasticsearch
+  module API
+    module Cat
+      module Actions
+
+        # Display thread pool statistics across nodes (use the `help` parameter to display a list
+        # of avaialable thread pools)
+        #
+        # @example Display information about all thread pools across nodes
+        #
+        #     puts client.cat.thread_pool
+        #
+        # @example Display header names in the output
+        #
+        #     puts client.cat.thread_pool v: true
+        #
+        # @example Display information about the indexing thread pool
+        #
+        #     puts client.cat.thread_pool h: %w(h ip index.active index.size index.queue index.rejected), v: true
+        #
+        # @example Display information about the indexing and search threads, using the short names
+        #
+        #     puts client.cat.thread_pool h: 'host,ia,is,iq,ir,sa,ss,sq,sr', v: true
+        #
+        # @option arguments [Boolean] :full_id Display the complete node ID
+        # @option arguments [List] :h Comma-separated list of column names to display -- see the `help` argument
+        # @option arguments [Boolean] :v Display column headers as part of the output
+        # @option arguments [String] :format The output format. Options: 'text', 'json'; default: 'text'
+        # @option arguments [Boolean] :help Return information about headers
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+        #                                    (default: false)
+        # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/cat-thread-pool.html
+        #
+        def thread_pool(arguments={})
+          valid_params = [
+            :full_id,
+            :local,
+            :master_timeout,
+            :h,
+            :help,
+            :v ]
+
+          method = 'GET'
+          path   = "_cat/thread_pool"
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          params[:h] = Utils.__listify(params[:h]) if params[:h]
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/clear_scroll.rb b/lib/elasticsearch/api/actions/clear_scroll.rb
new file mode 100644
index 0000000..69d84a7
--- /dev/null
+++ b/lib/elasticsearch/api/actions/clear_scroll.rb
@@ -0,0 +1,24 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Abort a particular scroll search and clear all the resources associated with it.
+      #
+      # @option arguments [List] :scroll_id A comma-separated list of scroll IDs to clear;
+      #                                     use `_all` clear all scroll search contexts
+      #
+      # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-search-type.html#clear-scroll
+      #
+      def clear_scroll(arguments={})
+        raise ArgumentError, "Required argument 'scroll_id' missing" unless arguments[:scroll_id]
+
+        method = 'DELETE'
+        path   = Utils.__pathify '_search/scroll', Utils.__listify(arguments[:scroll_id])
+        params = {}
+        body   = nil
+
+        perform_request(method, path, params, body).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/cluster/get_settings.rb b/lib/elasticsearch/api/actions/cluster/get_settings.rb
new file mode 100644
index 0000000..1a35eb8
--- /dev/null
+++ b/lib/elasticsearch/api/actions/cluster/get_settings.rb
@@ -0,0 +1,31 @@
+module Elasticsearch
+  module API
+    module Cluster
+      module Actions
+
+        # Get the cluster settings (previously set with {Cluster::Actions#put_settings})
+        #
+        # @example Get cluster settings
+        #
+        #     client.cluster.get_settings
+        #
+        # @option arguments [Boolean] :flat_settings Return settings in flat format (default: false)
+        #
+        # @see http://elasticsearch.org/guide/reference/api/admin-cluster-update-settings/
+        #
+        def get_settings(arguments={})
+          valid_params = [
+            :flat_settings
+          ]
+
+          method = 'GET'
+          path   = "_cluster/settings"
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/cluster/health.rb b/lib/elasticsearch/api/actions/cluster/health.rb
new file mode 100644
index 0000000..47acfd6
--- /dev/null
+++ b/lib/elasticsearch/api/actions/cluster/health.rb
@@ -0,0 +1,54 @@
+module Elasticsearch
+  module API
+    module Cluster
+      module Actions
+
+        # Returns information about cluster "health".
+        #
+        # @example Get the cluster health information
+        #
+        #     client.cluster.health
+        #
+        # @example Block the request until the cluster is in the "yellow" state
+        #
+        #     client.cluster.health wait_for_status: 'yellow'
+        #
+        # @option arguments [String] :index Limit the information returned to a specific index
+        # @option arguments [String] :level Specify the level of detail for returned information
+        #                                   (options: cluster, indices, shards)
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+        #                                    (default: false)
+        # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node
+        # @option arguments [Time] :timeout Explicit operation timeout
+        # @option arguments [Number] :wait_for_active_shards Wait until the specified number of shards is active
+        # @option arguments [Number] :wait_for_nodes Wait until the specified number of nodes is available
+        # @option arguments [Number] :wait_for_relocating_shards Wait until the specified number of relocating
+        #                                                        shards is finished
+        # @option arguments [String] :wait_for_status Wait until cluster is in a specific state
+        #                                             (options: green, yellow, red)
+        #
+        # @see http://elasticsearch.org/guide/reference/api/admin-cluster-health/
+        #
+        def health(arguments={})
+          valid_params = [
+            :level,
+            :local,
+            :master_timeout,
+            :timeout,
+            :wait_for_active_shards,
+            :wait_for_nodes,
+            :wait_for_relocating_shards,
+            :wait_for_status ]
+
+          method = 'GET'
+          path   = "_cluster/health"
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/cluster/pending_tasks.rb b/lib/elasticsearch/api/actions/cluster/pending_tasks.rb
new file mode 100644
index 0000000..42357ce
--- /dev/null
+++ b/lib/elasticsearch/api/actions/cluster/pending_tasks.rb
@@ -0,0 +1,33 @@
+module Elasticsearch
+  module API
+    module Cluster
+      module Actions
+
+        # Returns a list of any cluster-level changes (e.g. create index, update mapping, allocate or fail shard)
+        # which have not yet been executed and are queued up.
+        #
+        # @example Get a list of currently queued up tasks in the cluster
+        #
+        #     client.cluster.pending_tasks
+        #
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+        #                                    (default: false)
+        # @option arguments [Time] :master_timeout Specify timeout for connection to master
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/cluster-pending.html
+        #
+        def pending_tasks(arguments={})
+          valid_params = [
+            :local,
+            :master_timeout ]
+          method = 'GET'
+          path   = "/_cluster/pending_tasks"
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/cluster/put_settings.rb b/lib/elasticsearch/api/actions/cluster/put_settings.rb
new file mode 100644
index 0000000..4114f80
--- /dev/null
+++ b/lib/elasticsearch/api/actions/cluster/put_settings.rb
@@ -0,0 +1,30 @@
+module Elasticsearch
+  module API
+    module Cluster
+      module Actions
+
+        # Update cluster settings.
+        #
+        # @example Disable shard allocation in the cluster until restart
+        #
+        #     client.cluster.put_settings body: { transient: { 'cluster.routing.allocation.disable_allocation' => true } }
+        #
+        # @option arguments [Hash] :body The settings to be updated. Can be either `transient` or `persistent`
+        #                                (survives cluster restart).
+        #
+        # @see http://elasticsearch.org/guide/reference/api/admin-cluster-update-settings/
+        #
+        def put_settings(arguments={})
+          valid_params = [ :flat_settings ]
+
+          method = 'PUT'
+          path   = "_cluster/settings"
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = arguments[:body] || {}
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/cluster/reroute.rb b/lib/elasticsearch/api/actions/cluster/reroute.rb
new file mode 100644
index 0000000..c4d61f2
--- /dev/null
+++ b/lib/elasticsearch/api/actions/cluster/reroute.rb
@@ -0,0 +1,43 @@
+module Elasticsearch
+  module API
+    module Cluster
+      module Actions
+
+        # Perform manual shard allocation in the cluster.
+        #
+        # Pass the operations you want to perform in the `:body` option. Use the `dry_run` option to
+        # evaluate the result of operations without actually performing them.
+        #
+        # @example Move shard `0` of index `myindex` from node named _Node1_ to node named _Node2_
+        #
+        #     client.cluster.reroute body: {
+        #       commands: [
+        #         { move: { index: 'myindex', shard: 0, from_node: 'Node1', to_node: 'Node2' } }
+        #       ]
+        #     }
+        #
+        # @note If you want to explicitely set the shard allocation to a certain node, you might
+        #       want to look at the `allocation.*` cluster settings.
+        #
+        # @option arguments [Hash] :body The definition of `commands` to perform (`move`, `cancel`, `allocate`)
+        # @option arguments [Boolean] :dry_run Simulate the operation only and return the resulting state
+        # @option arguments [Boolean] :explain Return an explanation for why the commands can or cannot be executed
+        # @option arguments [Boolean] :filter_metadata Don't return cluster state metadata (default: false)
+        #
+        # @see http://elasticsearch.org/guide/reference/api/admin-cluster-reroute/
+        #
+        def reroute(arguments={})
+          valid_params = [ :dry_run, :explain, :filter_metadata ]
+
+          method = 'POST'
+          path   = "_cluster/reroute"
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = arguments[:body] || {}
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/cluster/state.rb b/lib/elasticsearch/api/actions/cluster/state.rb
new file mode 100644
index 0000000..4602cd6
--- /dev/null
+++ b/lib/elasticsearch/api/actions/cluster/state.rb
@@ -0,0 +1,57 @@
+module Elasticsearch
+  module API
+    module Cluster
+      module Actions
+
+        # Get information about the cluster state (indices settings, allocations, etc)
+        #
+        # @example
+        #
+        #     client.cluster.state
+        #
+        # @option arguments [List] :index A comma-separated list of index names; use `_all` or omit to
+        #                                 perform the operation on all indices
+        # @option arguments [List] :metric Limit the information returned to the specified metrics
+        #                                 (options: _all, blocks, index_templates, metadata, nodes, routing_table,
+        #                                  master_node, version)
+        # @option arguments [List] :index_templates A comma separated list to return specific index templates when
+        #                                           returning metadata
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+        #                                    (default: false)
+        # @option arguments [Time] :master_timeout Specify timeout for connection to master
+        #
+        # @see http://elasticsearch.org/guide/reference/api/admin-cluster-state/
+        #
+        def state(arguments={})
+          arguments = arguments.clone
+          index     = arguments.delete(:index)
+          metric    = arguments.delete(:metric)
+
+          valid_params = [
+            :metric,
+            :index_templates,
+            :local,
+            :master_timeout,
+            :flat_settings ]
+
+          method = 'GET'
+          path   = "_cluster/state"
+
+          path   = Utils.__pathify '_cluster/state',
+                                   Utils.__listify(metric),
+                                   Utils.__listify(index)
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+
+          [:index_templates].each do |key|
+            params[key] = Utils.__listify(params[key]) if params[key]
+          end
+
+          body = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/count.rb b/lib/elasticsearch/api/actions/count.rb
new file mode 100644
index 0000000..1c5299b
--- /dev/null
+++ b/lib/elasticsearch/api/actions/count.rb
@@ -0,0 +1,58 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Get the number of documents for the cluster, index, type, or a query.
+      #
+      # @example Get the number of all documents in the cluster
+      #
+      #     client.count
+      #
+      # @example Get the number of documents in a specified index
+      #
+      #     client.count index: 'myindex'
+      #
+      # @example Get the number of documents matching a specific query
+      #
+      #     index: 'my_index', body: { filtered: { filter: { terms: { foo: ['bar'] } } } }
+      #
+      # @option arguments [List] :index A comma-separated list of indices to restrict the results
+      # @option arguments [List] :type A comma-separated list of types to restrict the results
+      # @option arguments [Hash] :body A query to restrict the results (optional)
+      # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+      #                                               no concrete indices. (This includes `_all` string or when no
+      #                                               indices have been specified)
+      # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+      #                                            `missing` ones (options: none, missing) @until 1.0
+      # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+      #                                                 unavailable (missing, closed, etc)
+      # @option arguments [Number] :min_score Include only documents with a specific `_score` value in the result
+      # @option arguments [String] :preference Specify the node or shard the operation should be performed on
+      #                                        (default: random)
+      # @option arguments [String] :routing Specific routing value
+      # @option arguments [String] :source The URL-encoded query definition (instead of using the request body)
+      #
+      # @see http://elasticsearch.org/guide/reference/api/count/
+      #
+      def count(arguments={})
+        valid_params = [
+          :ignore_indices,
+          :ignore_unavailable,
+          :allow_no_indices,
+          :expand_wildcards,
+          :min_score,
+          :preference,
+          :routing,
+          :source ]
+
+        method = 'GET'
+        path   = Utils.__pathify( Utils.__listify(arguments[:index]), Utils.__listify(arguments[:type]), '_count' )
+
+        params = Utils.__validate_and_extract_params arguments, valid_params
+        body   = arguments[:body]
+
+        perform_request(method, path, params, body).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/count_percolate.rb b/lib/elasticsearch/api/actions/count_percolate.rb
new file mode 100644
index 0000000..5dbb3b8
--- /dev/null
+++ b/lib/elasticsearch/api/actions/count_percolate.rb
@@ -0,0 +1,78 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Return the number of queries matching a document.
+      #
+      # Percolator allows you to register queries and then evaluate a document against them:
+      # the number of matching queries is returned in the response.
+      #
+      # @example Register query named "alert-1" for the "my-index" index
+      #
+      #     client.index index: 'my-index',
+      #                  type: '.percolator',
+      #                  id: 'alert-1',
+      #                  body: { query: { query_string: { query: 'foo' } } }
+      #
+      # @example Return the number of matching queries for a custom document
+      #
+      #     client.count_percolate index: 'my-index', type: 'my-type', body: { doc: { title: "Foo Bar" } }
+      #     # => { ..., total: 1}
+      #
+      # @example Return the number of matching queries for an existing document
+      #
+      #     client.index index: 'my-index', type: 'my-type', id: '123', body: { title: "Foo Bar" }
+      #
+      #     client.count_percolate index: 'my-index', type: 'my-type', id: '123'
+      #     # => { ..., total: 1}
+      #
+      # @option arguments [String] :index The index of the document being percolated. (*Required*)
+      # @option arguments [String] :type The type of the document being percolated. (*Required*)
+      # @option arguments [String] :id Fetch the document specified by index/type/id and
+      #                                use it instead of the passed `doc`
+      # @option arguments [Hash] :body The percolator request definition using the percolate DSL
+      # @option arguments [List] :routing A comma-separated list of specific routing values
+      # @option arguments [String] :preference Specify the node or shard the operation should be performed on
+      #                                        (default: random)
+      # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+      #                                                 unavailable (missing or closed)
+      # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+      #                                               no concrete indices. (This includes `_all` string or when no
+      #                                               indices have been specified)
+      # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are
+      #                                              open, closed or both. (options: open, closed)
+      # @option arguments [String] :percolate_index The index to percolate the document into. Defaults to passed `index`.
+      # @option arguments [String] :percolate_type The type to percolate document into. Defaults to passed `type`.
+      # @option arguments [Number] :version Explicit version number for concurrency control
+      # @option arguments [String] :version_type Specific version type (options: internal, external, external_gte, force)
+      #
+      # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/search-percolate.html
+      #
+      def count_percolate(arguments={})
+        raise ArgumentError, "Required argument 'index' missing" unless arguments[:index]
+        raise ArgumentError, "Required argument 'type' missing"  unless arguments[:type]
+        valid_params = [
+          :routing,
+          :preference,
+          :ignore_unavailable,
+          :allow_no_indices,
+          :expand_wildcards,
+          :percolate_index,
+          :percolate_type,
+          :version,
+          :version_type ]
+
+        method = 'GET'
+        path   = Utils.__pathify Utils.__escape(arguments[:index]),
+                                 Utils.__escape(arguments[:type]),
+                                 arguments[:id],
+                                 '_percolate/count'
+
+        params = Utils.__validate_and_extract_params arguments, valid_params
+        body   = arguments[:body]
+
+        perform_request(method, path, params, body).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/create.rb b/lib/elasticsearch/api/actions/create.rb
new file mode 100644
index 0000000..c63e4eb
--- /dev/null
+++ b/lib/elasticsearch/api/actions/create.rb
@@ -0,0 +1,34 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Create a document.
+      #
+      # Enforce the _create_ operation when indexing a document --
+      # the operation will return an error when the document already exists.
+      #
+      # @example Create a document
+      #
+      #     client.create index: 'myindex',
+      #                   type: 'mytype',
+      #                   id: '1',
+      #                   body: {
+      #                    title: 'Test 1',
+      #                    tags: ['y', 'z'],
+      #                    published: true,
+      #                    published_at: Time.now.utc.iso8601,
+      #                    counter: 1
+      #                   }
+      #
+      # @option (see Actions#index)
+      #
+      # (The `:op_type` argument is ignored.)
+      #
+      # @see http://elasticsearch.org/guide/reference/api/index_/
+      #
+      def create(arguments={})
+        index arguments.update :op_type => 'create'
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/delete.rb b/lib/elasticsearch/api/actions/delete.rb
new file mode 100644
index 0000000..a5f80c2
--- /dev/null
+++ b/lib/elasticsearch/api/actions/delete.rb
@@ -0,0 +1,64 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Delete a single document.
+      #
+      # @example Delete a document
+      #
+      #     client.delete index: 'myindex', type: 'mytype', id: '1'
+      #
+      # @example Delete a document with specific routing
+      #
+      #     client.delete index: 'myindex', type: 'mytype', id: '1', routing: 'abc123'
+      #
+      # @option arguments [String] :id The document ID (*Required*)
+      # @option arguments [Number,List] :ignore The list of HTTP errors to ignore; only `404` supported at the moment
+      # @option arguments [String] :index The name of the index (*Required*)
+      # @option arguments [String] :type The type of the document (*Required*)
+      # @option arguments [String] :consistency Specific write consistency setting for the operation
+      #                                         (options: one, quorum, all)
+      # @option arguments [String] :parent ID of parent document
+      # @option arguments [Boolean] :refresh Refresh the index after performing the operation
+      # @option arguments [String] :replication Specific replication type (options: sync, async)
+      # @option arguments [String] :routing Specific routing value
+      # @option arguments [Time] :timeout Explicit operation timeout
+      # @option arguments [Number] :version Explicit version number for concurrency control
+      # @option arguments [String] :version_type Specific version type (options: internal, external, external_gte, force)
+      #
+      # @see http://elasticsearch.org/guide/reference/api/delete/
+      #
+      def delete(arguments={})
+        raise ArgumentError, "Required argument 'index' missing" unless arguments[:index]
+        raise ArgumentError, "Required argument 'type' missing"  unless arguments[:type]
+        raise ArgumentError, "Required argument 'id' missing"    unless arguments[:id]
+
+        valid_params = [
+          :consistency,
+          :parent,
+          :refresh,
+          :replication,
+          :routing,
+          :timeout,
+          :version,
+          :version_type ]
+
+        method = 'DELETE'
+        path   = Utils.__pathify Utils.__escape(arguments[:index]),
+                                 Utils.__escape(arguments[:type]),
+                                 Utils.__escape(arguments[:id])
+
+        params = Utils.__validate_and_extract_params arguments, valid_params
+        body   = nil
+
+        perform_request(method, path, params, body).body
+
+      rescue Exception => e
+        # NOTE: Use exception name, not full class in Elasticsearch::Client to allow client plugability
+        if Array(arguments[:ignore]).include?(404) && e.class.to_s =~ /NotFound/; false
+        else raise(e)
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/delete_by_query.rb b/lib/elasticsearch/api/actions/delete_by_query.rb
new file mode 100644
index 0000000..cdeb518
--- /dev/null
+++ b/lib/elasticsearch/api/actions/delete_by_query.rb
@@ -0,0 +1,75 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Delete documents which match specified query.
+      #
+      # Provide the query either as a "query string" query in the `:q` argument, or using the Elasticsearch's
+      # [Query DSL](http://www.elasticsearch.org/guide/reference/query-dsl/) in the `:body` argument.
+      #
+      # @example Deleting documents with a simple query
+      #
+      #     client.delete_by_query index: 'myindex', q: 'title:test'
+      #
+      # @example Deleting documents using the Query DSL
+      #
+      #     client.delete_by_query index: 'myindex', body: { term: { published: false } }
+      #
+      # @option arguments [List] :index A comma-separated list of indices to restrict the operation;
+      #                                 use `_all`to perform the operation on all indices (*Required*)
+      # @option arguments [List] :type A comma-separated list of types to restrict the operation
+      # @option arguments [Hash] :body A query to restrict the operation
+      # @option arguments [String] :analyzer The analyzer to use for the query string
+      # @option arguments [String] :consistency Specific write consistency setting for the operation
+      #                                         (options: one, quorum, all)
+      # @option arguments [String] :default_operator The default operator for query string query (AND or OR)
+      #                                              (options: AND, OR)
+      # @option arguments [String] :df The field to use as default where no field prefix is given in the query string
+      # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+      #                                               no concrete indices. (This includes `_all` string or when no
+      #                                               indices have been specified)
+      # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+      #                                              are open, closed or both. (options: open, closed)
+      # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+      #                                            `missing` ones (options: none, missing) @until 1.0
+      # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+      #                                                 unavailable (missing, closed, etc)
+      # @option arguments [String] :replication Specific replication type (options: sync, async)
+      # @option arguments [String] :q Query in the Lucene query string syntax
+      # @option arguments [String] :routing Specific routing value
+      # @option arguments [String] :source The URL-encoded query definition (instead of using the request body)
+      # @option arguments [Time] :timeout Explicit operation timeout
+      #
+      # @see http://www.elasticsearch.org/guide/reference/api/delete-by-query/
+      #
+      def delete_by_query(arguments={})
+        raise ArgumentError, "Required argument 'index' missing" unless arguments[:index]
+
+        valid_params = [
+          :analyzer,
+          :consistency,
+          :default_operator,
+          :df,
+          :ignore_indices,
+          :ignore_unavailable,
+          :allow_no_indices,
+          :expand_wildcards,
+          :replication,
+          :q,
+          :routing,
+          :source,
+          :timeout ]
+
+        method = 'DELETE'
+        path   = Utils.__pathify Utils.__listify(arguments[:index]),
+                                 Utils.__listify(arguments[:type]),
+                                 '/_query'
+
+        params = Utils.__validate_and_extract_params arguments, valid_params
+        body   = arguments[:body]
+
+        perform_request(method, path, params, body).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/exists.rb b/lib/elasticsearch/api/actions/exists.rb
new file mode 100644
index 0000000..6e3b913
--- /dev/null
+++ b/lib/elasticsearch/api/actions/exists.rb
@@ -0,0 +1,53 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Return true if the specified document exists, false otherwise.
+      #
+      # @example
+      #
+      #     client.exists index: 'myindex', type: 'mytype', id: '1'
+      #
+      # @option arguments [String] :id The document ID (*Required*)
+      # @option arguments [String] :index The name of the index (*Required*)
+      # @option arguments [String] :type The type of the document (default: `_all`)
+      # @option arguments [String] :parent The ID of the parent document
+      # @option arguments [String] :preference Specify the node or shard the operation should be performed on
+      #                                        (default: random)
+      # @option arguments [Boolean] :realtime Specify whether to perform the operation in realtime or search mode
+      # @option arguments [Boolean] :refresh Refresh the shard containing the document before performing the operation
+      # @option arguments [String] :routing Specific routing value
+      #
+      # @see http://elasticsearch.org/guide/reference/api/get/
+      #
+      def exists(arguments={})
+        raise ArgumentError, "Required argument 'id' missing"    unless arguments[:id]
+        raise ArgumentError, "Required argument 'index' missing" unless arguments[:index]
+        arguments[:type] ||= '_all'
+
+        valid_params = [
+          :parent,
+          :preference,
+          :realtime,
+          :refresh,
+          :routing ]
+
+        method = 'HEAD'
+        path   = Utils.__pathify Utils.__escape(arguments[:index]),
+                                 Utils.__escape(arguments[:type]),
+                                 Utils.__escape(arguments[:id])
+
+        params = Utils.__validate_and_extract_params arguments, valid_params
+        body   = nil
+
+        perform_request(method, path, params, body).status == 200 ? true : false
+        rescue Exception => e
+          if e.class.to_s =~ /NotFound/ || e.message =~ /Not\s*Found|404/i
+            false
+          else
+            raise e
+          end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/explain.rb b/lib/elasticsearch/api/actions/explain.rb
new file mode 100644
index 0000000..b244b03
--- /dev/null
+++ b/lib/elasticsearch/api/actions/explain.rb
@@ -0,0 +1,82 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Return information if and how well a document matches a query.
+      #
+      # The returned information contains a `_score` and its explanation, if the document matches the query.
+      #
+      # @example Passing the query in the Lucene query syntax as the `:q` URL parameter
+      #
+      #     client.explain index: 'myindex', type: 'mytype', id: '1', q: 'test'
+      #
+      # @example Passing the query in the Query DSL as the request `:body`
+      #
+      #     client.explain index: 'myindex', type: 'mytype', id: '1',
+      #                    body: { query: { match: { title: 'test' } } }
+      #
+      # @option arguments [String] :id The document ID (*Required*)
+      # @option arguments [String] :index The name of the index (*Required*)
+      # @option arguments [String] :type The type of the document (*Required*)
+      # @option arguments [Hash] :body The query definition using the Query DSL (*Required*)
+      # @option arguments [Boolean] :analyze_wildcard Specify whether wildcards and prefix queries in the query string
+      #                                               query should be analyzed (default: false)
+      # @option arguments [String] :analyzer The analyzer for the query string query
+      # @option arguments [String] :default_operator The default operator for query string query (AND or OR)
+      #                                              (options: AND, OR)
+      # @option arguments [String] :df The default field for query string query (default: _all)
+      # @option arguments [List] :fields A comma-separated list of fields to return in the response
+      # @option arguments [Boolean] :lenient Specify whether format-based query failures
+      #                                      (such as providing text to a numeric field) should be ignored
+      # @option arguments [Boolean] :lowercase_expanded_terms Specify whether query terms should be lowercased
+      # @option arguments [String] :parent The ID of the parent document
+      # @option arguments [String] :preference Specify the node or shard the operation should be performed on
+      #                                        (default: random)
+      # @option arguments [String] :q Query in the Lucene query string syntax
+      # @option arguments [String] :routing Specific routing value
+      # @option arguments [String] :source The URL-encoded query definition (instead of using the request body)
+      # @option arguments [String] :_source Specify whether the _source field should be returned,
+      #                                     or a list of fields to return
+      # @option arguments [String] :_source_exclude A list of fields to exclude from the returned _source field
+      # @option arguments [String] :_source_include A list of fields to extract and return from the _source field
+      #
+      # @see http://elasticsearch.org/guide/reference/api/explain/
+      #
+      def explain(arguments={})
+        raise ArgumentError, "Required argument 'index' missing" unless arguments[:index]
+        raise ArgumentError, "Required argument 'type' missing"  unless arguments[:type]
+        raise ArgumentError, "Required argument 'id' missing"    unless arguments[:id]
+
+        valid_params = [
+          :analyze_wildcard,
+          :analyzer,
+          :default_operator,
+          :df,
+          :fields,
+          :lenient,
+          :lowercase_expanded_terms,
+          :parent,
+          :preference,
+          :q,
+          :routing,
+          :source,
+          :_source,
+          :_source_include,
+          :_source_exclude ]
+
+        method = 'GET'
+        path   = Utils.__pathify Utils.__escape(arguments[:index]),
+                                 Utils.__escape(arguments[:type]),
+                                 Utils.__escape(arguments[:id]),
+                                 '_explain'
+
+        params = Utils.__validate_and_extract_params arguments, valid_params
+        body   = arguments[:body]
+
+        params[:fields] = Utils.__listify(params[:fields]) if params[:fields]
+
+        perform_request(method, path, params, body).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/get.rb b/lib/elasticsearch/api/actions/get.rb
new file mode 100644
index 0000000..0730038
--- /dev/null
+++ b/lib/elasticsearch/api/actions/get.rb
@@ -0,0 +1,72 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Return a specified document.
+      #
+      # The response contains full document, as stored in Elasticsearch, incl. `_source`, `_version`, etc.
+      #
+      # @example Get a document
+      #
+      #     client.get index: 'myindex', type: 'mytype', id: '1'
+      #
+      # @option arguments [String] :id The document ID (*Required*)
+      # @option arguments [Number,List] :ignore The list of HTTP errors to ignore; only `404` supported at the moment
+      # @option arguments [String] :index The name of the index (*Required*)
+      # @option arguments [String] :type The type of the document; use `_all` to fetch the first document
+      #                                  matching the ID across all types) (*Required*)
+      # @option arguments [List] :fields A comma-separated list of fields to return in the response
+      # @option arguments [String] :parent The ID of the parent document
+      # @option arguments [String] :preference Specify the node or shard the operation should be performed on
+      #                                        (default: random)
+      # @option arguments [Boolean] :realtime Specify whether to perform the operation in realtime or search mode
+      # @option arguments [Boolean] :refresh Refresh the shard containing the document before performing the operation
+      # @option arguments [String] :routing Specific routing value
+      # @option arguments [Number] :version Explicit version number for concurrency control
+      # @option arguments [String] :version_type Specific version type (options: internal, external, external_gte, force)
+      # @option arguments [String] :_source Specify whether the _source field should be returned,
+      #                                     or a list of fields to return
+      # @option arguments [String] :_source_exclude A list of fields to exclude from the returned _source field
+      # @option arguments [String] :_source_include A list of fields to extract and return from the _source field
+      #
+      # @see http://elasticsearch.org/guide/reference/api/get/
+      #
+      def get(arguments={})
+        raise ArgumentError, "Required argument 'index' missing" unless arguments[:index]
+        raise ArgumentError, "Required argument 'id' missing"    unless arguments[:id]
+        arguments[:type] ||= '_all'
+
+        valid_params = [
+          :fields,
+          :parent,
+          :preference,
+          :realtime,
+          :refresh,
+          :routing,
+          :version,
+          :version_type,
+          :_source,
+          :_source_include,
+          :_source_exclude ]
+
+        method = 'GET'
+        path   = Utils.__pathify Utils.__escape(arguments[:index]),
+                                 Utils.__escape(arguments[:type]),
+                                 Utils.__escape(arguments[:id])
+
+        params = Utils.__validate_and_extract_params arguments, valid_params
+        body   = nil
+
+        params[:fields] = Utils.__listify(params[:fields]) if params[:fields]
+
+        perform_request(method, path, params, body).body
+
+      rescue Exception => e
+        # NOTE: Use exception name, not full class in Elasticsearch::Client to allow client plugability
+        if Array(arguments[:ignore]).include?(404) && e.class.to_s =~ /NotFound/; false
+        else raise(e)
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/get_source.rb b/lib/elasticsearch/api/actions/get_source.rb
new file mode 100644
index 0000000..625478d
--- /dev/null
+++ b/lib/elasticsearch/api/actions/get_source.rb
@@ -0,0 +1,71 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Return a specified document's `_source`.
+      #
+      # The response contains just the original document, as passed to Elasticsearch during indexing.
+      #
+      # @example Get a document `_source`
+      #
+      #     client.get_source index: 'myindex', type: 'mytype', id: '1'
+      #
+      # @option arguments [String] :id The document ID (*Required*)
+      # @option arguments [Number,List] :ignore The list of HTTP errors to ignore; only `404` supported at the moment
+      # @option arguments [String] :index The name of the index (*Required*)
+      # @option arguments [String] :type The type of the document; use `_all` to fetch the first document
+      #                                  matching the ID across all types) (*Required*)
+      # @option arguments [List] :fields A comma-separated list of fields to return in the response
+      # @option arguments [String] :parent The ID of the parent document
+      # @option arguments [String] :preference Specify the node or shard the operation should be performed on
+      #                                        (default: random)
+      # @option arguments [Boolean] :realtime Specify whether to perform the operation in realtime or search mode
+      # @option arguments [Boolean] :refresh Refresh the shard containing the document before performing the operation
+      # @option arguments [String] :routing Specific routing value
+      # @option arguments [String] :_source Specify whether the _source field should be returned,
+      #                                     or a list of fields to return
+      # @option arguments [String] :_source_exclude A list of fields to exclude from the returned _source field
+      # @option arguments [String] :_source_include A list of fields to extract and return from the _source field
+      #
+      # @see http://elasticsearch.org/guide/reference/api/get/
+      #
+      # @since 0.90.1
+      #
+      def get_source(arguments={})
+        raise ArgumentError, "Required argument 'index' missing" unless arguments[:index]
+        raise ArgumentError, "Required argument 'id' missing"    unless arguments[:id]
+        arguments[:type] ||= '_all'
+
+        valid_params = [
+          :fields,
+          :parent,
+          :preference,
+          :realtime,
+          :refresh,
+          :routing,
+          :_source,
+          :_source_include,
+          :_source_exclude ]
+
+        method = 'GET'
+        path   = Utils.__pathify Utils.__escape(arguments[:index]),
+                                 Utils.__escape(arguments[:type]),
+                                 Utils.__escape(arguments[:id]),
+                                 '_source'
+
+        params = Utils.__validate_and_extract_params arguments, valid_params
+        body   = nil
+
+        params[:fields] = Utils.__listify(params[:fields]) if params[:fields]
+
+        perform_request(method, path, params, body).body
+
+      rescue Exception => e
+        # NOTE: Use exception name, not full class in Elasticsearch::Client to allow client plugability
+        if Array(arguments[:ignore]).include?(404) && e.class.to_s =~ /NotFound/; false
+        else raise(e)
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/index.rb b/lib/elasticsearch/api/actions/index.rb
new file mode 100644
index 0000000..2c7d025
--- /dev/null
+++ b/lib/elasticsearch/api/actions/index.rb
@@ -0,0 +1,103 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Create or update a document.
+      #
+      # The `index` API will either _create_ a new document, or _update_ an existing one, when a document `:id`
+      # is passed. When creating a document, an ID will be auto-generated, when it's not passed as an argument.
+      #
+      # You can specifically enforce the _create_ operation by settint the `op_type` argument to `create`, or
+      # by using the {Actions#create} method.
+      #
+      # Optimistic concurrency control is performed, when the `version` argument is specified. By default,
+      # no version checks are performed.
+      #
+      # By default, the document will be available for {Actions#get} immediately, for {Actions#search} only
+      # after an index refresh operation has been performed (either automatically or manually).
+      #
+      # @example Create or update a document `myindex/mytype/1`
+      #
+      #     client.index index: 'myindex',
+      #                  type: 'mytype',
+      #                  id: '1',
+      #                  body: {
+      #                   title: 'Test 1',
+      #                   tags: ['y', 'z'],
+      #                   published: true,
+      #                   published_at: Time.now.utc.iso8601,
+      #                   counter: 1
+      #                 }
+      #
+      # @example Refresh the index after the operation (useful e.g. in integration tests)
+      #
+      #     client.index index: 'myindex', type: 'mytype', id: '1', body: { title: 'TEST' }, refresh: true
+      #     client.search index: 'myindex', q: 'title:test'
+      #
+      # @example Create a document with a specific expiration time (TTL)
+      #
+      #     # Decrease the default housekeeping interval first:
+      #     client.cluster.put_settings body: { transient: { 'indices.ttl.interval' => '1s' } }
+      #
+      #     # Enable the `_ttl` property for all types within the index
+      #     client.indices.create index: 'myindex', body: { mappings: { mytype: { _ttl: { enabled: true } }  } }
+      #
+      #     client.index index: 'myindex', type: 'mytype', id: '1', body: { title: 'TEST' }, ttl: '5s'
+      #
+      #     sleep 3 and client.get index: 'myindex', type: 'mytype', id: '1'
+      #     # => {"_index"=>"myindex" ... "_source"=>{"title"=>"TEST"}}
+      #
+      #     sleep 3 and client.get index: 'myindex', type: 'mytype', id: '1'
+      #     # => Elasticsearch::Transport::Transport::Errors::NotFound: [404] ...
+      #
+      # @option arguments [String] :id Document ID (optional, will be auto-generated if missing)
+      # @option arguments [String] :index The name of the index (*Required*)
+      # @option arguments [String] :type The type of the document (*Required*)
+      # @option arguments [Hash] :body The document
+      # @option arguments [String] :consistency Explicit write consistency setting for the operation
+      #                                         (options: one, quorum, all)
+      # @option arguments [String] :op_type Explicit operation type (options: index, create)
+      # @option arguments [String] :parent ID of the parent document
+      # @option arguments [String] :percolate Percolator queries to execute while indexing the document
+      # @option arguments [Boolean] :refresh Refresh the index after performing the operation
+      # @option arguments [String] :replication Specific replication type (options: sync, async)
+      # @option arguments [String] :routing Specific routing value
+      # @option arguments [Time] :timeout Explicit operation timeout
+      # @option arguments [Time] :timestamp Explicit timestamp for the document
+      # @option arguments [Duration] :ttl Expiration time for the document
+      # @option arguments [Number] :version Explicit version number for concurrency control
+      # @option arguments [String] :version_type Specific version type (options: internal, external, external_gte, force)
+      #
+      # @see http://elasticsearch.org/guide/reference/api/index_/
+      #
+      def index(arguments={})
+        raise ArgumentError, "Required argument 'index' missing" unless arguments[:index]
+        raise ArgumentError, "Required argument 'type' missing"  unless arguments[:type]
+
+        valid_params = [
+          :consistency,
+          :op_type,
+          :parent,
+          :percolate,
+          :refresh,
+          :replication,
+          :routing,
+          :timeout,
+          :timestamp,
+          :ttl,
+          :version,
+          :version_type ]
+
+        method = arguments[:id] ? 'PUT' : 'POST'
+        path   = Utils.__pathify Utils.__escape(arguments[:index]),
+                                 Utils.__escape(arguments[:type]),
+                                 Utils.__escape(arguments[:id])
+
+        params = Utils.__validate_and_extract_params arguments, valid_params
+        body   = arguments[:body]
+
+        perform_request(method, path, params, body).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/analyze.rb b/lib/elasticsearch/api/actions/indices/analyze.rb
new file mode 100644
index 0000000..e8bc420
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/analyze.rb
@@ -0,0 +1,62 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Return the result of the analysis process (tokens)
+        #
+        # Allows to "test-drive" the Elasticsearch analysis process by performing the analysis on the
+        # same text with different analyzers. An ad-hoc analysis chain can be built from specific
+        # _tokenizer_ and _filters_.
+        #
+        # @example Analyze text "Quick Brown Jumping Fox" with the _snowball_ analyzer
+        #
+        #     client.indices.analyze text: 'The Quick Brown Jumping Fox', analyzer: 'snowball'
+        #
+        # @example Analyze text "Quick Brown Jumping Fox" with a custom tokenizer and filter chain
+        #
+        #     client.indices.analyze text: 'The Quick Brown Jumping Fox',
+        #                            tokenizer: 'whitespace',
+        #                            filters: ['lowercase','stop']
+        #
+        # @option arguments [String] :index The name of the index to scope the operation
+        # @option arguments [Hash] :body The text on which the analysis should be performed
+        # @option arguments [String] :analyzer The name of the analyzer to use
+        # @option arguments [String] :field Use the analyzer configured for this field
+        #                                   (instead of passing the analyzer name)
+        # @option arguments [List] :filters A comma-separated list of filters to use for the analysis
+        # @option arguments [String] :index The name of the index to scope the operation
+        # @option arguments [Boolean] :prefer_local With `true`, specify that a local shard should be used if available,
+        #                                           with `false`, use a random shard (default: true)
+        # @option arguments [String] :text The text on which the analysis should be performed
+        #                                  (when request body is not used)
+        # @option arguments [String] :tokenizer The name of the tokenizer to use for the analysis
+        # @option arguments [String] :format Format of the output (options: detailed, text)
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-analyze/
+        #
+        def analyze(arguments={})
+          valid_params = [
+            :analyzer,
+            :field,
+            :filters,
+            :index,
+            :prefer_local,
+            :text,
+            :tokenizer,
+            :format ]
+
+          method = 'GET'
+          path   = Utils.__pathify Utils.__listify(arguments[:index]), '_analyze'
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          params[:filters] = Utils.__listify(params[:filters]) if params[:filters]
+
+          body   = arguments[:body]
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/clear_cache.rb b/lib/elasticsearch/api/actions/indices/clear_cache.rb
new file mode 100644
index 0000000..5fa37f7
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/clear_cache.rb
@@ -0,0 +1,79 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Clear caches and other auxiliary data structures.
+        #
+        # Can be performed against a specific index, or against all indices.
+        #
+        # By default, all caches and data structures will be cleared.
+        # Pass a specific cache or structure name to clear just a single one.
+        #
+        # @example Clear all caches and data structures
+        #
+        #     client.indices.clear_cache
+        #
+        # @example Clear the field data structure only
+        #
+        #     client.indices.clear_cache field_data: true
+        #
+        # @example Clear only specific field in the field data structure
+        #
+        #     client.indices.clear_cache field_data: true, fields: 'created_at', filter_cache: false, id_cache: false
+        #
+        # @option arguments [List] :index A comma-separated list of index name to limit the operation
+        # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+        #                                               no concrete indices. (This includes `_all` string or when no
+        #                                               indices have been specified)
+        # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+        #                                              are open, closed or both. (options: open, closed)
+        # @option arguments [Boolean] :field_data Clear field data
+        # @option arguments [Boolean] :fielddata Clear field data
+        # @option arguments [List] :fields A comma-separated list of fields to clear when using the
+        #                                  `field_data` parameter(default: all)
+        # @option arguments [Boolean] :filter Clear filter caches
+        # @option arguments [Boolean] :filter_cache Clear filter caches
+        # @option arguments [Boolean] :filter_keys A comma-separated list of keys to clear when using the
+        #                                          `filter_cache` parameter (default: all)
+        # @option arguments [Boolean] :id Clear ID caches for parent/child
+        # @option arguments [Boolean] :id_cache Clear ID caches for parent/child
+        # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+        #                                            `missing` ones (options: none, missing) @until 1.0
+        # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+        #                                                 unavailable (missing, closed, etc)
+        # @option arguments [List] :index A comma-separated list of index name to limit the operation
+        # @option arguments [Boolean] :recycler Clear the recycler cache
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-clearcache/
+        #
+        def clear_cache(arguments={})
+          valid_params = [
+            :field_data,
+            :fielddata,
+            :fields,
+            :filter,
+            :filter_cache,
+            :filter_keys,
+            :id,
+            :id_cache,
+            :ignore_indices,
+            :ignore_unavailable,
+            :allow_no_indices,
+            :expand_wildcards,
+            :recycler ]
+
+          method = 'POST'
+          path   = Utils.__pathify Utils.__listify(arguments[:index]), '_cache/clear'
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          params[:fields] = Utils.__listify(params[:fields]) if params[:fields]
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/close.rb b/lib/elasticsearch/api/actions/indices/close.rb
new file mode 100644
index 0000000..d396a68
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/close.rb
@@ -0,0 +1,50 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Close an index (keep the data on disk, but deny operations with the index).
+        #
+        # A closed index can be opened again with the {Indices::Actions#close} API.
+        #
+        # @example Close index named _myindex_
+        #
+        #     client.indices.close index: 'myindex'
+        #
+        # @option arguments [String] :index The name of the index (*Required*)
+        # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+        #                                               no concrete indices. (This includes `_all` string or when no
+        #                                               indices have been specified)
+        # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+        #                                              are open, closed or both. (options: open, closed)
+        # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+        #                                            `missing` ones (options: none, missing) @until 1.0
+        # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+        #                                                 unavailable (missing, closed, etc)
+        # @option arguments [Time] :timeout Explicit operation timeout
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-open-close/
+        #
+        def close(arguments={})
+          raise ArgumentError, "Required argument 'index' missing" unless arguments[:index]
+
+          valid_params = [
+            :ignore_indices,
+            :ignore_unavailable,
+            :allow_no_indices,
+            :expand_wildcards,
+            :timeout
+          ]
+
+          method = 'POST'
+          path   = Utils.__pathify Utils.__listify(arguments[:index]), '_close'
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/create.rb b/lib/elasticsearch/api/actions/indices/create.rb
new file mode 100644
index 0000000..e75f42c
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/create.rb
@@ -0,0 +1,82 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Create an index.
+        #
+        # Pass the index `settings` and `mappings` in the `:body` attribute.
+        #
+        # @example Create an index with specific settings, custom analyzers and mappings
+        #
+        #     client.indices.create index: 'test',
+        #                           body: {
+        #                             settings: {
+        #                               index: {
+        #                                 number_of_shards: 1,
+        #                                 number_of_replicas: 0,
+        #                                 'routing.allocation.include.name' => 'node-1'
+        #                               },
+        #                               analysis: {
+        #                                 filter: {
+        #                                   ngram: {
+        #                                     type: 'nGram',
+        #                                     min_gram: 3,
+        #                                     max_gram: 25
+        #                                   }
+        #                                 },
+        #                                 analyzer: {
+        #                                   ngram: {
+        #                                     tokenizer: 'whitespace',
+        #                                     filter: ['lowercase', 'stop', 'ngram'],
+        #                                     type: 'custom'
+        #                                   },
+        #                                   ngram_search: {
+        #                                     tokenizer: 'whitespace',
+        #                                     filter: ['lowercase', 'stop'],
+        #                                     type: 'custom'
+        #                                   }
+        #                                 }
+        #                               }
+        #                             },
+        #                             mappings: {
+        #                               document: {
+        #                                 properties: {
+        #                                   title: {
+        #                                     type: 'multi_field',
+        #                                     fields: {
+        #                                         title:  { type: 'string', analyzer: 'snowball' },
+        #                                         exact:  { type: 'string', analyzer: 'keyword' },
+        #                                         ngram:  { type: 'string',
+        #                                                   index_analyzer: 'ngram',
+        #                                                   search_analyzer: 'ngram_search'
+        #                                         }
+        #                                     }
+        #                                   }
+        #                                 }
+        #                               }
+        #                             }
+        #                           }
+        #
+        # @option arguments [String] :index The name of the index (*Required*)
+        # @option arguments [Hash] :body Optional configuration for the index (`settings` and `mappings`)
+        # @option arguments [Time] :timeout Explicit operation timeout
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-create-index/
+        #
+        def create(arguments={})
+          raise ArgumentError, "Required argument 'index' missing" unless arguments[:index]
+          valid_params = [ :timeout ]
+
+          method = 'PUT'
+          path   = Utils.__pathify Utils.__escape(arguments[:index])
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = arguments[:body]
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/delete.rb b/lib/elasticsearch/api/actions/indices/delete.rb
new file mode 100644
index 0000000..4295fb4
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/delete.rb
@@ -0,0 +1,47 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Delete an index, list of indices, or all indices in the cluster.
+        #
+        # @example Delete an index
+        #
+        #     client.indices.delete index: 'foo'
+        #
+        # @example Delete a list of indices
+        #
+        #     client.indices.delete index: ['foo', 'bar']
+        #     client.indices.delete index: 'foo,bar'
+        #
+        #
+        # @example Delete a list of indices matching wildcard expression
+        #
+        #     client.indices.delete index: 'foo*'
+        #
+        # @example Delete all indices
+        #
+        #     client.indices.delete
+        #     client.indices.delete index: '_all'
+        #
+        # @option arguments [List] :index A comma-separated list of indices to delete;
+        #                                 use `_all` or leave empty to delete all indices
+        # @option arguments [Time] :timeout Explicit operation timeout
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-delete-index/
+        #
+        def delete(arguments={})
+          valid_params = [ :timeout ]
+
+          method = 'DELETE'
+          path   = Utils.__pathify Utils.__listify(arguments[:index])
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/delete_alias.rb b/lib/elasticsearch/api/actions/indices/delete_alias.rb
new file mode 100644
index 0000000..5f7d4be
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/delete_alias.rb
@@ -0,0 +1,36 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Delete a single index alias.
+        #
+        # @example Delete an alias
+        #
+        #     client.indices.delete_alias index: 'foo', name: 'bar'
+        #
+        # See the {Indices::Actions#update_aliases} for performing operations with index aliases in bulk.
+        #
+        # @option arguments [String] :index The name of the index with an alias (*Required*)
+        # @option arguments [String] :name The name of the alias to be deleted (*Required*)
+        # @option arguments [Time] :timeout Explicit timestamp for the document
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-aliases/
+        #
+        def delete_alias(arguments={})
+          raise ArgumentError, "Required argument 'index' missing" unless arguments[:index]
+          raise ArgumentError, "Required argument 'name' missing"  unless arguments[:name]
+          valid_params = [ :timeout ]
+
+          method = 'DELETE'
+          path   = Utils.__pathify Utils.__escape(arguments[:index]), '_alias', Utils.__escape(arguments[:name])
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/delete_mapping.rb b/lib/elasticsearch/api/actions/indices/delete_mapping.rb
new file mode 100644
index 0000000..d5a03a6
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/delete_mapping.rb
@@ -0,0 +1,26 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Delete all documents and mapping for a specific document type.
+        #
+        # @option arguments [List] :index A comma-separated list of index names; use `_all` for all indices (*Required*)
+        # @option arguments [String] :type The name of the document type to delete (*Required*)
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-delete-mapping/
+        #
+        def delete_mapping(arguments={})
+          raise ArgumentError, "Required argument 'index' missing" unless arguments[:index]
+          raise ArgumentError, "Required argument 'type' missing"  unless arguments[:type]
+          method = 'DELETE'
+          path   = Utils.__pathify Utils.__listify(arguments[:index]), Utils.__escape(arguments[:type])
+          params = {}
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/delete_template.rb b/lib/elasticsearch/api/actions/indices/delete_template.rb
new file mode 100644
index 0000000..bc32573
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/delete_template.rb
@@ -0,0 +1,42 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Delete an index template.
+        #
+        # @example Delete a template named _mytemplate_
+        #
+        #     client.indices.delete_template name: 'mytemplate'
+        #
+        # @example Delete all templates
+        #
+        #     client.indices.delete_template name: '*'
+        #
+        # @option arguments [String] :name The name of the template (*Required*)
+        # @option arguments [Time] :timeout Explicit operation timeout
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-templates/
+        #
+        def delete_template(arguments={})
+          raise ArgumentError, "Required argument 'name' missing" unless arguments[:name]
+          valid_params = [ :timeout ]
+
+          method = 'DELETE'
+          path   = Utils.__pathify '_template', Utils.__escape(arguments[:name])
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body = nil
+
+          perform_request(method, path, params, body).body
+
+        rescue Exception => e
+          # NOTE: Use exception name, not full class in Elasticsearch::Client to allow client plugability
+          if Array(arguments[:ignore]).include?(404) && e.class.to_s =~ /NotFound/; false
+          else raise(e)
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/delete_warmer.rb b/lib/elasticsearch/api/actions/indices/delete_warmer.rb
new file mode 100644
index 0000000..4731426
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/delete_warmer.rb
@@ -0,0 +1,32 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Delete one or more warmers for a list of indices.
+        #
+        # @example Delete a warmer named _mywarmer_ for index named _myindex_
+        #
+        #     client.indices.delete_warmer index: 'myindex', name: 'mywarmer'
+        #
+        # @option arguments [List] :index A comma-separated list of index names to register warmer for; use `_all`
+        #                                 or empty string to perform the operation on all indices (*Required*)
+        # @option arguments [String] :name The name of the warmer (supports wildcards); leave empty to delete all warmers
+        # @option arguments [List] :type A comma-separated list of document types to register warmer for; use `_all`
+        #                                or empty string to perform the operation on all types
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-warmers/
+        #
+        def delete_warmer(arguments={})
+          raise ArgumentError, "Required argument 'index' missing" unless arguments[:index]
+          method = 'DELETE'
+          path   = Utils.__pathify Utils.__listify(arguments[:index]), '_warmer', Utils.__listify(arguments[:name])
+          params = {}
+          body = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/exists.rb b/lib/elasticsearch/api/actions/indices/exists.rb
new file mode 100644
index 0000000..08c3206
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/exists.rb
@@ -0,0 +1,56 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Return true if the index (or all indices in a list) exists, false otherwise.
+        #
+        # @example Check whether index named _myindex_ exists
+        #
+        #     client.indices.exists index: 'myindex'
+        #
+        # @option arguments [List] :index A comma-separated list of indices to check (*Required*)
+        # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+        #                                               no concrete indices. (This includes `_all` string or when no
+        #                                               indices have been specified)
+        # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+        #                                              are open, closed or both. (options: open, closed)
+        # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+        #                                            `missing` ones (options: none, missing) @until 1.0
+        # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+        #                                                 unavailable (missing, closed, etc)
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+        #                                    (default: false)
+        #
+        # @return [true,false]
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-indices-exists/
+        #
+        def exists(arguments={})
+          raise ArgumentError, "Required argument 'index' missing" unless arguments[:index]
+
+          valid_params = [
+            :ignore_indices,
+            :ignore_unavailable,
+            :allow_no_indices,
+            :expand_wildcards,
+            :local
+          ]
+
+          method = 'HEAD'
+          path   = Utils.__listify(arguments[:index])
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).status == 200 ? true : false
+        rescue Exception => e
+          if e.class.to_s =~ /NotFound/ || e.message =~ /Not\s*Found|404/i
+            false
+          else
+            raise e
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/exists_alias.rb b/lib/elasticsearch/api/actions/indices/exists_alias.rb
new file mode 100644
index 0000000..1335a1d
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/exists_alias.rb
@@ -0,0 +1,54 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Return true if the specified alias exists, false otherwise.
+        #
+        # @example Check whether index alias named _myalias_ exists
+        #
+        #     client.indices.exists_alias name: 'myalias'
+        #
+        # @option arguments [List] :index A comma-separated list of index names to filter aliases
+        # @option arguments [List] :name A comma-separated list of alias names to return
+        # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+        #                                               no concrete indices. (This includes `_all` string or when no
+        #                                               indices have been specified)
+        # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+        #                                              are open, closed or both. (options: open, closed)
+        # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+        #                                            `missing` ones (options: none, missing) @until 1.0
+        # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+        #                                                 unavailable (missing, closed, etc)
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+        #                                    (default: false)
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-aliases/
+        #
+        def exists_alias(arguments={})
+          valid_params = [
+            :ignore_indices,
+            :ignore_unavailable,
+            :allow_no_indices,
+            :expand_wildcards,
+            :local
+          ]
+
+          method = 'HEAD'
+          path   = Utils.__pathify Utils.__listify(arguments[:index]), '_alias', Utils.__escape(arguments[:name])
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body = nil
+
+          perform_request(method, path, params, body).status == 200 ? true : false
+        rescue Exception => e
+          if e.class.to_s =~ /NotFound/ || e.message =~ /Not\s*Found|404/i
+            false
+          else
+            raise e
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/exists_template.rb b/lib/elasticsearch/api/actions/indices/exists_template.rb
new file mode 100644
index 0000000..f0f4310
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/exists_template.rb
@@ -0,0 +1,34 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # TODO: Description
+        #
+        # @option arguments [String] :name The name of the template (*Required*)
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node (default: false)
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/indices-templates.html
+        #
+        def exists_template(arguments={})
+          raise ArgumentError, "Required argument 'name' missing" unless arguments[:name]
+          valid_params = [ :local ]
+
+          method = 'HEAD'
+          path   = Utils.__pathify '_template', Utils.__escape(arguments[:name])
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body = nil
+
+          perform_request(method, path, params, body).status == 200 ? true : false
+        rescue Exception => e
+          if e.class.to_s =~ /NotFound/ || e.message =~ /Not\s*Found|404/i
+            false
+          else
+            raise e
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/exists_type.rb b/lib/elasticsearch/api/actions/indices/exists_type.rb
new file mode 100644
index 0000000..4a86b95
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/exists_type.rb
@@ -0,0 +1,53 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Return true if the specified type exists, false otherwise.
+        #
+        # @option arguments [List] :index A comma-separated list of index names; use `_all`
+        #                                 to check the types across all indices (*Required*)
+        # @option arguments [List] :type A comma-separated list of document types to check (*Required*)
+        # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+        #                                               no concrete indices. (This includes `_all` string or when no
+        #                                               indices have been specified)
+        # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+        #                                              are open, closed or both. (options: open, closed)
+        # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+        #                                            `missing` ones (options: none, missing) @until 1.0
+        # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+        #                                                 unavailable (missing, closed, etc)
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+        #                                    (default: false)
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-types-exists/
+        #
+        def exists_type(arguments={})
+          raise ArgumentError, "Required argument 'index' missing" unless arguments[:index]
+          raise ArgumentError, "Required argument 'type' missing" unless arguments[:type]
+          valid_params = [
+            :ignore_indices,
+            :ignore_unavailable,
+            :allow_no_indices,
+            :expand_wildcards,
+            :local
+          ]
+
+          method = 'HEAD'
+          path   = Utils.__pathify Utils.__listify(arguments[:index]), Utils.__escape(arguments[:type])
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body = nil
+
+          perform_request(method, path, params, body).status == 200 ? true : false
+        rescue Exception => e
+          if e.class.to_s =~ /NotFound/ || e.message =~ /Not\s*Found|404/i
+            false
+          else
+            raise e
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/flush.rb b/lib/elasticsearch/api/actions/indices/flush.rb
new file mode 100644
index 0000000..f45265c
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/flush.rb
@@ -0,0 +1,52 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # "Flush" the index or indices.
+        #
+        # The "flush" operation clears the transaction log and memory and writes data to disk.
+        # It corresponds to a Lucene "commit" operation.
+        #
+        # @note The flush operation is handled automatically by Elasticsearch, you don't need to perform it manually.
+        #
+        # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string for all indices
+        # @option arguments [Boolean] :force Whether a flush should be forced even if it is not necessarily needed ie.
+        #                                    if no changes will be committed to the index. (Internal)
+        # @option arguments [Boolean] :full If set to true a new index writer is created and settings that have been
+        #                                   changed related to the index writer will be refreshed. (Internal)
+        # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+        #                                               no concrete indices. (This includes `_all` string or when no
+        #                                               indices have been specified)
+        # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+        #                                              are open, closed or both. (options: open, closed)
+        # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+        #                                            `missing` ones (options: none, missing) @until 1.0
+        # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+        #                                                 unavailable (missing, closed, etc)
+        # @option arguments [Boolean] :refresh Refresh the index after performing the operation
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-flush/
+        #
+        def flush(arguments={})
+          valid_params = [
+            :force,
+            :full,
+            :ignore_indices,
+            :ignore_unavailable,
+            :allow_no_indices,
+            :expand_wildcards,
+            :refresh ]
+
+          method = 'POST'
+          path   = Utils.__pathify Utils.__listify(arguments[:index]), '_flush'
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/get_alias.rb b/lib/elasticsearch/api/actions/indices/get_alias.rb
new file mode 100644
index 0000000..e0b6877
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/get_alias.rb
@@ -0,0 +1,52 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Get information about a specific alias.
+        #
+        # @example Return all indices an alias points to
+        #
+        #     client.indices.get_alias name: '2013'
+        #
+        # @example Return all indices matching a wildcard pattern an alias points to
+        #
+        #     client.indices.get_alias index: 'log*', name: '2013'
+        #
+        # @option arguments [List] :index A comma-separated list of index names to filter aliases
+        # @option arguments [List] :name A comma-separated list of alias names to return
+        # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+        #                                               no concrete indices. (This includes `_all` string or when no
+        #                                               indices have been specified)
+        # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+        #                                              are open, closed or both. (options: open, closed)
+        # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+        #                                            `missing` ones (options: none, missing) @until 1.0
+        # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+        #                                                 unavailable (missing, closed, etc)
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+        #                                    (default: false)
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-aliases/
+        #
+        def get_alias(arguments={})
+          valid_params = [
+            :ignore_indices,
+            :ignore_unavailable,
+            :allow_no_indices,
+            :expand_wildcards,
+            :local
+          ]
+
+          method = 'GET'
+          path   = Utils.__pathify Utils.__listify(arguments[:index]), '_alias', Utils.__escape(arguments[:name])
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/get_aliases.rb b/lib/elasticsearch/api/actions/indices/get_aliases.rb
new file mode 100644
index 0000000..8db161b
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/get_aliases.rb
@@ -0,0 +1,34 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Get a list of all aliases, or aliases for a specific index.
+        #
+        # @example Get a list of all aliases
+        #
+        #     client.indices.get_aliases
+        #
+        # @option arguments [List] :index A comma-separated list of index names to filter aliases
+        # @option arguments [List] :name A comma-separated list of alias names to filter
+        # @option arguments [Time] :timeout Explicit timestamp for the document
+        # @option arguments [Boolean] :local Return local information,
+        #                                    do not retrieve the state from master node (default: false)
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-aliases.html
+        #
+        def get_aliases(arguments={})
+          valid_params = [ :timeout, :local ]
+
+          method = 'GET'
+          path   = Utils.__pathify Utils.__listify(arguments[:index]), '_aliases', Utils.__listify(arguments[:name])
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/get_field_mapping.rb b/lib/elasticsearch/api/actions/indices/get_field_mapping.rb
new file mode 100644
index 0000000..b36ad1d
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/get_field_mapping.rb
@@ -0,0 +1,62 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Return the mapping definition for specific field (or fields)
+        #
+        # @example Get mapping for a specific field across all indices
+        #
+        #     client.indices.get_field_mapping field: 'foo'
+        #
+        # @example Get mapping for a specific field in an index
+        #
+        #     client.indices.get_field_mapping index: 'foo', field: 'bar'
+        #
+        # @example Get mappings for multiple fields in an index
+        #
+        #     client.indices.get_field_mapping index: 'foo', field: ['bar', 'bam']
+        #
+        # @option arguments [List] :index A comma-separated list of index names
+        # @option arguments [List] :type  A comma-separated list of document types
+        # @option arguments [List] :field A comma-separated list of fields (*Required*)
+        # @option arguments [Boolean] :include_defaults Whether default mapping values should be returned as well
+        # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+        #                                               no concrete indices. (This includes `_all` string or when no
+        #                                               indices have been specified)
+        # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+        #                                              are open, closed or both. (options: open, closed)
+        # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+        #                                            `missing` ones (options: none, missing) @until 1.0
+        # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+        #                                                 unavailable (missing, closed, etc)
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-get-field-mapping.html
+        #
+        def get_field_mapping(arguments={})
+          raise ArgumentError, "Required argument 'field' missing" unless arguments[:field]
+          valid_params = [
+            :include_defaults,
+            :ignore_indices,
+            :ignore_unavailable,
+            :allow_no_indices,
+            :expand_wildcards
+          ]
+
+          method = 'GET'
+          path   = Utils.__pathify(
+                     Utils.__listify(arguments[:index]),
+                     '_mapping',
+                     Utils.__listify(arguments[:type]),
+                     'field',
+                     Utils.__listify(arguments[:field])
+                   )
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/get_mapping.rb b/lib/elasticsearch/api/actions/indices/get_mapping.rb
new file mode 100644
index 0000000..6e549c3
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/get_mapping.rb
@@ -0,0 +1,57 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Return the mapping definitions for all indices, or specific indices/types.
+        #
+        # @example Get all mappings in the cluster
+        #
+        #     client.indices.get_mapping
+        #
+        # @example Get mapping for a specific index
+        #
+        #     client.indices.get_mapping index: 'foo'
+        #
+        # @example Get mapping for a specific type in a specific index
+        #
+        #     client.indices.get_mapping index: 'foo', type: 'baz'
+        #
+        # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string for all indices
+        # @option arguments [List] :type A comma-separated list of document types
+        # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+        #                                               no concrete indices. (This includes `_all` string or when no
+        #                                               indices have been specified)
+        # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+        #                                              are open, closed or both. (options: open, closed)
+        # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+        #                                            `missing` ones (options: none, missing) @until 1.0
+        # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+        #                                                 unavailable (missing, closed, etc)
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+        #                                    (default: false)
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-get-mapping.html
+        #
+        def get_mapping(arguments={})
+          valid_params = [
+            :ignore_indices,
+            :ignore_unavailable,
+            :allow_no_indices,
+            :expand_wildcards,
+            :local
+          ]
+
+          method = 'GET'
+          path   = Utils.__pathify Utils.__listify(arguments[:index]),
+                                   '_mapping',
+                                   Utils.__listify(arguments[:type])
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/get_settings.rb b/lib/elasticsearch/api/actions/indices/get_settings.rb
new file mode 100644
index 0000000..727b0b0
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/get_settings.rb
@@ -0,0 +1,68 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Return the settings for all indices, or a list of indices.
+        #
+        # @example Get settings for all indices
+        #
+        #     client.indices.get_settings
+        #
+        # @example Get settings for the 'foo' index
+        #
+        #     client.indices.get_settings index: 'foo'
+        #
+        # @example Get settings for indices beginning with foo
+        #
+        #     client.indices.get_settings prefix: 'foo'
+        #
+        # @example Get settings for an index named _myindex_
+        #
+        #     client.indices.get_settings index: 'myindex'
+        #
+        # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string
+        #                                 to perform the operation on all indices
+        # @option arguments [List] :name The name of the settings that should be included in the response
+        # @option arguments [String] :prefix The prefix all settings must have in order to be included
+        # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+        #                                               no concrete indices. (This includes `_all` string or when no
+        #                                               indices have been specified)
+        # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+        #                                              are open, closed or both. (options: open, closed)
+        # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+        #                                            `missing` ones (options: none, missing) @until 1.0
+        # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+        #                                                 unavailable (missing, closed, etc)
+        # @option arguments [Boolean] :flat_settings Return settings in flat format (default: false)
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+        #                                    (default: false)
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-get-settings/
+        #
+        def get_settings(arguments={})
+          valid_params = [
+            :prefix,
+            :ignore_indices,
+            :ignore_unavailable,
+            :allow_no_indices,
+            :expand_wildcards,
+            :flat_settings,
+            :local
+          ]
+
+          method = 'GET'
+          path   = Utils.__pathify Utils.__listify(arguments[:index]),
+                                   Utils.__listify(arguments[:type]),
+                                   arguments.delete(:prefix),
+                                   '_settings',
+                                   Utils.__escape(arguments[:name])
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/get_template.rb b/lib/elasticsearch/api/actions/indices/get_template.rb
new file mode 100644
index 0000000..e77d46b
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/get_template.rb
@@ -0,0 +1,33 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Get a single index template.
+        #
+        # @example Get all templates
+        #
+        #     client.indices.get_template
+        #
+        # @example Get a template named _mytemplate_
+        #
+        #     client.indices.get_template name: 'mytemplate'
+        #
+        # @note Use the {Cluster::Actions#state} API to get a list of all templates.
+        #
+        # @option arguments [String] :name The name of the template (supports wildcards)
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-templates/
+        #
+        def get_template(arguments={})
+          method = 'GET'
+          path   = Utils.__pathify '_template', Utils.__escape(arguments[:name])
+          params = {}
+          body = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/get_warmer.rb b/lib/elasticsearch/api/actions/indices/get_warmer.rb
new file mode 100644
index 0000000..a61f4c3
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/get_warmer.rb
@@ -0,0 +1,59 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Get one or more warmers for an index.
+        #
+        # @example Get all warmers
+        #
+        #     client.indices.get_warmer index: '_all'
+        #
+        # @example Get all warmers matching a wildcard expression
+        #
+        #     client.indices.get_warmer index: '_all', name: 'ba*'
+        #
+        # @example Get all warmers for a single index
+        #
+        #     client.indices.get_warmer index: 'foo'
+        #
+        # @example Get a specific warmer
+        #
+        #     client.indices.get_warmer index: 'foo', name: 'bar'
+        #
+        # @option arguments [List] :index A comma-separated list of index names to restrict the operation;
+        #                                 use `_all` to perform the operation on all indices (*Required*)
+        # @option arguments [String] :name The name of the warmer (supports wildcards); leave empty to get all warmers
+        # @option arguments [List] :type A comma-separated list of document types to restrict the operation;
+        #                                leave empty to perform the operation on all types
+        # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+        #                                               no concrete indices. (This includes `_all` string or when no
+        #                                               indices have been specified)
+        # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+        #                                              are open, closed or both. (options: open, closed)
+        # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+        #                                            `missing` ones (options: none, missing) @until 1.0
+        # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+        #                                                 unavailable (missing, closed, etc)
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-warmers/
+        #
+        def get_warmer(arguments={})
+          valid_params = [
+            :ignore_indices,
+            :ignore_unavailable,
+            :allow_no_indices,
+            :expand_wildcards
+          ]
+
+          method = 'GET'
+          path   = Utils.__pathify( Utils.__listify(arguments[:index]), '_warmer', Utils.__escape(arguments[:name]) )
+          params = {}
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/open.rb b/lib/elasticsearch/api/actions/indices/open.rb
new file mode 100644
index 0000000..508585b
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/open.rb
@@ -0,0 +1,48 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Open a previously closed index (see the {Indices::Actions#close} API).
+        #
+        # @example Open index named _myindex_
+        #
+        #     client.indices.open index: 'myindex'
+        #
+        # @option arguments [String] :index The name of the index (*Required*)
+        # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+        #                                               no concrete indices. (This includes `_all` string or when no
+        #                                               indices have been specified)
+        # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+        #                                              are open, closed or both. (options: open, closed)
+        # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+        #                                            `missing` ones (options: none, missing) @until 1.0
+        # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+        #                                                 unavailable (missing, closed, etc)
+        # @option arguments [Time] :timeout Explicit operation timeout
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-open-close/
+        #
+        def open(arguments={})
+          raise ArgumentError, "Required argument 'index' missing" unless arguments[:index]
+
+          valid_params = [
+            :ignore_indices,
+            :ignore_unavailable,
+            :allow_no_indices,
+            :expand_wildcards,
+            :timeout
+          ]
+
+          method = 'POST'
+          path   = Utils.__pathify Utils.__escape(arguments[:index]), '_open'
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/optimize.rb b/lib/elasticsearch/api/actions/indices/optimize.rb
new file mode 100644
index 0000000..8325966
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/optimize.rb
@@ -0,0 +1,72 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Perform an index optimization.
+        #
+        # The "optimize" operation merges the index segments, increasing search performance.
+        # It corresponds to a Lucene "merge" operation.
+        #
+        # @example Fully optimize an index (merge to one segment)
+        #
+        #     client.indices.optimize index: 'foo', max_num_segments: 1, wait_for_merge: false
+        #
+        # @note The optimize operation is handled automatically by Elasticsearch, you don't need to perform it manually.
+        #       The operation is expensive in terms of resources (I/O, CPU, memory) and can take a long time to
+        #       finish, potentially reducing operability of your cluster; schedule the manual optimization accordingly.
+        #
+        # @option arguments [List] :index A comma-separated list of index names; use `_all`
+        #                                 or empty string to perform the operation on all indices
+        # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+        #                                               no concrete indices. (This includes `_all` string or when no
+        #                                               indices have been specified)
+        # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+        #                                              are open, closed or both. (options: open, closed)
+        # @option arguments [Boolean] :flush Specify whether the index should be flushed after performing the operation
+        #                                    (default: true)
+        # @option arguments [Boolean] :force Force a merge operation to run, even when the index has a single segment
+        #                                    (default: true)
+        # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+        #                                            `missing` ones (options: none, missing) @until 1.0
+        # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+        #                                                 unavailable (missing, closed, etc)
+        # @option arguments [Number] :max_num_segments The number of segments the index should be merged into
+        #                                              (default: dynamic)
+        # @option arguments [Time] :master_timeout Specify timeout for connection to master
+        # @option arguments [Boolean] :only_expunge_deletes Specify whether the operation should only expunge
+        #                                                   deleted documents
+        # @option arguments [Boolean] :refresh Specify whether the index should be refreshed after performing the operation
+        #                                      (default: true)
+        # @option arguments [Boolean] :wait_for_merge Specify whether the request should block until the merge process
+        #                                             is finished (default: true)
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-optimize/
+        #
+        def optimize(arguments={})
+          valid_params = [
+            :ignore_indices,
+            :ignore_unavailable,
+            :allow_no_indices,
+            :expand_wildcards,
+            :flush,
+            :force,
+            :master_timeout,
+            :max_num_segments,
+            :only_expunge_deletes,
+            :operation_threading,
+            :refresh,
+            :wait_for_merge ]
+
+          method = 'POST'
+          path   = Utils.__pathify Utils.__listify(arguments[:index]), '_optimize'
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/put_alias.rb b/lib/elasticsearch/api/actions/indices/put_alias.rb
new file mode 100644
index 0000000..ed84c75
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/put_alias.rb
@@ -0,0 +1,41 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Create or update a single index alias.
+        #
+        # @example Create an alias for current month
+        #
+        #     client.indices.put_alias index: 'logs-2013-06', name: 'current-month'
+        #
+        # @example Create an alias for multiple indices
+        #
+        #     client.indices.put_alias index: 'logs-2013-06', name: 'year-2013'
+        #     client.indices.put_alias index: 'logs-2013-05', name: 'year-2013'
+        #
+        # See the {Indices::Actions#update_aliases} for performing operations with index aliases in bulk.
+        #
+        # @option arguments [String] :index The name of the index with an alias
+        # @option arguments [String] :name The name of the alias to be created or updated
+        # @option arguments [Hash] :body The settings for the alias, such as `routing` or `filter`
+        # @option arguments [Time] :timeout Explicit timestamp for the document
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-aliases/
+        #
+        def put_alias(arguments={})
+          raise ArgumentError, "Required argument 'name' missing"  unless arguments[:name]
+          valid_params = [ :timeout ]
+
+          method = 'PUT'
+          path   = Utils.__pathify Utils.__escape(arguments[:index]), '_alias', Utils.__escape(arguments[:name])
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = arguments[:body]
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/put_mapping.rb b/lib/elasticsearch/api/actions/indices/put_mapping.rb
new file mode 100644
index 0000000..c9ae2ba
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/put_mapping.rb
@@ -0,0 +1,73 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Create or update mapping.
+        #
+        # Pass the mapping definition(s) in the `:body` argument.
+        #
+        # @example Create or update a mapping for a specific document type
+        #
+        #     client.indices.put_mapping index: 'myindex', type: 'mytype', body: {
+        #       mytype: {
+        #         properties: {
+        #           title: { type: 'string', analyzer: 'snowball' }
+        #         }
+        #       }
+        #     }
+        #
+        # @example Update the mapping for a specific type in all indices
+        #
+        #     client.indices.put_mapping type: 'mytype', body: {
+        #       mytype: {
+        #         dynamic: 'strict'
+        #       }
+        #     }
+        #
+        # @option arguments [Hash] :body The mapping definition (*Required*)
+        # @option arguments [List] :index A comma-separated list of index names; use `_all` or omit to
+        #                                 update the mapping for all indices
+        # @option arguments [String] :type The name of the document type (*Required*)
+        # @option arguments [Boolean] :ignore_conflicts Specify whether to ignore conflicts while updating the mapping
+        #                                               (default: false)
+        # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+        #                                               no concrete indices. (This includes `_all` string or when no
+        #                                               indices have been specified)
+        # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+        #                                              are open, closed or both. (options: open, closed)
+        # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+        #                                            `missing` ones (options: none, missing) @until 1.0
+        # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+        #                                                 unavailable (missing, closed, etc)
+        # @option arguments [Time] :master_timeout Specify timeout for connection to master
+        # @option arguments [Time] :timeout Explicit operation timeout
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-put-mapping/
+        #
+        def put_mapping(arguments={})
+          raise ArgumentError, "Required argument 'type' missing"  unless arguments[:type]
+          raise ArgumentError, "Required argument 'body' missing"  unless arguments[:body]
+
+          valid_params = [
+            :ignore_conflicts,
+            :ignore_indices,
+            :ignore_unavailable,
+            :allow_no_indices,
+            :expand_wildcards,
+            :master_timeout,
+            :timeout
+          ]
+
+          method = 'PUT'
+          path   = Utils.__pathify Utils.__listify(arguments[:index]), '_mapping', Utils.__escape(arguments[:type])
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = arguments[:body]
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/put_settings.rb b/lib/elasticsearch/api/actions/indices/put_settings.rb
new file mode 100644
index 0000000..25004d0
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/put_settings.rb
@@ -0,0 +1,66 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Update the settings for one or multiple indices.
+        #
+        # @example Change the number of replicas for all indices
+        #
+        #     client.indices.put_settings body: { index: { number_of_replicas: 0 } }
+        #
+        #
+        # @example Change the number of replicas for a specific index
+        #
+        #     client.indices.put_settings index: 'myindex', body: { index: { number_of_replicas: 0 } }
+        #
+        #
+        # @example Disable "flush" for all indices
+        #
+        #     client.indices.put_settings body: { 'index.translog.disable_flush' => true }
+        #
+        # @example Allocate specific index on specific nodes
+        #
+        #     client.indices.put_settings index: 'my-big-index',
+        #                                 body: { 'index.routing.allocation.require.tag' => 'bigbox' }
+        #
+        # @option arguments [Hash] :body The index settings to be updated (*Required*)
+        # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string
+        #                                to perform the operation on all indices
+        # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+        #                                               no concrete indices. (This includes `_all` string or when no
+        #                                               indices have been specified)
+        # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+        #                                              are open, closed or both. (options: open, closed)
+        # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+        #                                            `missing` ones (options: none, missing) @until 1.0
+        # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+        #                                                 unavailable (missing, closed, etc)
+        # @option arguments [Time] :master_timeout Specify timeout for connection to master
+        # @option arguments [Boolean] :flat_settings Return settings in flat format (default: false)
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-update-settings/
+        #
+        def put_settings(arguments={})
+          raise ArgumentError, "Required argument 'body' missing" unless arguments[:body]
+
+          valid_params = [
+            :ignore_indices,
+            :ignore_unavailable,
+            :allow_no_indices,
+            :expand_wildcards,
+            :master_timeout,
+            :flat_settings
+          ]
+
+          method = 'PUT'
+          path   = Utils.__pathify Utils.__listify(arguments[:index]), '_settings'
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = arguments[:body]
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/put_template.rb b/lib/elasticsearch/api/actions/indices/put_template.rb
new file mode 100644
index 0000000..7979f28
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/put_template.rb
@@ -0,0 +1,40 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Create or update an index template.
+        #
+        # @example Create a template for all indices starting with `logs-`
+        #
+        #     client.indices.put_template name: 'foo',
+        #                                 body: { template: 'logs-*', settings: { 'index.number_of_shards' => 1 } }
+        #
+        # @option arguments [String] :name The name of the template (*Required*)
+        # @option arguments [Hash] :body The template definition (*Required*)
+        # @option arguments [Boolean] :create Whether the index template should only be added for a new one, #                                     or can also replace an existing one (default: false)
+        # @option arguments [Number] :order The order for this template when merging multiple matching ones
+        #                                   (higher numbers are merged later, overriding the lower numbers)
+        # @option arguments [Time] :timeout Explicit operation timeout
+        # @option arguments [Time] :master_timeout Specify timeout for connection to master
+        # @option arguments [Boolean] :flat_settings Return settings in flat format (default: false)
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-templates/
+        #
+        def put_template(arguments={})
+          raise ArgumentError, "Required argument 'name' missing" unless arguments[:name]
+          raise ArgumentError, "Required argument 'body' missing" unless arguments[:body]
+          valid_params = [ :create, :order, :timeout ]
+
+          method = 'PUT'
+          path   = Utils.__pathify '_template', Utils.__escape(arguments[:name])
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = arguments[:body]
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/put_warmer.rb b/lib/elasticsearch/api/actions/indices/put_warmer.rb
new file mode 100644
index 0000000..eef7229
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/put_warmer.rb
@@ -0,0 +1,64 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Create or update an index warmer.
+        #
+        # An index warmer will run before an index is refreshed, ie. available for search.
+        # It allows you to register "heavy" queries with popular filters, facets or sorts,
+        # increasing performance when the index is searched for the first time.
+        #
+        # @example Register a warmer which will populate the caches for `published` filter and sorting on `created_at`
+        #
+        #     client.indices.put_warmer index: 'myindex',
+        #                               name: 'main',
+        #                               body: {
+        #                                 query: { filtered: { filter: { term: { published: true } } } },
+        #                                 sort:  [ "created_at" ]
+        #                               }
+        #
+        # @option arguments [List] :index A comma-separated list of index names to register the warmer for; use `_all`
+        #                                 or empty string to perform the operation on all indices (*Required*)
+        # @option arguments [String] :name The name of the warmer (*Required*)
+        # @option arguments [List] :type A comma-separated list of document types to register the warmer for;
+        #                                leave empty to perform the operation on all types
+        # @option arguments [Hash] :body The search request definition for the warmer
+        #                                (query, filters, facets, sorting, etc) (*Required*)
+        # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+        #                                               no concrete indices. (This includes `_all` string or when no
+        #                                               indices have been specified)
+        # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+        #                                              are open, closed or both. (options: open, closed)
+        # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+        #                                            `missing` ones (options: none, missing) @until 1.0
+        # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+        #                                                 unavailable (missing, closed, etc)
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-warmers/
+        #
+        def put_warmer(arguments={})
+          raise ArgumentError, "Required argument 'name' missing"  unless arguments[:name]
+          raise ArgumentError, "Required argument 'body' missing"  unless arguments[:body]
+
+          valid_params = [
+            :ignore_indices,
+            :ignore_unavailable,
+            :allow_no_indices,
+            :expand_wildcards
+          ]
+
+          method = 'PUT'
+          path   = Utils.__pathify( Utils.__listify(arguments[:index]),
+                                    Utils.__listify(arguments[:type]),
+                                    '_warmer',
+                                    Utils.__listify(arguments[:name]) )
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = arguments[:body]
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/recovery.rb b/lib/elasticsearch/api/actions/indices/recovery.rb
new file mode 100644
index 0000000..0688530
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/recovery.rb
@@ -0,0 +1,42 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Return information about shard recovery for one or more indices
+        #
+        # @example Get recovery information for a single index
+        #
+        #     client.indices.recovery index: 'foo'
+        #
+        # @example Get detailed recovery information for multiple indices
+        #
+        #     client.indices.recovery index: ['foo', 'bar'], detailed: true
+        #
+        # @example Get recovery information for all indices
+        #
+        #     client.indices.recovery
+        #
+        # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string to perform the operation on all indices
+        # @option arguments [Boolean] :detailed Whether to display detailed information about shard recovery
+        # @option arguments [Boolean] :active_only Display only those recoveries that are currently on-going
+        # @option arguments [Boolean] :human Whether to return time and byte values in human readable format
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/indices-recovery.html
+        #
+        def recovery(arguments={})
+          valid_params = [
+            :detailed,
+            :active_only,
+            :human ]
+          method = 'GET'
+          path   = Utils.__pathify Utils.__listify(arguments[:index]), '_recovery'
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/refresh.rb b/lib/elasticsearch/api/actions/indices/refresh.rb
new file mode 100644
index 0000000..dcb70e5
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/refresh.rb
@@ -0,0 +1,54 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Refresh the index and to make the changes (creates, updates, deletes) searchable.
+        #
+        # By default, Elasticsearch has a delay of 1 second until changes to an index are
+        # available for search; the delay is configurable, see {Indices::Actions#put_settings}.
+        #
+        # You can trigger this operation explicitely, for example when performing a sequence of commands
+        # in integration tests, or when you need to perform a manual "synchronization" of the index
+        # with an external system at given moment.
+        #
+        # @example Refresh an index named _myindex_
+        #
+        #     client.indices.refresh index: 'myindex'
+        #
+        # @note The refresh operation can adversely affect indexing throughput when used too frequently.
+        #
+        # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string
+        #                                 to perform the operation on all indices
+        # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+        #                                               no concrete indices. (This includes `_all` string or when no
+        #                                               indices have been specified)
+        # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+        #                                              are open, closed or both. (options: open, closed)
+        # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+        #                                            `missing` ones (options: none, missing) @until 1.0
+        # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+        #                                                 unavailable (missing, closed, etc)
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-refresh/
+        #
+        def refresh(arguments={})
+          valid_params = [
+            :ignore_indices,
+            :ignore_unavailable,
+            :allow_no_indices,
+            :expand_wildcards
+          ]
+
+          method = 'POST'
+          path   = Utils.__pathify Utils.__listify(arguments[:index]), '_refresh'
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/segments.rb b/lib/elasticsearch/api/actions/indices/segments.rb
new file mode 100644
index 0000000..9b2d244
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/segments.rb
@@ -0,0 +1,44 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Return information about segments for one or more indices.
+        #
+        # The response contains information about segment size, number of documents, deleted documents, etc.
+        # See also {Indices::Actions#optimize}.
+        #
+        # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string
+        #                                 to perform the operation on all indices
+        # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+        #                                               no concrete indices. (This includes `_all` string or when no
+        #                                               indices have been specified)
+        # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+        #                                              are open, closed or both. (options: open, closed)
+        # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+        #                                            `missing` ones (options: none, missing) @until 1.0
+        # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+        #                                                 unavailable (missing, closed, etc)
+        #
+        # @see http://elasticsearch.org/guide/reference/api/admin-indices-segments/
+        #
+        def segments(arguments={})
+          valid_params = [
+            :ignore_indices,
+            :ignore_unavailable,
+            :allow_no_indices,
+            :expand_wildcards
+          ]
+
+          method = 'GET'
+          path   = Utils.__pathify Utils.__listify(arguments[:index]), '_segments'
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/snapshot_index.rb b/lib/elasticsearch/api/actions/indices/snapshot_index.rb
new file mode 100644
index 0000000..4b37855
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/snapshot_index.rb
@@ -0,0 +1,43 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # When using the shared storage gateway, manually trigger the snapshot operation.
+        #
+        # @deprecated The shared gateway has been deprecated [https://github.com/elasticsearch/elasticsearch/issues/2458]
+        #
+        # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string
+        #                                to perform the operation on all indices
+        # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+        #                                               no concrete indices. (This includes `_all` string or when no
+        #                                               indices have been specified)
+        # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+        #                                              are open, closed or both. (options: open, closed)
+        # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+        #                                            `missing` ones (options: none, missing) @until 1.0
+        # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+        #                                                 unavailable (missing, closed, etc)
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-gateway-snapshot/
+        #
+        def snapshot_index(arguments={})
+          valid_params = [
+            :ignore_indices,
+            :ignore_unavailable,
+            :allow_no_indices,
+            :expand_wildcards
+          ]
+
+          method = 'POST'
+          path   = Utils.__pathify Utils.__listify(arguments[:index]), '_gateway/snapshot'
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/stats.rb b/lib/elasticsearch/api/actions/indices/stats.rb
new file mode 100644
index 0000000..4917b65
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/stats.rb
@@ -0,0 +1,120 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Return statistical information about one or more indices.
+        #
+        # The response contains comprehensive statistical information about metrics related to index:
+        # how much time did indexing, search and other operations take, how much disk space it takes,
+        # how much memory filter caches or field data require, etc.
+        #
+        # @example Get all available statistics for all indices
+        #
+        #     client.indices.stats
+        #
+        # @example Get statistics for a single index
+        #
+        #     client.indices.stats index: 'foo'
+        #
+        # @example Get statistics about documents and disk size for multiple indices
+        #
+        #     client.indices.stats index: ['foo', 'bar'], docs: true, store: true
+        #
+        # @example Get statistics about filter cache and field data for all fields
+        #
+        #     client.indices.stats fielddata: true, filter_cache: true
+        #
+        # @example Get statistics about filter cache and field data for specific fields
+        #
+        #     client.indices.stats fielddata: true, filter_cache: true, fields: 'created_at,tags'
+        #
+        # @example Get statistics about filter cache and field data per field for all fields
+        #
+        #     client.indices.stats fielddata: true, filter_cache: true, fields: '*'
+        #
+        # @example Get statistics about searches, with segmentation for different search groups
+        #
+        #     client.indices.stats search: true, groups: ['groupA', 'groupB']
+        #
+        # @option arguments [Boolean] :docs Return information about indexed and deleted documents
+        # @option arguments [Boolean] :fielddata Return information about field data
+        # @option arguments [Boolean] :fields A comma-separated list of fields for `fielddata` metric (supports wildcards)
+        # @option arguments [Boolean] :filter_cache Return information about filter cache
+        # @option arguments [Boolean] :flush Return information about flush operations
+        # @option arguments [Boolean] :get Return information about get operations
+        # @option arguments [Boolean] :groups A comma-separated list of search groups for `search` statistics
+        # @option arguments [Boolean] :id_cache Return information about ID cache
+        # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string
+        #                                 to perform the operation on all indices
+        # @option arguments [Boolean] :indexing Return information about indexing operations
+        # @option arguments [String] :level Return stats aggregated at cluster, index or shard level
+        #                                   (Options: cluster, indices, shards)
+        # @option arguments [List] :types A comma-separated list of document types to include in the `indexing` info
+        # @option arguments [Boolean] :merge Return information about merge operations
+        # @option arguments [List] :metric Limit the information returned the specific metrics
+        #                                  (_all, completion, docs, fielddata, filter_cache, flush, get,
+        #                                  id_cache, indexing, merge, percolate, refresh, search, segments,
+        #                                  store, warmer, suggest)
+        # @option arguments [Boolean] :refresh Return information about refresh operations
+        # @option arguments [Boolean] :search Return information about search operations; use the `groups` parameter to
+        #                                     include information for specific search groups
+        # @option arguments [List] :groups A comma-separated list of search groups to include in the `search` statistics
+        # @option arguments [Boolean] :suggest Return information about suggest statistics
+        # @option arguments [Boolean] :store Return information about the size of the index
+        # @option arguments [Boolean] :warmer Return information about warmers
+        # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+        #                                                 unavailable (missing, closed, etc)
+        # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+        #                                               no concrete indices. (This includes `_all` string or when no
+        #                                               indices have been specified)
+        # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+        #                                              are open, closed or both. (options: open, closed)
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-stats.html
+        #
+        def stats(arguments={})
+          valid_parts = [
+            :docs,
+            :fielddata,
+            :filter_cache,
+            :flush,
+            :get,
+            :indexing,
+            :merge,
+            :metric,
+            :refresh,
+            :search,
+            :suggest,
+            :store,
+            :warmer ]
+
+          valid_params = [
+            :fields,
+            :completion_fields,
+            :fielddata_fields,
+            :groups,
+            :level,
+            :types,
+            :ignore_indices,
+            :ignore_unavailable,
+            :allow_no_indices,
+            :expand_wildcards ]
+
+          method = 'GET'
+
+          parts  = Utils.__extract_parts arguments, valid_parts
+          path   = Utils.__pathify Utils.__listify(arguments[:index]), '_stats', Utils.__listify(parts)
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          params[:fields] = Utils.__listify(params[:fields]) if params[:fields]
+          params[:groups] = Utils.__listify(params[:groups]) if params[:groups]
+
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/status.rb b/lib/elasticsearch/api/actions/indices/status.rb
new file mode 100644
index 0000000..e7cedc5
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/status.rb
@@ -0,0 +1,56 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Return information about one or more indices
+        #
+        # @example Get information about all indices
+        #
+        #     client.indices.status
+        #
+        # @example Get information about a specific index
+        #
+        #     client.indices.status index: 'foo'
+        #
+        # @example Get information about shard recovery for a specific index
+        #
+        #     client.indices.status index: 'foo', recovery: true
+        #
+        # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string
+        #                                 to perform the operation on all indices
+        # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+        #                                               no concrete indices. (This includes `_all` string or when no
+        #                                               indices have been specified)
+        # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+        #                                              are open, closed or both. (options: open, closed)
+        # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+        #                                            `missing` ones (options: none, missing) @until 1.0
+        # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+        #                                                 unavailable (missing, closed, etc)
+        # @option arguments [Boolean] :recovery Return information about shard recovery (progress, size, etc)
+        # @option arguments [Boolean] :snapshot Return information about snapshots (when shared gateway is used)
+        #
+        # @see http://elasticsearch.org/guide/reference/api/admin-indices-status/
+        #
+        def status(arguments={})
+          valid_params = [
+            :ignore_indices,
+            :ignore_unavailable,
+            :allow_no_indices,
+            :expand_wildcards,
+            :recovery,
+            :snapshot ]
+
+          method = 'GET'
+          path   = Utils.__pathify Utils.__listify(arguments[:index]), '_status'
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/update_aliases.rb b/lib/elasticsearch/api/actions/indices/update_aliases.rb
new file mode 100644
index 0000000..a1f9050
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/update_aliases.rb
@@ -0,0 +1,48 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Perform multiple operation on index aliases in a single request.
+        #
+        # Pass the `actions` (add, remove) in the `body` argument.
+        #
+        # @example Add multiple indices to a single alias
+        #
+        #     client.indices.update_aliases body: {
+        #       actions: [
+        #         { add: { index: 'logs-2013-06', alias: 'year-2013' } },
+        #         { add: { index: 'logs-2013-05', alias: 'year-2013' } }
+        #       ]
+        #     }
+        #
+        # @example Swap an alias (atomic operation)
+        #
+        #     client.indices.update_aliases body: {
+        #       actions: [
+        #         { remove: { index: 'logs-2013-06', alias: 'current-month' } },
+        #         { add:    { index: 'logs-2013-07', alias: 'current-month' } }
+        #       ]
+        #     }
+        #
+        # @option arguments [Hash] :body The operations definition and other configuration (*Required*)
+        # @option arguments [Time] :timeout Explicit operation timeout
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-indices-aliases/
+        #
+        def update_aliases(arguments={})
+          raise ArgumentError, "Required argument 'body' missing" unless arguments[:body]
+          valid_params = [ :timeout ]
+
+          method = 'POST'
+          path   = "_aliases"
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = arguments[:body]
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/indices/validate_query.rb b/lib/elasticsearch/api/actions/indices/validate_query.rb
new file mode 100644
index 0000000..4158633
--- /dev/null
+++ b/lib/elasticsearch/api/actions/indices/validate_query.rb
@@ -0,0 +1,80 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions
+
+        # Validate a query
+        #
+        # @example Validate a simple query string query
+        #
+        #     client.indices.validate_query index: 'myindex', q: 'title:foo AND body:bar'
+        #
+        # @example Validate an invalid query (with explanation)
+        #
+        #     client.indices.validate_query index: 'myindex', q: '[[[ BOOM! ]]]', explain: true
+        #
+        # @example Validate a DSL query (with explanation)
+        #
+        #     client.indices.validate_query index: 'myindex',
+        #                                   explain: true,
+        #                                   body: {
+        #                                     filtered: {
+        #                                       query: {
+        #                                         match: {
+        #                                           title: 'foo'
+        #                                         }
+        #                                       },
+        #                                       filter: {
+        #                                         range: {
+        #                                           published_at: {
+        #                                             from: '2013-06-01'
+        #                                           }
+        #                                         }
+        #                                       }
+        #                                     }
+        #                                   }
+        #
+        # @option arguments [List] :index A comma-separated list of index names to restrict the operation;
+        #                                 use `_all` or empty string to perform the operation on all indices
+        # @option arguments [List] :type A comma-separated list of document types to restrict the operation;
+        #                                leave empty to perform the operation on all types
+        # @option arguments [Hash] :body The query definition (*without* the top-level `query` element)
+        # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+        #                                               no concrete indices. (This includes `_all` string or when no
+        #                                               indices have been specified)
+        # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that
+        #                                              are open, closed or both. (options: open, closed)
+        # @option arguments [Boolean] :explain Return detailed information about the error
+        # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore
+        #                                            `missing` ones (options: none, missing) @until 1.0
+        # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+        #                                                 unavailable (missing, closed, etc)
+        # @option arguments [String] :source The URL-encoded query definition (instead of using the request body)
+        # @option arguments [String] :q Query in the Lucene query string syntax
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/validate/
+        #
+        def validate_query(arguments={})
+          valid_params = [
+            :q,
+            :explain,
+            :ignore_indices,
+            :ignore_unavailable,
+            :allow_no_indices,
+            :expand_wildcards,
+            :source ]
+
+          method = 'GET'
+          path   = Utils.__pathify Utils.__listify(arguments[:index]),
+                                   Utils.__listify(arguments[:type]),
+                                   '_validate/query'
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = arguments[:body]
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/info.rb b/lib/elasticsearch/api/actions/info.rb
new file mode 100644
index 0000000..1424301
--- /dev/null
+++ b/lib/elasticsearch/api/actions/info.rb
@@ -0,0 +1,19 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Return simple information about the cluster (name, version).
+      #
+      # @see http://elasticsearch.org/guide/
+      #
+      def info(arguments={})
+        method = 'GET'
+        path   = ""
+        params = {}
+        body   = nil
+
+        perform_request(method, path, params, body).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/list_benchmarks.rb b/lib/elasticsearch/api/actions/list_benchmarks.rb
new file mode 100644
index 0000000..da7d280
--- /dev/null
+++ b/lib/elasticsearch/api/actions/list_benchmarks.rb
@@ -0,0 +1,29 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Return a list of running benchmarks
+      #
+      # @example
+      #
+      #     client.list_benchmarks
+      #
+      # @option arguments [List] :index A comma-separated list of index names; use `_all` or empty string
+      #                                 to perform the operation on all indices
+      # @option arguments [String] :type The name of the document type
+      #
+      # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/search-benchmark.html
+      #
+      def list_benchmarks(arguments={})
+        valid_params = [
+           ]
+        method = 'GET'
+        path   = "_bench"
+        params = {}
+        body   = nil
+
+        perform_request(method, path, params, body).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/mget.rb b/lib/elasticsearch/api/actions/mget.rb
new file mode 100644
index 0000000..fb32e69
--- /dev/null
+++ b/lib/elasticsearch/api/actions/mget.rb
@@ -0,0 +1,74 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Return multiple documents from one or more indices in a single request.
+      #
+      # Pass the request definition in the `:body` argument, either as an Array of `docs` specifications,
+      # or `ids`, when the `:index` and document `:type` are specified.
+      #
+      # @example Get multiple documents fully specified in the `docs` definition
+      #
+      #     client.mget body: {
+      #       docs: [
+      #         { _index: 'myindex', _type: 'mytype', _id: '1' },
+      #         { _index: 'myindex', _type: 'mytype', _id: '2' },
+      #         { _index: 'myindex', _type: 'mytype', _id: '3' }
+      #       ]
+      #     }
+      #
+      # @example Get multiple documents specified by `ids` while passing `:index` and `:type`
+      #
+      #     client.mget index: 'myindex', type: 'mytype', body: { ids: ['1', '2', '3'] }
+      #
+      # @example Get only specific fields from documents
+      #
+      #     client.mget index: 'myindex', type: 'mytype', body: { ids: ['1', '2', '3'] }, fields: ['title']
+      #
+      # @option arguments [String] :index The name of the index
+      # @option arguments [String] :type The type of the document
+      # @option arguments [Hash] :body Document identifiers; can be either `docs` (containing full document information)
+      #                                or `ids` (when index and type is provided in the URL (*Required*)
+      # @option arguments [List] :fields A comma-separated list of fields to return in the response
+      # @option arguments [String] :parent The ID of the parent document
+      # @option arguments [String] :preference Specify the node or shard the operation should be performed on
+      #                                        (default: random)
+      # @option arguments [Boolean] :realtime Specify whether to perform the operation in realtime or search mode
+      # @option arguments [Boolean] :refresh Refresh the shard containing the document before performing the operation
+      # @option arguments [String] :routing Specific routing value
+      # @option arguments [String] :_source Specify whether the _source field should be returned,
+      #                                     or a list of fields to return
+      # @option arguments [String] :_source_exclude A list of fields to exclude from the returned _source field
+      # @option arguments [String] :_source_include A list of fields to extract and return from the _source field
+      #
+      # @see http://elasticsearch.org/guide/reference/api/multi-get/
+      #
+      def mget(arguments={})
+        raise ArgumentError, "Required argument 'body' missing" unless arguments[:body]
+
+        valid_params = [
+          :fields,
+          :parent,
+          :preference,
+          :realtime,
+          :refresh,
+          :routing,
+          :_source,
+          :_source_include,
+          :_source_exclude ]
+
+        method = 'GET'
+        path   = Utils.__pathify Utils.__escape(arguments[:index]),
+                                 Utils.__escape(arguments[:type]),
+                                 '_mget'
+
+        params = Utils.__validate_and_extract_params arguments, valid_params
+        body   = arguments[:body]
+
+        params[:fields] = Utils.__listify(params[:fields]) if params[:fields]
+
+        perform_request(method, path, params, body).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/mlt.rb b/lib/elasticsearch/api/actions/mlt.rb
new file mode 100644
index 0000000..e169578
--- /dev/null
+++ b/lib/elasticsearch/api/actions/mlt.rb
@@ -0,0 +1,128 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Return documents similar to the specified one.
+      #
+      # Performs a `more_like_this` query with the specified document as the input.
+      #
+      # @example Search for similar documents using the `title` property of document `myindex/mytype/1`
+      #
+      #     # First, let's setup a synonym-aware analyzer ("quick" <=> "fast")
+      #     client.indices.create index: 'myindex', body: {
+      #       settings: {
+      #         analysis: {
+      #           filter: {
+      #             synonyms: {
+      #               type: 'synonym',
+      #               synonyms: [ "quick,fast" ]
+      #             }
+      #           },
+      #           analyzer: {
+      #             title_synonym: {
+      #               type: 'custom',
+      #               tokenizer: 'whitespace',
+      #               filter: ['lowercase', 'stop', 'snowball', 'synonyms']
+      #             }
+      #           }
+      #         }
+      #       },
+      #       mappings: {
+      #         mytype: {
+      #           properties: {
+      #             title: {
+      #               type: 'string',
+      #               analyzer: 'title_synonym'
+      #             }
+      #           }
+      #         }
+      #       }
+      #     }
+      #
+      #     # Index three documents
+      #     client.index index: 'myindex', type: 'mytype', id: 1, body: { title: 'Quick Brown Fox'   }
+      #     client.index index: 'myindex', type: 'mytype', id: 2, body: { title: 'Slow Black Dog'    }
+      #     client.index index: 'myindex', type: 'mytype', id: 3, body: { title: 'Fast White Rabbit' }
+      #     client.indices.refresh index: 'myindex'
+      #
+      #     client.mlt index: 'myindex', type: 'mytype', id: 1, mlt_fields: 'title', min_doc_freq: 1, min_term_freq: 1
+      #     # => { ... {"title"=>"Fast White Rabbit"}}]}}
+      #
+      # @option arguments [String] :id The document ID (*Required*)
+      # @option arguments [String] :index The name of the index (*Required*)
+      # @option arguments [String] :type The type of the document (use `_all` to fetch
+      #                                  the first document matching the ID across all types) (*Required*)
+      # @option arguments [Hash] :body A specific search request definition
+      # @option arguments [Number] :boost_terms The boost factor
+      # @option arguments [Number] :max_doc_freq The word occurrence frequency as count: words with higher occurrence
+      #                                          in the corpus will be ignored
+      # @option arguments [Number] :max_query_terms The maximum query terms to be included in the generated query
+      # @option arguments [Number] :max_word_len The minimum length of the word: longer words will be ignored
+      # @option arguments [Number] :min_doc_freq The word occurrence frequency as count: words with lower occurrence
+      #                                          in the corpus will be ignored
+      # @option arguments [Number] :min_term_freq The term frequency as percent: terms with lower occurence
+      #                                           in the source document will be ignored
+      # @option arguments [Number] :min_word_len The minimum length of the word: shorter words will be ignored
+      # @option arguments [List] :mlt_fields Specific fields to perform the query against
+      # @option arguments [Number] :percent_terms_to_match How many terms have to match in order to consider
+      #                                                    the document a match (default: 0.3)
+      # @option arguments [String] :routing Specific routing value
+      # @option arguments [Number] :search_from The offset from which to return results
+      # @option arguments [List] :search_indices A comma-separated list of indices to perform the query against
+      #                                          (default: the index containing the document)
+      # @option arguments [String] :search_query_hint The search query hint
+      # @option arguments [String] :search_scroll A scroll search request definition
+      # @option arguments [Number] :search_size The number of documents to return (default: 10)
+      # @option arguments [String] :search_source A specific search request definition (instead of using the request body)
+      # @option arguments [String] :search_type Specific search type (eg. `dfs_then_fetch`, `count`, etc)
+      # @option arguments [List] :search_types A comma-separated list of types to perform the query against
+      #                                        (default: the same type as the document)
+      # @option arguments [List] :stop_words A list of stop words to be ignored
+      #
+      # @see http://elasticsearch.org/guide/reference/api/more-like-this/
+      #
+      def mlt(arguments={})
+        raise ArgumentError, "Required argument 'index' missing" unless arguments[:index]
+        raise ArgumentError, "Required argument 'type' missing"  unless arguments[:type]
+        raise ArgumentError, "Required argument 'id' missing"    unless arguments[:id]
+
+        valid_params = [
+          :boost_terms,
+          :max_doc_freq,
+          :max_query_terms,
+          :max_word_len,
+          :min_doc_freq,
+          :min_term_freq,
+          :min_word_len,
+          :mlt_fields,
+          :percent_terms_to_match,
+          :routing,
+          :search_from,
+          :search_indices,
+          :search_query_hint,
+          :search_scroll,
+          :search_size,
+          :search_source,
+          :search_type,
+          :search_types,
+          :stop_words ]
+
+        method = 'GET'
+        path   = Utils.__pathify Utils.__escape(arguments[:index]),
+                                 Utils.__escape(arguments[:type]),
+                                 Utils.__escape(arguments[:id]),
+                                 '_mlt'
+
+        params = Utils.__validate_and_extract_params arguments, valid_params
+
+        [:mlt_fields, :search_indices, :search_types, :stop_words].each do |name|
+          params[name] = Utils.__listify(params[name]) if params[name]
+        end
+
+        body   = arguments[:body]
+
+        perform_request(method, path, params, body).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/mpercolate.rb b/lib/elasticsearch/api/actions/mpercolate.rb
new file mode 100644
index 0000000..79e87e1
--- /dev/null
+++ b/lib/elasticsearch/api/actions/mpercolate.rb
@@ -0,0 +1,58 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Perform multiple percolate operations in a single request, similar to the {#msearch} API
+      #
+      # Pass the percolate definitions as header-body pairs in the `:body` argument, as an Array of Hashes.
+      #
+      # @example Perform two different percolations in a single request
+      #
+      #     client.mpercolate \
+      #         body: [
+      #           { percolate: { index: "my-index", type: "my-type" } },
+      #           { doc: { message: "foo bar" } },
+      #           { percolate: { index: "my-other-index", type: "my-other-type", id: "1" } },
+      #           { }
+      #         ]
+      #
+      # @option arguments [String] :index The index of the document being count percolated to use as default
+      # @option arguments [String] :type The type of the document being percolated to use as default.
+      # @option arguments [Array<Hash>]  The percolate request definitions (header & body pairs) (*Required*)
+      # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+      #                                                 unavailable (missing or closed)
+      # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+      #                                               no concrete indices. (This includes `_all` string or when no
+      #                                               indices have been specified)
+      # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are
+      #                                              open, closed or both. (options: open, closed)
+      #
+      # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/search-percolate.html
+      #
+      def mpercolate(arguments={})
+        raise ArgumentError, "Required argument 'body' missing" unless arguments[:body]
+        valid_params = [
+          :ignore_unavailable,
+          :allow_no_indices,
+          :expand_wildcards ]
+
+        method = 'GET'
+        path   = "_mpercolate"
+
+        params = Utils.__validate_and_extract_params arguments, valid_params
+        body   = arguments[:body]
+
+        case
+        when body.is_a?(Array)
+          payload = body.map { |d| d.is_a?(String) ? d : MultiJson.dump(d) }
+          payload << "" unless payload.empty?
+          payload = payload.join("\n")
+        else
+          payload = body
+        end
+
+        perform_request(method, path, params, payload).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/msearch.rb b/lib/elasticsearch/api/actions/msearch.rb
new file mode 100644
index 0000000..3ff9837
--- /dev/null
+++ b/lib/elasticsearch/api/actions/msearch.rb
@@ -0,0 +1,74 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Perform multiple search operations in a single request.
+      #
+      # Pass the search definitions in the `:body` argument
+      #
+      # @example Perform multiple different searches as `:search`
+      #
+      #     client.msearch \
+      #       body: [
+      #         { search: { query: { match_all: {} } } },
+      #         { index: 'myindex', type: 'mytype', search: { query: { query_string: { query: '"Test 1"' } } } },
+      #         { search_type: 'count', search: { facets: { published: { terms: { field: 'published' } } } } }
+      #       ]
+      #
+      # @example Perform multiple different searches as an array of meta/data pairs
+      #
+      #     client.msearch \
+      #       body: [
+      #         { query: { match_all: {} } },
+      #         { index: 'myindex', type: 'mytype' },
+      #         { query: { query_string: { query: '"Test 1"' } } },
+      #         { search_type: 'count' },
+      #         { facets: { published: { terms: { field: 'published' } } } }
+      #       ]
+      #
+      # @option arguments [List] :index A comma-separated list of index names to use as default
+      # @option arguments [List] :type A comma-separated list of document types to use as default
+      # @option arguments [Array<Hash>] :body An array of request definitions, each definition is a Hash;
+      #                                       pass the search definition as a `:search` argument
+      # @option arguments [String] :search_type Search operation type (options: query_then_fetch, query_and_fetch,
+      #                                         dfs_query_then_fetch, dfs_query_and_fetch, count, scan)
+      #
+      # @see http://www.elasticsearch.org/guide/reference/api/multi-search/
+      #
+      def msearch(arguments={})
+        raise ArgumentError, "Required argument 'body' missing" unless arguments[:body]
+        valid_params = [ :search_type ]
+
+        method = 'GET'
+        path   = Utils.__pathify( Utils.__listify(arguments[:index]), Utils.__listify(arguments[:type]), '_msearch' )
+
+        params = Utils.__validate_and_extract_params arguments, valid_params
+        body   = arguments[:body]
+
+        case
+        when body.is_a?(Array) && body.any? { |d| d.has_key? :search }
+          payload = body.
+            inject([]) do |sum, item|
+              meta = item
+              data = meta.delete(:search)
+
+              sum << meta
+              sum << data
+              sum
+            end.
+            map { |item| MultiJson.dump(item) }
+          payload << "" unless payload.empty?
+          payload = payload.join("\n")
+        when body.is_a?(Array)
+          payload = body.map { |d| d.is_a?(String) ? d : MultiJson.dump(d) }
+          payload << "" unless payload.empty?
+          payload = payload.join("\n")
+        else
+          payload = body
+        end
+
+        perform_request(method, path, params, payload).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/mtermvectors.rb b/lib/elasticsearch/api/actions/mtermvectors.rb
new file mode 100644
index 0000000..1aed251
--- /dev/null
+++ b/lib/elasticsearch/api/actions/mtermvectors.rb
@@ -0,0 +1,67 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Returns information and statistics about terms in the fields of multiple documents
+      # in a single request/response. The semantics are similar to the {#mget} API.
+      #
+      # @example Return information about multiple documents in a specific index
+      #
+      #     subject.mtermvectors index: 'my-index', type: 'my-type', body: { ids: [1, 2, 3] }
+      #
+      # @option arguments [String] :index The name of the index
+      # @option arguments [String] :type The type of the document
+      # @option arguments [Hash] :body Document identifiers; can be either `docs` (containing full document information)
+      #                                or `ids` (when index and type is provided in the URL (*Required*)
+      # @option arguments [List] :ids A comma-separated list of documents ids (alternative to `:body`)
+      # @option arguments [Boolean] :term_statistics Whether total term frequency and
+      #                                              document frequency should be returned.
+      # @option arguments [Boolean] :field_statistics Whether document count, sum of document frequencies
+      #                                               and sum of total term frequencies should be returned.
+      # @option arguments [List] :fields A comma-separated list of fields to return
+      # @option arguments [Boolean] :offsets Whether term offsets should be returned
+      # @option arguments [Boolean] :positions Whether term positions should be returned
+      # @option arguments [Boolean] :payloads Whether term payloads should be returned
+      # @option arguments [String] :preference Specify the node or shard the operation should be performed on
+      #                                        (default: random)
+      # @option arguments [String] :routing Specific routing value
+      # @option arguments [String] :parent Parent ID of documents
+      #
+      # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/docs-multi-termvectors.html
+      #
+      # @see #mget
+      # @see #termvector
+      #
+      def mtermvectors(arguments={})
+        valid_params = [
+          :ids,
+          :term_statistics,
+          :field_statistics,
+          :fields,
+          :offsets,
+          :positions,
+          :payloads,
+          :preference,
+          :routing,
+          :parent ]
+
+        ids = arguments.delete(:ids)
+
+        method = 'GET'
+        path   = Utils.__pathify Utils.__escape(arguments[:index]),
+                                 Utils.__escape(arguments[:type]),
+                                 '_mtermvectors'
+
+        params = Utils.__validate_and_extract_params arguments, valid_params
+
+        if ids
+          body = { :ids => ids }
+        else
+          body = arguments[:body]
+        end
+
+        perform_request(method, path, params, body).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/nodes/hot_threads.rb b/lib/elasticsearch/api/actions/nodes/hot_threads.rb
new file mode 100644
index 0000000..523cbe6
--- /dev/null
+++ b/lib/elasticsearch/api/actions/nodes/hot_threads.rb
@@ -0,0 +1,46 @@
+module Elasticsearch
+  module API
+    module Nodes
+      module Actions
+
+        # Returns information about the hottest threads in the cluster or on a specific node as a String.
+        #
+        #
+        # The information is returned as text, and allows you to understand what are currently
+        # the most taxing operations happening in the cluster, for debugging or monitoring purposes.
+        #
+        # @example Return 10 hottest threads
+        #
+        #     client.nodes.hot_threads threads: 10
+        #
+        # @option arguments [List] :node_id A comma-separated list of node IDs or names to limit the returned information;
+        #                                   use `_local` to return information from the node you're connecting to,
+        #                                   leave empty to get information from all nodes
+        # @option arguments [Time] :interval The interval for the second sampling of threads
+        # @option arguments [Number] :snapshots Number of samples of thread stacktrace (default: 10)
+        # @option arguments [Number] :threads Specify the number of threads to provide information for (default: 3)
+        # @option arguments [String] :type The type to sample (default: cpu) (options: cpu, wait, block)
+        #
+        # @return [String]
+        #
+        # @see http://www.elasticsearch.org/guide/reference/api/admin-cluster-nodes-hot-threads/
+        #
+        def hot_threads(arguments={})
+          valid_params = [
+            :interval,
+            :snapshots,
+            :threads,
+            :type ]
+
+          method = 'GET'
+          path   = Utils.__pathify '_nodes', Utils.__listify(arguments[:node_id]), 'hot_threads'
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/nodes/info.rb b/lib/elasticsearch/api/actions/nodes/info.rb
new file mode 100644
index 0000000..0899cdf
--- /dev/null
+++ b/lib/elasticsearch/api/actions/nodes/info.rb
@@ -0,0 +1,61 @@
+module Elasticsearch
+  module API
+    module Nodes
+      module Actions
+
+        # Returns information about nodes in the cluster (cluster settings, JVM version, etc).
+        #
+        # Use the `all` option to return all available settings, or limit the information returned
+        # to a specific type (eg. `http`).
+        #
+        # Use the `node_id` option to limit information to specific node(s).
+        #
+        # @example Return information about JVM
+        #
+        #     client.nodes.info jvm: true
+        #
+        # @option arguments [List] :node_id A comma-separated list of node IDs or names to limit the returned information;
+        #                                   use `_local` to return information from the node you're connecting to, leave
+        #                                   empty to get information from all nodes
+        # @option arguments [Boolean] :_all Return all available information
+        # @option arguments [Boolean] :http Return information about HTTP
+        # @option arguments [Boolean] :jvm Return information about the JVM
+        # @option arguments [Boolean] :network Return information about network
+        # @option arguments [Boolean] :os Return information about the operating system
+        # @option arguments [Boolean] :plugins Return information about plugins
+        # @option arguments [Boolean] :process Return information about the Elasticsearch process
+        # @option arguments [Boolean] :settings Return information about node settings
+        # @option arguments [Boolean] :thread_pool Return information about the thread pool
+        # @option arguments [Boolean] :transport Return information about transport
+        #
+        # @see http://elasticsearch.org/guide/reference/api/admin-cluster-nodes-info/
+        #
+        def info(arguments={})
+          valid_parts = [
+            :_all,
+            :http,
+            :jvm,
+            :network,
+            :os,
+            :plugins,
+            :process,
+            :settings,
+            :thread_pool,
+            :transport ]
+
+          valid_params = []
+
+          method = 'GET'
+
+          parts  = Utils.__extract_parts arguments, valid_parts
+          path   = Utils.__pathify '_nodes', Utils.__listify(arguments[:node_id]), Utils.__listify(parts)
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/nodes/shutdown.rb b/lib/elasticsearch/api/actions/nodes/shutdown.rb
new file mode 100644
index 0000000..2b17ec1
--- /dev/null
+++ b/lib/elasticsearch/api/actions/nodes/shutdown.rb
@@ -0,0 +1,36 @@
+module Elasticsearch
+  module API
+    module Nodes
+      module Actions
+
+        # Shutdown one or all nodes
+        #
+        # @example Shut down node named _Bloke_
+        #
+        #     client.nodes.shutdown node_id: 'Bloke'
+        #
+        # @option arguments [List] :node_id A comma-separated list of node IDs or names to perform the operation on; use
+        #                                   `_local` to shutdown the node you're connected to, leave empty to
+        #                                   shutdown all nodes
+        # @option arguments [Time] :delay Set the delay for the operation (default: 1s)
+        # @option arguments [Boolean] :exit Exit the JVM as well (default: true)
+        #
+        # @see http://elasticsearch.org/guide/reference/api/admin-cluster-nodes-shutdown/
+        #
+        def shutdown(arguments={})
+          valid_params = [
+            :delay,
+            :exit ]
+
+          method = 'POST'
+          path   = Utils.__pathify '_cluster/nodes', Utils.__listify(arguments[:node_id]), '_shutdown'
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/nodes/stats.rb b/lib/elasticsearch/api/actions/nodes/stats.rb
new file mode 100644
index 0000000..5b2c0d6
--- /dev/null
+++ b/lib/elasticsearch/api/actions/nodes/stats.rb
@@ -0,0 +1,79 @@
+module Elasticsearch
+  module API
+    module Nodes
+      module Actions
+
+        # Returns statistical information about nodes in the cluster.
+        #
+        # @example Return statistics about JVM
+        #
+        #     client.nodes.stats metric: 'jvm'
+        #
+        # @example Return statistics about field data structures for all fields
+        #
+        #     client.nodes.stats metric: 'indices', index_metric: 'fielddata', fields: '*', human: true
+        #
+        # @option arguments [List] :metric Limit the information returned to the specified metrics
+        #                                  (options: _all, breaker, fs, http, indices, jvm, network,
+        #                                  os, process, thread_pool, transport)
+        # @option arguments [List] :index_metric Limit the information returned for the `indices` metric
+        #                                        to the specified index metrics. Used only when
+        #                                        `indices` or `all` metric is specified.
+        #                                  (options: _all, completion, docs, fielddata, filter_cache, flush, get,
+        #                                  id_cache, indexing, merge, percolate, refresh, search, segments, store,
+        #                                  warmer)
+        # @option arguments [List] :node_id A comma-separated list of node IDs or names to limit
+        #                                   the returned information; use `_local` to return information
+        #                                   from the node you're connecting to, leave empty to get information
+        #                                   from all nodes
+        # @option arguments [List] :completion_fields A comma-separated list of fields for `fielddata` and `suggest`
+        #                                             index metrics (supports wildcards)
+        # @option arguments [List] :fielddata_fields A comma-separated list of fields for `fielddata` index metric
+        #                                            (supports wildcards)
+        # @option arguments [List] :fields A comma-separated list of fields for `fielddata` and `completion` index
+        #                                  metrics (supports wildcards)
+        # @option arguments [Boolean] :groups A comma-separated list of search groups for `search` index metric
+        # @option arguments [Boolean] :human Whether to return time and byte values in human-readable format
+        # @option arguments [String] :level Specify the level for aggregating indices stats
+        #                                   (options: node, indices, shards)
+        # @option arguments [List] :types A comma-separated list of document types for the `indexing` index metric
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/cluster-nodes-stats.html
+        #
+        def stats(arguments={})
+          arguments = arguments.clone
+
+          valid_params = [
+            :metric,
+            :index_metric,
+            :node_id,
+            :completion_fields,
+            :fielddata_fields,
+            :fields,
+            :groups,
+            :human,
+            :level,
+            :types ]
+
+          method = 'GET'
+
+          path   = Utils.__pathify '_nodes',
+                                   Utils.__listify(arguments[:node_id]),
+                                   'stats',
+                                   Utils.__listify(arguments.delete(:metric)),
+                                   Utils.__listify(arguments.delete(:index_metric))
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+
+          [:completion_fields, :fielddata_fields, :fields, :groups, :types].each do |key|
+            params[key] = Utils.__listify(params[key]) if params[key]
+          end
+
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/percolate.rb b/lib/elasticsearch/api/actions/percolate.rb
new file mode 100644
index 0000000..5e3ea95
--- /dev/null
+++ b/lib/elasticsearch/api/actions/percolate.rb
@@ -0,0 +1,107 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Return names of queries matching a document.
+      #
+      # Percolator allows you to register queries and then evaluate a document against them:
+      # the IDs of matching queries are returned in the response.
+      #
+      # @example Register queries named "alert-1" and "alert-2" for the "my-index" index
+      #
+      #     client.index index: 'my-index',
+      #                  type: '.percolator',
+      #                  id: 'alert-1',
+      #                  body: { query: { query_string: { query: 'foo' } } }
+      #
+      #     client.index index: 'my-index',
+      #                  type: '.percolator',
+      #                  id: 'alert-2',
+      #                  body: { query: { query_string: { query: 'bar' } } }
+      #
+      # @example Evaluate a custom document (passed as `:doc`) against the queries
+      #
+      #     client.percolate index: 'my-index', body: { doc: { title: "Foo" } }
+      #     # => {..., matches: [ {_index: 'my-index', _id: 'alert-1'} ]}
+      #
+      #     client.percolate index: 'my-index', body: { doc: { title: "Foo Bar" } }
+      #     # => {..., matches: [ {_index: 'my-index', _id: 'alert-2'}, {_index: 'my-index', _id: 'alert-1'} ] }
+      #
+      # @example Evaluate an existing document against the queries
+      #
+      #     client.index index: 'my-index', type: 'my-type', id: 123, body: { title: "Foo Bar" }
+      #
+      #     client.percolate index: 'my-index', type: 'my-type', id: '123'
+      #     # => { ..., matches: [ {_index: 'my-index', _id: 'alert-2'}, { _index: 'my-index', _id: 'alert-1'} ] }
+      #
+      # @example Register a query with custom `priority` property
+      #
+      #     client.index index: 'my-index',
+      #                  type: '.percolator',
+      #                  id: 'alert-high-1',
+      #                  body: { query: { query_string: { query: 'foo' } },
+      #                          priority: 'high' }
+      #
+      # @example Evaluate a document against "high priority" percolator queries
+      #
+      #     client.percolate index: 'my-index', body: {
+      #         doc:    { title: "Foo" },
+      #         filter: { term: { priority: 'high' } }
+      #       }
+      #     # => {..., matches: [ {_index: 'my-index', _id: 'alert-high-1'} ]}
+      #
+      #
+      # @option arguments [String] :index The index of the document being percolated. (*Required*)
+      # @option arguments [String] :type The type of the document being percolated. (*Required*)
+      # @option arguments [String] :id Fetch the document specified by index/type/id and
+      #                                use it instead of the passed `doc`
+      # @option arguments [Hash] :body The percolator request definition using the percolate DSL
+      # @option arguments [List] :routing A comma-separated list of specific routing values
+      # @option arguments [String] :preference Specify the node or shard the operation should be performed on
+      #                                        (default: random)
+      # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+      #                                                 unavailable (missing or closed)
+      # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+      #                                               no concrete indices. (This includes `_all` string or when no
+      #                                               indices have been specified)
+      # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices that are
+      #                                              open, closed or both. (options: open, closed)
+      # @option arguments [String] :percolate_index The index to percolate the document into. Defaults to passed `index`.
+      # @option arguments [String] :percolate_format Return an array of matching query IDs instead of objects.
+      #                                              (options: ids)
+      # @option arguments [String] :percolate_type The type to percolate document into. Defaults to passed `type`.
+      # @option arguments [Number] :version Explicit version number for concurrency control
+      # @option arguments [String] :version_type Specific version type (options: internal, external, external_gte, force)
+      #
+      # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/search-percolate.html
+      #
+      def percolate(arguments={})
+        raise ArgumentError, "Required argument 'index' missing" unless arguments[:index]
+        raise ArgumentError, "Required argument 'type' missing"  unless arguments[:type]
+
+        valid_params = [
+          :routing,
+          :preference,
+          :ignore_unavailable,
+          :allow_no_indices,
+          :expand_wildcards,
+          :percolate_index,
+          :percolate_type,
+          :percolate_format,
+          :version,
+          :version_type ]
+
+        method = 'GET'
+        path   = Utils.__pathify Utils.__escape(arguments[:index]),
+                                 Utils.__escape(arguments[:type]),
+                                 arguments[:id],
+                                 '_percolate'
+
+        params = Utils.__validate_and_extract_params arguments, valid_params
+        body   = arguments[:body]
+
+        perform_request(method, path, params, body).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/ping.rb b/lib/elasticsearch/api/actions/ping.rb
new file mode 100644
index 0000000..9f4d8e6
--- /dev/null
+++ b/lib/elasticsearch/api/actions/ping.rb
@@ -0,0 +1,29 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Returns true if the cluster returns a sucessfull HTTP response, false otherwise.
+      #
+      # @example
+      #
+      #     client.ping
+      #
+      # @see http://elasticsearch.org/guide/
+      #
+      def ping(arguments={})
+        method = 'HEAD'
+        path   = ""
+        params = {}
+        body   = nil
+
+        perform_request(method, path, params, body).status == 200 ? true : false
+        rescue Exception => e
+          if e.class.to_s =~ /NotFound/ || e.message =~ /Not\s*Found|404/i
+            false
+          else
+            raise e
+          end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/scroll.rb b/lib/elasticsearch/api/actions/scroll.rb
new file mode 100644
index 0000000..6cc9af3
--- /dev/null
+++ b/lib/elasticsearch/api/actions/scroll.rb
@@ -0,0 +1,61 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Efficiently iterate over a large result set.
+      #
+      # When using `from` and `size` to return a large result sets, performance drops as you "paginate" in the set,
+      # and you can't guarantee the consistency when the index is being updated at the same time.
+      #
+      # "Scrolling" the results is frequently used with the `scan` search type.
+      #
+      # @example A basic example
+      #
+      #     result = client.search index: 'scrollindex',
+      #                            scroll: '5m',
+      #                            body: { query: { match: { title: 'test' } }, sort: '_id' }
+      #
+      #     result = client.scroll scroll: '5m', scroll_id: result['_scroll_id']
+      #
+      # @example Call the `scroll` API until all the documents are returned
+      #
+      #     # Index 1,000 documents
+      #     client.indices.delete index: 'test'
+      #     1_000.times do |i| client.index index: 'test', type: 'test', id: i+1, body: {title: "Test #{i}"} end
+      #     client.indices.refresh index: 'test'
+      #
+      #     # Open the "view" of the index with the `scan` search_type
+      #     r = client.search index: 'test', search_type: 'scan', scroll: '5m', size: 10
+      #
+      #     # Call the `scroll` API until empty results are returned
+      #     while r = client.scroll(scroll_id: r['_scroll_id'], scroll: '5m') and not r['hits']['hits'].empty? do
+      #       puts "--- BATCH #{defined?($i) ? $i += 1 : $i = 1} -------------------------------------------------"
+      #       puts r['hits']['hits'].map { |d| d['_source']['title'] }.inspect
+      #       puts
+      #     end
+      #
+      # @option arguments [String] :scroll_id The scroll ID
+      # @option arguments [Hash] :body The scroll ID if not passed by URL or query parameter.
+      # @option arguments [Duration] :scroll Specify how long a consistent view of the index
+      #                                      should be maintained for scrolled search
+      # @option arguments [String] :scroll_id The scroll ID for scrolled search
+      #
+      # @see http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/scan-scroll.html#scan-scroll
+      # @see http://www.elasticsearch.org/guide/reference/api/search/scroll/
+      # @see http://www.elasticsearch.org/guide/reference/api/search/search-type/
+      #
+      def scroll(arguments={})
+        method = 'GET'
+        path   = "_search/scroll"
+        valid_params = [
+          :scroll,
+          :scroll_id ]
+
+        params = Utils.__validate_and_extract_params arguments, valid_params
+        body   = arguments[:body]
+
+        perform_request(method, path, params, body).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/search.rb b/lib/elasticsearch/api/actions/search.rb
new file mode 100644
index 0000000..5d3ff16
--- /dev/null
+++ b/lib/elasticsearch/api/actions/search.rb
@@ -0,0 +1,153 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Return documents matching a query, as well as aggregations (facets), highlighted snippets, suggestions, etc.
+      #
+      # The search API is used to query one or more indices either using simple
+      # [query string queries](http://www.elasticsearch.org/guide/reference/api/search/uri-request/)
+      # as the `:q` argument , or by passing the
+      # [full request definition](http://www.elasticsearch.org/guide/reference/api/search/request-body/)
+      # in the [Query DSL](http://www.elasticsearch.org/guide/reference/query-dsl/) as the `:body` argument.
+      #
+      # @example Search with a simple query string query
+      #
+      #     client.search index: 'myindex', q: 'title:test'
+      #
+      # @example Passing a full request definition in the Elasticsearch's Query DSL as a `Hash`
+      #
+      #     client.search index: 'myindex',
+      #                   body: {
+      #                     query: { match: { title: 'test' } },
+      #                     facets: { tags: { terms: { field: 'tags' } } }
+      #                   }
+      #
+      # @example Passing the search definition as a `String`, built with a JSON builder
+      #
+      #     require 'jbuilder'
+      #
+      #     json = Jbuilder.encode do |json|
+      #       json.query do
+      #         json.match do
+      #           json.title do
+      #             json.query    'test 1'
+      #             json.operator 'and'
+      #           end
+      #         end
+      #       end
+      #     end
+      #
+      #     client.search index: 'myindex', body: json
+      #
+      # @example Wrapping the result in [`Hashie::Mash`](https://github.com/intridea/hashie) for easier access
+      #
+      #     response = client.search index: 'myindex',
+      #                              body: {
+      #                                query:  { match: { title: 'test' } },
+      #                                facets: { tags:  { terms: { field: 'tags' } } }
+      #                              }
+      #
+      #     response = Hashie::Mash.new response
+      #
+      #     response.hits.hits.first._source.title
+      #
+      #     response.facets.tags.terms.to_a.map { |f| "#{f.term} [#{f.count}]" }.join(', ')
+      #
+      # @option arguments [List] :index A comma-separated list of index names to search; use `_all`
+      #                                 or empty string to perform the operation on all indices
+      # @option arguments [List] :type A comma-separated list of document types to search;
+      #                                leave empty to perform the operation on all types
+      # @option arguments [Hash] :body The search definition using the Query DSL
+      # @option arguments [String] :analyzer The analyzer to use for the query string
+      # @option arguments [Boolean] :analyze_wildcard Specify whether wildcard and prefix queries should be analyzed
+      #                                               (default: false)
+      # @option arguments [String] :default_operator The default operator for query string query (AND or OR)
+      #                                              (options: AND, OR)
+      # @option arguments [String] :df The field to use as default where no field prefix is given in the query string
+      # @option arguments [Boolean] :explain Specify whether to return detailed information about score computation
+      #                                      as part of a hit
+      # @option arguments [List] :fields A comma-separated list of fields to return as part of a hit
+      # @option arguments [Number] :from Starting offset (default: 0)
+      # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore `missing` ones
+      #                                            (options: none, missing)
+      # @option arguments [Boolean] :lenient Specify whether format-based query failures
+      #                                      (such as providing text to a numeric field) should be ignored
+      # @option arguments [Boolean] :lowercase_expanded_terms Specify whether query terms should be lowercased
+      # @option arguments [String] :preference Specify the node or shard the operation should be performed on
+      #                                        (default: random)
+      # @option arguments [String] :q Query in the Lucene query string syntax
+      # @option arguments [List] :routing A comma-separated list of specific routing values
+      # @option arguments [Duration] :scroll Specify how long a consistent view of the index should be maintained
+      #                                      for scrolled search
+      # @option arguments [String] :search_type Search operation type (options: query_then_fetch, query_and_fetch,
+      #                                         dfs_query_then_fetch, dfs_query_and_fetch, count, scan)
+      # @option arguments [Number] :size Number of hits to return (default: 10)
+      # @option arguments [List] :sort A comma-separated list of <field>:<direction> pairs
+      # @option arguments [String] :source The URL-encoded request definition using the Query DSL
+      #                                    (instead of using request body)
+      # @option arguments [String] :_source Specify whether the _source field should be returned,
+      #                                     or a list of fields to return
+      # @option arguments [String] :_source_exclude A list of fields to exclude from the returned _source field
+      # @option arguments [String] :_source_include A list of fields to extract and return from the _source field
+      # @option arguments [List] :stats Specific 'tag' of the request for logging and statistical purposes
+      # @option arguments [String] :suggest_field Specify which field to use for suggestions
+      # @option arguments [String] :suggest_mode Specify suggest mode (options: missing, popular, always)
+      # @option arguments [Number] :suggest_size How many suggestions to return in response
+      # @option arguments [Text] :suggest_text The source text for which the suggestions should be returned
+      # @option arguments [Time] :timeout Explicit operation timeout
+      # @option arguments [Boolean] :version Specify whether to return document version as part of a hit
+      #
+      # @return [Hash]
+      #
+      # @see http://www.elasticsearch.org/guide/reference/api/search/
+      # @see http://www.elasticsearch.org/guide/reference/api/search/request-body/
+      #
+      def search(arguments={})
+        arguments[:index] = '_all' if ! arguments[:index] && arguments[:type]
+
+        valid_params = [
+          :analyzer,
+          :analyze_wildcard,
+          :default_operator,
+          :df,
+          :explain,
+          :fields,
+          :from,
+          :ignore_indices,
+          :ignore_unavailable,
+          :allow_no_indices,
+          :expand_wildcards,
+          :lenient,
+          :lowercase_expanded_terms,
+          :preference,
+          :q,
+          :routing,
+          :scroll,
+          :search_type,
+          :size,
+          :sort,
+          :source,
+          :_source,
+          :_source_include,
+          :_source_exclude,
+          :stats,
+          :suggest_field,
+          :suggest_mode,
+          :suggest_size,
+          :suggest_text,
+          :timeout,
+          :version ]
+
+        method = 'GET'
+        path   = Utils.__pathify( Utils.__listify(arguments[:index]), Utils.__listify(arguments[:type]), '_search' )
+
+        params = Utils.__validate_and_extract_params arguments, valid_params
+        body   = arguments[:body]
+
+        params[:fields] = Utils.__listify(params[:fields]) if params[:fields]
+
+        perform_request(method, path, params, body).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/search_shards.rb b/lib/elasticsearch/api/actions/search_shards.rb
new file mode 100644
index 0000000..137a84e
--- /dev/null
+++ b/lib/elasticsearch/api/actions/search_shards.rb
@@ -0,0 +1,41 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Returns the names of indices and shards on which a search request would be executed
+      #
+      # @option arguments [String] :index The name of the index
+      # @option arguments [String] :type The type of the document
+      # @option arguments [String] :preference Specify the node or shard the operation should be performed on
+      #                                        (default: random)
+      # @option arguments [String] :routing Specific routing value
+      # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+      #                                    (default: false)
+      # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored when
+      #                                                 unavailable (missing or closed)
+      # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves
+      #                                               into no concrete indices.
+      #                                               (This includes `_all` or when no indices have been specified)
+      # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices
+      #                                              that are open, closed or both. (options: open, closed)
+      #
+      # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/search-shards.html
+      #
+      def search_shards(arguments={})
+        valid_params = [
+          :preference,
+          :routing,
+          :local,
+          :ignore_unavailable,
+          :allow_no_indices,
+          :expand_wildcards ]
+        method = 'GET'
+        path   = Utils.__pathify( Utils.__listify(arguments[:index]), Utils.__listify(arguments[:type]), '_search_shards' )
+        params = Utils.__validate_and_extract_params arguments, valid_params
+        body   = nil
+
+        perform_request(method, path, params, body).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/search_template.rb b/lib/elasticsearch/api/actions/search_template.rb
new file mode 100644
index 0000000..39b628a
--- /dev/null
+++ b/lib/elasticsearch/api/actions/search_template.rb
@@ -0,0 +1,61 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Configure the search definition witha template in Mustache and parameters
+      #
+      # @example Insert the start and end values for the `range` query
+      #
+      #     client.search_template index: 'myindex',
+      #                            body: {
+      #                              template: {
+      #                                query: {
+      #                                  range: {
+      #                                    date: { gte: "{{start}}", lte: "{{end}}" }
+      #                                  }
+      #                                }
+      #                              },
+      #                              params: { start: "2014-02-01", end: "2014-03-01" }
+      #                            }
+      #
+      # @option arguments [List] :index A comma-separated list of index names to search; use `_all` or empty
+      #                                 string to perform the operation on all indices
+      # @option arguments [List] :type A comma-separated list of document types to search;
+      #                                leave empty to perform the operation on all types
+      # @option arguments [Hash] :body The search definition template and its params
+      # @option arguments [Boolean] :ignore_unavailable Whether specified concrete indices should be ignored
+      #                                                 when unavailable (missing or closed)
+      # @option arguments [Boolean] :allow_no_indices Whether to ignore if a wildcard indices expression resolves into
+      #                                               no concrete indices. (This includes `_all` string or when no
+      #                                               indices have been specified)
+      # @option arguments [String] :expand_wildcards Whether to expand wildcard expression to concrete indices
+      #                                              that are open, closed or both. (options: open, closed)
+      # @option arguments [String] :preference Specify the node or shard the operation should be performed on
+      #                                        (default: random)
+      # @option arguments [List] :routing A comma-separated list of specific routing values
+      # @option arguments [Duration] :scroll Specify how long a consistent view of the index should be maintained
+      #                                      for scrolled search
+      # @option arguments [String] :search_type Search operation type (options: query_then_fetch, query_and_fetch,
+      #                                         dfs_query_then_fetch, dfs_query_and_fetch, count, scan)
+      #
+      # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-template.html
+      #
+      def search_template(arguments={})
+        valid_params = [
+          :ignore_unavailable,
+          :allow_no_indices,
+          :expand_wildcards,
+          :preference,
+          :routing,
+          :scroll,
+          :search_type ]
+        method = 'GET'
+        path   = Utils.__pathify( Utils.__listify(arguments[:index]), Utils.__listify(arguments[:type]), '_search/template' )
+        params = Utils.__validate_and_extract_params arguments, valid_params
+        body   = arguments[:body]
+
+        perform_request(method, path, params, body).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/snapshot/create.rb b/lib/elasticsearch/api/actions/snapshot/create.rb
new file mode 100644
index 0000000..65727d9
--- /dev/null
+++ b/lib/elasticsearch/api/actions/snapshot/create.rb
@@ -0,0 +1,48 @@
+module Elasticsearch
+  module API
+    module Snapshot
+      module Actions
+
+        # Create a new snapshot in the repository
+        #
+        # @example Create a snapshot of the whole cluster in the `my-backups` repository
+        #
+        #     client.snapshot.create repository: 'my-backups', snapshot: 'snapshot-1'
+        #
+        # @example Create a snapshot for specific indices in the `my-backups` repository
+        #
+        #     client.snapshot.create repository: 'my-backups',
+        #                            snapshot: 'snapshot-2',
+        #                            body: { indices: 'foo,bar', ignore_unavailable: true }
+        #
+        # @option arguments [String] :repository A repository name (*Required*)
+        # @option arguments [String] :snapshot A snapshot name (*Required*)
+        # @option arguments [Hash] :body The snapshot definition
+        # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node
+        # @option arguments [Boolean] :wait_for_completion Whether the request should block and wait until
+        #                                                  the operation has completed
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/modules-snapshots.html#_snapshot
+        #
+        def create(arguments={})
+          raise ArgumentError, "Required argument 'repository' missing" unless arguments[:repository]
+          raise ArgumentError, "Required argument 'snapshot' missing"   unless arguments[:snapshot]
+          valid_params = [
+            :master_timeout,
+            :wait_for_completion ]
+
+          repository = arguments.delete(:repository)
+          snapshot   = arguments.delete(:snapshot)
+
+          method = 'PUT'
+          path   = Utils.__pathify( '_snapshot', Utils.__escape(repository), Utils.__escape(snapshot) )
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = arguments[:body]
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/snapshot/create_repository.rb b/lib/elasticsearch/api/actions/snapshot/create_repository.rb
new file mode 100644
index 0000000..27f476b
--- /dev/null
+++ b/lib/elasticsearch/api/actions/snapshot/create_repository.rb
@@ -0,0 +1,44 @@
+module Elasticsearch
+  module API
+    module Snapshot
+      module Actions
+
+        # Create a repository for storing snapshots
+        #
+        # @example Create a repository at `/tmp/backup`
+        #
+        #     client.snapshot.create_repository repository: 'my-backups',
+        #                                       body: {
+        #                                         type: 'fs',
+        #                                         settings: { location: '/tmp/backup', compress: true  }
+        #                                       }
+        #
+        # @option arguments [String] :repository A repository name (*Required*)
+        # @option arguments [Hash] :body The repository definition (*Required*)
+        # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node
+        # @option arguments [Time] :timeout Explicit operation timeout
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/modules-snapshots.html#_repositories
+        #
+        def create_repository(arguments={})
+          raise ArgumentError, "Required argument 'repository' missing" unless arguments[:repository]
+          raise ArgumentError, "Required argument 'body' missing"       unless arguments[:body]
+          valid_params = [
+            :repository,
+            :master_timeout,
+            :timeout ]
+
+          repository = arguments.delete(:repository)
+
+          method = 'PUT'
+          path   = Utils.__pathify( '_snapshot', Utils.__escape(repository) )
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = arguments[:body]
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/snapshot/delete.rb b/lib/elasticsearch/api/actions/snapshot/delete.rb
new file mode 100644
index 0000000..4cb2343
--- /dev/null
+++ b/lib/elasticsearch/api/actions/snapshot/delete.rb
@@ -0,0 +1,41 @@
+module Elasticsearch
+  module API
+    module Snapshot
+      module Actions
+
+        # Delete a snapshot from the repository
+        #
+        # @note Will also abort a currently running snapshot.
+        #
+        # @example Delete the `snapshot-1` snapshot
+        #
+        #     client.snapshot.delete repository: 'my-backups', snapshot: 'snapshot-1'
+        #
+        # @option arguments [String] :repository A repository name (*Required*)
+        # @option arguments [String] :snapshot A snapshot name (*Required*)
+        # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/modules-snapshots.html
+        #
+        def delete(arguments={})
+          raise ArgumentError, "Required argument 'repository' missing" unless arguments[:repository]
+          raise ArgumentError, "Required argument 'snapshot' missing"   unless arguments[:snapshot]
+
+          valid_params = [
+            :master_timeout ]
+
+          repository = arguments.delete(:repository)
+          snapshot   = arguments.delete(:snapshot)
+
+          method = 'DELETE'
+          path   = Utils.__pathify( '_snapshot', Utils.__escape(repository), Utils.__listify(snapshot) )
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/snapshot/delete_repository.rb b/lib/elasticsearch/api/actions/snapshot/delete_repository.rb
new file mode 100644
index 0000000..0725045
--- /dev/null
+++ b/lib/elasticsearch/api/actions/snapshot/delete_repository.rb
@@ -0,0 +1,38 @@
+module Elasticsearch
+  module API
+    module Snapshot
+      module Actions
+
+        # Delete a specific repository or repositories
+        #
+        # @example Delete the `my-backups` repository
+        #
+        #     client.snapshot.delete_repository repository: 'my-backups'
+        #
+        # @option arguments [List] :repository A comma-separated list of repository names (*Required*)
+        # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node
+        # @option arguments [Time] :timeout Explicit operation timeout
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/modules-snapshots.html
+        #
+        def delete_repository(arguments={})
+          raise ArgumentError, "Required argument 'repository' missing" unless arguments[:repository]
+
+          valid_params = [
+            :master_timeout,
+            :timeout ]
+
+          repository = arguments.delete(:repository)
+
+          method = 'DELETE'
+          path   = Utils.__pathify( '_snapshot', Utils.__listify(repository) )
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/snapshot/get.rb b/lib/elasticsearch/api/actions/snapshot/get.rb
new file mode 100644
index 0000000..0213a69
--- /dev/null
+++ b/lib/elasticsearch/api/actions/snapshot/get.rb
@@ -0,0 +1,47 @@
+module Elasticsearch
+  module API
+    module Snapshot
+      module Actions
+
+        # Return information about specific (or all) snapshots
+        #
+        # @example Return information about the `snapshot-2` snapshot
+        #
+        #     client.snapshot.get repository: 'my-backup', snapshot: 'snapshot-2'
+        #
+        # @example Return information about multiple snapshots
+        #
+        #     client.snapshot.get repository: 'my-backup', snapshot: ['snapshot-2', 'snapshot-3']
+        #
+        # @example Return information about all snapshots in the repository
+        #
+        #     client.snapshot.get repository: 'my-backup', snapshot: '_all'
+        #
+        # @option arguments [String] :repository A repository name (*Required*)
+        # @option arguments [List] :snapshot A comma-separated list of snapshot names (*Required*)
+        # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/modules-snapshots.html
+        #
+        def get(arguments={})
+          raise ArgumentError, "Required argument 'repository' missing" unless arguments[:repository]
+          raise ArgumentError, "Required argument 'snapshot' missing"   unless arguments[:snapshot]
+
+          valid_params = [
+            :master_timeout ]
+
+          repository = arguments.delete(:repository)
+          snapshot   = arguments.delete(:snapshot)
+
+          method = 'GET'
+          path   = Utils.__pathify( '_snapshot', Utils.__escape(repository), Utils.__listify(snapshot) )
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/snapshot/get_repository.rb b/lib/elasticsearch/api/actions/snapshot/get_repository.rb
new file mode 100644
index 0000000..2fb44cc
--- /dev/null
+++ b/lib/elasticsearch/api/actions/snapshot/get_repository.rb
@@ -0,0 +1,42 @@
+module Elasticsearch
+  module API
+    module Snapshot
+      module Actions
+
+        # Get information about snapshot repositories or a specific repository
+        #
+        # @example Get all repositories
+        #
+        #     client.snapshot.get_repository
+        #
+        # @example Get a specific repository
+        #
+        #     client.snapshot.get_repository repository: 'my-backups'
+        #
+        # @option arguments [List] :repository A comma-separated list of repository names. Leave blank or use `_all`
+        #                                      to get a list of repositories
+        # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node
+        # @option arguments [Boolean] :local Return local information, do not retrieve the state from master node
+        #                                    (default: false)
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/modules-snapshots.html
+        #
+        def get_repository(arguments={})
+          valid_params = [
+            :master_timeout,
+            :local ]
+
+          repository = arguments.delete(:repository)
+
+          method = 'GET'
+          path   = Utils.__pathify( '_snapshot', Utils.__escape(repository) )
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/snapshot/restore.rb b/lib/elasticsearch/api/actions/snapshot/restore.rb
new file mode 100644
index 0000000..7a85265
--- /dev/null
+++ b/lib/elasticsearch/api/actions/snapshot/restore.rb
@@ -0,0 +1,53 @@
+module Elasticsearch
+  module API
+    module Snapshot
+      module Actions
+
+        # Restore the state from a snapshot
+        #
+        # @example Restore from the `snapshot-1` snapshot
+        #
+        #     client.snapshot.restore repository: 'my-backups', snapshot: 'snapshot-1'
+        #
+        # @example Restore a specific index under a different name
+        #
+        #     client.snapshot.restore repository: 'my-backups',
+        #                             snapshot: 'snapshot-1',
+        #                             body: {
+        #                               rename_pattern: "^(.*)$",
+        #                               rename_replacement: "restored_$1"
+        #                             }
+        #
+        # @note You cannot restore into an open index, you have to {Indices::Actions#close} it first
+        #
+        # @option arguments [String] :repository A repository name (*Required*)
+        # @option arguments [String] :snapshot A snapshot name (*Required*)
+        # @option arguments [Hash] :body Details of what to restore
+        # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node
+        # @option arguments [Boolean] :wait_for_completion Should this request wait until the operation has completed before returning
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/modules-snapshots.html
+        #
+        def restore(arguments={})
+          raise ArgumentError, "Required argument 'repository' missing" unless arguments[:repository]
+          raise ArgumentError, "Required argument 'snapshot' missing"   unless arguments[:snapshot]
+
+          valid_params = [
+            :master_timeout,
+            :wait_for_completion ]
+
+          repository = arguments.delete(:repository)
+          snapshot   = arguments.delete(:snapshot)
+
+          method = 'POST'
+          path   = Utils.__pathify( '_snapshot', Utils.__escape(repository), Utils.__escape(snapshot), '_restore' )
+
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = arguments[:body]
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/snapshot/status.rb b/lib/elasticsearch/api/actions/snapshot/status.rb
new file mode 100644
index 0000000..839ac7b
--- /dev/null
+++ b/lib/elasticsearch/api/actions/snapshot/status.rb
@@ -0,0 +1,40 @@
+module Elasticsearch
+  module API
+    module Snapshot
+      module Actions
+
+        # Return information about a running snapshot
+        #
+        # @example Return information about all currently running snapshots
+        #
+        #     client.snapshot.status repository: 'my-backups', human: true
+        #
+        # @example Return information about a specific snapshot
+        #
+        #     client.snapshot.status repository: 'my-backups', human: true
+        #
+        # @option arguments [String] :repository A repository name
+        # @option arguments [List] :snapshot A comma-separated list of snapshot names
+        # @option arguments [Time] :master_timeout Explicit operation timeout for connection to master node
+        #
+        # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/modules-snapshots.html#_snapshot_status
+        #
+        def status(arguments={})
+          valid_params = [
+            :master_timeout ]
+
+          repository = arguments.delete(:repository)
+          snapshot   = arguments.delete(:snapshot)
+
+          method = 'GET'
+
+          path   = Utils.__pathify( '_snapshot', Utils.__escape(repository), Utils.__escape(snapshot), '_status')
+          params = Utils.__validate_and_extract_params arguments, valid_params
+          body   = nil
+
+          perform_request(method, path, params, body).body
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/suggest.rb b/lib/elasticsearch/api/actions/suggest.rb
new file mode 100644
index 0000000..54eb1fe
--- /dev/null
+++ b/lib/elasticsearch/api/actions/suggest.rb
@@ -0,0 +1,46 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Return query terms suggestions based on provided text and configuration.
+      #
+      # Pass the request definition in the `:body` argument.
+      #
+      # @example Return query terms suggestions ("auto-correction")
+      #
+      #     client.suggest index: 'myindex',
+      #                    body: { my_suggest: { text: 'tset', term: { field: 'title' } } }
+      #     # => { ... "my_suggest"=>[ {"text"=>"tset", ... "options"=>[{"text"=>"test", "score"=>0.75, "freq"=>5}] }]}
+      #
+      # @option arguments [List] :index A comma-separated list of index names to restrict the operation;
+      #                                 use `_all` or empty string to perform the operation on all indices
+      # @option arguments [Hash] :body The request definition
+      # @option arguments [String] :ignore_indices When performed on multiple indices, allows to ignore `missing` ones
+      #                                            (options: none, missing)
+      # @option arguments [String] :preference Specify the node or shard the operation should be performed on
+      #                                        (default: random)
+      # @option arguments [String] :routing Specific routing value
+      # @option arguments [String] :source The URL-encoded request definition (instead of using request body)
+      #
+      # @since 0.90
+      #
+      # @see http://elasticsearch.org/guide/reference/api/search/suggest/
+      #
+      def suggest(arguments={})
+        valid_params = [
+          :ignore_indices,
+          :preference,
+          :routing,
+          :source ]
+
+        method = 'POST'
+        path   = Utils.__pathify( Utils.__listify(arguments[:index]), '_suggest' )
+
+        params = Utils.__validate_and_extract_params arguments, valid_params
+        body   = arguments[:body]
+
+        perform_request(method, path, params, body).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/termvector.rb b/lib/elasticsearch/api/actions/termvector.rb
new file mode 100644
index 0000000..2a7e401
--- /dev/null
+++ b/lib/elasticsearch/api/actions/termvector.rb
@@ -0,0 +1,77 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Return information and statistics about terms in the fields of a particular document
+      #
+      # @example Get statistics for a specific document
+      #
+      #     client.indices.create index: 'my_index',
+      #                           body: {
+      #                             mappings: {
+      #                               my_type: {
+      #                                 properties: {
+      #                                   text: {
+      #                                     type: 'string',
+      #                                     term_vector: 'with_positions_offsets_payloads'
+      #                                   }
+      #                                 }
+      #                               }
+      #                             }
+      #                           }
+      #
+      #     client.index index: 'my_index', type: 'my_type', id: '1', body: { text: 'Foo Bar Fox' }
+      #
+      #     client.termvector index: 'my_index', type: 'my_type', id: '1'
+      #     # => { ..., "term_vectors" => { "text" => { "field_statistics" => { ... }, "terms" => { "bar" => ... } } }
+      #
+      # @option arguments [String] :index The name of the index (*Required*)
+      # @option arguments [String] :type The type of the document (*Required*)
+      # @option arguments [String] :id The document ID (*Required*)
+      # @option arguments [Hash] :body The request definition
+      # @option arguments [Boolean] :term_statistics Whether total term frequency and
+      #                                              document frequency should be returned
+      # @option arguments [Boolean] :field_statistics Whether document count, sum of document frequencies
+      #                                               and sum of total term frequencies should be returned
+      # @option arguments [List] :fields A comma-separated list of fields to return
+      # @option arguments [Boolean] :offsets Whether term offsets should be returned
+      # @option arguments [Boolean] :positions Whether term positions should be returned
+      # @option arguments [Boolean] :payloads Whether term payloads should be returned
+      # @option arguments [String] :preference Specify the node or shard the operation should be performed on
+      #                                        (default: random)
+      # @option arguments [String] :routing Specific routing value
+      # @option arguments [String] :parent Parent ID of the documents
+      #
+      # @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/docs-termvectors.html
+      #
+      def termvector(arguments={})
+        raise ArgumentError, "Required argument 'index' missing" unless arguments[:index]
+        raise ArgumentError, "Required argument 'type' missing" unless arguments[:type]
+        raise ArgumentError, "Required argument 'id' missing" unless arguments[:id]
+
+        valid_params = [
+          :term_statistics,
+          :field_statistics,
+          :fields,
+          :offsets,
+          :positions,
+          :payloads,
+          :preference,
+          :routing,
+          :parent ]
+
+        method = 'GET'
+
+        path   = Utils.__pathify Utils.__escape(arguments[:index]),
+                                 Utils.__escape(arguments[:type]),
+                                 arguments[:id],
+                                 '_termvector'
+
+        params = Utils.__validate_and_extract_params arguments, valid_params
+        body   = arguments[:body]
+
+        perform_request(method, path, params, body).body
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/actions/update.rb b/lib/elasticsearch/api/actions/update.rb
new file mode 100644
index 0000000..696ec1b
--- /dev/null
+++ b/lib/elasticsearch/api/actions/update.rb
@@ -0,0 +1,107 @@
+module Elasticsearch
+  module API
+    module Actions
+
+      # Update a document without sending the whole document in the request ("partial update").
+      #
+      # Send either a partial document (`doc` ) which will be deeply merged into an existing document,
+      # or a `script`, which will update the document content, in the `:body` argument.
+      #
+      # The partial update operation allows you to limit the amount of data you send over the wire and
+      # reduces the chance of failed updates due to conflict.
+      #
+      # Specify the `:version` and `:retry_on_conflict` arguments to balance convenience and consistency.
+      #
+      # @example Update document _title_ using partial `doc`-ument
+      #
+      #     client.update index: 'myindex', type: 'mytype', id: '1',
+      #                   body: { doc: { title: 'Updated' } }
+      #
+      # @example Add a tag to document `tags` property using a `script`
+      #
+      #     client.update index: 'myindex', type: 'mytype', id: '1',
+      #                   body: { script: 'ctx._source.tags += tag', params: { tag: 'x' } }
+      #
+      # @example Increment a document counter by 1 _or_ initialize it, when the document does not exist
+      #
+      #     client.update index: 'myindex', type: 'mytype', id: '666',
+      #                   body: { script: 'ctx._source.counter += 1', upsert: { counter: 1 } }
+      #
+      # @example Delete a document if it's tagged "to-delete"
+      #
+      #     client.update index: 'myindex', type: 'mytype', id: '1',
+      #                   body: { script: 'ctx._source.tags.contains(tag) ? ctx.op = "delete" : ctx.op = "none"',
+      #                           params: { tag: 'to-delete' } }
+      #
+      # @option arguments [String] :id Document ID (*Required*)
+      # @option arguments [Number,List] :ignore The list of HTTP errors to ignore; only `404` supported at the moment
+      # @option arguments [String] :index The name of the index (*Required*)
+      # @option arguments [String] :type The type of the document (*Required*)
+      # @option arguments [Hash] :body The request definition using either `script` or partial `doc` (*Required*)
+      # @option arguments [String] :consistency Explicit write consistency setting for the operation
+      #                                         (options: one, quorum, all)
+      # @option arguments [List] :fields A comma-separated list of fields to return in the response
+      # @option arguments [String] :lang The script language (default: mvel)
+      # @option arguments [String] :parent ID of the parent document
+      # @option arguments [String] :percolate Perform percolation during the operation;
+      #                                       use specific registered query name, attribute, or wildcard
+      # @option arguments [Boolean] :refresh Refresh the index after performing the operation
+      # @option arguments [String] :replication Specific replication type (options: sync, async)
+      # @option arguments [Number] :retry_on_conflict Specify how many times should the operation be retried
+      #                                               when a conflict occurs (default: 0)
+      # @option arguments [String] :routing Specific routing value
+      # @option arguments [String] :script The URL-encoded script definition (instead of using request body)
+      # @option arguments [Time] :timeout Explicit operation timeout
+      # @option arguments [Time] :timestamp Explicit timestamp for the document
+      # @option arguments [Duration] :ttl Expiration time for the document
+      # @option arguments [Number] :version Explicit version number for concurrency control
+      # @option arguments [Number] :version_type Explicit version number for concurrency control
+      #
+      # @since 0.20
+      #
+      # @see http://elasticsearch.org/guide/reference/api/update/
+      #
+      def update(arguments={})
+        raise ArgumentError, "Required argument 'index' missing" unless arguments[:index]
+        raise ArgumentError, "Required argument 'type' missing"  unless arguments[:type]
+        raise ArgumentError, "Required argument 'id' missing"    unless arguments[:id]
+
+        valid_params = [
+          :consistency,
+          :fields,
+          :lang,
+          :parent,
+          :percolate,
+          :refresh,
+          :replication,
+          :retry_on_conflict,
+          :routing,
+          :script,
+          :timeout,
+          :timestamp,
+          :ttl,
+          :version,
+          :version_type ]
+
+        method = 'POST'
+        path   = Utils.__pathify Utils.__escape(arguments[:index]),
+                                 Utils.__escape(arguments[:type]),
+                                 Utils.__escape(arguments[:id]),
+                                 '_update'
+
+        params = Utils.__validate_and_extract_params arguments, valid_params
+        body   = arguments[:body]
+
+        params[:fields] = Utils.__listify(params[:fields]) if params[:fields]
+
+        perform_request(method, path, params, body).body
+
+      rescue Exception => e
+        # NOTE: Use exception name, not full class in Elasticsearch::Client to allow client plugability
+        if Array(arguments[:ignore]).include?(404) && e.class.to_s =~ /NotFound/; false
+        else raise(e)
+        end
+      end
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/namespace/cat.rb b/lib/elasticsearch/api/namespace/cat.rb
new file mode 100644
index 0000000..d8f31ae
--- /dev/null
+++ b/lib/elasticsearch/api/namespace/cat.rb
@@ -0,0 +1,20 @@
+module Elasticsearch
+  module API
+    module Cat
+      module Actions; end
+
+      # Client for the "cat" namespace (includes the {Cat::Actions} methods)
+      #
+      class CatClient
+        include Common::Client, Common::Client::Base, Cat::Actions
+      end
+
+      # Proxy method for {CatClient}, available in the receiving object
+      #
+      def cat
+        @cat ||= CatClient.new(self)
+      end
+
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/namespace/cluster.rb b/lib/elasticsearch/api/namespace/cluster.rb
new file mode 100644
index 0000000..df24128
--- /dev/null
+++ b/lib/elasticsearch/api/namespace/cluster.rb
@@ -0,0 +1,20 @@
+module Elasticsearch
+  module API
+    module Cluster
+      module Actions; end
+
+      # Client for the "cluster" namespace (includes the {Cluster::Actions} methods)
+      #
+      class ClusterClient
+        include Common::Client, Common::Client::Base, Cluster::Actions
+      end
+
+      # Proxy method for {ClusterClient}, available in the receiving object
+      #
+      def cluster
+        @cluster ||= ClusterClient.new(self)
+      end
+
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/namespace/common.rb b/lib/elasticsearch/api/namespace/common.rb
new file mode 100644
index 0000000..36fb653
--- /dev/null
+++ b/lib/elasticsearch/api/namespace/common.rb
@@ -0,0 +1,27 @@
+module Elasticsearch
+  module API
+    module Common
+      module Actions; end
+
+      module Client
+
+        # Base client wrapper
+        #
+        module Base
+          attr_reader :client
+
+          def initialize(client)
+            @client = client
+          end
+        end
+
+        # Delegates the `perform_request` method to the wrapped client
+        #
+        def perform_request(method, path, params={}, body=nil)
+          client.perform_request method, path, params, body
+        end
+      end
+
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/namespace/indices.rb b/lib/elasticsearch/api/namespace/indices.rb
new file mode 100644
index 0000000..bcda17e
--- /dev/null
+++ b/lib/elasticsearch/api/namespace/indices.rb
@@ -0,0 +1,20 @@
+module Elasticsearch
+  module API
+    module Indices
+      module Actions; end
+
+      # Client for the "indices" namespace (includes the {Indices::Actions} methods)
+      #
+      class IndicesClient
+        include Common::Client, Common::Client::Base, Indices::Actions
+      end
+
+      # Proxy method for {IndicesClient}, available in the receiving object
+      #
+      def indices
+        @indices ||= IndicesClient.new(self)
+      end
+
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/namespace/nodes.rb b/lib/elasticsearch/api/namespace/nodes.rb
new file mode 100644
index 0000000..2262215
--- /dev/null
+++ b/lib/elasticsearch/api/namespace/nodes.rb
@@ -0,0 +1,20 @@
+module Elasticsearch
+  module API
+    module Nodes
+      module Actions; end
+
+      # Client for the "nodes" namespace (includes the {Nodes::Actions} methods)
+      #
+      class NodesClient
+        include Common::Client, Common::Client::Base, Nodes::Actions
+      end
+
+      # Proxy method for {NodesClient}, available in the receiving object
+      #
+      def nodes
+        @nodes ||= NodesClient.new(self)
+      end
+
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/namespace/snapshot.rb b/lib/elasticsearch/api/namespace/snapshot.rb
new file mode 100644
index 0000000..7c337db
--- /dev/null
+++ b/lib/elasticsearch/api/namespace/snapshot.rb
@@ -0,0 +1,20 @@
+module Elasticsearch
+  module API
+    module Snapshot
+      module Actions; end
+
+      # Client for the "snapshot" namespace (includes the {Snapshot::Actions} methods)
+      #
+      class SnapshotClient
+        include Common::Client, Common::Client::Base, Snapshot::Actions
+      end
+
+      # Proxy method for {SnapshotClient}, available in the receiving object
+      #
+      def snapshot
+        @snapshot ||= SnapshotClient.new(self)
+      end
+
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/utils.rb b/lib/elasticsearch/api/utils.rb
new file mode 100644
index 0000000..31d1d41
--- /dev/null
+++ b/lib/elasticsearch/api/utils.rb
@@ -0,0 +1,163 @@
+module Elasticsearch
+  module API
+
+    # Generic utility methods
+    #
+    module Utils
+
+      # URL-escape a string
+      #
+      # @example
+      #     __escape('foo/bar') # => 'foo%2Fbar'
+      #     __escape('bar^bam') # => 'bar%5Ebam'
+      #
+      # @api private
+      def __escape(string)
+        return string if string == '*'
+        defined?(EscapeUtils) ? EscapeUtils.escape_url(string.to_s) : CGI.escape(string.to_s)
+      end
+
+      # Create a "list" of values from arguments, ignoring nil values and encoding special characters.
+      #
+      # @example Create a list from array
+      #     __listify(['A','B']) # => 'A,B'
+      #
+      # @example Create a list from arguments
+      #     __listify('A','B') # => 'A,B'
+      #
+      # @example Escape values
+      #     __listify('foo','bar^bam') # => 'foo,bar%5Ebam'
+      #
+      # @api private
+      def __listify(*list)
+        Array(list).flatten.
+          map { |e| e.respond_to?(:split) ? e.split(',') : e }.
+          flatten.
+          compact.
+          map { |e| __escape(e) }.
+          join(',')
+      end
+
+      # Create a path (URL part) from arguments, ignoring nil values and empty strings.
+      #
+      # @example Create a path from array
+      #     __pathify(['foo', '', nil, 'bar']) # => 'foo/bar'
+      #
+      # @example Create a path from arguments
+      #     __pathify('foo', '', nil, 'bar') # => 'foo/bar'
+      #
+      # # @example Encode special characters
+      #     __pathify(['foo', 'bar^bam']) # => 'foo/bar%5Ebam'
+      #
+      # @api private
+      def __pathify(*segments)
+        Array(segments).flatten.
+          compact.
+          reject { |s| s.to_s =~ /^\s*$/ }.
+          join('/').
+          squeeze('/')
+      end
+
+      # Convert an array of payloads into Elasticsearch `header\ndata` format
+      #
+      #     Elasticsearch::API::Utils.__bulkify [
+      #       { :index =>  { :_index => 'myindexA', :_type => 'mytype', :_id => '1', :data => { :title => 'Test' } } },
+      #       { :update => { :_index => 'myindexB', :_type => 'mytype', :_id => '2', :data => { :doc => { :title => 'Update' } } } }
+      #     ]
+      #
+      #     # => {"index":{"_index":"myindexA","_type":"mytype","_id":"1"}}
+      #     # => {"title":"Test"}
+      #     # => {"update":{"_index":"myindexB","_type":"mytype","_id":"2"}}
+      #     # => {"doc":{"title":"Update"}}
+      #
+      def __bulkify(payload)
+        case
+        # Hashes with `:data`
+        when payload.any? { |d| d.is_a?(Hash) && d.values.first.is_a?(Hash) && (d.values.first[:data] || d.values.first['data']) }
+          payload = payload.
+          inject([]) do |sum, item|
+            operation, meta = item.to_a.first
+            meta            = meta.clone
+            data            = meta.delete(:data) || meta.delete('data')
+
+            sum << { operation => meta }
+            sum << data if data
+            sum
+          end.
+          map { |item| MultiJson.dump(item) }
+          payload << "" unless payload.empty?
+          return payload.join("\n")
+
+        # Array of strings
+        when payload.all? { |d| d.is_a? String }
+          payload << ''
+
+        # Header/Data pairs
+        else
+          payload = payload.map { |item| MultiJson.dump(item) }
+          payload << ''
+        end
+
+        payload = payload.join("\n")
+      end
+
+      # Validates the argument Hash against common and valid API parameters
+      #
+      # @param arguments    [Hash]          Hash of arguments to verify and extract, **with symbolized keys**
+      # @param valid_params [Array<Symbol>] An array of symbols with valid keys
+      #
+      # @return [Hash]         Return whitelisted Hash
+      # @raise [ArgumentError] If the arguments Hash contains invalid keys
+      #
+      # @example Extract parameters
+      #   __validate_and_extract_params { :foo => 'qux' }, [:foo, :bar]
+      #   # => { :foo => 'qux' }
+      #
+      # @example Raise an exception for invalid parameters
+      #   __validate_and_extract_params { :foo => 'qux', :bam => 'mux' }, [:foo, :bar]
+      #   # ArgumentError: "URL parameter 'bam' is not supported"
+      #
+      # @api private
+      #
+      def __validate_and_extract_params(arguments, valid_params=[])
+        arguments.each do |k,v|
+          raise ArgumentError, "URL parameter '#{k}' is not supported" \
+            unless COMMON_PARAMS.include?(k) || COMMON_QUERY_PARAMS.include?(k) || valid_params.include?(k)
+        end
+
+        params = arguments.select { |k,v| COMMON_QUERY_PARAMS.include?(k) || valid_params.include?(k) }
+        params = Hash[params] unless params.is_a?(Hash) # Normalize Ruby 1.8 and Ruby 1.9 Hash#select behaviour
+        params
+      end
+
+      # Extracts the valid parts of the URL from the arguments
+      #
+      # @note Mutates the `arguments` argument, to prevent failures in `__validate_and_extract_params`.
+      #
+      # @param arguments   [Hash]          Hash of arguments to verify and extract, **with symbolized keys**
+      # @param valid_parts [Array<Symbol>] An array of symbol with valid keys
+      #
+      # @return [Array<String>]            Valid parts of the URL as an array of strings
+      #
+      # @example Extract parts
+      #   __extract_parts { :foo => true }, [:foo, :bar]
+      #   # => [:foo]
+      #
+      #
+      # @api private
+      #
+      def __extract_parts(arguments, valid_parts=[])
+        # require 'pry'; binding.pry;
+        # parts  = arguments.keys.select { |a| valid_parts.include?(a) }.map { |a| a.to_s }.sort
+
+        parts = Hash[arguments.select { |k,v| valid_parts.include?(k) }]
+        parts = parts.reduce([]) { |sum, item| k, v = item; v.is_a?(TrueClass) ? sum << k.to_s : sum << v  }
+
+        arguments.delete_if { |k,v| valid_parts.include? k }
+        return parts
+      end
+
+      extend self
+    end
+  end
+end
diff --git a/lib/elasticsearch/api/version.rb b/lib/elasticsearch/api/version.rb
new file mode 100644
index 0000000..bd40bf3
--- /dev/null
+++ b/lib/elasticsearch/api/version.rb
@@ -0,0 +1,5 @@
+module Elasticsearch
+  module API
+    VERSION = "1.0.4"
+  end
+end
diff --git a/metadata.yml b/metadata.yml
new file mode 100644
index 0000000..fd01d90
--- /dev/null
+++ b/metadata.yml
@@ -0,0 +1,705 @@
+--- !ruby/object:Gem::Specification
+name: elasticsearch-api
+version: !ruby/object:Gem::Version
+  version: 1.0.4
+platform: ruby
+authors:
+- Karel Minarik
+autorequire: 
+bindir: bin
+cert_chain: []
+date: 2014-06-25 00:00:00.000000000 Z
+dependencies:
+- !ruby/object:Gem::Dependency
+  name: multi_json
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :runtime
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
+  name: bundler
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>'
+      - !ruby/object:Gem::Version
+        version: '1'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>'
+      - !ruby/object:Gem::Version
+        version: '1'
+- !ruby/object:Gem::Dependency
+  name: rake
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
+  name: elasticsearch
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
+  name: elasticsearch-transport
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
+  name: minitest
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ~>
+      - !ruby/object:Gem::Version
+        version: '4.0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ~>
+      - !ruby/object:Gem::Version
+        version: '4.0'
+- !ruby/object:Gem::Dependency
+  name: elasticsearch-extensions
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
+  name: ansi
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
+  name: shoulda-context
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
+  name: mocha
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
+  name: turn
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
+  name: yard
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
+  name: pry
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
+  name: ci_reporter
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
+  name: jsonify
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
+  name: hashie
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
+  name: ruby-prof
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
+  name: jbuilder
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
+  name: escape_utils
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
+  name: simplecov
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
+  name: simplecov-rcov
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
+  name: cane
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
+  name: require-prof
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
+  name: coveralls
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: '0'
+description: ! 'Ruby API for Elasticsearch. See the `elasticsearch` gem for full integration.
+
+'
+email:
+- karel.minarik at elasticsearch.org
+executables: []
+extensions: []
+extra_rdoc_files:
+- README.md
+- LICENSE.txt
+files:
+- .gitignore
+- Gemfile
+- LICENSE.txt
+- README.md
+- Rakefile
+- elasticsearch-api.gemspec
+- lib/elasticsearch-api.rb
+- lib/elasticsearch/api.rb
+- lib/elasticsearch/api/actions/abort_benchmark.rb
+- lib/elasticsearch/api/actions/benchmark.rb
+- lib/elasticsearch/api/actions/bulk.rb
+- lib/elasticsearch/api/actions/cat/aliases.rb
+- lib/elasticsearch/api/actions/cat/allocation.rb
+- lib/elasticsearch/api/actions/cat/count.rb
+- lib/elasticsearch/api/actions/cat/fielddata.rb
+- lib/elasticsearch/api/actions/cat/health.rb
+- lib/elasticsearch/api/actions/cat/help.rb
+- lib/elasticsearch/api/actions/cat/indices.rb
+- lib/elasticsearch/api/actions/cat/master.rb
+- lib/elasticsearch/api/actions/cat/nodes.rb
+- lib/elasticsearch/api/actions/cat/pending_tasks.rb
+- lib/elasticsearch/api/actions/cat/recovery.rb
+- lib/elasticsearch/api/actions/cat/shards.rb
+- lib/elasticsearch/api/actions/cat/thread_pool.rb
+- lib/elasticsearch/api/actions/clear_scroll.rb
+- lib/elasticsearch/api/actions/cluster/get_settings.rb
+- lib/elasticsearch/api/actions/cluster/health.rb
+- lib/elasticsearch/api/actions/cluster/pending_tasks.rb
+- lib/elasticsearch/api/actions/cluster/put_settings.rb
+- lib/elasticsearch/api/actions/cluster/reroute.rb
+- lib/elasticsearch/api/actions/cluster/state.rb
+- lib/elasticsearch/api/actions/count.rb
+- lib/elasticsearch/api/actions/count_percolate.rb
+- lib/elasticsearch/api/actions/create.rb
+- lib/elasticsearch/api/actions/delete.rb
+- lib/elasticsearch/api/actions/delete_by_query.rb
+- lib/elasticsearch/api/actions/exists.rb
+- lib/elasticsearch/api/actions/explain.rb
+- lib/elasticsearch/api/actions/get.rb
+- lib/elasticsearch/api/actions/get_source.rb
+- lib/elasticsearch/api/actions/index.rb
+- lib/elasticsearch/api/actions/indices/analyze.rb
+- lib/elasticsearch/api/actions/indices/clear_cache.rb
+- lib/elasticsearch/api/actions/indices/close.rb
+- lib/elasticsearch/api/actions/indices/create.rb
+- lib/elasticsearch/api/actions/indices/delete.rb
+- lib/elasticsearch/api/actions/indices/delete_alias.rb
+- lib/elasticsearch/api/actions/indices/delete_mapping.rb
+- lib/elasticsearch/api/actions/indices/delete_template.rb
+- lib/elasticsearch/api/actions/indices/delete_warmer.rb
+- lib/elasticsearch/api/actions/indices/exists.rb
+- lib/elasticsearch/api/actions/indices/exists_alias.rb
+- lib/elasticsearch/api/actions/indices/exists_template.rb
+- lib/elasticsearch/api/actions/indices/exists_type.rb
+- lib/elasticsearch/api/actions/indices/flush.rb
+- lib/elasticsearch/api/actions/indices/get_alias.rb
+- lib/elasticsearch/api/actions/indices/get_aliases.rb
+- lib/elasticsearch/api/actions/indices/get_field_mapping.rb
+- lib/elasticsearch/api/actions/indices/get_mapping.rb
+- lib/elasticsearch/api/actions/indices/get_settings.rb
+- lib/elasticsearch/api/actions/indices/get_template.rb
+- lib/elasticsearch/api/actions/indices/get_warmer.rb
+- lib/elasticsearch/api/actions/indices/open.rb
+- lib/elasticsearch/api/actions/indices/optimize.rb
+- lib/elasticsearch/api/actions/indices/put_alias.rb
+- lib/elasticsearch/api/actions/indices/put_mapping.rb
+- lib/elasticsearch/api/actions/indices/put_settings.rb
+- lib/elasticsearch/api/actions/indices/put_template.rb
+- lib/elasticsearch/api/actions/indices/put_warmer.rb
+- lib/elasticsearch/api/actions/indices/recovery.rb
+- lib/elasticsearch/api/actions/indices/refresh.rb
+- lib/elasticsearch/api/actions/indices/segments.rb
+- lib/elasticsearch/api/actions/indices/snapshot_index.rb
+- lib/elasticsearch/api/actions/indices/stats.rb
+- lib/elasticsearch/api/actions/indices/status.rb
+- lib/elasticsearch/api/actions/indices/update_aliases.rb
+- lib/elasticsearch/api/actions/indices/validate_query.rb
+- lib/elasticsearch/api/actions/info.rb
+- lib/elasticsearch/api/actions/list_benchmarks.rb
+- lib/elasticsearch/api/actions/mget.rb
+- lib/elasticsearch/api/actions/mlt.rb
+- lib/elasticsearch/api/actions/mpercolate.rb
+- lib/elasticsearch/api/actions/msearch.rb
+- lib/elasticsearch/api/actions/mtermvectors.rb
+- lib/elasticsearch/api/actions/nodes/hot_threads.rb
+- lib/elasticsearch/api/actions/nodes/info.rb
+- lib/elasticsearch/api/actions/nodes/shutdown.rb
+- lib/elasticsearch/api/actions/nodes/stats.rb
+- lib/elasticsearch/api/actions/percolate.rb
+- lib/elasticsearch/api/actions/ping.rb
+- lib/elasticsearch/api/actions/scroll.rb
+- lib/elasticsearch/api/actions/search.rb
+- lib/elasticsearch/api/actions/search_shards.rb
+- lib/elasticsearch/api/actions/search_template.rb
+- lib/elasticsearch/api/actions/snapshot/create.rb
+- lib/elasticsearch/api/actions/snapshot/create_repository.rb
+- lib/elasticsearch/api/actions/snapshot/delete.rb
+- lib/elasticsearch/api/actions/snapshot/delete_repository.rb
+- lib/elasticsearch/api/actions/snapshot/get.rb
+- lib/elasticsearch/api/actions/snapshot/get_repository.rb
+- lib/elasticsearch/api/actions/snapshot/restore.rb
+- lib/elasticsearch/api/actions/snapshot/status.rb
+- lib/elasticsearch/api/actions/suggest.rb
+- lib/elasticsearch/api/actions/termvector.rb
+- lib/elasticsearch/api/actions/update.rb
+- lib/elasticsearch/api/namespace/cat.rb
+- lib/elasticsearch/api/namespace/cluster.rb
+- lib/elasticsearch/api/namespace/common.rb
+- lib/elasticsearch/api/namespace/indices.rb
+- lib/elasticsearch/api/namespace/nodes.rb
+- lib/elasticsearch/api/namespace/snapshot.rb
+- lib/elasticsearch/api/utils.rb
+- lib/elasticsearch/api/version.rb
+- test/integration/yaml_test_runner.rb
+- test/test_helper.rb
+- test/unit/abort_benchmark_test.rb
+- test/unit/benchmark_test.rb
+- test/unit/bulk_test.rb
+- test/unit/cat/aliases_test.rb
+- test/unit/cat/allocation_test.rb
+- test/unit/cat/count_test.rb
+- test/unit/cat/fielddata_test.rb
+- test/unit/cat/health_test.rb
+- test/unit/cat/help_test.rb
+- test/unit/cat/indices_test.rb
+- test/unit/cat/master_test.rb
+- test/unit/cat/nodes_test.rb
+- test/unit/cat/pending_tasks_test.rb
+- test/unit/cat/recovery_test.rb
+- test/unit/cat/shards_test.rb
+- test/unit/cat/thread_pool_test.rb
+- test/unit/clear_scroll_test.rb
+- test/unit/client_test.rb
+- test/unit/cluster/get_settings_test.rb
+- test/unit/cluster/health_test.rb
+- test/unit/cluster/pending_tasks_test.rb
+- test/unit/cluster/put_settings_test.rb
+- test/unit/cluster/reroute_test.rb
+- test/unit/cluster/state_test.rb
+- test/unit/count_percolate_test.rb
+- test/unit/count_test.rb
+- test/unit/create_document_test.rb
+- test/unit/delete_by_query_test.rb
+- test/unit/delete_document_test.rb
+- test/unit/exists_document_test.rb
+- test/unit/explain_document_test.rb
+- test/unit/get_document_source_test.rb
+- test/unit/get_document_test.rb
+- test/unit/hashie_test.rb
+- test/unit/index_document_test.rb
+- test/unit/indices/analyze_test.rb
+- test/unit/indices/clear_cache_test.rb
+- test/unit/indices/close_test.rb
+- test/unit/indices/create_test.rb
+- test/unit/indices/delete_alias_test.rb
+- test/unit/indices/delete_mapping_test.rb
+- test/unit/indices/delete_template_test.rb
+- test/unit/indices/delete_test.rb
+- test/unit/indices/delete_warmer_test.rb
+- test/unit/indices/exists_alias_test.rb
+- test/unit/indices/exists_template_test.rb
+- test/unit/indices/exists_test.rb
+- test/unit/indices/exists_type_test.rb
+- test/unit/indices/flush_test.rb
+- test/unit/indices/get_alias_test.rb
+- test/unit/indices/get_aliases_test.rb
+- test/unit/indices/get_field_mapping_test.rb
+- test/unit/indices/get_mapping_test.rb
+- test/unit/indices/get_settings_test.rb
+- test/unit/indices/get_template_test.rb
+- test/unit/indices/get_warmer_test.rb
+- test/unit/indices/open_test.rb
+- test/unit/indices/optimize_test.rb
+- test/unit/indices/put_alias_test.rb
+- test/unit/indices/put_mapping_test.rb
+- test/unit/indices/put_settings_test.rb
+- test/unit/indices/put_template_test.rb
+- test/unit/indices/put_warmer_test.rb
+- test/unit/indices/recovery_test.rb
+- test/unit/indices/refresh_test.rb
+- test/unit/indices/segments_test.rb
+- test/unit/indices/snapshot_index_test.rb
+- test/unit/indices/stats_test.rb
+- test/unit/indices/status_test.rb
+- test/unit/indices/update_aliases_test.rb
+- test/unit/indices/validate_query_test.rb
+- test/unit/info_test.rb
+- test/unit/json_builders_test.rb
+- test/unit/list_benchmarks_test.rb
+- test/unit/mget_test.rb
+- test/unit/mlt_test.rb
+- test/unit/mpercolate_test.rb
+- test/unit/msearch_test.rb
+- test/unit/mtermvectors_test.rb
+- test/unit/nodes/hot_threads_test.rb
+- test/unit/nodes/info_test.rb
+- test/unit/nodes/shutdown_test.rb
+- test/unit/nodes/stats_test.rb
+- test/unit/percolate_test.rb
+- test/unit/ping_test.rb
+- test/unit/scroll_test.rb
+- test/unit/search_shards_test.rb
+- test/unit/search_template_test.rb
+- test/unit/search_test.rb
+- test/unit/snapshot/create_repository_test.rb
+- test/unit/snapshot/create_test.rb
+- test/unit/snapshot/delete_repository_test.rb
+- test/unit/snapshot/delete_test.rb
+- test/unit/snapshot/get_repository_test.rb
+- test/unit/snapshot/get_test.rb
+- test/unit/snapshot/restore_test.rb
+- test/unit/snapshot/status_test.rb
+- test/unit/suggest_test.rb
+- test/unit/termvector_test.rb
+- test/unit/update_document_test.rb
+- test/unit/utils_test.rb
+homepage: https://github.com/elasticsearch/elasticsearch-ruby/tree/master/elasticsearch-api
+licenses:
+- Apache 2
+metadata: {}
+post_install_message: 
+rdoc_options:
+- --charset=UTF-8
+require_paths:
+- lib
+required_ruby_version: !ruby/object:Gem::Requirement
+  requirements:
+  - - ! '>='
+    - !ruby/object:Gem::Version
+      version: '0'
+required_rubygems_version: !ruby/object:Gem::Requirement
+  requirements:
+  - - ! '>='
+    - !ruby/object:Gem::Version
+      version: '0'
+requirements: []
+rubyforge_project: 
+rubygems_version: 2.2.2
+signing_key: 
+specification_version: 4
+summary: Ruby API for Elasticsearch.
+test_files:
+- test/integration/yaml_test_runner.rb
+- test/test_helper.rb
+- test/unit/abort_benchmark_test.rb
+- test/unit/benchmark_test.rb
+- test/unit/bulk_test.rb
+- test/unit/cat/aliases_test.rb
+- test/unit/cat/allocation_test.rb
+- test/unit/cat/count_test.rb
+- test/unit/cat/fielddata_test.rb
+- test/unit/cat/health_test.rb
+- test/unit/cat/help_test.rb
+- test/unit/cat/indices_test.rb
+- test/unit/cat/master_test.rb
+- test/unit/cat/nodes_test.rb
+- test/unit/cat/pending_tasks_test.rb
+- test/unit/cat/recovery_test.rb
+- test/unit/cat/shards_test.rb
+- test/unit/cat/thread_pool_test.rb
+- test/unit/clear_scroll_test.rb
+- test/unit/client_test.rb
+- test/unit/cluster/get_settings_test.rb
+- test/unit/cluster/health_test.rb
+- test/unit/cluster/pending_tasks_test.rb
+- test/unit/cluster/put_settings_test.rb
+- test/unit/cluster/reroute_test.rb
+- test/unit/cluster/state_test.rb
+- test/unit/count_percolate_test.rb
+- test/unit/count_test.rb
+- test/unit/create_document_test.rb
+- test/unit/delete_by_query_test.rb
+- test/unit/delete_document_test.rb
+- test/unit/exists_document_test.rb
+- test/unit/explain_document_test.rb
+- test/unit/get_document_source_test.rb
+- test/unit/get_document_test.rb
+- test/unit/hashie_test.rb
+- test/unit/index_document_test.rb
+- test/unit/indices/analyze_test.rb
+- test/unit/indices/clear_cache_test.rb
+- test/unit/indices/close_test.rb
+- test/unit/indices/create_test.rb
+- test/unit/indices/delete_alias_test.rb
+- test/unit/indices/delete_mapping_test.rb
+- test/unit/indices/delete_template_test.rb
+- test/unit/indices/delete_test.rb
+- test/unit/indices/delete_warmer_test.rb
+- test/unit/indices/exists_alias_test.rb
+- test/unit/indices/exists_template_test.rb
+- test/unit/indices/exists_test.rb
+- test/unit/indices/exists_type_test.rb
+- test/unit/indices/flush_test.rb
+- test/unit/indices/get_alias_test.rb
+- test/unit/indices/get_aliases_test.rb
+- test/unit/indices/get_field_mapping_test.rb
+- test/unit/indices/get_mapping_test.rb
+- test/unit/indices/get_settings_test.rb
+- test/unit/indices/get_template_test.rb
+- test/unit/indices/get_warmer_test.rb
+- test/unit/indices/open_test.rb
+- test/unit/indices/optimize_test.rb
+- test/unit/indices/put_alias_test.rb
+- test/unit/indices/put_mapping_test.rb
+- test/unit/indices/put_settings_test.rb
+- test/unit/indices/put_template_test.rb
+- test/unit/indices/put_warmer_test.rb
+- test/unit/indices/recovery_test.rb
+- test/unit/indices/refresh_test.rb
+- test/unit/indices/segments_test.rb
+- test/unit/indices/snapshot_index_test.rb
+- test/unit/indices/stats_test.rb
+- test/unit/indices/status_test.rb
+- test/unit/indices/update_aliases_test.rb
+- test/unit/indices/validate_query_test.rb
+- test/unit/info_test.rb
+- test/unit/json_builders_test.rb
+- test/unit/list_benchmarks_test.rb
+- test/unit/mget_test.rb
+- test/unit/mlt_test.rb
+- test/unit/mpercolate_test.rb
+- test/unit/msearch_test.rb
+- test/unit/mtermvectors_test.rb
+- test/unit/nodes/hot_threads_test.rb
+- test/unit/nodes/info_test.rb
+- test/unit/nodes/shutdown_test.rb
+- test/unit/nodes/stats_test.rb
+- test/unit/percolate_test.rb
+- test/unit/ping_test.rb
+- test/unit/scroll_test.rb
+- test/unit/search_shards_test.rb
+- test/unit/search_template_test.rb
+- test/unit/search_test.rb
+- test/unit/snapshot/create_repository_test.rb
+- test/unit/snapshot/create_test.rb
+- test/unit/snapshot/delete_repository_test.rb
+- test/unit/snapshot/delete_test.rb
+- test/unit/snapshot/get_repository_test.rb
+- test/unit/snapshot/get_test.rb
+- test/unit/snapshot/restore_test.rb
+- test/unit/snapshot/status_test.rb
+- test/unit/suggest_test.rb
+- test/unit/termvector_test.rb
+- test/unit/update_document_test.rb
+- test/unit/utils_test.rb
+has_rdoc: 
diff --git a/test/integration/yaml_test_runner.rb b/test/integration/yaml_test_runner.rb
new file mode 100644
index 0000000..0adde7a
--- /dev/null
+++ b/test/integration/yaml_test_runner.rb
@@ -0,0 +1,439 @@
+RUBY_1_8 = defined?(RUBY_VERSION) && RUBY_VERSION < '1.9'
+JRUBY    = defined?(JRUBY_VERSION)
+
+require 'pathname'
+require 'logger'
+require 'yaml'
+require 'active_support/inflector'
+require 'ansi'
+require 'turn'
+
+require 'elasticsearch'
+require 'elasticsearch/extensions/test/cluster'
+require 'elasticsearch/extensions/test/startup_shutdown'
+require 'elasticsearch/extensions/test/profiling' unless JRUBY
+
+# Skip features
+SKIP_FEATURES = ENV['TEST_SKIP_FEATURES'] || ''
+
+# Turn configuration
+ENV['ansi'] = 'false' if ENV['CI']
+Turn.config.format = :pretty
+
+# Launch test cluster
+#
+Elasticsearch::Extensions::Test::Cluster.start(nodes: 1) if ENV['SERVER'] and not Elasticsearch::Extensions::Test::Cluster.running?
+
+# Register `at_exit` handler for server shutdown.
+# MUST be called before requiring `test/unit`.
+#
+at_exit { Elasticsearch::Extensions::Test::Cluster.stop if ENV['SERVER'] }
+
+class String
+  # Reset the `ansi` method on CI
+  def ansi(*args)
+    self
+  end
+end if ENV['CI']
+
+module CapturedLogger
+  def self.included base
+    base.class_eval do
+      %w[ info error warn fatal debug ].each do |m|
+        alias_method "#{m}_without_capture", m
+
+        define_method m do |*args|
+          @logdev.__send__ :puts, *(args.join("\n") + "\n")
+          self.__send__ "#{m}_without_capture", *args
+        end
+      end
+    end
+  end
+end
+
+Logger.__send__ :include, CapturedLogger if ENV['CI']
+
+logger = Logger.new($stderr)
+logger.progname = 'elasticsearch'
+logger.formatter = proc do |severity, datetime, progname, msg|
+  color = case severity
+    when /INFO/ then :green
+    when /ERROR|WARN|FATAL/ then :red
+    when /DEBUG/ then :cyan
+    else :white
+  end
+  "#{severity[0]} ".ansi(color, :faint) + msg.ansi(:white, :faint) + "\n"
+end
+
+tracer = Logger.new($stdout)
+tracer.progname = 'elasticsearch.tracer'
+tracer.formatter = proc { |severity, datetime, progname, msg| "#{msg}\n" }
+
+# Set up the client for the test
+#
+# To set up your own client, just set the `$client` variable in a file, and then require it:
+#
+#     ruby -I lib:test -r ./tmp/my_special_client.rb test/integration/yaml_test_runner.rb
+#
+$client ||= Elasticsearch::Client.new host: "localhost:#{ENV['TEST_CLUSTER_PORT'] || 9250}"
+
+$client.transport.logger = logger unless ENV['QUIET'] || ENV['CI']
+$client.transport.tracer = tracer if ENV['CI']
+
+# Store Elasticsearch version
+#
+es_version_info = $client.info['version']
+$es_version = es_version_info['number']
+
+puts '-'*80,
+     "Elasticsearch #{$es_version.ansi(:bold)} [#{es_version_info['build_hash'].to_s[0...7]}]".center(80),
+     '-'*80
+
+require 'test_helper'
+require 'test/unit'
+require 'shoulda/context'
+
+# Monkeypatch shoulda to remove "should" from test name
+#
+module Shoulda
+  module Context
+    class Context
+      def create_test_from_should_hash(should)
+        test_name = ["test:", full_name, "|", "#{should[:name]}"].flatten.join(' ').to_sym
+
+        if test_methods[test_unit_class][test_name.to_s] then
+          raise DuplicateTestError, "'#{test_name}' is defined more than once."
+        end
+
+        test_methods[test_unit_class][test_name.to_s] = true
+
+        context = self
+        test_unit_class.send(:define_method, test_name) do
+          @shoulda_context = context
+          begin
+            context.run_parent_setup_blocks(self)
+            should[:before].bind(self).call if should[:before]
+            context.run_current_setup_blocks(self)
+            should[:block].bind(self).call
+          ensure
+            context.run_all_teardown_blocks(self)
+          end
+        end
+      end
+    end
+  end
+end
+
+module Elasticsearch
+  module YamlTestSuite
+    $results = {}
+    $stash   = {}
+
+    module Utils
+      def titleize(word)
+        word.to_s.gsub(/[^\w]+/, ' ').gsub(/\b('?[a-z])/) { $1.capitalize }.tr('_', ' ')
+      end
+
+      def symbolize_keys(object)
+        if object.is_a? Hash
+          object.reduce({}) { |memo,(k,v)| memo[k.to_sym] = symbolize_keys(v); memo }
+        else
+          object
+        end
+      end
+
+      extend self
+    end
+
+    module Runner
+      def perform_api_call(test, api, arguments=nil)
+        namespace = api.split('.')
+
+        replacer = lambda do |value|
+          case value
+            when Array
+              value.map { |v| replacer.call(v) }
+            when Hash
+              Hash[ value.map { |v| replacer.call(v) } ]
+            else
+              fetch_or_return value
+          end
+        end
+
+        timefixer = lambda do |value|
+          if value.is_a?(Time)
+            value.iso8601
+          else
+            value
+          end
+        end
+
+        arguments = Hash[
+          arguments.map do |key, value|
+            replacement = replacer.call(value)
+            replacement = timefixer.call(replacement)
+            [key, replacement]
+          end
+        ]
+
+        $stderr.puts "ARGUMENTS: #{arguments.inspect}" if ENV['DEBUG']
+
+        $results[test.hash] = namespace.reduce($client) do |memo, current|
+          unless current == namespace.last
+            memo = memo.send(current)
+          else
+            arguments ? memo = memo.send(current, arguments) : memo = memo.send(current)
+          end
+          memo
+        end
+      end
+
+      def evaluate(test, property)
+        property.gsub(/\\\./, '_____').split('.').reduce($results[test.hash]) do |memo, attr|
+          if memo
+            attr = attr.gsub(/_____/, '.') if attr
+            memo = memo.is_a?(Hash) ? memo[attr] : memo[attr.to_i]
+          end
+          memo
+        end
+      end
+
+      def in_context(name, &block)
+        klass = Class.new(YamlTestCase)
+        Object::const_set "%sTest" % name.split(/\s/).map { |d| d.capitalize }.join('').gsub(/[^\w]+/, ''), klass
+        klass.context name, &block
+      end
+
+      def fetch_or_return(var)
+        if var.is_a?(String) && var =~ /^\$(.+)/
+          $stash[var]
+        else
+          var
+        end
+      end
+
+      def set(var, val)
+        $stash["$#{var}"] = val
+      end
+
+      def skip?(actions)
+        skip = actions.select { |a| a['skip'] }.first
+        $stderr.puts "SKIP: #{skip.inspect}" if ENV['DEBUG']
+
+        # Skip version
+        if skip && skip['skip']['version']
+          min, max = skip['skip']['version'].split('-').map(&:strip)
+
+          min_normalized = sprintf "%03d-%03d-%03d",
+                           *min.split('.')
+                               .map(&:to_i)
+                               .fill(0, min.split('.').length, 3-min.split('.').length)
+
+          max_normalized = sprintf "%03d-%03d-%03d",
+                           *max.split('.')
+                               .map(&:to_i)
+                               .map(&:to_i)
+                               .fill(0, max.split('.').length, 3-max.split('.').length)
+
+          es_normalized  = sprintf "%03d-%03d-%03d", *$es_version.split('.').map(&:to_i)
+
+          if min_normalized <= es_normalized && max_normalized >= es_normalized
+            return skip['skip']['reason'] ? skip['skip']['reason'] : true
+          end
+
+        # Skip features
+        elsif skip && skip['skip']['features']
+          if (skip['skip']['features'].split(',') & SKIP_FEATURES.split(',') ).size > 0
+            return skip['skip']['features']
+          end
+        end
+
+        return false
+      end
+
+      extend self
+    end
+
+    class YamlTestCase < ::Test::Unit::TestCase; end
+  end
+end
+
+include Elasticsearch::YamlTestSuite
+
+PATH    = Pathname(ENV['TEST_REST_API_SPEC'] || \
+          File.expand_path('../../../../support/elasticsearch/rest-api-spec/test', __FILE__))
+suites  = Dir.glob(PATH.join('*')).map { |d| Pathname(d) }
+suites  = suites.select { |s| s.to_s =~ Regexp.new(ENV['FILTER']) } if ENV['FILTER']
+
+suites.each do |suite|
+  name = Elasticsearch::YamlTestSuite::Utils.titleize(suite.basename)
+
+  Elasticsearch::YamlTestSuite::Runner.in_context name do
+
+    # --- Register context setup -------------------------------------------
+    #
+    setup do
+      $client.indices.delete index: '_all'
+      $client.indices.delete_template name: '*'
+      $results = {}
+      $stash   = {}
+    end
+
+    # --- Register context teardown ----------------------------------------
+    #
+    teardown do
+      $client.indices.delete index: '_all'
+    end
+
+    files = Dir[suite.join('*.{yml,yaml}')]
+    files.each do |file|
+      tests = YAML.load_documents File.new(file)
+
+      # Extract setup actions
+      setup_actions = tests.select { |t| t['setup'] }.first['setup'] rescue []
+
+      # Skip all the tests when `skip` is part of the `setup` part
+      if features = Runner.skip?(setup_actions)
+        $stdout.puts "#{'SKIP'.ansi(:yellow)} [#{name}] #{file.gsub(PATH.to_s, '').ansi(:bold)} (Feature not implemented: #{features})"
+        next
+      end
+
+      # Remove setup actions from tests
+      tests = tests.reject { |t| t['setup'] }
+
+      # Add setup actions to each individual test
+      tests.each { |t| t[t.keys.first] << { 'setup' => setup_actions } }
+
+      tests.each do |test|
+        context '' do
+          test_name = test.keys.first.to_s + (ENV['QUIET'] ? '' : " | #{file.gsub(PATH.to_s, '').ansi(:bold)}")
+          actions   = test.values.first
+
+          if reason = Runner.skip?(actions)
+            $stdout.puts "#{'SKIP'.ansi(:yellow)} [#{name}] #{test_name} (Reason: #{reason})"
+            next
+          end
+
+          # --- Register test setup -------------------------------------------
+          setup do
+            actions.select { |a| a['setup'] }.first['setup'].each do |action|
+              next unless action['do']
+              api, arguments = action['do'].to_a.first
+              arguments      = Utils.symbolize_keys(arguments)
+              Runner.perform_api_call((test.to_s + '___setup'), api, arguments)
+            end
+          end
+
+          # --- Register test method ------------------------------------------
+          should test_name do
+            if ENV['CI']
+              ref = ENV['TEST_BUILD_REF'].to_s.gsub(/origin\//, '') || 'master'
+              $stderr.puts "https://github.com/elasticsearch/elasticsearch/blob/#{ref}/rest-api-spec/test/" \
+                          + file.gsub(PATH.to_s, ''), ""
+              $stderr.puts YAML.dump(test)
+            end
+            actions.each do |action|
+              $stderr.puts "ACTION: #{action.inspect}" if ENV['DEBUG']
+
+              case
+
+                # --- Perform action ------------------------------------------
+                #
+                when action['do']
+                  catch_exception = action['do'].delete('catch') if action['do']
+                  api, arguments = action['do'].to_a.first
+                  arguments      = Utils.symbolize_keys(arguments)
+
+                  begin
+                    $results[test.hash] = Runner.perform_api_call(test, api, arguments)
+                  rescue Exception => e
+                    if catch_exception
+                      $stderr.puts "CATCH '#{catch_exception}': #{e.inspect}" if ENV['DEBUG']
+                      case e
+                        when 'missing'
+                          assert_match /\[404\]/, e.message
+                        when 'conflict'
+                          assert_match /\[409\]/, e.message
+                        when 'request'
+                          assert_match /\[500\]/, e.message
+                        when 'param'
+                          raise ArgumentError, "NOT IMPLEMENTED"
+                        when /\/.+\//
+                          assert_match Regexp.new(catch_exception.tr('/', '')), e.message
+                      end
+                    else
+                      raise e
+                    end
+                  end
+
+                # --- Evaluate predicates -------------------------------------
+                #
+                when property = action['is_true']
+                  result = Runner.evaluate(test, property)
+                  $stderr.puts "CHECK: Expected '#{property}' to be true, is: #{result.inspect}" if ENV['DEBUG']
+                  assert(result, "Property '#{property}' should be true, is: #{result.inspect}")
+
+                when property = action['is_false']
+                  result = Runner.evaluate(test, property)
+                  $stderr.puts "CHECK: Expected '#{property}' to be false, is: #{result.inspect}" if ENV['DEBUG']
+                  assert( !!! result, "Property '#{property}' should be false, is: #{result.inspect}")
+
+                when a = action['match']
+                  property, value = a.to_a.first
+
+                  if value.is_a?(String) && value =~ %r{\s*^/\s*.*\s*/$\s*}mx # Begins and ends with /
+                    pattern = Regexp.new(value.strip[1..-2], Regexp::EXTENDED|Regexp::MULTILINE)
+                  else
+                    value  = Runner.fetch_or_return(value)
+                  end
+
+                  if property == '$body'
+                    result = $results[test.hash]
+                  else
+                    result = Runner.evaluate(test, property)
+                  end
+
+                  if pattern
+                    $stderr.puts "CHECK: Expected '#{property}' to match #{pattern}, is: #{result.inspect}" if ENV['DEBUG']
+                    assert_match(pattern, result)
+                  else
+                    value = value.reduce({}) { |memo, (k,v)| memo[k] =  Runner.fetch_or_return(v); memo  } if value.is_a? Hash
+                    $stderr.puts "CHECK: Expected '#{property}' to be '#{value}', is: #{result.inspect}" if ENV['DEBUG']
+                    assert_equal(value, result)
+                  end
+
+                when a = action['length']
+                  property, value = a.to_a.first
+
+                  result = Runner.evaluate(test, property)
+                  length = result.size
+                  $stderr.puts "CHECK: Expected '#{property}' to be #{value}, is: #{length.inspect}" if ENV['DEBUG']
+                  assert_equal(value, length)
+
+                when a = action['lt'] || action['gt']
+                  next
+                  property, value = a.to_a.first
+                  operator        = action['lt'] ? '<' : '>'
+
+                  result  = Runner.evaluate(test, property)
+                  message = "Expected '#{property}' to be #{operator} #{value}, is: #{result.inspect}"
+
+                  $stderr.puts "CHECK: #{message}" if ENV['DEBUG']
+                  # operator == 'less than' ? assert(value.to_f < result.to_f, message) : assert(value.to_f > result.to_f, message)
+                  assert_operator result, operator.to_sym, value.to_i
+
+                when stash = action['set']
+                  property, variable = stash.to_a.first
+                  result  = Runner.evaluate(test, property)
+                  $stderr.puts "STASH: '$#{variable}' => #{result.inspect}" if ENV['DEBUG']
+                  Runner.set variable, result
+              end
+            end
+          end
+        end
+      end
+    end
+
+  end
+
+end
diff --git a/test/test_helper.rb b/test/test_helper.rb
new file mode 100644
index 0000000..0590278
--- /dev/null
+++ b/test/test_helper.rb
@@ -0,0 +1,69 @@
+RUBY_1_8 = defined?(RUBY_VERSION) && RUBY_VERSION < '1.9'
+JRUBY    = defined?(JRUBY_VERSION)
+
+if RUBY_1_8 and not ENV['BUNDLE_GEMFILE']
+  require 'rubygems'
+  gem 'test-unit'
+end
+
+if ENV['COVERAGE'] && ENV['CI'].nil? && !RUBY_1_8
+  require 'simplecov'
+  SimpleCov.start { add_filter "/test|test_/" }
+end
+
+if ENV['CI'] && !RUBY_1_8
+  require 'simplecov'
+  require 'simplecov-rcov'
+  SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
+  SimpleCov.start { add_filter "/test|test_" }
+end
+
+require 'test/unit'
+require 'shoulda-context'
+require 'mocha/setup'
+
+unless ENV["NOTURN"] || RUBY_1_8
+  require 'turn'
+
+  if ENV['QUIET']
+    Turn.config.format = :outline
+    Turn.config.trace = 1
+  end
+end
+
+require 'require-prof' if ENV["REQUIRE_PROF"]
+require 'elasticsearch/api'
+RequireProf.print_timing_infos if ENV["REQUIRE_PROF"]
+
+if defined?(RUBY_VERSION) && RUBY_VERSION > '1.9'
+  require 'elasticsearch/extensions/test/cluster'
+  require 'elasticsearch/extensions/test/startup_shutdown'
+  require 'elasticsearch/extensions/test/profiling' unless JRUBY
+end
+
+module Elasticsearch
+  module Test
+    class FakeClient
+      include Elasticsearch::API
+
+      def perform_request(method, path, params, body)
+        puts "PERFORMING REQUEST:", "--> #{method.to_s.upcase} #{path} #{params} #{body}"
+        FakeResponse.new(200, 'FAKE', {})
+      end
+    end
+
+    FakeResponse = Struct.new(:status, :body, :headers) do
+      def status
+        values[0] || 200
+      end
+      def body
+        values[1] || '{}'
+      end
+      def headers
+        values[2] || {}
+      end
+    end
+
+    class NotFound < StandardError; end
+  end
+end
diff --git a/test/unit/abort_benchmark_test.rb b/test/unit/abort_benchmark_test.rb
new file mode 100644
index 0000000..63b5f18
--- /dev/null
+++ b/test/unit/abort_benchmark_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class AbortBenchmarkTest < ::Test::Unit::TestCase
+
+      context "Abort benchmark" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'POST', method
+            assert_equal '_bench/abort/foo', url
+            assert_equal nil, params[:name]
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.abort_benchmark :name => 'foo'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/benchmark_test.rb b/test/unit/benchmark_test.rb
new file mode 100644
index 0000000..5fb4a59
--- /dev/null
+++ b/test/unit/benchmark_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class BenchmarkTest < ::Test::Unit::TestCase
+
+      context "Benchmark" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'PUT', method
+            assert_equal '_bench', url
+            assert_equal Hash.new, params
+            assert_equal 'foo', body[:name]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.benchmark :body => { :name => 'foo' }
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/bulk_test.rb b/test/unit/bulk_test.rb
new file mode 100644
index 0000000..46228e0
--- /dev/null
+++ b/test/unit/bulk_test.rb
@@ -0,0 +1,94 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class BulkTest < ::Test::Unit::TestCase
+
+      context "Bulk" do
+        subject { FakeClient.new }
+
+        should "post correct payload to the endpoint" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'POST', method
+            assert_equal '_bulk', url
+            assert_equal Hash.new, params
+
+            if RUBY_1_8
+              lines = body.split("\n")
+
+              assert_equal 5, lines.size
+              assert_match /\{"index"\:\{/, lines[0]
+              assert_match /\{"title"\:"Test"/, lines[1]
+              assert_match /\{"update"\:\{/, lines[2]
+              assert_match /\{"doc"\:\{"title"/, lines[3]
+            else
+              assert_equal <<-PAYLOAD.gsub(/^\s+/, ''), body
+                {"index":{"_index":"myindexA","_type":"mytype","_id":"1"}}
+                {"title":"Test"}
+                {"update":{"_index":"myindexB","_type":"mytype","_id":"2"}}
+                {"doc":{"title":"Update"}}
+                {"delete":{"_index":"myindexC","_type":"mytypeC","_id":"3"}}
+              PAYLOAD
+            end
+            true
+          end.returns(FakeResponse.new)
+
+          subject.bulk :body => [
+            { :index =>  { :_index => 'myindexA', :_type => 'mytype', :_id => '1', :data => { :title => 'Test' } } },
+            { :update => { :_index => 'myindexB', :_type => 'mytype', :_id => '2', :data => { :doc => { :title => 'Update' } } } },
+            { :delete => { :_index => 'myindexC', :_type => 'mytypeC', :_id => '3' } }
+          ]
+        end
+
+        should "post payload to the correct endpoint" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'POST', method
+            assert_equal 'myindex/_bulk', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.bulk :index => 'myindex', :body => []
+        end
+
+        should "post a string payload" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal "foo\nbar", body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.bulk :body => "foo\nbar"
+        end
+
+        should "post an array of strings payload" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal "foo\nbar\n", body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.bulk :body => ["foo", "bar"]
+        end
+
+        should "encode URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_bulk', url
+            assert_equal({:refresh => true}, params)
+            true
+          end.returns(FakeResponse.new)
+
+          subject.bulk :refresh => true, :body => []
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_bulk', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.bulk :index => 'foo^bar', :body => []
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/cat/aliases_test.rb b/test/unit/cat/aliases_test.rb
new file mode 100644
index 0000000..4f81564
--- /dev/null
+++ b/test/unit/cat/aliases_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class CatAliasesTest < ::Test::Unit::TestCase
+
+      context "Cat: Aliases" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_cat/aliases', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cat.aliases
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/cat/allocation_test.rb b/test/unit/cat/allocation_test.rb
new file mode 100644
index 0000000..ab764c3
--- /dev/null
+++ b/test/unit/cat/allocation_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class CatAllocationTest < ::Test::Unit::TestCase
+
+      context "Cat: Allocation" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_cat/allocation', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cat.allocation
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/cat/count_test.rb b/test/unit/cat/count_test.rb
new file mode 100644
index 0000000..e1ea5b1
--- /dev/null
+++ b/test/unit/cat/count_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class CatCountTest < ::Test::Unit::TestCase
+
+      context "Cat: Count" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_cat/count', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cat.count
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/cat/fielddata_test.rb b/test/unit/cat/fielddata_test.rb
new file mode 100644
index 0000000..c51e9ec
--- /dev/null
+++ b/test/unit/cat/fielddata_test.rb
@@ -0,0 +1,38 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class CatFielddataTest < ::Test::Unit::TestCase
+
+      context "Cat: Fielddata" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_cat/fielddata', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cat.fielddata
+        end
+
+        should "pass the fields in the URL" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_cat/fielddata/foo,bar', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cat.fielddata :fields => ['foo', 'bar']
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/cat/health_test.rb b/test/unit/cat/health_test.rb
new file mode 100644
index 0000000..a8ac34a
--- /dev/null
+++ b/test/unit/cat/health_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class CatHealthTest < ::Test::Unit::TestCase
+
+      context "Cat: Health" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_cat/health', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cat.health
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/cat/help_test.rb b/test/unit/cat/help_test.rb
new file mode 100644
index 0000000..6cad8cc
--- /dev/null
+++ b/test/unit/cat/help_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class CatHelpTest < ::Test::Unit::TestCase
+
+      context "Cat: Help" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_cat', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cat.help
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/cat/indices_test.rb b/test/unit/cat/indices_test.rb
new file mode 100644
index 0000000..0d1e222
--- /dev/null
+++ b/test/unit/cat/indices_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class CatIndicesTest < ::Test::Unit::TestCase
+
+      context "Cat: Indices" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_cat/indices', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cat.indices
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/cat/master_test.rb b/test/unit/cat/master_test.rb
new file mode 100644
index 0000000..76f4071
--- /dev/null
+++ b/test/unit/cat/master_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class CatMasterTest < ::Test::Unit::TestCase
+
+      context "Cat: Master" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_cat/master', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cat.master
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/cat/nodes_test.rb b/test/unit/cat/nodes_test.rb
new file mode 100644
index 0000000..c74d68c
--- /dev/null
+++ b/test/unit/cat/nodes_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class CatNodesTest < ::Test::Unit::TestCase
+
+      context "Cat: Nodes" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_cat/nodes', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cat.nodes
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/cat/pending_tasks_test.rb b/test/unit/cat/pending_tasks_test.rb
new file mode 100644
index 0000000..771ed5a
--- /dev/null
+++ b/test/unit/cat/pending_tasks_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class CatPendingTasksTest < ::Test::Unit::TestCase
+
+      context "Cat: Pending tasks" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_cat/pending_tasks', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cat.pending_tasks
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/cat/recovery_test.rb b/test/unit/cat/recovery_test.rb
new file mode 100644
index 0000000..b267ba2
--- /dev/null
+++ b/test/unit/cat/recovery_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class CatRecoveryTest < ::Test::Unit::TestCase
+
+      context "Cat: Recovery" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_cat/recovery', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cat.recovery
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/cat/shards_test.rb b/test/unit/cat/shards_test.rb
new file mode 100644
index 0000000..9f153fe
--- /dev/null
+++ b/test/unit/cat/shards_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class CatShardsTest < ::Test::Unit::TestCase
+
+      context "Cat: Shards" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_cat/shards', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cat.shards
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/cat/thread_pool_test.rb b/test/unit/cat/thread_pool_test.rb
new file mode 100644
index 0000000..b00cf44
--- /dev/null
+++ b/test/unit/cat/thread_pool_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class CatThreadPoolTest < ::Test::Unit::TestCase
+
+      context "Cat: Thread pool" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_cat/thread_pool', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cat.thread_pool
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/clear_scroll_test.rb b/test/unit/clear_scroll_test.rb
new file mode 100644
index 0000000..6ce0a2b
--- /dev/null
+++ b/test/unit/clear_scroll_test.rb
@@ -0,0 +1,38 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class ClearScrollTest < ::Test::Unit::TestCase
+
+      context "Clear scroll" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'DELETE', method
+            assert_equal '_search/scroll/abc123', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.clear_scroll :scroll_id => 'abc123'
+        end
+
+        should "listify scroll IDs" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'DELETE', method
+            assert_equal '_search/scroll/abc123,def456', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.clear_scroll :scroll_id => ['abc123', 'def456']
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/client_test.rb b/test/unit/client_test.rb
new file mode 100644
index 0000000..4a94abd
--- /dev/null
+++ b/test/unit/client_test.rb
@@ -0,0 +1,31 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class ClientTest < ::Test::Unit::TestCase
+
+      context "API Client" do
+
+        class MyDummyClient
+          include Elasticsearch::API
+        end
+
+        subject { MyDummyClient.new }
+
+        should "have the cluster namespace" do
+          assert_respond_to subject, :cluster
+        end
+
+        should "have the indices namespace" do
+          assert_respond_to subject, :indices
+        end
+
+        should "have API methods" do
+          assert_respond_to subject, :bulk
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/cluster/get_settings_test.rb b/test/unit/cluster/get_settings_test.rb
new file mode 100644
index 0000000..bd74fb3
--- /dev/null
+++ b/test/unit/cluster/get_settings_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class ClusterGetSettingsTest < ::Test::Unit::TestCase
+
+      context "Cluster: Get settings" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_cluster/settings', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cluster.get_settings
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/cluster/health_test.rb b/test/unit/cluster/health_test.rb
new file mode 100644
index 0000000..2e5382d
--- /dev/null
+++ b/test/unit/cluster/health_test.rb
@@ -0,0 +1,38 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class Cluster_Test < ::Test::Unit::TestCase
+
+      context "Health" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_cluster/health', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cluster.health
+        end
+
+        should "encode URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_cluster/health', url
+            assert_equal({:level => 'indices'}, params)
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cluster.health :level => 'indices'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/cluster/pending_tasks_test.rb b/test/unit/cluster/pending_tasks_test.rb
new file mode 100644
index 0000000..01b31c0
--- /dev/null
+++ b/test/unit/cluster/pending_tasks_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class ClusterPendingTasksTest < ::Test::Unit::TestCase
+
+      context "Cluster: Pending tasks" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '/_cluster/pending_tasks', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cluster.pending_tasks
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/cluster/put_settings_test.rb b/test/unit/cluster/put_settings_test.rb
new file mode 100644
index 0000000..5d7284e
--- /dev/null
+++ b/test/unit/cluster/put_settings_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class ClusterPutSettingsTest < ::Test::Unit::TestCase
+
+      context "Cluster: Put settings" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'PUT', method
+            assert_equal '_cluster/settings', url
+            assert_equal Hash.new, params
+            assert_equal Hash.new, body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cluster.put_settings
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/cluster/reroute_test.rb b/test/unit/cluster/reroute_test.rb
new file mode 100644
index 0000000..dc2306e
--- /dev/null
+++ b/test/unit/cluster/reroute_test.rb
@@ -0,0 +1,38 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class ClusterRerouteTest < ::Test::Unit::TestCase
+
+      context "Cluster: Reroute" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'POST', method
+            assert_equal '_cluster/reroute', url
+            assert_equal Hash.new, params
+            assert_equal Hash.new, body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cluster.reroute
+        end
+
+        should "send the body" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'POST', method
+            assert_equal '_cluster/reroute', url
+            assert_equal Hash.new, params
+            assert_equal({:commands => [ :move => { :index => 'myindex', :shard => 0 } ]}, body)
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cluster.reroute :body => { :commands => [ :move => { :index => 'myindex', :shard => 0 } ] }
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/cluster/state_test.rb b/test/unit/cluster/state_test.rb
new file mode 100644
index 0000000..71bcf74
--- /dev/null
+++ b/test/unit/cluster/state_test.rb
@@ -0,0 +1,46 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class ClusterStateTest < ::Test::Unit::TestCase
+
+      context "Cluster: State" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_cluster/state', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cluster.state
+        end
+
+        should "build the correct path" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_cluster/state/foo,bar', url
+            assert_equal({}, params)
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cluster.state :metric => ['foo', 'bar']
+        end
+
+        should "send the API parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_cluster/state', url
+            assert_equal({:index_templates => 'foo,bar'}, params)
+            true
+          end.returns(FakeResponse.new)
+
+          subject.cluster.state :index_templates => ['foo', 'bar']
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/count_percolate_test.rb b/test/unit/count_percolate_test.rb
new file mode 100644
index 0000000..091c230
--- /dev/null
+++ b/test/unit/count_percolate_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class CountPercolateTest < ::Test::Unit::TestCase
+
+      context "Count percolate" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal 'foo/bar/_percolate/count', url
+            assert_equal Hash.new, params
+            assert_equal 'bar', body[:doc][:foo]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.count_percolate :index => 'foo', :type => 'bar', :body => { :doc => { :foo => 'bar' } }
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/count_test.rb b/test/unit/count_test.rb
new file mode 100644
index 0000000..dc37e47
--- /dev/null
+++ b/test/unit/count_test.rb
@@ -0,0 +1,46 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class CountTest < ::Test::Unit::TestCase
+
+      context "Count" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_count', url
+            assert_equal Hash.new, params
+            assert_nil body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.count
+        end
+
+        should "encode indices and types" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal 'foo,bar/t1,t2/_count', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.count :index => ['foo','bar'], :type => ['t1','t2']
+        end
+
+        should "take the query" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal( {:match => {:foo => 'bar'}}, body)
+            true
+          end.returns(FakeResponse.new)
+
+          subject.count :body => { :match => { :foo => 'bar' } }
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/create_document_test.rb b/test/unit/create_document_test.rb
new file mode 100644
index 0000000..46b345c
--- /dev/null
+++ b/test/unit/create_document_test.rb
@@ -0,0 +1,47 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndexDocumentTest < ::Test::Unit::TestCase
+
+      context "Creating a document with the #create method" do
+        subject { FakeClient.new }
+
+        should "perform the create request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'POST', method
+            assert_equal 'foo/bar', url
+            assert_equal({:op_type => 'create'}, params)
+            assert_equal({:foo => 'bar'}, body)
+            true
+          end.returns(FakeResponse.new)
+
+          subject.create :index => 'foo', :type => 'bar', :body => {:foo => 'bar'}
+        end
+
+        should "perform the create request with a specific ID" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'PUT', method
+            assert_equal 'foo/bar/123', url
+            assert_equal 'create', params[:op_type]
+            assert_nil   params[:id]
+            assert_equal({:foo => 'bar'}, body)
+            true
+          end.returns(FakeResponse.new)
+
+          subject.create :index => 'foo', :type => 'bar', :id => '123', :body => {:foo => 'bar'}
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/bar%2Fbam/123', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.create :index => 'foo', :type => 'bar/bam', :id => '123', :body => {}
+        end
+      end
+
+    end
+  end
+end
diff --git a/test/unit/delete_by_query_test.rb b/test/unit/delete_by_query_test.rb
new file mode 100644
index 0000000..45ac552
--- /dev/null
+++ b/test/unit/delete_by_query_test.rb
@@ -0,0 +1,51 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class DeleteByQueryTest < ::Test::Unit::TestCase
+
+      context "Delete by query" do
+        subject { FakeClient.new }
+
+        should "require the :index argument" do
+          assert_raise ArgumentError do
+            subject.delete_by_query :body => {}
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'DELETE', method
+            assert_equal 'foo/_query', url
+            assert_equal Hash.new, params
+            assert_equal Hash.new, body[:term]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.delete_by_query :index => 'foo', :body => { :term => {} }
+        end
+
+        should "optionally take the :type argument" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/tweet,post/_query', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.delete_by_query :index => 'foo', :type => ['tweet', 'post'], :body => { :term => {} }
+        end
+
+        should "pass the query in URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_query', url
+            assert_equal 'foo:bar', params[:q]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.delete_by_query :index => 'foo', :q => 'foo:bar'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/delete_document_test.rb b/test/unit/delete_document_test.rb
new file mode 100644
index 0000000..d8c39cf
--- /dev/null
+++ b/test/unit/delete_document_test.rb
@@ -0,0 +1,77 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class DeleteTest < ::Test::Unit::TestCase
+
+      context "Delete document" do
+        subject { FakeClient.new }
+
+        should "require the :index argument" do
+          assert_raise ArgumentError do
+            subject.delete :type => 'bar', :id => '1'
+          end
+        end
+
+        should "require the :type argument" do
+          assert_raise ArgumentError do
+            subject.delete :index => 'foo', :id => '1'
+          end
+        end
+
+        should "require the :id argument" do
+          assert_raise ArgumentError do
+            subject.delete :index => 'foo', :type => 'bar'
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'DELETE', method
+            assert_equal 'foo/bar/1', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.delete :index => 'foo', :type => 'bar', :id => '1'
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/bar/1', url
+            assert_equal 'abc123', params[:routing]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.delete :index => 'foo', :type => 'bar', :id => '1', :routing => 'abc123'
+        end
+
+        should "validate URL parameters" do
+          assert_raise ArgumentError do
+            subject.delete :index => 'foo', :type => 'bar', :id => '1', :qwertypoiuy => 'asdflkjhg'
+          end
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/bar%2Fbam/1', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.delete :index => 'foo^bar', :type => 'bar/bam', :id => 1
+        end
+
+        should "catch a NotFound exception with the ignore parameter" do
+          subject.expects(:perform_request).raises(NotFound)
+
+          assert_nothing_raised do
+            subject.get :index => 'foo', :type => 'bar', :id => 'XXX', :ignore => 404
+          end
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/exists_document_test.rb b/test/unit/exists_document_test.rb
new file mode 100644
index 0000000..d127c11
--- /dev/null
+++ b/test/unit/exists_document_test.rb
@@ -0,0 +1,85 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class ExistsTest < ::Test::Unit::TestCase
+
+      context "Exists document" do
+        subject { FakeClient.new }
+
+        should "require the :index argument" do
+          assert_raise ArgumentError do
+            subject.exists :type => 'bar', :id => '1'
+          end
+        end
+
+        should "NOT require the :type argument" do
+          assert_nothing_raised do
+            subject.exists :index => 'foo', :id => '1'
+          end
+        end
+
+        should "require the :id argument" do
+          assert_raise ArgumentError do
+            subject.exists :index => 'foo', :type => 'bar'
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'HEAD', method
+            assert_equal 'foo/bar/1', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.exists :index => 'foo', :type => 'bar', :id => '1'
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/bar/1', url
+            assert_equal 'abc123', params[:routing]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.exists :index => 'foo', :type => 'bar', :id => '1', :routing => 'abc123'
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/bar%2Fbam/1', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.exists :index => 'foo', :type => 'bar/bam', :id => '1'
+        end
+
+        should "return true for successful response" do
+          subject.expects(:perform_request).returns(FakeResponse.new 200, 'OK')
+          assert_equal true, subject.exists(:index => 'foo', :type => 'bar', :id => '1')
+        end
+
+        should "return false for 404 response" do
+          subject.expects(:perform_request).returns(FakeResponse.new 404, 'Not Found')
+          assert_equal false, subject.exists(:index => 'foo', :type => 'bar', :id => '1')
+        end
+
+        should "return false on 'not found' exceptions" do
+          subject.expects(:perform_request).raises(StandardError.new '404 NotFound')
+          assert_equal false, subject.exists(:index => 'foo', :type => 'bar', :id => '1')
+        end
+
+        should "re-raise generic exceptions" do
+          subject.expects(:perform_request).raises(StandardError)
+          assert_raise(StandardError) do
+            assert_equal false, subject.exists(:index => 'foo', :type => 'bar', :id => '1')
+          end
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/explain_document_test.rb b/test/unit/explain_document_test.rb
new file mode 100644
index 0000000..a239cfd
--- /dev/null
+++ b/test/unit/explain_document_test.rb
@@ -0,0 +1,73 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class ExplainTest < ::Test::Unit::TestCase
+
+      context "Explain document" do
+        subject { FakeClient.new }
+
+        should "require the :index argument" do
+          assert_raise ArgumentError do
+            subject.explain :type => 'bar', :id => '1'
+          end
+        end
+
+        should "require the :type argument" do
+          assert_raise ArgumentError do
+            subject.explain :index => 'foo', :id => '1'
+          end
+        end
+
+        should "require the :id argument" do
+          assert_raise ArgumentError do
+            subject.explain :index => 'foo', :type => 'bar'
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal 'foo/bar/1/_explain', url
+            assert_equal Hash.new, params
+            assert_equal Hash.new, body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.explain :index => 'foo', :type => 'bar', :id => 1, :body => {}
+        end
+
+        should "pass the query in URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/bar/1/_explain', url
+            assert_equal 'foo', params[:q]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.explain :index => 'foo', :type => 'bar', :id => 1, :q => 'foo'
+        end
+
+        should "pass the request definition in the body" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/bar/1/_explain', url
+            assert_equal Hash.new, body[:query][:match]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.explain :index => 'foo', :type => 'bar', :id => 1, :body => { :query => { :match => {} } }
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/bar%2Fbam/1/_explain', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.explain :index => 'foo^bar', :type => 'bar/bam', :id => '1', :body => {}
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/get_document_source_test.rb b/test/unit/get_document_source_test.rb
new file mode 100644
index 0000000..a4f9578
--- /dev/null
+++ b/test/unit/get_document_source_test.rb
@@ -0,0 +1,71 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class GetSourceTest < ::Test::Unit::TestCase
+
+      context "Get document source" do
+        subject { FakeClient.new }
+
+        should "require the :index argument" do
+          assert_raise ArgumentError do
+            subject.get_source :type => 'bar', :id => '1'
+          end
+        end
+
+        should "NOT require the :type argument" do
+          assert_nothing_raised do
+            subject.get_source :index => 'foo', :id => '1'
+          end
+        end
+
+        should "require the :id argument" do
+          assert_raise ArgumentError do
+            subject.get_source :index => 'foo', :type => 'bar'
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal 'foo/bar/1/_source', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.get_source :index => 'foo', :type => 'bar', :id => '1'
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/bar/1/_source', url
+            assert_equal 'abc123', params[:routing]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.get_source :index => 'foo', :type => 'bar', :id => '1', :routing => 'abc123'
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/bar%2Fbam/1/_source', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.get_source :index => 'foo^bar', :type => 'bar/bam', :id => '1'
+        end
+
+        should "catch a NotFound exception with the ignore parameter" do
+          subject.expects(:perform_request).raises(NotFound)
+
+          assert_nothing_raised do
+            subject.get :index => 'foo', :type => 'bar', :id => 'XXX', :ignore => 404
+          end
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/get_document_test.rb b/test/unit/get_document_test.rb
new file mode 100644
index 0000000..cbbcd45
--- /dev/null
+++ b/test/unit/get_document_test.rb
@@ -0,0 +1,77 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class GetTest < ::Test::Unit::TestCase
+
+      context "Get document" do
+        subject { FakeClient.new }
+
+        should "require the :index argument" do
+          assert_raise ArgumentError do
+            subject.get :type => 'bar', :id => '1'
+          end
+        end
+
+        should "NOT require the :type argument" do
+          assert_nothing_raised do
+            subject.get :index => 'foo', :id => '1'
+          end
+        end
+
+        should "require the :id argument" do
+          assert_raise ArgumentError do
+            subject.get :index => 'foo', :type => 'bar'
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal 'foo/bar/1', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.get :index => 'foo', :type => 'bar', :id => '1'
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/bar/1', url
+            assert_equal 'abc123', params[:routing]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.get :index => 'foo', :type => 'bar', :id => '1', :routing => 'abc123'
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/bar%2Fbam/1', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.exists :index => 'foo^bar', :type => 'bar/bam', :id => '1'
+        end
+
+        should "validate URL parameters" do
+          assert_raise ArgumentError do
+            subject.get :index => 'foo', :type => 'bar', :id => '1', :qwertypoiuy => 'asdflkjhg'
+          end
+        end
+
+        should "catch a NotFound exception with the ignore parameter" do
+          subject.expects(:perform_request).raises(NotFound)
+
+          assert_nothing_raised do
+            subject.get :index => 'foo', :type => 'bar', :id => 'XXX', :ignore => 404
+          end
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/hashie_test.rb b/test/unit/hashie_test.rb
new file mode 100644
index 0000000..aa5f763
--- /dev/null
+++ b/test/unit/hashie_test.rb
@@ -0,0 +1,78 @@
+require 'test_helper'
+
+require 'hashie'
+
+module Elasticsearch
+  module Test
+    class HashieTest < ::Test::Unit::TestCase
+
+      context "Hashie" do
+        subject { FakeClient.new }
+
+        should "wrap the response" do
+          json =<<-JSON
+            {
+              "took": 14,
+              "timed_out": false,
+              "_shards": {
+                "total": 1,
+                "successful": 1,
+                "failed": 0
+              },
+              "hits": {
+                "total": 5,
+                "max_score": 0.51104903,
+                "hits": [
+                  {
+                    "_index": "myindex",
+                    "_type": "mytype",
+                    "_id": "1",
+                    "_score": 0.51104903,
+                    "_source": {
+                      "title": "Test 1",
+                      "tags": [
+                        "y",
+                        "z"
+                      ],
+                      "published": true,
+                      "published_at": "2013-06-22T21:13:00Z",
+                      "counter": 1
+                    }
+                  }
+                ]
+              },
+              "facets": {
+                "tags": {
+                  "_type": "terms",
+                  "missing": 0,
+                  "total": 10,
+                  "other": 0,
+                  "terms": [
+                    {
+                      "term": "z",
+                      "count": 4
+                    },
+                    {
+                      "term": "y",
+                      "count": 3
+                    },
+                    {
+                      "term": "x",
+                      "count": 3
+                    }
+                  ]
+                }
+              }
+            }
+          JSON
+
+          response = Hashie::Mash.new MultiJson.load(json)
+
+          assert_equal 'Test 1', response.hits.hits.first._source.title
+          assert_equal 'z',      response.facets.tags.terms.first.term
+        end
+      end
+
+    end
+  end
+end
diff --git a/test/unit/index_document_test.rb b/test/unit/index_document_test.rb
new file mode 100644
index 0000000..70e09bf
--- /dev/null
+++ b/test/unit/index_document_test.rb
@@ -0,0 +1,92 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndexDocumentTest < ::Test::Unit::TestCase
+
+      context "Indexing a document" do
+        subject { FakeClient.new }
+
+        should "require the :index argument" do
+          assert_raise ArgumentError do
+            subject.index :type => 'foo'
+          end
+        end
+
+        should "require the :type argument" do
+          assert_raise ArgumentError do
+            subject.index :index => 'foo'
+          end
+        end
+
+        should "perform the index request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'POST', method
+            assert_equal 'foo/bar', url
+            assert_equal({:foo => 'bar'}, body)
+            true
+          end.returns(FakeResponse.new)
+
+          subject.index :index => 'foo', :type => 'bar', :body => {:foo => 'bar'}
+        end
+
+        should "perform the index request with a specific ID" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'PUT', method
+            assert_equal 'foo/bar/123', url
+            assert_nil   params[:id]
+            assert_equal({:foo => 'bar'}, body)
+            true
+          end.returns(FakeResponse.new)
+
+          subject.index :index => 'foo', :type => 'bar', :id => '123', :body => {:foo => 'bar'}
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/bar%2Fbam/123', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.index :index => 'foo', :type => 'bar/bam', :id => '123', :body => {}
+        end
+
+        should "validate URL parameters" do
+          assert_raise ArgumentError do
+            subject.index :index => 'foo', :type => 'bar/bam', :id => '123', :body => {}, :qwertypoiuy => 'asdflkjhg'
+          end
+        end
+      end
+
+      context "Creating a document" do
+        subject { FakeClient.new }
+
+        should "perform the create request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'POST', method
+            assert_equal 'foo/bar', url
+            assert_equal({:op_type => 'create'}, params)
+            assert_equal({:foo => 'bar'}, body)
+            true
+          end.returns(FakeResponse.new)
+
+          subject.index :index => 'foo', :type => 'bar', :op_type => 'create', :body => {:foo => 'bar'}
+        end
+
+        should "perform the create request with a specific ID" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'PUT', method
+            assert_equal 'foo/bar/123', url
+            assert_equal 'create', params[:op_type]
+            assert_nil   params[:id]
+            assert_equal({:foo => 'bar'}, body)
+            true
+          end.returns(FakeResponse.new)
+
+          subject.index :index => 'foo', :type => 'bar', :id => '123', :op_type => 'create', :body => {:foo => 'bar'}
+        end
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/analyze_test.rb b/test/unit/indices/analyze_test.rb
new file mode 100644
index 0000000..2fb8f1a
--- /dev/null
+++ b/test/unit/indices/analyze_test.rb
@@ -0,0 +1,76 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesAnalyzeTest < ::Test::Unit::TestCase
+
+      context "Indices: Analyze" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_analyze', url
+            assert_equal Hash.new, params
+            assert_nil body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.analyze
+        end
+
+        should "perform request against an index" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_analyze', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.analyze :index => 'foo'
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_analyze', url
+            assert_equal 'foo', params[:text]
+            assert_equal 'bar', params[:analyzer]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.analyze :text => 'foo', :analyzer => 'bar'
+        end
+
+        should "pass the text in body" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_analyze', url
+            assert_equal Hash.new, params
+            assert_equal 'foo', body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.analyze :body => 'foo'
+        end
+
+        should "pass the filters parameter as a list" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_analyze', url
+            assert_equal 'foo,bar', params[:filters]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.analyze :text => 'Test', :tokenizer => 'whitespace', :filters => ['foo,bar']
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_analyze', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.analyze :index => 'foo^bar', :text => 'Test'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/clear_cache_test.rb b/test/unit/indices/clear_cache_test.rb
new file mode 100644
index 0000000..34c0b41
--- /dev/null
+++ b/test/unit/indices/clear_cache_test.rb
@@ -0,0 +1,54 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesClearCacheTest < ::Test::Unit::TestCase
+
+      context "Indices: Clear cache" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'POST', method
+            assert_equal '_cache/clear', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.clear_cache
+        end
+
+        should "perform request against an index" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_cache/clear', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.clear_cache :index => 'foo'
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_cache/clear', url
+            assert_equal true, params[:field_data]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.clear_cache :field_data => true
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_cache/clear', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.clear_cache :index => 'foo^bar'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/close_test.rb b/test/unit/indices/close_test.rb
new file mode 100644
index 0000000..432e511
--- /dev/null
+++ b/test/unit/indices/close_test.rb
@@ -0,0 +1,51 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesCloseTest < ::Test::Unit::TestCase
+
+      context "Indices: Close" do
+        subject { FakeClient.new }
+
+        should "require the :index argument" do
+          assert_raise ArgumentError do
+            subject.indices.close
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'POST', method
+            assert_equal 'foo/_close', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.close :index => 'foo'
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_close', url
+            assert_equal '1s', params[:timeout]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.close :index => 'foo', :timeout => '1s'
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_close', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.close :index => 'foo^bar'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/create_test.rb b/test/unit/indices/create_test.rb
new file mode 100644
index 0000000..4b2f99e
--- /dev/null
+++ b/test/unit/indices/create_test.rb
@@ -0,0 +1,51 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesCreateTest < ::Test::Unit::TestCase
+
+      context "Indices: Create" do
+        subject { FakeClient.new }
+
+        should "require the :index argument" do
+          assert_raise ArgumentError do
+            subject.indices.create
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'PUT', method
+            assert_equal 'foo', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.create :index => 'foo'
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo', url
+            assert_equal '1s', params[:timeout]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.create :index => 'foo', :timeout => '1s'
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.create :index => 'foo^bar'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/delete_alias_test.rb b/test/unit/indices/delete_alias_test.rb
new file mode 100644
index 0000000..c3489ad
--- /dev/null
+++ b/test/unit/indices/delete_alias_test.rb
@@ -0,0 +1,47 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesDeleteAliasTest < ::Test::Unit::TestCase
+
+      context "Indices: Delete alias" do
+        subject { FakeClient.new }
+
+        should "require the :index argument" do
+          assert_raise ArgumentError do
+            subject.indices.delete_alias :name => 'bar'
+          end
+        end
+
+        should "require the :name argument" do
+          assert_raise ArgumentError do
+            subject.indices.delete_alias :index => 'foo'
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'DELETE', method
+            assert_equal 'foo/_alias/bar', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.delete_alias :index => 'foo', :name => 'bar'
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_alias/bar%2Fbam', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.delete_alias :index => 'foo^bar', :name => 'bar/bam'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/delete_mapping_test.rb b/test/unit/indices/delete_mapping_test.rb
new file mode 100644
index 0000000..8ff680c
--- /dev/null
+++ b/test/unit/indices/delete_mapping_test.rb
@@ -0,0 +1,56 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesDeleteMappingTest < ::Test::Unit::TestCase
+
+      context "Indices: Delete mapping" do
+        subject { FakeClient.new }
+
+        should "require the :index argument" do
+          assert_raise ArgumentError do
+            subject.indices.delete_mapping :type => 'bar'
+          end
+        end
+
+        should "require the :type argument" do
+          assert_raise ArgumentError do
+            subject.indices.delete_mapping :index => 'foo'
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'DELETE', method
+            assert_equal 'foo/bar', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.delete_mapping :index => 'foo', :type => 'bar'
+        end
+
+        should "perform request against multiple indices" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/baz', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.delete_mapping :index => ['foo','bar'], :type => 'baz'
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/bar%2Fbam', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.delete_mapping :index => 'foo^bar', :type => 'bar/bam'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/delete_template_test.rb b/test/unit/indices/delete_template_test.rb
new file mode 100644
index 0000000..4b98c26
--- /dev/null
+++ b/test/unit/indices/delete_template_test.rb
@@ -0,0 +1,43 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesDeleteTemplateTest < ::Test::Unit::TestCase
+
+      context "Indices: Delete template" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'DELETE', method
+            assert_equal '_template/foo', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.delete_template :name => 'foo'
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_template/foo%5Ebar', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.delete_template :name => 'foo^bar'
+        end
+
+        should "ignore 404s" do
+          subject.expects(:perform_request).raises(NotFound)
+
+          assert_nothing_raised do
+            assert ! subject.indices.delete_template(:name => 'foo^bar', :ignore => 404)
+          end
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/delete_test.rb b/test/unit/indices/delete_test.rb
new file mode 100644
index 0000000..53cc0d1
--- /dev/null
+++ b/test/unit/indices/delete_test.rb
@@ -0,0 +1,54 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesDeleteTest < ::Test::Unit::TestCase
+
+      context "Indices: Delete" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'DELETE', method
+            assert_equal 'foo', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.delete :index => 'foo'
+        end
+
+        should "perform the request for more indices" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.delete :index => ['foo','bar']
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo', url
+            assert_equal '1s', params[:timeout]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.delete :index => 'foo', :timeout => '1s'
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.delete :index => 'foo^bar'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/delete_warmer_test.rb b/test/unit/indices/delete_warmer_test.rb
new file mode 100644
index 0000000..002761c
--- /dev/null
+++ b/test/unit/indices/delete_warmer_test.rb
@@ -0,0 +1,68 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesDeleteWarmerTest < ::Test::Unit::TestCase
+
+      context "Indices: Delete warmer" do
+        subject { FakeClient.new }
+
+        should "require the :index argument" do
+          assert_raise ArgumentError do
+            subject.indices.delete_warmer
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'DELETE', method
+            assert_equal 'foo/_warmer', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.delete_warmer :index => 'foo'
+        end
+
+        should "perform request against multiple indices" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/_warmer', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.delete_warmer :index => ['foo','bar']
+        end
+
+        should "perform request against single warmer" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_warmer/bar', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.delete_warmer :index => 'foo', :name => 'bar'
+        end
+
+        should "perform request against multiple warmers" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_warmer/bar,baz', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.delete_warmer :index => 'foo', :name => ['bar', 'baz']
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_warmer/bar%2Fbam', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.delete_warmer :index => 'foo^bar', :name => 'bar/bam'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/exists_alias_test.rb b/test/unit/indices/exists_alias_test.rb
new file mode 100644
index 0000000..fcc809f
--- /dev/null
+++ b/test/unit/indices/exists_alias_test.rb
@@ -0,0 +1,68 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesExistsAliasTest < ::Test::Unit::TestCase
+
+      context "Indices: Exists alias" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'HEAD', method
+            assert_equal '_alias/foo', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.exists_alias :name => 'foo'
+        end
+
+        should "perform request against multiple indices" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/_alias/bam', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.exists_alias :index => ['foo','bar'], :name => 'bam'
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_alias/bar%2Fbam', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.exists_alias :index => 'foo^bar', :name => 'bar/bam'
+        end
+
+        should "return true for successful response" do
+          subject.expects(:perform_request).returns(FakeResponse.new 200, 'OK')
+          assert_equal true, subject.indices.exists_alias(:name => 'foo')
+        end
+
+        should "return false for 404 response" do
+          subject.expects(:perform_request).returns(FakeResponse.new 404, 'Not Found')
+          assert_equal false, subject.indices.exists_alias(:name => 'none')
+        end
+
+        should "return false on 'not found' exceptions" do
+          subject.expects(:perform_request).raises(StandardError.new '404 NotFound')
+          assert_nothing_raised do
+            assert_equal false, subject.indices.exists_alias(:name => 'none')
+          end
+        end
+
+        should "re-raise generic exceptions" do
+          subject.expects(:perform_request).raises(StandardError)
+          assert_raise(StandardError) do
+            assert_equal false, subject.indices.exists_alias(:name => 'none')
+          end
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/exists_template_test.rb b/test/unit/indices/exists_template_test.rb
new file mode 100644
index 0000000..60aefcc
--- /dev/null
+++ b/test/unit/indices/exists_template_test.rb
@@ -0,0 +1,59 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesExistsTemplateTest < ::Test::Unit::TestCase
+
+      context "Indices: Exists template" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'HEAD', method
+            assert_equal '_template/foo', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.exists_template :name => 'foo'
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_template/bar%2Fbam', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.exists_template :name => 'bar/bam'
+        end
+
+        should "return true for successful response" do
+          subject.expects(:perform_request).returns(FakeResponse.new 200, 'OK')
+          assert_equal true, subject.indices.exists_template(:name => 'bar')
+        end
+
+        should "return false for 404 response" do
+          subject.expects(:perform_request).returns(FakeResponse.new 404, 'Not Found')
+          assert_equal false, subject.indices.exists_template(:name => 'none')
+        end
+
+        should "return false on 'not found' exceptions" do
+          subject.expects(:perform_request).raises(StandardError.new '404 NotFound')
+          assert_nothing_raised do
+            assert_equal false, subject.indices.exists_template(:name => 'none')
+          end
+        end
+
+        should "re-raise generic exceptions" do
+          subject.expects(:perform_request).raises(StandardError)
+          assert_raise(StandardError) do
+            assert_equal false, subject.indices.exists_template(:name => 'none')
+          end
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/exists_test.rb b/test/unit/indices/exists_test.rb
new file mode 100644
index 0000000..356d40f
--- /dev/null
+++ b/test/unit/indices/exists_test.rb
@@ -0,0 +1,66 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesExistsTest < ::Test::Unit::TestCase
+
+      context "Indices: Exists" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'HEAD', method
+            assert_equal 'foo', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.exists(:index => 'foo')
+        end
+
+        should "perform the request against multiple indices" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.exists(:index => ['foo', 'bar'])
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar,bar%2Fbam', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.exists :index => 'foo^bar,bar/bam'
+        end
+
+        should "return true for successful response" do
+          subject.expects(:perform_request).returns(FakeResponse.new 200, 'OK')
+          assert_equal true, subject.indices.exists(:index => 'foo')
+        end
+
+        should "return false for 404 response" do
+          subject.expects(:perform_request).returns(FakeResponse.new 404, 'Not Found')
+          assert_equal false, subject.indices.exists(:index => 'none')
+        end
+
+        should "return false on 'not found' exceptions" do
+          subject.expects(:perform_request).raises(StandardError.new '404 NotFound')
+          assert_equal false, subject.indices.exists(:index => 'none')
+        end
+
+        should "re-raise generic exceptions" do
+          subject.expects(:perform_request).raises(StandardError)
+          assert_raise(StandardError) do
+            assert_equal false, subject.indices.exists(:index => 'none')
+          end
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/exists_type_test.rb b/test/unit/indices/exists_type_test.rb
new file mode 100644
index 0000000..9ad2407
--- /dev/null
+++ b/test/unit/indices/exists_type_test.rb
@@ -0,0 +1,68 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesExistsTypeTest < ::Test::Unit::TestCase
+
+      context "Indices: Exists type" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'HEAD', method
+            assert_equal 'foo/bar', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.exists_type :index => 'foo', :type => 'bar'
+        end
+
+        should "perform request against multiple indices" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/bam', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.exists_type :index => ['foo','bar'], :type => 'bam'
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/bar%2Fbam', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.exists_type :index => 'foo^bar', :type => 'bar/bam'
+        end
+
+        should "return true for successful response" do
+          subject.expects(:perform_request).returns(FakeResponse.new 200, 'OK')
+          assert_equal true, subject.indices.exists_type(:index => 'foo', :type => 'bar')
+        end
+
+        should "return false for 404 response" do
+          subject.expects(:perform_request).returns(FakeResponse.new 404, 'Not Found')
+          assert_equal false, subject.indices.exists_type(:index => 'foo', :type => 'none')
+        end
+
+        should "return false on 'not found' exceptions" do
+          subject.expects(:perform_request).raises(StandardError.new '404 NotFound')
+          assert_nothing_raised do
+            assert_equal false, subject.indices.exists_type(:index => 'foo', :type => 'none')
+          end
+        end
+
+        should "re-raise generic exceptions" do
+          subject.expects(:perform_request).raises(StandardError)
+          assert_raise(StandardError) do
+            assert_equal false, subject.indices.exists_type(:index => 'foo', :type => 'none')
+          end
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/flush_test.rb b/test/unit/indices/flush_test.rb
new file mode 100644
index 0000000..f15b520
--- /dev/null
+++ b/test/unit/indices/flush_test.rb
@@ -0,0 +1,54 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesFlushTest < ::Test::Unit::TestCase
+
+      context "Indices: Flush" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'POST', method
+            assert_equal '_flush', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.flush
+        end
+
+        should "perform request against multiple indices" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/_flush', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.flush :index => ['foo','bar']
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_flush', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.flush :index => 'foo^bar'
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_flush', url
+            assert_equal true, params[:refresh]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.flush :index => 'foo', :refresh => true
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/get_alias_test.rb b/test/unit/indices/get_alias_test.rb
new file mode 100644
index 0000000..56adde4
--- /dev/null
+++ b/test/unit/indices/get_alias_test.rb
@@ -0,0 +1,44 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesGetAliasTest < ::Test::Unit::TestCase
+
+      context "Indices: Get alias" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_alias/foo', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_alias :name => 'foo'
+        end
+
+        should "perform request against multiple indices" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/_alias/bam', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_alias :index => ['foo','bar'], :name => 'bam'
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_alias/bar%2Fbam', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_alias :index => 'foo^bar', :name => 'bar/bam'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/get_aliases_test.rb b/test/unit/indices/get_aliases_test.rb
new file mode 100644
index 0000000..d4ae11e
--- /dev/null
+++ b/test/unit/indices/get_aliases_test.rb
@@ -0,0 +1,54 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesGetAliasesTest < ::Test::Unit::TestCase
+
+      context "Indices: Get aliases" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_aliases', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_aliases
+        end
+
+        should "perform request against an index" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_aliases', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_aliases :index => 'foo'
+        end
+
+        should "get a specific alias" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_aliases/bar', url
+            assert_equal Hash.new, params
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_aliases :index => 'foo', :name => 'bar'
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_aliases', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_aliases :index => 'foo^bar'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/get_field_mapping_test.rb b/test/unit/indices/get_field_mapping_test.rb
new file mode 100644
index 0000000..c481ad7
--- /dev/null
+++ b/test/unit/indices/get_field_mapping_test.rb
@@ -0,0 +1,44 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesGetFieldMappingTest < ::Test::Unit::TestCase
+
+      context "Indices: Get field mapping" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_mapping/field/foo', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_field_mapping :field => 'foo'
+        end
+
+        should "perform request against an index" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_mapping/field/bam', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_field_mapping :index => 'foo', :field => 'bam'
+        end
+
+        should "perform request against an index and type" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_mapping/bar/field/bam', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_field_mapping :index => 'foo', :type => 'bar', :field => 'bam'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/get_mapping_test.rb b/test/unit/indices/get_mapping_test.rb
new file mode 100644
index 0000000..d4bc8ae
--- /dev/null
+++ b/test/unit/indices/get_mapping_test.rb
@@ -0,0 +1,62 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesGetMappingTest < ::Test::Unit::TestCase
+
+      context "Indices: Get mapping" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_mapping', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_mapping
+        end
+
+        should "perform request against an index" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_mapping', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_mapping :index => 'foo'
+        end
+
+        should "perform request against an index and type" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_mapping/bar', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_mapping :index => 'foo', :type => 'bar'
+        end
+
+        should "perform request against multiple indices and types" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/_mapping/bam,baz', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_mapping :index => ['foo', 'bar'], :type => ['bam', 'baz']
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_mapping/bar%2Fbam', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_mapping :index => 'foo^bar', :type => 'bar/bam'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/get_settings_test.rb b/test/unit/indices/get_settings_test.rb
new file mode 100644
index 0000000..9854740
--- /dev/null
+++ b/test/unit/indices/get_settings_test.rb
@@ -0,0 +1,54 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesGetSettingsTest < ::Test::Unit::TestCase
+
+      context "Indices: Get settings" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_settings', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_settings
+        end
+
+        should "perform request against an index" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_settings', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_settings :index => 'foo'
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_settings', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_settings :index => 'foo^bar'
+        end
+
+        should "get specific settings" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_settings/foo.bar', url
+            assert_equal Hash.new, params
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_settings :index => 'foo', :name => 'foo.bar'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/get_template_test.rb b/test/unit/indices/get_template_test.rb
new file mode 100644
index 0000000..7f30abd
--- /dev/null
+++ b/test/unit/indices/get_template_test.rb
@@ -0,0 +1,36 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesGetTemplateTest < ::Test::Unit::TestCase
+
+      context "Indices: Get template" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_template/foo', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_template :name => 'foo'
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_template/foo%5Ebar', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_template :name => 'foo^bar'
+        end
+
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/get_warmer_test.rb b/test/unit/indices/get_warmer_test.rb
new file mode 100644
index 0000000..e4d6063
--- /dev/null
+++ b/test/unit/indices/get_warmer_test.rb
@@ -0,0 +1,44 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesGetWarmerTest < ::Test::Unit::TestCase
+
+      context "Indices: Get warmer" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_all/_warmer', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_warmer :index => '_all'
+        end
+
+        should "return single warmer" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_warmer/bar', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_warmer :index => 'foo', :name => 'bar'
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_warmer/bar%2Fbam', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.get_warmer :index => 'foo^bar', :name => 'bar/bam'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/open_test.rb b/test/unit/indices/open_test.rb
new file mode 100644
index 0000000..534b7ba
--- /dev/null
+++ b/test/unit/indices/open_test.rb
@@ -0,0 +1,51 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesOpenTest < ::Test::Unit::TestCase
+
+      context "Indices: Open" do
+        subject { FakeClient.new }
+
+        should "require the :index argument" do
+          assert_raise ArgumentError do
+            subject.indices.open
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'POST', method
+            assert_equal 'foo/_open', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.open :index => 'foo'
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_open', url
+            assert_equal '1s', params[:timeout]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.open :index => 'foo', :timeout => '1s'
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_open', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.open :index => 'foo^bar'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/optimize_test.rb b/test/unit/indices/optimize_test.rb
new file mode 100644
index 0000000..a89c50e
--- /dev/null
+++ b/test/unit/indices/optimize_test.rb
@@ -0,0 +1,54 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesOptimizeTest < ::Test::Unit::TestCase
+
+      context "Indices: Optimize" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'POST', method
+            assert_equal '_optimize', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.optimize
+        end
+
+        should "perform request against multiple indices" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/_optimize', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.optimize :index => ['foo','bar']
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_optimize', url
+            assert_equal 1, params[:max_num_segments]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.optimize :index => 'foo', :max_num_segments => 1
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_optimize', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.optimize :index => 'foo^bar'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/put_alias_test.rb b/test/unit/indices/put_alias_test.rb
new file mode 100644
index 0000000..36be958
--- /dev/null
+++ b/test/unit/indices/put_alias_test.rb
@@ -0,0 +1,50 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesPutAliasTest < ::Test::Unit::TestCase
+
+      context "Indices: Put alias" do
+        subject { FakeClient.new }
+
+        should "require the :name argument" do
+          assert_raise ArgumentError do
+            subject.indices.put_alias :index => 'foo'
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'PUT', method
+            assert_equal 'foo/_alias/bar', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.put_alias :index => 'foo', :name => 'bar'
+        end
+
+        should "send the alias settings in :body" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo', body[:filter]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.put_alias :index => 'foo', :name => 'bar', :body => { :filter => 'foo' }
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_alias/bar%2Fbam', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.put_alias :index => 'foo^bar', :name => 'bar/bam', :body => {}
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/put_mapping_test.rb b/test/unit/indices/put_mapping_test.rb
new file mode 100644
index 0000000..40fafb0
--- /dev/null
+++ b/test/unit/indices/put_mapping_test.rb
@@ -0,0 +1,60 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesPutMappingTest < ::Test::Unit::TestCase
+
+      context "Indices: Put mapping" do
+        subject { FakeClient.new }
+
+        should "require the :type argument" do
+          assert_raise ArgumentError do
+            subject.indices.put_mapping :index => 'foo', :body => {}
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'PUT', method
+            assert_equal 'foo/_mapping/bar', url
+            assert_equal Hash.new, params
+            assert_equal({ :foo => {} }, body)
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.put_mapping :index => 'foo', :type => 'bar', :body => { :foo => {} }
+        end
+
+        should "perform request against multiple indices" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/_mapping/bam', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.put_mapping :index => ['foo','bar'], :type => 'bam', :body => {}
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_mapping/bar', url
+            assert_equal true, params[:ignore_conflicts]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.put_mapping :index => 'foo', :type => 'bar', :body => {}, :ignore_conflicts => true
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_mapping/bar%2Fbam', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.put_mapping :index => 'foo^bar', :type => 'bar/bam', :body => {}
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/put_settings_test.rb b/test/unit/indices/put_settings_test.rb
new file mode 100644
index 0000000..774eab9
--- /dev/null
+++ b/test/unit/indices/put_settings_test.rb
@@ -0,0 +1,68 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesPutSettingsTest < ::Test::Unit::TestCase
+
+      context "Indices: Put settings" do
+        subject { FakeClient.new }
+
+        should "require the :body argument" do
+          assert_raise ArgumentError do
+            subject.indices.put_settings
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'PUT', method
+            assert_equal '_settings', url
+            assert_equal Hash.new, params
+            assert_equal Hash.new, body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.put_settings :body => {}
+        end
+
+        should "perform request with parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal true, params[:flat_settings]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.put_settings :index => 'foo', :flat_settings => true, :body => {}
+        end
+
+        should "perform request against a specific indices" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_settings', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.put_settings :index => 'foo', :body => {}
+        end
+
+        should "perform request against multiple indices" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/_settings', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.put_settings :index => ['foo','bar'], :body => {}
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_settings', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.put_settings :index => 'foo^bar', :body => {}
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/put_template_test.rb b/test/unit/indices/put_template_test.rb
new file mode 100644
index 0000000..7d97878
--- /dev/null
+++ b/test/unit/indices/put_template_test.rb
@@ -0,0 +1,57 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesPutTemplateTest < ::Test::Unit::TestCase
+
+      context "Indices: Put template" do
+        subject { FakeClient.new }
+
+        should "require the :name argument" do
+          assert_raise ArgumentError do
+            subject.indices.put_template :body => {}
+          end
+        end
+
+        should "require the :body argument" do
+          assert_raise ArgumentError do
+            subject.indices.put_template :name => 'foo'
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'PUT', method
+            assert_equal '_template/foo', url
+            assert_equal Hash.new, params
+            assert_equal 'bar', body[:template]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.put_template :name => 'foo', :body => { :template => 'bar' }
+        end
+
+         should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_template/foo', url
+            assert_equal 3, params[:order]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.put_template :name => 'foo', :body => {}, :order => 3
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_template/foo%5Ebar', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.put_template :name => 'foo^bar', :body => {}
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/put_warmer_test.rb b/test/unit/indices/put_warmer_test.rb
new file mode 100644
index 0000000..a24764a
--- /dev/null
+++ b/test/unit/indices/put_warmer_test.rb
@@ -0,0 +1,65 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesPutWarmerTest < ::Test::Unit::TestCase
+
+      context "Indices: Put warmer" do
+        subject { FakeClient.new }
+
+        should "require the :name argument" do
+          assert_raise ArgumentError do
+            subject.indices.put_warmer :index => 'foo', :body => {}
+          end
+        end
+
+        should "require the :body argument" do
+          assert_raise ArgumentError do
+            subject.indices.put_warmer :index => 'foo', :name => 'bar'
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'PUT', method
+            assert_equal 'foo/_warmer/bar', url
+            assert_equal Hash.new, params
+            assert_equal :match_all, body[:query].keys.first
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.put_warmer :index => 'foo', :name => 'bar', :body => { :query => { :match_all => {} } }
+        end
+
+        should "perform request against multiple indices" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/_warmer/xul', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.put_warmer :index => ['foo','bar'], :name => 'xul', :body => {}
+        end
+
+        should "perform request against an index and type" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/bar/_warmer/xul', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.put_warmer :index => 'foo', :type => 'bar', :name => 'xul', :body => {}
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/bar%2Fbam/_warmer/qu+uz', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.put_warmer :index => 'foo^bar', :type => 'bar/bam', :name => 'qu uz', :body => {}
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/recovery_test.rb b/test/unit/indices/recovery_test.rb
new file mode 100644
index 0000000..50b4b35
--- /dev/null
+++ b/test/unit/indices/recovery_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesRecoveryTest < ::Test::Unit::TestCase
+
+      context "Indices: Recovery" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal 'foo/_recovery', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.recovery :index => 'foo'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/refresh_test.rb b/test/unit/indices/refresh_test.rb
new file mode 100644
index 0000000..76d4164
--- /dev/null
+++ b/test/unit/indices/refresh_test.rb
@@ -0,0 +1,64 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesRefreshTest < ::Test::Unit::TestCase
+
+      context "Indices: Refresh" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'POST', method
+            assert_equal '_refresh', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.refresh
+        end
+
+        should "perform request against an index" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_refresh', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.refresh :index => 'foo'
+        end
+
+        should "perform request against multiple indices" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/_refresh', url
+            true
+          end.returns(FakeResponse.new).twice
+
+          subject.indices.refresh :index => ['foo','bar']
+          subject.indices.refresh :index => 'foo,bar'
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/_refresh', url
+            assert_equal 'missing', params[:ignore_indices]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.refresh :index => ['foo','bar'], :ignore_indices => 'missing'
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_refresh', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.refresh :index => 'foo^bar'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/segments_test.rb b/test/unit/indices/segments_test.rb
new file mode 100644
index 0000000..e9779b6
--- /dev/null
+++ b/test/unit/indices/segments_test.rb
@@ -0,0 +1,64 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesSegmentsTest < ::Test::Unit::TestCase
+
+      context "Indices: Segments" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_segments', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.segments
+        end
+
+        should "perform request against an index" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_segments', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.segments :index => 'foo'
+        end
+
+        should "perform request against multiple indices" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/_segments', url
+            true
+          end.returns(FakeResponse.new).twice
+
+          subject.indices.segments :index => ['foo','bar']
+          subject.indices.segments :index => 'foo,bar'
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/_segments', url
+            assert_equal 'missing', params[:ignore_indices]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.segments :index => ['foo','bar'], :ignore_indices => 'missing'
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_segments', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.segments :index => 'foo^bar'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/snapshot_index_test.rb b/test/unit/indices/snapshot_index_test.rb
new file mode 100644
index 0000000..a30ca15
--- /dev/null
+++ b/test/unit/indices/snapshot_index_test.rb
@@ -0,0 +1,64 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesSnapshotIndexTest < ::Test::Unit::TestCase
+
+      context "Indices: Snapshot index" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'POST', method
+            assert_equal '_gateway/snapshot', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.snapshot_index
+        end
+
+        should "perform request against an index" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_gateway/snapshot', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.snapshot_index :index => 'foo'
+        end
+
+        should "perform request against multiple indices" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/_gateway/snapshot', url
+            true
+          end.returns(FakeResponse.new).twice
+
+          subject.indices.snapshot_index :index => ['foo','bar']
+          subject.indices.snapshot_index :index => 'foo,bar'
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/_gateway/snapshot', url
+            assert_equal 'missing', params[:ignore_indices]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.snapshot_index :index => ['foo','bar'], :ignore_indices => 'missing'
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_gateway/snapshot', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.snapshot_index :index => 'foo^bar'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/stats_test.rb b/test/unit/indices/stats_test.rb
new file mode 100644
index 0000000..cd5f9bc
--- /dev/null
+++ b/test/unit/indices/stats_test.rb
@@ -0,0 +1,76 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesStatsTest < ::Test::Unit::TestCase
+
+      context "Indices: Stats" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_stats', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.stats
+        end
+
+        should "perform request against an index" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_stats', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.stats :index => 'foo'
+        end
+
+        should "perform request against multiple indices" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/_stats', url
+            true
+          end.returns(FakeResponse.new).twice
+
+          subject.indices.stats :index => ['foo','bar']
+          subject.indices.stats :index => 'foo,bar'
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_stats', url
+            assert_equal true, params[:expand_wildcards]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.stats :index => 'foo', :expand_wildcards => true
+        end
+
+        should "pass the fields parameter as a list" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_stats/fielddata', url
+            assert_nil   params[:fielddata]
+            assert_equal 'foo,bar', params[:fields]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.stats :index => 'foo', :fielddata => true, :fields => ['foo', 'bar']
+        end
+
+        should "pass the groups parameter as a list" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_stats/search', url
+            assert_equal 'groupA,groupB', params[:groups]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.stats :search => true, :groups => ['groupA','groupB']
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/status_test.rb b/test/unit/indices/status_test.rb
new file mode 100644
index 0000000..7295492
--- /dev/null
+++ b/test/unit/indices/status_test.rb
@@ -0,0 +1,64 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesStatusTest < ::Test::Unit::TestCase
+
+      context "Indices: Status" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_status', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.status
+        end
+
+        should "perform request against an index" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_status', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.status :index => 'foo'
+        end
+
+        should "perform request against multiple indices" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/_status', url
+            true
+          end.returns(FakeResponse.new).twice
+
+          subject.indices.status :index => ['foo','bar']
+          subject.indices.status :index => 'foo,bar'
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_status', url
+            assert_equal true, params[:recovery]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.status :index => 'foo', :recovery => true
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_status', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.status :index => 'foo^bar'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/update_aliases_test.rb b/test/unit/indices/update_aliases_test.rb
new file mode 100644
index 0000000..c7831ee
--- /dev/null
+++ b/test/unit/indices/update_aliases_test.rb
@@ -0,0 +1,42 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesPutAliasesTest < ::Test::Unit::TestCase
+
+      context "Indices: Update aliases" do
+        subject { FakeClient.new }
+
+        should "require the :body argument" do
+          assert_raise ArgumentError do
+            subject.indices.update_aliases
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'POST', method
+            assert_equal '_aliases', url
+            assert_equal Hash.new, params
+            assert_equal [], body[:actions]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.update_aliases :body => { :actions => [] }
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_aliases', url
+            assert_equal '1s', params[:timeout]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.update_aliases :body => {}, :timeout => '1s'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/indices/validate_query_test.rb b/test/unit/indices/validate_query_test.rb
new file mode 100644
index 0000000..bdb13cb
--- /dev/null
+++ b/test/unit/indices/validate_query_test.rb
@@ -0,0 +1,84 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class IndicesValidateQueryTest < ::Test::Unit::TestCase
+
+      context "Indices: Validate query" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_validate/query', url
+            assert_equal Hash.new, params
+            assert_nil body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.validate_query
+        end
+
+        should "perform request against an index" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_validate/query', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.validate_query :index => 'foo'
+        end
+
+        should "perform request against an index and type" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/bar/_validate/query', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.validate_query :index => 'foo', :type => 'bar'
+        end
+
+        should "perform request against multiple indices" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/_validate/query', url
+            true
+          end.returns(FakeResponse.new).twice
+
+          subject.indices.validate_query :index => ['foo', 'bar']
+          subject.indices.validate_query :index => 'foo,bar'
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_validate/query', url
+            assert_equal true, params[:explain]
+            assert_equal 'foo', params[:q]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.validate_query :explain => true, :q => 'foo'
+        end
+
+        should "pass the query definition in body" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_validate/query', url
+            assert_equal Hash.new, body[:filtered]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.validate_query :body => { :filtered => {} }
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_validate/query', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.indices.validate_query :index => 'foo^bar', :body => {}
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/info_test.rb b/test/unit/info_test.rb
new file mode 100644
index 0000000..650458a
--- /dev/null
+++ b/test/unit/info_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class InfoTest < ::Test::Unit::TestCase
+
+      context "Info" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.info
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/json_builders_test.rb b/test/unit/json_builders_test.rb
new file mode 100644
index 0000000..9f61b22
--- /dev/null
+++ b/test/unit/json_builders_test.rb
@@ -0,0 +1,64 @@
+require 'test_helper'
+
+require 'jbuilder' if defined?(RUBY_VERSION) && RUBY_VERSION > '1.9'
+require 'jsonify'
+
+module Elasticsearch
+  module Test
+    class JsonBuildersTest < ::Test::Unit::TestCase
+
+      context "JBuilder" do
+        subject { FakeClient.new }
+
+        should "build a JSON" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            json = MultiJson.load(body)
+
+            assert_instance_of String, body
+            assert_equal       'test', json['query']['match']['title']['query']
+            true
+          end.returns(FakeResponse.new)
+
+          json = Jbuilder.encode do |json|
+                   json.query do
+                     json.match do
+                       json.title do
+                         json.query    'test'
+                       end
+                     end
+                   end
+                 end
+
+          subject.search :body => json
+        end
+      end if defined?(RUBY_VERSION) && RUBY_VERSION > '1.9'
+
+      context "Jsonify" do
+        subject { FakeClient.new }
+
+        should "build a JSON" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            json = MultiJson.load(body)
+
+            assert_instance_of String, body
+            assert_equal       'test', json['query']['match']['title']['query']
+            true
+          end.returns(FakeResponse.new)
+
+          json = Jsonify::Builder.compile do |json|
+                   json.query do
+                     json.match do
+                       json.title do
+                         json.query    'test'
+                       end
+                     end
+                   end
+                 end
+
+          subject.search :body => json
+        end
+      end
+
+    end
+  end
+end
diff --git a/test/unit/list_benchmarks_test.rb b/test/unit/list_benchmarks_test.rb
new file mode 100644
index 0000000..222ba44
--- /dev/null
+++ b/test/unit/list_benchmarks_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class ListBenchmarksTest < ::Test::Unit::TestCase
+
+      context "List benchmarks" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_bench', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.list_benchmarks
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/mget_test.rb b/test/unit/mget_test.rb
new file mode 100644
index 0000000..333536c
--- /dev/null
+++ b/test/unit/mget_test.rb
@@ -0,0 +1,79 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class MgetTest < ::Test::Unit::TestCase
+
+      context "Mget" do
+        subject { FakeClient.new }
+
+        should "require the :body argument" do
+          assert_raise ArgumentError do
+            subject.mget
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_mget', url
+            assert_equal Hash.new, params
+            assert_equal [], body[:docs]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.mget :body => { :docs => [] }
+        end
+
+        should "perform request against an index" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_mget', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.mget :index => 'foo', :body => {}
+        end
+
+        should "perform request against an index and type" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/bar/_mget', url
+            assert_equal ['1', '2'], body[:ids]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.mget :index => 'foo', :type => 'bar', :body => { :ids => ['1','2'] }
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_mget', url
+            assert_equal true, params[:refresh]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.mget :body => {}, :refresh => true
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/bar%2Fbam/_mget', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.mget :index => 'foo^bar', :type => 'bar/bam', :body => { :ids => ['1','2'] }
+        end
+
+        should "pass the fields parameter as a list" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar', params[:fields]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.mget :body => {}, :fields => ['foo', 'bar']
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/mlt_test.rb b/test/unit/mlt_test.rb
new file mode 100644
index 0000000..16cf486
--- /dev/null
+++ b/test/unit/mlt_test.rb
@@ -0,0 +1,89 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class MltTest < ::Test::Unit::TestCase
+
+      context "More Like This" do
+        subject { FakeClient.new }
+
+        should "require the :index argument" do
+          assert_raise ArgumentError do
+            subject.mlt :type => 'bar', :id => '1'
+          end
+        end
+
+        should "require the :type argument" do
+          assert_raise ArgumentError do
+            subject.mlt :index => 'foo', :id => '1'
+          end
+        end
+
+        should "require the :id argument" do
+          assert_raise ArgumentError do
+            subject.mlt :index => 'foo', :type => 'bar'
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal 'foo/bar/1/_mlt', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.mlt :index => 'foo', :type => 'bar', :id => '1'
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/bar/1/_mlt', url
+            assert_equal 1, params[:max_doc_freq]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.mlt :index => 'foo', :type => 'bar', :id => '1', :max_doc_freq => 1
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/bar%2Fbam/1/_mlt', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.mlt :index => 'foo^bar', :type => 'bar/bam', :id => '1'
+        end
+
+        should "pass the specific parameters as a list" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar', params[:mlt_fields]
+            assert_equal 'A,B',     params[:search_indices]
+            assert_equal 'X,Y',     params[:search_types]
+            assert_equal 'lam,bam', params[:stop_words]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.mlt :index => 'foo', :type => 'bar', :id => '1',
+                      :mlt_fields     => ['foo', 'bar'],
+                      :search_indices => ['A', 'B'],
+                      :search_types   => ['X', 'Y'],
+                      :stop_words     => ['lam','bam']
+        end
+
+        should "pass a specific search definition in body" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/bar/1/_mlt', url
+            assert_equal Hash.new, body[:query]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.mlt :index => 'foo', :type => 'bar', :id => '1', :body => { :query => {} }
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/mpercolate_test.rb b/test/unit/mpercolate_test.rb
new file mode 100644
index 0000000..6176297
--- /dev/null
+++ b/test/unit/mpercolate_test.rb
@@ -0,0 +1,51 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class MpercolateTest < ::Test::Unit::TestCase
+
+      context "Mpercolate" do
+        subject { FakeClient.new }
+
+        should "require the :body argument" do
+          assert_raise ArgumentError do
+            subject.mpercolate
+          end
+        end
+
+        should "post correct payload to the endpoint" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_mpercolate', url
+            assert_equal Hash.new, params
+
+            lines = body.split("\n")
+            assert_match /\{"percolate"/, lines[0]
+            assert_match /\{"doc"/,       lines[1]
+            assert_match /\{"percolate"/, lines[2]
+            assert_match /\{\}/,          lines[3]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.mpercolate :body => [
+            { :percolate => { :index => "my-index", :type => "my-type" } },
+            { :doc => { :message => "foo bar" } },
+            { :percolate => { :index => "my-other-index", :type => "my-other-type", :id => "1" } },
+            { }
+          ]
+        end
+
+        should "post a string payload intact" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal %Q|{"foo":"bar"}\n{"moo":"lam"}|, body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.mpercolate :body => %Q|{"foo":"bar"}\n{"moo":"lam"}|
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/msearch_test.rb b/test/unit/msearch_test.rb
new file mode 100644
index 0000000..1bce870
--- /dev/null
+++ b/test/unit/msearch_test.rb
@@ -0,0 +1,129 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class MsearchTest < ::Test::Unit::TestCase
+
+      context "Msearch" do
+        subject { FakeClient.new }
+
+        should "require the :body argument" do
+          assert_raise ArgumentError do
+            subject.msearch
+          end
+        end
+
+        should "post correct payload to the endpoint" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_msearch', url
+            assert_equal Hash.new, params
+            assert_equal <<-PAYLOAD.gsub(/^\s+/, ''), body
+            {"index":"foo"}
+            {"query":{"match_all":{}}}
+            {"index":"bar"}
+            {"query":{"match":{"foo":"bar"}}}
+            {"search_type":"count"}
+            {"facets":{"tags":{}}}
+            PAYLOAD
+            true
+          end.returns(FakeResponse.new)
+
+          subject.msearch :body => [
+            { :index => 'foo', :search => { :query => { :match_all => {}  } } },
+            { :index => 'bar', :search => { :query => { :match => { :foo => 'bar' } } } },
+            { :search_type => 'count', :search => { :facets => { :tags => {} } } }
+          ]
+        end
+
+        should "post a string payload intact" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal %Q|{"foo":"bar"}\n{"moo":"lam"}|, body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.msearch :body => %Q|{"foo":"bar"}\n{"moo":"lam"}|
+        end
+
+        should "serialize and post header/data pairs" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_msearch', url
+            assert_equal Hash.new, params
+            assert_equal <<-PAYLOAD.gsub(/^\s+/, ''), body
+            {"index":"foo"}
+            {"query":{"match_all":{}}}
+            {"index":"bar"}
+            {"query":{"match":{"foo":"bar"}}}
+            PAYLOAD
+            true
+          end.returns(FakeResponse.new)
+
+          subject.msearch :body => [
+            { :index => 'foo' },
+            { :query => { :match_all => {}  } },
+            { :index => 'bar' },
+            { :query => { :match => { :foo => 'bar' } } }
+          ]
+        end
+
+        should "perform request against an index" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_msearch', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.msearch :index => 'foo', :body => []
+        end
+
+        should "perform request against an index and type" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/bar/_msearch', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.msearch :index => 'foo', :type => 'bar', :body => []
+        end
+
+        should "perform request against multiple indices" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/_msearch', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.msearch :index => ['foo', 'bar'], :body => []
+        end
+
+        should "perform request against multiple indices and types" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/lam,bam/_msearch', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.msearch :index => ['foo', 'bar'], :type => ['lam', 'bam'], :body => []
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/bar%2Fbam/_msearch', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.msearch :index => 'foo^bar', :type => 'bar/bam', :body => []
+        end
+
+        should "encode URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_msearch', url
+            assert_equal 'scroll', params[:search_type]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.msearch :body => [], :search_type => 'scroll'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/mtermvectors_test.rb b/test/unit/mtermvectors_test.rb
new file mode 100644
index 0000000..a053187
--- /dev/null
+++ b/test/unit/mtermvectors_test.rb
@@ -0,0 +1,38 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class MtermvectorsTest < ::Test::Unit::TestCase
+
+      context "Mtermvectors" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal 'my-index/my-type/_mtermvectors', url
+            assert_equal Hash.new, params
+            assert_equal [1, 2, 3], body[:ids]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.mtermvectors :index => 'my-index', :type => 'my-type', :body => { :ids => [1, 2, 3] }
+        end
+
+        should "allow passing a list of IDs instead of the body" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal 'my-index/my-type/_mtermvectors', url
+            assert_equal Hash.new, params
+            assert_equal [1, 2, 3], body[:ids]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.mtermvectors :index => 'my-index', :type => 'my-type', :ids => [1, 2, 3]
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/nodes/hot_threads_test.rb b/test/unit/nodes/hot_threads_test.rb
new file mode 100644
index 0000000..dd93ef2
--- /dev/null
+++ b/test/unit/nodes/hot_threads_test.rb
@@ -0,0 +1,44 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class NodesHotThreadsTest < ::Test::Unit::TestCase
+
+      context "Nodes: Hot Threads" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_nodes/hot_threads', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.nodes.hot_threads
+        end
+
+        should "send :node_id correctly" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_nodes/foo/hot_threads', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.nodes.hot_threads :node_id => 'foo'
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_nodes/foo%5Ebar/hot_threads', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.nodes.hot_threads :node_id => 'foo^bar'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/nodes/info_test.rb b/test/unit/nodes/info_test.rb
new file mode 100644
index 0000000..a2c63d4
--- /dev/null
+++ b/test/unit/nodes/info_test.rb
@@ -0,0 +1,66 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class NodesInfoTest < ::Test::Unit::TestCase
+
+      context "Nodes: Info" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_nodes', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.nodes.info
+        end
+
+        should "send :node_id correctly" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_nodes/foo', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.nodes.info :node_id => 'foo'
+        end
+
+        should "send multiple :node_id-s correctly" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_nodes/A,B,C', url
+            true
+          end.returns(FakeResponse.new).twice
+
+          subject.nodes.info :node_id => 'A,B,C'
+          subject.nodes.info :node_id => ['A', 'B', 'C']
+        end
+
+        should "properly pass URL parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_same_elements ['http','jvm'], url.split('/').last.split(',')
+            assert_nil   params[:jvm]
+            assert_nil   params[:http]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.nodes.info :jvm => true, :http => true
+        end
+
+        should "properly pass URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_nodes', url
+            assert_equal 'yaml',   params[:format]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.nodes.info :format => 'yaml'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/nodes/shutdown_test.rb b/test/unit/nodes/shutdown_test.rb
new file mode 100644
index 0000000..5efee19
--- /dev/null
+++ b/test/unit/nodes/shutdown_test.rb
@@ -0,0 +1,45 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class NodesShutdownTest < ::Test::Unit::TestCase
+
+      context "Nodes: Shutdown" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'POST', method
+            assert_equal '_cluster/nodes/_shutdown', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.nodes.shutdown
+        end
+
+        should "send :node_id correctly" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_cluster/nodes/foo/_shutdown', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.nodes.shutdown :node_id => 'foo'
+        end
+
+        should "send multiple :node_id-s correctly" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_cluster/nodes/A,B,C/_shutdown', url
+            true
+          end.returns(FakeResponse.new).twice
+
+          subject.nodes.shutdown :node_id => 'A,B,C'
+          subject.nodes.shutdown :node_id => ['A', 'B', 'C']
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/nodes/stats_test.rb b/test/unit/nodes/stats_test.rb
new file mode 100644
index 0000000..17d445b
--- /dev/null
+++ b/test/unit/nodes/stats_test.rb
@@ -0,0 +1,65 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class NodesStatsTest < ::Test::Unit::TestCase
+
+      context "Nodes: Stats" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_nodes/stats', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.nodes.stats
+        end
+
+        should "send :node_id correctly" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_nodes/foo/stats', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.nodes.stats :node_id => 'foo'
+        end
+
+        should "get specific metric families" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_nodes/stats/http,fs', url
+            assert_equal( {}, params )
+            true
+          end.returns(FakeResponse.new)
+
+          subject.nodes.stats :metric => [:http, :fs]
+        end
+
+        should "get specific metric for the indices family" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_nodes/stats/indices/filter_cache', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.nodes.stats :metric => :indices, :index_metric => 'filter_cache'
+        end
+
+        should "get fielddata statistics for the indices family" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_nodes/stats/indices/fielddata', url
+            assert_equal( {:fields => 'foo,bar'}, params )
+            true
+          end.returns(FakeResponse.new).twice
+
+          subject.nodes.stats :metric => 'indices', :index_metric => 'fielddata', :fields => 'foo,bar'
+          subject.nodes.stats :metric => 'indices', :index_metric => 'fielddata', :fields => ['foo','bar']
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/percolate_test.rb b/test/unit/percolate_test.rb
new file mode 100644
index 0000000..dc68c68
--- /dev/null
+++ b/test/unit/percolate_test.rb
@@ -0,0 +1,47 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class PercolateTest < ::Test::Unit::TestCase
+
+      context "Percolate" do
+        subject { FakeClient.new }
+
+        should "require the :index argument" do
+          assert_raise ArgumentError do
+            subject.percolate :type => 'bar', :body => {}
+          end
+        end
+
+        should "require the :type argument" do
+          assert_raise ArgumentError do
+            subject.percolate :index => 'bar', :body => {}
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal 'foo/bar/_percolate', url
+            assert_equal Hash.new, params
+            assert_equal 'bar', body[:doc][:foo]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.percolate :index => 'foo', :type => 'bar', :body => { :doc => { :foo => 'bar' } }
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/bar%2Fbam/_percolate', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.percolate :index => 'foo^bar', :type => 'bar/bam', :body => { :doc => { :foo => 'bar' } }
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/ping_test.rb b/test/unit/ping_test.rb
new file mode 100644
index 0000000..8b8d60a
--- /dev/null
+++ b/test/unit/ping_test.rb
@@ -0,0 +1,48 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class PingTest < ::Test::Unit::TestCase
+
+      context "Indices: Exists" do
+        subject { FakeClient.new }
+
+         should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'HEAD', method
+            assert_equal '', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.ping
+        end
+
+        should "return true for successful response" do
+          subject.expects(:perform_request).returns(FakeResponse.new 200, 'OK')
+          assert_equal true, subject.ping
+        end
+
+        should "return false for 404 response" do
+          subject.expects(:perform_request).returns(FakeResponse.new 404, 'Not Found')
+          assert_equal false, subject.ping
+        end
+
+        should "return false on 'not found' exceptions" do
+          subject.expects(:perform_request).raises(StandardError.new '404 NotFound')
+          assert_equal false, subject.ping
+        end
+
+        should "re-raise generic exceptions" do
+          subject.expects(:perform_request).raises(StandardError)
+          assert_raise(StandardError) do
+            assert_equal false, subject.ping
+          end
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/scroll_test.rb b/test/unit/scroll_test.rb
new file mode 100644
index 0000000..17e4c0d
--- /dev/null
+++ b/test/unit/scroll_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class ScrollTest < ::Test::Unit::TestCase
+
+      context "Scroll" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_search/scroll', url
+            assert_equal 'cXVlcn...', params[:scroll_id]
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.scroll :scroll_id => 'cXVlcn...'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/search_shards_test.rb b/test/unit/search_shards_test.rb
new file mode 100644
index 0000000..c1b1cf8
--- /dev/null
+++ b/test/unit/search_shards_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class SearchShardsTest < ::Test::Unit::TestCase
+
+      context "Search shards" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_search_shards', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.search_shards
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/search_template_test.rb b/test/unit/search_template_test.rb
new file mode 100644
index 0000000..b9e46bc
--- /dev/null
+++ b/test/unit/search_template_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class SearchTemplateTest < ::Test::Unit::TestCase
+
+      context "Search template" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal 'foo/_search/template', url
+            assert_equal Hash.new, params
+            assert_equal 'bar', body[:foo]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.search_template :index => 'foo', :body => { :foo => 'bar' }
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/search_test.rb b/test/unit/search_test.rb
new file mode 100644
index 0000000..a65df64
--- /dev/null
+++ b/test/unit/search_test.rb
@@ -0,0 +1,108 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class SearchTest < ::Test::Unit::TestCase
+
+      context "Search" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_search', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.search
+        end
+
+        should "have default value for index" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_all/foo/_search', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.search :type => 'foo'
+        end
+
+        should "post a request definition in body" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal :match, body[:query].keys.first
+            true
+          end.returns(FakeResponse.new)
+
+          subject.search :body => { :query => { :match => {} } }
+        end
+
+        should "perform request against an index" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_search', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.search :index => 'foo'
+        end
+
+        should "perform request against an index and type" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/bar/_search', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.search :index => 'foo', :type => 'bar'
+        end
+
+        should "perform request against multiple indices" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/_search', url
+            true
+          end.returns(FakeResponse.new).twice
+
+          subject.search :index => ['foo', 'bar']
+          subject.search :index => 'foo,bar'
+        end
+
+        should "perform request against multiple indices and types" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo,bar/lam,bam/_search', url
+            true
+          end.returns(FakeResponse.new).twice
+
+          subject.search :index => ['foo', 'bar'], :type => ['lam', 'bam']
+          subject.search :index => 'foo,bar', :type => 'lam,bam'
+        end
+
+        should "encode URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_search', url
+            assert_equal 'count', params[:search_type]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.search :search_type => 'count'
+        end
+
+        should "validate URL parameters" do
+          assert_raise ArgumentError do
+            subject.search :search_type => 'count', :qwertypoiuy => 'asdflkjhg'
+          end
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/bar%2Fbam/_search', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.search :index => 'foo^bar', :type => 'bar/bam'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/snapshot/create_repository_test.rb b/test/unit/snapshot/create_repository_test.rb
new file mode 100644
index 0000000..efcaae2
--- /dev/null
+++ b/test/unit/snapshot/create_repository_test.rb
@@ -0,0 +1,38 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class SnapshotCreateRepositoryTest < ::Test::Unit::TestCase
+
+      context "Snapshot: Create repository" do
+        subject { FakeClient.new }
+
+        should "require the :repository argument" do
+          assert_raise ArgumentError do
+            subject.snapshot.create_repository :body => {}
+          end
+        end
+
+        should "require the :body argument" do
+          assert_raise ArgumentError do
+            subject.snapshot.create_repository :repository => 'foo'
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'PUT', method
+            assert_equal '_snapshot/foo', url
+            assert_equal Hash.new, params
+            assert_equal Hash.new, body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.snapshot.create_repository :repository => 'foo', :body => {}
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/snapshot/create_test.rb b/test/unit/snapshot/create_test.rb
new file mode 100644
index 0000000..00ccc17
--- /dev/null
+++ b/test/unit/snapshot/create_test.rb
@@ -0,0 +1,38 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class SnapshotCreateTest < ::Test::Unit::TestCase
+
+      context "Snapshot: Create" do
+        subject { FakeClient.new }
+
+        should "require the :repository argument" do
+          assert_raise ArgumentError do
+            subject.snapshot.create :snapshot => 'bar', :body => {}
+          end
+        end
+
+        should "require the :snapshot argument" do
+          assert_raise ArgumentError do
+            subject.snapshot.create :repository => 'foo', :body => {}
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'PUT', method
+            assert_equal '_snapshot/foo/bar', url
+            assert_equal Hash.new, params
+            assert_equal Hash.new, body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.snapshot.create :repository => 'foo', :snapshot => 'bar', :body => {}
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/snapshot/delete_repository_test.rb b/test/unit/snapshot/delete_repository_test.rb
new file mode 100644
index 0000000..0390b8c
--- /dev/null
+++ b/test/unit/snapshot/delete_repository_test.rb
@@ -0,0 +1,35 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class SnapshotDeleteRepositoryTest < ::Test::Unit::TestCase
+
+      context "Snapshot: Delete repository" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'DELETE', method
+            assert_equal '_snapshot/foo', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.snapshot.delete_repository :repository => 'foo'
+        end
+
+        should "perform the request for more indices" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_snapshot/foo,bar', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.snapshot.delete_repository :repository => ['foo','bar']
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/snapshot/delete_test.rb b/test/unit/snapshot/delete_test.rb
new file mode 100644
index 0000000..61bca6c
--- /dev/null
+++ b/test/unit/snapshot/delete_test.rb
@@ -0,0 +1,38 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class SnapshotDeleteTest < ::Test::Unit::TestCase
+
+      context "Snapshot: Delete" do
+        subject { FakeClient.new }
+
+        should "require the :repository argument" do
+          assert_raise ArgumentError do
+            subject.snapshot.delete :snapshot => 'bar', :body => {}
+          end
+        end
+
+        should "require the :snapshot argument" do
+          assert_raise ArgumentError do
+            subject.snapshot.delete :repository => 'foo', :body => {}
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'DELETE', method
+            assert_equal '_snapshot/foo/bar', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.snapshot.delete :repository => 'foo', :snapshot => 'bar'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/snapshot/get_repository_test.rb b/test/unit/snapshot/get_repository_test.rb
new file mode 100644
index 0000000..589916b
--- /dev/null
+++ b/test/unit/snapshot/get_repository_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class SnapshotGetRepositoryTest < ::Test::Unit::TestCase
+
+      context "Snapshot: Get repository" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_snapshot/foo', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.snapshot.get_repository :repository => 'foo'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/snapshot/get_test.rb b/test/unit/snapshot/get_test.rb
new file mode 100644
index 0000000..f12c20e
--- /dev/null
+++ b/test/unit/snapshot/get_test.rb
@@ -0,0 +1,38 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class SnapshotGetTest < ::Test::Unit::TestCase
+
+      context "Snapshot: Get" do
+        subject { FakeClient.new }
+
+        should "require the :repository argument" do
+          assert_raise ArgumentError do
+            subject.snapshot.get :snapshot => 'bar', :body => {}
+          end
+        end
+
+        should "require the :snapshot argument" do
+          assert_raise ArgumentError do
+            subject.snapshot.get :repository => 'foo', :body => {}
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_snapshot/foo/bar', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.snapshot.get :repository => 'foo', :snapshot => 'bar'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/snapshot/restore_test.rb b/test/unit/snapshot/restore_test.rb
new file mode 100644
index 0000000..08c1efb
--- /dev/null
+++ b/test/unit/snapshot/restore_test.rb
@@ -0,0 +1,38 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class SnapshotRestoreTest < ::Test::Unit::TestCase
+
+      context "Snapshot: Restore" do
+        subject { FakeClient.new }
+
+        should "require the :repository argument" do
+          assert_raise ArgumentError do
+            subject.snapshot.restore :snapshot => 'bar'
+          end
+        end
+
+        should "require the :snapshot argument" do
+          assert_raise ArgumentError do
+            subject.snapshot.restore :repository => 'foo'
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'POST', method
+            assert_equal '_snapshot/foo/bar/_restore', url
+            assert_equal Hash.new, params
+            assert_equal nil, body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.snapshot.restore :repository => 'foo', :snapshot => 'bar'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/snapshot/status_test.rb b/test/unit/snapshot/status_test.rb
new file mode 100644
index 0000000..2d76a03
--- /dev/null
+++ b/test/unit/snapshot/status_test.rb
@@ -0,0 +1,38 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class SnapshotStatusTest < ::Test::Unit::TestCase
+
+      context "Snapshot: Status" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_snapshot/_status', url
+            assert_equal Hash.new, params
+            assert_nil   body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.snapshot.status
+        end
+
+        should "encode repository and snapshot" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal '_snapshot/foo/bar/_status', url
+            assert_equal Hash.new, params
+            assert_equal nil, body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.snapshot.status :repository => 'foo', :snapshot => 'bar'
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/suggest_test.rb b/test/unit/suggest_test.rb
new file mode 100644
index 0000000..17f08a6
--- /dev/null
+++ b/test/unit/suggest_test.rb
@@ -0,0 +1,64 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class SuggestTest < ::Test::Unit::TestCase
+
+      context "Suggest" do
+        subject { FakeClient.new }
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'POST', method
+            assert_equal '_suggest', url
+            assert_equal Hash.new, params
+            assert_equal Hash.new, body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.suggest :body => {}
+        end
+
+        should "perform request against an index" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_suggest', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.suggest :index => 'foo', :body => {}
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/_suggest', url
+            assert_equal 'abc123', params[:routing]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.suggest :index => 'foo', :routing => 'abc123', :body => {}
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/_suggest', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.suggest :index => 'foo^bar', :body => {}
+        end
+
+        should "pass the request definition in the body" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal '_suggest', url
+            assert_equal 'tset', body[:my_suggest][:text]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.suggest :body => { :my_suggest => { :text => 'tset' } }
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/termvector_test.rb b/test/unit/termvector_test.rb
new file mode 100644
index 0000000..ec04aa0
--- /dev/null
+++ b/test/unit/termvector_test.rb
@@ -0,0 +1,44 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class TermvectorTest < ::Test::Unit::TestCase
+
+      context "Termvector" do
+        subject { FakeClient.new }
+
+        should "require the :index argument" do
+          assert_raise ArgumentError do
+            subject.termvector :type => 'bar', :id => '1'
+          end
+        end
+
+        should "require the :type argument" do
+          assert_raise ArgumentError do
+            subject.termvector :index => 'foo', :id => '1'
+          end
+        end
+
+        should "require the :id argument" do
+          assert_raise ArgumentError do
+            subject.termvector :index => 'foo', :type => 'bar'
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'GET', method
+            assert_equal 'foo/bar/123/_termvector', url
+            assert_equal Hash.new, params
+            assert_equal Hash.new, body
+            true
+          end.returns(FakeResponse.new)
+
+          subject.termvector :index => 'foo', :type => 'bar', :id => '123', :body => {}
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/update_document_test.rb b/test/unit/update_document_test.rb
new file mode 100644
index 0000000..d47ab70
--- /dev/null
+++ b/test/unit/update_document_test.rb
@@ -0,0 +1,77 @@
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class UpdateTest < ::Test::Unit::TestCase
+
+      context "Update document" do
+        subject { FakeClient.new }
+
+        should "require the :index argument" do
+          assert_raise ArgumentError do
+            subject.update :type => 'bar', :id => '1'
+          end
+        end
+
+        should "require the :type argument" do
+          assert_raise ArgumentError do
+            subject.update :index => 'foo', :id => '1'
+          end
+        end
+
+        should "require the :id argument" do
+          assert_raise ArgumentError do
+            subject.update :index => 'foo', :type => 'bar'
+          end
+        end
+
+        should "perform correct request" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'POST', method
+            assert_equal 'foo/bar/1/_update', url
+            assert_equal Hash.new, params
+            assert_equal Hash.new, body[:doc]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.update :index => 'foo', :type => 'bar', :id => '1', :body => { :doc => {} }
+        end
+
+        should "pass the URL parameters" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo/bar/1/_update', url
+            assert_equal 100, params[:version]
+            true
+          end.returns(FakeResponse.new)
+
+          subject.update :index => 'foo', :type => 'bar', :id => '1', :version => 100, :body => {}
+        end
+
+        should "validate URL parameters" do
+          assert_raise ArgumentError do
+            subject.update :index => 'foo', :type => 'bar', :id => '1', :body => { :doc => {} }, :qwertypoiuy => 'asdflkjhg'
+          end
+        end
+
+        should "URL-escape the parts" do
+          subject.expects(:perform_request).with do |method, url, params, body|
+            assert_equal 'foo%5Ebar/bar%2Fbam/1/_update', url
+            true
+          end.returns(FakeResponse.new)
+
+          subject.update :index => 'foo^bar', :type => 'bar/bam', :id => '1', :body => {}
+        end
+
+        should "catch a NotFound exception with the ignore parameter" do
+          subject.expects(:perform_request).raises(NotFound)
+
+          assert_nothing_raised do
+            subject.get :index => 'foo', :type => 'bar', :id => 'XXX', :ignore => 404
+          end
+        end
+
+      end
+
+    end
+  end
+end
diff --git a/test/unit/utils_test.rb b/test/unit/utils_test.rb
new file mode 100644
index 0000000..db056a7
--- /dev/null
+++ b/test/unit/utils_test.rb
@@ -0,0 +1,184 @@
+# encoding: UTF-8
+
+require 'test_helper'
+
+module Elasticsearch
+  module Test
+    class UtilsTest < ::Test::Unit::TestCase
+      include Elasticsearch::API::Utils
+
+      context "Utils" do
+
+        context "__escape" do
+
+          should "encode Unicode characters" do
+            assert_equal '%E4%B8%AD%E6%96%87', __escape('中文')
+          end
+
+          should "encode special characters" do
+            assert_equal 'foo+bar',   __escape('foo bar')
+            assert_equal 'foo%2Fbar', __escape('foo/bar')
+            assert_equal 'foo%5Ebar', __escape('foo^bar')
+          end
+
+          should "not encode asterisks" do
+            assert_equal '*', __escape('*')
+          end
+
+          should "use CGI.escape by default" do
+            CGI.expects(:escape)
+            __escape('foo bar')
+          end
+
+          should "use the escape_utils gem when available" do
+            require 'escape_utils'
+            CGI.expects(:escape).never
+            EscapeUtils.expects(:escape_url)
+            __escape('foo bar')
+          end unless RUBY_1_8 || JRUBY
+
+        end
+
+        context "__listify" do
+
+          should "create a list from single value" do
+            assert_equal 'foo', __listify('foo')
+          end
+
+          should "create a list from an array" do
+            assert_equal 'foo,bar', __listify(['foo', 'bar'])
+          end
+
+          should "create a list from multiple arguments" do
+            assert_equal 'foo,bar', __listify('foo', 'bar')
+          end
+
+          should "ignore nil values" do
+            assert_equal 'foo,bar', __listify(['foo', nil, 'bar'])
+          end
+
+          should "encode special characters" do
+            assert_equal 'foo,bar%5Ebam', __listify(['foo', 'bar^bam'])
+          end
+
+        end
+
+        context "__pathify" do
+
+          should "create a path from single value" do
+            assert_equal 'foo', __pathify('foo')
+          end
+
+          should "create a path from an array" do
+            assert_equal 'foo/bar', __pathify(['foo', 'bar'])
+          end
+
+          should "ignore nil values" do
+            assert_equal 'foo/bar', __pathify(['foo', nil, 'bar'])
+          end
+
+          should "ignore empty string values" do
+            assert_equal 'foo/bar', __pathify(['foo', '', 'bar'])
+          end
+
+        end
+
+        context "__bulkify" do
+
+          should "serialize array of hashes" do
+            result = Elasticsearch::API::Utils.__bulkify [
+              { :index =>  { :_index => 'myindexA', :_type => 'mytype', :_id => '1', :data => { :title => 'Test' } } },
+              { :update => { :_index => 'myindexB', :_type => 'mytype', :_id => '2', :data => { :doc => { :title => 'Update' } } } },
+              { :delete => { :_index => 'myindexC', :_type => 'mytypeC', :_id => '3' } }
+            ]
+
+            if RUBY_1_8
+              lines = result.split("\n")
+
+              assert_equal 5, lines.size
+              assert_match /\{"index"\:\{/, lines[0]
+              assert_match /\{"title"\:"Test"/, lines[1]
+              assert_match /\{"update"\:\{/, lines[2]
+              assert_match /\{"doc"\:\{"title"/, lines[3]
+            else
+              assert_equal <<-PAYLOAD.gsub(/^\s+/, ''), result
+                {"index":{"_index":"myindexA","_type":"mytype","_id":"1"}}
+                {"title":"Test"}
+                {"update":{"_index":"myindexB","_type":"mytype","_id":"2"}}
+                {"doc":{"title":"Update"}}
+                {"delete":{"_index":"myindexC","_type":"mytypeC","_id":"3"}}
+              PAYLOAD
+            end
+          end
+
+          should "serialize arrays of strings" do
+            result = Elasticsearch::API::Utils.__bulkify ['{"foo":"bar"}','{"moo":"bam"}']
+            assert_equal <<-PAYLOAD.gsub(/^\s+/, ''), result
+              {"foo":"bar"}
+              {"moo":"bam"}
+            PAYLOAD
+          end
+
+          should "serialize arrays of header/data pairs" do
+            result = Elasticsearch::API::Utils.__bulkify [{:foo => "bar"},{:moo => "bam"},{:foo => "baz"}]
+            assert_equal <<-PAYLOAD.gsub(/^\s+/, ''), result
+              {"foo":"bar"}
+              {"moo":"bam"}
+              {"foo":"baz"}
+            PAYLOAD
+          end
+
+          should "not modify the original payload" do
+            original = [ { :index => {:foo => 'bar', :data => { :moo => 'bam' }} } ]
+            result = Elasticsearch::API::Utils.__bulkify original
+            assert_not_nil original.first[:index][:data], "Deleted :data from #{original}"
+            assert_equal <<-PAYLOAD.gsub(/^\s+/, ''), result
+              {"index":{"foo":"bar"}}
+              {"moo":"bam"}
+            PAYLOAD
+          end
+
+        end
+
+        context "__validate_and_extract_params" do
+
+          should "extract valid params from a Hash" do
+            assert_equal( {:foo => 'qux'},
+                         __validate_and_extract_params({ :foo => 'qux' }, [:foo, :bar]) )
+          end
+
+          should "raise an exception when invalid keys present" do
+            assert_raise ArgumentError do
+              __validate_and_extract_params({ :foo => 'qux', :bam => 'mux' }, [:foo, :bar])
+            end
+          end
+
+          should "not raise an exception for COMMON_PARAMS" do
+            assert_nothing_raised do
+              __validate_and_extract_params({ :index => 'foo'}, [:foo])
+            end
+          end
+
+          should "extract COMMON_QUERY_PARAMS" do
+            assert_equal( { :format => 'yaml' },
+                          __validate_and_extract_params( { :format => 'yaml' } ) )
+          end
+
+        end
+
+        context "__extract_parts" do
+
+          should "extract parts with true value from a Hash" do
+            assert_equal( ['foo'], __extract_parts({ :foo => true, :moo => 'blah' }, [:foo, :bar]) )
+          end
+
+          should "extract parts with string value from a Hash" do
+            assert_equal( ['qux'], __extract_parts({ :foo => 'qux', :moo => 'blah' }, [:foo, :bar]) )
+          end
+
+        end
+
+      end
+    end
+  end
+end

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-elasticsearch-api.git



More information about the Pkg-ruby-extras-commits mailing list