diff --git a/.gitignore b/.gitignore
index 363b240..59c1883 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,7 +10,6 @@ autom4te.cache/
 
 *.config
 *.creator
-*.files
 *.includes
 *.user
 *.mem
diff --git a/.gitmodules b/.gitmodules
index 4cf2081..8a236f9 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,3 @@
-[submodule "riack"]
-	path = riack
-	url = https://github.com/trifork/riack.git
+[submodule "LibRiack"]
+	path = LibRiack
+	url = https://github.com/trifork/riack.git 
diff --git a/.travis.yml b/.travis.yml
index 2d33250..7a306a0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,18 +1,20 @@
 language: php
 php:
+  - "5.6"
   - "5.5"
   - "5.4"
   - "5.3"
-env:
-services: riak
+services:
+  - riak
 before_install:
-  - sudo apt-get update -qq
+  - sudo apt-get update
   - sudo apt-get install -qq valgrind
-  - git submodule update --init --recursive
 before_script:
-  - "ulimit -n 2048"
+  - git submodule update --init --recursive
   - ./script/build_module.sh
-  - search-cmd install testsearch
 script:
+  - sudo search-cmd install testsearch
   - PHP=`which php`
+  - PHP=~/.phpenv/versions/$(phpenv version-name)/bin/php
   - REPORT_EXIT_STATUS=1 TEST_PHP_EXECUTABLE=$PHP $PHP run-tests.php -q -m --show-diff
+  - find . -name *.mem | xargs cat
diff --git a/CREDITS.md b/CREDITS.md
index 63622c0..be84b91 100644
--- a/CREDITS.md
+++ b/CREDITS.md
@@ -1,5 +1,9 @@
 #THANKS TO
 
+##FabioBatSilva - https://github.com/FabioBatSilva
+- Conflict resolvers idea and code
+- Added vector clock on objects.
+
 ##guilhermeblanco - https://github.com/guilhermeblanco
 - Improving the names and API in general.
 
diff --git a/LibRiack b/LibRiack
new file mode 160000
index 0000000..973f546
--- /dev/null
+++ b/LibRiack
@@ -0,0 +1 @@
+Subproject commit 973f546e0039816e127e07aebc5556b5e2cdd6f2
diff --git a/README.md b/README.md
index 65de6ae..1f9a75d 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
-[![Build Status](https://travis-ci.org/TriKaspar/php_riak.png)](https://travis-ci.org/TriKaspar/php_riak)
+[![Build Status](https://travis-ci.org/php-riak/php_riak.png?branch=master)](https://travis-ci.org/php-riak/php_riak)
 
-More documentation can be found at http://phpriak.bachpedersen.dk/  
-Stubs for editor autocompletion at https://github.com/TriKaspar/php_riak_stub  
+Discussion forum: http://ost.io/@php-riak/php_riak  
+Stubs for editor autocompletion at https://github.com/php-riak/php_riak_stub  
 
 # Riak PHP extension
 PHP extension for interfacing with Riak.  
@@ -12,7 +12,7 @@ PHP extension for interfacing with Riak.
 - Riak PHP session store replacement, that can be enabled directly in php.ini no code needed.
 
 ## Building
-First make sure you have the riack submodule checked out, if not do it:
+First make sure you have the LibRiack submodule checked out, if not do it:
 
 	git submodule init
 	git submodule update
@@ -26,13 +26,13 @@ In a terminal make sure you are in project root, then run the following commands
 Module is now installed but it needs to be added to the appropriate php.ini as well, this can be done by adding the following line to your php.ini  
 
 	extension=riak.so
-Migh vary depending on you php installation though.
+Might vary depending on your php installation though.
 
 ## ini settings
 You can override the following settings in your php.ini (settings shown below are the default settings if not specified in php.ini)
 
-	; How many persistent connections pr. host:port so if you are connecting to 5 differenct servers there will be 20 persistent connections to each.  
-	; If you do not want to reuse connections between request set this value to 0  
+        ; How many persistent connections pr. host:port so if you are connecting to 5 different servers there will be 20 persistent connections to each.  
+        ; If you do not want to reuse connections between request set this value to 0  
         riak.persistent.connections=20
         ; If a connection has not been active within this time frame, automatically reconnect before using it again
         ; (in seconds)
@@ -43,14 +43,16 @@ You can override the following settings in your php.ini (settings shown below ar
         riak.socket.recv_timeout=10000
         ; Socket send timeout [ms]
         riak.socket.send_timeout=10000
+        ; Number of retries if riak returns an error  
+        riak.default.retries=1
 
 ## Usage
 
 ### Riak session
 This extension includes a session module that can replace the default PHP session handler, no code changes needed just setup the following in your php.ini:
 
-	session.save_handler=riak
-	session.save_path=proto://HOST:PORT/SESSIONBUCKET
+        session.save_handler=riak
+        session.save_path=proto://HOST:PORT/SESSIONBUCKET
 
 You can specify w, dw, pw, r, rw and pr values by adding them to the session.save_path.
 For instance to use a local riak with w and r values of 2:
@@ -68,12 +70,259 @@ Recommended bucket properties:
 The session handler does not implement garbage collection, use riak´s key-expire setting instead
 See http://docs.basho.com/riak/1.3.1/tutorials/choosing-a-backend/Bitcask/ for betails on how to enable automatic key expire.
 
-### PHP Code
-Examples of usage can be found in the .phpt files in the test folder...
+### From PHP
+####Riak connection
+To create a connection to Riak you simply instantiate a \Riak\Connection class.  
+If no connection could be made a \Riak\Exception\ConnectionException will be thrown.
+```
+$connection = new \Riak\Connection('localhost', 8087);
+```
+Remember php_riak uses to protobuffers interface which means you should use the riak probuffers port, which by default is set to 8087.  
+  
+####Get/put
+Since all objects in Riak are stored in buckets you start by creating a \Riak\Bucket and then you can call put to store an object.  
+Below is a simple example that show how to do a put an object and get it back from Riak, the example assumes siblings(allowMult) are turned off on the bucket, which it is be by default.  
+```PHP
+// Create a new bucket
+$bucket = new \Riak\Bucket($connection, 'bucket_name');
+ 
+// Create a new object
+$obj = new \Riak\Object('object_name');
+// Set the object data that will be saved to Riak
+$obj->setContent("some content to save");
+// Store the object in the bucket
+$bucket->put($obj);
+ 
+// Read back the object from Riak
+$response = $bucket->get('object_name');
+// Make sure we got an object back
+if ($response->hasObject()) {
+  // Get the first returned object
+  $readdenObject = $response->getFirstObject();
+  echo "Object content: ".$readdenObject->getContent();
+}
+```
+
+####Bucket properties (Riak 1.4 and above)
+Modifying bucket properties are easy, create a \Riak\BucketPropertyList object and set the desired properties and then call setPropertyList on a \Riak\Bucket.   
+
+ ```PHP
+use \Riak\Property\ReplicationMode as RM;
+
+$bucket = new \Riak\Bucket($connection, 'bucket_props_ext');
+
+// Create new bucket properties
+$newProps = new \Riak\BucketPropertyList();
+$newProps->setSearchEnabled(true) // Enable riak search on bucket
+  ->setR(1) // Set R value
+  ->setNValue(1) // Set N value
+  ->setW(1) // Set W value
+  ->setRW(1) // Set RW value
+  ->setDW(1) // Set DW value
+  ->setBigVClock(5000) // Set big vclock
+  ->setReplicationMode(new RM\FullSyncOnly()); // Set replication mode to fullsync only
+ 
+// Create some post commit hooks we can set on the bucket
+$postCommitHooks = new \Riak\Property\CommitHookList();
+$postCommitHooks[] = new \Riak\Property\CommitHook('module', 'function');
+$postCommitHooks[] = new \Riak\Property\CommitHook('js_function_name');
+$newProps->setPostCommitHookList($postCommitHooks);
+ 
+// Apply the properties
+$bucket->setPropertyList($newProps);
+ 
+// Properties are now applied on the bucket
+```
+
+####Siblings
+Siblings are an important feature in Riak, if you are unsure how they work I recommend reading about Vector Clocks here http://docs.basho.com/riak/latest/theory/concepts/Vector-Clocks/  
+Sibling can occur when bucket properties have allowMult set to true and multiple values are written to the same key at the same time, or without vector clocks.  
+
+When siblings occur they should be resolved, this should preferable happen when an object is updated, this is the normal workflow for sibling resolution:  
+* An object value needs to be changed.  
+* The object is fetched from riak using ->get()  
+* getObject is called on the output (this makes php_riak automatically call the conflict resolver, which results in a single object)  
+* Update the value like normal  
+* Save back the object  
+
+The conflict is now gone since you resolved it after the read and you put the resolved version back into riak.  
+
+What about when you don't want to update the object but just read the value?  
+* Either ignore the conflict, this means that your resolver will be called on every read until next time the object is updated, 
+however your resolver function should always return a single merged object so you should not see any difference on the output.  
+* Or put back your resolved object, you can make your conflict resolver do a put after it have resolved the object, remember to read back the vclock as well.  
+  Be very carefull when doing it this ways as you increases the chance of multiple clients trying to resolve the same conflict at the same time 
+which will result in even more conflicts (read more about it here http://docs.basho.com/riak/latest/theory/concepts/Vector-Clocks/ )  
+  
+
+####Merging siblings
+To deal with the siblings your code needs to merge siblings, for this purpose php_riak have a Riak\Output\ConflictResolver interface, you implement this interface and tell the \Riak\Bucket object to use this resolver when it encounters conflicts, below is a simple example that will just merge the content of the siblings.  
+ ```PHP
+ // Make sure allowMult = true on your bucket
+ // Create a conflict resolver
+class SimpleMergeResolver implements \Riak\Output\ConflictResolver {
+
+    /**
+     * Resolve or merge the conflicting objects and return one that should be stored back into riak.
+     * @param \Riak\ObjectList $objects
+     * @return Object|null
+     */
+    public function resolve(\Riak\ObjectList $objects)
+    {
+        $result = null;
+        $mergedContent = "";
+        foreach ($objects as $object) {
+            if (!$object->isDeleted()) {
+                if (is_null($result)) {
+                    // We just take the first object that is not deleted and use as base for our result
+                    // that way we don't need to create a new object and copy the vclock, metadata and indexes etc.
+                    $result = $object;
+                }
+                $mergedContent .= $object->getContent();
+            }
+        }
+        // If we actually found a result, set the content to the merged value.
+        if (isset($result)) {
+            $result->setContent($mergedContent);
+        }
+        return $result;
+    }
+}
+
+$bucket = new \Riak\Bucket($connection, 'siblings');
+// Set our resolver on the bucket, to have it invoked automatically on conflicts
+$bucket->setConflictResolver(new SimpleMergeResolver());
+
+// Create an object with some data
+$obj = new \Riak\Object('conflicting');
+$obj->setContent('some data');
+$bucket->put($obj);
+// Now create a new object on same key, without reading the value first
+$obj = new \Riak\Object('conflicting');
+$obj->setContent('some other data');
+$bucket->put($obj);
+
+
+$getOutput = $bucket->get('conflicting');
+// To make sure the resolver is called you should use the getObject on the output
+$resolvedObject = $getOutput->getObject();
+// Save back the object
+$bucket->put($resolvedObject);
+
+// Read back and ensure the sibling is now gone.
+$getOutput = $bucket->get('conflicting');
+echo var_export($getOutput->hasSiblings(), true).PHP_EOL;
+echo var_export($getOutput->getObject()->getContent(), true).PHP_EOL;
+```
+
+####Secondary Indexes
+Secondary indexes can be added to \Riak\Object by calling addIndex.  
+Querying secondary indexes is also very easy, simply call the index function on an \Riak\Bucket object, see the example below:  
+ ```PHP
+// Create 10 objects with indexes
+for ($i=0; $i<10; $i++) {
+   $obj = new \Riak\Object("obj$i");
+   $obj->setContent('dummy data');
+   // Set a integer index num_int and a binary index text_bin
+   // remember secondary index should always end on _int or _bin
+   $obj->addIndex('num_int', $i);
+   $obj->addIndex('text_bin', "text$i");
+   // Store object
+   $bucket->put($obj);
+}
+ 
+// Query for all objects where num_int = 1
+$result = $bucket->index("num_int", 1);
+// Result is an array of keys, in this case obj1 should be the only entry
+echo "First query returned key: ".$result[0].PHP_EOL;
+ 
+// Now make a ranged query on the text_bin index
+$result = $bucket->index("text_bin", "text4", "text6");
+// This query will match objects which index is text4, text5 and text6
+echo "Second query returned: ";
+print_r($result);
+```
+ 
+####Search
+Riak have builtin full text search which can be very useful, I will only demonstrate 
+how php_riak client can query Riak search not how it works in general, to get the 
+full picture jump to the http://docs.basho.com/riak/latest/dev/using/search/  
+
+The example below demonstrates how to do a simple search.  
+```PHP
+// Make sure search is enabled in both riak app.config and on the bucket
+
+// Create some test data
+$testDataArr[] = '{"name": "apple","price": 2.50, "tags": ["fruit"]}';
+$testDataArr[] = '{"name": "potato","price": 1.50, "tags": ["veg", "something"]}';
+$testDataArr[] = '{"name": "pineapple","price": 15, "tags": ["fruit"]}';
+$testDataArr[] = '{"name": "cheese", "price": 45, "tags": ["cow", "dairy"]}';
+$i = 0;
+foreach ($testDataArr as $testData) {
+   $i++;
+   $obj = new \Riak\Object("id$i");
+   $obj->setContentType("application/json");
+   $obj->setContent($testData);
+   $bucket->put($obj);
+}
+ 
+// Perform the search
+$search = new \Riak\Search\Search($connection);
+$searchInput = new \Riak\Search\Input\ParameterBag();
+// Search on the name field
+$searchInput->setDefaultField('name');
+// Now search in our search_ex_bucket after documents with the name apple
+$searchResult = $search->search('search_ex_bucket', 'apple', $searchInput);
+// Did we find something?
+ 
+// Number of found documents:
+echo 'Search found '.$searchResult->getNumFound().' with the name apple'.PHP_EOL;
+$foundDocuments = $searchResult->getDocuments();
+foreach ($foundDocuments as $document) {
+   var_dump($document);
+}
+```  
+
+####Counters
+In Riak 1.4 basho added support CRDT counters http://docs.basho.com/riak/latest/dev/references/http/counters/  
+Counters are very simple to use, and they are very useful for a lot of use cases.  
+The example below shows how to get and modify counters:  
+```PHP
+// Make sure allowMult is set to true on the bucket, as this is required for CRDT's to work.
+
+// Counter can be constructed in two ways
+// With new:
+$counter1 = new \Riak\CRDT\Counter($bucket, "counter1");
+// Or with Riak\Bucket's counter function
+$counter2 = $bucket->counter("counter2");
+ 
+// All counters start at 0
+// All changes to the counter value is done using increment like this
+$counter1->increment(10);
+// Use negative values to decrement
+$counter2->increment(-10);
+ 
+// Increment can also return the updated value
+echo "Counter1 value: ".$counter1->incrementAndGet(10).PHP_EOL;
+ 
+// The Riak\Bucket->counter function can save some typing
+// the counter function will always return a counter object or throw exception
+$c2val = $bucket->counter("counter2")->get();
+echo "Counter2 value: ".$c2val.PHP_EOL;
+```  
+
+####MapReduce  
+php_riak is able to do advanced map reduce queries including streaming results etc.  
+I have not had the time to do an example yet, 
+however take a look in this php_riak unittest: https://github.com/php-riak/php_riak/blob/master/tests/mapreduce.phpt and the classes here https://github.com/php-riak/php_riak_stub/tree/master/Riak/MapReduce  
 
 ## Test requirements
 To make all tests succeed you need a running riak server with eleveldb backend and riak search enabled in app.config.
-You also need to have seach enabled on the ´testsearch´ bucket, this can be done using the riak search-cmd like this:
+You also need to have search enabled on the ´testsearch´ bucket, this can be done using the riak search-cmd like this:
 ```
 bin/search-cmd install testsearch
 ```
+
+##Documentation
+Generated documentation can be found at http://phpriak.bachpedersen.dk/docs  
+More documentation and examples can be found at http://phpriak.bachpedersen.dk/  
diff --git a/bucket.c b/bucket.c
deleted file mode 100644
index 6088500..0000000
--- a/bucket.c
+++ /dev/null
@@ -1,830 +0,0 @@
-/*
-   Copyright 2013 Trifork A/S
-   Author: Kaspar Bach Pedersen
-
-   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.
-*/
-
-#include <php.h>
-#include <riack.h>
-#include <ext/spl/spl_iterators.h>
-#include <ext/spl/spl_array.h>
-#include "php_riak.h"
-#include "bucket.h"
-#include "bucket_properties.h"
-#include "connection.h"
-#include "object.h"
-#include "exceptions.h"
-#include "req_inputs.h"
-#include "req_outputs.h"
-
-riak_connection *get_riak_connection(zval *zbucket TSRMLS_DC);
-
-zend_class_entry *riak_bucket_ce;
-
-#define RIAK_REQ_PROP_SET_LONG(CLASS_ALIAS, GETTER, TARGET) \
-    RIAK_CALL_METHOD(CLASS_ALIAS, GETTER, &ztmp, zinput); \
-    if (Z_TYPE(ztmp) == IS_LONG) { TARGET##_use = 1; TARGET = Z_LVAL(ztmp); }
-
-#define RIAK_REQ_PROP_SET_BOOL(CLASS_ALIAS, GETTER, TARGET) \
-    RIAK_CALL_METHOD(CLASS_ALIAS, GETTER, &ztmp, zinput); \
-    if (Z_TYPE(ztmp) == IS_BOOL && Z_BVAL(ztmp)) { TARGET##_use = TARGET = 1; }
-
-#define RIAK_GET_STR_COPY_TO(CLASSNAME, GETTER, ZOBJ, TARGET, TARGET_LEN) { \
-    zval *z_getter_res; MAKE_STD_ZVAL(z_getter_res); \
-    RIAK_CALL_METHOD(CLASSNAME, GETTER, z_getter_res, ZOBJ); \
-    if (Z_TYPE_P(z_getter_res) == IS_STRING && Z_STRLEN_P(z_getter_res) > 0) { \
-        RMALLOCCOPY(connection->client, TARGET, TARGET_LEN, Z_STRVAL_P(z_getter_res), Z_STRLEN_P(z_getter_res)); \
-    } \
-    zval_ptr_dtor(&z_getter_res); }
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_ctor, 0, ZEND_RETURN_VALUE, 2)
-    ZEND_ARG_INFO(0, client)
-    ZEND_ARG_INFO(0, name)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_put, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, object)
-    ZEND_ARG_INFO(0, key)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_get, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, key)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_delete, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, object)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_fetchprops, 0, ZEND_RETURN_VALUE, 0)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_applyprops, 0, ZEND_RETURN_VALUE, 1)
-	ZEND_ARG_INFO(0, bucket_properties)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_indexq, 0, ZEND_RETURN_VALUE, 2)
-    ZEND_ARG_INFO(0, index)
-    ZEND_ARG_INFO(0, from)
-    ZEND_ARG_INFO(0, to)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_streamkeys, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, keystreamer)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_bucket_noargs, 0, ZEND_RETURN_VALUE, 0)
-ZEND_END_ARG_INFO()
-
-static zend_function_entry riak_bucket_methods[] = {
-	PHP_ME(RiakBucket, __construct, arginfo_bucket_ctor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
-    PHP_ME(RiakBucket, put, arginfo_bucket_put, ZEND_ACC_PUBLIC)
-    PHP_ME(RiakBucket, get, arginfo_bucket_get, ZEND_ACC_PUBLIC)
-    PHP_ME(RiakBucket, delete, arginfo_bucket_delete, ZEND_ACC_PUBLIC)
-    PHP_ME(RiakBucket, index, arginfo_bucket_indexq, ZEND_ACC_PUBLIC)
-
-    PHP_ME(RiakBucket, getPropertyList, arginfo_bucket_fetchprops, ZEND_ACC_PUBLIC)
-    PHP_ME(RiakBucket, setPropertyList, arginfo_bucket_applyprops, ZEND_ACC_PUBLIC)
-    PHP_ME(RiakBucket, getKeyStream, arginfo_bucket_streamkeys, ZEND_ACC_PUBLIC)
-    PHP_ME(RiakBucket, getKeyList, arginfo_riak_bucket_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(RiakBucket, getName, arginfo_riak_bucket_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(RiakBucket, getConnection, arginfo_riak_bucket_noargs, ZEND_ACC_PUBLIC)
-	{NULL, NULL, NULL}
-};
-
-void riak_bucket_init(TSRMLS_D) /* {{{ */
-{
-	zend_class_entry ce;
-
-    INIT_NS_CLASS_ENTRY(ce, "Riak", "Bucket", riak_bucket_methods);
-	riak_bucket_ce = zend_register_internal_class(&ce TSRMLS_CC);
-
-    zend_declare_property_null(riak_bucket_ce, "name", sizeof("name")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_bucket_ce, "connection", sizeof("connection")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-}
-/* }}} */
-
-zval* create_bucket_object(zval* zclient, char* name, int name_len TSRMLS_DC) /* {{{ */
-{
-	zval *zbucket, *zname;
-	MAKE_STD_ZVAL(zbucket);
-	MAKE_STD_ZVAL(zname);
-
-    ZVAL_STRINGL(zname, name, name_len, 1);
-
-	object_init_ex(zbucket, riak_bucket_ce);
-	RIAK_CALL_METHOD2(RiakBucket, __construct, zbucket, zbucket, zclient, zname);
-
-	zval_ptr_dtor(&zname);
-	return zbucket;
-}
-/* }}} */
-
-/* {{{ proto void Riak\Bucket->__construct(Riak\Connection $connection, string $name)
-Create a new Riak\Bucket */
-PHP_METHOD(RiakBucket, __construct)
-{
-	char *name;
-	int nameLen;
-    zval* zconnection;
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os", &zconnection, riak_connection_ce, &name, &nameLen) == FAILURE) {
-        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
-		return;
-	}
-	zend_update_property_stringl(riak_bucket_ce, getThis(), "name", sizeof("name")-1, name, nameLen TSRMLS_CC);
-    zend_update_property(riak_bucket_ce, getThis(), "connection", sizeof("connection")-1, zconnection TSRMLS_CC);
-}
-/* }}} */
-
-struct riak_stream_key_cb_param {/* {{{ */
-#ifdef ZTS
-    TSRMLS_D;
-#endif
-    zval *zstreamer;
-};
-/* }}} */
-
-void riak_stream_key_cb(struct RIACK_CLIENT* c, void* p, RIACK_STRING key) {/* {{{ */
-    zval *zkey, zret, zfuncname;
-
-    struct riak_stream_key_cb_param *param = (struct riak_stream_key_cb_param*)p;
-    MAKE_STD_ZVAL(zkey);
-    ZVAL_STRINGL(zkey, key.value, key.len, 1);
-    ZVAL_STRING(&zfuncname, "process", 0);
-#ifdef ZTS
-    call_user_function(NULL, &param->zstreamer, &zfuncname, &zret, 1, &zkey, param->tsrm_ls);
-#else
-    call_user_function(NULL, &param->zstreamer, &zfuncname, &zret, 1, &zkey);
-#endif
-
-    zval_ptr_dtor(&zkey);
-}
-/* }}} */
-
-/* {{{ proto void Riak\Bucket->getKeyStream(Riak\Output\KeyStreamOutput streamer)
-Streams all keys in the bucket */
-PHP_METHOD(RiakBucket, getKeyStream)
-{
-    struct riak_stream_key_cb_param cb_params;
-    RIACK_STRING rsbucket;
-    riak_connection *connection;
-    zval* zstreamer;
-    int riackstatus;
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zstreamer) == FAILURE) {
-        return;
-    }
-    connection = get_riak_connection(getThis() TSRMLS_CC);
-    rsbucket = riack_name_from_bucket(getThis() TSRMLS_CC);
-#ifdef ZTS
-    cb_params.tsrm_ls = TSRMLS_C;
-#endif
-    cb_params.zstreamer = zstreamer;
-    riackstatus = riack_stream_keys(connection->client, rsbucket, riak_stream_key_cb, &cb_params);
-    CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, riackstatus);
-}
-/* }}} */
-
-
-/* {{{ proto string[] Riak\Bucket->getKeyList()
-List all keys in the bucket */
-PHP_METHOD(RiakBucket, getKeyList)
-{
-    struct RIACK_STRING_LINKED_LIST* resultlist, *curr;
-    RIACK_STRING rsbucket;
-    riak_connection *connection;
-    zval* zresultarr;
-    int riackstatus;
-    connection = get_riak_connection(getThis() TSRMLS_CC);
-    rsbucket = riack_name_from_bucket(getThis() TSRMLS_CC);
-    riackstatus = riack_list_keys(connection->client, rsbucket, &resultlist);
-    CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, riackstatus);
-
-    MAKE_STD_ZVAL(zresultarr);
-    array_init(zresultarr);
-    curr = resultlist;
-    while (curr) {
-        add_next_index_stringl(zresultarr, curr->string.value, curr->string.len, 1);
-        curr = curr->next;
-    }
-    riack_free_string_linked_list(connection->client, &resultlist);
-
-    RETURN_ZVAL(zresultarr, 0, 1);
-}
-/* }}} */
-
-
-/* {{{ proto array Riak\Bucket->index(string $index, string $from [, string $to])
-Apply given properties to this bucket */
-PHP_METHOD(RiakBucket, index)
-{
-    RIACK_STRING rsbucket, rsindex, rsfrom, rsto;
-    RIACK_STRING_LIST resultlist;
-    char *index, *from, *to;
-    int indexlen, fromlen, tolen, riackstatus, i;
-    riak_connection *connection;
-    zval *zresult;
-    tolen = 0; to = NULL;
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|s", &index, &indexlen, &from, &fromlen, &to, &tolen) == FAILURE) {
-        return;
-    }
-    connection = get_riak_connection(getThis() TSRMLS_CC);
-    rsbucket = riack_name_from_bucket(getThis() TSRMLS_CC);
-
-    rsindex.len = indexlen;
-    rsindex.value = index;
-    rsfrom.len = fromlen;
-    rsfrom.value = from;
-    if (to != NULL && tolen > 0) {
-        rsto.len = tolen;
-        rsto.value = to;
-        riackstatus = riack_2i_query_range(connection->client, rsbucket, rsindex, rsfrom, rsto, &resultlist);
-    } else {
-        riackstatus = riack_2i_query_exact(connection->client, rsbucket, rsindex, rsfrom, &resultlist);
-    }
-    CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, riackstatus);
-
-    MAKE_STD_ZVAL(zresult);
-    array_init(zresult);
-    for (i=0; i<resultlist.string_count; ++i) {
-        add_next_index_stringl(zresult, resultlist.strings[i].value, resultlist.strings[i].len, 1);
-    }
-    riack_free_string_list(connection->client, &resultlist);
-    RETURN_ZVAL(zresult, 0, 1);
-}
-/* }}} */
-
-/* {{{ */
-void riak_set_riack_commit_hook(riak_connection *connection, zval* zhook, struct RIACK_COMMIT_HOOK* hook TSRMLS_DC)
-{
-    zval *zjs;
-    memset(hook, 0, sizeof(struct RIACK_COMMIT_HOOK));
-    MAKE_STD_ZVAL(zjs);
-    RIAK_CALL_METHOD(RiakCommitHook, isJavascript, zjs, zhook);
-    if (Z_BVAL_P(zjs)) {
-        RIAK_GET_STR_COPY_TO(RiakCommitHook, getJsName, zhook, hook->name.value, hook->name.len);
-    } else {
-        RIAK_GET_STR_COPY_TO(RiakCommitHook, getErlModule, zhook, hook->modfun.module.value, hook->modfun.module.len);
-        RIAK_GET_STR_COPY_TO(RiakCommitHook, getErlFunction, zhook, hook->modfun.function.value, hook->modfun.function.len);
-    }
-    zval_ptr_dtor(&zjs);
-}
-/* }}} */
-
-/* {{{ */
-void riak_set_commit_hooks_properties(riak_connection *connection, zval *zhook_list,  uint8_t *has_hooks,
-                                      size_t* hook_count, struct RIACK_COMMIT_HOOK** hooks TSRMLS_DC)
-{
-    *has_hooks = 0;
-    *hook_count = 0;
-    if (Z_TYPE_P(zhook_list) != IS_NULL && Z_TYPE_P(zhook_list) == IS_OBJECT) {
-        zval *ziter, *zcount;
-        MAKE_STD_ZVAL(zcount);
-        RIAK_CALL_METHOD(RiakCommitHookList, count, zcount, zhook_list);
-
-        MAKE_STD_ZVAL(ziter);
-        object_init(ziter);
-        RIAK_CALL_METHOD(RiakCommitHookList, getIterator, ziter, zhook_list);
-        if (Z_TYPE_P(zcount) == IS_LONG && Z_TYPE_P(ziter) == IS_OBJECT) {
-            zval *zhook, zcurrname, znextname;
-            zend_bool done;
-            int i=0;
-            *has_hooks = 1;
-            *hook_count = Z_LVAL_P(zcount);
-            *hooks = RMALLOC(connection->client, sizeof(struct RIACK_COMMIT_HOOK) * Z_LVAL_P(zcount));
-
-            ZVAL_STRING(&zcurrname, "current", 0);
-            ZVAL_STRING(&znextname, "next", 0);
-            done = 0;
-            while (!done) {
-                MAKE_STD_ZVAL(zhook);
-                call_user_function(NULL, &ziter, &zcurrname, zhook, 0, NULL TSRMLS_CC);
-                if (Z_TYPE_P(zhook) == IS_OBJECT) {
-                    zval zret;
-                    riak_set_riack_commit_hook(connection, zhook, &((*hooks)[i++]) TSRMLS_CC);
-                    call_user_function(NULL, &ziter, &znextname, &zret, 0, NULL TSRMLS_CC);
-                } else {
-                    done = 1;
-                }
-                zval_ptr_dtor(&zhook);
-            }
-        }
-        zval_ptr_dtor(&ziter);
-        zval_ptr_dtor(&zcount);
-    }
-}
-/* }}} */
-
-/* {{{ proto Riak\Bucket Riak\Bucket->setPropertyList(Riak\BucketProperties $properties)
-Apply given properties to this bucket */
-PHP_METHOD(RiakBucket, setPropertyList)
-{
-#define SET_PROPLIST_LONG(GETTER_NAME, PROP_NAME) MAKE_STD_ZVAL(ztmp); \
-                                                  RIAK_CALL_METHOD(RiakBucketProperties, GETTER_NAME, ztmp, zprop_obj); \
-                                                  if (Z_TYPE_P(ztmp) == IS_LONG) { \
-                                                      properties.PROP_NAME##_use = 1; \
-                                                      properties.PROP_NAME = Z_LVAL_P(ztmp); } \
-                                                  zval_ptr_dtor(&ztmp);
-#define SET_PROPLIST_BOOL(GETTER_NAME, PROP_NAME) MAKE_STD_ZVAL(ztmp); \
-                                                  RIAK_CALL_METHOD(RiakBucketProperties, GETTER_NAME, ztmp, zprop_obj); \
-                                                  if (Z_TYPE_P(ztmp) == IS_BOOL) { \
-                                                      properties.PROP_NAME##_use = 1; \
-                                                      properties.PROP_NAME = Z_BVAL_P(ztmp); } \
-                                                  zval_ptr_dtor(&ztmp);
-	riak_connection *connection;
-    struct RIACK_BUCKET_PROPERTIES properties;
-	RIACK_STRING bucketName;
-    zval *ztmp, *zprop_obj;
-	int riackResult;
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zprop_obj, riak_bucket_properties_ce) == FAILURE) {
-        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 501 TSRMLS_CC);
-		return;
-	}
-    memset(&properties, 0, sizeof(struct RIACK_BUCKET_PROPERTIES));
-
-    connection = get_riak_connection(getThis() TSRMLS_CC);
-    bucketName = riack_name_from_bucket(getThis() TSRMLS_CC);
-
-    SET_PROPLIST_LONG(getNValue, n_val);
-    SET_PROPLIST_BOOL(getAllowMult, allow_mult);
-
-    // 1.4+ below
-    SET_PROPLIST_BOOL(getLastWriteWins, last_write_wins);
-    SET_PROPLIST_LONG(getOldVClock, old_vclock);
-    SET_PROPLIST_LONG(getYoungVClock, young_vclock);
-    SET_PROPLIST_LONG(getSmallVClock, small_vclock);
-    SET_PROPLIST_LONG(getBigVClock, big_vclock);
-
-    SET_PROPLIST_LONG(getPR, pr);
-    SET_PROPLIST_LONG(getR, r);
-    SET_PROPLIST_LONG(getW, w);
-    SET_PROPLIST_LONG(getDW, dw);
-    SET_PROPLIST_LONG(getPW, pw);
-    SET_PROPLIST_LONG(getRW, rw);
-
-    SET_PROPLIST_BOOL(getBasicQuorum, basic_quorum);
-    SET_PROPLIST_BOOL(getNotFoundOk, notfound_ok);
-
-    SET_PROPLIST_BOOL(getSearchEnabled, search);
-
-    RIAK_GET_STR_COPY_TO(RiakBucketProperties, getBackend, zprop_obj, properties.backend.value, properties.backend.len);
-
-    MAKE_STD_ZVAL(ztmp);
-    RIAK_CALL_METHOD(RiakBucketProperties, getLinkFun, ztmp, zprop_obj);
-    if (Z_TYPE_P(ztmp) == IS_OBJECT) {
-        properties.linkfun_use = 1;
-        RIAK_GET_STR_COPY_TO(RiakModuleFunction, getFunction, ztmp,
-                             properties.linkfun.function.value, properties.linkfun.function.len);
-        RIAK_GET_STR_COPY_TO(RiakModuleFunction, getModule, ztmp,
-                             properties.linkfun.module.value, properties.linkfun.module.len);
-    }
-    zval_ptr_dtor(&ztmp);
-    MAKE_STD_ZVAL(ztmp);
-    RIAK_CALL_METHOD(RiakBucketProperties, getCHashKeyFun, ztmp, zprop_obj);
-    if (Z_TYPE_P(ztmp) == IS_OBJECT) {
-        properties.chash_keyfun_use = 1;
-        RIAK_GET_STR_COPY_TO(RiakModuleFunction, getFunction, ztmp,
-                             properties.chash_keyfun.function.value, properties.chash_keyfun.function.len);
-        RIAK_GET_STR_COPY_TO(RiakModuleFunction, getModule, ztmp,
-                             properties.chash_keyfun.module.value, properties.chash_keyfun.module.len);
-    }
-    zval_ptr_dtor(&ztmp);
-
-    MAKE_STD_ZVAL(ztmp);
-    RIAK_CALL_METHOD(RiakBucketProperties, getPreCommitHookList, ztmp, zprop_obj);
-    riak_set_commit_hooks_properties(connection, ztmp, &properties.has_precommit_hooks, &properties.precommit_hook_count,
-                                     &properties.precommit_hooks TSRMLS_CC);
-    zval_ptr_dtor(&ztmp);
-    MAKE_STD_ZVAL(ztmp);
-    RIAK_CALL_METHOD(RiakBucketProperties, getPostCommitHookList, ztmp, zprop_obj);
-    riak_set_commit_hooks_properties(connection, ztmp, &properties.has_postcommit_hooks, &properties.postcommit_hook_count,
-                                     &properties.postcommit_hooks TSRMLS_CC);
-    zval_ptr_dtor(&ztmp);
-
-    riackResult = riack_set_bucket_props_ext(connection->client, bucketName, &properties);
-
-    RSTR_SAFE_FREE(connection->client, properties.backend);
-    RSTR_SAFE_FREE(connection->client, properties.linkfun.module);
-    RSTR_SAFE_FREE(connection->client, properties.linkfun.function);
-    RSTR_SAFE_FREE(connection->client, properties.chash_keyfun.module);
-    RSTR_SAFE_FREE(connection->client, properties.chash_keyfun.function);
-    RFREE(connection->client, properties.precommit_hooks);
-    RFREE(connection->client, properties.postcommit_hooks);
- 	CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, riackResult);
-
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-zval *riak_linkfun_from_riack(struct RIACK_MODULE_FUNCTION* modfun TSRMLS_DC) {
-    zval *zmodfun, *zmod, *zfunc;
-    MAKE_STD_ZVAL(zmodfun);
-
-    MAKE_STD_ZVAL(zmod);
-    ZVAL_STRINGL(zmod, modfun->module.value, modfun->module.len, 1);
-
-    MAKE_STD_ZVAL(zfunc);
-    ZVAL_STRINGL(zfunc, modfun->function.value, modfun->function.len, 1);
-
-    object_init_ex(zmodfun, riak_module_function_ce);
-    RIAK_CALL_METHOD2(RiakModuleFunction, __construct, NULL, zmodfun, zmod, zfunc)
-
-    zval_ptr_dtor(&zmod);
-    zval_ptr_dtor(&zfunc);
-    return zmodfun;
-}
-
-/* {{{ */
-zval* zhook_list_from_riack(size_t hook_count, struct RIACK_COMMIT_HOOK* hooks TSRMLS_DC)
-{
-    zval *zhook_list;
-    size_t i;
-    MAKE_STD_ZVAL(zhook_list);
-    object_init_ex(zhook_list, riak_commit_hook_list_ce);
-    RIAK_CALL_METHOD(RiakCommitHookList, __construct, zhook_list, zhook_list);
-    for (i=0; i<hook_count; ++i) {
-        struct RIACK_COMMIT_HOOK* current_hook;
-        zval* zhook, *zoffset;
-        current_hook = &hooks[i];
-
-        // Create hook
-        MAKE_STD_ZVAL(zhook);
-        object_init_ex(zhook, riak_commit_hook_ce);
-
-        if (RSTR_HAS_CONTENT(current_hook->name)) {
-            zval *zname;
-            // We have name so this is a js function
-            MAKE_STD_ZVAL(zname);
-            ZVAL_STRINGL(zname, current_hook->name.value, current_hook->name.len, 1);
-            RIAK_CALL_METHOD1(RiakCommitHook, __construct, zhook, zhook, zname);
-            zval_ptr_dtor(&zname);
-        } else {
-            zval *zmod, *zfun;
-            // No name present, so must be mod/fun
-            MAKE_STD_ZVAL(zfun);
-            MAKE_STD_ZVAL(zmod);
-            ZVAL_STRINGL(zfun, current_hook->modfun.function.value, current_hook->modfun.function.len, 1);
-            ZVAL_STRINGL(zmod, current_hook->modfun.module.value, current_hook->modfun.module.len, 1);
-            RIAK_CALL_METHOD2(RiakCommitHook, __construct, zhook, zhook, zmod, zfun);
-            zval_ptr_dtor(&zfun);
-            zval_ptr_dtor(&zmod);
-        }
-        MAKE_STD_ZVAL(zoffset);
-        ZVAL_LONG(zoffset, i);
-        RIAK_CALL_METHOD2(RiakCommitHookList, offsetSet, NULL, zhook_list, zoffset, zhook);
-        zval_ptr_dtor(&zoffset);
-        zval_ptr_dtor(&zhook);
-    }
-    return zhook_list;
-}/* }}} */
-
-/* {{{ proto Riak\BucketPropertyList Riak\Bucket->getPropertyList()
-Fetch and return a RiakBucketProperties object with properties for this bucket */
-PHP_METHOD(RiakBucket, getPropertyList)
-{
-#define GET_PROP_SET_ON_LIST(ZVAL_METHOD, SETTER_NAME, PROP_NAME) if (PROP_NAME##_use) { \
-                                                        MAKE_STD_ZVAL(ztmp); \
-                                                        ZVAL_METHOD(ztmp, PROP_NAME); \
-                                                        RIAK_CALL_METHOD1(RiakBucketProperties, SETTER_NAME, zbucket_props, zbucket_props, ztmp); \
-                                                        zval_ptr_dtor(&ztmp); }
-    struct RIACK_BUCKET_PROPERTIES *properties;
-	riak_connection *connection;
-    RIACK_STRING bucketName;
-    int riackResult;
-    zval *ztmp, *zbucket_props;
-
-    connection = get_riak_connection(getThis() TSRMLS_CC);
-    bucketName = riack_name_from_bucket(getThis() TSRMLS_CC);
-
-    riackResult = riack_get_bucket_props_ext(connection->client,  bucketName, &properties);
-	CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, riackResult);
-
-    MAKE_STD_ZVAL(zbucket_props);
-    object_init_ex(zbucket_props, riak_bucket_properties_ce);
-    RIAK_CALL_METHOD(RiakBucketProperties, __construct, NULL, zbucket_props);
-
-    GET_PROP_SET_ON_LIST(ZVAL_LONG, setNValue, properties->n_val);
-    GET_PROP_SET_ON_LIST(ZVAL_BOOL, setAllowMult, properties->allow_mult);
-    GET_PROP_SET_ON_LIST(ZVAL_BOOL, setLastWriteWins, properties->last_write_wins);
-    GET_PROP_SET_ON_LIST(ZVAL_LONG, setOldVClock, properties->old_vclock);
-    GET_PROP_SET_ON_LIST(ZVAL_LONG, setYoungVClock, properties->young_vclock);
-    GET_PROP_SET_ON_LIST(ZVAL_LONG, setSmallVClock, properties->small_vclock);
-    GET_PROP_SET_ON_LIST(ZVAL_LONG, setBigVClock, properties->big_vclock);
-
-    GET_PROP_SET_ON_LIST(ZVAL_LONG, setR, properties->r);
-    GET_PROP_SET_ON_LIST(ZVAL_LONG, setPR, properties->pr);
-    GET_PROP_SET_ON_LIST(ZVAL_LONG, setW, properties->w);
-    GET_PROP_SET_ON_LIST(ZVAL_LONG, setDW, properties->dw);
-    GET_PROP_SET_ON_LIST(ZVAL_LONG, setPW, properties->pw);
-    GET_PROP_SET_ON_LIST(ZVAL_LONG, setRW, properties->rw);
-
-    GET_PROP_SET_ON_LIST(ZVAL_BOOL, setBasicQuorum, properties->basic_quorum);
-    GET_PROP_SET_ON_LIST(ZVAL_BOOL, setNotFoundOk, properties->notfound_ok);
-    GET_PROP_SET_ON_LIST(ZVAL_BOOL, setSearchEnabled, properties->search);
-    if (RSTR_HAS_CONTENT(properties->backend)) {
-        MAKE_STD_ZVAL(ztmp);
-        ZVAL_STRINGL(ztmp, properties->backend.value, properties->backend.len, 1);
-        RIAK_CALL_METHOD1(RiakBucketProperties, setBackend, zbucket_props, zbucket_props, ztmp);
-        zval_ptr_dtor(&ztmp);
-    }
-    if (properties->linkfun_use) {
-        ztmp = riak_linkfun_from_riack(&properties->linkfun TSRMLS_CC);
-        RIAK_CALL_METHOD1(RiakBucketProperties, setLinkFun, zbucket_props, zbucket_props, ztmp);
-        zval_ptr_dtor(&ztmp);
-    }
-    if (properties->chash_keyfun_use) {
-        ztmp = riak_linkfun_from_riack(&properties->chash_keyfun TSRMLS_CC);
-        RIAK_CALL_METHOD1(RiakBucketProperties, setCHashKeyFun, zbucket_props, zbucket_props, ztmp);
-        zval_ptr_dtor(&ztmp);
-    }
-    if (properties->has_precommit_hooks) {
-        zval *zhook_list;
-        zhook_list = zhook_list_from_riack(properties->precommit_hook_count, properties->precommit_hooks TSRMLS_CC);
-        RIAK_CALL_METHOD1(RiakBucketProperties, setPreCommitHookList, zbucket_props, zbucket_props, zhook_list);
-        zval_ptr_dtor(&zhook_list);
-    }
-    if (properties->has_postcommit_hooks) {
-        zval *zhook_list;
-        zhook_list = zhook_list_from_riack(properties->postcommit_hook_count, properties->postcommit_hooks TSRMLS_CC);
-        RIAK_CALL_METHOD1(RiakBucketProperties, setPostCommitHookList, zbucket_props, zbucket_props, zhook_list);
-        zval_ptr_dtor(&zhook_list);
-    }
-    riack_free_bucket_properties(connection->client, &properties);
-    RETURN_ZVAL(zbucket_props, 0, 1);
-}
-/* }}} */
-
-/* {{{ proto void RiakBucket->delete(RiakObject|string $object)
-Deletes given object from riak */
-PHP_METHOD(RiakBucket, delete)
-{
-	struct RIACK_DEL_PROPERTIES props;
-	riak_connection *connection;
-    zval *zparam, *zTmp, *zinput;
-	RIACK_STRING bucketName, key;
-	int riackResult;
-    zinput = NULL;
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|o", &zparam, &zinput) == FAILURE) {
-		return;
-	}
-    memset(&props, 0, sizeof(props));
-    connection = get_riak_connection(getThis() TSRMLS_CC);
-
-    /* Set bucket name */
-    bucketName = riack_name_from_bucket(getThis() TSRMLS_CC);
-    if (Z_TYPE_P(zparam) == IS_STRING) {
-        key.len = Z_STRLEN_P(zparam);
-        key.value = Z_STRVAL_P(zparam);
-    } else {
-        /* If zparam is not a string it should be a RiakObject, get the key from the object. */
-        GET_PROPERTY_INTO_RIACK_STR_OR_ELSE(riak_object_ce, zparam, "key", zTmp, key) {
-            zend_throw_exception(riak_badarguments_exception_ce, "key missing from object", 5001 TSRMLS_CC);
-            return;
-        }
-    }
-
-    if (zinput != NULL && Z_TYPE_P(zinput) == IS_OBJECT) {
-        zval ztmp;
-        RIAK_REQ_PROP_SET_LONG(Riak_Input_DeleteInput, getR, props.r);
-        RIAK_REQ_PROP_SET_LONG(Riak_Input_DeleteInput, getPR, props.pr);
-        RIAK_REQ_PROP_SET_LONG(Riak_Input_DeleteInput, getRW, props.rw);
-        RIAK_REQ_PROP_SET_LONG(Riak_Input_DeleteInput, getW, props.w);
-        RIAK_REQ_PROP_SET_LONG(Riak_Input_DeleteInput, getDW, props.dw);
-        RIAK_REQ_PROP_SET_LONG(Riak_Input_DeleteInput, getPW, props.pw);
-        RIAK_CALL_METHOD(Riak_Input_DeleteInput, getVClock, &ztmp, zinput);
-        if (Z_TYPE(ztmp) == IS_STRING) {
-            RMALLOCCOPY(connection->client, props.vclock.clock, props.vclock.len, Z_STRVAL(ztmp), Z_STRLEN(ztmp));
-            zval_dtor(&ztmp);
-        }
-    }
-	riackResult = riack_delete(connection->client, bucketName, key, &props);
-    if (props.vclock.clock) {
-        RFREE(connection->client, props.vclock.clock);
-    }
-	CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, riackResult);
-}
-/* }}} */
-
-/* {{{ proto Riak\Output\PutOutput Riak\Bucket->put(Riak\Object $object [, RiakPutRequestConfiguration $configuration])
-Store a RiakObject in riak, if something goes wrong an RiakException is thrown */
-PHP_METHOD(RiakBucket, put)
-{
-    int riackResult;
-    zval *zObject, *zTmp, *zinput, *zout;
-	struct RIACK_OBJECT obj, returnedObj;
-	struct RIACK_CONTENT riackContent;
-	struct RIACK_PUT_PROPERTIES props;
-	riak_connection *connection;
-    long options;
-
-    options = 0;
-    zinput = NULL;
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|o", &zObject, &zinput) == FAILURE) {
-		return;
-	}
-    connection = get_riak_connection(getThis() TSRMLS_CC);
-
-	memset(&obj, 0, sizeof(obj));
-	memset(&returnedObj, 0, sizeof(returnedObj));
-	memset(&riackContent, 0, sizeof(riackContent));
-    memset(&props, 0, sizeof(props));
-    /* fill content */
-    set_riak_content_from_object(&riackContent, zObject, connection->client TSRMLS_CC);
-
-    if (zinput != NULL && Z_TYPE_P(zinput) == IS_OBJECT) {
-        zval ztmp;
-        RIAK_REQ_PROP_SET_BOOL(Riak_Input_PutInput, getReturnHead, props.return_head);
-        RIAK_REQ_PROP_SET_BOOL(Riak_Input_PutInput, getReturnBody, props.return_body);
-        RIAK_REQ_PROP_SET_BOOL(Riak_Input_PutInput, getIfNotModified, props.if_not_modified);
-        RIAK_REQ_PROP_SET_BOOL(Riak_Input_PutInput, getIfNoneMatch, props.if_none_match);
-        RIAK_REQ_PROP_SET_LONG(Riak_Input_PutInput, getW, props.w);
-        RIAK_REQ_PROP_SET_LONG(Riak_Input_PutInput, getDW, props.dw);
-        RIAK_REQ_PROP_SET_LONG(Riak_Input_PutInput, getPW, props.pw);
-        RIAK_CALL_METHOD(Riak_Input_PutInput, getVClock, &ztmp, zinput);
-        if (Z_TYPE(ztmp) == IS_STRING) {
-            RMALLOCCOPY(connection->client, obj.vclock.clock, obj.vclock.len, Z_STRVAL(ztmp), Z_STRLEN(ztmp));
-            zval_dtor(&ztmp);
-        }
-    }
-    /* Set bucket name */
-    obj.bucket = riack_name_from_bucket(getThis() TSRMLS_CC);
-	obj.content_count = 1;
-	obj.content = &riackContent;
-    /* No ket provided on function call, get it from RiakObject */
-    GET_PROPERTY_INTO_RIACK_STR_OR_ELSE(riak_object_ce, zObject, "key", zTmp, obj.key) {
-        // Key is null this is ok
-        obj.key.len = 0;
-        obj.key.value = 0;
-    }
-	riackResult = riack_put(connection->client, obj, &returnedObj, &props);
-    if (obj.vclock.clock) {
-        RFREE(connection->client, obj.vclock.clock);
-    }
-	CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, riackResult);
-
-    // Now make put output from the response
-    MAKE_STD_ZVAL(zTmp);
-    if (returnedObj.key.len > 0) {
-        ZVAL_STRINGL(zTmp, (char*)returnedObj.key.value, returnedObj.key.len, 1);
-    } else {
-        ZVAL_NULL(zTmp);
-    }
-    zout = put_output_from_riack_object(&returnedObj, zTmp TSRMLS_CC);
-    RETVAL_ZVAL(zout, 0, 1);
-
-    zval_ptr_dtor(&zTmp);
-    riack_free_object(connection->client, &returnedObj);
-}
-/* }}} */
-
-/* {{{ proto Output\GetOutput Riak\Bucket->get(string $key [, Riak\Input\GetInput $input])
-Get value from riak */
-PHP_METHOD(RiakBucket, get)
-{
-	char *key;
-    int keyLen, riackResult;
-	size_t contentCount;
-    zval *zKey, *zinput;
-	struct RIACK_GET_PROPERTIES props;
-	struct RIACK_GET_OBJECT getResult;
-	RIACK_STRING rsBucket, rsKey;
-	riak_connection *connection;
-	
-    zinput = NULL;
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|o", &key, &keyLen, &zinput) == FAILURE) {
-		return;
-    }
-    connection = get_riak_connection(getThis() TSRMLS_CC);
-
-	MAKE_STD_ZVAL(zKey);
-	ZVAL_STRINGL(zKey, key, keyLen, 1);
-	memset(&props, 0, sizeof(props));
-    memset(&getResult, 0, sizeof(getResult));
-    if (zinput != NULL && Z_TYPE_P(zinput) == IS_OBJECT) {
-        zval ztmp;
-        RIAK_REQ_PROP_SET_BOOL(Riak_Input_GetInput, getReturnHead, props.head);
-        RIAK_REQ_PROP_SET_LONG(Riak_Input_GetInput, getR, props.r);
-        RIAK_REQ_PROP_SET_LONG(Riak_Input_GetInput, getPR, props.pr);
-        RIAK_REQ_PROP_SET_BOOL(Riak_Input_GetInput, getBasicQuorum, props.basic_quorum);
-        RIAK_REQ_PROP_SET_BOOL(Riak_Input_GetInput, getNotFoundOk, props.notfound_ok);
-        RIAK_REQ_PROP_SET_BOOL(Riak_Input_GetInput, getReturnDeletedVClock, props.deletedvclock);
-        RIAK_CALL_METHOD(Riak_Input_GetInput, getIfModifiedVClock, &ztmp, zinput);
-        if (Z_TYPE(ztmp) == IS_STRING) {
-            props.if_modified_use = 1;
-            RMALLOCCOPY(connection->client, props.if_modified.clock, props.if_modified.len, Z_STRVAL(ztmp), Z_STRLEN(ztmp));
-            zval_dtor(&ztmp);
-        }
-    }
-
-    rsBucket = riack_name_from_bucket(getThis() TSRMLS_CC);
-	rsKey.len = keyLen;
-	rsKey.value = key;
-	riackResult = riack_get(connection->client, rsBucket, rsKey, &props, &getResult);
-    if (props.if_modified.clock) {
-        RFREE(connection->client, props.if_modified.clock);
-    }
-    if (riackResult == RIACK_SUCCESS) {
-        contentCount = getResult.object.content_count;
-        if (contentCount > 0) {
-            zval *zout = get_output_from_riack_get_object(&getResult, zKey TSRMLS_CC);
-            RETVAL_ZVAL(zout, 0, 1);
-		} else {
-            // Hack warning!!
-            // Work around for session module, when session.auto_start is enabled read is called before a stackframe has been setup
-            // in that case we cannot throw exception without halting execution, return null instead.
-            if (!EG(current_execute_data)) {
-                // No stack dont throw
-                RETVAL_NULL();
-            } else {
-                /* Throw not found exception */
-                zend_throw_exception(riak_not_found_exception_ce, "Not Found", 2000 TSRMLS_CC);
-            }
-        }
-		riack_free_get_object(connection->client, &getResult);
-    } else {
-        connection->needs_reconnect = 1;
-        // Hack warning, same as above
-        if (!EG(current_execute_data)) {
-            // No stack dont throw
-            RETVAL_NULL();
-        } else {
-            riak_throw_exception(connection->client,  riackResult TSRMLS_CC);
-        }
-	}
-    zval_ptr_dtor(&zKey);
-}
-/* }}} */
-
-/* {{{ proto string Riak\Bucket->getName()
-Get bucket name */
-PHP_METHOD(RiakBucket, getName)
-{
-    RIAK_GETTER_STRING(riak_object_ce, "name");
-}
-/* }}} */
-
-/* {{{ proto string Riak\Bucket->getConnection() */
-PHP_METHOD(RiakBucket, getConnection)
-{
-    RIAK_GETTER_OBJECT(riak_object_ce, "connection");
-}
-/* }}} */
-
-zval* object_from_riak_content(zval* key, struct RIACK_CONTENT* content TSRMLS_DC)/* {{{ */
-{
-	zval *object;
-	MAKE_STD_ZVAL(object);
-	object_init_ex(object, riak_object_ce);
-	RIAK_CALL_METHOD1(RiakObject, __construct, object, object, key);
-
-	set_object_from_riak_content(object, content TSRMLS_CC);
-
-	return object;
-}
-/* }}} */
-
-void riak_name_from_bucket(zval* bucket, char **name, int *namelen TSRMLS_DC)/* {{{ */
-{
-    zval *zname = zend_read_property(riak_bucket_ce, bucket, "name", sizeof("name")-1, 1 TSRMLS_CC);
-    if (Z_TYPE_P(zname) == IS_STRING) {
-        *name = Z_STRVAL_P(zname);
-        *namelen = Z_STRLEN_P(zname);
-    } else {
-        *name = NULL;
-        *namelen = 0;
-    }
-}
-/* }}} */
-
-RIACK_STRING riack_name_from_bucket(zval* bucket TSRMLS_DC)/* {{{ */
-{
-    RIACK_STRING bucketName;
-    int namelen;
-    riak_name_from_bucket(bucket, &bucketName.value, &namelen TSRMLS_CC);
-    bucketName.len = namelen;
-    return bucketName;
-}
-/* }}} */
-
-riak_connection *get_riak_connection(zval *zbucket TSRMLS_DC)/* {{{ */
-{
-    zval *zclient;
-    riak_connection *connection = NULL;
-    zclient = zend_read_property(riak_bucket_ce, zbucket, "connection", sizeof("connection")-1, 1 TSRMLS_CC);
-    if (zclient) {
-        GET_RIAK_CONNECTION(zclient, connection);
-		ensure_connected(connection TSRMLS_CC);
-    }
-	return connection;
-}
-/* }}} */
-
diff --git a/config.m4 b/config.m4
index d7333c2..ede1e4a 100644
--- a/config.m4
+++ b/config.m4
@@ -1,56 +1,114 @@
 dnl lines starting with "dnl" are comments
 
 PHP_ARG_ENABLE(riak, whether to enable Riak extension, [  --enable-riak   Enable Riak extension])
-
+PHP_ARG_ENABLE(riak-session, whether to enable riak sessions, [ --disable-riak-session Disable riak session support], yes, no)
 if test "$PHP_RIAK" != "no"; then
-
-  AC_DEFINE(PHP_SESSION,1,[riak session])
+  if test "$PHP_RIAK_SESSION" != "no"; then
+    AC_DEFINE(PHP_RIAK_SESSION,1,[riak session])
+  fi
 
   dnl this defines the extension
   PHP_NEW_EXTENSION(riak, php_riak.c \
-    connection.c \
-    bucket.c \
-    object.c \
-    exceptions.c \
-    bucket_properties.c \
-    pool.c \
-    link.c \
-    pool_info.c \
-    riak_session.c \
-    mapreduce.c \
-    mr_phase.c \
-    mr_functions.c \
-    mr_inputs.c \
-    mr_output.c \
     ht_utils.c \
-    search.c \
-    streaming.c \
-    req_inputs.c \
-    req_outputs.c \
-    riack/src/riack_sock.c \
-    riack/src/riack.c \
-    riack/src/riack_kv.c \
-    riack/src/riack_search.c \
-    riack/src/riack_msg.c \
-    riack/src/riack_mem.c \
-    riack/src/riack_helpers.c \
-    riack/src/protocol/riak_msg_codes.c \
-    riack/src/protocol/riak_search.pb-c.c \
-    riack/src/protocol/riak.pb-c.c \
-    riack/src/protocol/riak_kv.pb-c.c \
-    riack/src/google/protobuf-c/protobuf-c.c, $ext_shared)
+    riak_session.c \
+    riak/bucket.c \
+    riak/connection.c \
+    riak/object.c \
+    riak/exception/exception.c \
+    riak/bucket_properties.c \
+    riak/pool.c \
+    riak/link.c \
+    riak/pool_info.c \
+    riak/server_info.c \
+    riak/object_list.c \
+    riak/crdt/counter.c \
+    riak/crdt/input/get_input.c \
+    riak/crdt/input/update_input.c \
+    riak/input/input.c \
+    riak/input/delete_input.c \
+    riak/input/get_input.c \
+    riak/input/get_resolver_input.c \
+    riak/input/put_input.c \
+    riak/input/index_input.c \
+    riak/query/index_query.c \
+    riak/output/output.c \
+    riak/output/get_output.c \
+    riak/output/put_output.c \
+    riak/output/conflict_resolver.c \
+    riak/output/youngest_sibling_resolver.c \
+    riak/output/index_result.c \
+    riak/output/index_result_list.c \
+    riak/output/index_output.c \
+    riak/output/key_stream_output.c \
+    riak/property/module_function.c \
+    riak/property/commit_hook.c \
+    riak/property/commit_hook_list.c \
+    riak/property/replication_mode/replication_mode.c \
+    riak/search/search.c \
+    riak/search/input/parameter_bag.c \
+    riak/search/output/document_output.c \
+    riak/search/output/output.c \
+    riak/map_reduce/mapreduce.c \
+    riak/map_reduce/phase/phase.c \
+    riak/map_reduce/phase/map_phase.c \
+    riak/map_reduce/phase/reduce_phase.c \
+    riak/map_reduce/output/output.c \
+    riak/map_reduce/output/stream_output.c \
+    riak/map_reduce/input/input.c \
+    riak/map_reduce/input/bucket_input.c \
+    riak/map_reduce/input/key_data_list_input.c \
+    riak/map_reduce/input/key_list_input.c \
+    riak/map_reduce/functions/base_function.c \
+    riak/map_reduce/functions/javascript_function.c \
+    riak/map_reduce/functions/erlang_function.c \
+    LibRiack/src/riack_sock.c \
+    LibRiack/src/riack.c \
+    LibRiack/src/riack_kv.c \
+    LibRiack/src/riack_2i.c \
+    LibRiack/src/riack_crdt.c \
+    LibRiack/src/riack_mapreduce.c \
+    LibRiack/src/riack_commands.c \
+    LibRiack/src/riack_search.c \
+    LibRiack/src/riack_msg.c \
+    LibRiack/src/riack_mem.c \
+    LibRiack/src/riack_helpers.c \
+    LibRiack/src/protocol/riak_msg_codes.c \
+    LibRiack/src/protocol/riak_search.pb-c.c \
+    LibRiack/src/protocol/riak.pb-c.c \
+    LibRiack/src/protocol/riak_kv.pb-c.c \
+    LibRiack/src/protocol/riak_dt.pb-c.c \
+    LibRiack/src/protocol/riak_yokozuna.pb-c.c \
+    LibRiack/src/protobuf-c/protobuf-c.c, $ext_shared)
+
+    PHP_ADD_BUILD_DIR([$ext_builddir/riak], 1)
+    PHP_ADD_BUILD_DIR([$ext_builddir/riak/crdt], 1)
+    PHP_ADD_BUILD_DIR([$ext_builddir/riak/crdt/input], 1)
+    PHP_ADD_BUILD_DIR([$ext_builddir/riak/exception], 1)
+    PHP_ADD_BUILD_DIR([$ext_builddir/riak/input], 1)
+    PHP_ADD_BUILD_DIR([$ext_builddir/riak/output], 1)
+    PHP_ADD_BUILD_DIR([$ext_builddir/riak/property], 1)
+    PHP_ADD_BUILD_DIR([$ext_builddir/riak/property/replication_mode], 1)
+    PHP_ADD_BUILD_DIR([$ext_builddir/riak/map_reduce], 1)
+    PHP_ADD_BUILD_DIR([$ext_builddir/riak/map_reduce/functions], 1)
+    PHP_ADD_BUILD_DIR([$ext_builddir/riak/map_reduce/input], 1)
+    PHP_ADD_BUILD_DIR([$ext_builddir/riak/map_reduce/output], 1)
+    PHP_ADD_BUILD_DIR([$ext_builddir/riak/map_reduce/phase], 1)
+    PHP_ADD_BUILD_DIR([$ext_builddir/riak/search], 1)
+    PHP_ADD_BUILD_DIR([$ext_builddir/riak/query], 1)
+    PHP_ADD_BUILD_DIR([$ext_builddir/riak/search/input], 1)
+    PHP_ADD_BUILD_DIR([$ext_builddir/riak/search/output], 1)
 
-  PHP_ADD_BUILD_DIR([$ext_builddir/riack/src], 1)
-  PHP_ADD_INCLUDE([$ext_builddir/riack/src])
-  PHP_ADD_INCLUDE([$ext_srcdir/riack/src])
+  PHP_ADD_BUILD_DIR([$ext_builddir/LibRiack/src], 1)
+  PHP_ADD_INCLUDE([$ext_builddir/LibRiack/src])
+  PHP_ADD_INCLUDE([$ext_srcdir/LibRiack/src])
 
-  PHP_ADD_BUILD_DIR([$ext_builddir/riack/src/protocol], 1)
-  PHP_ADD_INCLUDE([$ext_builddir/riack/src/protocol])
-  PHP_ADD_INCLUDE([$ext_srcdir/riack/src/protocol])
+  PHP_ADD_BUILD_DIR([$ext_builddir/LibRiack/src/protocol], 1)
+  PHP_ADD_INCLUDE([$ext_builddir/LibRiack/src/protocol])
+  PHP_ADD_INCLUDE([$ext_srcdir/LibRiack/src/protocol])
 
-  PHP_ADD_BUILD_DIR([$ext_builddir/riack/src/google/protobuf-c], 1)
-  PHP_ADD_INCLUDE([$ext_builddir/riack/src/google/protobuf-c])
-  PHP_ADD_INCLUDE([$ext_srcdir/riack/src/google/protobuf-c])
+  PHP_ADD_BUILD_DIR([$ext_builddir/LibRiack/src/google/protobuf-c], 1)
+  PHP_ADD_INCLUDE([$ext_builddir/LibRiack/src/google/protobuf-c])
+  PHP_ADD_INCLUDE([$ext_srcdir/LibRiack/src/google/protobuf-c])
 
   dnl this is boilerplate to make the extension work on OS X
   case $build_os in
diff --git a/config.w32 b/config.w32
index 5746803..232a485 100644
--- a/config.w32
+++ b/config.w32
@@ -3,19 +3,38 @@
 
 ARG_ENABLE("riak", "Riak php support", "no");
 if (PHP_RIAK != "no") {
-	if (CHECK_HEADER_ADD_INCLUDE("riack.h", "CFLAGS_RIAK", PHP_RIAK + ";" + configure_module_dirname + "/riack/src"))
+        if (CHECK_HEADER_ADD_INCLUDE("riack.h", "CFLAGS_RIAK", PHP_RIAK + ";" + configure_module_dirname + "/LibRiack/src"))
 	{
-                EXTENSION("riak", "php_riak.c connection.c bucket.c object.c exceptions.c bucket_properties.c pool.c link.c pool_info.c riak_session.c mapreduce.c mr_phase.c mr_functions.c mr_inputs.c mr_output.c ht_utils.c streaming.c req_inputs.c req_outputs.c search.c", true, "/I" + configure_module_dirname + "/riack/src");
-                ADD_SOURCES(configure_module_dirname + "/riack/src", "riack_sock.c riack.c riack_kv.c riack_search.c riack_msg.c riack_mem.c riack_helpers.c", "riak");
-                ADD_SOURCES(configure_module_dirname + "/riack/src/google/protobuf-c", "protobuf-c.c", "riak");
-                ADD_SOURCES(configure_module_dirname + "/riack/src/protocol", "riak_msg_codes.c riak_search.pb-c.c riak.pb-c.c riak_kv.pb-c.c", "riak");
+                EXTENSION("riak", "php_riak.c riak_session.c  ht_utils.c ", true, "/I" + configure_module_dirname + "/LibRiack/src");
+                ADD_SOURCES(configure_module_dirname + "/riak", "connection.c bucket.c object.c bucket_properties.c pool.c link.c pool_info.c object_list.c server_info.c", "riak");
+                ADD_SOURCES(configure_module_dirname + "/riak/map_reduce", "mapreduce.c", "riak");
+                ADD_SOURCES(configure_module_dirname + "/riak/map_reduce/input", "input.c bucket_input.c key_data_list_input.c key_list_input.c", "riak");
+                ADD_SOURCES(configure_module_dirname + "/riak/map_reduce/output", "output.c stream_output.c", "riak");
+                ADD_SOURCES(configure_module_dirname + "/riak/map_reduce/phase", "phase.c map_phase.c reduce_phase.c", "riak");
+                ADD_SOURCES(configure_module_dirname + "/riak/map_reduce/functions", "base_function.c erlang_function.c javascript_function.c", "riak");
+                ADD_SOURCES(configure_module_dirname + "/riak/output", "output.c get_output.c put_output.c key_stream_output.c index_result.c index_result_list.c index_output.c conflict_resolver.c youngest_sibling_resolver.c", "riak");
+                ADD_SOURCES(configure_module_dirname + "/riak/input", "input.c delete_input.c get_input.c put_input.c index_input.c get_resolver_input.c", "riak");
+                ADD_SOURCES(configure_module_dirname + "/riak/exception", "exception.c", "riak");
+                ADD_SOURCES(configure_module_dirname + "/riak/crdt", "counter.c", "riak");
+                ADD_SOURCES(configure_module_dirname + "/riak/crdt/input", "update_input.c get_input.c", "riak");
+                ADD_SOURCES(configure_module_dirname + "/riak/search", "search.c", "riak");
+                ADD_SOURCES(configure_module_dirname + "/riak/query", "index_query.c", "riak");
+                ADD_SOURCES(configure_module_dirname + "/riak/search/input", "parameter_bag.c", "riak");
+                ADD_SOURCES(configure_module_dirname + "/riak/search/output", "output.c document_output.c", "riak");
+                ADD_SOURCES(configure_module_dirname + "/riak/property", "module_function.c commit_hook.c commit_hook_list.c", "riak");
+                ADD_SOURCES(configure_module_dirname + "/riak/property/replication_mode", "replication_mode.c", "riak");
+                ADD_SOURCES(configure_module_dirname + "/LibRiack/src", "riack_sock.c riack.c riack_kv.c riack_search.c riack_msg.c riack_mem.c riack_helpers.c riack_2i.c riack_crdt.c riack_commands.c riack_mapreduce.c", "riak");
+                ADD_SOURCES(configure_module_dirname + "/LibRiack/src/protobuf-c", "protobuf-c.c", "riak");
+                ADD_SOURCES(configure_module_dirname + "/LibRiack/src/protocol", "riak_msg_codes.c riak_search.pb-c.c riak.pb-c.c riak_kv.pb-c.c riak_yokozuna.pb-c.c riak_dt.pb-c.c", "riak");
 
+		ADD_FLAG("CFLAGS_RIAK", "/I " + configure_module_dirname);
 		ADD_FLAG("CFLAGS_RIAK", "/D riack_EXPORTS");
 		AC_DEFINE('HAVE_RIAK', 1);
+                AC_DEFINE('PHP_RIAK_SESSION', 1);
 		ADD_EXTENSION_DEP('riak', 'json');
                 ADD_EXTENSION_DEP('riak', 'spl');
 		ADD_EXTENSION_DEP('riak', 'session');
 	} else {
-		WARNING("Riack header not found, did you remember to checkout the riack submodule?");
+                WARNING("Riack header not found, did you remember to checkout the LibRiack submodule?");
 	}
 }
diff --git a/ht_utils.c b/ht_utils.c
index 38cc236..291a267 100644
--- a/ht_utils.c
+++ b/ht_utils.c
@@ -31,9 +31,11 @@ void foreach_in_hashtable(void* callingObj, void* custom_ptr, HashTable *ht, ht_
         zend_hash_move_forward_ex(hindex, &pointer)) {
         key_type = zend_hash_get_current_key_ex(hindex, &key, &key_len, &index, 0, &pointer);
         if (key_type == HASH_KEY_IS_STRING) {
-            (*cb)(callingObj, custom_ptr, key, key_len, 0, data, cnt++ TSRMLS_CC);
+            (*cb)(callingObj, custom_ptr, key, key_len, 0, data, &cnt TSRMLS_CC);
+            cnt++;
         } else if (key_type == HASH_KEY_IS_LONG) {
-            (*cb)(callingObj, custom_ptr, NULL, 0, index, data, cnt++ TSRMLS_CC);
+            (*cb)(callingObj, custom_ptr, NULL, 0, index, data, &cnt TSRMLS_CC);
+            cnt++;
         }
     }
 }
diff --git a/ht_utils.h b/ht_utils.h
index 0c23ea2..2de6b60 100644
--- a/ht_utils.h
+++ b/ht_utils.h
@@ -20,7 +20,7 @@
 
 #include <php.h>
 
-typedef void (*ht_entry_callback)(void* callingObj, void* custom_ptr, char* key, uint keylen, uint index, zval** data, int cnt TSRMLS_DC);
+typedef void (*ht_entry_callback)(void* callingObj, void* custom_ptr, char* key, uint keylen, uint index, zval** data, int *cnt TSRMLS_DC);
 
 void foreach_in_hashtable(void* callingObj, void* custom_ptr, HashTable* ht, ht_entry_callback cb TSRMLS_DC);
 
diff --git a/leak-test.sh b/leak-test.sh
index f6c21ec..37e3266 100755
--- a/leak-test.sh
+++ b/leak-test.sh
@@ -1,4 +1,6 @@
 #!/bin/sh
 export PHP=`which php`
 export TEST_PHP_EXECUTABLE=$PHP
+
 $PHP run-tests.php -q -m --show-diff
+find . -name *.mem | xargs cat
diff --git a/mr_inputs.c b/mr_inputs.c
deleted file mode 100644
index b9e86de..0000000
--- a/mr_inputs.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
-   Copyright 2012 Trifork A/S
-   Author: Kaspar Pedersen
-
-   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.
-*/
-#include <php.h>
-#include <riack.h>
-#include "mr_inputs.h"
-#include "ext/standard/php_array.h"
-#include "php_riak.h"
-#include "ht_utils.h"
-#include "object.h"
-#include "bucket.h"
-#include "exceptions.h"
-
-zend_class_entry *riak_mrinput_ce;
-zend_class_entry *riak_mrinput_bucket_ce;
-zend_class_entry *riak_mrinput_keylist_ce;
-zend_class_entry *riak_mrinput_keydatalist_ce;
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_mrinput_toarr, 0, ZEND_RETURN_VALUE, 0)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_mrinput_ctor, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, name)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_mrinputbucket_setindex, 0, ZEND_RETURN_VALUE, 2)
-    ZEND_ARG_INFO(0, name)
-    ZEND_ARG_INFO(0, start)
-    ZEND_ARG_INFO(0, end)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_mrinputkeylist_ctor, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, bucketkeys_arr)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_mrinputkeylist_single, 0, ZEND_RETURN_VALUE, 2)
-    ZEND_ARG_INFO(0, bucket)
-    ZEND_ARG_INFO(0, key)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_mrinputkeydatalist_add, 0, ZEND_RETURN_VALUE, 3)
-    ZEND_ARG_INFO(0, bucket)
-    ZEND_ARG_INFO(0, key)
-    ZEND_ARG_INFO(0, data)
-ZEND_END_ARG_INFO()
-
-static zend_function_entry riak_mrinput_methods[] = {
-    ZEND_ABSTRACT_ME(RiakMrInput, getValue, arginfo_mrinput_toarr)
-    {NULL, NULL, NULL}
-};
-
-static zend_function_entry riak_mrinputbucket_methods[] = {
-    PHP_ME(Riak_MapReduce_Input_BucketInput, __construct, arginfo_mrinput_ctor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
-    PHP_ME(Riak_MapReduce_Input_BucketInput, setIndexFilter, arginfo_mrinputbucket_setindex, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_MapReduce_Input_BucketInput, getValue, arginfo_mrinput_toarr, ZEND_ACC_PUBLIC)
-    {NULL, NULL, NULL}
-};
-
-static zend_function_entry riak_mrinputlist_methods[] = {
-    PHP_ME(Riak_MapReduce_Input_KeyListInput, __construct, arginfo_mrinputkeylist_ctor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
-    PHP_ME(Riak_MapReduce_Input_KeyListInput, addArray, arginfo_mrinputkeylist_ctor, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_MapReduce_Input_KeyListInput, addSingle, arginfo_mrinputkeylist_single, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_MapReduce_Input_KeyListInput, getValue, arginfo_mrinput_toarr, ZEND_ACC_PUBLIC)
-    {NULL, NULL, NULL}
-};
-
-static zend_function_entry riak_mrinputkeydatalist_methods[] = {
-    PHP_ME(Riak_MapReduce_Input_KeyDataListInput, __construct, arginfo_mrinput_ctor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
-    PHP_ME(Riak_MapReduce_Input_KeyDataListInput, add, arginfo_mrinputkeydatalist_add, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_MapReduce_Input_KeyDataListInput, getValue, arginfo_mrinput_toarr, ZEND_ACC_PUBLIC)
-    {NULL, NULL, NULL}
-};
-
-void riak_mrinputs_init(TSRMLS_D) /* {{{ */
-{
-    zend_class_entry ce;
-
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\MapReduce\\Input", "Input", riak_mrinput_methods);
-    riak_mrinput_ce = zend_register_internal_class(&ce TSRMLS_CC);
-
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\MapReduce\\Input", "BucketInput", riak_mrinputbucket_methods);
-    riak_mrinput_bucket_ce = zend_register_internal_class_ex(&ce, riak_mrinput_ce, NULL TSRMLS_CC);
-    zend_declare_property_null(riak_mrinput_bucket_ce, "name", sizeof("name")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_mrinput_bucket_ce, "keyFilters", sizeof("keyFilters")-1, ZEND_ACC_PUBLIC TSRMLS_CC);
-    zend_declare_property_null(riak_mrinput_bucket_ce, "idxname", sizeof("idxname")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_mrinput_bucket_ce, "idxstart", sizeof("idxstart")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_mrinput_bucket_ce, "idxend", sizeof("idxend")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\MapReduce\\Input", "KeyListInput", riak_mrinputlist_methods);
-    riak_mrinput_keylist_ce = zend_register_internal_class_ex(&ce, riak_mrinput_ce, NULL TSRMLS_CC);
-    zend_declare_property_null(riak_mrinput_bucket_ce, "inputList", sizeof("inputList")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\MapReduce\\Input", "KeyDataListInput", riak_mrinputkeydatalist_methods);
-    riak_mrinput_keydatalist_ce = zend_register_internal_class_ex(&ce, riak_mrinput_ce, NULL TSRMLS_CC);
-    zend_declare_property_null(riak_mrinput_keydatalist_ce, "inputList", sizeof("inputList")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-}
-/* }}} */
-
-/*************************************************************
-* Implementation: Riak\MapReduce\Input\BucketInput
-*************************************************************/
-
-/* {{{ proto void Riak\MapReduce\Input\BucketInput->__construct(string $bucketName)
-Creates a new BucketInput */
-PHP_METHOD(Riak_MapReduce_Input_BucketInput, __construct)
-{
-    char *name;
-    int namelen;
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &namelen) == FAILURE) {
-        return;
-    }
-    zend_update_property_stringl(riak_mrinput_bucket_ce, getThis(), "name", sizeof("name")-1, name, namelen TSRMLS_CC);
-}
-/* }}} */
-
-/* {{{ proto void Riak\MapReduce\Input\BucketInput->setIndexFilter($indexname, $start [, $end])
-Add a index query filter */
-PHP_METHOD(Riak_MapReduce_Input_BucketInput, setIndexFilter)
-{
-    char *index, *start, *end;
-    int indexlen, startlen, endlen;
-    end = NULL;
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|s", &index, &indexlen, &start, &startlen, &end, &endlen) == FAILURE) {
-        return;
-    }
-    zend_update_property_stringl(riak_mrinput_bucket_ce, getThis(), "idxname", sizeof("idxname")-1, index, indexlen TSRMLS_CC);
-    zend_update_property_stringl(riak_mrinput_bucket_ce, getThis(), "idxstart", sizeof("idxstart")-1, start, startlen TSRMLS_CC);
-    if (end != NULL && endlen > 0) {
-        zend_update_property_stringl(riak_mrinput_bucket_ce, getThis(), "idxend", sizeof("idxend")-1, end, endlen TSRMLS_CC);
-    }
-    RIAK_RETURN_THIS
-}
-
-/* {{{ proto string|array Riak\MapReduce\Input\BucketInput->getValue()
-Returns value to use in Mapreduce */
-PHP_METHOD(Riak_MapReduce_Input_BucketInput, getValue)
-{
-    zval* zname, *zfilters, *zresult, *zindex;
-    zname = zend_read_property(riak_mrinput_bucket_ce, getThis(), "name", sizeof("name")-1, 1 TSRMLS_CC);
-    zfilters = zend_read_property(riak_mrinput_bucket_ce, getThis(), "keyFilters", sizeof("keyFilters")-1, 1 TSRMLS_CC);
-    zindex = zend_read_property(riak_mrinput_bucket_ce, getThis(), "idxname", sizeof("idxname")-1, 1 TSRMLS_CC);
-
-    if (Z_TYPE_P(zfilters) == IS_ARRAY || Z_TYPE_P(zindex) == IS_STRING) {
-        MAKE_STD_ZVAL(zresult);
-        array_init(zresult);
-        zval_addref_p(zname);
-        add_assoc_zval_ex(zresult, "bucket", sizeof("bucket"), zname);
-        if (Z_TYPE_P(zindex) == IS_STRING) {
-            zval *start, *end;
-            start = zend_read_property(riak_mrinput_bucket_ce, getThis(), "idxstart", sizeof("idxstart")-1, 1 TSRMLS_CC);
-            end = zend_read_property(riak_mrinput_bucket_ce, getThis(), "idxend", sizeof("idxend")-1, 1 TSRMLS_CC);
-
-            zval_addref_p(zindex);
-            add_assoc_zval_ex(zresult, "index", sizeof("index"), zindex);
-            if (Z_TYPE_P(end) != IS_STRING) {
-                zval_addref_p(start);
-                add_assoc_zval_ex(zresult, "key", sizeof("key"), start);
-            } else {
-                zval_addref_p(start);
-                zval_addref_p(end);
-                add_assoc_zval_ex(zresult, "start", sizeof("start"), start);
-                add_assoc_zval_ex(zresult, "end", sizeof("end"), end);
-            }
-        }
-        if (Z_TYPE_P(zfilters) == IS_ARRAY) {
-            zval_addref_p(zfilters);
-            add_assoc_zval_ex(zresult, "key_filters", sizeof("key_filters"), zfilters);
-        }
-        RETURN_ZVAL(zresult, 0, 1);
-    } else {
-        RETURN_ZVAL(zname, 1, 0);
-    }
-}
-/* }}} */
-
-/*************************************************************
-* Implementation: Riak\MapReduce\Input\KeyListInput
-*************************************************************/
-
-
-zval *riak_create_kv_pair(char* bucket, int bucketlen, char* key, int keylen)/* {{{{ */
-{
-    zval *pair;
-    MAKE_STD_ZVAL(pair);
-    array_init(pair);
-    add_next_index_stringl(pair, bucket, bucketlen, 1);
-    add_next_index_stringl(pair, key, keylen, 1);
-    return pair;
-}
-/* }}} */
-
-void riak_array_to_tupple_array_deep_cb(void* callingObj, void* custom_ptr, char* key,
-                                   uint keylen, uint index, zval** data, int cnt TSRMLS_DC)/* {{{{ */
-{
-    zval *add;
-    char* addkey;
-    int addkeylen;
-    zval *bucket = (zval*)callingObj;
-    zval *to = (zval*)custom_ptr;
-
-    if (Z_TYPE_PP(data) == IS_STRING) {
-        add = riak_create_kv_pair(Z_STRVAL_P(bucket), Z_STRLEN_P(bucket), Z_STRVAL_PP(data), Z_STRLEN_PP(data));
-        add_next_index_zval(to, add);
-    } else if (Z_TYPE_PP(data) == IS_OBJECT) {
-        riak_key_from_object(*data, &addkey, &addkeylen TSRMLS_CC);
-        add = riak_create_kv_pair(Z_STRVAL_P(bucket), Z_STRLEN_P(bucket), addkey, addkeylen);
-        add_next_index_zval(to, add);
-    }
-}
-/* }}} */
-
-void riak_array_to_tupple_array_cb(void* callingObj, void* custom_ptr, char* arraykey,
-                                   uint arraykeylen, uint index, zval** data, int cnt TSRMLS_DC)/* {{{{ */
-{
-    char* riakkey;
-    int riakkeylen;
-    zval *add, bucket;
-    zval *to = (zval*)custom_ptr;
-
-    /* arraykey is actually the bucket name */
-    if (arraykey == NULL || arraykeylen == 0) {
-        return;
-    }
-    if (Z_TYPE_PP(data) == IS_ARRAY) {
-        /* Data is array of keys, iterate those aswell */
-        ZVAL_STRINGL(&bucket, arraykey, arraykeylen-1, 0);
-        foreach_in_hashtable(&bucket, to, Z_ARRVAL_PP(data), &riak_array_to_tupple_array_deep_cb TSRMLS_CC);
-    } else if (Z_TYPE_PP(data) == IS_STRING) {
-        /* Data is a string with the riak key */
-        add = riak_create_kv_pair(arraykey, arraykeylen-1, Z_STRVAL_PP(data), Z_STRLEN_PP(data));
-        add_next_index_zval(to, add);
-    } else if (Z_TYPE_PP(data) == IS_OBJECT) {
-        /* Data is RiakObject */
-        riak_key_from_object(*data, &riakkey, &riakkeylen TSRMLS_CC);
-        add = riak_create_kv_pair(arraykey, arraykeylen-1, riakkey, riakkeylen);
-        add_next_index_zval(to, add);
-    }
-}
-/* }}} */
-
-zval* riak_array_to_tupple_array(HashTable* from TSRMLS_DC)/* {{{{ */
-{
-    zval *to;
-    MAKE_STD_ZVAL(to);
-    array_init(to);
-    foreach_in_hashtable(NULL, to, from, &riak_array_to_tupple_array_cb TSRMLS_CC);
-    return to;
-}
-/* }}} */
-
-/* {{{ proto void Riak\MapReduce\Input\KeyListInput->__construct(array $bucketKeys)
-Create a KeyListInput, input should be an array with ["bucket" => "key", "bucket2" => "key2"] or ["bucket" => ["key1", "key2"]] */
-PHP_METHOD(Riak_MapReduce_Input_KeyListInput, __construct)
-{
-    zval *zarr;
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &zarr) == FAILURE) {
-        return;
-    }
-    zend_update_property(riak_mrinput_keylist_ce, getThis(), "inputList", sizeof("inputList")-1, zarr TSRMLS_CC);
-}
-/* }}} */
-
-/* {{{ proto Riak\MapReduce\Input\KeyListInput Riak\MapReduce\Input\KeyListInput->addArray(array $bucketKeys)
-Add bucket/key inputs to the current list, $bucketKeys must be an array with ["bucket" => "key", "bucket2" => "key2"] or ["bucket" => ["key1", "key2"]] */
-PHP_METHOD(Riak_MapReduce_Input_KeyListInput, addArray)
-{
-    zval *zarr[2], zfuncname, *zcombinedarr;
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &zarr[1]) == FAILURE) {
-        return;
-    }
-    ZVAL_STRING(&zfuncname, "array_merge_recursive", 0);
-    zarr[0] = zend_read_property(riak_mrinput_keylist_ce, getThis(), "inputList", sizeof("inputList")-1, 1 TSRMLS_CC);
-
-    MAKE_STD_ZVAL(zcombinedarr);
-    call_user_function(EG(function_table), NULL, &zfuncname, zcombinedarr, 2, zarr TSRMLS_CC);
-
-    zend_update_property(riak_mrinput_keylist_ce, getThis(), "inputList", sizeof("inputList")-1, zcombinedarr TSRMLS_CC);
-    //zval_ptr_dtor(&zarr[0]);
-    zval_ptr_dtor(&zcombinedarr);
-
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto Riak\MapReduce\Input\KeyListInput Riak\MapReduce\Input\KeyListInput->addSingle(string $bucket, string $key)
-Add a single bucket/key to the current list of inputs */
-PHP_METHOD(Riak_MapReduce_Input_KeyListInput, addSingle)
-{
-    zval *zbucket, *zobject, *zarray;
-    char *bucket, *key;
-    int bucketlen, keylen;
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &zbucket, &zobject) == FAILURE) {
-        return;
-    }
-    key = bucket = NULL;
-    keylen = bucketlen = 0;
-    if (Z_TYPE_P(zbucket) == IS_STRING) {
-        bucket = Z_STRVAL_P(zbucket);
-        bucketlen = Z_STRLEN_P(zbucket);
-    } else if (Z_TYPE_P(zbucket) == IS_OBJECT) {
-        riak_name_from_bucket(zbucket, &bucket, &bucketlen TSRMLS_CC);
-    }
-    if (Z_TYPE_P(zobject) == IS_STRING) {
-        key = Z_STRVAL_P(zobject);
-        keylen = Z_STRLEN_P(zobject);
-    } else if (Z_TYPE_P(zobject) == IS_OBJECT) {
-        riak_key_from_object(zobject, &key, &keylen TSRMLS_CC);
-    }
-    if (keylen > 0 && bucketlen > 0) {
-        MAKE_STD_ZVAL(zarray);
-        array_init(zarray);
-        add_assoc_stringl_ex(zarray, bucket, bucketlen, key, keylen, 1);
-        RIAK_CALL_METHOD1(Riak_MapReduce_Input_KeyListInput, addArray, return_value, getThis(), zarray);
-        zval_ptr_dtor(&zarray);
-    } else {
-        zend_throw_exception(riak_badarguments_exception_ce, "Key or bucketname missing", 5001 TSRMLS_CC);
-    }
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto array Riak\MapReduce\Input\KeyListInput->getValue()
-Returns value to use in Mapreduce */
-PHP_METHOD(Riak_MapReduce_Input_KeyListInput, getValue)
-{
-    zval* zresult;
-    zval* zinputlist = zend_read_property(riak_mrinput_keylist_ce, getThis(), "inputList", sizeof("inputList")-1, 1 TSRMLS_CC);
-    zresult = riak_array_to_tupple_array(Z_ARRVAL_P(zinputlist) TSRMLS_CC);
-    RETURN_ZVAL(zresult, 0, 1);
-}
-/* }}} */
-
-/*************************************************************
-* Implementation: Riak\MapReduce\Input\KeyDataListInput
-*************************************************************/
-
-/* {{{ proto void Riak\MapReduce\Input\KeyDataListInput->__construct()
-Create a KeyDataListInput */
-PHP_METHOD(Riak_MapReduce_Input_KeyDataListInput, __construct)
-{
-    zval *list;
-    MAKE_STD_ZVAL(list);
-    array_init(list);
-    zend_update_property(riak_mrinput_keydatalist_ce, getThis(), "inputList", sizeof("inputList")-1, list TSRMLS_CC);
-    zval_ptr_dtor(&list);
-}
-/* }}} */
-
-/* {{{ proto void Riak\MapReduce\Input\KeyDataListInput->add(string|RiakBucket $bucket, string|RiakObject $object, $data)
-Add a bucket/key/data set to input */
-PHP_METHOD(Riak_MapReduce_Input_KeyDataListInput, add)
-{
-    zval *zbucket, *zkey, *zdata, *zarr, *zlist;
-    char *bucket, *key;
-    int bucketlen, keylen;
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzz", &zbucket, &zkey, &zdata) == FAILURE) {
-        return;
-    }
-    bucket = NULL;
-    bucketlen = 0;
-    if (Z_TYPE_P(zbucket) == IS_STRING) {
-        bucket = Z_STRVAL_P(zbucket);
-        bucketlen = Z_STRLEN_P(zbucket);
-    } else if (Z_TYPE_P(zbucket) == IS_OBJECT) {
-        riak_name_from_bucket(zbucket, &bucket, &bucketlen TSRMLS_CC);
-    }
-    if (Z_TYPE_P(zkey) == IS_STRING) {
-        key = Z_STRVAL_P(zkey);
-        keylen = Z_STRLEN_P(zkey);
-    } else if (Z_TYPE_P(zkey) == IS_OBJECT) {
-        riak_key_from_object(zkey, &key, &keylen TSRMLS_CC);
-    }
-    if (bucket != NULL && bucketlen > 0 && key != NULL && keylen > 0) {
-        MAKE_STD_ZVAL(zarr);
-        array_init(zarr);
-        add_next_index_stringl(zarr, bucket, bucketlen, 1);
-        add_next_index_stringl(zarr, key, keylen, 1);
-        zval_addref_p(zdata);
-        add_next_index_zval(zarr, zdata);
-        zlist = zend_read_property(riak_mrinput_keydatalist_ce, getThis(), "inputList", sizeof("inputList")-1, 1 TSRMLS_CC);
-        add_next_index_zval(zlist, zarr);
-    } else {
-        zend_throw_exception(riak_badarguments_exception_ce, "Key or bucketname missing", 5001 TSRMLS_CC);
-    }
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-
-/* {{{ proto array Riak\MapReduce\Input\KeyDataListInput->getValue()
-Returns value to use in Mapreduce */
-PHP_METHOD(Riak_MapReduce_Input_KeyDataListInput, getValue)
-{
-    zval* zinputlist = zend_read_property(riak_mrinput_keydatalist_ce, getThis(), "inputList", sizeof("inputList")-1, 1 TSRMLS_CC);
-    if (Z_TYPE_P(zinputlist) == IS_ARRAY) {
-        RETURN_ZVAL(zinputlist, 1, 0);
-    }
-
-}
-/* }}} */
-
diff --git a/mr_phase.c b/mr_phase.c
deleted file mode 100644
index aff042d..0000000
--- a/mr_phase.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
-   Copyright 2012 Trifork A/S
-   Author: Kaspar Pedersen
-
-   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.
-*/
-#include <php.h>
-#include <riack.h>
-#include "mr_phase.h"
-#include "mr_functions.h"
-#include "php_riak.h"
-
-zend_class_entry *riak_mrphase_ce;
-zend_class_entry *riak_mr_mapphase_ce;
-zend_class_entry *riak_mr_reducephase_ce;
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_mrphase_xx_ctor, 0, ZEND_RETURN_VALUE, 2)
-    ZEND_ARG_INFO(0, function)
-    ZEND_ARG_INFO(0, keep)
-    ZEND_ARG_INFO(0, args)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_phase_toarr, 0, ZEND_RETURN_VALUE, 0)
-ZEND_END_ARG_INFO()
-
-
-static zend_function_entry riak_mrphase_methods[] = {
-    ZEND_ABSTRACT_ME(Riak_MapReduce_Phase_Phase, toArray, arginfo_phase_toarr)
-    {NULL, NULL, NULL}
-};
-
-static zend_function_entry riak_mrphase_map_methods[] = {
-    PHP_ME(Riak_MapReduce_Phase_MapPhase, __construct, arginfo_mrphase_xx_ctor, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
-    PHP_ME(Riak_MapReduce_Phase_MapPhase, toArray, arginfo_phase_toarr, ZEND_ACC_PUBLIC)
-    {NULL, NULL, NULL}
-};
-
-static zend_function_entry riak_mrphase_reduce_methods[] = {
-    PHP_ME(Riak_MapReduce_Phase_ReducePhase, __construct, arginfo_mrphase_xx_ctor, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
-    PHP_ME(Riak_MapReduce_Phase_ReducePhase, toArray, arginfo_phase_toarr, ZEND_ACC_PUBLIC)
-    {NULL, NULL, NULL}
-};
-
-void riak_mrphase_init(TSRMLS_D)/* {{{ */
-{
-    zend_class_entry ce;
-
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\MapReduce\\Phase", "Phase", riak_mrphase_methods);
-    riak_mrphase_ce = zend_register_internal_class(&ce TSRMLS_CC);
-    zend_declare_property_null(riak_mrphase_ce, "function", sizeof("functions")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_bool(riak_mrphase_ce, "keep", sizeof("keep")-1, 0, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_mrphase_ce, "arg", sizeof("arg")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\MapReduce\\Phase", "MapPhase", riak_mrphase_map_methods);
-    riak_mr_mapphase_ce = zend_register_internal_class_ex(&ce, riak_mrphase_ce, NULL TSRMLS_CC);
-
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\MapReduce\\Phase", "ReducePhase", riak_mrphase_reduce_methods);
-    riak_mr_reducephase_ce = zend_register_internal_class_ex(&ce, riak_mrphase_ce, NULL TSRMLS_CC);
-}
-/* }}} */
-
-/*************************************************************
-* Implementation: Riak\MapReduce\Phase\MapPhase
-*************************************************************/
-
-/* {{{ proto void Riak\MapReduce\Phase\MapPhase->__construct(Riak\MapReduce\Function\Function $function [, bool $keep [, array $arguments]])
-Create a new MapPhase */
-PHP_METHOD(Riak_MapReduce_Phase_MapPhase, __construct)
-{
-    zval *zfunction, *zargs;
-    zend_bool keep;
-    keep = 0;
-    zargs = NULL;
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|ba", &zfunction, &keep, &zargs) == FAILURE) {
-        return;
-    }
-    zend_update_property(riak_mr_mapphase_ce, getThis(), "function", sizeof("function")-1, zfunction TSRMLS_CC);
-    zend_update_property_bool(riak_mr_mapphase_ce, getThis(), "keep", sizeof("keep")-1, keep TSRMLS_CC);
-    if (zargs) {
-        zend_update_property(riak_mr_mapphase_ce, getThis(), "arg", sizeof("arg")-1, zargs TSRMLS_CC);
-    }
-}
-/* }}} */
-
-/* {{{ proto array Riak\MapReduce\Phase\MapPhase->toArray()
-Convert this phase into an array */
-PHP_METHOD(Riak_MapReduce_Phase_MapPhase, toArray)
-{
-    zval *zarray, *zfuncarray, *zfunc, *zarg, zname;
-    zend_bool keep;
-    MAKE_STD_ZVAL(zarray);
-    array_init(zarray);
-
-    MAKE_STD_ZVAL(zfuncarray);
-    zfunc = zend_read_property(riak_mr_mapphase_ce, getThis(), "function", sizeof("function")-1, 1 TSRMLS_CC);
-    ZVAL_STRING(&zname, "toArray", 0);
-    call_user_function(NULL, &zfunc, &zname, zfuncarray, 0, NULL TSRMLS_CC);
-
-    keep = Z_BVAL_P(zend_read_property(riak_mr_mapphase_ce, getThis(), "keep", sizeof("keep")-1, 1 TSRMLS_CC));
-    if (keep) {
-        add_assoc_bool_ex(zfuncarray, "keep", sizeof("keep"), 1);
-    }
-    add_assoc_zval_ex(zarray, "map", sizeof("map"), zfuncarray);
-    zarg = zend_read_property(riak_mr_mapphase_ce, getThis(), "arg", sizeof("arg")-1, 1 TSRMLS_CC);
-    if (Z_TYPE_P(zarg) != IS_NULL) {
-        add_assoc_zval_ex(zarray, "arg", sizeof("arg"), zarg);
-        zval_addref_p(zarg);
-    }
-    RETURN_ZVAL(zarray, 0, 1);
-}
-/* }}} */
-
-
-/*************************************************************
-* Implementation: Riak\MapReduce\Phase\ReducePhase
-*************************************************************/
-
-/* {{{ proto void Riak\MapReduce\Phase\ReducePhase->__construct(Riak\MapReduce\Function\Function $function [, bool $keep [, array $arguments]])
-Create a new ReducePhase */
-PHP_METHOD(Riak_MapReduce_Phase_ReducePhase, __construct)
-{
-    zval *zfunction, *zargs;
-    zend_bool keep;
-    keep = 0;
-    zargs = NULL;
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|ba", &zfunction, &keep, &zargs) == FAILURE) {
-        return;
-    }
-    zend_update_property(riak_mr_reducephase_ce, getThis(), "function", sizeof("function")-1, zfunction TSRMLS_CC);
-    zend_update_property_bool(riak_mr_reducephase_ce, getThis(), "keep", sizeof("keep")-1, keep TSRMLS_CC);
-    if (zargs) {
-        zend_update_property(riak_mr_reducephase_ce, getThis(), "arg", sizeof("arg")-1, zargs TSRMLS_CC);
-    }
-}
-/* }}} */
-
-/* {{{ proto array Riak\MapReduce\Phase\ReducePhase->toArray()
-Convert this phase into an array */
-PHP_METHOD(Riak_MapReduce_Phase_ReducePhase, toArray)
-{
-    zval *zarray, *zfuncarray, *zfunc, *zarg, zname;
-    zend_bool keep;
-    MAKE_STD_ZVAL(zarray);
-    array_init(zarray);
-
-    MAKE_STD_ZVAL(zfuncarray);
-    zfunc = zend_read_property(riak_mr_reducephase_ce, getThis(), "function", sizeof("function")-1, 1 TSRMLS_CC);
-    ZVAL_STRING(&zname, "toArray", 0);
-    call_user_function(NULL, &zfunc, &zname, zfuncarray, 0, NULL TSRMLS_CC);
-
-    keep = Z_BVAL_P(zend_read_property(riak_mr_reducephase_ce, getThis(), "keep", sizeof("keep")-1, 1 TSRMLS_CC));
-    if (keep) {
-        add_assoc_bool_ex(zfuncarray, "keep", sizeof("keep"), 1);
-    }
-    add_assoc_zval_ex(zarray, "reduce", sizeof("reduce"), zfuncarray);
-    zarg = zend_read_property(riak_mr_reducephase_ce, getThis(), "arg", sizeof("arg")-1, 1 TSRMLS_CC);
-    if (Z_TYPE_P(zarg) != IS_NULL) {
-        zval_addref_p(zarg);
-        add_assoc_zval_ex(zarray, "arg", sizeof("arg"), zarg);
-    }
-    RETURN_ZVAL(zarray, 0, 1);
-}
-/* }}} */
-
diff --git a/package.xml b/package.xml
index 4676cea..223409c 100644
--- a/package.xml
+++ b/package.xml
@@ -15,81 +15,186 @@
         <email>kasparp@me.com</email>
         <active>yes</active>
     </lead>
-    <date>2013-10-02</date>
-    <time>18:42:00</time>
+    <date>2014-06-22</date>
+    <time>16:00:00</time>
     <version>
-        <release>0.5.4</release>
-        <api>0.5.0</api>
+        <release>1.2.0</release>
+        <api>1.2.0</api>
     </version>
     <stability>
-        <release>beta</release>
-        <api>beta</api>
+        <release>stable</release>
+        <api>stable</api>
     </stability>
     <license uri="http://www.apache.org/licenses/LICENSE-2.0">Apache 2</license>
-        <notes>
-This release fixes:
-  Issue36: SessionHandler intermitently cannot save session data
-  Issue35: Memoryleak in MapReduce and search has been fixed.
-  Issue37: session.auto_start breaks session handling
-        </notes>
+<notes>
+Fixes issue 78: Segmentation fault with numeric key
+Fixes issue 80: Support lazy connection
+</notes>
     <contents>
         <dir baseinstalldir="/" name="/">
-            <file role="src" name="bucket_properties.c"/>
-            <file role="src" name="bucket_properties.h"/>
-            <file role="src" name="bucket.c"/>
-            <file role="src" name="bucket.h"/>
-            <file role="src" name="connection.c"/>
-            <file role="src" name="connection.h"/>
+            <file role="doc" name="LICENSE"/>
+            <file role="doc" name="README.md"/>
             <file role="src" name="config.m4"/>
             <file role="src" name="config.w32"/>
-            <file role="src" name="exceptions.c"/>
-            <file role="src" name="exceptions.h"/>
             <file role="src" name="ht_utils.c"/>
             <file role="src" name="ht_utils.h"/>
-            <file role="doc" name="LICENSE"/>
-            <file role="src" name="link.c"/>
-            <file role="src" name="link.h"/>
-            <file role="src" name="mapreduce.c"/>
-            <file role="src" name="mapreduce.h"/>
-            <file role="src" name="mr_functions.c"/>
-            <file role="src" name="mr_functions.h"/>
-            <file role="src" name="mr_inputs.c"/>
-            <file role="src" name="mr_inputs.h"/>
-            <file role="src" name="mr_phase.c"/>
-            <file role="src" name="mr_phase.h"/>
-            <file role="src" name="mr_output.c"/>
-            <file role="src" name="mr_output.h"/>
-            <file role="src" name="object.c"/>
-            <file role="src" name="object.h"/>
-            <file role="src" name="php_riak.c"/>
-            <file role="src" name="php_riak.h"/>
-            <file role="src" name="pool.c"/>
-            <file role="src" name="pool.h"/>
-            <file role="doc" name="README.md"/>
             <file role="src" name="riak_session.c"/>
             <file role="src" name="riak_session.h"/>
-            <file role="src" name="search.c"/>
-            <file role="src" name="search.h"/>
-            <file role="src" name="pool_info.c"/>
-            <file role="src" name="pool_info.h"/>
-            <file role="src" name="streaming.c"/>
-            <file role="src" name="streaming.h"/>
-            <file role="src" name="req_inputs.c"/>
-            <file role="src" name="req_inputs.h"/>
-            <file role="src" name="req_outputs.c"/>
-            <file role="src" name="req_outputs.h"/>
+            <file role="src" name="php_riak.c"/>
+            <file role="src" name="php_riak.h"/>
+            <file role="src" name="php_riak_internal.h"/>
+            <dir name="riak">
+                <file role="src" name="bucket_properties.c"/>
+                <file role="src" name="bucket_properties.h"/>
+                <file role="src" name="bucket.c"/>
+                <file role="src" name="bucket.h"/>
+                <file role="src" name="connection.c"/>
+                <file role="src" name="connection.h"/>
+                <file role="src" name="link.c"/>
+                <file role="src" name="link.h"/>
+                <file role="src" name="object.c"/>
+                <file role="src" name="object.h"/>
+                <file role="src" name="object_list.c"/>
+                <file role="src" name="object_list.h"/>
+                <file role="src" name="pool.c"/>
+                <file role="src" name="pool.h"/>
+                <file role="src" name="pool_info.c"/>
+                <file role="src" name="pool_info.h"/>
+                <file role="src" name="server_info.c"/>
+                <file role="src" name="server_info.h"/>
+                <dir name="crdt">
+                    <file role="src" name="counter.c"/>
+                    <file role="src" name="counter.h"/>
+                    <dir name="input">
+                        <file role="src" name="get_input.c"/>
+                        <file role="src" name="get_input.h"/>
+                        <file role="src" name="update_input.c"/>
+                        <file role="src" name="update_input.h"/>
+                    </dir>
+                </dir>
+                <dir name="exception">
+                    <file role="src" name="exception.c"/>
+                    <file role="src" name="exception.h"/>
+                </dir>
+                <dir name="query">
+                    <file role="src" name="index_query.c"/>
+                    <file role="src" name="index_query.h"/>
+                </dir>
+                <dir name="input">
+                    <file role="src" name="input.c"/>
+                    <file role="src" name="input.h"/>
+                    <file role="src" name="delete_input.c"/>
+                    <file role="src" name="delete_input.h"/>
+                    <file role="src" name="get_input.c"/>
+                    <file role="src" name="get_input.h"/>
+                    <file role="src" name="get_resolver_input.c"/>
+                    <file role="src" name="get_resolver_input.h"/>
+                    <file role="src" name="put_input.c"/>
+                    <file role="src" name="put_input.h"/>
+                    <file role="src" name="index_input.c"/>
+                    <file role="src" name="index_input.h"/>
+                </dir>
+                <dir name="output">
+                    <file role="src" name="output.c"/>
+                    <file role="src" name="output.h"/>
+                    <file role="src" name="get_output.c"/>
+                    <file role="src" name="get_output.h"/>
+                    <file role="src" name="put_output.c"/>
+                    <file role="src" name="put_output.h"/>
+                    <file role="src" name="conflict_resolver.c"/>
+                    <file role="src" name="conflict_resolver.h"/>
+                    <file role="src" name="youngest_sibling_resolver.c"/>
+                    <file role="src" name="youngest_sibling_resolver.h"/>
+                    <file role="src" name="index_result.c"/>
+                    <file role="src" name="index_result.h"/>
+                    <file role="src" name="index_result_list.c"/>
+                    <file role="src" name="index_result_list.h"/>
+                    <file role="src" name="index_output.c"/>
+                    <file role="src" name="index_output.h"/>
+                    <file role="src" name="key_stream_output.c"/>
+                    <file role="src" name="key_stream_output.h"/>
+                </dir>
+                <dir name="property">
+                    <file role="src" name="module_function.c"/>
+                    <file role="src" name="module_function.h"/>
+                    <file role="src" name="commit_hook.c"/>
+                    <file role="src" name="commit_hook.h"/>
+                    <file role="src" name="commit_hook_list.c"/>
+                    <file role="src" name="commit_hook_list.h"/>
+                    <dir name="replication_mode">
+                        <file role="src" name="replication_mode.c"/>
+                        <file role="src" name="replication_mode.h"/>
+                    </dir>
+                </dir>
+                <dir name="map_reduce">
+                    <file role="src" name="mapreduce.c"/>
+                    <file role="src" name="mapreduce.h"/>
+                    <dir name="phase">
+                        <file role="src" name="phase.c"/>
+                        <file role="src" name="phase.h"/>
+                        <file role="src" name="map_phase.c"/>
+                        <file role="src" name="map_phase.h"/>
+                        <file role="src" name="reduce_phase.c"/>
+                        <file role="src" name="reduce_phase.h"/>
+                    </dir>
+                    <dir name="output">
+                        <file role="src" name="output.c"/>
+                        <file role="src" name="output.h"/>
+                        <file role="src" name="stream_output.c"/>
+                        <file role="src" name="stream_output.h"/>
+                    </dir>
+                    <dir name="input">
+                        <file role="src" name="input.c"/>
+                        <file role="src" name="input.h"/>
+                        <file role="src" name="bucket_input.c"/>
+                        <file role="src" name="bucket_input.h"/>
+                        <file role="src" name="key_data_list_input.c"/>
+                        <file role="src" name="key_data_list_input.h"/>
+                        <file role="src" name="key_list_input.c"/>
+                        <file role="src" name="key_list_input.h"/>
+                    </dir>
+                    <dir name="functions">
+                        <file role="src" name="base_function.c"/>
+                        <file role="src" name="base_function.h"/>
+                        <file role="src" name="erlang_function.c"/>
+                        <file role="src" name="erlang_function.h"/>
+                        <file role="src" name="javascript_function.c"/>
+                        <file role="src" name="javascript_function.h"/>
+                    </dir>
+                </dir>
+                <dir name="search">
+                    <file role="src" name="search.c"/>
+                    <file role="src" name="search.h"/>
+                    <dir name="input">
+                        <file role="src" name="parameter_bag.c"/>
+                        <file role="src" name="parameter_bag.h"/>
+                    </dir>
+                    <dir name="output">
+                        <file role="src" name="output.c"/>
+                        <file role="src" name="output.h"/>
+                        <file role="src" name="document_output.c"/>
+                        <file role="src" name="document_output.h"/>
+                    </dir>
+                </dir>
+            </dir>
             
-            <dir name="riack">
+            <dir name="LibRiack">
                 <dir name="src">
                     <file role="src" name="ints.h"/>
                     <file role="src" name="riack_defines.h"/>
                     <file role="src" name="riack_helpers.c"/>
                     <file role="src" name="riack_helpers.h"/>
                     <file role="src" name="riack_kv.c"/>
+                    <file role="src" name="riack_2i.c"/>
+                    <file role="src" name="riack_crdt.c"/>
+                    <file role="src" name="riack_mapreduce.c"/>
                     <file role="src" name="riack_search.c"/>
+                    <file role="src" name="riack_commands.c"/>
                     <file role="src" name="riack_mem.c"/>
                     <file role="src" name="riack_msg.c"/>
                     <file role="src" name="riack_msg.h"/>
+                    <file role="src" name="riack_compat.h"/>
+                    <file role="src" name="riack_internal.h"/>
                     <file role="src" name="riack_sock.c"/>
                     <file role="src" name="riack_sock.h"/>
                     <file role="src" name="riack-config.h"/>
@@ -98,6 +203,10 @@ This release fixes:
                     <dir name="protocol">
                         <file role="src" name="riak_kv.pb-c.c"/>
                         <file role="src" name="riak_kv.pb-c.h"/>
+                        <file role="src" name="riak_dt.pb-c.c"/>
+                        <file role="src" name="riak_dt.pb-c.h"/>
+                        <file role="src" name="riak_yokozuna.pb-c.c"/>
+                        <file role="src" name="riak_yokozuna.pb-c.h"/>
                         <file role="src" name="riak_search.pb-c.c"/>
                         <file role="src" name="riak_search.pb-c.h"/>
                         <file role="src" name="riak.pb-c.c"/>
@@ -105,37 +214,51 @@ This release fixes:
                         <file role="src" name="riak_msg_codes.c"/>
                         <file role="src" name="riak_msg_codes.h"/>
                     </dir>
-                    <dir name="google">
-                        <dir name="protobuf-c">
-                            <file role="doc" name="LICENSE"/>
-                            <file role="src" name="protobuf-c-private.h"/>
-                            <file role="src" name="protobuf-c.c"/>
-                            <file role="src" name="protobuf-c.h"/>
-                            <file role="doc" name="README.md"/>
-                        </dir>
+                    <dir name="protobuf-c">
+                        <file role="doc" name="LICENSE"/>
+                        <file role="src" name="protobuf-c-private.h"/>
+                        <file role="src" name="protobuf-c.c"/>
+                        <file role="src" name="protobuf-c.h"/>
+                        <file role="doc" name="README.md"/>
                     </dir>
                 </dir>
             </dir>
             <dir name="tests">
+                <file name="bucket.phpt" role="test" />
                 <file name="bucket_props.phpt" role="test" />
-                <file name="key_not_found.phpt" role="test" />
-                <file name="mrfunctions.phpt" role="test" />
-                <file name="ping.phpt" role="test" />
-                <file name="session.phpt" role="test" />
+                <file name="bucket_props_ext.phpt" role="test" />
                 <file name="client_ctor.phpt" role="test" />
-                <file name="links.phpt" role="test" />
-                <file name="mrinputs.phpt" role="test" />
-                <file name="pool.phpt" role="test" />
-                <file name="session_respects_options.phpt" role="test" />
+                <file name="connect.inc" role="test" />
+                <file name="connection.phpt" role="test" />
+                <file name="builtin_conflict_resolver_db_objs.phpt" role="test" />
+                <file name="builtin_conflict_resolvers.phpt" role="test" />
+                <file name="conflict_resolver_bucket.phpt" role="test" />
+                <file name="conflict_resolver_exception.phpt" role="test" />
+                <file name="conflict_resolver_key.phpt" role="test" />
+                <file name="conflict_resolver_precedence.phpt" role="test" />
                 <file name="get1.phpt" role="test" />
+                <file name="index_perform.phpt" role="test" />
+                <file name="key_not_found.phpt" role="test" />
+                <file name="links.phpt" role="test" />
+                <file name="list_keys.phpt" role="test" />
                 <file name="mapreduce.phpt" role="test" />
-                <file name="mrkeyfilters.phpt" role="test" />
-                <file name="put1.phpt" role="test" />
-                <file name="pool_info.phpt" role="test" />
-                <file name="indexquery.phpt" role="test" />
                 <file name="metadata.phpt" role="test" />
+                <file name="mrfunctions.phpt" role="test" />
+                <file name="mrinputs.phpt" role="test" />
+                <file name="mrkeyfilters.phpt" role="test" />
                 <file name="mrphase.phpt" role="test" />
+                <file name="object_list.phpt" role="test" />
+                <file name="ping.phpt" role="test" />
+                <file name="pool.phpt" role="test" />
+                <file name="property_commit_hook.phpt" role="test" />
+                <file name="put1.phpt" role="test" />
                 <file name="reconnect.phpt" role="test" />
+                <file name="search.phpt" role="test" />
+                <file name="search_input.phpt" role="test" />
+                <file name="session.phpt" role="test" />
+                <file name="session_respects_options.phpt" role="test" />
+                <file name="stream_keys.phpt" role="test" />
+                <file name="reset_object_properties.phpt" role="test" />
             </dir>
         </dir>
     </contents>
@@ -153,6 +276,289 @@ This release fixes:
     <providesextension>riak</providesextension>
     <extsrcrelease />
     <changelog>
+    <release>
+        <version>
+            <release>1.2.0</release>
+            <api>1.2.0</api>
+        </version>
+        <stability>
+            <release>stable</release>
+            <api>stable</api>
+        </stability>
+        <date>2014-06-22</date>
+        <license>Apache2</license>
+<notes>
+Fixes issue 78: Segmentation fault with numeric key
+Fixes issue 80: Support lazy connection
+</notes>
+    </release>
+    <release>
+        <version>
+            <release>1.1.6</release>
+            <api>1.1.6</api>
+        </version>
+        <stability>
+            <release>stable</release>
+            <api>stable</api>
+        </stability>
+        <date>2013-05-15</date>
+        <license>Apache2</license>
+<notes>
+Fixes issue 73: Secondary index - multiple values:
+Too keep backward compatibility indexes with only one value will still point to a string but indexes with multiple values will instead have an array of strings.
+</notes>
+    </release>
+    <release>
+        <version>
+            <release>1.1.5</release>
+            <api>1.1.5</api>
+        </version>
+        <stability>
+            <release>stable</release>
+            <api>stable</api>
+        </stability>
+        <date>2013-04-17</date>
+        <license>Apache2</license>
+<notes>
+New: Object now allows contentEncoding, contentType, content and vTag to be set to NULL.
+Fixes issue 72: Riak HTTP stops working after update
+</notes>
+    </release>
+    <release>
+        <version>
+            <release>1.1.4</release>
+            <api>1.1.3</api>
+        </version>
+        <stability>
+            <release>stable</release>
+            <api>stable</api>
+        </stability>
+        <date>2013-03-20</date>
+        <license>Apache2</license>
+<notes>
+Fixes serious issue 68: Protobuf implementation not thread safe.
+</notes>
+    </release>
+    <release>
+        <version>
+            <release>1.1.3</release>
+            <api>1.1.3</api>
+        </version>
+        <stability>
+            <release>stable</release>
+            <api>stable</api>
+        </stability>
+        <date>2013-12-20</date>
+        <license>Apache2</license>
+<notes>
+Since 1.1.3
+Fixes serious issue 68: Protobuf implementation not thread safe.
+</notes>
+    </release>
+    <release>
+        <version>
+            <release>1.1.2</release>
+            <api>1.1.2</api>
+        </version>
+        <stability>
+            <release>beta</release>
+            <api>beta</api>
+        </stability>
+        <date>2013-12-18</date>
+        <license>Apache2</license>
+<notes>
+Fixed issue 65: Conflict resolvers no longer do an automatic put when conflicts are resolved.
+</notes>
+    </release>
+    <release>
+        <version>
+            <release>1.1.1</release>
+            <api>1.1.1</api>
+        </version>
+        <stability>
+            <release>beta</release>
+            <api>beta</api>
+        </stability>
+        <date>2013-12-14</date>
+        <license>Apache2</license>
+<notes>
+Fix windows build
+</notes>
+    </release>
+    <release>
+        <version>
+            <release>1.1.0</release>
+            <api>1.1.0</api>
+        </version>
+        <stability>
+            <release>beta</release>
+            <api>beta</api>
+        </stability>
+        <date>2013-12-14</date>
+        <license>Apache2</license>
+<notes>
+New features:
+Issue 50: vClock now gets read from object if not present in input, making vclock easier to work with.
+Issue 54: Conflict resolver can now be set on a bucket or passed along to the get function, which can make conflict resolving a lot easier.
+Issue 10: Automatic retry implemented and set to 1 retry by default
+Fixes:
+Issue 55: Implemented missing getter for last modified on object.
+</notes>
+    </release>
+    <release>
+        <version>
+            <release>1.0.0</release>
+            <api>1.0.0</api>
+        </version>
+        <stability>
+            <release>stable</release>
+            <api>stable</api>
+        </stability>
+        <date>2013-11-17</date>
+        <license>Apache2</license>
+<notes>
+Fixed issue 52: A temporary connection is now taken from pool when doing streaming operations
+</notes>
+    </release>
+    <release>
+        <version>
+            <release>0.9.1</release>
+            <api>0.9.1</api>
+        </version>
+        <stability>
+            <release>beta</release>
+            <api>beta</api>
+        </stability>
+        <date>2013-11-16</date>
+        <license>Apache2</license>
+        <notes>
+Added some missing ZEND_ARG_INFO's in bucket.c
+Possibly breaking change: Removed NotFoundException, you always want an GetOutput with vclock even though the object is not found.
+</notes>
+    </release>
+    <release>
+        <version>
+            <release>0.9.0</release>
+            <api>0.9.0</api>
+        </version>
+        <stability>
+            <release>beta</release>
+            <api>beta</api>
+        </stability>
+        <date>2013-10-08</date>
+        <license>Apache2</license>
+        <notes>
+- Added Riak\ServerInfo class.
+- Fixed: The connection pool never got used if PHP was compiled without ZTS-
+</notes>
+    </release>
+    <release>
+        <version>
+            <release>0.8.0</release>
+            <api>0.8.0</api>
+        </version>
+        <stability>
+            <release>beta</release>
+            <api>beta</api>
+        </stability>
+        <date>2013-11-02</date>
+        <license>Apache2</license>
+        <notes>
+- Riak 1.4+ feature: CRDT counters implemented
+</notes>
+    </release>
+    <release>
+        <version>
+            <release>0.7.0</release>
+            <api>0.7.0</api>
+        </version>
+        <stability>
+            <release>beta</release>
+            <api>beta</api>
+        </stability>
+        <date>2013-10-31</date>
+        <license>Apache2</license>
+        <notes>
+- Riak 1.4+ feature: secondary index paging implemented
+</notes>
+    </release>
+    <release>
+        <version>
+            <release>0.6.2</release>
+            <api>0.6.2</api>
+        </version>
+        <stability>
+            <release>beta</release>
+            <api>beta</api>
+        </stability>
+        <date>2013-10-23</date>
+        <license>Apache2</license>
+        <notes>
+- Fixed potential bug in map reduce function
+- Restructured extension sources so php FQN can be mapped directly to source.
+- Changed get output from array to collection, which implements ArrayAccess so it maintains compatability
+</notes>
+    </release>
+    <release>
+        <version>
+            <release>0.6.1</release>
+            <api>0.6.0</api>
+        </version>
+        <stability>
+            <release>beta</release>
+            <api>beta</api>
+        </stability>
+        <date>2013-10-13</date>
+        <license>Apache2</license>
+        <notes>
+        Bug fixes:
+            - Issue43: Search\Output: hasMaxScore and hasNumFound fails
+            - Issue42: Riak\Bucket::getName() does not work
+</notes>
+    </release>
+    <release>
+        <version>
+            <release>0.6.0</release>
+            <api>0.6.0</api>
+        </version>
+        <stability>
+            <release>beta</release>
+            <api>beta</api>
+        </stability>
+        <date>2013-10-09</date>
+        <license>Apache2</license>
+        <notes>
+        Improvements:
+            - Added extended bucket properties that can be set and read on riak 1.4 and later.
+            - Enable keep-alive on sockets.
+
+            - New .ini options added:
+             ; Keep sockets alive (recommended)
+             riak.socket.keep_alive=1
+             ; Socket receive timeout [ms]
+             riak.socket.recv_timeout=10000
+             ; Socket send timeout [ms]
+             riak.socket.send_timeout=10000
+
+            - default connection timeout is changed to 1800 seconds.
+
+        Bug fixes:
+            - Issue38: Windows build failing
+</notes>
+    </release>
+    <release>
+        <version>
+            <release>0.5.2</release>
+            <api>0.5.0</api>
+        </version>
+        <stability>
+            <release>beta</release>
+            <api>beta</api>
+        </stability>
+        <date>2013-09-24</date>
+        <license>Apache2</license>
+        <notes>Bugfixes in the session handler</notes>
+    </release>
     <release>
         <version>
             <release>0.5.3</release>
diff --git a/php_riak.c b/php_riak.c
index 4c08750..a8569e4 100644
--- a/php_riak.c
+++ b/php_riak.c
@@ -15,31 +15,63 @@
    limitations under the License.
 */
 
-#include <php.h>
-#include <php_ini.h>
-#include <riack.h>
+#include "php_riak_internal.h"
 #include "php_riak.h"
+#include <php_ini.h>
 
-#include "pool.h"
-#include "connection.h"
-#include "object.h"
-#include "bucket.h"
-#include "bucket_properties.h"
-#include "exceptions.h"
-#include "pool_info.h"
-#include "link.h"
+#include "riak/pool.h"
+#include "riak/connection.h"
+#include "riak/object.h"
+#include "riak/bucket.h"
+#include "riak/bucket_properties.h"
+#include "riak/pool_info.h"
+#include "riak/link.h"
 #include "riak_session.h"
-#include "mapreduce.h"
-#include "mr_phase.h"
-#include "mr_functions.h"
-#include "mr_inputs.h"
-#include "mr_output.h"
-#include "streaming.h"
-#include "req_inputs.h"
-#include "req_outputs.h"
-#include "search.h"
-
-#ifdef PHP_SESSION
+#include "riak/exception/exception.h"
+#include "riak/map_reduce/mapreduce.h"
+#include "riak/map_reduce/phase/phase.h"
+#include "riak/map_reduce/phase/map_phase.h"
+#include "riak/map_reduce/phase/reduce_phase.h"
+#include "riak/map_reduce/output/output.h"
+#include "riak/map_reduce/output/stream_output.h"
+#include "riak/map_reduce/input/input.h"
+#include "riak/map_reduce/input/bucket_input.h"
+#include "riak/map_reduce/input/key_data_list_input.h"
+#include "riak/map_reduce/input/key_list_input.h"
+#include "riak/map_reduce/functions/base_function.h"
+#include "riak/map_reduce/functions/erlang_function.h"
+#include "riak/map_reduce/functions/javascript_function.h"
+#include "riak/crdt/counter.h"
+#include "riak/crdt/input/get_input.h"
+#include "riak/crdt/input/update_input.h"
+#include "riak/input/input.h"
+#include "riak/input/index_input.h"
+#include "riak/input/delete_input.h"
+#include "riak/input/get_input.h"
+#include "riak/input/get_resolver_input.h"
+#include "riak/input/put_input.h"
+#include "riak/query/index_query.h"
+#include "riak/output/output.h"
+#include "riak/output/get_output.h"
+#include "riak/output/put_output.h"
+#include "riak/output/conflict_resolver.h"
+#include "riak/output/youngest_sibling_resolver.h"
+#include "riak/output/key_stream_output.h"
+#include "riak/output/index_result.h"
+#include "riak/output/index_result_list.h"
+#include "riak/output/index_output.h"
+#include "riak/object_list.h"
+#include "riak/search/search.h"
+#include "riak/search/input/parameter_bag.h"
+#include "riak/search/output/output.h"
+#include "riak/search/output/document_output.h"
+#include "riak/property/module_function.h"
+#include "riak/property/commit_hook.h"
+#include "riak/property/commit_hook_list.h"
+#include "riak/property/replication_mode/replication_mode.h"
+#include "riak/server_info.h"
+
+#ifdef PHP_RIAK_SESSION
   extern ps_module ps_mod_riak;
 #endif
 
@@ -51,13 +83,13 @@ zend_function_entry riak_functions[] = {
   { NULL, NULL, NULL }
 };
 
-struct RIACK_ALLOCATOR riack_php_persistent_allocator = 
+riack_allocator riack_php_persistent_allocator =
 {
   riack_php_persistent_alloc,
   riack_php_persistent_free,
 };
 
-struct RIACK_ALLOCATOR riack_php_allocator =
+riack_allocator riack_php_allocator =
 {
   riack_php_alloc,
   riack_php_free
@@ -88,6 +120,7 @@ PHP_INI_BEGIN()
   STD_PHP_INI_ENTRY("riak.socket.keep_alive",      "1",    PHP_INI_ALL, OnUpdateBool, keep_alive,             zend_riak_globals, riak_globals)
   STD_PHP_INI_ENTRY("riak.socket.recv_timeout",    "10000",PHP_INI_ALL, OnUpdateLong, recv_timeout,           zend_riak_globals, riak_globals)
   STD_PHP_INI_ENTRY("riak.socket.send_timeout",    "10000",PHP_INI_ALL, OnUpdateLong, send_timeout,           zend_riak_globals, riak_globals)
+  STD_PHP_INI_ENTRY("riak.default.retries",        "1",    PHP_INI_ALL, OnUpdateLong, default_retries,        zend_riak_globals, riak_globals)
 PHP_INI_END()
 
 PHP_MINIT_FUNCTION(riak) /* {{{ */
@@ -100,21 +133,58 @@ PHP_MINIT_FUNCTION(riak) /* {{{ */
     riak_link_init(TSRMLS_C);
     riak_bucket_init(TSRMLS_C);
     riak_bucket_props_init(TSRMLS_C);
+    riak_property_module_function_init(TSRMLS_C);
+    riak_property_commit_hook_init(TSRMLS_C);
+    riak_property_commit_hook_list_init(TSRMLS_C);
+    riak_property_replication_mode_init(TSRMLS_C);
 
     riak_mapreduce_init(TSRMLS_C);
-    riak_mrphase_init(TSRMLS_C);
-    riak_mrfunctions_init(TSRMLS_C);
-    riak_mrinputs_init(TSRMLS_C);
-    riak_mroutput_init(TSRMLS_C);
+    riak_map_reduce_phase_phase_init(TSRMLS_C);
+    riak_map_reduce_phase_map_phase_init(TSRMLS_C);
+    riak_map_reduce_phase_reduce_phase_init(TSRMLS_C);
+    riak_map_reduce_input_input_init(TSRMLS_C);
+    riak_map_reduce_input_bucket_input_init(TSRMLS_C);
+    riak_map_reduce_input_key_data_list_input_init(TSRMLS_C);
+    riak_map_reduce_input_key_list_input_init(TSRMLS_C);
+    riak_map_reduce_output_output_init(TSRMLS_C);
+    riak_map_reduce_output_stream_output_init(TSRMLS_C);
+    riak_map_reduce_functions_base_function_init(TSRMLS_C);
+    riak_map_reduce_functions_erlang_function_init(TSRMLS_C);
+    riak_map_reduce_functions_javascript_function_init(TSRMLS_C);
+
+    riak_input_input_init(TSRMLS_C);
+    riak_input_delete_input_init(TSRMLS_C);
+    riak_input_get_input_init(TSRMLS_C);
+    riak_input_get_resolver_input_init(TSRMLS_C);
+    riak_input_put_input_init(TSRMLS_C);
+    riak_input_index_input_init(TSRMLS_C);
+    riak_query_index_query_init(TSRMLS_C);
+
+    riak_output_init(TSRMLS_C);
+    riak_output_get_output_init(TSRMLS_C);
+    riak_output_put_output_init(TSRMLS_C);
+    riak_output_stream_output_init(TSRMLS_C);
+    riak_output_object_list_init(TSRMLS_C);
+    riak_output_index_result_init(TSRMLS_C);
+    riak_output_index_result_list_init(TSRMLS_C);
+    riak_output_index_output_init(TSRMLS_C);
+    riak_output_conflict_resolver_init(TSRMLS_C);
+    riak_output_youngest_sibling_resolver_init(TSRMLS_C);
 
     riak_exceptions_init(TSRMLS_C);
     riak_poolinfo_init(TSRMLS_C);
-    riak_streaming_init(TSRMLS_C);
-    riak_req_inputs_init(TSRMLS_C);
-    riak_req_outputs_init(TSRMLS_C);
+
     riak_search_init(TSRMLS_C);
+    riak_search_input_parameterbag_init(TSRMLS_C);
+    riak_search_output_output_init(TSRMLS_C);
+    riak_search_output_document_output_init(TSRMLS_C);
+
+    riak_crdt_counter_init(TSRMLS_C);
+    riak_crdt_input_get_input_init(TSRMLS_C);
+    riak_crdt_input_update_input_init(TSRMLS_C);
 
-#ifdef PHP_SESSION
+    riak_server_info_init(TSRMLS_C);
+#ifdef PHP_RIAK_SESSION
     php_session_register_module(&ps_mod_riak);
 #endif
     return SUCCESS;
@@ -139,6 +209,7 @@ PHP_GINIT_FUNCTION(riak) /* {{{ */
     riak_globals->keep_alive = 1;
     riak_globals->recv_timeout = 10000;
     riak_globals->send_timeout = 10000;
+    riak_globals->default_retries = 1;
 #ifdef ZTS
     riak_globals->pool_mutex = tsrm_mutex_alloc();
 #endif
@@ -152,7 +223,7 @@ PHP_GSHUTDOWN_FUNCTION(riak) /* {{{ */
 #endif
 }
 /* {{{ */
-void riak_throw_exception(struct RIACK_CLIENT* client, int errorStatus TSRMLS_DC)/* {{{ */
+void riak_throw_exception(riack_client* client, int errorStatus TSRMLS_DC)/* {{{ */
 {
     if (errorStatus == RIACK_ERROR_COMMUNICATION) {
         zend_throw_exception(riak_communication_exception_ce, "Communication error", 1001 TSRMLS_CC);
diff --git a/php_riak.files b/php_riak.files
new file mode 100644
index 0000000..e57ced5
--- /dev/null
+++ b/php_riak.files
@@ -0,0 +1,256 @@
+LibRiack/src/cmake/Modules/FindProtoBufC.cmake
+LibRiack/src/protocol/riak.pb-c.c
+LibRiack/src/protocol/riak.pb-c.h
+LibRiack/src/protocol/riak.proto
+LibRiack/src/protocol/riak_kv.pb-c.c
+LibRiack/src/protocol/riak_kv.pb-c.h
+LibRiack/src/protocol/riak_kv.proto
+LibRiack/src/protocol/riak_msg_codes.c
+LibRiack/src/protocol/riak_msg_codes.h
+LibRiack/src/protocol/riak_search.pb-c.c
+LibRiack/src/protocol/riak_search.pb-c.h
+LibRiack/src/protocol/riak_search.proto
+LibRiack/src/tests/test.c
+LibRiack/src/tests/test.h
+LibRiack/src/tests/test_2i.c
+LibRiack/src/tests/test_bucket.c
+LibRiack/src/tests/test_clientid.c
+LibRiack/src/tests/test_delete.c
+LibRiack/src/tests/test_get_put.c
+LibRiack/src/tests/test_load.c
+LibRiack/src/tests/test_mapred.c
+LibRiack/src/tests/test_mem.c
+LibRiack/src/tests/test_meta_links.c
+LibRiack/src/tests/test_misc.c
+LibRiack/src/tests/test_ping.c
+LibRiack/src/CMakeLists.txt
+LibRiack/src/riack.c
+LibRiack/src/riack.h
+LibRiack/src/riack_defines.h
+LibRiack/src/riack_helpers.c
+LibRiack/src/riack_helpers.h
+LibRiack/src/riack_kv.c
+LibRiack/src/riack_mem.c
+LibRiack/src/riack_msg.c
+LibRiack/src/riack_msg.h
+LibRiack/src/riack_sock.c
+LibRiack/src/riack_sock.h
+LibRiack/testdata/make_c_friendly.php
+LibRiack/cmake_install.cmake
+LibRiack/CMakeCache.txt
+LibRiack/CTestTestfile.cmake
+LibRiack/install_manifest.txt
+LibRiack/README.md
+LibRiack/src/google/protobuf-c/protobuf-c.h
+LibRiack/src/google/protobuf-c/protobuf-c-private.h
+LibRiack/src/google/protobuf-c/protobuf-c.c
+LibRiack/src/riack_search.c
+LibRiack/src/ints.h
+script/build_module.sh
+tests/bucket_props.phpt
+tests/client_ctor.phpt
+tests/connect.inc
+tests/get1.phpt
+tests/key_not_found.phpt
+tests/metadata.phpt
+tests/ping.phpt
+tests/pool.phpt
+tests/put1.phpt
+tests/reconnect.phpt
+tests/session.phpt
+acinclude.m4
+aclocal.m4
+riak/bucket.c
+riak/bucket.h
+riak/bucket_properties.c
+riak/bucket_properties.h
+riak/connection.c
+riak/connection.h
+config.guess
+config.h
+config.h.in
+config.log
+config.m4
+config.nice
+config.status
+config.sub
+configure
+configure.in
+debug.php
+riak/exception/exception.c
+riak/exception/exception.h
+install-sh
+riak/object.c
+riak/object.h
+php-setup.sh
+php_riak.c
+php_riak.h
+riak/pool.c
+riak/pool.h
+README.md
+riak.la
+riak_session.c
+riak_session.h
+run-tests.php
+riak/link.h
+riak/link.c
+ht_utils.h
+ht_utils.c
+tests/links.phpt
+riak/map_reduce/mapreduce.c
+riak/map_reduce/mapreduce.h
+tests/mrphase.phpt
+tests/mapreduce.phpt
+tests/mrfunctions.phpt
+tests/mrinputs.phpt
+tests/session_respects_options.phpt
+tests/mrkeyfilters.phpt
+tests/index_perform.phpt
+package.xml
+config.w32
+tests/list_keys.phpt
+tests/stream_keys.phpt
+riak/search/search.c
+riak/search/search.h
+tests/search.phpt
+tests/search_input.phpt
+CREDITS.md
+riak/output/output.c
+riak/output/output.h
+tests/connection.phpt
+tests/property_commit_hook.phpt
+tests/bucket_props_ext.phpt
+tests/session_autostart.php
+tests/bucket.phpt
+riak/search/input/parameter_bag.c
+riak/search/input/parameter_bag.h
+riak/search/output/output.c
+riak/search/output/output.h
+riak/search/output/document_output.c
+riak/search/output/document_output.h
+php_riak_internal.h
+riak/pool_info.h
+riak/pool_info.c
+riak/property/module_function.c
+riak/property/module_function.h
+riak/property/commit_hook.c
+riak/property/commit_hook.h
+riak/property/commit_hook_list.c
+riak/property/commit_hook_list.h
+riak/property/replication_mode/replication_mode.c
+riak/property/replication_mode/replication_mode.h
+riak/output/get_output.c
+riak/output/get_output.h
+riak/output/put_output.c
+riak/output/put_output.h
+riak/input/input.c
+riak/input/input.h
+riak/input/delete_input.c
+riak/input/delete_input.h
+riak/input/get_input.c
+riak/input/get_input.h
+riak/input/put_input.c
+riak/input/put_input.h
+riak/map_reduce/functions/base_function.c
+riak/map_reduce/functions/base_function.h
+riak/map_reduce/functions/erlang_function.c
+riak/map_reduce/functions/erlang_function.h
+riak/map_reduce/functions/javascript_function.c
+riak/map_reduce/functions/javascript_function.h
+riak/map_reduce/input/input.c
+riak/map_reduce/input/input.h
+riak/map_reduce/input/bucket_input.c
+riak/map_reduce/input/bucket_input.h
+riak/map_reduce/input/key_data_list_input.c
+riak/map_reduce/input/key_data_list_input.h
+riak/map_reduce/input/key_list_input.c
+riak/map_reduce/input/key_list_input.h
+riak/map_reduce/output/output.c
+riak/map_reduce/output/output.h
+riak/map_reduce/output/stream_output.c
+riak/map_reduce/output/stream_output.h
+riak/map_reduce/phase/phase.c
+riak/map_reduce/phase/phase.h
+riak/map_reduce/phase/map_phase.c
+riak/map_reduce/phase/map_phase.h
+riak/map_reduce/phase/reduce_phase.c
+riak/map_reduce/phase/reduce_phase.h
+riak/output/key_stream_output.c
+riak/output/key_stream_output.h
+riak/object_list.c
+riak/object_list.h
+tests/object_list.phpt
+riak/input/index_input.c
+riak/input/index_input.h
+riak/output/index_result.c
+riak/output/index_result.h
+riak/output/index_result_list.c
+riak/output/index_result_list.h
+riak/output/index_output.c
+riak/output/index_output.h
+tests/index_output.phpt
+riak/query/index_query.c
+riak/query/index_query.h
+tests/index_query.phpt
+tests/index_query_ext.phpt
+riak/crdt/counter.c
+riak/crdt/counter.h
+riak/crdt/input/update_input.c
+riak/crdt/input/update_input.h
+riak/crdt/input/get_input.c
+riak/crdt/input/get_input.h
+tests/crdt_counter.phpt
+riak/server_info.h
+riak/server_info.c
+php_riak.includes
+tests/server_info.phpt
+riak/input/get_resolver_input.h
+riak/input/get_resolver_input.c
+riak/output/conflict_resolver.h
+riak/output/youngest_sibling_resolver.h
+riak/output/conflict_resolver.c
+riak/output/youngest_sibling_resolver.c
+tests/update_object.phpt
+tests/stream_keys.phpt
+tests/session.phpt
+tests/session_respects_options.phpt
+tests/server_info.phpt
+tests/search.phpt
+tests/search_input.phpt
+tests/resolve_siblings.phpt
+tests/reconnect.phpt
+tests/put1.phpt
+tests/property_commit_hook.phpt
+tests/pool.phpt
+tests/pool_info.phpt
+tests/ping.phpt
+tests/object_list.phpt
+tests/mrphase.phpt
+tests/mrkeyfilters.phpt
+tests/mrinputs.phpt
+tests/mrfunctions.phpt
+tests/metadata.phpt
+tests/mapreduce.phpt
+tests/list_keys.phpt
+tests/links.phpt
+tests/key_not_found.phpt
+tests/indexquery.phpt
+tests/index_query.phpt
+tests/index_query_ext.phpt
+tests/index_output.phpt
+tests/get1.phpt
+tests/delete_badarguments.phpt
+tests/crdt_counter.phpt
+tests/connection.phpt
+tests/conflict_resolver_precedence.phpt
+tests/conflict_resolver_key.phpt
+tests/conflict_resolver_exception.phpt
+tests/conflict_resolver_bucket.phpt
+tests/client_ctor.phpt
+tests/builtin_conflict_resolvers.phpt
+tests/bucket.phpt
+tests/bucket_props.phpt
+tests/bucket_props_ext.phpt
+tests/builtin_conflict_resolver_db_objs.phpt
+tests/reset_object_properties.phpt
+tests/index_perform_arr.phpt
diff --git a/php_riak.h b/php_riak.h
index 0234874..023ff65 100644
--- a/php_riak.h
+++ b/php_riak.h
@@ -23,155 +23,7 @@
 #endif
 
 #define PHP_RIAK_EXTNAME "riak"
-#define PHP_RIAK_VERSION "0.1"
-
-/*************************************************
-* Macros
-*************************************************/
-
-#define RIAK_PUSH_PARAM(arg) zend_vm_stack_push(arg TSRMLS_CC)
-#define RIAK_POP_PARAM() (void)zend_vm_stack_pop(TSRMLS_C)
-#define RIAK_PUSH_EO_PARAM()
-#define RIAK_POP_EO_PARAM()
-
-#define RIAK_RETURN_THIS RETURN_ZVAL(getThis(), 1, 0);
-
-#define RIAK_GETTER_LONG(CE, PROPERTY_NAME) \
-    zval* ztmp = zend_read_property(CE, getThis(), PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, 1 TSRMLS_CC); \
-    if (Z_TYPE_P(ztmp) == IS_LONG) { RETURN_LONG(Z_LVAL_P(ztmp)); } \
-    RETURN_NULL();
-
-#define RIAK_GETTER_BOOL(CE, PROPERTY_NAME) \
-    zval* ztmp = zend_read_property(CE, getThis(), PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, 1 TSRMLS_CC); \
-    if (Z_TYPE_P(ztmp) == IS_BOOL) { RETURN_BOOL(Z_BVAL_P(ztmp)); } \
-    RETURN_NULL();
-
-#define RIAK_GETTER_ARRAY(CE, PROPERTY_NAME) \
-    zval* ztmp = zend_read_property(CE, getThis(), PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, 1 TSRMLS_CC); \
-    if (Z_TYPE_P(ztmp) == IS_ARRAY) { RETURN_ZVAL(ztmp, 1, 0); } \
-    RETURN_NULL();
-
-#define RIAK_GETTER_OBJECT(CE, PROPERTY_NAME) \
-    zval* ztmp = zend_read_property(CE, getThis(), PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, 1 TSRMLS_CC); \
-    if (Z_TYPE_P(ztmp) == IS_OBJECT) { RETURN_ZVAL(ztmp, 1, 0); } \
-    RETURN_NULL();
-
-#define RIAK_GETTER_MIXED(CE, PROPERTY_NAME) \
-    zval* ztmp = zend_read_property(CE, getThis(), PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, 1 TSRMLS_CC); \
-    RETURN_ZVAL(ztmp, 1, 0);
-
-#define RIAK_GETTER_DOUBLE(CE, PROPERTY_NAME) \
-    zval* ztmp = zend_read_property(CE, getThis(), PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, 1 TSRMLS_CC); \
-    if (Z_TYPE_P(ztmp) == IS_DOUBLE) { RETURN_DOUBLE(Z_DVAL_P(ztmp)); } \
-    RETURN_NULL();
-
-#define RIAK_GETTER_STRING(CE, PROPERTY_NAME) \
-    zval* ztmp = zend_read_property(CE, getThis(), PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, 1 TSRMLS_CC); \
-    if (Z_TYPE_P(ztmp) == IS_STRING) { RETURN_ZVAL(ztmp, 1, 0); } \
-    RETURN_NULL();
-
-#define RIAK_SETTER_LONG(CE, PROPERTY_NAME) \
-    long val; \
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &val) == FAILURE) { return; } \
-    zend_update_property_long(CE, getThis(), PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, val TSRMLS_CC);
-
-#define RIAK_SETTER_BOOL(CE, PROPERTY_NAME) \
-    zend_bool val; \
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &val) == FAILURE) { return; } \
-    zend_update_property_bool(CE, getThis(), PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, val TSRMLS_CC);
-
-#define RIAK_SETTER_STRING(CE, PROPERTY_NAME) \
-    char* val; int val_len; \
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &val, &val_len) == FAILURE) { return; } \
-    zend_update_property_stringl(CE, getThis(), PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, val, val_len TSRMLS_CC);
-
-#define RIAK_CALL_METHOD_BASE(classname, name) zim_##classname##_##name
-
-#define RIAK_CALL_METHOD_HELPER(classname, name, retval, thisptr, num, param) \
-  RIAK_PUSH_PARAM(param); RIAK_PUSH_PARAM((void*)num);                            \
-  RIAK_PUSH_EO_PARAM();                                                      \
-  RIAK_CALL_METHOD_BASE(classname, name)(num, retval, NULL, thisptr, 0 TSRMLS_CC); \
-  RIAK_POP_EO_PARAM();                       \
-  RIAK_POP_PARAM(); RIAK_POP_PARAM();
- 
-#define RIAK_CALL_METHOD(classname, name, retval, thisptr)                  \
-  RIAK_CALL_METHOD_BASE(classname, name)(0, retval, NULL, thisptr, 0 TSRMLS_CC);
- 
-#define RIAK_CALL_METHOD1(classname, name, retval, thisptr, param1)         \
-  RIAK_CALL_METHOD_HELPER(classname, name, retval, thisptr, 1, param1);
- 
-#define RIAK_CALL_METHOD2(classname, name, retval, thisptr, param1, param2) \
-  RIAK_PUSH_PARAM(param1);                                                  \
-  RIAK_CALL_METHOD_HELPER(classname, name, retval, thisptr, 2, param2);     \
-  RIAK_POP_PARAM();
- 
-#define RIAK_CALL_METHOD3(classname, name, retval, thisptr, param1, param2, param3) \
-  RIAK_PUSH_PARAM(param1); RIAK_PUSH_PARAM(param2);                              \
-  RIAK_CALL_METHOD_HELPER(classname, name, retval, thisptr, 3, param3);     \
-  RIAK_POP_PARAM(); RIAK_POP_PARAM();
-
-#define CHECK_RIACK_STATUS_THROW_ON_ERROR(CONNECTION, STATUS) \
-  if ( STATUS != RIACK_SUCCESS) { \
-    CONNECTION->needs_reconnect = 1; \
-    riak_throw_exception(CONNECTION->client,  STATUS TSRMLS_CC); \
-  }
-
-#define CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(CONNECTION, STATUS) \
-  if ( STATUS != RIACK_SUCCESS) { \
-    CONNECTION->needs_reconnect = 1; \
-    riak_throw_exception(CONNECTION->client,  STATUS TSRMLS_CC); \
-  return; }
-
-#define GET_PROPERTY_INTO_RIACK_STR_OR_ELSE(CE, ZOBJ, KEY, ZVAL, RIACK_STR) ZVAL = zend_read_property(CE, ZOBJ, KEY, sizeof(KEY)-1, 1 TSRMLS_CC); \
-     if (Z_TYPE_P(ZVAL) == IS_STRING) { \
-       RIACK_STR.len = Z_STRLEN_P(ZVAL); \
-       RIACK_STR.value = Z_STRVAL_P(ZVAL); } else
-
-#ifdef ZTS
-#include <TSRM.h>
-# define RIAK_GLOBAL(v) TSRMG(riak_globals_id, zend_riak_globals *, v)
-#else
-# define RIAK_GLOBAL(v) (riak_globals.v)
-#endif
-
-
-/*************************************************
-* Vars
-*************************************************/
-
-extern struct RIACK_ALLOCATOR riack_php_allocator;
-extern struct RIACK_ALLOCATOR riack_php_persistent_allocator;
-
-extern int le_riak_connection_list;
-
-ZEND_BEGIN_MODULE_GLOBALS(riak)
-  long persistent_connections;
-  long persistent_timeout;
-
-  long keep_alive;
-  long recv_timeout;
-  long send_timeout;
-
-  long open_connections;
-  long open_connections_persistent;
-
-  long reconnects;
-#ifdef ZTS
-  MUTEX_T pool_mutex;
-#endif
-ZEND_END_MODULE_GLOBALS(riak)
-
-ZEND_EXTERN_MODULE_GLOBALS(riak)
-
-/*************************************************
-* Functions
-*************************************************/
-
-void *riack_php_alloc(void *allocator_data, size_t size);
-void riack_php_free (void *allocator_data, void *data);
-
-void *riack_php_persistent_alloc(void *allocator_data, size_t size);
-void riack_php_persistent_free (void *allocator_data, void *data);
+#define PHP_RIAK_VERSION "1.2.0"
 
 PHP_MINIT_FUNCTION(riak);
 PHP_MSHUTDOWN_FUNCTION(riak);
@@ -179,6 +31,4 @@ PHP_MSHUTDOWN_FUNCTION(riak);
 PHP_GINIT_FUNCTION(riak);
 PHP_GSHUTDOWN_FUNCTION(riak);
 
-void riak_throw_exception(struct RIACK_CLIENT* client, int errorStatus TSRMLS_DC);
-
 #endif
diff --git a/php_riak_internal.h b/php_riak_internal.h
new file mode 100644
index 0000000..7123cd6
--- /dev/null
+++ b/php_riak_internal.h
@@ -0,0 +1,209 @@
+/*
+   Copyright 2013 Trifork A/S
+   Author: Kaspar Bach Pedersen
+
+   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.
+*/
+
+
+#ifndef PHP_RIAK_INTERNAL_H
+#define PHP_RIAK_INTERNAL_H
+
+#ifdef HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <php.h>
+#include <riack.h>
+
+/*************************************************
+* Macros
+*************************************************/
+
+#define RIACK_RETRY_OP(RIACK_RESULT_VAR, CONN, OPERATION) { long retry_cnt; \
+    retry_cnt = RIAK_GLOBAL(default_retries); \
+    do {  \
+        RIACK_RESULT_VAR = OPERATION; \
+        if (RIACK_RESULT_VAR != RIACK_SUCCESS) { \
+            CONN->needs_reconnect = 1; \
+        } \
+        retry_cnt--; \
+    } while (RIACK_RESULT_VAR != RIACK_SUCCESS && retry_cnt >= 0 && ensure_connected(CONN TSRMLS_CC)); }
+
+#define RIAK_PUSH_PARAM(arg) zend_vm_stack_push(arg TSRMLS_CC)
+#define RIAK_POP_PARAM() (void)zend_vm_stack_pop(TSRMLS_C)
+#define RIAK_PUSH_EO_PARAM()
+#define RIAK_POP_EO_PARAM()
+
+#define RIAK_RETURN_THIS RETURN_ZVAL(getThis(), 1, 0);
+
+#define RIAK_GETTER_LONG(CE, PROPERTY_NAME) \
+    zval* ztmp = zend_read_property(CE, getThis(), PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, 1 TSRMLS_CC); \
+    if (Z_TYPE_P(ztmp) == IS_LONG) { RETURN_LONG(Z_LVAL_P(ztmp)); } \
+    RETURN_NULL();
+
+#define RIAK_GETTER_BOOL(CE, PROPERTY_NAME) \
+    zval* ztmp = zend_read_property(CE, getThis(), PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, 1 TSRMLS_CC); \
+    if (Z_TYPE_P(ztmp) == IS_BOOL) { RETURN_BOOL(Z_BVAL_P(ztmp)); } \
+    RETURN_NULL();
+
+#define RIAK_GETTER_ARRAY(CE, PROPERTY_NAME) \
+    zval* ztmp = zend_read_property(CE, getThis(), PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, 1 TSRMLS_CC); \
+    if (Z_TYPE_P(ztmp) == IS_ARRAY) { RETURN_ZVAL(ztmp, 1, 0); } \
+    RETURN_NULL();
+
+#define RIAK_GETTER_OBJECT(CE, PROPERTY_NAME) \
+    zval* ztmp = zend_read_property(CE, getThis(), PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, 1 TSRMLS_CC); \
+    if (Z_TYPE_P(ztmp) == IS_OBJECT) { RETURN_ZVAL(ztmp, 1, 0); } \
+    RETURN_NULL();
+
+#define RIAK_GETTER_MIXED(CE, PROPERTY_NAME) \
+    zval* ztmp = zend_read_property(CE, getThis(), PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, 1 TSRMLS_CC); \
+    RETURN_ZVAL(ztmp, 1, 0);
+
+#define RIAK_GETTER_DOUBLE(CE, PROPERTY_NAME) \
+    zval* ztmp = zend_read_property(CE, getThis(), PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, 1 TSRMLS_CC); \
+    if (Z_TYPE_P(ztmp) == IS_DOUBLE) { RETURN_DOUBLE(Z_DVAL_P(ztmp)); } \
+    RETURN_NULL();
+
+#define RIAK_GETTER_STRING(CE, PROPERTY_NAME) \
+    zval* ztmp = zend_read_property(CE, getThis(), PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, 1 TSRMLS_CC); \
+    if (Z_TYPE_P(ztmp) == IS_STRING) { RETURN_ZVAL(ztmp, 1, 0); } \
+    RETURN_NULL();
+
+#define RIAK_SETTER_LONG(CE, PROPERTY_NAME) \
+    long val; \
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &val) == FAILURE) { return; } \
+    zend_update_property_long(CE, getThis(), PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, val TSRMLS_CC);
+
+#define RIAK_SETTER_BOOL(CE, PROPERTY_NAME) \
+    zend_bool val; \
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &val) == FAILURE) { return; } \
+    zend_update_property_bool(CE, getThis(), PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, val TSRMLS_CC);
+
+#define RIAK_SETTER_STRING(CE, PROPERTY_NAME) \
+    char* val; int val_len; \
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &val, &val_len) == FAILURE) { return; } \
+    zend_update_property_stringl(CE, getThis(), PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, val, val_len TSRMLS_CC);
+
+#define RIAK_SETTER_OPTIONAL_STRING(CE, PROPERTY_NAME) \
+    char* val; int val_len; \
+    val = 0; \
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &val, &val_len) == FAILURE) { return; } \
+    if (val == 0) { \
+        zend_update_property_null(CE, getThis(), PROPERTY_NAME, sizeof(PROPERTY_NAME)-1 TSRMLS_CC); \
+    } else { \
+        zend_update_property_stringl(CE, getThis(), PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, val, val_len TSRMLS_CC); \
+    }
+
+#define RIAK_CALL_METHOD_BASE(classname, name) zim_##classname##_##name
+
+#define RIAK_CALL_METHOD_HELPER(classname, name, retval, thisptr, num, param) \
+  RIAK_PUSH_PARAM(param); RIAK_PUSH_PARAM((void*)num);                            \
+  RIAK_PUSH_EO_PARAM();                                                      \
+  RIAK_CALL_METHOD_BASE(classname, name)(num, retval, NULL, thisptr, 0 TSRMLS_CC); \
+  RIAK_POP_EO_PARAM();                       \
+  RIAK_POP_PARAM(); RIAK_POP_PARAM();
+
+#define RIAK_CALL_METHOD(classname, name, retval, thisptr)                  \
+  RIAK_CALL_METHOD_BASE(classname, name)(0, retval, NULL, thisptr, 0 TSRMLS_CC);
+
+#define RIAK_CALL_METHOD1(classname, name, retval, thisptr, param1)         \
+  RIAK_CALL_METHOD_HELPER(classname, name, retval, thisptr, 1, param1);
+
+#define RIAK_CALL_METHOD2(classname, name, retval, thisptr, param1, param2) \
+  RIAK_PUSH_PARAM(param1);                                                  \
+  RIAK_CALL_METHOD_HELPER(classname, name, retval, thisptr, 2, param2);     \
+  RIAK_POP_PARAM();
+
+#define RIAK_CALL_METHOD3(classname, name, retval, thisptr, param1, param2, param3) \
+  RIAK_PUSH_PARAM(param1); RIAK_PUSH_PARAM(param2);                              \
+  RIAK_CALL_METHOD_HELPER(classname, name, retval, thisptr, 3, param3);     \
+  RIAK_POP_PARAM(); RIAK_POP_PARAM();
+
+#define CHECK_RIACK_STATUS_THROW_ON_ERROR(CONNECTION, STATUS) \
+  if ( STATUS != RIACK_SUCCESS) { \
+    CONNECTION->needs_reconnect = 1; \
+    riak_throw_exception(CONNECTION->client,  STATUS TSRMLS_CC); \
+  }
+
+#define THROW_EXCEPTION_IF_CONNECTION_IS_NULL(CONN) \
+  if ( ! CONN) { \
+    zend_throw_exception(riak_connection_exception_ce, "Connection error", 1000 TSRMLS_CC); return; \
+  }
+
+#define THROW_EXCEPTION_IF_CONNECTION_IS_NULL_WITH_RETURN(CONN, RET) \
+  if ( ! CONN) { \
+    zend_throw_exception(riak_connection_exception_ce, "Connection error", 1000 TSRMLS_CC); return RET; \
+  }
+
+#define CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(CONNECTION, STATUS) \
+  if ( STATUS != RIACK_SUCCESS) { \
+    CONNECTION->needs_reconnect = 1; \
+    riak_throw_exception(CONNECTION->client,  STATUS TSRMLS_CC); \
+  return; }
+
+#define GET_PROPERTY_INTO_RIACK_STR_OR_ELSE(CE, ZOBJ, KEY, ZVAL, RIACK_STR) ZVAL = zend_read_property(CE, ZOBJ, KEY, sizeof(KEY)-1, 1 TSRMLS_CC); \
+     if (Z_TYPE_P(ZVAL) == IS_STRING) { \
+       RIACK_STR.len = Z_STRLEN_P(ZVAL); \
+       RIACK_STR.value = Z_STRVAL_P(ZVAL); } else
+
+#ifdef ZTS
+#include <TSRM.h>
+# define RIAK_GLOBAL(v) TSRMG(riak_globals_id, zend_riak_globals *, v)
+#else
+# define RIAK_GLOBAL(v) (riak_globals.v)
+#endif
+
+
+/*************************************************
+* Vars
+*************************************************/
+
+extern riack_allocator riack_php_allocator;
+extern riack_allocator riack_php_persistent_allocator;
+
+extern int le_riak_connection_list;
+
+ZEND_BEGIN_MODULE_GLOBALS(riak)
+  long persistent_connections;
+  long persistent_timeout;
+
+  long keep_alive;
+  long recv_timeout;
+  long send_timeout;
+
+  long open_connections;
+  long open_connections_persistent;
+
+  long reconnects;
+  long default_retries;
+#ifdef ZTS
+  MUTEX_T pool_mutex;
+#endif
+ZEND_END_MODULE_GLOBALS(riak)
+ZEND_EXTERN_MODULE_GLOBALS(riak)
+
+/*************************************************
+* Functions
+*************************************************/
+
+void *riack_php_alloc(void *allocator_data, size_t size);
+void riack_php_free (void *allocator_data, void *data);
+
+void *riack_php_persistent_alloc(void *allocator_data, size_t size);
+void riack_php_persistent_free (void *allocator_data, void *data);
+
+void riak_throw_exception(riack_client* client, int errorStatus TSRMLS_DC);
+
+#endif // PHP_RIAK_INTERNAL_H
diff --git a/req_inputs.c b/req_inputs.c
deleted file mode 100644
index 9f134da..0000000
--- a/req_inputs.c
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
-   Copyright 2013 Kaspar Bach Pedersen
-
-   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.
-*/
-#include "req_inputs.h"
-#include "php_riak.h"
-
-zend_class_entry *riak_get_input_ce;
-zend_class_entry *riak_put_input_ce;
-zend_class_entry *riak_delete_input_ce;
-zend_class_entry *riak_input_ce;
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_get_config_set_head, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, return_head)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_get_config_set_r, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, r)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_get_config_set_pr, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, pr)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_get_config_set_bq, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, basic_quorum)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_get_config_set_notfoundok, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, not_found_ok)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_get_config_set_ifnotmod, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, ifModified_vclock)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_get_config_set_deleted_vclock, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, deleted_vclock)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_xxx_config_set_w, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, w)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_xxx_config_set_dw, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, dw)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_xxx_config_set_pw, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, pw)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_xxx_config_set_vclock, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, vclock)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_xxx_config_set_ret_body, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, return_body)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_xxx_config_set_if_none_m, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, if_none_match)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_xxx_config_set_if_not_modifed, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, if_not_modified)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_xxx_config_set_rw, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, rw)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_get_config_noargs, 0, ZEND_RETURN_VALUE, 0)
-ZEND_END_ARG_INFO()
-
-static zend_function_entry riak_input_methods[] = {
-    {NULL, NULL, NULL}
-};
-
-static zend_function_entry riak_get_input_methods[] = {
-    PHP_ME(Riak_Input_GetInput, setReturnHead, arginfo_riak_get_config_set_head, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_GetInput, getReturnHead, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_GetInput, setR, arginfo_riak_get_config_set_r, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_GetInput, getR, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_GetInput, setPR, arginfo_riak_get_config_set_pr, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_GetInput, getPR, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_GetInput, setBasicQuorum, arginfo_riak_get_config_set_bq, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_GetInput, getBasicQuorum, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_GetInput, setNotFoundOk, arginfo_riak_get_config_set_notfoundok, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_GetInput, getNotFoundOk, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_GetInput, setIfModifiedVClock, arginfo_riak_get_config_set_ifnotmod, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_GetInput, getIfModifiedVClock, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_GetInput, setReturnDeletedVClock, arginfo_riak_get_config_set_deleted_vclock, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_GetInput, getReturnDeletedVClock, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
-    {NULL, NULL, NULL}
-};
-
-static zend_function_entry riak_put_input_methods[] = {
-    PHP_ME(Riak_Input_PutInput, setReturnHead, arginfo_riak_get_config_set_head, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_PutInput, getReturnHead, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_PutInput, setW, arginfo_riak_xxx_config_set_w, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_PutInput, getW, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_PutInput, setDW, arginfo_riak_xxx_config_set_dw, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_PutInput, getDW, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_PutInput, setPW, arginfo_riak_xxx_config_set_pw, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_PutInput, getPW, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_PutInput, setVClock, arginfo_riak_xxx_config_set_vclock, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_PutInput, getVClock, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_PutInput, setReturnBody, arginfo_riak_xxx_config_set_ret_body, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_PutInput, getReturnBody, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_PutInput, setIfNoneMatch, arginfo_riak_xxx_config_set_if_none_m, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_PutInput, getIfNoneMatch, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_PutInput, setIfNotModified, arginfo_riak_xxx_config_set_if_not_modifed, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_PutInput, getIfNotModified, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
-    {NULL, NULL, NULL}
-};
-
-static zend_function_entry riak_delete_input_methods[] = {
-    PHP_ME(Riak_Input_DeleteInput, setR, arginfo_riak_get_config_set_r, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_DeleteInput, getR, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_DeleteInput, setPR, arginfo_riak_get_config_set_pr, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_DeleteInput, getPR, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_DeleteInput, setRW, arginfo_riak_xxx_config_set_rw, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_DeleteInput, getRW, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_DeleteInput, setW, arginfo_riak_xxx_config_set_w, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_DeleteInput, getW, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_DeleteInput, setDW, arginfo_riak_xxx_config_set_dw, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_DeleteInput, getDW, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_DeleteInput, setPW, arginfo_riak_xxx_config_set_pw, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_DeleteInput, getPW, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_DeleteInput, setVClock, arginfo_riak_xxx_config_set_vclock, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Input_DeleteInput, getVClock, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
-    {NULL, NULL, NULL}
-};
-
-
-void riak_req_inputs_init(TSRMLS_D) /* {{{ */
-{
-    zend_class_entry ce;
-
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\Input","Input", riak_input_methods);
-    riak_input_ce = zend_register_internal_class(&ce TSRMLS_CC);
-
-
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\Input", "GetInput", riak_get_input_methods);
-    riak_get_input_ce = zend_register_internal_class_ex(&ce, riak_input_ce, NULL TSRMLS_CC);
-    zend_declare_property_null(riak_get_input_ce, "r", sizeof("r")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_get_input_ce, "pr", sizeof("pr")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_get_input_ce, "basicQuorum", sizeof("basicQuorum")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_get_input_ce, "notFoundOk", sizeof("notFoundOk")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_get_input_ce, "ifModifiedVClock", sizeof("ifModifiedVClock")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_get_input_ce, "returnHead", sizeof("returnHead")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_get_input_ce, "deletedVClock", sizeof("deletedVClock")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\Input", "PutInput", riak_put_input_methods);
-    riak_put_input_ce = zend_register_internal_class_ex(&ce, riak_input_ce, NULL TSRMLS_CC);
-    zend_declare_property_null(riak_put_input_ce, "w", sizeof("w")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_put_input_ce, "dw", sizeof("dw")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_put_input_ce, "pw", sizeof("pw")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_put_input_ce, "vClock", sizeof("vClock")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_put_input_ce, "returnHead", sizeof("returnHead")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_put_input_ce, "returnBody", sizeof("returnBody")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_put_input_ce, "ifNoneMatch", sizeof("ifNoneMatch")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_put_input_ce, "ifNotModified", sizeof("ifNotModified")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\Input", "DeleteInput", riak_delete_input_methods);
-    riak_delete_input_ce = zend_register_internal_class_ex(&ce, riak_input_ce, NULL TSRMLS_CC);
-    zend_declare_property_null(riak_delete_input_ce, "r", sizeof("r")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_delete_input_ce, "rw", sizeof("rw")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_delete_input_ce, "pr", sizeof("pr")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_delete_input_ce, "w", sizeof("w")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_delete_input_ce, "dw", sizeof("dw")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_delete_input_ce, "pw", sizeof("pw")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_delete_input_ce, "vClock", sizeof("vClock")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-}
-/* }}} */
-
-/*************************************************************
-* Implementation: Riak\Input\DeleteInput
-*************************************************************/
-
-/* {{{ proto Riak\Input\DeleteInput Riak\Input\DeleteInput->setR(int $r)
-Set R value */
-PHP_METHOD(Riak_Input_DeleteInput, setR)
-{
-    RIAK_SETTER_LONG(riak_delete_input_ce, "r");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto null|int Riak\Input\PutInput->getR()
-Gets R value */
-PHP_METHOD(Riak_Input_DeleteInput, getR)
-{
-    RIAK_GETTER_LONG(riak_delete_input_ce, "r")
-}
-/* }}} */
-
-/* {{{ proto Riak\Input\DeleteInput Riak\Input\DeleteInput->setPR(int $pr)
-Set PR value */
-PHP_METHOD(Riak_Input_DeleteInput, setPR)
-{
-    RIAK_SETTER_LONG(riak_delete_input_ce, "pr");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto null|int Riak\Input\PutInput->getPR()
-Gets PR value */
-PHP_METHOD(Riak_Input_DeleteInput, getPR)
-{
-    RIAK_GETTER_LONG(riak_delete_input_ce, "pr")
-}
-/* }}} */
-
-/* {{{ proto Riak\Input\DeleteInput Riak\Input\DeleteInput->setRW(int $rw)
-Set RW value */
-PHP_METHOD(Riak_Input_DeleteInput, setRW)
-{
-    RIAK_SETTER_LONG(riak_delete_input_ce, "rw");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto null|int Riak\Input\PutInput->getRW()
-Gets RW value */
-PHP_METHOD(Riak_Input_DeleteInput, getRW)
-{
-    RIAK_GETTER_LONG(riak_delete_input_ce, "rw")
-}
-/* }}} */
-
-/* {{{ proto Riak\Input\DeleteInput Riak\Input\DeleteInput->setW(int $w)
-Set W value */
-PHP_METHOD(Riak_Input_DeleteInput, setW)
-{
-    RIAK_SETTER_LONG(riak_delete_input_ce, "w");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto null|int Riak\Input\PutInput->getW()
-Gets W value */
-PHP_METHOD(Riak_Input_DeleteInput, getW)
-{
-    RIAK_GETTER_LONG(riak_delete_input_ce, "w")
-}
-/* }}} */
-
-/* {{{ proto Riak\Input\DeleteInput Riak\Input\DeleteInput->setDW(int $dw)
-Set DW value */
-PHP_METHOD(Riak_Input_DeleteInput, setDW)
-{
-    RIAK_SETTER_LONG(riak_delete_input_ce, "dw");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto null|int Riak\Input\PutInput->getDW()
-Gets DW value */
-PHP_METHOD(Riak_Input_DeleteInput, getDW)
-{
-    RIAK_GETTER_LONG(riak_delete_input_ce, "dw")
-}
-/* }}} */
-
-/* {{{ proto Riak\Input\DeleteInput Riak\Input\DeleteInput->setPW(int $pw)
-Set PW value */
-PHP_METHOD(Riak_Input_DeleteInput, setPW)
-{
-    RIAK_SETTER_LONG(riak_delete_input_ce, "pw");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto null|int Riak\Input\PutInput->getPW()
-Gets PW value */
-PHP_METHOD(Riak_Input_DeleteInput, getPW)
-{
-    RIAK_GETTER_LONG(riak_delete_input_ce, "pw")
-}
-/* }}} */
-
-/* {{{ proto Riak\Input\DeleteInput Riak\Input\DeleteInput->setVClock(string $rw)
-Set set vector clock */
-PHP_METHOD(Riak_Input_DeleteInput, setVClock)
-{
-    RIAK_SETTER_STRING(riak_delete_input_ce, "vClock");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto null|string Riak\Input\PutInput->getVClock()
-Gets vector clock */
-PHP_METHOD(Riak_Input_DeleteInput, getVClock)
-{
-    RIAK_GETTER_STRING(riak_delete_input_ce, "vClock")
-}
-/* }}} */
-
-/*************************************************************
-* Implementation: Riak\Input\PutInput
-*************************************************************/
-
-/* {{{ proto Riak\Input\PutInput Riak\Input\PutInput->setReturnHead(bool $returnHead)
-Sets return head option */
-PHP_METHOD(Riak_Input_PutInput, setReturnHead)
-{
-    RIAK_SETTER_BOOL(riak_put_input_ce, "returnHead");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto bool|null Riak\Input\PutInput->getReturnHead()
-Gets return head option */
-PHP_METHOD(Riak_Input_PutInput, getReturnHead)
-{
-    RIAK_GETTER_BOOL(riak_put_input_ce, "returnHead");
-}
-/* }}} */
-
-/* {{{ proto int|null Riak\Input\PutInput->getW()
-Gets W value */
-PHP_METHOD(Riak_Input_PutInput, getW)
-{
-    RIAK_GETTER_LONG(riak_put_input_ce, "w");
-}
-/* }}} */
-
-/* {{{ proto Riak\Input\PutInput Riak\Input\PutInput->setW(int $w)
-Set W value */
-PHP_METHOD(Riak_Input_PutInput, setW)
-{
-    RIAK_SETTER_LONG(riak_put_input_ce, "w");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto int|null Riak\Input\PutInput->getDW()
-Gets DW value */
-PHP_METHOD(Riak_Input_PutInput, getDW)
-{
-    RIAK_GETTER_LONG(riak_put_input_ce, "dw");
-}
-/* }}} */
-
-/* {{{ proto Riak\Input\PutInput Riak\Input\PutInput->setDW(int $dw)
-Set DW value */
-PHP_METHOD(Riak_Input_PutInput, setDW)
-{
-    RIAK_SETTER_LONG(riak_put_input_ce, "dw");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto int|null Riak\Input\PutInput->getPW()
-Gets PW value */
-PHP_METHOD(Riak_Input_PutInput, getPW)
-{
-    RIAK_GETTER_LONG(riak_put_input_ce, "pw");
-}
-/* }}} */
-
-/* {{{ proto Riak\Input\PutInput Riak\Input\PutInput->setPW(int $pw)
-Set PW value */
-PHP_METHOD(Riak_Input_PutInput, setPW)
-{
-    RIAK_SETTER_LONG(riak_put_input_ce, "pw");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto string|null Riak\Input\PutInput->getVClock()
-Get the vector clock value */
-PHP_METHOD(Riak_Input_PutInput, getVClock)
-{
-    RIAK_GETTER_STRING(riak_put_input_ce, "vClock");
-}
-/* }}} */
-
-/* {{{ proto Riak\Input\PutInput Riak\Input\PutInput->setVClock(string $vClock)
-Set the vector clock value */
-PHP_METHOD(Riak_Input_PutInput, setVClock)
-{
-    RIAK_SETTER_STRING(riak_put_input_ce, "vClock");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto bool|null Riak\Input\PutInput->getReturnBody()
-Get return body value */
-PHP_METHOD(Riak_Input_PutInput, getReturnBody)
-{
-    RIAK_GETTER_STRING(riak_put_input_ce, "returnBody");
-}
-/* }}} */
-
-/* {{{ proto Riak\Input\PutInput Riak\Input\PutInput->setReturnBody(bool $returnBody)
-Set return body value */
-PHP_METHOD(Riak_Input_PutInput, setReturnBody)
-{
-    RIAK_SETTER_STRING(riak_put_input_ce, "returnBody");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-
-/* {{{ proto bool|null Riak\Input\PutInput->getIfNoneMatch()
-Get if none match value */
-PHP_METHOD(Riak_Input_PutInput, getIfNoneMatch)
-{
-    RIAK_GETTER_BOOL(riak_put_input_ce, "ifNoneMatch");
-}
-/* }}} */
-
-/* {{{ proto Riak\Input\PutInput Riak\Input\PutInput->setIfNoneMatch(bool $ifNoneMatch)
-Set if none match value */
-PHP_METHOD(Riak_Input_PutInput, setIfNoneMatch)
-{
-    RIAK_SETTER_BOOL(riak_put_input_ce, "ifNoneMatch");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto bool|null Riak\Input\PutInput->getIfNotModified()
-Get if not modified */
-PHP_METHOD(Riak_Input_PutInput, getIfNotModified)
-{
-    RIAK_GETTER_BOOL(riak_put_input_ce, "ifNotModified");
-}
-/* }}} */
-
-/* {{{ proto Riak\Input\PutInput Riak\Input\PutInput->setIfNotModified(bool $ifNotModified)
-Set if not modified */
-PHP_METHOD(Riak_Input_PutInput, setIfNotModified)
-{
-    RIAK_SETTER_BOOL(riak_put_input_ce, "ifNotModified");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/*************************************************************
-* Implementation: Riak\Input\GetInput
-*************************************************************/
-
-/* {{{ proto Riak\Input\GetInput Riak\Input\GetInput->setReturnHead(bool $returnHead)
-Sets return head option */
-PHP_METHOD(Riak_Input_GetInput, setReturnHead)
-{
-    RIAK_SETTER_BOOL(riak_get_input_ce, "returnHead");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto void Riak\Input\GetInput->getReturnHead()
-Gets return head option */
-PHP_METHOD(Riak_Input_GetInput, getReturnHead)
-{
-    RIAK_GETTER_BOOL(riak_get_input_ce, "returnHead");
-}
-/* }}} */
-
-/* {{{ proto Riak\Input\GetInput Riak\Input\GetInput->setR(int $r)
-Set R value */
-PHP_METHOD(Riak_Input_GetInput, setR)
-{
-    RIAK_SETTER_BOOL(riak_get_input_ce, "r");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto int Riak\Input\GetInput->getR()
-Get R value */
-PHP_METHOD(Riak_Input_GetInput, getR)
-{
-    RIAK_GETTER_BOOL(riak_get_input_ce, "r");
-}
-/* }}} */
-
-/* {{{ proto Riak\Input\GetInput Riak\Input\GetInput->setPR(int $r)
-Set PR value */
-PHP_METHOD(Riak_Input_GetInput, setPR)
-{
-    RIAK_SETTER_BOOL(riak_get_input_ce, "pr");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto int Riak\Input\GetInput->getPR()
-Get PR value */
-PHP_METHOD(Riak_Input_GetInput, getPR)
-{
-    RIAK_GETTER_BOOL(riak_get_input_ce, "pr");
-}
-/* }}} */
-
-/* {{{ proto bool Riak\Input\GetInput->getBasicQuorum()
-Get basicQuerum */
-PHP_METHOD(Riak_Input_GetInput, getBasicQuorum)
-{
-    RIAK_GETTER_BOOL(riak_get_input_ce, "basicQuorum");
-}
-/* }}} */
-
-/* {{{ proto Riak\Input\GetInput Riak\Input\GetInput->setBasicQuorum(bool $basicQuorum)
-Set basicQuerum value */
-PHP_METHOD(Riak_Input_GetInput, setBasicQuorum)
-{
-    RIAK_SETTER_BOOL(riak_get_input_ce, "basicQuorum");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto bool Riak\Input\GetInput->getNotFoundOk()
-Get not found ok */
-PHP_METHOD(Riak_Input_GetInput, getNotFoundOk)
-{
-    RIAK_GETTER_BOOL(riak_get_input_ce, "notFoundOk");
-}
-/* }}} */
-
-/* {{{ proto Riak\Input\GetInput Riak\Input\GetInput->setNotFoundOk(bool $notFoundOk)
-Set not found ok */
-PHP_METHOD(Riak_Input_GetInput, setNotFoundOk)
-{
-    RIAK_SETTER_BOOL(riak_get_input_ce, "notFoundOk");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto string Riak\Input\GetInput->getIfModifiedVClock()
-Get IfModifiedVClock */
-PHP_METHOD(Riak_Input_GetInput, getIfModifiedVClock)
-{
-    RIAK_GETTER_STRING(riak_get_input_ce, "ifModifiedVClock");
-}
-/* }}} */
-
-/* {{{ proto Riak\Input\GetInput Riak\Input\GetInput->setIfModifiedVClock(string $ifModifiedVClock)
-Set IfModifiedVClock */
-PHP_METHOD(Riak_Input_GetInput, setIfModifiedVClock)
-{
-    RIAK_SETTER_STRING(riak_get_input_ce, "ifModifiedVClock");
-    RIAK_RETURN_THIS
-}
-
-/* {{{ proto bool Riak\Input\GetInput->getReturnDeletedVClock()
-Get returns deleted vclock */
-PHP_METHOD(Riak_Input_GetInput, getReturnDeletedVClock)
-{
-    RIAK_GETTER_BOOL(riak_get_input_ce, "deletedVClock");
-}
-/* }}} */
-
-/* {{{ proto Riak\Input\GetInput Riak\Input\GetInput->setReturnDeletedVClock(bool $returnDeletedVClock)
-Set returnDeletedVClock */
-PHP_METHOD(Riak_Input_GetInput, setReturnDeletedVClock)
-{
-    RIAK_SETTER_BOOL(riak_get_input_ce, "deletedVClock");
-    RIAK_RETURN_THIS
-}
diff --git a/req_inputs.h b/req_inputs.h
deleted file mode 100644
index b00603d..0000000
--- a/req_inputs.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-   Copyright 2013 Kaspar Bach Pedersen
-
-   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.
-*/
-
-#ifndef RIAK_REQ_CONFIGS__H__
-#define RIAK_REQ_CONFIGS__H__
-
-#include <php.h>
-#include <riack.h>
-
-extern zend_class_entry *riak_get_input_ce;
-extern zend_class_entry *riak_put_input_ce;
-extern zend_class_entry *riak_delete_input_ce;
-
-void riak_req_inputs_init(TSRMLS_D);
-
-/* Riak\Input\GetInput */
-PHP_METHOD(Riak_Input_GetInput, setReturnHead);
-PHP_METHOD(Riak_Input_GetInput, getReturnHead);
-PHP_METHOD(Riak_Input_GetInput, getR);
-PHP_METHOD(Riak_Input_GetInput, setR);
-PHP_METHOD(Riak_Input_GetInput, getPR);
-PHP_METHOD(Riak_Input_GetInput, setPR);
-PHP_METHOD(Riak_Input_GetInput, getBasicQuorum);
-PHP_METHOD(Riak_Input_GetInput, setBasicQuorum);
-PHP_METHOD(Riak_Input_GetInput, getNotFoundOk);
-PHP_METHOD(Riak_Input_GetInput, setNotFoundOk);
-PHP_METHOD(Riak_Input_GetInput, getIfModifiedVClock);
-PHP_METHOD(Riak_Input_GetInput, setIfModifiedVClock);
-PHP_METHOD(Riak_Input_GetInput, getReturnDeletedVClock);
-PHP_METHOD(Riak_Input_GetInput, setReturnDeletedVClock);
-
-/* Riak\Input\PutInput */
-PHP_METHOD(Riak_Input_PutInput, setReturnHead);
-PHP_METHOD(Riak_Input_PutInput, getReturnHead);
-PHP_METHOD(Riak_Input_PutInput, getW);
-PHP_METHOD(Riak_Input_PutInput, setW);
-PHP_METHOD(Riak_Input_PutInput, getDW);
-PHP_METHOD(Riak_Input_PutInput, setDW);
-PHP_METHOD(Riak_Input_PutInput, getPW);
-PHP_METHOD(Riak_Input_PutInput, setPW);
-PHP_METHOD(Riak_Input_PutInput, getVClock);
-PHP_METHOD(Riak_Input_PutInput, setVClock);
-PHP_METHOD(Riak_Input_PutInput, getReturnBody);
-PHP_METHOD(Riak_Input_PutInput, setReturnBody);
-PHP_METHOD(Riak_Input_PutInput, getIfNoneMatch);
-PHP_METHOD(Riak_Input_PutInput, setIfNoneMatch);
-PHP_METHOD(Riak_Input_PutInput, getIfNotModified);
-PHP_METHOD(Riak_Input_PutInput, setIfNotModified);
-
-/* Riak\Input\DeleteInput */
-PHP_METHOD(Riak_Input_DeleteInput, setR);
-PHP_METHOD(Riak_Input_DeleteInput, getR);
-PHP_METHOD(Riak_Input_DeleteInput, setPR);
-PHP_METHOD(Riak_Input_DeleteInput, getPR);
-PHP_METHOD(Riak_Input_DeleteInput, setRW);
-PHP_METHOD(Riak_Input_DeleteInput, getRW);
-PHP_METHOD(Riak_Input_DeleteInput, setW);
-PHP_METHOD(Riak_Input_DeleteInput, getW);
-PHP_METHOD(Riak_Input_DeleteInput, setDW);
-PHP_METHOD(Riak_Input_DeleteInput, getDW);
-PHP_METHOD(Riak_Input_DeleteInput, setPW);
-PHP_METHOD(Riak_Input_DeleteInput, getPW);
-PHP_METHOD(Riak_Input_DeleteInput, setVClock);
-PHP_METHOD(Riak_Input_DeleteInput, getVClock);
-
-#endif
diff --git a/req_outputs.c b/req_outputs.c
deleted file mode 100644
index d72c4ff..0000000
--- a/req_outputs.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
-   Copyright 2013: Kaspar Pedersen
-
-   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.
-*/
-
-#include "req_outputs.h"
-#include "php_riak.h"
-#include "object.h"
-
-zend_class_entry *riak_output_ce;
-zend_class_entry *riak_get_output_ce;
-zend_class_entry *riak_put_output_ce;
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_output_noargs, 0, ZEND_RETURN_VALUE, 0)
-ZEND_END_ARG_INFO()
-
-static zend_function_entry riak_output_methods[] = {
-    PHP_ME(Riak_Output_Output, getObjectList, arginfo_riak_output_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Output_Output, getVClock, arginfo_riak_output_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Output_Output, getKey, arginfo_riak_output_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Output_Output, hasSiblings, arginfo_riak_output_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Output_Output, hasObject, arginfo_riak_output_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Output_Output, getFirstObject, arginfo_riak_output_noargs, ZEND_ACC_PUBLIC)
-    {NULL, NULL, NULL}
-};
-
-static zend_function_entry riak_get_output_methods[] = {
-    PHP_ME(Riak_Output_GetOutput, isUnchanged, arginfo_riak_output_noargs, ZEND_ACC_PUBLIC)
-    {NULL, NULL, NULL}
-};
-
-static zend_function_entry riak_put_output_methods[] = {
-    {NULL, NULL, NULL}
-};
-
-void riak_req_outputs_init(TSRMLS_D)/* {{{ */
-{
-    zend_class_entry ce;
-
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\Output", "Output", riak_output_methods);
-    riak_output_ce = zend_register_internal_class(&ce TSRMLS_CC);
-    zend_declare_property_null(riak_output_ce, "vClock", sizeof("vClock")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_output_ce, "objectList", sizeof("objectList")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_output_ce, "key", sizeof("key")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\Output", "GetOutput", riak_get_output_methods);
-    riak_get_output_ce = zend_register_internal_class_ex(&ce, riak_output_ce, NULL TSRMLS_CC);
-    zend_declare_property_null(riak_get_output_ce, "unchanged", sizeof("unchanged")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\Output", "PutOutput", riak_put_output_methods);
-    riak_put_output_ce = zend_register_internal_class_ex(&ce, riak_output_ce, NULL TSRMLS_CC);
-}
-/* }}} */
-
-void riak_set_output_properties(zval* zoutput, zval* zkey, struct RIACK_OBJECT* obj TSRMLS_DC) /* {{{ */
-{
-    size_t content_cnt, i;
-    zval *zobjectlist;
-    if (obj->vclock.len > 0) {
-        zend_update_property_stringl(riak_output_ce, zoutput, "vClock", sizeof("vClock")-1,
-                                     (char*)obj->vclock.clock, obj->vclock.len TSRMLS_CC);
-    }
-    if (Z_TYPE_P(zkey) == IS_STRING) {
-        zend_update_property_stringl(riak_output_ce, zoutput, "key", sizeof("key")-1,
-                                     Z_STRVAL_P(zkey), Z_STRLEN_P(zkey) TSRMLS_CC);
-    }
-    MAKE_STD_ZVAL(zobjectlist);
-    array_init(zobjectlist);
-    content_cnt = obj->content_count;
-    for (i=0; i<content_cnt; ++i) {
-        // Create a new Riak\Object for each content
-        zval *zobject;
-        MAKE_STD_ZVAL(zobject);
-        object_init_ex(zobject, riak_object_ce);
-        if (Z_TYPE_P(zkey) != IS_NULL) {
-            RIAK_CALL_METHOD1(RiakObject, __construct, zobject, zobject, zkey);
-        } else {
-            RIAK_CALL_METHOD(RiakObject, __construct, zobject, zobject);
-        }
-        set_object_from_riak_content(zobject, &obj->content[i] TSRMLS_CC);
-        add_next_index_zval(zobjectlist, zobject);
-    }
-    zend_update_property(riak_output_ce, zoutput, "objectList", sizeof("objectList")-1, zobjectlist TSRMLS_CC);
-    zval_ptr_dtor(&zobjectlist);
-}
-/* }}} */
-
-zval *put_output_from_riack_object(struct RIACK_OBJECT* obj, zval* zkey TSRMLS_DC) /* {{{ */
-{
-    zval *zoutput;
-    MAKE_STD_ZVAL(zoutput);
-    object_init_ex(zoutput, riak_put_output_ce);
-    riak_set_output_properties(zoutput, zkey, obj TSRMLS_CC);
-    return zoutput;
-}
-/* }}} */
-
-zval *get_output_from_riack_get_object(struct RIACK_GET_OBJECT* getobj, zval* zkey TSRMLS_DC) /* {{{ */
-{
-    zval *zoutput;
-    MAKE_STD_ZVAL(zoutput);
-    object_init_ex(zoutput, riak_get_output_ce);
-    if (getobj->unchanged_present) {
-        zend_update_property_bool(riak_get_output_ce, zoutput, "unchanged", sizeof("unchanged")-1, getobj->unchanged TSRMLS_CC);
-    }
-    riak_set_output_properties(zoutput, zkey, &getobj->object TSRMLS_CC);
-    return zoutput;
-}
-/* }}} */
-
-/*************************************************************
-* Implementation: Riak\Output\Output
-*************************************************************/
-
-/* {{{ proto Riak\Object[] Riak\Output\Output->getObjectList()
-Get list of returned objects */
-PHP_METHOD(Riak_Output_Output, getObjectList)
-{
-    RIAK_GETTER_ARRAY(riak_output_ce, "objectList")
-}
-/* }}} */
-
-/* {{{ proto string|null Riak\Output\Output->getVClock()
-Get vclock from riak if present */
-PHP_METHOD(Riak_Output_Output, getVClock)
-{
-    RIAK_GETTER_STRING(riak_output_ce, "vClock")
-}
-/* }}} */
-
-/* {{{ proto string|null Riak\Output\Output->getKey()
-Get key if present */
-PHP_METHOD(Riak_Output_Output, getKey)
-{
-    RIAK_GETTER_STRING(riak_output_ce, "key")
-}
-/* }}} */
-
-
-/* {{{ proto bool|null Riak\Output\Output->hasSiblings()
-Does this output have multiple objects */
-PHP_METHOD(Riak_Output_Output, hasSiblings)
-{
-    zval* zlist = zend_read_property(riak_output_ce, getThis(), "objectList", sizeof("objectList")-1, 1 TSRMLS_CC);
-    if (Z_TYPE_P(zlist) == IS_ARRAY) {
-        int elems = zend_hash_num_elements(Z_ARRVAL_P(zlist));
-        if (elems > 1) {
-            RETURN_BOOL(1);
-        }
-    }
-    RETURN_BOOL(0);
-}
-/* }}} */
-
-/* {{{ proto bool Riak\Output\Output->hasObject()
-Does this output have atleast one object */
-PHP_METHOD(Riak_Output_Output, hasObject)
-{
-    zval* zlist = zend_read_property(riak_output_ce, getThis(), "objectList", sizeof("objectList")-1, 1 TSRMLS_CC);
-    if (Z_TYPE_P(zlist) == IS_ARRAY) {
-        int elems = zend_hash_num_elements(Z_ARRVAL_P(zlist));
-        if (elems > 0) {
-            RETURN_BOOL(1);
-        }
-    }
-    RETURN_BOOL(0);
-}
-/* }}} */
-
-/* {{{ proto Riak\Object|null Riak\Output\Output->getFirstObject()
-Get first object in objectlist */
-PHP_METHOD(Riak_Output_Output, getFirstObject)
-{
-    // TODO
-    zval* zlist = zend_read_property(riak_output_ce, getThis(), "objectList", sizeof("objectList")-1, 1 TSRMLS_CC);
-    if (Z_TYPE_P(zlist) == IS_ARRAY) {
-        int elems = zend_hash_num_elements(Z_ARRVAL_P(zlist));
-        if (elems > 0) {
-            zval **zfirst;
-            if (zend_hash_index_find(Z_ARRVAL_P(zlist), 0, (void**)&zfirst) == SUCCESS) {
-                RETURN_ZVAL(*zfirst, 1, 0);
-            }
-        }
-    }
-    RETURN_NULL();
-}
-/* }}} */
-
-
-/*************************************************************
-* Implementation: Riak\Output\GetOutput
-*************************************************************/
-
-/* {{{ proto bool|null Riak\Output\GetOutput->isUnchanged()
-Is unchanged */
-PHP_METHOD(Riak_Output_GetOutput, isUnchanged)
-{
-    zval* zunc = zend_read_property(riak_get_output_ce, getThis(), "unchanged", sizeof("unchanged")-1, 1 TSRMLS_CC);
-    if (Z_TYPE_P(zunc) == IS_BOOL) {
-        RETURN_BOOL(Z_BVAL_P(zunc));
-    }
-    RETURN_BOOL(0);
-}
-/* }}} */
diff --git a/riack b/riack
deleted file mode 160000
index 6d1d45b..0000000
--- a/riack
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 6d1d45b8a711aa791685410f301311b234b94827
diff --git a/riak/bucket.c b/riak/bucket.c
new file mode 100644
index 0000000..b9cbd19
--- /dev/null
+++ b/riak/bucket.c
@@ -0,0 +1,1179 @@
+/*
+   Copyright 2013 Trifork A/S
+   Author: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#include "bucket.h"
+#include "bucket_properties.h"
+#include "property/commit_hook.h"
+#include "property/commit_hook_list.h"
+#include "property/module_function.h"
+#include "property/replication_mode/replication_mode.h"
+#include "input/delete_input.h"
+#include "input/get_input.h"
+#include "input/put_input.h"
+#include "exception/exception.h"
+#include "object.h"
+#include "output/output.h"
+#include "output/put_output.h"
+#include "output/get_output.h"
+#include "riak/output/conflict_resolver.h"
+#include "riak/input/get_resolver_input.h"
+#include "output/index_output.h"
+#include "input/index_input.h"
+#include "query/index_query.h"
+#include "output/key_stream_output.h"
+#include "crdt/counter.h"
+#include "zend_interfaces.h"
+#include <ext/spl/spl_iterators.h>
+#include <ext/spl/spl_array.h>
+
+riak_connection *get_riak_connection(zval *zbucket TSRMLS_DC);
+
+zend_class_entry *riak_bucket_ce;
+
+#define RIAK_REQ_PROP_SET_LONG(CLASS_ALIAS, ZV, GETTER, TARGET) \
+    RIAK_CALL_METHOD(CLASS_ALIAS, GETTER, &ZV, zinput); \
+    if (Z_TYPE(ZV) == IS_LONG) { TARGET##_use = 1; TARGET = Z_LVAL(ZV); }
+
+#define RIAK_REQ_PROP_SET_BOOL(CLASS_ALIAS, ZV, GETTER, TARGET) \
+    RIAK_CALL_METHOD(CLASS_ALIAS, GETTER, &ZV, zinput); \
+    if (Z_TYPE(ZV) == IS_BOOL && Z_BVAL(ZV)) { TARGET##_use = TARGET = 1; }
+
+#define RIAK_GET_STR_COPY_TO(CLASSNAME, GETTER, ZOBJ, TARGET, TARGET_LEN) { \
+    zval *z_getter_res; MAKE_STD_ZVAL(z_getter_res); \
+    RIAK_CALL_METHOD(CLASSNAME, GETTER, z_getter_res, ZOBJ); \
+    if (Z_TYPE_P(z_getter_res) == IS_STRING && Z_STRLEN_P(z_getter_res) > 0) { \
+        RMALLOCCOPY(connection->client, TARGET, TARGET_LEN, Z_STRVAL_P(z_getter_res), Z_STRLEN_P(z_getter_res)); \
+    } \
+    zval_ptr_dtor(&z_getter_res); }
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_ctor, 0, ZEND_RETURN_VALUE, 2)
+    ZEND_ARG_INFO(0, client)
+    ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_put, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, object)
+    ZEND_ARG_INFO(0, putInput)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_get, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, key)
+    ZEND_ARG_INFO(0, getInput)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_delete, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, object)
+    ZEND_ARG_INFO(0, delInput)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_fetchprops, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_applyprops, 0, ZEND_RETURN_VALUE, 1)
+	ZEND_ARG_INFO(0, bucket_properties)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_set_conflictresolver, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_OBJ_INFO(0, resolver, Riak\\Output\\ConflictResolver, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_indexq, 0, ZEND_RETURN_VALUE, 2)
+    ZEND_ARG_INFO(0, index)
+    ZEND_ARG_INFO(0, from)
+    ZEND_ARG_INFO(0, to)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_indexq_ext, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, query)
+    ZEND_ARG_INFO(0, input)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_streamkeys, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, keystreamer)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_counter, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, key)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_bucket_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_bucket_methods[] = {
+    PHP_ME(RiakBucket, __construct, arginfo_bucket_ctor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+    PHP_ME(RiakBucket, put, arginfo_bucket_put, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakBucket, get, arginfo_bucket_get, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakBucket, delete, arginfo_bucket_delete, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakBucket, index, arginfo_bucket_indexq, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakBucket, indexQuery, arginfo_bucket_indexq_ext, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakBucket, counter, arginfo_bucket_counter, ZEND_ACC_PUBLIC)
+
+    PHP_ME(RiakBucket, getPropertyList, arginfo_bucket_fetchprops, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakBucket, setPropertyList, arginfo_bucket_applyprops, ZEND_ACC_PUBLIC)
+
+    PHP_ME(RiakBucket, getConflictResolver, arginfo_riak_bucket_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakBucket, setConflictResolver, arginfo_bucket_set_conflictresolver, ZEND_ACC_PUBLIC)
+
+    PHP_ME(RiakBucket, getKeyStream, arginfo_bucket_streamkeys, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakBucket, getKeyList, arginfo_riak_bucket_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakBucket, getName, arginfo_riak_bucket_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakBucket, getConnection, arginfo_riak_bucket_noargs, ZEND_ACC_PUBLIC)
+	{NULL, NULL, NULL}
+};
+
+void riak_bucket_init(TSRMLS_D) /* {{{ */
+{
+	zend_class_entry ce;
+
+    INIT_NS_CLASS_ENTRY(ce, "Riak", "Bucket", riak_bucket_methods);
+	riak_bucket_ce = zend_register_internal_class(&ce TSRMLS_CC);
+
+    zend_declare_property_null(riak_bucket_ce, "name", sizeof("name")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_bucket_ce, "connection", sizeof("connection")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_bucket_ce, "type", sizeof("type")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_bucket_ce, "conflictResolver", sizeof("conflictResolver")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+}
+/* }}} */
+
+zval* create_bucket_object(zval* zclient, char* name, int name_len TSRMLS_DC) /* {{{ */
+{
+	zval *zbucket, *zname;
+	MAKE_STD_ZVAL(zbucket);
+	MAKE_STD_ZVAL(zname);
+
+    ZVAL_STRINGL(zname, name, name_len, 1);
+
+	object_init_ex(zbucket, riak_bucket_ce);
+	RIAK_CALL_METHOD2(RiakBucket, __construct, zbucket, zbucket, zclient, zname);
+
+	zval_ptr_dtor(&zname);
+	return zbucket;
+}
+/* }}} */
+
+/* {{{ proto void Riak\Bucket->__construct(Riak\Connection $connection, string $name)
+Create a new Riak\Bucket */
+PHP_METHOD(RiakBucket, __construct)
+{
+    char *name, *type;
+    int nameLen, typeLen;
+    zval* zconnection;
+    type = NULL;
+    typeLen = 0;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os|s",
+                              &zconnection, riak_connection_ce, &name, &nameLen, &type, &typeLen) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+		return;
+	}
+	zend_update_property_stringl(riak_bucket_ce, getThis(), "name", sizeof("name")-1, name, nameLen TSRMLS_CC);
+    zend_update_property(riak_bucket_ce, getThis(), "connection", sizeof("connection")-1, zconnection TSRMLS_CC);
+    if (type != NULL && typeLen > 0) {
+        zend_update_property(riak_bucket_ce, getThis(), "type", sizeof("type")-1, zconnection TSRMLS_CC);
+    }
+}
+/* }}} */
+
+struct riak_stream_key_cb_param {/* {{{ */
+#ifdef ZTS
+    TSRMLS_D;
+#endif
+    zval *zstreamer;
+};
+/* }}} */
+
+void riak_stream_key_cb(riack_client* c, void* p, riack_string key) {/* {{{ */
+    zval *zkey, zret, zfuncname;
+
+    struct riak_stream_key_cb_param *param = (struct riak_stream_key_cb_param*)p;
+    MAKE_STD_ZVAL(zkey);
+    ZVAL_STRINGL(zkey, key.value, key.len, 1);
+    ZVAL_STRING(&zfuncname, "process", 0);
+#ifdef ZTS
+    call_user_function(NULL, &param->zstreamer, &zfuncname, &zret, 1, &zkey, param->tsrm_ls);
+#else
+    call_user_function(NULL, &param->zstreamer, &zfuncname, &zret, 1, &zkey);
+#endif
+
+    zval_ptr_dtor(&zkey);
+}
+/* }}} */
+
+/* {{{ proto void Riak\Bucket->getKeyStream(Riak\Output\KeyStreamOutput streamer [, int $timeout = 0])
+Streams all keys in the bucket */
+PHP_METHOD(RiakBucket, getKeyStream)
+{
+    struct riak_stream_key_cb_param cb_params;
+    riack_string rsbucket, *rstype;
+    riak_connection *connection, *stream_connection;
+    zval* zstreamer;
+    long timeout;
+    int riackstatus;
+    timeout = 0;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|l", &zstreamer, riak_key_streamer_ce, &timeout) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    // Create a new connection only for this stream
+    // LibRiack can only handle one operation at the time pr connection
+    connection = get_riak_connection(getThis() TSRMLS_CC);
+
+    THROW_EXCEPTION_IF_CONNECTION_IS_NULL(connection);
+
+    stream_connection = take_connection(connection->client->host, strlen(connection->client->host), connection->client->port TSRMLS_CC);
+    if (!stream_connection) {
+        CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(stream_connection, RIACK_ERROR_COMMUNICATION);
+    }
+    rsbucket = riack_name_from_bucket(getThis() TSRMLS_CC);
+#ifdef ZTS
+    cb_params.tsrm_ls = TSRMLS_C;
+#endif
+    cb_params.zstreamer = zstreamer;
+    rstype = riack_get_bucket_type_from_bucket(connection->client, getThis() TSRMLS_CC);
+    // Not gonna do a retry here on purpose... no reason to retry a mistake in the first place
+    riackstatus = riack_stream_keys_ext(stream_connection->client, &rsbucket, rstype, riak_stream_key_cb, &cb_params, timeout);
+    CHECK_RIACK_STATUS_THROW_ON_ERROR(stream_connection, riackstatus);
+    RFREE(connection->client, rstype);
+    release_connection(stream_connection TSRMLS_CC);
+}
+/* }}} */
+
+
+/* {{{ proto string[] Riak\Bucket->getKeyList([int $timeout = 0])
+List all keys in the bucket */
+PHP_METHOD(RiakBucket, getKeyList)
+{
+    riack_string_linked_list* resultlist, *curr;
+    riack_string rsbucket, *rstype;
+    riak_connection *connection;
+    zval* zresultarr;
+    long timeout;
+    int riackstatus;
+    timeout = 0;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &timeout) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    connection = get_riak_connection(getThis() TSRMLS_CC);
+    rsbucket   = riack_name_from_bucket(getThis() TSRMLS_CC);
+
+    THROW_EXCEPTION_IF_CONNECTION_IS_NULL(connection);
+    rstype = riack_get_bucket_type_from_bucket(connection->client, getThis() TSRMLS_CC);
+
+    // Not gonna do a retry here on purpose... no reason to retry a mistake in the first place
+    riackstatus = riack_list_keys_ext(connection->client, &rsbucket, rstype, &resultlist, timeout);
+    RFREE(connection->client, rstype);
+
+    CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, riackstatus);
+
+    MAKE_STD_ZVAL(zresultarr);
+    array_init(zresultarr);
+    curr = resultlist;
+    while (curr) {
+        add_next_index_stringl(zresultarr, curr->string.value, curr->string.len, 1);
+        curr = curr->next;
+    }
+    riack_free_string_linked_list_p(connection->client, &resultlist);
+
+    RETURN_ZVAL(zresultarr, 0, 1);
+}
+/* }}} */
+
+
+/* {{{ proto Riak\Crdt\Counter Riak\Bucket->counter(string $key)
+Creates a new counter on this bucket */
+PHP_METHOD(RiakBucket, counter)
+{
+    zval *zcounter, *zkey;
+    char *key;
+    int keylen;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &key, &keylen) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    MAKE_STD_ZVAL(zkey);
+    ZVAL_STRINGL(zkey, key, keylen, 1);
+
+    MAKE_STD_ZVAL(zcounter);
+    object_init_ex(zcounter, riak_crdt_counter_ce);
+    RIAK_CALL_METHOD2(Riak_Crdt_Counter, __construct, NULL, zcounter, getThis(), zkey);
+
+    zval_ptr_dtor(&zkey);
+
+    RETURN_ZVAL(zcounter, 0, 1);
+}
+
+/* {{{ proto array Riak\Bucket->index(string $index, string $from [, string $to])
+Perform a secondary index lookup */
+PHP_METHOD(RiakBucket, index)
+{
+    riack_string rsbucket, rsindex, rsfrom, rsto, *type;
+    riack_string_list *resultlist;
+    char *index, *from, *to;
+    int indexlen, fromlen, tolen, riackstatus, i;
+    riak_connection *connection;
+    zval *zresult;
+    tolen = 0; to = NULL;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|s", &index, &indexlen, &from, &fromlen, &to, &tolen) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    connection = get_riak_connection(getThis() TSRMLS_CC);
+    rsbucket = riack_name_from_bucket(getThis() TSRMLS_CC);
+    type = riack_get_bucket_type_from_bucket(connection->client, getThis() TSRMLS_CC);
+    THROW_EXCEPTION_IF_CONNECTION_IS_NULL(connection);
+
+    rsindex.len = indexlen;
+    rsindex.value = index;
+    rsfrom.len = fromlen;
+    rsfrom.value = from;
+    if (to != NULL && tolen > 0) {
+        rsto.len = tolen;
+        rsto.value = to;
+        RIACK_RETRY_OP(riackstatus, connection, riack_2i_query_range_ext(connection->client,
+                &rsbucket, type, &rsindex, &rsfrom, &rsto, &resultlist));
+    } else {
+        RIACK_RETRY_OP(riackstatus, connection, riack_2i_query_exact_ext(connection->client,
+                &rsbucket, type, &rsindex, &rsfrom, &resultlist));
+    }
+    RFREE(connection->client, type);
+    CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, riackstatus);
+
+    MAKE_STD_ZVAL(zresult);
+    array_init(zresult);
+    for (i=0; i<resultlist->string_count; ++i) {
+        add_next_index_stringl(zresult, resultlist->strings[i].value, resultlist->strings[i].len, 1);
+    }
+    riack_free_string_list_p(connection->client, &resultlist);
+    RETURN_ZVAL(zresult, 0, 1);
+}
+/* }}} */
+
+
+/* {{{ proto array Riak\Bucket->indexQuery(IndexQuery $query[, IndexInput $input])
+Apply given properties to this bucket */
+PHP_METHOD(RiakBucket, indexQuery)
+{
+    riak_connection *connection;
+    riack_2i_query_req req;
+    riack_string_list *result_keys;
+    riack_string *continuation, *type;
+    zval *zquery, *zinput, *zname, *zisrange, *zcontinuation, *zresult;
+    int riackstatus;
+
+    zinput = zquery = 0;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|O", &zquery, riak_index_query_ce, &zinput, riak_index_input_ce) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    // TODO Validate query have exact or ranged values
+    connection = get_riak_connection(getThis() TSRMLS_CC);
+    THROW_EXCEPTION_IF_CONNECTION_IS_NULL(connection);
+
+    memset(&req, 0, sizeof(req));
+    type = riack_get_bucket_type_from_bucket(connection->client, getThis() TSRMLS_CC);
+    if (type != NULL) {
+        req.bucket_type.len = type->len;
+        req.bucket_type.value = type->value;
+    }
+    req.bucket = riack_name_from_bucket(getThis() TSRMLS_CC);
+
+    MAKE_STD_ZVAL(zname);
+    RIAK_CALL_METHOD(Riak_Query_IndexQuery, getName, zname, zquery);
+    req.index.len = Z_STRLEN_P(zname);
+    req.index.value = Z_STRVAL_P(zname);
+
+    continuation = NULL;
+    zcontinuation = NULL;
+    if (zinput) {
+        zval *zmaxresults;
+        MAKE_STD_ZVAL(zmaxresults);
+        RIAK_CALL_METHOD(Riak_Input_IndexInput, getMaxResults, zmaxresults, zinput);
+        if (Z_TYPE_P(zmaxresults) == IS_LONG) {
+            req.max_results = Z_LVAL_P(zmaxresults);
+        }
+        zval_ptr_dtor(&zmaxresults);
+
+        MAKE_STD_ZVAL(zcontinuation);
+        RIAK_CALL_METHOD(Riak_Input_IndexInput, getContinuation, zcontinuation, zinput);
+        if (Z_TYPE_P(zcontinuation) == IS_STRING) {
+            req.continuation_token.len = Z_STRLEN_P(zcontinuation);
+            req.continuation_token.value = Z_STRVAL_P(zcontinuation);
+        }
+    }
+    MAKE_STD_ZVAL(zisrange);
+    RIAK_CALL_METHOD(Riak_Query_IndexQuery, isRangeQuery, zisrange, zquery);
+    if (Z_BVAL_P(zisrange)) {
+        zval *zmin, *zmax;
+        // TODO Call getter instead, this is cheat
+        zmin = zend_read_property(riak_index_query_ce, zquery, "minValue", sizeof("minValue")-1, 1 TSRMLS_CC);
+        zmax = zend_read_property(riak_index_query_ce, zquery, "maxValue", sizeof("maxValue")-1, 1 TSRMLS_CC);
+        req.search_min.len = Z_STRLEN_P(zmin);
+        req.search_min.value = Z_STRVAL_P(zmin);
+        req.search_max.len = Z_STRLEN_P(zmax);
+        req.search_max.value = Z_STRVAL_P(zmax);
+        RIACK_RETRY_OP(riackstatus, connection, riack_2i_query(connection->client, &req, &result_keys, &continuation));
+    } else {
+        zval *zexact;
+        zexact = zend_read_property(riak_index_query_ce, zquery, "exactValue", sizeof("exactValue")-1, 1 TSRMLS_CC);
+        req.search_exact.len = Z_STRLEN_P(zexact);
+        req.search_exact.value = Z_STRVAL_P(zexact);
+        RIACK_RETRY_OP(riackstatus, connection, riack_2i_query(connection->client, &req, &result_keys, &continuation));
+    }
+    zval_ptr_dtor(&zname);
+    zval_ptr_dtor(&zisrange);
+    if (zcontinuation) {
+        zval_ptr_dtor(&zcontinuation);
+    }
+    RFREE(connection->client, type);
+    CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, riackstatus);
+    zresult = riak_index_output_from_string_list_and_continuation(result_keys, continuation TSRMLS_CC);
+    riack_free_string_p(connection->client, &continuation);
+    riack_free_string_list_p(connection->client, &result_keys);
+    RETURN_ZVAL(zresult, 0, 1);
+}
+/* }}} */
+
+/* {{{ */
+void riak_set_riack_commit_hook(riak_connection *connection, zval* zhook, riack_commit_hook* hook TSRMLS_DC)
+{
+    zval *zjs;
+    memset(hook, 0, sizeof(riack_commit_hook));
+    MAKE_STD_ZVAL(zjs);
+    RIAK_CALL_METHOD(RiakCommitHook, isJavascript, zjs, zhook);
+    if (Z_BVAL_P(zjs)) {
+        RIAK_GET_STR_COPY_TO(RiakCommitHook, getJsName, zhook, hook->name.value, hook->name.len);
+    } else {
+        RIAK_GET_STR_COPY_TO(RiakCommitHook, getErlModule, zhook, hook->modfun.module.value, hook->modfun.module.len);
+        RIAK_GET_STR_COPY_TO(RiakCommitHook, getErlFunction, zhook, hook->modfun.function.value, hook->modfun.function.len);
+    }
+    zval_ptr_dtor(&zjs);
+}
+/* }}} */
+
+/* {{{ */
+void riak_set_commit_hooks_properties(riak_connection *connection, zval *zhook_list,  uint8_t *has_hooks,
+                                      size_t* hook_count, riack_commit_hook** hooks TSRMLS_DC)
+{
+    *has_hooks = 0;
+    *hook_count = 0;
+    if (Z_TYPE_P(zhook_list) != IS_NULL && Z_TYPE_P(zhook_list) == IS_OBJECT) {
+        zval *ziter, *zcount;
+        MAKE_STD_ZVAL(zcount);
+        RIAK_CALL_METHOD(RiakCommitHookList, count, zcount, zhook_list)
+
+        MAKE_STD_ZVAL(ziter);
+        object_init(ziter);
+        RIAK_CALL_METHOD(RiakCommitHookList, getIterator, ziter, zhook_list)
+        if (Z_TYPE_P(zcount) == IS_LONG && Z_TYPE_P(ziter) == IS_OBJECT) {
+            zval zcurrname, znextname, zvalidname;
+            zend_bool done;
+            int i=0;
+            *has_hooks = 1;
+            *hook_count = Z_LVAL_P(zcount);
+            *hooks = RMALLOC(connection->client, sizeof(riack_commit_hook) * Z_LVAL_P(zcount));
+
+            ZVAL_STRING(&zcurrname, "current", 0);
+            ZVAL_STRING(&znextname, "next", 0);
+            ZVAL_STRING(&zvalidname, "valid", 0);
+
+            done = 0;
+            while (!done) {
+                zval* zvalid;
+                MAKE_STD_ZVAL(zvalid);
+                call_user_function(NULL, &ziter, &zvalidname, zvalid, 0, NULL TSRMLS_CC);
+                if (Z_TYPE_P(zvalid) == IS_BOOL && Z_BVAL_P(zvalid)) {
+                    zval *zhook;
+                    MAKE_STD_ZVAL(zhook)
+                    call_user_function(NULL, &ziter, &zcurrname, zhook, 0, NULL TSRMLS_CC);
+                    if (Z_TYPE_P(zhook) == IS_OBJECT) {
+                        zval zret;
+                        riak_set_riack_commit_hook(connection, zhook, &((*hooks)[i++]) TSRMLS_CC);
+                        call_user_function(NULL, &ziter, &znextname, &zret, 0, NULL TSRMLS_CC);
+                    }
+                    zval_ptr_dtor(&zhook);
+                } else {
+                    done = 1;
+                }
+                zval_ptr_dtor(&zvalid);
+
+            }
+        }
+        zval_ptr_dtor(&ziter);
+        zval_ptr_dtor(&zcount);
+    }
+}
+/* }}} */
+
+/* {{{ proto Riak\Bucket Riak\Bucket->setPropertyList(Riak\BucketProperties $properties)
+Apply given properties to this bucket */
+PHP_METHOD(RiakBucket, setPropertyList)
+{
+#define SET_PROPLIST_LONG(GETTER_NAME, PROP_NAME) MAKE_STD_ZVAL(ztmp); \
+                                                  RIAK_CALL_METHOD(RiakBucketProperties, GETTER_NAME, ztmp, zprop_obj); \
+                                                  if (Z_TYPE_P(ztmp) == IS_LONG) { \
+                                                      properties.PROP_NAME##_use = 1; \
+                                                      properties.PROP_NAME = Z_LVAL_P(ztmp); } \
+                                                  zval_ptr_dtor(&ztmp);
+#define SET_PROPLIST_BOOL(GETTER_NAME, PROP_NAME) MAKE_STD_ZVAL(ztmp); \
+                                                  RIAK_CALL_METHOD(RiakBucketProperties, GETTER_NAME, ztmp, zprop_obj); \
+                                                  if (Z_TYPE_P(ztmp) == IS_BOOL) { \
+                                                      properties.PROP_NAME##_use = 1; \
+                                                      properties.PROP_NAME = Z_BVAL_P(ztmp); } \
+                                                  zval_ptr_dtor(&ztmp);
+	riak_connection *connection;
+    riack_bucket_properties properties;
+    riack_string bucketName, *type;
+    zval *ztmp, *zprop_obj;
+	int riackResult;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zprop_obj, riak_bucket_properties_ce) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 501 TSRMLS_CC);
+		return;
+	}
+    memset(&properties, 0, sizeof(riack_bucket_properties));
+
+    connection = get_riak_connection(getThis() TSRMLS_CC);
+    bucketName = riack_name_from_bucket(getThis() TSRMLS_CC);
+
+    THROW_EXCEPTION_IF_CONNECTION_IS_NULL(connection);
+
+    SET_PROPLIST_LONG(getNValue, n_val);
+    SET_PROPLIST_BOOL(getAllowMult, allow_mult);
+
+    // 1.4+ below
+    SET_PROPLIST_BOOL(getLastWriteWins, last_write_wins);
+    SET_PROPLIST_LONG(getOldVClock, old_vclock);
+    SET_PROPLIST_LONG(getYoungVClock, young_vclock);
+    SET_PROPLIST_LONG(getSmallVClock, small_vclock);
+    SET_PROPLIST_LONG(getBigVClock, big_vclock);
+
+    SET_PROPLIST_LONG(getPR, pr);
+    SET_PROPLIST_LONG(getR, r);
+    SET_PROPLIST_LONG(getW, w);
+    SET_PROPLIST_LONG(getDW, dw);
+    SET_PROPLIST_LONG(getPW, pw);
+    SET_PROPLIST_LONG(getRW, rw);
+
+    SET_PROPLIST_BOOL(getBasicQuorum, basic_quorum);
+    SET_PROPLIST_BOOL(getNotFoundOk, notfound_ok);
+
+    SET_PROPLIST_BOOL(getSearchEnabled, search);
+    SET_PROPLIST_BOOL(isConsistent, consistent);
+
+    RIAK_GET_STR_COPY_TO(RiakBucketProperties, getBackend, zprop_obj, properties.backend.value, properties.backend.len);
+    RIAK_GET_STR_COPY_TO(RiakBucketProperties, getDatatype, zprop_obj, properties.datatype.value, properties.datatype.len);
+
+    MAKE_STD_ZVAL(ztmp);
+    RIAK_CALL_METHOD(RiakBucketProperties, getLinkFun, ztmp, zprop_obj);
+    if (Z_TYPE_P(ztmp) == IS_OBJECT) {
+        properties.linkfun_use = 1;
+        RIAK_GET_STR_COPY_TO(RiakModuleFunction, getFunction, ztmp,
+                             properties.linkfun.function.value, properties.linkfun.function.len);
+        RIAK_GET_STR_COPY_TO(RiakModuleFunction, getModule, ztmp,
+                             properties.linkfun.module.value, properties.linkfun.module.len);
+    }
+    zval_ptr_dtor(&ztmp);
+    MAKE_STD_ZVAL(ztmp);
+    RIAK_CALL_METHOD(RiakBucketProperties, getCHashKeyFun, ztmp, zprop_obj);
+    if (Z_TYPE_P(ztmp) == IS_OBJECT) {
+        properties.chash_keyfun_use = 1;
+        RIAK_GET_STR_COPY_TO(RiakModuleFunction, getFunction, ztmp,
+                             properties.chash_keyfun.function.value, properties.chash_keyfun.function.len);
+        RIAK_GET_STR_COPY_TO(RiakModuleFunction, getModule, ztmp,
+                             properties.chash_keyfun.module.value, properties.chash_keyfun.module.len);
+    }
+    zval_ptr_dtor(&ztmp);
+
+    MAKE_STD_ZVAL(ztmp);
+    RIAK_CALL_METHOD(RiakBucketProperties, getPreCommitHookList, ztmp, zprop_obj);
+    riak_set_commit_hooks_properties(connection, ztmp, &properties.has_precommit_hooks, &properties.precommit_hook_count,
+                                     &properties.precommit_hooks TSRMLS_CC);
+    zval_ptr_dtor(&ztmp);
+    MAKE_STD_ZVAL(ztmp);
+    RIAK_CALL_METHOD(RiakBucketProperties, getPostCommitHookList, ztmp, zprop_obj);
+    riak_set_commit_hooks_properties(connection, ztmp, &properties.has_postcommit_hooks, &properties.postcommit_hook_count,
+                                     &properties.postcommit_hooks TSRMLS_CC);
+    zval_ptr_dtor(&ztmp);
+
+    MAKE_STD_ZVAL(ztmp);
+    RIAK_CALL_METHOD(RiakBucketProperties, getReplicationMode, ztmp, zprop_obj);
+    if (Z_TYPE_P(ztmp) == IS_OBJECT) {
+        zend_class_entry *ce;
+        ce = Z_OBJCE_P(ztmp);
+        properties.replication_mode_use = 1;
+        if (instanceof_function(ce, riak_replication_mode_disabled_ce TSRMLS_CC)) {
+            properties.replication_mode = DISABLED;
+        } else if  (instanceof_function(ce, riak_replication_mode_full_only_ce TSRMLS_CC)) {
+            properties.replication_mode = FULLSYNC;
+        } else if (instanceof_function(ce, riak_replication_mode_realtime_and_full_ce TSRMLS_CC)) {
+            properties.replication_mode = REALTIME_AND_FULLSYNC;
+        } else if (instanceof_function(ce, riak_replication_mode_realtime_only_ce TSRMLS_CC)) {
+            properties.replication_mode = REALTIME;
+        } else {
+            properties.replication_mode_use = 0;
+        }
+    }
+    zval_ptr_dtor(&ztmp);
+
+    type = riack_get_bucket_type_from_bucket(connection->client, getThis() TSRMLS_CC);
+    RIACK_RETRY_OP(riackResult, connection, riack_set_bucket_props_ext(connection->client, &bucketName, type, &properties));
+
+    RSTR_SAFE_FREE(connection->client, properties.backend);
+    RSTR_SAFE_FREE(connection->client, properties.datatype);
+    RSTR_SAFE_FREE(connection->client, properties.linkfun.module);
+    RSTR_SAFE_FREE(connection->client, properties.linkfun.function);
+    RSTR_SAFE_FREE(connection->client, properties.chash_keyfun.module);
+    RSTR_SAFE_FREE(connection->client, properties.chash_keyfun.function);
+    RFREE(connection->client, type);
+    RFREE(connection->client, properties.precommit_hooks);
+    RFREE(connection->client, properties.postcommit_hooks);
+ 	CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, riackResult);
+
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+zval *riak_linkfun_from_riack(riack_module_function* modfun TSRMLS_DC) {
+    zval *zmodfun, *zmod, *zfunc;
+    MAKE_STD_ZVAL(zmodfun);
+
+    MAKE_STD_ZVAL(zmod);
+    ZVAL_STRINGL(zmod, modfun->module.value, modfun->module.len, 1);
+
+    MAKE_STD_ZVAL(zfunc);
+    ZVAL_STRINGL(zfunc, modfun->function.value, modfun->function.len, 1);
+
+    object_init_ex(zmodfun, riak_module_function_ce);
+    RIAK_CALL_METHOD2(RiakModuleFunction, __construct, NULL, zmodfun, zmod, zfunc)
+
+    zval_ptr_dtor(&zmod);
+    zval_ptr_dtor(&zfunc);
+    return zmodfun;
+}
+
+/* {{{ */
+zval* zhook_list_from_riack(size_t hook_count, riack_commit_hook *hooks TSRMLS_DC)
+{
+    zval *zhook_list;
+    size_t i;
+    MAKE_STD_ZVAL(zhook_list);
+    object_init_ex(zhook_list, riak_commit_hook_list_ce);
+    RIAK_CALL_METHOD(RiakCommitHookList, __construct, zhook_list, zhook_list);
+    for (i=0; i<hook_count; ++i) {
+        riack_commit_hook* current_hook;
+        zval* zhook, *zoffset;
+        current_hook = &hooks[i];
+
+        // Create hook
+        MAKE_STD_ZVAL(zhook);
+        object_init_ex(zhook, riak_commit_hook_ce);
+
+        if (RSTR_HAS_CONTENT(current_hook->name)) {
+            zval *zname;
+            // We have name so this is a js function
+            MAKE_STD_ZVAL(zname);
+            ZVAL_STRINGL(zname, current_hook->name.value, current_hook->name.len, 1);
+            RIAK_CALL_METHOD1(RiakCommitHook, __construct, zhook, zhook, zname);
+            zval_ptr_dtor(&zname);
+        } else {
+            zval *zmod, *zfun;
+            // No name present, so must be mod/fun
+            MAKE_STD_ZVAL(zfun);
+            MAKE_STD_ZVAL(zmod);
+            ZVAL_STRINGL(zfun, current_hook->modfun.function.value, current_hook->modfun.function.len, 1);
+            ZVAL_STRINGL(zmod, current_hook->modfun.module.value, current_hook->modfun.module.len, 1);
+            RIAK_CALL_METHOD2(RiakCommitHook, __construct, zhook, zhook, zmod, zfun);
+            zval_ptr_dtor(&zfun);
+            zval_ptr_dtor(&zmod);
+        }
+        MAKE_STD_ZVAL(zoffset);
+        ZVAL_LONG(zoffset, i);
+        RIAK_CALL_METHOD2(RiakCommitHookList, offsetSet, NULL, zhook_list, zoffset, zhook);
+        zval_ptr_dtor(&zoffset);
+        zval_ptr_dtor(&zhook);
+    }
+    return zhook_list;
+}/* }}} */
+
+/* {{{ proto Riak\BucketPropertyList Riak\Bucket->getPropertyList()
+Fetch and return a RiakBucketProperties object with properties for this bucket */
+PHP_METHOD(RiakBucket, getPropertyList)
+{
+#define GET_PROP_SET_ON_LIST(ZVAL_METHOD, SETTER_NAME, PROP_NAME) if (PROP_NAME##_use) { \
+                                                        MAKE_STD_ZVAL(ztmp); \
+                                                        ZVAL_METHOD(ztmp, PROP_NAME); \
+                                                        RIAK_CALL_METHOD1(RiakBucketProperties, SETTER_NAME, zbucket_props, zbucket_props, ztmp); \
+                                                        zval_ptr_dtor(&ztmp); }
+    riack_bucket_properties *properties;
+	riak_connection *connection;
+    riack_string bucketName, *type;
+    int riackResult;
+    zval *ztmp, *zbucket_props;
+
+    connection = get_riak_connection(getThis() TSRMLS_CC);
+    bucketName = riack_name_from_bucket(getThis() TSRMLS_CC);
+
+    THROW_EXCEPTION_IF_CONNECTION_IS_NULL(connection);
+
+    type = riack_get_bucket_type_from_bucket(connection->client, getThis() TSRMLS_CC);
+    RIACK_RETRY_OP(riackResult, connection, riack_get_bucket_props_ext(connection->client, &bucketName, type, &properties));
+	CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, riackResult);
+    RFREE(connection->client, type);
+
+    MAKE_STD_ZVAL(zbucket_props);
+    object_init_ex(zbucket_props, riak_bucket_properties_ce);
+    RIAK_CALL_METHOD(RiakBucketProperties, __construct, NULL, zbucket_props);
+
+    GET_PROP_SET_ON_LIST(ZVAL_LONG, setNValue, properties->n_val);
+    GET_PROP_SET_ON_LIST(ZVAL_BOOL, setAllowMult, properties->allow_mult);
+    GET_PROP_SET_ON_LIST(ZVAL_BOOL, setLastWriteWins, properties->last_write_wins);
+    GET_PROP_SET_ON_LIST(ZVAL_LONG, setOldVClock, properties->old_vclock);
+    GET_PROP_SET_ON_LIST(ZVAL_LONG, setYoungVClock, properties->young_vclock);
+    GET_PROP_SET_ON_LIST(ZVAL_LONG, setSmallVClock, properties->small_vclock);
+    GET_PROP_SET_ON_LIST(ZVAL_LONG, setBigVClock, properties->big_vclock);
+
+    GET_PROP_SET_ON_LIST(ZVAL_LONG, setR, properties->r);
+    GET_PROP_SET_ON_LIST(ZVAL_LONG, setPR, properties->pr);
+    GET_PROP_SET_ON_LIST(ZVAL_LONG, setW, properties->w);
+    GET_PROP_SET_ON_LIST(ZVAL_LONG, setDW, properties->dw);
+    GET_PROP_SET_ON_LIST(ZVAL_LONG, setPW, properties->pw);
+    GET_PROP_SET_ON_LIST(ZVAL_LONG, setRW, properties->rw);
+
+    GET_PROP_SET_ON_LIST(ZVAL_BOOL, setBasicQuorum, properties->basic_quorum);
+    GET_PROP_SET_ON_LIST(ZVAL_BOOL, setNotFoundOk, properties->notfound_ok);
+    GET_PROP_SET_ON_LIST(ZVAL_BOOL, setSearchEnabled, properties->search);
+    GET_PROP_SET_ON_LIST(ZVAL_BOOL, setConsistent, properties->consistent);
+    if (RSTR_HAS_CONTENT(properties->datatype)) {
+        MAKE_STD_ZVAL(ztmp);
+        ZVAL_STRINGL(ztmp, properties->datatype.value, properties->datatype.len, 1);
+        RIAK_CALL_METHOD1(RiakBucketProperties, setDatatype, zbucket_props, zbucket_props, ztmp);
+        zval_ptr_dtor(&ztmp);
+    }
+    if (RSTR_HAS_CONTENT(properties->backend)) {
+        MAKE_STD_ZVAL(ztmp);
+        ZVAL_STRINGL(ztmp, properties->backend.value, properties->backend.len, 1);
+        RIAK_CALL_METHOD1(RiakBucketProperties, setBackend, zbucket_props, zbucket_props, ztmp);
+        zval_ptr_dtor(&ztmp);
+    }
+    if (properties->linkfun_use) {
+        ztmp = riak_linkfun_from_riack(&properties->linkfun TSRMLS_CC);
+        RIAK_CALL_METHOD1(RiakBucketProperties, setLinkFun, zbucket_props, zbucket_props, ztmp);
+        zval_ptr_dtor(&ztmp);
+    }
+    if (properties->chash_keyfun_use) {
+        ztmp = riak_linkfun_from_riack(&properties->chash_keyfun TSRMLS_CC);
+        RIAK_CALL_METHOD1(RiakBucketProperties, setCHashKeyFun, zbucket_props, zbucket_props, ztmp);
+        zval_ptr_dtor(&ztmp);
+    }
+    if (properties->has_precommit_hooks) {
+        zval *zhook_list;
+        zhook_list = zhook_list_from_riack(properties->precommit_hook_count, properties->precommit_hooks TSRMLS_CC);
+        RIAK_CALL_METHOD1(RiakBucketProperties, setPreCommitHookList, zbucket_props, zbucket_props, zhook_list);
+        zval_ptr_dtor(&zhook_list);
+    }
+    if (properties->has_postcommit_hooks) {
+        zval *zhook_list;
+        zhook_list = zhook_list_from_riack(properties->postcommit_hook_count, properties->postcommit_hooks TSRMLS_CC);
+        RIAK_CALL_METHOD1(RiakBucketProperties, setPostCommitHookList, zbucket_props, zbucket_props, zhook_list);
+        zval_ptr_dtor(&zhook_list);
+    }
+    if (properties->replication_mode_use) {
+        zend_class_entry *ce = NULL;
+        switch (properties->replication_mode) {
+        case FULLSYNC:
+            ce = riak_replication_mode_full_only_ce;
+            break;
+        case REALTIME:
+            ce = riak_replication_mode_realtime_only_ce;
+            break;
+        case REALTIME_AND_FULLSYNC:
+            ce = riak_replication_mode_realtime_and_full_ce;
+            break;
+        case DISABLED:
+            ce = riak_replication_mode_disabled_ce;
+            break;
+        default:
+            break;
+        }
+        if (ce != NULL) {
+            zval *zrepclass;
+            MAKE_STD_ZVAL(zrepclass);
+            object_init_ex(zrepclass, ce);
+            RIAK_CALL_METHOD1(RiakBucketProperties, setReplicationMode, zbucket_props, zbucket_props, zrepclass);
+            zval_ptr_dtor(&zrepclass);
+        }
+    }
+    riack_free_bucket_properties_p(connection->client, &properties);
+    RETURN_ZVAL(zbucket_props, 0, 1);
+}
+/* }}} */
+
+/* {{{ proto void Riak\Bucket->delete(\Riak\Object|string $object [, \Riak\Input\DeleteInput $deleteInput[, int $timeout = 0]])
+Deletes given object from riak */
+PHP_METHOD(RiakBucket, delete)
+{
+    riack_del_properties props;
+    riak_connection *connection;
+    zval *zparam, *zinput, zKey;
+    riack_string bucketName, key, *rstype;
+    int riackResult;
+    long timeout;
+
+    zinput = NULL;
+    timeout = 0;
+
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|O!l", &zparam, &zinput, riak_delete_input_ce, &timeout) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    if (Z_TYPE_P(zparam) == IS_DOUBLE || Z_TYPE_P(zparam) == IS_LONG) {
+        convert_to_string(zparam);
+    }
+
+    if (Z_TYPE_P(zparam) != IS_STRING && (Z_TYPE_P(zparam) != IS_OBJECT || ! instanceof_function(Z_OBJCE_P(zparam), riak_object_ce TSRMLS_CC))) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Argument 1 passed to Riak\\Bucket#delete() must be a string or an instance of Riak\\Object.", 5001 TSRMLS_CC);
+        return;
+    }
+
+    memset(&props, 0, sizeof(props));
+
+    // Set connection and bucket name
+    connection = get_riak_connection(getThis() TSRMLS_CC);
+    bucketName = riack_name_from_bucket(getThis() TSRMLS_CC);
+    rstype = riack_get_bucket_type_from_bucket(connection->client, getThis() TSRMLS_CC);
+
+    THROW_EXCEPTION_IF_CONNECTION_IS_NULL(connection);
+
+    key.len   = 0;
+    key.value = NULL;
+
+    // Set input properties if provided
+    if (zinput != NULL && Z_TYPE_P(zinput) == IS_OBJECT) {
+        zval zget;
+        RIAK_REQ_PROP_SET_LONG(Riak_Input_DeleteInput, zget, getR, props.r);
+        RIAK_REQ_PROP_SET_LONG(Riak_Input_DeleteInput, zget, getPR, props.pr);
+        RIAK_REQ_PROP_SET_LONG(Riak_Input_DeleteInput, zget, getRW, props.rw);
+        RIAK_REQ_PROP_SET_LONG(Riak_Input_DeleteInput, zget, getW, props.w);
+        RIAK_REQ_PROP_SET_LONG(Riak_Input_DeleteInput, zget, getDW, props.dw);
+        RIAK_REQ_PROP_SET_LONG(Riak_Input_DeleteInput, zget, getPW, props.pw);
+
+        RIAK_CALL_METHOD(Riak_Input_DeleteInput, getVClock, &zget, zinput);
+        if (Z_TYPE(zget) == IS_STRING) {
+            RMALLOCCOPY(connection->client, props.vclock.clock, props.vclock.len, Z_STRVAL(zget), Z_STRLEN(zget));
+        }
+        zval_dtor(&zget);
+    }
+
+    ZVAL_NULL(&zKey);
+    if (Z_TYPE_P(zparam) == IS_OBJECT) {
+        RIAK_CALL_METHOD(RiakObject, getKey, &zKey, zparam);
+        if (Z_TYPE(zKey) == IS_STRING && Z_STRVAL(zKey) > 0) {
+            key.len   = Z_STRLEN(zKey);
+            key.value = Z_STRVAL(zKey);
+        }
+
+        // If vclock is not set retrieve from object
+        if (!props.vclock.clock) {
+            zval zObjVClock;
+            RIAK_CALL_METHOD(RiakObject, getVClock, &zObjVClock, zparam);
+            if (Z_TYPE(zObjVClock) == IS_STRING) {
+                RMALLOCCOPY(connection->client, props.vclock.clock, props.vclock.len, Z_STRVAL(zObjVClock), Z_STRLEN(zObjVClock));
+            }
+            zval_dtor(&zObjVClock);
+        }
+    } else if (Z_TYPE_P(zparam) == IS_STRING && Z_STRVAL_P(zparam) > 0) {
+        key.len   = Z_STRLEN_P(zparam);
+        key.value = Z_STRVAL_P(zparam);
+    }
+
+    if (key.len == 0) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Unable to resolve the object key.", 5001 TSRMLS_CC);
+    }
+    RIACK_RETRY_OP(riackResult, connection, riack_delete_ext(connection->client, &bucketName, rstype, &key, &props, timeout));
+    RFREE(connection->client, rstype);
+    RFREE(connection->client, props.vclock.clock);
+    zval_dtor(&zKey);
+    CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, riackResult);
+}
+/* }}} */
+
+/* {{{ proto Riak\Output\PutOutput Riak\Bucket->put(Riak\Object $object [, \Riak\Input\PutInput $putInput [, int $timeout = 0]])
+Store a RiakObject in riak, if something goes wrong an RiakException is thrown */
+PHP_METHOD(RiakBucket, put)
+{
+    int riackResult;
+    zval *zObject, *zTmp, *zinput, *zout, zvclock;
+    riack_object obj, *returnedObj;
+    riack_content riackContent;
+    riack_put_properties props;
+    riack_string *rstype;
+	riak_connection *connection;
+    long options, timeout;
+
+    options = 0;
+    timeout = 0;
+    zinput = NULL;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|O!l", &zObject, riak_object_ce, &zinput, riak_put_input_ce, &timeout) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+		return;
+    }
+    connection = get_riak_connection(getThis() TSRMLS_CC);
+
+    THROW_EXCEPTION_IF_CONNECTION_IS_NULL(connection);
+
+	memset(&obj, 0, sizeof(obj));
+	memset(&returnedObj, 0, sizeof(returnedObj));
+	memset(&riackContent, 0, sizeof(riackContent));
+    memset(&props, 0, sizeof(props));
+    /* fill content */
+    set_riak_content_from_object(&riackContent, zObject, connection->client TSRMLS_CC);
+    ZVAL_NULL(&zvclock);
+    if (zinput != NULL && Z_TYPE_P(zinput) == IS_OBJECT) {
+        zval zget;
+        RIAK_REQ_PROP_SET_BOOL(Riak_Input_PutInput, zget, getReturnHead, props.return_head);
+        RIAK_REQ_PROP_SET_BOOL(Riak_Input_PutInput, zget, getReturnBody, props.return_body);
+        RIAK_REQ_PROP_SET_BOOL(Riak_Input_PutInput, zget, getIfNotModified, props.if_not_modified);
+        RIAK_REQ_PROP_SET_BOOL(Riak_Input_PutInput, zget, getIfNoneMatch, props.if_none_match);
+        RIAK_REQ_PROP_SET_LONG(Riak_Input_PutInput, zget, getW, props.w);
+        RIAK_REQ_PROP_SET_LONG(Riak_Input_PutInput, zget, getDW, props.dw);
+        RIAK_REQ_PROP_SET_LONG(Riak_Input_PutInput, zget, getPW, props.pw);
+        RIAK_CALL_METHOD(Riak_Input_PutInput, getVClock, &zvclock, zinput);
+    }
+    if (Z_TYPE(zvclock) == IS_NULL) {
+        // vclock was not set from input, try getting it from object instead
+        RIAK_CALL_METHOD(RiakObject, getVClock, &zvclock, zObject);
+    }
+    if (Z_TYPE(zvclock) == IS_STRING) {
+        RMALLOCCOPY(connection->client, obj.vclock.clock, obj.vclock.len, Z_STRVAL(zvclock), Z_STRLEN(zvclock));
+        zval_dtor(&zvclock);
+    }
+
+    rstype = riack_get_bucket_type_from_bucket(connection->client, getThis() TSRMLS_CC);
+    /* Set bucket name */
+    obj.bucket = riack_name_from_bucket(getThis() TSRMLS_CC);
+	obj.content_count = 1;
+	obj.content = &riackContent;
+    /* No ket provided on function call, get it from RiakObject */
+    GET_PROPERTY_INTO_RIACK_STR_OR_ELSE(riak_object_ce, zObject, "key", zTmp, obj.key) {
+        // Key is null this is ok
+        obj.key.len = 0;
+        obj.key.value = 0;
+    }
+    RIACK_RETRY_OP(riackResult, connection, riack_put_ext(connection->client, &obj, rstype, &returnedObj, &props, timeout));
+    RFREE(connection->client, obj.vclock.clock);
+    RFREE(connection->client, rstype);
+	CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, riackResult);
+
+    // Now make put output from the response
+    MAKE_STD_ZVAL(zTmp);
+    if (returnedObj->key.len > 0) {
+        ZVAL_STRINGL(zTmp, (char*)returnedObj->key.value, returnedObj->key.len, 1);
+    } else {
+        ZVAL_NULL(zTmp);
+    }
+    zout = put_output_from_riack_object(returnedObj, zTmp TSRMLS_CC);
+    RETVAL_ZVAL(zout, 0, 1);
+
+    zval_ptr_dtor(&zTmp);
+    riack_free_object_p(connection->client, &returnedObj);
+}
+/* }}} */
+
+/* {{{ proto Output\GetOutput Riak\Bucket->get(string $key [, Riak\Input\GetInput $input [, int $timeout = 0]])
+Get value from riak */
+PHP_METHOD(RiakBucket, get)
+{
+	char *key;
+    int keyLen, riackResult;
+    zval *zKey, *zinput;
+    riack_get_properties props;
+    riack_get_object *getResult;
+    riack_string rsBucket, rsKey, *rstype;
+	riak_connection *connection;
+
+    zinput = NULL;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|o", &key, &keyLen, &zinput) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+		return;
+    }
+    connection = get_riak_connection(getThis() TSRMLS_CC);
+    THROW_EXCEPTION_IF_CONNECTION_IS_NULL(connection);
+
+	MAKE_STD_ZVAL(zKey);
+	ZVAL_STRINGL(zKey, key, keyLen, 1);
+    memset(&props, 0, sizeof(props));
+    if (zinput != NULL && Z_TYPE_P(zinput) == IS_OBJECT) {
+        zval zget;
+        RIAK_REQ_PROP_SET_BOOL(Riak_Input_GetInput, zget, getReturnHead, props.head);
+        RIAK_REQ_PROP_SET_LONG(Riak_Input_GetInput, zget, getR, props.r);
+        RIAK_REQ_PROP_SET_LONG(Riak_Input_GetInput, zget, getPR, props.pr);
+        RIAK_REQ_PROP_SET_BOOL(Riak_Input_GetInput, zget, getBasicQuorum, props.basic_quorum);
+        RIAK_REQ_PROP_SET_BOOL(Riak_Input_GetInput, zget, getNotFoundOk, props.notfound_ok);
+        RIAK_REQ_PROP_SET_BOOL(Riak_Input_GetInput, zget, getReturnDeletedVClock, props.deletedvclock);
+        RIAK_CALL_METHOD(Riak_Input_GetInput, getIfModifiedVClock, &zget, zinput);
+        if (Z_TYPE(zget) == IS_STRING) {
+            props.if_modified_use = 1;
+            RMALLOCCOPY(connection->client, props.if_modified.clock, props.if_modified.len, Z_STRVAL(zget), Z_STRLEN(zget));
+            zval_dtor(&zget);
+        }
+    }
+
+    rsKey.len   = keyLen;
+    rsKey.value = key;
+    rsBucket    = riack_name_from_bucket(getThis() TSRMLS_CC);
+    rstype = riack_get_bucket_type_from_bucket(connection->client, getThis() TSRMLS_CC);
+
+    RIACK_RETRY_OP(riackResult, connection, riack_get(connection->client, &rsBucket, &rsKey, &props, &getResult));
+
+    RFREE(connection->client, rstype);
+    RFREE(connection->client, props.if_modified.clock);
+
+    if (riackResult == RIACK_SUCCESS) {
+        zval *zout, *zResolver;
+        zout      = get_output_from_riack_get_object(getResult, zKey TSRMLS_CC);
+        zResolver = (zinput != NULL && Z_TYPE_P(zinput) == IS_OBJECT)
+            ? zend_read_property(riak_get_resolver_input_ce, zinput, "conflictResolver", sizeof("conflictResolver")-1, 1 TSRMLS_CC)
+            : zend_read_property(riak_bucket_ce, getThis(), "conflictResolver", sizeof("conflictResolver")-1, 1 TSRMLS_CC);
+
+        if (Z_TYPE_P(zResolver) == IS_OBJECT) {
+            zend_update_property(riak_output_ce, zout, "conflictResolver", sizeof("conflictResolver")-1, zResolver TSRMLS_CC);
+        }
+        zend_update_property(riak_output_ce, zout, "bucket", sizeof("bucket")-1, getThis() TSRMLS_CC);
+        RETVAL_ZVAL(zout, 0, 1);
+        riack_free_get_object_p(connection->client, &getResult);
+    } else {
+        connection->needs_reconnect = 1;
+        // Hack warning, same as above
+        if (!EG(current_execute_data)) {
+            // No stack dont throw
+            RETVAL_NULL();
+        } else {
+            riak_throw_exception(connection->client,  riackResult TSRMLS_CC);
+        }
+	}
+    zval_ptr_dtor(&zKey);
+}
+/* }}} */
+
+/* {{{ proto string Riak\Bucket->getName()
+Get bucket name */
+PHP_METHOD(RiakBucket, getName)
+{
+    RIAK_GETTER_STRING(riak_bucket_ce, "name");
+}
+/* }}} */
+
+/* {{{ proto string Riak\Bucket->getType() */
+PHP_METHOD(RiakBucket, getType)
+{
+    RIAK_GETTER_OBJECT(riak_bucket_ce, "type");
+}
+/* }}} */
+
+/* {{{ proto string Riak\Bucket->getConnection() */
+PHP_METHOD(RiakBucket, getConnection)
+{
+    RIAK_GETTER_OBJECT(riak_bucket_ce, "connection");
+}
+/* }}} */
+
+/* {{{ proto \Riak\Output\ConflictResolver Riak\Bucket->getConflictResolver()
+ */
+PHP_METHOD(RiakBucket, getConflictResolver)
+{
+    RIAK_GETTER_OBJECT(riak_bucket_ce, "conflictResolver");
+}
+/* }}} */
+
+/* {{{ proto Riak\Bucket Riak\Object->setConflictResolver(\Riak\Output\ConflictResolver $resolver)
+ */
+PHP_METHOD(RiakBucket, setConflictResolver)
+{
+    zval* zResolver; 
+
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zResolver, riak_output_conflict_resolver_ce) == FAILURE) {
+        return;
+    }
+
+    zend_update_property(riak_bucket_ce, getThis(), "conflictResolver", sizeof("conflictResolver")-1, zResolver TSRMLS_CC);
+
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+zval* object_from_riak_content(zval* key, riack_content* content TSRMLS_DC)/* {{{ */
+{
+	zval *object;
+	MAKE_STD_ZVAL(object);
+	object_init_ex(object, riak_object_ce);
+	RIAK_CALL_METHOD1(RiakObject, __construct, object, object, key);
+
+	set_object_from_riak_content(object, content TSRMLS_CC);
+
+	return object;
+}
+/* }}} */
+
+void riak_name_from_bucket(zval* bucket, char **name, int *namelen TSRMLS_DC)/* {{{ */
+{
+    zval *zname = zend_read_property(riak_bucket_ce, bucket, "name", sizeof("name")-1, 1 TSRMLS_CC);
+    if (Z_TYPE_P(zname) == IS_STRING) {
+        *name = Z_STRVAL_P(zname);
+        *namelen = Z_STRLEN_P(zname);
+    } else {
+        *name = NULL;
+        *namelen = 0;
+    }
+}
+/* }}} */
+
+riack_string *riack_get_bucket_type_from_bucket(riack_client *client, zval* bucket TSRMLS_DC) /* {{{ */
+{
+    zval *ztype = zend_read_property(riak_bucket_ce, bucket, "type", sizeof("type")-1, 1 TSRMLS_CC);
+    if (Z_TYPE_P(ztype) == IS_STRING) {
+        riack_string *type = riack_string_alloc(client);
+        type->len = Z_STRLEN_P(ztype);
+        type->value = Z_STRVAL_P(ztype);
+        return type;
+    } else {
+        return 0;
+    }
+}
+/* }}} */
+
+riack_string riack_name_from_bucket(zval* bucket TSRMLS_DC)/* {{{ */
+{
+    riack_string bucketName;
+    int namelen;
+    riak_name_from_bucket(bucket, &bucketName.value, &namelen TSRMLS_CC);
+    bucketName.len = namelen;
+    return bucketName;
+}
+/* }}} */
+
+riak_connection *get_riak_connection(zval *zbucket TSRMLS_DC)/* {{{ */
+{
+    zval *zclient;
+
+    zend_call_method_with_0_params(&zbucket, NULL, NULL, "getConnection", &zclient);
+
+    if ( ! zclient) {
+        return NULL;
+    }
+
+    return get_client_connection(zclient TSRMLS_CC);
+}
+/* }}} */
diff --git a/bucket.h b/riak/bucket.h
similarity index 70%
rename from bucket.h
rename to riak/bucket.h
index 31cd361..8a3d559 100644
--- a/bucket.h
+++ b/riak/bucket.h
@@ -18,8 +18,8 @@
 #ifndef RIAK_BUCKET__H__
 #define RIAK_BUCKET__H__
 
-#include <php.h>
-#include <riack.h>
+#include "php_riak_internal.h"
+#include "connection.h"
 
 extern zend_class_entry *riak_bucket_ce;
 
@@ -34,14 +34,22 @@ PHP_METHOD(RiakBucket, put);
 PHP_METHOD(RiakBucket, get);
 PHP_METHOD(RiakBucket, delete);
 PHP_METHOD(RiakBucket, index);
+PHP_METHOD(RiakBucket, indexQuery);
+PHP_METHOD(RiakBucket, counter);
 
 PHP_METHOD(RiakBucket, getKeyStream);
 PHP_METHOD(RiakBucket, getKeyList);
 PHP_METHOD(RiakBucket, getName);
+PHP_METHOD(RiakBucket, getType);
 PHP_METHOD(RiakBucket, getConnection);
 
-zval* object_from_riak_content(zval* key, struct RIACK_CONTENT* content TSRMLS_DC);
-RIACK_STRING riack_name_from_bucket(zval* bucket TSRMLS_DC);
+PHP_METHOD(RiakBucket, getConflictResolver);
+PHP_METHOD(RiakBucket, setConflictResolver);
+
+riak_connection *get_riak_connection(zval *zbucket TSRMLS_DC);
+zval* object_from_riak_content(zval* key, riack_content* content TSRMLS_DC);
+riack_string riack_name_from_bucket(zval* bucket TSRMLS_DC);
+riack_string *riack_get_bucket_type_from_bucket(riack_client *client, zval* bucket TSRMLS_DC);
 void riak_name_from_bucket(zval* bucket, char **name, int *namelen TSRMLS_DC);
 
 #endif
diff --git a/bucket_properties.c b/riak/bucket_properties.c
similarity index 61%
rename from bucket_properties.c
rename to riak/bucket_properties.c
index e285378..e3bcc4a 100644
--- a/bucket_properties.c
+++ b/riak/bucket_properties.c
@@ -13,21 +13,18 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 */
-#include <php.h>
-#include <zend_interfaces.h>
-#include <ext/spl/spl_iterators.h>
-#include <ext/spl/spl_array.h>
+
 #include "bucket_properties.h"
+#include "property/module_function.h"
+#include "property/commit_hook.h"
+#include "property/commit_hook_list.h"
+#include "property/replication_mode/replication_mode.h"
+#include "exception/exception.h"
 #include "bucket.h"
 #include "connection.h"
 #include "object.h"
-#include "exceptions.h"
-#include "php_riak.h"
 
 zend_class_entry *riak_bucket_properties_ce;
-zend_class_entry *riak_module_function_ce;
-zend_class_entry *riak_commit_hook_ce;
-zend_class_entry *riak_commit_hook_list_ce;
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_props_ctor, 0, ZEND_RETURN_VALUE, 0)
     ZEND_ARG_INFO(0, nVal)
@@ -37,6 +34,14 @@ ZEND_END_ARG_INFO()
 ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_props_noargs, 0, ZEND_RETURN_VALUE, 0)
 ZEND_END_ARG_INFO()
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_props_set_consistent, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, consistent)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_props_set_datatype, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, datatype)
+ZEND_END_ARG_INFO()
+
 ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_props_set_nval, 0, ZEND_RETURN_VALUE, 1)
     ZEND_ARG_INFO(0, nVal)
 ZEND_END_ARG_INFO()
@@ -57,74 +62,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_props_set_rwpr, 0, ZEND_RETURN_VALUE, 1)
     ZEND_ARG_INFO(0, value)
 ZEND_END_ARG_INFO()
 
-ZEND_BEGIN_ARG_INFO_EX(arginfo_module_function_ctor, 0, ZEND_RETURN_VALUE, 2)
-    ZEND_ARG_INFO(0, module)
-    ZEND_ARG_INFO(0, function)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_module_function_set, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, value)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_module_function_noargs, 0, ZEND_RETURN_VALUE, 0)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_commit_hook_ctor, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, moduleOrName)
-    ZEND_ARG_INFO(0, function)
-ZEND_END_ARG_INFO()
-
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_commit_hook_set, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, value)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_commit_hook_set_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_bucket_properties_noargs, 0, ZEND_RETURN_VALUE, 0)
 ZEND_END_ARG_INFO()
 
 
-ZEND_BEGIN_ARG_INFO_EX(arginfo_commit_hook_list_offset_exists, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, offset)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_commit_hook_list_offset_set, 0, ZEND_RETURN_VALUE, 2)
-    ZEND_ARG_INFO(0, offset)
-    ZEND_ARG_INFO(0, value)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_commit_hook_list_noargs, 0, ZEND_RETURN_VALUE, 0)
-ZEND_END_ARG_INFO()
-
-static zend_function_entry riak_module_function_methods[] = {
-    PHP_ME(RiakModuleFunction, __construct, arginfo_module_function_ctor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
-    PHP_ME(RiakModuleFunction, getModule, arginfo_module_function_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(RiakModuleFunction, setModule, arginfo_module_function_set, ZEND_ACC_PUBLIC)
-    PHP_ME(RiakModuleFunction, getFunction, arginfo_module_function_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(RiakModuleFunction, setFunction, arginfo_module_function_set, ZEND_ACC_PUBLIC)
-    {NULL, NULL, NULL}
-};
-
-static zend_function_entry riak_commit_hook_methods[] = {
-    PHP_ME(RiakCommitHook, __construct, arginfo_commit_hook_ctor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
-    PHP_ME(RiakCommitHook, getJsName, arginfo_module_function_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(RiakCommitHook, getErlModule, arginfo_module_function_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(RiakCommitHook, getErlFunction, arginfo_commit_hook_set, ZEND_ACC_PUBLIC)
-    PHP_ME(RiakCommitHook, isJavascript, arginfo_module_function_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(RiakCommitHook, isErlang, arginfo_module_function_noargs, ZEND_ACC_PUBLIC)
-    {NULL, NULL, NULL}
-};
-
-static zend_function_entry riak_commit_hook_list_methods[] = {
-    PHP_ME(RiakCommitHookList, __construct, arginfo_commit_hook_list_noargs, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
-    PHP_ME(RiakCommitHookList, offsetExists, arginfo_commit_hook_list_offset_exists, ZEND_ACC_PUBLIC)
-    PHP_ME(RiakCommitHookList, offsetGet, arginfo_commit_hook_list_offset_exists, ZEND_ACC_PUBLIC)
-    PHP_ME(RiakCommitHookList, offsetSet, arginfo_commit_hook_list_offset_set, ZEND_ACC_PUBLIC)
-    PHP_ME(RiakCommitHookList, offsetUnset, arginfo_commit_hook_list_offset_exists, ZEND_ACC_PUBLIC)
-    PHP_ME(RiakCommitHookList, count, arginfo_commit_hook_list_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(RiakCommitHookList, getIterator, arginfo_commit_hook_list_noargs, ZEND_ACC_PUBLIC)
-    {NULL, NULL, NULL}
-};
-
 static zend_function_entry riak_bucket_properties_methods[] = {
 	PHP_ME(RiakBucketProperties, __construct, arginfo_bucket_props_ctor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
     PHP_ME(RiakBucketProperties, getNValue, arginfo_bucket_props_noargs, ZEND_ACC_PUBLIC)
@@ -171,6 +112,14 @@ static zend_function_entry riak_bucket_properties_methods[] = {
     PHP_ME(RiakBucketProperties, getLinkFun, arginfo_bucket_props_noargs, ZEND_ACC_PUBLIC)
     PHP_ME(RiakBucketProperties, setLinkFun, arginfo_bucket_props_set_rwpr, ZEND_ACC_PUBLIC)
 
+    PHP_ME(RiakBucketProperties, getReplicationMode, arginfo_bucket_props_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakBucketProperties, setReplicationMode, arginfo_bucket_props_set_rwpr, ZEND_ACC_PUBLIC)
+
+    PHP_ME(RiakBucketProperties, isConsistent, arginfo_bucket_props_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakBucketProperties, setConsistent, arginfo_bucket_props_set_consistent, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakBucketProperties, getDatatype, arginfo_bucket_props_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakBucketProperties, setDatatype, arginfo_bucket_props_set_datatype, ZEND_ACC_PUBLIC)
+
 	{NULL, NULL, NULL}
 };
 
@@ -203,183 +152,13 @@ void riak_bucket_props_init(TSRMLS_D)/* {{{ */
     zend_declare_property_null(riak_bucket_properties_ce, "postCommitHooks", sizeof("postCommitHooks")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
     zend_declare_property_null(riak_bucket_properties_ce, "chashKeyFun", sizeof("chashKeyFun")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
     zend_declare_property_null(riak_bucket_properties_ce, "linkFun", sizeof("linkFun")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
+    zend_declare_property_null(riak_bucket_properties_ce, "replicationMode", sizeof("replicationMode")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
+    zend_declare_property_null(riak_bucket_properties_ce, "consistent", sizeof("consistent")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
+    zend_declare_property_null(riak_bucket_properties_ce, "datatype", sizeof("datatype")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
 
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\Property", "ModuleFunction", riak_module_function_methods);
-    riak_module_function_ce = zend_register_internal_class(&ce TSRMLS_CC);
-    zend_declare_property_null(riak_module_function_ce, "module", sizeof("module")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
-    zend_declare_property_null(riak_module_function_ce, "function", sizeof("function")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
-
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\Property", "CommitHook", riak_commit_hook_methods);
-    riak_commit_hook_ce = zend_register_internal_class(&ce TSRMLS_CC);
-    zend_declare_property_null(riak_commit_hook_ce, "moduleOrName", sizeof("moduleOrName")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
-    zend_declare_property_null(riak_commit_hook_ce, "function", sizeof("function")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
-
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\Property", "CommitHookList", riak_commit_hook_list_methods);
-    riak_commit_hook_list_ce = zend_register_internal_class(&ce TSRMLS_CC);
-    zend_class_implements(riak_commit_hook_list_ce TSRMLS_CC, 3, spl_ce_ArrayAccess, spl_ce_Aggregate, spl_ce_Countable);
-    zend_declare_property_null(riak_commit_hook_list_ce, "hooks", sizeof("hooks")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
-}
-/* }}} */
-
-/* {{{ proto void Riak\Property\RiakCommitHookList->__construct()
-Creates a new Riak\Property\RiakCommitHookList */
-PHP_METHOD(RiakCommitHookList, __construct)
-{
-    zval* zhooks;
-    // Start with an empty array
-    MAKE_STD_ZVAL(zhooks);
-    object_init_ex(zhooks, spl_ce_ArrayObject);
-    zend_update_property(riak_commit_hook_list_ce, getThis(), "hooks", sizeof("hooks")-1, zhooks TSRMLS_CC);
-    zval_ptr_dtor(&zhooks);
-}/* }}} */
-
-PHP_METHOD(RiakCommitHookList, offsetExists)
-{
-    zval *zoffset, *zhooks, *zresult;
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zoffset) == FAILURE) {
-        return;
-    }
-    zhooks = zend_read_property(riak_commit_hook_list_ce, getThis(), "hooks", sizeof("hooks")-1, 1 TSRMLS_CC);
-    zend_call_method_with_1_params(&zhooks, spl_ce_ArrayObject, NULL, "offsetexists", &zresult, zoffset);
-    RETURN_ZVAL(zresult, 0, 1);
-}
-
-PHP_METHOD(RiakCommitHookList, offsetGet)
-{
-    zval *zoffset, *zhooks, *zresult;
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zoffset) == FAILURE) {
-        return;
-    }
-    zhooks = zend_read_property(riak_commit_hook_list_ce, getThis(), "hooks", sizeof("hooks")-1, 1 TSRMLS_CC);
-    zend_call_method_with_1_params(&zhooks, spl_ce_ArrayObject, NULL, "offsetget", &zresult, zoffset);
-    RETURN_ZVAL(zresult, 0, 1);
-}
-
-PHP_METHOD(RiakCommitHookList, offsetSet)
-{
-    zval *zoffset, *zvalue, *zhooks;
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zO", &zoffset, &zvalue, riak_commit_hook_ce) == FAILURE) {
-        return;
-    }
-    zhooks = zend_read_property(riak_commit_hook_list_ce, getThis(), "hooks", sizeof("hooks")-1, 1 TSRMLS_CC);
-    zend_call_method_with_2_params(&zhooks, spl_ce_ArrayObject, NULL, "offsetset", NULL, zoffset, zvalue);
-}
-
-PHP_METHOD(RiakCommitHookList, offsetUnset)
-{
-    zval *zoffset, *zhooks;
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zoffset) == FAILURE) {
-        return;
-    }
-    zhooks = zend_read_property(riak_commit_hook_list_ce, getThis(), "hooks", sizeof("hooks")-1, 1 TSRMLS_CC);
-    zend_call_method_with_1_params(&zhooks, spl_ce_ArrayObject, NULL, "offsetunset", NULL, zoffset);
-}
-
-PHP_METHOD(RiakCommitHookList, count)
-{
-    zval *zhooks, *zresult;
-    zhooks = zend_read_property(riak_commit_hook_list_ce, getThis(), "hooks", sizeof("hooks")-1, 1 TSRMLS_CC);
-    zend_call_method_with_0_params(&zhooks, spl_ce_ArrayObject, NULL, "count", &zresult);
-    RETURN_ZVAL(zresult, 0, 1);
-}
-
-PHP_METHOD(RiakCommitHookList, getIterator)
-{
-    zval *zhooks, *zresult;
-    zhooks = zend_read_property(riak_commit_hook_list_ce, getThis(), "hooks", sizeof("hooks")-1, 1 TSRMLS_CC);
-    zend_call_method_with_0_params(&zhooks, spl_ce_ArrayObject, NULL, "getiterator", &zresult);
-    RETURN_ZVAL(zresult, 0, 1);
-}
-
-/* {{{ proto void Riak\Property\ModuleFunction->__construct(string $module, string $function)
-Creates a new Riak\Property\ModuleFunction */
-PHP_METHOD(RiakModuleFunction, __construct)
-{
-    char *module, *efunction;
-    int module_len, efunction_len;
-
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &module, &module_len, &efunction, &efunction_len) == FAILURE) {
-        return;
-    }
-
-    zend_update_property_stringl(riak_module_function_ce, getThis(), "module", sizeof("module")-1, module, module_len TSRMLS_CC);
-    zend_update_property_stringl(riak_module_function_ce, getThis(), "function", sizeof("function")-1, efunction, efunction_len TSRMLS_CC);
-}
-/* }}} */
-
-PHP_METHOD(RiakModuleFunction, getModule)
-{
-    RIAK_GETTER_STRING(riak_module_function_ce, "module")
-}
-
-PHP_METHOD(RiakModuleFunction, setModule)
-{
-    RIAK_SETTER_STRING(riak_module_function_ce, "module")
-    RIAK_RETURN_THIS
-}
-
-PHP_METHOD(RiakModuleFunction, getFunction)
-{
-    RIAK_GETTER_STRING(riak_module_function_ce, "function")
-}
-
-PHP_METHOD(RiakModuleFunction, setFunction)
-{
-    RIAK_SETTER_STRING(riak_module_function_ce, "function")
-    RIAK_RETURN_THIS
-}
-
-/* {{{ proto void Riak\Property\CommitHook->__construct(string $name, ModuleFunction $moduleFunction)
-Creates a new Riak\Property\CommitHook */
-PHP_METHOD(RiakCommitHook, __construct)
-{
-    char *mod_or_name, *fun;
-    int mod_or_name_len, fun_len;
-    fun_len = 0;
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &mod_or_name, &mod_or_name_len, &fun, &fun_len) == FAILURE) {
-        return;
-    }
-    zend_update_property_stringl(riak_commit_hook_ce, getThis(), "moduleOrName", sizeof("moduleOrName")-1, mod_or_name, mod_or_name_len TSRMLS_CC);
-    if (fun_len > 0) {
-        zend_update_property_stringl(riak_commit_hook_ce, getThis(), "function", sizeof("function")-1, fun, fun_len TSRMLS_CC);
-    }
 }
 /* }}} */
 
-PHP_METHOD(RiakCommitHook, getJsName)
-{
-    RIAK_GETTER_STRING(riak_commit_hook_ce, "moduleOrName")
-}
-
-PHP_METHOD(RiakCommitHook, getErlModule)
-{
-    RIAK_GETTER_STRING(riak_commit_hook_ce, "moduleOrName")
-}
-
-PHP_METHOD(RiakCommitHook, getErlFunction)
-{
-    RIAK_GETTER_STRING(riak_commit_hook_ce, "function")
-}
-
-PHP_METHOD(RiakCommitHook, isJavascript)
-{
-    zval* ztmp = zend_read_property(riak_commit_hook_ce, getThis(), "function", sizeof("function")-1, 1 TSRMLS_CC);
-    if (Z_TYPE_P(ztmp) == IS_STRING) {
-        RETURN_FALSE;
-    }
-    RETURN_TRUE;
-}
-
-PHP_METHOD(RiakCommitHook, isErlang)
-{
-    zval* ztmp = zend_read_property(riak_commit_hook_ce, getThis(), "function", sizeof("function")-1, 1 TSRMLS_CC);
-    if (Z_TYPE_P(ztmp) == IS_STRING) {
-        RETURN_TRUE;
-    }
-    RETURN_FALSE;
-}
-
-
 /* {{{ proto void Riak\BucketProperties->__construct(int $nVal, bool $allowMult)
 Creates a new RiakBucketProperties */
 PHP_METHOD(RiakBucketProperties, __construct)
@@ -387,6 +166,7 @@ PHP_METHOD(RiakBucketProperties, __construct)
 	long nVal;
     zend_bool allowMult;
     if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lb", &nVal, &allowMult) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
 		return;
 	}
     if (ZEND_NUM_ARGS() >= 1) {
@@ -650,3 +430,42 @@ PHP_METHOD(RiakBucketProperties, setLinkFun)
     zend_update_property(riak_bucket_properties_ce, getThis(), "linkFun", sizeof("linkFun")-1, zhooks TSRMLS_CC);
     RIAK_RETURN_THIS
 }
+
+PHP_METHOD(RiakBucketProperties, setReplicationMode)
+{
+    zval* zmode;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zmode, riak_replication_mode_ce) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "", 501 TSRMLS_CC);
+        return;
+    }
+    zend_update_property(riak_bucket_properties_ce, getThis(), "replicationMode", sizeof("replicationMode")-1, zmode TSRMLS_CC);
+    RIAK_RETURN_THIS
+}
+
+PHP_METHOD(RiakBucketProperties, getReplicationMode)
+{
+    RIAK_GETTER_OBJECT(riak_bucket_properties_ce, "replicationMode")
+}
+
+PHP_METHOD(RiakBucketProperties, isConsistent)
+{
+    RIAK_GETTER_BOOL(riak_bucket_properties_ce, "consistent")
+}
+
+
+PHP_METHOD(RiakBucketProperties, setConsistent)
+{
+    RIAK_SETTER_BOOL(riak_bucket_properties_ce, "consistent")
+    RIAK_RETURN_THIS
+}
+
+PHP_METHOD(RiakBucketProperties, getDatatype)
+{
+    RIAK_GETTER_STRING(riak_bucket_properties_ce, "datatype")
+}
+
+PHP_METHOD(RiakBucketProperties, setDatatype)
+{
+    RIAK_SETTER_STRING(riak_bucket_properties_ce, "datatype")
+    RIAK_RETURN_THIS
+}
diff --git a/bucket_properties.h b/riak/bucket_properties.h
similarity index 74%
rename from bucket_properties.h
rename to riak/bucket_properties.h
index 1fff84f..8a3f0e0 100644
--- a/bucket_properties.h
+++ b/riak/bucket_properties.h
@@ -18,12 +18,10 @@
 #ifndef RIAK_BUCKET__PROPERTIES__H__
 #define RIAK_BUCKET__PROPERTIES__H__
 
+#include "php_riak_internal.h"
+
 extern zend_class_entry *riak_bucket_properties_ce;
-extern zend_class_entry *riak_module_function_ce;
-extern zend_class_entry *riak_commit_hook_ce;
-extern zend_class_entry *riak_commit_hook_list_ce;
 
-void riak_bucket_props_init(TSRMLS_D);
 void riak_bucket_props_init(TSRMLS_D);
 
 PHP_METHOD(RiakBucketProperties, __construct);
@@ -72,25 +70,12 @@ PHP_METHOD(RiakBucketProperties, getCHashKeyFun);
 PHP_METHOD(RiakBucketProperties, setLinkFun);
 PHP_METHOD(RiakBucketProperties, getLinkFun);
 
-PHP_METHOD(RiakModuleFunction, __construct);
-PHP_METHOD(RiakModuleFunction, getModule);
-PHP_METHOD(RiakModuleFunction, setModule);
-PHP_METHOD(RiakModuleFunction, getFunction);
-PHP_METHOD(RiakModuleFunction, setFunction);
-
-PHP_METHOD(RiakCommitHook, __construct);
-PHP_METHOD(RiakCommitHook, getJsName);
-PHP_METHOD(RiakCommitHook, getErlModule);
-PHP_METHOD(RiakCommitHook, getErlFunction);
-PHP_METHOD(RiakCommitHook, isJavascript);
-PHP_METHOD(RiakCommitHook, isErlang);
+PHP_METHOD(RiakBucketProperties, getReplicationMode);
+PHP_METHOD(RiakBucketProperties, setReplicationMode);
 
-PHP_METHOD(RiakCommitHookList, __construct);
-PHP_METHOD(RiakCommitHookList, offsetExists);
-PHP_METHOD(RiakCommitHookList, offsetGet);
-PHP_METHOD(RiakCommitHookList, offsetSet);
-PHP_METHOD(RiakCommitHookList, offsetUnset);
-PHP_METHOD(RiakCommitHookList, count);
-PHP_METHOD(RiakCommitHookList, getIterator);
+PHP_METHOD(RiakBucketProperties, isConsistent);
+PHP_METHOD(RiakBucketProperties, setConsistent);
+PHP_METHOD(RiakBucketProperties, getDatatype);
+PHP_METHOD(RiakBucketProperties, setDatatype);
 
 #endif
diff --git a/connection.c b/riak/connection.c
similarity index 57%
rename from connection.c
rename to riak/connection.c
index 7cf5fed..f4aa11f 100644
--- a/connection.c
+++ b/riak/connection.c
@@ -14,15 +14,14 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 */
-#include <php.h>
-#include <zend_exceptions.h>
-#include <riack.h>
-#include "php_riak.h"
+
 #include "connection.h"
 #include "object.h"
 #include "bucket.h"
-#include "pool.h"
-#include "exceptions.h"
+#include "exception/exception.h"
+#include "server_info.h"
+#include "zend_interfaces.h"
+#include <zend_exceptions.h>
 
 zend_class_entry *riak_connection_ce;
 
@@ -44,6 +43,7 @@ static zend_function_entry riak_connection_methods[] = {
     PHP_ME(RiakConnection, getHost, arginfo_riak_connection_noargs, ZEND_ACC_PUBLIC)
     PHP_ME(RiakConnection, getPort, arginfo_riak_connection_noargs, ZEND_ACC_PUBLIC)
     PHP_ME(RiakConnection, getBucket, arginfo_riak_connection_get_bucket, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakConnection, getServerInfo, arginfo_riak_connection_noargs, ZEND_ACC_PUBLIC)
 	{NULL, NULL, NULL}
 };
 
@@ -51,13 +51,13 @@ static zend_function_entry riak_connection_methods[] = {
 
 void riak_connection_init(TSRMLS_D) /* {{{ */
 {
-	zend_class_entry ce;
- 
+    zend_class_entry ce;
+
     INIT_NS_CLASS_ENTRY(ce, "Riak", "Connection", riak_connection_methods);
 
-	ce.create_object = create_client_data;
+    ce.create_object = create_client_data;
     riak_connection_ce = zend_register_internal_class(&ce TSRMLS_CC);
-  
+
     zend_declare_property_null(riak_connection_ce, "host", sizeof("host")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
     zend_declare_property_null(riak_connection_ce, "port", sizeof("port")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
 }
@@ -65,42 +65,41 @@ void riak_connection_init(TSRMLS_D) /* {{{ */
 
 zend_object_value create_client_data(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
 {
-	zend_object_value retval;
-	client_data *tobj;
- 
-	tobj = emalloc(sizeof(client_data));
+    zend_object_value retval;
+    client_data *tobj;
 
-	memset(tobj, 0, sizeof(client_data));
-	zend_object_std_init((zend_object *) &tobj->std, class_type TSRMLS_CC);
+    tobj = emalloc(sizeof(client_data));
+
+    memset(tobj, 0, sizeof(client_data));
+    zend_object_std_init((zend_object *) &tobj->std, class_type TSRMLS_CC);
 
 #if ZEND_MODULE_API_NO >= 20100525
-	object_properties_init((zend_object*) &tobj->std, class_type);
+    object_properties_init((zend_object*) &tobj->std, class_type);
 #else
-	{
-		zval *tmp;
-		zend_hash_copy(tobj->std.properties, &class_type->default_properties, (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));
-	}
+    {
+        zval *tmp;
+        zend_hash_copy(tobj->std.properties, &class_type->default_properties, (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));
+    }
 #endif
 
-	retval.handle = zend_objects_store_put(tobj, (zend_objects_store_dtor_t) zend_objects_destroy_object, 
-		(zend_objects_free_object_storage_t) free_client_data, NULL TSRMLS_CC);
-	retval.handlers = zend_get_std_object_handlers();
+    retval.handle   = zend_objects_store_put(tobj, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) free_client_data, NULL TSRMLS_CC);
+    retval.handlers = zend_get_std_object_handlers();
 
-	return retval;
+    return retval;
 }
 /* }}} */
 
 void free_client_data(void *object TSRMLS_DC) /* {{{ */
 {
-	client_data* data = (client_data*)object;
+    client_data* data = (client_data*)object;
 
-	zend_object_std_dtor(&data->std TSRMLS_CC);
+    zend_object_std_dtor(&data->std TSRMLS_CC);
 
-	if (data->connection) {
-		release_connection(data->connection TSRMLS_CC);
-	}
+    if (data->connection) {
+        release_connection(data->connection TSRMLS_CC);
+    }
 
-	efree(data);
+    efree(data);
 }
 /* }}} */
 
@@ -124,19 +123,65 @@ zval* create_client_object(char* host, long port TSRMLS_DC) /* {{{ */
 }
 /* }}} */
 
+riak_connection *get_client_connection(zval *zclient TSRMLS_DC)/* {{{ */
+{
+    client_data *data;
+    if ( ! zclient) {
+        return NULL;
+    }
+
+    data = (client_data*) zend_object_store_get_object(zclient TSRMLS_CC);
+
+    if (data->connection) {
+        ensure_connected(data->connection TSRMLS_CC);
+
+        return data->connection;
+    }
+
+    if ( ! create_object_connection(zclient TSRMLS_CC)) {
+        return NULL;
+    }
+
+    return data->connection;
+}
+/* }}} */
+
+int create_object_connection(zval* zConn TSRMLS_DC)/* {{{ */
+{
+    client_data* data;
+    zval *zHost, *zPort;
+
+    zend_call_method_with_0_params(&zConn, NULL, NULL, "getHost", &zHost);
+    zend_call_method_with_0_params(&zConn, NULL, NULL, "getPort", &zPort);
+
+    data = (client_data*) zend_object_store_get_object(zConn TSRMLS_CC);
+    data->connection  = take_connection(Z_STRVAL_P(zHost), Z_STRLEN_P(zHost), Z_LVAL_P(zPort) TSRMLS_CC);
+
+    zval_ptr_dtor(&zHost);
+    zval_ptr_dtor(&zPort);
+
+    if ( ! data->connection) {
+        return 0;
+    }
+
+    return 1;
+}
+/* }}} */
+
 /* {{{ proto void RiakConnection->__construct(string $host, [int $port])
 Create a new RiakConnection */
 PHP_METHOD(RiakConnection, __construct)
 {
-	client_data *data;
+    client_data *data;
     char *host;
-	int hostLen;
-	long port = DEFAULT_PORT;
+    int hostLen;
+    long port = DEFAULT_PORT;
     zval* zbucketarr;
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &host, &hostLen, &port) == FAILURE) {
-		return;
-	}
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &host, &hostLen, &port) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
 
     zend_update_property_stringl(riak_connection_ce, getThis(), "host", sizeof("host")-1, host, hostLen TSRMLS_CC);
     zend_update_property_long(riak_connection_ce, getThis(), "port", sizeof("port")-1, port TSRMLS_CC);
@@ -145,34 +190,37 @@ PHP_METHOD(RiakConnection, __construct)
     array_init(zbucketarr);
     zend_update_property(riak_connection_ce, getThis(), "buckets", sizeof("buckets")-1, zbucketarr TSRMLS_CC);
     zval_ptr_dtor(&zbucketarr);
+}
+/* }}} */
 
-	data = (client_data*)zend_object_store_get_object(getThis() TSRMLS_CC);
-
-	data->connection = take_connection(host, hostLen, port TSRMLS_CC);
-
-	if (!data->connection) {
-		zend_throw_exception(riak_connection_exception_ce, "Connection error", 1000 TSRMLS_CC);
-	}
+/* {{{ proto void Riak\Connection->getServerInfo()
+Get a ServerInfo object */
+PHP_METHOD(RiakConnection, getServerInfo)
+{
+    zval* sinfo;
+    MAKE_STD_ZVAL(sinfo);
+    object_init_ex(sinfo, riak_server_info_ce);
+    RIAK_CALL_METHOD1(Riak_Server_Info, __construct, NULL, sinfo, getThis());
+    RETURN_ZVAL(sinfo, 0, 1);
 }
 /* }}} */
 
-/* {{{ proto void RiakConnection->ping()
+/* {{{ proto void Riak\Connection->ping()
 Ping riak to see if it is alive, an exception is thrown if no response is received */
 PHP_METHOD(RiakConnection, ping)
 {
-	int pingStatus;
-	riak_connection *connection;
+    int pingStatus;
+    riak_connection *connection = get_client_connection(getThis() TSRMLS_CC);
 
-	GET_RIAK_CONNECTION(getThis(), connection);
-	ensure_connected(connection TSRMLS_CC);
+    THROW_EXCEPTION_IF_CONNECTION_IS_NULL(connection);
 
-	pingStatus = riack_ping(connection->client);
+    pingStatus = riack_ping(connection->client);
 
-	CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, pingStatus);
+    CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, pingStatus);
 }
 /* }}} */
 
-/* {{{ proto string RiakConnection->getHost()
+/* {{{ proto string Riak\Connection->getHost()
 Get this connections hostname */
 PHP_METHOD(RiakConnection, getHost)
 {
@@ -180,7 +228,7 @@ PHP_METHOD(RiakConnection, getHost)
 }
 /* }}} */
 
-/* {{{ proto int RiakConnection->getPort()
+/* {{{ proto int Riak\Connection->getPort()
 Get this connections port number */
 PHP_METHOD(RiakConnection, getPort)
 {
@@ -188,7 +236,7 @@ PHP_METHOD(RiakConnection, getPort)
 }
 /* }}} */
 
-/* {{{ proto Riak\Bucket RiakConnection->getBucket(string $bucketName)
+/* {{{ proto Riak\Bucket Riak\Connection->getBucket(string $bucketName)
 Get a Riak\Bucket */
 PHP_METHOD(RiakConnection, getBucket)
 {
@@ -197,6 +245,7 @@ PHP_METHOD(RiakConnection, getBucket)
     zval* zbucketarr, *zbucket;
 
     if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
         return;
     }
 
@@ -213,7 +262,7 @@ PHP_METHOD(RiakConnection, getBucket)
 
     // If we are here we did not find an existing bucket, create a new
     zbucket = create_bucket_object(getThis(), name, name_len TSRMLS_CC);
-    
+
     RETURN_ZVAL(zbucket, 0, 1);
 }
 /* }}} */
diff --git a/connection.h b/riak/connection.h
similarity index 89%
rename from connection.h
rename to riak/connection.h
index 0a6a293..2c344d9 100644
--- a/connection.h
+++ b/riak/connection.h
@@ -18,7 +18,7 @@
 #ifndef RIAK_CONNECTION__H__
 #define RIAK_CONNECTION__H__
 
-#include <riack.h>
+#include "php_riak_internal.h"
 #include "pool.h"
 
 extern zend_class_entry *riak_connection_ce;
@@ -30,8 +30,6 @@ typedef struct _client_data {
   riak_connection *connection;
 } client_data;
 
-#define GET_RIAK_CONNECTION(ZOBJ, VAR) VAR = ((client_data*)zend_object_store_get_object(ZOBJ TSRMLS_CC))->connection
-
 /*************************************************
 * Constants
 *************************************************/
@@ -45,6 +43,8 @@ typedef struct _client_data {
 zval* create_client_object(char* host, long port TSRMLS_DC);
 
 void riak_connection_init(TSRMLS_D);
+int create_object_connection(zval* zConn TSRMLS_DC);
+riak_connection *get_client_connection(zval *zclient TSRMLS_DC);
 zend_object_value create_client_data(zend_class_entry *class_type TSRMLS_DC);
 void free_client_data(void *object TSRMLS_DC);
 
@@ -53,5 +53,6 @@ PHP_METHOD(RiakConnection, ping);
 PHP_METHOD(RiakConnection, getHost);
 PHP_METHOD(RiakConnection, getPort);
 PHP_METHOD(RiakConnection, getBucket);
+PHP_METHOD(RiakConnection, getServerInfo);
 
 #endif
diff --git a/riak/crdt/counter.c b/riak/crdt/counter.c
new file mode 100644
index 0000000..8201f0e
--- /dev/null
+++ b/riak/crdt/counter.c
@@ -0,0 +1,186 @@
+/*
+   Copyright 2013 Trifork A/S
+   Author: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "counter.h"
+#include "../connection.h"
+#include "../bucket.h"
+#include "../exception/exception.h"
+#include "input/update_input.h"
+#include "input/get_input.h"
+
+zend_class_entry *riak_crdt_counter_ce;
+
+#define RIAK_COUNTER_GET_BUCKET_KEY_CONN zbucket = zend_read_property(riak_crdt_counter_ce, getThis(), "bucket", sizeof("bucket")-1, 1 TSRMLS_CC); \
+                                         zkey = zend_read_property(riak_crdt_counter_ce, getThis(), "key", sizeof("key")-1, 1 TSRMLS_CC); \
+                                         connection = get_riak_connection(zbucket TSRMLS_CC); \
+                                         bucket = riack_name_from_bucket(zbucket TSRMLS_CC); \
+                                         key.len = Z_STRLEN_P(zkey); \
+                                         key.value = Z_STRVAL_P(zkey) \
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_crdt_counter_ctor, 0, ZEND_RETURN_VALUE, 2)
+    ZEND_ARG_INFO(0, bucket)
+    ZEND_ARG_INFO(0, key)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_crdt_counter_inc, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, amount)
+    ZEND_ARG_INFO(0, updateInput)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_crdt_counter_get, 0, ZEND_RETURN_VALUE, 0)
+    ZEND_ARG_INFO(0, getInput)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_crdt_counter_methods[] = {
+    PHP_ME(Riak_Crdt_Counter, __construct, arginfo_riak_crdt_counter_ctor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+    PHP_ME(Riak_Crdt_Counter, increment, arginfo_riak_crdt_counter_inc, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Crdt_Counter, incrementAndGet, arginfo_riak_crdt_counter_inc, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Crdt_Counter, get, arginfo_riak_crdt_counter_get, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+void riak_crdt_counter_init(TSRMLS_D) /* {{{ */
+{
+    zend_class_entry ce;
+
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Crdt", "Counter", riak_crdt_counter_methods);
+    riak_crdt_counter_ce = zend_register_internal_class(&ce TSRMLS_CC);
+
+    zend_declare_property_null(riak_crdt_counter_ce, "bucket", sizeof("bucket")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_crdt_counter_ce, "key", sizeof("key")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto void Riak\Crdt\Counter->__construct(Riak\Connection $connection, Riak\Bucket $bucket, string $key)
+Create a Riak\Crdt\Counter */
+PHP_METHOD(Riak_Crdt_Counter, __construct)
+{
+    char *key;
+    int keylen;
+    zval *zbucket;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os", &zbucket, riak_bucket_ce, &key, &keylen) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    zend_update_property(riak_crdt_counter_ce, getThis(), "bucket", sizeof("bucket")-1, zbucket TSRMLS_CC);
+    zend_update_property_stringl(riak_crdt_counter_ce, getThis(), "key", sizeof("key")-1, key, keylen TSRMLS_CC);
+}
+/* }}} */
+
+
+void riak_update_riack_counter_inc_props_from_input(riack_counter_update_properties *props, zval* zinput TSRMLS_DC) { /* {{{ */
+#define SET_RIAK_CNT_UPDATE_PROP_LONG(GETTER_NAME, PROP_NAME) MAKE_STD_ZVAL(ztmp); \
+                                                  RIAK_CALL_METHOD(Riak_Crdt_Input_UpdateInput, GETTER_NAME, ztmp, zinput); \
+                                                  props->PROP_NAME##_use = 1; \
+                                                  props->PROP_NAME = Z_LVAL_P(ztmp); \
+                                                  zval_ptr_dtor(&ztmp)
+    zval* ztmp;
+    if (zinput && Z_TYPE_P(zinput) == IS_OBJECT) {
+        SET_RIAK_CNT_UPDATE_PROP_LONG(getDW, dw);
+        SET_RIAK_CNT_UPDATE_PROP_LONG(getPW, pw);
+        SET_RIAK_CNT_UPDATE_PROP_LONG(getW, w);
+    }
+}/* }}} */
+
+
+/* {{{ proto void Riak\Crdt\Counter->increment($amount [, Riak\Crdt\Input\UpdateInput $input])
+Increment counter, use negative amount to decrement */
+PHP_METHOD(Riak_Crdt_Counter, increment)
+{
+    riack_counter_update_properties props;
+    zval *zinput, *zbucket, *zkey;
+    riak_connection *connection;
+    riack_string bucket, key;
+    long amount;
+    int riackresult;
+    zinput = 0;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|O", &amount, &zinput, riak_crdt_input_update_ce) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    memset(&props, 0, sizeof(props));
+    riak_update_riack_counter_inc_props_from_input(&props, zinput TSRMLS_CC);
+    RIAK_COUNTER_GET_BUCKET_KEY_CONN;
+
+    riackresult = riack_counter_increment(connection->client, &bucket, &key, (int64_t)amount, &props, 0);
+    CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, riackresult);
+}/* }}} */
+
+
+/* {{{ proto int Riak\Crdt\Counter->increment($amount [, Riak\Crdt\Input\UpdateInput $input])
+Increment counter, use negative amount to decrement, returns updated value */
+PHP_METHOD(Riak_Crdt_Counter, incrementAndGet)
+{
+    riack_counter_update_properties props;
+    zval *zinput, *zbucket, *zkey;
+    riak_connection *connection;
+    riack_string bucket, key;
+    long amount;
+    int64_t return_val;
+    int riackresult;
+    zinput = 0;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|O", &amount, &zinput, riak_crdt_input_update_ce) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    memset(&props, 0, sizeof(props));
+    riak_update_riack_counter_inc_props_from_input(&props, zinput TSRMLS_CC);
+    RIAK_COUNTER_GET_BUCKET_KEY_CONN;
+
+    riackresult = riack_counter_increment(connection->client, &bucket, &key, (int64_t)amount, &props, &return_val);
+    CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, riackresult);
+    RETURN_LONG((long)return_val);
+}/* }}} */
+
+
+/* {{{ proto int Riak\Crdt\Counter->get([Riak\Crdt\Input\GetInput $input])
+Get counter value from riak */
+PHP_METHOD(Riak_Crdt_Counter, get)
+{
+#define SET_RIAK_CNT_GET_PROP_LONG(GETTER_NAME, PROP_NAME) MAKE_STD_ZVAL(ztmp); \
+                                                  RIAK_CALL_METHOD(Riak_Crdt_Input_GetInput, GETTER_NAME, ztmp, zinput); \
+                                                  props.PROP_NAME##_use = 1; \
+                                                  props.PROP_NAME = Z_LVAL_P(ztmp); \
+                                                  zval_ptr_dtor(&ztmp)
+#define SET_RIAK_CNT_GET_PROP_BOOL(GETTER_NAME, PROP_NAME) MAKE_STD_ZVAL(ztmp); \
+                                                  RIAK_CALL_METHOD(Riak_Crdt_Input_GetInput, GETTER_NAME, ztmp, zinput); \
+                                                  props.PROP_NAME##_use = 1; \
+                                                  props.PROP_NAME = Z_BVAL_P(ztmp); \
+                                                  zval_ptr_dtor(&ztmp)
+    riack_counter_get_properties props;
+    zval *zinput, *zbucket, *zkey;
+    riak_connection *connection;
+    riack_string bucket, key;
+    int riackresult;
+    int64_t result;
+    zinput = 0;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|O", &zinput, riak_crdt_input_get_ce) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    memset(&props, 0, sizeof(props));
+    RIAK_COUNTER_GET_BUCKET_KEY_CONN;
+    if (zinput) {
+        zval* ztmp;
+        SET_RIAK_CNT_GET_PROP_LONG(getR, r);
+        SET_RIAK_CNT_GET_PROP_LONG(getPR, pr);
+        SET_RIAK_CNT_GET_PROP_BOOL(getBasicQuorum, basic_quorum);
+        SET_RIAK_CNT_GET_PROP_BOOL(getNotFoundOk, notfound_ok);
+    }
+    riackresult = riack_counter_get(connection->client, &bucket, &key, &props, &result);
+    CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, riackresult);
+    RETURN_LONG((long)result);
+}/* }}} */
diff --git a/riak/crdt/counter.h b/riak/crdt/counter.h
new file mode 100644
index 0000000..1d872af
--- /dev/null
+++ b/riak/crdt/counter.h
@@ -0,0 +1,33 @@
+/*
+   Copyright 2013 Trifork A/S
+   Author: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK__CRDT__COUNTER__H__
+#define RIAK__CRDT__COUNTER__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_crdt_counter_ce;
+
+void riak_crdt_counter_init(TSRMLS_D);
+
+PHP_METHOD(Riak_Crdt_Counter, __construct);
+
+PHP_METHOD(Riak_Crdt_Counter, increment);
+PHP_METHOD(Riak_Crdt_Counter, incrementAndGet);
+PHP_METHOD(Riak_Crdt_Counter, get);
+
+#endif // RIAK__CRDT__COUNTER__H__
diff --git a/riak/crdt/input/get_input.c b/riak/crdt/input/get_input.c
new file mode 100644
index 0000000..1923972
--- /dev/null
+++ b/riak/crdt/input/get_input.c
@@ -0,0 +1,135 @@
+/*
+   Copyright 2013 Trifork A/S
+   Author: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "get_input.h"
+
+zend_class_entry *riak_crdt_input_get_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_crdt_input_get_set_r, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, r)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_crdt_input_get_set_pr, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, pr)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_crdt_input_get_set_not_foundok, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, notFoundOk)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_crdt_input_get_set_bq, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, basicQuorum)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_crdt_input_get_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_crdt_input_get_methods[] = {
+    PHP_ME(Riak_Crdt_Input_GetInput, setR, arginfo_riak_crdt_input_get_set_r, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Crdt_Input_GetInput, getR, arginfo_riak_crdt_input_get_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Crdt_Input_GetInput, setPR, arginfo_riak_crdt_input_get_set_pr, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Crdt_Input_GetInput, getPR, arginfo_riak_crdt_input_get_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Crdt_Input_GetInput, setBasicQuorum, arginfo_riak_crdt_input_get_set_bq, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Crdt_Input_GetInput, getBasicQuorum, arginfo_riak_crdt_input_get_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Crdt_Input_GetInput, setNotFoundOk, arginfo_riak_crdt_input_get_set_not_foundok, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Crdt_Input_GetInput, getNotFoundOk, arginfo_riak_crdt_input_get_noargs, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+void riak_crdt_input_get_input_init(TSRMLS_D) /* {{{ */
+{
+    zend_class_entry ce;
+
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Crdt\\Input", "GetInput", riak_crdt_input_get_methods);
+    riak_crdt_input_get_ce = zend_register_internal_class(&ce TSRMLS_CC);
+
+    zend_declare_property_null(riak_crdt_input_get_ce, "r", sizeof("r")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_crdt_input_get_ce, "pr", sizeof("pr")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_crdt_input_get_ce, "basicQuorum", sizeof("basicQuorum")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_crdt_input_get_ce, "notFoundOk", sizeof("notFoundOk")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+}
+/* }}} */
+
+
+/* {{{ proto Riak\Input\Crdt\GetInput Riak\Crdt\Input\GetInput->setR(int $r)
+Set R value */
+PHP_METHOD(Riak_Crdt_Input_GetInput, setR)
+{
+    RIAK_SETTER_BOOL(riak_crdt_input_get_ce, "r");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto int Riak\Crdt\Input\GetInput->getR()
+Get R value */
+PHP_METHOD(Riak_Crdt_Input_GetInput, getR)
+{
+    RIAK_GETTER_BOOL(riak_crdt_input_get_ce, "r");
+}
+/* }}} */
+
+/* {{{ proto Riak\Crdt\Input\GetInput Riak\Crdt\Input\GetInput->setPR(int $r)
+Set PR value */
+PHP_METHOD(Riak_Crdt_Input_GetInput, setPR)
+{
+    RIAK_SETTER_BOOL(riak_crdt_input_get_ce, "pr");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto int Riak\Crdt\Input\GetInput->getPR()
+Get PR value */
+PHP_METHOD(Riak_Crdt_Input_GetInput, getPR)
+{
+    RIAK_GETTER_BOOL(riak_crdt_input_get_ce, "pr");
+}
+/* }}} */
+
+
+/* {{{ proto bool Riak\Crdt\Input\GetInput->getBasicQuorum()
+Get basicQuerum */
+PHP_METHOD(Riak_Crdt_Input_GetInput, getBasicQuorum)
+{
+    RIAK_GETTER_BOOL(riak_crdt_input_get_ce, "basicQuorum");
+}
+/* }}} */
+
+/* {{{ proto Riak\Input\Crdt\GetInput Riak\Input\Crdt\GetInput->setBasicQuorum(bool $basicQuorum)
+Set basicQuerum value */
+PHP_METHOD(Riak_Crdt_Input_GetInput, setBasicQuorum)
+{
+    RIAK_SETTER_BOOL(riak_crdt_input_get_ce, "basicQuorum");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto bool Riak\Crdt\Input\GetInput->getNotFoundOk()
+Get not found ok */
+PHP_METHOD(Riak_Crdt_Input_GetInput, getNotFoundOk)
+{
+    RIAK_GETTER_BOOL(riak_crdt_input_get_ce, "notFoundOk");
+}
+/* }}} */
+
+/* {{{ proto Riak\Crdt\Input\GetInput Riak\Crdt\Input\GetInput->setNotFoundOk(bool $notFoundOk)
+Set not found ok */
+PHP_METHOD(Riak_Crdt_Input_GetInput, setNotFoundOk)
+{
+    RIAK_SETTER_BOOL(riak_crdt_input_get_ce, "notFoundOk");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
diff --git a/riak/crdt/input/get_input.h b/riak/crdt/input/get_input.h
new file mode 100644
index 0000000..c7b6311
--- /dev/null
+++ b/riak/crdt/input/get_input.h
@@ -0,0 +1,36 @@
+/*
+   Copyright 2013 Trifork A/S
+   Author: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK__CRDT__INPUT__GET_INPUT__H__
+#define RIAK__CRDT__INPUT__GET_INPUT__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_crdt_input_get_ce;
+
+void riak_crdt_input_get_input_init(TSRMLS_D);
+
+PHP_METHOD(Riak_Crdt_Input_GetInput, getR);
+PHP_METHOD(Riak_Crdt_Input_GetInput, setR);
+PHP_METHOD(Riak_Crdt_Input_GetInput, getPR);
+PHP_METHOD(Riak_Crdt_Input_GetInput, setPR);
+PHP_METHOD(Riak_Crdt_Input_GetInput, getBasicQuorum);
+PHP_METHOD(Riak_Crdt_Input_GetInput, setBasicQuorum);
+PHP_METHOD(Riak_Crdt_Input_GetInput, getNotFoundOk);
+PHP_METHOD(Riak_Crdt_Input_GetInput, setNotFoundOk);
+
+#endif // RIAK__CRDT__INPUT__GET_INPUT__H__
diff --git a/riak/crdt/input/update_input.c b/riak/crdt/input/update_input.c
new file mode 100644
index 0000000..b9b908b
--- /dev/null
+++ b/riak/crdt/input/update_input.c
@@ -0,0 +1,109 @@
+/*
+   Copyright 2013 Trifork A/S
+   Author: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "update_input.h"
+
+zend_class_entry *riak_crdt_input_update_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_crdt_input_update_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_crdt_input_update_set_w, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, w)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_crdt_input_update_set_dw, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, dw)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_crdt_input_update_set_pw, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, pw)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_crdt_input_update_methods[] = {
+    PHP_ME(Riak_Crdt_Input_UpdateInput, setW, arginfo_riak_crdt_input_update_set_w, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Crdt_Input_UpdateInput, getW, arginfo_riak_crdt_input_update_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Crdt_Input_UpdateInput, setDW, arginfo_riak_crdt_input_update_set_dw, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Crdt_Input_UpdateInput, getDW, arginfo_riak_crdt_input_update_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Crdt_Input_UpdateInput, setPW, arginfo_riak_crdt_input_update_set_pw, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Crdt_Input_UpdateInput, getPW, arginfo_riak_crdt_input_update_noargs, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+
+void riak_crdt_input_update_input_init(TSRMLS_D)/* {{{ */
+{
+    zend_class_entry ce;
+
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Crdt\\Input", "UpdateInput", riak_crdt_input_update_methods);
+    riak_crdt_input_update_ce = zend_register_internal_class(&ce TSRMLS_CC);
+    zend_declare_property_null(riak_crdt_input_update_ce, "w", sizeof("w")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_crdt_input_update_ce, "dw", sizeof("dw")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_crdt_input_update_ce, "pw", sizeof("pw")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+}/* }}} */
+
+
+/* {{{ proto int|null Riak\Crdt\Input\UpdateInput->getW()
+Gets W value */
+PHP_METHOD(Riak_Crdt_Input_UpdateInput, getW)
+{
+    RIAK_GETTER_LONG(riak_crdt_input_update_ce, "w");
+}
+/* }}} */
+
+/* {{{ proto Riak\Crdt\Input\UpdateInput Riak\Crdt\Input\UpdateInput->setW(int $w)
+Set W value */
+PHP_METHOD(Riak_Crdt_Input_UpdateInput, setW)
+{
+    RIAK_SETTER_LONG(riak_crdt_input_update_ce, "w");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto int|null Riak\Crdt\Input\UpdateInput->getDW()
+Gets DW value */
+PHP_METHOD(Riak_Crdt_Input_UpdateInput, getDW)
+{
+    RIAK_GETTER_LONG(riak_crdt_input_update_ce, "dw");
+}
+/* }}} */
+
+/* {{{ proto Riak\Crdt\Input\UpdateInput Riak\Crdt\Input\UpdateInput->setDW(int $dw)
+Set DW value */
+PHP_METHOD(Riak_Crdt_Input_UpdateInput, setDW)
+{
+    RIAK_SETTER_LONG(riak_crdt_input_update_ce, "dw");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto int|null Riak\Crdt\Input\UpdateInput->getPW()
+Gets PW value */
+PHP_METHOD(Riak_Crdt_Input_UpdateInput, getPW)
+{
+    RIAK_GETTER_LONG(riak_crdt_input_update_ce, "pw");
+}
+/* }}} */
+
+/* {{{ proto Riak\Crdt\Input\UpdateInput Riak\Crdt\Input\UpdateInput->setPW(int $pw)
+Set PW value */
+PHP_METHOD(Riak_Crdt_Input_UpdateInput, setPW)
+{
+    RIAK_SETTER_LONG(riak_crdt_input_update_ce, "pw");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
diff --git a/riak/crdt/input/update_input.h b/riak/crdt/input/update_input.h
new file mode 100644
index 0000000..5252514
--- /dev/null
+++ b/riak/crdt/input/update_input.h
@@ -0,0 +1,34 @@
+/*
+   Copyright 2013 Trifork A/S
+   Author: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK__CRDT__INPUT__UPDATE_INPUT__H__
+#define RIAK__CRDT__INPUT__UPDATE_INPUT__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_crdt_input_update_ce;
+
+void riak_crdt_input_update_input_init(TSRMLS_D);
+
+PHP_METHOD(Riak_Crdt_Input_UpdateInput, getW);
+PHP_METHOD(Riak_Crdt_Input_UpdateInput, setW);
+PHP_METHOD(Riak_Crdt_Input_UpdateInput, getDW);
+PHP_METHOD(Riak_Crdt_Input_UpdateInput, setDW);
+PHP_METHOD(Riak_Crdt_Input_UpdateInput, getPW);
+PHP_METHOD(Riak_Crdt_Input_UpdateInput, setPW);
+
+#endif // RIAK__CRDT__INPUT__UPDATE_INPUT__H__
diff --git a/exceptions.c b/riak/exception/exception.c
similarity index 50%
rename from exceptions.c
rename to riak/exception/exception.c
index 8c891cc..642ae35 100644
--- a/exceptions.c
+++ b/riak/exception/exception.c
@@ -14,9 +14,8 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 */
-#include <php.h>
-#include <zend_exceptions.h>
-#include "exceptions.h"
+
+#include "exception.h"
 
 zend_class_entry *riak_exception_ce;
 
@@ -24,34 +23,39 @@ zend_class_entry *riak_badarguments_exception_ce;
 zend_class_entry *riak_connection_exception_ce;
 zend_class_entry *riak_communication_exception_ce;
 zend_class_entry *riak_response_exception_ce;
-zend_class_entry *riak_not_found_exception_ce;
+zend_class_entry *riak_nonunique_exception_ce;
+zend_class_entry *riak_unresolvedconflict_exception_ce;
 
 void riak_exceptions_init(TSRMLS_D) 
 {
-	zend_class_entry ceBadArgs, ceRiak, ceConnExc, ceCommExc, ceRespExc, ceNotFound;
+    zend_class_entry ceBadArgs, ceRiak, ceConnExc, ceCommExc, ceRespExc;
 
     INIT_NS_CLASS_ENTRY(ceRiak, "Riak\\Exception", "RiakException", NULL);
-	riak_exception_ce = zend_register_internal_class_ex(&ceRiak, 
-		(zend_class_entry*)zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
+    riak_exception_ce = zend_register_internal_class_ex(&ceRiak, 
+        (zend_class_entry*)zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
 
     INIT_NS_CLASS_ENTRY(ceBadArgs, "Riak\\Exception", "BadArgumentsException", NULL);
-	riak_badarguments_exception_ce = zend_register_internal_class_ex(&ceBadArgs, 
-		riak_exception_ce, NULL TSRMLS_CC);
+    riak_badarguments_exception_ce = zend_register_internal_class_ex(&ceBadArgs,
+        riak_exception_ce, NULL TSRMLS_CC);
 
     INIT_NS_CLASS_ENTRY(ceConnExc, "Riak\\Exception", "ConnectionException", NULL);
-	riak_connection_exception_ce = zend_register_internal_class_ex(&ceConnExc, 
-		riak_exception_ce, NULL TSRMLS_CC);
+    riak_connection_exception_ce = zend_register_internal_class_ex(&ceConnExc, 
+        riak_exception_ce, NULL TSRMLS_CC);
 
     INIT_NS_CLASS_ENTRY(ceCommExc, "Riak\\Exception","CommunicationException", NULL);
-	riak_communication_exception_ce = zend_register_internal_class_ex(&ceCommExc, 
-		riak_exception_ce, NULL TSRMLS_CC);
+    riak_communication_exception_ce = zend_register_internal_class_ex(&ceCommExc, 
+        riak_exception_ce, NULL TSRMLS_CC);
 
     INIT_NS_CLASS_ENTRY(ceRespExc, "Riak\\Exception", "UnexpectedResponseException", NULL);
-	riak_response_exception_ce = zend_register_internal_class_ex(&ceRespExc, 
-		riak_exception_ce, NULL TSRMLS_CC);
+    riak_response_exception_ce = zend_register_internal_class_ex(&ceRespExc, 
+        riak_exception_ce, NULL TSRMLS_CC);
+
+    INIT_NS_CLASS_ENTRY(ceRespExc, "Riak\\Exception", "NonUniqueException", NULL);
+    riak_nonunique_exception_ce = zend_register_internal_class_ex(&ceRespExc, 
+        riak_exception_ce, NULL TSRMLS_CC);
 
-    INIT_NS_CLASS_ENTRY(ceNotFound, "Riak\\Exception","NotFoundException", NULL);
-	riak_not_found_exception_ce = zend_register_internal_class_ex(&ceNotFound, 
-		riak_exception_ce, NULL TSRMLS_CC);
+    INIT_NS_CLASS_ENTRY(ceRespExc, "Riak\\Exception", "UnresolvedConflictException", NULL);
+    riak_unresolvedconflict_exception_ce = zend_register_internal_class_ex(&ceRespExc, 
+        riak_exception_ce, NULL TSRMLS_CC);
 
 }
diff --git a/exceptions.h b/riak/exception/exception.h
similarity index 86%
rename from exceptions.h
rename to riak/exception/exception.h
index 6a5c40b..66d5cf1 100644
--- a/exceptions.h
+++ b/riak/exception/exception.h
@@ -18,6 +18,7 @@
 #ifndef RIAK_EXCEPTIONS__H__
 #define RIAK_EXCEPTIONS__H__
 
+#include "php_riak_internal.h"
 #include <zend_exceptions.h>
 
 extern zend_class_entry *riak_badarguments_exception_ce;
@@ -25,8 +26,8 @@ extern zend_class_entry *riak_badarguments_exception_ce;
 extern zend_class_entry *riak_connection_exception_ce;
 extern zend_class_entry *riak_communication_exception_ce;
 extern zend_class_entry *riak_response_exception_ce;
-
-extern zend_class_entry *riak_not_found_exception_ce;
+extern zend_class_entry *riak_nonunique_exception_ce;
+extern zend_class_entry *riak_unresolvedconflict_exception_ce;
 
 void riak_exceptions_init(TSRMLS_D);
 
diff --git a/riak/input/delete_input.c b/riak/input/delete_input.c
new file mode 100644
index 0000000..b74fdc8
--- /dev/null
+++ b/riak/input/delete_input.c
@@ -0,0 +1,210 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#include "delete_input.h"
+#include "input.h"
+
+zend_class_entry *riak_delete_input_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_del_config_set_r, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, r)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_del_config_set_pr, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, pr)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_del_config_set_w, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, w)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_del_config_set_dw, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, dw)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_del_config_set_pw, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, pw)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_del_config_set_vclock, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, vclock)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_del_config_set_rw, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, rw)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_del_config_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+
+static zend_function_entry riak_delete_input_methods[] = {
+    PHP_ME(Riak_Input_DeleteInput, setR, arginfo_riak_del_config_set_r, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_DeleteInput, getR, arginfo_riak_del_config_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_DeleteInput, setPR, arginfo_riak_del_config_set_pr, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_DeleteInput, getPR, arginfo_riak_del_config_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_DeleteInput, setRW, arginfo_riak_del_config_set_rw, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_DeleteInput, getRW, arginfo_riak_del_config_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_DeleteInput, setW, arginfo_riak_del_config_set_w, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_DeleteInput, getW, arginfo_riak_del_config_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_DeleteInput, setDW, arginfo_riak_del_config_set_dw, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_DeleteInput, getDW, arginfo_riak_del_config_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_DeleteInput, setPW, arginfo_riak_del_config_set_pw, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_DeleteInput, getPW, arginfo_riak_del_config_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_DeleteInput, setVClock, arginfo_riak_del_config_set_vclock, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_DeleteInput, getVClock, arginfo_riak_del_config_noargs, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+void riak_input_delete_input_init(TSRMLS_D) /* {{{ */
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Input", "DeleteInput", riak_delete_input_methods);
+    riak_delete_input_ce = zend_register_internal_class_ex(&ce, riak_input_ce, NULL TSRMLS_CC);
+    zend_declare_property_null(riak_delete_input_ce, "r", sizeof("r")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_delete_input_ce, "rw", sizeof("rw")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_delete_input_ce, "pr", sizeof("pr")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_delete_input_ce, "w", sizeof("w")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_delete_input_ce, "dw", sizeof("dw")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_delete_input_ce, "pw", sizeof("pw")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_delete_input_ce, "vClock", sizeof("vClock")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+}
+/* }}} */
+
+
+/*************************************************************
+* Implementation: Riak\Input\DeleteInput
+*************************************************************/
+
+/* {{{ proto Riak\Input\DeleteInput Riak\Input\DeleteInput->setR(int $r)
+Set R value */
+PHP_METHOD(Riak_Input_DeleteInput, setR)
+{
+    RIAK_SETTER_LONG(riak_delete_input_ce, "r");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto null|int Riak\Input\PutInput->getR()
+Gets R value */
+PHP_METHOD(Riak_Input_DeleteInput, getR)
+{
+    RIAK_GETTER_LONG(riak_delete_input_ce, "r")
+}
+/* }}} */
+
+/* {{{ proto Riak\Input\DeleteInput Riak\Input\DeleteInput->setPR(int $pr)
+Set PR value */
+PHP_METHOD(Riak_Input_DeleteInput, setPR)
+{
+    RIAK_SETTER_LONG(riak_delete_input_ce, "pr");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto null|int Riak\Input\PutInput->getPR()
+Gets PR value */
+PHP_METHOD(Riak_Input_DeleteInput, getPR)
+{
+    RIAK_GETTER_LONG(riak_delete_input_ce, "pr")
+}
+/* }}} */
+
+/* {{{ proto Riak\Input\DeleteInput Riak\Input\DeleteInput->setRW(int $rw)
+Set RW value */
+PHP_METHOD(Riak_Input_DeleteInput, setRW)
+{
+    RIAK_SETTER_LONG(riak_delete_input_ce, "rw");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto null|int Riak\Input\PutInput->getRW()
+Gets RW value */
+PHP_METHOD(Riak_Input_DeleteInput, getRW)
+{
+    RIAK_GETTER_LONG(riak_delete_input_ce, "rw")
+}
+/* }}} */
+
+/* {{{ proto Riak\Input\DeleteInput Riak\Input\DeleteInput->setW(int $w)
+Set W value */
+PHP_METHOD(Riak_Input_DeleteInput, setW)
+{
+    RIAK_SETTER_LONG(riak_delete_input_ce, "w");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto null|int Riak\Input\PutInput->getW()
+Gets W value */
+PHP_METHOD(Riak_Input_DeleteInput, getW)
+{
+    RIAK_GETTER_LONG(riak_delete_input_ce, "w")
+}
+/* }}} */
+
+/* {{{ proto Riak\Input\DeleteInput Riak\Input\DeleteInput->setDW(int $dw)
+Set DW value */
+PHP_METHOD(Riak_Input_DeleteInput, setDW)
+{
+    RIAK_SETTER_LONG(riak_delete_input_ce, "dw");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto null|int Riak\Input\PutInput->getDW()
+Gets DW value */
+PHP_METHOD(Riak_Input_DeleteInput, getDW)
+{
+    RIAK_GETTER_LONG(riak_delete_input_ce, "dw")
+}
+/* }}} */
+
+/* {{{ proto Riak\Input\DeleteInput Riak\Input\DeleteInput->setPW(int $pw)
+Set PW value */
+PHP_METHOD(Riak_Input_DeleteInput, setPW)
+{
+    RIAK_SETTER_LONG(riak_delete_input_ce, "pw");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto null|int Riak\Input\PutInput->getPW()
+Gets PW value */
+PHP_METHOD(Riak_Input_DeleteInput, getPW)
+{
+    RIAK_GETTER_LONG(riak_delete_input_ce, "pw")
+}
+/* }}} */
+
+/* {{{ proto Riak\Input\DeleteInput Riak\Input\DeleteInput->setVClock(string $rw)
+Set set vector clock */
+PHP_METHOD(Riak_Input_DeleteInput, setVClock)
+{
+    RIAK_SETTER_STRING(riak_delete_input_ce, "vClock");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto null|string Riak\Input\PutInput->getVClock()
+Gets vector clock */
+PHP_METHOD(Riak_Input_DeleteInput, getVClock)
+{
+    RIAK_GETTER_STRING(riak_delete_input_ce, "vClock")
+}
+/* }}} */
+
diff --git a/riak/input/delete_input.h b/riak/input/delete_input.h
new file mode 100644
index 0000000..22b9a84
--- /dev/null
+++ b/riak/input/delete_input.h
@@ -0,0 +1,43 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_INPUT__DELETE_INPUT__H__
+#define RIAK_INPUT__DELETE_INPUT__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_delete_input_ce;
+
+void riak_input_delete_input_init(TSRMLS_D);
+
+/* Riak\Input\DeleteInput */
+PHP_METHOD(Riak_Input_DeleteInput, setR);
+PHP_METHOD(Riak_Input_DeleteInput, getR);
+PHP_METHOD(Riak_Input_DeleteInput, setPR);
+PHP_METHOD(Riak_Input_DeleteInput, getPR);
+PHP_METHOD(Riak_Input_DeleteInput, setRW);
+PHP_METHOD(Riak_Input_DeleteInput, getRW);
+PHP_METHOD(Riak_Input_DeleteInput, setW);
+PHP_METHOD(Riak_Input_DeleteInput, getW);
+PHP_METHOD(Riak_Input_DeleteInput, setDW);
+PHP_METHOD(Riak_Input_DeleteInput, getDW);
+PHP_METHOD(Riak_Input_DeleteInput, setPW);
+PHP_METHOD(Riak_Input_DeleteInput, getPW);
+PHP_METHOD(Riak_Input_DeleteInput, setVClock);
+PHP_METHOD(Riak_Input_DeleteInput, getVClock);
+
+
+#endif //RIAK_INPUT__DELETE_INPUT__H__
diff --git a/riak/input/get_input.c b/riak/input/get_input.c
new file mode 100644
index 0000000..9bb9a1a
--- /dev/null
+++ b/riak/input/get_input.c
@@ -0,0 +1,208 @@
+/*
+   Copyright 2013 Kaspar Bach Pedersen
+
+   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.
+*/
+#include "get_input.h"
+#include "input.h"
+
+zend_class_entry *riak_get_input_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_get_config_set_head, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, return_head)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_get_config_set_r, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, r)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_get_config_set_pr, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, pr)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_get_config_set_bq, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, basic_quorum)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_get_config_set_notfoundok, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, not_found_ok)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_get_config_set_ifnotmod, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, ifModified_vclock)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_get_config_set_deleted_vclock, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, deleted_vclock)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_get_config_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+
+static zend_function_entry riak_get_input_methods[] = {
+    PHP_ME(Riak_Input_GetInput, setReturnHead, arginfo_riak_get_config_set_head, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_GetInput, getReturnHead, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_GetInput, setR, arginfo_riak_get_config_set_r, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_GetInput, getR, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_GetInput, setPR, arginfo_riak_get_config_set_pr, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_GetInput, getPR, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_GetInput, setBasicQuorum, arginfo_riak_get_config_set_bq, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_GetInput, getBasicQuorum, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_GetInput, setNotFoundOk, arginfo_riak_get_config_set_notfoundok, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_GetInput, getNotFoundOk, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_GetInput, setIfModifiedVClock, arginfo_riak_get_config_set_ifnotmod, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_GetInput, getIfModifiedVClock, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_GetInput, setReturnDeletedVClock, arginfo_riak_get_config_set_deleted_vclock, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_GetInput, getReturnDeletedVClock, arginfo_riak_get_config_noargs, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+void riak_input_get_input_init(TSRMLS_D) /* {{{ */
+{
+    zend_class_entry ce;
+
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Input", "GetInput", riak_get_input_methods);
+    riak_get_input_ce = zend_register_internal_class_ex(&ce, riak_input_ce, NULL TSRMLS_CC);
+    zend_declare_property_null(riak_get_input_ce, "r", sizeof("r")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_get_input_ce, "pr", sizeof("pr")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_get_input_ce, "basicQuorum", sizeof("basicQuorum")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_get_input_ce, "notFoundOk", sizeof("notFoundOk")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_get_input_ce, "ifModifiedVClock", sizeof("ifModifiedVClock")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_get_input_ce, "returnHead", sizeof("returnHead")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_get_input_ce, "deletedVClock", sizeof("deletedVClock")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+}
+/* }}} */
+
+
+/*************************************************************
+* Implementation: Riak\Input\GetInput
+*************************************************************/
+
+/* {{{ proto Riak\Input\GetInput Riak\Input\GetInput->setReturnHead(bool $returnHead)
+Sets return head option */
+PHP_METHOD(Riak_Input_GetInput, setReturnHead)
+{
+    RIAK_SETTER_BOOL(riak_get_input_ce, "returnHead");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto void Riak\Input\GetInput->getReturnHead()
+Gets return head option */
+PHP_METHOD(Riak_Input_GetInput, getReturnHead)
+{
+    RIAK_GETTER_BOOL(riak_get_input_ce, "returnHead");
+}
+/* }}} */
+
+/* {{{ proto Riak\Input\GetInput Riak\Input\GetInput->setR(int $r)
+Set R value */
+PHP_METHOD(Riak_Input_GetInput, setR)
+{
+    RIAK_SETTER_BOOL(riak_get_input_ce, "r");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto int Riak\Input\GetInput->getR()
+Get R value */
+PHP_METHOD(Riak_Input_GetInput, getR)
+{
+    RIAK_GETTER_BOOL(riak_get_input_ce, "r");
+}
+/* }}} */
+
+/* {{{ proto Riak\Input\GetInput Riak\Input\GetInput->setPR(int $r)
+Set PR value */
+PHP_METHOD(Riak_Input_GetInput, setPR)
+{
+    RIAK_SETTER_BOOL(riak_get_input_ce, "pr");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto int Riak\Input\GetInput->getPR()
+Get PR value */
+PHP_METHOD(Riak_Input_GetInput, getPR)
+{
+    RIAK_GETTER_BOOL(riak_get_input_ce, "pr");
+}
+/* }}} */
+
+/* {{{ proto bool Riak\Input\GetInput->getBasicQuorum()
+Get basicQuerum */
+PHP_METHOD(Riak_Input_GetInput, getBasicQuorum)
+{
+    RIAK_GETTER_BOOL(riak_get_input_ce, "basicQuorum");
+}
+/* }}} */
+
+/* {{{ proto Riak\Input\GetInput Riak\Input\GetInput->setBasicQuorum(bool $basicQuorum)
+Set basicQuerum value */
+PHP_METHOD(Riak_Input_GetInput, setBasicQuorum)
+{
+    RIAK_SETTER_BOOL(riak_get_input_ce, "basicQuorum");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto bool Riak\Input\GetInput->getNotFoundOk()
+Get not found ok */
+PHP_METHOD(Riak_Input_GetInput, getNotFoundOk)
+{
+    RIAK_GETTER_BOOL(riak_get_input_ce, "notFoundOk");
+}
+/* }}} */
+
+/* {{{ proto Riak\Input\GetInput Riak\Input\GetInput->setNotFoundOk(bool $notFoundOk)
+Set not found ok */
+PHP_METHOD(Riak_Input_GetInput, setNotFoundOk)
+{
+    RIAK_SETTER_BOOL(riak_get_input_ce, "notFoundOk");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto string Riak\Input\GetInput->getIfModifiedVClock()
+Get IfModifiedVClock */
+PHP_METHOD(Riak_Input_GetInput, getIfModifiedVClock)
+{
+    RIAK_GETTER_STRING(riak_get_input_ce, "ifModifiedVClock");
+}
+/* }}} */
+
+/* {{{ proto Riak\Input\GetInput Riak\Input\GetInput->setIfModifiedVClock(string $ifModifiedVClock)
+Set IfModifiedVClock */
+PHP_METHOD(Riak_Input_GetInput, setIfModifiedVClock)
+{
+    RIAK_SETTER_STRING(riak_get_input_ce, "ifModifiedVClock");
+    RIAK_RETURN_THIS
+}
+
+/* {{{ proto bool Riak\Input\GetInput->getReturnDeletedVClock()
+Get returns deleted vclock */
+PHP_METHOD(Riak_Input_GetInput, getReturnDeletedVClock)
+{
+    RIAK_GETTER_BOOL(riak_get_input_ce, "deletedVClock");
+}
+/* }}} */
+
+/* {{{ proto Riak\Input\GetInput Riak\Input\GetInput->setReturnDeletedVClock(bool $returnDeletedVClock)
+Set returnDeletedVClock */
+PHP_METHOD(Riak_Input_GetInput, setReturnDeletedVClock)
+{
+    RIAK_SETTER_BOOL(riak_get_input_ce, "deletedVClock");
+    RIAK_RETURN_THIS
+}
+
diff --git a/riak/input/get_input.h b/riak/input/get_input.h
new file mode 100644
index 0000000..b43e6f8
--- /dev/null
+++ b/riak/input/get_input.h
@@ -0,0 +1,45 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_INPUT__GET_INPUT__H__
+#define RIAK_INPUT__GET_INPUT__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_get_input_ce;
+
+void riak_input_get_input_init(TSRMLS_D);
+
+
+/* Riak\Input\GetInput */
+PHP_METHOD(Riak_Input_GetInput, setReturnHead);
+PHP_METHOD(Riak_Input_GetInput, getReturnHead);
+PHP_METHOD(Riak_Input_GetInput, getR);
+PHP_METHOD(Riak_Input_GetInput, setR);
+PHP_METHOD(Riak_Input_GetInput, getPR);
+PHP_METHOD(Riak_Input_GetInput, setPR);
+PHP_METHOD(Riak_Input_GetInput, getBasicQuorum);
+PHP_METHOD(Riak_Input_GetInput, setBasicQuorum);
+PHP_METHOD(Riak_Input_GetInput, getNotFoundOk);
+PHP_METHOD(Riak_Input_GetInput, setNotFoundOk);
+PHP_METHOD(Riak_Input_GetInput, getIfModifiedVClock);
+PHP_METHOD(Riak_Input_GetInput, setIfModifiedVClock);
+PHP_METHOD(Riak_Input_GetInput, getReturnDeletedVClock);
+PHP_METHOD(Riak_Input_GetInput, setReturnDeletedVClock);
+
+
+
+#endif //RIAK_INPUT__GET_INPUT__H__
diff --git a/riak/input/get_resolver_input.c b/riak/input/get_resolver_input.c
new file mode 100644
index 0000000..d93e29d
--- /dev/null
+++ b/riak/input/get_resolver_input.c
@@ -0,0 +1,71 @@
+/*
+   Copyright 2013 Kaspar Bach Pedersen
+
+   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.
+*/
+
+#include "riak/output/conflict_resolver.h"
+#include "get_resolver_input.h"
+#include "get_input.h"
+
+zend_class_entry *riak_get_resolver_input_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_get_resolver_input_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_get_resolver_input_ctor, 0, ZEND_RETURN_VALUE, 2)
+    ZEND_ARG_OBJ_INFO(0, resolver, Riak\\Output\\ConflictResolver, 0) 
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_get_resolver_input_methods[] = {
+    PHP_ME(Riak_Input_GetResolverInput, __construct, arginfo_riak_get_resolver_input_ctor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+    PHP_ME(Riak_Input_GetResolverInput, getConflictResolver, arginfo_riak_get_resolver_input_noargs, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+void riak_input_get_resolver_input_init(TSRMLS_D) /* {{{ */
+{
+    zend_class_entry ce;
+
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Input", "GetResolverInput", riak_get_resolver_input_methods);
+    
+    riak_get_resolver_input_ce = zend_register_internal_class_ex(&ce, riak_get_input_ce, NULL TSRMLS_CC);
+
+    zend_declare_property_null(riak_get_resolver_input_ce, "conflictResolver", sizeof("conflictResolver")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+}
+/* }}} */
+
+/*************************************************************************
+* Implementation: Riak\Input\GetResolverInput extends Riak\Input\GetInput
+**************************************************************************/
+
+/* {{{ proto void Riak\Input\GetResolverInput->__construct(Riak\Output\ConflictResolver $resolver)
+Create a new Riak\Input\GetResolverInput */
+PHP_METHOD(Riak_Input_GetResolverInput, __construct)
+{
+    zval* zResolver;
+
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zResolver, riak_output_conflict_resolver_ce) == FAILURE) {
+        return;
+    }
+
+    zend_update_property(riak_get_resolver_input_ce, getThis(), "conflictResolver", sizeof("conflictResolver")-1, zResolver TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto Riak\Output\ConflictResolver Riak\Input\GetResolverInput->getConflictResolver() */
+PHP_METHOD(Riak_Input_GetResolverInput, getConflictResolver)
+{
+    RIAK_GETTER_OBJECT(riak_get_resolver_input_ce, "conflictResolver");
+}
+/* }}} */
diff --git a/riak/input/get_resolver_input.h b/riak/input/get_resolver_input.h
new file mode 100644
index 0000000..a6e2536
--- /dev/null
+++ b/riak/input/get_resolver_input.h
@@ -0,0 +1,30 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_INPUT__GET_RESOLVER_INPUT__H__
+#define RIAK_INPUT__GET_RESOLVER_INPUT__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_get_resolver_input_ce;
+
+void riak_input_get_resolver_input_init(TSRMLS_D);
+
+/* Riak\Input\GetResolverInput */
+PHP_METHOD(Riak_Input_GetResolverInput, __construct);
+PHP_METHOD(Riak_Input_GetResolverInput, getConflictResolver);
+
+#endif //RIAK_INPUT__GET_RESOLVER_INPUT__H__
diff --git a/riak/input/index_input.c b/riak/input/index_input.c
new file mode 100644
index 0000000..d357cac
--- /dev/null
+++ b/riak/input/index_input.c
@@ -0,0 +1,71 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#include "index_input.h"
+#include "input.h"
+
+zend_class_entry *riak_index_input_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_index_input_set_continuation, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, continuation)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_index_input_set_maxresults, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, continuation)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_index_input_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_index_input_methods[] = {
+    PHP_ME(Riak_Input_IndexInput, setContinuation, arginfo_riak_index_input_set_continuation, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_IndexInput, getContinuation, arginfo_riak_index_input_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_IndexInput, setMaxResults, arginfo_riak_index_input_set_maxresults, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_IndexInput, getMaxResults, arginfo_riak_index_input_noargs, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+
+void riak_input_index_input_init(TSRMLS_D)
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Input", "IndexInput", riak_index_input_methods);
+    riak_index_input_ce = zend_register_internal_class_ex(&ce, riak_input_ce, NULL TSRMLS_CC);
+    zend_declare_property_null(riak_index_input_ce, "continuation", sizeof("continuation")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_index_input_ce, "maxResults", sizeof("maxResults")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+}
+
+PHP_METHOD(Riak_Input_IndexInput, setContinuation)
+{
+    RIAK_SETTER_STRING(riak_index_input_ce, "continuation");
+    RIAK_RETURN_THIS
+}
+
+PHP_METHOD(Riak_Input_IndexInput, getContinuation)
+{
+    RIAK_GETTER_STRING(riak_index_input_ce, "continuation");
+}
+
+PHP_METHOD(Riak_Input_IndexInput, setMaxResults)
+{
+    RIAK_SETTER_LONG(riak_index_input_ce, "maxResults");
+    RIAK_RETURN_THIS
+}
+
+PHP_METHOD(Riak_Input_IndexInput, getMaxResults)
+{
+    RIAK_GETTER_LONG(riak_index_input_ce, "maxResults");
+}
diff --git a/riak/input/index_input.h b/riak/input/index_input.h
new file mode 100644
index 0000000..9abc5fd
--- /dev/null
+++ b/riak/input/index_input.h
@@ -0,0 +1,33 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_INPUT__INDEX_INPUT__H__
+#define RIAK_INPUT__INDEX_INPUT__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_index_input_ce;
+
+void riak_input_index_input_init(TSRMLS_D);
+
+PHP_METHOD(Riak_Input_IndexInput, setContinuation);
+PHP_METHOD(Riak_Input_IndexInput, getContinuation);
+
+PHP_METHOD(Riak_Input_IndexInput, getMaxResults);
+PHP_METHOD(Riak_Input_IndexInput, setMaxResults);
+
+
+#endif //RIAK_INPUT__INDEX_INPUT__H__
diff --git a/riak/input/input.c b/riak/input/input.c
new file mode 100644
index 0000000..bfd13ae
--- /dev/null
+++ b/riak/input/input.c
@@ -0,0 +1,35 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#include "input.h"
+
+zend_class_entry *riak_input_ce;
+
+
+static zend_function_entry riak_input_methods[] = {
+    {NULL, NULL, NULL}
+};
+
+
+void riak_input_input_init(TSRMLS_D) /* {{{ */
+{
+    zend_class_entry ce;
+
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Input","Input", riak_input_methods);
+    riak_input_ce = zend_register_internal_class(&ce TSRMLS_CC);
+}
+/* }}} */
+
diff --git a/streaming.h b/riak/input/input.h
similarity index 74%
rename from streaming.h
rename to riak/input/input.h
index 627cb94..f21c042 100644
--- a/streaming.h
+++ b/riak/input/input.h
@@ -14,12 +14,13 @@
    limitations under the License.
 */
 
-#ifndef RIAK_STREAMING__H__
-#define RIAK_STREAMING__H__
+#ifndef RIAK_INPUT__INPUT__H__
+#define RIAK_INPUT__INPUT__H__
 
-#include <php.h>
-#include <riack.h>
+#include "php_riak_internal.h"
 
-void riak_streaming_init(TSRMLS_D);
+extern zend_class_entry *riak_input_ce;
 
-#endif
+void riak_input_input_init(TSRMLS_D);
+
+#endif //RIAK_INPUT__INPUT__H__
diff --git a/riak/input/put_input.c b/riak/input/put_input.c
new file mode 100644
index 0000000..27a7aa2
--- /dev/null
+++ b/riak/input/put_input.c
@@ -0,0 +1,235 @@
+/*
+   Copyright 2013 Kaspar Bach Pedersen
+
+   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.
+*/
+#include "put_input.h"
+#include "input.h"
+
+zend_class_entry *riak_put_input_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_put_config_set_head, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, return_head)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_put_config_set_w, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, w)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_put_config_set_dw, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, dw)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_put_config_set_pw, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, pw)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_put_config_set_vclock, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, vclock)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_put_config_set_ret_body, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, return_body)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_put_config_set_if_none_m, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, if_none_match)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_put_config_set_if_not_modifed, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, if_not_modified)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_put_config_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+
+static zend_function_entry riak_put_input_methods[] = {
+    PHP_ME(Riak_Input_PutInput, setReturnHead, arginfo_riak_put_config_set_head, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_PutInput, getReturnHead, arginfo_riak_put_config_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_PutInput, setW, arginfo_riak_put_config_set_w, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_PutInput, getW, arginfo_riak_put_config_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_PutInput, setDW, arginfo_riak_put_config_set_dw, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_PutInput, getDW, arginfo_riak_put_config_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_PutInput, setPW, arginfo_riak_put_config_set_pw, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_PutInput, getPW, arginfo_riak_put_config_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_PutInput, setVClock, arginfo_riak_put_config_set_vclock, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_PutInput, getVClock, arginfo_riak_put_config_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_PutInput, setReturnBody, arginfo_riak_put_config_set_ret_body, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_PutInput, getReturnBody, arginfo_riak_put_config_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_PutInput, setIfNoneMatch, arginfo_riak_put_config_set_if_none_m, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_PutInput, getIfNoneMatch, arginfo_riak_put_config_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_PutInput, setIfNotModified, arginfo_riak_put_config_set_if_not_modifed, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Input_PutInput, getIfNotModified, arginfo_riak_put_config_noargs, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+void riak_input_put_input_init(TSRMLS_D) /* {{{ */
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Input", "PutInput", riak_put_input_methods);
+    riak_put_input_ce = zend_register_internal_class_ex(&ce, riak_input_ce, NULL TSRMLS_CC);
+    zend_declare_property_null(riak_put_input_ce, "w", sizeof("w")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_put_input_ce, "dw", sizeof("dw")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_put_input_ce, "pw", sizeof("pw")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_put_input_ce, "vClock", sizeof("vClock")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_put_input_ce, "returnHead", sizeof("returnHead")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_put_input_ce, "returnBody", sizeof("returnBody")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_put_input_ce, "ifNoneMatch", sizeof("ifNoneMatch")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_put_input_ce, "ifNotModified", sizeof("ifNotModified")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+}
+/* }}} */
+
+
+/*************************************************************
+* Implementation: Riak\Input\PutInput
+*************************************************************/
+
+/* {{{ proto Riak\Input\PutInput Riak\Input\PutInput->setReturnHead(bool $returnHead)
+Sets return head option */
+PHP_METHOD(Riak_Input_PutInput, setReturnHead)
+{
+    RIAK_SETTER_BOOL(riak_put_input_ce, "returnHead");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto bool|null Riak\Input\PutInput->getReturnHead()
+Gets return head option */
+PHP_METHOD(Riak_Input_PutInput, getReturnHead)
+{
+    RIAK_GETTER_BOOL(riak_put_input_ce, "returnHead");
+}
+/* }}} */
+
+/* {{{ proto int|null Riak\Input\PutInput->getW()
+Gets W value */
+PHP_METHOD(Riak_Input_PutInput, getW)
+{
+    RIAK_GETTER_LONG(riak_put_input_ce, "w");
+}
+/* }}} */
+
+/* {{{ proto Riak\Input\PutInput Riak\Input\PutInput->setW(int $w)
+Set W value */
+PHP_METHOD(Riak_Input_PutInput, setW)
+{
+    RIAK_SETTER_LONG(riak_put_input_ce, "w");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto int|null Riak\Input\PutInput->getDW()
+Gets DW value */
+PHP_METHOD(Riak_Input_PutInput, getDW)
+{
+    RIAK_GETTER_LONG(riak_put_input_ce, "dw");
+}
+/* }}} */
+
+/* {{{ proto Riak\Input\PutInput Riak\Input\PutInput->setDW(int $dw)
+Set DW value */
+PHP_METHOD(Riak_Input_PutInput, setDW)
+{
+    RIAK_SETTER_LONG(riak_put_input_ce, "dw");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto int|null Riak\Input\PutInput->getPW()
+Gets PW value */
+PHP_METHOD(Riak_Input_PutInput, getPW)
+{
+    RIAK_GETTER_LONG(riak_put_input_ce, "pw");
+}
+/* }}} */
+
+/* {{{ proto Riak\Input\PutInput Riak\Input\PutInput->setPW(int $pw)
+Set PW value */
+PHP_METHOD(Riak_Input_PutInput, setPW)
+{
+    RIAK_SETTER_LONG(riak_put_input_ce, "pw");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto string|null Riak\Input\PutInput->getVClock()
+Get the vector clock value */
+PHP_METHOD(Riak_Input_PutInput, getVClock)
+{
+    RIAK_GETTER_STRING(riak_put_input_ce, "vClock");
+}
+/* }}} */
+
+/* {{{ proto Riak\Input\PutInput Riak\Input\PutInput->setVClock(string $vClock)
+Set the vector clock value */
+PHP_METHOD(Riak_Input_PutInput, setVClock)
+{
+    RIAK_SETTER_STRING(riak_put_input_ce, "vClock");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto bool|null Riak\Input\PutInput->getReturnBody()
+Get return body value */
+PHP_METHOD(Riak_Input_PutInput, getReturnBody)
+{
+    RIAK_GETTER_BOOL(riak_put_input_ce, "returnBody");
+}
+/* }}} */
+
+/* {{{ proto Riak\Input\PutInput Riak\Input\PutInput->setReturnBody(bool $returnBody)
+Set return body value */
+PHP_METHOD(Riak_Input_PutInput, setReturnBody)
+{
+    RIAK_SETTER_BOOL(riak_put_input_ce, "returnBody");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+
+/* {{{ proto bool|null Riak\Input\PutInput->getIfNoneMatch()
+Get if none match value */
+PHP_METHOD(Riak_Input_PutInput, getIfNoneMatch)
+{
+    RIAK_GETTER_BOOL(riak_put_input_ce, "ifNoneMatch");
+}
+/* }}} */
+
+/* {{{ proto Riak\Input\PutInput Riak\Input\PutInput->setIfNoneMatch(bool $ifNoneMatch)
+Set if none match value */
+PHP_METHOD(Riak_Input_PutInput, setIfNoneMatch)
+{
+    RIAK_SETTER_BOOL(riak_put_input_ce, "ifNoneMatch");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto bool|null Riak\Input\PutInput->getIfNotModified()
+Get if not modified */
+PHP_METHOD(Riak_Input_PutInput, getIfNotModified)
+{
+    RIAK_GETTER_BOOL(riak_put_input_ce, "ifNotModified");
+}
+/* }}} */
+
+/* {{{ proto Riak\Input\PutInput Riak\Input\PutInput->setIfNotModified(bool $ifNotModified)
+Set if not modified */
+PHP_METHOD(Riak_Input_PutInput, setIfNotModified)
+{
+    RIAK_SETTER_BOOL(riak_put_input_ce, "ifNotModified");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+
diff --git a/riak/input/put_input.h b/riak/input/put_input.h
new file mode 100644
index 0000000..9da9801
--- /dev/null
+++ b/riak/input/put_input.h
@@ -0,0 +1,45 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_INPUT__PUT_INPUT__H__
+#define RIAK_INPUT__PUT_INPUT__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_put_input_ce;
+
+void riak_input_put_input_init(TSRMLS_D);
+
+/* Riak\Input\PutInput */
+PHP_METHOD(Riak_Input_PutInput, setReturnHead);
+PHP_METHOD(Riak_Input_PutInput, getReturnHead);
+PHP_METHOD(Riak_Input_PutInput, getW);
+PHP_METHOD(Riak_Input_PutInput, setW);
+PHP_METHOD(Riak_Input_PutInput, getDW);
+PHP_METHOD(Riak_Input_PutInput, setDW);
+PHP_METHOD(Riak_Input_PutInput, getPW);
+PHP_METHOD(Riak_Input_PutInput, setPW);
+PHP_METHOD(Riak_Input_PutInput, getVClock);
+PHP_METHOD(Riak_Input_PutInput, setVClock);
+PHP_METHOD(Riak_Input_PutInput, getReturnBody);
+PHP_METHOD(Riak_Input_PutInput, setReturnBody);
+PHP_METHOD(Riak_Input_PutInput, getIfNoneMatch);
+PHP_METHOD(Riak_Input_PutInput, setIfNoneMatch);
+PHP_METHOD(Riak_Input_PutInput, getIfNotModified);
+PHP_METHOD(Riak_Input_PutInput, setIfNotModified);
+
+
+#endif //RIAK_INPUT__PUT_INPUT__H__
diff --git a/link.c b/riak/link.c
similarity index 98%
rename from link.c
rename to riak/link.c
index 8bdd032..47b6d0e 100644
--- a/link.c
+++ b/riak/link.c
@@ -14,10 +14,8 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 */
-#include <php.h>
-#include <riack.h>
+
 #include "link.h"
-#include "php_riak.h"
 
 zend_class_entry *riak_link_ce;
 
diff --git a/link.h b/riak/link.h
similarity index 96%
rename from link.h
rename to riak/link.h
index 476ed04..8ff87ba 100644
--- a/link.h
+++ b/riak/link.h
@@ -18,7 +18,7 @@
 #ifndef RIAK_LINK__H__
 #define RIAK_LINK__H__
 
-#include <php.h>
+#include "php_riak_internal.h"
 
 extern zend_class_entry *riak_link_ce;
 
diff --git a/riak/map_reduce/functions/base_function.c b/riak/map_reduce/functions/base_function.c
new file mode 100644
index 0000000..b60f171
--- /dev/null
+++ b/riak/map_reduce/functions/base_function.c
@@ -0,0 +1,34 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "base_function.h"
+
+zend_class_entry *riak_mrfunction_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mrfunction_toarray, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_mrfunction_methods[] = {
+    ZEND_ABSTRACT_ME(RiakMrFunction, toArray, arginfo_mrfunction_toarray)
+    {NULL, NULL, NULL}
+};
+
+void riak_map_reduce_functions_base_function_init(TSRMLS_D)/* {{{ */
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\MapReduce\\Functions", "BaseFunction", riak_mrfunction_methods);
+    riak_mrfunction_ce = zend_register_internal_class(&ce TSRMLS_CC);
+}
+/* }}} */
diff --git a/riak/map_reduce/functions/base_function.h b/riak/map_reduce/functions/base_function.h
new file mode 100644
index 0000000..7d2632e
--- /dev/null
+++ b/riak/map_reduce/functions/base_function.h
@@ -0,0 +1,28 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+
+#ifndef RIAK_MAP_REDUCE__FUNCTIONS__BASE_FUNCTION__H__
+#define RIAK_MAP_REDUCE__FUNCTIONS__BASE_FUNCTION__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_mrfunction_ce;
+
+void riak_map_reduce_functions_base_function_init(TSRMLS_D);
+
+#endif //RIAK_MAP_REDUCE__FUNCTIONS__BASE_FUNCTION__H__
+
diff --git a/riak/map_reduce/functions/erlang_function.c b/riak/map_reduce/functions/erlang_function.c
new file mode 100644
index 0000000..76fcbba
--- /dev/null
+++ b/riak/map_reduce/functions/erlang_function.c
@@ -0,0 +1,85 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "erlang_function.h"
+#include "base_function.h"
+
+zend_class_entry *riak_mrfunction_erl_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_function_erl_toarray, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_create_erl_named_ctor, 0, ZEND_RETURN_VALUE, 2)
+    ZEND_ARG_INFO(0, module)
+    ZEND_ARG_INFO(0, function)
+ZEND_END_ARG_INFO()
+
+
+static zend_function_entry riak_mrfunction_erl_methods[] = {
+    PHP_ME(RiakMrErlangFunction, __construct, arginfo_create_erl_named_ctor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+    PHP_ME(RiakMrErlangFunction, toArray, arginfo_function_erl_toarray, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+void riak_map_reduce_functions_erlang_function_init(TSRMLS_D)/* {{{ */
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\MapReduce\\Functions", "ErlangFunction", riak_mrfunction_erl_methods);
+    riak_mrfunction_erl_ce = zend_register_internal_class_ex(&ce, riak_mrfunction_ce, NULL TSRMLS_CC);
+    zend_declare_property_null(riak_mrfunction_erl_ce, "module", sizeof("module")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_mrfunction_erl_ce, "function", sizeof("function")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+}
+/* }}} */
+
+
+/*************************************************************
+* Implementation: Riak\MapReduce\Function\ErlangFunction
+*************************************************************/
+
+/* {{{ proto void Riak\MapReduce\Function\ErlangFunction->__construct(string $module, string $function)
+Creates a new ErlangFunction */
+PHP_METHOD(RiakMrErlangFunction, __construct)
+{
+    char *module, *function;
+    int modulelen, functionlen;
+
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &module, &modulelen, &function, &functionlen) == FAILURE) {
+        return;
+    }
+    zend_update_property_stringl(riak_mrfunction_erl_ce, getThis(), "module", sizeof("module")-1, module, modulelen TSRMLS_CC);
+    zend_update_property_stringl(riak_mrfunction_erl_ce, getThis(), "function", sizeof("function")-1, function, functionlen TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto array Riak\MapReduce\Function\ErlangFunction->toArray()
+Returns this Funtion as an array */
+PHP_METHOD(RiakMrErlangFunction, toArray)
+{
+    zval *zarray, *zmodule, *zfunc;
+
+    MAKE_STD_ZVAL(zarray);
+    array_init(zarray);
+
+    zmodule = zend_read_property(riak_mrfunction_erl_ce, getThis(), "module", sizeof("module")-1, 1 TSRMLS_CC);
+    zfunc = zend_read_property(riak_mrfunction_erl_ce, getThis(), "function", sizeof("function")-1, 1 TSRMLS_CC);
+
+    add_assoc_string_ex(zarray, "language", sizeof("language"), "erlang", 1);
+    add_assoc_stringl_ex(zarray, "module", sizeof("module"), Z_STRVAL_P(zmodule), Z_STRLEN_P(zmodule), 1);
+    add_assoc_stringl_ex(zarray, "function", sizeof("function"), Z_STRVAL_P(zfunc), Z_STRLEN_P(zfunc), 1);
+
+    RETURN_ZVAL(zarray, 0, 1);
+}
+/* }}} */
+
diff --git a/riak/map_reduce/functions/erlang_function.h b/riak/map_reduce/functions/erlang_function.h
new file mode 100644
index 0000000..19ae8e1
--- /dev/null
+++ b/riak/map_reduce/functions/erlang_function.h
@@ -0,0 +1,27 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_MAP_REDUCE__FUNCTIONS__ERLANG_FUNCTION__H__
+#define RIAK_MAP_REDUCE__FUNCTIONS__ERLANG_FUNCTION__H__
+
+#include "php_riak_internal.h"
+
+void riak_map_reduce_functions_erlang_function_init(TSRMLS_D);
+
+PHP_METHOD(RiakMrErlangFunction, __construct);
+PHP_METHOD(RiakMrErlangFunction, toArray);
+
+#endif //RIAK_MAP_REDUCE__FUNCTIONS__ERLANG_FUNCTION__H__
diff --git a/mr_functions.c b/riak/map_reduce/functions/javascript_function.c
similarity index 56%
rename from mr_functions.c
rename to riak/map_reduce/functions/javascript_function.c
index a9723f7..9aa4131 100644
--- a/mr_functions.c
+++ b/riak/map_reduce/functions/javascript_function.c
@@ -1,6 +1,5 @@
 /*
-   Copyright 2012 Trifork A/S
-   Author: Kaspar Pedersen
+   Copyright 2013: Kaspar Bach Pedersen
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -14,16 +13,12 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 */
-#include <php.h>
-#include <riack.h>
-#include "mr_functions.h"
-#include "php_riak.h"
+#include "javascript_function.h"
+#include "base_function.h"
 
-zend_class_entry *riak_mrfunction_ce;
 zend_class_entry *riak_mrfunction_js_ce;
-zend_class_entry *riak_mrfunction_erl_ce;
 
-ZEND_BEGIN_ARG_INFO_EX(arginfo_mrfunction_toarray, 0, ZEND_RETURN_VALUE, 0)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_function_js_toarray, 0, ZEND_RETURN_VALUE, 0)
 ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_mrfunction_js_ctor, 0, ZEND_RETURN_VALUE, 2)
@@ -35,46 +30,22 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_create_anon_js, 0, ZEND_RETURN_VALUE, 1)
     ZEND_ARG_INFO(0, source)
 ZEND_END_ARG_INFO()
 
-ZEND_BEGIN_ARG_INFO_EX(arginfo_create_erl_named_ctor, 0, ZEND_RETURN_VALUE, 2)
-    ZEND_ARG_INFO(0, module)
-    ZEND_ARG_INFO(0, function)
-ZEND_END_ARG_INFO()
-
-static zend_function_entry riak_mrfunction_methods[] = {
-    ZEND_ABSTRACT_ME(RiakMrFunction, toArray, arginfo_mrfunction_toarray)
-    {NULL, NULL, NULL}
-};
 
 static zend_function_entry riak_mrfunction_js_methods[] = {
     PHP_ME(RiakMrJavascriptFunction, __construct, arginfo_mrfunction_js_ctor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
     PHP_ME(RiakMrJavascriptFunction, anon,  arginfo_create_anon_js,  ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
     PHP_ME(RiakMrJavascriptFunction, named, arginfo_create_anon_js, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-    PHP_ME(RiakMrJavascriptFunction, toArray, arginfo_mrfunction_toarray, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakMrJavascriptFunction, toArray, arginfo_function_js_toarray, ZEND_ACC_PUBLIC)
     {NULL, NULL, NULL}
 };
 
-static zend_function_entry riak_mrfunction_erl_methods[] = {
-    PHP_ME(RiakMrErlangFunction, __construct, arginfo_create_erl_named_ctor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
-    PHP_ME(RiakMrErlangFunction, toArray, arginfo_mrfunction_toarray, ZEND_ACC_PUBLIC)
-    {NULL, NULL, NULL}
-};
-
-void riak_mrfunctions_init(TSRMLS_D)/* {{{ */
+void riak_map_reduce_functions_javascript_function_init(TSRMLS_D)/* {{{ */
 {
-    zend_class_entry ce, jsce, erlce;
-
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\MapReduce\\Functions", "BaseFunction", riak_mrfunction_methods);
-    riak_mrfunction_ce = zend_register_internal_class(&ce TSRMLS_CC);
-
-    INIT_NS_CLASS_ENTRY(jsce, "Riak\\MapReduce\\Functions", "JavascriptFunction", riak_mrfunction_js_methods);
-    riak_mrfunction_js_ce = zend_register_internal_class_ex(&jsce, riak_mrfunction_ce, NULL TSRMLS_CC);
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\MapReduce\\Functions", "JavascriptFunction", riak_mrfunction_js_methods);
+    riak_mrfunction_js_ce = zend_register_internal_class_ex(&ce, riak_mrfunction_ce, NULL TSRMLS_CC);
     zend_declare_property_null(riak_mrfunction_js_ce, "named", sizeof("named")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
     zend_declare_property_null(riak_mrfunction_js_ce, "source", sizeof("source")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-
-    INIT_NS_CLASS_ENTRY(erlce, "Riak\\MapReduce\\Functions", "ErlangFunction", riak_mrfunction_erl_methods);
-    riak_mrfunction_erl_ce = zend_register_internal_class_ex(&erlce, riak_mrfunction_ce, NULL TSRMLS_CC);
-    zend_declare_property_null(riak_mrfunction_erl_ce, "module", sizeof("module")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_mrfunction_erl_ce, "function", sizeof("function")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
 }
 /* }}} */
 
@@ -91,6 +62,7 @@ void create_named_mr_js_function(zend_class_entry *classentry, zval* result,
 }
 /* }}} */
 
+
 /*************************************************************
 * Implementation: Riak\MapReduce\Function\JavascriptFunction
 *************************************************************/
@@ -161,41 +133,3 @@ PHP_METHOD(RiakMrJavascriptFunction, anon)
 /* }}} */
 
 
-/*************************************************************
-* Implementation: Riak\MapReduce\Function\ErlangFunction
-*************************************************************/
-
-/* {{{ proto void Riak\MapReduce\Function\ErlangFunction->__construct(string $module, string $function)
-Creates a new ErlangFunction */
-PHP_METHOD(RiakMrErlangFunction, __construct)
-{
-    char *module, *function;
-    int modulelen, functionlen;
-
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &module, &modulelen, &function, &functionlen) == FAILURE) {
-        return;
-    }
-    zend_update_property_stringl(riak_mrfunction_erl_ce, getThis(), "module", sizeof("module")-1, module, modulelen TSRMLS_CC);
-    zend_update_property_stringl(riak_mrfunction_erl_ce, getThis(), "function", sizeof("function")-1, function, functionlen TSRMLS_CC);
-}
-/* }}} */
-
-/* {{{ proto array Riak\MapReduce\Function\ErlangFunction->toArray()
-Returns this Funtion as an array */
-PHP_METHOD(RiakMrErlangFunction, toArray)
-{
-    zval *zarray, *zmodule, *zfunc;
-
-    MAKE_STD_ZVAL(zarray);
-    array_init(zarray);
-
-    zmodule = zend_read_property(riak_mrfunction_erl_ce, getThis(), "module", sizeof("module")-1, 1 TSRMLS_CC);
-    zfunc = zend_read_property(riak_mrfunction_erl_ce, getThis(), "function", sizeof("function")-1, 1 TSRMLS_CC);
-
-    add_assoc_string_ex(zarray, "language", sizeof("language"), "erlang", 1);
-    add_assoc_stringl_ex(zarray, "module", sizeof("module"), Z_STRVAL_P(zmodule), Z_STRLEN_P(zmodule), 1);
-    add_assoc_stringl_ex(zarray, "function", sizeof("function"), Z_STRVAL_P(zfunc), Z_STRLEN_P(zfunc), 1);
-
-    RETURN_ZVAL(zarray, 0, 1);
-}
-/* }}} */
diff --git a/mr_functions.h b/riak/map_reduce/functions/javascript_function.h
similarity index 60%
rename from mr_functions.h
rename to riak/map_reduce/functions/javascript_function.h
index 95e46dd..3594355 100644
--- a/mr_functions.h
+++ b/riak/map_reduce/functions/javascript_function.h
@@ -1,6 +1,5 @@
 /*
-   Copyright 2013 Trifork A/S
-   Author: Kaspar Bach Pedersen
+   Copyright 2013: Kaspar Bach Pedersen
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -15,24 +14,16 @@
    limitations under the License.
 */
 
-#ifndef RIAK_MR_FUNCTION__H__
-#define RIAK_MR_FUNCTION__H__
+#ifndef RIAK_MAP_REDUCE__FUNCTIONS__JAVASCRIPT_FUNCTION__H__
+#define RIAK_MAP_REDUCE__FUNCTIONS__JAVASCRIPT_FUNCTION__H__
 
-#include <php.h>
+#include "php_riak_internal.h"
 
-extern zend_class_entry *riak_mrfunction_ce;
-
-void riak_mrfunctions_init(TSRMLS_D);
-
-void create_named_mr_function(zend_class_entry *classentry, zval* result,
-                               zend_bool named, const char* source, int sourcelen TSRMLS_DC);
+void riak_map_reduce_functions_javascript_function_init(TSRMLS_D);
 
 PHP_METHOD(RiakMrJavascriptFunction, __construct);
 PHP_METHOD(RiakMrJavascriptFunction, toArray);
 PHP_METHOD(RiakMrJavascriptFunction, named);
 PHP_METHOD(RiakMrJavascriptFunction, anon);
 
-PHP_METHOD(RiakMrErlangFunction, __construct);
-PHP_METHOD(RiakMrErlangFunction, toArray);
-
-#endif
+#endif //RIAK_MAP_REDUCE__FUNCTIONS__JAVASCRIPT_FUNCTION__H__
diff --git a/riak/map_reduce/input/bucket_input.c b/riak/map_reduce/input/bucket_input.c
new file mode 100644
index 0000000..b81a7c5
--- /dev/null
+++ b/riak/map_reduce/input/bucket_input.c
@@ -0,0 +1,131 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "bucket_input.h"
+#include "input.h"
+#include "riak/bucket.h"
+
+zend_class_entry *riak_mrinput_bucket_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mr_input_bucket_toarr, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mr_input_bucket_ctor, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mr_input_bucket_setindex, 0, ZEND_RETURN_VALUE, 2)
+    ZEND_ARG_INFO(0, name)
+    ZEND_ARG_INFO(0, start)
+    ZEND_ARG_INFO(0, end)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_mrinputbucket_methods[] = {
+    PHP_ME(Riak_MapReduce_Input_BucketInput, __construct, arginfo_mr_input_bucket_ctor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+    PHP_ME(Riak_MapReduce_Input_BucketInput, setIndexFilter, arginfo_mr_input_bucket_setindex, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_MapReduce_Input_BucketInput, getValue, arginfo_mr_input_bucket_toarr, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+void riak_map_reduce_input_bucket_input_init(TSRMLS_D) /* {{{ */
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\MapReduce\\Input", "BucketInput", riak_mrinputbucket_methods);
+    riak_mrinput_bucket_ce = zend_register_internal_class_ex(&ce, riak_mrinput_ce, NULL TSRMLS_CC);
+    zend_declare_property_null(riak_mrinput_bucket_ce, "name", sizeof("name")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_mrinput_bucket_ce, "keyFilters", sizeof("keyFilters")-1, ZEND_ACC_PUBLIC TSRMLS_CC);
+    zend_declare_property_null(riak_mrinput_bucket_ce, "idxname", sizeof("idxname")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_mrinput_bucket_ce, "idxstart", sizeof("idxstart")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_mrinput_bucket_ce, "idxend", sizeof("idxend")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+}
+/* }}} */
+
+/*************************************************************
+* Implementation: Riak\MapReduce\Input\BucketInput
+*************************************************************/
+
+/* {{{ proto void Riak\MapReduce\Input\BucketInput->__construct(string $bucketName)
+Creates a new BucketInput */
+PHP_METHOD(Riak_MapReduce_Input_BucketInput, __construct)
+{
+    char *name;
+    int namelen;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &namelen) == FAILURE) {
+        return;
+    }
+    zend_update_property_stringl(riak_mrinput_bucket_ce, getThis(), "name", sizeof("name")-1, name, namelen TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto void Riak\MapReduce\Input\BucketInput->setIndexFilter($indexname, $start [, $end])
+Add a index query filter */
+PHP_METHOD(Riak_MapReduce_Input_BucketInput, setIndexFilter)
+{
+    char *index, *start, *end;
+    int indexlen, startlen, endlen;
+    end = NULL;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|s", &index, &indexlen, &start, &startlen, &end, &endlen) == FAILURE) {
+        return;
+    }
+    zend_update_property_stringl(riak_mrinput_bucket_ce, getThis(), "idxname", sizeof("idxname")-1, index, indexlen TSRMLS_CC);
+    zend_update_property_stringl(riak_mrinput_bucket_ce, getThis(), "idxstart", sizeof("idxstart")-1, start, startlen TSRMLS_CC);
+    if (end != NULL && endlen > 0) {
+        zend_update_property_stringl(riak_mrinput_bucket_ce, getThis(), "idxend", sizeof("idxend")-1, end, endlen TSRMLS_CC);
+    }
+    RIAK_RETURN_THIS
+}
+
+/* {{{ proto string|array Riak\MapReduce\Input\BucketInput->getValue()
+Returns value to use in Mapreduce */
+PHP_METHOD(Riak_MapReduce_Input_BucketInput, getValue)
+{
+    zval* zname, *zfilters, *zresult, *zindex;
+    zname = zend_read_property(riak_mrinput_bucket_ce, getThis(), "name", sizeof("name")-1, 1 TSRMLS_CC);
+    zfilters = zend_read_property(riak_mrinput_bucket_ce, getThis(), "keyFilters", sizeof("keyFilters")-1, 1 TSRMLS_CC);
+    zindex = zend_read_property(riak_mrinput_bucket_ce, getThis(), "idxname", sizeof("idxname")-1, 1 TSRMLS_CC);
+
+    if (Z_TYPE_P(zfilters) == IS_ARRAY || Z_TYPE_P(zindex) == IS_STRING) {
+        MAKE_STD_ZVAL(zresult);
+        array_init(zresult);
+        zval_addref_p(zname);
+        add_assoc_zval_ex(zresult, "bucket", sizeof("bucket"), zname);
+        if (Z_TYPE_P(zindex) == IS_STRING) {
+            zval *start, *end;
+            start = zend_read_property(riak_mrinput_bucket_ce, getThis(), "idxstart", sizeof("idxstart")-1, 1 TSRMLS_CC);
+            end = zend_read_property(riak_mrinput_bucket_ce, getThis(), "idxend", sizeof("idxend")-1, 1 TSRMLS_CC);
+
+            zval_addref_p(zindex);
+            add_assoc_zval_ex(zresult, "index", sizeof("index"), zindex);
+            if (Z_TYPE_P(end) != IS_STRING) {
+                zval_addref_p(start);
+                add_assoc_zval_ex(zresult, "key", sizeof("key"), start);
+            } else {
+                zval_addref_p(start);
+                zval_addref_p(end);
+                add_assoc_zval_ex(zresult, "start", sizeof("start"), start);
+                add_assoc_zval_ex(zresult, "end", sizeof("end"), end);
+            }
+        }
+        if (Z_TYPE_P(zfilters) == IS_ARRAY) {
+            zval_addref_p(zfilters);
+            add_assoc_zval_ex(zresult, "key_filters", sizeof("key_filters"), zfilters);
+        }
+        RETURN_ZVAL(zresult, 0, 1);
+    } else {
+        RETURN_ZVAL(zname, 1, 0);
+    }
+}
+/* }}} */
+
diff --git a/riak/map_reduce/input/bucket_input.h b/riak/map_reduce/input/bucket_input.h
new file mode 100644
index 0000000..e6b75a5
--- /dev/null
+++ b/riak/map_reduce/input/bucket_input.h
@@ -0,0 +1,31 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+
+#ifndef RIAK_MAP_REDUCE__INPUT__BUCKET_INPUT__H__
+#define RIAK_MAP_REDUCE__INPUT__BUCKET_INPUT__H__
+
+#include "php_riak_internal.h"
+
+void riak_map_reduce_input_bucket_input_init(TSRMLS_D);
+
+PHP_METHOD(Riak_MapReduce_Input_BucketInput, __construct);
+PHP_METHOD(Riak_MapReduce_Input_BucketInput, getValue);
+PHP_METHOD(Riak_MapReduce_Input_BucketInput, setIndexFilter);
+
+
+#endif //RIAK_MAP_REDUCE__INPUT__BUCKET_INPUT__H__
+
diff --git a/riak/map_reduce/input/input.c b/riak/map_reduce/input/input.c
new file mode 100644
index 0000000..ad2150f
--- /dev/null
+++ b/riak/map_reduce/input/input.c
@@ -0,0 +1,36 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "input.h"
+
+zend_class_entry *riak_mrinput_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mr_input_toarr, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_mrinput_methods[] = {
+    ZEND_ABSTRACT_ME(RiakMrInput, getValue, arginfo_mr_input_toarr)
+    {NULL, NULL, NULL}
+};
+
+void riak_map_reduce_input_input_init(TSRMLS_D) /* {{{ */
+{
+    zend_class_entry ce;
+
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\MapReduce\\Input", "Input", riak_mrinput_methods);
+    riak_mrinput_ce = zend_register_internal_class(&ce TSRMLS_CC);
+}
+/* }}} */
+
diff --git a/riak/map_reduce/input/input.h b/riak/map_reduce/input/input.h
new file mode 100644
index 0000000..ad2efd0
--- /dev/null
+++ b/riak/map_reduce/input/input.h
@@ -0,0 +1,30 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+
+#ifndef RIAK_MAP_REDUCE__INPUT__INPUT__H__
+#define RIAK_MAP_REDUCE__INPUT__INPUT__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_mrinput_ce;
+
+void riak_map_reduce_input_input_init(TSRMLS_D);
+
+PHP_METHOD(RiakMrInput, toArray);
+
+#endif //RIAK_MAP_REDUCE__INPUT__INPUT__H__
+
diff --git a/riak/map_reduce/input/key_data_list_input.c b/riak/map_reduce/input/key_data_list_input.c
new file mode 100644
index 0000000..4e001fb
--- /dev/null
+++ b/riak/map_reduce/input/key_data_list_input.c
@@ -0,0 +1,123 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "key_data_list_input.h"
+#include "input.h"
+#include "riak/bucket.h"
+#include "riak/object.h"
+#include "riak/exception/exception.h"
+
+zend_class_entry *riak_mrinput_keydatalist_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mr_input_keydatalist_input_ctor, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mr_input_keydatalist_add, 0, ZEND_RETURN_VALUE, 3)
+    ZEND_ARG_INFO(0, bucket)
+    ZEND_ARG_INFO(0, key)
+    ZEND_ARG_INFO(0, data)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mr_input_keydatalist_toarr, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_mrinputkeydatalist_methods[] = {
+    PHP_ME(Riak_MapReduce_Input_KeyDataListInput, __construct, arginfo_mr_input_keydatalist_input_ctor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+    PHP_ME(Riak_MapReduce_Input_KeyDataListInput, add, arginfo_mr_input_keydatalist_add, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_MapReduce_Input_KeyDataListInput, getValue, arginfo_mr_input_keydatalist_toarr, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+void riak_map_reduce_input_key_data_list_input_init(TSRMLS_D) /* {{{ */
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\MapReduce\\Input", "KeyDataListInput", riak_mrinputkeydatalist_methods);
+    riak_mrinput_keydatalist_ce = zend_register_internal_class_ex(&ce, riak_mrinput_ce, NULL TSRMLS_CC);
+    zend_declare_property_null(riak_mrinput_keydatalist_ce, "inputList", sizeof("inputList")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+}
+/* }}} */
+
+
+/*************************************************************
+* Implementation: Riak\MapReduce\Input\KeyDataListInput
+*************************************************************/
+
+/* {{{ proto void Riak\MapReduce\Input\KeyDataListInput->__construct()
+Create a KeyDataListInput */
+PHP_METHOD(Riak_MapReduce_Input_KeyDataListInput, __construct)
+{
+    zval *list;
+    MAKE_STD_ZVAL(list);
+    array_init(list);
+    zend_update_property(riak_mrinput_keydatalist_ce, getThis(), "inputList", sizeof("inputList")-1, list TSRMLS_CC);
+    zval_ptr_dtor(&list);
+}
+/* }}} */
+
+/* {{{ proto void Riak\MapReduce\Input\KeyDataListInput->add(string|RiakBucket $bucket, string|RiakObject $object, $data)
+Add a bucket/key/data set to input */
+PHP_METHOD(Riak_MapReduce_Input_KeyDataListInput, add)
+{
+    zval *zbucket, *zkey, *zdata, *zarr, *zlist;
+    char *bucket, *key;
+    int bucketlen, keylen;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzz", &zbucket, &zkey, &zdata) == FAILURE) {
+        return;
+    }
+    bucket = NULL;
+    bucketlen = 0;
+    if (Z_TYPE_P(zbucket) == IS_STRING) {
+        bucket = Z_STRVAL_P(zbucket);
+        bucketlen = Z_STRLEN_P(zbucket);
+    } else if (Z_TYPE_P(zbucket) == IS_OBJECT) {
+        riak_name_from_bucket(zbucket, &bucket, &bucketlen TSRMLS_CC);
+    }
+    if (Z_TYPE_P(zkey) == IS_STRING) {
+        key = Z_STRVAL_P(zkey);
+        keylen = Z_STRLEN_P(zkey);
+    } else if (Z_TYPE_P(zkey) == IS_OBJECT) {
+        riak_key_from_object(zkey, &key, &keylen TSRMLS_CC);
+    }
+    if (bucket != NULL && bucketlen > 0 && key != NULL && keylen > 0) {
+        MAKE_STD_ZVAL(zarr);
+        array_init(zarr);
+        add_next_index_stringl(zarr, bucket, bucketlen, 1);
+        add_next_index_stringl(zarr, key, keylen, 1);
+        zval_addref_p(zdata);
+        add_next_index_zval(zarr, zdata);
+        zlist = zend_read_property(riak_mrinput_keydatalist_ce, getThis(), "inputList", sizeof("inputList")-1, 1 TSRMLS_CC);
+        add_next_index_zval(zlist, zarr);
+    } else {
+        zend_throw_exception(riak_badarguments_exception_ce, "Key or bucketname missing", 5001 TSRMLS_CC);
+    }
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+
+/* {{{ proto array Riak\MapReduce\Input\KeyDataListInput->getValue()
+Returns value to use in Mapreduce */
+PHP_METHOD(Riak_MapReduce_Input_KeyDataListInput, getValue)
+{
+    zval* zinputlist = zend_read_property(riak_mrinput_keydatalist_ce, getThis(), "inputList", sizeof("inputList")-1, 1 TSRMLS_CC);
+    if (Z_TYPE_P(zinputlist) == IS_ARRAY) {
+        RETURN_ZVAL(zinputlist, 1, 0);
+    }
+
+}
+/* }}} */
+
+
diff --git a/riak/map_reduce/input/key_data_list_input.h b/riak/map_reduce/input/key_data_list_input.h
new file mode 100644
index 0000000..3f5e7cf
--- /dev/null
+++ b/riak/map_reduce/input/key_data_list_input.h
@@ -0,0 +1,31 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+
+#ifndef RIAK_MAP_REDUCE__INPUT__KEY_DATA_LIST_INPUT__H__
+#define RIAK_MAP_REDUCE__INPUT__KEY_DATA_LIST_INPUT__H__
+
+#include "php_riak_internal.h"
+
+void riak_map_reduce_input_key_data_list_input_init(TSRMLS_D);
+
+PHP_METHOD(Riak_MapReduce_Input_KeyDataListInput, __construct);
+PHP_METHOD(Riak_MapReduce_Input_KeyDataListInput, getValue);
+PHP_METHOD(Riak_MapReduce_Input_KeyDataListInput, add);
+
+
+#endif //RIAK_MAP_REDUCE__INPUT__KEY_DATA_LIST_INPUT__H__
+
diff --git a/riak/map_reduce/input/key_list_input.c b/riak/map_reduce/input/key_list_input.c
new file mode 100644
index 0000000..d7fa8b2
--- /dev/null
+++ b/riak/map_reduce/input/key_list_input.c
@@ -0,0 +1,210 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "key_list_input.h"
+#include "input.h"
+#include "riak/object.h"
+#include "riak/bucket.h"
+#include "riak/exception/exception.h"
+#include "ht_utils.h"
+
+zend_class_entry *riak_mrinput_keylist_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mr_input_keylist_ctor, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, bucketkeys_arr)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mr_input_keylist_single, 0, ZEND_RETURN_VALUE, 2)
+    ZEND_ARG_INFO(0, bucket)
+    ZEND_ARG_INFO(0, key)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mr_input_keylist_toarr, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_mrinputlist_methods[] = {
+    PHP_ME(Riak_MapReduce_Input_KeyListInput, __construct, arginfo_mr_input_keylist_ctor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+    PHP_ME(Riak_MapReduce_Input_KeyListInput, addArray, arginfo_mr_input_keylist_ctor, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_MapReduce_Input_KeyListInput, addSingle, arginfo_mr_input_keylist_single, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_MapReduce_Input_KeyListInput, getValue, arginfo_mr_input_keylist_toarr, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+void riak_map_reduce_input_key_list_input_init(TSRMLS_D) /* {{{ */
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\MapReduce\\Input", "KeyListInput", riak_mrinputlist_methods);
+    riak_mrinput_keylist_ce = zend_register_internal_class_ex(&ce, riak_mrinput_ce, NULL TSRMLS_CC);
+    zend_declare_property_null(riak_mrinput_keylist_ce, "inputList", sizeof("inputList")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+}
+/* }}} */
+
+
+/*************************************************************
+* Implementation: Riak\MapReduce\Input\KeyListInput
+*************************************************************/
+
+zval *riak_create_kv_pair(char* bucket, int bucketlen, char* key, int keylen)/* {{{{ */
+{
+    zval *pair;
+    MAKE_STD_ZVAL(pair);
+    array_init(pair);
+    add_next_index_stringl(pair, bucket, bucketlen, 1);
+    add_next_index_stringl(pair, key, keylen, 1);
+    return pair;
+}
+/* }}} */
+
+void riak_array_to_tupple_array_deep_cb(void* callingObj, void* custom_ptr, char* key,
+                                   uint keylen, uint index, zval** data, int *cnt TSRMLS_DC)/* {{{{ */
+{
+    zval *add;
+    char* addkey;
+    int addkeylen;
+    zval *bucket = (zval*)callingObj;
+    zval *to = (zval*)custom_ptr;
+
+    if (Z_TYPE_PP(data) == IS_STRING) {
+        add = riak_create_kv_pair(Z_STRVAL_P(bucket), Z_STRLEN_P(bucket), Z_STRVAL_PP(data), Z_STRLEN_PP(data));
+        add_next_index_zval(to, add);
+    } else if (Z_TYPE_PP(data) == IS_OBJECT) {
+        riak_key_from_object(*data, &addkey, &addkeylen TSRMLS_CC);
+        add = riak_create_kv_pair(Z_STRVAL_P(bucket), Z_STRLEN_P(bucket), addkey, addkeylen);
+        add_next_index_zval(to, add);
+    }
+}
+/* }}} */
+
+void riak_array_to_tupple_array_cb(void* callingObj, void* custom_ptr, char* arraykey,
+                                   uint arraykeylen, uint index, zval** data, int *cnt TSRMLS_DC)/* {{{{ */
+{
+    char* riakkey;
+    int riakkeylen;
+    zval *add, bucket;
+    zval *to = (zval*)custom_ptr;
+
+    /* arraykey is actually the bucket name */
+    if (arraykey == NULL || arraykeylen == 0) {
+        return;
+    }
+    if (Z_TYPE_PP(data) == IS_ARRAY) {
+        /* Data is array of keys, iterate those aswell */
+        ZVAL_STRINGL(&bucket, arraykey, arraykeylen-1, 0);
+        foreach_in_hashtable(&bucket, to, Z_ARRVAL_PP(data), &riak_array_to_tupple_array_deep_cb TSRMLS_CC);
+    } else if (Z_TYPE_PP(data) == IS_STRING) {
+        /* Data is a string with the riak key */
+        add = riak_create_kv_pair(arraykey, arraykeylen-1, Z_STRVAL_PP(data), Z_STRLEN_PP(data));
+        add_next_index_zval(to, add);
+    } else if (Z_TYPE_PP(data) == IS_OBJECT) {
+        /* Data is RiakObject */
+        riak_key_from_object(*data, &riakkey, &riakkeylen TSRMLS_CC);
+        add = riak_create_kv_pair(arraykey, arraykeylen-1, riakkey, riakkeylen);
+        add_next_index_zval(to, add);
+    }
+}
+/* }}} */
+
+zval* riak_array_to_tupple_array(HashTable* from TSRMLS_DC)/* {{{{ */
+{
+    zval *to;
+    MAKE_STD_ZVAL(to);
+    array_init(to);
+    foreach_in_hashtable(NULL, to, from, &riak_array_to_tupple_array_cb TSRMLS_CC);
+    return to;
+}
+/* }}} */
+
+/* {{{ proto void Riak\MapReduce\Input\KeyListInput->__construct(array $bucketKeys)
+Create a KeyListInput, input should be an array with ["bucket" => "key", "bucket2" => "key2"] or ["bucket" => ["key1", "key2"]] */
+PHP_METHOD(Riak_MapReduce_Input_KeyListInput, __construct)
+{
+    zval *zarr;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &zarr) == FAILURE) {
+        return;
+    }
+    zend_update_property(riak_mrinput_keylist_ce, getThis(), "inputList", sizeof("inputList")-1, zarr TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto Riak\MapReduce\Input\KeyListInput Riak\MapReduce\Input\KeyListInput->addArray(array $bucketKeys)
+Add bucket/key inputs to the current list, $bucketKeys must be an array with ["bucket" => "key", "bucket2" => "key2"] or ["bucket" => ["key1", "key2"]] */
+PHP_METHOD(Riak_MapReduce_Input_KeyListInput, addArray)
+{
+    zval *zarr[2], zfuncname, *zcombinedarr;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &zarr[1]) == FAILURE) {
+        return;
+    }
+    ZVAL_STRING(&zfuncname, "array_merge_recursive", 0);
+    zarr[0] = zend_read_property(riak_mrinput_keylist_ce, getThis(), "inputList", sizeof("inputList")-1, 1 TSRMLS_CC);
+
+    MAKE_STD_ZVAL(zcombinedarr);
+    call_user_function(EG(function_table), NULL, &zfuncname, zcombinedarr, 2, zarr TSRMLS_CC);
+
+    zend_update_property(riak_mrinput_keylist_ce, getThis(), "inputList", sizeof("inputList")-1, zcombinedarr TSRMLS_CC);
+    //zval_ptr_dtor(&zarr[0]);
+    zval_ptr_dtor(&zcombinedarr);
+
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto Riak\MapReduce\Input\KeyListInput Riak\MapReduce\Input\KeyListInput->addSingle(string $bucket, string $key)
+Add a single bucket/key to the current list of inputs */
+PHP_METHOD(Riak_MapReduce_Input_KeyListInput, addSingle)
+{
+    zval *zbucket, *zobject, *zarray;
+    char *bucket, *key;
+    int bucketlen, keylen;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &zbucket, &zobject) == FAILURE) {
+        return;
+    }
+    key = bucket = NULL;
+    keylen = bucketlen = 0;
+    if (Z_TYPE_P(zbucket) == IS_STRING) {
+        bucket = Z_STRVAL_P(zbucket);
+        bucketlen = Z_STRLEN_P(zbucket);
+    } else if (Z_TYPE_P(zbucket) == IS_OBJECT) {
+        riak_name_from_bucket(zbucket, &bucket, &bucketlen TSRMLS_CC);
+    }
+    if (Z_TYPE_P(zobject) == IS_STRING) {
+        key = Z_STRVAL_P(zobject);
+        keylen = Z_STRLEN_P(zobject);
+    } else if (Z_TYPE_P(zobject) == IS_OBJECT) {
+        riak_key_from_object(zobject, &key, &keylen TSRMLS_CC);
+    }
+    if (keylen > 0 && bucketlen > 0) {
+        MAKE_STD_ZVAL(zarray);
+        array_init(zarray);
+        add_assoc_stringl_ex(zarray, bucket, bucketlen, key, keylen, 1);
+        RIAK_CALL_METHOD1(Riak_MapReduce_Input_KeyListInput, addArray, return_value, getThis(), zarray);
+        zval_ptr_dtor(&zarray);
+    } else {
+        zend_throw_exception(riak_badarguments_exception_ce, "Key or bucketname missing", 5001 TSRMLS_CC);
+    }
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto array Riak\MapReduce\Input\KeyListInput->getValue()
+Returns value to use in Mapreduce */
+PHP_METHOD(Riak_MapReduce_Input_KeyListInput, getValue)
+{
+    zval* zresult;
+    zval* zinputlist = zend_read_property(riak_mrinput_keylist_ce, getThis(), "inputList", sizeof("inputList")-1, 1 TSRMLS_CC);
+    zresult = riak_array_to_tupple_array(Z_ARRVAL_P(zinputlist) TSRMLS_CC);
+    RETURN_ZVAL(zresult, 0, 1);
+}
+/* }}} */
+
diff --git a/mr_inputs.h b/riak/map_reduce/input/key_list_input.h
similarity index 56%
rename from mr_inputs.h
rename to riak/map_reduce/input/key_list_input.h
index d180ce9..14a40ba 100644
--- a/mr_inputs.h
+++ b/riak/map_reduce/input/key_list_input.h
@@ -1,6 +1,5 @@
 /*
-   Copyright 2013 Trifork A/S
-   Author: Kaspar Bach Pedersen
+   Copyright 2013: Kaspar Bach Pedersen
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -15,28 +14,18 @@
    limitations under the License.
 */
 
-#ifndef RIAK_MR_INPUTS__H__
-#define RIAK_MR_INPUTS__H__
 
-#include <php.h>
+#ifndef RIAK_MAP_REDUCE__INPUT__KEY_LIST_INPUT__H__
+#define RIAK_MAP_REDUCE__INPUT__KEY_LIST_INPUT__H__
 
-extern zend_class_entry *riak_mrinput_ce;
+#include "php_riak_internal.h"
 
-void riak_mrinputs_init(TSRMLS_D);
-
-PHP_METHOD(RiakMrInput, toArray);
-
-PHP_METHOD(Riak_MapReduce_Input_BucketInput, __construct);
-PHP_METHOD(Riak_MapReduce_Input_BucketInput, getValue);
-PHP_METHOD(Riak_MapReduce_Input_BucketInput, setIndexFilter);
+void riak_map_reduce_input_key_list_input_init(TSRMLS_D);
 
 PHP_METHOD(Riak_MapReduce_Input_KeyListInput, __construct);
 PHP_METHOD(Riak_MapReduce_Input_KeyListInput, addArray);
 PHP_METHOD(Riak_MapReduce_Input_KeyListInput, addSingle);
 PHP_METHOD(Riak_MapReduce_Input_KeyListInput, getValue);
 
-PHP_METHOD(Riak_MapReduce_Input_KeyDataListInput, __construct);
-PHP_METHOD(Riak_MapReduce_Input_KeyDataListInput, getValue);
-PHP_METHOD(Riak_MapReduce_Input_KeyDataListInput, add);
+#endif //RIAK_MAP_REDUCE__INPUT__KEY_LIST_INPUT__H__
 
-#endif
diff --git a/mapreduce.c b/riak/map_reduce/mapreduce.c
similarity index 84%
rename from mapreduce.c
rename to riak/map_reduce/mapreduce.c
index 666c032..a0b5264 100644
--- a/mapreduce.c
+++ b/riak/map_reduce/mapreduce.c
@@ -15,13 +15,13 @@
    limitations under the License.
 */
 #include "mapreduce.h"
-#include "connection.h"
-#include "exceptions.h"
-#include "mr_output.h"
-#include "mr_inputs.h"
-#include "mr_phase.h"
+#include "phase/phase.h"
+#include "input/input.h"
+#include "output/output.h"
+#include "riak/connection.h"
+#include "riak/exception/exception.h"
 #include "ht_utils.h"
-#include "php_riak.h"
+#include "php_riak_internal.h"
 #include "ext/json/php_json.h"
 
 zend_class_entry *riak_mapreduce_ce;
@@ -123,7 +123,7 @@ struct riak_mr_stream_params {/* {{{ */
 /* }}} */
 
 
-void riak_mr_result_cb(struct RIACK_CLIENT* client, void* arg, struct RIACK_MAPRED_RESPONSE* response) /* {{{ */
+void riak_mr_result_cb(riack_client* client, void* arg, riack_mapred_response* response) /* {{{ */
 {
     zval zfuncname, *zresponse, zret;
     struct riak_mr_stream_params *params = (struct riak_mr_stream_params*)arg;
@@ -144,9 +144,9 @@ Runs the mapreduce query and returns the results as an array of Riak_MapReduce_O
 PHP_METHOD(RiakMapreduce, run)
 {
     zval* zjson, *zclient, *zresult, *zstreamer;
-    riak_connection *connection;
-    struct RIACK_MAPRED_RESPONSE_LIST *mapresult;
-    struct RIACK_MAPRED_RESPONSE_LIST *mapresult_iter;
+    riak_connection *connection, *stream_connection;
+    riack_mapred_response_list *mapresult;
+    riack_mapred_response_list *mapresult_iter;
     struct riak_mr_stream_params stream_params;
     int riackResult;
 
@@ -161,18 +161,28 @@ PHP_METHOD(RiakMapreduce, run)
 
     zclient = zend_read_property(riak_mapreduce_ce, getThis(), "connection", sizeof("connection")-1, 1 TSRMLS_CC);
     if (Z_TYPE_P(zclient) == IS_OBJECT) {
-        GET_RIAK_CONNECTION(zclient, connection);
-        ensure_connected(connection TSRMLS_CC);
+
+        connection = get_client_connection(zclient TSRMLS_CC);
+        THROW_EXCEPTION_IF_CONNECTION_IS_NULL(connection);
 
         if (zstreamer) {
+            // Create a new connection only for this stream
+            // LibRiack can only handle one operation at the time pr connection
+            stream_connection = take_connection(connection->client->host, strlen(connection->client->host), connection->client->port TSRMLS_CC);
+            if (!stream_connection) {
+                zval_ptr_dtor(&zjson);
+                CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(stream_connection, RIACK_ERROR_COMMUNICATION);
+            }
+
             stream_params.zstreamer = zstreamer;
             #ifdef ZTS
                 stream_params.tsrm_ls = TSRMLS_C;
             #endif
-            riackResult = riack_map_reduce_stream(connection->client, Z_STRLEN_P(zjson), (uint8_t*)Z_STRVAL_P(zjson), APPLICATION_JSON, &riak_mr_result_cb, &stream_params);
-            CHECK_RIACK_STATUS_THROW_ON_ERROR(connection, riackResult);
+            RIACK_RETRY_OP(riackResult, connection, riack_map_reduce_stream(stream_connection->client, Z_STRLEN_P(zjson), (uint8_t*)Z_STRVAL_P(zjson), APPLICATION_JSON, &riak_mr_result_cb, &stream_params));
+            CHECK_RIACK_STATUS_THROW_ON_ERROR(stream_connection, riackResult);
+            release_connection(stream_connection TSRMLS_CC);
         } else {
-            riackResult = riack_map_reduce(connection->client, Z_STRLEN_P(zjson), (uint8_t*)Z_STRVAL_P(zjson), APPLICATION_JSON, &mapresult);
+            RIACK_RETRY_OP(riackResult, connection, riack_map_reduce(connection->client, Z_STRLEN_P(zjson), (uint8_t*)Z_STRVAL_P(zjson), APPLICATION_JSON, &mapresult));
             if (riackResult == RIACK_SUCCESS) {
                 MAKE_STD_ZVAL(zresult);
                 array_init(zresult);
@@ -195,7 +205,7 @@ PHP_METHOD(RiakMapreduce, run)
 }
 /* }}} */
 
-void riak_mr_to_array_cb(void* callingObj, void* custom_ptr, char* key, uint keylen, uint index, zval** data, int cnt TSRMLS_DC)/* {{{ */
+void riak_mr_to_array_cb(void* callingObj, void* custom_ptr, char* key, uint keylen, uint index, zval** data, int *cnt TSRMLS_DC)/* {{{ */
 {
     zval *zarr, *ztargetarr, zfuncname;
     ztargetarr = (zval*)custom_ptr;
@@ -203,7 +213,6 @@ void riak_mr_to_array_cb(void* callingObj, void* custom_ptr, char* key, uint key
     MAKE_STD_ZVAL(zarr);
     ZVAL_STRING(&zfuncname, "toArray", 0);
     call_user_function(NULL, data, &zfuncname, zarr, 0, NULL TSRMLS_CC);
-    //call_user_function(NULL, &zfunc, &zname, zfuncarray, 0, NULL TSRMLS_CC);
     if (zarr && Z_TYPE_P(zarr) == IS_ARRAY) {
         add_next_index_zval(ztargetarr, zarr);
     }
diff --git a/mapreduce.h b/riak/map_reduce/mapreduce.h
similarity index 100%
rename from mapreduce.h
rename to riak/map_reduce/mapreduce.h
diff --git a/mr_output.c b/riak/map_reduce/output/output.c
similarity index 93%
rename from mr_output.c
rename to riak/map_reduce/output/output.c
index 4605b2e..6bf3828 100644
--- a/mr_output.c
+++ b/riak/map_reduce/output/output.c
@@ -1,6 +1,5 @@
 /*
-   Copyright 2012 Trifork A/S
-   Author: Kaspar Pedersen
+   Copyright 2013: Kaspar Bach Pedersen
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -14,8 +13,7 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 */
-#include "mr_output.h"
-#include "php_riak.h"
+#include "output.h"
 #include "ext/json/php_json.h"
 
 zend_class_entry *riak_mroutput_ce;
@@ -35,19 +33,21 @@ static zend_function_entry riak_mroutput_methods[] = {
     {NULL, NULL, NULL}
 };
 
-void riak_mroutput_init(TSRMLS_D)/* {{{ */
+
+
+void riak_map_reduce_output_output_init(TSRMLS_D)/* {{{ */
 {
     zend_class_entry ce;
 
     INIT_NS_CLASS_ENTRY(ce, "Riak\\MapReduce\\Output", "Output", riak_mroutput_methods);
     riak_mroutput_ce = zend_register_internal_class(&ce TSRMLS_CC);
-
     zend_declare_property_null(riak_mroutput_ce, "value", sizeof("value")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
     zend_declare_property_null(riak_mroutput_ce, "phase", sizeof("phase")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
 }
 /* }}} */
 
-zval *riak_mroutput_from_riack_mapred(struct RIACK_MAPRED_RESPONSE *mapresult TSRMLS_DC)/* {{{ */
+
+zval *riak_mroutput_from_riack_mapred(riack_mapred_response *mapresult TSRMLS_DC)/* {{{ */
 {
     zval *zresult, *zvalue, *zphase;
     MAKE_STD_ZVAL(zresult);
@@ -98,3 +98,4 @@ PHP_METHOD(Riak_MapReduce_Output_Output, getPhaseNumber)
     RIAK_GETTER_LONG(riak_mroutput_ce, "phase");
 }
 /* }}} */
+
diff --git a/mr_output.h b/riak/map_reduce/output/output.h
similarity index 69%
rename from mr_output.h
rename to riak/map_reduce/output/output.h
index 5571224..2cfb5fb 100644
--- a/mr_output.h
+++ b/riak/map_reduce/output/output.h
@@ -1,6 +1,5 @@
 /*
-   Copyright 2013 Trifork A/S
-   Author: Kaspar Bach Pedersen
+   Copyright 2013: Kaspar Bach Pedersen
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -15,20 +14,20 @@
    limitations under the License.
 */
 
-#ifndef RIAK_MR_OUTPUT__H__
-#define RIAK_MR_OUTPUT__H__
+#ifndef RIAK_MAP_REDUCE__OUTPUT__OUTPUT__H__
+#define RIAK_MAP_REDUCE__OUTPUT__OUTPUT__H__
 
-#include <php.h>
-#include <riack.h>
+#include "php_riak_internal.h"
 
 extern zend_class_entry *riak_mroutput_ce;
 
-zval *riak_mroutput_from_riack_mapred(struct RIACK_MAPRED_RESPONSE *mapresult TSRMLS_DC);
+void riak_map_reduce_output_output_init(TSRMLS_D);
 
-void riak_mroutput_init(TSRMLS_D);
+zval *riak_mroutput_from_riack_mapred(riack_mapred_response *mapresult TSRMLS_DC);
 
 PHP_METHOD(Riak_MapReduce_Output_Output, __construct);
 PHP_METHOD(Riak_MapReduce_Output_Output, getValue);
 PHP_METHOD(Riak_MapReduce_Output_Output, getPhaseNumber);
 
-#endif
+#endif //RIAK_MAP_REDUCE__OUTPUT__OUTPUT__H__
+
diff --git a/streaming.c b/riak/map_reduce/output/stream_output.c
similarity index 67%
rename from streaming.c
rename to riak/map_reduce/output/stream_output.c
index 3ba68f1..99634da 100644
--- a/streaming.c
+++ b/riak/map_reduce/output/stream_output.c
@@ -13,36 +13,25 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 */
+#include "stream_output.h"
 
-#include "streaming.h"
-
-zend_class_entry *riak_key_streamer_ce;
 zend_class_entry *riak_mr_streamer_ce;
 
-ZEND_BEGIN_ARG_INFO_EX(arginfo_keystreamer_key, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, key)
-ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_mrstreamer_rec, 0, ZEND_RETURN_VALUE, 1)
     ZEND_ARG_INFO(0, result)
 ZEND_END_ARG_INFO()
 
-static zend_function_entry riak_keystreamer_methods[] = {
-    ZEND_ABSTRACT_ME(RiakKeyStreamer, process, arginfo_keystreamer_key)
-    {NULL, NULL, NULL}
-};
 
 static zend_function_entry riak_mapreduce_out_stream_methods[] = {
     ZEND_ABSTRACT_ME(Riak_MapReduce_Output_StreamOutput, receive, arginfo_mrstreamer_rec)
     {NULL, NULL, NULL}
 };
 
-void riak_streaming_init(TSRMLS_D)/* {{{ */
+
+void riak_map_reduce_output_stream_output_init(TSRMLS_D)/* {{{ */
 {
     zend_class_entry ce;
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\Output", "KeyStreamOutput", riak_keystreamer_methods);
-    riak_key_streamer_ce = zend_register_internal_interface(&ce TSRMLS_CC);
-
     INIT_NS_CLASS_ENTRY(ce, "Riak\\MapReduce\\Output","StreamOutput", riak_mapreduce_out_stream_methods);
     riak_mr_streamer_ce = zend_register_internal_interface(&ce TSRMLS_CC);
 }
diff --git a/riak/map_reduce/output/stream_output.h b/riak/map_reduce/output/stream_output.h
new file mode 100644
index 0000000..c02d590
--- /dev/null
+++ b/riak/map_reduce/output/stream_output.h
@@ -0,0 +1,27 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_MAP_REDUCE__OUTPUT__STREAM_OUTPUT__H__
+#define RIAK_MAP_REDUCE__OUTPUT__STREAM_OUTPUT__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_mr_streamer_ce;
+
+void riak_map_reduce_output_stream_output_init(TSRMLS_D);
+
+#endif //RIAK_MAP_REDUCE__OUTPUT__STREAM_OUTPUT__H__
+
diff --git a/riak/map_reduce/phase/map_phase.c b/riak/map_reduce/phase/map_phase.c
new file mode 100644
index 0000000..6ddedba
--- /dev/null
+++ b/riak/map_reduce/phase/map_phase.c
@@ -0,0 +1,96 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "map_phase.h"
+#include "phase.h"
+
+zend_class_entry *riak_mr_mapphase_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_map_red_phase_map_phase_toarr, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_map_red_phase_map_phase_ctor, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, function)
+    ZEND_ARG_INFO(0, keep)
+    ZEND_ARG_INFO(0, args)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_mrphase_map_methods[] = {
+    PHP_ME(Riak_MapReduce_Phase_MapPhase, __construct, arginfo_map_red_phase_map_phase_ctor, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
+    PHP_ME(Riak_MapReduce_Phase_MapPhase, toArray, arginfo_map_red_phase_map_phase_toarr, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+
+void riak_map_reduce_phase_map_phase_init(TSRMLS_D)/* {{{ */
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\MapReduce\\Phase", "MapPhase", riak_mrphase_map_methods);
+    riak_mr_mapphase_ce = zend_register_internal_class_ex(&ce, riak_mrphase_ce, NULL TSRMLS_CC);
+}
+/* }}} */
+
+/*************************************************************
+* Implementation: Riak\MapReduce\Phase\MapPhase
+*************************************************************/
+
+/* {{{ proto void Riak\MapReduce\Phase\MapPhase->__construct(Riak\MapReduce\Function\Function $function [, bool $keep [, array $arguments]])
+Create a new MapPhase */
+PHP_METHOD(Riak_MapReduce_Phase_MapPhase, __construct)
+{
+    zval *zfunction, *zargs;
+    zend_bool keep;
+    keep = 0;
+    zargs = NULL;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|ba", &zfunction, &keep, &zargs) == FAILURE) {
+        return;
+    }
+    zend_update_property(riak_mr_mapphase_ce, getThis(), "function", sizeof("function")-1, zfunction TSRMLS_CC);
+    zend_update_property_bool(riak_mr_mapphase_ce, getThis(), "keep", sizeof("keep")-1, keep TSRMLS_CC);
+    if (zargs) {
+        zend_update_property(riak_mr_mapphase_ce, getThis(), "arg", sizeof("arg")-1, zargs TSRMLS_CC);
+    }
+}
+/* }}} */
+
+/* {{{ proto array Riak\MapReduce\Phase\MapPhase->toArray()
+Convert this phase into an array */
+PHP_METHOD(Riak_MapReduce_Phase_MapPhase, toArray)
+{
+    zval *zarray, *zfuncarray, *zfunc, *zarg, zname;
+    zend_bool keep;
+    MAKE_STD_ZVAL(zarray);
+    array_init(zarray);
+
+    MAKE_STD_ZVAL(zfuncarray);
+    zfunc = zend_read_property(riak_mr_mapphase_ce, getThis(), "function", sizeof("function")-1, 1 TSRMLS_CC);
+    ZVAL_STRING(&zname, "toArray", 0);
+    call_user_function(NULL, &zfunc, &zname, zfuncarray, 0, NULL TSRMLS_CC);
+
+    keep = Z_BVAL_P(zend_read_property(riak_mr_mapphase_ce, getThis(), "keep", sizeof("keep")-1, 1 TSRMLS_CC));
+    if (keep) {
+        add_assoc_bool_ex(zfuncarray, "keep", sizeof("keep"), 1);
+    }
+    add_assoc_zval_ex(zarray, "map", sizeof("map"), zfuncarray);
+    zarg = zend_read_property(riak_mr_mapphase_ce, getThis(), "arg", sizeof("arg")-1, 1 TSRMLS_CC);
+    if (Z_TYPE_P(zarg) != IS_NULL) {
+        add_assoc_zval_ex(zarray, "arg", sizeof("arg"), zarg);
+        zval_addref_p(zarg);
+    }
+    RETURN_ZVAL(zarray, 0, 1);
+}
+/* }}} */
+
+
diff --git a/riak/map_reduce/phase/map_phase.h b/riak/map_reduce/phase/map_phase.h
new file mode 100644
index 0000000..fdf8639
--- /dev/null
+++ b/riak/map_reduce/phase/map_phase.h
@@ -0,0 +1,29 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_MAP_REDUCE__PHASE__MAP_PHASE__H__
+#define RIAK_MAP_REDUCE__PHASE__MAP_PHASE__H__
+
+#include "php_riak_internal.h"
+
+void riak_map_reduce_phase_map_phase_init(TSRMLS_D);
+
+PHP_METHOD(Riak_MapReduce_Phase_MapPhase, __construct);
+PHP_METHOD(Riak_MapReduce_Phase_MapPhase, toArray);
+
+
+#endif //RIAK_MAP_REDUCE__PHASE__MAP_PHASE__H__
+
diff --git a/riak/map_reduce/phase/phase.c b/riak/map_reduce/phase/phase.c
new file mode 100644
index 0000000..3798fe9
--- /dev/null
+++ b/riak/map_reduce/phase/phase.c
@@ -0,0 +1,40 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "phase.h"
+
+zend_class_entry *riak_mrphase_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_map_red_phase_toarr, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_mrphase_methods[] = {
+    ZEND_ABSTRACT_ME(Riak_MapReduce_Phase_Phase, toArray, arginfo_map_red_phase_toarr)
+    {NULL, NULL, NULL}
+};
+
+
+void riak_map_reduce_phase_phase_init(TSRMLS_D)/* {{{ */
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\MapReduce\\Phase", "Phase", riak_mrphase_methods);
+    riak_mrphase_ce = zend_register_internal_class(&ce TSRMLS_CC);
+    zend_declare_property_null(riak_mrphase_ce, "function", sizeof("functions")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_bool(riak_mrphase_ce, "keep", sizeof("keep")-1, 0, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_mrphase_ce, "arg", sizeof("arg")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+}
+/* }}} */
+
+
diff --git a/riak/map_reduce/phase/phase.h b/riak/map_reduce/phase/phase.h
new file mode 100644
index 0000000..e4e2d46
--- /dev/null
+++ b/riak/map_reduce/phase/phase.h
@@ -0,0 +1,28 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_MAP_REDUCE__PHASE__PHASE__H__
+#define RIAK_MAP_REDUCE__PHASE__PHASE__H__
+
+#include "php_riak_internal.h"
+
+
+extern zend_class_entry *riak_mrphase_ce;
+
+void riak_map_reduce_phase_phase_init(TSRMLS_D);
+
+#endif //RIAK_MAP_REDUCE__PHASE__PHASE__H__
+
diff --git a/riak/map_reduce/phase/reduce_phase.c b/riak/map_reduce/phase/reduce_phase.c
new file mode 100644
index 0000000..d3a87db
--- /dev/null
+++ b/riak/map_reduce/phase/reduce_phase.c
@@ -0,0 +1,97 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "reduce_phase.h"
+#include "phase.h"
+
+zend_class_entry *riak_mr_reducephase_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_map_red_phase_reduce_phase_toarr, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_map_red_phase_reduce_phase_ctor, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, function)
+    ZEND_ARG_INFO(0, keep)
+    ZEND_ARG_INFO(0, args)
+ZEND_END_ARG_INFO()
+
+
+static zend_function_entry riak_mrphase_reduce_methods[] = {
+    PHP_ME(Riak_MapReduce_Phase_ReducePhase, __construct, arginfo_map_red_phase_reduce_phase_ctor, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
+    PHP_ME(Riak_MapReduce_Phase_ReducePhase, toArray, arginfo_map_red_phase_reduce_phase_toarr, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+
+void riak_map_reduce_phase_reduce_phase_init(TSRMLS_D)/* {{{ */
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\MapReduce\\Phase", "ReducePhase", riak_mrphase_reduce_methods);
+    riak_mr_reducephase_ce = zend_register_internal_class_ex(&ce, riak_mrphase_ce, NULL TSRMLS_CC);
+}
+/* }}} */
+
+
+/*************************************************************
+* Implementation: Riak\MapReduce\Phase\ReducePhase
+*************************************************************/
+
+/* {{{ proto void Riak\MapReduce\Phase\ReducePhase->__construct(Riak\MapReduce\Function\Function $function [, bool $keep [, array $arguments]])
+Create a new ReducePhase */
+PHP_METHOD(Riak_MapReduce_Phase_ReducePhase, __construct)
+{
+    zval *zfunction, *zargs;
+    zend_bool keep;
+    keep = 0;
+    zargs = NULL;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|ba", &zfunction, &keep, &zargs) == FAILURE) {
+        return;
+    }
+    zend_update_property(riak_mr_reducephase_ce, getThis(), "function", sizeof("function")-1, zfunction TSRMLS_CC);
+    zend_update_property_bool(riak_mr_reducephase_ce, getThis(), "keep", sizeof("keep")-1, keep TSRMLS_CC);
+    if (zargs) {
+        zend_update_property(riak_mr_reducephase_ce, getThis(), "arg", sizeof("arg")-1, zargs TSRMLS_CC);
+    }
+}
+/* }}} */
+
+/* {{{ proto array Riak\MapReduce\Phase\ReducePhase->toArray()
+Convert this phase into an array */
+PHP_METHOD(Riak_MapReduce_Phase_ReducePhase, toArray)
+{
+    zval *zarray, *zfuncarray, *zfunc, *zarg, zname;
+    zend_bool keep;
+    MAKE_STD_ZVAL(zarray);
+    array_init(zarray);
+
+    MAKE_STD_ZVAL(zfuncarray);
+    zfunc = zend_read_property(riak_mr_reducephase_ce, getThis(), "function", sizeof("function")-1, 1 TSRMLS_CC);
+    ZVAL_STRING(&zname, "toArray", 0);
+    call_user_function(NULL, &zfunc, &zname, zfuncarray, 0, NULL TSRMLS_CC);
+
+    keep = Z_BVAL_P(zend_read_property(riak_mr_reducephase_ce, getThis(), "keep", sizeof("keep")-1, 1 TSRMLS_CC));
+    if (keep) {
+        add_assoc_bool_ex(zfuncarray, "keep", sizeof("keep"), 1);
+    }
+    add_assoc_zval_ex(zarray, "reduce", sizeof("reduce"), zfuncarray);
+    zarg = zend_read_property(riak_mr_reducephase_ce, getThis(), "arg", sizeof("arg")-1, 1 TSRMLS_CC);
+    if (Z_TYPE_P(zarg) != IS_NULL) {
+        zval_addref_p(zarg);
+        add_assoc_zval_ex(zarray, "arg", sizeof("arg"), zarg);
+    }
+    RETURN_ZVAL(zarray, 0, 1);
+}
+/* }}} */
+
diff --git a/mr_phase.h b/riak/map_reduce/phase/reduce_phase.h
similarity index 67%
rename from mr_phase.h
rename to riak/map_reduce/phase/reduce_phase.h
index 9a5d51d..16fb058 100644
--- a/mr_phase.h
+++ b/riak/map_reduce/phase/reduce_phase.h
@@ -1,6 +1,5 @@
 /*
-   Copyright 2013 Trifork A/S
-   Author: Kaspar Bach Pedersen
+   Copyright 2013: Kaspar Bach Pedersen
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -15,19 +14,15 @@
    limitations under the License.
 */
 
-#ifndef RIAK_MR_PHASE__H__
-#define RIAK_MR_PHASE__H__
+#ifndef RIAK_MAP_REDUCE__PHASE__REDUCE_PHASE__H__
+#define RIAK_MAP_REDUCE__PHASE__REDUCE_PHASE__H__
 
-#include <php.h>
+#include "php_riak_internal.h"
 
-extern zend_class_entry *riak_mrphase_ce;
-
-void riak_mrphase_init(TSRMLS_D);
-
-PHP_METHOD(Riak_MapReduce_Phase_MapPhase, __construct);
-PHP_METHOD(Riak_MapReduce_Phase_MapPhase, toArray);
+void riak_map_reduce_phase_reduce_phase_init(TSRMLS_D);
 
 PHP_METHOD(Riak_MapReduce_Phase_ReducePhase, __construct);
 PHP_METHOD(Riak_MapReduce_Phase_ReducePhase, toArray);
 
-#endif
+#endif //RIAK_MAP_REDUCE__PHASE__REDUCE_PHASE__H__
+
diff --git a/object.c b/riak/object.c
similarity index 62%
rename from object.c
rename to riak/object.c
index 3bca117..9cc7aa0 100644
--- a/object.c
+++ b/riak/object.c
@@ -16,9 +16,9 @@
 */
 
 #include "object.h"
-#include "php_riak.h"
 #include "link.h"
 #include "ht_utils.h"
+#include "exception/exception.h"
 
 zend_class_entry *riak_object_ce;
 
@@ -63,6 +63,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_object_set_content_encoding, 0, ZEND_RETURN_
     ZEND_ARG_INFO(0, content_encoding)
 ZEND_END_ARG_INFO()
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_object_set_vclock, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, vclock)
+ZEND_END_ARG_INFO()
+
 static zend_function_entry riak_object_methods[] = {
     PHP_ME(RiakObject, __construct, arginfo_riak_object_ctor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
     PHP_ME(RiakObject, getKey, arginfo_riak_object_noargs, ZEND_ACC_PUBLIC)
@@ -83,7 +87,12 @@ static zend_function_entry riak_object_methods[] = {
     PHP_ME(RiakObject, getIndexMap, arginfo_riak_object_noargs, ZEND_ACC_PUBLIC)
     PHP_ME(RiakObject, getMetadataMap, arginfo_riak_object_noargs, ZEND_ACC_PUBLIC)
     PHP_ME(RiakObject, getLinkList, arginfo_riak_object_noargs, ZEND_ACC_PUBLIC)
-	{NULL, NULL, NULL}
+    PHP_ME(RiakObject, getVClock, arginfo_riak_object_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakObject, setVClock, arginfo_riak_object_set_vclock, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakObject, getLastModifiedUSecs, arginfo_riak_object_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakObject, getLastModified, arginfo_riak_object_noargs, ZEND_ACC_PUBLIC)
+
+    {NULL, NULL, NULL}
 };
 
 void riak_object_init(TSRMLS_D)/* {{{ */
@@ -93,6 +102,7 @@ void riak_object_init(TSRMLS_D)/* {{{ */
 	riak_object_ce = zend_register_internal_class(&ce TSRMLS_CC);
     zend_declare_property_null(riak_object_ce, "key", sizeof("key")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
     zend_declare_property_null(riak_object_ce, "vtag", sizeof("vtag")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
+    zend_declare_property_null(riak_object_ce, "vClock", sizeof("vClock")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
     zend_declare_property_null(riak_object_ce, "contentEncoding", sizeof("contentEncoding")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
     zend_declare_property_null(riak_object_ce, "charset", sizeof("charset")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
     zend_declare_property_string(riak_object_ce, "contentType", sizeof("contentType")-1, "text/plain", ZEND_ACC_PRIVATE TSRMLS_CC);
@@ -147,6 +157,22 @@ PHP_METHOD(RiakObject, __construct)
 }
 /* }}} */
 
+/* {{{ proto int Riak\Object->getLastModified()
+ */
+PHP_METHOD(RiakObject, getLastModified)
+{
+    RIAK_GETTER_LONG(riak_object_ce, "lastModified");
+}
+/* }}} */
+
+/* {{{ proto int Riak\Object->getLastModified()
+ */
+PHP_METHOD(RiakObject, getLastModifiedUSecs)
+{
+    RIAK_GETTER_LONG(riak_object_ce, "lastModifiedUSecs");
+}
+/* }}} */
+
 /* {{{ proto string Riak\Object->getKey()
  */
 PHP_METHOD(RiakObject, getKey)
@@ -176,7 +202,7 @@ PHP_METHOD(RiakObject, getContent)
  */
 PHP_METHOD(RiakObject, setContent)
 {
-    RIAK_SETTER_STRING(riak_object_ce, "content");
+    RIAK_SETTER_OPTIONAL_STRING(riak_object_ce, "content");
     RIAK_RETURN_THIS
 }
 /* }}} */
@@ -185,7 +211,7 @@ PHP_METHOD(RiakObject, setContent)
  */
 PHP_METHOD(RiakObject, addIndex)
 {
-    zval *zindexarr, *zidxvalue;
+    zval *zindexarr, *zidxvalue, **zfoundval;
     char* idxname;
     int idxname_len;
     zidxvalue = NULL;
@@ -193,11 +219,33 @@ PHP_METHOD(RiakObject, addIndex)
         return;
     }
     zindexarr = zend_read_property(riak_object_ce, getThis(), "indexes", sizeof("indexes")-1, 1 TSRMLS_CC);
-    if (zidxvalue != NULL && Z_TYPE_P(zidxvalue) != IS_NULL) {
-        zval_addref_p(zidxvalue);
-        add_assoc_zval_ex(zindexarr, idxname, idxname_len+1, zidxvalue);
+
+    // We need to check if the index already exists and if it does we should change it to an array or
+    // create a new array and add the existing and the new one.
+    zval_addref_p(zidxvalue);
+    if (zend_hash_find(Z_ARRVAL_P(zindexarr), idxname, idxname_len+1, (void**) &zfoundval) == SUCCESS) {
+        zval *ztmp;
+        ztmp = *zfoundval;
+        if (Z_TYPE_PP(zfoundval) != IS_ARRAY) {
+            zval *zarr;
+            MAKE_STD_ZVAL(zarr);
+            array_init(zarr);
+            zval_addref_p(ztmp);
+            add_next_index_zval(zarr, ztmp);
+            zend_hash_update(Z_ARRVAL_P(zindexarr), idxname, idxname_len+1, &zarr, sizeof(zval*), NULL);
+            ztmp = zarr;
+        }
+        if (zidxvalue == NULL) {
+            add_next_index_null(ztmp);
+        } else {
+            add_next_index_zval(ztmp, zidxvalue);
+        }
     } else {
-        add_assoc_null_ex(zindexarr, idxname, idxname_len+1);
+        if (zidxvalue == NULL) {
+            add_assoc_null_ex(zindexarr, idxname, idxname_len+1);
+        } else {
+            add_assoc_zval_ex(zindexarr, idxname, idxname_len+1, zidxvalue);
+        }
     }
     RIAK_RETURN_THIS
 }
@@ -240,10 +288,10 @@ PHP_METHOD(RiakObject, addLink)
 }
 /* }}} */
 
-/* {{{ proto Riak\Object Riak\Object->setCharset(string $charset) */
+/* {{{ proto Riak\Object Riak\Object->setCharset(null|string $charset) */
 PHP_METHOD(RiakObject, setCharset)
 {
-    RIAK_SETTER_STRING(riak_object_ce, "charset");
+    RIAK_SETTER_OPTIONAL_STRING(riak_object_ce, "charset");
     RIAK_RETURN_THIS
 }
 /* }}} */
@@ -255,10 +303,10 @@ PHP_METHOD(RiakObject, getCharset)
 }
 /* }}} */
 
-/* {{{ proto Riak\Object Riak\Object->setContentType(string $contentType) */
+/* {{{ proto Riak\Object Riak\Object->setContentType(null|string $contentType) */
 PHP_METHOD(RiakObject, setContentType)
 {
-    RIAK_SETTER_STRING(riak_object_ce, "contentType");
+    RIAK_SETTER_OPTIONAL_STRING(riak_object_ce, "contentType");
     RIAK_RETURN_THIS
 }
 /* }}} */
@@ -270,10 +318,10 @@ PHP_METHOD(RiakObject, getContentType)
 }
 /* }}} */
 
-/* {{{ proto Riak\Object Riak\Object->setContentEncoding(string $contentEncoding) */
+/* {{{ proto Riak\Object Riak\Object->setContentEncoding(null|string $contentEncoding) */
 PHP_METHOD(RiakObject, setContentEncoding)
 {
-    RIAK_SETTER_STRING(riak_object_ce, "contentEncoding");
+    RIAK_SETTER_OPTIONAL_STRING(riak_object_ce, "contentEncoding");
     RIAK_RETURN_THIS
 }
 /* }}} */
@@ -324,6 +372,20 @@ PHP_METHOD(RiakObject, getLinkList)
 }
 /* }}} */
 
+/* {{{ proto string|null Riak\Object->getVClock() */
+PHP_METHOD(RiakObject, getVClock)
+{
+    RIAK_GETTER_STRING(riak_object_ce, "vClock");
+}
+/* }}} */
+
+/* {{{ proto void Riak\Object->setVClock(null|string $vclock) */
+PHP_METHOD(RiakObject, setVClock)
+{
+    RIAK_SETTER_OPTIONAL_STRING(riak_object_ce, "vClock");
+    RIAK_RETURN_THIS
+}
+/* }}} */
 
 /*************************************************************
 * Implementation: Riak\Object Helpers
@@ -353,9 +415,9 @@ void riak_key_from_object(zval *zobject, char** key, int* keylen TSRMLS_DC)/* {{
 }
 /* }}} */
 
-zval *links_from_content(struct RIACK_CONTENT* content TSRMLS_DC)/* {{{ */
+zval *links_from_content(riack_content* content TSRMLS_DC)/* {{{ */
 {
-    struct RIACK_LINK *curr_link;
+    riack_link *curr_link;
     char *tag, *bucket, *key;
     zval *zlinkarr, *zlink;
     size_t i;
@@ -378,23 +440,44 @@ zval *links_from_content(struct RIACK_CONTENT* content TSRMLS_DC)/* {{{ */
 /* }}} */
 
 /* Get metadata array from returned content */
-zval *assoc_array_from_riack_pairs(struct RIACK_PAIR* pairs, size_t pairscnt TSRMLS_DC) /* {{{ */
+zval *assoc_array_from_riack_pairs(riack_pair* pairs, size_t pairscnt TSRMLS_DC) /* {{{ */
 {
     zval *zresultarr;
 	size_t i;
-    struct RIACK_PAIR* currentpair;
+    riack_pair* currentpair;
 	char* currentKey;
     MAKE_STD_ZVAL(zresultarr);
     array_init(zresultarr);
     for (i=0; i<pairscnt; ++i) {
         currentpair = &(pairs[i]);
         if (currentpair) {
+            zval **zfoundval;
             currentKey = pestrndup(currentpair->key.value, currentpair->key.len, 0);
-            if (currentpair->value_present) {
-                add_assoc_stringl(zresultarr, currentKey, (char*)currentpair->value, currentpair->value_len, 1);
-			} else {
-                add_assoc_null(zresultarr, currentKey);
-			}
+            if (zend_hash_find(Z_ARRVAL_P(zresultarr), currentKey, currentpair->key.len+1, (void**) &zfoundval) == SUCCESS) {
+                // TODO Make this conversion into a function, we are doing the same in two places
+                zval *ztmp;
+                ztmp = *zfoundval;
+                if (Z_TYPE_PP(zfoundval) != IS_ARRAY) {
+                    zval *zarr;
+                    MAKE_STD_ZVAL(zarr);
+                    array_init(zarr);
+                    zval_addref_p(ztmp);
+                    add_next_index_zval(zarr, ztmp);
+                    zend_hash_update(Z_ARRVAL_P(zresultarr), currentKey, currentpair->key.len+1, &zarr, sizeof(zval*), NULL);
+                    ztmp = zarr;
+                }
+                if (currentpair->value_present) {
+                    add_next_index_stringl(ztmp, (char*)currentpair->value, currentpair->value_len, 1);
+                } else {
+                    add_next_index_null(ztmp);
+                }
+            } else {
+                if (currentpair->value_present) {
+                    add_assoc_stringl(zresultarr, currentKey, (char*)currentpair->value, currentpair->value_len, 1);
+                } else {
+                    add_assoc_null(zresultarr, currentKey);
+                }
+            }
 			pefree(currentKey, 0);
 		}
 	}
@@ -402,23 +485,29 @@ zval *assoc_array_from_riack_pairs(struct RIACK_PAIR* pairs, size_t pairscnt TSR
 }
 /* }}} */
 
-
 /* Set object properties from returned content */
-void set_object_from_riak_content(zval* object, struct RIACK_CONTENT* content TSRMLS_DC) /* {{{ */
+void set_object_from_riak_content(zval* object, riack_content* content TSRMLS_DC) /* {{{ */
 {
     zval* zmetadata, *zlinks, *zindexes;
 
     zend_update_property_stringl(riak_object_ce, object, "content", sizeof("content")-1,
-		(const char*)content->data, content->data_len TSRMLS_CC);
-	zend_update_property_stringl(riak_object_ce, object, "contentEncoding", sizeof("contentEncoding")-1, 
-		(const char*)content->content_encoding.value, content->content_encoding.len TSRMLS_CC);
-	zend_update_property_stringl(riak_object_ce, object, "contentType", sizeof("contentType")-1, 
-		(const char*)content->content_type.value, content->content_type.len TSRMLS_CC);
+        (const char*)content->data, content->data_len TSRMLS_CC);
+    if (content->content_encoding.len > 0 && content->content_encoding.value != NULL) {
+        zend_update_property_stringl(riak_object_ce, object, "contentEncoding", sizeof("contentEncoding")-1,
+            (const char*)content->content_encoding.value, content->content_encoding.len TSRMLS_CC);
+    }
+    if (content->content_type.len > 0 && content->content_type.value != NULL) {
+        zend_update_property_stringl(riak_object_ce, object, "contentType", sizeof("contentType")-1,
+            (const char*)content->content_type.value, content->content_type.len TSRMLS_CC);
+    }
     if (content->vtag.len > 0 && content->vtag.value != NULL) {
         zend_update_property_stringl(riak_object_ce, object, "vtag", sizeof("vtag")-1,
             (const char*)content->vtag.value, content->vtag.len TSRMLS_CC);
     }
-	zend_update_property_stringl(riak_object_ce, object, "charset", sizeof("charset")-1, content->charset.value, content->charset.len TSRMLS_CC);
+    if (content->charset.len > 0 && content->charset.value != NULL) {
+        zend_update_property_stringl(riak_object_ce, object, "charset", sizeof("charset")-1,
+            content->charset.value, content->charset.len TSRMLS_CC);
+    }
 
 	if (content->deleted_present) {
 		zend_update_property_bool(riak_object_ce, object, "isDeleted", sizeof("isDeleted")-1, content->deleted TSRMLS_CC);
@@ -450,112 +539,166 @@ void set_object_from_riak_content(zval* object, struct RIACK_CONTENT* content TS
 /* }}} */
 
 /* Called once for each link in the links property of RiakObject */
-void set_links_from_object_cb(void* callingObj, void* custom_ptr, char* key, uint keylen, uint index, zval** data, int cnt TSRMLS_DC)/* {{{ */
+void set_links_from_object_cb(void* callingObj, void* custom_ptr, char* key, uint keylen, uint index, zval** data, int *cnt TSRMLS_DC)/* {{{ */
 {
     zval *zbucket, *ztag, *zkey;
-    RIACK_STRING rbucket, rtag, rkey;
-    struct RIACK_CLIENT* client = (struct RIACK_CLIENT*)callingObj;
-    struct RIACK_CONTENT* content = (struct RIACK_CONTENT*)custom_ptr;
+    riack_string rbucket, rtag, rkey;
+    riack_client* client = (riack_client*)callingObj;
+    riack_content* content = (riack_content*)custom_ptr;
 
     zbucket = zend_read_property(riak_link_ce, *data, "bucket", sizeof("bucket")-1, 1 TSRMLS_CC);
     rbucket.len = Z_STRLEN_P(zbucket);
     rbucket.value = Z_STRVAL_P(zbucket);
-    content->links[cnt].bucket = riack_copy_string(client, rbucket);
+    content->links[*cnt].bucket = riack_copy_string(client, rbucket);
 
     zkey = zend_read_property(riak_link_ce, *data, "key", sizeof("key")-1, 1 TSRMLS_CC);
     rkey.len = Z_STRLEN_P(zkey);
     rkey.value = Z_STRVAL_P(zkey);
-    content->links[cnt].key = riack_copy_string(client, rkey);
+    content->links[*cnt].key = riack_copy_string(client, rkey);
 
     ztag = zend_read_property(riak_link_ce, *data, "tag", sizeof("tag")-1, 1 TSRMLS_CC);
     rtag.len = Z_STRLEN_P(ztag);
     rtag.value = Z_STRVAL_P(ztag);
-    content->links[cnt].tag = riack_copy_string(client, rtag);
+    content->links[*cnt].tag = riack_copy_string(client, rtag);
 }
 /* }}} */
 
 /* Copy all links from link array to a content structure */
-void set_links_from_object(struct RIACK_CONTENT* content, zval* zlinksarr, struct RIACK_CLIENT* client TSRMLS_DC)/* {{{ */
+void set_links_from_object(riack_content* content, zval* zlinksarr, riack_client* client TSRMLS_DC)/* {{{ */
 {
     if (zlinksarr && Z_TYPE_P(zlinksarr) == IS_ARRAY) {
         content->link_count = zend_hash_num_elements(Z_ARRVAL_P(zlinksarr));
         if (content->link_count > 0) {
-            content->links = RMALLOC(client, sizeof(struct RIACK_LINK) * content->link_count);
-            memset(content->links, 0, sizeof(struct RIACK_LINK) * content->link_count);
+            content->links = RMALLOC(client, sizeof(riack_link) * content->link_count);
+            memset(content->links, 0, sizeof(riack_link) * content->link_count);
             foreach_in_hashtable(client, content, Z_ARRVAL_P(zlinksarr), &set_links_from_object_cb TSRMLS_CC);
         }
     }
 }
 /* }}} */
 
+/* Copies the content of a zval to the value of a riack pair */
+void copy_zval_to_pair_value(riack_client* client, zval* zv, riack_pair* pair TSRMLS_DC)
+{
+    if (Z_TYPE_P(zv) != IS_NULL) {
+        zval* ztmp;
+        ALLOC_ZVAL(ztmp);
+        *ztmp = *zv;
+        INIT_PZVAL(ztmp);
+        zval_copy_ctor(ztmp);
+        if (Z_TYPE_P(ztmp) != IS_STRING) {
+            convert_to_string(ztmp);
+        }
+        pair->value_present = 1;
+        RMALLOCCOPY(client, pair->value, pair->value_len, Z_STRVAL_P(ztmp), Z_STRLEN_P(ztmp));
+        zval_ptr_dtor(&ztmp);
+    }
+}
+
+/* Copies a key name to a riack pair key */
+void copy_key_string_to_pair(riack_client* client, char* key, uint keylen, riack_pair* pair TSRMLS_DC)
+{
+    riack_string rkey;
+    rkey.value = key;
+    rkey.len = keylen;
+    pair->key = riack_copy_string(client, rkey);
+}
+
+/* Converts an index integer to a string and sets the pair key to it */
+void copy_index_to_pair_key(riack_client* client, uint index, riack_pair* pair TSRMLS_DC)
+{
+    zval* ztmp;
+    MAKE_STD_ZVAL(ztmp);
+    ZVAL_LONG(ztmp, index);
+    convert_to_string(ztmp);
+    copy_key_string_to_pair(client, Z_STRVAL_P(ztmp), Z_STRLEN_P(ztmp), pair TSRMLS_CC);
+    zval_ptr_dtor(&ztmp);
+}
+
 /* Called once for each metadata or index entry in the RiakObject */
-void set_pairs_from_object_cb(void* callingObj, void* custom_ptr, char* key, uint keylen, uint index, zval** data, int cnt TSRMLS_DC)/* {{{ */
+void set_pairs_from_object_cb(void* callingObj, void* custom_ptr, char* key, uint keylen, uint index, zval** data, int *cnt TSRMLS_DC)/* {{{ */
 {
-    zval *tmp;
-    RIACK_STRING rkey;
-    struct RIACK_CLIENT* client = (struct RIACK_CLIENT*)callingObj;
-    struct RIACK_PAIR* pairs = (struct RIACK_PAIR*)custom_ptr;
+    riack_client* client = (riack_client*)callingObj;
+    riack_pair* pairs = (riack_pair*)custom_ptr;
     if (key) {
-        rkey.value = key;
-        rkey.len = keylen-1;
-        pairs[cnt].key = riack_copy_string(client, rkey);
+        copy_key_string_to_pair(client, key, keylen-1, &(pairs[*cnt]) TSRMLS_CC);
     } else {
-        MAKE_STD_ZVAL(tmp);
-        ZVAL_LONG(tmp, index);
-        convert_to_string(tmp);
-        rkey.value = Z_STRVAL_P(tmp);
-        rkey.len = Z_STRLEN_P(tmp);
-        pairs[cnt].key = riack_copy_string(client, rkey);
-        zval_ptr_dtor(&tmp);
-    }
-    ALLOC_ZVAL(tmp);
-    *tmp = **data;
-    if (Z_TYPE_P(tmp) != IS_NULL) {
-        INIT_PZVAL(tmp);
-        zval_copy_ctor(tmp);
-        if (Z_TYPE_P(tmp) != IS_STRING) {
-            convert_to_string(tmp);
-        }
-        pairs[cnt].value_present = 1;
-        RMALLOCCOPY(client, pairs[cnt].value, pairs[cnt].value_len, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
-        zval_ptr_dtor(&tmp);
+        copy_index_to_pair_key(client, index, &(pairs[*cnt]) TSRMLS_CC);
     }
-
+    copy_zval_to_pair_value(client, *data, &(pairs[*cnt]) TSRMLS_CC);
 }
 /* }}} */
 
 /* Copy all metadata from metadata array to a content structure */
-void set_metadata_from_object(struct RIACK_CONTENT* content, zval* zMetadata, struct RIACK_CLIENT* client TSRMLS_DC) /* {{{ */
+void set_metadata_from_object(riack_content* content, zval* zMetadata, riack_client* client TSRMLS_DC) /* {{{ */
 {
     if (zMetadata && Z_TYPE_P(zMetadata) == IS_ARRAY) {
         content->usermeta_count = zend_hash_num_elements(Z_ARRVAL_P(zMetadata));
         if (content->usermeta_count > 0) {
-			content->usermetas = RMALLOC(client, sizeof(struct RIACK_PAIR) * content->usermeta_count);
-			memset(content->usermetas, 0, sizeof(struct RIACK_PAIR) * content->usermeta_count);
+            content->usermetas = RMALLOC(client, sizeof(riack_pair) * content->usermeta_count);
+            memset(content->usermetas, 0, sizeof(riack_pair) * content->usermeta_count);
             foreach_in_hashtable(client, content->usermetas, Z_ARRVAL_P(zMetadata), &set_pairs_from_object_cb TSRMLS_CC);
-		}
-	}
+        }
+    }
+}
+/* }}} */
+
+/* This functions count recursuve how many values are in an array (including sub array values)
+ * custom_ptr should point to an integer
+*/
+void count_index_values_cb(void* callingObj, void* custom_ptr, char* key, uint keylen, uint index, zval** data, int *cnt TSRMLS_DC)/* {{{ */
+{
+    size_t *count = custom_ptr;
+    if (Z_TYPE_PP(data) != IS_ARRAY) {
+        (*count)++;
+    } else {
+        foreach_in_hashtable(NULL, count, Z_ARRVAL_PP(data), &count_index_values_cb TSRMLS_CC);
+    }
+}
+
+/* Called once for each index entry in the RiakObject */
+void set_index_pairs_from_object_cb(void* callingObj, void* custom_ptr, char* key, uint keylen, uint index, zval** data, int *cnt TSRMLS_DC)/* {{{ */
+{
+    if (Z_TYPE_PP(data) == IS_ARRAY) {
+        zval **zcurr;
+        HashPosition pointer;
+        HashTable *hindex = Z_ARRVAL_PP(data);
+        zcurr = NULL;
+        for(zend_hash_internal_pointer_reset_ex(hindex, &pointer);
+            zend_hash_get_current_data_ex(hindex, (void**)&zcurr, &pointer) == SUCCESS;
+            zend_hash_move_forward_ex(hindex, &pointer)) {
+            set_index_pairs_from_object_cb(callingObj, custom_ptr, key, keylen, 0, zcurr, cnt TSRMLS_CC);
+            (*cnt)++;
+        }
+        if (zcurr != NULL) {
+            (*cnt)--;
+        }
+        //foreach_in_hashtable(callingObj, custom_ptr, Z_ARRVAL_PP(data), &set_index_pairs_from_object_cb TSRMLS_CC);
+    } else {
+        set_pairs_from_object_cb(callingObj, custom_ptr, key, keylen, index, data, cnt TSRMLS_CC);
+    }
 }
 /* }}} */
 
 /* Copy all indexes from array to a content structure */
-void set_indexes_from_object(struct RIACK_CONTENT* content, zval* zindexsarray, struct RIACK_CLIENT* client TSRMLS_DC) /* {{{ */
+void set_indexes_from_object(riack_content* content, zval* zindexsarray, riack_client* client TSRMLS_DC) /* {{{ */
 {
-    if (zindexsarray && Z_TYPE_P(zindexsarray)) {
-        content->index_count = zend_hash_num_elements(Z_ARRVAL_P(zindexsarray));
+    if (zindexsarray && Z_TYPE_P(zindexsarray) == IS_ARRAY) {
+        foreach_in_hashtable(NULL, &content->index_count, Z_ARRVAL_P(zindexsarray), &count_index_values_cb TSRMLS_CC);
         if (content->index_count > 0) {
-            content->indexes = RMALLOC(client, sizeof(struct RIACK_PAIR) * content->index_count);
-            memset(content->indexes, 0, sizeof(struct RIACK_PAIR) * content->index_count);
-            foreach_in_hashtable(client, content->indexes, Z_ARRVAL_P(zindexsarray), &set_pairs_from_object_cb TSRMLS_CC);
+            content->indexes = RMALLOC(client, sizeof(riack_pair) * content->index_count);
+            memset(content->indexes, 0, sizeof(riack_pair) * content->index_count);
+            foreach_in_hashtable(client, content->indexes, Z_ARRVAL_P(zindexsarray), &set_index_pairs_from_object_cb TSRMLS_CC);
         }
     }
 }
 /* }}} */
 
+
 /* Fill out members of a content struct with this objects values */
-void set_riak_content_from_object(struct RIACK_CONTENT* content, zval* object, struct RIACK_CLIENT* client TSRMLS_DC)/* {{{ */
+void set_riak_content_from_object(riack_content* content, zval* object, riack_client* client TSRMLS_DC)/* {{{ */
 {
-	zval* zTmp;
+    zval* zTmp;
     zTmp = zend_read_property(riak_object_ce, object, "content", sizeof("content")-1, 1 TSRMLS_CC);
 	if (Z_TYPE_P(zTmp) == IS_STRING) {
 		content->data_len = Z_STRLEN_P(zTmp);
diff --git a/object.h b/riak/object.h
similarity index 80%
rename from object.h
rename to riak/object.h
index c0e8d26..092894a 100644
--- a/object.h
+++ b/riak/object.h
@@ -18,16 +18,15 @@
 #ifndef RIAK_OBJECT__H__
 #define RIAK_OBJECT__H__
 
-#include <php.h>
-#include <riack.h>
+#include "php_riak_internal.h"
 
 extern zend_class_entry *riak_object_ce;
 
 zval* create_object_object(const char* key TSRMLS_DC);
 
 void riak_object_init(TSRMLS_D);
-void set_object_from_riak_content(zval* object, struct RIACK_CONTENT* content TSRMLS_DC);
-void set_riak_content_from_object(struct RIACK_CONTENT* content, zval* object, struct RIACK_CLIENT* client TSRMLS_DC);
+void set_object_from_riak_content(zval* object, riack_content* content TSRMLS_DC);
+void set_riak_content_from_object(riack_content* content, zval* object, riack_client* client TSRMLS_DC);
 
 void riak_key_from_object(zval *zobject, char** key, int* keylen  TSRMLS_DC);
 
@@ -50,5 +49,9 @@ PHP_METHOD(RiakObject, getIndexMap);
 PHP_METHOD(RiakObject, getLinkList);
 PHP_METHOD(RiakObject, getMetadataMap);
 PHP_METHOD(RiakObject, getVTag);
+PHP_METHOD(RiakObject, getVClock);
+PHP_METHOD(RiakObject, setVClock);
+PHP_METHOD(RiakObject, getLastModified);
+PHP_METHOD(RiakObject, getLastModifiedUSecs);
 
 #endif
diff --git a/riak/object_list.c b/riak/object_list.c
new file mode 100644
index 0000000..ce22f40
--- /dev/null
+++ b/riak/object_list.c
@@ -0,0 +1,236 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "object_list.h"
+#include "exception/exception.h"
+#include "object.h"
+#include <zend_interfaces.h>
+#include <ext/spl/spl_iterators.h>
+#include <ext/spl/spl_array.h>
+
+zend_class_entry *riak_output_object_list_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_output_object_list_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_output_object_list_offset_exists, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, offset)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_output_object_list_offset_set, 0, ZEND_RETURN_VALUE, 2)
+    ZEND_ARG_INFO(0, offset)
+    ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
+
+static zend_function_entry riak_output_object_list_methods[] = {
+    PHP_ME(Riak_Object_List, __construct, arginfo_riak_output_object_list_noargs, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+    PHP_ME(Riak_Object_List, first, arginfo_riak_output_object_list_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Object_List, last, arginfo_riak_output_object_list_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Object_List, isEmpty, arginfo_riak_output_object_list_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Object_List, offsetExists, arginfo_riak_output_object_list_offset_exists, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Object_List, offsetGet, arginfo_riak_output_object_list_offset_exists, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Object_List, offsetSet, arginfo_riak_output_object_list_offset_set, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Object_List, offsetUnset, arginfo_riak_output_object_list_offset_exists, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Object_List, count, arginfo_riak_output_object_list_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Object_List, getIterator, arginfo_riak_output_object_list_noargs, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+
+void riak_output_object_list_init(TSRMLS_D) /* {{{ */
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak", "ObjectList", riak_output_object_list_methods);
+    riak_output_object_list_ce = zend_register_internal_class(&ce TSRMLS_CC);
+    zend_class_implements(riak_output_object_list_ce TSRMLS_CC, 3, spl_ce_ArrayAccess, spl_ce_Aggregate, spl_ce_Countable);
+    zend_declare_property_null(riak_output_object_list_ce, "objects", sizeof("objects")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto void Riak\ObjectList->__construct()
+Creates a new RiakObjectList */
+PHP_METHOD(Riak_Object_List, __construct)
+{
+    zval* zobjects;
+    // Start with an empty array
+    MAKE_STD_ZVAL(zobjects);
+    object_init_ex(zobjects, spl_ce_ArrayObject);
+    zend_update_property(riak_output_object_list_ce, getThis(), "objects", sizeof("objects")-1, zobjects TSRMLS_CC);
+    zval_ptr_dtor(&zobjects);
+}
+/* }}} */
+
+/* {{{ proto Object|null Riak\ObjectList->first()
+Get the first object in this list or null if list is empty*/
+PHP_METHOD(Riak_Object_List, first)
+{
+    zval *zobjects, *ztmp, *zoffset;
+    zobjects = zend_read_property(riak_output_object_list_ce, getThis(), "objects", sizeof("objects")-1, 1 TSRMLS_CC);
+
+    MAKE_STD_ZVAL(zoffset);
+    ZVAL_LONG(zoffset, 0);
+    MAKE_STD_ZVAL(ztmp);
+    RIAK_CALL_METHOD1(Riak_Object_List, offsetExists, ztmp, getThis(), zoffset);
+    RETVAL_NULL();
+    if (Z_TYPE_P(ztmp) == IS_BOOL && Z_BVAL_P(ztmp)) {
+        // Read offset 0
+        zval_ptr_dtor(&ztmp);
+        ztmp = NULL;
+        zend_call_method_with_1_params(&zobjects, spl_ce_ArrayObject, NULL, "offsetget", &ztmp, zoffset);
+        RETVAL_ZVAL(ztmp, 0, 1);
+    } else {
+        zval_ptr_dtor(&ztmp);
+        zend_call_method_with_0_params(&zobjects, spl_ce_ArrayObject, NULL, "getiterator", &ztmp);
+        if (Z_TYPE_P(ztmp) == IS_OBJECT) {
+            zval zvalidname, zcurrname, *zvalid;
+            ZVAL_STRING(&zvalidname, "valid", 0);
+            ZVAL_STRING(&zcurrname, "current", 0);
+            MAKE_STD_ZVAL(zvalid);
+            call_user_function(NULL, &ztmp, &zvalidname, zvalid, 0, NULL TSRMLS_CC);
+            if (Z_TYPE_P(zvalid) == IS_BOOL && Z_BVAL_P(zvalid)) {
+                zval *zresult;
+                MAKE_STD_ZVAL(zresult);
+                call_user_function(NULL, &ztmp, &zcurrname, zresult, 0, NULL TSRMLS_CC);
+                if (Z_TYPE_P(zresult) == IS_OBJECT) {
+                    RETVAL_ZVAL(zresult, 0, 1);
+                }
+            }
+            zval_ptr_dtor(&zvalid);
+        }
+        zval_ptr_dtor(&ztmp);
+    }
+    zval_ptr_dtor(&zoffset);
+}
+/* }}} */
+
+
+/* {{{ proto Object|null Riak\ObjectList->last()
+Get the last object in this list or null if list is empty*/
+PHP_METHOD(Riak_Object_List, last)
+{
+    zval *zList, *zArray, **zObject;
+
+    zList = zend_read_property(riak_output_object_list_ce, getThis(), "objects", sizeof("objects")-1, 1 TSRMLS_CC);
+
+    zend_call_method_with_0_params(&zList, NULL, NULL, "getArrayCopy", &zArray);
+    zend_hash_internal_pointer_end(Z_ARRVAL_P(zArray));
+
+    if (zend_hash_get_current_data(Z_ARRVAL_P(zArray), (void **) &zObject) == FAILURE) {
+        RETVAL_NULL();
+    } else {
+        RETVAL_ZVAL(*zObject, 1, 0);
+    }
+    zval_ptr_dtor(&zArray);
+}
+/* }}} */
+
+/* {{{ proto bool Riak\ObjectList->isEmpty()
+Is the list empty */
+PHP_METHOD(Riak_Object_List, isEmpty)
+{
+    zval *zobjects, *zcount;
+    zobjects = zend_read_property(riak_output_object_list_ce, getThis(), "objects", sizeof("objects")-1, 1 TSRMLS_CC);
+    zend_call_method_with_0_params(&zobjects, spl_ce_ArrayObject, NULL, "count", &zcount);
+    if (Z_TYPE_P(zcount) == IS_LONG && Z_LVAL_P(zcount) > 0) {
+        RETVAL_BOOL(0);
+    } else {
+        RETVAL_BOOL(1);
+    }
+    zval_ptr_dtor(&zcount);
+}
+/* }}} */
+
+/* {{{ proto bool Riak\ObjectList->offsetExists($offset)
+Whether a offset exists */
+PHP_METHOD(Riak_Object_List, offsetExists)
+{
+    zval *zoffset, *zobjects, *zresult;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zoffset) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    zobjects = zend_read_property(riak_output_object_list_ce, getThis(), "objects", sizeof("objects")-1, 1 TSRMLS_CC);
+    zend_call_method_with_1_params(&zobjects, spl_ce_ArrayObject, NULL, "offsetexists", &zresult, zoffset);
+    RETURN_ZVAL(zresult, 0, 1);
+}
+/* }}} */
+
+/* {{{ proto Object Riak\ObjectList->offsetGet($offset)
+retrieve an object at offset */
+PHP_METHOD(Riak_Object_List, offsetGet)
+{
+    zval *zoffset, *zobjects, *zresult;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zoffset) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    zobjects = zend_read_property(riak_output_object_list_ce, getThis(), "objects", sizeof("objects")-1, 1 TSRMLS_CC);
+    zend_call_method_with_1_params(&zobjects, spl_ce_ArrayObject, NULL, "offsetget", &zresult, zoffset);
+    RETURN_ZVAL(zresult, 0, 1);
+}
+/* }}} */
+
+/* {{{ proto void Riak\ObjectList->offsetGet($offset)
+Set an object at given offset */
+PHP_METHOD(Riak_Object_List, offsetSet)
+{
+    zval *zoffset, *zvalue, *zobjects;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zO", &zoffset, &zvalue, riak_object_ce) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    zobjects = zend_read_property(riak_output_object_list_ce, getThis(), "objects", sizeof("objects")-1, 1 TSRMLS_CC);
+    zend_call_method_with_2_params(&zobjects, spl_ce_ArrayObject, NULL, "offsetset", NULL, zoffset, zvalue);
+}
+
+/* }}} */
+
+/* {{{ proto void Riak\ObjectList->offsetUnset($offset)
+Removes an object at offset from list */
+PHP_METHOD(Riak_Object_List, offsetUnset)
+{
+    zval *zoffset, *zobjects;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zoffset) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    zobjects = zend_read_property(riak_output_object_list_ce, getThis(), "objects", sizeof("objects")-1, 1 TSRMLS_CC);
+    zend_call_method_with_1_params(&zobjects, spl_ce_ArrayObject, NULL, "offsetunset", NULL, zoffset);
+}
+/* }}} */
+
+/* {{{ proto int Riak\ObjectList->count()
+How many objects in the list */
+PHP_METHOD(Riak_Object_List, count)
+{
+    zval *zobjects, *zresult;
+    zobjects = zend_read_property(riak_output_object_list_ce, getThis(), "objects", sizeof("objects")-1, 1 TSRMLS_CC);
+    zend_call_method_with_0_params(&zobjects, spl_ce_ArrayObject, NULL, "count", &zresult);
+    RETURN_ZVAL(zresult, 0, 1);
+}
+/* }}} */
+
+/* {{{ proto Traversable Riak\ObjectList->getIterator()
+Retrieve an external iterator */
+PHP_METHOD(Riak_Object_List, getIterator)
+{
+    zval *zobjects, *zresult;
+    zobjects = zend_read_property(riak_output_object_list_ce, getThis(), "objects", sizeof("objects")-1, 1 TSRMLS_CC);
+    zend_call_method_with_0_params(&zobjects, spl_ce_ArrayObject, NULL, "getiterator", &zresult);
+    RETURN_ZVAL(zresult, 0, 1);
+}
+/* }}} */
diff --git a/riak/object_list.h b/riak/object_list.h
new file mode 100644
index 0000000..18eaa17
--- /dev/null
+++ b/riak/object_list.h
@@ -0,0 +1,38 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_OUTPUT__OBJECT_LIST__H__
+#define RIAK_OUTPUT__OBJECT_LIST__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_output_object_list_ce;
+
+void riak_output_object_list_init(TSRMLS_D);
+
+PHP_METHOD(Riak_Object_List, __construct);
+PHP_METHOD(Riak_Object_List, first);
+PHP_METHOD(Riak_Object_List, last);
+PHP_METHOD(Riak_Object_List, isEmpty);
+PHP_METHOD(Riak_Object_List, offsetExists);
+PHP_METHOD(Riak_Object_List, offsetGet);
+PHP_METHOD(Riak_Object_List, offsetSet);
+PHP_METHOD(Riak_Object_List, offsetUnset);
+PHP_METHOD(Riak_Object_List, count);
+PHP_METHOD(Riak_Object_List, getIterator);
+
+
+#endif //RIAK_OUTPUT__OBJECT_LIST__H__
diff --git a/riak/output/conflict_resolver.c b/riak/output/conflict_resolver.c
new file mode 100644
index 0000000..338672a
--- /dev/null
+++ b/riak/output/conflict_resolver.c
@@ -0,0 +1,35 @@
+/*
+   Copyright 2013: Kaspar Pedersen
+
+   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.
+*/
+
+#include "conflict_resolver.h"
+
+zend_class_entry *riak_output_conflict_resolver_ce;
+
+RIAK_OUTPUT_CONFLICT_RESOLVER_ARG_INFO_EXEC(arginfo_conflict_resolver_resolve)
+
+static zend_function_entry riak_conflict_resolver_methods[] = {
+    ZEND_ABSTRACT_ME(Riak_Output_ConflictResolver, resolve, arginfo_conflict_resolver_resolve)
+    {NULL, NULL, NULL}
+};
+
+void riak_output_conflict_resolver_init(TSRMLS_D)/* {{{ */
+{
+    zend_class_entry ce;
+
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Output", "ConflictResolver", riak_conflict_resolver_methods);
+    riak_output_conflict_resolver_ce = zend_register_internal_interface(&ce TSRMLS_CC);
+}
+/* }}} */
diff --git a/riak/output/conflict_resolver.h b/riak/output/conflict_resolver.h
new file mode 100644
index 0000000..9632d0c
--- /dev/null
+++ b/riak/output/conflict_resolver.h
@@ -0,0 +1,34 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_OUTPUT__CONFLICT_RESOLVER__H__
+#define RIAK_OUTPUT__CONFLICT_RESOLVER__H__
+
+#include "php_riak_internal.h"
+
+
+#define RIAK_OUTPUT_CONFLICT_RESOLVER_ARG_INFO_EXEC(name) \
+    ZEND_BEGIN_ARG_INFO_EX(name, 0, ZEND_RETURN_VALUE, 1) \
+       ZEND_ARG_OBJ_INFO(0, objects, Riak\\ObjectList, 0) \
+   ZEND_END_ARG_INFO();
+
+PHP_METHOD(Riak_Output_ConflictResolver, resolve);
+
+extern zend_class_entry *riak_output_conflict_resolver_ce;
+
+void riak_output_conflict_resolver_init(TSRMLS_D);
+
+#endif //RIAK_OUTPUT__CONFLICT_RESOLVER__H__
diff --git a/riak/output/get_output.c b/riak/output/get_output.c
new file mode 100644
index 0000000..0c1b3d0
--- /dev/null
+++ b/riak/output/get_output.c
@@ -0,0 +1,64 @@
+/*
+   Copyright 2013: Kaspar Pedersen
+
+   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.
+*/
+
+#include "get_output.h"
+#include "output.h"
+
+zend_class_entry *riak_get_output_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_get_output_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_get_output_methods[] = {
+    PHP_ME(Riak_Output_GetOutput, isUnchanged, arginfo_riak_get_output_noargs, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+void riak_output_get_output_init(TSRMLS_D)/* {{{ */
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Output", "GetOutput", riak_get_output_methods);
+    riak_get_output_ce = zend_register_internal_class_ex(&ce, riak_output_ce, NULL TSRMLS_CC);
+    zend_declare_property_null(riak_get_output_ce, "unchanged", sizeof("unchanged")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+}
+/* }}} */
+
+zval *get_output_from_riack_get_object(riack_get_object* getobj, zval* zkey TSRMLS_DC) /* {{{ */
+{
+    zval *zoutput;
+    MAKE_STD_ZVAL(zoutput);
+    object_init_ex(zoutput, riak_get_output_ce);
+    if (getobj->unchanged_present) {
+        zend_update_property_bool(riak_get_output_ce, zoutput, "unchanged", sizeof("unchanged")-1, getobj->unchanged TSRMLS_CC);
+    }
+    riak_set_output_properties(zoutput, zkey, &getobj->object TSRMLS_CC);
+    return zoutput;
+}
+/* }}} */
+
+
+/* {{{ proto bool|null Riak\Output\GetOutput->isUnchanged()
+Is unchanged */
+PHP_METHOD(Riak_Output_GetOutput, isUnchanged)
+{
+    zval* zunc = zend_read_property(riak_get_output_ce, getThis(), "unchanged", sizeof("unchanged")-1, 1 TSRMLS_CC);
+    if (Z_TYPE_P(zunc) == IS_BOOL) {
+        RETURN_BOOL(Z_BVAL_P(zunc));
+    }
+    RETURN_BOOL(0);
+}
+/* }}} */
+
diff --git a/riak/output/get_output.h b/riak/output/get_output.h
new file mode 100644
index 0000000..059e5f3
--- /dev/null
+++ b/riak/output/get_output.h
@@ -0,0 +1,29 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_OUTPUT__GET_OUTPUT__H__
+#define RIAK_OUTPUT__GET_OUTPUT__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_get_output_ce;
+
+void riak_output_get_output_init(TSRMLS_D);
+zval *get_output_from_riack_get_object(riack_get_object* getobj, zval* zkey TSRMLS_DC);
+
+PHP_METHOD(Riak_Output_GetOutput, isUnchanged);
+
+#endif //RIAK_OUTPUT__GET_OUTPUT__H__
diff --git a/riak/output/index_output.c b/riak/output/index_output.c
new file mode 100644
index 0000000..96e0450
--- /dev/null
+++ b/riak/output/index_output.c
@@ -0,0 +1,123 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "index_output.h"
+#include "output.h"
+#include "index_result_list.h"
+#include "index_result.h"
+#include "../exception/exception.h"
+
+zend_class_entry *riak_index_output_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_output_index_output_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_output_index_output_ctor, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, indexOutput)
+    ZEND_ARG_INFO(0, continuation)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_output_index_output_methods[] = {
+    PHP_ME(Riak_Index_Output, __construct, arginfo_riak_output_index_output_ctor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+    PHP_ME(Riak_Index_Output, getContinuation, arginfo_riak_output_index_output_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Index_Output, getResultList, arginfo_riak_output_index_output_noargs, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+
+void riak_output_index_output_init(TSRMLS_D)
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Output", "IndexOutput", riak_output_index_output_methods);
+    riak_index_output_ce = zend_register_internal_class(&ce TSRMLS_CC);
+
+    zend_declare_property_null(riak_index_output_ce, "result", sizeof("result")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_index_output_ce, "continuation", sizeof("continuation")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+}
+
+zval *get_index_output_from_riack_string_list(riack_string_list *result_keys TSRMLS_DC)
+{
+    zval *zresult;
+    size_t i;
+    MAKE_STD_ZVAL(zresult);
+    object_init_ex(zresult, riak_index_result_list_ce);
+    RIAK_CALL_METHOD(Riak_Index_Result_List, __construct, NULL, zresult);
+    for (i=0; i<result_keys->string_count; ++i) {
+        zval *zcurrent, *zkey, *zoffset;
+        MAKE_STD_ZVAL(zoffset);
+        ZVAL_LONG(zoffset, i);
+
+        MAKE_STD_ZVAL(zkey);
+        ZVAL_STRINGL(zkey, result_keys->strings[i].value, result_keys->strings[i].len, 1);
+
+        MAKE_STD_ZVAL(zcurrent);
+        object_init_ex(zcurrent, riak_index_result_ce);
+        RIAK_CALL_METHOD1(Riak_Output_IndexResult, __construct, NULL, zcurrent, zkey);
+
+        RIAK_CALL_METHOD2(Riak_Index_Result_List, offsetSet, NULL, zresult, zoffset, zcurrent);
+        zval_ptr_dtor(&zoffset);
+        zval_ptr_dtor(&zkey);
+        zval_ptr_dtor(&zcurrent);
+    }
+    return zresult;
+}
+
+zval *riak_index_output_from_string_list_and_continuation(riack_string_list *result_keys, riack_string *continuation TSRMLS_DC) {
+    zval* zlist, *zresult;
+    MAKE_STD_ZVAL(zresult);
+    object_init_ex(zresult, riak_index_output_ce);
+
+    zlist = get_index_output_from_riack_string_list(result_keys TSRMLS_CC);
+    if (continuation && RSTR_HAS_CONTENT((*continuation))) {
+        zval *zcontinuation;
+        MAKE_STD_ZVAL(zcontinuation);
+        ZVAL_STRINGL(zcontinuation, continuation->value, continuation->len, 1);
+        RIAK_CALL_METHOD2(Riak_Index_Output, __construct, NULL, zresult, zlist, zcontinuation);
+        zval_ptr_dtor(&zcontinuation);
+    } else {
+        RIAK_CALL_METHOD1(Riak_Index_Output, __construct, NULL, zresult, zlist);
+    }
+    zval_ptr_dtor(&zlist);
+    return zresult;
+}
+
+PHP_METHOD(Riak_Index_Output, __construct)
+{
+    char *continuation;
+    int continuation_len;
+    zval *zresultlist;
+    continuation = 0;
+    continuation_len = 0;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|s", &zresultlist, riak_index_result_list_ce,
+                              &continuation, &continuation_len) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    if (continuation && continuation_len > 0) {
+        zend_update_property_stringl(riak_index_output_ce, getThis(), "continuation",
+                                     sizeof("continuation")-1, continuation, continuation_len TSRMLS_CC);
+    }
+    zend_update_property(riak_index_output_ce, getThis(), "result", sizeof("result")-1, zresultlist TSRMLS_CC);
+}
+
+PHP_METHOD(Riak_Index_Output, getResultList)
+{
+    RIAK_GETTER_OBJECT(riak_index_output_ce, "result")
+}
+
+PHP_METHOD(Riak_Index_Output, getContinuation)
+{
+    RIAK_GETTER_STRING(riak_index_output_ce, "continuation");
+}
diff --git a/riak/output/index_output.h b/riak/output/index_output.h
new file mode 100644
index 0000000..29dbfda
--- /dev/null
+++ b/riak/output/index_output.h
@@ -0,0 +1,32 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_OUTPUT__INDEX_OUTPUT__H__
+#define RIAK_OUTPUT__INDEX_OUTPUT__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_index_output_ce;
+
+void riak_output_index_output_init(TSRMLS_D);
+
+zval *riak_index_output_from_string_list_and_continuation(riack_string_list *result_keys, riack_string *continuation TSRMLS_DC);
+
+PHP_METHOD(Riak_Index_Output, __construct);
+PHP_METHOD(Riak_Index_Output, getResultList);
+PHP_METHOD(Riak_Index_Output, getContinuation);
+
+#endif //RIAK_OUTPUT__INDEX_OUTPUT__H__
diff --git a/riak/output/index_result.c b/riak/output/index_result.c
new file mode 100644
index 0000000..342170d
--- /dev/null
+++ b/riak/output/index_result.c
@@ -0,0 +1,64 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "index_result.h"
+#include "../exception/exception.h"
+
+zend_class_entry *riak_index_result_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_output_index_result_ctor, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, key)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_output_index_result_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_output_index_result_methods[] = {
+    PHP_ME(Riak_Output_IndexResult, __construct, arginfo_riak_output_index_result_ctor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+    PHP_ME(Riak_Output_IndexResult, getKey, arginfo_riak_output_index_result_noargs, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+
+void riak_output_index_result_init(TSRMLS_D)
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Output", "IndexResult", riak_output_index_result_methods);
+    riak_index_result_ce = zend_register_internal_class(&ce TSRMLS_CC);
+    zend_declare_property_null(riak_index_result_ce, "key", sizeof("key")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+}
+
+/* {{{ proto void Riak\Output\IndexResult->__construct(string $key)
+Get list of returned objects */
+PHP_METHOD(Riak_Output_IndexResult, __construct)
+{
+    char *key;
+    int key_len;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &key, &key_len) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    zend_update_property_stringl(riak_index_result_ce, getThis(), "key", sizeof("key")-1, key, key_len TSRMLS_CC);
+}
+/* }}} */
+
+
+/* {{{ proto Riak\Output\IndexResult Riak\Output\IndexResult->getKey()
+Get key */
+PHP_METHOD(Riak_Output_IndexResult, getKey)
+{
+    RIAK_GETTER_STRING(riak_index_result_ce, "key")
+}
+/* }}} */
diff --git a/riak/output/index_result.h b/riak/output/index_result.h
new file mode 100644
index 0000000..18e96f6
--- /dev/null
+++ b/riak/output/index_result.h
@@ -0,0 +1,29 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_OUTPUT__INDEX_RESULT__H__
+#define RIAK_OUTPUT__INDEX_RESULT__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_index_result_ce;
+
+void riak_output_index_result_init(TSRMLS_D);
+
+PHP_METHOD(Riak_Output_IndexResult, __construct);
+PHP_METHOD(Riak_Output_IndexResult, getKey);
+
+#endif //RIAK_OUTPUT__INDEX_RESULT__H__
diff --git a/riak/output/index_result_list.c b/riak/output/index_result_list.c
new file mode 100644
index 0000000..7bd7c49
--- /dev/null
+++ b/riak/output/index_result_list.c
@@ -0,0 +1,153 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "index_result_list.h"
+#include "index_result.h"
+#include "../exception/exception.h"
+#include <zend_interfaces.h>
+#include <ext/spl/spl_iterators.h>
+#include <ext/spl/spl_array.h>
+
+zend_class_entry *riak_index_result_list_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_output_index_result_ctor, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, key)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_output_index_result_offsetexists, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, offset)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_output_index_result_offsetset, 0, ZEND_RETURN_VALUE, 2)
+    ZEND_ARG_INFO(0, offset)
+    ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_output_index_result_list_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+
+static zend_function_entry riak_output_index_result_list_methods[] = {
+    PHP_ME(Riak_Index_Result_List, __construct, arginfo_riak_output_index_result_list_noargs, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+
+    PHP_ME(Riak_Index_Result_List, offsetExists, arginfo_riak_output_index_result_offsetexists, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Index_Result_List, offsetGet, arginfo_riak_output_index_result_offsetexists, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Index_Result_List, offsetSet, arginfo_riak_output_index_result_offsetset, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Index_Result_List, offsetUnset, arginfo_riak_output_index_result_offsetexists, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Index_Result_List, count, arginfo_riak_output_index_result_list_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Index_Result_List, getIterator, arginfo_riak_output_index_result_list_noargs, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+
+void riak_output_index_result_list_init(TSRMLS_D)
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Output", "IndexResultList", riak_output_index_result_list_methods);
+    riak_index_result_list_ce = zend_register_internal_class(&ce TSRMLS_CC);
+    zend_class_implements(riak_index_result_list_ce TSRMLS_CC, 3, spl_ce_ArrayAccess, spl_ce_Aggregate, spl_ce_Countable);
+
+    zend_declare_property_null(riak_index_result_list_ce, "resultList", sizeof("resultList")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+}
+
+PHP_METHOD(Riak_Index_Result_List, __construct)
+{
+    zval* zresultlist;
+    MAKE_STD_ZVAL(zresultlist);
+    object_init_ex(zresultlist, spl_ce_ArrayObject);
+    zend_update_property(riak_index_result_list_ce, getThis(), "resultList", sizeof("resultList")-1, zresultlist TSRMLS_CC);
+    zval_ptr_dtor(&zresultlist);
+}
+
+/* {{{ proto bool Riak\Output\IndexResultList->offsetExists($offset)
+Does the offset exists */
+PHP_METHOD(Riak_Index_Result_List, offsetExists)
+{
+    zval *zoffset, *zresultlist, *zresult;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zoffset) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    zresultlist = zend_read_property(riak_index_result_list_ce, getThis(), "resultList", sizeof("resultList")-1, 1 TSRMLS_CC);
+    zend_call_method_with_1_params(&zresultlist, spl_ce_ArrayObject, NULL, "offsetexists", &zresult, zoffset);
+    RETURN_ZVAL(zresult, 0, 1);
+}
+/* }}} */
+
+/* {{{ proto IndexResult Riak\Output\IndexResultList->offsetGet($offset)
+retrieve an object at offset */
+PHP_METHOD(Riak_Index_Result_List, offsetGet)
+{
+    zval *zoffset, *zresultlist, *zresult;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zoffset) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    zresultlist = zend_read_property(riak_index_result_list_ce, getThis(), "resultList", sizeof("resultList")-1, 1 TSRMLS_CC);
+    zend_call_method_with_1_params(&zresultlist, spl_ce_ArrayObject, NULL, "offsetget", &zresult, zoffset);
+    RETURN_ZVAL(zresult, 0, 1);
+}
+/* }}} */
+
+/* {{{ proto void Riak\Output\IndexResultList->offsetSet($offset, IndexResult $value)
+Set an IndexResult at given offset */
+PHP_METHOD(Riak_Index_Result_List, offsetSet)
+{
+    zval *zoffset, *zvalue, *zresultlist;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zO", &zoffset, &zvalue, riak_index_result_ce) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    zresultlist = zend_read_property(riak_index_result_list_ce, getThis(), "resultList", sizeof("resultList")-1, 1 TSRMLS_CC);
+    zend_call_method_with_2_params(&zresultlist, spl_ce_ArrayObject, NULL, "offsetset", NULL, zoffset, zvalue);
+}
+/* }}} */
+
+/* {{{ proto void Riak\Output\IndexResultList->offsetUnset($offset)
+Removes a result at offset from list */
+PHP_METHOD(Riak_Index_Result_List, offsetUnset)
+{
+    zval *zoffset, *zresultlist;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zoffset) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    zresultlist = zend_read_property(riak_index_result_list_ce, getThis(), "resultList", sizeof("resultList")-1, 1 TSRMLS_CC);
+    zend_call_method_with_1_params(&zresultlist, spl_ce_ArrayObject, NULL, "offsetunset", NULL, zoffset);
+}
+/* }}} */
+
+/* {{{ proto int Riak\Output\IndexResultList->count()
+How many objects in the list */
+PHP_METHOD(Riak_Index_Result_List, count)
+{
+    zval *zresultlist, *zresult;
+    zresultlist = zend_read_property(riak_index_result_list_ce, getThis(), "resultList", sizeof("resultList")-1, 1 TSRMLS_CC);
+    zend_call_method_with_0_params(&zresultlist, spl_ce_ArrayObject, NULL, "count", &zresult);
+    RETURN_ZVAL(zresult, 0, 1);
+}
+/* }}} */
+
+/* {{{ proto TraversableRiak\Output\IndexResultList->getIterator()
+Retrieve an external iterator */
+PHP_METHOD(Riak_Index_Result_List, getIterator)
+{
+    zval *zresultlist, *zresult;
+    zresultlist = zend_read_property(riak_index_result_list_ce, getThis(), "resultList", sizeof("resultList")-1, 1 TSRMLS_CC);
+    zend_call_method_with_0_params(&zresultlist, spl_ce_ArrayObject, NULL, "getiterator", &zresult);
+    RETURN_ZVAL(zresult, 0, 1);
+}
+/* }}} */
diff --git a/riak/output/index_result_list.h b/riak/output/index_result_list.h
new file mode 100644
index 0000000..240922b
--- /dev/null
+++ b/riak/output/index_result_list.h
@@ -0,0 +1,35 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_OUTPUT__INDEX_RESULT_LIST__H__
+#define RIAK_OUTPUT__INDEX_RESULT_LIST__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_index_result_list_ce;
+
+void riak_output_index_result_list_init(TSRMLS_D);
+
+PHP_METHOD(Riak_Index_Result_List, __construct);
+PHP_METHOD(Riak_Index_Result_List, offsetExists);
+PHP_METHOD(Riak_Index_Result_List, offsetGet);
+PHP_METHOD(Riak_Index_Result_List, offsetSet);
+PHP_METHOD(Riak_Index_Result_List, offsetUnset);
+PHP_METHOD(Riak_Index_Result_List, count);
+PHP_METHOD(Riak_Index_Result_List, getIterator);
+
+
+#endif //RIAK_OUTPUT__INDEX_RESULT_LIST__H__
diff --git a/riak/output/key_stream_output.c b/riak/output/key_stream_output.c
new file mode 100644
index 0000000..0507787
--- /dev/null
+++ b/riak/output/key_stream_output.c
@@ -0,0 +1,36 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "key_stream_output.h"
+
+zend_class_entry *riak_key_streamer_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_keystreamer_key, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, key)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_keystreamer_methods[] = {
+    ZEND_ABSTRACT_ME(RiakKeyStreamer, process, arginfo_keystreamer_key)
+    {NULL, NULL, NULL}
+};
+
+void riak_output_stream_output_init(TSRMLS_D)/* {{{ */
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Output", "KeyStreamOutput", riak_keystreamer_methods);
+    riak_key_streamer_ce = zend_register_internal_interface(&ce TSRMLS_CC);
+}
+/* }}} */
+
diff --git a/riak/output/key_stream_output.h b/riak/output/key_stream_output.h
new file mode 100644
index 0000000..101f3e5
--- /dev/null
+++ b/riak/output/key_stream_output.h
@@ -0,0 +1,26 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK__OUTPUT__KEY_STREAMING_OUTPUT__H__
+#define RIAK__OUTPUT__KEY_STREAMING_OUTPUT__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_key_streamer_ce;
+
+void riak_output_stream_output_init(TSRMLS_D);
+
+#endif
diff --git a/riak/output/output.c b/riak/output/output.c
new file mode 100644
index 0000000..9f16c08
--- /dev/null
+++ b/riak/output/output.c
@@ -0,0 +1,239 @@
+/*
+   Copyright 2013: Kaspar Pedersen
+
+   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.
+*/
+
+#include "output.h"
+#include "riak/object.h"
+#include "riak/object_list.h"
+#include "riak/input/get_input.h"
+#include "riak/input/put_input.h"
+#include "get_output.h"
+#include "put_output.h"
+#include "riak/exception/exception.h"
+#include "zend_interfaces.h"
+
+zend_class_entry *riak_output_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_output_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_output_methods[] = {
+    PHP_ME(Riak_Output_Output, getObjectList, arginfo_riak_output_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Output_Output, getVClock, arginfo_riak_output_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Output_Output, getKey, arginfo_riak_output_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Output_Output, hasSiblings, arginfo_riak_output_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Output_Output, hasObject, arginfo_riak_output_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Output_Output, getObject, arginfo_riak_output_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Output_Output, getFirstObject, arginfo_riak_output_noargs, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+
+void riak_output_init(TSRMLS_D)/* {{{ */
+{
+    zend_class_entry ce;
+
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Output", "Output", riak_output_methods);
+    riak_output_ce = zend_register_internal_class(&ce TSRMLS_CC);
+
+    zend_declare_property_null(riak_output_ce, "vClock", sizeof("vClock")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_output_ce, "objectList", sizeof("objectList")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_output_ce, "key", sizeof("key")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_output_ce, "bucket", sizeof("bucket")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_output_ce, "conflictResolver", sizeof("conflictResolver")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+}
+/* }}} */
+
+void riak_set_output_properties(zval* zoutput, zval* zkey, riack_object* obj TSRMLS_DC) /* {{{ */
+{
+    size_t content_cnt, i;
+    zval *zobjectlist;
+    if (obj->vclock.len > 0) {
+        zend_update_property_stringl(riak_output_ce, zoutput, "vClock", sizeof("vClock")-1,
+                                     (char*)obj->vclock.clock, obj->vclock.len TSRMLS_CC);
+    }
+    if (Z_TYPE_P(zkey) == IS_STRING) {
+        zend_update_property_stringl(riak_output_ce, zoutput, "key", sizeof("key")-1,
+                                     Z_STRVAL_P(zkey), Z_STRLEN_P(zkey) TSRMLS_CC);
+    }
+    MAKE_STD_ZVAL(zobjectlist);
+    object_init_ex(zobjectlist, riak_output_object_list_ce);
+    RIAK_CALL_METHOD(Riak_Object_List, __construct, NULL, zobjectlist);
+    content_cnt = obj->content_count;
+    for (i=0; i<content_cnt; ++i) {
+        // Create a new Riak\Object for each content
+        zval *zobject, *zoffset;
+        MAKE_STD_ZVAL(zobject);
+        object_init_ex(zobject, riak_object_ce);
+
+        if (Z_TYPE_P(zkey) != IS_NULL) {
+            RIAK_CALL_METHOD1(RiakObject, __construct, NULL, zobject, zkey);
+        } else {
+            RIAK_CALL_METHOD(RiakObject, __construct, NULL, zobject);
+        }
+
+        if (obj->vclock.len > 0) {
+            zend_update_property_stringl(riak_object_ce, zobject, "vClock", sizeof("vClock")-1,
+                                     (char*)obj->vclock.clock, obj->vclock.len TSRMLS_CC);
+        }
+
+        set_object_from_riak_content(zobject, &obj->content[i] TSRMLS_CC);
+
+        MAKE_STD_ZVAL(zoffset);
+        ZVAL_LONG(zoffset, i);
+        RIAK_CALL_METHOD2(Riak_Object_List, offsetSet, NULL, zobjectlist, zoffset, zobject);
+        zval_ptr_dtor(&zobject);
+        zval_ptr_dtor(&zoffset);
+    }
+    zend_update_property(riak_output_ce, zoutput, "objectList", sizeof("objectList")-1, zobjectlist TSRMLS_CC);
+    zval_ptr_dtor(&zobjectlist);
+}
+/* }}} */
+
+/*************************************************************
+* Implementation: Riak\Output\Output
+*************************************************************/
+
+/* {{{ proto Riak\Output\ObjectList Riak\Output\Output->getObjectList()
+Get list of returned objects */
+PHP_METHOD(Riak_Output_Output, getObjectList)
+{
+    RIAK_GETTER_OBJECT(riak_output_ce, "objectList")
+}
+/* }}} */
+
+/* {{{ proto string|null Riak\Output\Output->getVClock()
+Get vclock from riak if present */
+PHP_METHOD(Riak_Output_Output, getVClock)
+{
+    RIAK_GETTER_STRING(riak_output_ce, "vClock")
+}
+/* }}} */
+
+/* {{{ proto string|null Riak\Output\Output->getKey()
+Get key if present */
+PHP_METHOD(Riak_Output_Output, getKey)
+{
+    RIAK_GETTER_STRING(riak_output_ce, "key")
+}
+/* }}} */
+
+
+/* {{{ proto bool|null Riak\Output\Output->hasSiblings()
+Does this output have multiple objects */
+PHP_METHOD(Riak_Output_Output, hasSiblings)
+{
+    zval* zlist = zend_read_property(riak_output_ce, getThis(), "objectList", sizeof("objectList")-1, 1 TSRMLS_CC);
+    RETVAL_BOOL(0);
+    if (Z_TYPE_P(zlist) == IS_OBJECT) {
+        zval *zcount;
+        MAKE_STD_ZVAL(zcount);
+        RIAK_CALL_METHOD(Riak_Object_List, count, zcount, zlist);
+        if (Z_TYPE_P(zcount) == IS_LONG && Z_LVAL_P(zcount) > 1) {
+            RETVAL_BOOL(1);
+        }
+        zval_ptr_dtor(&zcount);
+    }
+}
+/* }}} */
+
+/* {{{ proto bool Riak\Output\Output->hasObject()
+Does this output have atleast one object */
+PHP_METHOD(Riak_Output_Output, hasObject)
+{
+    zval* zlist = zend_read_property(riak_output_ce, getThis(), "objectList", sizeof("objectList")-1, 1 TSRMLS_CC);
+    RETVAL_BOOL(0);
+    if (Z_TYPE_P(zlist) == IS_OBJECT) {
+        zval *zisempty;
+        RETVAL_BOOL(1);
+        MAKE_STD_ZVAL(zisempty);
+        RIAK_CALL_METHOD(Riak_Object_List, isEmpty, zisempty, zlist);
+        if (Z_TYPE_P(zisempty) == IS_BOOL && Z_BVAL_P(zisempty)) {
+            RETVAL_BOOL(0);
+        }
+        zval_ptr_dtor(&zisempty);
+    }
+}
+/* }}} */
+
+/* {{{ proto Riak\Object|null Riak\Output\Output->getFirstObject()
+Get first object in objectlist */
+PHP_METHOD(Riak_Output_Output, getFirstObject)
+{
+    zval* zlist = zend_read_property(riak_output_ce, getThis(), "objectList", sizeof("objectList")-1, 1 TSRMLS_CC);
+    if (Z_TYPE_P(zlist) == IS_OBJECT) {
+        zval* zresult;
+        MAKE_STD_ZVAL(zresult);
+        RIAK_CALL_METHOD(Riak_Object_List, first, zresult, zlist);
+        RETURN_ZVAL(zresult, 0, 1);
+    }
+    RETURN_NULL();
+}
+/* }}} */
+
+/* {{{ proto Riak\Object|null Riak\Output\Output->getObject()
+Retrieves a unique riak object */
+PHP_METHOD(Riak_Output_Output, getObject)
+{
+    zval *zCount, *zResolver, *zObjectList, *zObject, *zBucket, *zVClock, *zPutInput, *zOutput, *zBool;
+
+    zObjectList = zend_read_property(riak_output_ce, getThis(), "objectList", sizeof("objectList")-1, 1 TSRMLS_CC);
+    if (Z_TYPE_P(zObjectList) != IS_OBJECT) {
+        RETURN_NULL();
+    }
+
+    zend_call_method_with_0_params(&zObjectList, NULL, NULL, "count", &zCount);
+    if (Z_LVAL_P(zCount) == 0) {
+        zval_ptr_dtor(&zCount);
+        RETURN_NULL();
+    }
+
+    if (Z_LVAL_P(zCount) == 1) {
+        zval *zFirst;
+        zend_call_method_with_0_params(&zObjectList, NULL, NULL, "first", &zFirst);
+        zval_ptr_dtor(&zCount);
+        RETURN_ZVAL(zFirst, 0, 1);
+    }
+
+    if (Z_LVAL_P(zCount) > 1) {
+        zResolver = zend_read_property(riak_output_ce, getThis(), "conflictResolver", sizeof("conflictResolver")-1, 1 TSRMLS_CC);
+        if (Z_TYPE_P(zResolver) != IS_OBJECT) {
+            zval_ptr_dtor(&zCount);
+            zend_throw_exception(riak_nonunique_exception_ce, "GetOutput contains unresolved siblings", 500 TSRMLS_CC);
+            return;
+        }
+    }
+
+    zval_ptr_dtor(&zCount);
+    zend_call_method_with_1_params(&zResolver, NULL, NULL, "resolve", &zObject, zObjectList);
+
+    if (Z_TYPE_P(zObject) != IS_OBJECT || ! instanceof_function(Z_OBJCE_P(zObject), riak_object_ce TSRMLS_CC)) {
+        zval_ptr_dtor(&zObject);
+        zend_throw_exception(riak_unresolvedconflict_exception_ce, "Conflict resolver should return a instance of Riak\\Object", 500 TSRMLS_CC);
+        return;
+    } else {
+        zval *zObjectKey;
+        zend_call_method_with_0_params(&zObject, NULL, NULL, "getKey", &zObjectKey);
+        if (Z_TYPE_P(zObjectKey) != IS_STRING) {
+            zval_ptr_dtor(&zObject);
+            zval_ptr_dtor(&zObjectKey);
+            zend_throw_exception(riak_unresolvedconflict_exception_ce, "The resolved Riak\\Object does not contain a valid key.", 500 TSRMLS_CC);
+            return;
+        }
+        zval_ptr_dtor(&zObjectKey);
+    }
+    RETURN_ZVAL(zObject, 0, 1);
+}
+/* }}} */
diff --git a/req_outputs.h b/riak/output/output.h
similarity index 71%
rename from req_outputs.h
rename to riak/output/output.h
index cad4c1e..c788e8d 100644
--- a/req_outputs.h
+++ b/riak/output/output.h
@@ -17,25 +17,20 @@
 #ifndef RIAK_OUTPUTS__H__
 #define RIAK_OUTPUTS__H__
 
-#include <php.h>
-#include <riack.h>
+#include "php_riak_internal.h"
 
 extern zend_class_entry *riak_output_ce;
-extern zend_class_entry *riak_get_output_ce;
-extern zend_class_entry *riak_put_output_ce;
 
-void riak_req_outputs_init(TSRMLS_D);
+void riak_output_init(TSRMLS_D);
 
-zval *get_output_from_riack_get_object(struct RIACK_GET_OBJECT* getobj, zval* zkey TSRMLS_DC);
-zval *put_output_from_riack_object(struct RIACK_OBJECT* obj, zval* zkey TSRMLS_DC);
+void riak_set_output_properties(zval* zoutput, zval* zkey, riack_object* obj TSRMLS_DC);
 
 PHP_METHOD(Riak_Output_Output, getObjectList);
 PHP_METHOD(Riak_Output_Output, getVClock);
 PHP_METHOD(Riak_Output_Output, getKey);
 PHP_METHOD(Riak_Output_Output, hasSiblings);
 PHP_METHOD(Riak_Output_Output, hasObject);
+PHP_METHOD(Riak_Output_Output, getObject);
 PHP_METHOD(Riak_Output_Output, getFirstObject);
 
-PHP_METHOD(Riak_Output_GetOutput, isUnchanged);
-
 #endif
diff --git a/riak/output/put_output.c b/riak/output/put_output.c
new file mode 100644
index 0000000..0e1da28
--- /dev/null
+++ b/riak/output/put_output.c
@@ -0,0 +1,45 @@
+/*
+   Copyright 2013: Kaspar Pedersen
+
+   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.
+*/
+
+#include "put_output.h"
+#include "output.h"
+
+zend_class_entry *riak_put_output_ce;
+
+static zend_function_entry riak_put_output_methods[] = {
+    {NULL, NULL, NULL}
+};
+
+void riak_output_put_output_init(TSRMLS_D)/* {{{ */
+{
+    zend_class_entry ce;
+
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Output", "PutOutput", riak_put_output_methods);
+    riak_put_output_ce = zend_register_internal_class_ex(&ce, riak_output_ce, NULL TSRMLS_CC);
+}
+/* }}} */
+
+
+zval *put_output_from_riack_object(riack_object* obj, zval* zkey TSRMLS_DC) /* {{{ */
+{
+    zval *zoutput;
+    MAKE_STD_ZVAL(zoutput);
+    object_init_ex(zoutput, riak_put_output_ce);
+    riak_set_output_properties(zoutput, zkey, obj TSRMLS_CC);
+    return zoutput;
+}
+/* }}} */
+
diff --git a/riak/output/put_output.h b/riak/output/put_output.h
new file mode 100644
index 0000000..fdfcb89
--- /dev/null
+++ b/riak/output/put_output.h
@@ -0,0 +1,27 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_OUTPUT__PUT_OUTPUT__H__
+#define RIAK_OUTPUT__PUT_OUTPUT__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_put_output_ce;
+
+void riak_output_put_output_init(TSRMLS_D);
+zval *put_output_from_riack_object(riack_object* obj, zval* zkey TSRMLS_DC);
+
+#endif //RIAK_OUTPUT__PUT_OUTPUT__H__
diff --git a/riak/output/youngest_sibling_resolver.c b/riak/output/youngest_sibling_resolver.c
new file mode 100644
index 0000000..7c6cd14
--- /dev/null
+++ b/riak/output/youngest_sibling_resolver.c
@@ -0,0 +1,120 @@
+/*
+   Copyright 2013: Kaspar Pedersen
+
+   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.
+*/
+
+#include "zend_interfaces.h"
+#include "conflict_resolver.h"
+#include "youngest_sibling_resolver.h"
+
+zend_class_entry *riak_output_youngest_sibling_resolver_ce;
+
+RIAK_OUTPUT_CONFLICT_RESOLVER_ARG_INFO_EXEC(arginfo_youngest_sibling_resolver_resolve)
+
+static zend_function_entry riak_output_first_sibling_resolver_methods[] = {
+    PHP_ME(Riak_Output_YoungestSiblingResolver, resolve, arginfo_youngest_sibling_resolver_resolve, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+void riak_output_youngest_sibling_resolver_init(TSRMLS_D)/* {{{ */
+{
+    zend_class_entry ce;
+
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Output", "YoungestSiblingResolver", riak_output_first_sibling_resolver_methods);
+
+    riak_output_youngest_sibling_resolver_ce = zend_register_internal_class(&ce TSRMLS_CC);
+
+    zend_class_implements(riak_output_youngest_sibling_resolver_ce TSRMLS_CC, 1, riak_output_conflict_resolver_ce);
+}
+/* }}} */
+
+/* {{{ proto \Riak\Object Riak\Output\GetOutput->resolve(\Riak\ObjectList $objects) */
+PHP_METHOD(Riak_Output_YoungestSiblingResolver, resolve)
+{
+    zval *zObjects, *ziter, *zwinner;
+    long winner_ts, winner_ts_us;
+    zend_bool valid;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zObjects) == FAILURE) {
+        return;
+    }
+    zwinner = NULL;
+    winner_ts = winner_ts_us = 0;
+    zend_call_method_with_0_params(&zObjects, NULL, NULL, "getiterator", &ziter);
+    if (Z_TYPE_P(ziter) == IS_OBJECT) {
+        zval zvalidname, zcurrname, zlastmodname, zlastmodusname, znextname, zdeletedname, *zvalid;
+        ZVAL_STRING(&zvalidname, "valid", 0);
+        ZVAL_STRING(&zcurrname, "current", 0);
+        ZVAL_STRING(&znextname, "next", 0);
+        ZVAL_STRING(&zlastmodname, "getLastModified", 0);
+        ZVAL_STRING(&zlastmodusname, "getLastModifiedUSecs", 0);
+        ZVAL_STRING(&zdeletedname, "isDeleted", 0);
+        valid = 1;
+
+        while (valid) {
+            MAKE_STD_ZVAL(zvalid);
+            call_user_function(NULL, &ziter, &zvalidname, zvalid, 0, NULL TSRMLS_CC);
+            if (Z_TYPE_P(zvalid) == IS_BOOL && Z_BVAL_P(zvalid)) {
+                zval *zobject, zdummy;
+                MAKE_STD_ZVAL(zobject);
+                call_user_function(NULL, &ziter, &zcurrname, zobject, 0, NULL TSRMLS_CC);
+                if (Z_TYPE_P(zobject) == IS_OBJECT) {
+                    zval zlastmod, zlastmod_us, zdeleted;
+                    long lastmod, lastmod_us;
+                    lastmod = lastmod_us = 0;
+                    call_user_function(NULL, &zobject, &zdeletedname, &zdeleted, 0, NULL TSRMLS_CC);
+
+                    // Ignore deleted objects
+                    if (Z_TYPE(zdeleted) != IS_BOOL || Z_BVAL(zdeleted) == 0) {
+                        call_user_function(NULL, &zobject, &zlastmodname, &zlastmod, 0, NULL TSRMLS_CC);
+                        call_user_function(NULL, &zobject, &zlastmodname, &zlastmod_us, 0, NULL TSRMLS_CC);
+                        if (Z_TYPE(zlastmod) == IS_LONG) {
+                            lastmod = Z_LVAL(zlastmod);
+                        }
+                        if (Z_TYPE(zlastmod_us) == IS_LONG) {
+                            lastmod_us = Z_LVAL(zlastmod_us);
+                        }
+                        // Always set the winner if it is not set at this point
+                        // otherwise just set it if the current object is newer.
+                        if ((zwinner == NULL) ||
+                                (lastmod > winner_ts) ||
+                                ((lastmod == winner_ts) && (lastmod_us > winner_ts_us))) {
+                            winner_ts = lastmod;
+                            winner_ts_us = lastmod_us;
+                            if (zwinner != NULL) {
+                                // dtor old winner
+                                zval_ptr_dtor(&zwinner);
+                            }
+                            zwinner = zobject;
+                            // Addref to new winner so it wont get dtored
+                            zval_addref_p(zwinner);
+                        }
+                    }
+                }
+                zval_ptr_dtor(&zobject);
+                call_user_function(NULL, &ziter, &znextname, &zdummy, 0, NULL TSRMLS_CC);
+            } else {
+                valid = 0;
+            }
+            zval_ptr_dtor(&zvalid);
+        }
+    }
+    zval_ptr_dtor(&ziter);
+    if (zwinner != NULL) {
+        RETURN_ZVAL(zwinner, 0, 1);
+    } else {
+        RETURN_NULL();
+    }
+}
+
+/* }}} */
diff --git a/riak/output/youngest_sibling_resolver.h b/riak/output/youngest_sibling_resolver.h
new file mode 100644
index 0000000..b25934b
--- /dev/null
+++ b/riak/output/youngest_sibling_resolver.h
@@ -0,0 +1,28 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_OUTPUT__FIRST_SIBLING_RESOLVER__H__
+#define RIAK_OUTPUT__FIRST_SIBLING_RESOLVER__H__
+
+#include "php_riak_internal.h"
+
+PHP_METHOD(Riak_Output_YoungestSiblingResolver, resolve);
+
+extern zend_class_entry *riak_output_youngest_sibling_resolver_ce;
+
+void riak_output_youngest_sibling_resolver_init(TSRMLS_D);
+
+#endif //RIAK_OUTPUT__FIRST_SIBLING_RESOLVER__H__
diff --git a/pool.c b/riak/pool.c
similarity index 97%
rename from pool.c
rename to riak/pool.c
index 0f0ace8..11e47a0 100644
--- a/pool.c
+++ b/riak/pool.c
@@ -15,9 +15,6 @@
    limitations under the License.
 */
 #include "pool.h"
-#include "php_riak.h"
-#include <php.h>
-#include <riack.h>
 
 zend_bool ensure_connected(riak_connection *connection TSRMLS_DC) /* {{{ */
 {
@@ -44,7 +41,7 @@ zend_bool ensure_connected_init(riak_connection *connection, char* host, int hos
     result = 0;
 
     if (connection->client->sockfd <= 0) {
-        struct RIACK_CONNECTION_OPTIONS options;
+        riack_connection_options options;
         options.send_timeout_ms = RIAK_GLOBAL(send_timeout);
         options.recv_timeout_ms = RIAK_GLOBAL(recv_timeout);
         options.keep_alive_enabled = RIAK_GLOBAL(keep_alive);
@@ -58,6 +55,7 @@ zend_bool ensure_connected_init(riak_connection *connection, char* host, int hos
     } else {
         result = ensure_connected(connection TSRMLS_CC);
     }
+
     return result;
 }
 /* }}} */
@@ -81,6 +79,7 @@ zend_bool lock_pool(TSRMLS_D) /* {{{ */
     return 0;
   }
 #endif
+  return 1;
 }
 /* }}} */
 
@@ -96,12 +95,13 @@ void release_connection(riak_connection *connection TSRMLS_DC) /* {{{ */
 {
    riak_connection_pool* pool = NULL;
    RIAK_GLOBAL(open_connections)--;
+
    if (connection->persistent) {
       /* If we fail to lock we might have a stuck client, find a way to deal with this. */
       if (lock_pool(TSRMLS_C)) {
          connection->last_used_at = time(NULL);
          RIAK_GLOBAL(open_connections_persistent)--;
-         pool = pool_for_host_port(connection->client->host, 
+         pool = pool_for_host_port(connection->client->host,
             strlen(connection->client->host), connection->client->port TSRMLS_CC);
          release_connection_from_pool(pool, connection);
          unlock_pool(TSRMLS_C);
@@ -126,6 +126,7 @@ riak_connection *take_connection(char* host, int host_len, int port TSRMLS_DC) /
       entry = take_connection_entry_from_pool(pool);
       unlock_pool(TSRMLS_C);
    }
+
    if (entry) {
       connection = &entry->connection;
       if (!ensure_connected_init(connection, host, host_len, port TSRMLS_CC)) {
@@ -146,9 +147,11 @@ riak_connection *take_connection(char* host, int host_len, int port TSRMLS_DC) /
          return NULL;
       }
    }
+
    if (connection) {
       RIAK_GLOBAL(open_connections)++;
    }
+
    return connection;
 }
 /* }}} */
diff --git a/pool.h b/riak/pool.h
similarity index 97%
rename from pool.h
rename to riak/pool.h
index 7b6f0c3..ace4737 100644
--- a/pool.h
+++ b/riak/pool.h
@@ -18,11 +18,12 @@
 #ifndef RIAK_POOL__H__
 #define RIAK_POOL__H__
 
+#include "php_riak_internal.h"
 #include <php.h>
 #include <time.h>
 
 typedef struct _riak_connection {
-  struct RIACK_CLIENT *client;
+  riack_client *client;
   zend_bool needs_reconnect;
   zend_bool persistent;
   time_t last_used_at;
diff --git a/pool_info.c b/riak/pool_info.c
similarity index 86%
rename from pool_info.c
rename to riak/pool_info.c
index b8d19ec..7fb3baf 100644
--- a/pool_info.c
+++ b/riak/pool_info.c
@@ -14,9 +14,7 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 */
-#include <php.h>
-#include <riack.h>
-#include "php_riak.h"
+
 #include "pool_info.h"
 
 zend_class_entry *riak_poolinfo_ce;
@@ -25,14 +23,14 @@ static zend_function_entry riak_pool_info_methods[] = {
     PHP_ME(RiakPoolInfo, getNumActiveConnection, NULL, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC)
     PHP_ME(RiakPoolInfo, getNumActivePersistentConnection, NULL, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC)
     PHP_ME(RiakPoolInfo, getNumReconnect, NULL, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC)
-	{NULL, NULL, NULL}
+    {NULL, NULL, NULL}
 };
 
 /* {{{ proto int Riak\PoolInfo::getNumActiveConnection()
 Returns number of active riak connections */
 PHP_METHOD(RiakPoolInfo, getNumActiveConnection)
 {
-	RETURN_LONG(RIAK_GLOBAL(open_connections));
+    RETURN_LONG(RIAK_GLOBAL(open_connections));
 }
 /* }}} */
 
@@ -40,7 +38,7 @@ PHP_METHOD(RiakPoolInfo, getNumActiveConnection)
 Returns number of active persistent riak connections */
 PHP_METHOD(RiakPoolInfo, getNumActivePersistentConnection)
 {
-	RETURN_LONG(RIAK_GLOBAL(open_connections_persistent));
+    RETURN_LONG(RIAK_GLOBAL(open_connections_persistent));
 }
 /* }}} */
 
@@ -48,15 +46,15 @@ PHP_METHOD(RiakPoolInfo, getNumActivePersistentConnection)
 How many reconnections has been performed, persistent and nonpersistent */
 PHP_METHOD(RiakPoolInfo, getNumReconnect)
 {
-	long reconnects = RIAK_GLOBAL(reconnects);
-	RETURN_LONG(reconnects);
+    long reconnects = RIAK_GLOBAL(reconnects);
+    RETURN_LONG(reconnects);
 }
 /* }}} */
 
 void riak_poolinfo_init(TSRMLS_D) /* {{{ */
 {
-	zend_class_entry ce;
- 
+    zend_class_entry ce;
+
     INIT_NS_CLASS_ENTRY(ce, "Riak", "PoolInfo", riak_pool_info_methods);
     riak_poolinfo_ce = zend_register_internal_class(&ce TSRMLS_CC);
 }
diff --git a/pool_info.h b/riak/pool_info.h
similarity index 96%
rename from pool_info.h
rename to riak/pool_info.h
index 860c511..a493f72 100644
--- a/pool_info.h
+++ b/riak/pool_info.h
@@ -18,6 +18,8 @@
 #ifndef RIAK_POOL_INFO__H__
 #define RIAK_POOL_INFO__H__
 
+#include "php_riak_internal.h"
+
 extern zend_class_entry *riak_poolinfo_ce;
 
 PHP_METHOD(RiakPoolInfo, getNumActiveConnection);
diff --git a/riak/property/commit_hook.c b/riak/property/commit_hook.c
new file mode 100644
index 0000000..6fb26d8
--- /dev/null
+++ b/riak/property/commit_hook.c
@@ -0,0 +1,106 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "commit_hook.h"
+#include "riak/exception/exception.h"
+
+zend_class_entry *riak_commit_hook_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_commit_hook_ctor, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, moduleOrName)
+    ZEND_ARG_INFO(0, function)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_commit_hook_set, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_commit_hook_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+
+static zend_function_entry riak_commit_hook_methods[] = {
+    PHP_ME(RiakCommitHook, __construct, arginfo_commit_hook_ctor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+    PHP_ME(RiakCommitHook, getJsName, arginfo_commit_hook_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakCommitHook, getErlModule, arginfo_commit_hook_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakCommitHook, getErlFunction, arginfo_commit_hook_set, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakCommitHook, isJavascript, arginfo_commit_hook_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakCommitHook, isErlang, arginfo_commit_hook_noargs, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+void riak_property_commit_hook_init(TSRMLS_D)/* {{{ */
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Property", "CommitHook", riak_commit_hook_methods);
+    riak_commit_hook_ce = zend_register_internal_class(&ce TSRMLS_CC);
+    zend_declare_property_null(riak_commit_hook_ce, "moduleOrName", sizeof("moduleOrName")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
+    zend_declare_property_null(riak_commit_hook_ce, "function", sizeof("function")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
+
+}
+/* }}} */
+
+
+/* {{{ proto void Riak\Property\CommitHook->__construct(string $name, ModuleFunction $moduleFunction)
+Creates a new Riak\Property\CommitHook */
+PHP_METHOD(RiakCommitHook, __construct)
+{
+    char *mod_or_name, *fun;
+    int mod_or_name_len, fun_len;
+    fun_len = 0;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &mod_or_name, &mod_or_name_len, &fun, &fun_len) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    zend_update_property_stringl(riak_commit_hook_ce, getThis(), "moduleOrName", sizeof("moduleOrName")-1, mod_or_name, mod_or_name_len TSRMLS_CC);
+    if (fun_len > 0) {
+        zend_update_property_stringl(riak_commit_hook_ce, getThis(), "function", sizeof("function")-1, fun, fun_len TSRMLS_CC);
+    }
+}
+/* }}} */
+
+PHP_METHOD(RiakCommitHook, getJsName)
+{
+    RIAK_GETTER_STRING(riak_commit_hook_ce, "moduleOrName")
+}
+
+PHP_METHOD(RiakCommitHook, getErlModule)
+{
+    RIAK_GETTER_STRING(riak_commit_hook_ce, "moduleOrName")
+}
+
+PHP_METHOD(RiakCommitHook, getErlFunction)
+{
+    RIAK_GETTER_STRING(riak_commit_hook_ce, "function")
+}
+
+PHP_METHOD(RiakCommitHook, isJavascript)
+{
+    zval* ztmp = zend_read_property(riak_commit_hook_ce, getThis(), "function", sizeof("function")-1, 1 TSRMLS_CC);
+    if (Z_TYPE_P(ztmp) == IS_STRING) {
+        RETURN_FALSE;
+    }
+    RETURN_TRUE;
+}
+
+PHP_METHOD(RiakCommitHook, isErlang)
+{
+    zval* ztmp = zend_read_property(riak_commit_hook_ce, getThis(), "function", sizeof("function")-1, 1 TSRMLS_CC);
+    if (Z_TYPE_P(ztmp) == IS_STRING) {
+        RETURN_TRUE;
+    }
+    RETURN_FALSE;
+}
+
diff --git a/riak/property/commit_hook.h b/riak/property/commit_hook.h
new file mode 100644
index 0000000..72f219a
--- /dev/null
+++ b/riak/property/commit_hook.h
@@ -0,0 +1,33 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_PROPERTY__COMMIT_HOOK__H__
+#define RIAK_PROPERTY__COMMIT_HOOK__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_commit_hook_ce;
+
+void riak_property_commit_hook_init(TSRMLS_D);
+
+PHP_METHOD(RiakCommitHook, __construct);
+PHP_METHOD(RiakCommitHook, getJsName);
+PHP_METHOD(RiakCommitHook, getErlModule);
+PHP_METHOD(RiakCommitHook, getErlFunction);
+PHP_METHOD(RiakCommitHook, isJavascript);
+PHP_METHOD(RiakCommitHook, isErlang);
+
+#endif
diff --git a/riak/property/commit_hook_list.c b/riak/property/commit_hook_list.c
new file mode 100644
index 0000000..d113046
--- /dev/null
+++ b/riak/property/commit_hook_list.c
@@ -0,0 +1,134 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "commit_hook_list.h"
+#include "riak/exception/exception.h"
+#include "commit_hook.h"
+#include <zend_interfaces.h>
+#include <ext/spl/spl_iterators.h>
+#include <ext/spl/spl_array.h>
+
+zend_class_entry *riak_commit_hook_list_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_commit_hook_list_offset_exists, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, offset)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_commit_hook_list_offset_set, 0, ZEND_RETURN_VALUE, 2)
+    ZEND_ARG_INFO(0, offset)
+    ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_commit_hook_list_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_commit_hook_list_methods[] = {
+    PHP_ME(RiakCommitHookList, __construct, arginfo_commit_hook_list_noargs, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+    PHP_ME(RiakCommitHookList, offsetExists, arginfo_commit_hook_list_offset_exists, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakCommitHookList, offsetGet, arginfo_commit_hook_list_offset_exists, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakCommitHookList, offsetSet, arginfo_commit_hook_list_offset_set, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakCommitHookList, offsetUnset, arginfo_commit_hook_list_offset_exists, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakCommitHookList, count, arginfo_commit_hook_list_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakCommitHookList, getIterator, arginfo_commit_hook_list_noargs, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+void riak_property_commit_hook_list_init(TSRMLS_D)/* {{{ */
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Property", "CommitHookList", riak_commit_hook_list_methods);
+    riak_commit_hook_list_ce = zend_register_internal_class(&ce TSRMLS_CC);
+    zend_class_implements(riak_commit_hook_list_ce TSRMLS_CC, 3, spl_ce_ArrayAccess, spl_ce_Aggregate, spl_ce_Countable);
+    zend_declare_property_null(riak_commit_hook_list_ce, "hooks", sizeof("hooks")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
+
+}
+/* }}} */
+
+
+/* {{{ proto void Riak\Property\RiakCommitHookList->__construct()
+Creates a new Riak\Property\RiakCommitHookList */
+PHP_METHOD(RiakCommitHookList, __construct)
+{
+    zval* zhooks;
+    // Start with an empty array
+    MAKE_STD_ZVAL(zhooks);
+    object_init_ex(zhooks, spl_ce_ArrayObject);
+    zend_update_property(riak_commit_hook_list_ce, getThis(), "hooks", sizeof("hooks")-1, zhooks TSRMLS_CC);
+    zval_ptr_dtor(&zhooks);
+}/* }}} */
+
+PHP_METHOD(RiakCommitHookList, offsetExists)
+{
+    zval *zoffset, *zhooks, *zresult;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zoffset) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    zhooks = zend_read_property(riak_commit_hook_list_ce, getThis(), "hooks", sizeof("hooks")-1, 1 TSRMLS_CC);
+    zend_call_method_with_1_params(&zhooks, spl_ce_ArrayObject, NULL, "offsetexists", &zresult, zoffset);
+    RETURN_ZVAL(zresult, 0, 1);
+}
+
+PHP_METHOD(RiakCommitHookList, offsetGet)
+{
+    zval *zoffset, *zhooks, *zresult;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zoffset) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    zhooks = zend_read_property(riak_commit_hook_list_ce, getThis(), "hooks", sizeof("hooks")-1, 1 TSRMLS_CC);
+    zend_call_method_with_1_params(&zhooks, spl_ce_ArrayObject, NULL, "offsetget", &zresult, zoffset);
+    RETURN_ZVAL(zresult, 0, 1);
+}
+
+PHP_METHOD(RiakCommitHookList, offsetSet)
+{
+    zval *zoffset, *zvalue, *zhooks;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zO", &zoffset, &zvalue, riak_commit_hook_ce) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    zhooks = zend_read_property(riak_commit_hook_list_ce, getThis(), "hooks", sizeof("hooks")-1, 1 TSRMLS_CC);
+    zend_call_method_with_2_params(&zhooks, spl_ce_ArrayObject, NULL, "offsetset", NULL, zoffset, zvalue);
+}
+
+PHP_METHOD(RiakCommitHookList, offsetUnset)
+{
+    zval *zoffset, *zhooks;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zoffset) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    zhooks = zend_read_property(riak_commit_hook_list_ce, getThis(), "hooks", sizeof("hooks")-1, 1 TSRMLS_CC);
+    zend_call_method_with_1_params(&zhooks, spl_ce_ArrayObject, NULL, "offsetunset", NULL, zoffset);
+}
+
+PHP_METHOD(RiakCommitHookList, count)
+{
+    zval *zhooks, *zresult;
+    zhooks = zend_read_property(riak_commit_hook_list_ce, getThis(), "hooks", sizeof("hooks")-1, 1 TSRMLS_CC);
+    zend_call_method_with_0_params(&zhooks, spl_ce_ArrayObject, NULL, "count", &zresult);
+    RETURN_ZVAL(zresult, 0, 1);
+}
+
+PHP_METHOD(RiakCommitHookList, getIterator)
+{
+    zval *zhooks, *zresult;
+    zhooks = zend_read_property(riak_commit_hook_list_ce, getThis(), "hooks", sizeof("hooks")-1, 1 TSRMLS_CC);
+    zend_call_method_with_0_params(&zhooks, spl_ce_ArrayObject, NULL, "getiterator", &zresult);
+    RETURN_ZVAL(zresult, 0, 1);
+}
+
+
diff --git a/riak/property/commit_hook_list.h b/riak/property/commit_hook_list.h
new file mode 100644
index 0000000..3069ac9
--- /dev/null
+++ b/riak/property/commit_hook_list.h
@@ -0,0 +1,33 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+#ifndef RIAK_PROPERTY__COMMIT_HOOK_LIST__H__
+#define RIAK_PROPERTY__COMMIT_HOOK_LIST__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_commit_hook_list_ce;
+
+void riak_property_commit_hook_list_init(TSRMLS_D);
+
+PHP_METHOD(RiakCommitHookList, __construct);
+PHP_METHOD(RiakCommitHookList, offsetExists);
+PHP_METHOD(RiakCommitHookList, offsetGet);
+PHP_METHOD(RiakCommitHookList, offsetSet);
+PHP_METHOD(RiakCommitHookList, offsetUnset);
+PHP_METHOD(RiakCommitHookList, count);
+PHP_METHOD(RiakCommitHookList, getIterator);
+
+#endif
diff --git a/riak/property/module_function.c b/riak/property/module_function.c
new file mode 100644
index 0000000..9ed597f
--- /dev/null
+++ b/riak/property/module_function.c
@@ -0,0 +1,94 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "module_function.h"
+#include "riak/exception/exception.h"
+
+zend_class_entry *riak_module_function_ce;
+
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_module_function_ctor, 0, ZEND_RETURN_VALUE, 2)
+    ZEND_ARG_INFO(0, module)
+    ZEND_ARG_INFO(0, function)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_module_function_set, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_module_function_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+
+static zend_function_entry riak_module_function_methods[] = {
+    PHP_ME(RiakModuleFunction, __construct, arginfo_module_function_ctor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+    PHP_ME(RiakModuleFunction, getModule, arginfo_module_function_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakModuleFunction, setModule, arginfo_module_function_set, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakModuleFunction, getFunction, arginfo_module_function_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(RiakModuleFunction, setFunction, arginfo_module_function_set, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+
+void riak_property_module_function_init(TSRMLS_D)/* {{{ */
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Property", "ModuleFunction", riak_module_function_methods);
+    riak_module_function_ce = zend_register_internal_class(&ce TSRMLS_CC);
+    zend_declare_property_null(riak_module_function_ce, "module", sizeof("module")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
+    zend_declare_property_null(riak_module_function_ce, "function", sizeof("function")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
+}
+/* }}} */
+
+
+/* {{{ proto void Riak\Property\ModuleFunction->__construct(string $module, string $function)
+Creates a new Riak\Property\ModuleFunction */
+PHP_METHOD(RiakModuleFunction, __construct)
+{
+    char *module, *efunction;
+    int module_len, efunction_len;
+
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &module, &module_len, &efunction, &efunction_len) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+
+    zend_update_property_stringl(riak_module_function_ce, getThis(), "module", sizeof("module")-1, module, module_len TSRMLS_CC);
+    zend_update_property_stringl(riak_module_function_ce, getThis(), "function", sizeof("function")-1, efunction, efunction_len TSRMLS_CC);
+}
+/* }}} */
+
+PHP_METHOD(RiakModuleFunction, getModule)
+{
+    RIAK_GETTER_STRING(riak_module_function_ce, "module")
+}
+
+PHP_METHOD(RiakModuleFunction, setModule)
+{
+    RIAK_SETTER_STRING(riak_module_function_ce, "module")
+    RIAK_RETURN_THIS
+}
+
+PHP_METHOD(RiakModuleFunction, getFunction)
+{
+    RIAK_GETTER_STRING(riak_module_function_ce, "function")
+}
+
+PHP_METHOD(RiakModuleFunction, setFunction)
+{
+    RIAK_SETTER_STRING(riak_module_function_ce, "function")
+    RIAK_RETURN_THIS
+}
+
diff --git a/riak/property/module_function.h b/riak/property/module_function.h
new file mode 100644
index 0000000..71c7a57
--- /dev/null
+++ b/riak/property/module_function.h
@@ -0,0 +1,33 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_PROPERTY__MODULE_FUNCTION__H__
+#define RIAK_PROPERTY__MODULE_FUNCTION__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_module_function_ce;
+
+void riak_property_module_function_init(TSRMLS_D);
+
+PHP_METHOD(RiakModuleFunction, __construct);
+PHP_METHOD(RiakModuleFunction, getModule);
+PHP_METHOD(RiakModuleFunction, setModule);
+PHP_METHOD(RiakModuleFunction, getFunction);
+PHP_METHOD(RiakModuleFunction, setFunction);
+
+
+#endif
diff --git a/riak/property/replication_mode/replication_mode.c b/riak/property/replication_mode/replication_mode.c
new file mode 100644
index 0000000..3c57a4d
--- /dev/null
+++ b/riak/property/replication_mode/replication_mode.c
@@ -0,0 +1,54 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "replication_mode.h"
+
+
+zend_class_entry *riak_replication_mode_ce;
+zend_class_entry *riak_replication_mode_full_only_ce;
+zend_class_entry *riak_replication_mode_disabled_ce;
+zend_class_entry *riak_replication_mode_realtime_and_full_ce;
+zend_class_entry *riak_replication_mode_realtime_only_ce;
+
+static zend_function_entry riak_replication_mode_functions[] = {
+    {NULL, NULL, NULL}
+};
+
+
+void riak_property_replication_mode_init(TSRMLS_D)/* {{{ */
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Property\\ReplicationMode", "ReplicationMode", riak_replication_mode_functions);
+    riak_replication_mode_ce = zend_register_internal_interface(&ce TSRMLS_CC);
+
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Property\\ReplicationMode", "FullSyncOnly", riak_replication_mode_functions);
+    riak_replication_mode_full_only_ce = zend_register_internal_class(&ce TSRMLS_CC);
+    zend_class_implements(riak_replication_mode_full_only_ce TSRMLS_CC, 1, riak_replication_mode_ce);
+
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Property\\ReplicationMode", "Disabled", riak_replication_mode_functions);
+    riak_replication_mode_disabled_ce = zend_register_internal_class(&ce TSRMLS_CC);
+    zend_class_implements(riak_replication_mode_disabled_ce TSRMLS_CC, 1, riak_replication_mode_ce);
+
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Property\\ReplicationMode", "RealTimeAndFullSync", riak_replication_mode_functions);
+    riak_replication_mode_realtime_and_full_ce = zend_register_internal_class(&ce TSRMLS_CC);
+    zend_class_implements(riak_replication_mode_realtime_and_full_ce TSRMLS_CC, 1, riak_replication_mode_ce);
+
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Property\\ReplicationMode", "RealTimeOnly", riak_replication_mode_functions);
+    riak_replication_mode_realtime_only_ce = zend_register_internal_class(&ce TSRMLS_CC);
+    zend_class_implements(riak_replication_mode_realtime_only_ce TSRMLS_CC, 1, riak_replication_mode_ce);
+
+}
+/* }}} */
+
diff --git a/riak/property/replication_mode/replication_mode.h b/riak/property/replication_mode/replication_mode.h
new file mode 100644
index 0000000..62ddc6a
--- /dev/null
+++ b/riak/property/replication_mode/replication_mode.h
@@ -0,0 +1,30 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_PROPERTY__REPLICATION_MODE__REPLICATION_MODE__H__
+#define RIAK_PROPERTY__REPLICATION_MODE__REPLICATION_MODE__H__
+
+#include "php_riak_internal.h"
+
+void riak_property_replication_mode_init(TSRMLS_D);
+
+extern zend_class_entry *riak_replication_mode_ce;
+extern zend_class_entry *riak_replication_mode_full_only_ce;
+extern zend_class_entry *riak_replication_mode_disabled_ce;
+extern zend_class_entry *riak_replication_mode_realtime_and_full_ce;
+extern zend_class_entry *riak_replication_mode_realtime_only_ce;
+
+#endif // RIAK_PROPERTY__REPLICATION_MODE__REPLICATION_MODE__H__
diff --git a/riak/query/index_query.c b/riak/query/index_query.c
new file mode 100644
index 0000000..1ec8253
--- /dev/null
+++ b/riak/query/index_query.c
@@ -0,0 +1,121 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "index_query.h"
+#include "../exception/exception.h"
+
+zend_class_entry *riak_index_query_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_query_index_query_set_name, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_query_index_query_set_value, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_query_index_query_set_range, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, min)
+    ZEND_ARG_INFO(0, max)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_query_index_query_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_query_index_query_methods[] = {
+    PHP_ME(Riak_Query_IndexQuery, __construct, arginfo_riak_query_index_query_set_name, ZEND_ACC_PUBLIC|ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Query_IndexQuery, setName, arginfo_riak_query_index_query_set_name, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Query_IndexQuery, getName, arginfo_riak_query_index_query_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Query_IndexQuery, setExactValue, arginfo_riak_query_index_query_set_value, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Query_IndexQuery, getExactValue, arginfo_riak_query_index_query_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Query_IndexQuery, setRangeValue, arginfo_riak_query_index_query_set_range, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Query_IndexQuery, getRangeValue, arginfo_riak_query_index_query_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Query_IndexQuery, isRangeQuery, arginfo_riak_query_index_query_noargs, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+
+void riak_query_index_query_init(TSRMLS_D)
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Query", "IndexQuery", riak_query_index_query_methods);
+    riak_index_query_ce = zend_register_internal_class(&ce TSRMLS_CC);
+    zend_declare_property_null(riak_index_query_ce, "name", sizeof("name")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
+    zend_declare_property_null(riak_index_query_ce, "exactValue", sizeof("exactValue")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
+    zend_declare_property_null(riak_index_query_ce, "minValue", sizeof("minValue")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
+    zend_declare_property_null(riak_index_query_ce, "maxValue", sizeof("maxValue")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
+    zend_declare_property_bool(riak_index_query_ce, "isRange", sizeof("isRange")-1, 0, ZEND_ACC_PRIVATE TSRMLS_CC);
+}
+
+
+PHP_METHOD(Riak_Query_IndexQuery, __construct)
+{
+    RIAK_SETTER_STRING(riak_index_query_ce, "name")
+}
+
+PHP_METHOD(Riak_Query_IndexQuery, setName)
+{
+    RIAK_SETTER_STRING(riak_index_query_ce, "name")
+    RIAK_RETURN_THIS
+}
+
+PHP_METHOD(Riak_Query_IndexQuery, getName)
+{
+    RIAK_GETTER_STRING(riak_index_query_ce, "name")
+}
+
+PHP_METHOD(Riak_Query_IndexQuery, setExactValue)
+{
+    RIAK_SETTER_STRING(riak_index_query_ce, "exactValue")
+    zend_update_property_bool(riak_index_query_ce, getThis(), "isRange", sizeof("isRange")-1, 0 TSRMLS_CC);
+    RIAK_RETURN_THIS
+}
+
+PHP_METHOD(Riak_Query_IndexQuery, getExactValue)
+{
+    RIAK_GETTER_STRING(riak_index_query_ce, "exactValue")
+}
+
+PHP_METHOD(Riak_Query_IndexQuery, setRangeValue)
+{
+    char *min, *max;
+    int minlen, maxlen;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &min, &minlen, &max, &maxlen) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "", 501 TSRMLS_CC);
+        return;
+    }
+    zend_update_property_stringl(riak_index_query_ce, getThis(), "minValue", sizeof("minValue")-1, min, minlen TSRMLS_CC);
+    zend_update_property_stringl(riak_index_query_ce, getThis(), "maxValue", sizeof("maxValue")-1, max, maxlen TSRMLS_CC);
+    zend_update_property_bool(riak_index_query_ce, getThis(), "isRange", sizeof("isRange")-1, 1 TSRMLS_CC);
+}
+
+PHP_METHOD(Riak_Query_IndexQuery, getRangeValue)
+{
+    zval *zrangearr, *zmin, *zmax;
+    MAKE_STD_ZVAL(zrangearr);
+    array_init(zrangearr);
+    zmin = zend_read_property(riak_index_query_ce, getThis(), "minValue", sizeof("minValue")-1, 1 TSRMLS_CC);
+    zval_addref_p(zmin);
+    add_next_index_zval(zrangearr, zmin);
+    zmax = zend_read_property(riak_index_query_ce, getThis(), "maxValue", sizeof("maxValue")-1, 1 TSRMLS_CC);
+    zval_addref_p(zmax);
+    add_next_index_zval(zrangearr, zmax);
+    RETURN_ZVAL(zrangearr, 0, 1);
+}
+
+PHP_METHOD(Riak_Query_IndexQuery, isRangeQuery)
+{
+    RIAK_GETTER_BOOL(riak_index_query_ce, "isRange")
+}
diff --git a/riak/query/index_query.h b/riak/query/index_query.h
new file mode 100644
index 0000000..65251d4
--- /dev/null
+++ b/riak/query/index_query.h
@@ -0,0 +1,35 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_QUERY__INDEX_QUERY__H__
+#define RIAK_QUERY__INDEX_QUERY__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_index_query_ce;
+
+void riak_query_index_query_init(TSRMLS_D);
+
+PHP_METHOD(Riak_Query_IndexQuery, setName);
+PHP_METHOD(Riak_Query_IndexQuery, getName);
+PHP_METHOD(Riak_Query_IndexQuery, setExactValue);
+PHP_METHOD(Riak_Query_IndexQuery, getExactValue);
+PHP_METHOD(Riak_Query_IndexQuery, setRangeValue);
+PHP_METHOD(Riak_Query_IndexQuery, getRangeValue);
+PHP_METHOD(Riak_Query_IndexQuery, isRangeQuery);
+PHP_METHOD(Riak_Query_IndexQuery, __construct);
+
+#endif //RIAK_QUERY__INDEX_QUERY__H__
diff --git a/riak/search/input/parameter_bag.c b/riak/search/input/parameter_bag.c
new file mode 100644
index 0000000..bcb3c79
--- /dev/null
+++ b/riak/search/input/parameter_bag.c
@@ -0,0 +1,238 @@
+/*
+   Copyright 2013 Kaspar Bach Pedersen
+
+   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.
+*/
+#include "parameter_bag.h"
+
+zend_class_entry *riak_search_input_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_search_input_setrowlimit, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, rowlimit)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_search_input_setstart, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, start)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_search_input_setsort, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, sort)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_search_input_setfilter, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, sort)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_search_input_setdefaultfield, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, defaultfield)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_search_input_setdefaultop, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, defaultop)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_search_input_setpresort, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, presort)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_search_input_setfieldlimit, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, fieldlimit)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_search_input_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_search_input_methods[] = {
+    PHP_ME(Riak_Search_Input, setRowLimit, arginfo_search_input_setrowlimit, ZEND_ACC_CTOR | ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Search_Input, getRowLimit, arginfo_search_input_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Search_Input, setStartOffset, arginfo_search_input_setstart, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Search_Input, getStartOffset, arginfo_search_input_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Search_Input, setSort, arginfo_search_input_setsort, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Search_Input, getSort, arginfo_search_input_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Search_Input, setFilter, arginfo_search_input_setfilter, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Search_Input, getFilter, arginfo_search_input_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Search_Input, setDefaultField, arginfo_search_input_setdefaultfield, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Search_Input, getDefaultField, arginfo_search_input_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Search_Input, setDefaultOperation, arginfo_search_input_setdefaultop, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Search_Input, getDefaultOperation, arginfo_search_input_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Search_Input, setPresort, arginfo_search_input_setpresort, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Search_Input, getPresort, arginfo_search_input_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Search_Input, setFieldLimits, arginfo_search_input_setfieldlimit, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Search_Input, getFieldLimits, arginfo_search_input_noargs, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+void riak_search_input_parameterbag_init(TSRMLS_D)/* {{{  */
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Search\\Input", "ParameterBag", riak_search_input_methods);
+    riak_search_input_ce = zend_register_internal_class(&ce TSRMLS_CC);
+    zend_declare_property_null(riak_search_input_ce, "rowLimit", sizeof("rowLimit")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_search_input_ce, "start", sizeof("start")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_search_input_ce, "sort", sizeof("sort")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_search_input_ce, "filter", sizeof("filter")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_search_input_ce, "defaultField", sizeof("defaultField")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_search_input_ce, "defaultOperation", sizeof("defaultOperation")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_search_input_ce, "presort", sizeof("presort")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+    zend_declare_property_null(riak_search_input_ce, "fieldLimits", sizeof("fieldLimits")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+}
+/* }}} */
+
+/*************************************************************
+* Implementation: Riak\Search\Input\ParameterBag
+*************************************************************/
+
+/* {{{ proto Riak\Search\Input\ParameterBag Riak\Search\Input\ParameterBag->setRowLimit(int $rowLimit)
+Set row limit for search */
+PHP_METHOD(Riak_Search_Input, setRowLimit)
+{
+    RIAK_SETTER_LONG(riak_search_input_ce, "rowLimit");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto int|null Riak\Search\Input\ParameterBag->getRowLimit()
+Set row limit for search */
+PHP_METHOD(Riak_Search_Input, getRowLimit)
+{
+    RIAK_GETTER_LONG(riak_search_input_ce, "rowLimit");
+}
+/* }}} */
+
+/* {{{ proto Riak\Search\Input\ParameterBag Riak\Search\Input\ParameterBag->setStartOffset(int $startOffset)
+Set start offset for this search */
+PHP_METHOD(Riak_Search_Input, setStartOffset)
+{
+    RIAK_SETTER_LONG(riak_search_input_ce, "start");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto int|null Riak\Search\Input\ParameterBag->getStartOffset()
+Get start offset */
+PHP_METHOD(Riak_Search_Input, getStartOffset)
+{
+    RIAK_GETTER_LONG(riak_search_input_ce, "start");
+}
+/* }}} */
+
+/* {{{ proto Riak\Search\Input\ParameterBag Riak\Search\Input\ParameterBag->setSort(string $sort)
+Set the sort string */
+PHP_METHOD(Riak_Search_Input, setSort)
+{
+    RIAK_SETTER_STRING(riak_search_input_ce, "sort");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto string|null Riak\Search\Input\ParameterBag->getSort()
+Get the sort string */
+PHP_METHOD(Riak_Search_Input, getSort)
+{
+    RIAK_GETTER_STRING(riak_search_input_ce, "sort");
+}
+/* }}} */
+
+/* {{{ proto Riak\Search\Input\ParameterBag Riak\Search\Input\ParameterBag->setFilter(string $filter)
+Set the filter string */
+PHP_METHOD(Riak_Search_Input, setFilter)
+{
+    RIAK_SETTER_STRING(riak_search_input_ce, "filter");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto string|null Riak\Search\Input\ParameterBag->getFilter()
+Get the filter string */
+PHP_METHOD(Riak_Search_Input, getFilter)
+{
+    RIAK_GETTER_STRING(riak_search_input_ce, "filter");
+}
+/* }}} */
+
+/* {{{ proto Riak\Search\Input\ParameterBag Riak\Search\Input\ParameterBag->setDefaultField(string $defaultField)
+Set the default field name */
+PHP_METHOD(Riak_Search_Input, setDefaultField)
+{
+    RIAK_SETTER_STRING(riak_search_input_ce, "defaultField");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto string|null Riak\Search\Input\ParameterBag->getDefaultField()
+Get the default field name */
+PHP_METHOD(Riak_Search_Input, getDefaultField)
+{
+    RIAK_GETTER_STRING(riak_search_input_ce, "defaultField");
+}
+/* }}} */
+
+/* {{{ proto Riak\Search\Input\ParameterBag Riak\Search\Input\ParameterBag->setDefaultOperation(string $defaultOperation)
+Set the default opereration */
+PHP_METHOD(Riak_Search_Input, setDefaultOperation)
+{
+    RIAK_SETTER_STRING(riak_search_input_ce, "defaultOperation");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto string|null Riak\Search\Input\ParameterBag->getDefaultOperation()
+Get the default operation */
+PHP_METHOD(Riak_Search_Input, getDefaultOperation)
+{
+    RIAK_GETTER_STRING(riak_search_input_ce, "defaultOperation");
+}
+/* }}} */
+
+/* {{{ proto Riak\Search\Input\ParameterBag Riak\Search\Input\ParameterBag->setPresort(string $presort)
+Set the presort string */
+PHP_METHOD(Riak_Search_Input, setPresort)
+{
+    RIAK_SETTER_STRING(riak_search_input_ce, "presort");
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto string|null Riak\Search\Input\ParameterBag->getPresort()
+Get the presort string */
+PHP_METHOD(Riak_Search_Input, getPresort)
+{
+    RIAK_GETTER_STRING(riak_search_input_ce, "presort");
+}
+/* }}} */
+
+/* {{{ proto Riak\Search\Input\ParameterBag Riak\Search\Input\ParameterBag->setFieldLimits(array $fieldLimits)
+Set field limits */
+PHP_METHOD(Riak_Search_Input, setFieldLimits)
+{
+    zval* zlimits;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &zlimits) == FAILURE) {
+        return;
+    }
+    zend_update_property(riak_search_input_ce, getThis(), "fieldLimits", sizeof("fieldLimits")-1, zlimits TSRMLS_CC);
+    RIAK_RETURN_THIS
+}
+/* }}} */
+
+/* {{{ proto array|null Riak\Search\Input\ParameterBag->getFieldLimits()
+Get the field limits array */
+PHP_METHOD(Riak_Search_Input, getFieldLimits)
+{
+    zval* zlimits = zend_read_property(riak_search_input_ce, getThis(), "fieldLimits", sizeof("fieldLimits")-1, 1 TSRMLS_CC);
+    if (Z_TYPE_P(zlimits) == IS_ARRAY) {
+        RETURN_ZVAL(zlimits, 1, 0);
+    }
+    RETURN_NULL();
+}
+/* }}} */
+
diff --git a/search.h b/riak/search/input/parameter_bag.h
similarity index 54%
rename from search.h
rename to riak/search/input/parameter_bag.h
index 245657d..80608ca 100644
--- a/search.h
+++ b/riak/search/input/parameter_bag.h
@@ -14,34 +14,14 @@
    limitations under the License.
 */
 
-#ifndef RIAK_SEARCH__H__
-#define RIAK_SEARCH__H__
+#ifndef RIAK_SEARCH__INPUT__PARAMETER_BAG__H__
+#define RIAK_SEARCH__INPUT__PARAMETER_BAG__H__
 
-extern zend_class_entry *riak_search_ce;
+#include "php_riak_internal.h"
 
-/* helpers */
+extern zend_class_entry *riak_search_input_ce;
 
-void riak_search_init(TSRMLS_D);
-void riak_search_set_optional_params(struct RIACK_CLIENT *client, zval* zparams, struct RIACK_SEARCH_OPTIONAL_PARAMETERS* search_params TSRMLS_DC);
-void riak_search_free_optional_params(struct RIACK_CLIENT *client, struct RIACK_SEARCH_OPTIONAL_PARAMETERS* search_params TSRMLS_DC);
-
-zval* riak_search_output_from_riack_search_result(struct RIACK_SEARCH_RESULT *search_result TSRMLS_DC);
-zval *riak_search_document_from_riack_document(struct RIACK_SEARCH_DOCUMENT* document TSRMLS_DC);
-
-/* Search */
-
-PHP_METHOD(Riak_Search, __construct);
-PHP_METHOD(Riak_Search, search);
-
-/* Riak\Search\Output\Output */
-PHP_METHOD(Riak_Search_Output_Output, hasMaxScore);
-PHP_METHOD(Riak_Search_Output_Output, getMaxScore);
-PHP_METHOD(Riak_Search_Output_Output, hasNumFound);
-PHP_METHOD(Riak_Search_Output_Output, getNumFound);
-PHP_METHOD(Riak_Search_Output_Output, getDocuments);
-
-/* Riak\Search\Output\DocumentOutput */
-PHP_METHOD(Riak_Search_Output_DocumentOutput, getFields);
+void riak_search_input_parameterbag_init(TSRMLS_D);
 
 /* Search\Input */
 PHP_METHOD(Riak_Search_Input, setRowLimit);
@@ -61,4 +41,4 @@ PHP_METHOD(Riak_Search_Input, getPresort);
 PHP_METHOD(Riak_Search_Input, setFieldLimits);
 PHP_METHOD(Riak_Search_Input, getFieldLimits);
 
-#endif
+#endif // RIAK_SEARCH__INPUT__PARAMETER_BAG__H__
diff --git a/riak/search/output/document_output.c b/riak/search/output/document_output.c
new file mode 100644
index 0000000..5442c51
--- /dev/null
+++ b/riak/search/output/document_output.c
@@ -0,0 +1,80 @@
+/*
+   Copyright 2013 Kaspar Bach Pedersen
+
+   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.
+*/
+#include "document_output.h"
+
+zend_class_entry *riak_search_doc_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_search_output_document_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_search_doc_methods[] = {
+    PHP_ME(Riak_Search_Output_DocumentOutput, getFields, arginfo_search_output_document_noargs, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+void riak_search_output_document_output_init(TSRMLS_D) /* {{{  */
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Search\\Output", "DocumentOutput", riak_search_doc_methods);
+    riak_search_doc_ce = zend_register_internal_class(&ce TSRMLS_CC);
+    zend_declare_property_null(riak_search_doc_ce, "fields", sizeof("fields")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
+}
+/* }}} */
+
+zval *riak_search_document_from_riack_document(riack_search_doc* document TSRMLS_DC) /* {{{  */
+{
+    int cnt, i;
+    zval *zresult, *zarr;
+    MAKE_STD_ZVAL(zarr)
+    array_init(zarr);
+
+    MAKE_STD_ZVAL(zresult)
+    object_init_ex(zresult, riak_search_doc_ce);
+
+    cnt = document->field_count;
+    for (i=0; i<cnt; ++i) {
+        char* szkey;
+        size_t key_len;
+        riack_pair *current_pair = &document->fields[i];
+        key_len = current_pair->key.len;
+        // Silly... we need to make a copy because add_assoc relies on zero terminated string
+        // riack will not zero terminate since it includes a length.
+        // However estrndup will be nice enough to add a zero termination for us...
+        szkey = estrndup(current_pair->key.value, key_len);
+        if (current_pair->value_present) {
+            add_assoc_stringl_ex(zarr, szkey, key_len + 1,
+                                 (char*)current_pair->value, current_pair->value_len, 1);
+        } else {
+            add_assoc_null_ex(zarr,  szkey, key_len+1);
+        }
+        efree(szkey);
+    }
+    zend_update_property(riak_search_doc_ce, zresult, "fields", sizeof("fields")-1, zarr TSRMLS_CC);
+    zval_ptr_dtor(&zarr);
+    return zresult;
+}
+/* }}} */
+
+
+/*************************************************************
+* Implementation: Riak\Search\Output\DocumentOutput
+*************************************************************/
+
+PHP_METHOD(Riak_Search_Output_DocumentOutput, getFields)
+{
+    RIAK_GETTER_ARRAY(riak_search_doc_ce, "fields");
+}
+
diff --git a/riak/search/output/document_output.h b/riak/search/output/document_output.h
new file mode 100644
index 0000000..542c0ce
--- /dev/null
+++ b/riak/search/output/document_output.h
@@ -0,0 +1,31 @@
+/*
+   Copyright 2013 Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK__SEARCH__OUTPUT__DOCUMENT_OUTPUT__H__
+#define RIAK__SEARCH__OUTPUT__DOCUMENT_OUTPUT__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_search_doc_ce;
+
+void riak_search_output_document_output_init(TSRMLS_D);
+zval *riak_search_document_from_riack_document(riack_search_doc* document TSRMLS_DC);
+
+
+/* Riak\Search\Output\DocumentOutput */
+PHP_METHOD(Riak_Search_Output_DocumentOutput, getFields);
+
+#endif //#ifndef RIAK__SEARCH__OUTPUT__DOCUMENT_OUTPUT__H__
diff --git a/riak/search/output/output.c b/riak/search/output/output.c
new file mode 100644
index 0000000..447aaf3
--- /dev/null
+++ b/riak/search/output/output.c
@@ -0,0 +1,107 @@
+/*
+   Copyright 2013 Kaspar Bach Pedersen
+
+   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.
+*/
+#include "output.h"
+#include "document_output.h"
+
+zend_class_entry *riak_search_output_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_search_output_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_search_output_methods[] = {
+    PHP_ME(Riak_Search_Output_Output, hasMaxScore, arginfo_search_output_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Search_Output_Output, getMaxScore, arginfo_search_output_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Search_Output_Output, hasNumFound, arginfo_search_output_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Search_Output_Output, getNumFound, arginfo_search_output_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Search_Output_Output, getDocuments, arginfo_search_output_noargs, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+void riak_search_output_output_init(TSRMLS_D) /* {{{  */
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Search\\Output", "Output", riak_search_output_methods);
+    riak_search_output_ce = zend_register_internal_class(&ce TSRMLS_CC);
+    zend_declare_property_null(riak_search_output_ce, "maxScore", sizeof("maxScore")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
+    zend_declare_property_null(riak_search_output_ce, "numFound", sizeof("numFound")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
+    zend_declare_property_null(riak_search_output_ce, "documents", sizeof("documents")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
+}
+/* }}} */
+
+/*************************************************************
+* Implementation: Riak\Search\Output\Output
+*************************************************************/
+
+zval* riak_search_output_from_riack_search_result(riack_search_result *search_result TSRMLS_DC)
+{
+    zval *zresult;
+    MAKE_STD_ZVAL(zresult);
+    object_init_ex(zresult, riak_search_output_ce);
+    if (search_result->document_count > 0) {
+        int cnt, i;
+        zval* zdocs;
+        cnt = search_result->document_count;
+        MAKE_STD_ZVAL(zdocs);
+        array_init(zdocs);
+        for (i=0; i<cnt; ++i) {
+            zval* doc = riak_search_document_from_riack_document(&search_result->documents[i] TSRMLS_CC);
+            add_next_index_zval(zdocs, doc);
+        }
+        zend_update_property(riak_search_output_ce, zresult, "documents", sizeof("documents")-1, zdocs TSRMLS_CC);
+        zval_ptr_dtor(&zdocs);
+    }
+    if (search_result->max_score_present) {
+        zend_update_property_double(riak_search_output_ce, zresult, "maxScore", sizeof("maxScore")-1, search_result->max_score TSRMLS_CC);
+    }
+    if (search_result->num_found_present) {
+        zend_update_property_long(riak_search_output_ce, zresult, "numFound", sizeof("numFound")-1, search_result->num_found TSRMLS_CC);
+    }
+    return zresult;
+}
+
+PHP_METHOD(Riak_Search_Output_Output, hasMaxScore)
+{
+    zval *zprop = zend_read_property(riak_search_output_ce, getThis(), "maxScore", sizeof("maxScore")-1, 1 TSRMLS_CC);
+    if (!zprop || Z_TYPE_P(zprop) == IS_NULL) {
+        RETURN_BOOL(0);
+    }
+    RETURN_BOOL(1);
+}
+
+PHP_METHOD(Riak_Search_Output_Output, getMaxScore)
+{
+    RIAK_GETTER_DOUBLE(riak_search_output_ce, "maxScore");
+}
+
+PHP_METHOD(Riak_Search_Output_Output, hasNumFound)
+{
+    zval *zprop = zend_read_property(riak_search_output_ce, getThis(), "numFound", sizeof("numFound")-1, 1 TSRMLS_CC);
+    if (zprop == NULL || Z_TYPE_P(zprop) == IS_NULL) {
+        RETURN_BOOL(0);
+    }
+    RETURN_BOOL(1);
+}
+
+PHP_METHOD(Riak_Search_Output_Output, getNumFound)
+{
+    RIAK_GETTER_LONG(riak_search_output_ce, "numFound");
+}
+
+PHP_METHOD(Riak_Search_Output_Output, getDocuments)
+{
+    RIAK_GETTER_ARRAY(riak_search_output_ce, "documents");
+}
+
diff --git a/riak/search/output/output.h b/riak/search/output/output.h
new file mode 100644
index 0000000..02f723c
--- /dev/null
+++ b/riak/search/output/output.h
@@ -0,0 +1,33 @@
+/*
+   Copyright 2013 Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_SEARCH__OUTPUT__OUTPUT__H__
+#define RIAK_SEARCH__OUTPUT__OUTPUT__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_search_output_ce;
+
+void riak_search_output_output_init(TSRMLS_D);
+
+/* Riak\Search\Output\Output */
+PHP_METHOD(Riak_Search_Output_Output, hasMaxScore);
+PHP_METHOD(Riak_Search_Output_Output, getMaxScore);
+PHP_METHOD(Riak_Search_Output_Output, hasNumFound);
+PHP_METHOD(Riak_Search_Output_Output, getNumFound);
+PHP_METHOD(Riak_Search_Output_Output, getDocuments);
+
+#endif // RIAK_SEARCH__OUTPUT__OUTPUT__H__
diff --git a/riak/search/search.c b/riak/search/search.c
new file mode 100644
index 0000000..6e2cb09
--- /dev/null
+++ b/riak/search/search.c
@@ -0,0 +1,167 @@
+/*
+   Copyright 2013 Kaspar Bach Pedersen
+
+   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.
+*/
+
+#include "search.h"
+#include "riak/connection.h"
+#include "input/parameter_bag.h"
+#include "output/output.h"
+#include "riak/exception/exception.h"
+
+zend_class_entry *riak_search_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_search_ctor, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, client)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_search_search, 0, ZEND_RETURN_VALUE, 2)
+    ZEND_ARG_INFO(0, index)
+    ZEND_ARG_INFO(0, query)
+    ZEND_ARG_INFO(0, parameters)
+ZEND_END_ARG_INFO()
+
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_search_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_search_methods[] = {
+    PHP_ME(Riak_Search, __construct, arginfo_search_ctor, ZEND_ACC_CTOR | ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Search, search, arginfo_search_search, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+
+void riak_search_init(TSRMLS_D) /* {{{ */
+{
+    zend_class_entry ce;
+    INIT_NS_CLASS_ENTRY(ce, "Riak\\Search", "Search", riak_search_methods);
+    riak_search_ce = zend_register_internal_class(&ce TSRMLS_CC);
+    zend_declare_property_null(riak_search_ce, "connection", sizeof("connection")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
+}
+/* }}} */
+
+
+/*************************************************************
+* Implementation: Riak\Search\Search
+*************************************************************/
+
+
+/* {{{ proto void Riak\Search->__construct(Riak\Connection $client)
+Create a new Search object */
+PHP_METHOD(Riak_Search, __construct)
+{
+    zval *zclient;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zclient) == FAILURE) {
+        return;
+    }
+    zend_update_property(riak_search_ce, getThis(), "connection", sizeof("connection")-1, zclient TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto Riak\Search\Output\Output Riak\Search->search(string $index, string $query[, Riak\Search\Input] $parameters)
+Create a new Search object */
+PHP_METHOD(Riak_Search, search)
+{
+    riak_connection *connection;
+    riack_search_optional_params search_params;
+    riack_search_result *search_result;
+    riack_string rsquery, rsindex;
+    char* index, *query;
+    int index_len, query_len, riackstatus;
+    zval *zclient, *zresult, *zparams = NULL;
+
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|o", &index, &index_len, &query, &query_len, &zparams) == FAILURE) {
+        return;
+    }
+    zclient = zend_read_property(riak_search_ce, getThis(), "connection", sizeof("connection")-1, 1 TSRMLS_CC);
+
+    connection = get_client_connection(zclient TSRMLS_CC);
+
+    THROW_EXCEPTION_IF_CONNECTION_IS_NULL(connection);
+
+    memset(&search_params, 0, sizeof(riack_search_optional_params));
+    rsquery.value = query;
+    rsquery.len = query_len;
+    rsindex.value = index;
+    rsindex.len = index_len;
+    riak_search_set_optional_params(connection->client, zparams, &search_params TSRMLS_CC);
+    RIACK_RETRY_OP(riackstatus, connection, riack_search(connection->client, &rsquery, &rsindex, &search_params, &search_result));
+    riak_search_free_optional_params(connection->client, &search_params TSRMLS_CC);
+    CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, riackstatus);
+    zresult = riak_search_output_from_riack_search_result(search_result TSRMLS_CC);
+    riack_free_search_result_p(connection->client, &search_result);
+
+    RETURN_ZVAL(zresult, 0, 1);
+}
+/* }}} */
+
+/*************************************************************
+* Helpers: Riak\Search\
+*************************************************************/
+
+#define RIAK_SEARCH_OPT_READ_PROP_AND_SET_STRING(ZPARAMS, PROPERTY_NAME, TARGET, ZTMP) \
+    ZTMP = zend_read_property(riak_search_input_ce, ZPARAMS, PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, 1 TSRMLS_CC); \
+    if (Z_TYPE_P(ZTMP) == IS_STRING) { \
+        TARGET##_present = 1; \
+        TARGET.len = Z_STRLEN_P(ZTMP); \
+        TARGET.value = Z_STRVAL_P(ZTMP); }
+
+#define RIAK_SEARCH_OPT_READ_PROP_AND_SET_LONG(ZPARAMS, PROPERTY_NAME, TARGET, ZTMP) \
+    ZTMP = zend_read_property(riak_search_input_ce, ZPARAMS, PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, 1 TSRMLS_CC); \
+    if (Z_TYPE_P(ZTMP) == IS_LONG) { \
+        TARGET##_present = 1; \
+        TARGET= Z_LVAL_P(ZTMP); }
+
+void riak_search_free_optional_params(riack_client *client, riack_search_optional_params* search_params TSRMLS_DC)
+{
+    size_t cnt = search_params->field_limits_count;
+    if (cnt > 0) {
+        RFREE(client, search_params->field_limits);
+        /* The actual strings was not copied so they do not need to be freed */
+    }
+}
+
+void riak_search_set_optional_params(riack_client *client, zval* zparams, riack_search_optional_params* search_params TSRMLS_DC)
+{
+    zval *zprop;
+    if (!zparams || Z_TYPE_P(zparams) == IS_NULL) {
+        return;
+    }
+    RIAK_SEARCH_OPT_READ_PROP_AND_SET_LONG(zparams, "rowLimit", search_params->rowlimit, zprop);
+    RIAK_SEARCH_OPT_READ_PROP_AND_SET_LONG(zparams, "start", search_params->start, zprop);
+    RIAK_SEARCH_OPT_READ_PROP_AND_SET_STRING(zparams, "sort", search_params->sort, zprop);
+    RIAK_SEARCH_OPT_READ_PROP_AND_SET_STRING(zparams, "filter", search_params->filter, zprop);
+    RIAK_SEARCH_OPT_READ_PROP_AND_SET_STRING(zparams, "defaultField", search_params->default_field, zprop);
+    RIAK_SEARCH_OPT_READ_PROP_AND_SET_STRING(zparams, "defaultOperation", search_params->default_operation, zprop);
+    RIAK_SEARCH_OPT_READ_PROP_AND_SET_STRING(zparams, "presort", search_params->presort, zprop);
+    zprop = zend_read_property(riak_search_input_ce, zparams, "fieldLimits", sizeof("fieldLimits")-1, 1 TSRMLS_CC); \
+    if (Z_TYPE_P(zprop) == IS_ARRAY) {
+        int i, cnt = zend_hash_num_elements(Z_ARRVAL_P(zprop));
+        if (cnt > 0) {
+            search_params->field_limits_count = cnt;
+            search_params->field_limits = RMALLOC(client, sizeof(riack_string) * cnt);
+            for (i=0; i<cnt; ++i) {
+                zval **zflpp;
+                /* important these string are not copied so only the array should be freed later */
+                if (zend_hash_index_find(Z_ARRVAL_P(zprop), i, (void**)&zflpp) == SUCCESS) {
+                    if (Z_TYPE_PP(zflpp) == IS_STRING) {
+                        search_params->field_limits[i].len = Z_STRLEN_PP(zflpp);
+                        search_params->field_limits[i].value = Z_STRVAL_PP(zflpp);
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/riak/search/search.h b/riak/search/search.h
new file mode 100644
index 0000000..79cd6a6
--- /dev/null
+++ b/riak/search/search.h
@@ -0,0 +1,37 @@
+/*
+   Copyright 2013 Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK_SEARCH__H__
+#define RIAK_SEARCH__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_search_ce;
+
+/* helpers */
+
+void riak_search_init(TSRMLS_D);
+void riak_search_set_optional_params(riack_client *client, zval* zparams, riack_search_optional_params* search_params TSRMLS_DC);
+void riak_search_free_optional_params(riack_client *client, riack_search_optional_params* search_params TSRMLS_DC);
+
+zval* riak_search_output_from_riack_search_result(riack_search_result *search_result TSRMLS_DC);
+
+/* Search */
+
+PHP_METHOD(Riak_Search, __construct);
+PHP_METHOD(Riak_Search, search);
+
+#endif
diff --git a/riak/server_info.c b/riak/server_info.c
new file mode 100644
index 0000000..fd80c10
--- /dev/null
+++ b/riak/server_info.c
@@ -0,0 +1,118 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+#include "server_info.h"
+#include "exception/exception.h"
+#include "connection.h"
+
+zend_class_entry *riak_server_info_ce;
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_server_info_ctor, 0, ZEND_RETURN_VALUE, 1)
+    ZEND_ARG_INFO(0, connection)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_riak_server_info_noargs, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry riak_server_info_methods[] = {
+    PHP_ME(Riak_Server_Info, __construct, arginfo_riak_server_info_ctor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+    PHP_ME(Riak_Server_Info, getNode, arginfo_riak_server_info_noargs, ZEND_ACC_PUBLIC)
+    PHP_ME(Riak_Server_Info, getServerVersion, arginfo_riak_server_info_noargs, ZEND_ACC_PUBLIC)
+    {NULL, NULL, NULL}
+};
+
+void riak_server_info_init(TSRMLS_D) /* {{{ */
+{
+    zend_class_entry ce;
+
+    INIT_NS_CLASS_ENTRY(ce, "Riak", "ServerInfo", riak_server_info_methods);
+    riak_server_info_ce = zend_register_internal_class(&ce TSRMLS_CC);
+
+    zend_declare_property_null(riak_server_info_ce, "connection", sizeof("connection")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
+}
+/* }}} */
+
+PHP_METHOD(Riak_Server_Info, __construct)/* {{{ */
+{
+    zval* zconnection;
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zconnection, riak_connection_ce) == FAILURE) {
+        zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC);
+        return;
+    }
+    zend_update_property(riak_server_info_ce, getThis(), "connection", sizeof("connection")-1, zconnection TSRMLS_CC);
+}
+/* }}} */
+
+int riak_get_server_info_as_zvals(riak_connection **connection, zval** znode,
+                                  zval **zserver_version, zval* zthis TSRMLS_DC)
+{
+    zval *zconn;
+    int riackresult;
+    riack_string *node, *server_version;
+    *zserver_version = *znode = 0;
+    node = 0;
+    server_version = 0;
+
+    zconn = zend_read_property(riak_server_info_ce, zthis, "connection", sizeof("connection")-1, 1 TSRMLS_CC);
+
+    *connection = get_client_connection(zconn TSRMLS_CC);
+
+    THROW_EXCEPTION_IF_CONNECTION_IS_NULL_WITH_RETURN(connection, riackresult);
+
+    riackresult = riack_server_info((*connection)->client, &node, &server_version);
+    if (riackresult == RIACK_SUCCESS) {
+        MAKE_STD_ZVAL(*znode);
+        ZVAL_STRINGL(*znode, node->value, node->len, 1);
+        MAKE_STD_ZVAL(*zserver_version);
+        ZVAL_STRINGL(*zserver_version, server_version->value, server_version->len, 1);
+    }
+    riack_free_string_p((*connection)->client, &node);
+    riack_free_string_p((*connection)->client, &server_version);
+    return riackresult;
+}
+
+PHP_METHOD(Riak_Server_Info, getNode)/* {{{ */
+{
+    riak_connection *connection;
+    zval *znode, *zserver;
+    int riackresult;
+    riackresult = riak_get_server_info_as_zvals(&connection, &znode, &zserver, getThis() TSRMLS_CC);
+    if (zserver) {
+        zval_ptr_dtor(&zserver);
+    }
+    if (riackresult != RIACK_SUCCESS) {
+        CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, riackresult);
+    } else {
+        RETURN_ZVAL(znode, 0, 1);
+    }
+}
+/* }}} */
+
+PHP_METHOD(Riak_Server_Info, getServerVersion)/* {{{ */
+{
+    riak_connection *connection;
+    zval *znode, *zserver;
+    int riackresult;
+    riackresult = riak_get_server_info_as_zvals(&connection, &znode, &zserver, getThis() TSRMLS_CC);
+    if (znode) {
+        zval_ptr_dtor(&znode);
+    }
+    if (riackresult != RIACK_SUCCESS) {
+        CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, riackresult);
+    } else {
+        RETURN_ZVAL(zserver, 0, 1);
+    }
+}
+/* }}} */
diff --git a/riak/server_info.h b/riak/server_info.h
new file mode 100644
index 0000000..36c7a26
--- /dev/null
+++ b/riak/server_info.h
@@ -0,0 +1,30 @@
+/*
+   Copyright 2013: Kaspar Bach Pedersen
+
+   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.
+*/
+
+#ifndef RIAK__SERVER_INFO__H__
+#define RIAK__SERVER_INFO__H__
+
+#include "php_riak_internal.h"
+
+extern zend_class_entry *riak_server_info_ce;
+
+void riak_server_info_init(TSRMLS_D);
+
+PHP_METHOD(Riak_Server_Info, __construct);
+PHP_METHOD(Riak_Server_Info, getNode);
+PHP_METHOD(Riak_Server_Info, getServerVersion);
+
+#endif //RIAK__SERVER_INFO__H__
diff --git a/riak_session.c b/riak_session.c
index be73d93..5c96fd5 100644
--- a/riak_session.c
+++ b/riak_session.c
@@ -15,17 +15,19 @@
    limitations under the License.
 */
 
-#include <php.h>
-#include <riack.h>
 #include "riak_session.h"
 
-// #ifdef PHP_SESSION
+#ifdef PHP_RIAK_SESSION
+
 #include <zend_exceptions.h>
-#include "connection.h"
-#include "bucket.h"
-#include "object.h"
-#include "req_inputs.h"
-#include "req_outputs.h"
+#include "riak/connection.h"
+#include "riak/bucket.h"
+#include "riak/object.h"
+#include "riak/object_list.h"
+#include "riak/input/delete_input.h"
+#include "riak/input/get_input.h"
+#include "riak/input/put_input.h"
+#include "riak/output/output.h"
 #include "SAPI.h"
 #include <ext/standard/php_string.h>
 #include <ext/standard/url.h>
@@ -58,6 +60,13 @@ typedef struct _riak_session_data {
    zval *zdelprops;
 } riak_session_data;
 
+PS_OPEN_FUNC(riak);
+PS_CLOSE_FUNC(riak);
+PS_READ_FUNC(riak);
+PS_WRITE_FUNC(riak);
+PS_DESTROY_FUNC(riak);
+PS_GC_FUNC(riak);
+
 ps_module ps_mod_riak = {
 	PS_MOD(riak)
 };
@@ -180,7 +189,7 @@ PS_CLOSE_FUNC(riak) /* {{{ */
 
 PS_READ_FUNC(riak) /* {{{ */
 {
-    zval *zoutput, *zkey, *zdata, *zex;
+    zval *zoutput, *zkey, *zdata;
     riak_session_data *data = PS_GET_MOD_DATA();
     *vallen = 0;
 
@@ -193,27 +202,25 @@ PS_READ_FUNC(riak) /* {{{ */
     RIAK_CALL_METHOD2(RiakBucket, get, zoutput, data->zbucket, zkey, data->zgetprops);
 
     if (!EG(exception) && Z_TYPE_P(zoutput) == IS_OBJECT) {
-        zval *zobjarr;
-
-        MAKE_STD_ZVAL(zobjarr);
-        RIAK_CALL_METHOD(Riak_Output_Output, getObjectList, zobjarr, zoutput);
-
-        if (Z_TYPE_P(zobjarr) == IS_ARRAY && zend_hash_num_elements(Z_ARRVAL_P(zobjarr)) > 0) {
-            zval **found = NULL;
-
-            zend_hash_index_find(Z_ARRVAL_P(zobjarr), 0, (void**)&found);
-
-            zdata = zend_read_property(riak_object_ce, *found, "content", sizeof("content")-1, 1 TSRMLS_CC);
-
-            if (zdata->type == IS_STRING && Z_STRLEN_P(zdata) > 0) {
-                *vallen = Z_STRLEN_P(zdata);
-                *val = emalloc(Z_STRLEN_P(zdata));
-
-                memcpy(*val, Z_STRVAL_P(zdata), Z_STRLEN_P(zdata));
+        zval *zobjlist;
+
+        MAKE_STD_ZVAL(zobjlist);
+        RIAK_CALL_METHOD(Riak_Output_Output, getObjectList, zobjlist, zoutput);
+        if (Z_TYPE_P(zobjlist) == IS_OBJECT) {
+            zval *zobject;
+            MAKE_STD_ZVAL(zobject);
+            RIAK_CALL_METHOD(Riak_Object_List, first, zobject, zobjlist);
+            if (Z_TYPE_P(zobject) == IS_OBJECT) {
+                zdata = zend_read_property(riak_object_ce, zobject, "content", sizeof("content")-1, 1 TSRMLS_CC);
+                if (zdata->type == IS_STRING && Z_STRLEN_P(zdata) > 0) {
+                    *vallen = Z_STRLEN_P(zdata);
+                    *val = emalloc(Z_STRLEN_P(zdata));
+                    memcpy(*val, Z_STRVAL_P(zdata), Z_STRLEN_P(zdata));
+                }
             }
+            zval_ptr_dtor(&zobject);
         }
-
-        zval_ptr_dtor(&zobjarr);
+        zval_ptr_dtor(&zobjlist);
     } else if (EG(exception)) {
         zend_clear_exception(TSRMLS_C);
     }
@@ -277,5 +284,4 @@ PS_GC_FUNC(riak) /* {{{ */
 }
 /* }}} */
 
-//#endif
-
+#endif // PHP_RIAK_SESSION
diff --git a/riak_session.h b/riak_session.h
index ef5c5cb..0c22669 100644
--- a/riak_session.h
+++ b/riak_session.h
@@ -18,10 +18,10 @@
 #ifndef RIAK_SESSION__H__
 #define RIAK_SESSION__H__
 
-#include "php_riak.h"
+#include "php_riak_internal.h"
 #include "ext/session/php_session.h"
 
-#ifdef PHP_SESSION
+#ifdef PHP_RIAK_SESSION
 
 PS_FUNCS(riak);
 
diff --git a/script/configure-riak.php b/script/configure-riak.php
new file mode 100644
index 0000000..3527cc3
--- /dev/null
+++ b/script/configure-riak.php
@@ -0,0 +1,14 @@
+<?php
+//  {riak_search, [
+//                %% To enable Search functionality set this 'true'.
+//                {enabled, false}
+//               ]},
+//-->
+//  {riak_search, [
+//                %% To enable Search functionality set this 'true'.
+//                {enabled, true}
+//               ]},
+
+//            {storage_backend, riak_kv_bitcask_backend},
+//-->
+//            {storage_backend, riak_kv_eleveldb_backend},
\ No newline at end of file
diff --git a/search.c b/search.c
deleted file mode 100644
index 7f9d925..0000000
--- a/search.c
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
-   Copyright 2013 Kaspar Bach Pedersen
-
-   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.
-*/
-#include <php.h>
-#include <riack.h>
-#include "php_riak.h"
-#include "connection.h"
-#include "search.h"
-
-zend_class_entry *riak_search_ce;
-zend_class_entry *riak_search_input_ce;
-zend_class_entry *riak_search_output_ce;
-zend_class_entry *riak_search_doc_ce;
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_search_ctor, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, client)
-ZEND_END_ARG_INFO()
-
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_search_search, 0, ZEND_RETURN_VALUE, 2)
-    ZEND_ARG_INFO(0, index)
-    ZEND_ARG_INFO(0, query)
-    ZEND_ARG_INFO(0, parameters)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_search_input_setrowlimit, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, rowlimit)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_search_input_setstart, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, start)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_search_input_setsort, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, sort)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_search_input_setfilter, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, sort)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_search_input_setdefaultfield, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, defaultfield)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_search_input_setdefaultop, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, defaultop)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_search_input_setpresort, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, presort)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_search_input_setfieldlimit, 0, ZEND_RETURN_VALUE, 1)
-    ZEND_ARG_INFO(0, fieldlimit)
-ZEND_END_ARG_INFO()
-
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_search_noargs, 0, ZEND_RETURN_VALUE, 0)
-ZEND_END_ARG_INFO()
-
-static zend_function_entry riak_search_methods[] = {
-    PHP_ME(Riak_Search, __construct, arginfo_search_ctor, ZEND_ACC_CTOR | ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Search, search, arginfo_search_search, ZEND_ACC_PUBLIC)
-    {NULL, NULL, NULL}
-};
-
-
-static zend_function_entry riak_search_output_methods[] = {
-    PHP_ME(Riak_Search_Output_Output, hasMaxScore, arginfo_search_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Search_Output_Output, getMaxScore, arginfo_search_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Search_Output_Output, hasNumFound, arginfo_search_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Search_Output_Output, getNumFound, arginfo_search_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Search_Output_Output, getDocuments, arginfo_search_noargs, ZEND_ACC_PUBLIC)
-    {NULL, NULL, NULL}
-};
-
-
-static zend_function_entry riak_search_input_methods[] = {
-    PHP_ME(Riak_Search_Input, setRowLimit, arginfo_search_input_setrowlimit, ZEND_ACC_CTOR | ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Search_Input, getRowLimit, arginfo_search_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Search_Input, setStartOffset, arginfo_search_input_setstart, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Search_Input, getStartOffset, arginfo_search_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Search_Input, setSort, arginfo_search_input_setsort, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Search_Input, getSort, arginfo_search_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Search_Input, setFilter, arginfo_search_input_setfilter, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Search_Input, getFilter, arginfo_search_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Search_Input, setDefaultField, arginfo_search_input_setdefaultfield, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Search_Input, getDefaultField, arginfo_search_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Search_Input, setDefaultOperation, arginfo_search_input_setdefaultop, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Search_Input, getDefaultOperation, arginfo_search_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Search_Input, setPresort, arginfo_search_input_setpresort, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Search_Input, getPresort, arginfo_search_noargs, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Search_Input, setFieldLimits, arginfo_search_input_setfieldlimit, ZEND_ACC_PUBLIC)
-    PHP_ME(Riak_Search_Input, getFieldLimits, arginfo_search_noargs, ZEND_ACC_PUBLIC)
-    {NULL, NULL, NULL}
-};
-
-static zend_function_entry riak_search_doc_methods[] = {
-    PHP_ME(Riak_Search_Output_DocumentOutput, getFields, arginfo_search_noargs, ZEND_ACC_PUBLIC)
-    {NULL, NULL, NULL}
-};
-
-void riak_search_init(TSRMLS_D) /* {{{ */
-{
-    zend_class_entry ce;
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\Search", "Search", riak_search_methods);
-    riak_search_ce = zend_register_internal_class(&ce TSRMLS_CC);
-    zend_declare_property_null(riak_search_ce, "connection", sizeof("connection")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-
-
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\Search\\Input", "ParameterBag", riak_search_input_methods);
-    riak_search_input_ce = zend_register_internal_class(&ce TSRMLS_CC);
-    zend_declare_property_null(riak_search_input_ce, "rowLimit", sizeof("rowLimit")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_search_input_ce, "start", sizeof("start")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_search_input_ce, "sort", sizeof("sort")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_search_input_ce, "filter", sizeof("filter")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_search_input_ce, "defaultField", sizeof("defaultField")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_search_input_ce, "defaultOperation", sizeof("defaultOperation")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_search_input_ce, "presort", sizeof("presort")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-    zend_declare_property_null(riak_search_input_ce, "fieldLimits", sizeof("fieldLimits")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
-
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\Search\\Output", "Output", riak_search_output_methods);
-    riak_search_output_ce = zend_register_internal_class(&ce TSRMLS_CC);
-    zend_declare_property_null(riak_search_output_ce, "maxScore", sizeof("maxScore")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
-    zend_declare_property_null(riak_search_output_ce, "numFound", sizeof("numFound")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
-    zend_declare_property_null(riak_search_output_ce, "documents", sizeof("documents")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
-
-    INIT_NS_CLASS_ENTRY(ce, "Riak\\Search\\Output", "DocumentOutput", riak_search_doc_methods);
-    riak_search_doc_ce = zend_register_internal_class(&ce TSRMLS_CC);
-    zend_declare_property_null(riak_search_doc_ce, "fields", sizeof("fields")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
-}
-/* }}} */
-
-
-/*************************************************************
-* Implementation: Riak\Search\Search
-*************************************************************/
-
-
-/* {{{ proto void Riak\Search->__construct(Riak\Connection $client)
-Create a new Search object */
-PHP_METHOD(Riak_Search, __construct)
-{
-    zval *zclient;
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zclient) == FAILURE) {
-        return;
-    }
-    zend_update_property(riak_search_ce, getThis(), "connection", sizeof("connection")-1, zclient TSRMLS_CC);
-}
-/* }}} */
-
-/* {{{ proto Riak\Search\Output\Output Riak\Search->search(string $index, string $query[, Riak\Search\Input] $parameters)
-Create a new Search object */
-PHP_METHOD(Riak_Search, search)
-{
-    riak_connection *connection;
-    struct RIACK_SEARCH_OPTIONAL_PARAMETERS search_params;
-    struct RIACK_SEARCH_RESULT search_result;
-    RIACK_STRING rsquery, rsindex;
-    char* index, *query;
-    int index_len, query_len, riackstatus;
-    zval *zclient, *zresult, *zparams = NULL;
-
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|o", &index, &index_len, &query, &query_len, &zparams) == FAILURE) {
-        return;
-    }
-    zclient = zend_read_property(riak_search_ce, getThis(), "connection", sizeof("connection")-1, 1 TSRMLS_CC);
-    GET_RIAK_CONNECTION(zclient, connection);
-    memset(&search_params, 0, sizeof(struct RIACK_SEARCH_OPTIONAL_PARAMETERS));
-    rsquery.value = query;
-    rsquery.len = query_len;
-    rsindex.value = index;
-    rsindex.len = index_len;
-    riak_search_set_optional_params(connection->client, zparams, &search_params TSRMLS_CC);
-    riackstatus = riack_search(connection->client, rsquery, rsindex, &search_params, &search_result);
-    riak_search_free_optional_params(connection->client, &search_params TSRMLS_CC);
-    CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, riackstatus);
-    zresult = riak_search_output_from_riack_search_result(&search_result TSRMLS_CC);
-    riack_free_search_result(connection->client, &search_result);
-
-    RETURN_ZVAL(zresult, 0, 1);
-}
-/* }}} */
-
-/*************************************************************
-* Implementation: Riak\Search\Output\Output
-*************************************************************/
-
-zval* riak_search_output_from_riack_search_result(struct RIACK_SEARCH_RESULT *search_result TSRMLS_DC)
-{
-    zval *zresult;
-    MAKE_STD_ZVAL(zresult);
-    object_init_ex(zresult, riak_search_output_ce);
-    if (search_result->document_count > 0) {
-        int cnt, i;
-        zval* zdocs;
-        cnt = search_result->document_count;
-        MAKE_STD_ZVAL(zdocs);
-        array_init(zdocs);
-        for (i=0; i<cnt; ++i) {
-            zval* doc = riak_search_document_from_riack_document(&search_result->documents[i] TSRMLS_CC);
-            add_next_index_zval(zdocs, doc);
-        }
-        zend_update_property(riak_search_output_ce, zresult, "documents", sizeof("documents")-1, zdocs TSRMLS_CC);
-        zval_ptr_dtor(&zdocs);
-    }
-    if (search_result->max_score_present) {
-        zend_update_property_double(riak_search_output_ce, zresult, "maxScore", sizeof("maxScore")-1, search_result->max_score TSRMLS_CC);
-    }
-    if (search_result->num_found_present) {
-        zend_update_property_long(riak_search_output_ce, zresult, "numFound", sizeof("numFound")-1, search_result->num_found TSRMLS_CC);
-    }
-    return zresult;
-}
-
-PHP_METHOD(Riak_Search_Output_Output, hasMaxScore)
-{
-    zval *zprop = zend_read_property(riak_search_output_ce, getThis(), "maxScore", sizeof("maxScore"), 1 TSRMLS_CC);
-    if (!zprop || Z_TYPE_P(zprop) == IS_NULL) {
-        RETURN_BOOL(0);
-    }
-    RETURN_BOOL(1);
-}
-
-PHP_METHOD(Riak_Search_Output_Output, getMaxScore)
-{
-    RIAK_GETTER_DOUBLE(riak_search_output_ce, "maxScore");
-}
-
-PHP_METHOD(Riak_Search_Output_Output, hasNumFound)
-{
-    zval *zprop = zend_read_property(riak_search_output_ce, getThis(), "numFound", sizeof("numFound"), 1 TSRMLS_CC);
-    if (zprop == NULL || Z_TYPE_P(zprop) == IS_NULL) {
-        RETURN_BOOL(0);
-    }
-    RETURN_BOOL(1);
-}
-
-PHP_METHOD(Riak_Search_Output_Output, getNumFound)
-{
-    RIAK_GETTER_LONG(riak_search_output_ce, "numFound");
-}
-
-PHP_METHOD(Riak_Search_Output_Output, getDocuments)
-{
-    RIAK_GETTER_ARRAY(riak_search_output_ce, "documents");
-}
-
-/*************************************************************
-* Implementation: Riak\Search\Output\DocumentOutput
-*************************************************************/
-zval *riak_search_document_from_riack_document(struct RIACK_SEARCH_DOCUMENT* document TSRMLS_DC)
-{
-    int cnt, i;
-    zval *zresult, *zarr;
-    MAKE_STD_ZVAL(zarr)
-    array_init(zarr);
-
-    MAKE_STD_ZVAL(zresult)
-    object_init_ex(zresult, riak_search_doc_ce);
-
-    cnt = document->field_count;
-    for (i=0; i<cnt; ++i) {
-        char* szkey;
-        size_t key_len;
-        struct RIACK_PAIR *current_pair = &document->fields[i];
-        key_len = current_pair->key.len;
-        // Silly... we need to make a copy because add_assoc relies on zero terminated string
-        // riack will not zero terminate since it includes a length.
-        // However estrndup will be nice enough to add a zero termination for us...
-        szkey = estrndup(current_pair->key.value, key_len);
-        if (current_pair->value_present) {
-            add_assoc_stringl_ex(zarr, szkey, key_len + 1,
-                                 (char*)current_pair->value, current_pair->value_len, 1);
-        } else {
-            add_assoc_null_ex(zarr,  szkey, key_len+1);
-        }
-        efree(szkey);
-    }
-    zend_update_property(riak_search_doc_ce, zresult, "fields", sizeof("fields")-1, zarr TSRMLS_CC);
-    zval_ptr_dtor(&zarr);
-    return zresult;
-}
-
-PHP_METHOD(Riak_Search_Output_DocumentOutput, getFields)
-{
-    RIAK_GETTER_ARRAY(riak_search_doc_ce, "fields");
-}
-
-/*************************************************************
-* Implementation: Riak\Search\Input\ParameterBag
-*************************************************************/
-
-/* {{{ proto Riak\Search\Input\ParameterBag Riak\Search\Input\ParameterBag->setRowLimit(int $rowLimit)
-Set row limit for search */
-PHP_METHOD(Riak_Search_Input, setRowLimit)
-{
-    RIAK_SETTER_LONG(riak_search_input_ce, "rowLimit");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto int|null Riak\Search\Input\ParameterBag->getRowLimit()
-Set row limit for search */
-PHP_METHOD(Riak_Search_Input, getRowLimit)
-{
-    RIAK_GETTER_LONG(riak_search_input_ce, "rowLimit");
-}
-/* }}} */
-
-/* {{{ proto Riak\Search\Input\ParameterBag Riak\Search\Input\ParameterBag->setStartOffset(int $startOffset)
-Set start offset for this search */
-PHP_METHOD(Riak_Search_Input, setStartOffset)
-{
-    RIAK_SETTER_LONG(riak_search_input_ce, "start");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto int|null Riak\Search\Input\ParameterBag->getStartOffset()
-Get start offset */
-PHP_METHOD(Riak_Search_Input, getStartOffset)
-{
-    RIAK_GETTER_LONG(riak_search_input_ce, "start");
-}
-/* }}} */
-
-/* {{{ proto Riak\Search\Input\ParameterBag Riak\Search\Input\ParameterBag->setSort(string $sort)
-Set the sort string */
-PHP_METHOD(Riak_Search_Input, setSort)
-{
-    RIAK_SETTER_STRING(riak_search_input_ce, "sort");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto string|null Riak\Search\Input\ParameterBag->getSort()
-Get the sort string */
-PHP_METHOD(Riak_Search_Input, getSort)
-{
-    RIAK_GETTER_STRING(riak_search_input_ce, "sort");
-}
-/* }}} */
-
-/* {{{ proto Riak\Search\Input\ParameterBag Riak\Search\Input\ParameterBag->setFilter(string $filter)
-Set the filter string */
-PHP_METHOD(Riak_Search_Input, setFilter)
-{
-    RIAK_SETTER_STRING(riak_search_input_ce, "filter");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto string|null Riak\Search\Input\ParameterBag->getFilter()
-Get the filter string */
-PHP_METHOD(Riak_Search_Input, getFilter)
-{
-    RIAK_GETTER_STRING(riak_search_input_ce, "filter");
-}
-/* }}} */
-
-/* {{{ proto Riak\Search\Input\ParameterBag Riak\Search\Input\ParameterBag->setDefaultField(string $defaultField)
-Set the default field name */
-PHP_METHOD(Riak_Search_Input, setDefaultField)
-{
-    RIAK_SETTER_STRING(riak_search_input_ce, "defaultField");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto string|null Riak\Search\Input\ParameterBag->getDefaultField()
-Get the default field name */
-PHP_METHOD(Riak_Search_Input, getDefaultField)
-{
-    RIAK_GETTER_STRING(riak_search_input_ce, "defaultField");
-}
-/* }}} */
-
-/* {{{ proto Riak\Search\Input\ParameterBag Riak\Search\Input\ParameterBag->setDefaultOperation(string $defaultOperation)
-Set the default opereration */
-PHP_METHOD(Riak_Search_Input, setDefaultOperation)
-{
-    RIAK_SETTER_STRING(riak_search_input_ce, "defaultOperation");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto string|null Riak\Search\Input\ParameterBag->getDefaultOperation()
-Get the default operation */
-PHP_METHOD(Riak_Search_Input, getDefaultOperation)
-{
-    RIAK_GETTER_STRING(riak_search_input_ce, "defaultOperation");
-}
-/* }}} */
-
-/* {{{ proto Riak\Search\Input\ParameterBag Riak\Search\Input\ParameterBag->setPresort(string $presort)
-Set the presort string */
-PHP_METHOD(Riak_Search_Input, setPresort)
-{
-    RIAK_SETTER_STRING(riak_search_input_ce, "presort");
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto string|null Riak\Search\Input\ParameterBag->getPresort()
-Get the presort string */
-PHP_METHOD(Riak_Search_Input, getPresort)
-{
-    RIAK_GETTER_STRING(riak_search_input_ce, "presort");
-}
-/* }}} */
-
-/* {{{ proto Riak\Search\Input\ParameterBag Riak\Search\Input\ParameterBag->setFieldLimits(array $fieldLimits)
-Set field limits */
-PHP_METHOD(Riak_Search_Input, setFieldLimits)
-{
-    zval* zlimits;
-    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &zlimits) == FAILURE) {
-        return;
-    }
-    zend_update_property(riak_search_input_ce, getThis(), "fieldLimits", sizeof("fieldLimits")-1, zlimits TSRMLS_CC);
-    RIAK_RETURN_THIS
-}
-/* }}} */
-
-/* {{{ proto array|null Riak\Search\Input\ParameterBag->getFieldLimits()
-Get the field limits array */
-PHP_METHOD(Riak_Search_Input, getFieldLimits)
-{
-    zval* zlimits = zend_read_property(riak_search_input_ce, getThis(), "fieldLimits", sizeof("fieldLimits")-1, 1 TSRMLS_CC);
-    if (Z_TYPE_P(zlimits) == IS_ARRAY) {
-        RETURN_ZVAL(zlimits, 1, 0);
-    }
-    RETURN_NULL();
-}
-/* }}} */
-
-/*************************************************************
-* Helpers: Riak\Search\
-*************************************************************/
-
-#define RIAK_SEARCH_OPT_READ_PROP_AND_SET_STRING(ZPARAMS, PROPERTY_NAME, TARGET, ZTMP) \
-    ZTMP = zend_read_property(riak_search_input_ce, ZPARAMS, PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, 1 TSRMLS_CC); \
-    if (Z_TYPE_P(ZTMP) == IS_STRING) { \
-        TARGET##_present = 1; \
-        TARGET.len = Z_STRLEN_P(ZTMP); \
-        TARGET.value = Z_STRVAL_P(ZTMP); }
-
-#define RIAK_SEARCH_OPT_READ_PROP_AND_SET_LONG(ZPARAMS, PROPERTY_NAME, TARGET, ZTMP) \
-    ZTMP = zend_read_property(riak_search_input_ce, ZPARAMS, PROPERTY_NAME, sizeof(PROPERTY_NAME)-1, 1 TSRMLS_CC); \
-    if (Z_TYPE_P(ZTMP) == IS_LONG) { \
-        TARGET##_present = 1; \
-        TARGET= Z_LVAL_P(ZTMP); }
-
-void riak_search_free_optional_params(struct RIACK_CLIENT *client, struct RIACK_SEARCH_OPTIONAL_PARAMETERS* search_params TSRMLS_DC)
-{
-    size_t cnt = search_params->field_limits_count;
-    if (cnt > 0) {
-        RFREE(client, search_params->field_limits);
-        /* The actual strings was not copied so they do not need to be freed */
-    }
-}
-
-void riak_search_set_optional_params(struct RIACK_CLIENT *client, zval* zparams, struct RIACK_SEARCH_OPTIONAL_PARAMETERS* search_params TSRMLS_DC)
-{
-    zval *zprop;
-    if (!zparams || Z_TYPE_P(zparams) == IS_NULL) {
-        return;
-    }
-    RIAK_SEARCH_OPT_READ_PROP_AND_SET_LONG(zparams, "rowLimit", search_params->rowlimit, zprop);
-    RIAK_SEARCH_OPT_READ_PROP_AND_SET_LONG(zparams, "start", search_params->start, zprop);
-    RIAK_SEARCH_OPT_READ_PROP_AND_SET_STRING(zparams, "sort", search_params->sort, zprop);
-    RIAK_SEARCH_OPT_READ_PROP_AND_SET_STRING(zparams, "filter", search_params->filter, zprop);
-    RIAK_SEARCH_OPT_READ_PROP_AND_SET_STRING(zparams, "defaultField", search_params->default_field, zprop);
-    RIAK_SEARCH_OPT_READ_PROP_AND_SET_STRING(zparams, "defaultOperation", search_params->default_operation, zprop);
-    RIAK_SEARCH_OPT_READ_PROP_AND_SET_STRING(zparams, "presort", search_params->presort, zprop);
-    zprop = zend_read_property(riak_search_input_ce, zparams, "fieldLimits", sizeof("fieldLimits")-1, 1 TSRMLS_CC); \
-    if (Z_TYPE_P(zprop) == IS_ARRAY) {
-        int i, cnt = zend_hash_num_elements(Z_ARRVAL_P(zprop));
-        if (cnt > 0) {
-            search_params->field_limits_count = cnt;
-            search_params->field_limits = RMALLOC(client, sizeof(RIACK_STRING) * cnt);
-            for (i=0; i<cnt; ++i) {
-                zval **zflpp;
-                /* important these string are not copied so only the array should be freed later */
-                if (zend_hash_index_find(Z_ARRVAL_P(zprop), i, (void**)&zflpp) == SUCCESS) {
-                    if (Z_TYPE_PP(zflpp) == IS_STRING) {
-                        search_params->field_limits[i].len = Z_STRLEN_PP(zflpp);
-                        search_params->field_limits[i].value = Z_STRVAL_PP(zflpp);
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/tests/bucket.phpt b/tests/bucket.phpt
index 62f0548..ca724ae 100644
--- a/tests/bucket.phpt
+++ b/tests/bucket.phpt
@@ -5,9 +5,14 @@ Test Riak\Bucket throws exception when connection is NULL
 
 try {
     $connection = null;
-    $bucket     = new \Riak\Bucket($connection, 'test');
+    $bucket     = new \Riak\Bucket($connection, 'test', 'phpriak_type');
 
-    echo "done!" . PHP_EOL;
+    if ($bucket->getType() != 'phpriak_type') {
+        echo "type mismatch " . $bucket->getType() . PHP_EOL;
+    }
+    if ($bucket->getName() == 'test') {
+        echo "done!" . PHP_EOL;
+    }
 } catch (\Riak\Exception\BadArgumentsException $e) {
     echo $e->getMessage();
 }
@@ -15,4 +20,4 @@ try {
 ?>
 --EXPECTF--
 Warning: Riak\Bucket::__construct() expects parameter 1 to be Riak\Connection, null given in %s on line %d
-First parameter must be an instance of Riak\Connection.
+Bad or missing argument
diff --git a/tests/bucket_props_ext.phpt b/tests/bucket_props_ext.phpt
index 5dbe2d2..5f140b4 100644
--- a/tests/bucket_props_ext.phpt
+++ b/tests/bucket_props_ext.phpt
@@ -3,9 +3,10 @@ Test bucket properties
 --FILE--
 <?php
 use \Riak\BucketPropertyList;
+use \Riak\Property\ReplicationMode as RM;
 include_once "connect.inc";
 $client = new \Riak\Connection($host, $port);
-$bucket = new \Riak\Bucket($client, "test_bucket_asdf_props_ext");
+$bucket = new \Riak\Bucket($client, "test_bucket_asdf_props_ext", "phpriak_type");
 $oldProps = $bucket->getPropertyList();
 
 $newProps = new BucketPropertyList();
@@ -19,7 +20,8 @@ $newProps->setSearchEnabled(true)
          ->setRW(1)
          ->setDW(1)
          ->setPostCommitHookList($postCommitHooks)
-         ->setBigVClock(5000);
+         ->setBigVClock(5000)
+         ->setReplicationMode(new RM\FullSyncOnly());
 
 $bucket->setPropertyList($newProps);
 $currentProps = $bucket->getPropertyList();
@@ -34,6 +36,10 @@ if ($currentProps->getNValue() === 1 &&
     $postHooks = $currentProps->getPostCommitHookList();
     $foundJs = false;
     $foundErl = false;
+    $replMode = $currentProps->getReplicationMode();
+    if (!is_a($replMode, 'Riak\Property\ReplicationMode\FullSyncOnly')) {
+        var_dump($replMode);
+    }
     foreach ($postHooks as $hook) {
         if ($hook->isJavascript() && $hook->getJsName() == "js_name") {
             $foundJs = true;
diff --git a/tests/builtin_conflict_resolver_db_objs.phpt b/tests/builtin_conflict_resolver_db_objs.phpt
new file mode 100644
index 0000000..e7d38bc
--- /dev/null
+++ b/tests/builtin_conflict_resolver_db_objs.phpt
@@ -0,0 +1,36 @@
+--TEST--
+Test built-in conflict resolvers with real db fetch
+--FILE--
+<?php
+
+include_once "connect.inc";
+
+use Riak\ObjectList;
+use Riak\Output\ConflictResolver;
+
+$client   = new \Riak\Connection($host, $port);
+$bucket   = new \Riak\Bucket($client, 'test_bucket');
+$props    = new \Riak\BucketPropertyList();
+$props->setAllowMult(true);
+$props->setLastWriteWins(false);
+
+$youngestResolver = new \Riak\Output\YoungestSiblingResolver();
+$bucket->setConflictResolver($youngestResolver);
+
+// Put two objects on same key with no vclocks
+$object1  = new \Riak\Object('key_conflict');
+$object1->setContent("content_1");
+$object2  = new \Riak\Object('key_conflict');
+$object2->setContent("content_2");
+$bucket->put($object1);
+sleep(1);
+$bucket->put($object2);
+
+$getOutput = $bucket->get('key_conflict');
+$winner = $getOutput->getObject();
+echo "Resolve youngest : " . var_export($winner->getContent() == "content_2", true) . PHP_EOL;
+
+$bucket->delete($winner);
+?>
+--EXPECT--
+Resolve youngest : true
diff --git a/tests/builtin_conflict_resolvers.phpt b/tests/builtin_conflict_resolvers.phpt
new file mode 100644
index 0000000..7b80ea0
--- /dev/null
+++ b/tests/builtin_conflict_resolvers.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Test built-in conflict resolvers
+--FILE--
+<?php
+
+include_once "connect.inc";
+
+use Riak\ObjectList;
+use Riak\Output\ConflictResolver;
+
+$youngestResolver = new \Riak\Output\YoungestSiblingResolver();
+
+$object1  = new \Riak\Object('key_1');
+$object2  = new \Riak\Object('key_2');
+$object3  = new \Riak\Object('key_3');
+$list     = new \Riak\ObjectList();
+
+echo "Resolve empty : " . var_export($youngestResolver->resolve($list), true) . PHP_EOL;
+
+$list[] = $object1;
+$list[] = $object2;
+$list[] = $object3;
+
+echo "Is a resolver : " . var_export($youngestResolver instanceof ConflictResolver, true) . PHP_EOL;
+echo "Resolve youngest : " . var_export($youngestResolver->resolve($list) === $object1, true) . PHP_EOL;
+
+?>
+--EXPECT--
+Resolve empty : NULL
+Is a resolver : true
+Resolve youngest : true
diff --git a/tests/client_ctor.phpt b/tests/client_ctor.phpt
index 02cf5be..57d1147 100644
--- a/tests/client_ctor.phpt
+++ b/tests/client_ctor.phpt
@@ -5,15 +5,21 @@ Basic riak connection
 use \Riak\Exception\ConnectionException;
 include_once "connect.inc";
 try {
-	$riak = new \Riak\Connection($host, $port);
-	if (isset($riak)) {
-		echo "done!".PHP_EOL;
-	}
-	$riak = new \Riak\Connection("255.255.255.255");
+    $riak1 = new \Riak\Connection($host, $port);
+    $riak2 = new \Riak\Connection("255.255.255.255");
+
+    $riak1->ping();
+
+    echo "done!"  .PHP_EOL;
+
+    $riak2->ping();
+
+    echo "fail!"  .PHP_EOL;
+
 } catch (ConnectionException $e) {
-	echo "Connection error!".PHP_EOL;
+    echo $e->getMessage() . PHP_EOL;
 }
 ?>
 --EXPECT--
 done!
-Connection error!
+Connection error
diff --git a/tests/conflict_resolver_bucket.phpt b/tests/conflict_resolver_bucket.phpt
new file mode 100644
index 0000000..3e20a85
--- /dev/null
+++ b/tests/conflict_resolver_bucket.phpt
@@ -0,0 +1,87 @@
+--TEST--
+Test bucket conflict resolver
+--FILE--
+<?php
+
+include_once "connect.inc";
+
+use Riak\ObjectList;
+use Riak\Output\ConflictResolver;
+
+class MyResolver implements ConflictResolver 
+{
+    public function resolve(ObjectList $objects)
+    {
+        $winner = $objects->first();
+        $value  = 0;
+
+        foreach ($objects as $object) {
+            $value += intval($object->getContent());
+        }
+
+        $winner->setContent($value);
+
+        return $winner;
+    }
+}
+
+$key      = uniqid();
+$resolver = new MyResolver();
+$object1  = new \Riak\Object($key);
+$object2  = new \Riak\Object($key);
+$client   = new \Riak\Connection($host, $port);
+$bucket   = new \Riak\Bucket($client, 'test_bucket');
+$props    = new \Riak\BucketPropertyList($nVal = 1, $allowMult = true);
+
+$bucket->setPropertyList($props);
+$object1->setContent(1);
+$object2->setContent(2);
+$bucket->delete($key);
+
+$output = $bucket->get($key);
+$object = $output->getObject();
+
+echo "Has object        : " . var_export($output->hasObject(), true) . PHP_EOL;
+echo "Retrieve null     : " . var_export($object, true) . PHP_EOL;
+
+$bucket->put($object1);
+
+$output = $bucket->get($key);
+$object = $output->getObject();
+
+echo "Has Siblings      : " . var_export($bucket->get($key)->hasSiblings(), true) . PHP_EOL;
+echo "Has object        : " . var_export($bucket->get($key)->hasObject(), true) . PHP_EOL;
+echo "Unique count      : " . count($bucket->get($key)->getObjectList()) . PHP_EOL;
+echo "Retrieve unique   : " . var_export($object instanceof \Riak\Object, true) . PHP_EOL;
+
+$bucket->put($object2);
+$bucket->setConflictResolver($resolver);
+
+$output = $bucket->get($key);
+$object = $output->getObject();
+// New put the winner back
+$bucket->put($object);
+
+echo "Has object        : " . var_export($output->hasObject(), true) . PHP_EOL;
+echo "Siblings          : " . count($output->getObjectList()) . PHP_EOL;
+echo "Get/Set Resolver  : " . var_export($resolver === $bucket->getConflictResolver(), true) . PHP_EOL;
+echo "Winner value      : " . $object->getContent() . PHP_EOL;
+echo "Has Siblings      : " . var_export($bucket->get($key)->hasSiblings(), true) . PHP_EOL;
+echo "Read Winner       : " . $bucket->get($key)->getFirstObject()->getContent() . PHP_EOL;
+
+$bucket->delete($key);
+
+?>
+--EXPECT--
+Has object        : false
+Retrieve null     : NULL
+Has Siblings      : false
+Has object        : true
+Unique count      : 1
+Retrieve unique   : true
+Has object        : true
+Siblings          : 2
+Get/Set Resolver  : true
+Winner value      : 3
+Has Siblings      : false
+Read Winner       : 3
diff --git a/tests/conflict_resolver_exception.phpt b/tests/conflict_resolver_exception.phpt
new file mode 100644
index 0000000..09655fc
--- /dev/null
+++ b/tests/conflict_resolver_exception.phpt
@@ -0,0 +1,95 @@
+--TEST--
+Test conflict resolver exceptions
+--FILE--
+<?php
+
+include_once "connect.inc";
+
+use Riak\ObjectList;
+use Riak\Output\ConflictResolver;
+
+class DummyResolver implements ConflictResolver 
+{
+    public $return;
+
+    public function __constructor($return = null)
+    {
+        $this->return = $return;
+    }
+
+    public function resolve(ObjectList $objects)
+    {
+        return $this->return;
+    }
+}
+
+$key      = uniqid();
+$resolver = new DummyResolver();
+$object1  = new \Riak\Object($key);
+$object2  = new \Riak\Object($key);
+$client   = new \Riak\Connection($host, $port);
+$props    = new \Riak\BucketPropertyList($nVal = 1, $allowMult = true);
+$bucket   = new \Riak\Bucket($client, 'test_bucket');
+
+$bucket->setPropertyList($props);
+$object1->setContent(1);
+$object2->setContent(2);
+
+$bucket->put($object1);
+$bucket->put($object2);
+
+try {
+    $output = $bucket->get($key);
+    $object = $output->getObject();
+} catch (Exception $e) {
+    echo get_class($e) . ' : ' . $e->getMessage() . PHP_EOL;
+}
+
+
+$bucket->setConflictResolver($resolver);
+
+try {
+    $resolver->return = new \Riak\Object();
+
+    $output = $bucket->get($key);
+    $object = $output->getObject();
+} catch (Exception $e) {
+    echo get_class($e) . ' : ' . $e->getMessage() . PHP_EOL;
+}
+
+try {
+    $resolver->return = new \stdClass();
+
+    $output = $bucket->get($key);
+    $object = $output->getObject();
+} catch (Exception $e) {
+    echo get_class($e) . ' : ' . $e->getMessage() . PHP_EOL;
+}
+
+try {
+    $resolver->return = 0;
+
+    $output = $bucket->get($key);
+    $object = $output->getObject();
+} catch (Exception $e) {
+    echo get_class($e) . ' : ' . $e->getMessage() . PHP_EOL;
+}
+
+try {
+    $resolver->return = null;
+
+    $output = $bucket->get($key);
+    $object = $output->getObject();
+} catch (Exception $e) {
+    echo get_class($e) . ' : ' . $e->getMessage() . PHP_EOL;
+}
+
+$bucket->delete($key);
+
+?>
+--EXPECT--
+Riak\Exception\NonUniqueException : GetOutput contains unresolved siblings
+Riak\Exception\UnresolvedConflictException : The resolved Riak\Object does not contain a valid key.
+Riak\Exception\UnresolvedConflictException : Conflict resolver should return a instance of Riak\Object
+Riak\Exception\UnresolvedConflictException : Conflict resolver should return a instance of Riak\Object
+Riak\Exception\UnresolvedConflictException : Conflict resolver should return a instance of Riak\Object
diff --git a/tests/conflict_resolver_key.phpt b/tests/conflict_resolver_key.phpt
new file mode 100644
index 0000000..7b550f1
--- /dev/null
+++ b/tests/conflict_resolver_key.phpt
@@ -0,0 +1,67 @@
+--TEST--
+Test key conflict resolver
+--FILE--
+<?php
+
+include_once "connect.inc";
+
+use Riak\ObjectList;
+use Riak\Output\ConflictResolver;
+
+class MyGetResolver implements ConflictResolver 
+{
+    public function resolve(ObjectList $objects)
+    {
+        $winner = $objects->first();
+        $value  = 0;
+
+        foreach ($objects as $object) {
+            $value += intval($object->getContent());
+        }
+
+        $winner->setContent($value);
+
+        return $winner;
+    }
+}
+
+$key      = uniqid();
+$resolver = new MyGetResolver();
+$object1  = new \Riak\Object($key);
+$object2  = new \Riak\Object($key);
+$client   = new \Riak\Connection($host, $port);
+$bucket   = new \Riak\Bucket($client, 'test_bucket');
+$options  = new \Riak\Input\GetResolverInput($resolver);
+$props    = new \Riak\BucketPropertyList($nVal = 1, $allowMult = true);
+
+$bucket->setPropertyList($props);
+$bucket->delete($key);
+
+$object1->setContent(1);
+$object2->setContent(2);
+
+$bucket->put($object1);
+$bucket->put($object2);
+
+$output = $bucket->get($key, $options);
+$object = $output->getObject();
+// New put the winner back
+$bucket->put($object);
+
+echo "Has object        : " . var_export($output->hasObject(), true) . PHP_EOL;
+echo "Siblings          : " . count($output->getObjectList()) . PHP_EOL;
+echo "Get/Set Resolver  : " . var_export($resolver === $options->getConflictResolver(), true) . PHP_EOL;
+echo "Winner value      : " . $object->getContent() . PHP_EOL;
+echo "Has Siblings      : " . var_export($bucket->get($key)->hasSiblings(), true) . PHP_EOL;
+echo "Read Winner       : " . $bucket->get($key)->getFirstObject()->getContent() . PHP_EOL;
+
+$bucket->delete($key);
+
+?>
+--EXPECT--
+Has object        : true
+Siblings          : 2
+Get/Set Resolver  : true
+Winner value      : 3
+Has Siblings      : false
+Read Winner       : 3
diff --git a/tests/conflict_resolver_precedence.phpt b/tests/conflict_resolver_precedence.phpt
new file mode 100644
index 0000000..9a0ebac
--- /dev/null
+++ b/tests/conflict_resolver_precedence.phpt
@@ -0,0 +1,85 @@
+--TEST--
+Test conflict resolver precedence
+--FILE--
+<?php
+
+include_once "connect.inc";
+
+use Riak\ObjectList;
+use Riak\Output\ConflictResolver;
+
+class MyBuketResolver implements ConflictResolver 
+{
+    public function resolve(ObjectList $objects)
+    {
+        echo __CLASS__ . PHP_EOL;
+
+        $winner = $objects->first();
+        $value  = 0;
+
+        foreach ($objects as $object) {
+            $value += intval($object->getContent());
+        }
+
+        $winner->setContent($value);
+
+        return $winner;
+    }
+}
+
+class MyKeyResolver implements ConflictResolver 
+{
+    public function resolve(ObjectList $objects)
+    {
+        echo __CLASS__ . PHP_EOL;
+
+        $winner = $objects->first();
+        $value  = 0;
+
+        foreach ($objects as $object) {
+            $value += intval($object->getContent());
+        }
+
+        $winner->setContent($value);
+
+        return $winner;
+    }
+}
+
+$key            = uniqid();
+$keyResolver    = new MyKeyResolver();
+$buketResolver  = new MyBuketResolver();
+$object1        = new \Riak\Object($key);
+$object2        = new \Riak\Object($key);
+$client         = new \Riak\Connection($host, $port);
+$bucket         = new \Riak\Bucket($client, 'test_bucket');
+$options        = new \Riak\Input\GetResolverInput($keyResolver);
+$props          = new \Riak\BucketPropertyList($nVal = 1, $allowMult = true);
+
+$bucket->delete($key);
+$bucket->setPropertyList($props);
+$bucket->setConflictResolver($buketResolver);
+
+$object1->setContent(1);
+$object2->setContent(2);
+
+$bucket->put($object1);
+$bucket->put($object2);
+
+$output = $bucket->get($key, $options);
+$object = $output->getObject();
+// New put the winner back
+$bucket->put($object);
+
+echo "Siblings          : " . count($output->getObjectList()) . PHP_EOL;
+echo "Read Winner       : " . $bucket->get($key)->getFirstObject()->getContent() . PHP_EOL;
+echo "Has Siblings      : " . var_export($bucket->get($key)->hasSiblings(), true) . PHP_EOL;
+
+$bucket->delete($key);
+
+?>
+--EXPECT--
+MyKeyResolver
+Siblings          : 2
+Read Winner       : 3
+Has Siblings      : false
diff --git a/tests/connection_lazy.phpt b/tests/connection_lazy.phpt
new file mode 100644
index 0000000..a7e9791
--- /dev/null
+++ b/tests/connection_lazy.phpt
@@ -0,0 +1,112 @@
+--TEST--
+Test Lazy Riak\Connection
+--FILE--
+<?php
+include_once "connect.inc";
+
+use Riak\BucketPropertyList;
+use Riak\Connection;
+use Riak\Bucket;
+
+class RiakConnectionProxy extends Connection
+{
+    private $valueHolder = null;
+
+    private $initializer = null;
+
+    public function __construct(\Closure $initializer)
+    {
+        $this->initializer = $initializer;
+    }
+
+    public function setValueHolder($valueHolder)
+    {
+        $this->valueHolder = $valueHolder;
+    }
+
+    public function getBucket($name)
+    {
+        $this->initializer->__invoke($this->valueHolder);
+
+        return $this->valueHolder->getBucket($name);
+    }
+
+    public function getHost()
+    {
+        $this->initializer->__invoke($this->valueHolder);
+
+        return $this->valueHolder->getHost();
+    }
+
+    public function getPort()
+    {
+        $this->initializer->__invoke($this->valueHolder);
+
+        return $this->valueHolder->getPort();
+    }
+}
+
+class RiakBucketProxy extends Bucket
+{
+    private $valueHolder = null;
+
+    private $initializer = null;
+
+    public function __construct(\Closure $initializer)
+    {
+        $this->initializer = $initializer;
+    }
+
+    public function setValueHolder($valueHolder)
+    {
+        $this->valueHolder = $valueHolder;
+    }
+
+    public function setPropertyList($bucketPropertyList)
+    {
+       $this->initializer->__invoke($this->valueHolder);
+
+        return $this->valueHolder->setPropertyList($bucketPropertyList);
+    }
+
+    public function getPropertyList()
+    {
+        $this->initializer->__invoke($this->valueHolder);
+
+        return $this->valueHolder->getPropertyList();
+    }
+
+    public function getConnection()
+    {
+        $this->initializer->__invoke($this->valueHolder);
+
+        return $this->valueHolder->getConnection();
+    }
+
+    public function getKeyList()
+    {
+        $this->initializer->__invoke($this->valueHolder);
+
+        return $this->valueHolder->getKeyList();
+    }
+}
+
+$connectionInitializer = function(&$valueHolder) use ($host, $port) {
+    $valueHolder = $valueHolder ?: new Connection($host, $port);
+};
+
+$bucketInitializer = function(&$valueHolder) use ($connectionInitializer) {
+    $valueHolder = $valueHolder ?: new \Riak\Bucket(new RiakConnectionProxy($connectionInitializer), "test_bucket");
+};
+
+$bucket       = new RiakBucketProxy($bucketInitializer);
+$propList     = new BucketPropertyList(1, false);
+
+$bucket->setPropertyList($propList);
+
+printf("bucket property : %s\n", json_encode($bucket->getPropertyList() instanceof BucketPropertyList));
+printf("bucket keys     : %s\n", json_encode(is_array($bucket->getKeyList())));
+?>
+--EXPECT--
+bucket property : true
+bucket keys     : true
diff --git a/tests/crdt_counter.phpt b/tests/crdt_counter.phpt
new file mode 100644
index 0000000..2ac4f89
--- /dev/null
+++ b/tests/crdt_counter.phpt
@@ -0,0 +1,50 @@
+--TEST--
+Test Riak\Crdt\Counter
+--FILE--
+<?php
+include_once "connect.inc";
+$client = new \Riak\Connection($host, $port);
+$bucket = new \Riak\Bucket($client, "cnt_test_bucket");
+$newProps = new \Riak\BucketPropertyList(1, true);
+$bucket->setPropertyList($newProps);
+
+$counter1 = $bucket->counter("cnt1");
+$counter2 = new \Riak\Crdt\Counter($bucket, "cnt2");
+
+
+$getInput = new \Riak\Crdt\Input\GetInput();
+$getInput->setR(1);
+$getInput->setPR(1);
+$getInput->setBasicQuorum(true);
+$getInput->setNotFoundOk(false);
+
+$updateInput = new \Riak\Crdt\Input\UpdateInput();
+$updateInput->setW(1);
+$updateInput->setDW(1);
+$updateInput->setPW(1);
+
+$start1 = $counter1->get();
+$start2 = $counter2->get($getInput);
+$read1 = $counter1->incrementAndGet(1);
+if ($start1+1 != $read1) {
+    echo "Inc1 a failed".PHP_EOL;
+}
+$read1 = $counter1->incrementAndGet(1, $updateInput);
+if ($start1+2 != $read1) {
+    echo "Inc1 b failed".PHP_EOL;
+}
+
+$counter2->increment(-1);
+$read2 = $counter2->get($getInput);
+if ($start2 - 1 != $read2) {
+    echo "Inc2 a failed".PHP_EOL;
+}
+
+$counter2->increment(-1, $updateInput);
+$read2 = $counter2->get($getInput);
+if ($start2 - 2 != $read2) {
+    echo "Inc2 b failed".PHP_EOL;
+}
+echo "done!".PHP_EOL;
+--EXPECT--
+done!
diff --git a/tests/delete_badarguments.phpt b/tests/delete_badarguments.phpt
new file mode 100644
index 0000000..a965edf
--- /dev/null
+++ b/tests/delete_badarguments.phpt
@@ -0,0 +1,38 @@
+--TEST--
+Test bucket delete using bad arguments
+--FILE--
+<?php
+use \Riak\Object;
+include_once "connect.inc";
+
+$key    = uniqid();
+$obj    = new \Riak\Object($key);
+$client = new \Riak\Connection($host, $port);
+$bucket = new \Riak\Bucket($client, "test_bucket");
+
+
+$obj->setContent("foo");
+
+$bucket->put($obj);
+
+try {
+    $bucket->delete(new \Riak\Object());
+} catch (Exception $e) {
+    echo get_class($e) . ' : ' .$e->getMessage() . PHP_EOL;
+}
+
+try {
+    $bucket->delete(new stdClass());
+} catch (Exception $e) {
+    echo get_class($e) . ' : ' .$e->getMessage() . PHP_EOL;
+}
+
+$bucket->delete($key);
+
+echo var_export($bucket->get($key)->hasObject()) . PHP_EOL;
+
+?>
+--EXPECT--
+Riak\Exception\BadArgumentsException : Unable to resolve the object key.
+Riak\Exception\BadArgumentsException : Argument 1 passed to Riak\Bucket#delete() must be a string or an instance of Riak\Object.
+false
diff --git a/tests/index_output.phpt b/tests/index_output.phpt
new file mode 100644
index 0000000..311c256
--- /dev/null
+++ b/tests/index_output.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Test index output
+--FILE--
+<?php
+use \Riak\Output\IndexResult;
+use \Riak\Output\IndexResultList;
+$r1 = new IndexResult("key1");
+$r2 = new IndexResult("key2");
+$resultList = new IndexResultList();
+$resultList[] = $r1;
+$resultList[] = $r2;
+if ($resultList[0] !== $r1) {
+    echo "Error".PHP_EOL;
+}
+echo "done!".PHP_EOL;
+?>
+--EXPECT--
+done!
diff --git a/tests/indexquery.phpt b/tests/index_perform.phpt
similarity index 97%
rename from tests/indexquery.phpt
rename to tests/index_perform.phpt
index 1918522..61d7966 100644
--- a/tests/indexquery.phpt
+++ b/tests/index_perform.phpt
@@ -1,5 +1,5 @@
 --TEST--
-Test index queries
+Test basic index queries
 --FILE--
 <?php
 use \Riak\BucketPropertyList;
diff --git a/tests/index_perform_arr.phpt b/tests/index_perform_arr.phpt
new file mode 100644
index 0000000..d80660b
--- /dev/null
+++ b/tests/index_perform_arr.phpt
@@ -0,0 +1,43 @@
+--TEST--
+Test index with multiple values
+--FILE--
+<?php
+use \Riak\BucketPropertyList;
+include_once "connect.inc";
+$client = new \Riak\Connection($host, $port);
+$bucket = new \Riak\Bucket($client, "index_test_bucket2");
+$props = new BucketPropertyList(3, false);
+$bucket->setPropertyList($props);
+try {
+    $obj = new \Riak\Object("obj");
+    $obj->setContent("test-idx");
+    $obj->addIndex("tal_int", 0)->addIndex("tekst_bin", "text0")
+        ->addIndex("tal_int", 1)->addIndex("tekst_bin", "text1")
+        ->addIndex("tal_int", 2)->addIndex("tekst_bin", "text3")
+        ->addIndex("tal_int", 3)->addIndex("tekst_bin", "text4");
+    $in = $obj->getIndexMap("tal_int");
+    $bucket->put($obj);
+    $getOutput = $bucket->get("obj");
+    $getObj = $getOutput->getObject();
+    $out = $obj->getIndexMap("tal_int");
+    if ($in !== $out) {
+        echo "Different 1".PHP_EOL;
+        var_dump($in);
+        var_dump($out);
+    }
+    $bucket->put($getObj);
+    $getOutput = $bucket->get("obj");
+    $getObj = $getOutput->getObject();
+    $out2 = $obj->getIndexMap("tal_int");
+    if ($in !== $out2) {
+        echo "Different 2".PHP_EOL;
+        var_dump($in);
+        var_dump($out2);
+    }
+    echo "done!";
+} catch (Exception $e) {
+    var_dump($e);
+}
+?>
+--EXPECT--
+done!
diff --git a/tests/index_query.phpt b/tests/index_query.phpt
new file mode 100644
index 0000000..2e16f27
--- /dev/null
+++ b/tests/index_query.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Test index query
+--FILE--
+<?php
+use \Riak\Query\IndexQuery;
+$q = new IndexQuery("asdf");
+if ($q->isRangeQuery() == true) {
+    echo "Should not be ranged query at this time".PHP_EOL;
+}
+$q->setRangeValue("min", "max");
+if ($q->isRangeQuery() != true) {
+    echo "Should be ranged query now".PHP_EOL;
+}
+$rv = $q->getRangeValue();
+if ($rv[0] !== "min" || $rv[1] !== "max") {
+    echo "Rangedvalues does not match".PHP_EOL;
+}
+$q->setExactValue("exact");
+if ($q->isRangeQuery() == true) {
+    echo "Should not be ranged query now".PHP_EOL;
+}
+echo "done!".PHP_EOL;
+?>
+--EXPECT--
+done!
diff --git a/tests/index_query_ext.phpt b/tests/index_query_ext.phpt
new file mode 100644
index 0000000..86f3f09
--- /dev/null
+++ b/tests/index_query_ext.phpt
@@ -0,0 +1,48 @@
+--TEST--
+Test extended index querying
+--FILE--
+<?php
+use \Riak\Query\IndexQuery;
+include_once "connect.inc";
+$client = new \Riak\Connection($host, $port);
+$bucket = new \Riak\Bucket($client, "index_test_bucket", "phpriak_type");
+
+for ($i=0; $i<10; $i++) {
+    $obj = new \Riak\Object("obj$i");
+    $obj->setContent("test-idx");
+    $obj->addIndex("tal_int", $i)->addIndex("tekst_bin", "text$i");
+    $bucket->put($obj);
+}
+
+$q = new IndexQuery("tal_int");
+$q->setExactValue(1);
+$result = $bucket->indexQuery($q);
+$resultList = $result->getResultList();
+if ($resultList[0]->getKey() !== "obj1") {
+    echo "exact failed".PHP_EOL;
+    var_dump($result);
+}
+
+$q->setRangeValue(1, 8);
+$input = new \Riak\Input\IndexInput();
+$input->setMaxResults(4);
+$result = $bucket->indexQuery($q, $input);
+$resultList = $result->getResultList();
+if ($resultList[0]->getKey() !== "obj1") {
+    echo "ranged failed".PHP_EOL;
+    var_dump($result);
+}
+$cont = $result->getContinuation();
+$input->setContinuation($cont);
+$input->setMaxResults(10);
+$result = $bucket->indexQuery($q, $input);
+$resultList = $result->getResultList();
+if ($resultList[0]->getKey() !== "obj5") {
+    echo "continuation failed ".$cont.PHP_EOL;
+    var_dump($result);
+}
+
+echo "done!".PHP_EOL;
+?>
+--EXPECT--
+done!
diff --git a/tests/key_not_found.phpt b/tests/key_not_found.phpt
index 95ee118..edea967 100644
--- a/tests/key_not_found.phpt
+++ b/tests/key_not_found.phpt
@@ -1,5 +1,5 @@
 --TEST--
-Test key not found exception getting thrown
+Test key not found result in GetOutput with no objects
 --FILE--
 <?php
 use \Riak\Exception\NotFoundException;
@@ -8,12 +8,16 @@ try {
 	$client = new \Riak\Connection($host, $port);
 	$bucket = new \Riak\Bucket($client, "test_bucket");
         $readdenObj = $bucket->get("Long_key_that_should_never_exists_hopefully");
-	var_dump($readdenObj);
-} catch (NotFoundException $e) {
-	echo "success!";
+        if ($readdenObj->hasObject()) {
+            echo "fail!".PHP_EOL;
+        }
+        if (count($readdenObj->getObjectList()) > 0) {
+            echo "fail2!".PHP_EOL;
+        }
 } catch (Exception $e) {
 	var_dump($e);
 }
+echo "done!".PHP_EOL;
 ?>
 --EXPECT--
-success!
+done!
diff --git a/tests/numeric_key.phpt b/tests/numeric_key.phpt
new file mode 100644
index 0000000..b6b3602
--- /dev/null
+++ b/tests/numeric_key.phpt
@@ -0,0 +1,67 @@
+--TEST--
+Test Segmentation fault with numeric key
+--FILE--
+<?php
+
+include_once "connect.inc";
+
+use Riak\Output\PutOutput;
+use Riak\Connection;
+use Riak\Object;
+use Riak\Bucket;
+
+$client = new Connection($host, $port);
+$bucket = new Bucket($client, 'test_bucket');
+
+function testRiakKey(Bucket $bucket, $key)
+{
+    echo PHP_EOL;
+    echo "Using key         : " . gettype($key) . PHP_EOL;
+    echo "Delete object     : " . var_export($bucket->delete($key) === null, true) . PHP_EOL;
+    echo "Has object        : " . var_export($bucket->get($key)->hasObject(), true) . PHP_EOL;
+}
+
+$object1 = new Object();
+$object2 = new Object();
+
+$object1->setKey('9999');
+$object1->setContent('test 9999');
+
+$object2->setKey('99.99');
+$object2->setContent('test 99.99');
+
+$bucket->put($object1);
+$bucket->put($object2);
+
+testRiakKey($bucket, 9999);
+testRiakKey($bucket, 99.99);
+
+try {
+    testRiakKey($bucket, array(9999));
+} catch (\Exception $e) {
+    echo $e->getMessage() . PHP_EOL;
+}
+
+try {
+    testRiakKey($bucket, new \ArrayObject(array(99.99)));
+} catch (\Exception $e) {
+    echo $e->getMessage() . PHP_EOL;
+}
+
+
+?>
+--EXPECT--
+
+Using key         : integer
+Delete object     : true
+Has object        : false
+
+Using key         : double
+Delete object     : true
+Has object        : false
+
+Using key         : array
+Argument 1 passed to Riak\Bucket#delete() must be a string or an instance of Riak\Object.
+
+Using key         : object
+Argument 1 passed to Riak\Bucket#delete() must be a string or an instance of Riak\Object.
diff --git a/tests/object_list.phpt b/tests/object_list.phpt
new file mode 100644
index 0000000..afbfa4d
--- /dev/null
+++ b/tests/object_list.phpt
@@ -0,0 +1,60 @@
+--TEST--
+Test Riak\Output\ObjectList works
+--FILE--
+<?php
+$obj1 = new \Riak\Object("1");
+$obj2 = new \Riak\Object("2");
+$objList = new \Riak\ObjectList();
+if (!$objList->isEmpty()) {
+    echo "List is supposed to be empty!".PHP_EOL;
+}
+if (!is_null($objList->first())) {
+    echo "When list is empty null should be returned as first!".PHP_EOL;
+}
+$objList[] = $obj1;
+$objList["2"] = $obj2;
+
+if ($objList->count() !== 2) {
+    echo "Count should be 2".PHP_EOL;
+}
+
+if (!$objList->offsetExists("2")) {
+    echo "2 should exist in list".PHP_EOL;
+}
+
+if ($objList->first()->getKey() !== $obj1->getKey()) {
+    echo "Keys key should be equal".PHP_EOL;
+}
+
+if ($objList->last()->getKey() !== $obj2->getKey()) {
+    echo "Last key should be equal".PHP_EOL;
+}
+
+if ($objList->first() !== $obj1) {
+    echo "First object fail".PHP_EOL;
+}
+
+if ($objList->last() !== $obj2) {
+    echo "Last object fail".PHP_EOL;
+}
+
+$objList2 = new \Riak\ObjectList();
+$objList2["plappe"] = $obj2;
+if ($objList2->isEmpty()) {
+    echo "List2 is not supposed to be empty".PHP_EOL;
+}
+if ($objList2->first()->getKey() !== $obj2->getKey()) {
+    echo "List2 keys should equal".PHP_EOL;
+}
+
+//////
+// Try inserting a non riak object
+try {
+    $objList2["fail"] = 3;
+} catch (\Riak\Exception\BadArgumentsException $e) {
+    echo "done!".PHP_EOL;
+}
+?>
+--EXPECTF--
+Warning: Riak\ObjectList::offsetSet() expects parameter 2 to be Riak\Object, integer given in %s
+done!
diff --git a/tests/pool.phpt b/tests/pool.phpt
index e76c58a..f18cf63 100644
--- a/tests/pool.phpt
+++ b/tests/pool.phpt
@@ -7,24 +7,33 @@ riak.persistent.timeout=2000
 <?php
 include_once "connect.inc";
 
-echo \Riak\PoolInfo::getNumActiveConnection().PHP_EOL;
+use Riak\PoolInfo;
+use Riak\Connection;
+
 $clients = array();
+
+
+echo 'active connection     : ' . PoolInfo::getNumActiveConnection().PHP_EOL;
+
 for ($i=0; $i<25; ++$i) {
-	$clients[] = new \Riak\Connection($host, $port);
+    $clients[] = new Connection($host, $port);
+
+    $clients[$i]->ping();
 }
-echo \Riak\PoolInfo::getNumActiveConnection().PHP_EOL;
-echo \Riak\PoolInfo::getNumActivePersistentConnection().PHP_EOL;
+
+echo 'active connection     : ' . PoolInfo::getNumActiveConnection().PHP_EOL;
+echo 'persistent connection : ' . PoolInfo::getNumActivePersistentConnection().PHP_EOL;
 
 $clients = NULL;
 
-echo \Riak\PoolInfo::getNumActiveConnection().PHP_EOL;
-echo \Riak\PoolInfo::getNumActivePersistentConnection().PHP_EOL;
-echo \Riak\PoolInfo::getNumReconnect().PHP_EOL;
+echo 'active connection     : ' . PoolInfo::getNumActiveConnection().PHP_EOL;
+echo 'persistent connection : ' . PoolInfo::getNumActivePersistentConnection().PHP_EOL;
+echo 'reconnect             : ' . PoolInfo::getNumReconnect().PHP_EOL;
 ?>
 --EXPECT--
-0
-25
-20
-0
-0
-0
+active connection     : 0
+active connection     : 25
+persistent connection : 20
+active connection     : 0
+persistent connection : 0
+reconnect             : 0
diff --git a/tests/pool_info.phpt b/tests/pool_info.phpt
index 45f1365..c20c060 100644
--- a/tests/pool_info.phpt
+++ b/tests/pool_info.phpt
@@ -6,25 +6,38 @@ riak.persistent.connections=20
 --FILE--
 <?php
 include_once "connect.inc";
-echo \Riak\PoolInfo::getNumActiveConnection().PHP_EOL;
-$client = new \Riak\Connection($host, $port);
-echo \Riak\PoolInfo::getNumActiveConnection().PHP_EOL;
-echo \Riak\PoolInfo::getNumActivePersistentConnection().PHP_EOL;
-$client2 = new \Riak\Connection($host, $port);
-echo \Riak\PoolInfo::getNumActiveConnection().PHP_EOL;
-echo \Riak\PoolInfo::getNumActivePersistentConnection().PHP_EOL;
+
+use Riak\PoolInfo;
+use Riak\Connection;
+
+
+echo 'active connection     : ' . PoolInfo::getNumActiveConnection().PHP_EOL;
+
+$client = new Connection($host, $port);
+$client->ping();
+
+echo 'active connection     : ' . PoolInfo::getNumActiveConnection().PHP_EOL;
+echo 'persistent connection : ' . PoolInfo::getNumActivePersistentConnection().PHP_EOL;
+
+$client2 = new Connection($host, $port);
+$client2->ping();
+
+echo 'active connection     : ' . PoolInfo::getNumActiveConnection().PHP_EOL;
+echo 'persistent connection : ' . PoolInfo::getNumActivePersistentConnection().PHP_EOL;
+
 $client = NULL;
 $client2 = NULL;
-echo \Riak\PoolInfo::getNumActiveConnection().PHP_EOL;
-echo \Riak\PoolInfo::getNumActivePersistentConnection().PHP_EOL;
-echo \Riak\PoolInfo::getNumReconnect().PHP_EOL;
+
+echo 'active connection     : ' . PoolInfo::getNumActiveConnection().PHP_EOL;
+echo 'persistent connection : ' . PoolInfo::getNumActivePersistentConnection().PHP_EOL;
+echo 'reconnect             : ' . PoolInfo::getNumReconnect().PHP_EOL;
 ?>
 --EXPECT--
-0
-1
-1
-2
-2
-0
-0
-0
+active connection     : 0
+active connection     : 1
+persistent connection : 1
+active connection     : 2
+persistent connection : 2
+active connection     : 0
+persistent connection : 0
+reconnect             : 0
diff --git a/tests/put1.phpt b/tests/put1.phpt
index a24a5df..560aa69 100644
--- a/tests/put1.phpt
+++ b/tests/put1.phpt
@@ -6,22 +6,22 @@ use \Riak\Object;
 include_once "connect.inc";
 try {
   $client = new \Riak\Connection($host, $port);
-  $bucket = new \Riak\Bucket($client, "test_bucket");
+  $bucket = new \Riak\Bucket($client, "test_bucket", "phpriak_type");
 
   // No key provieded
   $obj = new Object();
   $obj->setContent("dummy");
-  $output = $bucket->put($obj);
+  $output = $bucket->put($obj, new \Riak\Input\PutInput(), 1000);
   if (is_null($output->getKey()) || strlen($output->getKey()) == 0) {
     var_dump($output);
   }
-  $bucket->delete($output->getKey());
+  $bucket->delete($output->getKey(), new \Riak\Input\DeleteInput(), 1000);
 
   $obj = new Object("dummy");
   $obj->setContentType("text/plain");
   $obj->setContent("test value that should get written");
-  $bucket->put($obj);
-  $bucket->delete($obj);
+  $bucket->put($obj, null, 1000);
+  $bucket->delete($obj, null, 1000);
   echo "done!";
 } catch (Exception $e) {
   echo $e->getMessage();
diff --git a/tests/reset_object_properties.phpt b/tests/reset_object_properties.phpt
new file mode 100644
index 0000000..d9a5221
--- /dev/null
+++ b/tests/reset_object_properties.phpt
@@ -0,0 +1,41 @@
+--TEST--
+Test we can set properties of an object to null
+--FILE--
+<?php
+use \Riak\Object;
+include_once "connect.inc";
+$client = new \Riak\Connection($host, $port);
+$bucket = new \Riak\Bucket($client, "test_bucket");
+
+// No key provieded
+$obj = new Object();
+$obj->setContent("dummy");
+$obj->setContentEncoding("encoding");
+$obj->setContentType("type");
+$output = $bucket->put($obj);
+$key = $output->getKey();
+
+$getOutput = $bucket->get($key);
+$obj = $getOutput->getFirstObject();
+if (($obj->getContentEncoding() != "encoding") || ($obj->getContentType() != "type")) {
+    var_dump($obj);
+}
+$obj->setContent(null);
+$obj->setContentEncoding(null);
+$obj->setContentType(null);
+
+$bucket->put($obj);
+$getOutput = $bucket->get($key);
+$obj = $getOutput->getFirstObject();
+// It seems Riak set contentType to text/plain if it is not set
+if (($obj->getContentEncoding() != null) ||
+    ($obj->getContentType() != "text/plain") ||
+    ($obj->getContent() != null)) {
+    echo "Not all properties was NULL as expected".PHP_EOL;
+    var_dump($obj);
+}
+$bucket->delete($key);
+echo "done!";
+?>
+--EXPECT--
+done!
diff --git a/tests/resolve_siblings.phpt b/tests/resolve_siblings.phpt
new file mode 100644
index 0000000..b3325a0
--- /dev/null
+++ b/tests/resolve_siblings.phpt
@@ -0,0 +1,49 @@
+--TEST--
+Test Resolve Siblings
+--FILE--
+<?php
+
+include_once "connect.inc";
+
+$key     = "my_key";
+$client  = new \Riak\Connection($host, $port);
+$object1 = new \Riak\Object($key);
+$object2 = new \Riak\Object($key);
+$props   = new \Riak\BucketPropertyList($nVal = 1, $allowMult = true);
+$bucket  = new \Riak\Bucket($client, 'test_bucket');
+
+$bucket->setPropertyList($props);
+$object1->setContent("object value 1");
+$object2->setContent("object value 2");
+
+$bucket->put($object1);
+$bucket->put($object2);
+
+$output  = $bucket->get($key);
+$vClock  = $output->getVClock();
+$objects = $output->getObjectList();
+
+echo "Has Siblings  : " . var_export($bucket->get($key)->hasSiblings(), true) . PHP_EOL;
+echo "Same VClock 1 : " . var_export($objects[0]->getVClock() === $vClock, true) . PHP_EOL;
+echo "Same VClock 2 : " . var_export($objects[1]->getVClock() === $vClock, true) . PHP_EOL;
+
+$winner    = $objects[1];
+$putInput  = new \Riak\Input\PutInput();
+$merged    = new \Riak\Object($key);
+
+$putInput->setVClock($vClock);
+$merged->setContent($winner->getContent());
+
+$bucket->put($merged, $putInput);
+
+echo "Has Siblings  : " . var_export($bucket->get($key)->hasSiblings(), true) . PHP_EOL;
+
+$getOutput = $bucket->get($key);
+$deleteInput = new \Riak\Input\DeleteInput();
+$bucket->delete($key, $deleteInput->setVClock($getOutput->getVClock()));
+?>
+--EXPECT--
+Has Siblings  : true
+Same VClock 1 : true
+Same VClock 2 : true
+Has Siblings  : false
diff --git a/tests/search.phpt b/tests/search.phpt
index 9849ff5..1115034 100644
--- a/tests/search.phpt
+++ b/tests/search.phpt
@@ -28,6 +28,9 @@ $search = new Search($riak);
 $si = new ParameterBag();
 $si->setDefaultField('name');
 $res = $search->search("testsearch", "apple", $si);
+if (!$res->hasMaxScore() && !$res->hasNumFound()) {
+    echo "Did not find any results :(".PHP_EOL;
+}
 foreach ($res->getDocuments() as $doc) {
     $fields = $doc->getFields();
     if ($fields["name"] != "apple") {
diff --git a/tests/server_info.phpt b/tests/server_info.phpt
new file mode 100644
index 0000000..0369e2e
--- /dev/null
+++ b/tests/server_info.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Test server info
+--FILE--
+<?php
+include_once "connect.inc";
+
+$conn = new \Riak\Connection($host, $port);
+$serverInfo = $conn->getServerInfo();
+$node = $serverInfo->getNode();
+$serverVersion = $serverInfo->getServerVersion();
+if (is_string($node) && is_string($serverVersion)) {
+    echo "done!".PHP_EOL;
+} else {
+    var_dump($node);
+    var_dump($serverVersion);
+}
+?>
+--EXPECT--
+done!
diff --git a/tests/update_object.phpt b/tests/update_object.phpt
new file mode 100644
index 0000000..b573d0e
--- /dev/null
+++ b/tests/update_object.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Object update
+--FILE--
+<?php
+
+include_once "connect.inc";
+
+$key    = "my_key_update";
+$client = new \Riak\Connection($host, $port);
+$object = new \Riak\Object($key);
+$props  = new \Riak\BucketPropertyList($nVal = 1, $allowMult = true);
+$bucket = new \Riak\Bucket($client, 'test_bucket');
+
+$objectValue1 = "object value 1";
+$objectValue2 = "object value 2";
+
+$bucket->setPropertyList($props);
+$object->setContent($objectValue1);
+$bucket->put($object);
+
+var_dump($bucket->get($key)->hasSiblings());
+var_dump($bucket->get($key)->getFirstObject()->getContent());
+
+$output = $bucket->get($key);
+$object = $output->getFirstObject();
+
+var_dump($object->getVClock() === $output->getVClock());
+
+$object->setContent($objectValue2);
+$bucket->put($object);
+
+$getOutput = $bucket->get($key);
+var_dump($getOutput->getFirstObject()->getContent());
+var_dump($getOutput->hasSiblings());
+
+$deleteInput = new \Riak\Input\DeleteInput();
+$bucket->delete($key, $deleteInput->setVClock($getOutput->getVClock()));
+?>
+--EXPECT--
+bool(false)
+string(14) "object value 1"
+bool(true)
+string(14) "object value 2"
+bool(false)
