diff --git a/.gitignore b/.gitignore
index 8b46e52ae05fa635144698467ef09e615c6daae3..1cf4bbec883150c1ca80778f7faa17d4c52c7db0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,7 +42,7 @@ doc/user/tarantool_user_guide.txt
 doc/tnt.ent
 doc/www-data/*.html
 doc/www-data/*.ru.html
-doc/www-data.in/download
+doc/www-data.in/_text/download.md
 extra/rpm.spec
 src/trivia/config.h
 install_manifest.txt
diff --git a/client/tarantool/print.c b/client/tarantool/print.c
index e6ace8a2a9429b900fad0e5d7ff69534de03dbfb..a0042e349cedc6398619032da828bf936e98935a 100644
--- a/client/tarantool/print.c
+++ b/client/tarantool/print.c
@@ -56,6 +56,8 @@ void tc_printf(char *fmt, ...) {
 	if (stat == -1)
 		tc_error("Can't write into pager - %d", errno);
 	va_end(args);
+	if (str)
+		free(str);
 	return;
 }
 
diff --git a/connector/c/tb b/connector/c/tb
index 0d24b62555958ae6d5e0682c25062a9354ba3ae0..dc8c432ac9840a7171301188777c75b5b17d3a02 160000
--- a/connector/c/tb
+++ b/connector/c/tb
@@ -1 +1 @@
-Subproject commit 0d24b62555958ae6d5e0682c25062a9354ba3ae0
+Subproject commit dc8c432ac9840a7171301188777c75b5b17d3a02
diff --git a/doc/www-data.in/_layout/base b/doc/www-data.in/_layout/base
index 65114ca414e1f0192e94d8a2c114c782c9e602ba..7271eed61a049113a868a2bce912a5ad3848dfc7 100644
--- a/doc/www-data.in/_layout/base
+++ b/doc/www-data.in/_layout/base
@@ -17,7 +17,7 @@
         <h2>An in-memory NoSQL database</h2>
         <h3>
           <a href="intro.html" class="intro">Overview</a> &nbsp;
-          <a href="doc/site-gen/mpage/index.html" class="documentation">Documentation</a> &nbsp;
+          <a href="doc/stable/mpage/index.html" class="documentation">Documentation</a> &nbsp;
           <a href="download.html" class="download">Download</a> &nbsp;
           <a href="support.html" class="support">Support</a>
         </h3>
diff --git a/src/box/box.cc b/src/box/box.cc
index 0be2b85f414075c431e311a9f583761bba2d44de..6a00a8572dff9ebe814fe456d14eee1415a42382 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -28,6 +28,7 @@
  */
 #include "box/box.h"
 #include <arpa/inet.h>
+#include <sys/wait.h>
 
 extern "C" {
 #include <cfg/warning.h>
diff --git a/src/box/tree_index.cc b/src/box/tree_index.cc
index 540fc3cb426cf3d81b1a821a16f9b27ff3e6748f..c35126e752f40cbe68126d7af5dfdee7befcaa52 100644
--- a/src/box/tree_index.cc
+++ b/src/box/tree_index.cc
@@ -30,6 +30,7 @@
 #include "tuple.h"
 #include "space.h"
 #include "exception.h"
+#include "errinj.h"
 
 /* {{{ Utilities. *************************************************/
 
@@ -80,6 +81,16 @@ sptree_index_node_compare_with_key(const void *key, const void *node,
 				       key_data->part_count, key_def);
 }
 
