diff --git a/doc/sphinx/_static/headers.js b/doc/sphinx/_static/headers.js
index 6e5f577cfc7cc2796e9a1612b2dc4a849c3e5b57..c797fbb23c44fdf18a0487a0eb599b8eec1ebc8f 100644
--- a/doc/sphinx/_static/headers.js
+++ b/doc/sphinx/_static/headers.js
@@ -11,6 +11,17 @@ $(document).ready(function () {
       }
     }
   );
+  $("[id^='lua-object'], [id^='lua-function'], [id^='lua-data']").each(
+    function(i, el) {
+      var icon = '<i class="fa fa-link"></i>';
+      var hlink = $(el).find(".headerlink");
+      var hlink_id = hlink.attr("href");
+      if (typeof(hlink_id) != 'undefined') {
+        $(hlink).remove();
+        $(el).prepend($("<a />").addClass("headerlink").attr("href", hlink_id).html(icon));
+      }
+    }
+  );
   $(".admonition.note p.first.admonition-title").each(
     function(i, el) {
       var icon = '<i class="fa fa-comments-o"></i>';
diff --git a/doc/sphinx/_static/sphinx_design.css b/doc/sphinx/_static/sphinx_design.css
index 760feb48d4d87e9f3d201709a9abc0039231f607..e670f964e688b9608797185973474209508d5b99 100644
--- a/doc/sphinx/_static/sphinx_design.css
+++ b/doc/sphinx/_static/sphinx_design.css
@@ -13,6 +13,7 @@
 }
 li.toctree-l1>a {
     color:#168de2;
+
     font-size:20px;
     margin:0;
     text-decoration:none;
@@ -187,7 +188,8 @@ a.headerlink {
 .b-article h2,
 .b-article h3,
 .b-article h4,
-.b-article h5 {
+.b-article h5,
+.b-article h6 {
     margin: 16px 0 16px -25px;
     font-weight: bold;
 }
@@ -211,12 +213,24 @@ a.headerlink {
   -ms-transition: opacity 0.2s ease-in-out 0.1s;
 }
 
+[id^="lua-object"  ],
+[id^="lua-function"],
+[id^="lua-data"    ] {
+    margin-left: -25px;
+}
+
+[id^="lua-object"  ]:hover .headerlink,
+[id^="lua-function"]:hover .headerlink,
+[id^="lua-data"    ]:hover .headerlink {
+    opacity: 1;
+}
+
 h2:hover .headerlink,
 h3:hover .headerlink,
 h4:hover .headerlink,
 h5:hover .headerlink,
 h6:hover .headerlink {
-  opacity: 1;
+    opacity: 1;
 }
 
 table.docutils.footnote {
@@ -368,3 +382,70 @@ div.b-cols_content_left .b-search-text {
     float: left;
     position: relative;
 }
+
+.b-switcher-item-url {
+    -webkit-transition: all 0.2s ease-in-out;
+    -moz-transition: all 0.2s ease-in-out;
+    -o-transition: all 0.2s ease-in-out;
+    -ms-transition: all 0.2s ease-in-out;
+    transition: all 0.2s ease-in-out;
+}
+.b-tab_switcher {
+    display:inline-block;
+    border:2px solid #797979;
+    background:#fff;
+    -webkit-border-radius: 6px 6px 0 0;
+    -moz-border-radius: 6px 6px 0 0;
+    border-radius: 6px 6px 0 0;
+    font-size: 0;
+    padding: 0px !important;
+}
+
+.b-tab_switcher-item {
+    display:inline-block;
+    font-size:16px;
+    color:#262626;
+    border-right:2px solid #797979;
+    padding: 0px !important;
+}
+.b-tab_switcher-item:last-child {
+    border: 0;
+}
+.b-tab_switcher-item-url {
+    display:inline-block;
+    color:#797979;
+    text-decoration:none;
+    padding:8px 19px;
+    text-transform:uppercase;
+}
+.b-tab_switcher-item-url:hover {
+    background:#c9c9c9;
+    color:#fff
+}
+.b-tab_switcher-item-url.p-active {
+    background:#797979;
+    color:#fff;
+}
+.b-tab_switcher-item:first-child .b-tab_switcher-item-url {
+    -webkit-border-radius: 4px 0 0 0px;
+    -moz-border-radius: 4px 0 0 0px;
+    border-radius: 4px 0 0 0px;
+}
+.b-tab_switcher-item:last-child .b-tab_switcher-item-url {
+    -webkit-border-radius: 0 4px 0px 0;
+    -moz-border-radius: 0 4px 0px 0;
+    border-radius: 0 4px 0px 0;
+}
+
+.b-documentation-tab-content {
+    border: 2px solid #797979;
+    margin-top: -2px;
+    padding: 5px;
+    -webkit-border-radius: 0 6px 6px 6px;
+    -moz-border-radius: 0 6px 6px 6px;
+    border-radius: 0 6px 6px 6px;
+}
+
+.b-documentation-tab div {
+    height: 100%;
+}
diff --git a/doc/sphinx/_templates/searchbox.html b/doc/sphinx/_templates/searchbox.html
index 508b4b30257d4d207f3b38c565122adc9a9aec70..d2d38c46c82994c3186b50482ff6d58b1d145b46 100644
--- a/doc/sphinx/_templates/searchbox.html
+++ b/doc/sphinx/_templates/searchbox.html
@@ -1,6 +1,6 @@
 {%- if builder != "singlehtml" %}
 <form id="searchbox" role="search" class="search b-search" action="{{ pathto('search') }}" method="get">
-  <input class="b-search-text" name="q" type="text"/ placeholder="Search">
+  <input class="b-search-text" name="q" type="text"/ placeholder="Search the manual">
   <input class="b-search-but" type="submit" />
   <input type="hidden" name="check_keywords" value="yes" />
   <input type="hidden" name="area" value="default" />
diff --git a/doc/sphinx/book/app_c_lua_tutorial.rst b/doc/sphinx/book/app_c_lua_tutorial.rst
index 80e91273d86e300d010b2396934148102996765a..b04ccdd21f28df39f084505fdfa2f939d95320e8 100644
--- a/doc/sphinx/book/app_c_lua_tutorial.rst
+++ b/doc/sphinx/book/app_c_lua_tutorial.rst
@@ -511,7 +511,7 @@ that are declared in line 1, because all of them are for use only within the fun
 
 LINE 3: WHY "PAIRS()". Our job is to go through all the rows and there are two
 ways to do it: with ``box.space.space-name:pairs()`` or with
-:func:`index.iterator <box.space.space-name.index[.index-name]:pairs>`.
+:func:`index.iterator <index_object.pairs>`.
 We preferred ``pairs()`` because it is simpler.
 
 LINE 4: WHY "PCALL". If we simply said "``lua_table = json.decode(t[2]))``", then
diff --git a/doc/sphinx/book/box/box_index.rst b/doc/sphinx/book/box/box_index.rst
index 899ee23d44f428c609f5a44c9aeadaf370df490f..481d5a8a36b9e250822df79926a7c57423c72ef7 100644
--- a/doc/sphinx/book/box/box_index.rst
+++ b/doc/sphinx/book/box/box_index.rst
@@ -10,478 +10,480 @@ API is a direct binding to corresponding methods of index objects of type
 
 .. module:: box.index
 
-.. data:: box.space.space-name.index.index-name.unique
-
-    true if the index is unique.
-
-    :rtype: boolean
-
-.. data:: box.space.space-name.index.index-name.type
-
-    Index type, 'TREE' or 'HASH' or 'BITSET' or 'RTREE'.
-
-    :rtype: string
-
-.. data:: box.space.space-name.index.index-name.parts
-
-    An array describing index key fields.
-
-    :rtype: table
-
-    .. code-block:: lua
-
-        tarantool> box.space.tester.index.primary
-        ---
-        unique: true
-        parts:
-          0:
-            type: NUM
-            fieldno: 1
-        id: 0
-        space_id: 513
-        name: primary
-        type: TREE
-        ...
-
-.. function:: box.space.space-name.index[.index-name]:pairs(bitset-value | field-value..., iterator-type)
-
-    This method provides iteration support within an index. Parameter type is
-    used to identify the semantics of iteration. Different index types support
-    different iterators. The remaining arguments of the function are varying
-    and depend on the iteration type. For example, a TREE index maintains a
-    strict order of keys and can return all tuples in ascending or descending
-    order, starting from the specified key. Other index types, however, do not
-    support ordering.
-
-    To understand consistency of tuples returned by an iterator, it's essential
-    to know the principles of the Tarantool transaction processing subsystem. An
-    iterator in Tarantool does not own a consistent read view. Instead, each
-    procedure is granted exclusive access to all tuples and spaces until it
-    encounters a "context switch": by causing a write to disk, network, or by an
-    explicit call to :func:`fiber.yield`. When the execution flow returns
-    to the yielded procedure, the data set could have changed significantly.
-    Iteration, resumed after a yield point, does not preserve the read view,
-    but continues with the new content of the database.
-
-    :param type: iteration strategy as defined in tables below
-    :return: this method returns an iterator closure, i.e. a function which can
-             be used to get the next value on each invocation
-    :rtype:  function, tuple
-
-    :except: Selected iteration type is not supported in the subject index type,
-             or supplied parameters do not match iteration type.
-
-    Complexity Factors: Index size, Index type, Number of tuples accessed.
-
-    .. container:: table
-
-        **TREE iterator types**
-
-        +---------------+-----------+---------------------------------------------+
-        | Type          | Arguments | Description                                 |
-        +===============+===========+=============================================+
-        | box.index.ALL | none      | Iterate over all tuples in an index. Tuples |
-        | or 'ALL'      |           | are returned in ascending order of the key. |
-        +---------------+-----------+---------------------------------------------+
-        | box.index.EQ  | field     | Equality iterator: iterate over all tuples  |
-        | or 'EQ'       | values    | where field values = key values. Parts of a |
-        |               |           | multi-part key need to be separated by      |
-        |               |           | commas.                                     |
-        |               |           |                                             |
-        |               |           | If the number of field values is less than  |
-        |               |           | the number of parts of a multi-part key,    |
-        |               |           | the missing field values are considered to  |
-        |               |           | be matching.                                |
-        |               |           |                                             |
-        |               |           | If there are multiple matches, then tuples  |
-        |               |           | are returned in ascending order by key.     |
-        +---------------+-----------+---------------------------------------------+
-        | box.index.GT  | field     | Keys match if key values are greater than   |
-        | or 'GT'       | values    | field values. If the number of field values |
-        |               |           | is less than the number of parts of a       |
-        |               |           | multi-part key, the missing field values    |
-        |               |           | are considered to be matching. If the field |
-        |               |           | value is ``nil``, iteration starts from the |
-        |               |           | smallest key in the index. Tuples are       |
-        |               |           | returned in ascending order by key.         |
-        +---------------+-----------+---------------------------------------------+
-        | box.index.REQ | field     | Reverse equality iterator. Matching is      |
-        | or 'REQ'      | values    | determined in the same way as for           |
-        |               |           | ``box.index.EQ``, but, if there are multiple|
-        |               |           | matches, then tuples are returned in        |
-        |               |           | descending order by key,                    |
-        +---------------+-----------+---------------------------------------------+
-        | box.index.GE  | field     | Keys match if key values are greater than   |
-        | or 'GE'       | values    | or equal to field values. Tuples are        |
-        |               |           | returned in ascending order by key. If the  |
-        |               |           | field value is ``nil``, iteration starts    |
-        |               |           | from the first key in the index.            |
-        +---------------+-----------+---------------------------------------------+
-        | box.index.LT  | field     | Keys match if key values are less than      |
-        | or 'LT'       | values    | field values. Tuples are returned in        |
-        |               |           | descending order by key. If the field value |
-        |               |           | is ``nil``, iteration starts from the last  |
-        |               |           | key in the index.                           |
-        +---------------+-----------+---------------------------------------------+
-        | box.index.LE  | field     | Keys match if key values are less than or   |
-        | or 'LE'       | values    | equal to field values. Tuples are returned  |
-        |               |           | in descending order by key. If the field    |
-        |               |           | value is ``nil``, iteration starts from     |
-        |               |           | the last key in the index.                  |
-        +---------------+-----------+---------------------------------------------+
-
-        **HASH iterator types**
-
-        +---------------+-----------+---------------------------------------------+
-        | Type          | Arguments | Description                                 |
-        +===============+===========+=============================================+
-        | box.index.ALL | none      | Iterate over all tuples in an index. Tuples |
-        | or 'ALL'      |           | are returned in ascending order of the key. |
-        +---------------+-----------+---------------------------------------------+
-        | box.index.EQ  | field     | Equality iterator: iterate over all tuples  |
-        | or 'EQ'       | values    | matching the key. Parts of a multi-part     |
-        |               |           | key need to be separated by commas.         |
-        |               |           |                                             |
-        |               |           | A HASH index only supports exact match:     |
-        |               |           | all parts of a key participating in the     |
-        |               |           | index must be provided.                     |
-        |               |           |                                             |
-        |               |           | HASH indexes are always unique.             |
-        +---------------+-----------+---------------------------------------------+
-        | box.index.GT  | field     | Keys match if hashed key values are greater |
-        | or 'GT'       | values    | than hashed field values. If the number of  |
-        |               |           | field values is less than the number of     |
-        |               |           | parts of a multi-part key, the result is an |
-        |               |           | error. Tuples are returned in ascending     |
-        |               |           | order by hashed key, so the order will      |
-        |               |           | appear to be random. Provided that the      |
-        |               |           | space is not being updated, the 'GT'        |
-        |               |           | iterator can be used to retrieve all        |
-        |               |           | tuples piece by piece, by supplying the     |
-        |               |           | last returned value from the previous       |
-        |               |           | range as the start field value for an       |
-        |               |           | iterator over the next range.               |
-        +---------------+-----------+---------------------------------------------+
-
-        **BITSET iterator types**
-
-        +----------------------------+-----------+---------------------------------------------+
-        | Type                       | Arguments | Description                                 |
-        +============================+===========+=============================================+
-        | box.index.ALL              | none      | Iterate over all tuples in an index. Tuples |
-        | or 'ALL'                   |           | are returned in ascending order of the      |
-        |                            |           | key's bitset, and so will appear to be      |
-        |                            |           | unordered.                                  |
-        +----------------------------+-----------+---------------------------------------------+
-        | box.index.EQ               | field     | Equality iterator: iterate over all tuples  |
-        | or 'EQ'                    | values    | matching the field values. If there are     |
-        |                            |           | multiple field values, they need to be      |
-        |                            |           | separated by commas.                        |
-        |                            |           |                                             |
-        |                            |           | BITSET indexes are always unique.           |
-        +----------------------------+-----------+---------------------------------------------+
-        | box.index.BITS_ALL_SET     | field     | Keys match if all of the bits specified in  |
-        |                            | values    | 'bit mask' are set.                         |
-        +----------------------------+-----------+---------------------------------------------+
-        | box.index.BITS_ANY_SET     | field     | Keys match if any of the bits specified in  |
-        |                            | values    | 'bit mask' is set.                          |
-        +----------------------------+-----------+---------------------------------------------+
-        | box.index.BITS_ALL_NOT_SET | field     | Keys match if none of the bits specified in |
-        |                            | values    | 'bit mask' is set.                          |
-        +----------------------------+-----------+---------------------------------------------+
-
-        .. _rtree-iterator:
-
-        **RTREE iterator types**
-
-        +--------------------+-----------+---------------------------------------------+
-        | Type               | Arguments | Description                                 |
-        +====================+===========+=============================================+
-        | box.index.ALL      | none      | All keys match. Tuples are returned in      |
-        | or 'ALL'           |           | ascending order of the primary key.         |
-        +--------------------+-----------+---------------------------------------------+
-        | box.index.EQ       | field     | Keys match if the rectangle defined by the  |
-        | or 'EQ'            | values    | field values is the same as the rectangle   |
-        |                    |           | defined by the key -- where "key" means     |
-        |                    |           | "the key in the RTREE index" and            |
-        |                    |           | "rectangle" means "rectangle as explained   |
-        |                    |           | in section RTREE_.                          |
-        +--------------------+-----------+---------------------------------------------+
-        | box.index.GT       | field     | Keys match if all points of the rectangle   |
-        | or 'GT'            | values    | defined by the field values are within the  |
-        |                    |           | rectangle defined by the key.               |
-        +--------------------+-----------+---------------------------------------------+
-        | box.index.GE       | field     | Keys match if all points of the rectangle   |
-        | or 'GE'            | values    | defined by the field values are within, or  |
-        |                    |           | at the side of, the rectangle defined by    |
-        |                    |           | the key.                                    |
-        +--------------------+-----------+---------------------------------------------+
-        | box.index.LT       | field     | Keys match if all points of the rectangle   |
-        | or 'LT'            | values    | defined by the key are within the rectangle |
-        |                    |           | defined by the field values.                |
-        +--------------------+-----------+---------------------------------------------+
-        | box.index.LE       | field     | Keys match if all points of the rectangle   |
-        | or 'LE'            | values    | defined by the key are within, or at the    |
-        |                    |           | side of, the rectangle defined by the field |
-        |                    |           | values.                                     |
-        +--------------------+-----------+---------------------------------------------+
-        | box.index.OVERLAPS | field     | Keys match if all points of the rectangle   |
-        | or 'OVERLAPS'      | values    | defined by the key are within, or at the    |
-        |                    |           | side of, the rectangle defined by the field |
-        |                    |           | values.                                     |
-        +--------------------+-----------+---------------------------------------------+
-        | box.index.NEIGHBOR | field     | Keys match if all points of the rectangle   |
-        | or 'NEIGHBOR'      | values    | defined by the key are within, or at the    |
-        |                    |           | side of, the rectangle defined by the field |
-        |                    |           | values.                                     |
-        +--------------------+-----------+---------------------------------------------+
-
-    .. code-block:: lua
-
-        tarantool> s = box.schema.space.create('space17')
-        ---
-        ...
-        tarantool> s:create_index('primary', {parts = {1, 'STR', 2, 'STR'}})
-        ---
-        ...
-        tarantool> s:insert{'C', 'C'}
-        ---
-        - ['C', 'C']
-        ...
-        tarantool> s:insert{'B', 'A'}
-        ---
-        - ['B', 'A']
-        ...
-        tarantool> s:insert{'C', '!'}
-        ---
-        - ['C', '!']
-        ...
-        tarantool> s:insert{'A', 'C'}
-        ---
-        - ['A', 'C']
-        ...
-        tarantool> console = require('console'); console.delimiter('!')
-        ---
-        ...
-        tarantool> function example()
-                 >   for _, tuple in
-                 >   s.index.primary:pairs(nil, {iterator = box.index.ALL}) do
-                 >     print(tuple)
-                 >   end
-                 > end!
-        ---
-        ...
-        tarantool> console.delimiter('')!
-        ---
-        ...
-        tarantool> example()
-        ['A', 'C']
-        ['B', 'A']
-        ['C', '!']
-        ['C', 'C']
-        ---
-        ...
-        tarantool> s:drop()
-        ---
-        ...
-
-.. function:: box.space.space-name[.index.index-name]:select({[field-value [, field-value ...]]}, {[option [, option ...]]})
-
-    This is is an alternative to box.space...select() which goes via a
-    particular index and can make use of additional parameters that specify the
-    iterator type, and the limit (that is, the maximum number of tuples to
-    return) and the offset (that is, which tuple to start with in the list).
-
-    :param lua-value field-value(s): values to be matched against the index key.
-    :param lua-value option(s): any or all of iterator=iterator-type
-                                limit=maximum-number-of-tuples,
-                                offset=start-tuple-number.
-
-    :return: the tuple or tuples that match the field values.
-    :rtype:  tuple set as a Lua table
-
-    .. code-block:: lua
-
-        -- Create a space named tester.
-        -- Create a unique index 'primary', which won't be needed for this example.
-        -- Create a non-unique index 'secondary' with an index on the second field.
-        -- Insert three tuples, values in field[2] equal to 'X', 'Y', and 'Z'.
-        -- Select all tuples where the secondary index keys are greater than 'X'.
-        box.schema.space.create('tester')
-        box.space.tester:create_index('primary', {parts = {1, 'NUM' }})
-        box.space.tester:create_index('secondary', {type = 'tree', unique = false, parts = {2, 'STR'}})
-        box.space.tester:insert{1,'X','Row with field[2]=X'}
-        box.space.tester:insert{2,'Y','Row with field[2]=Y'}
-        box.space.tester:insert{3,'Z','Row with field[2]=Z'}
-        box.space.tester.index.secondary:select({'X'}, {iterator = 'GT', limit = 1000})
-
-    The result will be a table of tuple and will look like this:
-
-    .. code-block:: yaml
-
-        ---
-        - - [2, 'Y', 'Row with field[2]=Y']
-          - [3, 'Z', 'Row with field[2]=Z']
-        ...
-
-    .. NOTE::
-
-        [.index.index-name] is optional. If it is omitted, then the assumed
-        index is the first (primary-key) index. Therefore, for the example
-        above, ``box.space.tester:select({1}, {iterator = 'GT'})`` would have
-        returned the same two rows, via the 'primary' index.
-
-    .. NOTE::
-
-        ``iterator = iterator type`` is optional. If it is omitted, then
-        ``iterator = 'EQ'`` is assumed.
-
-    .. NOTE::
-
-        ``field-value [, field-value ...]`` is optional. If it is omitted,
-        then every key in the index is considered to be a match, regardless of
-        iterator type. Therefore, for the example above,
-        ``box.space.tester:select{}`` will select every tuple in the tester
-        space via the first (primary-key) index.
-
-    .. NOTE::
-
-        ``box.space.space-name.index.index-name:select(...)[1]``. can be
-        replaced by ``box.space.space-name.index.index-name:get(...)``.
-        That is, get can be used as a convenient shorthand to get the first
-        tuple in the tuple set that would be returned by select. However,
-        if there is more than one tuple in the tuple set, then get returns
-        an error.
-
-.. function:: box.space.space-name.index.index-name:min([key-value])
+.. class:: index_object
+
+    .. data:: unique
+
+        true if the index is unique.
+
+        :rtype: boolean
+
+    .. data:: type
+
+        Index type, 'TREE' or 'HASH' or 'BITSET' or 'RTREE'.
+
+        :rtype: string
+
+    .. data:: parts
+
+        An array describing index key fields.
+
+        :rtype: table
+
+        .. code-block:: lua
+
+            tarantool> box.space.tester.index.primary
+            ---
+            unique: true
+            parts:
+            0:
+                type: NUM
+                fieldno: 1
+            id: 0
+            space_id: 513
+            name: primary
+            type: TREE
+            ...
+
+    .. function:: pairs(bitset-value | field-value..., iterator-type)
+
+        This method provides iteration support within an index. Parameter type is
+        used to identify the semantics of iteration. Different index types support
+        different iterators. The remaining arguments of the function are varying
+        and depend on the iteration type. For example, a TREE index maintains a
+        strict order of keys and can return all tuples in ascending or descending
+        order, starting from the specified key. Other index types, however, do not
+        support ordering.
+
+        To understand consistency of tuples returned by an iterator, it's essential
+        to know the principles of the Tarantool transaction processing subsystem. An
+        iterator in Tarantool does not own a consistent read view. Instead, each
+        procedure is granted exclusive access to all tuples and spaces until it
+        encounters a "context switch": by causing a write to disk, network, or by an
+        explicit call to :func:`fiber.yield`. When the execution flow returns
+        to the yielded procedure, the data set could have changed significantly.
+        Iteration, resumed after a yield point, does not preserve the read view,
+        but continues with the new content of the database.
+
+        :param type: iteration strategy as defined in tables below
+        :return: this method returns an iterator closure, i.e. a function which can
+                be used to get the next value on each invocation
+        :rtype:  function, tuple
+
+        :except: Selected iteration type is not supported in the subject index type,
+                or supplied parameters do not match iteration type.
+
+        Complexity Factors: Index size, Index type, Number of tuples accessed.
+
+        .. container:: table
+
+            **TREE iterator types**
+
+            +---------------+-----------+---------------------------------------------+
+            | Type          | Arguments | Description                                 |
+            +===============+===========+=============================================+
+            | box.index.ALL | none      | Iterate over all tuples in an index. Tuples |
+            | or 'ALL'      |           | are returned in ascending order of the key. |
+            +---------------+-----------+---------------------------------------------+
+            | box.index.EQ  | field     | Equality iterator: iterate over all tuples  |
+            | or 'EQ'       | values    | where field values = key values. Parts of a |
+            |               |           | multi-part key need to be separated by      |
+            |               |           | commas.                                     |
+            |               |           |                                             |
+            |               |           | If the number of field values is less than  |
+            |               |           | the number of parts of a multi-part key,    |
+            |               |           | the missing field values are considered to  |
+            |               |           | be matching.                                |
+            |               |           |                                             |
+            |               |           | If there are multiple matches, then tuples  |
+            |               |           | are returned in ascending order by key.     |
+            +---------------+-----------+---------------------------------------------+
+            | box.index.GT  | field     | Keys match if key values are greater than   |
+            | or 'GT'       | values    | field values. If the number of field values |
+            |               |           | is less than the number of parts of a       |
+            |               |           | multi-part key, the missing field values    |
+            |               |           | are considered to be matching. If the field |
+            |               |           | value is ``nil``, iteration starts from the |
+            |               |           | smallest key in the index. Tuples are       |
+            |               |           | returned in ascending order by key.         |
+            +---------------+-----------+---------------------------------------------+
+            | box.index.REQ | field     | Reverse equality iterator. Matching is      |
+            | or 'REQ'      | values    | determined in the same way as for           |
+            |               |           | ``box.index.EQ``, but, if there are multiple|
+            |               |           | matches, then tuples are returned in        |
+            |               |           | descending order by key,                    |
+            +---------------+-----------+---------------------------------------------+
+            | box.index.GE  | field     | Keys match if key values are greater than   |
+            | or 'GE'       | values    | or equal to field values. Tuples are        |
+            |               |           | returned in ascending order by key. If the  |
+            |               |           | field value is ``nil``, iteration starts    |
+            |               |           | from the first key in the index.            |
+            +---------------+-----------+---------------------------------------------+
+            | box.index.LT  | field     | Keys match if key values are less than      |
+            | or 'LT'       | values    | field values. Tuples are returned in        |
+            |               |           | descending order by key. If the field value |
+            |               |           | is ``nil``, iteration starts from the last  |
+            |               |           | key in the index.                           |
+            +---------------+-----------+---------------------------------------------+
+            | box.index.LE  | field     | Keys match if key values are less than or   |
+            | or 'LE'       | values    | equal to field values. Tuples are returned  |
+            |               |           | in descending order by key. If the field    |
+            |               |           | value is ``nil``, iteration starts from     |
+            |               |           | the last key in the index.                  |
+            +---------------+-----------+---------------------------------------------+
+
+            **HASH iterator types**
+
+            +---------------+-----------+---------------------------------------------+
+            | Type          | Arguments | Description                                 |
+            +===============+===========+=============================================+
+            | box.index.ALL | none      | Iterate over all tuples in an index. Tuples |
+            | or 'ALL'      |           | are returned in ascending order of the key. |
+            +---------------+-----------+---------------------------------------------+
+            | box.index.EQ  | field     | Equality iterator: iterate over all tuples  |
+            | or 'EQ'       | values    | matching the key. Parts of a multi-part     |
+            |               |           | key need to be separated by commas.         |
+            |               |           |                                             |
+            |               |           | A HASH index only supports exact match:     |
+            |               |           | all parts of a key participating in the     |
+            |               |           | index must be provided.                     |
+            |               |           |                                             |
+            |               |           | HASH indexes are always unique.             |
+            +---------------+-----------+---------------------------------------------+
+            | box.index.GT  | field     | Keys match if hashed key values are greater |
+            | or 'GT'       | values    | than hashed field values. If the number of  |
+            |               |           | field values is less than the number of     |
+            |               |           | parts of a multi-part key, the result is an |
+            |               |           | error. Tuples are returned in ascending     |
+            |               |           | order by hashed key, so the order will      |
+            |               |           | appear to be random. Provided that the      |
+            |               |           | space is not being updated, the 'GT'        |
+            |               |           | iterator can be used to retrieve all        |
+            |               |           | tuples piece by piece, by supplying the     |
+            |               |           | last returned value from the previous       |
+            |               |           | range as the start field value for an       |
+            |               |           | iterator over the next range.               |
+            +---------------+-----------+---------------------------------------------+
+
+            **BITSET iterator types**
+
+            +----------------------------+-----------+---------------------------------------------+
+            | Type                       | Arguments | Description                                 |
+            +============================+===========+=============================================+
+            | box.index.ALL              | none      | Iterate over all tuples in an index. Tuples |
+            | or 'ALL'                   |           | are returned in ascending order of the      |
+            |                            |           | key's bitset, and so will appear to be      |
+            |                            |           | unordered.                                  |
+            +----------------------------+-----------+---------------------------------------------+
+            | box.index.EQ               | field     | Equality iterator: iterate over all tuples  |
+            | or 'EQ'                    | values    | matching the field values. If there are     |
+            |                            |           | multiple field values, they need to be      |
+            |                            |           | separated by commas.                        |
+            |                            |           |                                             |
+            |                            |           | BITSET indexes are always unique.           |
+            +----------------------------+-----------+---------------------------------------------+
+            | box.index.BITS_ALL_SET     | field     | Keys match if all of the bits specified in  |
+            |                            | values    | 'bit mask' are set.                         |
+            +----------------------------+-----------+---------------------------------------------+
+            | box.index.BITS_ANY_SET     | field     | Keys match if any of the bits specified in  |
+            |                            | values    | 'bit mask' is set.                          |
+            +----------------------------+-----------+---------------------------------------------+
+            | box.index.BITS_ALL_NOT_SET | field     | Keys match if none of the bits specified in |
+            |                            | values    | 'bit mask' is set.                          |
+            +----------------------------+-----------+---------------------------------------------+
+
+            .. _rtree-iterator:
+
+            **RTREE iterator types**
+
+            +--------------------+-----------+---------------------------------------------+
+            | Type               | Arguments | Description                                 |
+            +====================+===========+=============================================+
+            | box.index.ALL      | none      | All keys match. Tuples are returned in      |
+            | or 'ALL'           |           | ascending order of the primary key.         |
+            +--------------------+-----------+---------------------------------------------+
+            | box.index.EQ       | field     | Keys match if the rectangle defined by the  |
+            | or 'EQ'            | values    | field values is the same as the rectangle   |
+            |                    |           | defined by the key -- where "key" means     |
+            |                    |           | "the key in the RTREE index" and            |
+            |                    |           | "rectangle" means "rectangle as explained   |
+            |                    |           | in section RTREE_.                          |
+            +--------------------+-----------+---------------------------------------------+
+            | box.index.GT       | field     | Keys match if all points of the rectangle   |
+            | or 'GT'            | values    | defined by the field values are within the  |
+            |                    |           | rectangle defined by the key.               |
+            +--------------------+-----------+---------------------------------------------+
+            | box.index.GE       | field     | Keys match if all points of the rectangle   |
+            | or 'GE'            | values    | defined by the field values are within, or  |
+            |                    |           | at the side of, the rectangle defined by    |
+            |                    |           | the key.                                    |
+            +--------------------+-----------+---------------------------------------------+
+            | box.index.LT       | field     | Keys match if all points of the rectangle   |
+            | or 'LT'            | values    | defined by the key are within the rectangle |
+            |                    |           | defined by the field values.                |
+            +--------------------+-----------+---------------------------------------------+
+            | box.index.LE       | field     | Keys match if all points of the rectangle   |
+            | or 'LE'            | values    | defined by the key are within, or at the    |
+            |                    |           | side of, the rectangle defined by the field |
+            |                    |           | values.                                     |
+            +--------------------+-----------+---------------------------------------------+
+            | box.index.OVERLAPS | field     | Keys match if all points of the rectangle   |
+            | or 'OVERLAPS'      | values    | defined by the key are within, or at the    |
+            |                    |           | side of, the rectangle defined by the field |
+            |                    |           | values.                                     |
+            +--------------------+-----------+---------------------------------------------+
+            | box.index.NEIGHBOR | field     | Keys match if all points of the rectangle   |
+            | or 'NEIGHBOR'      | values    | defined by the key are within, or at the    |
+            |                    |           | side of, the rectangle defined by the field |
+            |                    |           | values.                                     |
+            +--------------------+-----------+---------------------------------------------+
+
+        .. code-block:: lua
+
+            tarantool> s = box.schema.space.create('space17')
+            ---
+            ...
+            tarantool> s:create_index('primary', {parts = {1, 'STR', 2, 'STR'}})
+            ---
+            ...
+            tarantool> s:insert{'C', 'C'}
+            ---
+            - ['C', 'C']
+            ...
+            tarantool> s:insert{'B', 'A'}
+            ---
+            - ['B', 'A']
+            ...
+            tarantool> s:insert{'C', '!'}
+            ---
+            - ['C', '!']
+            ...
+            tarantool> s:insert{'A', 'C'}
+            ---
+            - ['A', 'C']
+            ...
+            tarantool> console = require('console'); console.delimiter('!')
+            ---
+            ...
+            tarantool> function example()
+                     >   for _, tuple in
+                     >   s.index.primary:pairs(nil, {iterator = box.index.ALL}) do
+                     >     print(tuple)
+                     >   end
+                     > end!
+            ---
+            ...
+            tarantool> console.delimiter('')!
+            ---
+            ...
+            tarantool> example()
+            ['A', 'C']
+            ['B', 'A']
+            ['C', '!']
+            ['C', 'C']
+            ---
+            ...
+            tarantool> s:drop()
+            ---
+            ...
+
+    .. function:: select(key, options)
+
+        This is is an alternative to box.space...select() which goes via a
+        particular index and can make use of additional parameters that specify the
+        iterator type, and the limit (that is, the maximum number of tuples to
+        return) and the offset (that is, which tuple to start with in the list).
+
+        :param lua-table or scalar key: values to be matched against the index key.
+        :param lua-table options: table with any or all of iterator=iterator-type
+                                    limit=maximum-number-of-tuples,
+                                    offset=start-tuple-number.
+
+        :return: the tuple or tuples that match the field values.
+        :rtype:  tuple set as a Lua table
+
+        .. code-block:: lua
+
+            -- Create a space named tester.
+            -- Create a unique index 'primary', which won't be needed for this example.
+            -- Create a non-unique index 'secondary' with an index on the second field.
+            -- Insert three tuples, values in field[2] equal to 'X', 'Y', and 'Z'.
+            -- Select all tuples where the secondary index keys are greater than 'X'.
+            box.schema.space.create('tester')
+            box.space.tester:create_index('primary', {parts = {1, 'NUM' }})
+            box.space.tester:create_index('secondary', {type = 'tree', unique = false, parts = {2, 'STR'}})
+            box.space.tester:insert{1,'X','Row with field[2]=X'}
+            box.space.tester:insert{2,'Y','Row with field[2]=Y'}
+            box.space.tester:insert{3,'Z','Row with field[2]=Z'}
+            box.space.tester.index.secondary:select({'X'}, {iterator = 'GT', limit = 1000})
+
+        The result will be a table of tuple and will look like this:
+
+        .. code-block:: yaml
+
+            ---
+            - - [2, 'Y', 'Row with field[2]=Y']
+              - [3, 'Z', 'Row with field[2]=Z']
+            ...
+
+        .. NOTE::
+
+            [.index.index-name] is optional. If it is omitted, then the assumed
+            index is the first (primary-key) index. Therefore, for the example
+            above, ``box.space.tester:select({1}, {iterator = 'GT'})`` would have
+            returned the same two rows, via the 'primary' index.
+
+        .. NOTE::
+
+            ``iterator = iterator type`` is optional. If it is omitted, then
+            ``iterator = 'EQ'`` is assumed.
+
+        .. NOTE::
+
+            ``field-value [, field-value ...]`` is optional. If it is omitted,
+            then every key in the index is considered to be a match, regardless of
+            iterator type. Therefore, for the example above,
+            ``box.space.tester:select{}`` will select every tuple in the tester
+            space via the first (primary-key) index.
+
+        .. NOTE::
+
+            ``box.space.space-name.index.index-name:select(...)[1]``. can be
+            replaced by ``box.space.space-name.index.index-name:get(...)``.
+            That is, get can be used as a convenient shorthand to get the first
+            tuple in the tuple set that would be returned by select. However,
+            if there is more than one tuple in the tuple set, then get returns
+            an error.
+
+    .. function:: min([key-value])
 
-    Find the minimum value in the specified index.
+        Find the minimum value in the specified index.
 
-    :return: the tuple for the first key in the index. If optional
-             ``key-value`` is supplied, returns the first key which
-             is greater than or equal to ``key-value``.
-    :rtype:  tuple
-    :except: index is not of type 'TREE'.
+        :return: the tuple for the first key in the index. If optional
+                ``key-value`` is supplied, returns the first key which
+                is greater than or equal to ``key-value``.
+        :rtype:  tuple
+        :except: index is not of type 'TREE'.
 
-    Complexity Factors: Index size, Index type.
+        Complexity Factors: Index size, Index type.
 
-    .. code-block:: lua
+        .. code-block:: lua
 
-        tarantool> box.space.tester.index.primary:min()
-        ---
-        - ['Alpha!', 55, 'This is the first tuple!']
-        ...
+            tarantool> box.space.tester.index.primary:min()
+            ---
+            - ['Alpha!', 55, 'This is the first tuple!']
+            ...
 
-.. function:: box.space.space-name.index.index-name:max([key-value])
+    .. function:: max([key-value])
 
-    Find the maximum value in the specified index.
+        Find the maximum value in the specified index.
 
-    :return: the tuple for the last key in the index. If optional ``key-value``
-             is supplied, returns the last key which is less than or equal to
-             ``key-value``.
-    :rtype:  tuple
-    :except: index is not of type 'TREE'.
+        :return: the tuple for the last key in the index. If optional ``key-value``
+                is supplied, returns the last key which is less than or equal to
+                ``key-value``.
+        :rtype:  tuple
+        :except: index is not of type 'TREE'.
 
-    Complexity Factors: Index size, Index type.
+        Complexity Factors: Index size, Index type.
 
-    .. code-block:: lua
+        .. code-block:: lua
 
-        tarantool> box.space.tester.index.primary:max()
-        ---
-        - ['Gamma!', 55, 'This is the third tuple!']
-        ...
+            tarantool> box.space.tester.index.primary:max()
+            ---
+            - ['Gamma!', 55, 'This is the third tuple!']
+            ...
 
 
-.. function:: box.space.space-name.index.index-name:random(random-value)
+    .. function:: random(random-value)
 
-    Find a random value in the specified index. This method is useful when it's
-    important to get insight into data distribution in an index without having
-    to iterate over the entire data set.
+        Find a random value in the specified index. This method is useful when it's
+        important to get insight into data distribution in an index without having
+        to iterate over the entire data set.
 
-    :param integer random-value: an arbitrary non-negative integer.
-    :return: the tuple for the random key in the index.
-    :rtype:  tuple
+        :param integer random-value: an arbitrary non-negative integer.
+        :return: the tuple for the random key in the index.
+        :rtype:  tuple
 
-    Complexity Factors: Index size, Index type.
+        Complexity Factors: Index size, Index type.
 
-    .. code-block:: lua
+        .. code-block:: lua
 
-        tarantool> box.space.tester.index.secondary:random(1)
-        ---
-        - ['Beta!', 66, 'This is the second tuple!']
-        ...
+            tarantool> box.space.tester.index.secondary:random(1)
+            ---
+            - ['Beta!', 66, 'This is the second tuple!']
+            ...
 
-.. function:: box.space.space-name.index.index-name:count(key-value, options)
+    .. function:: count(key-value, options)
 
-    Iterate over an index, counting the number of
-    tuples which equal the provided search criteria.
+        Iterate over an index, counting the number of
+        tuples which equal the provided search criteria.
 
-    :param lua-value key-value: the value which must match the key(s) in the
-                                specified index. The type may be a list of
-                                field-values, or a tuple containing only
-                                the field-values.
+        :param lua-value key-value: the value which must match the key(s) in the
+                                    specified index. The type may be a list of
+                                    field-values, or a tuple containing only
+                                    the field-values.
 
-    :return: the number of matching index keys. The ``index`` function
-             is only applicable for the memtx storage engine.
-    :rtype:  number
+        :return: the number of matching index keys. The ``index`` function
+                is only applicable for the memtx storage engine.
+        :rtype:  number
 
-    .. code-block:: lua
+        .. code-block:: lua
 
-        tarantool> box.space.tester.index.primary:count(999)
-        ---
-        - 0
-        ...
-        tarantool> box.space.tester.index.primary:count('Alpha!', { iterator = 'LE' })
-        ---
-        - 1
-        ...
+            tarantool> box.space.tester.index.primary:count(999)
+            ---
+            - 0
+            ...
+            tarantool> box.space.tester.index.primary:count('Alpha!', { iterator = 'LE' })
+            ---
+            - 1
+            ...
 
-.. function:: box.space.space-name.index.index-name:alter{options}
+    .. function:: alter({options})
 
-    Alter an index.
+        Alter an index.
 
-    :param table options: options list for create_index().
-    :return: nil
+        :param table options: options list for create_index().
+        :return: nil
 
-    :except: If index-name doesn't exist.
-    :except: The first index cannot be changed to {unique = false}.
-    :except: The alter function is only applicable for the memtx storage engine.
+        :except: If index-name doesn't exist.
+        :except: The first index cannot be changed to {unique = false}.
+        :except: The alter function is only applicable for the memtx storage engine.
 
-    .. code-block:: lua
+        .. code-block:: lua
 
-        tarantool> box.space.space55.index.primary:alter({type = 'HASH'})
-        ---
-        ...
+            tarantool> box.space.space55.index.primary:alter({type = 'HASH'})
+            ---
+            ...
 
-.. function:: space-name.index.index-name:drop()
+    .. function:: drop()
 
-    Drop an index. Dropping a primary-key index has
-    a side effect: all tuples are deleted.
+        Drop an index. Dropping a primary-key index has
+        a side effect: all tuples are deleted.
 
-    :return: nil.
-    :except: If index-name doesn't exist.
+        :return: nil.
+        :except: If index-name doesn't exist.
 
-    .. code-block:: lua
+        .. code-block:: lua
 
-        tarantool> box.space.space55.index.primary:drop()
-        ---
-        ...
+            tarantool> box.space.space55.index.primary:drop()
+            ---
+            ...
 
-.. function:: space-name.index.index-name:rename(index-name)
+    .. function:: rename(index-name)
 
-    Rename an index.
+        Rename an index.
 
-    :param string index-name: new name for index.
-    :return: nil
-    :except: If index-name doesn't exist.
+        :param string index-name: new name for index.
+        :return: nil
+        :except: If index-name doesn't exist.
 
-    .. code-block:: lua
+        .. code-block:: lua
 
-        tarantool> box.space.space55.index.primary:rename('secondary')
-        ---
-        ...
+            tarantool> box.space.space55.index.primary:rename('secondary')
+            ---
+            ...
 
-    Complexity Factors: Index size, Index type, Number of tuples accessed.
+        Complexity Factors: Index size, Index type, Number of tuples accessed.
 
 
 ===========================================================
diff --git a/doc/sphinx/book/box/box_schema.rst b/doc/sphinx/book/box/box_schema.rst
index 8b6bdebc740c5702229e799299860279e43ad8b8..ce26ff70c6a2ca73df8e2b36a4db1d2f045608c4 100644
--- a/doc/sphinx/book/box/box_schema.rst
+++ b/doc/sphinx/book/box/box_schema.rst
@@ -55,6 +55,6 @@ The ``box.schema`` package has one data-definition function: ``space.create()``.
     ...
 
 After a space is created, usually the next step is to
-:func:`create an index <box.space.space-name.create_index>` for it,
+:func:`create an index <space_object.create_index>` for it,
 and then it is available for insert, select, and all the other :mod:`box.space`
 functions.
diff --git a/doc/sphinx/book/box/box_space.rst b/doc/sphinx/book/box/box_space.rst
index 0ba777a62beb3cd2a5f01164268287431925985a..8fa06ed36d5b7c32ad9e2b8ecdaf25da632e855a 100644
--- a/doc/sphinx/book/box/box_space.rst
+++ b/doc/sphinx/book/box/box_space.rst
@@ -13,566 +13,586 @@ is available in file
 A list of all ``box.space`` functions follows, then comes a list of all
 ``box.space`` members.
 
-.. function:: box.space.space-name:create_index(index-name [, {options} ])
-
-    Create an index. It is **mandatory** to create an index for a tuple set
-    before trying to insert tuples into it, or select tuples from it. The
-    first created index, which will be used as the primary-key index, must be
-    **unique**.
-
-    :param string index-name: name of index, which should not be a number and
-                              should not contain special characters;
-    :param table options:
-
-    :return: index object
-    :rtype:  userdata
-
-    .. container:: table
-
-        **Options for box.space...create_index**
-
-        +---------------+--------------------+-----------------------------+---------------------+
-        | Name          | Effect             | Type                        | Default             |
-        +===============+====================+=============================+=====================+
-        | type          | type of index      | string                      | 'TREE'              |
-        |               |                    | ('HASH',     'TREE',        |                     |
-        |               |                    | 'BITSET',   'RTREE')        |                     |
-        |               |                    |                             |                     |
-        |               |                    |                             |                     |
-        |               |                    |                             |                     |
-        +---------------+--------------------+-----------------------------+---------------------+
-        | id            | unique identifier  | number                      | last index's id, +1 |
-        +---------------+--------------------+-----------------------------+---------------------+
-        | unique        | index is unique    | boolean                     | true                |
-        +---------------+--------------------+-----------------------------+---------------------+
-        | if_not_exists | no error if        | boolean                     | false               |
-        |               | duplicate name     |                             |                     |
-        +---------------+--------------------+-----------------------------+---------------------+
-        | parts         | field-numbers  +   | ``{field_no, 'NUM'|'STR'}`` | ``{1, 'NUM'}``      |
-        |               | types              |                             |                     |
-        +---------------+--------------------+-----------------------------+---------------------+
-
-    Possible errors: too many parts. A type options other than TREE, or a
-    unique option other than unique, or a parts option with more than one
-    field component, is only applicable for the memtx storage engine.
+.. class:: space_object
 
-    .. code-block:: lua
+    .. function:: create_index(index-name [, {options} ])
 
-        tarantool> s = box.space.space55
-        ---
-        ...
-        tarantool> s:create_index('primary', {unique = true, parts = {1, 'NUM', 2, 'STR'}})
-        ---
-        ...
+        Create an index. It is **mandatory** to create an index for a tuple set
+        before trying to insert tuples into it, or select tuples from it. The
+        first created index, which will be used as the primary-key index, must be
+        **unique**.
 
-.. function:: box.space.space-name:insert{field-value [, field-value ...]}
+        :param string index-name: name of index, which should not be a number and
+                                should not contain special characters;
+        :param table options:
 
-    Insert a tuple into a space.
+        :return: index object
+        :rtype:  index_object
 
-    :param userdata      space-name:
-    :param lua-value field-value(s): fields of the new tuple.
-    :return: the inserted tuple
-    :rtype:  tuple
+        .. container:: table
 
-    :except: If a tuple with the same unique-key value already exists,
-             returns ``ER_TUPLE_FOUND``.
+            **Options table**
 
-    .. code-block:: lua
-
-        box.space.tester:insert{5000,'tuple number five thousand'}
+            +---------------+--------------------+-----------------------------+---------------------+
+            | Name          | Effect             | Type                        | Default             |
+            +===============+====================+=============================+=====================+
+            | type          | type of index      | string                      | 'TREE'              |
+            |               |                    | ('HASH',     'TREE',        |                     |
+            |               |                    | 'BITSET',   'RTREE')        |                     |
+            |               |                    |                             |                     |
+            |               |                    |                             |                     |
+            |               |                    |                             |                     |
+            +---------------+--------------------+-----------------------------+---------------------+
+            | id            | unique identifier  | number                      | last index's id, +1 |
+            +---------------+--------------------+-----------------------------+---------------------+
+            | unique        | index is unique    | boolean                     | true                |
+            +---------------+--------------------+-----------------------------+---------------------+
+            | if_not_exists | no error if        | boolean                     | false               |
+            |               | duplicate name     |                             |                     |
+            +---------------+--------------------+-----------------------------+---------------------+
+            | parts         | field-numbers  +   | ``{field_no, 'NUM'|'STR'}`` | ``{1, 'NUM'}``      |
+            |               | types              |                             |                     |
+            +---------------+--------------------+-----------------------------+---------------------+
 
-.. function:: box.space.space-name:select{field-value [, field-value ...]}
+        Possible errors: too many parts. A type options other than TREE, or a
+        unique option other than unique, or a parts option with more than one
+        field component, is only applicable for the memtx storage engine.
 
-    Search for a tuple or a set of tuples in the given space.
+        .. code-block:: lua
 
-    :param userdata      space-name:
-    :param lua-value field-value(s): values to be matched against the index
-                                     key, which may be multi-part.
+            tarantool> s = box.space.space55
+            ---
+            ...
+            tarantool> s:create_index('primary', {unique = true, parts = {1, 'NUM', 2, 'STR'}})
+            ---
+            ...
 
-    :return: the tuples whose primary-key fields are equal to the passed
-             field-values. If the number of passed field-values is less
-             than the number of fields in the primary key, then only the
-             passed field-values are compared, so ``select{1,2}`` will match
-             a tuple whose primary key is ``{1,2,3}``.
-    :rtype:  tuple
+    .. function:: insert(tuple)
 
-    :except: No such space; wrong type.
+        Insert a tuple into a space.
 
-    Complexity Factors: Index size, Index type.
+        :param space_object space-object:
+        :param lua-table,box.tuple tuple: tuple to be inserted.
+        :return: the inserted tuple
+        :rtype:  tuple
 
-    .. code-block:: lua
+        Possible errors: If a tuple with the same unique-key value already exists,
+        returns :errcode:`ER_TUPLE_FOUND`.
 
-        tarantool> s = box.schema.space.create('tmp', {temporary=true})
-        ---
-        ...
-        tarantool> s:create_index('primary',{parts = {1,'NUM', 2, 'STR'}})
-        ---
-        ...
-        tarantool> s:insert{1,'A'}
-        ---
-        - [1, 'A']
-        ...
-        tarantool> s:insert{1,'B'}
-        ---
-        - [1, 'B']
-        ...
-        tarantool> s:insert{1,'C'}
-        ---
-        - [1, 'C']
-        ...
-        tarantool> s:insert{2,'D'}
-        ---
-        - [2, 'D']
-        ...
-        tarantool> -- must equal both primary-key fields
-        tarantool> s:select{1,'B'}
-        ---
-        - - [1, 'B']
-        ...
-        tarantool> -- must equal only one primary-key field
-        tarantool> s:select{1}
-        ---
-        - - [1, 'A']
-          - [1, 'B']
-          - [1, 'C']
-        ...
-        tarantool> -- must equal 0 fields, so returns all tuples
-        tarantool> s:select{}
-        ---
-        - - [1, 'A']
-          - [1, 'B']
-          - [1, 'C']
-          - [2, 'D']
-        ...
+        .. code-block:: lua
 
-    For examples of complex ``select`` requests, where one can specify which index to
-    search and what condition to use (for example "greater than" instead of
-    "equal to") and how many tuples to return, see the later section
-    ``box.space.space-name[.index.index-name]:select``.
+            box.space.tester:insert{5000,'tuple number five thousand'}
 
-.. function:: box.space.space-name:get{field-value [, field-value ...]}
+    .. function:: select(key)
 
-    Search for a tuple in the given space.
+        Search for a tuple or a set of tuples in the given space.
 
-    :param userdata      space-name:
-    :param lua-value field-value(s): values to be matched against the index
+        :param space_object space-object:
+        :param lua-table,scalar key: key to be matched against the index
                                      key, which may be multi-part.
-    :return: the selected tuple.
-    :rtype:  tuple
-
-    :except: If space-name does not exist.
-
-    Complexity Factors: Index size, Index type,
-    Number of indexes accessed, WAL settings.
-
-    .. code-block:: lua
-
-        tarantool> box.space.tester:get{1}
-
-.. function:: box.space.space-name:drop()
-
-    Drop a space.
-
-    :return: nil
-    :except: If space-name does not exist.
-
-    Complexity Factors: Index size, Index type,
-    Number of indexes accessed, WAL settings.
-
-    .. code-block:: lua
-
-        tarantool> box.space.space_that_does_not_exist:drop()
-
-.. function:: box.space.space-name:rename(space-name)
-
-    Rename a space.
-
-    :param string space-name: new name for space.
-
-    :return: nil
-    :except: If space-name does not exist.
-
-    .. code-block:: lua
-
-        tarantool> box.space.space55:rename('space56')
-        ---
-        ...
-        tarantool> box.space.space56:rename('space55')
-        ---
-        ...
-
-.. function:: box.space.space-name:replace{field-value [, field-value ...]}
-              box.space.space-name:put{field-value [, field-value ...]}
-
-    Insert a tuple into a space. If a tuple with the same primary key already
-    exists, ``box.space...:replace()`` replaces the existing tuple with a new
-    one. The syntax variants ``box.space...:replace()`` and
-    ``box.space...:put()`` have the same effect; the latter is sometimes used
-    to show that the effect is the converse of ``box.space...:get()``.
-
-    :param userdata      space-name:
-    :param lua-value field-value(s): fields of the new tuple.
-
-    :return: the inserted tuple.
-    :rtype:  tuple
-
-    :except: If a different tuple with the same unique-key
-             value already exists, returns ``ER_TUPLE_FOUND``.
-             (This would only happen if there was a secondary
-             index. By default secondary indexes are unique.)
-
-    Complexity Factors: Index size, Index type,
-    Number of indexes accessed, WAL settings.
-
-    .. code-block:: lua
-
-        tarantool> box.space.tester:replace{5000, 'New value'}
-
-.. function:: box.space.space-name:update(key, {{operator, field_no, value}, ...})
-
-    Update a tuple.
-
-    The ``update`` function supports operations on fields — assignment,
-    arithmetic (if the field is unsigned numeric), cutting and pasting
-    fragments of a field, deleting or inserting a field. Multiple
-    operations can be combined in a single update request, and in this
-    case they are performed atomically and sequentially. Each operation
-    requires specification of a field number. When multiple operations
-    are present, the field number for each operation is assumed to be
-    relative to the most recent state of the tuple, that is, as if all
-    previous operations in a multi-operation update have already been
-    applied. In other words, it is always safe to merge multiple update
-    invocations into a single invocation, with no change in semantics.
-
-    :param userdata space-name:
-    :param lua-value key: primary-key field values, must be passed as a Lua
-                          table if key is multi-part
-    :param table {operator, field_no, value}: a group of arguments for each
-            operation, indicating what the operation is, what field the
-            operation will apply to, and what value will be applied. For
-            some operations the field number can be -1, meaning the last
-            field in the tuple. Possible operators are: “+” for addition,
-            “-” for subtraction, “&” for bitwise AND, “|” for bitwise OR,
-            “^” for bitwise exclusive OR (XOR), “:” for string splice, “!”
-            for insert, “#” for delete. Thus in the instruction
-            ``s:update(44, {{'+',1,55},{'=',3,'x'}})`` the primary-key
-            value is 44, the operators are '+' and '=' meaning "add a value
-            to a field and then assign a value to a field", the first
-            affected field is field 1 and the value which will be added to
-            it is 55, the second affected field is field 3 and the value
-            which will be assigned to it is 'x'.
-
-    :return: the updated tuple.
-    :rtype:  tuple
-
-    :except: it is illegal to modify a primary-key field.
-
-    Complexity Factors: Index size, Index type, number of indexes accessed, WAL
-    settings.
-
-    .. code-block:: lua
-
-        -- Assume that the initial state of the database is ...
-        --   tester has one tuple set and one primary key whose type is 'NUM'.
-        --   There is one tuple, with field[1] = 999 and field[2] = 'A'.
-
-        -- In the following update ...
-        --   The first argument is tester, that is, the affected space is tester
-        --   The second argument is 999, that is, the affected tuple is identified by
-        --     primary key value = 999
-        --   The third argument is '=', that is, there is one operation, assignment
-        --     to a field
-        --   The fourth argument is 2, that is, the affected field is field[2]
-        --   The fifth argument is 'B', that is, field[2] contents change to 'B'
-        --   Therefore, after the following update, field[1] = 999 and field[2] = 'B'.
-        box.space.tester:update(999, {{'=', 2, 'B'}})
-
-        -- In the following update, the arguments are the same, except that ...
-        --   the key is passed as a Lua table (inside braces). This is unnecessary
-        --   when the primary key has only one field, but would be necessary if the
-        --   primary key had more than one field.
-        --   Therefore, after the following update, field[1] = 999 and field[2] = 'B'
-        --     (no change).
-        box.space.tester:update({999}, {{'=', 2, 'B'}})
-
-        -- In the following update, the arguments are the same, except that ...
-        --    The fourth argument is 3, that is, the affected field is field[3].
-        --    It is okay that, until now, field[3] has not existed. It gets added.
-        --    Therefore, after the following update, field[1] = 999, field[2] = 'B',
-        --      field[3] = 1.
-        box.space.tester:update({999}, {{'=', 3, 1}})
-
-        -- In the following update, the arguments are the same, except that ...
-        --    The third argument is '+', that is, the operation is addition rather
-        --      than assignment.
-        --    Since field[3] previously contained 1, this means we're adding 1 to 1.
-        --    Therefore, after the following update, field[1] = 999, field[2] = 'B',
-        --      field[3] = 2.
-        box.space.tester:update({999}, {{'+', 3, 1}})
-
-        -- In the following update ...
-        --    The idea is to modify two fields at once.
-        --    The formats are '|' and '=', that is, there are two operations, OR and
-        --      assignment.
-        --    The fourth and fifth arguments mean that field[3] gets ORed with 1.
-        --    The seventh and eighth arguments mean that field[2] gets assigned 'C'.
-        --    Therefore, after the following update, field[1] = 999, field[2] = 'C',
-        --      field[3] = 3.
-        box.space.tester:update({999}, {{'|', 3, 1}, {'=', 2, 'C'}})
-
-        -- In the following update ...
-        --    The idea is to delete field[2], then subtract 3 from field[3], but ...
-        --    after the delete, there is a renumbering -- so field[3] becomes field[2]
-        --    before we subtract 3 from it, and that's why the seventh argument is 2 not 3.
-        --    Therefore, after the following update, field[1] = 999, field[2] = 0.
-        box.space.tester:update({999}, {{'-- ', 2, 1}, {'-', 2, 3}})
-
-        -- In the following update ...
-        --    We're making a long string so that splice will work in the next example.
-        --    Therefore, after the following update, field[1] = 999, field[2] = 'XYZ'.
-        box.space.tester:update({999}, {{'=', 2, 'XYZ'}})
-
-        -- In the following update ...
-        --    The third argument is ':', that is, this is the example of splice.
-        --    The fourth argument is 2 because the change will occur in field[2].
-        --    The fifth argument is 2 because deletion will begin with the second byte.
-        --    The sixth argument is 1 because the number of bytes to delete is 1.
-        --    The seventh argument is '!!' because '!!' is to be added at this position.
-        --    Therefore, after the following update, field[1] = 999, field[2] = 'X!!Z'.
-        box.space.tester:update({999}, {{':', 2, 2, 1, '!!'}})
-
-.. function:: box.space.space-name:delete{field-value [, field-value ...]}
-
-    Delete a tuple identified by a primary key.
-
-    :param userdata space-name:
-    :param lua-value field-value(s): values to match against keys
-                                     in the primary index.
-
-    :return: the deleted tuple
-    :rtype:  tuple
-
-    Complexity Factors: Index size, Index type
-
-    .. code-block:: lua
-
-        tarantool> box.space.tester:delete(0)
-        ---
-        - [0, 'My first tuple']
-        ...
-        tarantool> box.space.tester:delete(0)
-        ---
-        ...
-        tarantool> box.space.tester:delete('a')
-        ---
-        - error: 'Supplied key type of part 0 does not match index part type:
-          expected NUM'
-        ...
 
-.. data::     space-name.id
+        :return: the tuples whose primary-key fields are equal to the passed
+                 field-values. If the number of passed field-values is less
+                 than the number of fields in the primary key, then only the
+                 passed field-values are compared, so ``select{1,2}`` will match
+                 a tuple whose primary key is ``{1,2,3}``.
+        :rtype:  tuple
+
+        Possible errors: No such space; wrong type.
 
-    Ordinal space number. Spaces can be referenced by either name or
-    number. Thus, if space 'tester' has id = 800, then
-    ``box.space.tester:insert{0}`` and ``box.space[800]:insert{0}``
-    are equivalent requests.
+        Complexity Factors: Index size, Index type.
 
-    :rtype: number
+        .. code-block:: lua
 
-.. data::     space-name.enabled
+            tarantool> s = box.schema.space.create('tmp', {temporary=true})
+            ---
+            ...
+            tarantool> s:create_index('primary',{parts = {1,'NUM', 2, 'STR'}})
+            ---
+            ...
+            tarantool> s:insert{1,'A'}
+            ---
+            - [1, 'A']
+            ...
+            tarantool> s:insert{1,'B'}
+            ---
+            - [1, 'B']
+            ...
+            tarantool> s:insert{1,'C'}
+            ---
+            - [1, 'C']
+            ...
+            tarantool> s:insert{2,'D'}
+            ---
+            - [2, 'D']
+            ...
+            tarantool> -- must equal both primary-key fields
+            tarantool> s:select{1,'B'}
+            ---
+            - - [1, 'B']
+            ...
+            tarantool> -- must equal only one primary-key field
+            tarantool> s:select{1}
+            ---
+            - - [1, 'A']
+              - [1, 'B']
+              - [1, 'C']
+            ...
+            tarantool> -- must equal 0 fields, so returns all tuples
+            tarantool> s:select{}
+            ---
+            - - [1, 'A']
+              - [1, 'B']
+              - [1, 'C']
+              - [2, 'D']
+            ...
 
-    Whether or not this space is enabled.
-    The value is false if there is no index.
+        For examples of complex ``select`` requests, where one can specify which index to
+        search and what condition to use (for example "greater than" instead of
+        "equal to") and how many tuples to return, see the later section
+        ``box.space.space-name[.index.index-name]:select``.
 
-    :rtype: boolean
+    .. function:: get(key)
 
-.. data::     space-name.field_count
+        Search for a tuple in the given space.
 
-    The required field count for all tuples in this space. The field_count
-    can be set initially with
-    ``box.schema.space.create... field_count = new-field-count-value ...``.
-    The default value is 0, which means there is no required field count.
+        :param space_object space-object:
+        :param lua-table,scalar key: key to be matched against the index
+                                        key, which may be multi-part.
+        :return: the selected tuple.
+        :rtype:  tuple
+
+        Possible errors: If space-name does not exist.
+
+        Complexity Factors: Index size, Index type,
+        Number of indexes accessed, WAL settings.
+
+        .. code-block:: lua
+
+            tarantool> box.space.tester:get{1}
+
+    .. function:: drop()
+
+        Drop a space.
+
+        :param space_object space-object:
+
+        :return: nil
+
+        Possible errors: If space-name does not exist.
 
-    :rtype: number
+        Complexity Factors: Index size, Index type,
+        Number of indexes accessed, WAL settings.
 
-.. data::     space-name.index[]
+        .. code-block:: lua
+
+            tarantool> box.space.space_that_does_not_exist:drop()
+
+    .. function:: rename(space-name)
+
+        Rename a space.
+
+        :param space_object space-object:
+        :param string space-name: new name for space.
 
-    A container for all defined indexes. An index is a Lua object of type
-    :mod:`box.index` with methods to search tuples and iterate over them in
-    predefined order.
+        :return: nil
 
-    :rtype: table
+        Possible errors: ``space-name`` does not exist.
+
+        .. code-block:: lua
+
+            tarantool> box.space.space55:rename('space56')
+            ---
+            ...
+            tarantool> box.space.space56:rename('space55')
+            ---
+            ...
+
+    .. function:: replace(tuple)
+                  put(tuple)
+
+        Insert a tuple into a space. If a tuple with the same primary key already
+        exists, ``box.space...:replace()`` replaces the existing tuple with a new
+        one. The syntax variants ``box.space...:replace()`` and
+        ``box.space...:put()`` have the same effect; the latter is sometimes used
+        to show that the effect is the converse of ``box.space...:get()``.
+
+        :param space_object space-object:
+        :param lua-table,box.tuple tuple: tuple to be inserted.
+
+        :return: the inserted tuple.
+        :rtype:  tuple
+
+        Possible errors: If a different tuple with the same unique-key
+        value already exists, returns :errcode:`ER_TUPLE_FOUND`. (This
+        would only happen if there was a secondary index. By default
+        secondary indexes are unique)
+
+        Complexity Factors: Index size, Index type,
+        Number of indexes accessed, WAL settings.
 
-    .. code-block: lua
+        .. code-block:: lua
 
-        tarantool> box.space.tester.id
-        ---
-        - 512
-        ...
-        tarantool> box.space.tester.field_count
-        ---
-        - 0
-        ...
-        tarantool> box.space.tester.index.primary.type
-        ---
-        - TREE
-        ...
+            tarantool> box.space.tester:replace{5000, 'New value'}
 
-.. function:: box.space.space-name:len()
+    .. function:: update(key, {{operator, field_no, value}, ...})
 
-    .. NOTE::
+        Update a tuple.
 
-        The ``len()`` function is only applicable for the memtx storage engine.
+        The ``update`` function supports operations on fields — assignment,
+        arithmetic (if the field is unsigned numeric), cutting and pasting
+        fragments of a field, deleting or inserting a field. Multiple
+        operations can be combined in a single update request, and in this
+        case they are performed atomically and sequentially. Each operation
+        requires specification of a field number. When multiple operations
+        are present, the field number for each operation is assumed to be
+        relative to the most recent state of the tuple, that is, as if all
+        previous operations in a multi-operation update have already been
+        applied. In other words, it is always safe to merge multiple update
+        invocations into a single invocation, with no change in semantics.
 
-    :return: Number of tuples in the space.
+        Possible operators are:
 
-    .. code-block:: lua
+            * '+' for addition
+            * '-' for substraction
+            * '&' for bitwise AND
+            * '|' for bitwise OR
+            * '^' for butwise :abbr:`XOR(exclusive OR)`
+            * ':' for string splice
+            * '!' for insert
+            * '#' for delete
 
-        tarantool> box.space.tester:len()
-        ---
-        - 2
-        ...
+        :param space_object space-object:
+        :param lua-value key: primary-key field values, must be passed as a Lua
+                              table if key is multi-part
+        :param table {operator, field_no, value}: a group of arguments for each
+                operation, indicating what the operation is, what field the
+                operation will apply to, and what value will be applied. For
+                some operations the field number can be -1, meaning the last
+                field in the tuple. Thus in the instruction
 
-.. function:: box.space.space-name:truncate()
+        :return: the updated tuple.
+        :rtype:  tuple
+
+        Possible errors: it is illegal to modify a primary-key field.
+
+        Complexity Factors: Index size, Index type, number of indexes accessed, WAL
+        settings.
+
+        .. code-block:: lua
+
+            s:update(44, {{'+',1,55},{'=',3,'x'}})
+
+        the primary-key value is 44, the operators are '+' and '=' meaning
+        "add a value to a field and then assign a value to a field", the first
+        affected field is field 1 and the value which will be added to it is
+        55, the second affected field is field 3 and the value which will be
+        assigned to it is 'x'.
+
+        .. code-block:: lua
+
+            -- Assume that the initial state of the database is ...
+            --   tester has one tuple set and one primary key whose type is 'NUM'.
+            --   There is one tuple, with field[1] = 999 and field[2] = 'A'.
+
+            -- In the following update ...
+            --   The first argument is tester, that is, the affected space is tester
+            --   The second argument is 999, that is, the affected tuple is identified by
+            --     primary key value = 999
+            --   The third argument is '=', that is, there is one operation, assignment
+            --     to a field
+            --   The fourth argument is 2, that is, the affected field is field[2]
+            --   The fifth argument is 'B', that is, field[2] contents change to 'B'
+            --   Therefore, after the following update, field[1] = 999 and field[2] = 'B'.
+            box.space.tester:update(999, {{'=', 2, 'B'}})
+
+            -- In the following update, the arguments are the same, except that ...
+            --   the key is passed as a Lua table (inside braces). This is unnecessary
+            --   when the primary key has only one field, but would be necessary if the
+            --   primary key had more than one field.
+            --   Therefore, after the following update, field[1] = 999 and field[2] = 'B'
+            --     (no change).
+            box.space.tester:update({999}, {{'=', 2, 'B'}})
+
+            -- In the following update, the arguments are the same, except that ...
+            --    The fourth argument is 3, that is, the affected field is field[3].
+            --    It is okay that, until now, field[3] has not existed. It gets added.
+            --    Therefore, after the following update, field[1] = 999, field[2] = 'B',
+            --      field[3] = 1.
+            box.space.tester:update({999}, {{'=', 3, 1}})
+
+            -- In the following update, the arguments are the same, except that ...
+            --    The third argument is '+', that is, the operation is addition rather
+            --      than assignment.
+            --    Since field[3] previously contained 1, this means we're adding 1 to 1.
+            --    Therefore, after the following update, field[1] = 999, field[2] = 'B',
+            --      field[3] = 2.
+            box.space.tester:update({999}, {{'+', 3, 1}})
+
+            -- In the following update ...
+            --    The idea is to modify two fields at once.
+            --    The formats are '|' and '=', that is, there are two operations, OR and
+            --      assignment.
+            --    The fourth and fifth arguments mean that field[3] gets ORed with 1.
+            --    The seventh and eighth arguments mean that field[2] gets assigned 'C'.
+            --    Therefore, after the following update, field[1] = 999, field[2] = 'C',
+            --      field[3] = 3.
+            box.space.tester:update({999}, {{'|', 3, 1}, {'=', 2, 'C'}})
+
+            -- In the following update ...
+            --    The idea is to delete field[2], then subtract 3 from field[3], but ...
+            --    after the delete, there is a renumbering -- so field[3] becomes field[2]
+            --    before we subtract 3 from it, and that's why the seventh argument is 2 not 3.
+            --    Therefore, after the following update, field[1] = 999, field[2] = 0.
+            box.space.tester:update({999}, {{'-- ', 2, 1}, {'-', 2, 3}})
+
+            -- In the following update ...
+            --    We're making a long string so that splice will work in the next example.
+            --    Therefore, after the following update, field[1] = 999, field[2] = 'XYZ'.
+            box.space.tester:update({999}, {{'=', 2, 'XYZ'}})
+
+            -- In the following update ...
+            --    The third argument is ':', that is, this is the example of splice.
+            --    The fourth argument is 2 because the change will occur in field[2].
+            --    The fifth argument is 2 because deletion will begin with the second byte.
+            --    The sixth argument is 1 because the number of bytes to delete is 1.
+            --    The seventh argument is '!!' because '!!' is to be added at this position.
+            --    Therefore, after the following update, field[1] = 999, field[2] = 'X!!Z'.
+            box.space.tester:update({999}, {{':', 2, 2, 1, '!!'}})
+
+    .. function:: delete(key)
 
-    Deletes all tuples.
+        Delete a tuple identified by a primary key.
+
+        :param space_object space-object:
+        :param lua-table,scalar key: key to be matched against the index
+                                        key, which may be multi-part.
+
+        :return: the deleted tuple
+        :rtype:  tuple
 
-    Complexity Factors: Index size, Index type, Number of tuples accessed.
+        Complexity Factors: Index size, Index type
 
-    :return: nil
+        .. code-block:: lua
+
+            tarantool> box.space.tester:delete(0)
+            ---
+            - [0, 'My first tuple']
+            ...
+            tarantool> box.space.tester:delete(0)
+            ---
+            ...
+            tarantool> box.space.tester:delete('a')
+            ---
+            - error: 'Supplied key type of part 0 does not match index part type:
+              expected NUM'
+            ...
+
+    .. data:: id
+
+        Ordinal space number. Spaces can be referenced by either name or
+        number. Thus, if space 'tester' has id = 800, then
+        ``box.space.tester:insert{0}`` and ``box.space[800]:insert{0}``
+        are equivalent requests.
+
+        :rtype: number
+
+    .. data:: enabled
+
+        Whether or not this space is enabled.
+        The value is false if there is no index.
+
+        :rtype: boolean
+
+    .. data:: field_count
+
+        The required field count for all tuples in this space. The field_count
+        can be set initially with
+        ``box.schema.space.create... field_count = new-field-count-value ...``.
+        The default value is 0, which means there is no required field count.
+
+        :rtype: number
+
+    .. data:: index
+
+        A container for all defined indexes. An index is a Lua object of type
+        :mod:`box.index` with methods to search tuples and iterate over them in
+        predefined order.
+
+        :rtype: table
 
-    .. code-block:: lua
+        .. code-block: lua
+
+            tarantool> box.space.tester.id
+            ---
+            - 512
+            ...
+            tarantool> box.space.tester.field_count
+            ---
+            - 0
+            ...
+            tarantool> box.space.tester.index.primary.type
+            ---
+            - TREE
+            ...
+
+    .. function:: len()
+
+        .. NOTE::
+
+            The ``len()`` function is only applicable for the memtx storage engine.
+
+        :return: Number of tuples in the space.
+
+        .. code-block:: lua
 
-        tarantool> box.space.tester:truncate()
-        ---
-        ...
-        tarantool> box.space.tester:len()
-        ---
-        - 0
-        ...
+            tarantool> box.space.tester:len()
+            ---
+            - 2
+            ...
 
-.. function:: box.space.space-name:inc{field-value [, field-value ...]}
+    .. function:: truncate()
 
-    Increments a counter in a tuple whose primary key matches the
-    ``field-value(s)``. The field following the primary-key fields
-    will be the counter. If there is no tuple matching the
-    ``field-value(s)``, a new one is inserted with initial counter
-    value set to 1.
+        Deletes all tuples.
 
-    :param userdata space-name:
-    :param lua-value field-value(s): values which must match the primary key.
-    :return: the new counter value
-    :rtype:  number
+        Complexity Factors: Index size, Index type, Number of tuples accessed.
 
-    Complexity Factors: Index size, Index type, WAL settings.
+        :return: nil
 
-    .. code-block:: lua
+        .. code-block:: lua
 
-        tarantool> s = box.schema.space.create('forty_second_space')
-        ---
-        ...
-        tarantool> s:create_index('primary', {unique = true, parts = {1, 'NUM', 2, 'STR'}})
-        ---
-        ...
-        tarantool> box.space.forty_second_space:inc{1,'a'}
-        ---
-        - 1
-        ...
-        tarantool> box.space.forty_second_space:inc{1,'a'}
-        ---
-        - 2
-        ...
+            tarantool> box.space.tester:truncate()
+            ---
+            ...
+            tarantool> box.space.tester:len()
+            ---
+            - 0
+            ...
 
-.. function:: box.space.space-name:dec{field-value [, field-value ...]}
+    .. function:: inc(key)
 
-    Decrements a counter in a tuple whose primary key matches the
-    ``field-value(s)``. The field following the primary-key fields
-    will be the counter. If there is no tuple matching the
-    ``field-value(s)``, a new one is not inserted. If the counter value drops
-    to zero, the tuple is deleted.
+        Increments a counter in a tuple whose primary key matches the
+        ``key``. The field following the primary-key fields
+        will be the counter. If there is no tuple matching the
+        ``field-value(s)``, a new one is inserted with initial counter
+        value set to 1.
 
-    :param userdata space-name:
-    :param lua-value field-value(s): values which must match the primary key.
-    :return: the new counter value
-    :rtype:  number
+        :param space_object space-object:
+        :param lua-table,scalar key: key to be matched against the index
+                                        key, which may be multi-part.
+        :return: the new counter value
+        :rtype:  number
 
-    Complexity Factors: Index size, Index type, WAL settings.
+        Complexity Factors: Index size, Index type, WAL settings.
 
-    .. code-block:: lua
+        .. code-block:: lua
 
-        tarantool> s = box.schema.space.create('space19')
-        ---
-        ...
-        tarantool> s:create_index('primary', {unique = true, parts = {1, 'NUM', 2, 'STR'}})
-        ---
-        ...
-        tarantool> box.space.space19:insert{1,'a',1000}
-        ---
-        - [1, 'a', 1000]
-        ...
-        tarantool> box.space.space19:dec{1,'a'}
-        ---
-        - 999
-        ...
-        tarantool> box.space.space19:dec{1,'a'}
-        ---
-        - 998
-        ...
-
-.. function:: box.space.space-name:auto_increment{field-value [, field-value ...]}
-
-    Insert a new tuple using an auto-increment primary key. The space specified
-    by space-name must have a NUM primary key index of type TREE. The
-    primary-key field will be incremented before the insert.
-
-    :param userdata space-name:
-    :param lua-value field-value(s): values for the tuple's fields,
-                                     other than the primary-key field.
-
-    :return: the inserted tuple.
-    :rtype:  tuple
-
-    Complexity Factors: Index size, Index type,
-    Number of indexes accessed, WAL settings.
-
-    :except: index has wrong type or primary-key indexed field is not a number.
-
-    .. code-block:: lua
-
-        tarantool> box.space.tester:auto_increment{'Fld#1', 'Fld#2'}
-        ---
-        - [1, 'Fld#1', 'Fld#2']
-        ...
-        tarantool> box.space.tester:auto_increment{'Fld#3'}
-        ---
-        - [2, 'Fld#3']
-        ...
-
-.. function:: box.space.space-name:pairs()
-
-    A helper function to prepare for iterating over all tuples in a space.
-
-    :return: function which can be used in a for/end loop. Within the loop, a value is returned for each iteration.
-    :rtype:  function, tuple
-
-    .. code-block:: lua
-
-        tarantool> s = box.schema.space.create('space33')
-        ---
-        ...
-        tarantool> -- index 'X' has default parts {1,'NUM'}
-        tarantool> s:create_index('X', {})
-        ---
-        ...
-        tarantool> s:insert{0,'Hello my '}; s:insert{1,'Lua world'}
-        ---
-        ...
-        tarantool> tmp = ''; for k, v in s:pairs() do tmp = tmp .. v[2] end
-        ---
-        ...
-        tarantool> tmp
-        ---
-        - Hello my Lua world
-        ...
+            tarantool> s = box.schema.space.create('forty_second_space')
+            ---
+            ...
+            tarantool> s:create_index('primary', {unique = true, parts = {1, 'NUM', 2, 'STR'}})
+            ---
+            ...
+            tarantool> box.space.forty_second_space:inc{1,'a'}
+            ---
+            - 1
+            ...
+            tarantool> box.space.forty_second_space:inc{1,'a'}
+            ---
+            - 2
+            ...
+
+    .. function:: dec(key)
+
+        Decrements a counter in a tuple whose primary key matches the
+        ``field-value(s)``. The field following the primary-key fields
+        will be the counter. If there is no tuple matching the
+        ``field-value(s)``, a new one is not inserted. If the counter value drops
+        to zero, the tuple is deleted.
+
+        :param space_object space-object:
+        :param lua-table,scalar key: key to be matched against the index
+                                        key, which may be multi-part.
+        :return: the new counter value
+        :rtype:  number
+
+        Complexity Factors: Index size, Index type, WAL settings.
+
+        .. code-block:: lua
+
+            tarantool> s = box.schema.space.create('space19')
+            ---
+            ...
+            tarantool> s:create_index('primary', {unique = true, parts = {1, 'NUM', 2, 'STR'}})
+            ---
+            ...
+            tarantool> box.space.space19:insert{1,'a',1000}
+            ---
+            - [1, 'a', 1000]
+            ...
+            tarantool> box.space.space19:dec{1,'a'}
+            ---
+            - 999
+            ...
+            tarantool> box.space.space19:dec{1,'a'}
+            ---
+            - 998
+            ...
+
+    .. function:: auto_increment(tuple)
+
+        Insert a new tuple using an auto-increment primary key. The space specified
+        by space-name must have a NUM primary key index of type TREE. The
+        primary-key field will be incremented before the insert.
+
+        :param space_object space-object:
+        :param lua-table,box.tuple tuple: tuple's fields, other than the primary-key field.
+
+        :return: the inserted tuple.
+        :rtype:  tuple
+
+        Complexity Factors: Index size, Index type,
+        Number of indexes accessed, WAL settings.
+
+        Possible errors: index has wrong type or primary-key indexed field is not a number.
+
+        .. code-block:: lua
+
+            tarantool> box.space.tester:auto_increment{'Fld#1', 'Fld#2'}
+            ---
+            - [1, 'Fld#1', 'Fld#2']
+            ...
+            tarantool> box.space.tester:auto_increment{'Fld#3'}
+            ---
+            - [2, 'Fld#3']
+            ...
+
+    .. function:: pairs()
+
+        A helper function to prepare for iterating over all tuples in a space.
+
+        :return: function which can be used in a for/end loop. Within the loop, a value is returned for each iteration.
+        :rtype:  function, tuple
+
+        .. code-block:: lua
+
+            tarantool> s = box.schema.space.create('space33')
+            ---
+            ...
+            tarantool> -- index 'X' has default parts {1,'NUM'}
+            tarantool> s:create_index('X', {})
+            ---
+            ...
+            tarantool> s:insert{0,'Hello my '}; s:insert{1,'Lua world'}
+            ---
+            ...
+            tarantool> tmp = ''; for k, v in s:pairs() do tmp = tmp .. v[2] end
+            ---
+            ...
+            tarantool> tmp
+            ---
+            - Hello my Lua world
+            ...
 
 .. data::     _schema
 
diff --git a/doc/sphinx/book/replication/index.rst b/doc/sphinx/book/replication/index.rst
index 05ed77f15668937d408dceea4cda7cf2b079c8bd..4d28892092bed7112c396cbbf7b483858f86d976 100644
--- a/doc/sphinx/book/replication/index.rst
+++ b/doc/sphinx/book/replication/index.rst
@@ -95,7 +95,7 @@ the old master went down, they would have to be re-applied manually.
 
 
 =====================================================================
-  Instructions for quick startup of a new two-server simple cluster
+        Quick startup of a new two-server simple cluster
 =====================================================================
 
 Step 1. Start the first server thus:
@@ -212,17 +212,68 @@ a cluster and adding a replica.
 
 Start two shells. Put them side by side on the screen.
 
-.. container:: table-wide
-
-    +----------------------+---------------------+
-    |      Terminal #1     |      Terminal #2    |
-    +======================+=====================+
-    |                      |                     |
-    | .. code-block:: lua  | .. code-block:: lua |
-    |                      |                     |
-    |     $                |     $               |
-    |                      |                     |
-    +----------------------+---------------------+
+.. container:: b-block-wrapper_doc
+
+    .. container:: b-doc_catalog
+        :name: catalog-1
+
+        .. raw:: html
+
+            <ul class="b-tab_switcher">
+                <li class="b-tab_switcher-item">
+                    <a href="#terminal-1-1" class="b-tab_switcher-item-url p-active">Terminal #1</a>
+                </li>
+                <li class="b-tab_switcher-item">
+                    <a href="#terminal-1-2" class="b-tab_switcher-item-url">Terminal #2</a>
+                </li>
+            </ul>
+
+    .. container:: b-documentation_tab_content
+        :name: catalog-1-content
+
+        .. container:: b-documentation_tab
+            :name: terminal-1-1
+
+            .. code-block:: lua
+
+                $ 
+
+        .. container:: b-documentation_tab
+            :name: terminal-1-2
+
+            .. code-block:: lua
+
+                $ 
+
+    .. raw:: html
+
+        <script>
+            (function(){
+                var dOn = $(document);
+                dOn.on({
+                    click: function(event) {
+                        event.preventDefault();
+                        link = $(this).children('a');
+                        target = link.attr('href');
+                        if (!(link.hasClass('p-active'))) {
+                            active = $('#catalog-1 .b-tab_switcher-item-url.p-active');
+                            $(active.attr('href')).hide();
+                            active.removeClass('p-active');
+                            link.addClass('p-active');
+                            $(link.attr('href')).show();
+                        }
+                    }
+                }, '#catalog-1 .b-tab_switcher-item');
+                dOn.ready(function(event) {
+                    maxHeight = Math.max($('#terminal-1-1').height(), $('#terminal-1-2').height());
+                    $('#catalog-1-content').height(maxHeight + 10);
+                    $('#terminal-1-1').height(maxHeight);
+                    $('#terminal-1-2').height(maxHeight);
+                    $('#terminal-1-1').show();
+                    $('#terminal-1-2').hide();
+                });
+            })();
+        </script>
 
 On the first shell, which we'll call Terminal #1, execute these commands:
 
@@ -241,16 +292,64 @@ On the first shell, which we'll call Terminal #1, execute these commands:
 The result is that a new cluster is set up, and the UUID is displayed.
 Now the screen looks like this: (except that UUID values are always different):
 
-
-.. container:: table-wide
-
-    +----------------------------------+----------------------------------+
-    |          Terminal #1             |          Terminal #2             |
-    +==================================+==================================+
-    |                                  |                                  |
-    | .. include:: 1-1.rst             | .. include:: 1-2.rst             |
-    |                                  |                                  |
-    +----------------------------------+----------------------------------+
+.. container:: b-block-wrapper_doc
+
+    .. container:: b-doc_catalog
+        :name: catalog-2
+
+        .. raw:: html
+
+            <ul class="b-tab_switcher">
+                <li class="b-tab_switcher-item">
+                    <a href="#terminal-2-1" class="b-tab_switcher-item-url p-active">Terminal #1</a>
+                </li>
+                <li class="b-tab_switcher-item">
+                    <a href="#terminal-2-2" class="b-tab_switcher-item-url">Terminal #2</a>
+                </li>
+            </ul>
+
+    .. container:: b-documentation_tab_content
+        :name: catalog-2-content
+
+        .. container:: b-documentation_tab
+            :name: terminal-2-1
+
+            .. include:: 1-1.rst
+
+        .. container:: b-documentation_tab
+            :name: terminal-2-2
+
+            .. include:: 1-2.rst
+
+    .. raw:: html
+
+        <script>
+            (function(){
+                var dOn = $(document);
+                dOn.on({
+                    click: function(event) {
+                        event.preventDefault();
+                        link = $(this).children('a');
+                        target = link.attr('href');
+                        if (!(link.hasClass('p-active'))) {
+                            active = $('#catalog-2 .b-tab_switcher-item-url.p-active');
+                            $(active.attr('href')).hide();
+                            active.removeClass('p-active');
+                            link.addClass('p-active');
+                            $(link.attr('href')).show();
+                        }
+                    }
+                }, '#catalog-2 .b-tab_switcher-item');
+                dOn.ready(function(event) {
+                    maxHeight = Math.max($('#terminal-2-1').height(), $('#terminal-2-2').height());
+                    $('#catalog-2-content').height(maxHeight + 10);
+                    $('#terminal-2-1').height(maxHeight);
+                    $('#terminal-2-2').height(maxHeight);
+                    $('#terminal-2-1').show();
+                    $('#terminal-2-2').hide();
+                });
+            })();
+        </script>
 
 On the second shell, which we'll call Terminal #2, execute these commands:
 
@@ -271,16 +370,64 @@ replication is starting. Also on Terminal#2 the _cluster UUID value is
 displayed, and it is the same as the _cluster UUID value that was displayed
 on Terminal #1, because both servers are in the same cluster.
 
-
-.. container:: table-wide
-
-    +----------------------------------+----------------------------------+
-    |          Terminal #1             |          Terminal #2             |
-    +==================================+==================================+
-    |                                  |                                  |
-    | .. include:: 2-1.rst             | .. include:: 2-2.rst             |
-    |                                  |                                  |
-    +----------------------------------+----------------------------------+
+.. container:: b-block-wrapper_doc
+
+    .. container:: b-doc_catalog
+        :name: catalog-3
+
+        .. raw:: html
+
+            <ul class="b-tab_switcher">
+                <li class="b-tab_switcher-item">
+                    <a href="#terminal-3-1" class="b-tab_switcher-item-url p-active">Terminal #1</a>
+                </li>
+                <li class="b-tab_switcher-item">
+                    <a href="#terminal-3-2" class="b-tab_switcher-item-url">Terminal #2</a>
+                </li>
+            </ul>
+
+    .. container:: b-documentation_tab_content
+        :name: catalog-3-content
+
+        .. container:: b-documentation_tab
+            :name: terminal-3-1
+
+            .. include:: 2-1.rst
+
+        .. container:: b-documentation_tab
+            :name: terminal-3-2
+
+            .. include:: 2-2.rst
+
+    .. raw:: html
+
+        <script>
+            (function(){
+                var dOn = $(document);
+                dOn.on({
+                    click: function(event) {
+                        event.preventDefault();
+                        link = $(this).children('a');
+                        target = link.attr('href');
+                        if (!(link.hasClass('p-active'))) {
+                            active = $('#catalog-3 .b-tab_switcher-item-url.p-active');
+                            $(active.attr('href')).hide();
+                            active.removeClass('p-active');
+                            link.addClass('p-active');
+                            $(link.attr('href')).show();
+                        }
+                    }
+                }, '#catalog-3 .b-tab_switcher-item');
+                dOn.ready(function(event) {
+                    maxHeight = Math.max($('#terminal-3-1').height(), $('#terminal-3-2').height());
+                    $('#catalog-3-content').height(maxHeight + 10);
+                    $('#terminal-3-1').height(maxHeight);
+                    $('#terminal-3-2').height(maxHeight);
+                    $('#terminal-3-1').show();
+                    $('#terminal-3-2').hide();
+                });
+            })();
+        </script>
 
 On Terminal #1, execute these requests:
 
@@ -292,15 +439,64 @@ On Terminal #1, execute these requests:
 
 Now the screen looks like this:
 
-.. container:: table-wide
-
-    +----------------------------------+----------------------------------+
-    |          Terminal #1             |          Terminal #2             |
-    +==================================+==================================+
-    |                                  |                                  |
-    | .. include:: 3-1.rst             | .. include:: 3-2.rst             |
-    |                                  |                                  |
-    +----------------------------------+----------------------------------+
+.. container:: b-block-wrapper_doc
+
+    .. container:: b-doc_catalog
+        :name: catalog-4
+
+        .. raw:: html
+
+            <ul class="b-tab_switcher">
+                <li class="b-tab_switcher-item">
+                    <a href="#terminal-4-1" class="b-tab_switcher-item-url p-active">Terminal #1</a>
+                </li>
+                <li class="b-tab_switcher-item">
+                    <a href="#terminal-4-2" class="b-tab_switcher-item-url">Terminal #2</a>
+                </li>
+            </ul>
+
+    .. container:: b-documentation_tab_content
+        :name: catalog-4-content
+
+        .. container:: b-documentation_tab
+            :name: terminal-4-1
+
+            .. include:: 3-1.rst
+
+        .. container:: b-documentation_tab
+            :name: terminal-4-2
+
+            .. include:: 3-2.rst
+
+    .. raw:: html
+
+        <script>
+            (function(){
+                var dOn = $(document);
+                dOn.on({
+                    click: function(event) {
+                        event.preventDefault();
+                        link = $(this).children('a');
+                        target = link.attr('href');
+                        if (!(link.hasClass('p-active'))) {
+                            active = $('#catalog-4 .b-tab_switcher-item-url.p-active');
+                            $(active.attr('href')).hide();
+                            active.removeClass('p-active');
+                            link.addClass('p-active');
+                            $(link.attr('href')).show();
+                        }
+                    }
+                }, '#catalog-4 .b-tab_switcher-item');
+                dOn.ready(function(event) {
+                    maxHeight = Math.max($('#terminal-4-1').height(), $('#terminal-4-2').height());
+                    $('#catalog-4-content').height(maxHeight + 10);
+                    $('#terminal-4-1').height(maxHeight);
+                    $('#terminal-4-2').height(maxHeight);
+                    $('#terminal-4-1').show();
+                    $('#terminal-4-2').hide();
+                });
+            })();
+        </script>
 
 The creation and insertion were successful on Terminal #1.
 Nothing has happened on Terminal #2.
@@ -315,15 +511,64 @@ On Terminal #2, execute these requests:
 
 Now the screen looks like this:
 
-.. container:: table-wide
-
-    +----------------------------------+----------------------------------+
-    |          Terminal #1             |          Terminal #2             |
-    +==================================+==================================+
-    |                                  |                                  |
-    | .. include:: 4-1.rst             | .. include:: 4-2.rst             |
-    |                                  |                                  |
-    +----------------------------------+----------------------------------+
+.. container:: b-block-wrapper_doc
+
+    .. container:: b-doc_catalog
+        :name: catalog-5
+
+        .. raw:: html
+
+            <ul class="b-tab_switcher">
+                <li class="b-tab_switcher-item">
+                    <a href="#terminal-5-1" class="b-tab_switcher-item-url p-active">Terminal #1</a>
+                </li>
+                <li class="b-tab_switcher-item">
+                    <a href="#terminal-5-2" class="b-tab_switcher-item-url">Terminal #2</a>
+                </li>
+            </ul>
+
+    .. container:: b-documentation_tab_content
+        :name: catalog-5-content
+
+        .. container:: b-documentation_tab
+            :name: terminal-5-1
+
+            .. include:: 4-1.rst
+
+        .. container:: b-documentation_tab
+            :name: terminal-5-2
+
+            .. include:: 4-2.rst
+
+    .. raw:: html
+
+        <script>
+            (function(){
+                var dOn = $(document);
+                dOn.on({
+                    click: function(event) {
+                        event.preventDefault();
+                        link = $(this).children('a');
+                        target = link.attr('href');
+                        if (!(link.hasClass('p-active'))) {
+                            active = $('#catalog-5 .b-tab_switcher-item-url.p-active');
+                            $(active.attr('href')).hide();
+                            active.removeClass('p-active');
+                            link.addClass('p-active');
+                            $(link.attr('href')).show();
+                        }
+                    }
+                }, '#catalog-5 .b-tab_switcher-item');
+                dOn.ready(function(event) {
+                    maxHeight = Math.max($('#terminal-5-1').height(), $('#terminal-5-2').height());
+                    $('#catalog-5-content').height(maxHeight + 10);
+                    $('#terminal-5-1').height(maxHeight);
+                    $('#terminal-5-2').height(maxHeight);
+                    $('#terminal-5-1').show();
+                    $('#terminal-5-2').hide();
+                });
+            })();
+        </script>
 
 The selection and insertion were successful on Terminal #2. Nothing has
 happened on Terminal #1.
@@ -340,15 +585,64 @@ Now Tarantool #1 is stopped. Messages appear on Terminal #2 announcing that fact
 The "ls -l" commands show that both servers have made snapshots, which have the
 same size because they both contain the same tuples.
 
-.. container:: table-wide
-
-    +----------------------------------+----------------------------------+
-    |          Terminal #1             |          Terminal #2             |
-    +==================================+==================================+
-    |                                  |                                  |
-    | .. include:: 5-1.rst             | .. include:: 5-2.rst             |
-    |                                  |                                  |
-    +----------------------------------+----------------------------------+
+.. container:: b-block-wrapper_doc
+
+    .. container:: b-doc_catalog
+        :name: catalog-6
+
+        .. raw:: html
+
+            <ul class="b-tab_switcher">
+                <li class="b-tab_switcher-item">
+                    <a href="#terminal-6-1" class="b-tab_switcher-item-url p-active">Terminal #1</a>
+                </li>
+                <li class="b-tab_switcher-item">
+                    <a href="#terminal-6-2" class="b-tab_switcher-item-url">Terminal #2</a>
+                </li>
+            </ul>
+
+    .. container:: b-documentation_tab_content
+        :name: catalog-6-content
+
+        .. container:: b-documentation_tab
+            :name: terminal-6-1
+
+            .. include:: 5-1.rst
+
+        .. container:: b-documentation_tab
+            :name: terminal-6-2
+
+            .. include:: 5-2.rst
+
+    .. raw:: html
+
+        <script>
+            (function(){
+                var dOn = $(document);
+                dOn.on({
+                    click: function(event) {
+                        event.preventDefault();
+                        link = $(this).children('a');
+                        target = link.attr('href');
+                        if (!(link.hasClass('p-active'))) {
+                            active = $('#catalog-6 .b-tab_switcher-item-url.p-active');
+                            $(active.attr('href')).hide();
+                            active.removeClass('p-active');
+                            link.addClass('p-active');
+                            $(link.attr('href')).show();
+                        }
+                    }
+                }, '#catalog-6 .b-tab_switcher-item');
+                dOn.ready(function(event) {
+                    maxHeight = Math.max($('#terminal-6-1').height(), $('#terminal-6-2').height());
+                    $('#catalog-6-content').height(maxHeight + 10);
+                    $('#terminal-6-1').height(maxHeight);
+                    $('#terminal-6-2').height(maxHeight);
+                    $('#terminal-6-1').show();
+                    $('#terminal-6-2').hide();
+                });
+            })();
+        </script>
 
 On Terminal #2, ignore the repeated messages saying "failed to connect",
 and execute these requests:
@@ -361,15 +655,64 @@ and execute these requests:
 Now the screen looks like this (ignoring the repeated messages saying
 "failed to connect"):
 
-.. container:: table-wide
-
-    +----------------------------------+----------------------------------+
-    |          Terminal #1             |          Terminal #2             |
-    +==================================+==================================+
-    |                                  |                                  |
-    | .. include:: 6-1.rst             | .. include:: 6-2.rst             |
-    |                                  |                                  |
-    +----------------------------------+----------------------------------+
+.. container:: b-block-wrapper_doc
+
+    .. container:: b-doc_catalog
+        :name: catalog-7
+
+        .. raw:: html
+
+            <ul class="b-tab_switcher">
+                <li class="b-tab_switcher-item">
+                    <a href="#terminal-7-1" class="b-tab_switcher-item-url p-active">Terminal #1</a>
+                </li>
+                <li class="b-tab_switcher-item">
+                    <a href="#terminal-7-2" class="b-tab_switcher-item-url">Terminal #2</a>
+                </li>
+            </ul>
+
+    .. container:: b-documentation_tab_content
+        :name: catalog-7-content
+
+        .. container:: b-documentation_tab
+            :name: terminal-7-1
+
+            .. include:: 6-1.rst
+
+        .. container:: b-documentation_tab
+            :name: terminal-7-2
+
+            .. include:: 6-2.rst
+
+    .. raw:: html
+
+        <script>
+            (function(){
+                var dOn = $(document);
+                dOn.on({
+                    click: function(event) {
+                        event.preventDefault();
+                        link = $(this).children('a');
+                        target = link.attr('href');
+                        if (!(link.hasClass('p-active'))) {
+                            active = $('#catalog-7 .b-tab_switcher-item-url.p-active');
+                            $(active.attr('href')).hide();
+                            active.removeClass('p-active');
+                            link.addClass('p-active');
+                            $(link.attr('href')).show();
+                        }
+                    }
+                }, '#catalog-7 .b-tab_switcher-item');
+                dOn.ready(function(event) {
+                    maxHeight = Math.max($('#terminal-7-1').height(), $('#terminal-7-2').height());
+                    $('#catalog-7-content').height(maxHeight + 10);
+                    $('#terminal-7-1').height(maxHeight);
+                    $('#terminal-7-2').height(maxHeight);
+                    $('#terminal-7-1').show();
+                    $('#terminal-7-2').hide();
+                });
+            })();
+        </script>
 
 Terminal #2 has done a select and an insert, even though Terminal #1 is down.
 
@@ -384,15 +727,64 @@ On Terminal #1 execute these commands:
 Now the screen looks like this (ignoring the repeated messages on terminal
 #2 saying "failed to connect"):
 
-.. container:: table-wide
-
-    +----------------------------------+----------------------------------+
-    |          Terminal #1             |          Terminal #2             |
-    +==================================+==================================+
-    |                                  |                                  |
-    | .. include:: 7-1.rst             | .. include:: 7-2.rst             |
-    |                                  |                                  |
-    +----------------------------------+----------------------------------+
+.. container:: b-block-wrapper_doc
+
+    .. container:: b-doc_catalog
+        :name: catalog-8
+
+        .. raw:: html
+
+            <ul class="b-tab_switcher">
+                <li class="b-tab_switcher-item">
+                    <a href="#terminal-8-1" class="b-tab_switcher-item-url p-active">Terminal #1</a>
+                </li>
+                <li class="b-tab_switcher-item">
+                    <a href="#terminal-8-2" class="b-tab_switcher-item-url">Terminal #2</a>
+                </li>
+            </ul>
+
+    .. container:: b-documentation_tab_content
+        :name: catalog-8-content
+
+        .. container:: b-documentation_tab
+            :name: terminal-8-1
+
+            .. include:: 7-1.rst
+
+        .. container:: b-documentation_tab
+            :name: terminal-8-2
+
+            .. include:: 7-2.rst
+
+    .. raw:: html
+
+        <script>
+            (function(){
+                var dOn = $(document);
+                dOn.on({
+                    click: function(event) {
+                        event.preventDefault();
+                        link = $(this).children('a');
+                        target = link.attr('href');
+                        if (!(link.hasClass('p-active'))) {
+                            active = $('#catalog-8 .b-tab_switcher-item-url.p-active');
+                            $(active.attr('href')).hide();
+                            active.removeClass('p-active');
+                            link.addClass('p-active');
+                            $(link.attr('href')).show();
+                        }
+                    }
+                }, '#catalog-8 .b-tab_switcher-item');
+                dOn.ready(function(event) {
+                    maxHeight = Math.max($('#terminal-8-1').height(), $('#terminal-8-2').height());
+                    $('#catalog-8-content').height(maxHeight + 10);
+                    $('#terminal-8-1').height(maxHeight);
+                    $('#terminal-8-2').height(maxHeight);
+                    $('#terminal-8-1').show();
+                    $('#terminal-8-2').hide();
+                });
+            })();
+        </script>
 
 The master has reconnected to the cluster, and has NOT found what the replica
 wrote while the master was away. That is not a surprise -- the replica has not
@@ -407,15 +799,64 @@ On Terminal #1, say:
 
 The screen now looks like this:
 
-.. container:: table-wide
-
-    +----------------------------------+----------------------------------+
-    |          Terminal #1             |          Terminal #2             |
-    +==================================+==================================+
-    |                                  |                                  |
-    | .. include:: 8-1.rst             | .. include:: 8-2.rst             |
-    |                                  |                                  |
-    +----------------------------------+----------------------------------+
+.. container:: b-block-wrapper_doc
+
+    .. container:: b-doc_catalog
+        :name: catalog-9
+
+        .. raw:: html
+
+            <ul class="b-tab_switcher">
+                <li class="b-tab_switcher-item">
+                    <a href="#terminal-9-1" class="b-tab_switcher-item-url p-active">Terminal #1</a>
+                </li>
+                <li class="b-tab_switcher-item">
+                    <a href="#terminal-9-2" class="b-tab_switcher-item-url">Terminal #2</a>
+                </li>
+            </ul>
+
+    .. container:: b-documentation_tab_content
+        :name: catalog-9-content
+
+        .. container:: b-documentation_tab
+            :name: terminal-9-1
+
+            .. include:: 8-1.rst
+
+        .. container:: b-documentation_tab
+            :name: terminal-9-2
+
+            .. include:: 8-2.rst
+
+    .. raw:: html
+
+        <script>
+            (function(){
+                var dOn = $(document);
+                dOn.on({
+                    click: function(event) {
+                        event.preventDefault();
+                        link = $(this).children('a');
+                        target = link.attr('href');
+                        if (!(link.hasClass('p-active'))) {
+                            active = $('#catalog-9 .b-tab_switcher-item-url.p-active');
+                            $(active.attr('href')).hide();
+                            active.removeClass('p-active');
+                            link.addClass('p-active');
+                            $(link.attr('href')).show();
+                        }
+                    }
+                }, '#catalog-9 .b-tab_switcher-item');
+                dOn.ready(function(event) {
+                    maxHeight = Math.max($('#terminal-9-1').height(), $('#terminal-9-2').height());
+                    $('#catalog-9-content').height(maxHeight + 10);
+                    $('#terminal-9-1').height(maxHeight);
+                    $('#terminal-9-2').height(maxHeight);
+                    $('#terminal-9-1').show();
+                    $('#terminal-9-2').hide();
+                });
+            })();
+        </script>
 
 This shows that the two servers are once again in synch, and that each server
 sees what the other server wrote.
diff --git a/doc/user/configuration-reference.xml b/doc/user/configuration-reference.xml
deleted file mode 100644
index 11ae16e312d78a994cfd9252cb02c8c0318df15c..0000000000000000000000000000000000000000
--- a/doc/user/configuration-reference.xml
+++ /dev/null
@@ -1,766 +0,0 @@
-<!DOCTYPE book [
-<!ENTITY % tnt SYSTEM "../tnt.ent">
-%tnt;
-]>
-<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
-         xmlns:xi="http://www.w3.org/2001/XInclude"
-         xmlns:xlink="http://www.w3.org/1999/xlink"
-         xml:id="configuration-reference">
-
-<title>Configuration reference</title>
-<blockquote><para>
-  This chapter provides a reference of options which
-  can be set on the command line or in an initialization file.
-</para></blockquote>
-
-<para>
-Tarantool is started by entering the command:
-
-<programlisting><prompt>$ </prompt><userinput>tarantool</userinput></programlisting>
-or
-<programlisting><prompt>$ </prompt><userinput>tarantool <replaceable>options</replaceable></userinput></programlisting>
-or
-<programlisting><prompt>$ </prompt><userinput>tarantool <replaceable>Lua-initialization-file</replaceable> [<replaceable>arguments</replaceable>]</userinput></programlisting>
-
-</para>
-
-<section xml:id="command-line-options">
-<title>Command options</title>
-  <para>
-
-  </para>
-  <itemizedlist>
-    <listitem xml:id="help-option">
-      <para><option>--help</option>, <option>-h</option></para>
-      <para>Print an annotated list of all available options and exit.</para>
-    </listitem>
-
-    <listitem xml:id="version-option">
-      <para><option>--version</option>, <option>-V</option></para>
-      <para>Print product name and version, for example:
-       <programlisting><prompt>$ </prompt> <userinput>./tarantool --version</userinput>
-Tarantool 1.6.3-439-g7e1011b
-Target: Linux-x86_64-Debug
-...
-        </programlisting>
-        In this example:
-        <simplelist>
-          <member>
-            <quote>Tarantool</quote> is the name
-            of the reusable asynchronous networking programming framework.
-          </member>
-          <member>
-            The 3-number version follows the standard
-            <literal>&lt;major&gt;-&lt;minor&gt;-&lt;patch&gt;</literal>
-            scheme, in which <literal>&lt;major&gt;</literal> number
-            is changed only rarely, <literal>&lt;minor&gt;</literal>
-            is incremented for each new milestone and
-            indicates possible incompatible changes,
-            and <literal>&lt;patch&gt;</literal> stands for the number of
-            bug fix releases made after the start of the
-            milestone. For non-released versions only, there may be a
-            commit number and commit SHA1
-            to indicate how much this particular build has diverged
-            from the last release.
-         </member>
-          <member>
-            <quote>Target</quote> is the platform tarantool was built on.
-            Some platform-specific details may follow this line.
-         </member>
-        </simplelist>
-      </para>
-      <note><para>
-        Tarantool uses <link
-        xlink:href="http://www.kernel.org/pub/software/scm/git/docs/git-describe.html">git describe</link> to produce its version id, and
-        this id can be used at any time to check out the
-        corresponding source from our <link
-        xlink:href="http://github.com/tarantool/tarantool.git">git repository</link>.
-      </para></note>
-    </listitem>
-
-  </itemizedlist>
-
-</section>
-
-
-<section xml:id="URI" xreflabel="URI">
- <title>URI</title>
- <para>
-Some configuration parameters and some functions
-depend on a URI, or "Universal Resource Identifier".
-The URI string format is similar to the
-<link
-xlink:href="http://en.wikipedia.org/wiki/URI_scheme#Generic_syntax">generic syntax for a URI schema</link>.
-So it may contain (in order) a user name for login, a password,
-a host name or host IP address, and a port number.
-Only the port number is always mandatory. The password
-is mandatory if the user name is specified,
-unless the user name is 'guest'.
-So, formally, the URI syntax is
-<code>[host:]port</code>
-or <code>[username:password@]host:port</code>.
-If host is omitted, then 'localhost' is assumed.
-If username:password is omitted, then 'guest' is assumed.
-Some examples:
-    <informaltable>
-    <tgroup cols="2" align="left" colsep="1" rowsep="0">
-     <thead>
-      <row><entry>URI fragment</entry><entry>Example</entry></row>
-     </thead>
-    <tbody>
-    <row><entry>port</entry><entry>                  3301</entry></row>
-    <row><entry>host:port</entry><entry>             127.0.0.1:3301</entry></row>
-    <row><entry>username:password@host:port</entry><entry>                  guest:sesame@mail.ru:3301</entry></row>
-    </tbody>
-    </tgroup>                                   
-    </informaltable>
-In certain circumstances a Unix socket may be used where a URI is required.
-</para>
-</section>
-
-
-<section xml:id="initialization-file" xreflabel="initialization file">
-<title>Initialization file</title>
-<para>
-If the command to start Tarantool includes <option><replaceable>lua-initialization-file</replaceable></option>,
-then Tarantool begins by invoking the Lua program in the file,
-which by convention may have the name <filename>"script.lua"</filename>.
-
-The Lua program may get further arguments from the command line
-or may use operating-system functions, such as getenv().
-The Lua program almost always begins by invoking <code>box.cfg()</code>,
-if the database server will be used or if ports need to be opened.
-For example, suppose <filename>script.lua</filename> contains the lines<programlisting>#!/usr/bin/env tarantool
-box.cfg{
-    listen              = os.getenv("LISTEN_URI"),
-    slab_alloc_arena    = 0.1,
-    pid_file            = "tarantool.pid",
-    rows_per_wal        = 50
-}
-print('Starting ',arg[1])</programlisting>
-and suppose the environment variable LISTEN_URI contains 3301,
-and suppose the command line is <code>~/tarantool/src/tarantool script.lua ARG</code>.
-Then the screen might look like this:<programlisting>
-<prompt>$</prompt> <userinput>export LISTEN_URI=3301</userinput>
-<prompt>$</prompt> <userinput>~/tarantool/src/tarantool script.lua ARG</userinput>
-... main/101/script.lua C> version 1.6.3-439-g7e1011b
-... main/101/script.lua C> log level 5
-... main/101/script.lua I> mapping 107374184 bytes for a shared arena...
-... main/101/script.lua I> recovery start
-... main/101/script.lua I> recovering from `./00000000000000000000.snap'
-... main/101/script.lua I> primary: bound to 0.0.0.0:3301
-... main/102/leave_local_hot_standby I> ready to accept requests
-Starting  ARG
-... main C> entering the event loop</programlisting>
-</para>
-</section>
-
-<section xml:id="configuration-parameters" xreflabel="configuration parameters">
-<title>Configuration parameters</title>
-<para>
-    Configuration parameters have the form
-     <code>box.cfg{<replaceable> key = value [, key = value ...]</replaceable>}</code>.
-    Since box.cfg may contain many configuration parameters
-    and since some of the parameters (such as directory addresses)
-    are semi-permanent, it's best to keep box.cfg in a Lua file.
-    Typically this Lua file is the initialization file
-    which is specified on the tarantool command line.
-  </para>
-  <para>
-    Most configuration parameters are for allocating resources,
-    opening ports, and specifying database behavior.
-    All parameters are optional.
-    A few parameters are dynamic, that is, they can be changed
-    at runtime by calling box.cfg{} a second time.
-  </para>
-  <para>
-    To see all the non-null parameters, say <code>box.cfg</code> (no parentheses).
-    To see a particular parameter, for example the listen address, say <code>box.cfg.listen</code>.
-  </para>
-  <para>
-    The following tables describe all parameters for basic operation,
-    for storage, for binary logging and snapshots, for replication,
-    for networking, and for logging.
-  </para>
-
-  <table frame='all' pgwide='1'>
-    <title>Basic parameters</title>
-    <tgroup cols='5' colsep='1' rowsep='1'>
-      <colspec colnum="1" colname="col1" colwidth="2*"/>
-      <colspec colnum="5" colname="col4" colwidth="6*"/>
-
-      <thead>
-        <row>
-          <entry>Name</entry>
-          <entry>Type</entry>
-          <entry>Default</entry>
-          <entry>Dynamic?</entry>
-          <entry>Description</entry>
-        </row>
-      </thead>
-
-      <tbody>
-
-        <row>
-          <entry>username</entry>
-          <entry>string</entry>
-          <entry>null</entry>
-          <entry>no</entry>
-          <entry>UNIX user name to switch to after start.</entry>
-        </row>
-
-        <row>
-          <entry xml:id="work_dir" xreflabel="work_dir">work_dir</entry>
-          <entry>string</entry>
-          <entry>null</entry>
-          <entry>no</entry>
-          <entry>A directory where database working files will be stored.
-          The server switches to work_dir with chdir(2) after
-          start. Can be relative to the current directory.
-          If not specified, defaults to the current directory.</entry>
-        </row>
-
-        <row>
-          <entry xml:id="wal_dir" xreflabel="wal_dir">wal_dir</entry>
-          <entry>string</entry>
-          <entry>"."</entry>
-          <entry>no</entry>
-          <entry>A directory where write-ahead log (.xlog) files are stored.
-          Can be relative to work_dir. Most commonly used so
-          that snapshot files and write-ahead log files
-          can be stored on separate disks.
-          If not specified, defaults to work_dir.</entry>
-        </row>
-
-        <row>
-          <entry xml:id="snap_dir" xreflabel="snap_dir">snap_dir</entry>
-          <entry>string</entry>
-          <entry>"."</entry>
-          <entry>no</entry>
-          <entry>A directory where snapshot (.snap) files will be stored. Can be
-          relative to work_dir. If not specified, defaults to
-          work_dir. See also <olink targetptr="wal_dir"/>.</entry>
-        </row>
-        
-        <row>
-          <entry xml:id="sophia_dir" xreflabel="sophia_dir">sophia_dir</entry>
-          <entry>string</entry>
-          <entry>"sophia"</entry>
-          <entry>no</entry>
-          <entry>A directory where sophia files will be stored. Can be
-          relative to work_dir. If not specified, defaults to
-          work_dir/sophia.</entry>
-        </row>
-
-        <row>
-          <entry xml:id="core-dump" xreflabel="core-dump">coredump</entry>
-          <entry>boolean</entry>
-          <entry>false</entry>
-          <entry>no</entry>          
-          <entry>Deprecated. Do not use.</entry>
-        </row>
-        <row>
-          <entry xml:id="primary_port" xreflabel="primary_port">listen</entry>
-          <entry>integer or string</entry>
-          <entry>null</entry>
-          <entry>yes</entry>
-          <entry>The read/write data port number or <link linkend="URI">URI</link> (Universal Resource Identifier) string.
-          Has no default value, so <emphasis
-          role="strong">must be specified</emphasis>
-          if connections will occur from remote clients
-          that do not use "admin address" (the administrative host and port).
-          Note: a replica also binds to this port, and accepts
-          connections, but these connections can only serve
-          reads until the replica becomes a master.
-          A typical value is 3301.
-          The listen parameter may also be set for <olink targetptr="local_hot_standby">local hot standby</olink>.</entry>
-        </row>
-
-        <row>
-          <entry>pid_file</entry>
-          <entry>string</entry>
-          <entry>null</entry>
-          <entry>no</entry>
-          <entry>Store the process id in this file. Can be
-          relative to work_dir. A typical value is "tarantool.pid".</entry>
-        </row>
-
-        <row>
-          <entry xml:id="custom_proc_title"
-                 xreflabel="custom_proc_title">
-            custom_proc_title
-          </entry>
-          <entry>string</entry>
-          <entry>null</entry>
-          <entry>no</entry>
-          <entry>
-            <para>Inject the given string into <olink
-            targetptr="proctitle">server process title</olink>
-            (what's shown in the COMMAND column for <command>ps</command>
-            and <command>top</command> commands). For example,
-             ordinarily <command>ps</command> shows the Tarantool server process thus:
-            </para><programlisting><prompt>$</prompt> <userinput>ps -ef | grep tarantool</userinput>
-1000     22364  2778  0 09:14 pts/0    00:00:00 tarantool: running                  
-1000     22394 22364  0 09:14 pts/0    00:00:00 tarantool: spawner
-tarantool: primary pri: 3301 adm: 3313</programlisting>
-          <para>But if the configuration parameters include custom_proc_title='sessions' then
-          the output looks like:</para>
-<programlisting><prompt>$</prompt> <userinput>ps -ef | grep tarantool</userinput>
-1000     22364  2778  0 09:14 pts/0    00:00:00 tarantool: running@sessions          
-1000     22394 22364  0 09:14 pts/0    00:00:00 tarantool: spawner@sessions
-tarantool: primary pri: 3301 adm: 3313</programlisting>
-          </entry>
-        </row>
-
-        <row>
-          <entry>background</entry>
-          <entry>boolean</entry>
-          <entry>false</entry>
-          <entry>no</entry>
-          <entry>Run the server as a background task.
-          The logger and pid_file parameters must be non-null for this to work.</entry>
-        </row>
-
-      </tbody>
-    </tgroup>
-  </table>
-
-  <table frame='all' pgwide='1'>
-    <title>Configuring the storage</title>
-    <tgroup cols='5' colsep='1' rowsep='1'>
-      <colspec colnum="1" colname="col1" colwidth="2*"/>
-      <colspec colnum="5" colname="col4" colwidth="6*"/>
-
-      <thead>
-        <row>
-          <entry>Name</entry>
-          <entry>Type</entry>
-          <entry>Default</entry>
-          <entry>Dynamic?</entry>
-          <entry>Description</entry>
-        </row>
-      </thead>
-
-      <tbody>
-
-        <row>
-          <entry>slab_alloc_arena</entry>
-          <entry>float</entry>
-          <entry>1.0</entry>
-          <entry>no</entry>
-          <entry>
-            <anchor xml:id="slab_alloc_arena" xreflabel="slab_alloc_arena"/>
-            How much memory Tarantool
-          allocates to actually
-          store tuples, <emphasis role="strong">in
-          gigabytes</emphasis>. When the limit is reached, INSERT
-          or UPDATE requests begin failing with error
-          <olink targetptr="ER_MEMORY_ISSUE"/>.
-          While the server does not go
-          beyond the defined limit to allocate tuples, there is
-          additional memory used to store indexes and connection
-          information.  Depending on actual configuration and
-          workload, Tarantool can consume up to 20% more than the
-          limit set here.</entry>
-        </row>
-
-        <row>
-          <entry>slab_alloc_minimal</entry>
-          <entry>integer</entry>
-          <entry>64</entry>
-          <entry>no</entry>
-          <entry>Size of the smallest allocation unit. It can be
-          tuned down if most of the tuples are very small.</entry>
-        </row>
-
-        <row>
-          <entry>slab_alloc_factor</entry>
-          <entry>float</entry>
-          <entry>2.0</entry>
-          <entry>no</entry>
-          <entry>Use slab_alloc_factor as the multiplier for
-          computing the sizes of memory chunks that tuples are
-          stored in. A lower value  may result in less wasted
-          memory depending on the total amount of memory available
-          and the distribution of item sizes.</entry>
-        </row>
-        
-        <row>
-          <entry>sophia</entry>
-          <entry>table</entry>
-          <entry>(see the note)</entry>
-          <entry>no</entry>
-          <entry>The default sophia configuration can be changed with
-           sophia={page_size=<replaceable>number</replaceable>, threads=<replaceable>number</replaceable>,
-           node_size=<replaceable>number</replaceable>, memory_limit=<replaceable>number</replaceable> }.
-           This method may change in the future.</entry>
-        </row>
-
-      </tbody>
-    </tgroup>
-  </table>
-  
-  
-  <table xml:id="snapshot-daemon" frame='all' pgwide='1'>
-    <title>Snapshot daemon</title>
-    <tgroup cols='5' colsep='1' rowsep='1'>
-      <colspec colnum="1" colname="col1" colwidth="2*"/>
-      <colspec colnum="5" colname="col4" colwidth="6*"/>
-
-      <thead>
-        <row>
-          <entry>Name</entry>
-          <entry>Type</entry>
-          <entry>Default</entry>
-          <entry>Dynamic?</entry>
-          <entry>Description</entry>
-        </row>
-      </thead>
-
-      <tbody>
-
-        <row>
-          <entry>snapshot_period</entry>
-          <entry>float</entry>
-          <entry>0</entry>
-          <entry>yes</entry>
-          <entry>
-          The interval between actions by the snapshot daemon, in seconds.
-          The snapshot daemon is a fiber which is constantly running.
-          If snapshot_period is set to a value greater than zero,
-          then the snapshot daemon
-          will call <olink targetptr="box.snapshot"/> every snapshot_period seconds, creating
-          a new snapshot file each time.
-          For example, <code>box.cfg{snapshot_period=3600}</code>
-          will cause the snapshot daemon to create a new database
-          snapshot once per hour.
-          </entry>
-        </row>
-
-        <row>
-          <entry>snapshot_count</entry>
-          <entry>integer</entry>
-          <entry>6</entry>
-          <entry>yes</entry>
-          <entry>
-          	<para>
-          The maximum number of snapshots that the snapshot daemon maintains.
-          For example, <code>box.cfg{snapshot_period=3600, snapshot_count=10}</code>
-          will cause the snapshot daemon
-          to create a new snapshot each hour until it has created
-          ten snapshots. After that, it will remove the oldest
-          snapshot (and any associated write-ahead-log files) after creating
-          a new one. If snapshot_count equals zero, then the snapshot
-          daemon does not remove old snapshots.
-          	</para>
-          </entry>
-        </row>
-      </tbody>
-    </tgroup>
-  </table>
-
-  <table frame='all' pgwide='1'>
-    <title>Binary logging and snapshots</title>
-    <tgroup cols='5' colsep='1' rowsep='1'>
-      <colspec colnum="1" colname="col1" colwidth="2*"/>
-      <colspec colnum="5" colname="col4" colwidth="6*"/>
-
-      <thead>
-        <row>
-          <entry>Name</entry>
-          <entry>Type</entry>
-          <entry>Default</entry>
-          <entry>Dynamic?</entry>
-          <entry>Description</entry>
-        </row>
-      </thead>
-
-      <tbody>
-
-        <row>
-          <entry>panic_on_snap_error</entry>
-          <entry>boolean</entry>
-          <entry>true</entry>
-          <entry>no</entry>
-          <entry>If there is an error while reading the snapshot file (at
-            server start), abort.</entry>
-        </row>
-
-        <row>
-          <entry>panic_on_wal_error</entry>
-          <entry>boolean</entry>
-          <entry>false</entry>
-          <entry>no</entry>
-          <entry>If there is an error while reading a write-ahead
-          log file (at server start), abort.</entry>
-        </row>
-
-        <row>
-          <entry xml:id="rows_per_wal" xreflabel="rows_per_wal">rows_per_wal</entry>
-          <entry>integer</entry>
-          <entry>500000</entry>
-          <entry>no</entry>
-          <entry>How many log records to store in a single
-          write-ahead log file. When this limit is reached, Tarantool
-          creates another WAL file named
-          <filename>&lt;first-lsn-in-wal&gt;.xlog</filename>
-          This can be useful for simple rsync-based backups.
-          </entry>
-        </row>
-
-        <row>
-          <entry>snap_io_rate_limit</entry>
-          <entry>float</entry>
-          <entry>null</entry>
-          <entry><emphasis role="strong">yes</emphasis></entry>
-          <entry>Reduce the throttling effect of <olink
-          targetptr="box.snapshot"/> on INSERT/UPDATE/DELETE
-          performance by setting a limit on
-          how many megabytes per second it can write to disk.
-          The same can be achieved by splitting <olink
-          targetptr="wal_dir"/> and <olink targetptr="snap_dir"/>
-          locations and moving snapshots to a separate disk.</entry>
-        </row>
-
-        <row>
-          <entry xml:id="wal_mode" xreflabel="wal_mode">wal_mode</entry>
-          <entry>string</entry>
-          <entry>"write"</entry>
-          <entry><emphasis role="strong">yes</emphasis></entry>
-          <entry>Specify fiber-WAL-disk synchronization mode as:
-              <emphasis>none:</emphasis> write-ahead log is not maintained; <emphasis>write:</emphasis> fibers wait for their data to
-              be written to the write-ahead log (no fsync(2)); <emphasis>fsync</emphasis>:
-              fibers wait for their data, fsync(2) follows each write(2);
-          </entry>
-        </row>
-
-        <row>
-          <entry xml:id="wal_dir_rescan_delay" xreflabel="wal_dir_rescan_delay">wal_dir_rescan_delay</entry>
-          <entry>float</entry>
-          <entry>0.1</entry>
-          <entry>no</entry>
-          <entry>Number of seconds between periodic scans of the
-          write-ahead-log file directory, when checking for
-          changes to write-ahead-log files for the sake of
-          replication or local hot standby.</entry>
-        </row>
-
-      </tbody>
-    </tgroup>
-  </table>
-
-  <table frame='all' pgwide='1'>
-    <title>Replication</title>
-    <tgroup cols='5' colsep='1' rowsep='1'>
-      <colspec colnum="1" colname="col1" colwidth="2*"/>
-      <colspec colnum="5" colname="col4" colwidth="6*"/>
-
-      <thead>
-        <row>
-          <entry>Name</entry>
-          <entry>Type</entry>
-          <entry>Default</entry>
-          <entry>Dynamic?</entry>
-          <entry>Description</entry>
-        </row>
-      </thead>
-
-      <tbody>
-
-        <row>
-          <entry xml:id="replication_source"
-          xreflabel="replication_source">replication_source</entry>
-          <entry>string</entry>
-          <entry>null</entry>
-          <entry><emphasis role="strong">yes</emphasis></entry>
-          <entry>If replication_source is not an empty string, the
-          server is considered to be a Tarantool replica.
-          The replica server will try to connect to the master
-           which replication_source specifies with a <link linkend="URI">URI</link> (Universal Resource Identifier),
-          for example 'konstantin:secret_password@tarantool.org:3301'.
-          The default user name is 'guest'.
-          A replica server does not accept data-change requests
-          on the <olink targetptr="primary_port">listen</olink> port.
-          The replication_source parameter is
-          dynamic, that is, to enter master mode, simply set
-          replication_source to an empty string and issue
-          "box.cfg{replication_source=new-value}".</entry>
-        </row>
-
-      </tbody>
-    </tgroup>
-  </table>
-
-  <table frame='all' pgwide='1'>
-    <title>Networking</title>
-    <tgroup cols='5' colsep='1' rowsep='1'>
-      <colspec colnum="1" colname="col1" colwidth="2*"/>
-      <colspec colnum="5" colname="col4" colwidth="6*"/>
-
-      <thead>
-        <row>
-          <entry>Name</entry>
-          <entry>Type</entry>
-          <entry>Default</entry>
-          <entry>Dynamic?</entry>
-          <entry>Description</entry>
-        </row>
-      </thead>
-
-      <tbody>
-
-        <row>
-          <entry>io_collect_interval</entry>
-          <entry>float</entry>
-          <entry>null</entry>
-          <entry><emphasis role="strong">yes</emphasis></entry>
-          <entry>The server will sleep for io_collect_interval seconds
-          between iterations of the event loop. Can be
-          used to reduce CPU load in deployments in which the
-          number of client connections is large, but requests are
-          not so frequent (for example, each connection issues
-          just a handful of requests per second). </entry>
-        </row>
-
-        <row>
-          <entry>readahead</entry>
-          <entry>integer</entry>
-          <entry>16320</entry>
-          <entry>yes</entry>
-          <entry>The size of the read-ahead buffer associated with a
-          client connection. The larger the buffer, the more
-          memory an active connection consumes and the more requests
-          can be read from the operating system buffer in a single
-          system call. The rule of thumb is to make sure the buffer
-          can contain at least a few dozen requests. Therefore, if
-          a typical tuple in a request is large, e.g. a few
-          kilobytes or even megabytes, the read-ahead buffer size should
-          be increased.  If batched request processing is not
-          used, it's prudent to leave this setting at its
-          default.</entry>
-        </row>
-
-      </tbody>
-    </tgroup>
-  </table>
-
-  <table frame='all' pgwide='1'>
-    <title>Logging</title>
-    <tgroup cols='5' colsep='1' rowsep='1'>
-      <colspec colnum="1" colname="col1" colwidth="2*"/>
-      <colspec colnum="5" colname="col4" colwidth="6*"/>
-
-      <thead>
-        <row>
-          <entry>Name</entry>
-          <entry>Type</entry>
-          <entry>Default</entry>
-          <entry>Dynamic?</entry>
-          <entry>Description</entry>
-        </row>
-      </thead>
-
-      <tbody>
-
-        <row>
-          <entry xml:id="log_level" xreflabel="log_level">log_level</entry>
-          <entry>integer</entry>
-          <entry>5</entry>
-          <entry><emphasis role="strong">yes</emphasis></entry>
-          <entry>How verbose the logging is. There are six log
-            verbosity classes: 1 -- SYSERROR, 2 -- ERROR, 3 -- CRITICAL, 4 --
-            WARNING, 5 -- INFO, 6 -- DEBUG. By setting log_level,
-            one can enable logging of all classes below or equal
-            to the given level. Tarantool prints its logs to the
-            standard error stream by default, but this can be
-            changed with the "logger" configuration parameter.
-          </entry>
-        </row>
-
-        <row>
-          <entry xml:id="logger" xreflabel="logger">logger</entry>
-          <entry>string</entry>
-          <entry>null</entry>
-          <entry>no</entry>
-          <entry>By default, the log is sent to the standard
-          error stream (<filename>stderr</filename>). If logger
-          is specified, the log is sent to the file named in the string.
-          Example setting: logger = 'tarantool.log'
-          (this will open tarantool.log for output on the
-          server's default directory).
-          </entry>
-        </row>
-
-        <row>
-          <entry>logger_nonblock</entry>
-          <entry>boolean</entry>
-          <entry>true</entry>
-          <entry>no</entry>
-          <entry>If logger_nonblock equals true, Tarantool does not
-          block on the log file descriptor when it's not
-          ready for write, and drops the message instead. If
-          log_level is high, and a lot of messages go to the log
-          file, setting logger_nonblock to true may improve logging
-          performance at the cost of some log messages getting
-          lost.</entry>
-        </row>
-
-        <row>
-          <entry>too_long_threshold</entry>
-          <entry>float</entry>
-          <entry>0.5</entry>
-          <entry><emphasis role="strong">yes</emphasis></entry>
-          <entry>If processing a request takes longer than the
-          given value (in seconds), warn about it in the log.
-          Has effect only if log_level is less than or equal to 4
-          (WARNING).</entry>
-        </row>
-
-      </tbody>
-    </tgroup>
-  </table>
-
-</section>
-
-<section xml:id="local_hot_standby" xreflabel="local_hot_standby">
-<title>Local hot standby</title>
-
-          <para>
-          Local hot standby is a feature which provides a simple form of failover without replication.
-          To initiate it, start a second instance of the Tarantool server on the same computer with
-          the same <code>box.cfg</code> configuration settings -- including the same directories and
-          same non-null URIs.
-          A warning should appear with a message like
-          "W> primary: [URI] is already in use, will retry binding after [n] seconds".
-          This is fine.
-          It means that the second instance is ready to take over if the first instance goes down.
-          </para>
-          <para>
-          The expectation is that there will be two
-          instances of the server using the same configuration.
-          The first one to start will be the "primary" instance.
-          The second one to start will be the "standby" instance.
-          The standby instance will initialize and will try to connect on listen
-          address and admin address, but will fail because the
-          primary instance has already taken them.
-          So the standby instance goes into a loop, reading the write
-          ahead log which the primary instance is writing (so the
-          two instances are always in synch), and trying to connect on the
-          ports. If the primary instance goes down for any reason,
-          the ports will become free so the standby instance will
-          succeed in connecting, and will become the primary instance.
-          Thus there is no noticeable downtime if the primary instance goes down.
-          </para>
-          <para>
-          If this local_hot_standby feature is being used, then replication_source should be an
-          empty string and wal_mode should not be equal to "none".
-         </para>
-
-</section>
-
-</chapter>
-
-<!--
-vim: tw=66 syntax=docbk
-vim: spell spelllang=en_us
--->
diff --git a/doc/user/connectors.xml b/doc/user/connectors.xml
deleted file mode 100644
index 578ed4a6cbf86467dd208e38f673a99fdd64be40..0000000000000000000000000000000000000000
--- a/doc/user/connectors.xml
+++ /dev/null
@@ -1,324 +0,0 @@
-<!DOCTYPE book [
-<!ENTITY % tnt SYSTEM "../tnt.ent">
-%tnt;
-]>
-<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
-         xmlns:xlink="http://www.w3.org/1999/xlink"
-         xml:id="connectors">
-
-<title>Connectors</title>
-<blockquote><para>
-  This chapter documents APIs for various programming languages.
-</para></blockquote>
-
-<section xml:id="protocol">
- <title>Protocol</title>
-  <para>Tarantool protocol was designed with a focus on asynchronous
-    I/O and easy integration with proxies. Each client
-    request starts with a variable-length binary header, containing
-    request id, request type, server id, log sequence number, and
-    so on.
-  </para>
-
- <para>
-    The mandatory length, present in request header simplifies
-    client or proxy I/O.  A response to a request is sent to the
-    client as soon as it is ready. It always carries in its header
-    the same type and id as in the request. The id makes it
-    possible to match a request to a response, even if the latter
-    arrived out of order.
-  </para>
-
-  <para>Unless implementing a client driver, one needn't
-    concern oneself with the complications of the binary
-    protocol. <olink targetptr="connectors">Language-specific
-    drivers</olink> provide a friendly way to store domain
-    language data structures in Tarantool.
-    A complete description of the binary protocol
-    is maintained in annotated Backus-Naur
-    form in the source tree: please see
-    <link xlink:href="http://tarantool.org/doc/box-protocol.html"><filename>doc/box-protocol.html</filename></link>.
-  </para>
-</section>
-
-<section xml:id="connector-packet-example">
-<title>Packet example</title>
-<para>
-The Tarantool API exists so that a client program can send a request packet
-to the server, and receive a response. Here is an example of a what the client
- would send for <command>box.space[513]:insert{'A', 'BB'}</command>. The BNF description of the components
-is in file <link xlink:href="http://tarantool.org/doc/box-protocol.html" xlink:title="A complete BNF of Tarantool client/server protocol">doc/box-protocol.html</link>.
-
-</para>
-                <informaltable frame='topbot'>
-                <tgroup cols='5' align='left' colsep='1' rowsep='1'>
-                <colspec colname='c1'/>
-                <colspec colname='c2'/>
-                <colspec colname='c3'/>
-                <colspec colname='c4'/>
-                <colspec colname='c5'/>
-                <thead>
-                <row>
-                <entry>Component</entry>
-                <entry>Byte#0</entry>
-                <entry>Byte#1</entry>
-                <entry>Byte#2</entry>
-                <entry>Byte#3</entry>
-                </row>
-                </thead>
-                      <tbody>
-                        <row>
-                          <entry>code for insert</entry>
-                          <entry>2</entry>
-                        </row>
-                        <row>
-                          <entry>rest of header</entry>
-                          <entry>...</entry>
-                          <entry>...</entry>
-                          <entry>...</entry>
-                          <entry>...</entry>
-                        </row>
-                        <row>
-                          <entry>2-digit number: space id</entry>
-                          <entry>cd</entry>
-                          <entry>02</entry>
-                          <entry>01</entry>
-                        </row>
-                        <row>
-                          <entry>code for tuple</entry>
-                          <entry>21</entry>
-                        </row>
-                        <row>
-                          <entry>1-digit number: field count = 2</entry>
-                          <entry>92</entry>
-                        </row>
-                        <row>
-                          <entry>1-character string: field[1]</entry>
-                          <entry>a1</entry>
-                          <entry>41</entry>
-                        </row>
-                        <row>
-                          <entry>2-character string: field[2]</entry>
-                          <entry>a2</entry>
-                          <entry>42</entry>
-                          <entry>42</entry>
-                        </row>
-                       </tbody>
-                    </tgroup>
-                </informaltable>
-<para>
-Now, one could send that packet to the tarantool server,
-and interpret the response (doc/box-protocol.html has a description
-of the packet format for responses as well as requests).
-But it would be easier, and less error-prone, if one could
-invoke a routine that formats the packet according to typed
-parameters. Something like <code>response=tarantool_routine("insert",513,"A","B");</code>.
-And that is why APIs exist for drivers for Perl, Python, PHP, and so on.
-</para>
-  </section>
-  
-  <section xml:id="connector-server">
-   <title>Setting up the server for connector examples</title>
-   <para>
-   This chapter has examples that show how to connect to the Tarantool
-   server via the Perl, PHP, and Python connectors.
-   The examples contain hard code that will work if and only if
-   the server (tarantool) is running on localhost (127.0.0.1) and is listening on port 3301
-   (<code>box.cfg.listen='3301'</code>) and space 'examples' has id = 999
-   (<code>box.space.tester.id = 999</code>), and
-   space 'examples' has a primary-key index for a numeric field
-   (<code>box.space[999].index[0].parts[1].type = "NUM"</code>)
-   and user 'guest' has privileges for reading and writing.
-   </para>
-   <para>
-   It is easy to meet all the conditions by starting the
-   server and executing this script:<programlisting>
-box.cfg{listen=3301}
-box.schema.space.create('examples',{id=999})
-box.space.examples:create_index('primary', {type = 'hash', parts = {1, 'NUM'}})
-box.schema.user.grant('guest','read,write','space','examples')
-box.schema.user.grant('guest','read','space','_space')
-</programlisting>
-   </para>
-  </section>
-
-  <section xml:id="connector-java">
-    <title>Java</title>
-    <para>
-       Please see <link xlink:href="http://dgreenru.github.io/tarantool-java/"><filename>http://dgreenru.github.io/tarantool-java/</filename></link>.
-    </para>
-  </section>
-  
-  <section xml:id="connector-go">
-    <title>Go</title>
-    <para>
-       Please see <link xlink:href="https://github.com/mialinx/go-tarantool-1.6"><filename>https://github.com/mialinx/go-tarantool-1.6</filename></link>.
-    </para>
-  </section>
-
-  <section xml:id="connector-perl">
-    <title>Perl</title>
-    <para>
-     The most commonly used Perl driver is <link xlink:href='http://search.cpan.org/~unera/DR-Tarantool/'>DR::Tarantool</link>.
-     It is not supplied as part of the Tarantool repository; it must be installed separately.
-     The most common way to install it is with <link xlink:href='https://en.wikipedia.org/wiki/Cpan'>CPAN, the Comprehensive Perl Archive Network</link>.
-     DR::Tarantool requires other modules which should be installed first.
-     For example, on Ubuntu, the installation could look like this:<programlisting>
-sudo cpan install AnyEvent
-sudo cpan install Devel::GlobalDestruction
-sudo cpan install Coro
-sudo cpan install Test::Pod
-sudo cpan install Test::Spelling
-sudo cpan install PAR::Dist
-sudo cpan install List::MoreUtils
-sudo cpan install DR::Tarantool</programlisting>
-    </para>
-    <para>
-    Here is a complete Perl program that inserts [99999,'BB'] into space[999] via the Perl API.
-    Before trying to run, check that the server is listening and that <code>examples</code> exists,
-    as described <link linkend="connector-server">earlier</link>.
-    To run, paste the code into a file named example.pl and say <code>perl example.pl</code>.
-    The program will connect using an application-specific definition of the space.
-    The program will open a socket connection
-    with the tarantool server at localhost:3301, then send an INSERT request,
-    then &mdash; if all is well &mdash; end without displaying any messages.
-    If tarantool is not running on localhost with listen address = 3301, the program will print
-    <quote>Connection refused</quote>.
-    </para>
-    <para>
-     <programlisting language="perl">
-#!/usr/bin/perl
-use DR::Tarantool ':constant', 'tarantool';
-use DR::Tarantool ':all';
-use DR::Tarantool::MsgPack::SyncClient;
-
-my $tnt = DR::Tarantool::MsgPack::SyncClient->connect(
-  host    => '127.0.0.1',                      # look for tarantool on localhost
-  port    => 3301,                             # assume tarantool listen address = default
-  user    => 'guest',                          # username. one could also say 'password=>...'
-
-  spaces  => {
-    999 => {                                   # definition of space[999] ...
-      name => 'examples',                      #   space[999] name = 'examples'
-      default_type => 'STR',                   #   space[999] field type is 'STR' if undefined
-      fields => [ {                            #   definition of space[512].fields ...
-          name => 'field1', type => 'NUM' } ], #     space[999].field[1] name='field1',type='NUM'
-      indexes => {                             #   definition of space[999] indexes ...
-        0 => {
-          name => 'primary', fields => [ 'field1' ] } } } } );
-
-$tnt->insert('examples' => [ 99999, 'BB' ]);</programlisting>
-    </para>
-    <para>
-       The example program only shows one command and does not show all that's necessary for
-       good practice. For that, please see
-       <link xlink:href='http://search.cpan.org/~unera/DR-Tarantool/'>DR::Tarantool CPAN repository</link>.
-    </para>
-  </section>
-
-  <section xml:id="connector-php">
-    <title>PHP</title>
-    
-    <para>
-    The PHP driver is <link xlink:href='https://github.com/tarantool/tarantool-php'>tarantool-php</link>.
-    It is not supplied as part of the Tarantool repository; it must be installed separately.
-    It can be installed with git.
-    It requires other modules which should be installed first.
-    For example, on Ubuntu, the installation could look like this:
-    <programlisting>
-sudo apt-get install php5-cli
-sudo apt-get install php5-dev
-sudo apt-get install php-pear
-cd ~
-git clone https://github.com/tarantool/tarantool-php.git
-cd tarantool-php
-phpize
-./configure
-make
-#make install is optional</programlisting>
-    </para>
-    <para>
-    At this point there is a file named <filename>~/tarantool-php/modules/tarantool.so</filename>.
-    PHP will only find it if the PHP initialization file <filename>php.ini</filename> contains a line like
-    <code>extension=./tarantool.so</code>.
-    So copy <filename>tarantool.so</filename> to the working directory and tell PHP where
-    to find the <filename>php.ini</filename> file that contains that line ...
-    <programlisting>
-cd ~
-cp ./tarantool-php/modules/tarantool.so .
-export PHP_INI_SCAN_DIR=~/tarantool-php/test/shared</programlisting>
-    </para>
-    <para>
-    Here is a complete PHP program that inserts [99999,'BB'] into a space named 'examples' via the PHP API.
-    Before trying to run, check that the server is listening and that <code>examples</code> exists,
-    as described <link linkend="connector-server">earlier</link>.
-    To run, paste the code into a file named example.php and say <code>php example.php</code>.
-    The program will open a socket connection
-    with the tarantool server at localhost:3301, then send an INSERT request,
-    then &mdash; if all is well &mdash; print "Insert succeeded".
-    If the tuple already exists, the program will print <quote>Duplicate key exists in unique index 0</quote>.
-    </para>
-    <para>
-    <programlisting>
-&lt;?php
-$tarantool = new Tarantool("localhost", 3301);
-try {
-  $tarantool-&gt;insert("examples", array(99999, "BB"));
-  print "Insert succeeded\n";
-  }
-catch (Exception $e) {
-  echo "Exception: ", $e-&gt;getMessage(), "\n";
-  }
-?&gt;</programlisting>
-    </para>
-    <para>
-    After running the example, it is good practice to delete the file ./tarantool.so,
-    since it is only compatible with PHP and its existence could confuse non-PHP applications.
-    </para>
-    <para>
-    The example program only shows one command and does not show all that's necessary for
-    good practice. For that, please see
-    <link
-    xlink:href="https://github.com/tarantool/tarantool-php/"><filename>tarantool-php</filename></link> project at GitHub.
-    </para>
-  </section>
-
-  <section xml:id="connector-python">
-    <title>Python</title>
-    <para>
-     Here is a complete Python program that inserts [99999,'Value','Value'] into space <code>examples</code> via the high-level Python API.
-    </para>
-<programlisting language="python">
-#!/usr/bin/python
-from tarantool import Connection
-
-c = Connection("127.0.0.1", 3301)
-result = c.insert("examples",(99999,'Value', 'Value'))
-print result
-</programlisting>
-    <para>
-    To prepare, paste the code into a file named example.py and install tarantool-python with either
-    <userinput><code>pip install tarantool\>0.4</code></userinput> to install in <filename>/usr</filename> (requires root privilege)
-    or
-    <userinput><code>pip install tarantool\>0.4 --user</code></userinput> to install in <filename>~</filename> i.e. user's default directory.
-    Before trying to run, check that the server is listening and that <code>examples</code> exists,
-    as described <link linkend="connector-server">earlier</link>.
-    To run the program, say <code>python example.py</code>.
-    The program will connect to the server, will send the request, and will not throw an exception if all went well.
-    If the tuple already exists, the program will throw DatabaseException(“Duplicate key exists in unique index”).
-    </para>
-    <para>
-       The example program only shows one request and does not show all that's necessary for
-       good practice. For that, see
-       <link xlink:href="http://github.com/tarantool/tarantool-python"><filename>http://github.com/tarantool/tarantool-python</filename></link>.
-       For an example of a Python API for <link xlink:href="https://github.com/tarantool/queue">Queue managers on Tarantool</link>, see 
-       <link xlink:href="https://github.com/tarantool/tarantool-queue-python"><filename>https://github.com/tarantool/tarantool-queue-python</filename></link>.
-    </para>
-  </section>
-  
-</chapter>
-
-<!--
-vim: tw=66 syntax=docbk
-vim: spell spelllang=en_us
--->
diff --git a/doc/www/content/js/old_tabs.js b/doc/www/content/js/old_tabs.js
deleted file mode 100644
index 7f8891a8fb11ebf57c44f40cc141c724af1952d1..0000000000000000000000000000000000000000
--- a/doc/www/content/js/old_tabs.js
+++ /dev/null
@@ -1,187 +0,0 @@
-(function(){
-var dOn = $(document);
-
-dOn.on({
-    click: function(){
-        if (!($(this).hasClass('b-button_on'))){
-            $('.b-button_on').removeClass('b-button_on');
-            $(this).addClass('b-button_on');
-
-            switch ($(this).html()) {
-                case 'A_Read' : {
-                    $('#picture2').renderChart('/ycsb/A_READ_latency.json');
-                    break;
-                }
-                case 'A_Update' : {
-                    $('#picture2').renderChart('/ycsb/A_UPDATE_latency.json');
-                    break;
-                }
-                case 'B_Read' : {
-                    $('#picture2').renderChart('/ycsb/B_READ_latency.json');
-                    break;
-                }
-                case 'B_Update' : {
-                    $('#picture2').renderChart('/ycsb/B_UPDATE_latency.json');
-                    break;
-                }
-                case 'C_Read' : {
-                    $('#picture2').renderChart('/ycsb/C_READ_latency.json');
-                    break;
-                }
-                case 'D_Insert' : {
-                    $('#picture2').renderChart('/ycsb/D_INSERT_latency.json');
-                    break;
-                }
-                case 'D_Read' : {
-                    $('#picture2').renderChart('/ycsb/D_READ_latency.json');
-                    break;
-                }
-                case 'E_Insert' : {
-                    $('#picture2').renderChart('/ycsb/E_INSERT_latency.json');
-                    break;
-                }
-                case 'E_Scan' : {
-                    $('#picture2').renderChart('/ycsb/E_SCAN_latency.json');
-                    break;
-                }
-                case 'F_Read' : {
-                    $('#picture2').renderChart('/ycsb/F_READ_latency.json');
-                    break;
-                }
-                case 'F_Read-Modify-Write' : {
-                    $('#picture2').renderChart('/ycsb/F_READ-MODIFY-WRITE_latency.json');
-                    break;
-                }
-                case 'F_Update' : {
-                    $('#picture2').renderChart('/ycsb/F_UPDATE_latency.json');
-                    break;
-                }
-                case 'LOAD_Insert' : {
-                    $('#picture2').renderChart('/ycsb/LOAD_INSERT_latency.json');
-                    break;
-                }
-            }
-
-        }
-    }
-}, '.b-button');
-
-dOn.on({
-    click: function(){
-        if (!($(this).hasClass('b-tabs__li_on'))){
-            $('.b-tabs__li_on').removeClass('b-tabs__li_on');
-            $(this).addClass('b-tabs__li_on');
-
-            $('.b-button').remove();
-            var head = $('.b-tabs__header'), ul = $('.b-tabs__buttons'), li, desc = $('.b-tabs__description');
-
-            switch ($(this).html()) {
-                case 'A' : {
-                    head.html('Workload A')
-                    $('#picture1').renderChart('/ycsb/A_throughput.json');
-                    $('#picture2').renderChart('/ycsb/A_READ_latency.json');
-
-                    li = $('<li class="b-button b-button_on">A_Read</li>');
-                    ul.append(li);
-                    li = $('<li class="b-button">A_Update</li>');
-                    ul.append(li);
-
-                    desc.html('50/50 update/read ratio');
-
-                    break;
-                }
-                case 'B' : {
-                    head.html('Workload B')
-                    $('#picture1').renderChart('/ycsb/B_throughput.json');
-                    $('#picture2').renderChart('/ycsb/B_READ_latency.json');
-
-                    li = $('<li class="b-button b-button_on">B_Read</li>');
-                    ul.append(li);
-                    li = $('<li class="b-button">B_Update</li>');
-                    ul.append(li);
-
-                    desc.html('5/95 update/read ratio');
-
-                    break;
-                }
-                case 'C' : {
-                    head.html('Workload C')
-                    $('#picture1').renderChart('/ycsb/C_throughput.json');
-                    $('#picture2').renderChart('/ycsb/C_READ_latency.json');
-
-                    li = $('<li class="b-button b-button_on">C_Read</li>');
-                    ul.append(li);
-
-                    desc.html('100% read-only');
-
-                    break;
-                }
-                case 'D' : {
-                    head.html('Workload D')
-                    $('#picture1').renderChart('/ycsb/D_throughput.json');
-                    $('#picture2').renderChart('/ycsb/D_READ_latency.json');
-
-                    li = $('<li class="b-button b-button_on">D_Read</li>');
-                    ul.append(li);
-                    li = $('<li class="b-button">D_Insert</li>');
-                    ul.append(li);
-
-                    desc.html('5/95 insert/read ratio, the read load is skewed towards the end of the key range');
-
-                    break;
-                }
-                case 'E' : {
-                    head.html('Workload E')
-                    $('#picture1').renderChart('/ycsb/E_throughput.json');
-                    $('#picture2').renderChart('/ycsb/E_INSERT_latency.json');
-
-                    li = $('<li class="b-button b-button_on">E_Insert</li>');
-                    ul.append(li);
-                    li = $('<li class="b-button">E_Scan</li>');
-                    ul.append(li);
-
-                    desc.html('5/95 ratio of insert/reads over a range of 10 records');
-
-                    break;
-                }
-                case 'F' : {
-                    head.html('Workload F')
-                    $('#picture1').renderChart('/ycsb/F_throughput.json');
-                    $('#picture2').renderChart('/ycsb/F_READ_latency.json');
-
-                    li = $('<li class="b-button b-button_on">F_Read</li>');
-                    ul.append(li);
-                    li = $('<li class="b-button">F_Read-Modify-Write</li>');
-                    ul.append(li);
-                    li = $('<li class="b-button">F_Update</li>');
-                    ul.append(li);
-
-                    desc.html('95% read/modify/write, 5% read');
-
-                    break;
-                }
-                case 'LOAD' : {
-                    head.html('Insert only')
-                    $('#picture1').renderChart('/ycsb/LOAD_throughput.json');
-                    $('#picture2').renderChart('/ycsb/LOAD_INSERT_latency.json');
-
-                    li = $('<li class="b-button b-button_on">L_Insert</li>');
-                    ul.append(li);
-
-                    desc.html('');
-
-                    break;
-                }
-            }
-        }
-    }
-}, '.b-tabs__li');
-})();
-
-(function(){
-var dOn = $(document);
-dOn.ready(function() {
-    $('#picture1').renderChart('/ycsb/A_throughput.json');
-    $('#picture2').renderChart('/ycsb/A_READ_latency.json');
-});
-})();
diff --git a/doc/www/content/newsite/benchmark.yml b/doc/www/content/newsite/benchmark.yml
index e8df8c0b64717e98a35057ef08dece11b76cb677..ecc7e23f3068ad6935158be7be36561d5f14e4d6 100644
--- a/doc/www/content/newsite/benchmark.yml
+++ b/doc/www/content/newsite/benchmark.yml
@@ -40,10 +40,10 @@ blocks  :
       Tarantool support is available
       `here <https://github.com/bigbes92/YCSB>`_. Since YCSB
       was developed to compare cloud key/value servers, it
-      provides a very narrow view benchmarking kit is more
-      appropriate. This is why Yahoo! Cloud secondary keys
-      or overhead of locking (which Tarantool doesn't have)
-      is not tested at all.
+      provides a very narrow view at performance of a tested
+      server. For example, performance of secondary keys or
+      overhead of locking (which Tarantool doesn't have) is
+      not tested at all.
 
       .. |copy| unicode:: U+000A9
 
diff --git a/doc/www/content/newsite/documentation.yml b/doc/www/content/newsite/documentation.yml
deleted file mode 100644
index 739f503d27d4751ac0b1c6eae7f5d181a0b9b425..0000000000000000000000000000000000000000
--- a/doc/www/content/newsite/documentation.yml
+++ /dev/null
@@ -1,33 +0,0 @@
----
-title   : "Tarantool - Documentation"
-slug    : "documentation"
-save_as : "documentation.html"
-template: "documentation"
-blocks  :
-  sections:
-    - name: "Introduction"
-      list:
-        - name: "What is Tarantool?"
-          link: "doc/introduction.html#what-is-tarantool"
-        - name: "An overview of the architecture"
-          link: "doc/introduction.html#an-overview-of-the-architecture"
-        - name: "Key features"
-          link: "doc/introduction.html#key-features"
-        - name: "How stable is the software?"
-          link: "doc/introduction.html#how-stable-is-the-software"
-    - name: "User Guide"
-      list:
-        - name: "Multi page HTML"
-          link: "doc/user_guide/"
-        - name: "Single page HTML"
-          link: "doc/user_guide.html"
-        - name: "FAQ"
-          link: "doc/faq.html"
-    - name: "Developer section"
-      list:
-        - name: "Developer Guide"
-          link: "doc/dev_guide.html"
-        - name: "IProto Protocol"
-          link: "doc/box-protocol.html"
-
-...
diff --git a/doc/www/content/ycsb/1.py b/doc/www/content/ycsb/1.py
deleted file mode 100755
index 8cfe4ea923aba8dbf28d77e9fa3b524d9528363e..0000000000000000000000000000000000000000
--- a/doc/www/content/ycsb/1.py
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/usr/bin/env python
-import os
-import glob
-import json
-
-a = glob.glob("*.json")
-
-for f in a:
-    open(f + ".out", 'w').write(json.dumps(json.loads(open(f, 'r').read()), sort_keys=True, indent=4))
diff --git a/doc/www/content/ycsb/A_READ_latency.json b/doc/www/content/ycsb/A_READ_latency.json
index a99eb9336acce1c96fa49027c990eb40f01c680c..ae8cef9a8b2241c620e317999d408567e5a4db71 100644
--- a/doc/www/content/ycsb/A_READ_latency.json
+++ b/doc/www/content/ycsb/A_READ_latency.json
@@ -6,93 +6,96 @@
     "legend": {}, 
     "series": [
         {
+            "color": "#0d233a", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 238.3
+                    "y": 238.56
                 }, 
                 {
                     "x": 16, 
-                    "y": 322.78
+                    "y": 321.57
                 }, 
                 {
                     "x": 32, 
-                    "y": 422.29
+                    "y": 407.0
                 }, 
                 {
                     "x": 64, 
-                    "y": 823.54
+                    "y": 786.32
                 }, 
                 {
                     "x": 128, 
-                    "y": 1674.64
+                    "y": 1701.38
                 }, 
                 {
                     "x": 256, 
-                    "y": 3453.41
+                    "y": 3296.77
                 }
             ], 
             "name": "Redis 2.8.19", 
             "type": "line"
         }, 
         {
+            "color": "#2f7ed8", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 177.53
+                    "y": 173.25
                 }, 
                 {
                     "x": 16, 
-                    "y": 212.79
+                    "y": 223.19
                 }, 
                 {
                     "x": 32, 
-                    "y": 384.8
+                    "y": 327.81
                 }, 
                 {
                     "x": 64, 
-                    "y": 781.84
+                    "y": 691.3
                 }, 
                 {
                     "x": 128, 
-                    "y": 1557.11
+                    "y": 1431.62
                 }, 
                 {
                     "x": 256, 
-                    "y": 3152.47
+                    "y": 2877.7
                 }
             ], 
-            "name": "Tarantool (TREE, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (TREE, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }, 
         {
+            "color": "#8bbc21", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 196.98
+                    "y": 175.08
                 }, 
                 {
                     "x": 16, 
-                    "y": 255.04
+                    "y": 222.31
                 }, 
                 {
                     "x": 32, 
-                    "y": 526.46
+                    "y": 346.42
                 }, 
                 {
                     "x": 64, 
-                    "y": 1041.25
+                    "y": 714.42
                 }, 
                 {
                     "x": 128, 
-                    "y": 2083.02
+                    "y": 1421.44
                 }, 
                 {
                     "x": 256, 
-                    "y": 4115.76
+                    "y": 2877.45
                 }
             ], 
-            "name": "Tarantool (HASH, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (HASH, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }
     ], 
diff --git a/doc/www/content/ycsb/A_UPDATE_latency.json b/doc/www/content/ycsb/A_UPDATE_latency.json
index ec2bab41beac1db395765a27e9abdb198e189a79..d0528bb8b75f799cae2d6c67d50c767d0a2796a7 100644
--- a/doc/www/content/ycsb/A_UPDATE_latency.json
+++ b/doc/www/content/ycsb/A_UPDATE_latency.json
@@ -6,93 +6,96 @@
     "legend": {}, 
     "series": [
         {
+            "color": "#0d233a", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 217.73
+                    "y": 217.45
                 }, 
                 {
                     "x": 16, 
-                    "y": 300.25
+                    "y": 298.58
                 }, 
                 {
                     "x": 32, 
-                    "y": 402.81
+                    "y": 386.43
                 }, 
                 {
                     "x": 64, 
-                    "y": 808.84
+                    "y": 771.9
                 }, 
                 {
                     "x": 128, 
-                    "y": 1653.34
+                    "y": 1680.56
                 }, 
                 {
                     "x": 256, 
-                    "y": 3424.24
+                    "y": 3267.28
                 }
             ], 
             "name": "Redis 2.8.19", 
             "type": "line"
         }, 
         {
+            "color": "#2f7ed8", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 184.09
+                    "y": 178.18
                 }, 
                 {
                     "x": 16, 
-                    "y": 222.08
+                    "y": 230.49
                 }, 
                 {
                     "x": 32, 
-                    "y": 387.34
+                    "y": 329.9
                 }, 
                 {
                     "x": 64, 
-                    "y": 783.16
+                    "y": 691.71
                 }, 
                 {
                     "x": 128, 
-                    "y": 1558.04
+                    "y": 1431.35
                 }, 
                 {
                     "x": 256, 
-                    "y": 3152.19
+                    "y": 2876.22
                 }
             ], 
-            "name": "Tarantool (TREE, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (TREE, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }, 
         {
+            "color": "#8bbc21", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 201.19
+                    "y": 180.19
                 }, 
                 {
                     "x": 16, 
-                    "y": 260.99
+                    "y": 229.62
                 }, 
                 {
                     "x": 32, 
-                    "y": 527.1
+                    "y": 348.42
                 }, 
                 {
                     "x": 64, 
-                    "y": 1041.35
+                    "y": 714.79
                 }, 
                 {
                     "x": 128, 
-                    "y": 2082.11
+                    "y": 1421.39
                 }, 
                 {
                     "x": 256, 
-                    "y": 4114.76
+                    "y": 2876.09
                 }
             ], 
-            "name": "Tarantool (HASH, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (HASH, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }
     ], 
diff --git a/doc/www/content/ycsb/A_throughput.json b/doc/www/content/ycsb/A_throughput.json
index 0d7563a9cacc8ccd1358812b1b534668b79527c7..43c879e37b5ea6fee0868dbbaa2ad2ddf4e3396c 100644
--- a/doc/www/content/ycsb/A_throughput.json
+++ b/doc/www/content/ycsb/A_throughput.json
@@ -6,93 +6,96 @@
     "legend": {}, 
     "series": [
         {
+            "color": "#0d233a", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 31562.23
+                    "y": 31616.63
                 }, 
                 {
                     "x": 16, 
-                    "y": 48114.504
+                    "y": 48164.624
                 }, 
                 {
                     "x": 32, 
-                    "y": 74829.546
+                    "y": 77671.66
                 }, 
                 {
                     "x": 64, 
-                    "y": 76531.577
+                    "y": 80181.142
                 }, 
                 {
                     "x": 128, 
-                    "y": 75436.465
+                    "y": 74239.826
                 }, 
                 {
                     "x": 256, 
-                    "y": 73227.805
+                    "y": 76748.628
                 }
             ], 
             "name": "Redis 2.8.19", 
             "type": "line"
         }, 
         {
+            "color": "#2f7ed8", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 40138.01
+                    "y": 41198.855
                 }, 
                 {
                     "x": 16, 
-                    "y": 69150.347
+                    "y": 66591.308
                 }, 
                 {
                     "x": 32, 
-                    "y": 80856.866
+                    "y": 94335.042
                 }, 
                 {
                     "x": 64, 
-                    "y": 80825.48
+                    "y": 91319.348
                 }, 
                 {
                     "x": 128, 
-                    "y": 81415.534
+                    "y": 88474.373
                 }, 
                 {
                     "x": 256, 
-                    "y": 80197.603
+                    "y": 87626.284
                 }
             ], 
-            "name": "Tarantool (TREE, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (TREE, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }, 
         {
+            "color": "#8bbc21", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 36628.178
+                    "y": 41482.074
                 }, 
                 {
                     "x": 16, 
-                    "y": 58990.98
+                    "y": 66567.06
                 }, 
                 {
                     "x": 32, 
-                    "y": 59768.109
+                    "y": 89820.126
                 }, 
                 {
                     "x": 64, 
-                    "y": 60935.21
+                    "y": 88425.776
                 }, 
                 {
                     "x": 128, 
-                    "y": 61050.897
+                    "y": 89046.299
                 }, 
                 {
                     "x": 256, 
-                    "y": 61660.282
+                    "y": 87689.532
                 }
             ], 
-            "name": "Tarantool (HASH, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (HASH, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }
     ], 
diff --git a/doc/www/content/ycsb/B_READ_latency.json b/doc/www/content/ycsb/B_READ_latency.json
index 69ec3de179659ee9d297c4ff31179d132267f71f..1408d5f3463b561f07850aa23bc3a8e12f266d73 100644
--- a/doc/www/content/ycsb/B_READ_latency.json
+++ b/doc/www/content/ycsb/B_READ_latency.json
@@ -6,93 +6,96 @@
     "legend": {}, 
     "series": [
         {
+            "color": "#0d233a", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 234.07
+                    "y": 251.7
                 }, 
                 {
                     "x": 16, 
-                    "y": 332.82
+                    "y": 333.41
                 }, 
                 {
                     "x": 32, 
-                    "y": 434.14
+                    "y": 436.93
                 }, 
                 {
                     "x": 64, 
-                    "y": 827.22
+                    "y": 849.47
                 }, 
                 {
                     "x": 128, 
-                    "y": 1691.27
+                    "y": 1701.41
                 }, 
                 {
                     "x": 256, 
-                    "y": 3276.43
+                    "y": 3429.75
                 }
             ], 
             "name": "Redis 2.8.19", 
             "type": "line"
         }, 
         {
+            "color": "#2f7ed8", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 202.35
+                    "y": 186.74
                 }, 
                 {
                     "x": 16, 
-                    "y": 259.18
+                    "y": 237.12
                 }, 
                 {
                     "x": 32, 
-                    "y": 347.49
+                    "y": 281.9
                 }, 
                 {
                     "x": 64, 
-                    "y": 706.49
+                    "y": 525.57
                 }, 
                 {
                     "x": 128, 
-                    "y": 1438.33
+                    "y": 1073.18
                 }, 
                 {
                     "x": 256, 
-                    "y": 2904.98
+                    "y": 2140.08
                 }
             ], 
-            "name": "Tarantool (TREE, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (TREE, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }, 
         {
+            "color": "#8bbc21", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 215.67
+                    "y": 197.49
                 }, 
                 {
                     "x": 16, 
-                    "y": 268.06
+                    "y": 258.31
                 }, 
                 {
                     "x": 32, 
-                    "y": 506.92
+                    "y": 351.26
                 }, 
                 {
                     "x": 64, 
-                    "y": 999.01
+                    "y": 698.75
                 }, 
                 {
                     "x": 128, 
-                    "y": 1995.78
+                    "y": 1398.72
                 }, 
                 {
                     "x": 256, 
-                    "y": 4036.14
+                    "y": 2842.95
                 }
             ], 
-            "name": "Tarantool (HASH, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (HASH, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }
     ], 
diff --git a/doc/www/content/ycsb/B_UPDATE_latency.json b/doc/www/content/ycsb/B_UPDATE_latency.json
index 8ec339eb66585e2eda62d8b505e799103c9e4668..4e6b219ec6963eddccc863e6d20290b019d623e8 100644
--- a/doc/www/content/ycsb/B_UPDATE_latency.json
+++ b/doc/www/content/ycsb/B_UPDATE_latency.json
@@ -6,93 +6,96 @@
     "legend": {}, 
     "series": [
         {
+            "color": "#0d233a", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 229.62
+                    "y": 247.97
                 }, 
                 {
                     "x": 16, 
-                    "y": 324.93
+                    "y": 325.26
                 }, 
                 {
                     "x": 32, 
-                    "y": 423.11
+                    "y": 425.87
                 }, 
                 {
                     "x": 64, 
-                    "y": 820.99
+                    "y": 843.5
                 }, 
                 {
                     "x": 128, 
-                    "y": 1681.57
+                    "y": 1691.5
                 }, 
                 {
                     "x": 256, 
-                    "y": 3260.8
+                    "y": 3414.33
                 }
             ], 
             "name": "Redis 2.8.19", 
             "type": "line"
         }, 
         {
+            "color": "#2f7ed8", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 204.72
+                    "y": 185.36
                 }, 
                 {
                     "x": 16, 
-                    "y": 261.95
+                    "y": 239.46
                 }, 
                 {
                     "x": 32, 
-                    "y": 346.79
+                    "y": 284.44
                 }, 
                 {
                     "x": 64, 
-                    "y": 703.47
+                    "y": 523.05
                 }, 
                 {
                     "x": 128, 
-                    "y": 1435.14
+                    "y": 1070.05
                 }, 
                 {
                     "x": 256, 
-                    "y": 2901.57
+                    "y": 2136.53
                 }
             ], 
-            "name": "Tarantool (TREE, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (TREE, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }, 
         {
+            "color": "#8bbc21", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 216.46
+                    "y": 196.99
                 }, 
                 {
                     "x": 16, 
-                    "y": 269.8
+                    "y": 260.05
                 }, 
                 {
                     "x": 32, 
-                    "y": 502.79
+                    "y": 350.16
                 }, 
                 {
                     "x": 64, 
-                    "y": 995.77
+                    "y": 694.78
                 }, 
                 {
                     "x": 128, 
-                    "y": 1992.37
+                    "y": 1395.54
                 }, 
                 {
                     "x": 256, 
-                    "y": 4033.11
+                    "y": 2839.55
                 }
             ], 
-            "name": "Tarantool (HASH, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (HASH, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }
     ], 
diff --git a/doc/www/content/ycsb/B_throughput.json b/doc/www/content/ycsb/B_throughput.json
index f5b180bcae9d8c095749c4b5687b11e36d83edf8..517c80bc15df3e269dabf7eee6accb8f171d809b 100644
--- a/doc/www/content/ycsb/B_throughput.json
+++ b/doc/www/content/ycsb/B_throughput.json
@@ -6,93 +6,96 @@
     "legend": {}, 
     "series": [
         {
+            "color": "#0d233a", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 28485.608
+                    "y": 28377.237
                 }, 
                 {
                     "x": 16, 
-                    "y": 44253.794
+                    "y": 44401.604
                 }, 
                 {
                     "x": 32, 
-                    "y": 70902.442
+                    "y": 70977.722
                 }, 
                 {
                     "x": 64, 
-                    "y": 75737.47
+                    "y": 73819.817
                 }, 
                 {
                     "x": 128, 
-                    "y": 74245.59
+                    "y": 73776.249
                 }, 
                 {
                     "x": 256, 
-                    "y": 76628.854
+                    "y": 73478.511
                 }
             ], 
             "name": "Redis 2.8.19", 
             "type": "line"
         }, 
         {
+            "color": "#2f7ed8", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 34893.927
+                    "y": 37514.65
                 }, 
                 {
                     "x": 16, 
-                    "y": 57192.82
+                    "y": 62605.613
                 }, 
                 {
                     "x": 32, 
-                    "y": 89315.362
+                    "y": 108612.579
                 }, 
                 {
                     "x": 64, 
-                    "y": 89415.76
+                    "y": 119310.168
                 }, 
                 {
                     "x": 128, 
-                    "y": 88026.826
+                    "y": 117183.867
                 }, 
                 {
                     "x": 256, 
-                    "y": 86866.271
+                    "y": 116794.729
                 }
             ], 
-            "name": "Tarantool (TREE, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (TREE, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }, 
         {
+            "color": "#8bbc21", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 33145.744
+                    "y": 36015.58
                 }, 
                 {
                     "x": 16, 
-                    "y": 55755.676
+                    "y": 57811.373
                 }, 
                 {
                     "x": 32, 
-                    "y": 62043.479
+                    "y": 88502.1
                 }, 
                 {
                     "x": 64, 
-                    "y": 63502.111
+                    "y": 90438.228
                 }, 
                 {
                     "x": 128, 
-                    "y": 63688.278
+                    "y": 90389.708
                 }, 
                 {
                     "x": 256, 
-                    "y": 62882.635
+                    "y": 88585.185
                 }
             ], 
-            "name": "Tarantool (HASH, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (HASH, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }
     ], 
diff --git a/doc/www/content/ycsb/C_READ_latency.json b/doc/www/content/ycsb/C_READ_latency.json
index 9fe01b366945a090d10c2de9ee3256bea2116855..c32657caeba90528e59c4d208ee54ee57633998a 100644
--- a/doc/www/content/ycsb/C_READ_latency.json
+++ b/doc/www/content/ycsb/C_READ_latency.json
@@ -6,93 +6,96 @@
     "legend": {}, 
     "series": [
         {
+            "color": "#0d233a", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 237.65
+                    "y": 235.26
                 }, 
                 {
                     "x": 16, 
-                    "y": 326.34
+                    "y": 326.4
                 }, 
                 {
                     "x": 32, 
-                    "y": 427.78
+                    "y": 429.12
                 }, 
                 {
                     "x": 64, 
-                    "y": 721.95
+                    "y": 762.74
                 }, 
                 {
                     "x": 128, 
-                    "y": 1549.93
+                    "y": 1554.06
                 }, 
                 {
                     "x": 256, 
-                    "y": 3038.2
+                    "y": 3077.94
                 }
             ], 
             "name": "Redis 2.8.19", 
             "type": "line"
         }, 
         {
+            "color": "#2f7ed8", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 264.62
+                    "y": 207.76
                 }, 
                 {
                     "x": 16, 
-                    "y": 342.02
+                    "y": 291.43
                 }, 
                 {
                     "x": 32, 
-                    "y": 508.55
+                    "y": 389.65
                 }, 
                 {
                     "x": 64, 
-                    "y": 1015.86
+                    "y": 662.14
                 }, 
                 {
                     "x": 128, 
-                    "y": 2041.95
+                    "y": 1201.79
                 }, 
                 {
                     "x": 256, 
-                    "y": 4137.54
+                    "y": 2347.59
                 }
             ], 
-            "name": "Tarantool (TREE, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (TREE, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }, 
         {
+            "color": "#8bbc21", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 262.65
+                    "y": 230.83
                 }, 
                 {
                     "x": 16, 
-                    "y": 341.1
+                    "y": 307.77
                 }, 
                 {
                     "x": 32, 
-                    "y": 513.74
+                    "y": 389.51
                 }, 
                 {
                     "x": 64, 
-                    "y": 1028.74
+                    "y": 684.74
                 }, 
                 {
                     "x": 128, 
-                    "y": 2056.74
+                    "y": 1363.18
                 }, 
                 {
                     "x": 256, 
-                    "y": 4153.88
+                    "y": 2750.21
                 }
             ], 
-            "name": "Tarantool (HASH, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (HASH, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }
     ], 
diff --git a/doc/www/content/ycsb/C_throughput.json b/doc/www/content/ycsb/C_throughput.json
index a4b0e1baf8b9212ff6f97a64fb092320224367d7..8cb7f9f4fe588b4abc5ea10514ca07190a076ece 100644
--- a/doc/www/content/ycsb/C_throughput.json
+++ b/doc/www/content/ycsb/C_throughput.json
@@ -6,93 +6,96 @@
     "legend": {}, 
     "series": [
         {
+            "color": "#0d233a", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 29119.583
+                    "y": 27843.342
                 }, 
                 {
                     "x": 16, 
-                    "y": 45503.99
+                    "y": 45460.125
                 }, 
                 {
                     "x": 32, 
-                    "y": 72268.639
+                    "y": 71988.614
                 }, 
                 {
                     "x": 64, 
-                    "y": 86938.763
+                    "y": 82428.213
                 }, 
                 {
                     "x": 128, 
-                    "y": 81024.126
+                    "y": 80868.366
                 }, 
                 {
                     "x": 256, 
-                    "y": 82035.127
+                    "y": 81323.473
                 }
             ], 
             "name": "Redis 2.8.19", 
             "type": "line"
         }, 
         {
+            "color": "#2f7ed8", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 26085.671
+                    "y": 32443.698
                 }, 
                 {
                     "x": 16, 
-                    "y": 43450.932
+                    "y": 50471.791
                 }, 
                 {
                     "x": 32, 
-                    "y": 61286.668
+                    "y": 79508.113
                 }, 
                 {
                     "x": 64, 
-                    "y": 62427.818
+                    "y": 89683.067
                 }, 
                 {
                     "x": 128, 
-                    "y": 62266.579
+                    "y": 97592.776
                 }, 
                 {
                     "x": 256, 
-                    "y": 61389.134
+                    "y": 98615.937
                 }
             ], 
-            "name": "Tarantool (TREE, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (TREE, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }, 
         {
+            "color": "#8bbc21", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 26830.928
+                    "y": 28821.365
                 }, 
                 {
                     "x": 16, 
-                    "y": 43539.712
+                    "y": 47790.788
                 }, 
                 {
                     "x": 32, 
-                    "y": 60796.056
+                    "y": 79282.154
                 }, 
                 {
                     "x": 64, 
-                    "y": 61628.435
+                    "y": 92164.012
                 }, 
                 {
                     "x": 128, 
-                    "y": 61818.459
+                    "y": 92751.024
                 }, 
                 {
                     "x": 256, 
-                    "y": 61134.947
+                    "y": 91425.074
                 }
             ], 
-            "name": "Tarantool (HASH, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (HASH, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }
     ], 
diff --git a/doc/www/content/ycsb/D_INSERT_latency.json b/doc/www/content/ycsb/D_INSERT_latency.json
index c6104b490a9f622bebc846cd749d34aeecfba58c..87751ff1d6be2ab337c24236b0becd7896b1d6d8 100644
--- a/doc/www/content/ycsb/D_INSERT_latency.json
+++ b/doc/www/content/ycsb/D_INSERT_latency.json
@@ -6,93 +6,96 @@
     "legend": {}, 
     "series": [
         {
+            "color": "#0d233a", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 506.78
+                    "y": 515.11
                 }, 
                 {
                     "x": 16, 
-                    "y": 692.44
+                    "y": 697.82
                 }, 
                 {
                     "x": 32, 
-                    "y": 874.74
+                    "y": 885.49
                 }, 
                 {
                     "x": 64, 
-                    "y": 1628.55
+                    "y": 1642.56
                 }, 
                 {
                     "x": 128, 
-                    "y": 3290.35
+                    "y": 3344.88
                 }, 
                 {
                     "x": 256, 
-                    "y": 6598.28
+                    "y": 6563.97
                 }
             ], 
             "name": "Redis 2.8.19", 
             "type": "line"
         }, 
         {
+            "color": "#2f7ed8", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 309.23
+                    "y": 300.75
                 }, 
                 {
                     "x": 16, 
-                    "y": 379.22
+                    "y": 363.55
                 }, 
                 {
                     "x": 32, 
-                    "y": 445.48
+                    "y": 449.73
                 }, 
                 {
                     "x": 64, 
-                    "y": 725.08
+                    "y": 710.01
                 }, 
                 {
                     "x": 128, 
-                    "y": 1408.9
+                    "y": 1249.62
                 }, 
                 {
                     "x": 256, 
-                    "y": 2811.35
+                    "y": 2410.87
                 }
             ], 
-            "name": "Tarantool (TREE, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (TREE, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }, 
         {
+            "color": "#8bbc21", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 326.17
+                    "y": 301.08
                 }, 
                 {
                     "x": 16, 
-                    "y": 404.81
+                    "y": 382.13
                 }, 
                 {
                     "x": 32, 
-                    "y": 548.83
+                    "y": 463.92
                 }, 
                 {
                     "x": 64, 
-                    "y": 1013.01
+                    "y": 701.5
                 }, 
                 {
                     "x": 128, 
-                    "y": 1997.72
+                    "y": 1360.56
                 }, 
                 {
                     "x": 256, 
-                    "y": 4044.73
+                    "y": 2787.05
                 }
             ], 
-            "name": "Tarantool (HASH, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (HASH, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }
     ], 
diff --git a/doc/www/content/ycsb/D_READ_latency.json b/doc/www/content/ycsb/D_READ_latency.json
index 0af42b33900cda8b553f9d6c0bdd3c7643562c98..b9ecedd9d6575fdebe926e835821d264e097a2d3 100644
--- a/doc/www/content/ycsb/D_READ_latency.json
+++ b/doc/www/content/ycsb/D_READ_latency.json
@@ -6,93 +6,96 @@
     "legend": {}, 
     "series": [
         {
+            "color": "#0d233a", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 234.29
+                    "y": 239.06
                 }, 
                 {
                     "x": 16, 
-                    "y": 333.11
+                    "y": 336.21
                 }, 
                 {
                     "x": 32, 
-                    "y": 425.34
+                    "y": 430.47
                 }, 
                 {
                     "x": 64, 
-                    "y": 786.06
+                    "y": 794.71
                 }, 
                 {
                     "x": 128, 
-                    "y": 1598.31
+                    "y": 1623.38
                 }, 
                 {
                     "x": 256, 
-                    "y": 3259.53
+                    "y": 3244.48
                 }
             ], 
             "name": "Redis 2.8.19", 
             "type": "line"
         }, 
         {
+            "color": "#2f7ed8", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 239.51
+                    "y": 225.17
                 }, 
                 {
                     "x": 16, 
-                    "y": 308.28
+                    "y": 293.7
                 }, 
                 {
                     "x": 32, 
-                    "y": 383.94
+                    "y": 389.23
                 }, 
                 {
                     "x": 64, 
-                    "y": 704.85
+                    "y": 659.72
                 }, 
                 {
                     "x": 128, 
-                    "y": 1399.2
+                    "y": 1200.99
                 }, 
                 {
                     "x": 256, 
-                    "y": 2805.02
+                    "y": 2356.8
                 }
             ], 
-            "name": "Tarantool (TREE, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (TREE, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }, 
         {
+            "color": "#8bbc21", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 262.22
+                    "y": 228.37
                 }, 
                 {
                     "x": 16, 
-                    "y": 341.01
+                    "y": 312.93
                 }, 
                 {
                     "x": 32, 
-                    "y": 494.61
+                    "y": 403.93
                 }, 
                 {
                     "x": 64, 
-                    "y": 998.86
+                    "y": 676.18
                 }, 
                 {
                     "x": 128, 
-                    "y": 1987.73
+                    "y": 1349.59
                 }, 
                 {
                     "x": 256, 
-                    "y": 4039.56
+                    "y": 2774.49
                 }
             ], 
-            "name": "Tarantool (HASH, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (HASH, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }
     ], 
diff --git a/doc/www/content/ycsb/D_throughput.json b/doc/www/content/ycsb/D_throughput.json
index d6b148dd9ccba88fa30d306427b950e8d14237ff..f0239d714fbdb3ad6203d5303daf29df85d9a620 100644
--- a/doc/www/content/ycsb/D_throughput.json
+++ b/doc/www/content/ycsb/D_throughput.json
@@ -6,93 +6,96 @@
     "legend": {}, 
     "series": [
         {
+            "color": "#0d233a", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 27651.545
+                    "y": 27198.606
                 }, 
                 {
                     "x": 16, 
-                    "y": 42334.148
+                    "y": 42223.887
                 }, 
                 {
                     "x": 32, 
-                    "y": 69058.03
+                    "y": 68327.403
                 }, 
                 {
                     "x": 64, 
-                    "y": 75974.498
+                    "y": 75135.152
                 }, 
                 {
                     "x": 128, 
-                    "y": 74659.092
+                    "y": 73590.408
                 }, 
                 {
                     "x": 256, 
-                    "y": 73506.81
+                    "y": 73978.39
                 }
             ], 
             "name": "Redis 2.8.19", 
             "type": "line"
         }, 
         {
+            "color": "#2f7ed8", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 28808.773
+                    "y": 29905.066
                 }, 
                 {
                     "x": 16, 
-                    "y": 47085.67
+                    "y": 49494.828
                 }, 
                 {
                     "x": 32, 
-                    "y": 79941.384
+                    "y": 78919.769
                 }, 
                 {
                     "x": 64, 
-                    "y": 89276.877
+                    "y": 90182.796
                 }, 
                 {
                     "x": 128, 
-                    "y": 90329.51
+                    "y": 97636.591
                 }, 
                 {
                     "x": 256, 
-                    "y": 89717.039
+                    "y": 98765.799
                 }
             ], 
-            "name": "Tarantool (TREE, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (TREE, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }, 
         {
+            "color": "#8bbc21", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 26632.372
+                    "y": 29023.419
                 }, 
                 {
                     "x": 16, 
-                    "y": 42997.674
+                    "y": 46679.054
                 }, 
                 {
                     "x": 32, 
-                    "y": 62493.662
+                    "y": 75973.644
                 }, 
                 {
                     "x": 64, 
-                    "y": 63408.932
+                    "y": 93025.514
                 }, 
                 {
                     "x": 128, 
-                    "y": 63939.276
+                    "y": 93688.949
                 }, 
                 {
                     "x": 256, 
-                    "y": 62785.577
+                    "y": 90518.76
                 }
             ], 
-            "name": "Tarantool (HASH, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (HASH, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }
     ], 
diff --git a/doc/www/content/ycsb/E_INSERT_latency.json b/doc/www/content/ycsb/E_INSERT_latency.json
index 2dd8010334942743260684ba3ea4aaab56c5774b..e65959630e4da6f80c3402932eedc741bc3e74d1 100644
--- a/doc/www/content/ycsb/E_INSERT_latency.json
+++ b/doc/www/content/ycsb/E_INSERT_latency.json
@@ -6,63 +6,65 @@
     "legend": {}, 
     "series": [
         {
+            "color": "#0d233a", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 619.47
+                    "y": 597.75
                 }, 
                 {
                     "x": 16, 
-                    "y": 780.09
+                    "y": 785.29
                 }, 
                 {
                     "x": 32, 
-                    "y": 1003.09
+                    "y": 1005.3
                 }, 
                 {
                     "x": 64, 
-                    "y": 1870.34
+                    "y": 1893.66
                 }, 
                 {
                     "x": 128, 
-                    "y": 3756.31
+                    "y": 3655.0
                 }, 
                 {
                     "x": 256, 
-                    "y": 6354.63
+                    "y": 7133.25
                 }
             ], 
             "name": "Redis 2.8.19", 
             "type": "line"
         }, 
         {
+            "color": "#2f7ed8", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 311.51
+                    "y": 271.73
                 }, 
                 {
                     "x": 16, 
-                    "y": 305.95
+                    "y": 284.38
                 }, 
                 {
                     "x": 32, 
-                    "y": 317.73
+                    "y": 294.93
                 }, 
                 {
                     "x": 64, 
-                    "y": 322.43
+                    "y": 296.21
                 }, 
                 {
                     "x": 128, 
-                    "y": 324.71
+                    "y": 311.41
                 }, 
                 {
                     "x": 256, 
-                    "y": 353.2
+                    "y": 352.28
                 }
             ], 
-            "name": "Tarantool (TREE, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (TREE, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }
     ], 
@@ -88,4 +90,4 @@
             "text": "Latency(usec)"
         }
     }
-}
+}
\ No newline at end of file
diff --git a/doc/www/content/ycsb/E_SCAN_latency.json b/doc/www/content/ycsb/E_SCAN_latency.json
index 24c7c677eceffe8d80276e4fbd426bae6e523cf9..fa65ecd28470cbe7e4f32ceed996748e5f97b94c 100644
--- a/doc/www/content/ycsb/E_SCAN_latency.json
+++ b/doc/www/content/ycsb/E_SCAN_latency.json
@@ -6,34 +6,66 @@
     "legend": {}, 
     "series": [
         {
+            "color": "#0d233a", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 12647.3
+                    "y": 12604.61
                 }, 
                 {
                     "x": 16, 
-                    "y": 17509.19
+                    "y": 17581.77
                 }, 
                 {
                     "x": 32, 
-                    "y": 23218.92
+                    "y": 23121.94
                 }, 
                 {
                     "x": 64, 
-                    "y": 43893.15
+                    "y": 44215.36
                 }, 
                 {
                     "x": 128, 
-                    "y": 90066.49
+                    "y": 87342.63
                 }, 
                 {
                     "x": 256, 
-                    "y": 156887.52
+                    "y": 176624.64
                 }
             ], 
             "name": "Redis 2.8.19", 
             "type": "line"
+        }, 
+        {
+            "color": "#2f7ed8", 
+            "data": [
+                {
+                    "x": 8, 
+                    "y": 858.28
+                }, 
+                {
+                    "x": 16, 
+                    "y": 1818.22
+                }, 
+                {
+                    "x": 32, 
+                    "y": 3752.74
+                }, 
+                {
+                    "x": 64, 
+                    "y": 7428.16
+                }, 
+                {
+                    "x": 128, 
+                    "y": 15037.42
+                }, 
+                {
+                    "x": 256, 
+                    "y": 31995.84
+                }
+            ], 
+            "name": "Tarantool (TREE, 1.6.4-564-ge6e1429)", 
+            "type": "line"
         }
     ], 
     "subtitle": {
@@ -58,4 +90,4 @@
             "text": "Latency(usec)"
         }
     }
-}
+}
\ No newline at end of file
diff --git a/doc/www/content/ycsb/E_throughput.json b/doc/www/content/ycsb/E_throughput.json
index a9f13414029e94978379c61a1a58150ed6edb2bc..78efa21b760a70a30a454e28acd7167690c4874c 100644
--- a/doc/www/content/ycsb/E_throughput.json
+++ b/doc/www/content/ycsb/E_throughput.json
@@ -6,63 +6,65 @@
     "legend": {}, 
     "series": [
         {
+            "color": "#0d233a", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 580.348
+                    "y": 569.539
                 }, 
                 {
                     "x": 16, 
-                    "y": 895.467
+                    "y": 893.546
                 }, 
                 {
                     "x": 32, 
-                    "y": 1409.266
+                    "y": 1421.844
                 }, 
                 {
                     "x": 64, 
-                    "y": 1501.626
+                    "y": 1491.228
                 }, 
                 {
                     "x": 128, 
-                    "y": 1465.921
+                    "y": 1512.563
                 }, 
                 {
                     "x": 256, 
-                    "y": 1462.514
+                    "y": 1493.221
                 }
             ], 
             "name": "Redis 2.8.19", 
             "type": "line"
         }, 
         {
+            "color": "#2f7ed8", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 8345.315
+                    "y": 9299.282
                 }, 
                 {
                     "x": 16, 
-                    "y": 8649.963
+                    "y": 8976.991
                 }, 
                 {
                     "x": 32, 
-                    "y": 8585.98
+                    "y": 8780.54
                 }, 
                 {
                     "x": 64, 
-                    "y": 8432.671
+                    "y": 8871.066
                 }, 
                 {
                     "x": 128, 
-                    "y": 8460.972
+                    "y": 8740.354
                 }, 
                 {
                     "x": 256, 
-                    "y": 7924.404
+                    "y": 8195.7
                 }
             ], 
-            "name": "Tarantool (TREE, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (TREE, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }
     ], 
@@ -88,4 +90,4 @@
             "text": "RPS"
         }
     }
-}
+}
\ No newline at end of file
diff --git a/doc/www/content/ycsb/F_READ-MODIFY-WRITE_latency.json b/doc/www/content/ycsb/F_READ-MODIFY-WRITE_latency.json
index 710034be20f73f45a47925724f68a3062bea339e..29a89411c84fb3a7f9ac4fd5e6a17a98f983127f 100644
--- a/doc/www/content/ycsb/F_READ-MODIFY-WRITE_latency.json
+++ b/doc/www/content/ycsb/F_READ-MODIFY-WRITE_latency.json
@@ -6,93 +6,96 @@
     "legend": {}, 
     "series": [
         {
+            "color": "#0d233a", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 459.03
+                    "y": 463.27
                 }, 
                 {
                     "x": 16, 
-                    "y": 638.04
+                    "y": 646.42
                 }, 
                 {
                     "x": 32, 
-                    "y": 803.07
+                    "y": 847.48
                 }, 
                 {
                     "x": 64, 
-                    "y": 1616.46
+                    "y": 1675.71
                 }, 
                 {
                     "x": 128, 
-                    "y": 3401.07
+                    "y": 3452.37
                 }, 
                 {
                     "x": 256, 
-                    "y": 6862.11
+                    "y": 6854.32
                 }
             ], 
             "name": "Redis 2.8.19", 
             "type": "line"
         }, 
         {
+            "color": "#2f7ed8", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 395.41
+                    "y": 330.44
                 }, 
                 {
                     "x": 16, 
-                    "y": 503.29
+                    "y": 426.8
                 }, 
                 {
                     "x": 32, 
-                    "y": 998.46
+                    "y": 548.74
                 }, 
                 {
                     "x": 64, 
-                    "y": 1972.22
+                    "y": 1089.92
                 }, 
                 {
                     "x": 128, 
-                    "y": 3956.45
+                    "y": 2193.52
                 }, 
                 {
                     "x": 256, 
-                    "y": 8078.09
+                    "y": 4500.88
                 }
             ], 
-            "name": "Tarantool (TREE, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (TREE, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }, 
         {
+            "color": "#8bbc21", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 398.2
+                    "y": 359.62
                 }, 
                 {
                     "x": 16, 
-                    "y": 492.26
+                    "y": 456.5
                 }, 
                 {
                     "x": 32, 
-                    "y": 1006.59
+                    "y": 668.11
                 }, 
                 {
                     "x": 64, 
-                    "y": 2010.05
+                    "y": 1378.99
                 }, 
                 {
                     "x": 128, 
-                    "y": 4008.02
+                    "y": 2737.57
                 }, 
                 {
                     "x": 256, 
-                    "y": 8093.19
+                    "y": 5557.44
                 }
             ], 
-            "name": "Tarantool (HASH, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (HASH, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }
     ], 
diff --git a/doc/www/content/ycsb/F_READ_latency.json b/doc/www/content/ycsb/F_READ_latency.json
index 3dea857070c1f0f6af8f9c3e9a016c2f0aca953f..1d42ef57f517636147a54de13e60f9d05a5289de 100644
--- a/doc/www/content/ycsb/F_READ_latency.json
+++ b/doc/www/content/ycsb/F_READ_latency.json
@@ -6,93 +6,96 @@
     "legend": {}, 
     "series": [
         {
+            "color": "#0d233a", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 234.58
+                    "y": 238.27
                 }, 
                 {
                     "x": 16, 
-                    "y": 321.65
+                    "y": 326.03
                 }, 
                 {
                     "x": 32, 
-                    "y": 406.11
+                    "y": 428.58
                 }, 
                 {
                     "x": 64, 
-                    "y": 813.29
+                    "y": 842.29
                 }, 
                 {
                     "x": 128, 
-                    "y": 1705.28
+                    "y": 1728.37
                 }, 
                 {
                     "x": 256, 
-                    "y": 3431.76
+                    "y": 3424.16
                 }
             ], 
             "name": "Redis 2.8.19", 
             "type": "line"
         }, 
         {
+            "color": "#2f7ed8", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 193.35
+                    "y": 159.7
                 }, 
                 {
                     "x": 16, 
-                    "y": 245.7
+                    "y": 206.56
                 }, 
                 {
                     "x": 32, 
-                    "y": 494.63
+                    "y": 269.29
                 }, 
                 {
                     "x": 64, 
-                    "y": 981.15
+                    "y": 539.33
                 }, 
                 {
                     "x": 128, 
-                    "y": 1970.92
+                    "y": 1086.72
                 }, 
                 {
                     "x": 256, 
-                    "y": 4030.48
+                    "y": 2231.25
                 }
             ], 
-            "name": "Tarantool (TREE, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (TREE, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }, 
         {
+            "color": "#8bbc21", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 194.34
+                    "y": 174.48
                 }, 
                 {
                     "x": 16, 
-                    "y": 239.98
+                    "y": 221.86
                 }, 
                 {
                     "x": 32, 
-                    "y": 498.63
+                    "y": 329.54
                 }, 
                 {
                     "x": 64, 
-                    "y": 1000.1
+                    "y": 684.31
                 }, 
                 {
                     "x": 128, 
-                    "y": 1997.12
+                    "y": 1360.1
                 }, 
                 {
                     "x": 256, 
-                    "y": 4034.72
+                    "y": 2762.7
                 }
             ], 
-            "name": "Tarantool (HASH, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (HASH, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }
     ], 
diff --git a/doc/www/content/ycsb/F_UPDATE_latency.json b/doc/www/content/ycsb/F_UPDATE_latency.json
index d590d86e03e6cd097cdb447216b8a7f434655f39..7a4394f09a24b9f06040a5df5f4bea43e67829f0 100644
--- a/doc/www/content/ycsb/F_UPDATE_latency.json
+++ b/doc/www/content/ycsb/F_UPDATE_latency.json
@@ -6,93 +6,96 @@
     "legend": {}, 
     "series": [
         {
+            "color": "#0d233a", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 221.44
+                    "y": 221.68
                 }, 
                 {
                     "x": 16, 
-                    "y": 312.63
+                    "y": 316.53
                 }, 
                 {
                     "x": 32, 
-                    "y": 392.26
+                    "y": 414.07
                 }, 
                 {
                     "x": 64, 
-                    "y": 795.46
+                    "y": 826.63
                 }, 
                 {
                     "x": 128, 
-                    "y": 1681.44
+                    "y": 1708.21
                 }, 
                 {
                     "x": 256, 
-                    "y": 3400.16
+                    "y": 3397.42
                 }
             ], 
             "name": "Redis 2.8.19", 
             "type": "line"
         }, 
         {
+            "color": "#2f7ed8", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 198.21
+                    "y": 166.96
                 }, 
                 {
                     "x": 16, 
-                    "y": 253.66
+                    "y": 215.97
                 }, 
                 {
                     "x": 32, 
-                    "y": 500.29
+                    "y": 275.58
                 }, 
                 {
                     "x": 64, 
-                    "y": 986.68
+                    "y": 544.1
                 }, 
                 {
                     "x": 128, 
-                    "y": 1976.95
+                    "y": 1091.6
                 }, 
                 {
                     "x": 256, 
-                    "y": 4034.2
+                    "y": 2234.85
                 }
             ], 
-            "name": "Tarantool (TREE, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (TREE, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }, 
         {
+            "color": "#8bbc21", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 200.15
+                    "y": 181.14
                 }, 
                 {
                     "x": 16, 
-                    "y": 248.21
+                    "y": 230.36
                 }, 
                 {
                     "x": 32, 
-                    "y": 504.48
+                    "y": 334.89
                 }, 
                 {
                     "x": 64, 
-                    "y": 1005.67
+                    "y": 689.19
                 }, 
                 {
                     "x": 128, 
-                    "y": 2003.32
+                    "y": 1365.42
                 }, 
                 {
                     "x": 256, 
-                    "y": 4040.07
+                    "y": 2766.05
                 }
             ], 
-            "name": "Tarantool (HASH, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (HASH, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }
     ], 
diff --git a/doc/www/content/ycsb/F_throughput.json b/doc/www/content/ycsb/F_throughput.json
index 31c92d8f984bd0bd72142823f2772da3da78086a..133cf993da94ad9d34260b5b9a7d46a8649ddf3b 100644
--- a/doc/www/content/ycsb/F_throughput.json
+++ b/doc/www/content/ycsb/F_throughput.json
@@ -6,93 +6,96 @@
     "legend": {}, 
     "series": [
         {
+            "color": "#0d233a", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 20258.78
+                    "y": 20176.315
                 }, 
                 {
                     "x": 16, 
-                    "y": 31493.762
+                    "y": 30970.398
                 }, 
                 {
                     "x": 32, 
-                    "y": 51212.408
+                    "y": 48598.597
                 }, 
                 {
                     "x": 64, 
-                    "y": 51876.851
+                    "y": 49943.616
                 }, 
                 {
                     "x": 128, 
-                    "y": 49399.004
+                    "y": 48719.857
                 }, 
                 {
                     "x": 256, 
-                    "y": 49151.876
+                    "y": 49244.651
                 }
             ], 
             "name": "Redis 2.8.19", 
             "type": "line"
         }, 
         {
+            "color": "#2f7ed8", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 25019.921
+                    "y": 29521.74
                 }, 
                 {
                     "x": 16, 
-                    "y": 40993.359
+                    "y": 47992.147
                 }, 
                 {
                     "x": 32, 
-                    "y": 42311.419
+                    "y": 76225.974
                 }, 
                 {
                     "x": 64, 
-                    "y": 43051.195
+                    "y": 77599.478
                 }, 
                 {
                     "x": 128, 
-                    "y": 42910.444
+                    "y": 77191.581
                 }, 
                 {
                     "x": 256, 
-                    "y": 42003.284
+                    "y": 75095.998
                 }
             ], 
-            "name": "Tarantool (TREE, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (TREE, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }, 
         {
+            "color": "#8bbc21", 
             "data": [
                 {
                     "x": 8, 
-                    "y": 25113.338
+                    "y": 27194.077
                 }, 
                 {
                     "x": 16, 
-                    "y": 41810.641
+                    "y": 44936.537
                 }, 
                 {
                     "x": 32, 
-                    "y": 41984.073
+                    "y": 62744.686
                 }, 
                 {
                     "x": 64, 
-                    "y": 42242.509
+                    "y": 61460.56
                 }, 
                 {
                     "x": 128, 
-                    "y": 42338.889
+                    "y": 61952.441
                 }, 
                 {
                     "x": 256, 
-                    "y": 41935.18
+                    "y": 60938.137
                 }
             ], 
-            "name": "Tarantool (HASH, 1.6.4-510-g9d9f76d)", 
+            "name": "Tarantool (HASH, 1.6.4-564-ge6e1429)", 
             "type": "line"
         }
     ], 
diff --git a/doc/www/theme/static/docbook.css b/doc/www/theme/static/docbook.css
deleted file mode 100644
index d2fe22e9eb230662f7f3b2c73d3ffb6d10e7577c..0000000000000000000000000000000000000000
--- a/doc/www/theme/static/docbook.css
+++ /dev/null
@@ -1,89 +0,0 @@
-.tntadmin {
-    font-family: monospace;
-    font-weight: bold;
-    text-transform: uppercase;
-    color: green;
-}
-
-.lua {
-    font-family: monospace;
-    font-weight: bold;
-}
-
-strong.hl-keyword {
-    color: green !important;
-    font-weight: bold;
-}
-
-em.hl-comment {
-    color: #3366FF !important;
-    font-weight: normal;
-}
-
-strong.hl-string em {
-    color: red !important;
-    font-weight: bold;
-}
-
-body {
-    min-width: 768px;
-    max-width: 1024px;
-    margin: auto;
-}
-
-.book {
-    margin: 2pt auto;
-    font-size: 100%
-}
-
-.book h1 {
-    font-size: 150%
-}
-
-pre {
-    white-space: pre;
-    white-space: pre-wrap;
-    word-wrap: break-word;
-    text-decoration: none;
-    outline: 0;
-    padding: 5px;
-    background-color: rgba(0,0,0,0.1);
-    -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.3);
-    -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.3);
-    box-shadow: 0 1px 3px rgba(0,0,0,0.3);
-}
-
-div.toc dl{
-    margin-top: 0px;
-}
-
-div.itemizedlist ul li p{
-    margin: 4px;
-}
-
-div#header {
-    display: block;
-}
-
-div#content {
-    border-top:    1px dotted black;
-}
-
-div#headwrap {
-    width: 100%;
-}
-
-div.column {
-    display: inline-block;
-}
-
-div#headl {
-    float: left;
-    width: 30%;
-}
-
-div#headr {
-    float: right;
-    width: 69%;
-    text-align: right
-}
diff --git a/doc/www/theme/static/old_global.css b/doc/www/theme/static/old_global.css
deleted file mode 100644
index 781768112a00a318575533a63ef08f9e531d0b1a..0000000000000000000000000000000000000000
--- a/doc/www/theme/static/old_global.css
+++ /dev/null
@@ -1,355 +0,0 @@
-/* This stylesheet heavily borrows from http://necolas.github.com/normalize.css */
-
-/* =============================================================================
-   Base
-   ========================================================================== */
-
-/*
- * 1. Corrects text resizing oddly in IE6/7 when body font-size is set using em units
- *    http://clagnut.com/blog/348/#c790
- * 2. Keeps page centred in all browsers regardless of content height
- * 3. Prevents iOS text size adjust after orientation change, without disabling user zoom
- *    www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/
- */
-
-html {
-    font-size: 100%; /* 1 */
-    overflow-y: scroll; /* 2 */
-    -webkit-text-size-adjust: 100%; /* 3 */
-    -ms-text-size-adjust: 100%; /* 3 */
-}
-
-/*
- * Addresses margins handled incorrectly in IE6/7
- */
-
-body {
-    margin: 0;
-}
-
-/* =============================================================================
-   Typography
-   ========================================================================== */
-
-/*
- * Neutralise smaller font-size in 'section' and 'article' in FF4+, Chrome, S5
- */
-
-h1 {
-    font-size: 1.5em;
-}
-
-/*
- * Addresses style set to 'bolder' in FF3+, S4/5, Chrome
- */
-
-b, strong {
-    font-weight: bold;
-}
-
-blockquote {
-    margin: 1em 40px;
-}
-
-/*
- * Corrects font family set oddly in IE6, S4/5, Chrome
- * en.wikipedia.org/wiki/User:Davidgothberg/Test59
- */
-
-pre, code, kbd, samp {
-    font-family: monospace, serif;
-    _font-family: 'courier new', monospace;
-    font-size: 100%;
-}
-
-
-/*
- * Improves readability of pre-formatted text in all browsers
- */
-
-pre {
-    white-space: pre;
-    white-space: pre-wrap;
-    word-wrap: break-word;
-    text-decoration: none;
-    outline: 0;
-    background-color: rgba(0,0,0,0.1);
-    -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.3);
-    -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.3);
-    box-shadow: 0 1px 3px rgba(0,0,0,0.3);
-}
-
-/*
- * 1. Addresses CSS quotes not supported in IE6/7
- * 2. Addresses quote property not supported in S4
- */
-
-/* 1 */
-
-q {
-    quotes: none;
-}
-
-/* 2 */
-
-q:before,
-q:after {
-    content: '';
-    content: none;
-}
-
-/*
- * XXX
- */
-
-small {
-    font-size: 75%;
-}
-
-/*
- * Prevents sub and sup affecting line-height in all browsers
- * gist.github.com/413930
- */
-
-sub, sup {
-    font-size: 75%;
-    line-height: 0;
-    position: relative;
-    vertical-align: baseline;
-}
-
-sup {
-    top: -0.5em;
-}
-
-sub {
-    bottom: -0.25em;
-}
-
-
-/* =============================================================================
-   Lists
-   ========================================================================== */
-
-ul, ol {
-    margin-left: 0;
-    padding: 0 0 0 40px;
-}
-
-dd {
-    margin: 0 0 0 40px;
-}
-
-
-/* =============================================================================
-   Embedded content
-   ========================================================================== */
-
-/*
- * 1. Removes border when inside 'a' element in IE6/7/8/9, FF3
- * 2. Improves image quality when scaled in IE7
- *    code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/
- */
-
-img {
-    border: 0; /* 1 */
-    -ms-interpolation-mode: bicubic; /* 2 */
-}
-
-.ycsb {
-    width: 768px;
-}
-
-/* =============================================================================
-   Tables
-   ========================================================================== */
-
-/*
- * Remove most spacing between table cells
- */
-
-table {
-    border-collapse: collapse;
-    border-spacing: 0;
-}
-
-/* ==========================================================================
-   Grid
-   ======================================================================== */
-
-.grid {
-    width: 768px;
-    overflow: hidden;
-    margin-left: auto;
-    margin-right: auto;
-    padding: 0 10px 0 0;
-    -moz-border-radius: 3px;
-    -webkit-border-radius: 3px;
-    border-radius: 3px;
-    clear: both;
-}
-
-.span_1, .span_2, .span_3, .span_4, .span_5, .span_6,
-.span_7, .span_8, .span_9, .span_10, .span_11, .span_12 {
-    float: left;
-    dsiplay: inline; /* IE workaround */
-    margin-left: 10px;
-}
-
-.span_1 { width: 70px; }
-.span_2 { width: 150px; }
-.span_3 { width: 230px; }
-.span_4 { width: 303px; }
-.span_5 { width: 390px; }
-.span_6 { width: 470px; }
-.span_7 { width: 550px; }
-.span_8 { width: 630px; }
-.span_9 { width: 710px; }
-.span_10 { width: 790px; }
-.span_11 { width: 870px; }
-.span_12 { width: 950px; }
-
-.lpad_1 { padding-left: 80px; }
-.lpad_2 { padding-left: 160px; }
-.lpad_3 { padding-left: 240px; }
-.lpad_4 { padding-left: 320px; }
-.lpad_5 { padding-left: 400px; }
-.lpad_6 { padding-left: 480px; }
-.lpad_7 { padding-left: 560px; }
-.lpad_8 { padding-left: 640px; }
-.lpad_9 { padding-left: 720px; }
-.lpad_10 { padding-left: 800px; }
-.lpad_11 { padding-left: 880px; }
-
-.rpad_1 { padding-right: 80px; }
-.rpad_2 { padding-right: 160px; }
-.rpad_3 { padding-right: 240px; }
-.rpad_4 { padding-right: 320px; }
-.rpad_5 { padding-right: 400px; }
-.rpad_6 { padding-right: 480px; }
-.rpad_7 { padding-right: 560px; }
-.rpad_8 { padding-right: 640px; }
-.rpad_9 { padding-right: 720px; }
-.rpad_10 { padding-right: 800px; }
-.rpad_11 { padding-right: 880px; }
-
-
-/* =============================================================================
-   Custom styles
-   ========================================================================== */
-
-html, body{
-    width: 768px;
-    margin: auto;
-}
-
-/* =============================================================================
-   Styles for tabs and buttons used in benchmark*.html
-   ========================================================================== */
-
-.b-schedule{
-    height: 100%;
-    width: 768px;
-    margin:0 auto;
-    padding: 0;
-}
-
-.header{
-    font-size: 2em;
-    line-height: 1;
-    text-align: center;
-    margin: 40 auto;
-}
-
-.b-tabs{
-    height: 100%;
-}
-.b-tabs__list{
-    padding: 0px;
-    list-style: none;
-    border: 1px solid #b2b2b2;
-    border-bottom: 0;
-    -webkit-border-radius: 5px 5px 0 0;
-    -moz-border-radius: 5px 5px 0 0;
-    border-radius: 5px 5px 0 0;
-    -webkit-user-select: none;
-    box-shadow: 0 2px 4px -3px #000;
-    -webkit-padding-start: 0;
-    background-color: #f5f5f5;
-    -webkit-padding-start: 0;
-    overflow: hidden;
-    margin: 0;
-}
-.b-tabs__li{
-    float: left;
-    padding: 10px;
-    cursor: pointer;
-    border-right: 1px solid #b2b2b2;
-}
-.b-tabs__li:last-child{
-    border-right: none;
-}
-.b-tabs__li_on, .b-tabs__li:active{
-    background-color: #fafafa;
-    padding: 11px 9px 9px 11px;
-    color: #3f3f3f;
-}
-.b-tabs__body{
-    position: relative;
-    padding: 20px;
-    height: 980px;
-    border: 2px solid black;
-}
-#picture1, #picture2{
-    min-width: 400px;
-    margin: 0 auto;
-}
-.b-tabs__buttons{
-    padding: 0;
-    right: 20px;
-    border: 2px solid #b2b2b2;
-    -webkit-border-radius: 5px;
-    -moz-border-radius: 5px;
-    border-radius: 5px;
-    -webkit-user-select: none;
-    box-shadow: 0 2px 4px -3px #000;
-    -webkit-padding-start: 0;
-    background-color: #eaeaea;
-    outline: none;
-    cursor: pointer;
-    list-style: none;
-    float: right;
-}
-.b-button{
-    float: left;
-    margin: 0;
-    padding: 3px;
-    border-right: 1px solid #b2b2b2;
-    font-size: medium;
-}
-.b-button:last-child{
-    border: none;
-}
-.b-button_on, .b-button:active{
-    background-color: #fafafa;
-    padding: 4px 2px 3px 4px;
-    color: #3f3f3f;
-}
-
-h3 {
-    text-align:center;
-}
-
-/*
- * Disable current link in header, when we are on current page
- */
-
-body#tarantool.index #header #blurb h1 a.index,
-body#tarantool.intro #header #blurb h3 a.intro,
-body#tarantool.documentation #header #blurb h3 a.documentation,
-body#tarantool.download #header #blurb h3 a.download,
-body#tarantool.support #header #blurb h3 a.support {
-    pointer-events: none;
-    cursor: default;
-    text-decoration: none;
-}
diff --git a/doc/www/theme/static/old_header.css b/doc/www/theme/static/old_header.css
deleted file mode 100644
index 22ad82701c83ce70185c6e4f121f5c4eedf46855..0000000000000000000000000000000000000000
--- a/doc/www/theme/static/old_header.css
+++ /dev/null
@@ -1,142 +0,0 @@
-#header, #content{
-    background-color: #fff;
-}
-
-#content {
-    padding-bottom: 5px;
-}
-
-#blurb {
-    margin: 20px auto;
-}
-
-#blurb h1 {
-    font-size: 2em;
-    line-height: 1;
-    text-align: center;
-    margin: 15px;
-}
-
-#blurb h2 {
-    font-size: 1.2em;
-    font-weight: normal;
-    line-height: 1;
-    text-align: center;
-    margin: 5px;
-}
-
-#blurb h3 {
-    text-align: center;
-    margin: 5px;
-}
-
-/* ===========================================================================
-   Layout
-   ======================================================================== */
-
-/*
- * Top-level page sections:
- * body > #header #content
- */
-
-#header, #content {
-    width: 100%;
-    margin: 0px auto;
-    padding: 0px;
-    overflow: hidden;
-}
-
-#header {
-   margin-bottom: 5px;
-}
-/*
- * http://sonspring.com/journal/clearing-floats
- */
-
-.clear {
-  clear: both;
-  display: block;
-  visibility: hidden;
-  width: 0;
-  height: 0;
-}
-
-/* -- relbar ---------------------------------------------------------------- */
-
-div.related {
-    width: 100%;
-    font-size: 90%;
-}
-
-div.related h3 {
-    display: none;
-}
-
-div.related ul {
-    margin: 0;
-    padding: 0 0 0 10px;
-    list-style: none;
-}
-
-div.related li {
-    display: inline;
-}
-
-div.related li.right {
-    float: right;
-    margin-right: 5px;
-}
-
-div.related li.center {
-    float: center;
-    margin-right: 5px;
-}
-
-
-/* =============================================================================
-   Links
-   ========================================================================== */
-a {
-    color: #201e9e;
-}
-
-/*
- * Addresses outline displayed oddly in Chrome
- */
-
-a:focus {
-    outline: thin dotted;
-}
-
-/*
- * Improves readability when focused and also mouse hovered in all browsers
- * people.opera.com/patrickl/experiments/keyboard/test
- */
-
-a:active {
-    outline: 0;
-}
-
-a:hover {
-    outline: 0;
-    background-color: rgba(0,0,0,0.1);
-    -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.3);
-    -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.3);
-    box-shadow: 0 1px 3px rgba(0,0,0,0.3);
-}
-
-a.imglink:hover {
-    border : 0;
-    background-color: inherit;
-    -moz-box-shadow: none;
-    -webkit-box-shadow: none;
-    box-shadow: none;
-}
-
-a:visited {
-    color: #3f3f3f;
-}
-
-body {
-    margin-bottom: 100px;
-}
diff --git a/doc/www/theme/templates/documentation.html b/doc/www/theme/templates/documentation.html
deleted file mode 100644
index 195d1dfc065532f34092d2d83761c204bf30a7ae..0000000000000000000000000000000000000000
--- a/doc/www/theme/templates/documentation.html
+++ /dev/null
@@ -1,37 +0,0 @@
-{% extends "base" %}
-
-{% block header_scripts %}
-{% endblock header_scripts %}
-
-{% block content %}
-<section class="b-lightgray_block b-documentation_top b-clearbox">
-  <div class="b-block-wrapper">
-    <h2 class="b-section-title">Documentation</h2>
-    <!--div class="b-search">
-      <input class="b-search-text" data-placeholder="Search in documentation" />
-      <input class="b-search-but" type="submit" />
-    </div-->
-  </div>
-</section>
-
-<section class="b-block b-tcontents">
-  <div class="b-block-wrapper">
-    <ul class="b-tcontents-list">
-      {% for item in page.blocks.sections %}
-      <li class="b-tcontents-list-item">
-        <h2 class="b-tcontents-list-item-title">{{ item.name }}</h2>
-        <ul class="b-tcontents-sublist">
-          {% for itemli in item.list %}
-          <li class="b-tcontents-sublist-item">
-            <a href="{{ itemli.link }}">{{ itemli.name }}</a>
-          </li>
-          {% endfor %}
-        </ul>
-      </li>
-      {% endfor %}
-    </ul>
-  </div>
-</section>
-{% endblock content %}
-
-{# vim: syntax=htmldjango ts=2 sts=2 sw=2 expandtab #}
diff --git a/doc/www/theme/templates/documentation_rst.html b/doc/www/theme/templates/documentation_rst.html
deleted file mode 100644
index f7d4bab57b0ddac7d5922835dd10d0ce7dfcbde0..0000000000000000000000000000000000000000
--- a/doc/www/theme/templates/documentation_rst.html
+++ /dev/null
@@ -1,46 +0,0 @@
-{% extends "base" %}
-
-{% block header_scripts %}
-<script src="js/main.js"></script>
-{% endblock header_scripts %}
-
-{% block content %}
-<section class="b-lightgray_block b-documentation_top b-clearbox p-documentation_in">
-  <div class="b-block-wrapper">
-    <h2 class="b-section-title">Documentation</h2>
-    <!--div class="b-search">
-      <input class="b-search-text" data-placeholder="Search in documentation" />
-      <input class="b-search-but" type="submit" />
-    </div-->
-  </div>
-</section>
-
-<div class="b-cols_content b-clearbox">
-  <!--div class="b-cols_content_left">
-    <ul class="b-tcontents_full-list">
-      <li class="b-tcontents_full-list-item p-active">
-        <h2 class="b-tcontents_full-list-item-title">
-          {# number #}<a href="{# link #}">{# name #}</a>
-        </h2>
-        <p class="b-tcontents_full-list-item-disc">{# text #}</p>
-        <ul class="b-tcontents_full-sublist">
-          <li class="b-tcontents_full-sublist-item">
-            {# number #}<a href="{# link #}">{# name #}</a>
-          </li>
-        </ul>
-      </li>
-    </ul>
-  </div-->
-  <div class="b-cols_content_left">
-  </div>
-  <div class="b-cols_content_right">
-    <div class="b-cols_content_right-slot">
-      <article class="b-article">
-        {{ page.content }}
-      </article>
-    </div>
-  </div>
-</div>
-{% endblock %}
-
-{# vim: syntax=htmldjango ts=2 sts=2 sw=2 expandtab #}
diff --git a/doc/www/theme/templates/old_base b/doc/www/theme/templates/old_base
deleted file mode 100644
index 1b814a03124e8927d5fb175328026fd0d9c9e571..0000000000000000000000000000000000000000
--- a/doc/www/theme/templates/old_base
+++ /dev/null
@@ -1,22 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-  <head>
-    <title>{{ title }}</title>
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-    <link rel="shortcut icon" href="/theme/favicon.ico" />
-    {% if not documentation %}
-    <link rel="stylesheet" type="text/css" href="/theme/old_global.css" />
-    <link rel="stylesheet" type="text/css" href="/theme/pygmentize.css" />
-    {% endif %}
-    <link rel="stylesheet" type="text/css" href="/theme/old_header.css">
-    {% include "script" ignore missing %}
-  </head>
-  <body id="tarantool" {% if page %} class ="{{ page.slug }}" {% endif %}>
-    <div id="content">
-      {% block content %}
-      {% endblock content %}
-    </div>
-  </body>
-</html>
-
-{# vim: syntax=htmldjango ts=2 sts=2 sw=2 expandtab #}
diff --git a/doc/www/theme/templates/old_documentation.html b/doc/www/theme/templates/old_documentation.html
deleted file mode 100644
index 7ee4830249d895f2356116bc2658080f10d00306..0000000000000000000000000000000000000000
--- a/doc/www/theme/templates/old_documentation.html
+++ /dev/null
@@ -1,7 +0,0 @@
-{% extends "old_base" %}
-{% set title = page.title %}
-{% block content %}
-  {{ page.content }}
-{% endblock content %}
-
-{# vim: syntax=htmldjango ts=2 sts=2 sw=2 expandtab #}
diff --git a/doc/www/theme/templates/old_page.html b/doc/www/theme/templates/old_page.html
deleted file mode 100644
index 2db3be222790859035b829517805b1b5fec96721..0000000000000000000000000000000000000000
--- a/doc/www/theme/templates/old_page.html
+++ /dev/null
@@ -1,9 +0,0 @@
-{% extends "old_base" %}
-{% set title = page.title %}
-{% block content %}
-<section id="content" class="body">
-  {{ page.content }}
-</section>
-{% endblock %}
-
-{# vim: syntax=htmldjango ts=2 sts=2 sw=2 expandtab #}
diff --git a/extra/dist/tarantoolctl b/extra/dist/tarantoolctl
index 4275bf1c37f55f0ad63c0ffe88c9a6a23e6657b5..e79050ecba676c9bd08ee0d6ac70a46db2bdf882 100755
--- a/extra/dist/tarantoolctl
+++ b/extra/dist/tarantoolctl
@@ -106,9 +106,13 @@ local fiber = require 'fiber'
 
 ffi.cdef[[ int kill(int pid, int sig); ]]
 
-local config_file = os.getenv('HOME') .. '/.config/tarantool/tarantool'
+local config_file
 local usermode = true
 
+if os.getenv('HOME') then
+    config_file = os.getenv('HOME') .. '/.config/tarantool/tarantool'
+end
+
 if not fio.stat(config_file) then
     usermode = false
     local config_list = {
diff --git a/src/box/alter.cc b/src/box/alter.cc
index a1785d78e3f46cda41b996e24328c347d585a108..5916372715391ae3a2094b920f1bd6ca28d4f207 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -1212,10 +1212,13 @@ user_def_create_from_tuple(struct user_def *user, struct tuple *tuple)
 	 */
 	if (tuple_field_count(tuple) > AUTH_MECH_LIST) {
 		const char *auth_data = tuple_field(tuple, AUTH_MECH_LIST);
-		if (user->type == SC_ROLE && strlen(auth_data)) {
-			tnt_raise(ClientError, ER_CREATE_ROLE, user->name,
-				  "authentication data can not be set for "
-				  "a role");
+		if (strlen(auth_data)) {
+			if (user->type == SC_ROLE)
+				tnt_raise(ClientError, ER_CREATE_ROLE,
+					  user->name, "authentication "
+					  "data can not be set for a role");
+			if (user->uid == GUEST)
+				tnt_raise(ClientError, ER_GUEST_USER_PASSWORD);
 		}
 		user_def_fill_auth_data(user, auth_data);
 	}
diff --git a/src/box/errcode.h b/src/box/errcode.h
index 29b950a262883db4f38062bba966fec2e13c8cfc..d8b679d2605cf1413e82ef3a63a61d0736498883 100644
--- a/src/box/errcode.h
+++ b/src/box/errcode.h
@@ -54,8 +54,8 @@ struct errcode_record {
 	/*  0 */_(ER_UNKNOWN,			2, "Unknown error") \
 	/*  1 */_(ER_ILLEGAL_PARAMS,		2, "Illegal parameters, %s") \
 	/*  2 */_(ER_MEMORY_ISSUE,		1, "Failed to allocate %u bytes in %s for %s") \
-	/*  3 */_(ER_TUPLE_FOUND,		2, "Duplicate key exists in unique index '%s'") \
-	/*  4 */_(ER_TUPLE_NOT_FOUND,		2, "Tuple doesn't exist in index '%s'") \
+	/*  3 */_(ER_TUPLE_FOUND,		2, "Duplicate key exists in unique index '%s' in space '%s'") \
+	/*  4 */_(ER_TUPLE_NOT_FOUND,		2, "Tuple doesn't exist in index '%s' in space '%s'") \
 	/*  5 */_(ER_UNSUPPORTED,		2, "%s does not support %s") \
 	/*  6 */_(ER_NONMASTER,			2, "Can't modify data on a replication slave. My master is: %s") \
 	/*  7 */_(ER_READONLY,			2, "Can't modify data because this server in read-only mode.") \
@@ -145,8 +145,9 @@ struct errcode_record {
 	/* 91 */_(ER_PRIV_NOT_GRANTED,		2, "User '%s' does not have %s access on %s '%s'") \
 	/* 92 */_(ER_ROLE_NOT_GRANTED,		2, "User '%s' does not have role '%s'") \
 	/* 93 */_(ER_MISSING_SNAPSHOT,		2, "Can't find snapshot") \
-	/* 94 */_(ER_CANT_UPDATE_PRIMARY_KEY,	2, "Attempt to modify a tuple field which is part of index %s") \
+	/* 94 */_(ER_CANT_UPDATE_PRIMARY_KEY,	2, "Attempt to modify a tuple field which is part of index '%s' in space '%s'") \
 	/* 95 */_(ER_UPDATE_INTEGER_OVERFLOW,   2, "Integer overflow when performing '%c' operation on field %u") \
+	/* 96 */_(ER_GUEST_USER_PASSWORD,       2, "Setting password for guest user has no effect") \
 
 /*
  * !IMPORTANT! Please follow instructions at start of the file
diff --git a/src/box/lua/call.cc b/src/box/lua/call.cc
index cc92cf7b75fbfe8de9d24636bd4a1fdb4ef12c24..c05f22006838961263074fe97a57f55738c09271 100644
--- a/src/box/lua/call.cc
+++ b/src/box/lua/call.cc
@@ -478,7 +478,7 @@ SetuidGuard::SetuidGuard(const char *name, uint32_t name_len,
 	 * No special check for ADMIN user is necessary
 	 * since ADMIN has universal access.
 	 */
-	if (orig_credentials->universal_access & PRIV_ALL)
+	if ((orig_credentials->universal_access & PRIV_ALL) == PRIV_ALL)
 		return;
 	access &= ~orig_credentials->universal_access;
 	/*
diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index 3299532e59837f48890a7fb56708792a7fa660d0..54b09f82a181f00b3357a2f8142fb7fbac1615bd 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -1005,6 +1005,7 @@ end
 box.schema.func = {}
 box.schema.func.create = function(name, opts)
     opts = opts or {}
+    check_param_table(opts, { setuid = 'boolean', if_not_exists = 'boolean' })
     local _func = box.space[box.schema.FUNC_ID]
     local func = _func.index.name:get{name}
     if func then
@@ -1013,16 +1014,32 @@ box.schema.func.create = function(name, opts)
         end
         return
     end
-    check_param_table(opts, { setuid = 'boolean', if_not_exists = 'boolean' })
     opts = update_param_table(opts, { setuid = false })
     opts.setuid = opts.setuid and 1 or 0
     _func:auto_increment{session.uid(), name, opts.setuid}
 end
 
-box.schema.func.drop = function(name)
+box.schema.func.drop = function(name, opts)
+    opts = opts or {}
+    check_param_table(opts, { if_exists = 'boolean' })
     local _func = box.space[box.schema.FUNC_ID]
     local _priv = box.space[box.schema.PRIV_ID]
-    local fid = object_resolve('function', name)
+    local fid
+    local tuple
+    if type(name) == 'string' then
+        tuple = _func.index.name:get{name}
+    else
+        tuple = _func:get{name}
+    end
+    if tuple then
+        fid = tuple[1]
+    end
+    if fid == nil then
+        if not opts.if_exists then
+            box.error(box.error.NO_SUCH_FUNCTION, name)
+        end
+        return
+    end
     local privs = _priv.index.object:select{'function', fid}
     for k, tuple in pairs(privs) do
         box.schema.user.revoke(tuple[2], tuple[5], tuple[3], tuple[4])
@@ -1103,10 +1120,15 @@ box.schema.user.exists = function(name)
     end
 end
 
-box.schema.user.drop = function(name)
+box.schema.user.drop = function(name, opts)
+    opts = opts or {}
+    check_param_table(opts, { if_exists = 'boolean' })
     local uid = user_or_role_resolve(name)
     if uid == nil then
-        box.error(box.error.NO_SUCH_USER, name)
+        if not opts.if_exists then
+            box.error(box.error.NO_SUCH_USER, name)
+        end
+        return
     end
     -- recursive delete of user data
     local _priv = box.space[box.schema.PRIV_ID]
@@ -1279,10 +1301,15 @@ box.schema.role.create = function(name, opts)
     _user:auto_increment{session.uid(), name, 'role'}
 end
 
-box.schema.role.drop = function(name)
+box.schema.role.drop = function(name, opts)
+    opts = opts or {}
+    check_param_table(opts, { if_exists = 'boolean' })
     local uid = user_or_role_resolve(name)
     if uid == nil then
-        box.error(box.error.NO_SUCH_ROLE, name)
+        if not opts.if_exists then
+            box.error(box.error.NO_SUCH_ROLE, name)
+        end
+        return
     end
     return box.schema.user.drop(name)
 end
diff --git a/src/box/memtx_hash.cc b/src/box/memtx_hash.cc
index 4afad8dac1681834a15daa96bbbe37a917eb2e4a..93b7c63c658fc03fe83bbe273ef84301855cf7fa 100644
--- a/src/box/memtx_hash.cc
+++ b/src/box/memtx_hash.cc
@@ -30,6 +30,8 @@
 #include "say.h"
 #include "tuple.h"
 #include "memtx_engine.h"
+#include "space.h"
+#include "schema.h" /* space_cache_find() */
 #include "errinj.h"
 
 #include "third_party/PMurHash.h"
@@ -294,7 +296,9 @@ MemtxHash::replace(struct tuple *old_tuple, struct tuple *new_tuple,
 					      "recover of int hash_table");
 				}
 			}
-			tnt_raise(ClientError, errcode, index_name(this));
+			struct space *sp = space_cache_find(key_def->space_id);
+			tnt_raise(ClientError, errcode, index_name(this),
+				  space_name(sp));
 		}
 
 		if (dup_tuple)
diff --git a/src/box/memtx_tree.cc b/src/box/memtx_tree.cc
index 528c156e0829462736dc0519e4c8caba116498e3..af0a95b2970a8b9860c3427b46fa822787cf37ae 100644
--- a/src/box/memtx_tree.cc
+++ b/src/box/memtx_tree.cc
@@ -29,6 +29,7 @@
 #include "memtx_tree.h"
 #include "tuple.h"
 #include "space.h"
+#include "schema.h" /* space_cache_find() */
 #include "errinj.h"
 #include "memory.h"
 #include "fiber.h"
@@ -250,7 +251,9 @@ MemtxTree::replace(struct tuple *old_tuple, struct tuple *new_tuple,
 			bps_tree_index_delete(&tree, new_tuple);
 			if (dup_tuple)
 				bps_tree_index_insert(&tree, dup_tuple, 0);
-			tnt_raise(ClientError, errcode, index_name(this));
+			struct space *sp = space_cache_find(key_def->space_id);
+			tnt_raise(ClientError, errcode, index_name(this),
+				  space_name(sp));
 		}
 		if (dup_tuple)
 			return dup_tuple;
diff --git a/src/box/sophia_index.cc b/src/box/sophia_index.cc
index e7b47577c10c105d0e5f24447167cdd7996f5ca3..5bb10b2de896b5f00a7eb39b179366742d872b27 100644
--- a/src/box/sophia_index.cc
+++ b/src/box/sophia_index.cc
@@ -272,7 +272,10 @@ SophiaIndex::replace(struct tuple *old_tuple, struct tuple *new_tuple,
 				error = 1;
 			tuple_unref(dup_tuple);
 			if (error) {
-				tnt_raise(ClientError, ER_TUPLE_FOUND, index_name(this));
+				struct space *sp =
+					space_cache_find(key_def->space_id);
+				tnt_raise(ClientError, ER_TUPLE_FOUND,
+					  index_name(this), space_name(sp));
 			}
 		}
 	}
diff --git a/src/box/space.cc b/src/box/space.cc
index 85777d1eb394860e670bc675c04382f96dd52391..261c455041bc68b150fe167cd33c362366e4f71e 100644
--- a/src/box/space.cc
+++ b/src/box/space.cc
@@ -202,7 +202,7 @@ space_check_update(struct space *space,
 	Index *index = space->index[0];
 	if (tuple_compare(old_tuple, new_tuple, index->key_def))
 		tnt_raise(ClientError, ER_CANT_UPDATE_PRIMARY_KEY,
-			  index_name(index));
+			  index_name(index), space_name(space));
 }
 
 /* vim: set fm=marker */
diff --git a/src/coeio.cc b/src/coeio.cc
index 36efb2b3191f8293df5dfdd8e25e54054e2e8b70..e265d62096f414db3486f3b0aceefdcecdfdf5f5 100644
--- a/src/coeio.cc
+++ b/src/coeio.cc
@@ -151,19 +151,19 @@ static int
 coeio_on_complete(eio_req *req)
 {
 	/*
-	 * Don't touch the task if the request is cancelled:
-	 * the task is allocated on the caller's stack and
-	 * may be already gone. Don't wakeup the caller
-	 * if the task is cancelled: in this case the caller
-	 * is already woken up, avoid double wake-up.
+	 * If the request is cancelled, libeio doesn't
+	 * invoke finish callback. Indeed, it can't do
+	 * anything since its execution context has
+	 * already been gone.
 	 */
-	if (! EIO_CANCELLED(req)) {
-		struct coeio_task *task = (struct coeio_task *) req->data;
-		task->result = req->result;
-		task->errorno = req->errorno;
-		task->complete = 1;
-		fiber_wakeup(task->fiber);
-	}
+	assert(!EIO_CANCELLED(req));
+
+	struct coeio_task *task = (struct coeio_task *) req->data;
+	task->result = req->result;
+	task->errorno = req->errorno;
+	task->complete = 1;
+	fiber_wakeup(task->fiber);
+
 	return 0;
 }
 
diff --git a/src/lua/fio.lua b/src/lua/fio.lua
index 9f6b10d92fa7efefd86f443c2c1862829b144aa0..ee6d46bae1155914e2834bf7bdf0a89f6218815b 100644
--- a/src/lua/fio.lua
+++ b/src/lua/fio.lua
@@ -210,7 +210,7 @@ fio.dirname = function(path)
         return nil
     end
     path = tostring(path)
-    path = ffi.new('char[?]', #path, path)
+    path = ffi.new('char[?]', #path + 1, path)
     return ffi.string(ffi.C.dirname(path))
 end
 
diff --git a/src/util.cc b/src/util.cc
index 0e2165f650e39cdb0492e1180e2f25b298b6ba1d..574f6c5b7aac97db14ec6b44041c0778c3c0c3db 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -364,7 +364,7 @@ abspath(const char *filename)
 	if (filename[0] == '/')
 		return strdup(filename);
 
-	char *abspath = (char *) malloc(PATH_MAX);
+	char *abspath = (char *) malloc(PATH_MAX + 1);
 	if (abspath == NULL)
 		return NULL;
 
diff --git a/test/app/json.result b/test/app/json.result
index fa5ebb50583ffbf7b8ceb2253bf35654a2c4aef1..1443f601815a6e535bdf7db203855b7e66129a4b 100644
--- a/test/app/json.result
+++ b/test/app/json.result
@@ -1,6 +1,6 @@
 TAP version 13
 # json
-1..8
+1..9
     # unsigned
     1..56
     ok - encode/decode for 0
@@ -184,4 +184,10 @@ ok - table
     ok - udata  hook priority
     # ucdata: end
 ok - ucdata
+    # misc
+    1..2
+    ok - .NULL is cdata
+    ok - .NULL == nil
+    # misc: end
+ok - misc
 # json: end
diff --git a/test/app/json.test.lua b/test/app/json.test.lua
index 07ade39f47efe940ff1089c661b7b628bd778173..3884b41e786dc8e52ddc46b9da126d34e51d7ae2 100755
--- a/test/app/json.test.lua
+++ b/test/app/json.test.lua
@@ -14,9 +14,15 @@ local function is_array(s)
     return string.sub(s, 1, 1) == "["
 end
 
+local function test_misc(test, s)
+    test:plan(2)
+    test:iscdata(s.NULL, 'void *', '.NULL is cdata')
+    test:ok(s.NULL == nil, '.NULL == nil')
+end
+
 tap.test("json", function(test)
     local serializer = require('json')
-    test:plan(8)
+    test:plan(9)
     test:test("unsigned", common.test_unsigned, serializer)
     test:test("signed", common.test_signed, serializer)
     test:test("double", common.test_double, serializer)
@@ -25,4 +31,5 @@ tap.test("json", function(test)
     test:test("nil", common.test_nil, serializer)
     test:test("table", common.test_table, serializer, is_array, is_map)
     test:test("ucdata", common.test_ucdata, serializer)
+    test:test("misc", test_misc, serializer)
 end)
diff --git a/test/big/hash.result b/test/big/hash.result
index 9e3e9e7421c4cd9d3d94eb094995b1c7da3d2d79..d511bdc0773ae0a746072589a1f589b2c83829a5 100644
--- a/test/big/hash.result
+++ b/test/big/hash.result
@@ -538,7 +538,7 @@ hash.index['field3']:get{10}
 -- TupleFound (primary key)
 hash:insert{1, 10, 10, 10}
 ---
-- error: Duplicate key exists in unique index 'primary'
+- error: Duplicate key exists in unique index 'primary' in space 'tweedledum'
 ...
 hash.index['primary']:get{10}
 ---
@@ -580,7 +580,7 @@ hash.index['field3']:get{10}
 -- TupleFound (key --1)
 hash:insert{10, 0, 10, 10}
 ---
-- error: Duplicate key exists in unique index 'primary'
+- error: Duplicate key exists in unique index 'primary' in space 'tweedledum'
 ...
 hash.index['primary']:get{10}
 ---
@@ -627,7 +627,7 @@ hash.index['field1']:get{0}
 -- TupleFound (key --3)
 hash:insert{10, 10, 10, 0}
 ---
-- error: Duplicate key exists in unique index 'primary'
+- error: Duplicate key exists in unique index 'primary' in space 'tweedledum'
 ...
 hash.index['primary']:get{10}
 ---
diff --git a/test/big/hash_multipart.result b/test/big/hash_multipart.result
index 18545202e29dd5085c32cfe4296c86cdcc44d0fb..f70bb6a9f001d4206d73b74f0614a7d98c9e2024 100644
--- a/test/big/hash_multipart.result
+++ b/test/big/hash_multipart.result
@@ -46,7 +46,7 @@ hash:insert{1, 'bar', 1, '', 4}
 -- try to insert a row with a duplicate key
 hash:insert{1, 'bar', 1, '', 5}
 ---
-- error: Duplicate key exists in unique index 'primary'
+- error: Duplicate key exists in unique index 'primary' in space 'tweedledum'
 ...
 -- output all rows
 --# setopt delimiter ';'
diff --git a/test/big/lua.result b/test/big/lua.result
index d41273ab2ce11a7c09dc55d23094ecf96b234cbd..31b231e74366ae11caee99997d58216b3ac2425a 100644
--- a/test/big/lua.result
+++ b/test/big/lua.result
@@ -106,7 +106,7 @@ space:insert{'1', 'hello', 'world'}
 ...
 space:insert{'2', 'hello', 'world'}
 ---
-- error: Duplicate key exists in unique index 'minmax'
+- error: Duplicate key exists in unique index 'minmax' in space 'tweedledum'
 ...
 space:drop()
 ---
diff --git a/test/big/tree_pk.result b/test/big/tree_pk.result
index b4979a34ced6a26a68c8213425766fa33b0ea7c0..d75f06d5a05073dceee7e4759d0e868991538bef 100644
--- a/test/big/tree_pk.result
+++ b/test/big/tree_pk.result
@@ -364,7 +364,7 @@ s0.index['i3']:select{10}
 -- TupleFound (primary key)
 s0:insert{1, 10, 10, 10}
 ---
-- error: Duplicate key exists in unique index 'primary'
+- error: Duplicate key exists in unique index 'primary' in space 'tweedledum'
 ...
 s0.index['primary']:get{10}
 ---
@@ -409,7 +409,7 @@ s0.index['i3']:select{10}
 -- TupleFound (key #1)
 s0:insert{10, 0, 10, 10}
 ---
-- error: Duplicate key exists in unique index 'primary'
+- error: Duplicate key exists in unique index 'primary' in space 'tweedledum'
 ...
 s0.index['primary']:get{10}
 ---
@@ -434,7 +434,7 @@ s0.index['i1']:select{0}
 -- TupleFound (key #1)
 s0:replace{2, 0, 10, 10}
 ---
-- error: Duplicate key exists in unique index 'i1'
+- error: Duplicate key exists in unique index 'i1' in space 'tweedledum'
 ...
 s0.index['primary']:get{10}
 ---
@@ -459,7 +459,7 @@ s0.index['i1']:select{0}
 -- TupleFound (key #3)
 s0:insert{10, 10, 10, 0}
 ---
-- error: Duplicate key exists in unique index 'primary'
+- error: Duplicate key exists in unique index 'primary' in space 'tweedledum'
 ...
 s0.index['primary']:get{10}
 ---
@@ -484,7 +484,7 @@ s0.index['i3']:select{0}
 -- TupleFound (key #3)
 s0:replace{2, 10, 10, 0}
 ---
-- error: Duplicate key exists in unique index 'i1'
+- error: Duplicate key exists in unique index 'i1' in space 'tweedledum'
 ...
 s0.index['primary']:get{10}
 ---
diff --git a/test/big/tree_pk_multipart.result b/test/big/tree_pk_multipart.result
index ab094e3899251d34fc3b2ccb7c2bec6b1c72ef29..f91db4f383f898401dd8e7b6c2681f36fcd7c40d 100644
--- a/test/big/tree_pk_multipart.result
+++ b/test/big/tree_pk_multipart.result
@@ -269,7 +269,8 @@ space:delete{'Vincent', 'The Wolf!', 0}
 ...
 space:update({'Vincent', 'The Wolf!', 1}, {{ '=', 1, 'Updated' }, {'=', 5, 'New'}})
 ---
-- error: Attempt to modify a tuple field which is part of index primary
+- error: Attempt to modify a tuple field which is part of index 'primary' in space
+    'tweedledum'
 ...
 space:update({'Updated', 'The Wolf!', 1}, {{ '=', 1, 'Vincent'}, { '#', 5, 1 }})
 ---
diff --git a/test/box/access.result b/test/box/access.result
index 28d22005a549533843e6f30ae681023780a6721e..0e984bf7c31a101d653db9ddf36b66b938c2faac 100644
--- a/test/box/access.result
+++ b/test/box/access.result
@@ -649,3 +649,26 @@ box.schema.func.create('dummy', { if_not_exists = true })
 box.schema.func.drop('dummy')
 ---
 ...
+-- gh-664 roles: accepting bad syntax for create
+box.schema.user.create('user', 'blah')
+---
+- error: Illegal parameters, options should be a table
+...
+box.schema.user.drop('user', 'blah')
+---
+- error: Illegal parameters, options should be a table
+...
+-- gh-664 roles: accepting bad syntax for create
+box.schema.func.create('func', 'blah')
+---
+- error: Illegal parameters, options should be a table
+...
+box.schema.func.drop('blah', 'blah')
+---
+- error: Illegal parameters, options should be a table
+...
+-- gh-758 attempt to set password for user guest
+box.schema.user.passwd('guest', 'sesame')
+---
+- error: Setting password for guest user has no effect
+...
diff --git a/test/box/access.test.lua b/test/box/access.test.lua
index ec0e5193d63e13767fbf34a9920f0ea298db47ee..8d7b0d1658025df57b662b02a5746300a759783a 100644
--- a/test/box/access.test.lua
+++ b/test/box/access.test.lua
@@ -253,3 +253,13 @@ box.schema.user.revoke('guest', 'read,write,execute', 'universe', '', { if_exist
 box.schema.func.create('dummy', { if_not_exists = true })
 box.schema.func.create('dummy', { if_not_exists = true })
 box.schema.func.drop('dummy')
+
+-- gh-664 roles: accepting bad syntax for create
+box.schema.user.create('user', 'blah')
+box.schema.user.drop('user', 'blah')
+
+-- gh-664 roles: accepting bad syntax for create
+box.schema.func.create('func', 'blah')
+box.schema.func.drop('blah', 'blah')
+-- gh-758 attempt to set password for user guest
+box.schema.user.passwd('guest', 'sesame')
diff --git a/test/box/access_bin.result b/test/box/access_bin.result
index 850c0c0c073f1de6d099379ae04dceb040da4f0e..3dfc0a4172f2c2d39c78a7c71421093b6e27830b 100644
--- a/test/box/access_bin.result
+++ b/test/box/access_bin.result
@@ -285,3 +285,47 @@ box.schema.user.drop('test')
 test:drop()
 ---
 ...
+--
+-- gh-508 - wrong check for universal access of setuid functions
+--
+-- notice that guest can execute stuff, but can't read space _func
+box.schema.user.grant('guest', 'execute', 'universe')
+---
+...
+function f1() return box.space._func:get(1)[4] end
+---
+...
+function f2() return box.space._func:get(2)[4] end
+---
+...
+box.schema.func.create('f1')
+---
+...
+box.schema.func.create('f2',{setuid=true})
+---
+...
+c = net.new(box.cfg.listen)
+---
+...
+-- should return access denied
+c:call('f1')
+---
+- error: Read access denied for user 'guest' to space '_func'
+...
+-- should work (used to return access denied, because was not setuid
+c:call('f2')
+---
+- - [0]
+...
+c:close()
+---
+...
+box.schema.user.revoke('guest', 'execute', 'universe')
+---
+...
+box.schema.func.drop('f1')
+---
+...
+box.schema.func.drop('f2')
+---
+...
diff --git a/test/box/access_bin.test.lua b/test/box/access_bin.test.lua
index be54595ba650025554452babe3d2b3cc544dd1ec..24019668e175e3a9f5fd4bbd9b7669303b7609b1 100644
--- a/test/box/access_bin.test.lua
+++ b/test/box/access_bin.test.lua
@@ -106,3 +106,21 @@ box.session.su('admin')
 c:close()
 box.schema.user.drop('test')
 test:drop()
+--
+-- gh-508 - wrong check for universal access of setuid functions
+--
+-- notice that guest can execute stuff, but can't read space _func
+box.schema.user.grant('guest', 'execute', 'universe')
+function f1() return box.space._func:get(1)[4] end
+function f2() return box.space._func:get(2)[4] end
+box.schema.func.create('f1')
+box.schema.func.create('f2',{setuid=true})
+c = net.new(box.cfg.listen)
+-- should return access denied
+c:call('f1')
+-- should work (used to return access denied, because was not setuid
+c:call('f2')
+c:close()
+box.schema.user.revoke('guest', 'execute', 'universe')
+box.schema.func.drop('f1')
+box.schema.func.drop('f2')
diff --git a/test/box/alter.result b/test/box/alter.result
index e2a3ad5b6ee95110e41214dec2f6c6646f1e5f9a..67d91e2887797b7746b5a891a86e9fba75d7e781 100644
--- a/test/box/alter.result
+++ b/test/box/alter.result
@@ -13,7 +13,7 @@ ADMIN = 1
 --
 _space:insert{_space.id, ADMIN, 'test', 5 }
 ---
-- error: Duplicate key exists in unique index 'primary'
+- error: Duplicate key exists in unique index 'primary' in space '_space'
 ...
 --
 -- Bad space id
@@ -27,14 +27,14 @@ _space:insert{'hello', 'world', 'test'}
 --
 _space:insert{_space.id, ADMIN, 'test', 'world'}
 ---
-- error: Duplicate key exists in unique index 'primary'
+- error: Duplicate key exists in unique index 'primary' in space '_space'
 ...
 --
 -- There is already a tuple for the system space
 --
 _space:insert{_space.id, ADMIN, '_space', 'memtx', 0}
 ---
-- error: Duplicate key exists in unique index 'primary'
+- error: Duplicate key exists in unique index 'primary' in space '_space'
 ...
 _space:replace{_space.id, ADMIN, '_space', 'memtx', 0}
 ---
@@ -42,7 +42,7 @@ _space:replace{_space.id, ADMIN, '_space', 'memtx', 0}
 ...
 _space:insert{_index.id, ADMIN, '_index', 'memtx', 0}
 ---
-- error: Duplicate key exists in unique index 'primary'
+- error: Duplicate key exists in unique index 'primary' in space '_space'
 ...
 _space:replace{_index.id, ADMIN, '_index', 'memtx', 0}
 ---
@@ -71,11 +71,13 @@ _space:delete{_index.id}
 --
 _space:update({_space.id}, {{'+', 1, 1}})
 ---
-- error: Attempt to modify a tuple field which is part of index primary
+- error: Attempt to modify a tuple field which is part of index 'primary' in space
+    '_space'
 ...
 _space:update({_space.id}, {{'+', 1, 2}})
 ---
-- error: Attempt to modify a tuple field which is part of index primary
+- error: Attempt to modify a tuple field which is part of index 'primary' in space
+    '_space'
 ...
 --
 -- Create a space
@@ -138,7 +140,7 @@ space:replace{0}
 ...
 _index:insert{_space.id, 0, 'primary', 'tree', 1, 1, 0, 'num'}
 ---
-- error: Duplicate key exists in unique index 'primary'
+- error: Duplicate key exists in unique index 'primary' in space '_index'
 ...
 _index:replace{_space.id, 0, 'primary', 'tree', 1, 1, 0, 'num'}
 ---
@@ -146,7 +148,7 @@ _index:replace{_space.id, 0, 'primary', 'tree', 1, 1, 0, 'num'}
 ...
 _index:insert{_index.id, 0, 'primary', 'tree', 1, 2, 0, 'num', 1, 'num'}
 ---
-- error: Duplicate key exists in unique index 'primary'
+- error: Duplicate key exists in unique index 'primary' in space '_index'
 ...
 _index:replace{_index.id, 0, 'primary', 'tree', 1, 2, 0, 'num', 1, 'num'}
 ---
@@ -323,7 +325,7 @@ auto = box.schema.space.create('auto_original')
 ...
 auto2 = box.schema.space.create('auto', {id = auto.id})
 ---
-- error: Duplicate key exists in unique index 'primary'
+- error: Duplicate key exists in unique index 'primary' in space '_space'
 ...
 box.schema.space.drop('auto')
 ---
diff --git a/test/box/alter_limits.result b/test/box/alter_limits.result
index 3ba3ff295fa034499f5102db496bc4c155acc12a..e38eaac1c153bb2d04112b58206e97ef89c7aa3f 100644
--- a/test/box/alter_limits.result
+++ b/test/box/alter_limits.result
@@ -84,7 +84,7 @@ s.id
 -- duplicate id
 box.schema.space.create('tweedledee', { id = 3000 })
 ---
-- error: Duplicate key exists in unique index 'primary'
+- error: Duplicate key exists in unique index 'primary' in space '_space'
 ...
 -- stupid space id
 box.schema.space.create('tweedledee', { id = 'tweedledee' })
@@ -681,7 +681,7 @@ index = s:create_index('third', { type = 'hash', parts = {  3, 'num' } })
 ...
 s.index.third:rename('second')
 ---
-- error: Duplicate key exists in unique index 'name'
+- error: Duplicate key exists in unique index 'name' in space '_index'
 ...
 s.index.third.id
 ---
@@ -762,12 +762,12 @@ s.index.primary:select{}
 -- a duplicate in the created index
 index = s:create_index('nodups', { type = 'tree', unique=true, parts = { 2, 'num'} })
 ---
-- error: Duplicate key exists in unique index 'nodups'
+- error: Duplicate key exists in unique index 'nodups' in space 'full'
 ...
 -- change of non-unique index to unique: same effect
 s.index.year:alter({unique=true})
 ---
-- error: Duplicate key exists in unique index 'year'
+- error: Duplicate key exists in unique index 'year' in space 'full'
 ...
 s.index.primary:select{}
 ---
@@ -844,7 +844,7 @@ s:insert{2, 1}
 ...
 s.index.secondary:alter{ unique = true }
 ---
-- error: Duplicate key exists in unique index 'secondary'
+- error: Duplicate key exists in unique index 'secondary' in space 'test'
 ...
 s:delete{2}
 ---
@@ -855,7 +855,7 @@ s.index.secondary:alter{ unique = true }
 ...
 s:insert{2, 1}
 ---
-- error: Duplicate key exists in unique index 'secondary'
+- error: Duplicate key exists in unique index 'secondary' in space 'test'
 ...
 s:insert{2, 2}
 ---
diff --git a/test/box/call.result b/test/box/call.result
index 70928be52241af11dc485180a16a0ed46ab3f95a..42b24ee3b735953b2b9bc1f55aa6479043d1a777 100644
--- a/test/box/call.result
+++ b/test/box/call.result
@@ -4,7 +4,10 @@ box.schema.user.create('test', { password = 'test' })
 box.schema.user.grant('test', 'execute,read,write', 'universe')
 ---
 ...
-function f1() return 'testing', 1, false, -1, 1.123, 1e123, nil end
+exp_notation = 1e123
+---
+...
+function f1() return 'testing', 1, false, -1, 1.123, math.abs(exp_notation - 1e123) < 0.1, nil end
 ---
 ...
 f1()
@@ -14,7 +17,7 @@ f1()
 - false
 - -1
 - 1.123
-- 1e+123
+- true
 - null
 ...
 call f1()
@@ -24,7 +27,7 @@ call f1()
 - [False]
 - [-1]
 - [1.123]
-- [1e+123]
+- [True]
 - [None]
 ...
 f1=nil
@@ -324,11 +327,12 @@ call myinsert(3, 'old', 2)
 ---
 - error:
     errcode: ER_TUPLE_FOUND
-    errmsg: Duplicate key exists in unique index 'primary'
+    errmsg: Duplicate key exists in unique index 'primary' in space 'tweedledum'
 ...
 space:update({3}, {{'=', 1, 4}, {'=', 2, 'new'}})
 ---
-- error: Attempt to modify a tuple field which is part of index primary
+- error: Attempt to modify a tuple field which is part of index 'primary' in space
+    'tweedledum'
 ...
 space:insert(space:get{3}:update{{'=', 1, 4}, {'=', 2, 'new'}}) space:delete{3}
 ---
diff --git a/test/box/call.test.py b/test/box/call.test.py
index 7d64899a6a11d196bf2499ca89bc7f76d1b6fa36..a73fec928eff2d87d4cd003fbf9bc397af3ce10f 100644
--- a/test/box/call.test.py
+++ b/test/box/call.test.py
@@ -4,7 +4,9 @@ import sys
 admin("box.schema.user.create('test', { password = 'test' })")
 admin("box.schema.user.grant('test', 'execute,read,write', 'universe')")
 sql.authenticate('test', 'test')
-admin("function f1() return 'testing', 1, false, -1, 1.123, 1e123, nil end")
+# workaround for gh-770 centos 6 float representation
+admin('exp_notation = 1e123')
+admin("function f1() return 'testing', 1, false, -1, 1.123, math.abs(exp_notation - 1e123) < 0.1, nil end")
 admin("f1()")
 sql("call f1()")
 admin("f1=nil")
diff --git a/test/box/fiber.result b/test/box/fiber.result
index 1116fd5e651be7cc6a1726eb04ce6d0782b2b6de..d86c51ba5046a04da565fb3bb3468b6f76315a8a 100644
--- a/test/box/fiber.result
+++ b/test/box/fiber.result
@@ -141,7 +141,7 @@ space:insert{1953719668, 'old', 1684234849}
 -- test that insert produces a duplicate key error
 space:insert{1953719668, 'old', 1684234849}
 ---
-- error: Duplicate key exists in unique index 'primary'
+- error: Duplicate key exists in unique index 'primary' in space 'tweedledum'
 ...
 space:update(1953719668, {{'=', 1, 1953719668}, {'=', 2, 'new'}})
 ---
diff --git a/test/box/misc.result b/test/box/misc.result
index 0fe4994e168993ed3443eecb01de82a0155ed1ca..8b9c75937e307c040fe36703a5bd7f15b84af4fd 100644
--- a/test/box/misc.result
+++ b/test/box/misc.result
@@ -204,6 +204,7 @@ t;
   - 'box.error.MODIFY_INDEX : 14'
   - 'box.error.PASSWORD_MISMATCH : 47'
   - 'box.error.NO_SUCH_ENGINE : 57'
+  - 'box.error.FIELD_TYPE : 23'
   - 'box.error.ACCESS_DENIED : 42'
   - 'box.error.UPDATE_INTEGER_OVERFLOW : 95'
   - 'box.error.LAST_DROP : 15'
@@ -232,7 +233,7 @@ t;
   - 'box.error.ALTER_SPACE : 12'
   - 'box.error.ACTIVE_TRANSACTION : 79'
   - 'box.error.NO_CONNECTION : 77'
-  - 'box.error.FIELD_TYPE : 23'
+  - 'box.error.GUEST_USER_PASSWORD : 96'
   - 'box.error.INVALID_XLOG_NAME : 75'
   - 'box.error.INVALID_XLOG : 74'
   - 'box.error.REPLICA_MAX : 73'
@@ -295,7 +296,7 @@ pcall(myinsert, {1, 'hello'})
 pcall(myinsert, {1, 'hello'})
 ---
 - false
-- Duplicate key exists in unique index 'primary'
+- Duplicate key exists in unique index 'primary' in space 'tweedledum'
 ...
 box.space.tweedledum:truncate()
 ---
diff --git a/test/box/net.box.result b/test/box/net.box.result
index 7fb11049c6be505dbbc1ec774ad1a2237639fd91..7c66df2f3502f4aea92082c00d474b99f06858a6 100644
--- a/test/box/net.box.result
+++ b/test/box/net.box.result
@@ -228,7 +228,7 @@ cn.space.net_box_test_space:insert{234, 1,2,3}
 ...
 cn.space.net_box_test_space:insert{234, 1,2,3}
 ---
-- error: Duplicate key exists in unique index 'primary'
+- error: Duplicate key exists in unique index 'primary' in space 'net_box_test_space'
 ...
 cn.space.net_box_test_space.insert{234, 1,2,3}
 ---
diff --git a/test/box/role.result b/test/box/role.result
index f11af5c62afda24a603a9ed907fe61c3dac45d0a..4129c5635728a1a46e1b0dc3f87de123c3e7f2db 100644
--- a/test/box/role.result
+++ b/test/box/role.result
@@ -816,6 +816,10 @@ box.schema.user.create('test', { if_not_exists = true})
 ...
 box.schema.role.drop('test', { if_not_exists = true})
 ---
+- error: Illegal parameters, options parameter 'if_not_exists' is unexpected
+...
+box.schema.role.drop('test', { if_exists = true})
+---
 ...
 box.schema.role.create('test', { if_not_exists = true})
 ---
@@ -825,4 +829,17 @@ box.schema.role.create('test', { if_not_exists = true})
 ...
 box.schema.user.drop('test', { if_not_exists = true})
 ---
+- error: Illegal parameters, options parameter 'if_not_exists' is unexpected
+...
+-- gh-664 roles: accepting bad syntax for create
+box.schema.role.create('role', 'role')
+---
+- error: Illegal parameters, options should be a table
+...
+box.schema.role.drop('role', 'role')
+---
+- error: Illegal parameters, options should be a table
+...
+box.schema.user.drop('test', { if_exists = true})
+---
 ...
diff --git a/test/box/role.test.lua b/test/box/role.test.lua
index 6d3014edd5037b266be4809dedf0fdd9424a2b48..42e867aac186f13262ec36db3a166a809699f0ad 100644
--- a/test/box/role.test.lua
+++ b/test/box/role.test.lua
@@ -323,6 +323,11 @@ box.schema.user.create('guest', { if_not_exists = true})
 box.schema.user.create('test', { if_not_exists = true})
 box.schema.user.create('test', { if_not_exists = true})
 box.schema.role.drop('test', { if_not_exists = true})
+box.schema.role.drop('test', { if_exists = true})
 box.schema.role.create('test', { if_not_exists = true})
 box.schema.role.create('test', { if_not_exists = true})
 box.schema.user.drop('test', { if_not_exists = true})
+-- gh-664 roles: accepting bad syntax for create
+box.schema.role.create('role', 'role')
+box.schema.role.drop('role', 'role')
+box.schema.user.drop('test', { if_exists = true})
diff --git a/test/box/update.result b/test/box/update.result
index 2262ba7a72ca62a8b6ccda7dff361bc6e76a2634..aab2c05663ca6f3bf2fdd5965ae6168fc57a26df 100644
--- a/test/box/update.result
+++ b/test/box/update.result
@@ -11,7 +11,7 @@ s:insert{1000001, 1000002, 1000003, 1000004, 1000005}
 ...
 s:update({1000001}, {{'#', 1, 1}})
 ---
-- error: Attempt to modify a tuple field which is part of index pk
+- error: Attempt to modify a tuple field which is part of index 'pk' in space 'tweedledum'
 ...
 s:truncate()
 ---
@@ -142,7 +142,7 @@ s:update({1}, {{'=', 2, 'set tuple'}, {'!', 2, 'inserted tuple'}, {'#', 3, 1}})
 ...
 s:update({1}, {{'!', 1, 3}, {'!', 1, 2}})
 ---
-- error: Attempt to modify a tuple field which is part of index pk
+- error: Attempt to modify a tuple field which is part of index 'pk' in space 'tweedledum'
 ...
 s:truncate()
 ---
diff --git a/test/replication/cluster.result b/test/replication/cluster.result
index cd477fdb75a4ec8f1405c33c984bfae4363e2dec..466fd24f2d6ad9b4dc324cce851ca4c9042d7e89 100644
--- a/test/replication/cluster.result
+++ b/test/replication/cluster.result
@@ -142,7 +142,8 @@ box.info.vclock[10]
 ...
 box.space._cluster:update(10, {{'=', 1, 11}})
 ---
-- error: Attempt to modify a tuple field which is part of index primary
+- error: Attempt to modify a tuple field which is part of index 'primary' in space
+    '_cluster'
 ...
 box.info.server.id
 ---
diff --git a/test/replication/hot_standby.result b/test/replication/hot_standby.result
index 69ba5bc477babdf195774f07b2812c7e549eb7d6..b6ccad365c19f65802c7ad5128e42a3bb272c36e 100644
--- a/test/replication/hot_standby.result
+++ b/test/replication/hot_standby.result
@@ -2,6 +2,12 @@
 box.schema.user.grant('guest', 'replication')
 ---
 ...
+box.schema.func.create('_set_pri_lsn')
+---
+...
+box.schema.user.grant('guest', 'execute', 'function', '_set_pri_lsn')
+---
+...
 --# create server hot_standby with script='replication/hot_standby.lua', rpl_master=default
 --# create server replica with rpl_master=default, script='replication/replica.lua'
 --# start server hot_standby
diff --git a/test/replication/hot_standby.test.lua b/test/replication/hot_standby.test.lua
index e5865acc8e3bf43609af30cba1062ec9be605b67..68a5a6a4322f9e30e55071a03949bd176edd90c8 100644
--- a/test/replication/hot_standby.test.lua
+++ b/test/replication/hot_standby.test.lua
@@ -1,5 +1,7 @@
 --# set connection default
 box.schema.user.grant('guest', 'replication')
+box.schema.func.create('_set_pri_lsn')
+box.schema.user.grant('guest', 'execute', 'function', '_set_pri_lsn')
 --# create server hot_standby with script='replication/hot_standby.lua', rpl_master=default
 --# create server replica with rpl_master=default, script='replication/replica.lua'
 --# start server hot_standby
diff --git a/test/sophia/gh.result b/test/sophia/gh.result
index cbe6fa5d15900340ae29338bb207f548c769cc54..0f91fd492e5a07289e5a33bcd9c1b70eb37ff606 100644
--- a/test/sophia/gh.result
+++ b/test/sophia/gh.result
@@ -153,7 +153,8 @@ s:insert{1,'X'}
 ...
 s:update({'X'}, {{'=', 2, 'Y'}})
 ---
-- error: Attempt to modify a tuple field which is part of index primary
+- error: Attempt to modify a tuple field which is part of index 'primary' in space
+    'tester'
 ...
 s:select{'X'}
 ---
diff --git a/third_party/coro/coro.h b/third_party/coro/coro.h
index 779d800b4af6ce4729a366156a58c63ac54a48e4..481a3b61684f4383f454bc5eb1b1dcb7bd1f8091 100644
--- a/third_party/coro/coro.h
+++ b/third_party/coro/coro.h
@@ -299,7 +299,7 @@ void coro_stack_free (struct coro_stack *stack);
     && !defined CORO_SJLJ    && !defined CORO_LINUX \
     && !defined CORO_IRIX    && !defined CORO_ASM \
     && !defined CORO_PTHREAD && !defined CORO_FIBER
-# if defined WINDOWS && (defined __i386 || (__x86_64 || defined _M_IX86 || defined _M_AMD64)
+# if defined WINDOWS && (defined __i386 || __x86_64 || defined _M_IX86 || defined _M_AMD64)
 #  define CORO_ASM 1
 # elif defined WINDOWS || defined _WIN32
 #  define CORO_LOSER 1 /* you don't win with windoze */
diff --git a/third_party/libeio/CVS/Entries b/third_party/libeio/CVS/Entries
index b19391afe22a6fc0cc06f9cc981b172370da8a57..df3b2e43405d418ef93891b6f3c5553d3eb04ea6 100644
--- a/third_party/libeio/CVS/Entries
+++ b/third_party/libeio/CVS/Entries
@@ -1,14 +1,15 @@
-/Changes/1.51/Tue Aug 14 04:15:34 2012//
-/LICENSE/1.1/Sat May 17 12:32:11 2008//
-/Makefile.am/1.3/Fri Jun 10 12:46:20 2011//
-/autogen.sh/1.4/Mon May 30 15:27:30 2011//
-/configure.ac/1.10/Wed Jun 29 14:52:22 2011//
-/demo.c/1.4/Mon Nov 29 12:38:32 2010//
-/ecb.h/1.16/Tue Oct  9 04:53:53 2012//
-/eio.3/1.1/Sun May 11 13:05:10 2008//
-/eio.c/1.124/Thu Oct 11 05:01:56 2012//
-/eio.h/1.52/Tue Aug 14 04:15:35 2012//
-/eio.pod/1.30/Wed Jan 11 05:13:22 2012//
-/libeio.m4/1.22/Tue Nov 13 20:14:57 2012//
-/xthread.h/1.16/Thu Oct 11 03:20:52 2012//
+/Changes/1.53/Tue Apr  7 16:19:34 2015//
+/LICENSE/1.1/Tue Nov 18 10:15:55 2014//
+/Makefile.am/1.4/Tue Apr  7 16:19:34 2015//
+/autogen.sh/1.4/Tue Nov 18 10:15:55 2014//
+/configure.ac/1.10/Tue Nov 18 10:15:55 2014//
+/demo.c/1.4/Tue Nov 18 10:15:55 2014//
+/ecb.h/1.23/Tue Apr  7 16:19:34 2015//
+/eio.3/1.1/Tue Nov 18 10:15:55 2014//
+/eio.c/1.132/Result of merge//
+/eio.h/1.54/Tue Apr  7 16:19:34 2015//
+/eio.pod/1.35/Tue Apr  7 16:19:34 2015//
+/libeio.m4/1.22/Tue Nov 18 10:15:55 2014//
+/xthread.h/1.17/Result of merge//
+/etp.c/1.2/Mon Aug 18 04:26:03 2014//
 D
diff --git a/third_party/libeio/CVS/Template b/third_party/libeio/CVS/Template
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/third_party/libeio/Changes b/third_party/libeio/Changes
index 711baf5ea578942c061e17a124ad9db053c083a2..eed266e2fda0d1344fdf84942c9fc6718a644a4b 100644
--- a/third_party/libeio/Changes
+++ b/third_party/libeio/Changes
@@ -8,6 +8,7 @@ TODO: fadvise request
 TODO: fdopendir/utimensat
 TODO: maybe work around 3.996gb barrier in pread/pwrite as well, maybe readahead etc.?
 1.0
+	- for simple request api, initialise result/errorno to -1/ECANCELED.
 	- fix a deadlock where a wakeup signal could be missed when
           a timeout occured at the same time.
 	- use nonstandard but maybe-working-on-bsd fork technique.
@@ -73,4 +74,5 @@ TODO: maybe work around 3.996gb barrier in pread/pwrite as well, maybe readahead
         - remove pread/pwrite emulation, as the only system that lacked them
           (cygwin) provides them for a while now.
         - provide pread/pwrite implementations for win32.
+        - implement aio_realpath for windows.
 
diff --git a/third_party/libeio/Makefile.am b/third_party/libeio/Makefile.am
index e9866c0d5e7c33d45c3239a916aaff1df1f80e48..568f824b5741be017dfdae0b3cd791fed81c5b90 100644
--- a/third_party/libeio/Makefile.am
+++ b/third_party/libeio/Makefile.am
@@ -2,7 +2,7 @@ AUTOMAKE_OPTIONS = foreign no-dependencies
 
 VERSION_INFO = 1:0
 
-EXTRA_DIST = LICENSE Changes autogen.sh
+EXTRA_DIST = LICENSE Changes autogen.sh etp.c
 
 #man_MANS = ev.3
 
diff --git a/third_party/libeio/ecb.h b/third_party/libeio/ecb.h
index 81879d7014aa3d15c3d98ca81aa25349ab48002a..2348b6a243799d397e8eb070fedb4b9161880236 100644
--- a/third_party/libeio/ecb.h
+++ b/third_party/libeio/ecb.h
@@ -1,7 +1,7 @@
 /*
  * libecb - http://software.schmorp.de/pkg/libecb
  *
- * Copyright (©) 2009-2012 Marc Alexander Lehmann <libecb@schmorp.de>
+ * Copyright (©) 2009-2015 Marc Alexander Lehmann <libecb@schmorp.de>
  * Copyright (©) 2011 Emanuele Giaquinta
  * All rights reserved.
  *
@@ -25,13 +25,24 @@
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
  * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License ("GPL") version 2 or any later version,
+ * in which case the provisions of the GPL are applicable instead of
+ * the above. If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the BSD license, indicate your decision
+ * by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL. If you do not delete the
+ * provisions above, a recipient may use your version of this file under
+ * either the BSD or the GPL.
  */
 
 #ifndef ECB_H
 #define ECB_H
 
 /* 16 bits major, 16 bits minor */
-#define ECB_VERSION 0x00010002
+#define ECB_VERSION 0x00010004
 
 #ifdef _WIN32
   typedef   signed char   int8_t;
@@ -65,6 +76,15 @@
   #endif
 #endif
 
+/* work around x32 idiocy by defining proper macros */
+#if __amd64 || __x86_64 || _M_AMD64 || _M_X64
+  #if _ILP32
+    #define ECB_AMD64_X32 1
+  #else
+    #define ECB_AMD64 1
+  #endif
+#endif
+
 /* many compilers define _GNUC_ to some versions but then only implement
  * what their idiot authors think are the "more important" extensions,
  * causing enormous grief in return for some better fake benchmark numbers.
@@ -72,20 +92,40 @@
  * we try to detect these and simply assume they are not gcc - if they have
  * an issue with that they should have done it right in the first place.
  */
-#ifndef ECB_GCC_VERSION
-  #if !defined __GNUC_MINOR__ || defined __INTEL_COMPILER || defined __SUNPRO_C || defined __SUNPRO_CC || defined __llvm__ || defined __clang__
-    #define ECB_GCC_VERSION(major,minor) 0
-  #else
-    #define ECB_GCC_VERSION(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
-  #endif
+#if !defined __GNUC_MINOR__ || defined __INTEL_COMPILER || defined __SUNPRO_C || defined __SUNPRO_CC || defined __llvm__ || defined __clang__
+  #define ECB_GCC_VERSION(major,minor) 0
+#else
+  #define ECB_GCC_VERSION(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
+#endif
+
+#define ECB_CLANG_VERSION(major,minor) (__clang_major__ > (major) || (__clang_major__ == (major) && __clang_minor__ >= (minor)))
+
+#if __clang__ && defined __has_builtin
+  #define ECB_CLANG_BUILTIN(x) __has_builtin (x)
+#else
+  #define ECB_CLANG_BUILTIN(x) 0
+#endif
+
+#if __clang__ && defined __has_extension
+  #define ECB_CLANG_EXTENSION(x) __has_extension (x)
+#else
+  #define ECB_CLANG_EXTENSION(x) 0
 #endif
 
-#define ECB_C     (__STDC__+0) /* this assumes that __STDC__ is either empty or a number */
-#define ECB_C99   (__STDC_VERSION__ >= 199901L)
-#define ECB_C11   (__STDC_VERSION__ >= 201112L)
 #define ECB_CPP   (__cplusplus+0)
 #define ECB_CPP11 (__cplusplus >= 201103L)
 
+#if ECB_CPP
+  #define ECB_C            0
+  #define ECB_STDC_VERSION 0
+#else
+  #define ECB_C            1
+  #define ECB_STDC_VERSION __STDC_VERSION__
+#endif
+
+#define ECB_C99   (ECB_STDC_VERSION >= 199901L)
+#define ECB_C11   (ECB_STDC_VERSION >= 201112L)
+
 #if ECB_CPP
   #define ECB_EXTERN_C extern "C"
   #define ECB_EXTERN_C_BEG ECB_EXTERN_C {
@@ -127,14 +167,18 @@
     #elif defined __ARM_ARCH_7__  || defined __ARM_ARCH_7A__  \
        || defined __ARM_ARCH_7M__ || defined __ARM_ARCH_7R__
       #define ECB_MEMORY_FENCE         __asm__ __volatile__ ("dmb"      : : : "memory")
-    #elif __sparc || __sparc__
+    #elif __aarch64__
+      #define ECB_MEMORY_FENCE         __asm__ __volatile__ ("dmb ish"  : : : "memory")
+    #elif (__sparc || __sparc__) && !__sparcv8
       #define ECB_MEMORY_FENCE         __asm__ __volatile__ ("membar #LoadStore | #LoadLoad | #StoreStore | #StoreLoad" : : : "memory")
       #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad"                            : : : "memory")
       #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("membar #LoadStore             | #StoreStore")
     #elif defined __s390__ || defined __s390x__
       #define ECB_MEMORY_FENCE         __asm__ __volatile__ ("bcr 15,0" : : : "memory")
     #elif defined __mips__
-      #define ECB_MEMORY_FENCE         __asm__ __volatile__ ("sync"     : : : "memory")
+      /* GNU/Linux emulates sync on mips1 architectures, so we force its use */
+      /* anybody else who still uses mips1 is supposed to send in their version, with detection code. */
+      #define ECB_MEMORY_FENCE         __asm__ __volatile__ (".set mips2; sync; .set mips0" : : : "memory")
     #elif defined __alpha__
       #define ECB_MEMORY_FENCE         __asm__ __volatile__ ("mb"       : : : "memory")
     #elif defined __hppa__
@@ -142,6 +186,12 @@
       #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("")
     #elif defined __ia64__
       #define ECB_MEMORY_FENCE         __asm__ __volatile__ ("mf"       : : : "memory")
+    #elif defined __m68k__
+      #define ECB_MEMORY_FENCE         __asm__ __volatile__ (""         : : : "memory")
+    #elif defined __m88k__
+      #define ECB_MEMORY_FENCE         __asm__ __volatile__ ("tb1 0,%%r0,128" : : : "memory")
+    #elif defined __sh__
+      #define ECB_MEMORY_FENCE         __asm__ __volatile__ (""         : : : "memory")
     #endif
   #endif
 #endif
@@ -150,18 +200,23 @@
   #if ECB_GCC_VERSION(4,7)
     /* see comment below (stdatomic.h) about the C11 memory model. */
     #define ECB_MEMORY_FENCE         __atomic_thread_fence (__ATOMIC_SEQ_CST)
+    #define ECB_MEMORY_FENCE_ACQUIRE __atomic_thread_fence (__ATOMIC_ACQUIRE)
+    #define ECB_MEMORY_FENCE_RELEASE __atomic_thread_fence (__ATOMIC_RELEASE)
 
-  /* The __has_feature syntax from clang is so misdesigned that we cannot use it
-   * without risking compile time errors with other compilers. We *could*
-   * define our own ecb_clang_has_feature, but I just can't be bothered to work
-   * around this shit time and again.
-   * #elif defined __clang && __has_feature (cxx_atomic)
-   *   // see comment below (stdatomic.h) about the C11 memory model.
-   *   #define ECB_MEMORY_FENCE         __c11_atomic_thread_fence (__ATOMIC_SEQ_CST)
-   */
+  #elif ECB_CLANG_EXTENSION(c_atomic)
+    /* see comment below (stdatomic.h) about the C11 memory model. */
+    #define ECB_MEMORY_FENCE         __c11_atomic_thread_fence (__ATOMIC_SEQ_CST)
+    #define ECB_MEMORY_FENCE_ACQUIRE __c11_atomic_thread_fence (__ATOMIC_ACQUIRE)
+    #define ECB_MEMORY_FENCE_RELEASE __c11_atomic_thread_fence (__ATOMIC_RELEASE)
 
   #elif ECB_GCC_VERSION(4,4) || defined __INTEL_COMPILER || defined __clang__
     #define ECB_MEMORY_FENCE         __sync_synchronize ()
+  #elif _MSC_VER >= 1500 /* VC++ 2008 */
+    /* apparently, microsoft broke all the memory barrier stuff in Visual Studio 2008... */
+    #pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier)
+    #define ECB_MEMORY_FENCE         _ReadWriteBarrier (); MemoryBarrier()
+    #define ECB_MEMORY_FENCE_ACQUIRE _ReadWriteBarrier (); MemoryBarrier() /* according to msdn, _ReadBarrier is not a load fence */
+    #define ECB_MEMORY_FENCE_RELEASE _WriteBarrier (); MemoryBarrier()
   #elif _MSC_VER >= 1400 /* VC++ 2005 */
     #pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier)
     #define ECB_MEMORY_FENCE         _ReadWriteBarrier ()
@@ -191,6 +246,8 @@
     /* for most usages, or gcc and clang have a bug */
     /* I *currently* lean towards the latter, and inefficiently implement */
     /* all three of ecb's fences as a seq_cst fence */
+    /* Update, gcc-4.8 generates mfence for all c++ fences, but nothing */
+    /* for all __atomic_thread_fence's except seq_cst */
     #define ECB_MEMORY_FENCE         atomic_thread_fence (memory_order_seq_cst)
   #endif
 #endif
@@ -223,7 +280,7 @@
 
 /*****************************************************************************/
 
-#if __cplusplus
+#if ECB_CPP
   #define ecb_inline static inline
 #elif ECB_GCC_VERSION(2,5)
   #define ecb_inline static __inline__
@@ -250,23 +307,47 @@ typedef int ecb_bool;
 
 #define ecb_function_ ecb_inline
 
-#if ECB_GCC_VERSION(3,1)
-  #define ecb_attribute(attrlist)        __attribute__(attrlist)
-  #define ecb_is_constant(expr)          __builtin_constant_p (expr)
-  #define ecb_expect(expr,value)         __builtin_expect ((expr),(value))
-  #define ecb_prefetch(addr,rw,locality) __builtin_prefetch (addr, rw, locality)
+#if ECB_GCC_VERSION(3,1) || ECB_CLANG_VERSION(2,8)
+  #define ecb_attribute(attrlist)        __attribute__ (attrlist)
 #else
   #define ecb_attribute(attrlist)
+#endif
+
+#if ECB_GCC_VERSION(3,1) || ECB_CLANG_BUILTIN(__builtin_constant_p)
+  #define ecb_is_constant(expr)          __builtin_constant_p (expr)
+#else
+  /* possible C11 impl for integral types
+  typedef struct ecb_is_constant_struct ecb_is_constant_struct;
+  #define ecb_is_constant(expr)          _Generic ((1 ? (struct ecb_is_constant_struct *)0 : (void *)((expr) - (expr)), ecb_is_constant_struct *: 0, default: 1)) */
+
   #define ecb_is_constant(expr)          0
+#endif
+
+#if ECB_GCC_VERSION(3,1) || ECB_CLANG_BUILTIN(__builtin_expect)
+  #define ecb_expect(expr,value)         __builtin_expect ((expr),(value))
+#else
   #define ecb_expect(expr,value)         (expr)
+#endif
+
+#if ECB_GCC_VERSION(3,1) || ECB_CLANG_BUILTIN(__builtin_prefetch)
+  #define ecb_prefetch(addr,rw,locality) __builtin_prefetch (addr, rw, locality)
+#else
   #define ecb_prefetch(addr,rw,locality)
 #endif
 
 /* no emulation for ecb_decltype */
-#if ECB_GCC_VERSION(4,5)
-  #define ecb_decltype(x) __decltype(x)
-#elif ECB_GCC_VERSION(3,0)
-  #define ecb_decltype(x) __typeof(x)
+#if ECB_CPP11
+  // older implementations might have problems with decltype(x)::type, work around it
+  template<class T> struct ecb_decltype_t { typedef T type; };
+  #define ecb_decltype(x) ecb_decltype_t<decltype (x)>::type
+#elif ECB_GCC_VERSION(3,0) || ECB_CLANG_VERSION(2,8)
+  #define ecb_decltype(x) __typeof__ (x)
+#endif
+
+#if _MSC_VER >= 1300
+  #define ecb_deprecated __declspec (deprecated)
+#else
+  #define ecb_deprecated ecb_attribute ((__deprecated__))
 #endif
 
 #define ecb_noinline   ecb_attribute ((__noinline__))
@@ -274,7 +355,9 @@ typedef int ecb_bool;
 #define ecb_const      ecb_attribute ((__const__))
 #define ecb_pure       ecb_attribute ((__pure__))
 
-#if ECB_C11
+/* TODO http://msdn.microsoft.com/en-us/library/k6ktzx3s.aspx __declspec(noreturn) */
+#if ECB_C11 || __IBMC_NORETURN
+  /* http://pic.dhe.ibm.com/infocenter/compbg/v121v141/topic/com.ibm.xlcpp121.bg.doc/language_ref/noreturn.html */
   #define ecb_noreturn   _Noreturn
 #else
   #define ecb_noreturn   ecb_attribute ((__noreturn__))
@@ -300,7 +383,10 @@ typedef int ecb_bool;
 #define ecb_unlikely(expr) ecb_expect_false (expr)
 
 /* count trailing zero bits and count # of one bits */
-#if ECB_GCC_VERSION(3,4)
+#if ECB_GCC_VERSION(3,4) \
+    || (ECB_CLANG_BUILTIN(__builtin_clz) && ECB_CLANG_BUILTIN(__builtin_clzll) \
+        && ECB_CLANG_BUILTIN(__builtin_ctz) && ECB_CLANG_BUILTIN(__builtin_ctzll) \
+        && ECB_CLANG_BUILTIN(__builtin_popcount))
   /* we assume int == 32 bit, long == 32 or 64 bit and long long == 64 bit */
   #define ecb_ld32(x)      (__builtin_clz      (x) ^ 31)
   #define ecb_ld64(x)      (__builtin_clzll    (x) ^ 63)
@@ -309,8 +395,8 @@ typedef int ecb_bool;
   #define ecb_popcount32(x) __builtin_popcount (x)
   /* no popcountll */
 #else
-  ecb_function_ int ecb_ctz32 (uint32_t x) ecb_const;
-  ecb_function_ int
+  ecb_function_ ecb_const int ecb_ctz32 (uint32_t x);
+  ecb_function_ ecb_const int
   ecb_ctz32 (uint32_t x)
   {
     int r = 0;
@@ -334,16 +420,16 @@ typedef int ecb_bool;
     return r;
   }
 
-  ecb_function_ int ecb_ctz64 (uint64_t x) ecb_const;
-  ecb_function_ int
+  ecb_function_ ecb_const int ecb_ctz64 (uint64_t x);
+  ecb_function_ ecb_const int
   ecb_ctz64 (uint64_t x)
   {
     int shift = x & 0xffffffffU ? 0 : 32;
     return ecb_ctz32 (x >> shift) + shift;
   }
 
-  ecb_function_ int ecb_popcount32 (uint32_t x) ecb_const;
-  ecb_function_ int
+  ecb_function_ ecb_const int ecb_popcount32 (uint32_t x);
+  ecb_function_ ecb_const int
   ecb_popcount32 (uint32_t x)
   {
     x -=  (x >> 1) & 0x55555555;
@@ -354,8 +440,8 @@ typedef int ecb_bool;
     return x >> 24;
   }
 
-  ecb_function_ int ecb_ld32 (uint32_t x) ecb_const;
-  ecb_function_ int ecb_ld32 (uint32_t x)
+  ecb_function_ ecb_const int ecb_ld32 (uint32_t x);
+  ecb_function_ ecb_const int ecb_ld32 (uint32_t x)
   {
     int r = 0;
 
@@ -368,8 +454,8 @@ typedef int ecb_bool;
     return r;
   }
 
-  ecb_function_ int ecb_ld64 (uint64_t x) ecb_const;
-  ecb_function_ int ecb_ld64 (uint64_t x)
+  ecb_function_ ecb_const int ecb_ld64 (uint64_t x);
+  ecb_function_ ecb_const int ecb_ld64 (uint64_t x)
   {
     int r = 0;
 
@@ -379,20 +465,20 @@ typedef int ecb_bool;
   }
 #endif
 
-ecb_function_ ecb_bool ecb_is_pot32 (uint32_t x) ecb_const;
-ecb_function_ ecb_bool ecb_is_pot32 (uint32_t x) { return !(x & (x - 1)); }
-ecb_function_ ecb_bool ecb_is_pot64 (uint64_t x) ecb_const;
-ecb_function_ ecb_bool ecb_is_pot64 (uint64_t x) { return !(x & (x - 1)); }
+ecb_function_ ecb_const ecb_bool ecb_is_pot32 (uint32_t x);
+ecb_function_ ecb_const ecb_bool ecb_is_pot32 (uint32_t x) { return !(x & (x - 1)); }
+ecb_function_ ecb_const ecb_bool ecb_is_pot64 (uint64_t x);
+ecb_function_ ecb_const ecb_bool ecb_is_pot64 (uint64_t x) { return !(x & (x - 1)); }
 
-ecb_function_ uint8_t  ecb_bitrev8  (uint8_t  x) ecb_const;
-ecb_function_ uint8_t  ecb_bitrev8  (uint8_t  x)
+ecb_function_ ecb_const uint8_t  ecb_bitrev8  (uint8_t  x);
+ecb_function_ ecb_const uint8_t  ecb_bitrev8  (uint8_t  x)
 {
   return (  (x * 0x0802U & 0x22110U)
-          | (x * 0x8020U & 0x88440U)) * 0x10101U >> 16; 
+          | (x * 0x8020U & 0x88440U)) * 0x10101U >> 16;
 }
 
-ecb_function_ uint16_t ecb_bitrev16 (uint16_t x) ecb_const;
-ecb_function_ uint16_t ecb_bitrev16 (uint16_t x)
+ecb_function_ ecb_const uint16_t ecb_bitrev16 (uint16_t x);
+ecb_function_ ecb_const uint16_t ecb_bitrev16 (uint16_t x)
 {
   x = ((x >>  1) &     0x5555) | ((x &     0x5555) <<  1);
   x = ((x >>  2) &     0x3333) | ((x &     0x3333) <<  2);
@@ -402,8 +488,8 @@ ecb_function_ uint16_t ecb_bitrev16 (uint16_t x)
   return x;
 }
 
-ecb_function_ uint32_t ecb_bitrev32 (uint32_t x) ecb_const;
-ecb_function_ uint32_t ecb_bitrev32 (uint32_t x)
+ecb_function_ ecb_const uint32_t ecb_bitrev32 (uint32_t x);
+ecb_function_ ecb_const uint32_t ecb_bitrev32 (uint32_t x)
 {
   x = ((x >>  1) & 0x55555555) | ((x & 0x55555555) <<  1);
   x = ((x >>  2) & 0x33333333) | ((x & 0x33333333) <<  2);
@@ -416,71 +502,71 @@ ecb_function_ uint32_t ecb_bitrev32 (uint32_t x)
 
 /* popcount64 is only available on 64 bit cpus as gcc builtin */
 /* so for this version we are lazy */
-ecb_function_ int ecb_popcount64 (uint64_t x) ecb_const;
-ecb_function_ int
+ecb_function_ ecb_const int ecb_popcount64 (uint64_t x);
+ecb_function_ ecb_const int
 ecb_popcount64 (uint64_t x)
 {
   return ecb_popcount32 (x) + ecb_popcount32 (x >> 32);
 }
 
-ecb_inline uint8_t  ecb_rotl8  (uint8_t  x, unsigned int count) ecb_const;
-ecb_inline uint8_t  ecb_rotr8  (uint8_t  x, unsigned int count) ecb_const;
-ecb_inline uint16_t ecb_rotl16 (uint16_t x, unsigned int count) ecb_const;
-ecb_inline uint16_t ecb_rotr16 (uint16_t x, unsigned int count) ecb_const;
-ecb_inline uint32_t ecb_rotl32 (uint32_t x, unsigned int count) ecb_const;
-ecb_inline uint32_t ecb_rotr32 (uint32_t x, unsigned int count) ecb_const;
-ecb_inline uint64_t ecb_rotl64 (uint64_t x, unsigned int count) ecb_const;
-ecb_inline uint64_t ecb_rotr64 (uint64_t x, unsigned int count) ecb_const;
-
-ecb_inline uint8_t  ecb_rotl8  (uint8_t  x, unsigned int count) { return (x >> ( 8 - count)) | (x << count); }
-ecb_inline uint8_t  ecb_rotr8  (uint8_t  x, unsigned int count) { return (x << ( 8 - count)) | (x >> count); }
-ecb_inline uint16_t ecb_rotl16 (uint16_t x, unsigned int count) { return (x >> (16 - count)) | (x << count); }
-ecb_inline uint16_t ecb_rotr16 (uint16_t x, unsigned int count) { return (x << (16 - count)) | (x >> count); }
-ecb_inline uint32_t ecb_rotl32 (uint32_t x, unsigned int count) { return (x >> (32 - count)) | (x << count); }
-ecb_inline uint32_t ecb_rotr32 (uint32_t x, unsigned int count) { return (x << (32 - count)) | (x >> count); }
-ecb_inline uint64_t ecb_rotl64 (uint64_t x, unsigned int count) { return (x >> (64 - count)) | (x << count); }
-ecb_inline uint64_t ecb_rotr64 (uint64_t x, unsigned int count) { return (x << (64 - count)) | (x >> count); }
-
-#if ECB_GCC_VERSION(4,3)
+ecb_inline ecb_const uint8_t  ecb_rotl8  (uint8_t  x, unsigned int count);
+ecb_inline ecb_const uint8_t  ecb_rotr8  (uint8_t  x, unsigned int count);
+ecb_inline ecb_const uint16_t ecb_rotl16 (uint16_t x, unsigned int count);
+ecb_inline ecb_const uint16_t ecb_rotr16 (uint16_t x, unsigned int count);
+ecb_inline ecb_const uint32_t ecb_rotl32 (uint32_t x, unsigned int count);
+ecb_inline ecb_const uint32_t ecb_rotr32 (uint32_t x, unsigned int count);
+ecb_inline ecb_const uint64_t ecb_rotl64 (uint64_t x, unsigned int count);
+ecb_inline ecb_const uint64_t ecb_rotr64 (uint64_t x, unsigned int count);
+
+ecb_inline ecb_const uint8_t  ecb_rotl8  (uint8_t  x, unsigned int count) { return (x >> ( 8 - count)) | (x << count); }
+ecb_inline ecb_const uint8_t  ecb_rotr8  (uint8_t  x, unsigned int count) { return (x << ( 8 - count)) | (x >> count); }
+ecb_inline ecb_const uint16_t ecb_rotl16 (uint16_t x, unsigned int count) { return (x >> (16 - count)) | (x << count); }
+ecb_inline ecb_const uint16_t ecb_rotr16 (uint16_t x, unsigned int count) { return (x << (16 - count)) | (x >> count); }
+ecb_inline ecb_const uint32_t ecb_rotl32 (uint32_t x, unsigned int count) { return (x >> (32 - count)) | (x << count); }
+ecb_inline ecb_const uint32_t ecb_rotr32 (uint32_t x, unsigned int count) { return (x << (32 - count)) | (x >> count); }
+ecb_inline ecb_const uint64_t ecb_rotl64 (uint64_t x, unsigned int count) { return (x >> (64 - count)) | (x << count); }
+ecb_inline ecb_const uint64_t ecb_rotr64 (uint64_t x, unsigned int count) { return (x << (64 - count)) | (x >> count); }
+
+#if ECB_GCC_VERSION(4,3) || (ECB_CLANG_BUILTIN(__builtin_bswap32) && ECB_CLANG_BUILTIN(__builtin_bswap64))
   #define ecb_bswap16(x) (__builtin_bswap32 (x) >> 16)
   #define ecb_bswap32(x)  __builtin_bswap32 (x)
   #define ecb_bswap64(x)  __builtin_bswap64 (x)
 #else
-  ecb_function_ uint16_t ecb_bswap16 (uint16_t x) ecb_const;
-  ecb_function_ uint16_t
+  ecb_function_ ecb_const uint16_t ecb_bswap16 (uint16_t x);
+  ecb_function_ ecb_const uint16_t
   ecb_bswap16 (uint16_t x)
   {
     return ecb_rotl16 (x, 8);
   }
 
-  ecb_function_ uint32_t ecb_bswap32 (uint32_t x) ecb_const;
-  ecb_function_ uint32_t
+  ecb_function_ ecb_const uint32_t ecb_bswap32 (uint32_t x);
+  ecb_function_ ecb_const uint32_t
   ecb_bswap32 (uint32_t x)
   {
     return (((uint32_t)ecb_bswap16 (x)) << 16) | ecb_bswap16 (x >> 16);
   }
 
-  ecb_function_ uint64_t ecb_bswap64 (uint64_t x) ecb_const;
-  ecb_function_ uint64_t
+  ecb_function_ ecb_const uint64_t ecb_bswap64 (uint64_t x);
+  ecb_function_ ecb_const uint64_t
   ecb_bswap64 (uint64_t x)
   {
     return (((uint64_t)ecb_bswap32 (x)) << 32) | ecb_bswap32 (x >> 32);
   }
 #endif
 
-#if ECB_GCC_VERSION(4,5)
+#if ECB_GCC_VERSION(4,5) || ECB_CLANG_BUILTIN(__builtin_unreachable)
   #define ecb_unreachable() __builtin_unreachable ()
 #else
   /* this seems to work fine, but gcc always emits a warning for it :/ */
-  ecb_inline void ecb_unreachable (void) ecb_noreturn;
-  ecb_inline void ecb_unreachable (void) { }
+  ecb_inline ecb_noreturn void ecb_unreachable (void);
+  ecb_inline ecb_noreturn void ecb_unreachable (void) { }
 #endif
 
 /* try to tell the compiler that some condition is definitely true */
 #define ecb_assume(cond) if (!(cond)) ecb_unreachable (); else 0
 
-ecb_inline unsigned char ecb_byteorder_helper (void) ecb_const;
-ecb_inline unsigned char
+ecb_inline ecb_const unsigned char ecb_byteorder_helper (void);
+ecb_inline ecb_const unsigned char
 ecb_byteorder_helper (void)
 {
   /* the union code still generates code under pressure in gcc, */
@@ -505,10 +591,10 @@ ecb_byteorder_helper (void)
 #endif
 }
 
-ecb_inline ecb_bool ecb_big_endian    (void) ecb_const;
-ecb_inline ecb_bool ecb_big_endian    (void) { return ecb_byteorder_helper () == 0x11; }
-ecb_inline ecb_bool ecb_little_endian (void) ecb_const;
-ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44; }
+ecb_inline ecb_const ecb_bool ecb_big_endian    (void);
+ecb_inline ecb_const ecb_bool ecb_big_endian    (void) { return ecb_byteorder_helper () == 0x11; }
+ecb_inline ecb_const ecb_bool ecb_little_endian (void);
+ecb_inline ecb_const ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44; }
 
 #if ECB_GCC_VERSION(3,0) || ECB_C99
   #define ecb_mod(m,n) ((m) % (n) + ((m) % (n) < 0 ? (n) : 0))
@@ -516,7 +602,7 @@ ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () ==
   #define ecb_mod(m,n) ((m) < 0 ? ((n) - 1 - ((-1 - (m)) % (n))) : ((m) % (n)))
 #endif
 
-#if __cplusplus
+#if ECB_CPP
   template<typename T>
   static inline T ecb_div_rd (T val, T div)
   {
@@ -552,25 +638,66 @@ ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () ==
     || __i386 || __i386__ \
     || __amd64 || __amd64__ || __x86_64 || __x86_64__ \
     || __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__ \
-    || defined __arm__ && defined __ARM_EABI__ \
     || defined __s390__ || defined __s390x__ \
     || defined __mips__ \
     || defined __alpha__ \
     || defined __hppa__ \
     || defined __ia64__ \
-    || defined _M_IX86 || defined _M_AMD64 || defined _M_IA64
+    || defined __m68k__ \
+    || defined __m88k__ \
+    || defined __sh__ \
+    || defined _M_IX86 || defined _M_AMD64 || defined _M_IA64 \
+    || (defined __arm__ && (defined __ARM_EABI__ || defined __EABI__ || defined __VFP_FP__ || defined _WIN32_WCE || defined __ANDROID__)) \
+    || defined __aarch64__
   #define ECB_STDFP 1
   #include <string.h> /* for memcpy */
 #else
   #define ECB_STDFP 0
-  #include <math.h> /* for frexp*, ldexp* */
 #endif
 
 #ifndef ECB_NO_LIBM
 
+  #include <math.h> /* for frexp*, ldexp*, INFINITY, NAN */
+
+  /* only the oldest of old doesn't have this one. solaris. */
+  #ifdef INFINITY
+    #define ECB_INFINITY INFINITY
+  #else
+    #define ECB_INFINITY HUGE_VAL
+  #endif
+
+  #ifdef NAN
+    #define ECB_NAN NAN
+  #else
+    #define ECB_NAN ECB_INFINITY
+  #endif
+
+  #if ECB_C99 || _XOPEN_VERSION >= 600 || _POSIX_VERSION >= 200112L
+    #define ecb_ldexpf(x,e) ldexpf ((x), (e))
+  #else
+    #define ecb_ldexpf(x,e) (float) ldexp ((x), (e))
+  #endif
+
+  /* converts an ieee half/binary16 to a float */
+  ecb_function_ ecb_const float ecb_binary16_to_float (uint16_t x);
+  ecb_function_ ecb_const float
+  ecb_binary16_to_float (uint16_t x)
+  {
+    int e = (x >> 10) & 0x1f;
+    int m = x & 0x3ff;
+    float r;
+
+    if      (!e     ) r = ecb_ldexpf (m        ,    -24);
+    else if (e != 31) r = ecb_ldexpf (m + 0x400, e - 25);
+    else if (m      ) r = ECB_NAN;
+    else              r = ECB_INFINITY;
+
+    return x & 0x8000 ? -r : r;
+  }
+
   /* convert a float to ieee single/binary32 */
-  ecb_function_ uint32_t ecb_float_to_binary32 (float x) ecb_const;
-  ecb_function_ uint32_t
+  ecb_function_ ecb_const uint32_t ecb_float_to_binary32 (float x);
+  ecb_function_ ecb_const uint32_t
   ecb_float_to_binary32 (float x)
   {
     uint32_t r;
@@ -609,8 +736,8 @@ ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () ==
   }
 
   /* converts an ieee single/binary32 to a float */
-  ecb_function_ float ecb_binary32_to_float (uint32_t x) ecb_const;
-  ecb_function_ float
+  ecb_function_ ecb_const float ecb_binary32_to_float (uint32_t x);
+  ecb_function_ ecb_const float
   ecb_binary32_to_float (uint32_t x)
   {
     float r;
@@ -630,7 +757,7 @@ ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () ==
         e = 1;
 
       /* we distrust ldexpf a bit and do the 2**-24 scaling by an extra multiply */
-      r = ldexpf (x * (0.5f / 0x800000U), e - 126);
+      r = ecb_ldexpf (x * (0.5f / 0x800000U), e - 126);
 
       r = neg ? -r : r;
     #endif
@@ -639,8 +766,8 @@ ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () ==
   }
 
   /* convert a double to ieee double/binary64 */
-  ecb_function_ uint64_t ecb_double_to_binary64 (double x) ecb_const;
-  ecb_function_ uint64_t
+  ecb_function_ ecb_const uint64_t ecb_double_to_binary64 (double x);
+  ecb_function_ ecb_const uint64_t
   ecb_double_to_binary64 (double x)
   {
     uint64_t r;
@@ -679,8 +806,8 @@ ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () ==
   }
 
   /* converts an ieee double/binary64 to a double */
-  ecb_function_ double ecb_binary64_to_double (uint64_t x) ecb_const;
-  ecb_function_ double
+  ecb_function_ ecb_const double ecb_binary64_to_double (uint64_t x);
+  ecb_function_ ecb_const double
   ecb_binary64_to_double (uint64_t x)
   {
     double r;
diff --git a/third_party/libeio/eio.c b/third_party/libeio/eio.c
index c5396c92e5aeb973921e82d77d0abaebd4a8af29..c83a467ded5ddb0391edd0bf22467938ac278d80 100644
--- a/third_party/libeio/eio.c
+++ b/third_party/libeio/eio.c
@@ -1,19 +1,19 @@
 /*
  * libeio implementation
  *
- * Copyright (c) 2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann <libeio@schmorp.de>
+ * Copyright (c) 2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann <libeio@schmorp.de>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modifica-
  * tion, are permitted provided that the following conditions are met:
- * 
+ *
  *   1.  Redistributions of source code must retain the above copyright notice,
  *       this list of conditions and the following disclaimer.
- * 
+ *
  *   2.  Redistributions in binary form must reproduce the above copyright
  *       notice, this list of conditions and the following disclaimer in the
  *       documentation and/or other materials provided with the distribution.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
  * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
@@ -214,9 +214,9 @@ static void eio_destroy (eio_req *req);
     return EIO_ERRNO (ENOENT, -1);
   }
 
-  /* POSIX API only */
-  #define CreateHardLink(neu,old,flags) 0
-  #define CreateSymbolicLink(neu,old,flags) 0
+  /* POSIX API only, causing trouble for win32 apps */
+  #define CreateHardLink(neu,old,flags) 0 /* not really creating hardlink, still using relative paths? */
+  #define CreateSymbolicLink(neu,old,flags) 0 /* vista+ only */
 
   struct statvfs
   {
@@ -232,11 +232,19 @@ static void eio_destroy (eio_req *req);
 
   #include <sys/time.h>
   #include <sys/select.h>
-  #include <sys/statvfs.h>
   #include <unistd.h>
   #include <signal.h>
   #include <dirent.h>
 
+  #ifdef ANDROID
+    #include <sys/vfs.h>
+    #define statvfs statfs
+    #define fstatvfs fstatfs
+    #include <asm/page.h> /* supposedly limits.h does #define PAGESIZE PAGESIZE */
+  #else
+    #include <sys/statvfs.h>
+  #endif
+
   #if _POSIX_MEMLOCK || _POSIX_MEMLOCK_RANGE || _POSIX_MAPPED_FILES
     #include <sys/mman.h>
   #endif
@@ -317,7 +325,7 @@ static void eio_destroy (eio_req *req);
 /* buffer size for various temporary buffers */
 #define EIO_BUFSIZE 65536
 
-#define dBUF	 				\
+#define dBUF					\
   char *eio_buf = malloc (EIO_BUFSIZE);		\
   errno = ENOMEM;				\
   if (!eio_buf)					\
@@ -326,8 +334,6 @@ static void eio_destroy (eio_req *req);
 #define FUBd					\
   free (eio_buf)
 
-#define EIO_TICKS ((1000000 + 1023) >> 10)
-
 /*****************************************************************************/
 
 struct tmpbuf
@@ -375,6 +381,9 @@ struct eio_pwd
 #define ETP_PRI_MIN EIO_PRI_MIN
 #define ETP_PRI_MAX EIO_PRI_MAX
 
+#define ETP_TYPE_QUIT -1
+#define ETP_TYPE_GROUP EIO_GROUP
+
 struct etp_worker;
 
 #define ETP_REQ eio_req
@@ -382,434 +391,9 @@ struct etp_worker;
 static int eio_finish (eio_req *req);
 #define ETP_FINISH(req)  eio_finish (req)
 static void eio_execute (struct etp_worker *self, eio_req *req);
-#define ETP_EXECUTE(wrk,req) eio_execute (wrk,req)
-
-/*****************************************************************************/
-
-#define ETP_NUM_PRI (ETP_PRI_MAX - ETP_PRI_MIN + 1)
-
-/* calculate time difference in ~1/EIO_TICKS of a second */
-ecb_inline int
-tvdiff (struct timeval *tv1, struct timeval *tv2)
-{
-  return  (tv2->tv_sec  - tv1->tv_sec ) * EIO_TICKS
-       + ((tv2->tv_usec - tv1->tv_usec) >> 10);
-}
-
-static unsigned int started, idle, wanted = 4;
-
-static void (*want_poll_cb) (void);
-static void (*done_poll_cb) (void);
- 
-static unsigned int max_poll_time;     /* reslock */
-static unsigned int max_poll_reqs;     /* reslock */
-
-static unsigned int nreqs;    /* reqlock */
-static unsigned int nready;   /* reqlock */
-static unsigned int npending; /* reqlock */
-static unsigned int max_idle = 4;      /* maximum number of threads that can idle indefinitely */
-static unsigned int idle_timeout = 10; /* number of seconds after which an idle threads exit */
-
-static xmutex_t wrklock;
-static xmutex_t reslock;
-static xmutex_t reqlock;
-static xcond_t  reqwait;
-
-typedef struct etp_worker
-{
-  struct tmpbuf tmpbuf;
-
-  /* locked by wrklock */
-  struct etp_worker *prev, *next;
-
-  xthread_t tid;
-
-#ifdef ETP_WORKER_COMMON
-  ETP_WORKER_COMMON
-#endif
-} etp_worker;
-
-static etp_worker wrk_first; /* NOT etp */
-
-#define ETP_WORKER_LOCK(wrk)   X_LOCK   (wrklock)
-#define ETP_WORKER_UNLOCK(wrk) X_UNLOCK (wrklock)
-
-/* worker threads management */
-
-static void
-etp_worker_clear (etp_worker *wrk)
-{
-}
-
-static void ecb_cold
-etp_worker_free (etp_worker *wrk)
-{
-  free (wrk->tmpbuf.ptr);
+#define ETP_EXECUTE(wrk,req) eio_execute (wrk, req)
 
-  wrk->next->prev = wrk->prev;
-  wrk->prev->next = wrk->next;
-
-  free (wrk);
-}
-
-static unsigned int
-etp_nreqs (void)
-{
-  int retval;
-  if (WORDACCESS_UNSAFE) X_LOCK   (reqlock);
-  retval = nreqs;
-  if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock);
-  return retval;
-}
-
-static unsigned int
-etp_nready (void)
-{
-  unsigned int retval;
-
-  if (WORDACCESS_UNSAFE) X_LOCK   (reqlock);
-  retval = nready;
-  if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock);
-
-  return retval;
-}
-
-static unsigned int
-etp_npending (void)
-{
-  unsigned int retval;
-
-  if (WORDACCESS_UNSAFE) X_LOCK   (reqlock);
-  retval = npending;
-  if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock);
-
-  return retval;
-}
-
-static unsigned int
-etp_nthreads (void)
-{
-  unsigned int retval;
-
-  if (WORDACCESS_UNSAFE) X_LOCK   (reqlock);
-  retval = started;
-  if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock);
-
-  return retval;
-}
-
-/*
- * a somewhat faster data structure might be nice, but
- * with 8 priorities this actually needs <20 insns
- * per shift, the most expensive operation.
- */
-typedef struct {
-  ETP_REQ *qs[ETP_NUM_PRI], *qe[ETP_NUM_PRI]; /* qstart, qend */
-  int size;
-} etp_reqq;
-
-static etp_reqq req_queue;
-static etp_reqq res_queue;
-
-static void ecb_noinline ecb_cold
-reqq_init (etp_reqq *q)
-{
-  int pri;
-
-  for (pri = 0; pri < ETP_NUM_PRI; ++pri)
-    q->qs[pri] = q->qe[pri] = 0;
-
-  q->size = 0;
-}
-
-static int ecb_noinline
-reqq_push (etp_reqq *q, ETP_REQ *req)
-{
-  int pri = req->pri;
-  req->next = 0;
-
-  if (q->qe[pri])
-    {
-      q->qe[pri]->next = req;
-      q->qe[pri] = req;
-    }
-  else
-    q->qe[pri] = q->qs[pri] = req;
-
-  return q->size++;
-}
-
-static ETP_REQ * ecb_noinline
-reqq_shift (etp_reqq *q)
-{
-  int pri;
-
-  if (!q->size)
-    return 0;
-
-  --q->size;
-
-  for (pri = ETP_NUM_PRI; pri--; )
-    {
-      eio_req *req = q->qs[pri];
-
-      if (req)
-        {
-          if (!(q->qs[pri] = (eio_req *)req->next))
-            q->qe[pri] = 0;
-
-          return req;
-        }
-    }
-
-  abort ();
-}
-
-static int ecb_cold
-etp_init (void (*want_poll)(void), void (*done_poll)(void))
-{
-  X_MUTEX_CREATE (wrklock);
-  X_MUTEX_CREATE (reslock);
-  X_MUTEX_CREATE (reqlock);
-  X_COND_CREATE  (reqwait);
-
-  reqq_init (&req_queue);
-  reqq_init (&res_queue);
-
-  wrk_first.next =
-  wrk_first.prev = &wrk_first;
-
-  started  = 0;
-  idle     = 0;
-  nreqs    = 0;
-  nready   = 0;
-  npending = 0;
-
-  want_poll_cb = want_poll;
-  done_poll_cb = done_poll;
-
-  return 0;
-}
-
-X_THREAD_PROC (etp_proc);
-
-static void ecb_cold
-etp_start_thread (void)
-{
-  etp_worker *wrk = calloc (1, sizeof (etp_worker));
-
-  /*TODO*/
-  assert (("unable to allocate worker thread data", wrk));
-
-  X_LOCK (wrklock);
-
-  if (xthread_create (&wrk->tid, etp_proc, (void *)wrk))
-    {
-      wrk->prev = &wrk_first;
-      wrk->next = wrk_first.next;
-      wrk_first.next->prev = wrk;
-      wrk_first.next = wrk;
-      ++started;
-    }
-  else
-    free (wrk);
-
-  X_UNLOCK (wrklock);
-}
-
-static void
-etp_maybe_start_thread (void)
-{
-  if (ecb_expect_true (etp_nthreads () >= wanted))
-    return;
-  
-  /* todo: maybe use idle here, but might be less exact */
-  if (ecb_expect_true (0 <= (int)etp_nthreads () + (int)etp_npending () - (int)etp_nreqs ()))
-    return;
-
-  etp_start_thread ();
-}
-
-static void ecb_cold
-etp_end_thread (void)
-{
-  eio_req *req = calloc (1, sizeof (eio_req)); /* will be freed by worker */
-
-  req->type = -1;
-  req->pri  = ETP_PRI_MAX - ETP_PRI_MIN;
-
-  X_LOCK (reqlock);
-  reqq_push (&req_queue, req);
-  X_COND_SIGNAL (reqwait);
-  X_UNLOCK (reqlock);
-
-  X_LOCK (wrklock);
-  --started;
-  X_UNLOCK (wrklock);
-}
-
-static int
-etp_poll (void)
-{
-  unsigned int maxreqs;
-  unsigned int maxtime;
-  struct timeval tv_start, tv_now;
-
-  X_LOCK (reslock);
-  maxreqs = max_poll_reqs;
-  maxtime = max_poll_time;
-  X_UNLOCK (reslock);
-
-  if (maxtime)
-    gettimeofday (&tv_start, 0);
-
-  for (;;)
-    {
-      ETP_REQ *req;
-
-      etp_maybe_start_thread ();
-
-      X_LOCK (reslock);
-      req = reqq_shift (&res_queue);
-
-      if (req)
-        {
-          --npending;
-
-          if (!res_queue.size && done_poll_cb)
-            done_poll_cb ();
-        }
-
-      X_UNLOCK (reslock);
-
-      if (!req)
-        return 0;
-
-      X_LOCK (reqlock);
-      --nreqs;
-      X_UNLOCK (reqlock);
-
-      if (ecb_expect_false (req->type == EIO_GROUP && req->size))
-        {
-          req->int1 = 1; /* mark request as delayed */
-          continue;
-        }
-      else
-        {
-          int res = ETP_FINISH (req);
-          if (ecb_expect_false (res))
-            return res;
-        }
-
-      if (ecb_expect_false (maxreqs && !--maxreqs))
-        break;
-
-      if (maxtime)
-        {
-          gettimeofday (&tv_now, 0);
-
-          if (tvdiff (&tv_start, &tv_now) >= maxtime)
-            break;
-        }
-    }
-
-  errno = EAGAIN;
-  return -1;
-}
-
-static void
-etp_cancel (ETP_REQ *req)
-{
-  req->cancelled = 1;
-
-  eio_grp_cancel (req);
-}
-
-static void
-etp_submit (ETP_REQ *req)
-{
-  req->pri -= ETP_PRI_MIN;
-
-  if (ecb_expect_false (req->pri < ETP_PRI_MIN - ETP_PRI_MIN)) req->pri = ETP_PRI_MIN - ETP_PRI_MIN;
-  if (ecb_expect_false (req->pri > ETP_PRI_MAX - ETP_PRI_MIN)) req->pri = ETP_PRI_MAX - ETP_PRI_MIN;
-
-  if (ecb_expect_false (req->type == EIO_GROUP))
-    {
-      /* I hope this is worth it :/ */
-      X_LOCK (reqlock);
-      ++nreqs;
-      X_UNLOCK (reqlock);
-
-      X_LOCK (reslock);
-
-      ++npending;
-
-      if (!reqq_push (&res_queue, req) && want_poll_cb)
-        want_poll_cb ();
-
-      X_UNLOCK (reslock);
-    }
-  else
-    {
-      X_LOCK (reqlock);
-      ++nreqs;
-      ++nready;
-      reqq_push (&req_queue, req);
-      X_COND_SIGNAL (reqwait);
-      X_UNLOCK (reqlock);
-
-      etp_maybe_start_thread ();
-    }
-}
-
-static void ecb_cold
-etp_set_max_poll_time (double nseconds)
-{
-  if (WORDACCESS_UNSAFE) X_LOCK   (reslock);
-  max_poll_time = nseconds * EIO_TICKS;
-  if (WORDACCESS_UNSAFE) X_UNLOCK (reslock);
-}
-
-static void ecb_cold
-etp_set_max_poll_reqs (unsigned int maxreqs)
-{
-  if (WORDACCESS_UNSAFE) X_LOCK   (reslock);
-  max_poll_reqs = maxreqs;
-  if (WORDACCESS_UNSAFE) X_UNLOCK (reslock);
-}
-
-static void ecb_cold
-etp_set_max_idle (unsigned int nthreads)
-{
-  if (WORDACCESS_UNSAFE) X_LOCK   (reqlock);
-  max_idle = nthreads;
-  if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock);
-}
-
-static void ecb_cold
-etp_set_idle_timeout (unsigned int seconds)
-{
-  if (WORDACCESS_UNSAFE) X_LOCK   (reqlock);
-  idle_timeout = seconds;
-  if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock);
-}
-
-static void ecb_cold
-etp_set_min_parallel (unsigned int nthreads)
-{
-  if (wanted < nthreads)
-    wanted = nthreads;
-}
-
-static void ecb_cold
-etp_set_max_parallel (unsigned int nthreads)
-{
-  if (wanted > nthreads)
-    wanted = nthreads;
-
-  while (started > wanted)
-    etp_end_thread ();
-}
+#include "etp.c"
 
 /*****************************************************************************/
 
@@ -886,8 +470,7 @@ eio_finish (eio_req *req)
 void
 eio_grp_cancel (eio_req *grp)
 {
-  for (grp = grp->grp_first; grp; grp = grp->grp_next)
-    eio_cancel (grp);
+  etp_grp_cancel (grp);
 }
 
 void
@@ -1386,8 +969,8 @@ eio__lseek (eio_req *req)
 static int
 eio__realpath (struct tmpbuf *tmpbuf, eio_wd wd, const char *path)
 {
-  const char *rel = path;
   char *res;
+  const char *rel = path;
   char *tmp1, *tmp2;
 #if SYMLOOP_MAX > 32
   int symlinks = SYMLOOP_MAX;
@@ -1404,6 +987,23 @@ eio__realpath (struct tmpbuf *tmpbuf, eio_wd wd, const char *path)
     return -1;
 
   res  = tmpbuf_get (tmpbuf, PATH_MAX * 3);
+#ifdef _WIN32
+  if (_access (rel, 4) != 0)
+    return -1;
+
+  symlinks = GetFullPathName (rel, PATH_MAX * 3, res, 0);
+
+  errno = ENAMETOOLONG;
+  if (symlinks >= PATH_MAX * 3)
+    return -1;
+
+  errno = EIO;
+  if (symlinks <= 0)
+    return -1;
+
+  return symlinks;
+
+#else
   tmp1 = res  + PATH_MAX;
   tmp2 = tmp1 + PATH_MAX;
 
@@ -1417,15 +1017,14 @@ eio__realpath (struct tmpbuf *tmpbuf, eio_wd wd, const char *path)
       {
         sprintf (tmp1, "/proc/self/fd/%d", fd);
         req->result = readlink (tmp1, res, PATH_MAX);
-        close (fd);
-
         /* here we should probably stat the open file and the disk file, to make sure they still match */
+        close (fd);
 
         if (req->result > 0)
           goto done;
       }
     else if (errno == ELOOP || errno == ENAMETOOLONG || errno == ENOENT || errno == ENOTDIR || errno == EIO)
-      return;
+      return -1;
   }
 #endif
 #endif
@@ -1537,6 +1136,7 @@ eio__realpath (struct tmpbuf *tmpbuf, eio_wd wd, const char *path)
     *res++ = '/';
 
   return res - (char *)tmpbuf->ptr;
+#endif
 }
 
 static signed char
@@ -2150,6 +1750,7 @@ etp_proc_init (void)
 #endif
 }
 
+/* TODO: move somehow to etp.c */
 X_THREAD_PROC (etp_proc)
 {
   ETP_REQ *req;
@@ -2205,7 +1806,7 @@ X_THREAD_PROC (etp_proc)
 
       X_UNLOCK (reqlock);
      
-      if (req->type < 0)
+      if (req->type == ETP_TYPE_QUIT)
         goto quit;
 
       ETP_EXECUTE (self, req);
@@ -2270,6 +1871,8 @@ eio_api_destroy (eio_req *req)
       return 0;							\
     }
 
+#define SINGLEDOT(ptr) (0[(char *)(ptr)] == '.' && !1[(char *)(ptr)])
+
 static void
 eio_execute (etp_worker *self, eio_req *req)
 {
@@ -2334,9 +1937,15 @@ eio_execute (etp_worker *self, eio_req *req)
       case EIO_OPEN:      req->result = openat    (dirfd, req->ptr1, req->int1, (mode_t)req->int2); break;
 
       case EIO_UNLINK:    req->result = unlinkat  (dirfd, req->ptr1, 0); break;
-      case EIO_RMDIR:     req->result = unlinkat  (dirfd, req->ptr1, AT_REMOVEDIR); break;
+      case EIO_RMDIR:     /* complications arise because "." cannot be removed, so we might have to expand */
+                          req->result = req->wd && SINGLEDOT (req->ptr1)
+                             ? rmdir (req->wd->str)
+                             : unlinkat  (dirfd, req->ptr1, AT_REMOVEDIR); break;
       case EIO_MKDIR:     req->result = mkdirat   (dirfd, req->ptr1, (mode_t)req->int2); break;
-      case EIO_RENAME:    req->result = renameat  (dirfd, req->ptr1, WD2FD ((eio_wd)req->int3), req->ptr2); break;
+      case EIO_RENAME:    /* complications arise because "." cannot be renamed, so we might have to expand */
+                          req->result = req->wd && SINGLEDOT (req->ptr1)
+                             ? rename (req->wd->str, req->ptr2)
+                             : renameat (dirfd, req->ptr1, WD2FD ((eio_wd)req->int3), req->ptr2); break;
       case EIO_LINK:      req->result = linkat    (dirfd, req->ptr1, WD2FD ((eio_wd)req->int3), req->ptr2, 0); break;
       case EIO_SYMLINK:   req->result = symlinkat (req->ptr1, dirfd, req->ptr2); break;
       case EIO_MKNOD:     req->result = mknodat   (dirfd, req->ptr1, (mode_t)req->int2, (dev_t)req->offs); break;
diff --git a/third_party/libeio/eio.h b/third_party/libeio/eio.h
index f97f48fce655f2088986476d2daeb62dc15ef6a9..b61a8855d593ea727ce32ca2930c89b5f160fba6 100644
--- a/third_party/libeio/eio.h
+++ b/third_party/libeio/eio.h
@@ -256,21 +256,21 @@ struct eio_req
   eio_tstamp nv1;  /* utime, futime: atime; busy: sleep time */
   eio_tstamp nv2;  /* utime, futime: mtime */
 
-  int type;        /* EIO_xxx constant ETP */
   int int1;        /* all applicable requests: file descriptor; sendfile: output fd; open, msync, mlockall, readdir: flags */
   long int2;       /* chown, fchown: uid; sendfile: input fd; open, chmod, mkdir, mknod: file mode, seek: whence, sync_file_range, fallocate: flags */
   long int3;       /* chown, fchown: gid; rename, link: working directory of new name */
   int errorno;     /* errno value on syscall return */
 
+  unsigned char flags; /* private */
+
+  signed char type;/* EIO_xxx constant ETP */
+  signed char pri;     /* the priority ETP */
 #if __i386 || __amd64
-  unsigned char cancelled;
+  unsigned char cancelled; /* ETP */
 #else
-  sig_atomic_t cancelled;
+  sig_atomic_t  cancelled; /* ETP */
 #endif
 
-  unsigned char flags; /* private */
-  signed char pri;     /* the priority */
-
   void *data;
   eio_cb finish;
   void (*destroy)(eio_req *req); /* called when request no longer needed */
@@ -278,7 +278,7 @@ struct eio_req
 
   EIO_REQ_MEMBERS
 
-  eio_req *grp, *grp_prev, *grp_next, *grp_first; /* private */
+  eio_req *grp, *grp_prev, *grp_next, *grp_first; /* private ETP */
 };
 
 /* _private_ request flags */
diff --git a/third_party/libeio/eio.pod b/third_party/libeio/eio.pod
index 83a59894195cfdff24f6a78ba9ff103b01fe10f9..6afff56b637a638ad44a16e248a5d5935232646d 100644
--- a/third_party/libeio/eio.pod
+++ b/third_party/libeio/eio.pod
@@ -27,7 +27,7 @@ or C<readlink>.
 
 It also offers wrappers around C<sendfile> (Solaris, Linux, HP-UX and
 FreeBSD, with emulation on other platforms) and C<readahead> (Linux, with
-emulation elsewhere>).
+emulation elsewhere).
 
 The goal is to enable you to write fully non-blocking programs. For
 example, in a game server, you would not want to freeze for a few seconds
@@ -178,7 +178,7 @@ lot by removing the idle watcher logic):
 
     ev_idle_init (&repeat_watcher, repeat);
     ev_async_init (&ready_watcher, ready);
-    ev_async_start (loop &watcher);
+    ev_async_start (loop, &watcher);
 
     eio_init (want_poll, 0);
   }
@@ -292,21 +292,7 @@ Cancel the request (and all its subrequests). If the request is currently
 executing it might still continue to execute, and in other cases it might
 still take a while till the request is cancelled.
 
-Even if cancelled, the finish callback will still be invoked - the
-callbacks of all cancellable requests need to check whether the request
-has been cancelled by calling C<EIO_CANCELLED (req)>:
-
-  static int
-  my_eio_cb (eio_req *req)
-  {
-    if (EIO_CANCELLED (req))
-      return 0;
-  }
-
-In addition, cancelled requests will I<either> have C<< req->result >>
-set to C<-1> and C<errno> to C<ECANCELED>, or I<otherwise> they were
-successfully executed, despite being cancelled (e.g. when they have
-already been executed at the time they were cancelled).
+When cancelled, the finish callback will not be invoked.
 
 C<EIO_CANCELLED> is still true for requests that have successfully
 executed, as long as C<eio_cancel> was called on them at some point.
@@ -632,7 +618,7 @@ These requests are specific to libeio and do not correspond to any OS call.
 
 =item eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data)
 
-Reads (C<flags == 0>) or modifies (C<flags == EIO_MT_MODIFY) the given
+Reads (C<flags == 0>) or modifies (C<flags == EIO_MT_MODIFY>) the given
 memory area, page-wise, that is, it reads (or reads and writes back) the
 first octet of every page that spans the memory area.
 
@@ -790,8 +776,6 @@ sure you I<always> set C<< grp->result >> to some sensible value.
 void eio_grp_limit     (eio_req *grp, int limit);
 
 
-=back
-
 
 =head1 LOW LEVEL REQUEST API
 
@@ -928,10 +912,8 @@ was written to use very little stackspace, but when using C<EIO_CUSTOM>
 requests, you might want to increase this.
 
 If this symbol is undefined (the default) then libeio will use its default
-stack size (C<sizeof (void *) * 4096> currently). If it is defined, but
-C<0>, then the default operating system stack size will be used. In all
-other cases, the value must be an expression that evaluates to the desired
-stack size.
+stack size (C<sizeof (void *) * 4096> currently). In all other cases, the
+value must be an expression that evaluates to the desired stack size.
 
 =back
 
diff --git a/third_party/libeio/etp.c b/third_party/libeio/etp.c
new file mode 100644
index 0000000000000000000000000000000000000000..f97eaccae2c20a89ac0554c5a310640a30e357bc
--- /dev/null
+++ b/third_party/libeio/etp.c
@@ -0,0 +1,494 @@
+/*
+ * libetp implementation
+ *
+ * Copyright (c) 2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann <libetp@schmorp.de>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ *
+ *   1.  Redistributions of source code must retain the above copyright notice,
+ *       this list of conditions and the following disclaimer.
+ *
+ *   2.  Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
+ * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
+ * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
+ * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License ("GPL") version 2 or any later version,
+ * in which case the provisions of the GPL are applicable instead of
+ * the above. If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the BSD license, indicate your decision
+ * by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL. If you do not delete the
+ * provisions above, a recipient may use your version of this file under
+ * either the BSD or the GPL.
+ */
+
+#ifndef ETP_API_DECL
+# define ETP_API_DECL static
+#endif
+
+#ifndef ETP_PRI_MIN
+# define ETP_PRI_MIN 0
+# define ETP_PRI_MAX 0
+#endif
+
+#ifndef ETP_TYPE_QUIT
+# define ETP_TYPE_QUIT 0
+#endif
+
+#ifndef ETP_TYPE_GROUP
+# define ETP_TYPE_GROUP 1
+#endif
+
+#define ETP_NUM_PRI (ETP_PRI_MAX - ETP_PRI_MIN + 1)
+
+#define ETP_TICKS ((1000000 + 1023) >> 10)
+
+/* calculate time difference in ~1/ETP_TICKS of a second */
+ecb_inline int
+etp_tvdiff (struct timeval *tv1, struct timeval *tv2)
+{
+  return  (tv2->tv_sec  - tv1->tv_sec ) * ETP_TICKS
+       + ((tv2->tv_usec - tv1->tv_usec) >> 10);
+}
+
+static unsigned int started, idle, wanted = 4;
+
+static void (*want_poll_cb) (void);
+static void (*done_poll_cb) (void);
+ 
+static unsigned int max_poll_time;     /* reslock */
+static unsigned int max_poll_reqs;     /* reslock */
+
+static unsigned int nreqs;    /* reqlock */
+static unsigned int nready;   /* reqlock */
+static unsigned int npending; /* reqlock */
+static unsigned int max_idle = 4;      /* maximum number of threads that can idle indefinitely */
+static unsigned int idle_timeout = 10; /* number of seconds after which an idle threads exit */
+
+static xmutex_t wrklock;
+static xmutex_t reslock;
+static xmutex_t reqlock;
+static xcond_t  reqwait;
+
+typedef struct etp_worker
+{
+  struct tmpbuf tmpbuf;
+
+  /* locked by wrklock */
+  struct etp_worker *prev, *next;
+
+  xthread_t tid;
+
+#ifdef ETP_WORKER_COMMON
+  ETP_WORKER_COMMON
+#endif
+} etp_worker;
+
+static etp_worker wrk_first; /* NOT etp */
+
+#define ETP_WORKER_LOCK(wrk)   X_LOCK   (wrklock)
+#define ETP_WORKER_UNLOCK(wrk) X_UNLOCK (wrklock)
+
+/* worker threads management */
+
+static void
+etp_worker_clear (etp_worker *wrk)
+{
+}
+
+static void ecb_cold
+etp_worker_free (etp_worker *wrk)
+{
+  free (wrk->tmpbuf.ptr);
+
+  wrk->next->prev = wrk->prev;
+  wrk->prev->next = wrk->next;
+
+  free (wrk);
+}
+
+ETP_API_DECL unsigned int
+etp_nreqs (void)
+{
+  int retval;
+  if (WORDACCESS_UNSAFE) X_LOCK   (reqlock);
+  retval = nreqs;
+  if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock);
+  return retval;
+}
+
+ETP_API_DECL unsigned int
+etp_nready (void)
+{
+  unsigned int retval;
+
+  if (WORDACCESS_UNSAFE) X_LOCK   (reqlock);
+  retval = nready;
+  if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock);
+
+  return retval;
+}
+
+ETP_API_DECL unsigned int
+etp_npending (void)
+{
+  unsigned int retval;
+
+  if (WORDACCESS_UNSAFE) X_LOCK   (reqlock);
+  retval = npending;
+  if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock);
+
+  return retval;
+}
+
+ETP_API_DECL unsigned int
+etp_nthreads (void)
+{
+  unsigned int retval;
+
+  if (WORDACCESS_UNSAFE) X_LOCK   (reqlock);
+  retval = started;
+  if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock);
+
+  return retval;
+}
+
+/*
+ * a somewhat faster data structure might be nice, but
+ * with 8 priorities this actually needs <20 insns
+ * per shift, the most expensive operation.
+ */
+typedef struct {
+  ETP_REQ *qs[ETP_NUM_PRI], *qe[ETP_NUM_PRI]; /* qstart, qend */
+  int size;
+} etp_reqq;
+
+static etp_reqq req_queue;
+static etp_reqq res_queue;
+
+static void ecb_noinline ecb_cold
+reqq_init (etp_reqq *q)
+{
+  int pri;
+
+  for (pri = 0; pri < ETP_NUM_PRI; ++pri)
+    q->qs[pri] = q->qe[pri] = 0;
+
+  q->size = 0;
+}
+
+static int ecb_noinline
+reqq_push (etp_reqq *q, ETP_REQ *req)
+{
+  int pri = req->pri;
+  req->next = 0;
+
+  if (q->qe[pri])
+    {
+      q->qe[pri]->next = req;
+      q->qe[pri] = req;
+    }
+  else
+    q->qe[pri] = q->qs[pri] = req;
+
+  return q->size++;
+}
+
+static ETP_REQ * ecb_noinline
+reqq_shift (etp_reqq *q)
+{
+  int pri;
+
+  if (!q->size)
+    return 0;
+
+  --q->size;
+
+  for (pri = ETP_NUM_PRI; pri--; )
+    {
+      ETP_REQ *req = q->qs[pri];
+
+      if (req)
+        {
+          if (!(q->qs[pri] = (ETP_REQ *)req->next))
+            q->qe[pri] = 0;
+
+          return req;
+        }
+    }
+
+  abort ();
+}
+
+ETP_API_DECL int ecb_cold
+etp_init (void (*want_poll)(void), void (*done_poll)(void))
+{
+  X_MUTEX_CREATE (wrklock);
+  X_MUTEX_CREATE (reslock);
+  X_MUTEX_CREATE (reqlock);
+  X_COND_CREATE  (reqwait);
+
+  reqq_init (&req_queue);
+  reqq_init (&res_queue);
+
+  wrk_first.next =
+  wrk_first.prev = &wrk_first;
+
+  started  = 0;
+  idle     = 0;
+  nreqs    = 0;
+  nready   = 0;
+  npending = 0;
+
+  want_poll_cb = want_poll;
+  done_poll_cb = done_poll;
+
+  return 0;
+}
+
+/* not yet in etp.c */
+X_THREAD_PROC (etp_proc);
+
+static void ecb_cold
+etp_start_thread (void)
+{
+  etp_worker *wrk = calloc (1, sizeof (etp_worker));
+
+  /*TODO*/
+  assert (("unable to allocate worker thread data", wrk));
+
+  X_LOCK (wrklock);
+
+  if (xthread_create (&wrk->tid, etp_proc, (void *)wrk))
+    {
+      wrk->prev = &wrk_first;
+      wrk->next = wrk_first.next;
+      wrk_first.next->prev = wrk;
+      wrk_first.next = wrk;
+      ++started;
+    }
+  else
+    free (wrk);
+
+  X_UNLOCK (wrklock);
+}
+
+static void
+etp_maybe_start_thread (void)
+{
+  if (ecb_expect_true (etp_nthreads () >= wanted))
+    return;
+  
+  /* todo: maybe use idle here, but might be less exact */
+  if (ecb_expect_true (0 <= (int)etp_nthreads () + (int)etp_npending () - (int)etp_nreqs ()))
+    return;
+
+  etp_start_thread ();
+}
+
+static void ecb_cold
+etp_end_thread (void)
+{
+  ETP_REQ *req = calloc (1, sizeof (ETP_REQ)); /* will be freed by worker */
+
+  req->type = ETP_TYPE_QUIT;
+  req->pri  = ETP_PRI_MAX - ETP_PRI_MIN;
+
+  X_LOCK (reqlock);
+  reqq_push (&req_queue, req);
+  X_COND_SIGNAL (reqwait);
+  X_UNLOCK (reqlock);
+
+  X_LOCK (wrklock);
+  --started;
+  X_UNLOCK (wrklock);
+}
+
+ETP_API_DECL int
+etp_poll (void)
+{
+  unsigned int maxreqs;
+  unsigned int maxtime;
+  struct timeval tv_start, tv_now;
+
+  X_LOCK (reslock);
+  maxreqs = max_poll_reqs;
+  maxtime = max_poll_time;
+  X_UNLOCK (reslock);
+
+  if (maxtime)
+    gettimeofday (&tv_start, 0);
+
+  for (;;)
+    {
+      ETP_REQ *req;
+
+      etp_maybe_start_thread ();
+
+      X_LOCK (reslock);
+      req = reqq_shift (&res_queue);
+
+      if (req)
+        {
+          --npending;
+
+          if (!res_queue.size && done_poll_cb)
+            done_poll_cb ();
+        }
+
+      X_UNLOCK (reslock);
+
+      if (!req)
+        return 0;
+
+      X_LOCK (reqlock);
+      --nreqs;
+      X_UNLOCK (reqlock);
+
+      if (ecb_expect_false (req->type == ETP_TYPE_GROUP && req->size))
+        {
+          req->int1 = 1; /* mark request as delayed */
+          continue;
+        }
+      else
+        {
+          int res = ETP_FINISH (req);
+          if (ecb_expect_false (res))
+            return res;
+        }
+
+      if (ecb_expect_false (maxreqs && !--maxreqs))
+        break;
+
+      if (maxtime)
+        {
+          gettimeofday (&tv_now, 0);
+
+          if (etp_tvdiff (&tv_start, &tv_now) >= maxtime)
+            break;
+        }
+    }
+
+  errno = EAGAIN;
+  return -1;
+}
+
+ETP_API_DECL void
+etp_grp_cancel (ETP_REQ *grp);
+
+ETP_API_DECL void
+etp_cancel (ETP_REQ *req)
+{
+  req->cancelled = 1;
+
+  etp_grp_cancel (req);
+}
+
+ETP_API_DECL void
+etp_grp_cancel (ETP_REQ *grp)
+{
+  for (grp = grp->grp_first; grp; grp = grp->grp_next)
+    etp_cancel (grp);
+}
+
+ETP_API_DECL void
+etp_submit (ETP_REQ *req)
+{
+  req->pri -= ETP_PRI_MIN;
+
+  if (ecb_expect_false (req->pri < ETP_PRI_MIN - ETP_PRI_MIN)) req->pri = ETP_PRI_MIN - ETP_PRI_MIN;
+  if (ecb_expect_false (req->pri > ETP_PRI_MAX - ETP_PRI_MIN)) req->pri = ETP_PRI_MAX - ETP_PRI_MIN;
+
+  if (ecb_expect_false (req->type == ETP_TYPE_GROUP))
+    {
+      /* I hope this is worth it :/ */
+      X_LOCK (reqlock);
+      ++nreqs;
+      X_UNLOCK (reqlock);
+
+      X_LOCK (reslock);
+
+      ++npending;
+
+      if (!reqq_push (&res_queue, req) && want_poll_cb)
+        want_poll_cb ();
+
+      X_UNLOCK (reslock);
+    }
+  else
+    {
+      X_LOCK (reqlock);
+      ++nreqs;
+      ++nready;
+      reqq_push (&req_queue, req);
+      X_COND_SIGNAL (reqwait);
+      X_UNLOCK (reqlock);
+
+      etp_maybe_start_thread ();
+    }
+}
+
+ETP_API_DECL void ecb_cold
+etp_set_max_poll_time (double nseconds)
+{
+  if (WORDACCESS_UNSAFE) X_LOCK   (reslock);
+  max_poll_time = nseconds * ETP_TICKS;
+  if (WORDACCESS_UNSAFE) X_UNLOCK (reslock);
+}
+
+ETP_API_DECL void ecb_cold
+etp_set_max_poll_reqs (unsigned int maxreqs)
+{
+  if (WORDACCESS_UNSAFE) X_LOCK   (reslock);
+  max_poll_reqs = maxreqs;
+  if (WORDACCESS_UNSAFE) X_UNLOCK (reslock);
+}
+
+ETP_API_DECL void ecb_cold
+etp_set_max_idle (unsigned int nthreads)
+{
+  if (WORDACCESS_UNSAFE) X_LOCK   (reqlock);
+  max_idle = nthreads;
+  if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock);
+}
+
+ETP_API_DECL void ecb_cold
+etp_set_idle_timeout (unsigned int seconds)
+{
+  if (WORDACCESS_UNSAFE) X_LOCK   (reqlock);
+  idle_timeout = seconds;
+  if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock);
+}
+
+ETP_API_DECL void ecb_cold
+etp_set_min_parallel (unsigned int nthreads)
+{
+  if (wanted < nthreads)
+    wanted = nthreads;
+}
+
+ETP_API_DECL void ecb_cold
+etp_set_max_parallel (unsigned int nthreads)
+{
+  if (wanted > nthreads)
+    wanted = nthreads;
+
+  while (started > wanted)
+    etp_end_thread ();
+}
+
diff --git a/third_party/libeio/xthread.h b/third_party/libeio/xthread.h
index 60310d59cc024d44a930b1f5cced053c18a201f9..86ae73699c410b7aa2a359351d1907421310a186 100644
--- a/third_party/libeio/xthread.h
+++ b/third_party/libeio/xthread.h
@@ -17,8 +17,8 @@
 
 #ifdef _WIN32
 
-#define NTDDI_VERSION NTDDI_WIN2K // needed to get win2000 api calls
-#define _WIN32_WINNT 0x400
+//#define NTDDI_VERSION NTDDI_WIN2K // needed to get win2000 api calls, fails with mingw
+#define _WIN32_WINNT 0x400 // maybe working alternative for mingw
 #include <stdio.h>//D
 #include <fcntl.h>
 #include <io.h>
@@ -26,6 +26,12 @@
 #include <winsock2.h>
 #include <process.h>
 #include <windows.h>
+
+/* work around some bugs in ptw32 */
+#if defined(__MINGW32__) && defined(_TIMESPEC_DEFINED)
+#define HAVE_STRUCT_TIMESPEC 1
+#endif
+
 #include <pthread.h>
 #define sigset_t int
 #define sigfillset(a)
diff --git a/third_party/lua-cjson/lua_cjson.c b/third_party/lua-cjson/lua_cjson.c
index 3915127db3ca09dcdaca678d0c01771ee4329d02..88599082cffca475710fcccd0094b17f733ca99a 100644
--- a/third_party/lua-cjson/lua_cjson.c
+++ b/third_party/lua-cjson/lua_cjson.c
@@ -1037,6 +1037,8 @@ luaopen_json(lua_State *L)
     json_create_tokens();
     luaL_json_default = luaL_newserializer(L, jsonlib);
     luaL_register_module(L, "json", NULL);
+    luaL_pushnull(L);
+    lua_setfield(L, -2, "null"); /* compatibility with cjson */
     return 1;
 }
 
diff --git a/third_party/proctitle.c b/third_party/proctitle.c
index 92eca759c18e194448481049a1b38fa0f4e0406d..2e7009a695646ad54755362735392d02982d1d37 100644
--- a/third_party/proctitle.c
+++ b/third_party/proctitle.c
@@ -220,7 +220,7 @@ init_set_proc_title(int argc, char **argv)
 	ps_buffer_fixed_size = 0;
 #else
 	{
-		char basename_buf[PATH_MAX];
+		char basename_buf[PATH_MAX+1];
 
 		/*
 		 * At least partially mimic FreeBSD, which for
@@ -228,7 +228,7 @@ init_set_proc_title(int argc, char **argv)
 		 *
 		 * a.out: custom title here (a.out)
 	         */
-		snprintf(basename_buf, sizeof basename_buf, "%s", argv[0]);
+		snprintf(basename_buf, PATH_MAX, "%s", argv[0]);
 		snprintf(ps_buffer, ps_buffer_size, "%s: ", basename(basename_buf));
 	}