merging to master
diff --git a/.gitignore b/.gitignore
index ed97819..dca2977 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,5 @@
-coverage/
-doc/
-pkg/
+/coverage
+/doc
+/pkg
 *.gem
 Gemfile.lock
diff --git a/.travis.yml b/.travis.yml
index 34f69c5..4773bd7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,6 @@
 language: ruby
 rvm:
   - 1.9.3
-  - 2.1.1
+  - 2.1.5
 script:
   - rake
diff --git a/Gemfile b/Gemfile
index 783e457..9a39411 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,6 +1,11 @@
 source 'https://rubygems.org'
+
 group :test do
   gem 'coveralls', require: false
-  gem 'rspec', '~> 2.14.1'
-  gem 'webmock', '~> 1.17.4'
+  gem 'rspec', '~> 3.1.0'
+  gem 'webmock', '~> 1.20.4'
 end
+
+group :doc do
+  gem 'rdoc', '~> 4.2.0'
+end
\ No newline at end of file
diff --git a/README.md b/README.md
index 5c4526a..52f732a 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,4 @@
-PredictionIO Ruby SDK
-=====================
+# PredictionIO Ruby SDK
 
 [![Build Status](https://travis-ci.org/PredictionIO/PredictionIO-Ruby-SDK.svg?branch=develop)](https://travis-ci.org/PredictionIO/PredictionIO-Ruby-SDK)
 [![Code Climate](https://codeclimate.com/github/PredictionIO/PredictionIO-Ruby-SDK.png)](https://codeclimate.com/github/PredictionIO/PredictionIO-Ruby-SDK)
@@ -10,47 +9,36 @@
 
 The SDK requires Ruby 1.9.3+ to function properly.
 
+# Support
 
-Support
-=======
-
-
-Forum
------
+## Forum
 
 https://groups.google.com/group/predictionio-user
 
-
-Issue Tracker
--------------
+## Issue Tracker
 
 https://predictionio.atlassian.net
 
 If you are unsure whether a behavior is an issue, bringing it up in the forum is highly encouraged.
 
+# Installation
 
-Installation
-============
-
-The module is published to RubyGems and can be installed directly by
+The module is published to [RubyGems](http://rubygems.org/gems/predictionio) and can be installed directly by:
 
 ```sh
 gem install predictionio
 ```
 
-If you prefer to build and install from source
+Or using [Bundler](http://bundler.io/) with:
 
-```sh
-gem build predictionio.gemspec
-gem install predictionio-<version>.gem
+```
+gem 'predictionio', '0.8.3'
 ```
 
-
-Documentation and Usage
-=======================
-
-[Ruby quickstart guide](http://docs.prediction.io/current/tutorials/quickstart-ruby.html)
+# Documentation and Usage
 
 An online version of the documentation is [viewable here](http://docs.prediction.io/ruby/api/PredictionIO.html).
 
-A local copy of the documentation will also be installed by the gem.
+# Version
+
+The gem version **must** match the PredictionIO version, i.e. gem version 0.8.3 **only** works with PredictionIO 0.8.3.
\ No newline at end of file
diff --git a/lib/predictionio/connection.rb b/lib/predictionio/connection.rb
index 2644bb9..0159bc0 100644
--- a/lib/predictionio/connection.rb
+++ b/lib/predictionio/connection.rb
@@ -22,8 +22,7 @@
       threads.times do
         Thread.new do
           begin
-            Net::HTTP.start(uri.host, uri.port,
-                            :use_ssl => uri.scheme == 'https') do |http|
+            Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
               @counter_lock.synchronize do
                 @connections += 1
               end
@@ -46,7 +45,7 @@
                       http_req = Net::HTTP::Post.new("#{uri.path}#{request.path}")
                       http_req.set_form_data(request.params)
                     else
-                      http_req = Net::HTTP::Post.new("#{uri.path}#{request.path}", initheader = {'Content-Type' => 'application/json'})
+                      http_req = Net::HTTP::Post.new("#{uri.path}#{request.path}", initheader = { 'Content-Type' => 'application/json' })
                       http_req.body = request.params
                     end
                     begin
@@ -93,9 +92,7 @@
     # Create an asynchronous request and response package, put it in the pending queue, and return the response object.
     def request(method, request)
       response = AsyncResponse.new(request)
-      @packages.push(:method => method,
-                     :request => request,
-                     :response => response)
+      @packages.push(method: method, request: request, response: response)
       response
     end
 
diff --git a/lib/predictionio/engine_client.rb b/lib/predictionio/engine_client.rb
index 65ee8ad..f6617fb 100644
--- a/lib/predictionio/engine_client.rb
+++ b/lib/predictionio/engine_client.rb
@@ -51,8 +51,7 @@
     # - 1 concurrent HTTP(S) connections (threads)
     # - API entry point at http://localhost:8000 (apiurl)
     # - a 60-second timeout for each HTTP(S) connection (thread_timeout)
-    def initialize(apiurl = 'http://localhost:8000', threads = 1,
-                   thread_timeout = 60)
+    def initialize(apiurl = 'http://localhost:8000', threads = 1, thread_timeout = 60)
       @http = PredictionIO::Connection.new(URI(apiurl), threads, thread_timeout)
     end
 
@@ -108,8 +107,7 @@
     #
     # See also #send_query.
     def asend_query(query)
-      @http.apost(PredictionIO::AsyncRequest.new('/queries.json',
-                                                 query.to_json))
+      @http.apost(PredictionIO::AsyncRequest.new('/queries.json', query.to_json))
     end
 
     # :category: Synchronous Methods
diff --git a/lib/predictionio/event_client.rb b/lib/predictionio/event_client.rb
index 83c73a5..16b1e01 100644
--- a/lib/predictionio/event_client.rb
+++ b/lib/predictionio/event_client.rb
@@ -72,7 +72,7 @@
   #     begin
   #       result = client.record_user_action_on_item('rate', 'foouser',
   #                                                  'baritem',
-  #                                                  'pio_rating' => 4)
+  #                                                  'rating' => 4)
   #     rescue PredictionIO::EventClient::NotCreatedError => e
   #       ...
   #     end
@@ -84,8 +84,7 @@
     # - 1 concurrent HTTP(S) connections (threads)
     # - API entry point at http://localhost:7070 (apiurl)
     # - a 60-second timeout for each HTTP(S) connection (thread_timeout)
-    def initialize(access_key, apiurl = 'http://localhost:7070', threads = 1,
-                   thread_timeout = 60)
+    def initialize(access_key, apiurl = 'http://localhost:7070', threads = 1, thread_timeout = 60)
       @access_key = access_key
       @http = PredictionIO::Connection.new(URI(apiurl), threads, thread_timeout)
     end
@@ -164,7 +163,7 @@
     #
     # See also #set_user.
     def aset_user(uid, optional = {})
-      acreate_event('$set', 'pio_user', uid, optional)
+      acreate_event('$set', 'user', uid, optional)
     end
 
     # :category: Synchronous Methods
@@ -194,7 +193,7 @@
         fail(ArgumentError, 'properties must be present when event is $unset')
       optional['properties'].empty? &&
         fail(ArgumentError, 'properties cannot be empty when event is $unset')
-      acreate_event('$unset', 'pio_user', uid, optional)
+      acreate_event('$unset', 'user', uid, optional)
     end
 
     # :category: Synchronous Methods
@@ -218,7 +217,7 @@
     #
     # See also #delete_user.
     def adelete_user(uid)
-      acreate_event('$delete', 'pio_user', uid)
+      acreate_event('$delete', 'user', uid)
     end
 
     # :category: Synchronous Methods
@@ -242,7 +241,7 @@
     #
     # See also #set_item.
     def aset_item(iid, optional = {})
-      acreate_event('$set', 'pio_item', iid, optional)
+      acreate_event('$set', 'item', iid, optional)
     end
 
     # :category: Synchronous Methods
@@ -272,7 +271,7 @@
         fail(ArgumentError, 'properties must be present when event is $unset')
       optional['properties'].empty? &&
         fail(ArgumentError, 'properties cannot be empty when event is $unset')
-      acreate_event('$unset', 'pio_item', iid, optional)
+      acreate_event('$unset', 'item', iid, optional)
     end
 
     # :category: Synchronous Methods
@@ -296,7 +295,7 @@
     #
     # See also #delete_item.
     def adelete_item(uid)
-      acreate_event('$delete', 'pio_item', uid)
+      acreate_event('$delete', 'item', uid)
     end
 
     # :category: Synchronous Methods
@@ -320,9 +319,9 @@
     #
     # See also #record_user_action_on_item.
     def arecord_user_action_on_item(action, uid, iid, optional = {})
-      optional['targetEntityType'] = 'pio_item'
+      optional['targetEntityType'] = 'item'
       optional['targetEntityId'] = iid
-      acreate_event(action, 'pio_user', uid, optional)
+      acreate_event(action, 'user', uid, optional)
     end
 
     # :category: Synchronous Methods
diff --git a/lib/predictionio/version.rb b/lib/predictionio/version.rb
new file mode 100644
index 0000000..4159931
--- /dev/null
+++ b/lib/predictionio/version.rb
@@ -0,0 +1,3 @@
+module PredictionIO
+  VERSION = '0.8.3'
+end
\ No newline at end of file
diff --git a/predictionio.gemspec b/predictionio.gemspec
index 8bbb9f7..a7db2f5 100644
--- a/predictionio.gemspec
+++ b/predictionio.gemspec
@@ -1,18 +1,21 @@
+$:.push File.expand_path('../lib', __FILE__)
+require 'predictionio/version'
+
 Gem::Specification.new do |s|
   s.name = 'predictionio'
   s.summary = 'PredictionIO Ruby SDK'
   s.description = <<-EOF
 PredictionIO is a prediction server for building smart applications. This gem
 provides convenient access of the PredictionIO API to Ruby programmers so that
-they can focus on their application logic.
-  EOF
-  s.version = '0.8.2'
+they can focus on application logic.
+EOF
+  s.version = PredictionIO::VERSION
   s.licenses = ['Apache-2.0']
   s.author = 'The PredictionIO Team'
   s.email = 'support@prediction.io'
   s.homepage = 'http://prediction.io'
   s.platform = Gem::Platform::RUBY
-  s.required_ruby_version = '>=1.9'
+  s.required_ruby_version = '>= 1.9'
   s.files = Dir[File.join('lib', '**', '**')]
   s.has_rdoc = true
 end
diff --git a/spec/predictionio_spec.rb b/spec/predictionio_spec.rb
index b7f2045..d400898 100644
--- a/spec/predictionio_spec.rb
+++ b/spec/predictionio_spec.rb
@@ -1,45 +1,89 @@
 require 'predictionio'
 require 'spec_helper'
 
-event_client = PredictionIO::EventClient.new(1, 'http://fakeapi.com:8000', 10)
+event_client = PredictionIO::EventClient.new(1, 'http://fakeapi.com:7070', 10)
 engine_client = PredictionIO::EngineClient.new('http://fakeapi.com:8000', 10)
 
 describe PredictionIO do
   describe 'Events API' do
     it 'create_event should create an event' do
       response = event_client.create_event('register', 'user', 'foobar')
-      expect(response).to_not raise_error
+      expect(response.code).to eq('201')
     end
+
+    it 'create_event should not raise an error' do
+      response = event_client.create_event('register', 'user', 'foobar')
+      expect{ response }.to_not raise_error
+    end
+
     it 'set_user should set user properties' do
       response = event_client.set_user('foobar')
-      expect(response).to_not raise_error
+      expect(response.code).to eq('201')
     end
+
+    it 'set_user should not raise an error' do
+      response = event_client.set_user('foobar')
+      expect{ response }.to_not raise_error
+    end
+
     it 'unset_user should unset user properties' do
-      response = event_client.unset_user('foobar',
-                                         'properties' => { 'bar' => 'baz' })
-      expect(response).to_not raise_error
+      response = event_client.unset_user('foobar', 'properties' => { 'bar' => 'baz' })
+      expect(response.code).to eq('201')
     end
+
+    it 'unset_user should not raise an error' do
+      response = event_client.unset_user('foobar', 'properties' => { 'bar' => 'baz' })
+      expect{ response }.to_not raise_error
+    end
+
     it 'set_item should set item properties' do
       response = event_client.set_item('foobar')
-      expect(response).to_not raise_error
+      expect(response.code).to eq('201')
     end
+
+    it 'set_item should should not raise an error' do
+      response = event_client.set_item('foobar')
+      expect{ response }.to_not raise_error
+    end
+
     it 'unset_item should unset item properties' do
-      response = event_client.unset_item('foobar',
-                                         'properties' => { 'bar' => 'baz' })
-      expect(response).to_not raise_error
+      response = event_client.unset_item('foobar', 'properties' => { 'bar' => 'baz' })
+      expect(response.code).to eq('201')
     end
+
+    it 'unset_item should not raise an error' do
+      response = event_client.unset_item('foobar', 'properties' => { 'bar' => 'baz' })
+      expect{ response }.to_not raise_error
+    end
+
     it 'record_user_action_on_item should record a U2I action' do
-      response = event_client.record_user_action_on_item(
-        'greet', 'foobar', 'barbaz', 'properties' => { 'dead' => 'beef' })
-      expect(response).to_not raise_error
+      response = event_client.record_user_action_on_item('greet', 'foobar', 'barbaz', 'properties' => { 'dead' => 'beef' })
+      expect(response.code).to eq('201')
     end
+
+    it 'record_user_action_on_item should not raise an error' do
+      response = event_client.record_user_action_on_item('greet', 'foobar', 'barbaz', 'properties' => { 'dead' => 'beef' })
+      expect{ response }.to_not raise_error
+    end
+
     it 'delete_user should delete a user' do
       response = event_client.delete_user('foobar')
-      expect(response).to_not raise_error
+      expect(response.code).to eq('201')
     end
+
+    it 'delete_user should not raise an error' do
+      response = event_client.delete_user('foobar')
+      expect{ response }.to_not raise_error
+    end
+
     it 'delete_item should delete an item' do
       response = event_client.delete_item('foobar')
-      expect(response).to_not raise_error
+      expect(response.code).to eq('201')
+    end
+
+    it 'delete_item should not raise an error' do
+      response = event_client.delete_item('foobar')
+      expect{ response }.to_not raise_error
     end
   end
 
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 917ce65..dd2a85b 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -8,48 +8,62 @@
 RSpec.configure do |config|
   config.before(:each) do
     # Events API
-    stub_request(:post, 'http://fakeapi.com:8000/events.json?accessKey=1')
+    stub_request(:post, 'http://fakeapi.com:7070/events.json?accessKey=1')
       .with(body: hash_including(event: 'register',
-                                 entityType: 'user', entityId: 'foobar'))
+                                 entityType: 'user',
+                                 entityId: 'foobar'))
       .to_return(status: 201, body: JSON.generate(eventId: 'deadbeef00'))
-    stub_request(:post, 'http://fakeapi.com:8000/events.json?accessKey=1')
+
+    stub_request(:post, 'http://fakeapi.com:7070/events.json?accessKey=1')
       .with(body: hash_including(event: '$set',
-                                 entityType: 'pio_user', entityId: 'foobar'))
+                                 entityType: 'user',
+                                 entityId: 'foobar'))
       .to_return(status: 201, body: JSON.generate(eventId: 'deadbeef01'))
-    stub_request(:post, 'http://fakeapi.com:8000/events.json?accessKey=1')
+
+    stub_request(:post, 'http://fakeapi.com:7070/events.json?accessKey=1')
       .with(body: hash_including(event: '$unset',
-                                 entityType: 'pio_user', entityId: 'foobar',
+                                 entityType: 'user',
+                                 entityId: 'foobar',
                                  properties: { bar: 'baz' }))
       .to_return(status: 201, body: JSON.generate(eventId: 'deadbeef02'))
-    stub_request(:post, 'http://fakeapi.com:8000/events.json?accessKey=1')
+
+    stub_request(:post, 'http://fakeapi.com:7070/events.json?accessKey=1')
       .with(body: hash_including(event: '$set',
-                                 entityType: 'pio_item', entityId: 'foobar'))
+                                 entityType: 'item',
+                                 entityId: 'foobar'))
       .to_return(status: 201, body: JSON.generate(eventId: 'deadbeef03'))
-    stub_request(:post, 'http://fakeapi.com:8000/events.json?accessKey=1')
+
+    stub_request(:post, 'http://fakeapi.com:7070/events.json?accessKey=1')
       .with(body: hash_including(event: '$unset',
-                                 entityType: 'pio_item', entityId: 'foobar',
+                                 entityType: 'item',
+                                 entityId: 'foobar',
                                  properties: { bar: 'baz' }))
       .to_return(status: 201, body: JSON.generate(eventId: 'deadbeef04'))
-    stub_request(:post, 'http://fakeapi.com:8000/events.json?accessKey=1')
+
+    stub_request(:post, 'http://fakeapi.com:7070/events.json?accessKey=1')
       .with(body: hash_including(event: 'greet',
-                                 entityType: 'pio_user', entityId: 'foobar',
-                                 targetEntityType: 'pio_item',
+                                 entityType: 'user',
+                                 entityId: 'foobar',
+                                 targetEntityType: 'item',
                                  targetEntityId: 'barbaz',
                                  properties: { dead: 'beef' }))
       .to_return(status: 201, body: JSON.generate(eventId: 'deadbeef05'))
-    stub_request(:post, 'http://fakeapi.com:8000/events.json?accessKey=1')
+
+    stub_request(:post, 'http://fakeapi.com:7070/events.json?accessKey=1')
       .with(body: hash_including(event: '$delete',
-                                 entityType: 'pio_user', entityId: 'foobar'))
+                                 entityType: 'user',
+                                 entityId: 'foobar'))
       .to_return(status: 201, body: JSON.generate(eventId: 'deadbeef06'))
-    stub_request(:post, 'http://fakeapi.com:8000/events.json?accessKey=1')
+
+    stub_request(:post, 'http://fakeapi.com:7070/events.json?accessKey=1')
       .with(body: hash_including(event: '$delete',
-                                 entityType: 'pio_item', entityId: 'foobar'))
+                                 entityType: 'item',
+                                 entityId: 'foobar'))
       .to_return(status: 201, body: JSON.generate(eventId: 'deadbeef07'))
 
     # Engine Instance
     stub_request(:post, 'http://fakeapi.com:8000/queries.json')
       .with(body: { uid: 'foobar' })
-      .to_return(status: 200, body: JSON.generate(iids: %w(dead beef)),
-                 headers: {})
+      .to_return(status: 200, body: JSON.generate(iids: %w(dead beef)), headers: {})
   end
 end