+#ifndef NDEBUG
+void *
+realloc_inject(void *ptr, size_t size)
+{
+	if (size)
+		ERROR_INJECT(ERRINJ_TREE_ALLOC, return 0);
+	return realloc(ptr, size);
+}
+#endif
+
 /* {{{ TreeIndex Iterators ****************************************/
 
 struct tree_iterator {
@@ -252,7 +263,12 @@ TreeIndex::replace(struct tuple *old_tuple, struct tuple *new_tuple,
 		void *p_dup_node = &dup_tuple;
 
 		/* Try to optimistically replace the new_tuple. */
+		int tree_res =
 		sptree_index_replace(&tree, &new_tuple, &p_dup_node);
+		if (tree_res) {
+			tnt_raise(ClientError, ER_MEMORY_ISSUE, tree_res,
+				  "TreeIndex", "replace");
+		}
 
 		errcode = replace_check_dup(old_tuple, dup_tuple, mode);
 
@@ -306,12 +322,19 @@ TreeIndex::initIterator(struct iterator *iterator, enum iterator_type type,
 	it->key_data.key = key;
 	it->key_data.part_count = part_count;
 
-	if (iterator_type_is_reverse(type))
-		sptree_index_iterator_reverse_init_set(&tree, &it->iter,
-						       &it->key_data);
-	else
-		sptree_index_iterator_init_set(&tree, &it->iter,
-					       &it->key_data);
+	if (iterator_type_is_reverse(type)) {
+		int r = sptree_index_iterator_reverse_init_set(&tree,
+				&it->iter, &it->key_data);
+		if (r)
+			tnt_raise(ClientError, ER_MEMORY_ISSUE,
+				  r, "TreeIndex", "init iterator");
+	} else {
+		int r = sptree_index_iterator_init_set(&tree,
+				&it->iter, &it->key_data);
+		if (r)
+			tnt_raise(ClientError, ER_MEMORY_ISSUE,
+				  r, "TreeIndex", "init iterator");
+	}
 
 	switch (type) {
 	case ITER_EQ:
@@ -386,11 +409,15 @@ TreeIndex::endBuild()
 	void *nodes = tree.members;
 
 	/* If n_tuples == 0 then estimated_tuples = 0, elem == NULL, tree is empty */
+	int tree_res =
 	sptree_index_init(&tree, sizeof(struct tuple *),
 			  nodes, n_tuples, estimated_tuples,
 			  sptree_index_node_compare_with_key,
 			  key_def->is_unique ? sptree_index_node_compare
 					     : sptree_index_node_compare_dup,
 			  key_def);
+	if (tree_res) {
+		panic("tree_init: failed to allocate %d bytes", tree_res);
+	}
 }
 
diff --git a/src/box/tree_index.h b/src/box/tree_index.h
index 27ba9fbadd8f70ad9e97fed0ae6af0a5c9278e44..f4fd565ba12df5fabc1d041fde4fda8f4d746a5a 100644
--- a/src/box/tree_index.h
+++ b/src/box/tree_index.h
@@ -37,7 +37,13 @@
 /**
  * Instantiate sptree definitions
  */
+#ifdef NDEBUG
 SPTREE_DEF(index, realloc, qsort_arg);
+#else
+void *
+realloc_inject(void *ptr, size_t size);
+SPTREE_DEF(index, realloc_inject, qsort_arg);
+#endif
 
 class TreeIndex: public Index {
 public:
diff --git a/src/errinj.h b/src/errinj.h
index 11f6f81abd919f6f7712a1efe91e03b1f8b14d5a..ef38719065ef624e806eb107941129159df9a574 100644
--- a/src/errinj.h
+++ b/src/errinj.h
@@ -43,7 +43,8 @@ struct errinj {
 	_(ERRINJ_TESTING, false) \
 	_(ERRINJ_WAL_IO, false) \
 	_(ERRINJ_WAL_ROTATE, false) \
-	_(ERRINJ_INDEX_ALLOC, false)
+	_(ERRINJ_INDEX_ALLOC, false) \
+	_(ERRINJ_TREE_ALLOC, false)
 
 ENUM0(errinj_enum, ERRINJ_LIST);
 extern struct errinj errinjs[];
diff --git a/test/big/tarantool.cfg b/test/big/tarantool.cfg
index 5d669baffafffb071a400d85ee2878343f10e938..55b49bebeba6d88ac4c0ea75854942a77412ce7f 100644
--- a/test/big/tarantool.cfg
+++ b/test/big/tarantool.cfg
@@ -9,3 +9,4 @@ secondary_port = 33014
 admin_port = 33015
 
 rows_per_wal = 50
+
diff --git a/test/box/errinj.result b/test/box/errinj.result
index b36bbd2b0ef151053542a9d71ef693bfe0e87702..4b92f5868a0cd3c510d89cac6f36e8e7adce78b8 100644
--- a/test/box/errinj.result
+++ b/test/box/errinj.result
@@ -6,13 +6,15 @@ space:create_index('primary', 'hash', { parts = { 0, 'num' }})
 ...
 box.errinj.info()
 ---
-- ERRINJ_INDEX_ALLOC:
+- ERRINJ_WAL_IO:
     state: false
-  ERRINJ_WAL_IO:
+  ERRINJ_TESTING:
+    state: false
+  ERRINJ_INDEX_ALLOC:
     state: false
   ERRINJ_WAL_ROTATE:
     state: false
-  ERRINJ_TESTING:
+  ERRINJ_TREE_ALLOC:
     state: false
 ...
 box.errinj.set("some-injection", true)
diff --git a/test/box/errinj_index.result b/test/box/errinj_index.result
new file mode 100644
index 0000000000000000000000000000000000000000..71e489e95724b55dd47dc8ea3771569cb173eee7
--- /dev/null
+++ b/test/box/errinj_index.result
@@ -0,0 +1,238 @@
+s = box.schema.create_space('tweedledum')
+---
+...
+s:create_index('primary', 'tree', { parts = { 0, 'num' }})
+---
+...
+-- Check a failed realloc in tree.
+for i = 1,10 do s:insert(i, i, 'test' .. i) end
+---
+...
+res = {}
+---
+...
+for i = 1,10 do table.insert(res, s:select(0, i)) end
+---
+...
+res
+---
+- - [1, 1, 'test1']
+  - [2, 2, 'test2']
+  - [3, 3, 'test3']
+  - [4, 4, 'test4']
+  - [5, 5, 'test5']
+  - [6, 6, 'test6']
+  - [7, 7, 'test7']
+  - [8, 8, 'test8']
+  - [9, 9, 'test9']
+  - [10, 10, 'test10']
+...
+res = {}
+---
+...
+for t in s.index[0]:iterator(box.index.ALL) do table.insert(res, t) end
+---
+...
+res
+---
+- - [1, 1, 'test1']
+  - [2, 2, 'test2']
+  - [3, 3, 'test3']
+  - [4, 4, 'test4']
+  - [5, 5, 'test5']
+  - [6, 6, 'test6']
+  - [7, 7, 'test7']
+  - [8, 8, 'test8']
+  - [9, 9, 'test9']
+  - [10, 10, 'test10']
+...
+box.errinj.set("ERRINJ_TREE_ALLOC", true)
+---
+- ok
+...
+res = {}
+---
+...
+for i = 1,10 do table.insert(res, s:select(0, i)) end
+---
+...
+res
+---
+- - [1, 1, 'test1']
+  - [2, 2, 'test2']
+  - [3, 3, 'test3']
+  - [4, 4, 'test4']
+  - [5, 5, 'test5']
+  - [6, 6, 'test6']
+  - [7, 7, 'test7']
+  - [8, 8, 'test8']
+  - [9, 9, 'test9']
+  - [10, 10, 'test10']
+...
+for i = 501,1000 do s:insert(i, i) end
+---
+- error: Failed to allocate 1024 bytes in TreeIndex for replace
+...
+s:delete(1)
+---
+- [1, 1, 'test1']
+...
+res = {}
+---
+...
+for t in s.index[0]:iterator(box.index.ALL) do table.insert(res, t) end
+---
+- error: Failed to allocate 196 bytes in TreeIndex for init iterator
+...
+res
+---
+- []
+...
+-- reserve memory for iterator in index. last insert may increase tree depth
+box.errinj.set("ERRINJ_TREE_ALLOC", false)
+---
+- ok
+...
+s:select(0, 1)
+---
+...
+box.errinj.set("ERRINJ_TREE_ALLOC", true)
+---
+- ok
+...
+res = {}
+---
+...
+for i = 1,10 do table.insert(res, (s:select(0, i))) end
+---
+...
+res
+---
+- - [2, 2, 'test2']
+  - [3, 3, 'test3']
+  - [4, 4, 'test4']
+  - [5, 5, 'test5']
+  - [6, 6, 'test6']
+  - [7, 7, 'test7']
+  - [8, 8, 'test8']
+  - [9, 9, 'test9']
+  - [10, 10, 'test10']
+...
+for i = 1001,1500 do s:insert(i, i) end
+---
+- error: Failed to allocate 1024 bytes in TreeIndex for replace
+...
+s:delete(2)
+---
+- [2, 2, 'test2']
+...
+s.index[0]:iterator(box.index.ALL)
+---
+- error: Failed to allocate 200 bytes in TreeIndex for init iterator
+...
+-- reserve memory for iterator in index. last insert may increase tree depth
+-- (if rebalance was not initiated)
+box.errinj.set("ERRINJ_TREE_ALLOC", false)
+---
+- ok
+...
+s:select(0, 1)
+---
+...
+box.errinj.set("ERRINJ_TREE_ALLOC", true)
+---
+- ok
+...
+res = {}
+---
+...
+for i = 1,10 do table.insert(res, (s:select(0, i))) end
+---
+...
+res
+---
+- - [3, 3, 'test3']
+  - [4, 4, 'test4']
+  - [5, 5, 'test5']
+  - [6, 6, 'test6']
+  - [7, 7, 'test7']
+  - [8, 8, 'test8']
+  - [9, 9, 'test9']
+  - [10, 10, 'test10']
+...
+for i = 1501,2000 do s:insert(i, i) end
+---
+- error: Failed to allocate 1024 bytes in TreeIndex for replace
+...
+s:delete(3)
+---
+- [3, 3, 'test3']
+...
+s.index[0]:iterator(box.index.ALL)
+---
+- error: Failed to allocate 200 bytes in TreeIndex for init iterator
+...
+box.errinj.set("ERRINJ_TREE_ALLOC", false)
+---
+- ok
+...
+for i = 2001,2500 do s:insert(i, i) end
+---
+...
+res = {}
+---
+...
+for i = 1,10 do table.insert(res, (s:select(0, i))) end
+---
+...
+res
+---
+- - [4, 4, 'test4']
+  - [5, 5, 'test5']
+  - [6, 6, 'test6']
+  - [7, 7, 'test7']
+  - [8, 8, 'test8']
+  - [9, 9, 'test9']
+  - [10, 10, 'test10']
+...
+s:delete(8)
+---
+- [8, 8, 'test8']
+...
+res = {}
+---
+...
+for i = 1,10 do table.insert(res, (s:select(0, i))) end
+---
+...
+res
+---
+- - [4, 4, 'test4']
+  - [5, 5, 'test5']
+  - [6, 6, 'test6']
+  - [7, 7, 'test7']
+  - [9, 9, 'test9']
+  - [10, 10, 'test10']
+...
+res = {}
+---
+...
+for i = 2001,2010 do table.insert(res, (s:select(0, i))) end
+---
+...
+res
+---
+- - [2001, 2001]
+  - [2002, 2002]
+  - [2003, 2003]
+  - [2004, 2004]
+  - [2005, 2005]
+  - [2006, 2006]
+  - [2007, 2007]
+  - [2008, 2008]
+  - [2009, 2009]
+  - [2010, 2010]
+...
+s:drop()
+---
+...
diff --git a/test/box/errinj_index.test.lua b/test/box/errinj_index.test.lua
new file mode 100644
index 0000000000000000000000000000000000000000..1dcbf22143596bbf461ad4d0492b7088692e8cf5
--- /dev/null
+++ b/test/box/errinj_index.test.lua
@@ -0,0 +1,65 @@
+s = box.schema.create_space('tweedledum')
+s:create_index('primary', 'tree', { parts = { 0, 'num' }})
+
+-- Check a failed realloc in tree.
+
+for i = 1,10 do s:insert(i, i, 'test' .. i) end
+res = {}
+for i = 1,10 do table.insert(res, s:select(0, i)) end
+res
+res = {}
+for t in s.index[0]:iterator(box.index.ALL) do table.insert(res, t) end
+res
+
+box.errinj.set("ERRINJ_TREE_ALLOC", true)
+
+res = {}
+for i = 1,10 do table.insert(res, s:select(0, i)) end
+res
+for i = 501,1000 do s:insert(i, i) end
+s:delete(1)
+res = {}
+for t in s.index[0]:iterator(box.index.ALL) do table.insert(res, t) end
+res
+
+-- reserve memory for iterator in index. last insert may increase tree depth
+box.errinj.set("ERRINJ_TREE_ALLOC", false)
+s:select(0, 1)
+box.errinj.set("ERRINJ_TREE_ALLOC", true)
+
+res = {}
+for i = 1,10 do table.insert(res, (s:select(0, i))) end
+res
+
+for i = 1001,1500 do s:insert(i, i) end
+s:delete(2)
+s.index[0]:iterator(box.index.ALL)
+
+-- reserve memory for iterator in index. last insert may increase tree depth
+-- (if rebalance was not initiated)
+box.errinj.set("ERRINJ_TREE_ALLOC", false)
+s:select(0, 1)
+box.errinj.set("ERRINJ_TREE_ALLOC", true)
+
+res = {}
+for i = 1,10 do table.insert(res, (s:select(0, i))) end
+res
+for i = 1501,2000 do s:insert(i, i) end
+s:delete(3)
+s.index[0]:iterator(box.index.ALL)
+
+box.errinj.set("ERRINJ_TREE_ALLOC", false)
+
+for i = 2001,2500 do s:insert(i, i) end
+res = {}
+for i = 1,10 do table.insert(res, (s:select(0, i))) end
+res
+s:delete(8)
+res = {}
+for i = 1,10 do table.insert(res, (s:select(0, i))) end
+res
+res = {}
+for i = 2001,2010 do table.insert(res, (s:select(0, i))) end
+res
+s:drop()
+
diff --git a/test/box/suite.ini b/test/box/suite.ini
index d6dd29319553ca75cac479eae900cd137adfdab8..583d298659af9e017136f1ab623fc9b05dfdcda3 100644
--- a/test/box/suite.ini
+++ b/test/box/suite.ini
@@ -4,4 +4,4 @@ description = tarantool/box, minimal configuration
 config = tarantool.cfg
 disabled = snapshot_1_3.test.py session.test.py
 valgrind_disabled = admin_coredump.test.lua
-release_disabled = errinj.test.lua
+release_disabled = errinj.test.lua errinj_index.test.lua
diff --git a/test/box/xlog.test.py b/test/box/xlog.test.py
index 09e0857698e178217f864b26d13991055e0b6fa4..3e3e2b4e9b11fabd636430dfe3b260261c91aa4b 100644
--- a/test/box/xlog.test.py
+++ b/test/box/xlog.test.py
@@ -126,5 +126,3 @@ admin("#box.space[0]")
 # cleanup
 server.stop()
 server.deploy()
-
-# vim: syntax=python
diff --git a/test/lib/colorer.py b/test/lib/colorer.py
index 642199eb43f0c1abfaa60577fa25b34223f6f6c5..2edfeb2cf2366defde29b22beae3ebe39706e81c 100644
--- a/test/lib/colorer.py
+++ b/test/lib/colorer.py
@@ -8,6 +8,69 @@ class Singleton(type):
             cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
         return cls._instances[cls]
 
+class CSchema(object):
+    objects = {}
+
+    def __init__(self):
+        self.main_objects = {
+            'diff_mark': {},
+            'diff_in':   {},
+            'diff_out':  {},
+            'test_pass': {},
+            'test_fail': {},
+            'test_new':  {},
+            'test_skip': {},
+            'test_disa': {},
+            'error':     {},
+            'lerror':    {},
+            'tail':      {},
+            'ts_text':   {},
+            'path':      {},
+            'info':      {},
+            'separator': {},
+            't_name':    {},
+            'serv_text': {},
+            'version':   {},
+            'tr_text':   {},
+        }
+        self.main_objects.update(self.objects)
+
+class SchemaAscetic(CSchema):
+    objects = {
+        'diff_mark': {'fgcolor': 'magenta'},
+        'diff_in':   {'fgcolor': 'green'},
+        'diff_out':  {'fgcolor': 'red'},
+        'test_pass': {'fgcolor': 'green'},
+        'test_fail': {'fgcolor': 'red'},
+        'test_new':  {'fgcolor': 'lblue'},
+        'test_skip': {'fgcolor': 'grey'},
+        'test_disa': {'fgcolor': 'grey'},
+        'error':     {'fgcolor': 'red'},
+    }
+
+class SchemaPretty(CSchema):
+    objects = {
+        'diff_mark': {'fgcolor': 'magenta'},
+        'diff_in':   {'fgcolor': 'blue'},
+        'diff_out':  {'fgcolor': 'red'},
+        'test_pass': {'fgcolor': 'green'},
+        'test_fail': {'fgcolor': 'red'},
+        'test_new':  {'fgcolor': 'lblue'},
+        'test_skip': {'fgcolor': 'grey'},
+        'test_disa': {'fgcolor': 'grey'},
+        'error':     {'fgcolor': 'red'},
+        'lerror':    {'fgcolor': 'lred'},
+        'tail':      {'fgcolor': 'lblue'},
+        'ts_text':   {'fgcolor': 'lmagenta'},
+        'path':      {'fgcolor': 'green',  'bold':True},
+        'info':      {'fgcolor': 'yellow', 'bold':True},
+        'separator': {'fgcolor': 'blue'},
+        't_name':    {'fgcolor': 'lblue'},
+        'serv_text': {'fgcolor': 'lmagenta'},
+        'version':   {'fgcolor': 'yellow', 'bold':True},
+        'tr_text':   {'fgcolor': 'green'},
+    }
+
 class Colorer(object):
     """
     Colorer/Styler based on VT220+ specifications (Not full). Based on:
@@ -32,7 +95,7 @@ class Colorer(object):
         "lmagenta" : '1;35',
         "lcyan"    : '1;36',
         "white"    : '1;37',
-        }
+    }
     bgcolor = {
         "black"    : '0;40',
         "red"      : '0;41',
@@ -66,6 +129,15 @@ class Colorer(object):
         self.stdout = sys.stdout
         self.is_term = self.stdout.isatty()
         self.colors = int(os.popen('tput colors').read()) if self.is_term else None
+        print os.getenv('TT_SCHEMA')
+        schema = os.getenv('TT_SCHEMA', 'ascetic')
+        if schema == 'ascetic':
+            self.schema = SchemaAscetic()
+        elif schema == 'pretty':
+            self.schema = SchemaPretty()
+        else:
+            self.schema = CSchema()
+        self.schema = self.schema.main_objects
 
     def set_stdout(self):
         sys.stdout = self
@@ -75,6 +147,8 @@ class Colorer(object):
 
     def write(self, *args, **kwargs):
         flags = []
+        if 'schema' in kwargs:
+            kwargs.update(self.schema[kwargs['schema']])
         for i in self.attributes:
             if i in kwargs and kwargs[i] == True:
                 flags.append(self.attributes[i])
@@ -95,11 +169,11 @@ class Colorer(object):
     def writeout_unidiff(self, diff):
         for i in diff:
             if i.startswith('+'):
-                self.write(i, fgcolor='blue')
+                self.write(i, schema='diff_in')
             elif i.startswith('-'):
-                self.write(i, fgcolor='red')
+                self.write(i, schema='diff_out')
             elif i.startswith('@'):
-                self.write(i, fgcolor='magenta')
+                self.write(i, schema='diff_mark')
 
     def flush(self):
         return self.stdout.flush()
diff --git a/test/lib/tarantool_server.py b/test/lib/tarantool_server.py
index b385a6894f4d1aaef24f4e5750bec19e81cac2a3..c331e62afc7c3840143ff7e4c01feb14bd3a357a 100644
--- a/test/lib/tarantool_server.py
+++ b/test/lib/tarantool_server.py
@@ -165,8 +165,8 @@ class TarantoolServer(Server):
         builddir = os.path.join(builddir, "src/box")
         path = builddir + os.pathsep + os.environ["PATH"]
         if not silent:
-            color_stdout("Looking for server binary in ", fgcolor='lmagenta')
-            color_stdout(path+" ...\n", fgcolor='green')
+            color_stdout("Looking for server binary in ", schema='serv_text')
+            color_stdout(path+" ...\n", schema='path')
         for _dir in path.split(os.pathsep):
             exe = os.path.join(_dir, self.default_bin_name)
             if os.access(exe, os.X_OK):
@@ -186,15 +186,15 @@ class TarantoolServer(Server):
         self.valgrind_log = os.path.abspath(os.path.join(self.vardir, self.valgrind_log))
 
         if not silent:
-            color_stdout("Installing the server ...\n", fgcolor='lmagenta')
-            color_stdout("    Found executable at ", fgcolor='lmagenta')
-            color_stdout(self.binary+'\n', fgcolor='green', bold=True)
-            color_stdout("    Creating and populating working directory in ", fgcolor='lmagenta')
-            color_stdout(self.vardir+' ...\n', fgcolor='green', bold=True)
+            color_stdout("Installing the server ...\n", schema='serv_text')
+            color_stdout("    Found executable at ", schema='serv_text')
+            color_stdout(self.binary+'\n', schema='path')
+            color_stdout("    Creating and populating working directory in ", schema='serv_text')
+            color_stdout(self.vardir+' ...\n', schema='path')
 
         if os.access(self.vardir, os.F_OK):
             if not silent:
-                color_stdout("    Found old vardir, deleting ...\n", fgcolor='lmagenta')
+                color_stdout("    Found old vardir, deleting ...\n", schema='serv_text')
             self.kill_old_server()
             self.cleanup()
         else:
@@ -257,7 +257,7 @@ class TarantoolServer(Server):
                 stderr = subprocess.STDOUT, stdout = subprocess.PIPE)
         retcode = _init.wait()
         if retcode:
-            sys.stderr.write("tarantool_box --init-storage error: \n%s\n" %  _init.stdout.read())
+            color_stdout("tarantool_box --init-storage error: \n%s\n" %  _init.stdout.read(), schema='error')
             raise subprocess.CalledProcessError(retcode, cmd)
 
     def get_param(self, param):
@@ -305,23 +305,23 @@ class TarantoolServer(Server):
 
         if self.is_started:
             if not silent:
-                color_stdout("The server is already started.\n", fgcolor='lred')
+                color_stdout("The server is already started.\n", schema='lerror')
             return
 
         if not silent:
-            color_stdout("Starting the server ...\n", fgcolor='lmagenta')
+            color_stdout("Starting the server ...\n", schema='serv_text')
             version = self.version()
-            color_stdout("Starting ", fgcolor='lmagenta')
-            color_stdout(os.path.basename(self.binary), " \n", fgcolor='green')
-            color_stdout(version, "\n", fgcolor='grey')
+            color_stdout("Starting ", schema='serv_text')
+            color_stdout(os.path.basename(self.binary), " \n", schema='path')
+            color_stdout(version, "\n", schema='version')
 
         check_port(self.port)
         args = self.prepare_args()
 
         if self.gdb:
             args = prepare_gdb(self.binary, args)
-            color_stdout("You started the server in gdb mode.\n", fgcolor='yellow', bold=True)
-            color_stdout("To attach, use `screen -r tnt-gdb`\n", fgcolor='yellow', bold=True)
+            color_stdout("You started the server in gdb mode.\n", schema='info')
+            color_stdout("To attach, use `screen -r tnt-gdb`\n", schema='info')
         elif self.valgrind:
             args = prepare_valgrind([self.binary] + args, self.valgrind_log,
                                     os.path.abspath(os.path.join(self.vardir,
@@ -347,11 +347,11 @@ class TarantoolServer(Server):
         start up."""
         if not self.is_started:
             if not silent:
-                color_stdout("The server is not started.\n", fgcolor='red')
+                color_stdout("The server is not started.\n", schema='lerror')
             return
 
         if not silent:
-            color_stdout("Stopping the server ...\n", fgcolor='lmagenta')
+            color_stdout("Stopping the server ...\n", schema='serv_text')
 
         if self.process == None:
             self.kill_old_server()
@@ -429,7 +429,7 @@ class TarantoolServer(Server):
             return # Nothing to do
 
         if not silent:
-            color_stdout("    Found old server, pid {0}, killing ...".format(pid), fgcolor='yellow')
+            color_stdout("    Found old server, pid {0}, killing ...".format(pid), schema='info')
 
         try:
             os.kill(pid, signal.SIGTERM)
@@ -452,10 +452,10 @@ class TarantoolServer(Server):
         return pid
 
     def print_log(self, lines):
-        color_stdout.write("\nLast {0} lines of Tarantool Log file:\n".format(lines), fgcolor='lred')
+        color_stdout("\nLast {0} lines of Tarantool Log file:\n".format(lines), schema='error')
         with open(os.path.join(self.vardir, 'tarantool.log'), 'r') as log:
             for i in log.readlines()[-lines:]:
-                color_stdout.write(i, fgcolor='grey')
+                color_stdout(i, schema='log')
 
     def wait_until_started(self):
         """Wait until the server is started and accepting connections"""
diff --git a/test/lib/test_suite.py b/test/lib/test_suite.py
index 0ac0133b6290fd985c1d38d569b62165e18aa840..c00008e89717d1dc4fc7cef41d15b69db967972e 100644
--- a/test/lib/test_suite.py
+++ b/test/lib/test_suite.py
@@ -35,7 +35,7 @@ def check_libs():
         try:
             __import__(mod_name)
         except ImportError:
-            sys.stderr.write("\n\nNo %s library found\n" % mod_name)
+            color_stdout("\n\nNo %s library found\n" % mod_name, schema='error')
             sys.exit(1)
 
 
@@ -89,7 +89,7 @@ def print_tail_n(filename, num_lines):
     with open(filename, "r+") as logfile:
         tail_n = collections.deque(logfile, num_lines)
         for line in tail_n:
-            color_stdout.write(line, fgcolor='lblue')
+            color_stdout(line, schema='tail')
 
 
 class Test:
@@ -174,20 +174,20 @@ class Test:
             check_valgrind_log(server.valgrind_log) == False
 
         elif self.skip:
-            color_stdout("[ skip ]\n", fgcolor='grey')
+            color_stdout("[ skip ]\n", schema='test_skip')
             if os.path.exists(self.tmp_result):
                 os.remove(self.tmp_result)
         elif self.is_executed_ok and self.is_equal_result and self.is_valgrind_clean:
-            color_stdout("[ pass ]\n", fgcolor='green')
+            color_stdout("[ pass ]\n", schema='test_pass')
             if os.path.exists(self.tmp_result):
                 os.remove(self.tmp_result)
         elif (self.is_executed_ok and not self.is_equal_result and not
               os.path.isfile(self.result)):
             os.rename(self.tmp_result, self.result)
-            color_stdout("[ NEW ]\n", fgcolor='lblue')
+            color_stdout("[ new ]\n", schema='test_new')
         else:
             os.rename(self.tmp_result, self.reject)
-            color_stdout("[ FAIL ]\n" if not self.is_terminated else "[ TERMINATED ]\n", fgcolor='red')
+            color_stdout("[ fail ]\n", schema='test_fail')
 
             where = ""
             if not self.is_executed_ok:
@@ -210,7 +210,7 @@ class Test:
         """Print 10 lines of client program output leading to test
         failure. Used to diagnose a failure of the client program"""
 
-        color_stdout(message, color='lred')
+        color_stdout(message, schema='error')
         print_tail_n(logfile, 10)
 
     def print_unidiff(self):
@@ -218,7 +218,7 @@ class Test:
         to establish the cause of a failure when .test differs
         from .result."""
 
-        color_stdout("\nTest failed! Result content mismatch:\n", fgcolor='lred')
+        color_stdout("\nTest failed! Result content mismatch:\n", schema='error')
         with open(self.result, "r") as result:
             with open(self.reject, "r") as reject:
                 result_time = time.ctime(os.stat(self.result).st_mtime)
@@ -282,11 +282,11 @@ class TestSuite:
             raise RuntimeError("Unknown server: core = {0}".format(
                                self.ini["core"]))
 
-        color_stdout("Collecting tests in ", fgcolor='lmagenta')
-        color_stdout(repr(suite_path), fgcolor='green')
-        color_stdout(": ", self.ini["description"], ".\n", fgcolor='lmagenta')
+        color_stdout("Collecting tests in ", schema='ts_text')
+        color_stdout(repr(suite_path), schema='path')
+        color_stdout(": ", self.ini["description"], ".\n", schema='ts_text')
         self.server.find_tests(self, suite_path)
-        color_stdout("Found ", str(len(self.tests)), " tests.\n", fgcolor='green')
+        color_stdout("Found ", str(len(self.tests)), " tests.\n", schema='path')
 
     def run_all(self):
         """For each file in the test suite, run client program
@@ -310,19 +310,19 @@ class TestSuite:
             shutil.copy(i, self.args.vardir)
 
         if self.args.start_and_exit:
-            color_stdout("    Start and exit requested, exiting...\n", fgcolor='yellow')
+            color_stdout("    Start and exit requested, exiting...\n", schema='info')
             exit(0)
 
         longsep = '='*70
         shortsep = '-'*60
-        color_stdout(longsep, "\n", fgcolor='blue')
-        color_stdout("TEST".ljust(48), fgcolor='lblue')
-        color_stdout("RESULT\n", fgcolor='green')
-        color_stdout(shortsep, "\n", fgcolor='blue')
+        color_stdout(longsep, "\n", schema='separator')
+        color_stdout("TEST".ljust(48), schema='t_name')
+        color_stdout("RESULT\n", schema='test_pass')
+        color_stdout(shortsep, "\n", schema='separator')
         failed_tests = []
         try:
             for test in self.tests:
-                color_stdout(test.name.ljust(48), fgcolor='lblue')
+                color_stdout(test.name.ljust(48), schema='t_name')
                 # for better diagnostics in case of a long-running test
 
                 test_name = os.path.basename(test.name)
@@ -330,7 +330,7 @@ class TestSuite:
                 if (test_name in self.ini["disabled"]
                     or not self.server.debug and test_name in self.ini["release_disabled"]
                     or self.args.valgrind and test_name in self.ini["valgrind_disabled"]):
-                    color_stdout("[ disabled ]\n", fgcolor='grey')
+                    color_stdout("[ disabled ]\n", schema='t_name')
                 else:
                     test.run(self.server)
                     if not test.passed():
@@ -339,17 +339,17 @@ class TestSuite:
             color_stdout('\n')
             raise
         finally:
-            color_stdout(shortsep, "\n", fgcolor='blue')
+            color_stdout(shortsep, "\n", schema='separator')
             self.server.stop(silent=False)
             self.server.cleanup()
 
         if failed_tests:
             color_stdout("Failed {0} tests: {1}.".format(len(failed_tests),
                                                 ", ".join(failed_tests)),
-                                                fgcolor='red')
+                                                schema='error')
 
         if self.args.valgrind and check_valgrind_log(self.server.valgrind_log):
-            color_stdout("  Error! There were warnings/errors in valgrind log file:", fgcolor='red')
+            color_stdout("  Error! There were warnings/errors in valgrind log file:", schema='error')
             print_tail_n(self.server.valgrind_log, 20)
             return ['valgrind error in ' + self.suite_path]
         return failed_tests
diff --git a/test/test-run.py b/test/test-run.py
index 9e8f795680f90db480f4c47cff3b33279ab8df1c..ac780e79223ff9e20dd68baf3ec6b2f6dfd7d526 100755
--- a/test/test-run.py
+++ b/test/test-run.py
@@ -132,7 +132,7 @@ class Options:
         """Check the arguments for correctness."""
         check_error = False
         if self.args.gdb and self.args.valgrind:
-            color_stdout("Error: option --gdb is not compatible with option --valgrind", fgcolor='red')
+            color_stdout("Error: option --gdb is not compatible with option --valgrind", schema='error')
             check_error = True
         if check_error:
             exit(-1)
@@ -169,7 +169,7 @@ def main():
     failed_tests = []
 
     try:
-        color_stdout("Started {}\n".format(" ".join(sys.argv)), fgcolor='green')
+        color_stdout("Started {}\n".format(" ".join(sys.argv)), schema='tr_text')
         suite_names = []
         if options.args.suites != []:
             suite_names = options.args.suites
@@ -183,7 +183,7 @@ def main():
         for suite in suites:
             failed_tests.extend(suite.run_all())
     except RuntimeError as e:
-        color_stdout("\nFatal error: {0}. Execution aborted.\n".format(e), fgcolor='red')
+        color_stdout("\nFatal error: {0}. Execution aborted.\n".format(e), schema='error')
         if options.args.gdb:
             time.sleep(100)
         return (-1)
@@ -191,9 +191,9 @@ def main():
         os.chdir(oldcwd)
 
     if failed_tests and options.args.is_force:
-        color_stdout("\n===== {0} tests failed:".format(len(failed_tests))+"\n", fgcolor="red")
+        color_stdout("\n===== {0} tests failed:".format(len(failed_tests))+"\n", schema='error')
         for test in failed_tests:
-             color_stdout("----- "+test+"\n", fgcolor="yellow")
+             color_stdout("----- "+test+"\n", schema='info')
 
     return (-1 if failed_tests else 0)
 
diff --git a/third_party/sptree.h b/third_party/sptree.h
index a22e2a41d0dbfd2cbdecb0b27a3fd09c9ed2fb6e..6b109be4bbb41bc93337f445cfe1d6e0b0c2ca43 100644
--- a/third_party/sptree.h
+++ b/third_party/sptree.h
@@ -139,7 +139,7 @@ sptree_##name##_mktree(sptree_##name *t, spnode_t depth, spnode_t start, spnode_
     return half;                                                                          \
 }                                                                                         \
                                                                                           \
-static inline void                                                                        \
+static inline int                                                                         \
 sptree_##name##_init(sptree_##name *t, size_t elemsize, void *m,                          \
                      spnode_t nm, spnode_t nt,                                            \
                      sptree_##name##_compare compare,                                     \
@@ -176,13 +176,21 @@ sptree_##name##_init(sptree_##name *t, size_t elemsize, void *m,
         /* create tree */                                                                 \
         t->root = sptree_##name##_mktree(t, 1, 0, t->nmember);                            \
     }                                                                                     \
+    if (t->members && t->lrpointers)                                                      \
+        return 0;                                                                         \
+    else if (t->members)                                                                  \
+        return t->ntotal * sizeof(sptree_node_pointers);                                  \
+    else if (t->lrpointers)                                                               \
+        return t->ntotal * elemsize;                                                      \
+    else                                                                                  \
+        return t->ntotal * (sizeof(sptree_node_pointers) + elemsize);                     \
 }                                                                                         \
                                                                                           \
 static inline void                                                                        \
 sptree_##name##_destroy(sptree_##name *t) {                                               \
         if (t == NULL)    return;                                                         \
-    free(t->members);                                                                     \
-    free(t->lrpointers);                                                                  \
+    t->members = realloc(t->members, 0);                                                  \
+    t->lrpointers = (sptree_node_pointers *)realloc(t->lrpointers, 0);                    \
 }                                                                                         \
                                                                                           \
 /** Nodes in the garbage list have a loop on their right link. */                         \
@@ -254,6 +262,25 @@ sptree_##name##_size_of_subtree(sptree_##name *t, spnode_t node) {
         sptree_##name##_size_of_subtree(t, _GET_SPNODE_RIGHT(node));                      \
 }                                                                                         \
                                                                                           \
+static inline int                                                                         \
+sptree_##name##_reserve_places(sptree_##name *t, spnode_t nreserve) {                     \
+	spnode_t num_free = t->ntotal - t->size;                                          \
+	if (num_free >= nreserve)                                                         \
+		return 0;                                                                 \
+	spnode_t new_ntotal = MAX(t->ntotal * 2, t->ntotal + nreserve - num_free);        \
+	void *new_members = realloc(t->members, new_ntotal * t->elemsize);                \
+	if (!new_members)                                                                 \
+		return new_ntotal * t->elemsize;                                                                \
+	t->members = new_members;                                                         \
+	sptree_node_pointers *new_lrpointers = (sptree_node_pointers *)                   \
+		realloc(t->lrpointers, new_ntotal * sizeof(sptree_node_pointers));        \
+	if (!new_lrpointers)                                                              \
+		return new_ntotal * sizeof(sptree_node_pointers);                                                                \
+	t->lrpointers = new_lrpointers;                                                   \
+	t->ntotal = new_ntotal;                                                           \
+	return 0;                                                                         \
+}                                                                                         \
+                                                                                          \
 static inline spnode_t                                                                    \
 sptree_##name##_get_place(sptree_##name *t) {                                             \
     spnode_t    node;                                                                     \
@@ -262,10 +289,11 @@ sptree_##name##_get_place(sptree_##name *t) {
         t->garbage_head = _GET_SPNODE_LEFT(t->garbage_head);                              \
     } else {                                                                              \
         if (t->nmember >= t->ntotal) {                                                    \
-            t->ntotal *= 2;                                                               \
-            t->members = realloc(t->members, t->ntotal * t->elemsize);                    \
+            spnode_t new_ntotal = t->ntotal * 2;                                          \
+            t->members = realloc(t->members, new_ntotal * t->elemsize);                   \
             t->lrpointers = (sptree_node_pointers *) realloc(t->lrpointers,               \
-                                    t->ntotal * sizeof(sptree_node_pointers));            \
+                                    new_ntotal * sizeof(sptree_node_pointers));           \
+            t->ntotal = new_ntotal;                                                       \
         }                                                                                 \
                                                                                           \
         node = t->nmember;                                                                \
@@ -323,7 +351,7 @@ sptree_##name##_balance(sptree_##name *t, spnode_t node, spnode_t size) {
     return z;                                                                             \
 }                                                                                         \
                                                                                           \
-static inline void                                                                        \
+static inline int                                                                         \
 sptree_##name##_replace(sptree_##name *t, void *v, void **p_old) {                        \
     spnode_t    node, depth = 0;                                                          \
     spnode_t    path[ t->max_depth + 2];                                                  \
@@ -338,7 +366,7 @@ sptree_##name##_replace(sptree_##name *t, void *v, void **p_old) {
         t->size=1;                                                                        \
         if (p_old)                                                                        \
             *p_old = NULL;                                                                \
-        return;                                                                           \
+        return 0;                                                                         \
     } else {                                                                              \
         spnode_t    parent = t->root;                                                     \
                                                                                           \
@@ -348,12 +376,16 @@ sptree_##name##_replace(sptree_##name *t, void *v, void **p_old) {
                 if (p_old)                                                                \
                     memcpy(*p_old, ITHELEM(t, parent), t->elemsize);                      \
                 memcpy(ITHELEM(t, parent), v, t->elemsize);                               \
-                return;                                                                   \
+                return 0;                                                                 \
             }                                                                             \
             path[depth] = parent;                                                         \
             depth++;                                                                      \
             if (r>0) {                                                                    \
                 if (_GET_SPNODE_RIGHT(parent) == SPNIL) {                                 \
+                    /* extra element can be needed for current balance implementation*/   \
+                    int reserve_result = sptree_##name##_reserve_places(t, 2);            \
+                    if (reserve_result)            \
+                        return reserve_result;                                            \
                     node = sptree_##name##_get_place(t);                                  \
                     memcpy(ITHELEM(t, node), v, t->elemsize);                             \
                     _SET_SPNODE_RIGHT(parent, node);                                      \
@@ -363,6 +395,10 @@ sptree_##name##_replace(sptree_##name *t, void *v, void **p_old) {
                 }                                                                         \
             } else {                                                                      \
                 if (_GET_SPNODE_LEFT(parent) == SPNIL) {                                  \
+                    /* extra element can be needed for current balance implementation*/   \
+                    int reserve_result = sptree_##name##_reserve_places(t, 2);            \
+                    if (reserve_result)                                                   \
+                        return reserve_result;        	                                  \
                     node = sptree_##name##_get_place(t);                                  \
                     memcpy(ITHELEM(t, node), v, t->elemsize);                             \
                     _SET_SPNODE_LEFT(parent, node);                                       \
@@ -410,6 +446,7 @@ sptree_##name##_replace(sptree_##name *t, void *v, void **p_old) {
             }                                                                             \
         }                                                                                 \
     }                                                                                     \
+    return 0;                                                                             \
 }                                                                                         \
                                                                                           \
 static inline void                                                                        \
@@ -559,9 +596,11 @@ static inline sptree_##name##_iterator *
 sptree_##name##_iterator_alloc(sptree_##name *t) {                                        \
     sptree_##name##_iterator *i = (sptree_##name##_iterator *)                            \
         realloc(NULL, sizeof(*i) + sizeof(spnode_t) * (t->max_depth + 1));                \
-    i->t = t;                                                                             \
-    i->level = 0;                                                                         \
-    i->stack[0] = t->root;                                                                \
+    if (i) {                                                                              \
+        i->t = t;                                                                         \
+        i->level = 0;                                                                     \
+        i->stack[0] = t->root;                                                            \
+    }                                                                                     \
     return i;                                                                             \
 }                                                                                         \
                                                                                           \
@@ -572,6 +611,8 @@ sptree_##name##_iterator_init(sptree_##name *t) {
                                                                                           \
     if (t->root == SPNIL) return NULL;                                                    \
     i = sptree_##name##_iterator_alloc(t);                                                \
+    if (!i)                                                                               \
+        return i;                                                                         \
                                                                                           \
     while( (node = _GET_SPNODE_LEFT( i->stack[i->level] )) != SPNIL ) {                   \
         i->level++;                                                                       \
@@ -581,21 +622,26 @@ sptree_##name##_iterator_init(sptree_##name *t) {
     return i;                                                                             \
 }                                                                                         \
                                                                                           \
-static inline void                                                                        \
+static inline int                                                                         \
 sptree_##name##_iterator_init_set(const sptree_##name *t, sptree_##name##_iterator **i,   \
                                   void *k) {                                              \
     spnode_t node;                                                                        \
     int      lastLevelEq = -1, cmp;                                                       \
                                                                                           \
-    if ((*i) == NULL || t->max_depth > (*i)->max_depth)                                   \
-        *i = (sptree_##name##_iterator *) realloc(*i, sizeof(**i) +                       \
+    if ((*i) == NULL || t->max_depth > (*i)->max_depth) {                                 \
+        sptree_##name##_iterator *new_i;                                                  \
+        new_i = (sptree_##name##_iterator *) realloc(*i, sizeof(**i) +                    \
                                        sizeof(spnode_t) * (t->max_depth + 31));           \
+        if (!new_i)                                                                       \
+            return sizeof(**i) + sizeof(spnode_t) * (t->max_depth + 31);                  \
+        *i = new_i;                                                                       \
+    }                                                                                     \
                                                                                           \
     (*i)->t = t;                                                                          \
     (*i)->level = -1;                                                                     \
     if (t->root == SPNIL) {                                                               \
             (*i)->max_depth = 0; /* valgrind points out it's used in the check above ^.*/ \
-            return;                                                                       \
+            return 0;                                                                     \
     }                                                                                     \
                                                                                           \
     (*i)->max_depth = t->max_depth;                                                       \
@@ -621,6 +667,7 @@ sptree_##name##_iterator_init_set(const sptree_##name *t, sptree_##name##_iterat
                                                                                           \
     if (lastLevelEq >= 0)                                                                 \
         (*i)->level = lastLevelEq;                                                        \
+    return 0;                                                                             \
 }                                                                                         \
                                                                                           \
 static inline sptree_##name##_iterator *                                                  \
@@ -630,6 +677,8 @@ sptree_##name##_iterator_reverse_init(sptree_##name *t) {
                                                                                           \
     if (t->root == SPNIL) return NULL;                                                    \
     i = sptree_##name##_iterator_alloc(t);                                                \
+    if (!i)                                                                               \
+        return i;                                                                         \
                                                                                           \
     while( (node = _GET_SPNODE_RIGHT( i->stack[i->level] )) != SPNIL ) {                  \
         i->level++;                                                                       \
@@ -639,21 +688,26 @@ sptree_##name##_iterator_reverse_init(sptree_##name *t) {
     return i;                                                                             \
 }                                                                                         \
                                                                                           \
-static inline void                                                                        \
+static inline int                                                                         \
 sptree_##name##_iterator_reverse_init_set(const sptree_##name *t,                         \
                                           sptree_##name##_iterator **i, void *k) {        \
     spnode_t node;                                                                        \
     int      lastLevelEq = -1, cmp;                                                       \
                                                                                           \
-    if ((*i) == NULL || t->max_depth > (*i)->max_depth)                                   \
-        *i = (sptree_##name##_iterator *) realloc(*i, sizeof(**i) +                       \
-                                      sizeof(spnode_t) * (t->max_depth + 31));            \
+    if ((*i) == NULL || t->max_depth > (*i)->max_depth) {                                 \
+        sptree_##name##_iterator *new_i;                                                  \
+        new_i = (sptree_##name##_iterator *) realloc(*i, sizeof(**i) +                    \
+                                       sizeof(spnode_t) * (t->max_depth + 31));           \
+        if (!new_i)                                                                       \
+            return sizeof(**i) + sizeof(spnode_t) * (t->max_depth + 31);                  \
+        *i = new_i;                                                                       \
+    }                                                                                     \
                                                                                           \
     (*i)->t = t;                                                                          \
     (*i)->level = -1;                                                                     \
     if (t->root == SPNIL) {                                                               \
             (*i)->max_depth = 0;                                                          \
-            return;                                                                       \
+            return 0;                                                                     \
     }                                                                                     \
                                                                                           \
     (*i)->max_depth = t->max_depth;                                                       \
@@ -679,12 +733,13 @@ sptree_##name##_iterator_reverse_init_set(const sptree_##name *t,
                                                                                           \
     if (lastLevelEq >= 0)                                                                 \
         (*i)->level = lastLevelEq;                                                        \
+    return 0;                                                                             \
 }                                                                                         \
                                                                                           \
 static inline void                                                                        \
 sptree_##name##_iterator_free(sptree_##name##_iterator *i) {                              \
     if (i == NULL)    return;                                                             \
-    free(i);                                                                              \
+    i = (sptree_##name##_iterator *)realloc(i, 0);                                        \
 }                                                                                         \
                                                                                           \
 /**                                                                                       \