diff --git a/.travis.yml b/.travis.yml
index f88669a7e42d9b0804c784e76d838210ad1350c7..e828daa083980d5f49d9a8351f3228c9369adfb7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -29,7 +29,6 @@ install:
 script:
   - mkdir ./build && cd ./build && cmake .. -DCMAKE_BUILD_TYPE=RelWithDebugInfo
   - make -j8
-  - make test-force
 
 notifications:
   irc:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2056946f9a33f6fe8f9725a448106207db48fb65..f6281b7ad41999e58516a66f3d8f59bdb4b32fe5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -319,7 +319,6 @@ add_dependencies(build_bundled_libs misc)
 
 include(BuildSophia)
 sophia_build()
-set (sophia_lib "${PROJECT_BINARY_DIR}/third_party/sophia/env/libsophia.a")
 
 option(ENABLE_RPM "Enable install of a RPM specific files" OFF)
 
diff --git a/cmake/BuildSophia.cmake b/cmake/BuildSophia.cmake
index d2af2e5f60e7db5c680ec68a1872a5d3fba54797..65eaccf5dc2c4598b33df838ba5e76e4fcb2c6eb 100644
--- a/cmake/BuildSophia.cmake
+++ b/cmake/BuildSophia.cmake
@@ -1,13 +1,13 @@
 # A macro to build the bundled sophia library
 #
 macro(sophia_build)
-    set(SOPHIA_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/third_party/sophia/env)
+    set(SOPHIA_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/third_party/sophia/sophia)
 	set(SOPHIA_OPTS
 	    CFLAGS="${CMAKE_C_FLAGS}"
 	    LDFLAGS="${CMAKE_SHARED_LINKER_FLAGS}")
 	separate_arguments(SOPHIA_OPTS)
     if (${PROJECT_BINARY_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
-		add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/third_party/sophia/env/libsophia.a
+		add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/third_party/sophia/sophia/libsophia.a
 			WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/third_party/sophia
 			COMMAND $(MAKE) ${SOPHIA_OPTS} clean
 			COMMAND $(MAKE) ${SOPHIA_OPTS} static
@@ -17,7 +17,7 @@ macro(sophia_build)
         add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/third_party/sophia
             COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/third_party/sophia
         )
-		add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/third_party/sophia/env/libsophia.a
+		add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/third_party/sophia/sophia/libsophia.a
 			WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/third_party/sophia
             COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/third_party/sophia ${PROJECT_BINARY_DIR}/third_party/sophia
 			COMMAND $(MAKE) ${SOPHIA_OPTS} clean
@@ -26,7 +26,8 @@ macro(sophia_build)
 		)
     endif()
 	add_custom_target(libsophia ALL
-		DEPENDS ${PROJECT_BINARY_DIR}/third_party/sophia/env/libsophia.a
+		DEPENDS ${PROJECT_BINARY_DIR}/third_party/sophia/sophia/libsophia.a
 	)
-    message(STATUS "Use bundled sophia: ${SOPHIA_INCLUDE_DIR}")
+    message(STATUS "Use bundled Sophia: ${SOPHIA_INCLUDE_DIR}")
+    set (sophia_lib "${PROJECT_BINARY_DIR}/third_party/sophia/sophia/libsophia.a")
 endmacro(sophia_build)
diff --git a/debian/rules b/debian/rules
index de1f870a3af838d4533a5536142a36ec6712db20..1ba99320c456dc2632fdd825aa78fb905c23bbc5 100755
--- a/debian/rules
+++ b/debian/rules
@@ -58,23 +58,11 @@ clean::
 	rm -f doc/tnt.ent
 	rm -f www-data.in/download
 
-# install/tarantool-dbg::
-#         rm -fr debian/tarantool-dbg/usr/share/doc/tarantool-dbg
-
 install/tarantool::
-# 	pod2man -c 'tarantar' \
-# 		debian/tarantar.pod > build-area/tarantar.1
-#         make -C build-area test-force || /bin/true
 
 
-# install/tarantool-common::
-# 	pod2man -c 'tarantool instances control' \
-# 	    debian/tarantool_instance.pod > build-area/tarantool_instance.1
-# 	pod2man -c 'tarantool log rotation' \
-# 	    debian/scripts/tarantool_logrotate \
-# 	    	 > build-area/tarantool_logrotate.1
-# 	pod2man -c 'snapshot rotate' \
-# 	    debian/scripts/tarantool_snapshot_rotate \
-# 	    	> build-area/tarantool_snapshot_rotate.1
-# 	install -m0755 extra/logger.pl \
-# 	    debian/tarantool-common/usr/lib/tarantool/logger
+install/tarantool-common::
+	sed 's/dist.lua/tarantoolctl/g' extra/dist/dist.lua \
+	    > ${DEB_BUILDDIR}/tarantoolctl
+	pod2man -c 'tarantoolctl instances control' \
+	    ${DEB_BUILDDIR}/tarantoolctl > ${DEB_BUILDDIR}/tarantoolctl.1
diff --git a/debian/tarantool-common.logrotate b/debian/tarantool-common.logrotate
index 4fc10a52c0ddaa3f83751666ea5d07e32010e237..7d08ce3cf59ea1e7a7a255be0f3b802e2cef550d 100644
--- a/debian/tarantool-common.logrotate
+++ b/debian/tarantool-common.logrotate
@@ -7,7 +7,7 @@
     delaycompress
     create 0640 tarantool adm
     postrotate
-        /usr/bin/tarantool /usr/lib/tarantool/dist.lua logrotate `basename $1 .log`
+        /usr/bin/tarantool /usr/bin/tarantoolctl logrotate `basename $1 .log`
     endscript
 }
 
diff --git a/debian/tarantool-common.manpages b/debian/tarantool-common.manpages
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..58d0e39064e5094d2d4d4ef45b793c76ffea7dc9 100644
--- a/debian/tarantool-common.manpages
+++ b/debian/tarantool-common.manpages
@@ -0,0 +1 @@
+build-area/tarantoolctl.1
diff --git a/doc/user/configuration-reference.xml b/doc/user/configuration-reference.xml
index 4398484ac8b8b66644556aeec236ee0953a728d7..5a39f48fa1255fdbcbf04c93867626947aa98a3e 100644
--- a/doc/user/configuration-reference.xml
+++ b/doc/user/configuration-reference.xml
@@ -338,6 +338,65 @@ tarantool: primary pri: 3301 adm: 3313</programlisting>
       </tbody>
     </tgroup>
   </table>
+  
+  
+  <table 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>float</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>
@@ -362,7 +421,7 @@ tarantool: primary pri: 3301 adm: 3313</programlisting>
           <entry>boolean</entry>
           <entry>true</entry>
           <entry>no</entry>
-          <entry>If there is an error reading the snapshot file (at
+          <entry>If there is an error while reading the snapshot file (at
             server start), abort.</entry>
         </row>
 
@@ -371,7 +430,7 @@ tarantool: primary pri: 3301 adm: 3313</programlisting>
           <entry>boolean</entry>
           <entry>false</entry>
           <entry>no</entry>
-          <entry>If there is an error reading a write-ahead
+          <entry>If there is an error while reading a write-ahead
           log file (at server start), abort.</entry>
         </row>
 
@@ -456,11 +515,17 @@ tarantool: primary pri: 3301 adm: 3313</programlisting>
           <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 format ip:port.
-          For example, if replication_source = "1.2.3.4:55555" then
-          the replica server tries to connect to 1.2.3.4 port 55555.
-          A replica server does not accept updates
-          on <olink targetptr="primary_port">listen</olink>. This parameter is
+          which replication_source specifies with a URI.
+          The 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 be a user name and password and ip:port address such as 'guest:password@127.0.0.1:3301',
+          or just ip:port address such as '127.0.0.1:3301',
+          or just port such as '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>
@@ -542,7 +607,7 @@ tarantool: primary pri: 3301 adm: 3313</programlisting>
       <tbody>
 
         <row>
-          <entry>log_level</entry>
+          <entry xml:id="log_level" xreflabel="log_level">log_level</entry>
           <entry>integer</entry>
           <entry>5</entry>
           <entry><emphasis role="strong">yes</emphasis></entry>
@@ -557,18 +622,16 @@ tarantool: primary pri: 3301 adm: 3313</programlisting>
         </row>
 
         <row>
-          <entry>logger</entry>
+          <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 given a value, Tarantool creates a child process,
-          executes the command indicated by the value, and pipes its standard
-          output to the standard input of the created process.
-          Example setting: <command>tee -a
-          tarantool.log</command> (this will duplicate log output
-          to <filename>stdout</filename> and a log file).
+          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>
 
diff --git a/doc/user/databases.xml b/doc/user/databases.xml
index d3055c8976cc7bf269ac8ce99e644bab1d664ec2..cc92af0d232b553a19d9eb3f08959a40246e098d 100644
--- a/doc/user/databases.xml
+++ b/doc/user/databases.xml
@@ -638,7 +638,7 @@ tarantool> <userinput>box.space.space55.index.primary:rename('secondary')</useri
     <varlistentry>
         <term>
           <emphasis role="lua" xml:id="box.update">
-          box.space.<replaceable>space-name</replaceable>:update{<replaceable>key, format, {field_no, value}...</replaceable>)
+          box.space.<replaceable>space-name</replaceable>:update({<replaceable>key {, operator, field_no, value}...</replaceable>})
           </emphasis>
         </term>
         <listitem>
@@ -647,46 +647,37 @@ tarantool> <userinput>box.space.space55.index.primary:rename('secondary')</useri
                </para>
   <para>
    The <code>update</code> function supports operations on fields &mdash;
-    assignment, arithmetic operations (the field must be numeric),
-    cutting and pasting fragments of a field, &mdash; as well as
-    operations on a tuple: push and pop of a field at the tail of
-    a tuple, deletion and insertion of a field.  Multiple
-    operations can be combined into a single update, and in this
-    case they are performed atomically. Each operation expects
-    field number as its first argument. When a sequence of changes
-    is present, field identifier in each operation is assumed to
-    be relative to the most recent state of the tuple, i.e. as if
+    assignment, arithmetic (if the field is unsigned numeric),
+    cutting and pasting fragments of a field,
+    deletng 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's always safe to
+    already been applied. In other words, it is always safe to
     merge multiple <code>update</code> invocations into a single invocation, with no
     change in semantics.
   </para>
             <para>
              Parameters: <code>space-name</code>,
               <code>key</code> = primary-key field values, must be passed as a Lua table if key is multi-part,
-                <code>format</code> = a sequence of
-                pairs of characters, where the first character in each pair
-                is the operation specifier, and the second character in
-                each pair is the operation argument.
-                The <code>{field_no, value}</code> arguments are the
-                field numbers of affected fields and applicable values.
+                <code>{operator, field_no, value}</code> = 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.
-                There must be a pair of {field_no, value} arguments
-                for each character pair in the format argument.
-                The format and {field_no, value} arguments are passed to
-                <code>pickle.pack()</code> and the result is sent
-                to <code>box.process()</code>.
-                Possible operation specifiers are: <quote>+</quote>
+                Possible operators are: <quote>+</quote>
                 for addition, <quote>-</quote> for subtraction,
                 <quote>&amp;</quote> for bitwise AND,
                 <quote>|</quote> for bitwise OR, <quote>^</quote>
                 for bitwise exclusive OR (XOR), <quote>:</quote>
-                for string splice, <quote>!</quote> for insertion.
-                Possible operation arguments are: <quote>p</quote>.
-                Thus in the instruction <code>s:update{44,, {{'+p,1,55},{=p',3,'x'}})</code>
+                for string splice, <quote>!</quote> for insert,
+                <quote>#</quote> for delete.
+                Thus in the instruction <code>s:update{44,, {{'+,1,55},{=',3,'x'}})</code>
                 the primary-key value is 44,
-                the formats are '+p' and '=p'
+                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
@@ -764,11 +755,11 @@ 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 1 because deletion will begin with the second byte.
+#   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, 1, 1, '!!'}})
+box.space.tester:update({999}, {{':', 2, 2, 1, '!!'}})
 
 </programlisting>
             </para>
@@ -1871,7 +1862,7 @@ tarantool&gt; <userinput>#t</userinput>
     </varlistentry>
     <varlistentry>
         <term>
-            <emphasis role="lua"> <replaceable>tuple-value</replaceable> : bsize()</emphasis>
+            <emphasis role="lua"> <replaceable>tuple-value</replaceable>:bsize()</emphasis>
         </term>
         <listitem>
             <para>
@@ -1904,7 +1895,7 @@ tarantool&gt; <userinput>t:bsize()</userinput>
     </varlistentry>
     <varlistentry>
         <term>
-            <emphasis role="lua">[ <replaceable>field-number</replaceable> ]</emphasis>
+            <emphasis role="lua"><replaceable>tuple-value</replaceable> [ <replaceable>field-number</replaceable> ]</emphasis>
         </term>
         <listitem>
             <para>
@@ -1932,7 +1923,7 @@ tarantool&gt; <userinput>t[2]</userinput>
 
     <varlistentry>
         <term>
-            <emphasis role="lua">find(<replaceable>[field-number,] field-value) or findall([field-number,] field-value</replaceable>)</emphasis>
+         <emphasis role="lua"><replaceable>tuple-value</replaceable>:find(<replaceable>[field-number,] field-value</replaceable>) or <replaceable>tuple-value</replaceable>:findall(<replaceable>[field-number,] field-value</replaceable>)</emphasis>
         </term>
         <listitem>
             <para>
@@ -1974,7 +1965,7 @@ tarantool&gt; <userinput>t:findall(2, 'a')</userinput>
     </varlistentry>
     <varlistentry>
         <term>
-            <emphasis role="lua">transform(<replaceable>start-field-number, fields-to-remove [, field-value ...]</replaceable>)</emphasis>
+            <emphasis role="lua"><replaceable>tuple-value</replaceable>:transform(<replaceable>start-field-number, fields-to-remove [, field-value ...]</replaceable>)</emphasis>
         </term>
         <listitem>
             <para>
@@ -2007,7 +1998,7 @@ tarantool&gt; <userinput>t:transform(2,2,'x')</userinput>
 
     <varlistentry>
         <term>
-            <emphasis role="lua">slice(<replaceable>start-field-number [, end-field-number]</replaceable>)</emphasis>
+         <emphasis role="lua"><replaceable>tuple-value</replaceable>:slice(<replaceable>start-field-number [, end-field-number]</replaceable>)</emphasis>
         </term>
         <listitem>
             <para>
@@ -2039,7 +2030,7 @@ tarantool&gt; <userinput>t:slice(2, 4)</userinput>
     </varlistentry>
     <varlistentry>
         <term>
-            <emphasis role="lua">unpack()</emphasis>
+            <emphasis role="lua"><replaceable>tuple-value</replaceable>:unpack()</emphasis>
         </term>
         <listitem>
             <para>
@@ -2070,7 +2061,7 @@ tarantool&gt; <userinput>t:unpack()</userinput>
     </varlistentry>
     <varlistentry>
         <term>
-            <emphasis role="lua">pairs()</emphasis>
+            <emphasis role="lua"><replaceable>tuple-value</replaceable>:pairs()</emphasis>
         </term>
         <listitem>
             <para>
@@ -2096,6 +2087,46 @@ tarantool&gt; <userinput>tmp = ''; for k, v in t:pairs() do tmp = tmp .. v end</
 tarantool> <userinput>tmp</userinput>
 ---
 - Fld#1Fld#2Fld#3Fld#4Fld#5
+...</programlisting>
+        </listitem>
+    </varlistentry>
+    
+    <varlistentry>
+        <term>
+            <emphasis role="lua"><replaceable>tuple-value</replaceable>:update(<replaceable>{{format, field_no, value}...}</replaceable>)</emphasis>
+        </term>
+        <listitem>
+            <para>
+              Update a tuple.
+            </para>
+            <para>
+              This function updates a tuple which is not in a space.
+              Compare the function
+              <code>box.space.<replaceable>space-name</replaceable>:update{<replaceable>key, format, {field_no, value}...</replaceable>)</code>,
+              which updates a tuple in a space.
+            </para>
+            <para>
+              Parameters: briefly:
+              <code>format</code> indicates the type of update operation such as '=' for 'assign new value',
+              <code>field_no</code> indicates the field number to change such as 2 for field number 2,
+              <code>value</code> indicates the string which operates on the field such as 'B' for a new assignable value = 'B'.
+              For details: see the description for <code>format</code>, <code>field_no</code>, and <code>value</code>
+              in the section <olink targetptr="box.update"><code>box.space.<replaceable>space-name</replaceable>:update{<replaceable>key, format, {field_no, value}...</replaceable>)</code></olink>.
+            </para>
+            <para>
+              Returns: (type = tuple) the new tuple.
+            </para>
+            <para>
+              In the following example, a tuple named t is created
+              and then its second field is updated to equal 'B'.
+            </para>
+            <bridgehead renderas="sect4">Example</bridgehead>
+<programlisting>tarantool&gt; <userinput>t = box.tuple.new({'Fld#1','Fld#2','Fld#3','Fld#4','Fld#5'})</userinput>
+---
+...
+tarantool&gt; <userinput>t:update({{'=',2,'B'}})</userinput>
+---
+- ['Fld#1', 'B', 'Fld#3', 'Fld#4', 'Fld#5']
 ...</programlisting>
         </listitem>
     </varlistentry>
@@ -2487,7 +2518,7 @@ tarantool> <userinput>box.stat().DELETE -- a selected item of the table</userinp
 
     <varlistentry>
         <term><emphasis role="lua" xml:id="net.box.ping">
-        conn:ping()</emphasis></term>
+        <replaceable>conn</replaceable>:ping()</emphasis></term>
         <listitem>
             <para>
                 Execute a PING command.
@@ -2501,7 +2532,7 @@ tarantool> <userinput>box.stat().DELETE -- a selected item of the table</userinp
 
     <varlistentry>
         <term><emphasis role="lua" xml:id="net.box.close">
-        conn:close()</emphasis></term>
+        <replaceable>conn</replaceable>:close()</emphasis></term>
         <listitem>
             <para>
             Close a connection.
@@ -2522,7 +2553,7 @@ tarantool> <userinput>box.stat().DELETE -- a selected item of the table</userinp
 
     <varlistentry>
         <term><emphasis role="lua" xml:id="net.box.select">
-         conn.space.<replaceable>space-name</replaceable>:select{<replaceable>field-value</replaceable>, ...}</emphasis></term>
+         <replaceable>conn</replaceable>.space.<replaceable>space-name</replaceable>:select{<replaceable>field-value</replaceable>, ...}</emphasis></term>
         <listitem>
             <para>
               <code>conn.space.<replaceable>space-name</replaceable>:select{...}</code> is the remote-call equivalent of the local call
@@ -2536,7 +2567,7 @@ tarantool> <userinput>box.stat().DELETE -- a selected item of the table</userinp
 
     <varlistentry>
         <term><emphasis role="lua" xml:id="net.box.insert">
-         conn.space.<replaceable>space-name</replaceable>:insert{field-value, ...}</emphasis></term>
+         <replaceable>conn</replaceable>.space.<replaceable>space-name</replaceable>:insert{field-value, ...}</emphasis></term>
         <listitem>
             <para>
              <code>conn.space.<replaceable>space-name</replaceable>:insert(...)</code> is the remote-call equivalent of the local call
@@ -2547,7 +2578,7 @@ tarantool> <userinput>box.stat().DELETE -- a selected item of the table</userinp
 
     <varlistentry>
         <term><emphasis role="lua" xml:id="net.box.replace">
-         conn.space.<replaceable>space-name</replaceable>:replace{field-value, ...}</emphasis></term>
+         <replaceable>conn</replaceable>.space.<replaceable>space-name</replaceable>:replace{field-value, ...}</emphasis></term>
         <listitem>
             <para>
               <code>conn.space.<replaceable>space-name</replaceable>:replace(...)</code> is the remote-call equivalent of the local call
@@ -2558,7 +2589,7 @@ tarantool> <userinput>box.stat().DELETE -- a selected item of the table</userinp
 
     <varlistentry>
         <term><emphasis role="lua" xml:id="net.box.update">
-         conn.space.<replaceable>space-name</replaceable>:update(<replaceable>key</replaceable>, <replaceable>format</replaceable>, ...)</emphasis></term>
+         <replaceable>conn</replaceable>.space.<replaceable>space-name</replaceable>:update(<replaceable>key</replaceable>, <replaceable>format</replaceable>, ...)</emphasis></term>
         <listitem>
             <para>
              <code>conn.space.<replaceable>space-name</replaceable>:update(...)</code> is the remote-call equivalent of the local call
@@ -2569,7 +2600,7 @@ tarantool> <userinput>box.stat().DELETE -- a selected item of the table</userinp
 
     <varlistentry>
         <term><emphasis role="lua" xml:id="net.box.delete">
-         conn.space.<replaceable>space-name</replaceable>:delete{key}</emphasis></term>
+         <replaceable>conn</replaceable>.space.<replaceable>space-name</replaceable>:delete{key}</emphasis></term>
         <listitem>
             <para>
               <code>conn.space.<replaceable>space-name</replaceable>:delete{...}</code> is the remote-call equivalent of the local call
@@ -2580,7 +2611,7 @@ tarantool> <userinput>box.stat().DELETE -- a selected item of the table</userinp
 
     <varlistentry>
         <term><emphasis role="lua" xml:id="net.box.call">
-         conn:call(<replaceable>function-name</replaceable> [, <replaceable>arguments</replaceable>])</emphasis></term>
+         <replaceable>conn</replaceable>:call(<replaceable>function-name</replaceable> [, <replaceable>arguments</replaceable>])</emphasis></term>
         <listitem>
             <para>
               <code>conn:call('func', '1', '2', '3')</code> is the remote-call equivalent of <code>func('1', '2', '3')</code>.
@@ -2594,7 +2625,7 @@ tarantool> <userinput>box.stat().DELETE -- a selected item of the table</userinp
 
     <varlistentry>
         <term><emphasis role="lua" xml:id="net.box.timeout">
-         conn:timeout(<replaceable>timeout</replaceable>)</emphasis></term>
+         <replaceable>conn</replaceable>:timeout(<replaceable>timeout</replaceable>)</emphasis></term>
         <listitem>
             <para>
               <code>timeout(...)</code> is a wrapper which sets a timeout for the request that follows it.
diff --git a/doc/user/replication.xml b/doc/user/replication.xml
index c2856b36e5874370e625a3534334f78b97963d6d..668a80bd6a1b800db0fe88d7a206c24af18c13d5 100644
--- a/doc/user/replication.xml
+++ b/doc/user/replication.xml
@@ -68,8 +68,8 @@ identifier which is unique within the cluster, known as the
     To prepare the master for connections from the replica, it's only
     necessary to include "listen" in the initial <code>box.cfg</code>
     request, for example <code>box.cfg{listen=3301}</code>.
-    A master with enabled "listen" uri can accept connections
-    from as many replicas as necessary on that uri. Each replica
+    A master with enabled "listen" URI can accept connections
+    from as many replicas as necessary on that URI. Each replica
     has its own replication state.
   </para>
 </section>
@@ -120,7 +120,7 @@ identifier which is unique within the cluster, known as the
   <para>
     However, once a master failure is detected, the recovery
     is simple: declare that the replica is now the new master,
-    by saying <code>box.cfg{... listen=uri}</code>.
+    by saying <code>box.cfg{... listen=URI}</code>.
     Then, if there are updates on the old master that were not
     propagated before the old master went down, they would have
     to be re-applied manually.
diff --git a/doc/user/stored-procedures.xml b/doc/user/stored-procedures.xml
index 58316d104d4fdad4d2e9985e1017befdad78d44b..75f38d7bd02a37ff7a412f358714c67a1a3dae1b 100644
--- a/doc/user/stored-procedures.xml
+++ b/doc/user/stored-procedures.xml
@@ -154,7 +154,8 @@ The included language processor is <link xlink:href="http://luajit.org/">LuaJIT<
 Major "built-in" components are: fibers,
 <link xlink:href="http://msgpack.org">MsgPack</link>,
 digest, JSON, <link xlink:href="http://en.wikipedia.org/wiki/Yaml">YAML</link>,
-<link xlink:href="http://en.wikipedia.org/wiki/Inter-process_communication">IPC</link> , and box.
+<link xlink:href="http://en.wikipedia.org/wiki/Inter-process_communication">IPC</link>,
+fio, and box.
 </para>
 
 <para>
@@ -226,7 +227,12 @@ underlying information about typing, arrays, and structures.
 
 <para>
 <emphasis>IPC</emphasis> is Inter-Process Communication.
-this is useful for implementations of task queues and long polling.
+This is useful for implementations of task queues and long polling.
+</para>
+
+<para>
+<emphasis>Fio</emphasis> is standard file IO,
+adapted to work with Tarantool's fibers in a cooperative environment.
 </para>
 
 <para>
@@ -282,7 +288,8 @@ administration with the built-in packages.
     <link xlink:href="https://en.wikipedia.org/wiki/Sha-2">SHA-2</link>)
 
     as well as a checksum function
-    (<link xlink:href="https://en.wikipedia.org/wiki/Cyclic_redundancy_check">CRC32</link>).
+    (<link xlink:href="https://en.wikipedia.org/wiki/Cyclic_redundancy_check">CRC32</link>)
+    and two functions for <link xlink:href="https://en.wikipedia.org/wiki/Base64">base64</link>.
     The functions in <code>digest</code> are:
     <informaltable>
     <tgroup cols="2" align="left" colsep="1" rowsep="0">
@@ -308,6 +315,8 @@ administration with the built-in packages.
     <row><entry><code>digest.md4_hex(<replaceable>string</replaceable>)</code></entry><entry>                Returns hexadecimal of a digest calculated with md4.</entry></row>
     <row><entry><code>digest.md5(<replaceable>string</replaceable>)</code></entry><entry>                    Returns 256-bit digest made with MD5.</entry></row>
     <row><entry><code>digest.md5_hex(<replaceable>string</replaceable>)</code></entry><entry>                Returns hexadecimal of a digest calculated with md5.</entry></row>
+    <row><entry><code>digest.base64_encode(<replaceable>string</replaceable>)</code></entry><entry>          Returns base64 encoding from a regular string.</entry></row>
+    <row><entry><code>digest.base64_decode(<replaceable>string</replaceable>)</code></entry><entry>          Returns a regular string from a base64 encoding.</entry></row>
     </tbody>
     </tgroup>                                   
     </informaltable>
@@ -453,7 +462,7 @@ Password is not valid
 
     <varlistentry>
         <term>
-            <emphasis role="lua">:isnil(<replaceable>uuid_with_type_cdata</replaceable>)</emphasis>
+            <emphasis role="lua"><replaceable>uuid_with_type_cdata</replaceable>:isnil()</emphasis>
         </term>
         <listitem>
             <para>
@@ -1157,7 +1166,7 @@ the status is dead because the cancel worked.<programlisting>
         </listitem>
     </varlistentry>
     <varlistentry>
-        <term><emphasis role="lua">channel:put(<replaceable>message[, timeout]</replaceable>)</emphasis></term>
+        <term><emphasis role="lua"><replaceable>channel</replaceable>:put(<replaceable>message[, timeout]</replaceable>)</emphasis></term>
         <listitem>
             <para>
                 Send a message using a channel. If the channel is full,
@@ -1177,7 +1186,7 @@ the status is dead because the cancel worked.<programlisting>
         </listitem>
     </varlistentry>
     <varlistentry>
-        <term><emphasis role="lua">channel:close()</emphasis></term>
+        <term><emphasis role="lua"><replaceable>channel</replaceable>:close()</emphasis></term>
         <listitem>
             <para>
                Close the channel. All waiters in the channel will be
@@ -1188,7 +1197,7 @@ the status is dead because the cancel worked.<programlisting>
         </listitem>
     </varlistentry>
     <varlistentry>
-        <term><emphasis role="lua">channel:get(<replaceable>[timeout]</replaceable>)</emphasis></term>
+        <term><emphasis role="lua"><replaceable>channel</replaceable>:get(<replaceable>[timeout]</replaceable>)</emphasis></term>
         <listitem>
             <para>
                 Fetch a message from a channel. If the channel is empty,
@@ -1211,7 +1220,7 @@ the status is dead because the cancel worked.<programlisting>
         </listitem>
     </varlistentry>
     <varlistentry>
-        <term><emphasis role="lua">channel:broadcast(<replaceable>message</replaceable>)</emphasis></term>
+        <term><emphasis role="lua"><replaceable>channel</replaceable>:broadcast(<replaceable>message</replaceable>)</emphasis></term>
         <listitem>
             <para>
              If the channel is empty, <code>channel:broadcast()</code> is equivalent to
@@ -1225,7 +1234,7 @@ the status is dead because the cancel worked.<programlisting>
         </listitem>
     </varlistentry>
     <varlistentry>
-        <term><emphasis role="lua">channel:is_empty()</emphasis></term>
+        <term><emphasis role="lua"><replaceable>channel</replaceable>:is_empty()</emphasis></term>
         <listitem>
             <para>
                Check whether the specified channel is empty (has no messages).
@@ -1236,7 +1245,7 @@ the status is dead because the cancel worked.<programlisting>
         </listitem>
     </varlistentry>
     <varlistentry>
-        <term><emphasis role="lua">channel:is_full()</emphasis></term>
+        <term><emphasis role="lua"><replaceable>channel</replaceable>:is_full()</emphasis></term>
         <listitem>
             <para>
                 Check whether the specified channel is full.
@@ -1247,7 +1256,7 @@ the status is dead because the cancel worked.<programlisting>
         </listitem>
     </varlistentry>
     <varlistentry>
-        <term><emphasis role="lua">channel:has_readers()</emphasis></term>
+        <term><emphasis role="lua"><replaceable>channel</replaceable>:has_readers()</emphasis></term>
         <listitem>
             <para>
                Check whether the specified channel is empty and has readers waiting
@@ -1260,7 +1269,7 @@ the status is dead because the cancel worked.<programlisting>
         </listitem>
     </varlistentry>
     <varlistentry>
-        <term><emphasis role="lua">channel:has_writers()</emphasis></term>
+        <term><emphasis role="lua"><replaceable>channel</replaceable>:has_writers()</emphasis></term>
         <listitem>
             <para>
                 Check whether the specified channel is full and has writers waiting
@@ -1273,7 +1282,7 @@ the status is dead because the cancel worked.<programlisting>
         </listitem>
     </varlistentry>
     <varlistentry>
-        <term><emphasis role="lua">channel:is_closed()</emphasis></term>
+        <term><emphasis role="lua"><replaceable>channel</replaceable>:is_closed()</emphasis></term>
         <listitem>
             <simpara>
                 Returns: (type = boolean) true if the specified channel is already
@@ -1531,7 +1540,7 @@ end
     </varlistentry>
 
     <varlistentry>
-        <term xml:id="socket-sysconnect" xreflabel="socket-sysconnect"><emphasis role="lua">sock:sysconnect(<replaceable>host, port</replaceable>)</emphasis></term>
+        <term xml:id="socket-sysconnect" xreflabel="socket-sysconnect"><emphasis role="lua"><replaceable>sock</replaceable>:sysconnect(<replaceable>host, port</replaceable>)</emphasis></term>
         <listitem>
             <para>
                 Connect a socket to a remote host.
@@ -1554,7 +1563,7 @@ end
     </varlistentry>
 
     <varlistentry>
-        <term xml:id="socket-tcpconnect" xreflabel="socket-tcpconnect"><emphasis role="lua">sock:tcp_connect(<replaceable>host, port</replaceable>)</emphasis></term>
+        <term xml:id="socket-tcpconnect" xreflabel="socket-tcpconnect"><emphasis role="lua">socket.tcp_connect(<replaceable>host, port</replaceable>)</emphasis></term>
         <listitem>
             <para>
                 Connect a socket to a remote host.
@@ -1566,13 +1575,13 @@ end
                 Returns: (type = userdata) a connected socket, if no error.
             </para>
             <para>
-                Example: <code>sock:tcp_connect('tarantool.org', 80)</code>
+                Example: <code>socket.tcp_connect('tarantool.org', 80)</code>
             </para>
         </listitem>
     </varlistentry>
 
     <varlistentry>
-        <term xml:id="socket-send" xreflabel="socket-send"><emphasis role="lua">sock:send(<replaceable>data</replaceable>)</emphasis></term>
+        <term xml:id="socket-send" xreflabel="socket-send"><emphasis role="lua"><replaceable>sock</replaceable>:send(<replaceable>data</replaceable>)</emphasis></term>
         <listitem>
             <para>
              Send data over a connected socket.
@@ -1590,7 +1599,7 @@ end
     </varlistentry>
     
     <varlistentry>
-        <term xml:id="socket-syswrite" xreflabel="socket-syswrite"><emphasis role="lua">sock:syswrite(<replaceable>size</replaceable>)</emphasis></term>
+        <term xml:id="socket-syswrite" xreflabel="socket-syswrite"><emphasis role="lua"><replaceable>sock</replaceable>:syswrite(<replaceable>size</replaceable>)</emphasis></term>
         <listitem>
             <para>
               Write as much as possible data to the socket buffer if non-blocking.
@@ -1622,7 +1631,7 @@ end
     </varlistentry>
 
     <varlistentry>
-        <term xml:id="socket-readline" xreflabel="socket-readline"><emphasis role="lua">sock:readline(<replaceable>[limit] [, separator list]</replaceable>)</emphasis></term>
+        <term xml:id="socket-readline" xreflabel="socket-readline"><emphasis role="lua"><replaceable>sock</replaceable>:readline(<replaceable>[limit] [, separator list]</replaceable>)</emphasis></term>
         <listitem>
             <para>
                 Read a line from a connected socket.
@@ -1669,7 +1678,7 @@ end
     </varlistentry>
 
     <varlistentry>
-     <term xml:id="socket-read" xreflabel="socket-read"><emphasis role="lua">sock:read(<replaceable>size</replaceable>)</emphasis></term>
+     <term xml:id="socket-read" xreflabel="socket-read"><emphasis role="lua"><replaceable>sock</replaceable>:read(<replaceable>size</replaceable>)</emphasis></term>
         <listitem>
             <para>
              Read data on a socket, until <code>size</code> bytes have been read,
@@ -1680,7 +1689,7 @@ end
     </varlistentry>
 
     <varlistentry>
-        <term xml:id="socket-sysread" xreflabel="socket-sysread"><emphasis role="lua">sock:sysread(<replaceable>size</replaceable>)</emphasis></term>
+        <term xml:id="socket-sysread" xreflabel="socket-sysread"><emphasis role="lua"><replaceable>sock</replaceable>:sysread(<replaceable>size</replaceable>)</emphasis></term>
         <listitem>
             <para>
               Return all available data from the socket buffer if non-blocking.
@@ -1690,7 +1699,7 @@ end
     </varlistentry>
 
     <varlistentry>
-        <term xml:id="socket-bind" xreflabel="socket-bind"><emphasis role="lua">sock:bind(<replaceable>host, port</replaceable>)</emphasis></term>
+        <term xml:id="socket-bind" xreflabel="socket-bind"><emphasis role="lua"><replaceable>sock</replaceable>:bind(<replaceable>host, port</replaceable>)</emphasis></term>
         <listitem>
             <para>
                 Bind a socket to the given host/port.
@@ -1709,7 +1718,7 @@ end
     </varlistentry>
 
     <varlistentry>
-        <term xml:id="socket-listen" xreflabel="socket-listen"><emphasis role="lua">sock:listen(backlog)</emphasis></term>
+        <term xml:id="socket-listen" xreflabel="socket-listen"><emphasis role="lua"><replaceable>sock</replaceable>:listen(backlog)</emphasis></term>
         <listitem>
             <para>
                 Start listening for incoming connections.
@@ -1726,7 +1735,7 @@ end
     </varlistentry>
 
     <varlistentry>
-        <term xml:id="socket-accept" xreflabel="socket-accept"><emphasis role="lua">sock:accept()</emphasis></term>
+        <term xml:id="socket-accept" xreflabel="socket-accept"><emphasis role="lua"><replaceable>sock</replaceable>:accept()</emphasis></term>
         <listitem>
             <para>
                 Accept a new client connection and create a new connected socket.
@@ -1739,7 +1748,7 @@ end
     </varlistentry>
 
     <varlistentry>
-        <term xml:id="socket-sendto" xreflabel="socket-sendto"><emphasis role="lua">sock:sendto(<replaceable>data, host, port</replaceable>)</emphasis></term>
+        <term xml:id="socket-sendto" xreflabel="socket-sendto"><emphasis role="lua"><replaceable>sock</replaceable>:sendto(<replaceable>data, host, port</replaceable>)</emphasis></term>
         <listitem>
             <para>
                 Send a message on a UDP socket to a specified host.
@@ -1755,7 +1764,7 @@ end
     </varlistentry>
 
     <varlistentry>
-        <term xml:id="socket-recvfrom" xreflabel="socket-recvfrom"><emphasis role="lua">sock:recvfrom(<replaceable>limit</replaceable>)</emphasis></term>
+        <term xml:id="socket-recvfrom" xreflabel="socket-recvfrom"><emphasis role="lua"><replaceable>sock</replaceable>:recvfrom(<replaceable>limit</replaceable>)</emphasis></term>
         <listitem>
             <para>
                 Receive a message on a UDP socket.
@@ -1771,7 +1780,7 @@ end
     </varlistentry>
 
     <varlistentry>
-        <term xml:id="socket-shutdown" xreflabel="socket-shutdown"><emphasis role="lua">sock:shutdown(<replaceable>how</replaceable>)</emphasis></term>
+        <term xml:id="socket-shutdown" xreflabel="socket-shutdown"><emphasis role="lua"><replaceable>sock</replaceable>:shutdown(<replaceable>how</replaceable>)</emphasis></term>
         <listitem>
             <para>
                 Shutdown a reading end, a writing end, or both ends of a socket.
@@ -1787,7 +1796,7 @@ end
     </varlistentry>
 
     <varlistentry>
-        <term xml:id="socket-close" xreflabel="socket-close"><emphasis role="lua">sock:close()</emphasis></term>
+        <term xml:id="socket-close" xreflabel="socket-close"><emphasis role="lua"><replaceable>sock</replaceable>:close()</emphasis></term>
         <listitem>
             <para>
                 Close (destroy) a socket.
@@ -1803,7 +1812,7 @@ end
     </varlistentry>
 
     <varlistentry>
-        <term xml:id="socket-error" xreflabel="socket-error"><emphasis role="lua">sock:error() and sock:errno()</emphasis></term>
+        <term xml:id="socket-error" xreflabel="socket-error"><emphasis role="lua"><replaceable>sock</replaceable>:error() and <replaceable>sock</replaceable>:errno()</emphasis></term>
         <listitem>
             <para>
                 Retrieve information about the last error that occurred on a socket, if any.
@@ -1819,7 +1828,7 @@ end
     </varlistentry>
     
     <varlistentry>
-        <term xml:id="socket-setsockopt" xreflabel="socket-setsockopt"><emphasis role="lua">sock:setsockopt(<replaceable>level, name, value</replaceable>)</emphasis></term>
+        <term xml:id="socket-setsockopt" xreflabel="socket-setsockopt"><emphasis role="lua"><replaceable>sock</replaceable>:setsockopt(<replaceable>level, name, value</replaceable>)</emphasis></term>
         <listitem>
             <para>
              Set socket flags. The argument values are the same as in the <link xlink:href="http://man7.org/linux/man-pages/man2/setsockopt.2.html">Linux man page</link>.
@@ -1835,7 +1844,7 @@ end
     </varlistentry>
 
     <varlistentry>
-        <term xml:id="socket-getsockopt" xreflabel="socket-getsockopt"><emphasis role="lua">sock:getsockopt(<replaceable>level, name</replaceable>)</emphasis></term>
+        <term xml:id="socket-getsockopt" xreflabel="socket-getsockopt"><emphasis role="lua"><replaceable>sock</replaceable>:getsockopt(<replaceable>level, name</replaceable>)</emphasis></term>
         <listitem>
             <para>
               Get socket flags. For a list of possible flags see description of the previous function,
@@ -1845,7 +1854,7 @@ end
     </varlistentry>
 
     <varlistentry>
-        <term xml:id="socket-linger" xreflabel="socket-linger"><emphasis role="lua">sock:linger([<replaceable>active</replaceable>])</emphasis></term>
+        <term xml:id="socket-linger" xreflabel="socket-linger"><emphasis role="lua"><replaceable>sock</replaceable>:linger([<replaceable>active</replaceable>])</emphasis></term>
         <listitem>
             <para>
               Set or clear the SO_LINGER flag. For a description of the flag, see  <link xlink:href="http://man7.org/linux/man-pages/man1/loginctl.1.html">Linux man page</link>.
@@ -1860,7 +1869,7 @@ end
     </varlistentry>
     
     <varlistentry>
-        <term xml:id="socket-nonblock" xreflabel="socket-nonblock"><emphasis role="lua">sock:nonblock([<replaceable>flag</replaceable>])</emphasis></term>
+        <term xml:id="socket-nonblock" xreflabel="socket-nonblock"><emphasis role="lua"><replaceable>sock</replaceable>:nonblock([<replaceable>flag</replaceable>])</emphasis></term>
         <listitem>
             <para>
              <code>sock:nonblock()</code> returns the current flag value.
@@ -1872,7 +1881,7 @@ end
     </varlistentry>
     
     <varlistentry>
-     <term xml:id="socket-readable" xreflabel="socket-readable"><emphasis role="lua">sock:readable([<replaceable>timeout</replaceable>])</emphasis>, <emphasis>sock:writable([<replaceable>timeout</replaceable>])</emphasis>, <emphasis>sock:wait([<replaceable>timeout</replaceable>])</emphasis></term>
+     <term xml:id="socket-readable" xreflabel="socket-readable"><emphasis role="lua"><replaceable>sock</replaceable>:readable([<replaceable>timeout</replaceable>])</emphasis>, <emphasis>sock:writable([<replaceable>timeout</replaceable>])</emphasis>, <emphasis>sock:wait([<replaceable>timeout</replaceable>])</emphasis></term>
         <listitem>
             <para>
                <code>sock:readable()</code> waits until something is readable, or until a timeout value expires.
@@ -2432,7 +2441,7 @@ end
     one Tarantool server to start listening on an
     administrative host/port.
     </para> 
-    
+
  
 <variablelist>
  
@@ -2497,9 +2506,9 @@ end
         <listitem>
             <para>
                 Listen on host:port. The primary way of listening for incoming
-                requests is via the host and port, or uri, specified in
+                requests is via the host and port, or URI, specified in
                 <code>box.cfg{listen=...}</code>. The alternative way of
-                listening is via the host and port, or uri, specified in
+                listening is via the host and port, or URI, specified in
                 <code>console.listen(...)</code>. This alternative way is
                 called "administrative" or simply "admin port".
            </para>
@@ -2529,6 +2538,61 @@ end
 
 
 
+</section>
+
+
+<section xml:id="sp-log">
+ <title>package <code>log</code></title>
+     <para>
+     The Tarantool server puts all diagnostic messages in a log file
+     specified by the  <link linkend="logger">logger</link>
+     configuration parameter. Diagnostic messages may be either
+     system-generated by the server's internal code, or user-generated
+     with the <code>log.<replaceable>log_level_function_name</replaceable></code> function.
+     </para>
+<variablelist>
+    <varlistentry>
+     <term><emphasis role="lua">log.<replaceable>log_level_function_name</replaceable>(<replaceable>log_message</replaceable>)</emphasis></term>
+       <listitem>
+         <para>
+         Output a user-generated message to the <link linkend="logger">log file</link>, given
+         log_level_function_name = <code>error</code> or <code>warn</code> or <code>info</code>
+         or <code>debug</code> or <code>rotate</code>.
+         </para>
+         <para>
+         Returns: nothing.
+         </para>
+         <para>
+         Parameters: (type = string) log_message. The actual output will be a
+         line containing the current timestamp, a module name, 'E' or 'W' or 'I' or 'D' or 'R' depending on
+         log_level_function_name, and log_message. Output will not occur if log_level_function_name is for a type greater than
+         <link linkend="log_level">log_level</link>.
+         </para>
+         <para>
+         <bridgehead renderas="sect4">Example showing use of log</bridgehead><programlisting>
+#From the shell:
+#Start the server, do some requests, exit, and display the log, thus:
+~/tarantool/src/tarantool
+box.cfg{log_level=3, logger='tarantool.txt'}
+log = require('log')
+log.error('Error')
+log.info('Info')
+os.exit()
+less tarantool.txt
+</programlisting>
+         The output from the <code>less</code> command will look approximately like this:
+<programlisting>
+2014-09-21 17:58:40.820 [5257] main/101/interactive C> version 1.6.3-355-ga4f762d
+2014-09-21 17:58:40.821 [5257] main/101/interactive C> log level 3
+2014-09-21 17:58:40.821 [5261] main/101/spawner C> initialized
+2014-09-21 17:58:40.830 [5257] main/101/interactive [C]:-1 E> Error
+</programlisting>
+         The 'Error' line is visible in tarantool.txt preceded by the letter E.
+         The 'Info' line is not present because the log_level is 3.
+         </para>
+        </listitem>
+    </varlistentry>
+   </variablelist>
 </section>
 
 <section xml:id="sp-tonumber64">
diff --git a/doc/user/tutorial.xml b/doc/user/tutorial.xml
index 7379892b901524a450c1119f6b68edb753f277f3..c11b52f6ba3b147f2cf2c5c5f4d479015d1bc87f 100644
--- a/doc/user/tutorial.xml
+++ b/doc/user/tutorial.xml
@@ -350,16 +350,7 @@ ones unless you intend to work on the documentation.</para>
 <command>cd</command> python-daemon-1.5.5
 <command>sudo python</command> setup.py install
 </userinput>
-# python module for template engine (jinja2): For documentation:
-# (If wget fails, check the <citetitle xlink:href="https://pypi.python.org/pypi/Jinja2" xlink:title="Python Jinja2">python-jinja2</citetitle> web site
-# to see what the current version is.)
-<userinput>
-<command>cd</command> ~
-<command>wget</command> https://pypi.python.org/packages/source/J/Jinja2/Jinja2-2.7.2.tar.gz
-<command>tar</command> <option>-xzvf</option> Jinja2-2.7.2.tar.gz
-<command>cd</command> Jinja2-2.7.2
-<command>sudo python</command> setup.py install
-</userinput>
+
 # python module for text-to-html conversion (markdown): For documentation:
 # (If wget fails, check the <citetitle xlink:href="http://pypi.python.org/pypi/Markdown/" xlink:title="Python implementation of Markdown">python-markdown</citetitle> web site
 # to see what the current version is.)
@@ -370,6 +361,19 @@ ones unless you intend to work on the documentation.</para>
 <command>cd</command> Markdown-2.3.1
 <command>sudo python</command> setup.py install
 </userinput>
+# python module which includes Jinja2 template engine: For documentation:
+<userinput>
+<command>sudo pip install pelican</command>
+</userinput>
+# python module for HTML scraping: For documentation:
+<userinput>
+<command>cd</command> ~
+<command>wget</command> http://www.crummy.com/software/BeautifulSoup/bs3/download//3.x/BeautifulSoup-3.2.1.tar.gz
+<command>tar</command> -xzvf BeautifulSoup-3.2.1.tar.gz
+<command>cd</command> BeautifulSoup-3.2.1
+<command>sudo python</command> setup.py install
+</userinput>
+
 </programlisting>
 </para>
 
diff --git a/extra/dist/default/tarantool b/extra/dist/default/tarantool
index 81faf68920a1a7d6b61794b59c2ed71c736a532c..a861bdf5f135e95405a28eab718517f5992537d6 100644
--- a/extra/dist/default/tarantool
+++ b/extra/dist/default/tarantool
@@ -1,10 +1,11 @@
 -- Options for Tarantool
 default_cfg = {
-    pid_file    =   "/var/run/tarantool", -- will become pid_file .. instance .. '.pid'
-    wal_dir     =   "/var/lib/tarantool", -- will become wal_dir/instance/
-    snap_dir    =   "/var/lib/tarantool", -- snap_dir/instance/
-    logger      =   "/var/log/tarantool", -- logger/instance .. '.log'
-    username    =   "tarantool",
+    pid_file   = "/var/run/tarantool", -- will become pid_file .. instance .. '.pid'
+    wal_dir    = "/var/lib/tarantool", -- will become wal_dir/instance/
+    snap_dir   = "/var/lib/tarantool", -- snap_dir/instance/
+    sophia_dir = "/var/lib/tarantool", -- will become sophia_dir/sophia/instance/
+    logger     = "/var/log/tarantool", -- logger/instance .. '.log'
+    username   = "tarantool",
 }
 
 instance_dir = "/etc/tarantool/instances.enabled"
diff --git a/extra/dist/dist.lua b/extra/dist/dist.lua
index d48317b28faf6b0c8ae8207d21385618f0c211e9..9e14590b8bd400a2f8468817f7c23b2ebde78002 100755
--- a/extra/dist/dist.lua
+++ b/extra/dist/dist.lua
@@ -1,5 +1,93 @@
 #!/usr/bin/env tarantool
 
+--[[
+
+=head1 NAME
+
+dist.lua - an utility to control tarantool instances
+
+=head1 SYNOPSIS
+
+    vim /etc/tarantool/instances.enabled/my_instance.lua
+    dist.lua start my_instance
+    dist.lua stop  my_instance
+    dist.lua logrotate my_instance
+
+=head1 DESCRIPTION
+
+The script is read C</etc/sysconfig/tarantool> or C</etc/default/tarantool>.
+The file contains common default instances options:
+
+    $ cat /etc/default/tarantool
+
+
+    -- Options for Tarantool
+    default_cfg = {
+        -- will become pid_file .. instance .. '.pid'
+        pid_file    =   "/var/run/tarantool",
+        
+        -- will become wal_dir/instance/
+        wal_dir     =   "/var/lib/tarantool",
+        
+        -- snap_dir/instance/
+        snap_dir    =   "/var/lib/tarantool",
+
+        -- sophia_dir/instance/
+        sophia_dir  =   "/var/lib/tarantool/sophia",
+        
+        -- logger/instance .. '.log'
+        logger      =   "/var/log/tarantool",
+
+        username    =   "tarantool",
+    }
+
+    instance_dir = "/etc/tarantool/instances.enabled"
+
+
+The file defines C<instance_dir> where user can place his
+applications (instances).
+
+Each instance can be controlled by C<dist.lua>:
+
+=head2 Starting instance
+
+    dist.lua start instance_name
+
+=head2 Stopping instance
+
+    dist.lua stop instance_name
+
+=head2 Logrotate instance's log
+
+    dist.lua logrotate instance_name
+
+=head2 Enter instance admin console
+
+    dist.lua enter instance_name
+
+=head2 status
+
+    dist.lua status instance_name
+
+Check if instance is up.
+
+If pid file exists and control socket exists and control socket is alive
+returns code C<0>.
+
+Return code != 0 in other cases. Can complain in log (stderr) if pid file
+exists and socket doesn't, etc.
+
+=head1 COPYRIGHT
+
+Copyright (C) 2010-2013 Tarantool AUTHORS:
+please see AUTHORS file.
+
+
+
+=cut
+
+]]
+
 local fio = require 'fio'
 local log = require 'log'
 local errno = require 'errno'
@@ -41,19 +129,21 @@ if instance_dir == nil then
     instance_dir = '/etc/tarantool/instances.enabled'
 end
 
-default_cfg.pid_file =  default_cfg.pid_file and default_cfg.pid_file or "/var/run/tarantool"
-default_cfg.wal_dir =  default_cfg.wal_dir and default_cfg.wal_dir or "/var/lib/tarantool"
-default_cfg.snap_dir =  default_cfg.snap_dir and default_cfg.snap_dir or "/var/lib/tarantool"
-default_cfg.logger =  default_cfg.logger and default_cfg.logger or "/var/log/tarantool"
-default_cfg.username =  default_cfg.username and default_cfg.username or "tarantool"
+default_cfg.pid_file   = default_cfg.pid_file and default_cfg.pid_file or "/var/run/tarantool"
+default_cfg.wal_dir    = default_cfg.wal_dir and default_cfg.wal_dir or "/var/lib/tarantool"
+default_cfg.snap_dir   = default_cfg.snap_dir and default_cfg.snap_dir or "/var/lib/tarantool"
+default_cfg.sophia_dir = default_cfg.sophia_dir and default_cfg.sophia_dir or "/var/lib/tarantool"
+default_cfg.logger     = default_cfg.logger and default_cfg.logger or "/var/log/tarantool"
+default_cfg.username   = default_cfg.username and default_cfg.username or "tarantool"
 
 -- create  a path to the control socket (admin console)
 local console_sock = fio.pathjoin(default_cfg.pid_file, instance .. '.control')
 
-default_cfg.pid_file = fio.pathjoin(default_cfg.pid_file, instance .. '.pid')
-default_cfg.wal_dir = fio.pathjoin(default_cfg.wal_dir, instance)
-default_cfg.snap_dir = fio.pathjoin(default_cfg.snap_dir, instance)
-default_cfg.logger = fio.pathjoin(default_cfg.logger, instance .. '.log')
+default_cfg.pid_file   = fio.pathjoin(default_cfg.pid_file, instance .. '.pid')
+default_cfg.wal_dir    = fio.pathjoin(default_cfg.wal_dir, instance)
+default_cfg.snap_dir   = fio.pathjoin(default_cfg.snap_dir, instance)
+default_cfg.sophia_dir = fio.pathjoin(default_cfg.sophia_dir, instance, 'sophia')
+default_cfg.logger     = fio.pathjoin(default_cfg.logger, instance .. '.log')
 
 local instance_lua = fio.pathjoin(instance_dir, instance .. '.lua')
 
@@ -76,16 +166,18 @@ function mk_default_dirs(cfg)
     if fio.stat(pid_dir) == nil then
         mkdir(pid_dir)
     end
-
     -- create wal_dir 
     if fio.stat(cfg.wal_dir) == nil then
         mkdir(cfg.wal_dir)
     end
-
     -- create snap_dir 
     if fio.stat(cfg.snap_dir) == nil then
         mkdir(cfg.snap_dir)
     end
+    -- create sophia_dir
+    if fio.stat(cfg.sophia_dir) == nil then
+        mkdir(cfg.sophia_dir)
+    end
     -- create log_dir
     log_dir = fio.dirname(cfg.logger)
     if log_dir:find('|') == nil and fio.stat(log_dir) == nil then
@@ -176,6 +268,52 @@ elseif cmd == 'logrotate' then
     s:read({ '[.][.][.]' }, 2)
 
     os.exit(0)
+
+elseif cmd == 'enter' then
+    if fio.stat(console_sock) == nil then
+        log.error("Can't connect to %s (socket not found)", console_sock)
+        os.exit(-1)
+    end
+    
+    log.info('Connecting to %s', console_sock)
+    
+    local cmd = string.format(
+        "require('console').connect('%s')", console_sock)
+
+    console.on_start( function(self) self:eval(cmd) end )
+    console.on_client_disconnect( function(self) self.running = false end )
+    console.start()
+    os.exit(0)
+elseif cmd == 'status' then
+    if fio.stat(force_cfg.pid_file) == nil then
+        if errno() == errno.ENOENT then
+            os.exit(1)
+        end
+        log.error("Cant access pidfile %s: %s",
+            force_cfg.pid_file, errno.strerror())
+    end
+
+    if fio.stat(console_sock) == nil then
+        if errno() == errno.ENOENT then
+            log.warn("pidfile is exists, but control socket (%s) isn't",
+                console_sock)
+            os.exit(2)
+        end
+    end
+
+    local s = socket.tcp_connect('unix/', console_sock)
+    if s == nil then
+        if errno() ~= errno.EACCES then
+            log.warn("Can't access control socket %s: %s", console_sock,
+                errno.strerror())
+            os.exit(3)
+        else
+            os.exit(0)
+        end
+    end
+
+    s:close()
+    os.exit(0)
 else
     log.error("Unknown command '%s'", cmd)
     os.exit(-1)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 9a8208114aae464c3ea50e8f5742834d156b2b24..98020848997baf23b5339a0755f013ca9ce2084c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -20,6 +20,7 @@ lua_source(lua_sources lua/init.lua)
 lua_source(lua_sources lua/uuid.lua)
 lua_source(lua_sources lua/digest.lua)
 lua_source(lua_sources lua/msgpackffi.lua)
+lua_source(lua_sources lua/uri.lua)
 lua_source(lua_sources lua/console.lua)
 lua_source(lua_sources lua/bsdsocket.lua)
 lua_source(lua_sources lua/errno.lua)
@@ -39,7 +40,7 @@ set_property(DIRECTORY PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${lua_sources})
 
 add_custom_target(ragel
     WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
-    COMMAND ragel -G2 src/uri.rl -o src/uri.cc)
+    COMMAND ragel -G2 src/uri.rl -o src/uri.c)
 
 set (common_sources
      memory.cc
@@ -55,9 +56,6 @@ set (common_sources
      pickle.cc
      coro.cc
      stat.cc
-     iproto.cc
-     iproto_constants.cc
-     iproto_port.cc
      object.cc
      exception.cc
      ipc.cc
@@ -76,7 +74,7 @@ set (common_sources
      fiob.c
      tt_uuid.c
      ffisyms.cc
-     uri.cc
+     uri.c
      coeio_file.cc
      lua/digest.cc
      lua/init.cc
diff --git a/src/box/CMakeLists.txt b/src/box/CMakeLists.txt
index 896003798e417c1f183db36681e090db332d2fbc..bef3d928599d4b02f47441cda1c6e40f66c78c02 100644
--- a/src/box/CMakeLists.txt
+++ b/src/box/CMakeLists.txt
@@ -17,6 +17,10 @@ add_custom_target(box_generate_lua_sources
 set_property(DIRECTORY PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${lua_sources})
 
 add_library(box
+    iproto.cc
+    iproto_constants.c
+    iproto_port.cc
+    xrow.cc
     tuple.cc
     tuple_convert.cc
     tuple_update.cc
diff --git a/src/box/access.h b/src/box/access.h
index b0cbf366c4cafdc94261813ff62523d5fc363e50..385807aa4e37729031181450e945b76952ee21df 100644
--- a/src/box/access.h
+++ b/src/box/access.h
@@ -142,9 +142,12 @@ user_by_name(const char *name, uint32_t len);
 #define user()							\
 ({								\
 	struct session *s = session();				\
-	uint8_t auth_token = s ? s->auth_token : (int) ADMIN;	\
-	struct user *u = &users[auth_token];			\
-	assert(u->auth_token == auth_token);			\
+	struct user *u = &users[s->auth_token];			\
+	if (u->auth_token != s->auth_token ||			\
+	    u->uid != s->uid) {					\
+		tnt_raise(ClientError, ER_NO_SUCH_USER,		\
+			  int2str(s->uid));			\
+	}							\
 	u;							\
 })
 
diff --git a/src/box/alter.cc b/src/box/alter.cc
index b31eb9a6e7bf24c87f79280a3da6c30c859050c7..c02531e87960c23b25dea7a8d2ff0bdf7faa41c7 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -1638,7 +1638,7 @@ on_commit_dd_cluster(struct trigger *trigger, void *event)
 	uint32_t id = tuple_field_u32(new_tuple, 0);
 	tt_uuid uuid = tuple_field_uuid(new_tuple, 1);
 
-	cluster_add_server(&uuid, id);
+	cluster_set_server(&uuid, id);
 }
 
 static struct trigger commit_cluster_trigger =
@@ -1682,6 +1682,14 @@ on_replace_dd_cluster(struct trigger *trigger, void *event)
 	if (tt_uuid_is_nil(&server_uuid))
 		tnt_raise(ClientError, ER_INVALID_UUID,
 			  tt_uuid_str(&server_uuid));
+	struct tuple *old_tuple = stmt->old_tuple;
+	if (old_tuple != NULL) {
+		/* server_id is read-only, other fields can be changed */
+		uint32_t old_server_id = tuple_field_u32(old_tuple, 0);
+		if (server_id != old_server_id)
+			tnt_raise(ClientError, ER_SERVER_ID_IS_RO,
+				  (unsigned) server_id);
+	}
 
 	trigger_add(&txn->on_commit, &commit_cluster_trigger);
 }
diff --git a/src/box/box.cc b/src/box/box.cc
index 13d61afb28279632d87005b470d557cde67b9a30..8c9f0b41c64e73de8d6a812b3c3bb5d456e4e713 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -34,7 +34,7 @@
 #include "recovery.h"
 #include "log_io.h"
 #include <say.h>
-#include <iproto.h>
+#include "iproto.h"
 #include "replication.h"
 #include <stat.h>
 #include <tarantool.h>
@@ -90,12 +90,24 @@ static void
 process_ro(struct port *port, struct request *request)
 {
 	if (!iproto_type_is_select(request->type))
-		tnt_raise(LoggedError, ER_SECONDARY);
+		tnt_raise(LoggedError, ER_READONLY);
 	return process_rw(port, request);
 }
 
+void
+box_set_ro(bool ro)
+{
+	box_process = ro ? process_ro : process_rw;
+}
+
+bool
+box_is_ro(void)
+{
+	return box_process == process_ro;
+}
+
 static void
-recover_row(void *param __attribute__((unused)), struct iproto_header *row)
+recover_row(void *param __attribute__((unused)), struct xrow_header *row)
 {
 	assert(row->bodycnt == 1); /* always 1 for read */
 	struct request request;
@@ -114,15 +126,18 @@ box_check_replication_source(const char *source)
 	if (source == NULL)
 		return;
 	struct uri uri;
-	if (uri_parse(&uri, source)) {
-		tnt_raise(ClientError, ER_CFG,
-			  "incorrect replication source");
+
+	/* URI format is [host:]service */
+	if (uri_parse(&uri, source) || !uri.service) {
+		tnt_raise(ClientError, ER_CFG, "replication source, "
+			  "expected host:service or /unix.socket");
 	}
 }
 
 static void
 box_check_wal_mode(const char *mode_name)
 {
+	assert(mode_name != NULL); /* checked in Lua */
 	int mode = strindex(wal_mode_STRS, mode_name, WAL_MODE_MAX);
 	if (mode == WAL_MODE_MAX) {
 		tnt_raise(ClientError, ER_CFG,
@@ -134,6 +149,7 @@ static void
 box_check_config()
 {
 	box_check_wal_mode(cfg_gets("wal_mode"));
+	box_check_replication_source(cfg_gets("replication_source"));
 
 	/* check rows_per_wal configuration */
 	if (cfg_geti("rows_per_wal") <= 1) {
@@ -233,7 +249,6 @@ box_leave_local_standby_mode(void *data __attribute__((unused)))
 	stat_cleanup(stat_base, IPROTO_TYPE_DML_MAX);
 	box_set_wal_mode(cfg_gets("wal_mode"));
 
-	box_process = process_rw;
 	if (recovery_has_remote(recovery))
 		recovery_follow_remote(recovery);
 
@@ -359,15 +374,6 @@ engine_init()
 	SophiaFactory *sophia = new SophiaFactory();
 	sophia->init();
 	engine_register(sophia);
-
-	/* Prepare storage and recover data.
-	 *
-	 * This is first phase of recover, schema is not known yet.
-	 * Internal sophia spaces (databases) are created in
-	 * recover-delay mode and not accessible yet.
-	 * Recover completes on first engine index creation.
-	*/
-	sophia->recover();
 }
 
 void
@@ -419,6 +425,7 @@ box_init()
 		space_end_recover_snapshot();
 		snapshot_save(recovery);
 	}
+	fiber_gc();
 
 	title("orphan", NULL);
 	recovery_follow_local(recovery,
@@ -454,8 +461,8 @@ snapshot_write_tuple(struct log_io *l,
 	body.v_space_id = mp_bswap_u32(n);
 	body.k_tuple = IPROTO_TUPLE;
 
-	struct iproto_header row;
-	memset(&row, 0, sizeof(struct iproto_header));
+	struct xrow_header row;
+	memset(&row, 0, sizeof(struct xrow_header));
 	row.type = IPROTO_INSERT;
 
 	row.bodycnt = 2;
@@ -516,7 +523,7 @@ box_snapshot(void)
 		return (WIFSIGNALED(status) ? EINTR : WEXITSTATUS(status));
 	}
 
-	slab_arena_mprotect(&tuple_arena);
+	slab_arena_mprotect(&memtx_arena);
 
 	cord_set_name("snap");
 	title("dumper", "%" PRIu32, getppid());
diff --git a/src/box/box.h b/src/box/box.h
index 8bb7f8751759d976a8ceb68bf10399583b88fe08..970dad6d78e101a27876755f1fe77989e5535e66 100644
--- a/src/box/box.h
+++ b/src/box/box.h
@@ -62,7 +62,12 @@ void box_free(void);
 typedef void (*box_process_func)(struct port *port, struct request *request);
 /** For read-write operations. */
 extern box_process_func box_process;
-/** For read-only port. */
+
+void
+box_set_ro(bool ro);
+
+bool
+box_is_ro(void);
 
 /** Non zero if snapshot is in progress. */
 extern int snapshot_pid;
diff --git a/src/box/cluster.cc b/src/box/cluster.cc
index c42f28bd0110fbf23c6b795ba02eb6e0d48681df..356f49ff313f4fa86dfe74d4322b4fbe4edf9c21 100644
--- a/src/box/cluster.cc
+++ b/src/box/cluster.cc
@@ -26,6 +26,7 @@
  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+#include "box.h"
 #include "cluster.h"
 #include "recovery.h"
 #include "exception.h"
@@ -43,19 +44,28 @@ cluster_clock()
 }
 
 void
-cluster_add_server(const tt_uuid *server_uuid, uint32_t server_id)
+cluster_set_server(const tt_uuid *server_uuid, uint32_t server_id)
 {
 	struct recovery_state *r = recovery;
 	/** Checked in the before-commit trigger */
 	assert(!tt_uuid_is_nil(server_uuid));
 	assert(!cserver_id_is_reserved(server_id));
 
+	if (r->server_id == server_id) {
+		if (tt_uuid_is_equal(&r->server_uuid, server_uuid))
+			return;
+		say_warn("server uuid changed to %s", tt_uuid_str(server_uuid));
+		assert(vclock_has(&r->vclock, server_id));
+		memcpy(&r->server_uuid, server_uuid, sizeof(*server_uuid));
+		return;
+	}
+
 	/* Add server */
 	vclock_add_server(&r->vclock, server_id);
-
 	if (tt_uuid_is_equal(&r->server_uuid, server_uuid)) {
 		/* Assign local server id */
 		assert(r->server_id == 0);
 		r->server_id = server_id;
+		box_set_ro(false);
 	}
 }
diff --git a/src/box/cluster.h b/src/box/cluster.h
index 257e4b8c69ae8ab23730628a935161707a054ee1..b98e2ef1b1d2e3d623c65bce6aa17553854c0160 100644
--- a/src/box/cluster.h
+++ b/src/box/cluster.h
@@ -103,7 +103,7 @@ cserver_id_is_reserved(uint32_t id)
  * The server is added to the cluster lsn table with LSN 0.
  */
 void
-cluster_add_server(const tt_uuid *server_uuid, uint32_t id);
+cluster_set_server(const tt_uuid *server_uuid, uint32_t id);
 
 /** }}} **/
 
diff --git a/src/box/engine_sophia.cc b/src/box/engine_sophia.cc
index 8694511003986cbf020d2ce9d72cd27b653c8f5e..42318828566ff01fe04f35096cd3a7d7e821c317 100644
--- a/src/box/engine_sophia.cc
+++ b/src/box/engine_sophia.cc
@@ -26,6 +26,7 @@
  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+#include "cfg.h"
 #include "txn.h"
 #include "tuple.h"
 #include "engine.h"
@@ -41,6 +42,7 @@
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <dirent.h>
 #include <errno.h>
 
 struct Sophia: public Engine {
@@ -92,21 +94,9 @@ SophiaFactory::init()
 	env = sp_env();
 	if (env == NULL)
 		panic("failed to create sophia environment");
-	void *conf = sp_ctl(env, "conf");
-	sp_set(conf, "env.dir", "sophia");
-	sp_set(conf, "env.create_on_write", 1);
-}
-
-void
-SophiaFactory::recover()
-{
-	say_info("start sophia recover");
-
 	int rc = sp_open(env);
 	if (rc == -1)
-		panic("sophia recovery failed");
-
-	say_info("complete");
+		tnt_raise(ClientError, ER_SOPHIA, sp_error(env));
 }
 
 Engine*
@@ -122,7 +112,6 @@ SophiaFactory::recoveryEvent(enum engine_recovery_event event)
 	case END_RECOVERY_SNAPSHOT:
 		recovery.replace = sophia_replace_recover;
 		break;
-
 	case END_RECOVERY:
 		recovery.state   = READY_NO_KEYS;
 		recovery.replace = sophia_replace;
@@ -142,15 +131,41 @@ SophiaFactory::createIndex(struct key_def *key_def)
 	}
 }
 
+static inline int
+drop_repository(char *path)
+{
+	DIR *dir = opendir(path);
+	if (dir == NULL)
+		return -1;
+	char file[1024];
+	struct dirent *de;
+	while ((de = readdir(dir))) {
+		if (de->d_name[0] == '.')
+			continue;
+		snprintf(file, sizeof(file), "%s/%s", path, de->d_name);
+		int rc = unlink(file);
+		if (rc == -1) {
+			closedir(dir);
+			return -1;
+		}
+	}
+	closedir(dir);
+	return rmdir(path);
+}
+
 void
 SophiaFactory::dropIndex(Index *index)
 {
 	SophiaIndex *i = (SophiaIndex*)index;
-	int rc = sp_drop(i->db);
+	int rc = sp_destroy(i->db);
 	if (rc == -1)
 		tnt_raise(ClientError, ER_SOPHIA, sp_error(i->db));
 	i->db  = NULL;
 	i->env = NULL;
+	char path[PATH_MAX];
+	snprintf(path, sizeof(path), "%s/%" PRIu32,
+	         cfg_gets("sophia_dir"), index->key_def->space_id);
+	drop_repository(path);
 }
 
 void
diff --git a/src/box/engine_sophia.h b/src/box/engine_sophia.h
index 90c14ba9f3e2864cbcaf8afb673081f6aae7e4bb..3bb0bc0d544dd98d43fbb481c5f48e554366a3a7 100644
--- a/src/box/engine_sophia.h
+++ b/src/box/engine_sophia.h
@@ -32,7 +32,6 @@
 struct SophiaFactory: public EngineFactory {
 	SophiaFactory();
 	virtual void init();
-	virtual void recover();
 	virtual Engine *open();
 	virtual Index *createIndex(struct key_def *key_def);
 	virtual void dropIndex(Index *index);
diff --git a/src/iproto.cc b/src/box/iproto.cc
similarity index 99%
rename from src/iproto.cc
rename to src/box/iproto.cc
index eefc3b7130d6fb12a5566029f8ea280194004f03..512d11f0b43a1f5b9de7661b1d94edd88b5b7de8 100644
--- a/src/iproto.cc
+++ b/src/box/iproto.cc
@@ -42,10 +42,12 @@
 #include "scoped_guard.h"
 #include "memory.h"
 #include "msgpuck/msgpuck.h"
-#include "box/replication.h"
-#include "box/session.h"
+#include "replication.h"
+#include "session.h"
 #include "third_party/base64.h"
 #include "coio.h"
+#include "xrow.h"
+#include "iproto_constants.h"
 
 class IprotoConnectionShutdown: public Exception
 {
@@ -77,7 +79,7 @@ struct iproto_request
 	struct session *session;
 	iproto_request_f process;
 	/* Request message code and sync. */
-	struct iproto_header header;
+	struct xrow_header header;
 	/* Box request, if this is a DML */
 	struct request request;
 	size_t total_len;
@@ -485,10 +487,9 @@ iproto_enqueue_batch(struct iproto_connection *con, struct ibuf *in)
 			iproto_request_new(con, iproto_process_dml);
 		IprotoRequestGuard guard(ireq);
 
-		iproto_header_decode(&ireq->header, &pos, reqend);
+		xrow_header_decode(&ireq->header, &pos, reqend);
 		ireq->total_len = pos - reqstart; /* total request length */
 
-
 		/*
 		 * sic: in case of exception con->parse_size
 		 * as well as in->pos must not be advanced, to
diff --git a/src/iproto.h b/src/box/iproto.h
similarity index 100%
rename from src/iproto.h
rename to src/box/iproto.h
diff --git a/src/box/iproto_constants.c b/src/box/iproto_constants.c
new file mode 100644
index 0000000000000000000000000000000000000000..a0893501f7cf4bcb4e31acf23663fc7e05e1acb1
--- /dev/null
+++ b/src/box/iproto_constants.c
@@ -0,0 +1,154 @@
+/*
+ * Redistribution and use in source and binary forms, with or
+ * without modification, 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 <COPYRIGHT HOLDER> ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, 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 OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include "iproto_constants.h"
+
+const unsigned char iproto_key_type[IPROTO_KEY_MAX] =
+{
+	/* {{{ header */
+		/* 0x00 */	MP_UINT,   /* IPROTO_REQUEST_TYPE */
+		/* 0x01 */	MP_UINT,   /* IPROTO_SYNC */
+		/* 0x02 */	MP_UINT,   /* IPROTO_SERVER_ID */
+		/* 0x03 */	MP_UINT,   /* IPROTO_LSN */
+		/* 0x04 */	MP_DOUBLE, /* IPROTO_TIMESTAMP */
+	/* }}} */
+
+	/* {{{ unused */
+		/* 0x05 */	MP_UINT,
+		/* 0x06 */	MP_UINT,
+		/* 0x07 */	MP_UINT,
+		/* 0x08 */	MP_UINT,
+		/* 0x09 */	MP_UINT,
+		/* 0x0a */	MP_UINT,
+		/* 0x0b */	MP_UINT,
+		/* 0x0c */	MP_UINT,
+		/* 0x0d */	MP_UINT,
+		/* 0x0e */	MP_UINT,
+		/* 0x0f */	MP_UINT,
+	/* }}} */
+
+	/* {{{ body -- integer keys */
+		/* 0x10 */	MP_UINT, /* IPROTO_SPACE_ID */
+		/* 0x11 */	MP_UINT, /* IPROTO_INDEX_ID */
+		/* 0x12 */	MP_UINT, /* IPROTO_LIMIT */
+		/* 0x13 */	MP_UINT, /* IPROTO_OFFSET */
+		/* 0x14 */	MP_UINT, /* IPROTO_ITERATOR */
+	/* }}} */
+
+	/* {{{ unused */
+		/* 0x15 */	MP_UINT,
+		/* 0x16 */	MP_UINT,
+		/* 0x17 */	MP_UINT,
+		/* 0x18 */	MP_UINT,
+		/* 0x19 */	MP_UINT,
+		/* 0x1a */	MP_UINT,
+		/* 0x1b */	MP_UINT,
+		/* 0x1c */	MP_UINT,
+		/* 0x1d */	MP_UINT,
+		/* 0x1e */	MP_UINT,
+		/* 0x1f */	MP_UINT,
+	/* }}} */
+
+	/* {{{ body -- all keys */
+	/* 0x20 */	MP_ARRAY, /* IPROTO_KEY */
+	/* 0x21 */	MP_ARRAY, /* IPROTO_TUPLE */
+	/* 0x22 */	MP_STR, /* IPROTO_FUNCTION_NAME */
+	/* 0x23 */	MP_STR, /* IPROTO_USER_NAME */
+	/* 0x24 */	MP_STR, /* IPROTO_SERVER_UUID */
+	/* 0x25 */	MP_STR, /* IPROTO_CLUSTER_UUID */
+	/* 0x26 */	MP_MAP, /* IPROTO_VCLOCK */
+	/* }}} */
+};
+
+const char *iproto_type_strs[] =
+{
+	NULL,
+	"SELECT",
+	"INSERT",
+	"REPLACE",
+	"UPDATE",
+	"DELETE",
+	"CALL",
+	"AUTH"
+};
+
+#define bit(c) (1ULL<<IPROTO_##c)
+const uint64_t iproto_body_key_map[IPROTO_TYPE_DML_MAX] = {
+	0,                                                     /* unused */
+	bit(SPACE_ID) | bit(LIMIT) | bit(KEY),                 /* SELECT */
+	bit(SPACE_ID) | bit(TUPLE),                            /* INSERT */
+	bit(SPACE_ID) | bit(TUPLE),                            /* REPLACE */
+	bit(SPACE_ID) | bit(KEY) | bit(TUPLE),                 /* UPDATE */
+	bit(SPACE_ID) | bit(KEY),                              /* DELETE */
+	bit(FUNCTION_NAME) | bit(TUPLE),                       /* CALL */
+	bit(USER_NAME) | bit(TUPLE)                            /* AUTH */
+};
+#undef bit
+
+const char *iproto_key_strs[IPROTO_KEY_MAX] = {
+	"type",             /* 0x00 */
+	"sync",             /* 0x01 */
+	"server_id",          /* 0x02 */
+	"lsn",              /* 0x03 */
+	"timestamp",        /* 0x04 */
+	"",                 /* 0x05 */
+	"",                 /* 0x06 */
+	"",                 /* 0x07 */
+	"",                 /* 0x08 */
+	"",                 /* 0x09 */
+	"",                 /* 0x0a */
+	"",                 /* 0x0b */
+	"",                 /* 0x0c */
+	"",                 /* 0x0d */
+	"",                 /* 0x0e */
+	"",                 /* 0x0f */
+	"space_id",         /* 0x10 */
+	"index_id",         /* 0x11 */
+	"limit",            /* 0x12 */
+	"offset",           /* 0x13 */
+	"iterator",         /* 0x14 */
+	"",                 /* 0x15 */
+	"",                 /* 0x16 */
+	"",                 /* 0x17 */
+	"",                 /* 0x18 */
+	"",                 /* 0x19 */
+	"",                 /* 0x1a */
+	"",                 /* 0x1b */
+	"",                 /* 0x1c */
+	"",                 /* 0x1d */
+	"",                 /* 0x1e */
+	"",                 /* 0x1f */
+	"key",              /* 0x20 */
+	"tuple",            /* 0x21 */
+	"function name",    /* 0x22 */
+	"user name",        /* 0x23 */
+	"server UUID"       /* 0x24 */
+	"cluster UUID"      /* 0x25 */
+	"vector clock"      /* 0x26 */
+};
+
diff --git a/src/iproto_constants.h b/src/box/iproto_constants.h
similarity index 59%
rename from src/iproto_constants.h
rename to src/box/iproto_constants.h
index 0f79ed989b7f6c642847f2ea0d87a42509cdef46..e89ad4fd3301e3912b8d8753503b00ef1dd833f7 100644
--- a/src/iproto_constants.h
+++ b/src/box/iproto_constants.h
@@ -30,7 +30,6 @@
  */
 #include <stdbool.h>
 #include <stdint.h>
-#include <sys/uio.h> /* struct iovec */
 #include <msgpuck/msgpuck.h>
 
 #if defined(__cplusplus)
@@ -41,8 +40,8 @@ enum {
 	/** Maximal iproto package body length (2GiB) */
 	IPROTO_BODY_LEN_MAX = 2147483648UL,
 	IPROTO_GREETING_SIZE = 128,
-	IPROTO_FIXHEADER_SIZE = 5, /* len + (padding) */
-	XLOG_FIXHEADER_SIZE = 19 /* marker + len + prev crc32 + cur crc32 + (padding) */
+	/** marker + len + prev crc32 + cur crc32 + (padding) */
+	XLOG_FIXHEADER_SIZE = 19
 };
 
 
@@ -82,7 +81,7 @@ enum iproto_key {
 			  bit(OFFSET) | bit(ITERATOR) | bit(KEY) | \
 			  bit(TUPLE) | bit(FUNCTION_NAME) | bit(USER_NAME))
 static inline bool
-iproto_header_has_key(const char *pos, const char *end)
+xrow_header_has_key(const char *pos, const char *end)
 {
 	unsigned char key = pos < end ? *pos : (unsigned char) IPROTO_KEY_MAX;
 	return key < IPROTO_KEY_MAX && IPROTO_HEAD_BMAP & (1ULL<<key);
@@ -161,132 +160,6 @@ iproto_type_is_error(uint32_t type)
 	return (type & IPROTO_TYPE_ERROR) != 0;
 }
 
-enum {
-	IPROTO_PACKET_HEAD_IOVMAX = 1,
-	IPROTO_PACKET_BODY_IOVMAX = 2,
-	IPROTO_PACKET_IOVMAX = IPROTO_PACKET_HEAD_IOVMAX +
-		IPROTO_PACKET_BODY_IOVMAX
-};
-
-enum { IPROTO_ROW_IOVMAX = IPROTO_PACKET_IOVMAX + 1 };
-
-
-struct iproto_header {
-	uint32_t type;
-	uint32_t server_id;
-	uint64_t sync;
-	uint64_t lsn;
-	double tm;
-
-	int bodycnt;
-	struct iovec body[IPROTO_PACKET_BODY_IOVMAX];
-};
-
-void
-iproto_header_decode(struct iproto_header *header,
-		     const char **pos, const char *end);
-struct tt_uuid;
-
-void
-iproto_decode_uuid(const char **pos, struct tt_uuid *out);
-
-char *
-iproto_encode_uuid(char *pos, const struct tt_uuid *in);
-
-/** Return a 4-byte numeric error code, with status flags. */
-static inline uint32_t
-iproto_encode_error(uint32_t error)
-{
-	return error | IPROTO_TYPE_ERROR;
-}
-
-int
-iproto_header_encode(const struct iproto_header *header,
-		     struct iovec *out);
-
-int
-iproto_row_encode(const struct iproto_header *row, struct iovec *out);
-
-/**
- * \brief Decode ERROR and re-throw it as ClientError exception
- * \param row
- */
-void
-iproto_decode_error(struct iproto_header *row);
-
-/**
- * \brief Encode AUTH command
- * \param[out] row
- * \param greeting - IPROTO greeting
- * \param login - user login
- * \param password - user password
- */
-void
-iproto_encode_auth(struct iproto_header *row, const char *greeting,
-		   const char *login, const char *password);
-
-/**
- * \brief Encode SUBSCRIBE command
- * \param row[out]
- * \param cluster_uuid cluster uuid
- * \param server_uuid server uuid
- * \param vclock server vclock
- */
-void
-iproto_encode_subscribe(struct iproto_header *row,
-			const struct tt_uuid *cluster_uuid,
-			const struct tt_uuid *server_uuid,
-			const struct vclock *vclock);
-
-/**
- * \brief Decode SUBSCRIBE command
- * \param row
- * \param[out] cluster_uuid
- * \param[out] server_uuid
- * \param[out] vclock
- */
-void
-iproto_decode_subscribe(struct iproto_header *row, struct tt_uuid *cluster_uuid,
-			struct tt_uuid *server_uuid, struct vclock *vclock);
-
-/**
- * \brief Encode JOIN command
- * \param[out] row
- * \param server_uuid
- */
-void
-iproto_encode_join(struct iproto_header *row, const struct tt_uuid *server_uuid);
-
-/**
- * \brief Decode JOIN command
- * \param row
- * \param[out] server_uuid
- */
-static inline void
-iproto_decode_join(struct iproto_header *row, struct tt_uuid *server_uuid)
-{
-	return iproto_decode_subscribe(row, NULL, server_uuid, NULL);
-}
-
-/**
- * \brief Encode end of stream command (a response to JOIN command)
- * \param row[out]
- * \param vclock
- */
-void
-iproto_encode_eos(struct iproto_header *row, const struct vclock *vclock);
-
-/**
- * \brief Decode end of stream command (a response to JOIN command)
- * \param row
- * \param[out] vclock
- */
-static inline void
-iproto_decode_eos(struct iproto_header *row, struct vclock *vclock)
-{
-	return iproto_decode_subscribe(row, NULL, NULL, vclock);
-}
-
 #if defined(__cplusplus)
 } /* extern "C" */
 #endif
diff --git a/src/iproto_port.cc b/src/box/iproto_port.cc
similarity index 96%
rename from src/iproto_port.cc
rename to src/box/iproto_port.cc
index df15328626616bdc0c921a5bb0bbdcb08226a6b0..b1f227dd1d36d1f2ce459f9ca582ee2f4a6c3174 100644
--- a/src/iproto_port.cc
+++ b/src/box/iproto_port.cc
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  */
 #include "iproto_port.h"
-
+#include "iproto_constants.h"
 
 /* m_ - msgpack meta, k_ - key, v_ - value */
 struct iproto_header_bin {
@@ -61,6 +61,13 @@ static const struct iproto_body_bin iproto_error_bin = {
 	0x81, IPROTO_ERROR, 0xdb, 0
 };
 
+/** Return a 4-byte numeric error code, with status flags. */
+static inline uint32_t
+iproto_encode_error(uint32_t error)
+{
+	return error | IPROTO_TYPE_ERROR;
+}
+
 void
 iproto_reply_ping(struct obuf *out, uint64_t sync)
 {
diff --git a/src/iproto_port.h b/src/box/iproto_port.h
similarity index 96%
rename from src/iproto_port.h
rename to src/box/iproto_port.h
index 0c45798ceac4da8d2d8ffbd0cee05acf07737fee..0613854abf911c67eb00b04c6ccb513f3aaad344 100644
--- a/src/iproto_port.h
+++ b/src/box/iproto_port.h
@@ -28,13 +28,12 @@
  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include "box/box.h"
-#include "box/request.h"
-#include "box/port.h"
-#include "box/tuple.h"
+#include "box.h"
+#include "request.h"
+#include "port.h"
+#include "tuple.h"
 #include "iobuf.h"
 #include "msgpuck/msgpuck.h"
-#include "iproto_constants.h"
 
 /**
  * struct iproto_port users need to be careful to:
diff --git a/src/box/log_io.cc b/src/box/log_io.cc
index 69e6d1660d96a257229c9f05d4e026eaeb7aeef4..349538e4d880f610e82999a67a1af34dfd70fe9f 100644
--- a/src/box/log_io.cc
+++ b/src/box/log_io.cc
@@ -36,11 +36,11 @@
 #include "third_party/tarantool_eio.h"
 #include "fiob.h"
 #include "msgpuck/msgpuck.h"
-#include "iproto_constants.h"
 #include "scoped_guard.h"
 #define MH_UNDEF 1 /* conflicts with mh_nodeids_t */
 #include "recovery.h" /* for mh_cluster */
 #include "vclock.h"
+#include "iproto_constants.h"
 
 /*
  * marker is MsgPack fixext2
@@ -273,7 +273,7 @@ format_filename(struct log_dir *dir, int64_t signt, enum log_suffix suffix)
 /* {{{ struct log_io_cursor */
 
 static int
-row_reader(FILE *f, struct iproto_header *row)
+row_reader(FILE *f, struct xrow_header *row)
 {
 	const char *data;
 
@@ -326,15 +326,15 @@ row_reader(FILE *f, struct iproto_header *row)
 		tnt_raise(ClientError, ER_INVALID_MSGPACK, "invalid crc32");
 
 	data = bodybuf;
-	iproto_header_decode(row, &data, bodybuf + len);
+	xrow_header_decode(row, &data, bodybuf + len);
 
 	return 0;
 }
 
 int
-xlog_encode_row(const struct iproto_header *row, struct iovec *iov)
+xlog_encode_row(const struct xrow_header *row, struct iovec *iov)
 {
-	int iovcnt = iproto_header_encode(row, iov + 1) + 1;
+	int iovcnt = xrow_header_encode(row, iov + 1) + 1;
 	char *fixheader = (char *) region_alloc(&fiber()->gc,
 						XLOG_FIXHEADER_SIZE);
 	uint32_t len = 0;
@@ -362,7 +362,7 @@ xlog_encode_row(const struct iproto_header *row, struct iovec *iov)
 	iov[0].iov_base = fixheader;
 	iov[0].iov_len = XLOG_FIXHEADER_SIZE;
 
-	assert(iovcnt <= XLOG_ROW_IOVMAX);
+	assert(iovcnt <= XROW_IOVMAX);
 	return iovcnt;
 }
 
@@ -400,7 +400,7 @@ log_io_cursor_close(struct log_io_cursor *i)
  *
  */
 int
-log_io_cursor_next(struct log_io_cursor *i, struct iproto_header *row)
+log_io_cursor_next(struct log_io_cursor *i, struct xrow_header *row)
 {
 	struct log_io *l = i->log;
 	log_magic_t magic;
@@ -711,7 +711,8 @@ log_io_verify_meta(struct log_io *l, const tt_uuid *server_uuid)
 	if (server_uuid != NULL && !tt_uuid_is_nil(server_uuid) &&
 	    !tt_uuid_is_equal(server_uuid, &l->server_uuid)) {
 		say_error("%s: invalid server uuid", l->filename);
-		return -1;
+		if (l->dir->panic_if_error)
+			return -1;
 	}
 	return 0;
 }
diff --git a/src/box/log_io.h b/src/box/log_io.h
index 7cc63892b2249f71cc5384a2b098d0d2539acb31..52cf559db03c006f7eef059b21965a14afcfb680 100644
--- a/src/box/log_io.h
+++ b/src/box/log_io.h
@@ -34,7 +34,7 @@
 #include <sys/uio.h>
 #include "trivia/util.h"
 #include "third_party/tarantool_ev.h"
-#include "iproto_constants.h"
+#include "xrow.h"
 #include "tt_uuid.h"
 #include "vclock.h"
 
@@ -132,10 +132,9 @@ void
 log_io_cursor_close(struct log_io_cursor *i);
 
 int
-log_io_cursor_next(struct log_io_cursor *i, struct iproto_header *packet);
+log_io_cursor_next(struct log_io_cursor *i, struct xrow_header *packet);
 int
-xlog_encode_row(const struct iproto_header *packet, struct iovec *iov);
-enum { XLOG_ROW_IOVMAX = IPROTO_PACKET_IOVMAX + 1 };
+xlog_encode_row(const struct xrow_header *packet, struct iovec *iov);
 
 typedef uint32_t log_magic_t;
 
diff --git a/src/box/lua/info.cc b/src/box/lua/info.cc
index ec13926417ad5f5ae6fd001d809b03f2394dbe47..f1616df17f60b5bb94d5b3490b62e34f65a7ba72 100644
--- a/src/box/lua/info.cc
+++ b/src/box/lua/info.cc
@@ -59,11 +59,6 @@ lbox_info_recovery_last_update_tstamp(struct lua_State *L)
 static int
 lbox_info_server(struct lua_State *L)
 {
-	if (recovery->server_id == 0) {
-		lua_pushnil(L);
-		return 1;
-	}
-
 	lua_createtable(L, 0, 2);
 	lua_pushliteral(L, "id");
 	lua_pushinteger(L, recovery->server_id);
@@ -72,8 +67,11 @@ lbox_info_server(struct lua_State *L)
 	lua_pushlstring(L, tt_uuid_str(&recovery->server_uuid), UUID_STR_LEN);
 	lua_settable(L, -3);
 	lua_pushliteral(L, "lsn");
-	luaL_pushnumber64(L, vclock_get(&recovery->vclock,
-					recovery->server_id));
+	luaL_pushinumber64(L, vclock_get(&recovery->vclock,
+					 recovery->server_id));
+	lua_settable(L, -3);
+	lua_pushliteral(L, "ro");
+	lua_pushboolean(L, box_is_ro());
 	lua_settable(L, -3);
 
 	return 1;
diff --git a/src/box/lua/load_cfg.lua b/src/box/lua/load_cfg.lua
index 6743b23da7998e9fa98aa90ae65135bd6413a8c2..126bc550ce075005651b18de318ada60f0b1f2a1 100644
--- a/src/box/lua/load_cfg.lua
+++ b/src/box/lua/load_cfg.lua
@@ -32,6 +32,7 @@ local default_cfg = {
     work_dir            = nil,
     snap_dir            = ".",
     wal_dir             = ".",
+    sophia_dir          = './sophia',
     logger              = nil,
     logger_nonblock     = true,
     log_level           = 5,
@@ -51,14 +52,14 @@ local default_cfg = {
     username            = nil ,
     coredump            = false,
 
-    -- snap_daemon
+    -- snapshot_daemon
     snapshot_period     = 0,        -- 0 = disabled
     snapshot_count      = 6,
 }
 
 -- types of available options
 -- could be comma separated lua types or 'any' if any type is allowed
-local template_cfg = {
+local template = {
     listen              = 'string, number',
     slab_alloc_arena    = 'number',
     slab_alloc_minimal  = 'number',
@@ -66,6 +67,7 @@ local template_cfg = {
     work_dir            = 'string',
     snap_dir            = 'string',
     wal_dir             = 'string',
+    sophia_dir          = 'string',
     logger              = 'string',
     logger_nonblock     = 'boolean',
     log_level           = 'number',
@@ -97,50 +99,14 @@ local dynamic_cfg = {
     too_long_threshold      = ffi.C.box_set_too_long_threshold,
     snap_io_rate_limit      = ffi.C.box_set_snap_io_rate_limit,
 
-    -- snap_daemon
-    snapshot_period         = box.internal.snap_daemon.set_snapshot_period,
-    snapshot_count          = box.internal.snap_daemon.set_snapshot_count,
+    -- snapshot_daemon
+    snapshot_period         = box.internal.snapshot_daemon.set_snapshot_period,
+    snapshot_count          = box.internal.snapshot_daemon.set_snapshot_count,
 }
 
-local function reload_cfg(oldcfg, newcfg)
-    if newcfg == nil then
-        newcfg = {}
-    end
-    for key, val in pairs(newcfg) do
-        if dynamic_cfg[key] == nil then
-            box.error(box.error.RELOAD_CFG, key);
-        end
-        if val == "" then
-            val = nil
-        end
-        if wrapper_cfg[key] ~= nil then
-            val = wrapper_cfg[key](val)
-        end
-        dynamic_cfg[key](val)
-        rawset(oldcfg, key, val)
-    end
-    if type(box.on_reload_configuration) == 'function' then
-        box.on_reload_configuration()
-    end
-end
-
-local box = require('box')
--- Move all box members to box_saved
-local box_configured = {}
-for k, v in pairs(box) do
-    box_configured[k] = v
-    box[k] = nil
-end
-
-setmetatable(box, {
-    __index = function(table, index)
-        error("Please call box.cfg{} first")
-     end
-})
-
-local function check_param_table(table, template)
+local function prepare_cfg(table)
     if table == nil then
-        return
+        return {}
     end
     if type(table) ~= 'table' then
         error("Error: cfg should be a table")
@@ -149,9 +115,13 @@ local function check_param_table(table, template)
     if table.dont_check then
         return
     end
+    local newtable = {}
     for k,v in pairs(table) do
         if template[k] == nil then
             error("Error: cfg parameter '" .. k .. "' is unexpected")
+        elseif v == "" or v == nil then
+            -- "" and NULL = ffi.cast('void *', 0) set option to default value
+            v = default_cfg[k]
         elseif template[k] == 'any' then
             -- any type is ok
         elseif (string.find(template[k], ',') == nil) then
@@ -166,29 +136,52 @@ local function check_param_table(table, template)
                 error("Error: cfg parameter '" .. k .. "' should be one of types: " .. template[k])
             end
         end
+        if wrapper_cfg[k] ~= nil then
+            v = wrapper_cfg[k](v)
+        end
+        newtable[k] = v
     end
+    return newtable
 end
 
-
-local function update_param_table(table, defaults)
-    if table == nil then
-        table = {}
-    end
-    for k,v in pairs(defaults) do
-        if table[k] == nil then
-            table[k] = v
+local function reload_cfg(oldcfg, newcfg)
+    newcfg = prepare_cfg(newcfg)
+    for key, val in pairs(newcfg) do
+        if dynamic_cfg[key] == nil then
+            box.error(box.error.RELOAD_CFG, key);
         end
+        dynamic_cfg[key](val)
+        rawset(oldcfg, key, val)
+    end
+    if type(box.on_reload_configuration) == 'function' then
+        box.on_reload_configuration()
     end
-    return table
 end
 
-function box.cfg(cfg)
-    check_param_table(cfg, template_cfg)
-    cfg = update_param_table(cfg, default_cfg)
+local box = require('box')
+-- Move all box members to box_saved
+local box_configured = {}
+for k, v in pairs(box) do
+    box_configured[k] = v
+    -- box.net.box uses box.error and box.internal
+    if k ~= 'error' and k ~= 'internal' then
+        box[k] = nil
+    end
+end
+
+setmetatable(box, {
+    __index = function(table, index)
+        error(debug.traceback("Please call box.cfg{} first"))
+        error("Please call box.cfg{} first")
+     end
+})
 
-    for k,v in pairs(wrapper_cfg) do
-        -- options that can be number or string
-        cfg[k] = wrapper_cfg[k](cfg[k])
+function box.cfg(cfg)
+    cfg = prepare_cfg(cfg)
+    for k,v in pairs(default_cfg) do
+        if cfg[k] == nil then
+            cfg[k] = v
+        end
     end
     -- Restore box members from box_saved after initial configuration
     for k, v in pairs(box_configured) do
@@ -205,7 +198,7 @@ function box.cfg(cfg)
         })
     ffi.C.load_cfg()
 
-    box.internal.snap_daemon.start()
+    box.internal.snapshot_daemon.start()
 end
 jit.off(box.cfg)
 jit.off(reload_cfg)
diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index bb1e9a46f2f4a0d167c9a0b39baad5a224a7494b..0999acf65e7b9f28f83cd8880da1f253c8eaa09b 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -188,7 +188,7 @@ box.schema.space.create = function(name, options)
         engine = 'string',
         id = 'number',
         field_count = 'number',
-        user = 'user',
+        user = 'string, number',
     }
     local options_defaults = {
         engine = 'memtx',
@@ -303,6 +303,7 @@ box.schema.index.create = function(space_id, name, options)
         parts = 'table',
         unique = 'boolean',
         id = 'number',
+        if_not_exists = 'boolean',
     }
     local options_defaults = {
         type = 'tree',
@@ -315,6 +316,13 @@ box.schema.index.create = function(space_id, name, options)
     options.parts = update_index_parts(options.parts)
 
     local _index = box.space[box.schema.INDEX_ID]
+    if _index.index.name:get{space_id, name} then
+        if options.if_not_exists then
+            return box.space[space_id].index[name], "not created"
+        else
+            box.error(box.error.INDEX_EXISTS, name)
+        end
+    end
 
     local unique = options.unique and 1 or 0
     local part_count = bit.rshift(#options.parts, 1)
diff --git a/src/box/lua/slab.cc b/src/box/lua/slab.cc
index 4095ce312e2907288854a0ab631e5c57e7a53f9b..400c53d95784a745b1ed4c9def4e432bb9e83a4c 100644
--- a/src/box/lua/slab.cc
+++ b/src/box/lua/slab.cc
@@ -37,6 +37,7 @@ extern "C" {
 
 #include "box/tuple.h"
 #include "small/small.h"
+#include "memory.h"
 
 /** A callback passed into salloc_stat() and invoked for every slab class. */
 extern "C" {
@@ -88,7 +89,7 @@ lbox_slab_info(struct lua_State *L)
 	lua_pushstring(L, "slabs");
 	lua_newtable(L);
 	luaL_setmaphint(L, -1);
-	small_stats(&talloc, &totals, small_stats_lua_cb, L);
+	small_stats(&memtx_alloc, &totals, small_stats_lua_cb, L);
 	lua_settable(L, -3);
 
 	lua_pushstring(L, "arena_used");
@@ -102,15 +103,15 @@ lbox_slab_info(struct lua_State *L)
 	char value[32];
 	double items_used_ratio = 100
 		* ((double)totals.used)
-		/ ((double)talloc.cache->arena->prealloc + 0.0001);
+		/ ((double)memtx_alloc.cache->arena->prealloc + 0.0001);
 	snprintf(value, sizeof(value), "%0.1lf%%", items_used_ratio);
 	lua_pushstring(L, "items_used_ratio");
 	lua_pushstring(L, value);
 	lua_settable(L, -3);
 
 	double arena_used_ratio = 100
-		* ((double)talloc.cache->arena->used)
-		/ ((double)talloc.cache->arena->prealloc + 0.0001);
+		* ((double)memtx_alloc.cache->arena->used)
+		/ ((double)memtx_alloc.cache->arena->prealloc + 0.0001);
 	snprintf(value, sizeof(value), "%0.1lf%%", arena_used_ratio);
 	lua_pushstring(L, "arena_used_ratio");
 	lua_pushstring(L, value);
@@ -119,10 +120,26 @@ lbox_slab_info(struct lua_State *L)
 	return 1;
 }
 
+static int
+lbox_runtime_info(struct lua_State *L)
+{
+	lua_newtable(L);
+
+	lua_pushstring(L, "used");
+	luaL_pushnumber64(L, runtime.used);
+	lua_settable(L, -3);
+
+	lua_pushstring(L, "maxalloc");
+	luaL_pushnumber64(L, runtime.maxalloc);
+	lua_settable(L, -3);
+
+	return 1;
+}
+
 static int
 lbox_slab_check(struct lua_State *L __attribute__((unused)))
 {
-	slab_cache_check(talloc.cache);
+	slab_cache_check(memtx_alloc.cache);
 	return 0;
 }
 
@@ -142,6 +159,16 @@ box_lua_slab_init(struct lua_State *L)
 	lua_pushcfunction(L, lbox_slab_check);
 	lua_settable(L, -3);
 
+	lua_settable(L, -3); /* box.slab */
+
+	lua_pushstring(L, "runtime");
+	lua_newtable(L);
+
+	lua_pushstring(L, "info");
+	lua_pushcfunction(L, lbox_runtime_info);
 	lua_settable(L, -3);
-	lua_pop(L, 1);
+
+	lua_settable(L, -3); /* box.runtime */
+
+	lua_pop(L, 1); /* box. */
 }
diff --git a/src/box/lua/snapshot_daemon.lua b/src/box/lua/snapshot_daemon.lua
index 6dc9cff6ee46bdec3935cb5a6696c63e855e87ca..8b8938d2b6196de60a856e7e2cf227d097d64579 100644
--- a/src/box/lua/snapshot_daemon.lua
+++ b/src/box/lua/snapshot_daemon.lua
@@ -1,4 +1,4 @@
--- snap_daemon.lua (internal file)
+-- snapshot_daemon.lua (internal file)
 
 do
     local log = require 'log'
@@ -7,7 +7,7 @@ do
     local yaml = require 'yaml'
     local errno = require 'errno'
 
-    local PREFIX = 'snap_daemon'
+    local PREFIX = 'snapshot_daemon'
 
     local daemon = { status = 'stopped' }
 
@@ -239,6 +239,10 @@ do
             end,
 
             set_snapshot_count = function(snapshot_count)
+                if math.floor(snapshot_count) ~= snapshot_count then
+                    box.error(box.error.PROC_LUA,
+                        "snapshot_count must be integer")
+                end
                 local daemon = box.internal[PREFIX] or daemon
                 log.info("new snapshot count is %s", tostring(snapshot_count))
 
diff --git a/src/box/lua/tuple.cc b/src/box/lua/tuple.cc
index c5f0957892afb8ebb0a40491ebd720b6beeb76f9..a5057c1bec84f1109301c397d42044102ccd002f 100644
--- a/src/box/lua/tuple.cc
+++ b/src/box/lua/tuple.cc
@@ -374,3 +374,16 @@ box_lua_tuple_init(struct lua_State *L)
 
 	box_lua_slab_init(L);
 }
+
+struct tuple *
+boxffi_tuple_update(struct tuple *tuple, const char *expr, const char *expr_end)
+{
+	RegionGuard region_guard(&fiber()->gc);
+	try {
+		return tuple_update(tuple_format_ber,
+				    region_alloc_cb, &fiber()->gc,
+				    tuple, expr, expr_end, 1);
+	} catch (ClientError *e) {
+		return NULL;
+	}
+}
diff --git a/src/box/lua/tuple.h b/src/box/lua/tuple.h
index bdcb840840c3331f1a4cf3646fbdbad4b12f2a71..05a830b168ad46897ccd6fc49a28bc52235d8db2 100644
--- a/src/box/lua/tuple.h
+++ b/src/box/lua/tuple.h
@@ -52,4 +52,15 @@ luamp_encodestack(struct lua_State *L, struct tbuf *b,
 void
 box_lua_tuple_init(struct lua_State *L);
 
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+struct tuple *
+boxffi_tuple_update(struct tuple *tuple, const char *expr, const char *expr_end);
+
+#if defined(__cplusplus)
+} /* extern "C" */
+#endif
+
 #endif /* INCLUDES_TARANTOOL_MOD_BOX_LUA_TUPLE_H */
diff --git a/src/box/lua/tuple.lua b/src/box/lua/tuple.lua
index 695d9afd25e9957e20645c721e842e2522854fef..515c792f47aeaa9ef511d531df7e13214676016f 100644
--- a/src/box/lua/tuple.lua
+++ b/src/box/lua/tuple.lua
@@ -4,6 +4,7 @@ local ffi = require('ffi')
 local yaml = require('yaml')
 local msgpackffi = require('msgpackffi')
 local fun = require('fun')
+local internal = require('box.internal')
 
 ffi.cdef([[
 struct tuple
@@ -39,10 +40,26 @@ tuple_next(struct tuple_iterator *it);
 
 void
 tuple_to_buf(struct tuple *tuple, char *buf);
+
+struct tuple *
+boxffi_tuple_update(struct tuple *tuple, const char *expr, const char *expr_end);
 ]])
 
 local builtin = ffi.C
 
+local const_struct_tuple_ref_t = ffi.typeof('const struct tuple&')
+
+local tuple_gc = function(tuple)
+    builtin.tuple_ref(tuple, -1)
+end
+
+local tuple_bless = function(tuple)
+    -- update in-place, do not spent time calling tuple_ref
+    local tuple2 = ffi.gc(ffi.cast(const_struct_tuple_ref_t, tuple), tuple_gc)
+    tuple._refs = tuple._refs + 1
+    return tuple2
+end
+
 local tuple_iterator_t = ffi.typeof('struct tuple_iterator')
 
 local function tuple_iterator_next(it, tuple, pos)
@@ -130,6 +147,19 @@ local function tuple_findall(tuple, offset, val)
         :totable()
 end
 
+local function tuple_update(tuple, expr)
+    if type(expr) ~= 'table' then
+        error("Usage: tuple:update({ { op, field, arg}+ })")
+    end
+    expr = internal.normalize_update_ops(expr)
+    local pexpr, pexpr_end = msgpackffi.encode_tuple(expr)
+    local tuple = builtin.boxffi_tuple_update(tuple, pexpr, pexpr_end)
+    if tuple == NULL then
+        return box.error()
+    end
+    return tuple_bless(tuple)
+end
+
 -- Set encode hooks for msgpackffi
 local function tuple_to_msgpack(buf, tuple)
     buf:reserve(tuple._bsize)
@@ -137,7 +167,6 @@ local function tuple_to_msgpack(buf, tuple)
     buf.p = buf.p + tuple._bsize
 end
 
-
 msgpackffi.on_encode(ffi.typeof('const struct tuple &'), tuple_to_msgpack)
 
 
@@ -153,25 +182,13 @@ local methods = {
     ["findall"]     = tuple_findall;
     ["unpack"]      = tuple_unpack;
     ["totable"]     = tuple_totable;
+    ["update"]      = tuple_update;
     ["bsize"]       = function(tuple)
         return tonumber(tuple._bsize)
     end;
     ["__serialize"] = tuple_totable; -- encode hook for msgpack/yaml/json
 }
 
-local const_struct_tuple_ref_t = ffi.typeof('const struct tuple&')
-
-local tuple_gc = function(tuple)
-    builtin.tuple_ref(tuple, -1)
-end
-
-local tuple_bless = function(tuple)
-    -- update in-place, do not spent time calling tuple_ref
-    local tuple2 = ffi.gc(ffi.cast(const_struct_tuple_ref_t, tuple), tuple_gc)
-    tuple._refs = tuple._refs + 1
-    return tuple2
-end
-
 local tuple_field = function(tuple, field_n)
     local field = builtin.tuple_field(tuple, field_n - 1)
     if field == nil then
diff --git a/src/box/recovery.cc b/src/box/recovery.cc
index b56d40e7a3adda6f3fbd9264ed0fde00e1848c0b..e782e96bf8cd11a01a5713ca83a1f1e8be48ddfb 100644
--- a/src/box/recovery.cc
+++ b/src/box/recovery.cc
@@ -42,7 +42,7 @@
 #include "replica.h"
 #include "fiber.h"
 #include "msgpuck/msgpuck.h"
-#include "iproto_constants.h"
+#include "xrow.h"
 #include "crc32.h"
 #include "scoped_guard.h"
 #include "box/cluster.h"
@@ -118,7 +118,7 @@ const char *wal_mode_STRS[] = { "none", "write", "fsync", NULL };
 /* {{{ LSN API */
 
 static void
-fill_lsn(struct recovery_state *r, struct iproto_header *row)
+fill_lsn(struct recovery_state *r, struct xrow_header *row)
 {
 	if (row == NULL || row->server_id == 0) {
 		/* Local request */
@@ -226,7 +226,6 @@ recovery_free()
 		 */
 		log_io_close(&r->current_wal);
 	}
-
 	recovery= NULL;
 }
 
@@ -239,7 +238,7 @@ recovery_setup_panic(struct recovery_state *r, bool on_snap_error,
 }
 
 void
-recovery_process(struct recovery_state *r, struct iproto_header *row)
+recovery_process(struct recovery_state *r, struct xrow_header *row)
 {
 	/* Check lsn */
 	int64_t current_signt = vclock_get(&r->vclock, row->server_id);
@@ -326,7 +325,7 @@ recover_wal(struct recovery_state *r, struct log_io *l)
 
 	log_io_cursor_open(&i, l);
 
-	struct iproto_header row;
+	struct xrow_header row;
 	while (log_io_cursor_next(&i, &row) == 0) {
 		try {
 			recovery_process(r, &row);
@@ -483,9 +482,7 @@ recover_remaining_wals(struct recovery_state *r)
 		result = -1;
 	}
 
-#if 0
 	region_free(&fiber()->gc);
-#endif
 	return result;
 }
 
@@ -665,7 +662,7 @@ struct wal_write_request {
 	/* Auxiliary. */
 	int64_t res;
 	struct fiber *fiber;
-	struct iproto_header *row;
+	struct xrow_header *row;
 };
 
 /* Context of the WAL writer thread. */
@@ -979,7 +976,7 @@ wal_fill_batch(struct log_io *wal, struct fio_batch *batch, int rows_per_wal,
 	assert(max_rows > 0);
 	fio_batch_start(batch, max_rows);
 
-	struct iovec iov[XLOG_ROW_IOVMAX];
+	struct iovec iov[XROW_IOVMAX];
 	while (req != NULL && !fio_batch_has_space(batch, nelem(iov))) {
 		int iovcnt = xlog_encode_row(req->row, iov);
 		fio_batch_add(batch, iov, iovcnt);
@@ -1026,6 +1023,7 @@ wal_write_to_disk(struct recovery_state *r, struct wal_writer *writer,
 			break;
 		req = write_end;
 	}
+	fiber_gc();
 	STAILQ_SPLICE(input, write_end, wal_fifo_entry, rollback);
 	STAILQ_CONCAT(commit, input);
 }
@@ -1073,7 +1071,7 @@ wal_writer_thread(void *worker_args)
  * to be written to disk and wait until this task is completed.
  */
 int
-wal_write(struct recovery_state *r, struct iproto_header *row)
+wal_write(struct recovery_state *r, struct xrow_header *row)
 {
 	/*
 	 * Bump current LSN even if wal_mode = NONE, so that
@@ -1120,7 +1118,7 @@ wal_write(struct recovery_state *r, struct iproto_header *row)
 /* {{{ box.snapshot() */
 
 void
-snapshot_write_row(struct log_io *l, struct iproto_header *row)
+snapshot_write_row(struct log_io *l, struct xrow_header *row)
 {
 	static uint64_t bytes;
 	ev_tstamp elapsed;
@@ -1140,7 +1138,7 @@ snapshot_write_row(struct log_io *l, struct iproto_header *row)
 	row->lsn = ++l->rows;
 	row->sync = 0; /* don't write sync to wal */
 
-	struct iovec iov[XLOG_ROW_IOVMAX];
+	struct iovec iov[XROW_IOVMAX];
 	int iovcnt = xlog_encode_row(row, iov);
 
 	/* TODO: use writev here */
@@ -1156,7 +1154,7 @@ snapshot_write_row(struct log_io *l, struct iproto_header *row)
 	if (l->rows % 100000 == 0)
 		say_crit("%.1fM rows written", l->rows / 1000000.);
 
-	region_free_after(&fiber()->gc, 128 * 1024);
+	fiber_gc();
 
 	if (r->snap_io_rate_limit != UINT64_MAX) {
 		if (last == 0) {
diff --git a/src/box/recovery.h b/src/box/recovery.h
index 0c5a484b95586e5381e98322e4c7e008312f1cd9..60fff69fa0e90325a6225b310dac179d52a17d9e 100644
--- a/src/box/recovery.h
+++ b/src/box/recovery.h
@@ -36,6 +36,7 @@
 #include "vclock.h"
 #include "tt_uuid.h"
 #include "replica.h"
+#include "small/region.h"
 
 #if defined(__cplusplus)
 extern "C" {
@@ -44,7 +45,7 @@ extern "C" {
 struct fiber;
 struct tbuf;
 
-typedef void (row_handler)(void *, struct iproto_header *packet);
+typedef void (row_handler)(void *, struct xrow_header *packet);
 typedef void (snapshot_handler)(struct log_io *);
 typedef void (join_handler)(const struct tt_uuid *node_uuid);
 
@@ -113,15 +114,15 @@ void recovery_follow_local(struct recovery_state *r, ev_tstamp wal_dir_rescan_de
 void recovery_finalize(struct recovery_state *r);
 
 int recover_wal(struct recovery_state *r, struct log_io *l);
-int wal_write(struct recovery_state *r, struct iproto_header *packet);
+int wal_write(struct recovery_state *r, struct xrow_header *packet);
 
 void recovery_setup_panic(struct recovery_state *r, bool on_snap_error, bool on_wal_error);
-void recovery_process(struct recovery_state *r, struct iproto_header *packet);
+void recovery_process(struct recovery_state *r, struct xrow_header *packet);
 
 struct fio_batch;
 
 void
-snapshot_write_row(struct log_io *l, struct iproto_header *packet);
+snapshot_write_row(struct log_io *l, struct xrow_header *packet);
 void snapshot_save(struct recovery_state *r);
 
 #if defined(__cplusplus)
diff --git a/src/box/replica.cc b/src/box/replica.cc
index bb9a9975876aa862eaa310bf33807b0363297407..deff8eafbd89714840e344855d6e5b671eda392e 100644
--- a/src/box/replica.cc
+++ b/src/box/replica.cc
@@ -38,48 +38,48 @@
 #include "scoped_guard.h"
 #include "coio_buf.h"
 #include "recovery.h"
-#include "iproto_constants.h"
+#include "xrow.h"
 #include "msgpuck/msgpuck.h"
 #include "session.h"
 #include "box/cluster.h"
+#include "iproto_constants.h"
 
 static const int RECONNECT_DELAY = 1.0;
 
 static void
 remote_read_row(struct ev_io *coio, struct iobuf *iobuf,
-		struct iproto_header *row)
+		struct xrow_header *row)
 {
 	struct ibuf *in = &iobuf->in;
 
 	/* Read fixed header */
-	if (ibuf_size(in) < IPROTO_FIXHEADER_SIZE)
-		coio_breadn(coio, in, IPROTO_FIXHEADER_SIZE - ibuf_size(in));
+	if (ibuf_size(in) < 1)
+		coio_breadn(coio, in, 1);
 
 	/* Read length */
 	if (mp_typeof(*in->pos) != MP_UINT) {
 		tnt_raise(ClientError, ER_INVALID_MSGPACK,
-			  "invalid fixed header");
+			  "packet length");
 	}
+	ssize_t to_read = mp_check_uint(in->pos, in->end);
+	if (to_read > 0)
+		coio_breadn(coio, in, to_read);
 
 	uint32_t len = mp_decode_uint((const char **) &in->pos);
-	if (len > IPROTO_BODY_LEN_MAX) {
-		tnt_raise(ClientError, ER_INVALID_MSGPACK,
-			  "received packet is too big");
-	}
 
 	/* Read header and body */
-	ssize_t to_read = len - ibuf_size(in);
+	to_read = len - ibuf_size(in);
 	if (to_read > 0)
 		coio_breadn(coio, in, to_read);
 
-	iproto_header_decode(row, (const char **) &in->pos, in->pos + len);
+	xrow_header_decode(row, (const char **) &in->pos, in->pos + len);
 }
 
 static void
-remote_write_row(struct ev_io *coio, const struct iproto_header *row)
+remote_write_row(struct ev_io *coio, const struct xrow_header *row)
 {
-	struct iovec iov[IPROTO_ROW_IOVMAX];
-	int iovcnt = iproto_row_encode(row, iov);
+	struct iovec iov[XROW_IOVMAX];
+	int iovcnt = xrow_to_iovec(row, iov);
 	coio_writev(coio, iov, iovcnt, 0);
 }
 
@@ -89,25 +89,47 @@ remote_connect(struct recovery_state *r, struct ev_io *coio,
 {
 	char greeting[IPROTO_GREETING_SIZE];
 
-	evio_socket(coio, AF_INET, SOCK_STREAM, IPPROTO_TCP);
-
+	struct remote *remote = &r->remote;
 	struct uri *uri = &r->remote.uri;
-
-	coio_connect(coio, &uri->addr, uri->addr_len);
+	/*
+	 * coio_connect() stores resolved address to \a &remote->addr
+	 * on success. &remote->addr_len is a value-result argument which
+	 * must be initialized to the size of associated buffer (addrstorage)
+	 * before calling coio_connect(). Since coio_connect() performs
+	 * DNS resolution under the hood it is theoretically possible that
+	 * remote->addr_len will be different even for same uri.
+	 */
+	remote->addr_len = sizeof(remote->addrstorage);
+	/* Prepare null-terminated strings for coio_connect() */
+	char host[URI_MAXHOST] = { '\0' };
+	if (uri->host) {
+		snprintf(host, sizeof(host), "%.*s", (int) uri->host_len,
+			 uri->host);
+	}
+	char service[URI_MAXSERVICE];
+	snprintf(service, sizeof(service), "%.*s", (int) uri->service_len,
+		 uri->service);
+	coio_connect(coio, host, service, &remote->addr, &remote->addr_len);
+	assert(coio->fd >= 0);
 	coio_readn(coio, greeting, sizeof(greeting));
 
-	say_crit("connected to master");
-	if (!r->remote.uri.login[0])
+	say_crit("connected to %s", sio_strfaddr(&remote->addr,
+						 remote->addr_len));
+
+	/* Perform authentication if user provided at least login */
+	if (!r->remote.uri.login)
 		return;
 
 	/* Authenticate */
 	say_debug("authenticating...");
-	struct iproto_header row;
-	iproto_encode_auth(&row, greeting, uri->login, uri->password);
+	struct xrow_header row;
+	xrow_encode_auth(&row, greeting, uri->login,
+			 uri->login_len, uri->password,
+			 uri->password_len);
 	remote_write_row(coio, &row);
 	remote_read_row(coio, iobuf, &row);
 	if (row.type != IPROTO_OK)
-		iproto_decode_error(&row); /* auth failed */
+		xrow_decode_error(&row); /* auth failed */
 
 	/* auth successed */
 	say_info("authenticated");
@@ -152,8 +174,8 @@ replica_bootstrap(struct recovery_state *r)
 	}
 
 	/* Send JOIN request */
-	struct iproto_header row;
-	iproto_encode_join(&row, &r->server_uuid);
+	struct xrow_header row;
+	xrow_encode_join(&row, &r->server_uuid);
 	remote_write_row(&coio, &row);
 
 	/* Add a surrogate server id for snapshot rows */
@@ -170,7 +192,7 @@ replica_bootstrap(struct recovery_state *r)
 			/* Regular snapshot row  (IPROTO_INSERT) */
 			recovery_process(r, &row);
 		} else /* error or unexpected packet */ {
-			iproto_decode_error(&row);  /* rethrow error */
+			xrow_decode_error(&row);  /* rethrow error */
 		}
 	}
 
@@ -178,7 +200,7 @@ replica_bootstrap(struct recovery_state *r)
 	struct vclock vclock;
 	vclock_create(&vclock);
 	assert(row.type == IPROTO_OK);
-	iproto_decode_eos(&row, &vclock);
+	xrow_decode_vclock(&row, &vclock);
 
 	/* Replace server vclock using data from snapshot */
 	vclock_copy(&r->vclock, &vclock);
@@ -209,7 +231,7 @@ pull_from_remote(va_list ap)
 	for (;;) {
 		const char *err = NULL;
 		try {
-			struct iproto_header row;
+			struct xrow_header row;
 			fiber_setcancellable(true);
 			if (! evio_is_active(&coio)) {
 				remote_set_status(&r->remote, "connecting");
@@ -219,7 +241,7 @@ pull_from_remote(va_list ap)
 				remote_connect(r, &coio, iobuf);
 				/* Send SUBSCRIBE request */
 				err = "can't subscribe to master";
-				iproto_encode_subscribe(&row, &cluster_id,
+				xrow_encode_subscribe(&row, &cluster_id,
 					&r->server_uuid, &r->vclock);
 				remote_write_row(&coio, &row);
 				r->remote.warning_said = false;
@@ -228,7 +250,7 @@ pull_from_remote(va_list ap)
 			err = "can't read row";
 			remote_read_row(&coio, iobuf, &row);
 			if (!iproto_type_is_dml(row.type))
-				iproto_decode_error(&row);  /* error */
+				xrow_decode_error(&row);  /* error */
 			fiber_setcancellable(false);
 			err = NULL;
 
@@ -285,7 +307,7 @@ recovery_follow_remote(struct recovery_state *r)
 	assert(r->remote.reader == NULL);
 	assert(recovery_has_remote(r));
 
-	const char *uri = uri_to_string(&r->remote.uri);
+	const char *uri = uri_format(&r->remote.uri);
 	say_crit("starting replication from %s", uri);
 	snprintf(name, sizeof(name), "replica/%s", uri);
 
@@ -316,14 +338,12 @@ recovery_set_remote(struct recovery_state *r, const char *uri)
 		r->remote.source[0] = '\0';
 		return;
 	}
-	/*
-	 * @todo: as long as DNS is involved, this may fail even
-	 * on a valid uri. Don't panic in this case.
-	 */
-	if (uri_parse(&r->remote.uri, uri))
-		panic("Can't parse uri: %s", uri);
-	snprintf(r->remote.source,
-		 sizeof(r->remote.source), "%s", uri);
+	snprintf(r->remote.source, sizeof(r->remote.source), "%s", uri);
+	struct remote *remote = &r->remote;
+	int rc = uri_parse(&remote->uri, r->remote.source);
+	/* URI checked by box_check_replication_source() */
+	assert(rc == 0 && remote->uri.service != NULL);
+	(void) rc;
 }
 
 bool
diff --git a/src/box/replica.h b/src/box/replica.h
index 0f79c512ec4720afef23d8f095bf3c56c24d8c80..08832263537206c0c8cf26bf80de1279a8cd7d16 100644
--- a/src/box/replica.h
+++ b/src/box/replica.h
@@ -32,15 +32,20 @@
 #include "tarantool_ev.h"
 #include <uri.h>
 
-enum { REMOTE_SOURCE_MAXLEN = 64 };
+enum { REMOTE_SOURCE_MAXLEN = 1024 }; /* enough to fit URI with passwords */
 
 /** Master connection */
 struct remote {
-	struct uri uri;
 	struct fiber *reader;
 	ev_tstamp recovery_lag, recovery_last_update_tstamp;
 	bool warning_said;
 	char source[REMOTE_SOURCE_MAXLEN];
+	struct uri uri;
+	union {
+		struct sockaddr addr;
+		struct sockaddr_storage addrstorage;
+	};
+	socklen_t addr_len;
 };
 
 /** Connect to a master and request a snapshot.
diff --git a/src/box/replication.cc b/src/box/replication.cc
index 49a5aef7efaf5b117d24b2eb6386b0c10d66a742..295c1335149688d456629ef3417225588103a4ef 100644
--- a/src/box/replication.cc
+++ b/src/box/replication.cc
@@ -213,11 +213,11 @@ struct replication_request {
 
 /** Replication acceptor fiber handler. */
 void
-replication_join(int fd, struct iproto_header *header)
+replication_join(int fd, struct xrow_header *packet)
 {
-	assert(header->type == IPROTO_JOIN);
+	assert(packet->type == IPROTO_JOIN);
 	struct tt_uuid server_uuid = uuid_nil;
-	iproto_decode_join(header, &server_uuid);
+	xrow_decode_join(packet, &server_uuid);
 
 	/* Notify box about new cluster server */
 	recovery->join_handler(&server_uuid);
@@ -230,8 +230,8 @@ replication_join(int fd, struct iproto_header *header)
 	}
 	request->fd = fd;
 	request->io.data = request;
-	request->data.type = header->type;
-	request->data.sync = header->sync;
+	request->data.type = packet->type;
+	request->data.sync = packet->sync;
 
 	ev_io_init(&request->io, replication_send_socket,
 		   master_to_spawner_socket, EV_WRITE);
@@ -240,13 +240,13 @@ replication_join(int fd, struct iproto_header *header)
 
 /** Replication acceptor fiber handler. */
 void
-replication_subscribe(int fd, struct iproto_header *packet)
+replication_subscribe(int fd, struct xrow_header *packet)
 {
 	struct tt_uuid uu = uuid_nil, server_uuid = uuid_nil;
 
 	struct vclock vclock;
 	vclock_create(&vclock);
-	iproto_decode_subscribe(packet, &uu, &server_uuid, &vclock);
+	xrow_decode_subscribe(packet, &uu, &server_uuid, &vclock);
 
 	/**
 	 * Check that the given UUID matches the UUID of the
@@ -636,7 +636,7 @@ replication_relay_recv(ev_loop * /* loop */, struct ev_io *w, int __attribute__(
 
 /** Send a single row to the client. */
 static void
-replication_relay_send_row(void * /* param */, struct iproto_header *packet)
+replication_relay_send_row(void * /* param */, struct xrow_header *packet)
 {
 	assert(iproto_type_is_dml(packet->type));
 	struct recovery_state *r = recovery;
@@ -644,8 +644,8 @@ replication_relay_send_row(void * /* param */, struct iproto_header *packet)
 	/* Don't duplicate data */
 	if (packet->server_id == 0 || packet->server_id != r->server_id)  {
 		packet->sync = relay.sync;
-		struct iovec iov[IPROTO_ROW_IOVMAX];
-		int iovcnt = iproto_row_encode(packet, iov);
+		struct iovec iov[XROW_IOVMAX];
+		int iovcnt = xrow_to_iovec(packet, iov);
 		sio_writev_all(relay.sock, iov, iovcnt);
 	}
 
@@ -666,11 +666,11 @@ replication_relay_join(struct recovery_state *r)
 	recover_snap(r);
 
 	/* Send response to JOIN command = end of stream */
-	struct iproto_header row;
-	iproto_encode_eos(&row, &r->vclock);
+	struct xrow_header row;
+	xrow_encode_vclock(&row, &r->vclock);
 	row.sync = relay.sync;
-	struct iovec iov[IPROTO_ROW_IOVMAX];
-	int iovcnt = iproto_row_encode(&row, iov);
+	struct iovec iov[XROW_IOVMAX];
+	int iovcnt = xrow_to_iovec(&row, iov);
 	sio_writev_all(relay.sock, iov, iovcnt);
 
 	say_info("snapshot sent");
@@ -745,6 +745,8 @@ replication_relay_loop()
 	ev_io_init(&sock_read_ev, replication_relay_recv,
 		   relay.sock, EV_READ);
 	ev_io_start(loop(), &sock_read_ev);
+	/** Turn off the non-blocking mode,if any. */
+	sio_setfl(relay.sock, O_NONBLOCK, 0);
 
 	/* Initialize the recovery process */
 	recovery_init(cfg_snap_dir, cfg_wal_dir,
diff --git a/src/box/replication.h b/src/box/replication.h
index d6a869b9dca4a0163af76a0d996d4bfee0c9f2f1..c100196ddc43ca07e2b3b4aea6e632cca5e3eef0 100644
--- a/src/box/replication.h
+++ b/src/box/replication.h
@@ -40,7 +40,7 @@ void
 replication_prefork(const char *snap_dir, const char *wal_dir);
 
 void
-replication_join(int fd, struct iproto_header *packet);
+replication_join(int fd, struct xrow_header *packet);
 
 /**
  * Subscribe a replica to updates.
@@ -48,7 +48,7 @@ replication_join(int fd, struct iproto_header *packet);
  * @return None. On error, closes the socket.
  */
 void
-replication_subscribe(int fd, struct iproto_header *packet);
+replication_subscribe(int fd, struct xrow_header *packet);
 
 #endif // TARANTOOL_REPLICATION_H_INCLUDED
 
diff --git a/src/box/request.cc b/src/box/request.cc
index 200c6493963e161603dbeecc9566e56e822ed053..f8a19d2aa510610c5c809815a4026cfe5aef969f 100644
--- a/src/box/request.cc
+++ b/src/box/request.cc
@@ -155,6 +155,10 @@ execute_select(struct request *request, struct port *port)
 			break;
 		port_add_tuple(port, tuple);
 	}
+	if (! in_txn()) {
+		 /* no txn is created, so simply collect garbage here */
+		fiber_gc();
+	}
 }
 
 void
diff --git a/src/box/request.h b/src/box/request.h
index 3e06650310a91ffa8876c0cd858cf81868d9d281..e257109f65fc3b07820e2d040831cc57b7c77b8c 100644
--- a/src/box/request.h
+++ b/src/box/request.h
@@ -29,13 +29,12 @@
  * SUCH DAMAGE.
  */
 #include <stdbool.h>
-#include "iproto_constants.h"
+#include "xrow.h"
 
 struct txn;
 struct port;
 
 typedef void (*request_execute_f)(struct request *, struct port *);
-enum { REQUEST_IOVMAX = IPROTO_PACKET_BODY_IOVMAX };
 
 struct request
 {
@@ -44,7 +43,7 @@ struct request
 	 * on where this packet originated from: the write ahead
 	 * log/snapshot, client request, or a Lua request.
 	 */
-	struct iproto_header *header;
+	struct xrow_header *header;
 	/**
 	 * Request type - IPROTO type code
 	 */
diff --git a/src/box/sophia_index.cc b/src/box/sophia_index.cc
index 7e1c2811bfe2c76fa1c1e1b8a18e887d5a43f189..b50bf1c2c128acfe6a54323428d6387a01ac8bc0 100644
--- a/src/box/sophia_index.cc
+++ b/src/box/sophia_index.cc
@@ -32,11 +32,12 @@
 #include "scoped_guard.h"
 #include "exception.h"
 #include "errinj.h"
-
 #include "schema.h"
 #include "space.h"
+#include "cfg.h"
 #include "engine_sophia.h"
-
+#include <sys/stat.h>
+#include <sys/types.h>
 #include <sophia.h>
 #include <stdio.h>
 
@@ -47,7 +48,11 @@ sophia_delete(void *db, struct key_def *key_def, struct tuple *tuple)
 	const char *keyptr = key;
 	mp_next(&keyptr);
 	size_t keysize = keyptr - key;
-	int rc = sp_delete(db, key, keysize);
+	void *o = sp_object(db);
+	if (o == NULL)
+		tnt_raise(ClientError, ER_SOPHIA, sp_error(db));
+	sp_set(o, "key", key, keysize);
+	int rc = sp_delete(db, o);
 	if (rc == -1)
 		tnt_raise(ClientError, ER_SOPHIA, sp_error(db));
 }
@@ -59,7 +64,12 @@ sophia_set(void *db, struct key_def *key_def, struct tuple *tuple)
 	const char *keyptr = key;
 	mp_next(&keyptr);
 	size_t keysize = keyptr - key;
-	int rc = sp_set(db, key, keysize, tuple->data, tuple->bsize);
+	void *o = sp_object(db);
+	if (o == NULL)
+		tnt_raise(ClientError, ER_SOPHIA, sp_error(db));
+	sp_set(o, "key", key, keysize);
+	sp_set(o, "value", tuple->data, tuple->bsize);
+	int rc = sp_set(db, o);
 	if (rc == -1)
 		tnt_raise(ClientError, ER_SOPHIA, sp_error(db));
 }
@@ -105,16 +115,19 @@ static struct tuple *
 sophia_gettuple(void *db, const char *key, size_t keysize,
                 struct tuple_format *format)
 {
-	size_t valuesize = 0;
-	char *value = NULL;
-	int rc = sp_get(db, key, keysize, (void**)&value, &valuesize);
-	if (rc == -1)
+	void *o = sp_object(db);
+	if (o == NULL)
 		tnt_raise(ClientError, ER_SOPHIA, sp_error(db));
-	if (rc == 0)
+	sp_set(o, "key", key, keysize);
+	void *result = sp_get(db, o);
+	if (result == NULL)
 		return NULL;
-	auto scoped_guard = make_scoped_guard([=] { free(value); });
+	auto scoped_guard =
+		make_scoped_guard([=] { sp_destroy(result); });
+	int valuesize = 0;
+	void *value = sp_get(result, "value", &valuesize);
 	struct tuple *ret =
-		tuple_new(format, value, value + valuesize);
+		tuple_new(format, (char*)value, (char*)value + valuesize);
 	tuple_ref(ret, 1);
 	return ret;
 }
@@ -128,13 +141,21 @@ SophiaIndex::SophiaIndex(struct key_def *key_def_arg __attribute__((unused)))
 	SophiaFactory *factory =
 		(SophiaFactory*)space->engine->factory;
 	env = factory->env;
-
-	db = sp_database(env);
+	db = sp_storage(env);
 	if (db == NULL)
 		tnt_raise(ClientError, ER_SOPHIA, sp_error(env));
+
+	const char *sophia_dir = cfg_gets("sophia_dir");
+	mkdir(sophia_dir, 0755);
+
+	char path[PATH_MAX];
+	snprintf(path, sizeof(path), "%s/%" PRIu32,
+	         sophia_dir, key_def->space_id);
+
 	void *c = sp_ctl(db, "conf");
-	sp_set(c, "db.cmp", sophia_index_compare, key_def);
-	sp_set(c, "db.id", space->def.id);
+	sp_set(c, "storage.dir", path);
+	sp_set(c, "storage.cmp", sophia_index_compare, key_def);
+	sp_set(c, "storage.cmp_arg", key_def);
 	int rc = sp_open(db);
 	if (rc == -1)
 		tnt_raise(ClientError, ER_SOPHIA, sp_error(env));
@@ -151,10 +172,35 @@ SophiaIndex::~SophiaIndex()
 		int rc = sp_destroy(db);
 		if (rc == -1)
 			say_info("sophia space %d close error: %s", key_def->space_id,
-			         sp_error(env));
+			         (char*)sp_error(env));
 	}
 }
 
+struct tuple *
+SophiaIndex::random(uint32_t rnd) const
+{
+	void *o = sp_object(db);
+	if (o == NULL)
+		tnt_raise(ClientError, ER_SOPHIA, sp_error(db));
+	sp_set(o, "key", &rnd, sizeof(rnd));
+	void *c = sp_cursor(db, "random", o);
+	if (c == NULL)
+		tnt_raise(ClientError, ER_SOPHIA, sp_error(db));
+	auto scoped_guard =
+		make_scoped_guard([=] { sp_destroy(c); });
+	o = sp_get(c);
+	if (o == NULL)
+		return NULL;
+	struct space *space = space_cache_find(key_def->space_id);
+	int valuesize;
+	void *value = sp_get(o, "value", &valuesize);
+	struct tuple *ret =
+		tuple_new(space->format, (char*)value,
+		          (char*)value + valuesize);
+	tuple_ref(ret, 1);
+	return ret;
+}
+
 void
 SophiaIndex::endBuild()
 {
@@ -163,9 +209,9 @@ SophiaIndex::endBuild()
 size_t
 SophiaIndex::size() const
 {
-	tnt_raise(ClientError, ER_UNSUPPORTED,
-	          "SophiaIndex", "size operation");
-	return 0;
+	void *profiler = sp_ctl(db, "profiler");
+	uint64_t count = *(uint64_t*)sp_get(profiler, "count", NULL);
+	return count;
 }
 
 size_t
@@ -228,11 +274,10 @@ SophiaIndex::replace(struct tuple *old_tuple, struct tuple *new_tuple,
 		const char *keyptr = key;
 		mp_next(&keyptr);
 		size_t keysize = keyptr - key;
-
 		struct space *space = space_cache_find(key_def->space_id);
+
 		struct tuple *dup_tuple =
 			sophia_gettuple(db, key, keysize, space->format);
-
 		uint32_t errcode =
 			sophia_check_dup(key_def, old_tuple, dup_tuple, mode);
 		if (errcode) {
@@ -241,20 +286,25 @@ SophiaIndex::replace(struct tuple *old_tuple, struct tuple *new_tuple,
 			tnt_raise(ClientError, errcode, index_id(this));
 		}
 
-		int rc = sp_set(db, key, keysize, new_tuple->data, new_tuple->bsize);
+		void *o = sp_object(db);
+		if (o == NULL) {
+			if (dup_tuple)
+				tuple_ref(dup_tuple, -1);
+			tnt_raise(ClientError, ER_SOPHIA, sp_error(db));
+		}
+		sp_set(o, "key", key, keysize);
+		sp_set(o, "value", new_tuple->data, new_tuple->bsize);
+		int rc = sp_set(db, o);
 		if (rc == -1) {
 			if (dup_tuple)
 				tuple_ref(dup_tuple, -1);
 			tnt_raise(ClientError, ER_SOPHIA, sp_error(db));
 		}
-
 		if (dup_tuple)
 			return dup_tuple;
 	}
-
 	if (old_tuple)
 		sophia_delete(db, key_def, old_tuple);
-
 	return old_tuple;
 }
 
@@ -295,11 +345,11 @@ sophia_iterator_next(struct iterator *ptr)
 	assert(ptr->next == sophia_iterator_next);
 	struct sophia_iterator *it = (struct sophia_iterator *) ptr;
 	assert(it->cursor != NULL);
-	int rc = sp_fetch(it->cursor);
-	if (rc == 0)
+	void *o = sp_get(it->cursor);
+	if (o == NULL)
 		return NULL;
-	size_t valuesize = sp_valuesize(it->cursor);
-	const char *value = (const char*)sp_value(it->cursor);
+	int valuesize = 0;
+	const char *value = (const char*)sp_get(o, "value", &valuesize);
 	struct tuple *ret =
 		tuple_new(it->space->format, value, value + valuesize);
 	tuple_ref(ret, 1);
@@ -343,8 +393,6 @@ void
 SophiaIndex::initIterator(struct iterator *ptr, enum iterator_type type,
 		const char *key, uint32_t part_count) const
 {
-	assert(part_count <= 1);
-
 	struct sophia_iterator *it = (struct sophia_iterator *) ptr;
 	assert(it->cursor == NULL);
 
@@ -364,7 +412,8 @@ SophiaIndex::initIterator(struct iterator *ptr, enum iterator_type type,
 	it->space  = space_cache_find(key_def->space_id);
 	const char *compare;
 	switch (type) {
-	case ITER_EQ: it->base.next = sophia_iterator_eq;
+	case ITER_EQ:
+		it->base.next = sophia_iterator_eq;
 		return;
 	case ITER_ALL:
 	case ITER_GE: compare = ">=";
@@ -379,7 +428,15 @@ SophiaIndex::initIterator(struct iterator *ptr, enum iterator_type type,
 		tnt_raise(ClientError, ER_UNSUPPORTED,
 		          "SophiaIndex", "requested iterator type");
 	}
-	it->cursor = sp_cursor(db, compare, key, keysize);
+	it->base.next = sophia_iterator_next;
+	void *o = NULL;
+	if (key) {
+		o = sp_object(db);
+		if (o == NULL)
+			tnt_raise(ClientError, ER_SOPHIA, sp_error(db));
+		sp_set(o, "key", key, keysize);
+	}
+	it->cursor = sp_cursor(db, compare, o);
 	if (it->cursor == NULL)
 		tnt_raise(ClientError, ER_SOPHIA, sp_error(db));
 }
diff --git a/src/box/sophia_index.h b/src/box/sophia_index.h
index 063961d790843fd5f5c17a6977327f5b0ffc14c6..322db9d97b17a5f763f12b9b9fbbfeab746c8878 100644
--- a/src/box/sophia_index.h
+++ b/src/box/sophia_index.h
@@ -38,12 +38,11 @@ class SophiaIndex: public Index {
 
 	virtual size_t size() const;
 	virtual void endBuild();
-
+	virtual struct tuple *random(uint32_t rnd) const;
 	virtual struct tuple *findByKey(const char *key, uint32_t part_count) const;
 	virtual struct tuple *replace(struct tuple *old_tuple,
 				      struct tuple *new_tuple,
 				      enum dup_replace_mode mode);
-
 	virtual struct iterator *allocIterator() const;
 	virtual void initIterator(struct iterator *iterator,
 				  enum iterator_type type,
diff --git a/src/box/tuple.cc b/src/box/tuple.cc
index 383304acec6c9566ef2e31e66ebb717eb5a4a030..69d2dff18976e64d295c490b30f27f2fb99023a1 100644
--- a/src/box/tuple.cc
+++ b/src/box/tuple.cc
@@ -45,9 +45,9 @@ static uint32_t formats_size, formats_capacity;
 
 uint32_t snapshot_version;
 
-struct slab_arena tuple_arena;
-static struct slab_cache tuple_slab_cache;
-struct small_alloc talloc;
+struct slab_arena memtx_arena;
+struct slab_cache memtx_slab_cache;
+struct small_alloc memtx_alloc;
 
 /** Extract all available type info from keys. */
 void
@@ -252,7 +252,7 @@ struct tuple *
 tuple_alloc(struct tuple_format *format, size_t size)
 {
 	size_t total = sizeof(struct tuple) + size + format->field_map_size;
-	char *ptr = (char *) smalloc(&talloc, total, "tuple");
+	char *ptr = (char *) smalloc(&memtx_alloc, total, "tuple");
 	struct tuple *tuple = (struct tuple *)(ptr + format->field_map_size);
 
 	tuple->refs = 0;
@@ -277,10 +277,10 @@ tuple_delete(struct tuple *tuple)
 	struct tuple_format *format = tuple_format(tuple);
 	char *ptr = (char *) tuple - format->field_map_size;
 	tuple_format_ref(format, -1);
-	if (!talloc.is_delayed_free_mode || tuple->version == snapshot_version)
-		smfree(&talloc, ptr);
+	if (!memtx_alloc.is_delayed_free_mode || tuple->version == snapshot_version)
+		smfree(&memtx_alloc, ptr);
 	else
-		smfree_delayed(&talloc, ptr);
+		smfree_delayed(&memtx_alloc, ptr);
 }
 
 /**
@@ -545,14 +545,14 @@ tuple_init(float arena_prealloc, uint32_t objsize_min,
 		flags = MAP_SHARED;
 	}
 
-	if (slab_arena_create(&tuple_arena, prealloc, prealloc,
+	if (slab_arena_create(&memtx_arena, prealloc, prealloc,
 			      slab_size, flags)) {
 		panic_syserror("failed to preallocate %zu bytes",
 			       prealloc);
 	}
-	slab_cache_create(&tuple_slab_cache, &tuple_arena,
+	slab_cache_create(&memtx_slab_cache, &memtx_arena,
 			  slab_size);
-	small_alloc_create(&talloc, &tuple_slab_cache,
+	small_alloc_create(&memtx_alloc, &memtx_slab_cache,
 			   objsize_min, alloc_factor);
 }
 
@@ -577,11 +577,11 @@ void
 tuple_begin_snapshot()
 {
 	snapshot_version++;
-	small_alloc_setopt(&talloc, SMALL_DELAYED_FREE_MODE, true);
+	small_alloc_setopt(&memtx_alloc, SMALL_DELAYED_FREE_MODE, true);
 }
 
 void
 tuple_end_snapshot()
 {
-	small_alloc_setopt(&talloc, SMALL_DELAYED_FREE_MODE, false);
+	small_alloc_setopt(&memtx_alloc, SMALL_DELAYED_FREE_MODE, false);
 }
diff --git a/src/box/tuple.h b/src/box/tuple.h
index b07a3e4db7f11f3515e790424d45f67e800ecd3a..6e79795feed8fb28c8fefc539ae4fd5cf0833744 100644
--- a/src/box/tuple.h
+++ b/src/box/tuple.h
@@ -35,8 +35,9 @@ enum { FORMAT_ID_MAX = UINT16_MAX - 1, FORMAT_ID_NIL = UINT16_MAX };
 
 struct tbuf;
 
-extern struct small_alloc talloc;
-extern struct slab_arena tuple_arena;
+extern struct small_alloc memtx_alloc;
+extern struct slab_cache memtx_slab_cache;
+extern struct slab_arena memtx_arena;
 
 /**
  * @brief In-memory tuple format
diff --git a/src/box/txn.cc b/src/box/txn.cc
index 6a92204bb936576533ebe9d197236f64bd70c0ff..c350593c9d7ce40cfa64e91ff9b8e7a636d8780d 100644
--- a/src/box/txn.cc
+++ b/src/box/txn.cc
@@ -36,9 +36,17 @@
 #include "request.h" /* for request_name */
 #include "session.h"
 #include "port.h"
+#include "iproto_constants.h"
 
 double too_long_threshold;
 
+static inline void
+fiber_set_txn(struct fiber *fiber, struct txn *txn)
+{
+	fiber_set_key(fiber, FIBER_KEY_TXN, (void *) txn);
+}
+
+
 static void
 txn_add_redo(struct txn_stmt *stmt, struct request *request)
 {
@@ -47,8 +55,8 @@ txn_add_redo(struct txn_stmt *stmt, struct request *request)
 		return;
 
 	/* Create a redo log row for Lua requests */
-	struct iproto_header *row= (struct iproto_header *)
-		region_alloc0(&fiber()->gc, sizeof(struct iproto_header));
+	struct xrow_header *row= (struct xrow_header *)
+		region_alloc0(&fiber()->gc, sizeof(struct xrow_header));
 	row->type = request->type;
 	row->bodycnt = request_encode(request, row->body);
 	stmt->row = row;
@@ -131,7 +139,7 @@ txn_stmt_new(struct txn *txn)
 struct txn *
 txn_begin(bool autocommit)
 {
-	assert(! fiber_get_txn(fiber()));
+	assert(! in_txn());
 	struct txn *txn = (struct txn *)
 		region_alloc0(&fiber()->gc, sizeof(*txn));
 	rlist_create(&txn->stmts);
@@ -152,7 +160,7 @@ txn_begin(bool autocommit)
 struct txn *
 txn_begin_stmt(struct request *request)
 {
-	struct txn *txn = fiber_get_txn(fiber());
+	struct txn *txn = in_txn();
 	if (txn == NULL)
 		txn = txn_begin(true);
 	struct txn_stmt *stmt = txn_stmt_new(txn);
@@ -181,7 +189,7 @@ txn_commit_stmt(struct txn *txn, struct port *port)
 void
 txn_commit(struct txn *txn)
 {
-	assert(txn == fiber_get_txn(fiber()));
+	assert(txn == in_txn());
 	struct txn_stmt *stmt;
 	/* if (!txn->autocommit && txn->n_stmts && engine_no_yield(txn->engine)) */
 		trigger_clear(&txn->fiber_on_yield);
@@ -236,7 +244,7 @@ txn_finish(struct txn *txn)
 void
 txn_rollback_stmt()
 {
-	struct txn *txn = fiber_get_txn(fiber());
+	struct txn *txn = in_txn();
 	if (txn == NULL)
 		return;
 	if (txn->autocommit)
@@ -256,7 +264,7 @@ txn_rollback_stmt()
 void
 txn_rollback()
 {
-	struct txn *txn = fiber_get_txn(fiber());
+	struct txn *txn = in_txn();
 	if (txn == NULL)
 		return;
 	struct txn_stmt *stmt;
@@ -295,7 +303,7 @@ int
 boxffi_txn_begin()
 {
 	try {
-		if (fiber_get_txn(fiber()))
+		if (in_txn())
 			tnt_raise(ClientError, ER_ACTIVE_TRANSACTION);
 		(void) txn_begin(false);
 	} catch (Exception  *e) {
@@ -308,7 +316,7 @@ int
 boxffi_txn_commit()
 {
 	try {
-		struct txn *txn = fiber_get_txn(fiber());
+		struct txn *txn = in_txn();
 		/**
 		 * COMMIT is like BEGIN or ROLLBACK
 		 * a "transaction-initiating statement".
diff --git a/src/box/txn.h b/src/box/txn.h
index 412a90a5b3b0dee41d7c9ca6b3bb7d1b66010b5f..8f8247c9314ffa1ab254925690d28c78ddc189cf 100644
--- a/src/box/txn.h
+++ b/src/box/txn.h
@@ -50,7 +50,7 @@ struct txn_stmt {
 	struct tuple *new_tuple;
 
 	/** Redo info: the binary log row */
-	struct iproto_header *row;
+	struct xrow_header *row;
 };
 
 struct txn {
@@ -75,15 +75,9 @@ struct txn {
 
 /* Pointer to the current transaction (if any) */
 static inline struct txn *
-fiber_get_txn(struct fiber *fiber)
+in_txn()
 {
-	return (struct txn *) fiber_get_key(fiber, FIBER_KEY_TXN);
-}
-
-static inline void
-fiber_set_txn(struct fiber *fiber, struct txn *txn)
-{
-	fiber_set_key(fiber, FIBER_KEY_TXN, (void *) txn);
+	return (struct txn *) fiber_get_key(fiber(), FIBER_KEY_TXN);
 }
 
 /**
diff --git a/src/iproto_constants.cc b/src/box/xrow.cc
similarity index 60%
rename from src/iproto_constants.cc
rename to src/box/xrow.cc
index b9207d9eb92d475dc26f3b7e27f490404f809edb..1f5761d313d46ec91a71d6c5cb674026ba28bdda 100644
--- a/src/iproto_constants.cc
+++ b/src/box/xrow.cc
@@ -26,145 +26,21 @@
  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include "iproto_constants.h"
+#include "xrow.h"
 #include "msgpuck/msgpuck.h"
 #include "exception.h"
 #include "fiber.h"
-#include "crc32.h"
 #include "tt_uuid.h"
-#include "box/vclock.h"
+#include "vclock.h"
 #include "scramble.h"
 #include "third_party/base64.h"
-
-const unsigned char iproto_key_type[IPROTO_KEY_MAX] =
-{
-	/* {{{ header */
-		/* 0x00 */	MP_UINT,   /* IPROTO_REQUEST_TYPE */
-		/* 0x01 */	MP_UINT,   /* IPROTO_SYNC */
-		/* 0x02 */	MP_UINT,   /* IPROTO_SERVER_ID */
-		/* 0x03 */	MP_UINT,   /* IPROTO_LSN */
-		/* 0x04 */	MP_DOUBLE, /* IPROTO_TIMESTAMP */
-	/* }}} */
-
-	/* {{{ unused */
-		/* 0x05 */	MP_UINT,
-		/* 0x06 */	MP_UINT,
-		/* 0x07 */	MP_UINT,
-		/* 0x08 */	MP_UINT,
-		/* 0x09 */	MP_UINT,
-		/* 0x0a */	MP_UINT,
-		/* 0x0b */	MP_UINT,
-		/* 0x0c */	MP_UINT,
-		/* 0x0d */	MP_UINT,
-		/* 0x0e */	MP_UINT,
-		/* 0x0f */	MP_UINT,
-	/* }}} */
-
-	/* {{{ body -- integer keys */
-		/* 0x10 */	MP_UINT, /* IPROTO_SPACE_ID */
-		/* 0x11 */	MP_UINT, /* IPROTO_INDEX_ID */
-		/* 0x12 */	MP_UINT, /* IPROTO_LIMIT */
-		/* 0x13 */	MP_UINT, /* IPROTO_OFFSET */
-		/* 0x14 */	MP_UINT, /* IPROTO_ITERATOR */
-	/* }}} */
-
-	/* {{{ unused */
-		/* 0x15 */	MP_UINT,
-		/* 0x16 */	MP_UINT,
-		/* 0x17 */	MP_UINT,
-		/* 0x18 */	MP_UINT,
-		/* 0x19 */	MP_UINT,
-		/* 0x1a */	MP_UINT,
-		/* 0x1b */	MP_UINT,
-		/* 0x1c */	MP_UINT,
-		/* 0x1d */	MP_UINT,
-		/* 0x1e */	MP_UINT,
-		/* 0x1f */	MP_UINT,
-	/* }}} */
-
-	/* {{{ body -- all keys */
-	/* 0x20 */	MP_ARRAY, /* IPROTO_KEY */
-	/* 0x21 */	MP_ARRAY, /* IPROTO_TUPLE */
-	/* 0x22 */	MP_STR, /* IPROTO_FUNCTION_NAME */
-	/* 0x23 */	MP_STR, /* IPROTO_USER_NAME */
-	/* 0x24 */	MP_STR, /* IPROTO_SERVER_UUID */
-	/* 0x25 */	MP_STR, /* IPROTO_CLUSTER_UUID */
-	/* 0x26 */	MP_MAP, /* IPROTO_VCLOCK */
-	/* }}} */
-};
-
-const char *iproto_type_strs[] =
-{
-	NULL,
-	"SELECT",
-	"INSERT",
-	"REPLACE",
-	"UPDATE",
-	"DELETE",
-	"CALL",
-	"AUTH"
-};
-
-#define bit(c) (1ULL<<IPROTO_##c)
-const uint64_t iproto_body_key_map[IPROTO_TYPE_DML_MAX] = {
-	0,                                                     /* unused */
-	bit(SPACE_ID) | bit(LIMIT) | bit(KEY),                 /* SELECT */
-	bit(SPACE_ID) | bit(TUPLE),                            /* INSERT */
-	bit(SPACE_ID) | bit(TUPLE),                            /* REPLACE */
-	bit(SPACE_ID) | bit(KEY) | bit(TUPLE),                 /* UPDATE */
-	bit(SPACE_ID) | bit(KEY),                              /* DELETE */
-	bit(FUNCTION_NAME) | bit(TUPLE),                       /* CALL */
-	bit(USER_NAME) | bit(TUPLE)                            /* AUTH */
-};
-#undef bit
-
-const char *iproto_key_strs[IPROTO_KEY_MAX] = {
-	"type",             /* 0x00 */
-	"sync",             /* 0x01 */
-	"server_id",          /* 0x02 */
-	"lsn",              /* 0x03 */
-	"timestamp",        /* 0x04 */
-	"",                 /* 0x05 */
-	"",                 /* 0x06 */
-	"",                 /* 0x07 */
-	"",                 /* 0x08 */
-	"",                 /* 0x09 */
-	"",                 /* 0x0a */
-	"",                 /* 0x0b */
-	"",                 /* 0x0c */
-	"",                 /* 0x0d */
-	"",                 /* 0x0e */
-	"",                 /* 0x0f */
-	"space_id",         /* 0x10 */
-	"index_id",         /* 0x11 */
-	"limit",            /* 0x12 */
-	"offset",           /* 0x13 */
-	"iterator",         /* 0x14 */
-	"",                 /* 0x15 */
-	"",                 /* 0x16 */
-	"",                 /* 0x17 */
-	"",                 /* 0x18 */
-	"",                 /* 0x19 */
-	"",                 /* 0x1a */
-	"",                 /* 0x1b */
-	"",                 /* 0x1c */
-	"",                 /* 0x1d */
-	"",                 /* 0x1e */
-	"",                 /* 0x1f */
-	"key",              /* 0x20 */
-	"tuple",            /* 0x21 */
-	"function name",    /* 0x22 */
-	"user name",        /* 0x23 */
-	"server UUID"       /* 0x24 */
-	"cluster UUID"      /* 0x25 */
-	"vector clock"      /* 0x26 */
-};
+#include "iproto_constants.h"
 
 void
-iproto_header_decode(struct iproto_header *header, const char **pos,
-		     const char *end)
+xrow_header_decode(struct xrow_header *header, const char **pos,
+		   const char *end)
 {
-	memset(header, 0, sizeof(struct iproto_header));
+	memset(header, 0, sizeof(struct xrow_header));
 	const char *pos2 = *pos;
 	if (mp_check(&pos2, end) != 0) {
 error:
@@ -215,7 +91,7 @@ iproto_header_decode(struct iproto_header *header, const char **pos,
  * @pre pos points at a valid msgpack
  */
 void
-iproto_decode_uuid(const char **pos, struct tt_uuid *out)
+xrow_decode_uuid(const char **pos, struct tt_uuid *out)
 {
 	if (mp_typeof(**pos) != MP_STR)
 error:
@@ -228,7 +104,7 @@ iproto_decode_uuid(const char **pos, struct tt_uuid *out)
 }
 
 int
-iproto_header_encode(const struct iproto_header *header, struct iovec *out)
+xrow_header_encode(const struct xrow_header *header, struct iovec *out)
 {
 	enum { HEADER_LEN_MAX = 40 };
 
@@ -275,69 +151,66 @@ iproto_header_encode(const struct iproto_header *header, struct iovec *out)
 	out++;
 
 	memcpy(out, header->body, sizeof(*out) * header->bodycnt);
-	assert(1 + header->bodycnt <= IPROTO_PACKET_IOVMAX);
+	assert(1 + header->bodycnt <= XROW_IOVMAX);
 	return 1 + header->bodycnt; /* new iovcnt */
 }
 
 char *
-iproto_encode_uuid(char *pos, const struct tt_uuid *in)
+xrow_encode_uuid(char *pos, const struct tt_uuid *in)
 {
 	return mp_encode_str(pos, tt_uuid_str(in), UUID_STR_LEN);
 }
 
 int
-iproto_row_encode(const struct iproto_header *row,
-		  struct iovec *out)
+xrow_to_iovec(const struct xrow_header *row,
+	      struct iovec *out)
 {
-	int iovcnt = iproto_header_encode(row, out + 1) + 1;
-	char *fixheader = (char *)
-		region_alloc(&fiber()->gc, IPROTO_FIXHEADER_SIZE);
+	static const int iov0_len = mp_sizeof_uint(UINT32_MAX);
+	int iovcnt = xrow_header_encode(row, out + 1) + 1;
+	char *fixheader = (char *) region_alloc(&fiber()->gc, iov0_len);
 	uint32_t len = 0;
 	for (int i = 1; i < iovcnt; i++)
 		len += out[i].iov_len;
 
 	/* Encode length */
-	assert(IPROTO_FIXHEADER_SIZE == mp_sizeof_uint(UINT32_MAX));
 	char *data = fixheader;
 	*(data++) = 0xce; /* MP_UINT32 */
 	*(uint32_t *) data = mp_bswap_u32(len);
-	data += sizeof(uint32_t);
-	assert(data == fixheader + IPROTO_FIXHEADER_SIZE);
 	out[0].iov_base = fixheader;
-	out[0].iov_len = IPROTO_FIXHEADER_SIZE;
+	out[0].iov_len = iov0_len;
 
-	assert(iovcnt <= IPROTO_ROW_IOVMAX);
+	assert(iovcnt <= XROW_IOVMAX);
 	return iovcnt;
 }
 
 void
-iproto_encode_auth(struct iproto_header *packet, const char *greeting,
-		   const char *login, const char *password)
+xrow_encode_auth(struct xrow_header *packet, const char *greeting,
+		 const char *login, size_t login_len,
+		 const char *password, size_t password_len)
 {
+	assert(login != NULL);
 	memset(packet, 0, sizeof(*packet));
 
-	uint32_t login_len = strlen(login);
-	uint32_t password_len = strlen(password);
-
 	enum { PACKET_LEN_MAX = 128 };
 	size_t buf_size = PACKET_LEN_MAX + login_len + SCRAMBLE_SIZE;
 	char *buf = (char *) region_alloc(&fiber()->gc, buf_size);
 
-	char salt[SCRAMBLE_SIZE];
-	char scramble[SCRAMBLE_SIZE];
-	if (base64_decode(greeting + 64, SCRAMBLE_BASE64_SIZE, salt,
-			  SCRAMBLE_SIZE) != SCRAMBLE_SIZE)
-		panic("invalid salt: %64s", greeting + 64);
-	scramble_prepare(scramble, salt, password, password_len);
-
 	char *d = buf;
-	d = mp_encode_map(d, 2);
+	d = mp_encode_map(d, password != NULL ? 2 : 1);
 	d = mp_encode_uint(d, IPROTO_USER_NAME);
 	d = mp_encode_str(d, login, login_len);
-	d = mp_encode_uint(d, IPROTO_TUPLE);
-	d = mp_encode_array(d, 2);
-	d = mp_encode_str(d, "chap-sha1", strlen("chap-sha1"));
-	d = mp_encode_str(d, scramble, SCRAMBLE_SIZE);
+	if (password != NULL) { /* password can be omitted */
+		char salt[SCRAMBLE_SIZE];
+		char scramble[SCRAMBLE_SIZE];
+		if (base64_decode(greeting + 64, SCRAMBLE_BASE64_SIZE, salt,
+				  SCRAMBLE_SIZE) != SCRAMBLE_SIZE)
+			panic("invalid salt: %64s", greeting + 64);
+		scramble_prepare(scramble, salt, password, password_len);
+		d = mp_encode_uint(d, IPROTO_TUPLE);
+		d = mp_encode_array(d, 2);
+		d = mp_encode_str(d, "chap-sha1", strlen("chap-sha1"));
+		d = mp_encode_str(d, scramble, SCRAMBLE_SIZE);
+	}
 
 	assert(d <= buf + buf_size);
 	packet->body[0].iov_base = buf;
@@ -347,7 +220,7 @@ iproto_encode_auth(struct iproto_header *packet, const char *greeting,
 }
 
 void
-iproto_decode_error(struct iproto_header *row)
+xrow_decode_error(struct xrow_header *row)
 {
 	uint32_t code = row->type & (IPROTO_TYPE_ERROR - 1);
 
@@ -387,10 +260,10 @@ iproto_decode_error(struct iproto_header *row)
 }
 
 void
-iproto_encode_subscribe(struct iproto_header *row,
-			const struct tt_uuid *cluster_uuid,
-			const struct tt_uuid *server_uuid,
-			const struct vclock *vclock)
+xrow_encode_subscribe(struct xrow_header *row,
+		      const struct tt_uuid *cluster_uuid,
+		      const struct tt_uuid *server_uuid,
+		      const struct vclock *vclock)
 {
 	memset(row, 0, sizeof(*row));
 	uint32_t cluster_size = vclock_size(vclock);
@@ -400,9 +273,9 @@ iproto_encode_subscribe(struct iproto_header *row,
 	char *data = buf;
 	data = mp_encode_map(data, 3);
 	data = mp_encode_uint(data, IPROTO_CLUSTER_UUID);
-	data = iproto_encode_uuid(data, cluster_uuid);
+	data = xrow_encode_uuid(data, cluster_uuid);
 	data = mp_encode_uint(data, IPROTO_SERVER_UUID);
-	data = iproto_encode_uuid(data, server_uuid);
+	data = xrow_encode_uuid(data, server_uuid);
 	data = mp_encode_uint(data, IPROTO_VCLOCK);
 	data = mp_encode_map(data, cluster_size);
 	vclock_foreach(vclock, server) {
@@ -417,7 +290,7 @@ iproto_encode_subscribe(struct iproto_header *row,
 }
 
 void
-iproto_decode_subscribe(struct iproto_header *row, struct tt_uuid *cluster_uuid,
+xrow_decode_subscribe(struct xrow_header *row, struct tt_uuid *cluster_uuid,
 			struct tt_uuid *server_uuid, struct vclock *vclock)
 {
 	if (row->bodycnt == 0)
@@ -443,12 +316,12 @@ iproto_decode_subscribe(struct iproto_header *row, struct tt_uuid *cluster_uuid,
 		case IPROTO_CLUSTER_UUID:
 			if (cluster_uuid == NULL)
 				goto skip;
-			iproto_decode_uuid(&d, cluster_uuid);
+			xrow_decode_uuid(&d, cluster_uuid);
 			break;
 		case IPROTO_SERVER_UUID:
 			if (server_uuid == NULL)
 				goto skip;
-			iproto_decode_uuid(&d, server_uuid);
+			xrow_decode_uuid(&d, server_uuid);
 			break;
 		case IPROTO_VCLOCK:
 			if (vclock == NULL)
@@ -485,7 +358,7 @@ iproto_decode_subscribe(struct iproto_header *row, struct tt_uuid *cluster_uuid,
 }
 
 void
-iproto_encode_join(struct iproto_header *row, const struct tt_uuid *server_uuid)
+xrow_encode_join(struct xrow_header *row, const struct tt_uuid *server_uuid)
 {
 	memset(row, 0, sizeof(*row));
 
@@ -495,7 +368,7 @@ iproto_encode_join(struct iproto_header *row, const struct tt_uuid *server_uuid)
 	data = mp_encode_map(data, 1);
 	data = mp_encode_uint(data, IPROTO_SERVER_UUID);
 	/* Greet the remote server with our server UUID */
-	data = iproto_encode_uuid(data, server_uuid);
+	data = xrow_encode_uuid(data, server_uuid);
 	assert(data <= buf + size);
 
 	row->body[0].iov_base = buf;
@@ -505,7 +378,7 @@ iproto_encode_join(struct iproto_header *row, const struct tt_uuid *server_uuid)
 }
 
 void
-iproto_encode_eos(struct iproto_header *row, const struct vclock *vclock)
+xrow_encode_vclock(struct xrow_header *row, const struct vclock *vclock)
 {
 	memset(row, 0, sizeof(*row));
 
diff --git a/src/box/xrow.h b/src/box/xrow.h
new file mode 100644
index 0000000000000000000000000000000000000000..9cf1327779c3f39ba2964b68510cb2fe98d3ab0d
--- /dev/null
+++ b/src/box/xrow.h
@@ -0,0 +1,161 @@
+#ifndef TARANTOOL_XROW_H_INCLUDED
+#define TARANTOOL_XROW_H_INCLUDED
+/*
+ * Redistribution and use in source and binary forms, with or
+ * without modification, 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 <COPYRIGHT HOLDER> ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, 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 OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/uio.h> /* struct iovec */
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+enum {
+	XROW_HEADER_IOVMAX = 1,
+	XROW_BODY_IOVMAX = 2,
+	XROW_IOVMAX = XROW_HEADER_IOVMAX + XROW_BODY_IOVMAX + 1
+};
+
+struct xrow_header {
+	uint32_t type;
+	uint32_t server_id;
+	uint64_t sync;
+	uint64_t lsn;
+	double tm;
+
+	int bodycnt;
+	struct iovec body[XROW_BODY_IOVMAX];
+};
+
+void
+xrow_header_decode(struct xrow_header *header,
+		   const char **pos, const char *end);
+struct tt_uuid;
+
+void
+xrow_decode_uuid(const char **pos, struct tt_uuid *out);
+
+char *
+xrow_encode_uuid(char *pos, const struct tt_uuid *in);
+
+int
+xrow_header_encode(const struct xrow_header *header,
+		   struct iovec *out);
+
+int
+xrow_to_iovec(const struct xrow_header *row, struct iovec *out);
+
+/**
+ * \brief Decode ERROR and re-throw it as ClientError exception
+ * \param row
+*/
+void
+xrow_decode_error(struct xrow_header *row);
+
+/**
+ * \brief Encode AUTH command
+ * \param[out] row
+ * \param greeting - IPROTO greeting
+ * \param login - user login
+ * \param login_len - length of \a login
+ * \param password - user password
+ * \param password_len - length of \a password
+*/
+void
+xrow_encode_auth(struct xrow_header *row, const char *greeting,
+		 const char *login, size_t login_len,
+		 const char *password, size_t password_len);
+
+/**
+ * \brief Encode SUBSCRIBE command
+ * \param row[out]
+ * \param cluster_uuid cluster uuid
+ * \param server_uuid server uuid
+ * \param vclock server vclock
+*/
+void
+xrow_encode_subscribe(struct xrow_header *row,
+		      const struct tt_uuid *cluster_uuid,
+		      const struct tt_uuid *server_uuid,
+		      const struct vclock *vclock);
+
+/**
+ * \brief Decode SUBSCRIBE command
+ * \param row
+ * \param[out] cluster_uuid
+ * \param[out] server_uuid
+ * \param[out] vclock
+*/
+void
+xrow_decode_subscribe(struct xrow_header *row, struct tt_uuid *cluster_uuid,
+		      struct tt_uuid *server_uuid, struct vclock *vclock);
+
+/**
+ * \brief Encode JOIN command
+ * \param[out] row
+ * \param server_uuid
+*/
+void
+xrow_encode_join(struct xrow_header *row, const struct tt_uuid *server_uuid);
+
+/**
+ * \brief Decode JOIN command
+ * \param row
+ * \param[out] server_uuid
+*/
+static inline void
+xrow_decode_join(struct xrow_header *row, struct tt_uuid *server_uuid)
+{
+	return xrow_decode_subscribe(row, NULL, server_uuid, NULL);
+}
+
+/**
+ * \brief Encode end of stream command (a response to JOIN command)
+ * \param row[out]
+ * \param vclock
+*/
+void
+xrow_encode_vclock(struct xrow_header *row, const struct vclock *vclock);
+
+/**
+ * \brief Decode end of stream command (a response to JOIN command)
+ * \param row
+ * \param[out] vclock
+*/
+static inline void
+xrow_decode_vclock(struct xrow_header *row, struct vclock *vclock)
+{
+	return xrow_decode_subscribe(row, NULL, NULL, vclock);
+}
+
+#if defined(__cplusplus)
+} /* extern "C" */
+#endif
+
+#endif /* TARANTOOL_XROW_H_INCLUDED */
diff --git a/src/coeio.cc b/src/coeio.cc
index 223b5223c51fbb3447d9db60a21f4899092d9351..d9de772fac2ce61efb094e3947f3ef8241e1df04 100644
--- a/src/coeio.cc
+++ b/src/coeio.cc
@@ -42,7 +42,7 @@
  * manner, when libeio is ready to process some requests it
  * calls coeio_poller callback.
  *
- * Due to libeio design, want_pall callback is called while
+ * Due to libeio design, want_poll callback is called while
  * locks are being held, so it's not possible to call any libeio
  * function inside this callback. Thus coeio_want_poll raises an
  * async event which will be dealt with normally as part of the
@@ -107,6 +107,15 @@ coeio_init(void)
 	ev_async_start(loop(), &coeio_manager.coeio_async);
 }
 
+/**
+ * ReInit coeio subsystem (for example after 'fork')
+ */
+void
+coeio_reinit(void)
+{
+	eio_init(coeio_want_poll_cb, NULL);
+}
+
 /**
  * A single task context.
  */
@@ -260,8 +269,9 @@ coeio_resolve(int socktype, const char *host, const char *port,
 	hints.ai_protocol = 0;
 	/* do resolving */
 	errno = 0;
-	if (coeio_custom(getaddrinfo_cb, timeout, host, port,
-			 &hints, &result))
+	/* make no difference between empty string and NULL for host */
+	if (coeio_custom(getaddrinfo_cb, timeout, (host && *host) ? host : NULL,
+			 port, &hints, &result))
 		return NULL;
 	return result;
 }
diff --git a/src/coeio.h b/src/coeio.h
index e0fdc8885db464f153e1f3454d1c1d616f1a6b05..6536063c5560f2201600f96576b025de69ed76bd 100644
--- a/src/coeio.h
+++ b/src/coeio.h
@@ -57,6 +57,7 @@ extern "C" {
  */
 
 void coeio_init(void);
+void coeio_reinit(void);
 ssize_t coeio_custom(ssize_t (*f)(va_list ap), ev_tstamp timeout, ...);
 
 struct addrinfo *
diff --git a/src/coio.cc b/src/coio.cc
index e5cbe14e58fbb156c50e8f101baf8499f124d405..e3d92a0d7f7856c64c28a1f692eed6e99e7e712e 100644
--- a/src/coio.cc
+++ b/src/coio.cc
@@ -28,12 +28,15 @@
  */
 #include "coio.h"
 
+#include <sys/socket.h>
+#include <sys/un.h>
 #include <netinet/tcp.h>
 #include <stdio.h>
 
 #include "iobuf.h"
 #include "sio.h"
 #include "scoped_guard.h"
+#include "coeio.h" /* coeio_resolve() */
 
 struct CoioGuard {
 	struct ev_io *ev_io;
@@ -78,28 +81,23 @@ coio_fiber_yield_timeout(struct ev_io *coio, ev_tstamp delay)
 	return is_timedout;
 }
 
-/**
- * Connect to a host.
- */
-void
-coio_connect(struct ev_io *coio, struct sockaddr *addr, socklen_t addr_len)
-{
-	coio_connect_timeout(coio, addr, addr_len, TIMEOUT_INFINITY);
-}
-
 /**
  * Connect to a host with a specified timeout.
- * @retval true timeout
- * @retval false connected
+ * @retval -1 timeout
+ * @retval 0 connected
  */
-bool
-coio_connect_timeout(struct ev_io *coio, struct sockaddr *addr,
-		     socklen_t len, ev_tstamp timeout)
+static int
+coio_connect_addr(struct ev_io *coio, struct sockaddr *addr,
+		  socklen_t len, ev_tstamp timeout)
 {
-	if (sio_connect(coio->fd, addr, len) == 0)
-		return false;
-	assert(errno == EINPROGRESS);
 	ev_loop *loop = loop();
+	evio_socket(coio, addr->sa_family, SOCK_STREAM, 0);
+	auto coio_guard = make_scoped_guard([=]{ evio_close(loop, coio); });
+	if (sio_connect(coio->fd, addr, len) == 0) {
+		coio_guard.is_active = false;
+		return 0;
+	}
+	assert(errno == EINPROGRESS);
 	/*
 	 * Wait until socket is ready for writing or
 	 * timed out.
@@ -111,7 +109,7 @@ coio_connect_timeout(struct ev_io *coio, struct sockaddr *addr,
 	fiber_testcancel();
 	if (is_timedout) {
 		errno = ETIMEDOUT;
-		return true;
+		return -1;
 	}
 	int error = EINPROGRESS;
 	socklen_t sz = sizeof(error);
@@ -121,50 +119,87 @@ coio_connect_timeout(struct ev_io *coio, struct sockaddr *addr,
 		errno = error;
 		tnt_raise(SocketError, coio->fd, "connect");
 	}
-	return false;
+	coio_guard.is_active = false;
+	return 0;
 }
 
 /**
- * Connect to a first address in addrinfo list and initialize coio
- * with connected socket.
+ * Resolve hostname:service from \a uri and connect to the first available
+ * address with a specified timeout.
  *
- * If coio is already initialized, socket family,
- * type and protocol must match the remote address.
+ * If \a addr is not NULL the function provides resolved address on success.
+ * In this case, \a addr_len is a value-result argument. It should be
+ * initialized to the size of the buffer associated with \a addr. Upon return,
+ * \a addr_len is updated to contain the actual size of the source address.
+ * The returned address is truncated if the buffer provided is too small;
+ * in this case, addrlen will return a value greater than was supplied to the
+ * call.
  *
- * @retval true  timeout
- * @retval false sucess
+ * This function also supports UNIX domain sockets if uri->path is not NULL and
+ * uri->service is NULL.
+ *
+ * @retval -1 timeout
+ * @retval 0 connected
  */
-bool
-coio_connect_addrinfo(struct ev_io *coio, struct addrinfo *ai,
-		      ev_tstamp timeout)
+int
+coio_connect_timeout(struct ev_io *coio, const char *host, const char *service,
+		     struct sockaddr *addr, socklen_t *addr_len,
+		     ev_tstamp timeout)
 {
+	/* try to resolve a hostname */
+	struct ev_loop *loop = loop();
 	ev_tstamp start, delay;
-	ev_loop *loop = loop();
+	evio_timeout_init(loop, &start, &delay, timeout);
+
+	assert(service != NULL);
+	if (strcmp(host, URI_HOST_UNIX) == 0) {
+		/* UNIX socket */
+		struct sockaddr_un un;
+		snprintf(un.sun_path, sizeof(un.sun_path), "%s", service);
+		un.sun_family = AF_UNIX;
+		if (coio_connect_addr(coio, (struct sockaddr *) &un, sizeof(un),
+				      delay) != 0)
+			return -1;
+		if (addr != NULL) {
+			assert(addr_len != NULL);
+			*addr_len = MIN(sizeof(un), *addr_len);
+			memcpy(addr, &un, *addr_len);
+		}
+		return 0;
+	}
+
+	struct addrinfo *ai = coeio_resolve(SOCK_STREAM, host, service, delay);
+	if (ai == NULL)
+		return -1; /* timeout */
+
+	auto addrinfo_guard = make_scoped_guard([=]{ freeaddrinfo(ai); });
+	evio_timeout_update(loop(), start, &delay);
+
 	coio_timeout_init(&start, &delay, timeout);
 	assert(! evio_is_active(coio));
-	bool res = true;
 	while (ai) {
 		try {
-			evio_socket(coio, ai->ai_family,
-				    ai->ai_socktype,
-				    ai->ai_protocol);
-			res = coio_connect_timeout(coio, ai->ai_addr,
-					ai->ai_addrlen, delay);
-			if (res)
-				evio_close(loop, coio);
-			return res;
+			if (coio_connect_addr(coio, ai->ai_addr,
+					      ai->ai_addrlen, delay))
+				return -1;
+			if (addr != NULL) {
+				assert(addr_len != NULL);
+				*addr_len = MIN(ai->ai_addrlen, *addr_len);
+				memcpy(addr, ai->ai_addr, *addr_len);
+			}
+			return 0; /* connected */
 		} catch (SocketError *e) {
-			if (res)
-				evio_close(loop, coio);
-			if (ai->ai_next == NULL)
-				throw;
-			ev_now_update(loop);
-			coio_timeout_update(start, &delay);
+			/* ignore */
+			say_error("failed to connect to %s: %s",
+				  sio_strfaddr(ai->ai_addr, ai->ai_addrlen),
+				  e->errmsg());
 		}
 		ai = ai->ai_next;
+		ev_now_update(loop);
+		coio_timeout_update(start, &delay);
 	}
-	/* unreachable. */
-	tnt_raise(SocketError, coio->fd, "connect_addrinfo()");
+
+	tnt_raise(SocketError, coio->fd, "connection failed");
 }
 
 /**
diff --git a/src/coio.h b/src/coio.h
index 35d030e769942bce1d9fd13fcc3a2660dc1c95c1..876778a44cc54e321f6ae5e9210ac7acafe993d7 100644
--- a/src/coio.h
+++ b/src/coio.h
@@ -44,16 +44,18 @@ struct coio_service
 	void *handler_param;
 };
 
-void
-coio_connect(struct ev_io *coio, struct sockaddr *addr, socklen_t addr_len);
-
-bool
-coio_connect_timeout(struct ev_io *coio, struct sockaddr *addr,
-		     socklen_t len, ev_tstamp timeout);
+int
+coio_connect_timeout(struct ev_io *coio, const char *host, const char *service,
+		     struct sockaddr *addr, socklen_t *addr_len,
+		     ev_tstamp timeout);
 
-bool
-coio_connect_addrinfo(struct ev_io *coio, struct addrinfo *ai,
-		      ev_tstamp timeout);
+static inline int
+coio_connect(struct ev_io *coio, const char *host, const char *service,
+	     struct sockaddr *addr, socklen_t *addr_len)
+{
+	return coio_connect_timeout(coio, host, service, addr, addr_len,
+				    TIMEOUT_INFINITY);
+}
 
 void
 coio_bind(struct ev_io *coio, struct sockaddr *addr,
diff --git a/src/errcode.h b/src/errcode.h
index 26cbd753527d5ea92dca2abe0a4f2fc3edeeb6c2..355699e767524a0d84ae40f2ae13bb323151764f 100644
--- a/src/errcode.h
+++ b/src/errcode.h
@@ -56,7 +56,7 @@ enum { TNT_ERRMSG_MAX = 512 };
 	/*  4 */_(ER_TUPLE_NOT_FOUND,		2, "Tuple doesn't exist in index %u") \
 	/*  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_SECONDARY,			2, "Can't modify data upon a request on the secondary port.") \
+	/*  7 */_(ER_READONLY,			2, "Can't modify data because this server in read-only mode.") \
 	/*  8 */_(ER_INJECTION,			2, "Error injection '%s'") \
 	/*  9 */_(ER_CREATE_SPACE,		2, "Failed to create space %u: %s") \
 	/* 10 */_(ER_SPACE_EXISTS,		2, "Space '%s' already exists") \
@@ -134,6 +134,7 @@ enum { TNT_ERRMSG_MAX = 512 };
 	/* 82 */_(ER_NO_SUCH_ROLE,		2, "Role '%s' is not found") \
 	/* 83 */_(ER_ROLE_EXISTS,		2, "Role '%s' already exists") \
 	/* 84 */_(ER_CREATE_ROLE,		2, "Failed to create role '%s': %s") \
+	/* 85 */_(ER_INDEX_EXISTS,		2, "Index '%s' already exists") \
 
 /*
  * !IMPORTANT! Please follow instructions at start of the file
diff --git a/src/evio.cc b/src/evio.cc
index 2d4f8249aa6c72d4ba69421c20941cc6639f0ba4..75b721161c3f8d30fa18ec00cd17ec46856bde07 100644
--- a/src/evio.cc
+++ b/src/evio.cc
@@ -30,37 +30,14 @@
 #include "uri.h"
 #include "scoped_guard.h"
 #include <stdio.h>
+#include <sys/socket.h>
+#include <sys/un.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
 #include <arpa/inet.h>
 
 #define BIND_RETRY_DELAY 0.1
 
-/**
- * Try to convert IPv4 or IPv6 addresses from text to binary form.
- * sa buf must be sizeo of sizeof(sockaddr_in6).
- */
-int
-evio_pton(const char *addr, const char *port, struct sockaddr_storage *sa, socklen_t *salen) {
-	struct sockaddr_in *v4 = (struct sockaddr_in*)sa;
-	int rc = inet_pton(AF_INET, addr, &v4->sin_addr);
-	if (rc) {
-		v4->sin_family = AF_INET;
-		v4->sin_port = htons(atoi(port));
-		*salen = sizeof(struct sockaddr_in);
-		return AF_INET;
-	}
-	struct sockaddr_in6 *v6 = (struct sockaddr_in6*)sa;
-	rc = inet_pton(AF_INET6, addr, &v6->sin6_addr);
-	if (rc) {
-		v6->sin6_family = AF_INET6;
-		v6->sin6_port = htons(atoi(port));
-		*salen = sizeof(struct sockaddr_in6);
-		return AF_INET6;
-	}
-	return -1;
-}
-
 /** Note: this function does not throw. */
 void
 evio_close(ev_loop *loop, struct ev_io *evio)
@@ -133,37 +110,6 @@ evio_setsockopt_tcpserver(int fd)
 		       &linger, sizeof(linger));
 }
 
-/**
- * Bind to a first address in addrinfo list and initialize coio
- * with bound socket.
- */
-void
-evio_bind_addrinfo(struct ev_io *evio, struct addrinfo *ai)
-{
-	assert(! evio_is_active(evio));
-	int fd = -1;
-	while (ai) {
-		try {
-			fd = sio_socket(ai->ai_family, ai->ai_socktype,
-					ai->ai_protocol);
-			evio_setsockopt_tcpserver(fd);
-			if (sio_bind(fd, ai->ai_addr, ai->ai_addrlen) == 0) {
-				evio->fd = fd;
-				return; /* success. */
-			}
-			assert(errno == EADDRINUSE);
-		} catch (SocketError *e) {
-			if (ai->ai_next == NULL) {
-				close(fd);
-				throw;
-			}
-		}
-		close(fd);
-		ai = ai->ai_next;
-	}
-	tnt_raise(SocketError, evio->fd, "evio_bind_addrinfo()");
-}
-
 static inline const char *
 evio_service_name(struct evio_service *service)
 {
@@ -191,7 +137,7 @@ evio_service_accept_cb(ev_loop * /* loop */, ev_io *watcher,
 		if (fd < 0) /* EAGAIN, EWOULDLOCK, EINTR */
 			return;
 		/* set common tcp options */
-		evio_setsockopt_tcp(fd, service->port.addr.sa_family);
+		evio_setsockopt_tcp(fd, service->addr.sa_family);
 		/*
 		 * Invoke the callback and pass it the accepted
 		 * socket.
@@ -212,23 +158,25 @@ evio_service_accept_cb(ev_loop * /* loop */, ev_io *watcher,
  * needs to retry binding.
  */
 static int
-evio_service_bind_and_listen(struct evio_service *service)
+evio_service_bind_addr(struct evio_service *service)
 {
+	say_debug("%s: binding to %s...", evio_service_name(service),
+		  sio_strfaddr(&service->addr, service->addr_len));
 	/* Create a socket. */
-	int fd = sio_socket(service->port.addr.sa_family,
+	int fd = sio_socket(service->addr.sa_family,
 		SOCK_STREAM, IPPROTO_TCP);
 
 	try {
 		evio_setsockopt_tcpserver(fd);
 
-		if (sio_bind(fd, &service->port.addr,
-				service->port.addr_len) || sio_listen(fd)) {
+		if (sio_bind(fd, &service->addr, service->addr_len) ||
+		    sio_listen(fd)) {
 			assert(errno == EADDRINUSE);
 			close(fd);
 			return -1;
 		}
-		say_info("bound to %s port %s", evio_service_name(service),
-			uri_to_string(&service->port));
+		say_info("%s: bound to %s", evio_service_name(service),
+			 sio_strfaddr(&service->addr, service->addr_len));
 
 		/* Invoke on_bind callback if it is set. */
 		if (service->on_bind)
@@ -244,6 +192,50 @@ evio_service_bind_and_listen(struct evio_service *service)
 	return 0;
 }
 
+static int
+evio_service_bind_and_listen(struct evio_service *service)
+{
+	if (strcmp(service->host, URI_HOST_UNIX) == 0) {
+		/* UNIX domain socket */
+		struct sockaddr_un *un = (struct sockaddr_un *) &service->addr;
+		service->addr_len = sizeof(*un);
+		snprintf(un->sun_path, sizeof(un->sun_path), "%s",
+			 service->serv);
+		un->sun_family = AF_UNIX;
+		return evio_service_bind_addr(service);
+	}
+
+	/* IP socket */
+	struct addrinfo hints, *res;
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = AF_UNSPEC;
+	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_flags = AI_PASSIVE;
+
+	/* make no difference between empty string and NULL for host */
+	if (getaddrinfo(*service->host ? service->host : NULL, service->serv,
+			&hints, &res) != 0 || res == NULL)
+		tnt_raise(SocketError, -1, "can't resolve uri for bind");
+	auto addrinfo_guard = make_scoped_guard([=]{ freeaddrinfo(res); });
+
+	for (struct addrinfo *ai = res; ai != NULL; ai = ai->ai_next) {
+		memcpy(&service->addr, ai->ai_addr, ai->ai_addrlen);
+		service->addr_len = ai->ai_addrlen;
+		try {
+			return evio_service_bind_addr(service);
+		} catch (SocketError *e) {
+			say_error("%s: failed to bind on %s: %s",
+				  evio_service_name(service),
+				  sio_strfaddr(ai->ai_addr, ai->ai_addrlen),
+				  e->errmsg());
+			/* ignore */
+		}
+	}
+
+	tnt_raise(SocketError, -1, "%s: failed to bind",
+		  evio_service_name(service));
+}
+
 /** A callback invoked by libev when sleep timer expires.
  *
  * Retry binding. On success, stop the timer. If the port
@@ -272,10 +264,16 @@ evio_service_init(ev_loop *loop,
 
 	service->loop = loop;
 
+	struct uri u;
+	if (uri_parse(&u, uri) || u.service == NULL)
+		tnt_raise(IllegalParams, "invalid uri for bind: %s", uri);
 
-	if (uri_parse(&service->port, uri))
-		tnt_raise(SocketError, -1,
-			  "invalid address for bind: %s", uri);
+	snprintf(service->serv, sizeof(service->serv), "%.*s",
+		 (int) u.service_len, u.service);
+	if (u.host != NULL && strncmp(u.host, "*", u.host_len) != 0) {
+		snprintf(service->host, sizeof(service->host), "%.*s",
+			(int) u.host_len, u.host);
+	} /* else { service->host[0] = '\0'; } */
 
 	service->on_accept = on_accept;
 	service->on_accept_param = on_accept_param;
@@ -300,10 +298,11 @@ evio_service_start(struct evio_service *service)
 
 	if (evio_service_bind_and_listen(service)) {
 		/* Try again after a delay. */
-		say_warn("%s port %s is already in use, will "
+		say_warn("%s: %s is already in use, will "
 			 "retry binding after %lf seconds.",
 			 evio_service_name(service),
-			 uri_to_string(&service->port), BIND_RETRY_DELAY);
+			 sio_strfaddr(&service->addr, service->addr_len),
+			 BIND_RETRY_DELAY);
 
 		ev_timer_set(&service->timer,
 			     BIND_RETRY_DELAY, BIND_RETRY_DELAY);
@@ -320,8 +319,8 @@ evio_service_stop(struct evio_service *service)
 	} else {
 		ev_io_stop(service->loop, &service->ev);
 		close(service->ev.fd);
-		if (service->port.addr.sa_family == AF_UNIX) {
-			unlink(service->port.un.sun_path);
+		if (service->addr.sa_family == AF_UNIX) {
+			unlink(((struct sockaddr_un *) &service->addr)->sun_path);
 		}
 	}
 }
diff --git a/src/evio.h b/src/evio.h
index e2f0d44733f7839143c72c62a31cc5f8370b074b..e05c017556f487fc0a6e979311fda288f495c2a0 100644
--- a/src/evio.h
+++ b/src/evio.h
@@ -63,11 +63,16 @@ struct evio_service
 {
 	/** Service name. E.g. 'primary', 'secondary', etc. */
 	char name[SERVICE_NAME_MAXLEN];
-	/** Bind IP address, useful for logging */
-	char host[SERVICE_NAME_MAXLEN];
+	/** Bind host:service, useful for logging */
+	char host[URI_MAXHOST];
+	char serv[URI_MAXSERVICE];
 
 	/** Interface/port to bind to */
-	struct uri port;
+	union {
+		struct sockaddr addr;
+		struct sockaddr_storage addrstorage;
+	};
+	socklen_t addr_len;
 
 	/** A callback invoked upon a successful bind, optional.
 	 * If on_bind callback throws an exception, it's
@@ -152,10 +157,4 @@ evio_setsockopt_tcp(int fd, int family);
 void
 evio_setsockopt_tcpserver(int fd);
 
-void
-evio_bind_addrinfo(struct ev_io *coio, struct addrinfo *ai);
-
-int
-evio_pton(const char *addr, const char *port, struct sockaddr_storage *sa, socklen_t *salen);
-
 #endif /* TARANTOOL_EVIO_H_INCLUDED */
diff --git a/src/ffisyms.cc b/src/ffisyms.cc
index c37248260ba6bc719dcfbef1c7d14a35fdb4ad09..725dddb914adbb39748ffd775e5b3541d3687160 100644
--- a/src/ffisyms.cc
+++ b/src/ffisyms.cc
@@ -4,6 +4,7 @@
 #include <box/box.h>
 #include <box/tuple.h>
 #include <box/lua/index.h>
+#include <box/lua/tuple.h>
 #include <box/lua/call.h>
 #include <lua/init.h>
 #include <tarantool.h>
@@ -30,6 +31,7 @@ void *ffi_symbols[] = {
 	(void *) boxffi_index_len,
 	(void *) boxffi_index_random,
 	(void *) boxffi_index_iterator,
+	(void *) boxffi_tuple_update,
 	(void *) port_ffi_create,
 	(void *) port_ffi_destroy,
 	(void *) boxffi_select,
@@ -45,5 +47,7 @@ void *ffi_symbols[] = {
 	(void *) bsdsocket_local_resolve,
 	(void *) bsdsocket_nonblock,
 	(void *) base64_decode,
+	(void *) base64_encode,
+	(void *) base64_bufsize,
 	(void *) SHA1internal
 };
diff --git a/src/lua/box_net_box.lua b/src/lua/box_net_box.lua
index cef696ed4d8424f9cf912c1128b2bc463196cc2e..b8169e71f58a09859f1952440edc848facfe3b1b 100644
--- a/src/lua/box_net_box.lua
+++ b/src/lua/box_net_box.lua
@@ -8,6 +8,7 @@ local errno = require 'errno'
 local ffi = require 'ffi'
 local digest = require 'digest'
 local yaml = require 'yaml'
+local urilib = require 'uri'
 
 -- packet codes
 local OK                = 0
@@ -39,15 +40,11 @@ local GREETING_SIZE     = 128
 
 local TIMEOUT_INFINITY  = 500 * 365 * 86400
 
-
-ffi.cdef[[
-    int base64_decode(const char *in_base64, int in_len,
-                  char *out_bin, int out_len);
-]]
-
 local sequence_mt = { __serialize = 'sequence'}
 local mapping_mt = { __serialize = 'mapping'}
 
+local CONSOLE_FAKESYNC  = 15121974
+
 local function request(header, body)
 
     -- hint msgpack to always encode header and body as a map
@@ -75,13 +72,6 @@ local function strxor(s1, s2)
     return res
 end
 
-local function b64decode(str)
-    local so = ffi.new('char[?]', string.len(str) * 2);
-    local len =
-        ffi.C.base64_decode(str, string.len(str), so, string.len(str) * 2)
-    return ffi.string(so, len)
-end
-
 local function keyfy(v)
     if type(v) == 'table' then
         return v
@@ -215,7 +205,7 @@ local proto = {
 
     auth = function(sync, user, password, handshake)
         local saltb64 = string.sub(handshake, 65)
-        local salt = string.sub(b64decode(saltb64), 1, 20)
+        local salt = string.sub(digest.base64_decode(saltb64), 1, 20)
 
         local hpassword = digest.sha1(password)
         local hhpassword = digest.sha1(hpassword)
@@ -228,7 +218,7 @@ local proto = {
         )
     end,
 
-    b64decode = b64decode,
+    b64decode = digest.base64_decode,
 }
 
 
@@ -358,14 +348,51 @@ local remote_methods = {
             setmetatable(self, getmetatable(remote))
         end
 
+
+        -- uri as the first argument
+        if opts == nil then
+            opts = {}
+            if type(port) == 'table' then
+                opts = port
+                port = nil
+            end
+
+            if port == nil then
+                
+                local address = urilib.parse(tostring(host))
+                if address == nil or address.service == nil then
+                    box.error(box.error.PROC_LUA,
+                        "usage: remote:new(uri[, opts] | host, port[, opts])")
+                end
+
+                host = address.host
+                port = address.service
+
+                opts.user = address.login or opts.user
+                opts.password = address.password or opts.password
+            end
+        end
+
+
         self.is_instance = true
         self.host = host
         self.port = port
         self.opts = opts
+
         if self.opts == nil then
             self.opts = {}
         end
 
+        if self.opts.user ~= nil and self.opts.password == nil then
+            box.error(box.error.PROC_LUA,
+                "net.box: password is not defined")
+        end
+        if self.opts.user == nil and self.opts.password ~= nil then
+            box.error(box.error.PROC_LUA,
+                "net.box: user is not defined")
+        end
+            
+
         if self.host == nil then
             self.host = 'localhost'
         end
@@ -391,6 +418,9 @@ local remote_methods = {
 
 
     ping    = function(self)
+        if type(self) ~= 'table' then
+            box.error(box.error.PROC_LUA, "usage: remote:ping()")
+        end
         if not self:is_connected() then
             return false
         end
@@ -411,8 +441,37 @@ local remote_methods = {
     end,
 
     call    = function(self, proc_name, ...)
+        if type(self) ~= 'table' then
+            box.error(box.error.PROC_LUA, "usage: remote:call(proc_name, ...)")
+        end
+
         proc_name = tostring(proc_name)
-        local res = self:_request('call', true, proc_name, {...})
+
+        if not self.console then
+            local res = self:_request('call', true, proc_name, {...})
+            return res.body[DATA]
+        end
+        
+        local eval_str = proc_name .. '('
+        for i = 1, select('#', ...) do
+            if i > 1 then
+                eval_str = eval_str .. ', '
+            end
+            local arg = select(i, ...)
+
+            if arg == nil then
+                eval_str = eval_str .. 'nil'
+            elseif type(arg) == 'number' then
+                eval_str = eval_str .. tostring(arg)
+            else
+                arg = tostring(arg)
+                arg = string.gsub(arg, '"', '\\"')
+                eval_str = eval_str .. '"' .. arg .. '"'
+            end
+        end
+        eval_str = eval_str .. ")\n"
+
+        local res = self:_console_request(eval_str, true)
         return res.body[DATA]
     end,
 
@@ -484,7 +543,7 @@ local remote_methods = {
             self.s = nil
         end
 
-        log.warn(emsg)
+        log.warn("%s", tostring(emsg))
         self.error = emsg
         self.space = {}
         self:_switch_state('error')
@@ -510,7 +569,49 @@ local remote_methods = {
         end
     end,
 
+
+    _check_console_response = function(self)
+        while true do
+            local resp = string.match(self.rbuf, '.-\n[.][.][.]\r?\n')
+            if resp == nil then
+                break
+            end
+            self.rbuf = string.sub(self.rbuf, #resp + 1)
+
+            local result = yaml.decode(resp)
+            if result ~= nil then
+                result = result[1]
+            end
+            
+            local hdr = { [SYNC] = CONSOLE_FAKESYNC, [TYPE] = 0 }
+            local body = {}
+
+            if type(result) ~= 'table' then
+                result = { result }
+            end
+
+
+            if result.error ~= nil then
+                hdr[TYPE] = bit.bor(ERROR_TYPE, box.error.PROC_LUA)
+                body[ERROR] = result.error
+            else
+                body[DATA] = { result }
+            end
+
+            if self.ch.sync[CONSOLE_FAKESYNC] ~= nil then
+                self.ch.sync[CONSOLE_FAKESYNC]:put({hdr = hdr, body = body })
+                self.ch.sync[CONSOLE_FAKESYNC] = nil
+            else
+                log.warn("Unexpected console response: %s", resp)
+            end
+        end
+    end,
+
     _check_response = function(self)
+        if self.console then
+            return self:_check_console_response(self)
+        end
+    
         while true do
             if #self.rbuf < 5 then
                 break
@@ -540,7 +641,7 @@ local remote_methods = {
                 self.ch.sync[sync]:put({ hdr = hdr, body = body })
                 self.ch.sync[sync] = nil
             else
-                log.warn("Unexpected response %s", sync)
+                log.warn("Unexpected response %s", tostring(sync))
             end
         end
     end,
@@ -559,9 +660,11 @@ local remote_methods = {
         end
 
         for _, fid in pairs(list) do
-            if self.ch.fid[fid] ~= nil then
-                self.ch.fid[fid]:put(true)
-                self.ch.fid[fid] = nil
+            if fid ~= fiber.id() then
+                if self.ch.fid[fid] ~= nil then
+                    self.ch.fid[fid]:put(true)
+                    self.ch.fid[fid] = nil
+                end
             end
         end
     end,
@@ -610,6 +713,7 @@ local remote_methods = {
         end
     end,
 
+
     _connect_worker = function(self)
         fiber.name('net.box.connector')
         while true do
@@ -641,24 +745,29 @@ local remote_methods = {
                 elseif string.len(self.handshake) ~= 128 then
                     self:_fatal("Can't read handshake")
                 else
-
                     self.wbuf = ''
                     self.rbuf = ''
 
-                    local s, e = pcall(function()
-                        self:_auth()
-                    end)
-                    if not s then
-                        self:_fatal(e)
-                    end
-                        
-                    xpcall(function() self:_load_schema() end,
-                        function(e)
-                            log.info("Can't load schema: %s", tostring(e))
-                        end)
-                   
-                    if self.state ~= 'error' and self.state ~= 'closed' then
+                    if string.match(self.handshake, '^Tarantool .*console') then
+                        self.console = true
                         self:_switch_state('active')
+                    else
+                        self.console = false
+                        local s, e = pcall(function()
+                            self:_auth()
+                        end)
+                        if not s then
+                            self:_fatal(e)
+                        end
+                            
+                        xpcall(function() self:_load_schema() end,
+                            function(e)
+                                log.info("Can't load schema: %s", tostring(e))
+                            end)
+                       
+                        if self.state ~= 'error' and self.state ~= 'closed' then
+                            self:_switch_state('active')
+                        end
                     end
                 end
             end
@@ -799,7 +908,7 @@ local remote_methods = {
                 break
             end
 
-            if self.s:readable(.5) then
+            if self.s:readable() then
                 if self.state == 'closed' then
                     break
                 end
@@ -808,8 +917,12 @@ local remote_methods = {
                     local data = self.s:sysread()
 
                     if data ~= nil then
-                        self.rbuf = self.rbuf .. data
-                        self:_check_response()
+                        if data == '' then
+                            self:_fatal('Remote host closed connection')
+                        else
+                            self.rbuf = self.rbuf .. data
+                            self:_check_response()
+                        end
                     else
                         self:_fatal(errno.strerror(errno()))
                     end
@@ -893,16 +1006,20 @@ local remote_methods = {
         return self:_request_internal(name, raise, ...)
     end,
 
-    _request_internal = function(self, name, raise, ...)
+    _console_request = function(self, request_body, raise)
+        if raise == nil then
+            raise = true
+        end
+        return self:_request_raw(CONSOLE_FAKESYNC, request_body, raise)
+    end,
+
+    _request_raw = function(self, sync, request, raise)
         
         local fid = fiber.id()
         if self.timeouts[fid] == nil then
             self.timeouts[fid] = TIMEOUT_INFINITY
         end
 
-        local sync = self.proto:sync()
-        local request = self.proto[name](sync, ...)
-
         self.wbuf = self.wbuf .. request
 
         local wstate = self._to_wstate[self.state]
@@ -938,8 +1055,11 @@ local remote_methods = {
         end
 
         if response.body[DATA] ~= nil then
-            for i, v in pairs(response.body[DATA]) do
-                response.body[DATA][i] = box.tuple.new(response.body[DATA][i])
+            if rawget(box, 'tuple') ~= nil then
+                for i, v in pairs(response.body[DATA]) do
+                    response.body[DATA][i] =
+                        box.tuple.new(response.body[DATA][i])
+                end
             end
             -- disable YAML flow output (useful for admin console)
             setmetatable(response.body[DATA], sequence_mt)
@@ -948,6 +1068,14 @@ local remote_methods = {
         return response
     end,
 
+    _request_internal = function(self, name, raise, ...)
+
+        local sync = self.proto:sync()
+        local request = self.proto[name](sync, ...)
+        return self:_request_raw(sync, request, raise)
+        
+    end,
+
     -- private (low level) methods
     _select = function(self, spaceno, indexno, key, opts)
         local res = self:_request('select', true, spaceno, indexno, key, opts)
@@ -983,6 +1111,9 @@ remote.self = {
     timeout = function(self) return self end,
     wait_connected = function(self) return true end,
     call = function(_box, proc_name, ...)
+        if type(_box) ~= 'table' then
+            box.error(box.error.PROC_LUA, "usage: remote:call(proc_name, ...)")
+        end
         proc_name = tostring(proc_name)
         local proc = { package.loaded['box.internal']
             .call_loadproc(proc_name) }
@@ -1001,7 +1132,8 @@ remote.self = {
             result[i] = box.tuple.new(v)
         end
         return result
-    end
+    end,
+    console = false
 }
 
 
diff --git a/src/lua/bsdsocket.cc b/src/lua/bsdsocket.cc
index 9e1e1693ad30c545036faeb8955df280d6bf9fe0..422571af9aef4323fe2188c44657682353a013c4 100644
--- a/src/lua/bsdsocket.cc
+++ b/src/lua/bsdsocket.cc
@@ -336,8 +336,8 @@ bsdsocket_local_resolve(const char *host, const char *port,
 	}
 
 	/* IPv6 */
-	char ipv6[16];
-	if (inet_pton(AF_INET6, host, ipv6) == 1) {
+	struct in6_addr ipv6;
+	if (inet_pton(AF_INET6, host, &ipv6) == 1) {
 		struct sockaddr_in6 *inaddr6 = (struct sockaddr_in6 *) addr;
 		if (*socklen < sizeof(*inaddr6)) {
 			errno = ENOBUFS;
@@ -345,8 +345,8 @@ bsdsocket_local_resolve(const char *host, const char *port,
 		}
 		memset(inaddr6, 0, sizeof(*inaddr6));
 		inaddr6->sin6_family = AF_INET6;
-		inaddr6->sin6_port = htonl(atol(port));
-		memcpy(inaddr6->sin6_addr.s6_addr, ipv6, 16);
+		inaddr6->sin6_port = htons(atoi(port));
+		memcpy(inaddr6->sin6_addr.s6_addr, &ipv6, sizeof(ipv6));
 		*socklen = sizeof(*inaddr6);
 		return 0;
 	}
@@ -804,6 +804,24 @@ lbox_bsdsocket_peername(struct lua_State *L)
 	return 1;
 }
 
+static int
+lbox_bsdsocket_accept(struct lua_State *L)
+{
+	int fh = lua_tointeger(L, 1);
+
+	struct sockaddr_storage fa;
+	socklen_t len = sizeof(fa);
+
+	int sc = accept(fh, (struct sockaddr*)&fa, &len);
+	if (sc < 0) {
+		lua_pushnil(L);
+		return 1;
+	}
+	lua_pushnumber(L, sc);
+	lbox_bsdsocket_push_addr(L, (struct sockaddr *)&fa, len);
+	return 2;
+}
+
 static int
 lbox_bsdsocket_recvfrom(struct lua_State *L)
 {
@@ -860,6 +878,7 @@ tarantool_lua_bsdsocket_init(struct lua_State *L)
 		{ "peer",		lbox_bsdsocket_peername		},
 		{ "recvfrom",		lbox_bsdsocket_recvfrom		},
 		{ "abort",		lbox_bsdsocket_abort		},
+		{ "accept",		lbox_bsdsocket_accept		},
 		{ NULL,			NULL				}
 	};
 
diff --git a/src/lua/bsdsocket.lua b/src/lua/bsdsocket.lua
index 871bdbd356a6fdf65f1d67199b3681c9b0a3dffc..3b65bc04137cb3f88591bd588ceae8fba1c939e6 100644
--- a/src/lua/bsdsocket.lua
+++ b/src/lua/bsdsocket.lua
@@ -6,6 +6,8 @@ local ffi = require('ffi')
 local boxerrno = require('errno')
 local internal = require('socket')
 local fiber = require('fiber')
+local fio = require('fio')
+local log = require('log')
 
 ffi.cdef[[
     struct socket {
@@ -75,9 +77,9 @@ local socket_mt
 local function bless_socket(fd)
     -- Make socket to be non-blocked by default
     if ffi.C.bsdsocket_nonblock(fd, 1) < 0 then
-        local errno = box.errno()
+        local errno = boxerrno()
         ffi.C.close(fd)
-        box.errno(errno)
+        boxerrno(errno)
         return nil
     end
 
@@ -504,12 +506,12 @@ socket_methods.accept = function(self)
     local fd = check_socket(self)
     self._errno = nil
 
-    local cfd = ffi.C.accept(fd, nil, nil)
-    if cfd < 1 then
-        self._errno = box.errno()
+    local cfd, from = internal.accept(fd)
+    if cfd == nil then
+        self._errno = boxerrno()
         return nil
     end
-    return bless_socket(cfd)
+    return bless_socket(cfd), from
 end
 
 local function readchunk(self, size, timeout)
@@ -950,6 +952,11 @@ local function tcp_connect(host, port, timeout)
     if dns == nil then
         return nil
     end
+
+    if #dns == 0 then
+        boxerrno(boxerrno.EINVAL)
+        return nil
+    end
     for i, remote in pairs(dns) do
         timeout = stop - fiber.time()
         if timeout <= 0 then
@@ -964,96 +971,117 @@ local function tcp_connect(host, port, timeout)
     return nil
 end
 
-local function tcp_server_remote(list, prepare, handler)
-    local slist = {}
-
-    -- bind/create sockets
-    for _, addr in pairs(list) do
-        local s = create_socket(addr.family, addr.type, addr.protocol)
+local function tcp_server_handler(server, sc, from)
+    fiber.name(sprintf("%s/client/%s:%s", server.name, from.host, from.port))
+    server.handler(sc, from)
+    sc:close()
+end
 
-        local ok = false
-        if s ~= nil then
-            local backlog = prepare(s)
-            if s:bind(addr.host, addr.port) then
-                if s:listen(backlog) then
-                    ok = true
-                end
-            end
+local function tcp_server_loop(server, s, addr)
+    fiber.name(sprintf("%s/listen/%s:%s", server.name, addr.host, addr.port))
+    while s:readable() do
+        local sc, from = s:accept()
+        if sc == nil then
+            break
         end
+        fiber.create(tcp_server_handler, server, sc, from)
+    end
+    if addr.family == 'AF_UNIX' and addr.port then
+        fio.unlink(addr.port) -- remove unix socket
+    end
+end
 
-        -- errors
-        if not ok then
-            if s ~= nil then
-                s:close()
-            end
-            local save_errno = boxerrno()
-            for _, s in pairs(slist) do
-                s:close()
-            end
-            boxerrno(save_errno)
-            return nil
-        end
+local function tcp_server_usage()
+    error('Usage: socket.tcp_server(host, port, handler | opts)')
+end
 
-        table.insert(slist, s)
+local function tcp_server_bind(s, addr)
+    if s:bind(addr.host, addr.port) then
+        return true
     end
-    
-    local server = { s = slist }
 
-    server.stop = function()
-        if #server.s == 0 then
-            return false
-        end
-        for _, s in pairs(server.s) do
-            s:close()
-        end
-        server.s = {}
-        return true
+    if addr.family ~= 'AF_UNIX' then
+        return false
     end
 
-    for _, s in pairs(server.s) do
-        fiber.create(function(s)
-            fiber.name(sprintf("listen_fd=%d",s:fd()))
+    if boxerrno() ~= boxerrno.EADDRINUSE then
+        return false
+    end
 
-            while s:readable() do
-                
-                local sc = s:accept()
+    local save_errno = boxerrno()
 
-                if sc == nil then
-                    break
-                end
+    local sc = tcp_connect(addr.host, addr.port)
+    if sc ~= nil then
+        sc:close()
+        boxerrno(save_errno)
+        return false
+    end
 
-                fiber.create(function(sc)
-                    pcall(handler, sc)
-                    sc:close()
-                end, sc)
-            end
-        end, s)
+    if boxerrno() ~= boxerrno.ECONNREFUSED then
+        boxerrno(save_errno)
+        return false
     end
 
-    return server
+    log.info("tcp_server: remove dead UNIX socket: %s", addr.port)
+    if not fio.unlink(addr.port) then
+        log.warn("tcp_server: %s", boxerrno.strerror())
+        boxerrno(save_errno)
+        return false
+    end
+    return s:bind(addr.host, addr.port)
 end
 
-local function tcp_server(host, port, prepare, handler, timeout)
-    if handler == nil then
-        handler = prepare
-        prepare = function() end
-    end
 
-    if type(prepare) ~= 'function' or type(handler) ~= 'function' then
-        error("Usage: socket.tcp_server(host, port[, prepare], handler)")
+local function tcp_server(host, port, opts, timeout)
+    local server = {}
+    if type(opts) == 'function' then
+        server.handler = opts
+    elseif type(opts) == 'table' then
+        if type(opts.handler) ~='function' or (opts.prepare ~= nil and
+            type(opts.prepare) ~= 'function') then
+            tcp_server_usage()
+        end
+        for k, v in pairs(opts) do
+            server[k] = v
+        end
+    else
+        tcp_server_usage()
     end
-
+    server.name = server.name or 'server'
+    timeout = timeout and tonumber(timeout) or TIMEOUT_INFINITY
+    local dns
     if host == 'unix/' then
-        return tcp_server_remote({{host = host, port = port, protocol = 0,
-            family = 'PF_UNIX', type = 'SOCK_STREAM' }}, prepare, handler)
+        dns = {{host = host, port = port, family = 'AF_UNIX', protocol = 0,
+            type = 'SOCK_STREAM' }}
+    else
+        dns = getaddrinfo(host, port, timeout, { type = 'SOCK_STREAM' })
+        if dns == nil then
+            return nil
+        end
     end
 
-    local dns = getaddrinfo(host, port, timeout, { type = 'SOCK_STREAM',
-        protocol = 'tcp' })
-    if dns == nil then
-        return nil
+    for _, addr in ipairs(dns) do
+        local s = create_socket(addr.family, addr.type, addr.protocol)
+        if s ~= nil then
+            local backlog
+            if server.prepare then
+                backlog = server.prepare(s)
+            else
+                s:setsockopt('SOL_SOCKET', 'SO_REUSEADDR', 1) -- ignore error
+            end
+            if not tcp_server_bind(s, addr) or not s:listen(backlog) then
+                local save_errno = boxerrno()
+                s:close()
+                boxerrno(save_errno)
+                return nil
+            end
+            fiber.create(tcp_server_loop, server, s, addr)
+            return s, addr
+       end
     end
-    return tcp_server_remote(dns, prepare, handler)
+    -- DNS resolved successfully, but addresss family is not supported
+    boxerrno(boxerrno.EAFNOSUPPORT)
+    return nil
 end
 
 socket_mt   = {
diff --git a/src/lua/console.lua b/src/lua/console.lua
index 57d78d9f9093978fca5febda82ebba828ddd5405..7a591139111ecb596d5a780cc007e187bb32b9db 100644
--- a/src/lua/console.lua
+++ b/src/lua/console.lua
@@ -5,6 +5,7 @@ local fiber = require('fiber')
 local socket = require('socket')
 local log = require('log')
 local errno = require('errno')
+local urilib = require('uri')
 
 -- admin formatter must be able to encode any Lua variable
 local formatter = require('yaml').new()
@@ -69,6 +70,9 @@ end
 --
 local function remote_eval(self, line)
     if not line then
+        if type(self.on_client_disconnect) == 'function' then
+            self:on_client_disconnect()
+        end
         pcall(self.remote.close, self.remote)
         self.remote = nil
         self.eval = nil
@@ -150,7 +154,7 @@ local function client_print(self, output)
     elseif not output then
         -- disconnect peer
         local peer = self.client:peer()
-        log.info("console: client %s:%s disconnected", peer.host, peer.port)
+        log.info("client %s:%s disconnected", peer.host, peer.port)
         self.client:shutdown()
         self.client:close()
         self.client = nil
@@ -178,7 +182,12 @@ local repl_mt = {
 -- REPL = read-eval-print-loop
 --
 local function repl(self)
+    
     fiber.self().storage.console = self
+    if type(self.on_start) == 'function' then
+        self:on_start()
+    end
+
     while self.running do
         local command = self:read()
         local output = self:eval(command)
@@ -187,6 +196,22 @@ local function repl(self)
     fiber.self().storage.console = nil
 end
 
+local function on_start(foo)
+    if foo == nil or type(foo) == 'function' then
+        repl_mt.__index.on_start = foo 
+        return
+    end
+    error('Wrong type of on_start hook: ' .. type(foo))
+end
+
+local function on_client_disconnect(foo)
+    if foo == nil or type(foo) == 'function' then
+        repl_mt.__index.on_client_disconnect = foo 
+        return
+    end
+    error('Wrong type of on_client_disconnect hook: ' .. type(foo))
+end
+
 --
 -- Set delimiter
 --
@@ -221,13 +246,31 @@ end
 --
 -- Connect to remove server
 --
-local function connect(...)
+local function connect(uri)
     local self = fiber.self().storage.console
     if self == nil then
         error("console.connect() need existing console")
     end
+
+    local u
+    if uri then
+        u = urilib.parse(tostring(uri))
+    end
+    if u == nil or u.service == nil then
+        error('Usage: console.connect("[login:password@][host:]port")')
+    end
+
     -- connect to remote host
-    local remote = require('net.box'):new(...)
+    local remote = require('net.box'):new(u.host, u.service,
+        { user = u.login, password = u.password })
+
+    -- run disconnect trigger
+    if remote.state == 'closed' then
+        if type(self.on_client_disconnect) == 'function' then
+            self:on_client_disconnect()
+        end
+    end
+
     -- check permissions
     remote:call('dostring', 'return true')
     -- override methods
@@ -237,22 +280,19 @@ local function connect(...)
     log.info("connected to %s:%s", self.remote.host, self.remote.port)
 end
 
-local function server_loop(server)
-    while server:readable() do
-        local client = server:accept()
-        if client then
-            local peer = client:peer()
-            log.info("console: client %s:%s connected", peer.host, peer.port)
-            local state = setmetatable({
-                running = true;
-                read = client_read;
-                print = client_print;
-                client = client;
-            }, repl_mt)
-            fiber.create(repl, state)
-        end
-    end
-    log.info("console: stopped")
+local function client_handler(client, peer)
+    log.info("client %s:%s connected", peer.host, peer.port)
+    local state = setmetatable({
+        running = true;
+        read = client_read;
+        print = client_print;
+        client = client;
+    }, repl_mt)
+    state:print(string.format("%-63s\n%-63s\n",
+        "Tarantool ".. box.info.version.." (Lua console)",
+        "type 'help' for interactive help"))
+    repl(state)
+    log.info("client %s:%s disconnected", peer.host, peer.port)
 end
 
 --
@@ -262,46 +302,23 @@ local function listen(uri)
     local host, port
     if uri == nil then
         host = 'unix/'
-    elseif type(uri) == 'number' or uri:match("^%d+$") then
-        port = tonumber(uri)
-    elseif uri:match("^/") then
-        host = 'unix/'
-        port = uri
+        port = '/tmp/tarantool-console.sock'
     else
-        host, port = uri:match("^(.*):(.*)$")
-        if not host then
-            port = uri
+        local u = urilib.parse(tostring(uri))
+        if u == nil or u.service == nil then
+            error('Usage: console.listen("[host:]port")')
         end
+        host = u.host
+        port = u.service or 3313
     end
-    local server
-    if host == 'unix/' then
-        port = port or '/tmp/tarantool-console.sock'
-        os.remove(port)
-        server = socket('AF_UNIX', 'SOCK_STREAM', 0)
-    else
-        host = host or '127.0.0.1'
-        port = port or 3313
-        server = socket('AF_INET', 'SOCK_STREAM', 'tcp')
-    end
-    if not server then
-	error(string.format('failed to create socket %s%s : %s',
-			    host, port, errno.strerror()))
-    end
-    server:setsockopt('SOL_SOCKET', 'SO_REUSEADDR', true)
-
-    if not server:bind(host, port) then
-        local msg = string.format('failed to bind: %s', server:error())
-        server:close()
-        error(msg)
-    end
-    if not server:listen() then
-        local msg = string.format('failed to listen: %s', server:error())
-        server:close()
-        error(msg)
+    local s, addr = socket.tcp_server(host, port, { handler = client_handler,
+        name = 'console'})
+    if not s then
+        error(string.format('failed to create server %s:%s: %s',
+            host, port, errno.strerror()))
     end
-    log.info("console: started on %s:%s", host, port)
-    fiber.create(server_loop, server)
-    return server
+    log.info("started on %s:%s", addr.host, addr.port)
+    return s
 end
 
 return {
@@ -310,4 +327,6 @@ return {
     delimiter = delimiter;
     connect = connect;
     listen = listen;
+    on_start = on_start;
+    on_client_disconnect = on_client_disconnect;
 }
diff --git a/src/lua/digest.lua b/src/lua/digest.lua
index 41b28f30b69c3ea537d2596b396e8f351e90e647..3f5653be86145e88d8f376ed21873dc58ee1faef 100644
--- a/src/lua/digest.lua
+++ b/src/lua/digest.lua
@@ -25,6 +25,11 @@ ffi.cdef[[
     typedef uint32_t (*crc32_func)(uint32_t crc,
         const unsigned char *buf, unsigned int len);
     extern crc32_func crc32_calc;
+
+   /* base64 */
+   int base64_bufsize(int binsize);
+   int base64_decode(const char *in_base64, int in_len, char *out_bin, int out_len);
+   int base64_encode(const char *in_bin, int in_len, char *out_base64, int out_len);
 ]]
 
 local ssl
@@ -67,6 +72,28 @@ local function tohex(r, size)
 end
 
 local m = {
+    base64_encode = function(bin)
+        if type(bin) ~= 'string' then
+            error('Usage: digest.base64_encode(string)')
+        end
+        local blen = #bin
+        local slen = ffi.C.base64_bufsize(blen)
+        local str  = ffi.new('char[?]', slen)
+        local len = ffi.C.base64_encode(bin, blen, str, slen)
+        return ffi.string(str, len)
+    end,
+
+    base64_decode = function(str)
+        if type(str) ~= 'string' then
+            error('Usage: digest.base64_decode(string)')
+        end
+        local slen = #str
+        local blen = math.ceil(slen * 3 / 4)
+        local bin  = ffi.new('char[?]', blen)
+        local len = ffi.C.base64_decode(str, slen, bin, blen)
+        return ffi.string(bin, len)
+    end,
+
     crc32 = function(str)
         if str == nil then
             str = ''
diff --git a/src/lua/fiber.cc b/src/lua/fiber.cc
index f8eda08a993a28ee4a8b822994d2b09435c9cb31..6d9e42201880a301fa87d2b898787edc349ffdb9 100644
--- a/src/lua/fiber.cc
+++ b/src/lua/fiber.cc
@@ -220,9 +220,13 @@ lbox_fiber_statof(struct fiber *f, void *cb_ctx)
 {
 	struct lua_State *L = (struct lua_State *) cb_ctx;
 
-	lua_pushstring(L, fiber_name(f));
+	lua_pushinteger(L, f->fid);
 	lua_newtable(L);
 
+	lua_pushliteral(L, "name");
+	lua_pushstring(L, fiber_name(f));
+	lua_settable(L, -3);
+
 	lua_pushstring(L, "fid");
 	lua_pushnumber(L, f->fid);
 	lua_settable(L, -3);
diff --git a/src/lua/fio.lua b/src/lua/fio.lua
index 48687703bdfb83e2fc42e2debde74c4815949ab9..9f6b10d92fa7efefd86f443c2c1862829b144aa0 100644
--- a/src/lua/fio.lua
+++ b/src/lua/fio.lua
@@ -5,6 +5,7 @@ local ffi = require('ffi')
 
 ffi.cdef[[
     int umask(int mask);
+    char *dirname(char *path);
 ]]
 
 local internal = fio.internal
@@ -209,18 +210,8 @@ fio.dirname = function(path)
         return nil
     end
     path = tostring(path)
-
-    while true do
-        if path == "" or string.sub(path, -1) == "/" then
-            break
-        end
-        path = string.sub(path, 1, -2)
-    end
-    if path == "" then
-        path = "."
-    end
-
-    return path
+    path = ffi.new('char[?]', #path, path)
+    return ffi.string(ffi.C.dirname(path))
 end
 
 fio.umask = function(umask)
diff --git a/src/lua/init.cc b/src/lua/init.cc
index 633edffd93ad79407a13bb8e81109227cdc2d111..02fa51d7e6f357c9db52882451932aa0264b0a3b 100644
--- a/src/lua/init.cc
+++ b/src/lua/init.cc
@@ -73,6 +73,7 @@ extern char uuid_lua[],
 	digest_lua[],
 	init_lua[],
 	log_lua[],
+	uri_lua[],
 	bsdsocket_lua[],
 	console_lua[],
 	box_net_box_lua[],
@@ -92,11 +93,12 @@ static const char *lua_modules[] = {
 	"digest", digest_lua,
 	"uuid", uuid_lua,
 	"log", log_lua,
+	"uri", uri_lua,
+	"fio", fio_lua,
 	"socket", bsdsocket_lua,
 	"net.box", box_net_box_lua,
 	"console", console_lua,
 	"tap", tap_lua,
-	"fio", fio_lua,
 	"help.en_US", help_en_US_lua,
 	"help", help_lua,
 	NULL
@@ -291,9 +293,9 @@ tarantool_lua_init(const char *tarantool_bin, int argc, char **argv)
 	tarantool_lua_fiber_init(L);
 	tarantool_lua_ipc_init(L);
 	tarantool_lua_errno_init(L);
+	tarantool_lua_fio_init(L);
 	tarantool_lua_bsdsocket_init(L);
 	tarantool_lua_pickle_init(L);
-	tarantool_lua_fio_init(L);
 	luaopen_msgpack(L);
 	lua_pop(L, 1);
 	luaopen_yaml(L);
diff --git a/src/lua/uri.lua b/src/lua/uri.lua
new file mode 100644
index 0000000000000000000000000000000000000000..9f7bc7b0d9749e40be0f23a6e2a8f6af60792b58
--- /dev/null
+++ b/src/lua/uri.lua
@@ -0,0 +1,60 @@
+-- uri.lua (internal file)
+
+local ffi = require('ffi')
+
+ffi.cdef[[
+struct uri {
+    const char *scheme;
+    size_t scheme_len;
+    const char *login;
+    size_t login_len;
+    const char *password;
+    size_t password_len;
+    const char *host;
+    size_t host_len;
+    const char *service;
+    size_t service_len;
+    const char *path;
+    size_t path_len;
+    const char *query;
+    size_t query_len;
+    const char *fragment;
+    size_t fragment_len;
+    int host_hint;
+};
+
+int
+uri_parse(struct uri *uri, const char *str);
+]]
+
+local builtin = ffi.C;
+
+local uribuf = ffi.new('struct uri')
+
+local function parse(str)
+    if str == nil then
+        error("Usage: uri.parse(string)")
+    end
+    if builtin.uri_parse(uribuf, str) ~= 0 then
+        return nil
+    end
+    local result = {}
+    for _, k in ipairs({ 'scheme', 'login', 'password', 'host', 'service',
+        'path', 'query', 'fragment'}) do
+        if uribuf[k] ~= nil then
+            result[k] = ffi.string(uribuf[k], uribuf[k..'_len'])
+        end
+    end
+    if uribuf.host_hint == 1 then
+        result.ipv4 = result.host
+    elseif uribuf.host_hint == 2 then
+        result.ipv6 = result.host
+    elseif uribuf.host_hint == 3 then
+        result.unix = result.service
+    end
+    return result
+end
+
+return {
+    parse = parse;
+};
diff --git a/src/lua/utils.cc b/src/lua/utils.cc
index 7331bebc56ff7444be457a080d3e7ed422a8b37e..61f2786be6ec70ca79f08612844d5aad271f52b8 100644
--- a/src/lua/utils.cc
+++ b/src/lua/utils.cc
@@ -139,7 +139,7 @@ static struct {
 	int type;
 	int defvalue;
 } OPTIONS[] = {
-	OPTION(LUA_TBOOLEAN, encode_sparse_convert, 0),
+	OPTION(LUA_TBOOLEAN, encode_sparse_convert, 1),
 	OPTION(LUA_TNUMBER,  encode_sparse_ratio, 2),
 	OPTION(LUA_TNUMBER,  encode_sparse_safe, 10),
 	OPTION(LUA_TNUMBER,  encode_max_depth, 32),
diff --git a/src/sio.cc b/src/sio.cc
index 53d8469db0bd549a01e920b7837106cf87f9d419..3bafff5629503ea7d62c0d686af27bb1b08e5b7f 100644
--- a/src/sio.cc
+++ b/src/sio.cc
@@ -293,6 +293,33 @@ sio_writev(int fd, const struct iovec *iov, int iovcnt)
 	return n;
 }
 
+/** Blocking I/O writev */
+ssize_t
+sio_writev_all(int fd, struct iovec *iov, int iovcnt)
+{
+	ssize_t bytes_total = 0;
+	struct iovec *iovend = iov + iovcnt;
+	while(1) {
+		int cnt = iovend - iov;
+		if (cnt > IOV_MAX)
+			cnt = IOV_MAX;
+		ssize_t bytes_written = writev(fd, iov, cnt);
+		if (bytes_written < 0) {
+			if (errno == EINTR)
+				continue;
+			tnt_raise(SocketError, fd, "writev(%d)", cnt);
+		}
+		bytes_total += bytes_written;
+		while (bytes_written >= iov->iov_len)
+			bytes_written -= (iov++)->iov_len;
+		if (iov == iovend)
+			break;
+		iov->iov_base = (char *) iov->iov_base + bytes_written;
+		iov->iov_len -= bytes_written;
+	}
+	return bytes_total;
+}
+
 ssize_t
 sio_readn_ahead(int fd, void *buf, size_t count, size_t buf_size)
 {
@@ -443,26 +470,28 @@ sio_getpeername(int fd, struct sockaddr *addr, socklen_t *addrlen)
 const char *
 sio_strfaddr(struct sockaddr *addr, socklen_t addrlen)
 {
-	static __thread char name[SERVICE_NAME_MAXLEN];
+	static __thread char name[NI_MAXHOST + _POSIX_PATH_MAX + 2];
 	switch(addr->sa_family) {
 		case AF_UNIX:
 			if (addrlen >= sizeof(sockaddr_un)) {
-				snprintf(name, sizeof(name), "unix://%s",
+				snprintf(name, sizeof(name), "unix/:%s",
 					((struct sockaddr_un *)addr)->sun_path);
 			} else {
 				snprintf(name, sizeof(name),
-					"unix://%s", "");
+					 "unix/:(socket)");
 			}
 			break;
-		case AF_INET: {
-			struct sockaddr_in *in = (struct sockaddr_in *)addr;
-			snprintf(name, sizeof(name), "%s:%d",
-				 inet_ntoa(in->sin_addr), ntohs(in->sin_port));
-			break;
-		}
-		case AF_INET6: {
-			*name = 0;
-			inet_ntop(AF_INET6, addr, name, sizeof(name));
+		default: {
+			char host[NI_MAXHOST], serv[NI_MAXSERV];
+			if (getnameinfo(addr, addrlen, host, sizeof(host),
+					serv, sizeof(serv),
+					NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
+				snprintf(name, sizeof(name),
+					 addr->sa_family == AF_INET
+					 ? "%s:%s" : "[%s]:%s", host, serv);
+			} else {
+				snprintf(name, sizeof(name), "(host):(port)");
+			}
 			break;
 		}
 	}
diff --git a/src/sio.h b/src/sio.h
index bcd04a2ab1a1a235448736d485ec92b47087b0b4..d527c3802650a54283f883ddae758891936165c1 100644
--- a/src/sio.h
+++ b/src/sio.h
@@ -118,24 +118,8 @@ ssize_t
 sio_writen(int fd, const void *buf, size_t count);
 
 /* Only for blocked I/O */
-static inline ssize_t
-sio_writev_all(int fd, struct iovec *iov, int iovcnt)
-{
-	ssize_t bytes_total = 0;
-	struct iovec *iovend = iov + iovcnt;
-	while(1) {
-		ssize_t bytes_written = sio_writev(fd, iov, iovend - iov);
-		bytes_total += bytes_written;
-		while (bytes_written > 0 && bytes_written >= iov->iov_len)
-			bytes_written -= (iov++)->iov_len;
-		if (iov == iovend)
-			break;
-		iov->iov_base = (char *) iov->iov_base + bytes_written;
-		iov->iov_len -= bytes_written;
-	}
-
-	return bytes_total;
-}
+ssize_t
+sio_writev_all(int fd, struct iovec *iov, int iovcnt);
 
 /**
  * A wrapper over sendfile.
diff --git a/src/tarantool.cc b/src/tarantool.cc
index 92f360034d2fd6affd030ac8762a781422a13d12..c7c4830871c438ddc61351da2d4ce48f5b52749a 100644
--- a/src/tarantool.cc
+++ b/src/tarantool.cc
@@ -367,6 +367,8 @@ background()
 	if (setsid() == -1)
 		goto error;
 
+	/* reinit coeio after fork (because libeio required it) */
+	coeio_reinit();
 	/*
 	 * Prints to stdout on failure, so got to be done before
 	 * we close it.
diff --git a/src/uri.c b/src/uri.c
new file mode 100644
index 0000000000000000000000000000000000000000..8b66299c6d887b6e257cad23b964c8f19927916b
--- /dev/null
+++ b/src/uri.c
@@ -0,0 +1,6528 @@
+
+#line 1 "../../src/uri.rl"
+/*
+ * Redistribution and use in source and binary forms, with or
+ * without modification, 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 <COPYRIGHT HOLDER> ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, 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 OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include "uri.h"
+#include <string.h>
+#include <stdio.h> /* snprintf */
+int
+uri_parse(struct uri *uri, const char *p)
+{
+	const char *pe = p + strlen(p);
+	const char *eof = pe;
+	int cs;
+	memset(uri, 0, sizeof(*uri));
+
+	if (p == pe)
+		return -1;
+
+	const char *s = NULL, *login = NULL, *scheme = NULL;
+	size_t login_len = 0, scheme_len = 0;
+
+	
+#line 50 "../../src/uri.c"
+static const int uri_start = 144;
+static const int uri_first_final = 144;
+static const int uri_error = 0;
+
+static const int uri_en_main = 144;
+
+
+#line 58 "../../src/uri.c"
+	{
+	cs = uri_start;
+	}
+
+#line 63 "../../src/uri.c"
+	{
+	if ( p == pe )
+		goto _test_eof;
+	switch ( cs )
+	{
+case 144:
+	switch( (*p) ) {
+		case 33: goto tr150;
+		case 35: goto tr151;
+		case 37: goto tr152;
+		case 47: goto tr153;
+		case 59: goto tr150;
+		case 61: goto tr150;
+		case 63: goto tr155;
+		case 64: goto st204;
+		case 91: goto st38;
+		case 95: goto tr150;
+		case 117: goto tr158;
+		case 126: goto tr150;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto tr150;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto tr157;
+		} else if ( (*p) >= 65 )
+			goto tr157;
+	} else
+		goto tr154;
+	goto st0;
+st0:
+cs = 0;
+	goto _out;
+tr150:
+#line 137 "../../src/uri.rl"
+	{ s = p; }
+#line 92 "../../src/uri.rl"
+	{ s = p; }
+	goto st145;
+st145:
+	if ( ++p == pe )
+		goto _test_eof145;
+case 145:
+#line 109 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st145;
+		case 35: goto tr159;
+		case 37: goto st6;
+		case 47: goto tr161;
+		case 58: goto tr162;
+		case 61: goto st145;
+		case 63: goto tr163;
+		case 64: goto tr164;
+		case 95: goto st145;
+		case 126: goto st145;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st145;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st145;
+	} else
+		goto st145;
+	goto st0;
+tr151:
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+#line 185 "../../src/uri.rl"
+	{ s = p; }
+	goto st146;
+tr159:
+#line 93 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;}
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+#line 185 "../../src/uri.rl"
+	{ s = p; }
+	goto st146;
+tr170:
+#line 68 "../../src/uri.rl"
+	{ s = p; }
+#line 69 "../../src/uri.rl"
+	{ uri->query = s; uri->query_len = p - s; }
+#line 185 "../../src/uri.rl"
+	{ s = p; }
+	goto st146;
+tr172:
+#line 69 "../../src/uri.rl"
+	{ uri->query = s; uri->query_len = p - s; }
+#line 185 "../../src/uri.rl"
+	{ s = p; }
+	goto st146;
+tr175:
+#line 131 "../../src/uri.rl"
+	{ s = p; }
+#line 132 "../../src/uri.rl"
+	{ uri->service = s; uri->service_len = p - s; }
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+#line 185 "../../src/uri.rl"
+	{ s = p; }
+	goto st146;
+tr185:
+#line 132 "../../src/uri.rl"
+	{ uri->service = s; uri->service_len = p - s; }
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+#line 185 "../../src/uri.rl"
+	{ s = p; }
+	goto st146;
+tr200:
+#line 100 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;
+			   uri->host_hint = 1; }
+#line 93 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;}
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+#line 185 "../../src/uri.rl"
+	{ s = p; }
+	goto st146;
+tr209:
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+#line 185 "../../src/uri.rl"
+	{ s = p; }
+	goto st146;
+tr314:
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+#line 128 "../../src/uri.rl"
+	{ s = p;}
+#line 111 "../../src/uri.rl"
+	{
+			/*
+			 * This action is also called for path_* terminals.
+			 * I absolute have no idea why. Please don't blame
+			 * and fix grammar if you have a LOT of free time.
+			 */
+			if (uri->host_hint != 3) {
+				uri->host_hint = 3;
+				uri->host = URI_HOST_UNIX;
+				uri->host_len = strlen(URI_HOST_UNIX);
+				uri->service = s; uri->service_len = p - s;
+				/* a workaround for grammar limitations */
+				uri->path = NULL;
+				uri->path_len = 0;
+			};
+		}
+#line 185 "../../src/uri.rl"
+	{ s = p; }
+	goto st146;
+tr318:
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+#line 111 "../../src/uri.rl"
+	{
+			/*
+			 * This action is also called for path_* terminals.
+			 * I absolute have no idea why. Please don't blame
+			 * and fix grammar if you have a LOT of free time.
+			 */
+			if (uri->host_hint != 3) {
+				uri->host_hint = 3;
+				uri->host = URI_HOST_UNIX;
+				uri->host_len = strlen(URI_HOST_UNIX);
+				uri->service = s; uri->service_len = p - s;
+				/* a workaround for grammar limitations */
+				uri->path = NULL;
+				uri->path_len = 0;
+			};
+		}
+#line 185 "../../src/uri.rl"
+	{ s = p; }
+	goto st146;
+tr323:
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+#line 111 "../../src/uri.rl"
+	{
+			/*
+			 * This action is also called for path_* terminals.
+			 * I absolute have no idea why. Please don't blame
+			 * and fix grammar if you have a LOT of free time.
+			 */
+			if (uri->host_hint != 3) {
+				uri->host_hint = 3;
+				uri->host = URI_HOST_UNIX;
+				uri->host_len = strlen(URI_HOST_UNIX);
+				uri->service = s; uri->service_len = p - s;
+				/* a workaround for grammar limitations */
+				uri->path = NULL;
+				uri->path_len = 0;
+			};
+		}
+#line 185 "../../src/uri.rl"
+	{ s = p; }
+	goto st146;
+st146:
+	if ( ++p == pe )
+		goto _test_eof146;
+case 146:
+#line 281 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto tr165;
+		case 37: goto tr166;
+		case 61: goto tr165;
+		case 95: goto tr165;
+		case 126: goto tr165;
+	}
+	if ( (*p) < 63 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto tr165;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr165;
+	} else
+		goto tr165;
+	goto st0;
+tr165:
+#line 72 "../../src/uri.rl"
+	{ s = p; }
+	goto st147;
+st147:
+	if ( ++p == pe )
+		goto _test_eof147;
+case 147:
+#line 306 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st147;
+		case 37: goto st1;
+		case 61: goto st147;
+		case 95: goto st147;
+		case 126: goto st147;
+	}
+	if ( (*p) < 63 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st147;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st147;
+	} else
+		goto st147;
+	goto st0;
+tr166:
+#line 72 "../../src/uri.rl"
+	{ s = p; }
+	goto st1;
+st1:
+	if ( ++p == pe )
+		goto _test_eof1;
+case 1:
+#line 331 "../../src/uri.c"
+	switch( (*p) ) {
+		case 37: goto st147;
+		case 117: goto st2;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st147;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st147;
+	} else
+		goto st147;
+	goto st0;
+st2:
+	if ( ++p == pe )
+		goto _test_eof2;
+case 2:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st3;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st3;
+	} else
+		goto st3;
+	goto st0;
+st3:
+	if ( ++p == pe )
+		goto _test_eof3;
+case 3:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st4;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st4;
+	} else
+		goto st4;
+	goto st0;
+st4:
+	if ( ++p == pe )
+		goto _test_eof4;
+case 4:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st5;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st5;
+	} else
+		goto st5;
+	goto st0;
+st5:
+	if ( ++p == pe )
+		goto _test_eof5;
+case 5:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st147;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st147;
+	} else
+		goto st147;
+	goto st0;
+tr152:
+#line 137 "../../src/uri.rl"
+	{ s = p; }
+#line 92 "../../src/uri.rl"
+	{ s = p; }
+	goto st6;
+st6:
+	if ( ++p == pe )
+		goto _test_eof6;
+case 6:
+#line 407 "../../src/uri.c"
+	switch( (*p) ) {
+		case 37: goto st145;
+		case 117: goto st7;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st145;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st145;
+	} else
+		goto st145;
+	goto st0;
+st7:
+	if ( ++p == pe )
+		goto _test_eof7;
+case 7:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st8;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st8;
+	} else
+		goto st8;
+	goto st0;
+st8:
+	if ( ++p == pe )
+		goto _test_eof8;
+case 8:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st9;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st9;
+	} else
+		goto st9;
+	goto st0;
+st9:
+	if ( ++p == pe )
+		goto _test_eof9;
+case 9:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st10;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st10;
+	} else
+		goto st10;
+	goto st0;
+st10:
+	if ( ++p == pe )
+		goto _test_eof10;
+case 10:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st145;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st145;
+	} else
+		goto st145;
+	goto st0;
+tr161:
+#line 93 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;}
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+	goto st148;
+tr177:
+#line 131 "../../src/uri.rl"
+	{ s = p; }
+#line 132 "../../src/uri.rl"
+	{ uri->service = s; uri->service_len = p - s; }
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+	goto st148;
+tr186:
+#line 132 "../../src/uri.rl"
+	{ uri->service = s; uri->service_len = p - s; }
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+	goto st148;
+tr201:
+#line 100 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;
+			   uri->host_hint = 1; }
+#line 93 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;}
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+	goto st148;
+tr210:
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+	goto st148;
+st148:
+	if ( ++p == pe )
+		goto _test_eof148;
+case 148:
+#line 510 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st148;
+		case 35: goto tr151;
+		case 37: goto st11;
+		case 61: goto st148;
+		case 63: goto tr155;
+		case 95: goto st148;
+		case 126: goto st148;
+	}
+	if ( (*p) < 64 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st148;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st148;
+	} else
+		goto st148;
+	goto st0;
+st11:
+	if ( ++p == pe )
+		goto _test_eof11;
+case 11:
+	switch( (*p) ) {
+		case 37: goto st148;
+		case 117: goto st12;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st148;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st148;
+	} else
+		goto st148;
+	goto st0;
+st12:
+	if ( ++p == pe )
+		goto _test_eof12;
+case 12:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st13;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st13;
+	} else
+		goto st13;
+	goto st0;
+st13:
+	if ( ++p == pe )
+		goto _test_eof13;
+case 13:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st14;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st14;
+	} else
+		goto st14;
+	goto st0;
+st14:
+	if ( ++p == pe )
+		goto _test_eof14;
+case 14:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st15;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st15;
+	} else
+		goto st15;
+	goto st0;
+st15:
+	if ( ++p == pe )
+		goto _test_eof15;
+case 15:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st148;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st148;
+	} else
+		goto st148;
+	goto st0;
+tr155:
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+#line 185 "../../src/uri.rl"
+	{ s = p; }
+	goto st149;
+tr163:
+#line 93 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;}
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+#line 185 "../../src/uri.rl"
+	{ s = p; }
+	goto st149;
+tr179:
+#line 131 "../../src/uri.rl"
+	{ s = p; }
+#line 132 "../../src/uri.rl"
+	{ uri->service = s; uri->service_len = p - s; }
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+#line 185 "../../src/uri.rl"
+	{ s = p; }
+	goto st149;
+tr188:
+#line 132 "../../src/uri.rl"
+	{ uri->service = s; uri->service_len = p - s; }
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+#line 185 "../../src/uri.rl"
+	{ s = p; }
+	goto st149;
+tr204:
+#line 100 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;
+			   uri->host_hint = 1; }
+#line 93 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;}
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+#line 185 "../../src/uri.rl"
+	{ s = p; }
+	goto st149;
+tr212:
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+#line 185 "../../src/uri.rl"
+	{ s = p; }
+	goto st149;
+tr317:
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+#line 128 "../../src/uri.rl"
+	{ s = p;}
+#line 111 "../../src/uri.rl"
+	{
+			/*
+			 * This action is also called for path_* terminals.
+			 * I absolute have no idea why. Please don't blame
+			 * and fix grammar if you have a LOT of free time.
+			 */
+			if (uri->host_hint != 3) {
+				uri->host_hint = 3;
+				uri->host = URI_HOST_UNIX;
+				uri->host_len = strlen(URI_HOST_UNIX);
+				uri->service = s; uri->service_len = p - s;
+				/* a workaround for grammar limitations */
+				uri->path = NULL;
+				uri->path_len = 0;
+			};
+		}
+#line 185 "../../src/uri.rl"
+	{ s = p; }
+	goto st149;
+tr320:
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+#line 111 "../../src/uri.rl"
+	{
+			/*
+			 * This action is also called for path_* terminals.
+			 * I absolute have no idea why. Please don't blame
+			 * and fix grammar if you have a LOT of free time.
+			 */
+			if (uri->host_hint != 3) {
+				uri->host_hint = 3;
+				uri->host = URI_HOST_UNIX;
+				uri->host_len = strlen(URI_HOST_UNIX);
+				uri->service = s; uri->service_len = p - s;
+				/* a workaround for grammar limitations */
+				uri->path = NULL;
+				uri->path_len = 0;
+			};
+		}
+#line 185 "../../src/uri.rl"
+	{ s = p; }
+	goto st149;
+tr325:
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+#line 111 "../../src/uri.rl"
+	{
+			/*
+			 * This action is also called for path_* terminals.
+			 * I absolute have no idea why. Please don't blame
+			 * and fix grammar if you have a LOT of free time.
+			 */
+			if (uri->host_hint != 3) {
+				uri->host_hint = 3;
+				uri->host = URI_HOST_UNIX;
+				uri->host_len = strlen(URI_HOST_UNIX);
+				uri->service = s; uri->service_len = p - s;
+				/* a workaround for grammar limitations */
+				uri->path = NULL;
+				uri->path_len = 0;
+			};
+		}
+#line 185 "../../src/uri.rl"
+	{ s = p; }
+	goto st149;
+st149:
+	if ( ++p == pe )
+		goto _test_eof149;
+case 149:
+#line 734 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto tr169;
+		case 35: goto tr170;
+		case 37: goto tr171;
+		case 61: goto tr169;
+		case 95: goto tr169;
+		case 126: goto tr169;
+	}
+	if ( (*p) < 63 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto tr169;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr169;
+	} else
+		goto tr169;
+	goto st0;
+tr169:
+#line 68 "../../src/uri.rl"
+	{ s = p; }
+	goto st150;
+st150:
+	if ( ++p == pe )
+		goto _test_eof150;
+case 150:
+#line 760 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st150;
+		case 35: goto tr172;
+		case 37: goto st16;
+		case 61: goto st150;
+		case 95: goto st150;
+		case 126: goto st150;
+	}
+	if ( (*p) < 63 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st150;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st150;
+	} else
+		goto st150;
+	goto st0;
+tr171:
+#line 68 "../../src/uri.rl"
+	{ s = p; }
+	goto st16;
+st16:
+	if ( ++p == pe )
+		goto _test_eof16;
+case 16:
+#line 786 "../../src/uri.c"
+	switch( (*p) ) {
+		case 37: goto st150;
+		case 117: goto st17;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st150;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st150;
+	} else
+		goto st150;
+	goto st0;
+st17:
+	if ( ++p == pe )
+		goto _test_eof17;
+case 17:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st18;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st18;
+	} else
+		goto st18;
+	goto st0;
+st18:
+	if ( ++p == pe )
+		goto _test_eof18;
+case 18:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st19;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st19;
+	} else
+		goto st19;
+	goto st0;
+st19:
+	if ( ++p == pe )
+		goto _test_eof19;
+case 19:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st20;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st20;
+	} else
+		goto st20;
+	goto st0;
+st20:
+	if ( ++p == pe )
+		goto _test_eof20;
+case 20:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st150;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st150;
+	} else
+		goto st150;
+	goto st0;
+tr162:
+#line 138 "../../src/uri.rl"
+	{ login = s; login_len = p - s; }
+#line 93 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;}
+	goto st151;
+tr240:
+#line 138 "../../src/uri.rl"
+	{ login = s; login_len = p - s; }
+#line 100 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;
+			   uri->host_hint = 1; }
+#line 93 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;}
+	goto st151;
+st151:
+	if ( ++p == pe )
+		goto _test_eof151;
+case 151:
+#line 871 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto tr174;
+		case 35: goto tr175;
+		case 37: goto tr176;
+		case 47: goto tr177;
+		case 59: goto tr174;
+		case 61: goto tr174;
+		case 63: goto tr179;
+		case 95: goto tr174;
+		case 126: goto tr174;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto tr174;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto tr180;
+		} else if ( (*p) >= 65 )
+			goto tr180;
+	} else
+		goto tr178;
+	goto st0;
+tr174:
+#line 141 "../../src/uri.rl"
+	{ s = p; }
+	goto st21;
+st21:
+	if ( ++p == pe )
+		goto _test_eof21;
+case 21:
+#line 903 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st21;
+		case 37: goto st22;
+		case 59: goto st21;
+		case 61: goto st21;
+		case 64: goto tr23;
+		case 95: goto st21;
+		case 126: goto st21;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st21;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st21;
+		} else if ( (*p) >= 65 )
+			goto st21;
+	} else
+		goto st21;
+	goto st0;
+tr176:
+#line 141 "../../src/uri.rl"
+	{ s = p; }
+	goto st22;
+st22:
+	if ( ++p == pe )
+		goto _test_eof22;
+case 22:
+#line 933 "../../src/uri.c"
+	switch( (*p) ) {
+		case 37: goto st21;
+		case 117: goto st23;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st21;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st21;
+	} else
+		goto st21;
+	goto st0;
+st23:
+	if ( ++p == pe )
+		goto _test_eof23;
+case 23:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st24;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st24;
+	} else
+		goto st24;
+	goto st0;
+st24:
+	if ( ++p == pe )
+		goto _test_eof24;
+case 24:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st25;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st25;
+	} else
+		goto st25;
+	goto st0;
+st25:
+	if ( ++p == pe )
+		goto _test_eof25;
+case 25:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st26;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st26;
+	} else
+		goto st26;
+	goto st0;
+st26:
+	if ( ++p == pe )
+		goto _test_eof26;
+case 26:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st21;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st21;
+	} else
+		goto st21;
+	goto st0;
+tr23:
+#line 142 "../../src/uri.rl"
+	{ uri->password = s; uri->password_len = p - s; }
+#line 146 "../../src/uri.rl"
+	{ uri->login = login; uri->login_len = login_len; }
+	goto st27;
+tr164:
+#line 138 "../../src/uri.rl"
+	{ login = s; login_len = p - s; }
+#line 146 "../../src/uri.rl"
+	{ uri->login = login; uri->login_len = login_len; }
+	goto st27;
+st27:
+	if ( ++p == pe )
+		goto _test_eof27;
+case 27:
+#line 1015 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto tr28;
+		case 37: goto tr29;
+		case 47: goto tr30;
+		case 59: goto tr28;
+		case 61: goto tr28;
+		case 91: goto st38;
+		case 95: goto tr28;
+		case 117: goto tr33;
+		case 126: goto tr28;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto tr28;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto tr28;
+		} else if ( (*p) >= 65 )
+			goto tr28;
+	} else
+		goto tr31;
+	goto st0;
+tr28:
+#line 92 "../../src/uri.rl"
+	{ s = p; }
+	goto st152;
+st152:
+	if ( ++p == pe )
+		goto _test_eof152;
+case 152:
+#line 1047 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st152;
+		case 35: goto tr159;
+		case 37: goto st28;
+		case 47: goto tr161;
+		case 58: goto tr182;
+		case 61: goto st152;
+		case 63: goto tr163;
+		case 95: goto st152;
+		case 126: goto st152;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st152;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st152;
+	} else
+		goto st152;
+	goto st0;
+tr29:
+#line 92 "../../src/uri.rl"
+	{ s = p; }
+	goto st28;
+st28:
+	if ( ++p == pe )
+		goto _test_eof28;
+case 28:
+#line 1076 "../../src/uri.c"
+	switch( (*p) ) {
+		case 37: goto st152;
+		case 117: goto st29;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st152;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st152;
+	} else
+		goto st152;
+	goto st0;
+st29:
+	if ( ++p == pe )
+		goto _test_eof29;
+case 29:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st30;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st30;
+	} else
+		goto st30;
+	goto st0;
+st30:
+	if ( ++p == pe )
+		goto _test_eof30;
+case 30:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st31;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st31;
+	} else
+		goto st31;
+	goto st0;
+st31:
+	if ( ++p == pe )
+		goto _test_eof31;
+case 31:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st32;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st32;
+	} else
+		goto st32;
+	goto st0;
+st32:
+	if ( ++p == pe )
+		goto _test_eof32;
+case 32:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st152;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st152;
+	} else
+		goto st152;
+	goto st0;
+tr182:
+#line 93 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;}
+	goto st153;
+tr203:
+#line 100 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;
+			   uri->host_hint = 1; }
+#line 93 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;}
+	goto st153;
+st153:
+	if ( ++p == pe )
+		goto _test_eof153;
+case 153:
+#line 1157 "../../src/uri.c"
+	switch( (*p) ) {
+		case 35: goto tr175;
+		case 47: goto tr177;
+		case 63: goto tr179;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr183;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr184;
+	} else
+		goto tr184;
+	goto st0;
+tr183:
+#line 131 "../../src/uri.rl"
+	{ s = p; }
+	goto st154;
+st154:
+	if ( ++p == pe )
+		goto _test_eof154;
+case 154:
+#line 1180 "../../src/uri.c"
+	switch( (*p) ) {
+		case 35: goto tr185;
+		case 47: goto tr186;
+		case 63: goto tr188;
+	}
+	if ( 48 <= (*p) && (*p) <= 57 )
+		goto st154;
+	goto st0;
+tr184:
+#line 131 "../../src/uri.rl"
+	{ s = p; }
+	goto st155;
+st155:
+	if ( ++p == pe )
+		goto _test_eof155;
+case 155:
+#line 1197 "../../src/uri.c"
+	switch( (*p) ) {
+		case 35: goto tr185;
+		case 47: goto tr186;
+		case 63: goto tr188;
+	}
+	if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st155;
+	} else if ( (*p) >= 65 )
+		goto st155;
+	goto st0;
+tr30:
+#line 182 "../../src/uri.rl"
+	{ s = p; }
+	goto st156;
+st156:
+	if ( ++p == pe )
+		goto _test_eof156;
+case 156:
+#line 1217 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st157;
+		case 37: goto st33;
+		case 61: goto st157;
+		case 95: goto st157;
+		case 126: goto st157;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st157;
+	} else if ( (*p) > 59 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st157;
+		} else if ( (*p) >= 64 )
+			goto st157;
+	} else
+		goto st157;
+	goto st0;
+st157:
+	if ( ++p == pe )
+		goto _test_eof157;
+case 157:
+	switch( (*p) ) {
+		case 33: goto st157;
+		case 37: goto st33;
+		case 61: goto st157;
+		case 95: goto st157;
+		case 126: goto st157;
+	}
+	if ( (*p) < 64 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st157;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st157;
+	} else
+		goto st157;
+	goto st0;
+st33:
+	if ( ++p == pe )
+		goto _test_eof33;
+case 33:
+	switch( (*p) ) {
+		case 37: goto st157;
+		case 117: goto st34;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st157;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st157;
+	} else
+		goto st157;
+	goto st0;
+st34:
+	if ( ++p == pe )
+		goto _test_eof34;
+case 34:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st35;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st35;
+	} else
+		goto st35;
+	goto st0;
+st35:
+	if ( ++p == pe )
+		goto _test_eof35;
+case 35:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st36;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st36;
+	} else
+		goto st36;
+	goto st0;
+st36:
+	if ( ++p == pe )
+		goto _test_eof36;
+case 36:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st37;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st37;
+	} else
+		goto st37;
+	goto st0;
+st37:
+	if ( ++p == pe )
+		goto _test_eof37;
+case 37:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st157;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st157;
+	} else
+		goto st157;
+	goto st0;
+tr31:
+#line 99 "../../src/uri.rl"
+	{ s = p; }
+#line 92 "../../src/uri.rl"
+	{ s = p; }
+	goto st158;
+st158:
+	if ( ++p == pe )
+		goto _test_eof158;
+case 158:
+#line 1336 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st152;
+		case 35: goto tr159;
+		case 37: goto st28;
+		case 46: goto st159;
+		case 47: goto tr161;
+		case 58: goto tr182;
+		case 59: goto st152;
+		case 61: goto st152;
+		case 63: goto tr163;
+		case 95: goto st152;
+		case 126: goto st152;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st152;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st152;
+		} else if ( (*p) >= 65 )
+			goto st152;
+	} else
+		goto st171;
+	goto st0;
+st159:
+	if ( ++p == pe )
+		goto _test_eof159;
+case 159:
+	switch( (*p) ) {
+		case 33: goto st152;
+		case 35: goto tr159;
+		case 37: goto st28;
+		case 47: goto tr161;
+		case 58: goto tr182;
+		case 59: goto st152;
+		case 61: goto st152;
+		case 63: goto tr163;
+		case 95: goto st152;
+		case 126: goto st152;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st152;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st152;
+		} else if ( (*p) >= 65 )
+			goto st152;
+	} else
+		goto st160;
+	goto st0;
+st160:
+	if ( ++p == pe )
+		goto _test_eof160;
+case 160:
+	switch( (*p) ) {
+		case 33: goto st152;
+		case 35: goto tr159;
+		case 37: goto st28;
+		case 46: goto st161;
+		case 47: goto tr161;
+		case 58: goto tr182;
+		case 59: goto st152;
+		case 61: goto st152;
+		case 63: goto tr163;
+		case 95: goto st152;
+		case 126: goto st152;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st152;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st152;
+		} else if ( (*p) >= 65 )
+			goto st152;
+	} else
+		goto st169;
+	goto st0;
+st161:
+	if ( ++p == pe )
+		goto _test_eof161;
+case 161:
+	switch( (*p) ) {
+		case 33: goto st152;
+		case 35: goto tr159;
+		case 37: goto st28;
+		case 47: goto tr161;
+		case 58: goto tr182;
+		case 59: goto st152;
+		case 61: goto st152;
+		case 63: goto tr163;
+		case 95: goto st152;
+		case 126: goto st152;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st152;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st152;
+		} else if ( (*p) >= 65 )
+			goto st152;
+	} else
+		goto st162;
+	goto st0;
+st162:
+	if ( ++p == pe )
+		goto _test_eof162;
+case 162:
+	switch( (*p) ) {
+		case 33: goto st152;
+		case 35: goto tr159;
+		case 37: goto st28;
+		case 46: goto st163;
+		case 47: goto tr161;
+		case 58: goto tr182;
+		case 59: goto st152;
+		case 61: goto st152;
+		case 63: goto tr163;
+		case 95: goto st152;
+		case 126: goto st152;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st152;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st152;
+		} else if ( (*p) >= 65 )
+			goto st152;
+	} else
+		goto st167;
+	goto st0;
+st163:
+	if ( ++p == pe )
+		goto _test_eof163;
+case 163:
+	switch( (*p) ) {
+		case 33: goto st152;
+		case 35: goto tr159;
+		case 37: goto st28;
+		case 47: goto tr161;
+		case 58: goto tr182;
+		case 59: goto st152;
+		case 61: goto st152;
+		case 63: goto tr163;
+		case 95: goto st152;
+		case 126: goto st152;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st152;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st152;
+		} else if ( (*p) >= 65 )
+			goto st152;
+	} else
+		goto st164;
+	goto st0;
+st164:
+	if ( ++p == pe )
+		goto _test_eof164;
+case 164:
+	switch( (*p) ) {
+		case 33: goto st152;
+		case 35: goto tr200;
+		case 37: goto st28;
+		case 47: goto tr201;
+		case 58: goto tr203;
+		case 59: goto st152;
+		case 61: goto st152;
+		case 63: goto tr204;
+		case 95: goto st152;
+		case 126: goto st152;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st152;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st152;
+		} else if ( (*p) >= 65 )
+			goto st152;
+	} else
+		goto st165;
+	goto st0;
+st165:
+	if ( ++p == pe )
+		goto _test_eof165;
+case 165:
+	switch( (*p) ) {
+		case 33: goto st152;
+		case 35: goto tr200;
+		case 37: goto st28;
+		case 47: goto tr201;
+		case 58: goto tr203;
+		case 59: goto st152;
+		case 61: goto st152;
+		case 63: goto tr204;
+		case 95: goto st152;
+		case 126: goto st152;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st152;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st152;
+		} else if ( (*p) >= 65 )
+			goto st152;
+	} else
+		goto st166;
+	goto st0;
+st166:
+	if ( ++p == pe )
+		goto _test_eof166;
+case 166:
+	switch( (*p) ) {
+		case 33: goto st152;
+		case 35: goto tr200;
+		case 37: goto st28;
+		case 47: goto tr201;
+		case 58: goto tr203;
+		case 61: goto st152;
+		case 63: goto tr204;
+		case 95: goto st152;
+		case 126: goto st152;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st152;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st152;
+	} else
+		goto st152;
+	goto st0;
+st167:
+	if ( ++p == pe )
+		goto _test_eof167;
+case 167:
+	switch( (*p) ) {
+		case 33: goto st152;
+		case 35: goto tr159;
+		case 37: goto st28;
+		case 46: goto st163;
+		case 47: goto tr161;
+		case 58: goto tr182;
+		case 59: goto st152;
+		case 61: goto st152;
+		case 63: goto tr163;
+		case 95: goto st152;
+		case 126: goto st152;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st152;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st152;
+		} else if ( (*p) >= 65 )
+			goto st152;
+	} else
+		goto st168;
+	goto st0;
+st168:
+	if ( ++p == pe )
+		goto _test_eof168;
+case 168:
+	switch( (*p) ) {
+		case 33: goto st152;
+		case 35: goto tr159;
+		case 37: goto st28;
+		case 46: goto st163;
+		case 47: goto tr161;
+		case 58: goto tr182;
+		case 61: goto st152;
+		case 63: goto tr163;
+		case 95: goto st152;
+		case 126: goto st152;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st152;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st152;
+	} else
+		goto st152;
+	goto st0;
+st169:
+	if ( ++p == pe )
+		goto _test_eof169;
+case 169:
+	switch( (*p) ) {
+		case 33: goto st152;
+		case 35: goto tr159;
+		case 37: goto st28;
+		case 46: goto st161;
+		case 47: goto tr161;
+		case 58: goto tr182;
+		case 59: goto st152;
+		case 61: goto st152;
+		case 63: goto tr163;
+		case 95: goto st152;
+		case 126: goto st152;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st152;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st152;
+		} else if ( (*p) >= 65 )
+			goto st152;
+	} else
+		goto st170;
+	goto st0;
+st170:
+	if ( ++p == pe )
+		goto _test_eof170;
+case 170:
+	switch( (*p) ) {
+		case 33: goto st152;
+		case 35: goto tr159;
+		case 37: goto st28;
+		case 46: goto st161;
+		case 47: goto tr161;
+		case 58: goto tr182;
+		case 61: goto st152;
+		case 63: goto tr163;
+		case 95: goto st152;
+		case 126: goto st152;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st152;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st152;
+	} else
+		goto st152;
+	goto st0;
+st171:
+	if ( ++p == pe )
+		goto _test_eof171;
+case 171:
+	switch( (*p) ) {
+		case 33: goto st152;
+		case 35: goto tr159;
+		case 37: goto st28;
+		case 46: goto st159;
+		case 47: goto tr161;
+		case 58: goto tr182;
+		case 59: goto st152;
+		case 61: goto st152;
+		case 63: goto tr163;
+		case 95: goto st152;
+		case 126: goto st152;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st152;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st152;
+		} else if ( (*p) >= 65 )
+			goto st152;
+	} else
+		goto st172;
+	goto st0;
+st172:
+	if ( ++p == pe )
+		goto _test_eof172;
+case 172:
+	switch( (*p) ) {
+		case 33: goto st152;
+		case 35: goto tr159;
+		case 37: goto st28;
+		case 46: goto st159;
+		case 47: goto tr161;
+		case 58: goto tr182;
+		case 61: goto st152;
+		case 63: goto tr163;
+		case 95: goto st152;
+		case 126: goto st152;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st152;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st152;
+	} else
+		goto st152;
+	goto st0;
+st38:
+	if ( ++p == pe )
+		goto _test_eof38;
+case 38:
+	if ( (*p) == 58 )
+		goto tr45;
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto tr44;
+	} else if ( (*p) >= 48 )
+		goto tr44;
+	goto st0;
+tr44:
+#line 106 "../../src/uri.rl"
+	{ s = p; }
+	goto st39;
+st39:
+	if ( ++p == pe )
+		goto _test_eof39;
+case 39:
+#line 1766 "../../src/uri.c"
+	if ( (*p) == 58 )
+		goto st43;
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st40;
+	} else if ( (*p) >= 48 )
+		goto st40;
+	goto st0;
+st40:
+	if ( ++p == pe )
+		goto _test_eof40;
+case 40:
+	if ( (*p) == 58 )
+		goto st43;
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st41;
+	} else if ( (*p) >= 48 )
+		goto st41;
+	goto st0;
+st41:
+	if ( ++p == pe )
+		goto _test_eof41;
+case 41:
+	if ( (*p) == 58 )
+		goto st43;
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st42;
+	} else if ( (*p) >= 48 )
+		goto st42;
+	goto st0;
+st42:
+	if ( ++p == pe )
+		goto _test_eof42;
+case 42:
+	if ( (*p) == 58 )
+		goto st43;
+	goto st0;
+st43:
+	if ( ++p == pe )
+		goto _test_eof43;
+case 43:
+	switch( (*p) ) {
+		case 58: goto st48;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st44;
+	} else if ( (*p) >= 48 )
+		goto st44;
+	goto st0;
+st44:
+	if ( ++p == pe )
+		goto _test_eof44;
+case 44:
+	switch( (*p) ) {
+		case 58: goto st48;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st45;
+	} else if ( (*p) >= 48 )
+		goto st45;
+	goto st0;
+st45:
+	if ( ++p == pe )
+		goto _test_eof45;
+case 45:
+	switch( (*p) ) {
+		case 58: goto st48;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st46;
+	} else if ( (*p) >= 48 )
+		goto st46;
+	goto st0;
+st46:
+	if ( ++p == pe )
+		goto _test_eof46;
+case 46:
+	switch( (*p) ) {
+		case 58: goto st48;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st47;
+	} else if ( (*p) >= 48 )
+		goto st47;
+	goto st0;
+st47:
+	if ( ++p == pe )
+		goto _test_eof47;
+case 47:
+	switch( (*p) ) {
+		case 58: goto st48;
+		case 93: goto tr52;
+	}
+	goto st0;
+st48:
+	if ( ++p == pe )
+		goto _test_eof48;
+case 48:
+	switch( (*p) ) {
+		case 58: goto st53;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st49;
+	} else if ( (*p) >= 48 )
+		goto st49;
+	goto st0;
+st49:
+	if ( ++p == pe )
+		goto _test_eof49;
+case 49:
+	switch( (*p) ) {
+		case 58: goto st53;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st50;
+	} else if ( (*p) >= 48 )
+		goto st50;
+	goto st0;
+st50:
+	if ( ++p == pe )
+		goto _test_eof50;
+case 50:
+	switch( (*p) ) {
+		case 58: goto st53;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st51;
+	} else if ( (*p) >= 48 )
+		goto st51;
+	goto st0;
+st51:
+	if ( ++p == pe )
+		goto _test_eof51;
+case 51:
+	switch( (*p) ) {
+		case 58: goto st53;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st52;
+	} else if ( (*p) >= 48 )
+		goto st52;
+	goto st0;
+st52:
+	if ( ++p == pe )
+		goto _test_eof52;
+case 52:
+	switch( (*p) ) {
+		case 58: goto st53;
+		case 93: goto tr52;
+	}
+	goto st0;
+st53:
+	if ( ++p == pe )
+		goto _test_eof53;
+case 53:
+	switch( (*p) ) {
+		case 58: goto st58;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st54;
+	} else if ( (*p) >= 48 )
+		goto st54;
+	goto st0;
+st54:
+	if ( ++p == pe )
+		goto _test_eof54;
+case 54:
+	switch( (*p) ) {
+		case 58: goto st58;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st55;
+	} else if ( (*p) >= 48 )
+		goto st55;
+	goto st0;
+st55:
+	if ( ++p == pe )
+		goto _test_eof55;
+case 55:
+	switch( (*p) ) {
+		case 58: goto st58;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st56;
+	} else if ( (*p) >= 48 )
+		goto st56;
+	goto st0;
+st56:
+	if ( ++p == pe )
+		goto _test_eof56;
+case 56:
+	switch( (*p) ) {
+		case 58: goto st58;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st57;
+	} else if ( (*p) >= 48 )
+		goto st57;
+	goto st0;
+st57:
+	if ( ++p == pe )
+		goto _test_eof57;
+case 57:
+	switch( (*p) ) {
+		case 58: goto st58;
+		case 93: goto tr52;
+	}
+	goto st0;
+st58:
+	if ( ++p == pe )
+		goto _test_eof58;
+case 58:
+	switch( (*p) ) {
+		case 58: goto st63;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st59;
+	} else if ( (*p) >= 48 )
+		goto st59;
+	goto st0;
+st59:
+	if ( ++p == pe )
+		goto _test_eof59;
+case 59:
+	switch( (*p) ) {
+		case 58: goto st63;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st60;
+	} else if ( (*p) >= 48 )
+		goto st60;
+	goto st0;
+st60:
+	if ( ++p == pe )
+		goto _test_eof60;
+case 60:
+	switch( (*p) ) {
+		case 58: goto st63;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st61;
+	} else if ( (*p) >= 48 )
+		goto st61;
+	goto st0;
+st61:
+	if ( ++p == pe )
+		goto _test_eof61;
+case 61:
+	switch( (*p) ) {
+		case 58: goto st63;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st62;
+	} else if ( (*p) >= 48 )
+		goto st62;
+	goto st0;
+st62:
+	if ( ++p == pe )
+		goto _test_eof62;
+case 62:
+	switch( (*p) ) {
+		case 58: goto st63;
+		case 93: goto tr52;
+	}
+	goto st0;
+st63:
+	if ( ++p == pe )
+		goto _test_eof63;
+case 63:
+	switch( (*p) ) {
+		case 58: goto st68;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st64;
+	} else if ( (*p) >= 48 )
+		goto st64;
+	goto st0;
+st64:
+	if ( ++p == pe )
+		goto _test_eof64;
+case 64:
+	switch( (*p) ) {
+		case 58: goto st68;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st65;
+	} else if ( (*p) >= 48 )
+		goto st65;
+	goto st0;
+st65:
+	if ( ++p == pe )
+		goto _test_eof65;
+case 65:
+	switch( (*p) ) {
+		case 58: goto st68;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st66;
+	} else if ( (*p) >= 48 )
+		goto st66;
+	goto st0;
+st66:
+	if ( ++p == pe )
+		goto _test_eof66;
+case 66:
+	switch( (*p) ) {
+		case 58: goto st68;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st67;
+	} else if ( (*p) >= 48 )
+		goto st67;
+	goto st0;
+st67:
+	if ( ++p == pe )
+		goto _test_eof67;
+case 67:
+	switch( (*p) ) {
+		case 58: goto st68;
+		case 93: goto tr52;
+	}
+	goto st0;
+st68:
+	if ( ++p == pe )
+		goto _test_eof68;
+case 68:
+	switch( (*p) ) {
+		case 58: goto st73;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st69;
+	} else if ( (*p) >= 48 )
+		goto st69;
+	goto st0;
+st69:
+	if ( ++p == pe )
+		goto _test_eof69;
+case 69:
+	switch( (*p) ) {
+		case 58: goto st73;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st70;
+	} else if ( (*p) >= 48 )
+		goto st70;
+	goto st0;
+st70:
+	if ( ++p == pe )
+		goto _test_eof70;
+case 70:
+	switch( (*p) ) {
+		case 58: goto st73;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st71;
+	} else if ( (*p) >= 48 )
+		goto st71;
+	goto st0;
+st71:
+	if ( ++p == pe )
+		goto _test_eof71;
+case 71:
+	switch( (*p) ) {
+		case 58: goto st73;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st72;
+	} else if ( (*p) >= 48 )
+		goto st72;
+	goto st0;
+st72:
+	if ( ++p == pe )
+		goto _test_eof72;
+case 72:
+	switch( (*p) ) {
+		case 58: goto st73;
+		case 93: goto tr52;
+	}
+	goto st0;
+st73:
+	if ( ++p == pe )
+		goto _test_eof73;
+case 73:
+	switch( (*p) ) {
+		case 58: goto st78;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st74;
+	} else if ( (*p) >= 48 )
+		goto st74;
+	goto st0;
+st74:
+	if ( ++p == pe )
+		goto _test_eof74;
+case 74:
+	switch( (*p) ) {
+		case 58: goto st78;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st75;
+	} else if ( (*p) >= 48 )
+		goto st75;
+	goto st0;
+st75:
+	if ( ++p == pe )
+		goto _test_eof75;
+case 75:
+	switch( (*p) ) {
+		case 58: goto st78;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st76;
+	} else if ( (*p) >= 48 )
+		goto st76;
+	goto st0;
+st76:
+	if ( ++p == pe )
+		goto _test_eof76;
+case 76:
+	switch( (*p) ) {
+		case 58: goto st78;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st77;
+	} else if ( (*p) >= 48 )
+		goto st77;
+	goto st0;
+st77:
+	if ( ++p == pe )
+		goto _test_eof77;
+case 77:
+	switch( (*p) ) {
+		case 58: goto st78;
+		case 93: goto tr52;
+	}
+	goto st0;
+st78:
+	if ( ++p == pe )
+		goto _test_eof78;
+case 78:
+	if ( (*p) == 93 )
+		goto tr52;
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st79;
+	} else if ( (*p) >= 48 )
+		goto st79;
+	goto st0;
+st79:
+	if ( ++p == pe )
+		goto _test_eof79;
+case 79:
+	if ( (*p) == 93 )
+		goto tr52;
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st80;
+	} else if ( (*p) >= 48 )
+		goto st80;
+	goto st0;
+st80:
+	if ( ++p == pe )
+		goto _test_eof80;
+case 80:
+	if ( (*p) == 93 )
+		goto tr52;
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st81;
+	} else if ( (*p) >= 48 )
+		goto st81;
+	goto st0;
+st81:
+	if ( ++p == pe )
+		goto _test_eof81;
+case 81:
+	if ( (*p) == 93 )
+		goto tr52;
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st82;
+	} else if ( (*p) >= 48 )
+		goto st82;
+	goto st0;
+st82:
+	if ( ++p == pe )
+		goto _test_eof82;
+case 82:
+	if ( (*p) == 93 )
+		goto tr52;
+	goto st0;
+tr52:
+#line 107 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;
+				   uri->host_hint = 2; }
+	goto st173;
+st173:
+	if ( ++p == pe )
+		goto _test_eof173;
+case 173:
+#line 2325 "../../src/uri.c"
+	switch( (*p) ) {
+		case 35: goto tr209;
+		case 47: goto tr210;
+		case 58: goto st153;
+		case 63: goto tr212;
+	}
+	goto st0;
+tr45:
+#line 106 "../../src/uri.rl"
+	{ s = p; }
+	goto st83;
+st83:
+	if ( ++p == pe )
+		goto _test_eof83;
+case 83:
+#line 2341 "../../src/uri.c"
+	switch( (*p) ) {
+		case 58: goto st84;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st44;
+	} else if ( (*p) >= 48 )
+		goto st44;
+	goto st0;
+st84:
+	if ( ++p == pe )
+		goto _test_eof84;
+case 84:
+	switch( (*p) ) {
+		case 58: goto st53;
+		case 93: goto tr52;
+		case 102: goto st85;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 101 )
+			goto st49;
+	} else if ( (*p) >= 48 )
+		goto st49;
+	goto st0;
+st85:
+	if ( ++p == pe )
+		goto _test_eof85;
+case 85:
+	switch( (*p) ) {
+		case 58: goto st53;
+		case 93: goto tr52;
+		case 102: goto st86;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 101 )
+			goto st50;
+	} else if ( (*p) >= 48 )
+		goto st50;
+	goto st0;
+st86:
+	if ( ++p == pe )
+		goto _test_eof86;
+case 86:
+	switch( (*p) ) {
+		case 58: goto st53;
+		case 93: goto tr52;
+		case 102: goto st87;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 101 )
+			goto st51;
+	} else if ( (*p) >= 48 )
+		goto st51;
+	goto st0;
+st87:
+	if ( ++p == pe )
+		goto _test_eof87;
+case 87:
+	switch( (*p) ) {
+		case 58: goto st53;
+		case 93: goto tr52;
+		case 102: goto st88;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 101 )
+			goto st52;
+	} else if ( (*p) >= 48 )
+		goto st52;
+	goto st0;
+st88:
+	if ( ++p == pe )
+		goto _test_eof88;
+case 88:
+	switch( (*p) ) {
+		case 58: goto st89;
+		case 93: goto tr52;
+	}
+	goto st0;
+st89:
+	if ( ++p == pe )
+		goto _test_eof89;
+case 89:
+	switch( (*p) ) {
+		case 58: goto st58;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st54;
+	} else if ( (*p) >= 48 )
+		goto st90;
+	goto st0;
+st90:
+	if ( ++p == pe )
+		goto _test_eof90;
+case 90:
+	switch( (*p) ) {
+		case 46: goto st91;
+		case 58: goto st58;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st55;
+	} else if ( (*p) >= 48 )
+		goto st102;
+	goto st0;
+st91:
+	if ( ++p == pe )
+		goto _test_eof91;
+case 91:
+	if ( 48 <= (*p) && (*p) <= 57 )
+		goto st92;
+	goto st0;
+st92:
+	if ( ++p == pe )
+		goto _test_eof92;
+case 92:
+	if ( (*p) == 46 )
+		goto st93;
+	if ( 48 <= (*p) && (*p) <= 57 )
+		goto st100;
+	goto st0;
+st93:
+	if ( ++p == pe )
+		goto _test_eof93;
+case 93:
+	if ( 48 <= (*p) && (*p) <= 57 )
+		goto st94;
+	goto st0;
+st94:
+	if ( ++p == pe )
+		goto _test_eof94;
+case 94:
+	if ( (*p) == 46 )
+		goto st95;
+	if ( 48 <= (*p) && (*p) <= 57 )
+		goto st98;
+	goto st0;
+st95:
+	if ( ++p == pe )
+		goto _test_eof95;
+case 95:
+	if ( 48 <= (*p) && (*p) <= 57 )
+		goto st96;
+	goto st0;
+st96:
+	if ( ++p == pe )
+		goto _test_eof96;
+case 96:
+	if ( (*p) == 93 )
+		goto tr52;
+	if ( 48 <= (*p) && (*p) <= 57 )
+		goto st97;
+	goto st0;
+st97:
+	if ( ++p == pe )
+		goto _test_eof97;
+case 97:
+	if ( (*p) == 93 )
+		goto tr52;
+	if ( 48 <= (*p) && (*p) <= 57 )
+		goto st82;
+	goto st0;
+st98:
+	if ( ++p == pe )
+		goto _test_eof98;
+case 98:
+	if ( (*p) == 46 )
+		goto st95;
+	if ( 48 <= (*p) && (*p) <= 57 )
+		goto st99;
+	goto st0;
+st99:
+	if ( ++p == pe )
+		goto _test_eof99;
+case 99:
+	if ( (*p) == 46 )
+		goto st95;
+	goto st0;
+st100:
+	if ( ++p == pe )
+		goto _test_eof100;
+case 100:
+	if ( (*p) == 46 )
+		goto st93;
+	if ( 48 <= (*p) && (*p) <= 57 )
+		goto st101;
+	goto st0;
+st101:
+	if ( ++p == pe )
+		goto _test_eof101;
+case 101:
+	if ( (*p) == 46 )
+		goto st93;
+	goto st0;
+st102:
+	if ( ++p == pe )
+		goto _test_eof102;
+case 102:
+	switch( (*p) ) {
+		case 46: goto st91;
+		case 58: goto st58;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st56;
+	} else if ( (*p) >= 48 )
+		goto st103;
+	goto st0;
+st103:
+	if ( ++p == pe )
+		goto _test_eof103;
+case 103:
+	switch( (*p) ) {
+		case 46: goto st91;
+		case 58: goto st58;
+		case 93: goto tr52;
+	}
+	if ( (*p) > 57 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st57;
+	} else if ( (*p) >= 48 )
+		goto st57;
+	goto st0;
+tr33:
+#line 92 "../../src/uri.rl"
+	{ s = p; }
+	goto st174;
+st174:
+	if ( ++p == pe )
+		goto _test_eof174;
+case 174:
+#line 2577 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st152;
+		case 35: goto tr159;
+		case 37: goto st28;
+		case 47: goto tr161;
+		case 58: goto tr182;
+		case 61: goto st152;
+		case 63: goto tr163;
+		case 95: goto st152;
+		case 110: goto st175;
+		case 126: goto st152;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st152;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st152;
+	} else
+		goto st152;
+	goto st0;
+st175:
+	if ( ++p == pe )
+		goto _test_eof175;
+case 175:
+	switch( (*p) ) {
+		case 33: goto st152;
+		case 35: goto tr159;
+		case 37: goto st28;
+		case 47: goto tr161;
+		case 58: goto tr182;
+		case 61: goto st152;
+		case 63: goto tr163;
+		case 95: goto st152;
+		case 105: goto st176;
+		case 126: goto st152;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st152;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st152;
+	} else
+		goto st152;
+	goto st0;
+st176:
+	if ( ++p == pe )
+		goto _test_eof176;
+case 176:
+	switch( (*p) ) {
+		case 33: goto st152;
+		case 35: goto tr159;
+		case 37: goto st28;
+		case 47: goto tr161;
+		case 58: goto tr182;
+		case 61: goto st152;
+		case 63: goto tr163;
+		case 95: goto st152;
+		case 120: goto st177;
+		case 126: goto st152;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st152;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st152;
+	} else
+		goto st152;
+	goto st0;
+st177:
+	if ( ++p == pe )
+		goto _test_eof177;
+case 177:
+	switch( (*p) ) {
+		case 33: goto st152;
+		case 35: goto tr159;
+		case 37: goto st28;
+		case 47: goto tr216;
+		case 58: goto tr182;
+		case 61: goto st152;
+		case 63: goto tr163;
+		case 95: goto st152;
+		case 126: goto st152;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st152;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st152;
+	} else
+		goto st152;
+	goto st0;
+tr216:
+#line 93 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;}
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+	goto st178;
+st178:
+	if ( ++p == pe )
+		goto _test_eof178;
+case 178:
+#line 2683 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st148;
+		case 35: goto tr151;
+		case 37: goto st11;
+		case 58: goto st179;
+		case 61: goto st148;
+		case 63: goto tr155;
+		case 95: goto st148;
+		case 126: goto st148;
+	}
+	if ( (*p) < 64 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st148;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st148;
+	} else
+		goto st148;
+	goto st0;
+st179:
+	if ( ++p == pe )
+		goto _test_eof179;
+case 179:
+	switch( (*p) ) {
+		case 33: goto tr218;
+		case 35: goto tr151;
+		case 37: goto tr219;
+		case 47: goto tr220;
+		case 58: goto tr221;
+		case 61: goto tr218;
+		case 63: goto tr155;
+		case 95: goto tr218;
+		case 126: goto tr218;
+	}
+	if ( (*p) < 64 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto tr218;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr218;
+	} else
+		goto tr218;
+	goto st0;
+tr218:
+#line 128 "../../src/uri.rl"
+	{ s = p;}
+	goto st180;
+st180:
+	if ( ++p == pe )
+		goto _test_eof180;
+case 180:
+#line 2735 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st180;
+		case 35: goto tr151;
+		case 37: goto st104;
+		case 47: goto st181;
+		case 58: goto tr223;
+		case 61: goto st180;
+		case 63: goto tr155;
+		case 95: goto st180;
+		case 126: goto st180;
+	}
+	if ( (*p) < 64 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st180;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st180;
+	} else
+		goto st180;
+	goto st0;
+tr219:
+#line 128 "../../src/uri.rl"
+	{ s = p;}
+	goto st104;
+st104:
+	if ( ++p == pe )
+		goto _test_eof104;
+case 104:
+#line 2764 "../../src/uri.c"
+	switch( (*p) ) {
+		case 37: goto st180;
+		case 117: goto st105;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st180;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st180;
+	} else
+		goto st180;
+	goto st0;
+st105:
+	if ( ++p == pe )
+		goto _test_eof105;
+case 105:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st106;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st106;
+	} else
+		goto st106;
+	goto st0;
+st106:
+	if ( ++p == pe )
+		goto _test_eof106;
+case 106:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st107;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st107;
+	} else
+		goto st107;
+	goto st0;
+st107:
+	if ( ++p == pe )
+		goto _test_eof107;
+case 107:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st108;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st108;
+	} else
+		goto st108;
+	goto st0;
+st108:
+	if ( ++p == pe )
+		goto _test_eof108;
+case 108:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st180;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st180;
+	} else
+		goto st180;
+	goto st0;
+tr226:
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+	goto st181;
+tr220:
+#line 128 "../../src/uri.rl"
+	{ s = p;}
+	goto st181;
+st181:
+	if ( ++p == pe )
+		goto _test_eof181;
+case 181:
+#line 2842 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st181;
+		case 35: goto tr151;
+		case 37: goto st109;
+		case 58: goto tr225;
+		case 61: goto st181;
+		case 63: goto tr155;
+		case 95: goto st181;
+		case 126: goto st181;
+	}
+	if ( (*p) < 64 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st181;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st181;
+	} else
+		goto st181;
+	goto st0;
+st109:
+	if ( ++p == pe )
+		goto _test_eof109;
+case 109:
+	switch( (*p) ) {
+		case 37: goto st181;
+		case 117: goto st110;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st181;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st181;
+	} else
+		goto st181;
+	goto st0;
+st110:
+	if ( ++p == pe )
+		goto _test_eof110;
+case 110:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st111;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st111;
+	} else
+		goto st111;
+	goto st0;
+st111:
+	if ( ++p == pe )
+		goto _test_eof111;
+case 111:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st112;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st112;
+	} else
+		goto st112;
+	goto st0;
+st112:
+	if ( ++p == pe )
+		goto _test_eof112;
+case 112:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st113;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st113;
+	} else
+		goto st113;
+	goto st0;
+st113:
+	if ( ++p == pe )
+		goto _test_eof113;
+case 113:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st181;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st181;
+	} else
+		goto st181;
+	goto st0;
+tr225:
+#line 111 "../../src/uri.rl"
+	{
+			/*
+			 * This action is also called for path_* terminals.
+			 * I absolute have no idea why. Please don't blame
+			 * and fix grammar if you have a LOT of free time.
+			 */
+			if (uri->host_hint != 3) {
+				uri->host_hint = 3;
+				uri->host = URI_HOST_UNIX;
+				uri->host_len = strlen(URI_HOST_UNIX);
+				uri->service = s; uri->service_len = p - s;
+				/* a workaround for grammar limitations */
+				uri->path = NULL;
+				uri->path_len = 0;
+			};
+		}
+	goto st182;
+st182:
+	if ( ++p == pe )
+		goto _test_eof182;
+case 182:
+#line 2954 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st181;
+		case 35: goto tr209;
+		case 37: goto st109;
+		case 47: goto tr226;
+		case 58: goto tr225;
+		case 61: goto st181;
+		case 63: goto tr212;
+		case 95: goto st181;
+		case 126: goto st181;
+	}
+	if ( (*p) < 64 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st181;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st181;
+	} else
+		goto st181;
+	goto st0;
+tr223:
+#line 111 "../../src/uri.rl"
+	{
+			/*
+			 * This action is also called for path_* terminals.
+			 * I absolute have no idea why. Please don't blame
+			 * and fix grammar if you have a LOT of free time.
+			 */
+			if (uri->host_hint != 3) {
+				uri->host_hint = 3;
+				uri->host = URI_HOST_UNIX;
+				uri->host_len = strlen(URI_HOST_UNIX);
+				uri->service = s; uri->service_len = p - s;
+				/* a workaround for grammar limitations */
+				uri->path = NULL;
+				uri->path_len = 0;
+			};
+		}
+	goto st183;
+tr221:
+#line 128 "../../src/uri.rl"
+	{ s = p;}
+#line 111 "../../src/uri.rl"
+	{
+			/*
+			 * This action is also called for path_* terminals.
+			 * I absolute have no idea why. Please don't blame
+			 * and fix grammar if you have a LOT of free time.
+			 */
+			if (uri->host_hint != 3) {
+				uri->host_hint = 3;
+				uri->host = URI_HOST_UNIX;
+				uri->host_len = strlen(URI_HOST_UNIX);
+				uri->service = s; uri->service_len = p - s;
+				/* a workaround for grammar limitations */
+				uri->path = NULL;
+				uri->path_len = 0;
+			};
+		}
+	goto st183;
+st183:
+	if ( ++p == pe )
+		goto _test_eof183;
+case 183:
+#line 3019 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st148;
+		case 35: goto tr209;
+		case 37: goto st11;
+		case 47: goto tr210;
+		case 61: goto st148;
+		case 63: goto tr212;
+		case 95: goto st148;
+		case 126: goto st148;
+	}
+	if ( (*p) < 64 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st148;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st148;
+	} else
+		goto st148;
+	goto st0;
+tr178:
+#line 141 "../../src/uri.rl"
+	{ s = p; }
+#line 131 "../../src/uri.rl"
+	{ s = p; }
+	goto st184;
+st184:
+	if ( ++p == pe )
+		goto _test_eof184;
+case 184:
+#line 3049 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st21;
+		case 35: goto tr185;
+		case 37: goto st22;
+		case 47: goto tr186;
+		case 59: goto st21;
+		case 61: goto st21;
+		case 63: goto tr188;
+		case 64: goto tr23;
+		case 95: goto st21;
+		case 126: goto st21;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st21;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st21;
+		} else if ( (*p) >= 65 )
+			goto st21;
+	} else
+		goto st184;
+	goto st0;
+tr180:
+#line 141 "../../src/uri.rl"
+	{ s = p; }
+#line 131 "../../src/uri.rl"
+	{ s = p; }
+	goto st185;
+st185:
+	if ( ++p == pe )
+		goto _test_eof185;
+case 185:
+#line 3084 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st21;
+		case 35: goto tr185;
+		case 37: goto st22;
+		case 47: goto tr186;
+		case 59: goto st21;
+		case 61: goto st21;
+		case 63: goto tr188;
+		case 64: goto tr23;
+		case 95: goto st21;
+		case 126: goto st21;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 57 )
+			goto st21;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st185;
+	} else
+		goto st185;
+	goto st0;
+tr153:
+#line 182 "../../src/uri.rl"
+	{ s = p; }
+	goto st186;
+st186:
+	if ( ++p == pe )
+		goto _test_eof186;
+case 186:
+#line 3114 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st187;
+		case 35: goto tr151;
+		case 37: goto st114;
+		case 61: goto st187;
+		case 63: goto tr155;
+		case 95: goto st187;
+		case 126: goto st187;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st187;
+	} else if ( (*p) > 59 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st187;
+		} else if ( (*p) >= 64 )
+			goto st187;
+	} else
+		goto st187;
+	goto st0;
+st187:
+	if ( ++p == pe )
+		goto _test_eof187;
+case 187:
+	switch( (*p) ) {
+		case 33: goto st187;
+		case 35: goto tr151;
+		case 37: goto st114;
+		case 61: goto st187;
+		case 63: goto tr155;
+		case 95: goto st187;
+		case 126: goto st187;
+	}
+	if ( (*p) < 64 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st187;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st187;
+	} else
+		goto st187;
+	goto st0;
+st114:
+	if ( ++p == pe )
+		goto _test_eof114;
+case 114:
+	switch( (*p) ) {
+		case 37: goto st187;
+		case 117: goto st115;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st187;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st187;
+	} else
+		goto st187;
+	goto st0;
+st115:
+	if ( ++p == pe )
+		goto _test_eof115;
+case 115:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st116;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st116;
+	} else
+		goto st116;
+	goto st0;
+st116:
+	if ( ++p == pe )
+		goto _test_eof116;
+case 116:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st117;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st117;
+	} else
+		goto st117;
+	goto st0;
+st117:
+	if ( ++p == pe )
+		goto _test_eof117;
+case 117:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st118;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st118;
+	} else
+		goto st118;
+	goto st0;
+st118:
+	if ( ++p == pe )
+		goto _test_eof118;
+case 118:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st187;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st187;
+	} else
+		goto st187;
+	goto st0;
+tr154:
+#line 137 "../../src/uri.rl"
+	{ s = p; }
+#line 99 "../../src/uri.rl"
+	{ s = p; }
+#line 92 "../../src/uri.rl"
+	{ s = p; }
+#line 178 "../../src/uri.rl"
+	{ uri->service = p; }
+	goto st188;
+st188:
+	if ( ++p == pe )
+		goto _test_eof188;
+case 188:
+#line 3241 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st145;
+		case 35: goto tr159;
+		case 37: goto st6;
+		case 46: goto st189;
+		case 47: goto tr161;
+		case 58: goto tr162;
+		case 59: goto st145;
+		case 61: goto st145;
+		case 63: goto tr163;
+		case 64: goto tr164;
+		case 95: goto st145;
+		case 126: goto st145;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st145;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st145;
+		} else if ( (*p) >= 65 )
+			goto st145;
+	} else
+		goto st201;
+	goto st0;
+st189:
+	if ( ++p == pe )
+		goto _test_eof189;
+case 189:
+	switch( (*p) ) {
+		case 33: goto st145;
+		case 35: goto tr159;
+		case 37: goto st6;
+		case 47: goto tr161;
+		case 58: goto tr162;
+		case 59: goto st145;
+		case 61: goto st145;
+		case 63: goto tr163;
+		case 64: goto tr164;
+		case 95: goto st145;
+		case 126: goto st145;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st145;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st145;
+		} else if ( (*p) >= 65 )
+			goto st145;
+	} else
+		goto st190;
+	goto st0;
+st190:
+	if ( ++p == pe )
+		goto _test_eof190;
+case 190:
+	switch( (*p) ) {
+		case 33: goto st145;
+		case 35: goto tr159;
+		case 37: goto st6;
+		case 46: goto st191;
+		case 47: goto tr161;
+		case 58: goto tr162;
+		case 59: goto st145;
+		case 61: goto st145;
+		case 63: goto tr163;
+		case 64: goto tr164;
+		case 95: goto st145;
+		case 126: goto st145;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st145;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st145;
+		} else if ( (*p) >= 65 )
+			goto st145;
+	} else
+		goto st199;
+	goto st0;
+st191:
+	if ( ++p == pe )
+		goto _test_eof191;
+case 191:
+	switch( (*p) ) {
+		case 33: goto st145;
+		case 35: goto tr159;
+		case 37: goto st6;
+		case 47: goto tr161;
+		case 58: goto tr162;
+		case 59: goto st145;
+		case 61: goto st145;
+		case 63: goto tr163;
+		case 64: goto tr164;
+		case 95: goto st145;
+		case 126: goto st145;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st145;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st145;
+		} else if ( (*p) >= 65 )
+			goto st145;
+	} else
+		goto st192;
+	goto st0;
+st192:
+	if ( ++p == pe )
+		goto _test_eof192;
+case 192:
+	switch( (*p) ) {
+		case 33: goto st145;
+		case 35: goto tr159;
+		case 37: goto st6;
+		case 46: goto st193;
+		case 47: goto tr161;
+		case 58: goto tr162;
+		case 59: goto st145;
+		case 61: goto st145;
+		case 63: goto tr163;
+		case 64: goto tr164;
+		case 95: goto st145;
+		case 126: goto st145;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st145;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st145;
+		} else if ( (*p) >= 65 )
+			goto st145;
+	} else
+		goto st197;
+	goto st0;
+st193:
+	if ( ++p == pe )
+		goto _test_eof193;
+case 193:
+	switch( (*p) ) {
+		case 33: goto st145;
+		case 35: goto tr159;
+		case 37: goto st6;
+		case 47: goto tr161;
+		case 58: goto tr162;
+		case 59: goto st145;
+		case 61: goto st145;
+		case 63: goto tr163;
+		case 64: goto tr164;
+		case 95: goto st145;
+		case 126: goto st145;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st145;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st145;
+		} else if ( (*p) >= 65 )
+			goto st145;
+	} else
+		goto st194;
+	goto st0;
+st194:
+	if ( ++p == pe )
+		goto _test_eof194;
+case 194:
+	switch( (*p) ) {
+		case 33: goto st145;
+		case 35: goto tr200;
+		case 37: goto st6;
+		case 47: goto tr201;
+		case 58: goto tr240;
+		case 59: goto st145;
+		case 61: goto st145;
+		case 63: goto tr204;
+		case 64: goto tr164;
+		case 95: goto st145;
+		case 126: goto st145;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st145;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st145;
+		} else if ( (*p) >= 65 )
+			goto st145;
+	} else
+		goto st195;
+	goto st0;
+st195:
+	if ( ++p == pe )
+		goto _test_eof195;
+case 195:
+	switch( (*p) ) {
+		case 33: goto st145;
+		case 35: goto tr200;
+		case 37: goto st6;
+		case 47: goto tr201;
+		case 58: goto tr240;
+		case 59: goto st145;
+		case 61: goto st145;
+		case 63: goto tr204;
+		case 64: goto tr164;
+		case 95: goto st145;
+		case 126: goto st145;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st145;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st145;
+		} else if ( (*p) >= 65 )
+			goto st145;
+	} else
+		goto st196;
+	goto st0;
+st196:
+	if ( ++p == pe )
+		goto _test_eof196;
+case 196:
+	switch( (*p) ) {
+		case 33: goto st145;
+		case 35: goto tr200;
+		case 37: goto st6;
+		case 47: goto tr201;
+		case 58: goto tr240;
+		case 61: goto st145;
+		case 63: goto tr204;
+		case 64: goto tr164;
+		case 95: goto st145;
+		case 126: goto st145;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st145;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st145;
+	} else
+		goto st145;
+	goto st0;
+st197:
+	if ( ++p == pe )
+		goto _test_eof197;
+case 197:
+	switch( (*p) ) {
+		case 33: goto st145;
+		case 35: goto tr159;
+		case 37: goto st6;
+		case 46: goto st193;
+		case 47: goto tr161;
+		case 58: goto tr162;
+		case 59: goto st145;
+		case 61: goto st145;
+		case 63: goto tr163;
+		case 64: goto tr164;
+		case 95: goto st145;
+		case 126: goto st145;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st145;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st145;
+		} else if ( (*p) >= 65 )
+			goto st145;
+	} else
+		goto st198;
+	goto st0;
+st198:
+	if ( ++p == pe )
+		goto _test_eof198;
+case 198:
+	switch( (*p) ) {
+		case 33: goto st145;
+		case 35: goto tr159;
+		case 37: goto st6;
+		case 46: goto st193;
+		case 47: goto tr161;
+		case 58: goto tr162;
+		case 61: goto st145;
+		case 63: goto tr163;
+		case 64: goto tr164;
+		case 95: goto st145;
+		case 126: goto st145;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st145;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st145;
+	} else
+		goto st145;
+	goto st0;
+st199:
+	if ( ++p == pe )
+		goto _test_eof199;
+case 199:
+	switch( (*p) ) {
+		case 33: goto st145;
+		case 35: goto tr159;
+		case 37: goto st6;
+		case 46: goto st191;
+		case 47: goto tr161;
+		case 58: goto tr162;
+		case 59: goto st145;
+		case 61: goto st145;
+		case 63: goto tr163;
+		case 64: goto tr164;
+		case 95: goto st145;
+		case 126: goto st145;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st145;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st145;
+		} else if ( (*p) >= 65 )
+			goto st145;
+	} else
+		goto st200;
+	goto st0;
+st200:
+	if ( ++p == pe )
+		goto _test_eof200;
+case 200:
+	switch( (*p) ) {
+		case 33: goto st145;
+		case 35: goto tr159;
+		case 37: goto st6;
+		case 46: goto st191;
+		case 47: goto tr161;
+		case 58: goto tr162;
+		case 61: goto st145;
+		case 63: goto tr163;
+		case 64: goto tr164;
+		case 95: goto st145;
+		case 126: goto st145;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st145;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st145;
+	} else
+		goto st145;
+	goto st0;
+st201:
+	if ( ++p == pe )
+		goto _test_eof201;
+case 201:
+	switch( (*p) ) {
+		case 33: goto st145;
+		case 35: goto tr159;
+		case 37: goto st6;
+		case 46: goto st189;
+		case 47: goto tr161;
+		case 58: goto tr162;
+		case 59: goto st145;
+		case 61: goto st145;
+		case 63: goto tr163;
+		case 64: goto tr164;
+		case 95: goto st145;
+		case 126: goto st145;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st145;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st145;
+		} else if ( (*p) >= 65 )
+			goto st145;
+	} else
+		goto st202;
+	goto st0;
+st202:
+	if ( ++p == pe )
+		goto _test_eof202;
+case 202:
+	switch( (*p) ) {
+		case 33: goto st145;
+		case 35: goto tr159;
+		case 37: goto st6;
+		case 46: goto st189;
+		case 47: goto tr161;
+		case 58: goto tr162;
+		case 59: goto st145;
+		case 61: goto st145;
+		case 63: goto tr163;
+		case 64: goto tr164;
+		case 95: goto st145;
+		case 126: goto st145;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st145;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st145;
+		} else if ( (*p) >= 65 )
+			goto st145;
+	} else
+		goto st203;
+	goto st0;
+st203:
+	if ( ++p == pe )
+		goto _test_eof203;
+case 203:
+	switch( (*p) ) {
+		case 33: goto st145;
+		case 35: goto tr159;
+		case 37: goto st6;
+		case 47: goto tr161;
+		case 58: goto tr162;
+		case 59: goto st145;
+		case 61: goto st145;
+		case 63: goto tr163;
+		case 64: goto tr164;
+		case 95: goto st145;
+		case 126: goto st145;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st145;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st145;
+		} else if ( (*p) >= 65 )
+			goto st145;
+	} else
+		goto st203;
+	goto st0;
+st204:
+	if ( ++p == pe )
+		goto _test_eof204;
+case 204:
+	switch( (*p) ) {
+		case 35: goto tr151;
+		case 47: goto st148;
+		case 63: goto tr155;
+	}
+	goto st0;
+tr157:
+#line 151 "../../src/uri.rl"
+	{ s = p; }
+#line 137 "../../src/uri.rl"
+	{ s = p; }
+#line 92 "../../src/uri.rl"
+	{ s = p; }
+	goto st205;
+st205:
+	if ( ++p == pe )
+		goto _test_eof205;
+case 205:
+#line 3721 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st145;
+		case 35: goto tr159;
+		case 37: goto st6;
+		case 43: goto st205;
+		case 47: goto tr161;
+		case 58: goto tr247;
+		case 59: goto st145;
+		case 61: goto st145;
+		case 63: goto tr163;
+		case 64: goto tr164;
+		case 95: goto st145;
+		case 126: goto st145;
+	}
+	if ( (*p) < 45 ) {
+		if ( 36 <= (*p) && (*p) <= 44 )
+			goto st145;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st205;
+		} else if ( (*p) >= 65 )
+			goto st205;
+	} else
+		goto st205;
+	goto st0;
+tr247:
+#line 153 "../../src/uri.rl"
+	{scheme = s; scheme_len = p - s; }
+#line 138 "../../src/uri.rl"
+	{ login = s; login_len = p - s; }
+#line 93 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;}
+	goto st206;
+st206:
+	if ( ++p == pe )
+		goto _test_eof206;
+case 206:
+#line 3760 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto tr174;
+		case 35: goto tr175;
+		case 37: goto tr176;
+		case 47: goto tr248;
+		case 59: goto tr174;
+		case 61: goto tr174;
+		case 63: goto tr179;
+		case 95: goto tr174;
+		case 126: goto tr174;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto tr174;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto tr180;
+		} else if ( (*p) >= 65 )
+			goto tr180;
+	} else
+		goto tr178;
+	goto st0;
+tr248:
+#line 169 "../../src/uri.rl"
+	{ uri->scheme = scheme; uri->scheme_len = scheme_len;}
+#line 131 "../../src/uri.rl"
+	{ s = p; }
+#line 132 "../../src/uri.rl"
+	{ uri->service = s; uri->service_len = p - s; }
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+	goto st207;
+st207:
+	if ( ++p == pe )
+		goto _test_eof207;
+case 207:
+#line 3798 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st148;
+		case 35: goto tr151;
+		case 37: goto st11;
+		case 47: goto st208;
+		case 61: goto st148;
+		case 63: goto tr155;
+		case 95: goto st148;
+		case 126: goto st148;
+	}
+	if ( (*p) < 64 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st148;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st148;
+	} else
+		goto st148;
+	goto st0;
+st208:
+	if ( ++p == pe )
+		goto _test_eof208;
+case 208:
+	switch( (*p) ) {
+		case 33: goto tr250;
+		case 35: goto tr151;
+		case 37: goto tr251;
+		case 47: goto st148;
+		case 58: goto st148;
+		case 59: goto tr250;
+		case 61: goto tr250;
+		case 63: goto tr155;
+		case 64: goto st148;
+		case 91: goto st38;
+		case 95: goto tr250;
+		case 117: goto tr253;
+		case 126: goto tr250;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto tr250;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto tr250;
+		} else if ( (*p) >= 65 )
+			goto tr250;
+	} else
+		goto tr252;
+	goto st0;
+tr250:
+#line 137 "../../src/uri.rl"
+	{ s = p; }
+#line 92 "../../src/uri.rl"
+	{ s = p; }
+	goto st209;
+st209:
+	if ( ++p == pe )
+		goto _test_eof209;
+case 209:
+#line 3859 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st209;
+		case 35: goto tr159;
+		case 37: goto st119;
+		case 47: goto tr161;
+		case 58: goto tr255;
+		case 61: goto st209;
+		case 63: goto tr163;
+		case 64: goto tr256;
+		case 95: goto st209;
+		case 126: goto st209;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st209;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st209;
+	} else
+		goto st209;
+	goto st0;
+tr251:
+#line 137 "../../src/uri.rl"
+	{ s = p; }
+#line 92 "../../src/uri.rl"
+	{ s = p; }
+	goto st119;
+st119:
+	if ( ++p == pe )
+		goto _test_eof119;
+case 119:
+#line 3891 "../../src/uri.c"
+	switch( (*p) ) {
+		case 37: goto st209;
+		case 117: goto st120;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st209;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st209;
+	} else
+		goto st209;
+	goto st0;
+st120:
+	if ( ++p == pe )
+		goto _test_eof120;
+case 120:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st121;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st121;
+	} else
+		goto st121;
+	goto st0;
+st121:
+	if ( ++p == pe )
+		goto _test_eof121;
+case 121:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st122;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st122;
+	} else
+		goto st122;
+	goto st0;
+st122:
+	if ( ++p == pe )
+		goto _test_eof122;
+case 122:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st123;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st123;
+	} else
+		goto st123;
+	goto st0;
+st123:
+	if ( ++p == pe )
+		goto _test_eof123;
+case 123:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st209;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st209;
+	} else
+		goto st209;
+	goto st0;
+tr255:
+#line 138 "../../src/uri.rl"
+	{ login = s; login_len = p - s; }
+#line 93 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;}
+	goto st210;
+tr303:
+#line 138 "../../src/uri.rl"
+	{ login = s; login_len = p - s; }
+#line 100 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;
+			   uri->host_hint = 1; }
+#line 93 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;}
+	goto st210;
+st210:
+	if ( ++p == pe )
+		goto _test_eof210;
+case 210:
+#line 3976 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto tr257;
+		case 35: goto tr175;
+		case 37: goto tr258;
+		case 47: goto tr177;
+		case 58: goto st148;
+		case 59: goto tr257;
+		case 61: goto tr257;
+		case 63: goto tr179;
+		case 64: goto st148;
+		case 95: goto tr257;
+		case 126: goto tr257;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto tr257;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto tr260;
+		} else if ( (*p) >= 65 )
+			goto tr260;
+	} else
+		goto tr259;
+	goto st0;
+tr257:
+#line 141 "../../src/uri.rl"
+	{ s = p; }
+	goto st211;
+st211:
+	if ( ++p == pe )
+		goto _test_eof211;
+case 211:
+#line 4010 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st211;
+		case 35: goto tr151;
+		case 37: goto st124;
+		case 47: goto st148;
+		case 58: goto st148;
+		case 61: goto st211;
+		case 63: goto tr155;
+		case 64: goto tr262;
+		case 95: goto st211;
+		case 126: goto st211;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st211;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st211;
+	} else
+		goto st211;
+	goto st0;
+tr258:
+#line 141 "../../src/uri.rl"
+	{ s = p; }
+	goto st124;
+st124:
+	if ( ++p == pe )
+		goto _test_eof124;
+case 124:
+#line 4040 "../../src/uri.c"
+	switch( (*p) ) {
+		case 37: goto st211;
+		case 117: goto st125;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st211;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st211;
+	} else
+		goto st211;
+	goto st0;
+st125:
+	if ( ++p == pe )
+		goto _test_eof125;
+case 125:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st126;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st126;
+	} else
+		goto st126;
+	goto st0;
+st126:
+	if ( ++p == pe )
+		goto _test_eof126;
+case 126:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st127;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st127;
+	} else
+		goto st127;
+	goto st0;
+st127:
+	if ( ++p == pe )
+		goto _test_eof127;
+case 127:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st128;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st128;
+	} else
+		goto st128;
+	goto st0;
+st128:
+	if ( ++p == pe )
+		goto _test_eof128;
+case 128:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st211;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st211;
+	} else
+		goto st211;
+	goto st0;
+tr262:
+#line 142 "../../src/uri.rl"
+	{ uri->password = s; uri->password_len = p - s; }
+#line 146 "../../src/uri.rl"
+	{ uri->login = login; uri->login_len = login_len; }
+	goto st212;
+tr256:
+#line 138 "../../src/uri.rl"
+	{ login = s; login_len = p - s; }
+#line 146 "../../src/uri.rl"
+	{ uri->login = login; uri->login_len = login_len; }
+	goto st212;
+st212:
+	if ( ++p == pe )
+		goto _test_eof212;
+case 212:
+#line 4122 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto tr263;
+		case 35: goto tr151;
+		case 37: goto tr264;
+		case 47: goto st148;
+		case 58: goto st148;
+		case 59: goto tr263;
+		case 61: goto tr263;
+		case 63: goto tr155;
+		case 64: goto st148;
+		case 91: goto st38;
+		case 95: goto tr263;
+		case 117: goto tr266;
+		case 126: goto tr263;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto tr263;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto tr263;
+		} else if ( (*p) >= 65 )
+			goto tr263;
+	} else
+		goto tr265;
+	goto st0;
+tr263:
+#line 92 "../../src/uri.rl"
+	{ s = p; }
+	goto st213;
+st213:
+	if ( ++p == pe )
+		goto _test_eof213;
+case 213:
+#line 4158 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st213;
+		case 35: goto tr159;
+		case 37: goto st129;
+		case 47: goto tr161;
+		case 58: goto tr268;
+		case 61: goto st213;
+		case 63: goto tr163;
+		case 64: goto st148;
+		case 95: goto st213;
+		case 126: goto st213;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st213;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st213;
+	} else
+		goto st213;
+	goto st0;
+tr264:
+#line 92 "../../src/uri.rl"
+	{ s = p; }
+	goto st129;
+st129:
+	if ( ++p == pe )
+		goto _test_eof129;
+case 129:
+#line 4188 "../../src/uri.c"
+	switch( (*p) ) {
+		case 37: goto st213;
+		case 117: goto st130;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st213;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st213;
+	} else
+		goto st213;
+	goto st0;
+st130:
+	if ( ++p == pe )
+		goto _test_eof130;
+case 130:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st131;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st131;
+	} else
+		goto st131;
+	goto st0;
+st131:
+	if ( ++p == pe )
+		goto _test_eof131;
+case 131:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st132;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st132;
+	} else
+		goto st132;
+	goto st0;
+st132:
+	if ( ++p == pe )
+		goto _test_eof132;
+case 132:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st133;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st133;
+	} else
+		goto st133;
+	goto st0;
+st133:
+	if ( ++p == pe )
+		goto _test_eof133;
+case 133:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st213;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st213;
+	} else
+		goto st213;
+	goto st0;
+tr268:
+#line 93 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;}
+	goto st214;
+tr283:
+#line 100 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;
+			   uri->host_hint = 1; }
+#line 93 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;}
+	goto st214;
+st214:
+	if ( ++p == pe )
+		goto _test_eof214;
+case 214:
+#line 4269 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st148;
+		case 35: goto tr175;
+		case 37: goto st11;
+		case 47: goto tr177;
+		case 61: goto st148;
+		case 63: goto tr179;
+		case 64: goto st148;
+		case 95: goto st148;
+		case 126: goto st148;
+	}
+	if ( (*p) < 58 ) {
+		if ( (*p) > 46 ) {
+			if ( 48 <= (*p) && (*p) <= 57 )
+				goto tr269;
+		} else if ( (*p) >= 36 )
+			goto st148;
+	} else if ( (*p) > 59 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto tr270;
+		} else if ( (*p) >= 65 )
+			goto tr270;
+	} else
+		goto st148;
+	goto st0;
+tr269:
+#line 131 "../../src/uri.rl"
+	{ s = p; }
+	goto st215;
+st215:
+	if ( ++p == pe )
+		goto _test_eof215;
+case 215:
+#line 4304 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st148;
+		case 35: goto tr185;
+		case 37: goto st11;
+		case 47: goto tr186;
+		case 61: goto st148;
+		case 63: goto tr188;
+		case 95: goto st148;
+		case 126: goto st148;
+	}
+	if ( (*p) < 58 ) {
+		if ( (*p) > 46 ) {
+			if ( 48 <= (*p) && (*p) <= 57 )
+				goto st215;
+		} else if ( (*p) >= 36 )
+			goto st148;
+	} else if ( (*p) > 59 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st148;
+		} else if ( (*p) >= 64 )
+			goto st148;
+	} else
+		goto st148;
+	goto st0;
+tr270:
+#line 131 "../../src/uri.rl"
+	{ s = p; }
+	goto st216;
+st216:
+	if ( ++p == pe )
+		goto _test_eof216;
+case 216:
+#line 4338 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st148;
+		case 35: goto tr185;
+		case 37: goto st11;
+		case 47: goto tr186;
+		case 61: goto st148;
+		case 63: goto tr188;
+		case 64: goto st148;
+		case 95: goto st148;
+		case 126: goto st148;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st148;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st216;
+	} else
+		goto st216;
+	goto st0;
+tr265:
+#line 99 "../../src/uri.rl"
+	{ s = p; }
+#line 92 "../../src/uri.rl"
+	{ s = p; }
+	goto st217;
+st217:
+	if ( ++p == pe )
+		goto _test_eof217;
+case 217:
+#line 4369 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st213;
+		case 35: goto tr159;
+		case 37: goto st129;
+		case 46: goto st218;
+		case 47: goto tr161;
+		case 58: goto tr268;
+		case 59: goto st213;
+		case 61: goto st213;
+		case 63: goto tr163;
+		case 64: goto st148;
+		case 95: goto st213;
+		case 126: goto st213;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st213;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st213;
+		} else if ( (*p) >= 65 )
+			goto st213;
+	} else
+		goto st230;
+	goto st0;
+st218:
+	if ( ++p == pe )
+		goto _test_eof218;
+case 218:
+	switch( (*p) ) {
+		case 33: goto st213;
+		case 35: goto tr159;
+		case 37: goto st129;
+		case 47: goto tr161;
+		case 58: goto tr268;
+		case 59: goto st213;
+		case 61: goto st213;
+		case 63: goto tr163;
+		case 64: goto st148;
+		case 95: goto st213;
+		case 126: goto st213;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st213;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st213;
+		} else if ( (*p) >= 65 )
+			goto st213;
+	} else
+		goto st219;
+	goto st0;
+st219:
+	if ( ++p == pe )
+		goto _test_eof219;
+case 219:
+	switch( (*p) ) {
+		case 33: goto st213;
+		case 35: goto tr159;
+		case 37: goto st129;
+		case 46: goto st220;
+		case 47: goto tr161;
+		case 58: goto tr268;
+		case 59: goto st213;
+		case 61: goto st213;
+		case 63: goto tr163;
+		case 64: goto st148;
+		case 95: goto st213;
+		case 126: goto st213;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st213;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st213;
+		} else if ( (*p) >= 65 )
+			goto st213;
+	} else
+		goto st228;
+	goto st0;
+st220:
+	if ( ++p == pe )
+		goto _test_eof220;
+case 220:
+	switch( (*p) ) {
+		case 33: goto st213;
+		case 35: goto tr159;
+		case 37: goto st129;
+		case 47: goto tr161;
+		case 58: goto tr268;
+		case 59: goto st213;
+		case 61: goto st213;
+		case 63: goto tr163;
+		case 64: goto st148;
+		case 95: goto st213;
+		case 126: goto st213;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st213;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st213;
+		} else if ( (*p) >= 65 )
+			goto st213;
+	} else
+		goto st221;
+	goto st0;
+st221:
+	if ( ++p == pe )
+		goto _test_eof221;
+case 221:
+	switch( (*p) ) {
+		case 33: goto st213;
+		case 35: goto tr159;
+		case 37: goto st129;
+		case 46: goto st222;
+		case 47: goto tr161;
+		case 58: goto tr268;
+		case 59: goto st213;
+		case 61: goto st213;
+		case 63: goto tr163;
+		case 64: goto st148;
+		case 95: goto st213;
+		case 126: goto st213;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st213;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st213;
+		} else if ( (*p) >= 65 )
+			goto st213;
+	} else
+		goto st226;
+	goto st0;
+st222:
+	if ( ++p == pe )
+		goto _test_eof222;
+case 222:
+	switch( (*p) ) {
+		case 33: goto st213;
+		case 35: goto tr159;
+		case 37: goto st129;
+		case 47: goto tr161;
+		case 58: goto tr268;
+		case 59: goto st213;
+		case 61: goto st213;
+		case 63: goto tr163;
+		case 64: goto st148;
+		case 95: goto st213;
+		case 126: goto st213;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st213;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st213;
+		} else if ( (*p) >= 65 )
+			goto st213;
+	} else
+		goto st223;
+	goto st0;
+st223:
+	if ( ++p == pe )
+		goto _test_eof223;
+case 223:
+	switch( (*p) ) {
+		case 33: goto st213;
+		case 35: goto tr200;
+		case 37: goto st129;
+		case 47: goto tr201;
+		case 58: goto tr283;
+		case 59: goto st213;
+		case 61: goto st213;
+		case 63: goto tr204;
+		case 64: goto st148;
+		case 95: goto st213;
+		case 126: goto st213;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st213;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st213;
+		} else if ( (*p) >= 65 )
+			goto st213;
+	} else
+		goto st224;
+	goto st0;
+st224:
+	if ( ++p == pe )
+		goto _test_eof224;
+case 224:
+	switch( (*p) ) {
+		case 33: goto st213;
+		case 35: goto tr200;
+		case 37: goto st129;
+		case 47: goto tr201;
+		case 58: goto tr283;
+		case 59: goto st213;
+		case 61: goto st213;
+		case 63: goto tr204;
+		case 64: goto st148;
+		case 95: goto st213;
+		case 126: goto st213;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st213;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st213;
+		} else if ( (*p) >= 65 )
+			goto st213;
+	} else
+		goto st225;
+	goto st0;
+st225:
+	if ( ++p == pe )
+		goto _test_eof225;
+case 225:
+	switch( (*p) ) {
+		case 33: goto st213;
+		case 35: goto tr200;
+		case 37: goto st129;
+		case 47: goto tr201;
+		case 58: goto tr283;
+		case 61: goto st213;
+		case 63: goto tr204;
+		case 64: goto st148;
+		case 95: goto st213;
+		case 126: goto st213;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st213;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st213;
+	} else
+		goto st213;
+	goto st0;
+st226:
+	if ( ++p == pe )
+		goto _test_eof226;
+case 226:
+	switch( (*p) ) {
+		case 33: goto st213;
+		case 35: goto tr159;
+		case 37: goto st129;
+		case 46: goto st222;
+		case 47: goto tr161;
+		case 58: goto tr268;
+		case 59: goto st213;
+		case 61: goto st213;
+		case 63: goto tr163;
+		case 64: goto st148;
+		case 95: goto st213;
+		case 126: goto st213;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st213;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st213;
+		} else if ( (*p) >= 65 )
+			goto st213;
+	} else
+		goto st227;
+	goto st0;
+st227:
+	if ( ++p == pe )
+		goto _test_eof227;
+case 227:
+	switch( (*p) ) {
+		case 33: goto st213;
+		case 35: goto tr159;
+		case 37: goto st129;
+		case 46: goto st222;
+		case 47: goto tr161;
+		case 58: goto tr268;
+		case 61: goto st213;
+		case 63: goto tr163;
+		case 64: goto st148;
+		case 95: goto st213;
+		case 126: goto st213;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st213;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st213;
+	} else
+		goto st213;
+	goto st0;
+st228:
+	if ( ++p == pe )
+		goto _test_eof228;
+case 228:
+	switch( (*p) ) {
+		case 33: goto st213;
+		case 35: goto tr159;
+		case 37: goto st129;
+		case 46: goto st220;
+		case 47: goto tr161;
+		case 58: goto tr268;
+		case 59: goto st213;
+		case 61: goto st213;
+		case 63: goto tr163;
+		case 64: goto st148;
+		case 95: goto st213;
+		case 126: goto st213;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st213;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st213;
+		} else if ( (*p) >= 65 )
+			goto st213;
+	} else
+		goto st229;
+	goto st0;
+st229:
+	if ( ++p == pe )
+		goto _test_eof229;
+case 229:
+	switch( (*p) ) {
+		case 33: goto st213;
+		case 35: goto tr159;
+		case 37: goto st129;
+		case 46: goto st220;
+		case 47: goto tr161;
+		case 58: goto tr268;
+		case 61: goto st213;
+		case 63: goto tr163;
+		case 64: goto st148;
+		case 95: goto st213;
+		case 126: goto st213;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st213;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st213;
+	} else
+		goto st213;
+	goto st0;
+st230:
+	if ( ++p == pe )
+		goto _test_eof230;
+case 230:
+	switch( (*p) ) {
+		case 33: goto st213;
+		case 35: goto tr159;
+		case 37: goto st129;
+		case 46: goto st218;
+		case 47: goto tr161;
+		case 58: goto tr268;
+		case 59: goto st213;
+		case 61: goto st213;
+		case 63: goto tr163;
+		case 64: goto st148;
+		case 95: goto st213;
+		case 126: goto st213;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st213;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st213;
+		} else if ( (*p) >= 65 )
+			goto st213;
+	} else
+		goto st231;
+	goto st0;
+st231:
+	if ( ++p == pe )
+		goto _test_eof231;
+case 231:
+	switch( (*p) ) {
+		case 33: goto st213;
+		case 35: goto tr159;
+		case 37: goto st129;
+		case 46: goto st218;
+		case 47: goto tr161;
+		case 58: goto tr268;
+		case 61: goto st213;
+		case 63: goto tr163;
+		case 64: goto st148;
+		case 95: goto st213;
+		case 126: goto st213;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st213;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st213;
+	} else
+		goto st213;
+	goto st0;
+tr266:
+#line 92 "../../src/uri.rl"
+	{ s = p; }
+	goto st232;
+st232:
+	if ( ++p == pe )
+		goto _test_eof232;
+case 232:
+#line 4802 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st213;
+		case 35: goto tr159;
+		case 37: goto st129;
+		case 47: goto tr161;
+		case 58: goto tr268;
+		case 61: goto st213;
+		case 63: goto tr163;
+		case 64: goto st148;
+		case 95: goto st213;
+		case 110: goto st233;
+		case 126: goto st213;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st213;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st213;
+	} else
+		goto st213;
+	goto st0;
+st233:
+	if ( ++p == pe )
+		goto _test_eof233;
+case 233:
+	switch( (*p) ) {
+		case 33: goto st213;
+		case 35: goto tr159;
+		case 37: goto st129;
+		case 47: goto tr161;
+		case 58: goto tr268;
+		case 61: goto st213;
+		case 63: goto tr163;
+		case 64: goto st148;
+		case 95: goto st213;
+		case 105: goto st234;
+		case 126: goto st213;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st213;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st213;
+	} else
+		goto st213;
+	goto st0;
+st234:
+	if ( ++p == pe )
+		goto _test_eof234;
+case 234:
+	switch( (*p) ) {
+		case 33: goto st213;
+		case 35: goto tr159;
+		case 37: goto st129;
+		case 47: goto tr161;
+		case 58: goto tr268;
+		case 61: goto st213;
+		case 63: goto tr163;
+		case 64: goto st148;
+		case 95: goto st213;
+		case 120: goto st235;
+		case 126: goto st213;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st213;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st213;
+	} else
+		goto st213;
+	goto st0;
+st235:
+	if ( ++p == pe )
+		goto _test_eof235;
+case 235:
+	switch( (*p) ) {
+		case 33: goto st213;
+		case 35: goto tr159;
+		case 37: goto st129;
+		case 47: goto tr216;
+		case 58: goto tr268;
+		case 61: goto st213;
+		case 63: goto tr163;
+		case 64: goto st148;
+		case 95: goto st213;
+		case 126: goto st213;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st213;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st213;
+	} else
+		goto st213;
+	goto st0;
+tr259:
+#line 141 "../../src/uri.rl"
+	{ s = p; }
+#line 131 "../../src/uri.rl"
+	{ s = p; }
+	goto st236;
+st236:
+	if ( ++p == pe )
+		goto _test_eof236;
+case 236:
+#line 4912 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st211;
+		case 35: goto tr185;
+		case 37: goto st124;
+		case 47: goto tr186;
+		case 58: goto st148;
+		case 59: goto st211;
+		case 61: goto st211;
+		case 63: goto tr188;
+		case 64: goto tr262;
+		case 95: goto st211;
+		case 126: goto st211;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st211;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st211;
+		} else if ( (*p) >= 65 )
+			goto st211;
+	} else
+		goto st236;
+	goto st0;
+tr260:
+#line 141 "../../src/uri.rl"
+	{ s = p; }
+#line 131 "../../src/uri.rl"
+	{ s = p; }
+	goto st237;
+st237:
+	if ( ++p == pe )
+		goto _test_eof237;
+case 237:
+#line 4948 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st211;
+		case 35: goto tr185;
+		case 37: goto st124;
+		case 47: goto tr186;
+		case 58: goto st148;
+		case 61: goto st211;
+		case 63: goto tr188;
+		case 64: goto tr262;
+		case 95: goto st211;
+		case 126: goto st211;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st211;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st237;
+	} else
+		goto st237;
+	goto st0;
+tr252:
+#line 137 "../../src/uri.rl"
+	{ s = p; }
+#line 99 "../../src/uri.rl"
+	{ s = p; }
+#line 92 "../../src/uri.rl"
+	{ s = p; }
+	goto st238;
+st238:
+	if ( ++p == pe )
+		goto _test_eof238;
+case 238:
+#line 4982 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st209;
+		case 35: goto tr159;
+		case 37: goto st119;
+		case 46: goto st239;
+		case 47: goto tr161;
+		case 58: goto tr255;
+		case 59: goto st209;
+		case 61: goto st209;
+		case 63: goto tr163;
+		case 64: goto tr256;
+		case 95: goto st209;
+		case 126: goto st209;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st209;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st209;
+		} else if ( (*p) >= 65 )
+			goto st209;
+	} else
+		goto st251;
+	goto st0;
+st239:
+	if ( ++p == pe )
+		goto _test_eof239;
+case 239:
+	switch( (*p) ) {
+		case 33: goto st209;
+		case 35: goto tr159;
+		case 37: goto st119;
+		case 47: goto tr161;
+		case 58: goto tr255;
+		case 59: goto st209;
+		case 61: goto st209;
+		case 63: goto tr163;
+		case 64: goto tr256;
+		case 95: goto st209;
+		case 126: goto st209;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st209;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st209;
+		} else if ( (*p) >= 65 )
+			goto st209;
+	} else
+		goto st240;
+	goto st0;
+st240:
+	if ( ++p == pe )
+		goto _test_eof240;
+case 240:
+	switch( (*p) ) {
+		case 33: goto st209;
+		case 35: goto tr159;
+		case 37: goto st119;
+		case 46: goto st241;
+		case 47: goto tr161;
+		case 58: goto tr255;
+		case 59: goto st209;
+		case 61: goto st209;
+		case 63: goto tr163;
+		case 64: goto tr256;
+		case 95: goto st209;
+		case 126: goto st209;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st209;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st209;
+		} else if ( (*p) >= 65 )
+			goto st209;
+	} else
+		goto st249;
+	goto st0;
+st241:
+	if ( ++p == pe )
+		goto _test_eof241;
+case 241:
+	switch( (*p) ) {
+		case 33: goto st209;
+		case 35: goto tr159;
+		case 37: goto st119;
+		case 47: goto tr161;
+		case 58: goto tr255;
+		case 59: goto st209;
+		case 61: goto st209;
+		case 63: goto tr163;
+		case 64: goto tr256;
+		case 95: goto st209;
+		case 126: goto st209;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st209;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st209;
+		} else if ( (*p) >= 65 )
+			goto st209;
+	} else
+		goto st242;
+	goto st0;
+st242:
+	if ( ++p == pe )
+		goto _test_eof242;
+case 242:
+	switch( (*p) ) {
+		case 33: goto st209;
+		case 35: goto tr159;
+		case 37: goto st119;
+		case 46: goto st243;
+		case 47: goto tr161;
+		case 58: goto tr255;
+		case 59: goto st209;
+		case 61: goto st209;
+		case 63: goto tr163;
+		case 64: goto tr256;
+		case 95: goto st209;
+		case 126: goto st209;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st209;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st209;
+		} else if ( (*p) >= 65 )
+			goto st209;
+	} else
+		goto st247;
+	goto st0;
+st243:
+	if ( ++p == pe )
+		goto _test_eof243;
+case 243:
+	switch( (*p) ) {
+		case 33: goto st209;
+		case 35: goto tr159;
+		case 37: goto st119;
+		case 47: goto tr161;
+		case 58: goto tr255;
+		case 59: goto st209;
+		case 61: goto st209;
+		case 63: goto tr163;
+		case 64: goto tr256;
+		case 95: goto st209;
+		case 126: goto st209;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st209;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st209;
+		} else if ( (*p) >= 65 )
+			goto st209;
+	} else
+		goto st244;
+	goto st0;
+st244:
+	if ( ++p == pe )
+		goto _test_eof244;
+case 244:
+	switch( (*p) ) {
+		case 33: goto st209;
+		case 35: goto tr200;
+		case 37: goto st119;
+		case 47: goto tr201;
+		case 58: goto tr303;
+		case 59: goto st209;
+		case 61: goto st209;
+		case 63: goto tr204;
+		case 64: goto tr256;
+		case 95: goto st209;
+		case 126: goto st209;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st209;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st209;
+		} else if ( (*p) >= 65 )
+			goto st209;
+	} else
+		goto st245;
+	goto st0;
+st245:
+	if ( ++p == pe )
+		goto _test_eof245;
+case 245:
+	switch( (*p) ) {
+		case 33: goto st209;
+		case 35: goto tr200;
+		case 37: goto st119;
+		case 47: goto tr201;
+		case 58: goto tr303;
+		case 59: goto st209;
+		case 61: goto st209;
+		case 63: goto tr204;
+		case 64: goto tr256;
+		case 95: goto st209;
+		case 126: goto st209;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 46 )
+			goto st209;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st209;
+		} else if ( (*p) >= 65 )
+			goto st209;
+	} else
+		goto st246;
+	goto st0;
+st246:
+	if ( ++p == pe )
+		goto _test_eof246;
+case 246:
+	switch( (*p) ) {
+		case 33: goto st209;
+		case 35: goto tr200;
+		case 37: goto st119;
+		case 47: goto tr201;
+		case 58: goto tr303;
+		case 61: goto st209;
+		case 63: goto tr204;
+		case 64: goto tr256;
+		case 95: goto st209;
+		case 126: goto st209;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st209;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st209;
+	} else
+		goto st209;
+	goto st0;
+st247:
+	if ( ++p == pe )
+		goto _test_eof247;
+case 247:
+	switch( (*p) ) {
+		case 33: goto st209;
+		case 35: goto tr159;
+		case 37: goto st119;
+		case 46: goto st243;
+		case 47: goto tr161;
+		case 58: goto tr255;
+		case 59: goto st209;
+		case 61: goto st209;
+		case 63: goto tr163;
+		case 64: goto tr256;
+		case 95: goto st209;
+		case 126: goto st209;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st209;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st209;
+		} else if ( (*p) >= 65 )
+			goto st209;
+	} else
+		goto st248;
+	goto st0;
+st248:
+	if ( ++p == pe )
+		goto _test_eof248;
+case 248:
+	switch( (*p) ) {
+		case 33: goto st209;
+		case 35: goto tr159;
+		case 37: goto st119;
+		case 46: goto st243;
+		case 47: goto tr161;
+		case 58: goto tr255;
+		case 61: goto st209;
+		case 63: goto tr163;
+		case 64: goto tr256;
+		case 95: goto st209;
+		case 126: goto st209;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st209;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st209;
+	} else
+		goto st209;
+	goto st0;
+st249:
+	if ( ++p == pe )
+		goto _test_eof249;
+case 249:
+	switch( (*p) ) {
+		case 33: goto st209;
+		case 35: goto tr159;
+		case 37: goto st119;
+		case 46: goto st241;
+		case 47: goto tr161;
+		case 58: goto tr255;
+		case 59: goto st209;
+		case 61: goto st209;
+		case 63: goto tr163;
+		case 64: goto tr256;
+		case 95: goto st209;
+		case 126: goto st209;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st209;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st209;
+		} else if ( (*p) >= 65 )
+			goto st209;
+	} else
+		goto st250;
+	goto st0;
+st250:
+	if ( ++p == pe )
+		goto _test_eof250;
+case 250:
+	switch( (*p) ) {
+		case 33: goto st209;
+		case 35: goto tr159;
+		case 37: goto st119;
+		case 46: goto st241;
+		case 47: goto tr161;
+		case 58: goto tr255;
+		case 61: goto st209;
+		case 63: goto tr163;
+		case 64: goto tr256;
+		case 95: goto st209;
+		case 126: goto st209;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st209;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st209;
+	} else
+		goto st209;
+	goto st0;
+st251:
+	if ( ++p == pe )
+		goto _test_eof251;
+case 251:
+	switch( (*p) ) {
+		case 33: goto st209;
+		case 35: goto tr159;
+		case 37: goto st119;
+		case 46: goto st239;
+		case 47: goto tr161;
+		case 58: goto tr255;
+		case 59: goto st209;
+		case 61: goto st209;
+		case 63: goto tr163;
+		case 64: goto tr256;
+		case 95: goto st209;
+		case 126: goto st209;
+	}
+	if ( (*p) < 48 ) {
+		if ( 36 <= (*p) && (*p) <= 45 )
+			goto st209;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st209;
+		} else if ( (*p) >= 65 )
+			goto st209;
+	} else
+		goto st252;
+	goto st0;
+st252:
+	if ( ++p == pe )
+		goto _test_eof252;
+case 252:
+	switch( (*p) ) {
+		case 33: goto st209;
+		case 35: goto tr159;
+		case 37: goto st119;
+		case 46: goto st239;
+		case 47: goto tr161;
+		case 58: goto tr255;
+		case 61: goto st209;
+		case 63: goto tr163;
+		case 64: goto tr256;
+		case 95: goto st209;
+		case 126: goto st209;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st209;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st209;
+	} else
+		goto st209;
+	goto st0;
+tr253:
+#line 137 "../../src/uri.rl"
+	{ s = p; }
+#line 92 "../../src/uri.rl"
+	{ s = p; }
+	goto st253;
+st253:
+	if ( ++p == pe )
+		goto _test_eof253;
+case 253:
+#line 5417 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st209;
+		case 35: goto tr159;
+		case 37: goto st119;
+		case 47: goto tr161;
+		case 58: goto tr255;
+		case 61: goto st209;
+		case 63: goto tr163;
+		case 64: goto tr256;
+		case 95: goto st209;
+		case 110: goto st254;
+		case 126: goto st209;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st209;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st209;
+	} else
+		goto st209;
+	goto st0;
+st254:
+	if ( ++p == pe )
+		goto _test_eof254;
+case 254:
+	switch( (*p) ) {
+		case 33: goto st209;
+		case 35: goto tr159;
+		case 37: goto st119;
+		case 47: goto tr161;
+		case 58: goto tr255;
+		case 61: goto st209;
+		case 63: goto tr163;
+		case 64: goto tr256;
+		case 95: goto st209;
+		case 105: goto st255;
+		case 126: goto st209;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st209;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st209;
+	} else
+		goto st209;
+	goto st0;
+st255:
+	if ( ++p == pe )
+		goto _test_eof255;
+case 255:
+	switch( (*p) ) {
+		case 33: goto st209;
+		case 35: goto tr159;
+		case 37: goto st119;
+		case 47: goto tr161;
+		case 58: goto tr255;
+		case 61: goto st209;
+		case 63: goto tr163;
+		case 64: goto tr256;
+		case 95: goto st209;
+		case 120: goto st256;
+		case 126: goto st209;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st209;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st209;
+	} else
+		goto st209;
+	goto st0;
+st256:
+	if ( ++p == pe )
+		goto _test_eof256;
+case 256:
+	switch( (*p) ) {
+		case 33: goto st209;
+		case 35: goto tr159;
+		case 37: goto st119;
+		case 47: goto tr311;
+		case 58: goto tr255;
+		case 61: goto st209;
+		case 63: goto tr163;
+		case 64: goto tr256;
+		case 95: goto st209;
+		case 126: goto st209;
+	}
+	if ( (*p) < 65 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st209;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st209;
+	} else
+		goto st209;
+	goto st0;
+tr311:
+#line 93 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;}
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+	goto st257;
+st257:
+	if ( ++p == pe )
+		goto _test_eof257;
+case 257:
+#line 5527 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st148;
+		case 35: goto tr151;
+		case 37: goto st11;
+		case 58: goto st258;
+		case 61: goto st148;
+		case 63: goto tr155;
+		case 95: goto st148;
+		case 126: goto st148;
+	}
+	if ( (*p) < 64 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st148;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st148;
+	} else
+		goto st148;
+	goto st0;
+st258:
+	if ( ++p == pe )
+		goto _test_eof258;
+case 258:
+	switch( (*p) ) {
+		case 33: goto tr313;
+		case 35: goto tr314;
+		case 37: goto tr315;
+		case 47: goto tr316;
+		case 58: goto tr221;
+		case 61: goto tr313;
+		case 63: goto tr317;
+		case 95: goto tr313;
+		case 126: goto tr313;
+	}
+	if ( (*p) < 64 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto tr313;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr313;
+	} else
+		goto tr313;
+	goto st0;
+tr313:
+#line 128 "../../src/uri.rl"
+	{ s = p;}
+	goto st259;
+st259:
+	if ( ++p == pe )
+		goto _test_eof259;
+case 259:
+#line 5579 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st259;
+		case 35: goto tr318;
+		case 37: goto st134;
+		case 47: goto st260;
+		case 58: goto tr223;
+		case 61: goto st259;
+		case 63: goto tr320;
+		case 95: goto st259;
+		case 126: goto st259;
+	}
+	if ( (*p) < 64 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st259;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st259;
+	} else
+		goto st259;
+	goto st0;
+tr315:
+#line 128 "../../src/uri.rl"
+	{ s = p;}
+	goto st134;
+st134:
+	if ( ++p == pe )
+		goto _test_eof134;
+case 134:
+#line 5608 "../../src/uri.c"
+	switch( (*p) ) {
+		case 37: goto st259;
+		case 117: goto st135;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st259;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st259;
+	} else
+		goto st259;
+	goto st0;
+st135:
+	if ( ++p == pe )
+		goto _test_eof135;
+case 135:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st136;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st136;
+	} else
+		goto st136;
+	goto st0;
+st136:
+	if ( ++p == pe )
+		goto _test_eof136;
+case 136:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st137;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st137;
+	} else
+		goto st137;
+	goto st0;
+st137:
+	if ( ++p == pe )
+		goto _test_eof137;
+case 137:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st138;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st138;
+	} else
+		goto st138;
+	goto st0;
+st138:
+	if ( ++p == pe )
+		goto _test_eof138;
+case 138:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st259;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st259;
+	} else
+		goto st259;
+	goto st0;
+tr324:
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+	goto st260;
+tr316:
+#line 128 "../../src/uri.rl"
+	{ s = p;}
+	goto st260;
+st260:
+	if ( ++p == pe )
+		goto _test_eof260;
+case 260:
+#line 5686 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st260;
+		case 35: goto tr318;
+		case 37: goto st139;
+		case 58: goto tr322;
+		case 61: goto st260;
+		case 63: goto tr320;
+		case 95: goto st260;
+		case 126: goto st260;
+	}
+	if ( (*p) < 64 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st260;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st260;
+	} else
+		goto st260;
+	goto st0;
+st139:
+	if ( ++p == pe )
+		goto _test_eof139;
+case 139:
+	switch( (*p) ) {
+		case 37: goto st260;
+		case 117: goto st140;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st260;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st260;
+	} else
+		goto st260;
+	goto st0;
+st140:
+	if ( ++p == pe )
+		goto _test_eof140;
+case 140:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st141;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st141;
+	} else
+		goto st141;
+	goto st0;
+st141:
+	if ( ++p == pe )
+		goto _test_eof141;
+case 141:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st142;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st142;
+	} else
+		goto st142;
+	goto st0;
+st142:
+	if ( ++p == pe )
+		goto _test_eof142;
+case 142:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st143;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st143;
+	} else
+		goto st143;
+	goto st0;
+st143:
+	if ( ++p == pe )
+		goto _test_eof143;
+case 143:
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto st260;
+	} else if ( (*p) > 70 ) {
+		if ( 97 <= (*p) && (*p) <= 102 )
+			goto st260;
+	} else
+		goto st260;
+	goto st0;
+tr322:
+#line 111 "../../src/uri.rl"
+	{
+			/*
+			 * This action is also called for path_* terminals.
+			 * I absolute have no idea why. Please don't blame
+			 * and fix grammar if you have a LOT of free time.
+			 */
+			if (uri->host_hint != 3) {
+				uri->host_hint = 3;
+				uri->host = URI_HOST_UNIX;
+				uri->host_len = strlen(URI_HOST_UNIX);
+				uri->service = s; uri->service_len = p - s;
+				/* a workaround for grammar limitations */
+				uri->path = NULL;
+				uri->path_len = 0;
+			};
+		}
+	goto st261;
+st261:
+	if ( ++p == pe )
+		goto _test_eof261;
+case 261:
+#line 5798 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st260;
+		case 35: goto tr323;
+		case 37: goto st139;
+		case 47: goto tr324;
+		case 58: goto tr322;
+		case 61: goto st260;
+		case 63: goto tr325;
+		case 95: goto st260;
+		case 126: goto st260;
+	}
+	if ( (*p) < 64 ) {
+		if ( 36 <= (*p) && (*p) <= 59 )
+			goto st260;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto st260;
+	} else
+		goto st260;
+	goto st0;
+tr158:
+#line 151 "../../src/uri.rl"
+	{ s = p; }
+#line 137 "../../src/uri.rl"
+	{ s = p; }
+#line 92 "../../src/uri.rl"
+	{ s = p; }
+	goto st262;
+st262:
+	if ( ++p == pe )
+		goto _test_eof262;
+case 262:
+#line 5831 "../../src/uri.c"
+	switch( (*p) ) {
+		case 33: goto st145;
+		case 35: goto tr159;
+		case 37: goto st6;
+		case 43: goto st205;
+		case 47: goto tr161;
+		case 58: goto tr247;
+		case 59: goto st145;
+		case 61: goto st145;
+		case 63: goto tr163;
+		case 64: goto tr164;
+		case 95: goto st145;
+		case 110: goto st263;
+		case 126: goto st145;
+	}
+	if ( (*p) < 45 ) {
+		if ( 36 <= (*p) && (*p) <= 44 )
+			goto st145;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st205;
+		} else if ( (*p) >= 65 )
+			goto st205;
+	} else
+		goto st205;
+	goto st0;
+st263:
+	if ( ++p == pe )
+		goto _test_eof263;
+case 263:
+	switch( (*p) ) {
+		case 33: goto st145;
+		case 35: goto tr159;
+		case 37: goto st6;
+		case 43: goto st205;
+		case 47: goto tr161;
+		case 58: goto tr247;
+		case 59: goto st145;
+		case 61: goto st145;
+		case 63: goto tr163;
+		case 64: goto tr164;
+		case 95: goto st145;
+		case 105: goto st264;
+		case 126: goto st145;
+	}
+	if ( (*p) < 45 ) {
+		if ( 36 <= (*p) && (*p) <= 44 )
+			goto st145;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st205;
+		} else if ( (*p) >= 65 )
+			goto st205;
+	} else
+		goto st205;
+	goto st0;
+st264:
+	if ( ++p == pe )
+		goto _test_eof264;
+case 264:
+	switch( (*p) ) {
+		case 33: goto st145;
+		case 35: goto tr159;
+		case 37: goto st6;
+		case 43: goto st205;
+		case 47: goto tr161;
+		case 58: goto tr247;
+		case 59: goto st145;
+		case 61: goto st145;
+		case 63: goto tr163;
+		case 64: goto tr164;
+		case 95: goto st145;
+		case 120: goto st265;
+		case 126: goto st145;
+	}
+	if ( (*p) < 45 ) {
+		if ( 36 <= (*p) && (*p) <= 44 )
+			goto st145;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st205;
+		} else if ( (*p) >= 65 )
+			goto st205;
+	} else
+		goto st205;
+	goto st0;
+st265:
+	if ( ++p == pe )
+		goto _test_eof265;
+case 265:
+	switch( (*p) ) {
+		case 33: goto st145;
+		case 35: goto tr159;
+		case 37: goto st6;
+		case 43: goto st205;
+		case 47: goto tr311;
+		case 58: goto tr247;
+		case 59: goto st145;
+		case 61: goto st145;
+		case 63: goto tr163;
+		case 64: goto tr164;
+		case 95: goto st145;
+		case 126: goto st145;
+	}
+	if ( (*p) < 45 ) {
+		if ( 36 <= (*p) && (*p) <= 44 )
+			goto st145;
+	} else if ( (*p) > 57 ) {
+		if ( (*p) > 90 ) {
+			if ( 97 <= (*p) && (*p) <= 122 )
+				goto st205;
+		} else if ( (*p) >= 65 )
+			goto st205;
+	} else
+		goto st205;
+	goto st0;
+	}
+	_test_eof145: cs = 145; goto _test_eof; 
+	_test_eof146: cs = 146; goto _test_eof; 
+	_test_eof147: cs = 147; goto _test_eof; 
+	_test_eof1: cs = 1; goto _test_eof; 
+	_test_eof2: cs = 2; goto _test_eof; 
+	_test_eof3: cs = 3; goto _test_eof; 
+	_test_eof4: cs = 4; goto _test_eof; 
+	_test_eof5: cs = 5; goto _test_eof; 
+	_test_eof6: cs = 6; goto _test_eof; 
+	_test_eof7: cs = 7; goto _test_eof; 
+	_test_eof8: cs = 8; goto _test_eof; 
+	_test_eof9: cs = 9; goto _test_eof; 
+	_test_eof10: cs = 10; goto _test_eof; 
+	_test_eof148: cs = 148; goto _test_eof; 
+	_test_eof11: cs = 11; goto _test_eof; 
+	_test_eof12: cs = 12; goto _test_eof; 
+	_test_eof13: cs = 13; goto _test_eof; 
+	_test_eof14: cs = 14; goto _test_eof; 
+	_test_eof15: cs = 15; goto _test_eof; 
+	_test_eof149: cs = 149; goto _test_eof; 
+	_test_eof150: cs = 150; goto _test_eof; 
+	_test_eof16: cs = 16; goto _test_eof; 
+	_test_eof17: cs = 17; goto _test_eof; 
+	_test_eof18: cs = 18; goto _test_eof; 
+	_test_eof19: cs = 19; goto _test_eof; 
+	_test_eof20: cs = 20; goto _test_eof; 
+	_test_eof151: cs = 151; goto _test_eof; 
+	_test_eof21: cs = 21; goto _test_eof; 
+	_test_eof22: cs = 22; goto _test_eof; 
+	_test_eof23: cs = 23; goto _test_eof; 
+	_test_eof24: cs = 24; goto _test_eof; 
+	_test_eof25: cs = 25; goto _test_eof; 
+	_test_eof26: cs = 26; goto _test_eof; 
+	_test_eof27: cs = 27; goto _test_eof; 
+	_test_eof152: cs = 152; goto _test_eof; 
+	_test_eof28: cs = 28; goto _test_eof; 
+	_test_eof29: cs = 29; goto _test_eof; 
+	_test_eof30: cs = 30; goto _test_eof; 
+	_test_eof31: cs = 31; goto _test_eof; 
+	_test_eof32: cs = 32; goto _test_eof; 
+	_test_eof153: cs = 153; goto _test_eof; 
+	_test_eof154: cs = 154; goto _test_eof; 
+	_test_eof155: cs = 155; goto _test_eof; 
+	_test_eof156: cs = 156; goto _test_eof; 
+	_test_eof157: cs = 157; goto _test_eof; 
+	_test_eof33: cs = 33; goto _test_eof; 
+	_test_eof34: cs = 34; goto _test_eof; 
+	_test_eof35: cs = 35; goto _test_eof; 
+	_test_eof36: cs = 36; goto _test_eof; 
+	_test_eof37: cs = 37; goto _test_eof; 
+	_test_eof158: cs = 158; goto _test_eof; 
+	_test_eof159: cs = 159; goto _test_eof; 
+	_test_eof160: cs = 160; goto _test_eof; 
+	_test_eof161: cs = 161; goto _test_eof; 
+	_test_eof162: cs = 162; goto _test_eof; 
+	_test_eof163: cs = 163; goto _test_eof; 
+	_test_eof164: cs = 164; goto _test_eof; 
+	_test_eof165: cs = 165; goto _test_eof; 
+	_test_eof166: cs = 166; goto _test_eof; 
+	_test_eof167: cs = 167; goto _test_eof; 
+	_test_eof168: cs = 168; goto _test_eof; 
+	_test_eof169: cs = 169; goto _test_eof; 
+	_test_eof170: cs = 170; goto _test_eof; 
+	_test_eof171: cs = 171; goto _test_eof; 
+	_test_eof172: cs = 172; goto _test_eof; 
+	_test_eof38: cs = 38; goto _test_eof; 
+	_test_eof39: cs = 39; goto _test_eof; 
+	_test_eof40: cs = 40; goto _test_eof; 
+	_test_eof41: cs = 41; goto _test_eof; 
+	_test_eof42: cs = 42; goto _test_eof; 
+	_test_eof43: cs = 43; goto _test_eof; 
+	_test_eof44: cs = 44; goto _test_eof; 
+	_test_eof45: cs = 45; goto _test_eof; 
+	_test_eof46: cs = 46; goto _test_eof; 
+	_test_eof47: cs = 47; goto _test_eof; 
+	_test_eof48: cs = 48; goto _test_eof; 
+	_test_eof49: cs = 49; goto _test_eof; 
+	_test_eof50: cs = 50; goto _test_eof; 
+	_test_eof51: cs = 51; goto _test_eof; 
+	_test_eof52: cs = 52; goto _test_eof; 
+	_test_eof53: cs = 53; goto _test_eof; 
+	_test_eof54: cs = 54; goto _test_eof; 
+	_test_eof55: cs = 55; goto _test_eof; 
+	_test_eof56: cs = 56; goto _test_eof; 
+	_test_eof57: cs = 57; goto _test_eof; 
+	_test_eof58: cs = 58; goto _test_eof; 
+	_test_eof59: cs = 59; goto _test_eof; 
+	_test_eof60: cs = 60; goto _test_eof; 
+	_test_eof61: cs = 61; goto _test_eof; 
+	_test_eof62: cs = 62; goto _test_eof; 
+	_test_eof63: cs = 63; goto _test_eof; 
+	_test_eof64: cs = 64; goto _test_eof; 
+	_test_eof65: cs = 65; goto _test_eof; 
+	_test_eof66: cs = 66; goto _test_eof; 
+	_test_eof67: cs = 67; goto _test_eof; 
+	_test_eof68: cs = 68; goto _test_eof; 
+	_test_eof69: cs = 69; goto _test_eof; 
+	_test_eof70: cs = 70; goto _test_eof; 
+	_test_eof71: cs = 71; goto _test_eof; 
+	_test_eof72: cs = 72; goto _test_eof; 
+	_test_eof73: cs = 73; goto _test_eof; 
+	_test_eof74: cs = 74; goto _test_eof; 
+	_test_eof75: cs = 75; goto _test_eof; 
+	_test_eof76: cs = 76; goto _test_eof; 
+	_test_eof77: cs = 77; goto _test_eof; 
+	_test_eof78: cs = 78; goto _test_eof; 
+	_test_eof79: cs = 79; goto _test_eof; 
+	_test_eof80: cs = 80; goto _test_eof; 
+	_test_eof81: cs = 81; goto _test_eof; 
+	_test_eof82: cs = 82; goto _test_eof; 
+	_test_eof173: cs = 173; goto _test_eof; 
+	_test_eof83: cs = 83; goto _test_eof; 
+	_test_eof84: cs = 84; goto _test_eof; 
+	_test_eof85: cs = 85; goto _test_eof; 
+	_test_eof86: cs = 86; goto _test_eof; 
+	_test_eof87: cs = 87; goto _test_eof; 
+	_test_eof88: cs = 88; goto _test_eof; 
+	_test_eof89: cs = 89; goto _test_eof; 
+	_test_eof90: cs = 90; goto _test_eof; 
+	_test_eof91: cs = 91; goto _test_eof; 
+	_test_eof92: cs = 92; goto _test_eof; 
+	_test_eof93: cs = 93; goto _test_eof; 
+	_test_eof94: cs = 94; goto _test_eof; 
+	_test_eof95: cs = 95; goto _test_eof; 
+	_test_eof96: cs = 96; goto _test_eof; 
+	_test_eof97: cs = 97; goto _test_eof; 
+	_test_eof98: cs = 98; goto _test_eof; 
+	_test_eof99: cs = 99; goto _test_eof; 
+	_test_eof100: cs = 100; goto _test_eof; 
+	_test_eof101: cs = 101; goto _test_eof; 
+	_test_eof102: cs = 102; goto _test_eof; 
+	_test_eof103: cs = 103; goto _test_eof; 
+	_test_eof174: cs = 174; goto _test_eof; 
+	_test_eof175: cs = 175; goto _test_eof; 
+	_test_eof176: cs = 176; goto _test_eof; 
+	_test_eof177: cs = 177; goto _test_eof; 
+	_test_eof178: cs = 178; goto _test_eof; 
+	_test_eof179: cs = 179; goto _test_eof; 
+	_test_eof180: cs = 180; goto _test_eof; 
+	_test_eof104: cs = 104; goto _test_eof; 
+	_test_eof105: cs = 105; goto _test_eof; 
+	_test_eof106: cs = 106; goto _test_eof; 
+	_test_eof107: cs = 107; goto _test_eof; 
+	_test_eof108: cs = 108; goto _test_eof; 
+	_test_eof181: cs = 181; goto _test_eof; 
+	_test_eof109: cs = 109; goto _test_eof; 
+	_test_eof110: cs = 110; goto _test_eof; 
+	_test_eof111: cs = 111; goto _test_eof; 
+	_test_eof112: cs = 112; goto _test_eof; 
+	_test_eof113: cs = 113; goto _test_eof; 
+	_test_eof182: cs = 182; goto _test_eof; 
+	_test_eof183: cs = 183; goto _test_eof; 
+	_test_eof184: cs = 184; goto _test_eof; 
+	_test_eof185: cs = 185; goto _test_eof; 
+	_test_eof186: cs = 186; goto _test_eof; 
+	_test_eof187: cs = 187; goto _test_eof; 
+	_test_eof114: cs = 114; goto _test_eof; 
+	_test_eof115: cs = 115; goto _test_eof; 
+	_test_eof116: cs = 116; goto _test_eof; 
+	_test_eof117: cs = 117; goto _test_eof; 
+	_test_eof118: cs = 118; goto _test_eof; 
+	_test_eof188: cs = 188; goto _test_eof; 
+	_test_eof189: cs = 189; goto _test_eof; 
+	_test_eof190: cs = 190; goto _test_eof; 
+	_test_eof191: cs = 191; goto _test_eof; 
+	_test_eof192: cs = 192; goto _test_eof; 
+	_test_eof193: cs = 193; goto _test_eof; 
+	_test_eof194: cs = 194; goto _test_eof; 
+	_test_eof195: cs = 195; goto _test_eof; 
+	_test_eof196: cs = 196; goto _test_eof; 
+	_test_eof197: cs = 197; goto _test_eof; 
+	_test_eof198: cs = 198; goto _test_eof; 
+	_test_eof199: cs = 199; goto _test_eof; 
+	_test_eof200: cs = 200; goto _test_eof; 
+	_test_eof201: cs = 201; goto _test_eof; 
+	_test_eof202: cs = 202; goto _test_eof; 
+	_test_eof203: cs = 203; goto _test_eof; 
+	_test_eof204: cs = 204; goto _test_eof; 
+	_test_eof205: cs = 205; goto _test_eof; 
+	_test_eof206: cs = 206; goto _test_eof; 
+	_test_eof207: cs = 207; goto _test_eof; 
+	_test_eof208: cs = 208; goto _test_eof; 
+	_test_eof209: cs = 209; goto _test_eof; 
+	_test_eof119: cs = 119; goto _test_eof; 
+	_test_eof120: cs = 120; goto _test_eof; 
+	_test_eof121: cs = 121; goto _test_eof; 
+	_test_eof122: cs = 122; goto _test_eof; 
+	_test_eof123: cs = 123; goto _test_eof; 
+	_test_eof210: cs = 210; goto _test_eof; 
+	_test_eof211: cs = 211; goto _test_eof; 
+	_test_eof124: cs = 124; goto _test_eof; 
+	_test_eof125: cs = 125; goto _test_eof; 
+	_test_eof126: cs = 126; goto _test_eof; 
+	_test_eof127: cs = 127; goto _test_eof; 
+	_test_eof128: cs = 128; goto _test_eof; 
+	_test_eof212: cs = 212; goto _test_eof; 
+	_test_eof213: cs = 213; goto _test_eof; 
+	_test_eof129: cs = 129; goto _test_eof; 
+	_test_eof130: cs = 130; goto _test_eof; 
+	_test_eof131: cs = 131; goto _test_eof; 
+	_test_eof132: cs = 132; goto _test_eof; 
+	_test_eof133: cs = 133; goto _test_eof; 
+	_test_eof214: cs = 214; goto _test_eof; 
+	_test_eof215: cs = 215; goto _test_eof; 
+	_test_eof216: cs = 216; goto _test_eof; 
+	_test_eof217: cs = 217; goto _test_eof; 
+	_test_eof218: cs = 218; goto _test_eof; 
+	_test_eof219: cs = 219; goto _test_eof; 
+	_test_eof220: cs = 220; goto _test_eof; 
+	_test_eof221: cs = 221; goto _test_eof; 
+	_test_eof222: cs = 222; goto _test_eof; 
+	_test_eof223: cs = 223; goto _test_eof; 
+	_test_eof224: cs = 224; goto _test_eof; 
+	_test_eof225: cs = 225; goto _test_eof; 
+	_test_eof226: cs = 226; goto _test_eof; 
+	_test_eof227: cs = 227; goto _test_eof; 
+	_test_eof228: cs = 228; goto _test_eof; 
+	_test_eof229: cs = 229; goto _test_eof; 
+	_test_eof230: cs = 230; goto _test_eof; 
+	_test_eof231: cs = 231; goto _test_eof; 
+	_test_eof232: cs = 232; goto _test_eof; 
+	_test_eof233: cs = 233; goto _test_eof; 
+	_test_eof234: cs = 234; goto _test_eof; 
+	_test_eof235: cs = 235; goto _test_eof; 
+	_test_eof236: cs = 236; goto _test_eof; 
+	_test_eof237: cs = 237; goto _test_eof; 
+	_test_eof238: cs = 238; goto _test_eof; 
+	_test_eof239: cs = 239; goto _test_eof; 
+	_test_eof240: cs = 240; goto _test_eof; 
+	_test_eof241: cs = 241; goto _test_eof; 
+	_test_eof242: cs = 242; goto _test_eof; 
+	_test_eof243: cs = 243; goto _test_eof; 
+	_test_eof244: cs = 244; goto _test_eof; 
+	_test_eof245: cs = 245; goto _test_eof; 
+	_test_eof246: cs = 246; goto _test_eof; 
+	_test_eof247: cs = 247; goto _test_eof; 
+	_test_eof248: cs = 248; goto _test_eof; 
+	_test_eof249: cs = 249; goto _test_eof; 
+	_test_eof250: cs = 250; goto _test_eof; 
+	_test_eof251: cs = 251; goto _test_eof; 
+	_test_eof252: cs = 252; goto _test_eof; 
+	_test_eof253: cs = 253; goto _test_eof; 
+	_test_eof254: cs = 254; goto _test_eof; 
+	_test_eof255: cs = 255; goto _test_eof; 
+	_test_eof256: cs = 256; goto _test_eof; 
+	_test_eof257: cs = 257; goto _test_eof; 
+	_test_eof258: cs = 258; goto _test_eof; 
+	_test_eof259: cs = 259; goto _test_eof; 
+	_test_eof134: cs = 134; goto _test_eof; 
+	_test_eof135: cs = 135; goto _test_eof; 
+	_test_eof136: cs = 136; goto _test_eof; 
+	_test_eof137: cs = 137; goto _test_eof; 
+	_test_eof138: cs = 138; goto _test_eof; 
+	_test_eof260: cs = 260; goto _test_eof; 
+	_test_eof139: cs = 139; goto _test_eof; 
+	_test_eof140: cs = 140; goto _test_eof; 
+	_test_eof141: cs = 141; goto _test_eof; 
+	_test_eof142: cs = 142; goto _test_eof; 
+	_test_eof143: cs = 143; goto _test_eof; 
+	_test_eof261: cs = 261; goto _test_eof; 
+	_test_eof262: cs = 262; goto _test_eof; 
+	_test_eof263: cs = 263; goto _test_eof; 
+	_test_eof264: cs = 264; goto _test_eof; 
+	_test_eof265: cs = 265; goto _test_eof; 
+
+	_test_eof: {}
+	if ( p == eof )
+	{
+	switch ( cs ) {
+	case 150: 
+#line 69 "../../src/uri.rl"
+	{ uri->query = s; uri->query_len = p - s; }
+	break;
+	case 147: 
+#line 73 "../../src/uri.rl"
+	{ uri->fragment = s; uri->fragment_len = p - s; }
+	break;
+	case 156: 
+	case 157: 
+#line 111 "../../src/uri.rl"
+	{
+			/*
+			 * This action is also called for path_* terminals.
+			 * I absolute have no idea why. Please don't blame
+			 * and fix grammar if you have a LOT of free time.
+			 */
+			if (uri->host_hint != 3) {
+				uri->host_hint = 3;
+				uri->host = URI_HOST_UNIX;
+				uri->host_len = strlen(URI_HOST_UNIX);
+				uri->service = s; uri->service_len = p - s;
+				/* a workaround for grammar limitations */
+				uri->path = NULL;
+				uri->path_len = 0;
+			};
+		}
+	break;
+	case 144: 
+	case 148: 
+	case 178: 
+	case 179: 
+	case 180: 
+	case 181: 
+	case 204: 
+	case 207: 
+	case 208: 
+	case 211: 
+	case 212: 
+	case 257: 
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+	break;
+	case 149: 
+#line 68 "../../src/uri.rl"
+	{ s = p; }
+#line 69 "../../src/uri.rl"
+	{ uri->query = s; uri->query_len = p - s; }
+	break;
+	case 146: 
+#line 72 "../../src/uri.rl"
+	{ s = p; }
+#line 73 "../../src/uri.rl"
+	{ uri->fragment = s; uri->fragment_len = p - s; }
+	break;
+	case 173: 
+	case 182: 
+	case 183: 
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+	break;
+	case 186: 
+	case 187: 
+	case 259: 
+	case 260: 
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+#line 111 "../../src/uri.rl"
+	{
+			/*
+			 * This action is also called for path_* terminals.
+			 * I absolute have no idea why. Please don't blame
+			 * and fix grammar if you have a LOT of free time.
+			 */
+			if (uri->host_hint != 3) {
+				uri->host_hint = 3;
+				uri->host = URI_HOST_UNIX;
+				uri->host_len = strlen(URI_HOST_UNIX);
+				uri->service = s; uri->service_len = p - s;
+				/* a workaround for grammar limitations */
+				uri->path = NULL;
+				uri->path_len = 0;
+			};
+		}
+	break;
+	case 145: 
+	case 152: 
+	case 158: 
+	case 159: 
+	case 160: 
+	case 161: 
+	case 162: 
+	case 163: 
+	case 167: 
+	case 168: 
+	case 169: 
+	case 170: 
+	case 171: 
+	case 172: 
+	case 174: 
+	case 175: 
+	case 176: 
+	case 177: 
+	case 189: 
+	case 190: 
+	case 191: 
+	case 192: 
+	case 193: 
+	case 197: 
+	case 198: 
+	case 199: 
+	case 200: 
+	case 205: 
+	case 209: 
+	case 213: 
+	case 217: 
+	case 218: 
+	case 219: 
+	case 220: 
+	case 221: 
+	case 222: 
+	case 226: 
+	case 227: 
+	case 228: 
+	case 229: 
+	case 230: 
+	case 231: 
+	case 232: 
+	case 233: 
+	case 234: 
+	case 235: 
+	case 238: 
+	case 239: 
+	case 240: 
+	case 241: 
+	case 242: 
+	case 243: 
+	case 247: 
+	case 248: 
+	case 249: 
+	case 250: 
+	case 251: 
+	case 252: 
+	case 253: 
+	case 254: 
+	case 255: 
+	case 256: 
+	case 262: 
+	case 263: 
+	case 264: 
+	case 265: 
+#line 93 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;}
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+	break;
+	case 154: 
+	case 155: 
+	case 184: 
+	case 185: 
+	case 215: 
+	case 216: 
+	case 236: 
+	case 237: 
+#line 132 "../../src/uri.rl"
+	{ uri->service = s; uri->service_len = p - s; }
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+	break;
+	case 261: 
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+#line 111 "../../src/uri.rl"
+	{
+			/*
+			 * This action is also called for path_* terminals.
+			 * I absolute have no idea why. Please don't blame
+			 * and fix grammar if you have a LOT of free time.
+			 */
+			if (uri->host_hint != 3) {
+				uri->host_hint = 3;
+				uri->host = URI_HOST_UNIX;
+				uri->host_len = strlen(URI_HOST_UNIX);
+				uri->service = s; uri->service_len = p - s;
+				/* a workaround for grammar limitations */
+				uri->path = NULL;
+				uri->path_len = 0;
+			};
+		}
+	break;
+	case 258: 
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+#line 128 "../../src/uri.rl"
+	{ s = p;}
+#line 111 "../../src/uri.rl"
+	{
+			/*
+			 * This action is also called for path_* terminals.
+			 * I absolute have no idea why. Please don't blame
+			 * and fix grammar if you have a LOT of free time.
+			 */
+			if (uri->host_hint != 3) {
+				uri->host_hint = 3;
+				uri->host = URI_HOST_UNIX;
+				uri->host_len = strlen(URI_HOST_UNIX);
+				uri->service = s; uri->service_len = p - s;
+				/* a workaround for grammar limitations */
+				uri->path = NULL;
+				uri->path_len = 0;
+			};
+		}
+	break;
+	case 188: 
+	case 201: 
+	case 202: 
+	case 203: 
+#line 93 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;}
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+#line 179 "../../src/uri.rl"
+	{ uri->service_len = p - uri->service;
+			   uri->host = NULL; uri->host_len = 0; }
+	break;
+	case 164: 
+	case 165: 
+	case 166: 
+	case 194: 
+	case 195: 
+	case 196: 
+	case 223: 
+	case 224: 
+	case 225: 
+	case 244: 
+	case 245: 
+	case 246: 
+#line 100 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;
+			   uri->host_hint = 1; }
+#line 93 "../../src/uri.rl"
+	{ uri->host = s; uri->host_len = p - s;}
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+	break;
+	case 151: 
+	case 153: 
+	case 206: 
+	case 210: 
+	case 214: 
+#line 131 "../../src/uri.rl"
+	{ s = p; }
+#line 132 "../../src/uri.rl"
+	{ uri->service = s; uri->service_len = p - s; }
+#line 161 "../../src/uri.rl"
+	{ s = p; }
+#line 165 "../../src/uri.rl"
+	{ uri->path = s; uri->path_len = p - s; }
+	break;
+#line 6492 "../../src/uri.c"
+	}
+	}
+
+	_out: {}
+	}
+
+#line 192 "../../src/uri.rl"
+
+
+	if (uri->path_len == 0)
+		uri->path = NULL;
+	if (uri->service_len == 0)
+		uri->service = NULL;
+	if (uri->service_len >= URI_MAXSERVICE)
+		return -1;
+	if (uri->host_len >= URI_MAXHOST)
+		return -1;
+
+	(void)uri_first_final;
+	(void)uri_error;
+	(void)uri_en_main;
+	(void)eof;
+
+	return cs >= uri_first_final ? 0 : -1;
+}
+
+char *
+uri_format(const struct uri *uri)
+{
+	static char buf[1024];
+	/* very primitive implementation suitable for our needs */
+	snprintf(buf, sizeof(buf), "%.*s:%.*s",
+		 (int) uri->host_len, uri->host != NULL ? uri->host : "*",
+		 (int) uri->service_len, uri->service);
+	return buf;
+}
+/* vim: set ft=ragel: */
diff --git a/src/uri.cc b/src/uri.cc
deleted file mode 100644
index d970ef6ee7c4298af81a356ef1d1c84e854848fb..0000000000000000000000000000000000000000
--- a/src/uri.cc
+++ /dev/null
@@ -1,5538 +0,0 @@
-
-#line 1 "src/uri.rl"
-/*
- * Redistribution and use in source and binary forms, with or
- * without modification, 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 <COPYRIGHT HOLDER> ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, 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 OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-#include "uri.h"
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include <sys/socket.h>
-#include <netinet/ip.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/un.h>
-#include <netdb.h>
-
-const char *
-uri_to_string(const struct uri * uri)
-{
-	static __thread char
-		str[NI_MAXSERV + NI_MAXHOST + sizeof(uri->schema)];
-
-	if (!uri || !uri->addr_len) {
-		snprintf(str, sizeof(str), "unknown address");
-		return str;
-	}
-
-	switch (uri->addr.sa_family) {
-	case AF_INET6:
-	case AF_INET:
-	{
-		char shost[NI_MAXHOST];
-		char sservice[NI_MAXSERV];
-		getnameinfo(
-			    (struct sockaddr *)&uri->addr,
-			    uri->addr_len,
-			    shost, sizeof(shost),
-			    sservice, sizeof(sservice),
-			    NI_NUMERICHOST|NI_NUMERICSERV);
-		if (uri->addr.sa_family == AF_INET) {
-			if (strncmp(uri->schema, "tcp", 3) == 0) {
-				snprintf(str, sizeof(str), "%s:%s",
-					 shost, sservice);
-			} else {
-				snprintf(str, sizeof(str), "%s://%s:%s",
-					 uri->schema, shost, sservice);
-			}
-		} else {
-			if (strncmp(uri->schema, "tcp", 3) == 0) {
-				snprintf(str, sizeof(str), "%s:%s",
-					 shost, sservice);
-			} else {
-				snprintf(str, sizeof(str), "%s://[%s]:%s",
-					 uri->schema, shost, sservice);
-			}
-		}
-                break;
-	}
-	case AF_UNIX:
-	{
-		struct sockaddr_un *un =
-			(struct sockaddr_un *)&uri->addr;
-		snprintf(str, sizeof(str), "unix://%.*s",
-			 (int) sizeof(un->sun_path), un->sun_path);
-	        break;
-	}
-	default:
-		snprintf(str, sizeof(str), "unknown address");
-	        break;
-	}
-	return str;
-}
-
-int
-uri_parse(struct uri *uri, const char *p)
-{
-	(void) uri;
-	const char *pe = p + strlen(p);
-	const char *eof = pe;
-	int cs;
-	memset(uri, 0, sizeof(*uri));
-
-	struct {
-		const char *start;
-		const char *end;
-	}	schema		= { 0, 0 },
-		host		= { 0, 0 },
-		service		= { 0, 0 },
-		sport		= { 0, 0 },
-		login		= { 0, 0 },
-		password	= { 0, 0 },
-		ip4		= { 0, 0 },
-		ip6		= { 0, 0 },
-		path		= { 0, 0 },
-		dport		= { 0, 0 }
-	;
-
-	unsigned port = 0;
-
-	
-#line 128 "src/uri.cc"
-static const int uri_start = 1;
-static const int uri_first_final = 74;
-static const int uri_error = 0;
-
-static const int uri_en_main = 1;
-
-
-#line 136 "src/uri.cc"
-	{
-	cs = uri_start;
-	}
-
-#line 141 "src/uri.cc"
-	{
-	if ( p == pe )
-		goto _test_eof;
-	switch ( cs )
-	{
-case 1:
-	switch( (*p) ) {
-		case 47: goto tr1;
-		case 48: goto tr2;
-		case 58: goto st0;
-		case 63: goto st0;
-		case 91: goto tr6;
-		case 117: goto tr7;
-	}
-	if ( (*p) < 65 ) {
-		if ( 49 <= (*p) && (*p) <= 57 )
-			goto tr3;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr5;
-	} else
-		goto tr5;
-	goto tr0;
-tr0:
-#line 157 "src/uri.rl"
-	{ host.start   = p; }
-	goto st74;
-tr82:
-#line 133 "src/uri.rl"
-	{ schema.end   = p - 3; }
-#line 157 "src/uri.rl"
-	{ host.start   = p; }
-	goto st74;
-st74:
-	if ( ++p == pe )
-		goto _test_eof74;
-case 74:
-#line 179 "src/uri.cc"
-	switch( (*p) ) {
-		case 58: goto tr94;
-		case 63: goto st0;
-	}
-	goto st74;
-tr94:
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-	goto st2;
-tr144:
-#line 145 "src/uri.rl"
-	{ ip4.end   = p; }
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-	goto st2;
-tr157:
-#line 154 "src/uri.rl"
-	{ ip6.end   = p - 1; }
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-	goto st2;
-st2:
-	if ( ++p == pe )
-		goto _test_eof2;
-case 2:
-#line 205 "src/uri.cc"
-	if ( (*p) < 65 ) {
-		if ( 49 <= (*p) && (*p) <= 57 )
-			goto tr8;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr9;
-	} else
-		goto tr9;
-	goto st0;
-st0:
-cs = 0;
-	goto _out;
-tr8:
-#line 166 "src/uri.rl"
-	{ service.start = p; }
-#line 161 "src/uri.rl"
-	{ dport.start   = p; port = 0; }
-#line 162 "src/uri.rl"
-	{ port = port * 10 + (int)(*p - '0'); }
-	goto st75;
-tr95:
-#line 162 "src/uri.rl"
-	{ port = port * 10 + (int)(*p - '0'); }
-	goto st75;
-st75:
-	if ( ++p == pe )
-		goto _test_eof75;
-case 75:
-#line 234 "src/uri.cc"
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto tr95;
-	goto st0;
-tr9:
-#line 166 "src/uri.rl"
-	{ service.start = p; }
-	goto st76;
-st76:
-	if ( ++p == pe )
-		goto _test_eof76;
-case 76:
-#line 246 "src/uri.cc"
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st77;
-	} else if ( (*p) >= 65 )
-		goto st77;
-	goto st0;
-st77:
-	if ( ++p == pe )
-		goto _test_eof77;
-case 77:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st78;
-	} else if ( (*p) >= 65 )
-		goto st78;
-	goto st0;
-st78:
-	if ( ++p == pe )
-		goto _test_eof78;
-case 78:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st79;
-	} else if ( (*p) >= 65 )
-		goto st79;
-	goto st0;
-st79:
-	if ( ++p == pe )
-		goto _test_eof79;
-case 79:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st80;
-	} else if ( (*p) >= 65 )
-		goto st80;
-	goto st0;
-st80:
-	if ( ++p == pe )
-		goto _test_eof80;
-case 80:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st81;
-	} else if ( (*p) >= 65 )
-		goto st81;
-	goto st0;
-st81:
-	if ( ++p == pe )
-		goto _test_eof81;
-case 81:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st82;
-	} else if ( (*p) >= 65 )
-		goto st82;
-	goto st0;
-st82:
-	if ( ++p == pe )
-		goto _test_eof82;
-case 82:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st83;
-	} else if ( (*p) >= 65 )
-		goto st83;
-	goto st0;
-st83:
-	if ( ++p == pe )
-		goto _test_eof83;
-case 83:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st84;
-	} else if ( (*p) >= 65 )
-		goto st84;
-	goto st0;
-st84:
-	if ( ++p == pe )
-		goto _test_eof84;
-case 84:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st85;
-	} else if ( (*p) >= 65 )
-		goto st85;
-	goto st0;
-st85:
-	if ( ++p == pe )
-		goto _test_eof85;
-case 85:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st86;
-	} else if ( (*p) >= 65 )
-		goto st86;
-	goto st0;
-st86:
-	if ( ++p == pe )
-		goto _test_eof86;
-case 86:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st87;
-	} else if ( (*p) >= 65 )
-		goto st87;
-	goto st0;
-st87:
-	if ( ++p == pe )
-		goto _test_eof87;
-case 87:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st88;
-	} else if ( (*p) >= 65 )
-		goto st88;
-	goto st0;
-st88:
-	if ( ++p == pe )
-		goto _test_eof88;
-case 88:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st89;
-	} else if ( (*p) >= 65 )
-		goto st89;
-	goto st0;
-st89:
-	if ( ++p == pe )
-		goto _test_eof89;
-case 89:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st90;
-	} else if ( (*p) >= 65 )
-		goto st90;
-	goto st0;
-st90:
-	if ( ++p == pe )
-		goto _test_eof90;
-case 90:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st91;
-	} else if ( (*p) >= 65 )
-		goto st91;
-	goto st0;
-st91:
-	if ( ++p == pe )
-		goto _test_eof91;
-case 91:
-	goto st0;
-tr1:
-#line 157 "src/uri.rl"
-	{ host.start   = p; }
-#line 176 "src/uri.rl"
-	{ path.start = p; }
-	goto st92;
-st92:
-	if ( ++p == pe )
-		goto _test_eof92;
-case 92:
-#line 408 "src/uri.cc"
-	switch( (*p) ) {
-		case 58: goto tr112;
-		case 63: goto st95;
-	}
-	goto st93;
-st93:
-	if ( ++p == pe )
-		goto _test_eof93;
-case 93:
-	switch( (*p) ) {
-		case 58: goto tr112;
-		case 63: goto st95;
-	}
-	goto st93;
-tr112:
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-	goto st94;
-st94:
-	if ( ++p == pe )
-		goto _test_eof94;
-case 94:
-#line 431 "src/uri.cc"
-	if ( (*p) < 65 ) {
-		if ( 49 <= (*p) && (*p) <= 57 )
-			goto tr114;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr115;
-	} else
-		goto tr115;
-	goto st95;
-st95:
-	if ( ++p == pe )
-		goto _test_eof95;
-case 95:
-	goto st95;
-tr114:
-#line 166 "src/uri.rl"
-	{ service.start = p; }
-#line 161 "src/uri.rl"
-	{ dport.start   = p; port = 0; }
-#line 162 "src/uri.rl"
-	{ port = port * 10 + (int)(*p - '0'); }
-	goto st96;
-tr116:
-#line 162 "src/uri.rl"
-	{ port = port * 10 + (int)(*p - '0'); }
-	goto st96;
-st96:
-	if ( ++p == pe )
-		goto _test_eof96;
-case 96:
-#line 462 "src/uri.cc"
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto tr116;
-	goto st95;
-tr115:
-#line 166 "src/uri.rl"
-	{ service.start = p; }
-	goto st97;
-st97:
-	if ( ++p == pe )
-		goto _test_eof97;
-case 97:
-#line 474 "src/uri.cc"
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st98;
-	} else if ( (*p) >= 65 )
-		goto st98;
-	goto st95;
-st98:
-	if ( ++p == pe )
-		goto _test_eof98;
-case 98:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st99;
-	} else if ( (*p) >= 65 )
-		goto st99;
-	goto st95;
-st99:
-	if ( ++p == pe )
-		goto _test_eof99;
-case 99:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st100;
-	} else if ( (*p) >= 65 )
-		goto st100;
-	goto st95;
-st100:
-	if ( ++p == pe )
-		goto _test_eof100;
-case 100:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st101;
-	} else if ( (*p) >= 65 )
-		goto st101;
-	goto st95;
-st101:
-	if ( ++p == pe )
-		goto _test_eof101;
-case 101:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st102;
-	} else if ( (*p) >= 65 )
-		goto st102;
-	goto st95;
-st102:
-	if ( ++p == pe )
-		goto _test_eof102;
-case 102:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st103;
-	} else if ( (*p) >= 65 )
-		goto st103;
-	goto st95;
-st103:
-	if ( ++p == pe )
-		goto _test_eof103;
-case 103:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st104;
-	} else if ( (*p) >= 65 )
-		goto st104;
-	goto st95;
-st104:
-	if ( ++p == pe )
-		goto _test_eof104;
-case 104:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st105;
-	} else if ( (*p) >= 65 )
-		goto st105;
-	goto st95;
-st105:
-	if ( ++p == pe )
-		goto _test_eof105;
-case 105:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st106;
-	} else if ( (*p) >= 65 )
-		goto st106;
-	goto st95;
-st106:
-	if ( ++p == pe )
-		goto _test_eof106;
-case 106:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st107;
-	} else if ( (*p) >= 65 )
-		goto st107;
-	goto st95;
-st107:
-	if ( ++p == pe )
-		goto _test_eof107;
-case 107:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st108;
-	} else if ( (*p) >= 65 )
-		goto st108;
-	goto st95;
-st108:
-	if ( ++p == pe )
-		goto _test_eof108;
-case 108:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st109;
-	} else if ( (*p) >= 65 )
-		goto st109;
-	goto st95;
-st109:
-	if ( ++p == pe )
-		goto _test_eof109;
-case 109:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st110;
-	} else if ( (*p) >= 65 )
-		goto st110;
-	goto st95;
-st110:
-	if ( ++p == pe )
-		goto _test_eof110;
-case 110:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st111;
-	} else if ( (*p) >= 65 )
-		goto st111;
-	goto st95;
-st111:
-	if ( ++p == pe )
-		goto _test_eof111;
-case 111:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st112;
-	} else if ( (*p) >= 65 )
-		goto st112;
-	goto st95;
-st112:
-	if ( ++p == pe )
-		goto _test_eof112;
-case 112:
-	goto st95;
-tr2:
-#line 136 "src/uri.rl"
-	{ login.start  = p; }
-#line 157 "src/uri.rl"
-	{ host.start   = p; }
-#line 144 "src/uri.rl"
-	{ ip4.start = p; }
-	goto st113;
-tr83:
-#line 133 "src/uri.rl"
-	{ schema.end   = p - 3; }
-#line 136 "src/uri.rl"
-	{ login.start  = p; }
-#line 157 "src/uri.rl"
-	{ host.start   = p; }
-#line 144 "src/uri.rl"
-	{ ip4.start = p; }
-	goto st113;
-st113:
-	if ( ++p == pe )
-		goto _test_eof113;
-case 113:
-#line 648 "src/uri.cc"
-	switch( (*p) ) {
-		case 46: goto st114;
-		case 58: goto tr134;
-		case 63: goto st0;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st126;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st128;
-	} else
-		goto st128;
-	goto st74;
-st114:
-	if ( ++p == pe )
-		goto _test_eof114;
-case 114:
-	switch( (*p) ) {
-		case 58: goto tr94;
-		case 63: goto st0;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st115;
-	goto st74;
-st115:
-	if ( ++p == pe )
-		goto _test_eof115;
-case 115:
-	switch( (*p) ) {
-		case 46: goto st116;
-		case 58: goto tr94;
-		case 63: goto st0;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st124;
-	goto st74;
-st116:
-	if ( ++p == pe )
-		goto _test_eof116;
-case 116:
-	switch( (*p) ) {
-		case 58: goto tr94;
-		case 63: goto st0;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st117;
-	goto st74;
-st117:
-	if ( ++p == pe )
-		goto _test_eof117;
-case 117:
-	switch( (*p) ) {
-		case 46: goto st118;
-		case 58: goto tr94;
-		case 63: goto st0;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st122;
-	goto st74;
-st118:
-	if ( ++p == pe )
-		goto _test_eof118;
-case 118:
-	switch( (*p) ) {
-		case 58: goto tr94;
-		case 63: goto st0;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st119;
-	goto st74;
-st119:
-	if ( ++p == pe )
-		goto _test_eof119;
-case 119:
-	switch( (*p) ) {
-		case 58: goto tr144;
-		case 63: goto st0;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st120;
-	goto st74;
-st120:
-	if ( ++p == pe )
-		goto _test_eof120;
-case 120:
-	switch( (*p) ) {
-		case 58: goto tr144;
-		case 63: goto st0;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st121;
-	goto st74;
-st121:
-	if ( ++p == pe )
-		goto _test_eof121;
-case 121:
-	switch( (*p) ) {
-		case 58: goto tr144;
-		case 63: goto st0;
-	}
-	goto st74;
-st122:
-	if ( ++p == pe )
-		goto _test_eof122;
-case 122:
-	switch( (*p) ) {
-		case 46: goto st118;
-		case 58: goto tr94;
-		case 63: goto st0;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st123;
-	goto st74;
-st123:
-	if ( ++p == pe )
-		goto _test_eof123;
-case 123:
-	switch( (*p) ) {
-		case 46: goto st118;
-		case 58: goto tr94;
-		case 63: goto st0;
-	}
-	goto st74;
-st124:
-	if ( ++p == pe )
-		goto _test_eof124;
-case 124:
-	switch( (*p) ) {
-		case 46: goto st116;
-		case 58: goto tr94;
-		case 63: goto st0;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st125;
-	goto st74;
-st125:
-	if ( ++p == pe )
-		goto _test_eof125;
-case 125:
-	switch( (*p) ) {
-		case 46: goto st116;
-		case 58: goto tr94;
-		case 63: goto st0;
-	}
-	goto st74;
-st126:
-	if ( ++p == pe )
-		goto _test_eof126;
-case 126:
-	switch( (*p) ) {
-		case 46: goto st114;
-		case 58: goto tr134;
-		case 63: goto st0;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st127;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st128;
-	} else
-		goto st128;
-	goto st74;
-st127:
-	if ( ++p == pe )
-		goto _test_eof127;
-case 127:
-	switch( (*p) ) {
-		case 46: goto st114;
-		case 58: goto tr134;
-		case 63: goto st0;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st128;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st128;
-	} else
-		goto st128;
-	goto st74;
-tr84:
-#line 133 "src/uri.rl"
-	{ schema.end   = p - 3; }
-#line 136 "src/uri.rl"
-	{ login.start  = p; }
-#line 157 "src/uri.rl"
-	{ host.start   = p; }
-	goto st128;
-st128:
-	if ( ++p == pe )
-		goto _test_eof128;
-case 128:
-#line 843 "src/uri.cc"
-	switch( (*p) ) {
-		case 58: goto tr134;
-		case 63: goto st0;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st128;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st128;
-	} else
-		goto st128;
-	goto st74;
-tr134:
-#line 137 "src/uri.rl"
-	{ login.end    = p; }
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-	goto st3;
-st3:
-	if ( ++p == pe )
-		goto _test_eof3;
-case 3:
-#line 867 "src/uri.cc"
-	if ( (*p) == 48 )
-		goto tr10;
-	if ( (*p) < 65 ) {
-		if ( 49 <= (*p) && (*p) <= 57 )
-			goto tr11;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr12;
-	} else
-		goto tr12;
-	goto st0;
-tr10:
-#line 140 "src/uri.rl"
-	{ password.start = p; }
-	goto st4;
-st4:
-	if ( ++p == pe )
-		goto _test_eof4;
-case 4:
-#line 887 "src/uri.cc"
-	if ( (*p) == 64 )
-		goto tr14;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st4;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st4;
-	} else
-		goto st4;
-	goto st0;
-tr14:
-#line 141 "src/uri.rl"
-	{ password.end   = p; }
-	goto st5;
-st5:
-	if ( ++p == pe )
-		goto _test_eof5;
-case 5:
-#line 907 "src/uri.cc"
-	switch( (*p) ) {
-		case 58: goto st0;
-		case 63: goto st0;
-		case 91: goto tr6;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto tr15;
-	goto tr0;
-tr15:
-#line 157 "src/uri.rl"
-	{ host.start   = p; }
-#line 144 "src/uri.rl"
-	{ ip4.start = p; }
-	goto st129;
-st129:
-	if ( ++p == pe )
-		goto _test_eof129;
-case 129:
-#line 926 "src/uri.cc"
-	switch( (*p) ) {
-		case 46: goto st114;
-		case 58: goto tr94;
-		case 63: goto st0;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st130;
-	goto st74;
-st130:
-	if ( ++p == pe )
-		goto _test_eof130;
-case 130:
-	switch( (*p) ) {
-		case 46: goto st114;
-		case 58: goto tr94;
-		case 63: goto st0;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st131;
-	goto st74;
-st131:
-	if ( ++p == pe )
-		goto _test_eof131;
-case 131:
-	switch( (*p) ) {
-		case 46: goto st114;
-		case 58: goto tr94;
-		case 63: goto st0;
-	}
-	goto st74;
-tr6:
-#line 157 "src/uri.rl"
-	{ host.start   = p; }
-#line 153 "src/uri.rl"
-	{ ip6.start = p + 1; }
-	goto st132;
-tr85:
-#line 133 "src/uri.rl"
-	{ schema.end   = p - 3; }
-#line 157 "src/uri.rl"
-	{ host.start   = p; }
-#line 153 "src/uri.rl"
-	{ ip6.start = p + 1; }
-	goto st132;
-st132:
-	if ( ++p == pe )
-		goto _test_eof132;
-case 132:
-#line 975 "src/uri.cc"
-	switch( (*p) ) {
-		case 58: goto tr152;
-		case 63: goto st0;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st133;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st133;
-	} else
-		goto st133;
-	goto st74;
-st133:
-	if ( ++p == pe )
-		goto _test_eof133;
-case 133:
-	switch( (*p) ) {
-		case 58: goto tr154;
-		case 63: goto st0;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st134;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st134;
-	} else
-		goto st134;
-	goto st74;
-st134:
-	if ( ++p == pe )
-		goto _test_eof134;
-case 134:
-	switch( (*p) ) {
-		case 58: goto tr154;
-		case 63: goto st0;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st135;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st135;
-	} else
-		goto st135;
-	goto st74;
-st135:
-	if ( ++p == pe )
-		goto _test_eof135;
-case 135:
-	switch( (*p) ) {
-		case 58: goto tr154;
-		case 63: goto st0;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st136;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st136;
-	} else
-		goto st136;
-	goto st74;
-st136:
-	if ( ++p == pe )
-		goto _test_eof136;
-case 136:
-	switch( (*p) ) {
-		case 58: goto tr154;
-		case 63: goto st0;
-	}
-	goto st74;
-tr154:
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-	goto st6;
-st6:
-	if ( ++p == pe )
-		goto _test_eof6;
-case 6:
-#line 1057 "src/uri.cc"
-	switch( (*p) ) {
-		case 48: goto st7;
-		case 58: goto st11;
-		case 93: goto st137;
-	}
-	if ( (*p) < 71 ) {
-		if ( (*p) > 57 ) {
-			if ( 65 <= (*p) && (*p) <= 70 )
-				goto tr19;
-		} else if ( (*p) >= 49 )
-			goto tr17;
-	} else if ( (*p) > 90 ) {
-		if ( (*p) > 102 ) {
-			if ( 103 <= (*p) && (*p) <= 122 )
-				goto tr9;
-		} else if ( (*p) >= 97 )
-			goto tr19;
-	} else
-		goto tr9;
-	goto st0;
-st7:
-	if ( ++p == pe )
-		goto _test_eof7;
-case 7:
-	switch( (*p) ) {
-		case 58: goto st11;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st8;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st8;
-	} else
-		goto st8;
-	goto st0;
-st8:
-	if ( ++p == pe )
-		goto _test_eof8;
-case 8:
-	switch( (*p) ) {
-		case 58: goto st11;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st9;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st9;
-	} else
-		goto st9;
-	goto st0;
-st9:
-	if ( ++p == pe )
-		goto _test_eof9;
-case 9:
-	switch( (*p) ) {
-		case 58: goto st11;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st10;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st10;
-	} else
-		goto st10;
-	goto st0;
-st10:
-	if ( ++p == pe )
-		goto _test_eof10;
-case 10:
-	switch( (*p) ) {
-		case 58: goto st11;
-		case 93: goto st137;
-	}
-	goto st0;
-st11:
-	if ( ++p == pe )
-		goto _test_eof11;
-case 11:
-	switch( (*p) ) {
-		case 58: goto st16;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st12;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st12;
-	} else
-		goto st12;
-	goto st0;
-st12:
-	if ( ++p == pe )
-		goto _test_eof12;
-case 12:
-	switch( (*p) ) {
-		case 58: goto st16;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st13;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st13;
-	} else
-		goto st13;
-	goto st0;
-st13:
-	if ( ++p == pe )
-		goto _test_eof13;
-case 13:
-	switch( (*p) ) {
-		case 58: goto st16;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st14;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st14;
-	} else
-		goto st14;
-	goto st0;
-st14:
-	if ( ++p == pe )
-		goto _test_eof14;
-case 14:
-	switch( (*p) ) {
-		case 58: goto st16;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st15;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st15;
-	} else
-		goto st15;
-	goto st0;
-st15:
-	if ( ++p == pe )
-		goto _test_eof15;
-case 15:
-	switch( (*p) ) {
-		case 58: goto st16;
-		case 93: goto st137;
-	}
-	goto st0;
-st16:
-	if ( ++p == pe )
-		goto _test_eof16;
-case 16:
-	switch( (*p) ) {
-		case 58: goto st21;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st17;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st17;
-	} else
-		goto st17;
-	goto st0;
-st17:
-	if ( ++p == pe )
-		goto _test_eof17;
-case 17:
-	switch( (*p) ) {
-		case 58: goto st21;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st18;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st18;
-	} else
-		goto st18;
-	goto st0;
-st18:
-	if ( ++p == pe )
-		goto _test_eof18;
-case 18:
-	switch( (*p) ) {
-		case 58: goto st21;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st19;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st19;
-	} else
-		goto st19;
-	goto st0;
-st19:
-	if ( ++p == pe )
-		goto _test_eof19;
-case 19:
-	switch( (*p) ) {
-		case 58: goto st21;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st20;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st20;
-	} else
-		goto st20;
-	goto st0;
-st20:
-	if ( ++p == pe )
-		goto _test_eof20;
-case 20:
-	switch( (*p) ) {
-		case 58: goto st21;
-		case 93: goto st137;
-	}
-	goto st0;
-st21:
-	if ( ++p == pe )
-		goto _test_eof21;
-case 21:
-	switch( (*p) ) {
-		case 58: goto st26;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st22;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st22;
-	} else
-		goto st22;
-	goto st0;
-st22:
-	if ( ++p == pe )
-		goto _test_eof22;
-case 22:
-	switch( (*p) ) {
-		case 58: goto st26;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st23;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st23;
-	} else
-		goto st23;
-	goto st0;
-st23:
-	if ( ++p == pe )
-		goto _test_eof23;
-case 23:
-	switch( (*p) ) {
-		case 58: goto st26;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st24;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st24;
-	} else
-		goto st24;
-	goto st0;
-st24:
-	if ( ++p == pe )
-		goto _test_eof24;
-case 24:
-	switch( (*p) ) {
-		case 58: goto st26;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st25;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st25;
-	} else
-		goto st25;
-	goto st0;
-st25:
-	if ( ++p == pe )
-		goto _test_eof25;
-case 25:
-	switch( (*p) ) {
-		case 58: goto st26;
-		case 93: goto st137;
-	}
-	goto st0;
-st26:
-	if ( ++p == pe )
-		goto _test_eof26;
-case 26:
-	switch( (*p) ) {
-		case 58: goto st31;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st27;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st27;
-	} else
-		goto st27;
-	goto st0;
-st27:
-	if ( ++p == pe )
-		goto _test_eof27;
-case 27:
-	switch( (*p) ) {
-		case 58: goto st31;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st28;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st28;
-	} else
-		goto st28;
-	goto st0;
-st28:
-	if ( ++p == pe )
-		goto _test_eof28;
-case 28:
-	switch( (*p) ) {
-		case 58: goto st31;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st29;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st29;
-	} else
-		goto st29;
-	goto st0;
-st29:
-	if ( ++p == pe )
-		goto _test_eof29;
-case 29:
-	switch( (*p) ) {
-		case 58: goto st31;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st30;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st30;
-	} else
-		goto st30;
-	goto st0;
-st30:
-	if ( ++p == pe )
-		goto _test_eof30;
-case 30:
-	switch( (*p) ) {
-		case 58: goto st31;
-		case 93: goto st137;
-	}
-	goto st0;
-st31:
-	if ( ++p == pe )
-		goto _test_eof31;
-case 31:
-	switch( (*p) ) {
-		case 58: goto st36;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st32;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st32;
-	} else
-		goto st32;
-	goto st0;
-st32:
-	if ( ++p == pe )
-		goto _test_eof32;
-case 32:
-	switch( (*p) ) {
-		case 58: goto st36;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st33;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st33;
-	} else
-		goto st33;
-	goto st0;
-st33:
-	if ( ++p == pe )
-		goto _test_eof33;
-case 33:
-	switch( (*p) ) {
-		case 58: goto st36;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st34;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st34;
-	} else
-		goto st34;
-	goto st0;
-st34:
-	if ( ++p == pe )
-		goto _test_eof34;
-case 34:
-	switch( (*p) ) {
-		case 58: goto st36;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st35;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st35;
-	} else
-		goto st35;
-	goto st0;
-st35:
-	if ( ++p == pe )
-		goto _test_eof35;
-case 35:
-	switch( (*p) ) {
-		case 58: goto st36;
-		case 93: goto st137;
-	}
-	goto st0;
-st36:
-	if ( ++p == pe )
-		goto _test_eof36;
-case 36:
-	switch( (*p) ) {
-		case 58: goto st41;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st37;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st37;
-	} else
-		goto st37;
-	goto st0;
-st37:
-	if ( ++p == pe )
-		goto _test_eof37;
-case 37:
-	switch( (*p) ) {
-		case 58: goto st41;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st38;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st38;
-	} else
-		goto st38;
-	goto st0;
-st38:
-	if ( ++p == pe )
-		goto _test_eof38;
-case 38:
-	switch( (*p) ) {
-		case 58: goto st41;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st39;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st39;
-	} else
-		goto st39;
-	goto st0;
-st39:
-	if ( ++p == pe )
-		goto _test_eof39;
-case 39:
-	switch( (*p) ) {
-		case 58: goto st41;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st40;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st40;
-	} else
-		goto st40;
-	goto st0;
-st40:
-	if ( ++p == pe )
-		goto _test_eof40;
-case 40:
-	switch( (*p) ) {
-		case 58: goto st41;
-		case 93: goto st137;
-	}
-	goto st0;
-st41:
-	if ( ++p == pe )
-		goto _test_eof41;
-case 41:
-	if ( (*p) == 93 )
-		goto st137;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st42;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st42;
-	} else
-		goto st42;
-	goto st0;
-st42:
-	if ( ++p == pe )
-		goto _test_eof42;
-case 42:
-	if ( (*p) == 93 )
-		goto st137;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st43;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st43;
-	} else
-		goto st43;
-	goto st0;
-st43:
-	if ( ++p == pe )
-		goto _test_eof43;
-case 43:
-	if ( (*p) == 93 )
-		goto st137;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st44;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st44;
-	} else
-		goto st44;
-	goto st0;
-st44:
-	if ( ++p == pe )
-		goto _test_eof44;
-case 44:
-	if ( (*p) == 93 )
-		goto st137;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st45;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st45;
-	} else
-		goto st45;
-	goto st0;
-st45:
-	if ( ++p == pe )
-		goto _test_eof45;
-case 45:
-	if ( (*p) == 93 )
-		goto st137;
-	goto st0;
-st137:
-	if ( ++p == pe )
-		goto _test_eof137;
-case 137:
-	if ( (*p) == 58 )
-		goto tr157;
-	goto st0;
-tr17:
-#line 166 "src/uri.rl"
-	{ service.start = p; }
-#line 161 "src/uri.rl"
-	{ dport.start   = p; port = 0; }
-#line 162 "src/uri.rl"
-	{ port = port * 10 + (int)(*p - '0'); }
-	goto st138;
-st138:
-	if ( ++p == pe )
-		goto _test_eof138;
-case 138:
-#line 1686 "src/uri.cc"
-	switch( (*p) ) {
-		case 58: goto st11;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr158;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st8;
-	} else
-		goto st8;
-	goto st0;
-tr158:
-#line 162 "src/uri.rl"
-	{ port = port * 10 + (int)(*p - '0'); }
-	goto st139;
-st139:
-	if ( ++p == pe )
-		goto _test_eof139;
-case 139:
-#line 1708 "src/uri.cc"
-	switch( (*p) ) {
-		case 58: goto st11;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr159;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st9;
-	} else
-		goto st9;
-	goto st0;
-tr159:
-#line 162 "src/uri.rl"
-	{ port = port * 10 + (int)(*p - '0'); }
-	goto st140;
-st140:
-	if ( ++p == pe )
-		goto _test_eof140;
-case 140:
-#line 1730 "src/uri.cc"
-	switch( (*p) ) {
-		case 58: goto st11;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr160;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st10;
-	} else
-		goto st10;
-	goto st0;
-tr160:
-#line 162 "src/uri.rl"
-	{ port = port * 10 + (int)(*p - '0'); }
-	goto st141;
-st141:
-	if ( ++p == pe )
-		goto _test_eof141;
-case 141:
-#line 1752 "src/uri.cc"
-	switch( (*p) ) {
-		case 58: goto st11;
-		case 93: goto st137;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto tr95;
-	goto st0;
-tr19:
-#line 166 "src/uri.rl"
-	{ service.start = p; }
-	goto st142;
-st142:
-	if ( ++p == pe )
-		goto _test_eof142;
-case 142:
-#line 1768 "src/uri.cc"
-	switch( (*p) ) {
-		case 58: goto st11;
-		case 93: goto st137;
-	}
-	if ( (*p) < 71 ) {
-		if ( (*p) > 57 ) {
-			if ( 65 <= (*p) && (*p) <= 70 )
-				goto st143;
-		} else if ( (*p) >= 48 )
-			goto st8;
-	} else if ( (*p) > 90 ) {
-		if ( (*p) > 102 ) {
-			if ( 103 <= (*p) && (*p) <= 122 )
-				goto st77;
-		} else if ( (*p) >= 97 )
-			goto st143;
-	} else
-		goto st77;
-	goto st0;
-st143:
-	if ( ++p == pe )
-		goto _test_eof143;
-case 143:
-	switch( (*p) ) {
-		case 58: goto st11;
-		case 93: goto st137;
-	}
-	if ( (*p) < 71 ) {
-		if ( (*p) > 57 ) {
-			if ( 65 <= (*p) && (*p) <= 70 )
-				goto st144;
-		} else if ( (*p) >= 48 )
-			goto st9;
-	} else if ( (*p) > 90 ) {
-		if ( (*p) > 102 ) {
-			if ( 103 <= (*p) && (*p) <= 122 )
-				goto st78;
-		} else if ( (*p) >= 97 )
-			goto st144;
-	} else
-		goto st78;
-	goto st0;
-st144:
-	if ( ++p == pe )
-		goto _test_eof144;
-case 144:
-	switch( (*p) ) {
-		case 58: goto st11;
-		case 93: goto st137;
-	}
-	if ( (*p) < 71 ) {
-		if ( (*p) > 57 ) {
-			if ( 65 <= (*p) && (*p) <= 70 )
-				goto st145;
-		} else if ( (*p) >= 48 )
-			goto st10;
-	} else if ( (*p) > 90 ) {
-		if ( (*p) > 102 ) {
-			if ( 103 <= (*p) && (*p) <= 122 )
-				goto st79;
-		} else if ( (*p) >= 97 )
-			goto st145;
-	} else
-		goto st79;
-	goto st0;
-st145:
-	if ( ++p == pe )
-		goto _test_eof145;
-case 145:
-	switch( (*p) ) {
-		case 58: goto st11;
-		case 93: goto st137;
-	}
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st80;
-	} else if ( (*p) >= 65 )
-		goto st80;
-	goto st0;
-tr152:
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-	goto st46;
-st46:
-	if ( ++p == pe )
-		goto _test_eof46;
-case 46:
-#line 1856 "src/uri.cc"
-	switch( (*p) ) {
-		case 48: goto st7;
-		case 58: goto st47;
-		case 93: goto st137;
-	}
-	if ( (*p) < 71 ) {
-		if ( (*p) > 57 ) {
-			if ( 65 <= (*p) && (*p) <= 70 )
-				goto tr19;
-		} else if ( (*p) >= 49 )
-			goto tr17;
-	} else if ( (*p) > 90 ) {
-		if ( (*p) > 102 ) {
-			if ( 103 <= (*p) && (*p) <= 122 )
-				goto tr9;
-		} else if ( (*p) >= 97 )
-			goto tr19;
-	} else
-		goto tr9;
-	goto st0;
-st47:
-	if ( ++p == pe )
-		goto _test_eof47;
-case 47:
-	switch( (*p) ) {
-		case 58: goto st16;
-		case 70: goto st48;
-		case 93: goto st137;
-		case 102: goto st48;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st12;
-	} else if ( (*p) > 69 ) {
-		if ( 97 <= (*p) && (*p) <= 101 )
-			goto st12;
-	} else
-		goto st12;
-	goto st0;
-st48:
-	if ( ++p == pe )
-		goto _test_eof48;
-case 48:
-	switch( (*p) ) {
-		case 58: goto st16;
-		case 70: goto st49;
-		case 93: goto st137;
-		case 102: goto st49;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st13;
-	} else if ( (*p) > 69 ) {
-		if ( 97 <= (*p) && (*p) <= 101 )
-			goto st13;
-	} else
-		goto st13;
-	goto st0;
-st49:
-	if ( ++p == pe )
-		goto _test_eof49;
-case 49:
-	switch( (*p) ) {
-		case 58: goto st16;
-		case 70: goto st50;
-		case 93: goto st137;
-		case 102: goto st50;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st14;
-	} else if ( (*p) > 69 ) {
-		if ( 97 <= (*p) && (*p) <= 101 )
-			goto st14;
-	} else
-		goto st14;
-	goto st0;
-st50:
-	if ( ++p == pe )
-		goto _test_eof50;
-case 50:
-	switch( (*p) ) {
-		case 58: goto st16;
-		case 70: goto st51;
-		case 93: goto st137;
-		case 102: goto st51;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st15;
-	} else if ( (*p) > 69 ) {
-		if ( 97 <= (*p) && (*p) <= 101 )
-			goto st15;
-	} else
-		goto st15;
-	goto st0;
-st51:
-	if ( ++p == pe )
-		goto _test_eof51;
-case 51:
-	switch( (*p) ) {
-		case 58: goto st52;
-		case 93: goto st137;
-	}
-	goto st0;
-st52:
-	if ( ++p == pe )
-		goto _test_eof52;
-case 52:
-	switch( (*p) ) {
-		case 58: goto st21;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr64;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st17;
-	} else
-		goto st17;
-	goto st0;
-tr64:
-#line 144 "src/uri.rl"
-	{ ip4.start = p; }
-	goto st53;
-st53:
-	if ( ++p == pe )
-		goto _test_eof53;
-case 53:
-#line 1987 "src/uri.cc"
-	switch( (*p) ) {
-		case 46: goto st54;
-		case 58: goto st21;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st66;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st18;
-	} else
-		goto st18;
-	goto st0;
-st54:
-	if ( ++p == pe )
-		goto _test_eof54;
-case 54:
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st55;
-	goto st0;
-st55:
-	if ( ++p == pe )
-		goto _test_eof55;
-case 55:
-	if ( (*p) == 46 )
-		goto st56;
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st64;
-	goto st0;
-st56:
-	if ( ++p == pe )
-		goto _test_eof56;
-case 56:
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st57;
-	goto st0;
-st57:
-	if ( ++p == pe )
-		goto _test_eof57;
-case 57:
-	if ( (*p) == 46 )
-		goto st58;
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st62;
-	goto st0;
-st58:
-	if ( ++p == pe )
-		goto _test_eof58;
-case 58:
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st59;
-	goto st0;
-st59:
-	if ( ++p == pe )
-		goto _test_eof59;
-case 59:
-	if ( (*p) == 93 )
-		goto tr75;
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st60;
-	goto st0;
-st60:
-	if ( ++p == pe )
-		goto _test_eof60;
-case 60:
-	if ( (*p) == 93 )
-		goto tr75;
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st61;
-	goto st0;
-st61:
-	if ( ++p == pe )
-		goto _test_eof61;
-case 61:
-	if ( (*p) == 93 )
-		goto tr75;
-	goto st0;
-tr75:
-#line 145 "src/uri.rl"
-	{ ip4.end   = p; }
-	goto st146;
-st146:
-	if ( ++p == pe )
-		goto _test_eof146;
-case 146:
-#line 2074 "src/uri.cc"
-	if ( (*p) == 58 )
-		goto tr94;
-	goto st0;
-st62:
-	if ( ++p == pe )
-		goto _test_eof62;
-case 62:
-	if ( (*p) == 46 )
-		goto st58;
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st63;
-	goto st0;
-st63:
-	if ( ++p == pe )
-		goto _test_eof63;
-case 63:
-	if ( (*p) == 46 )
-		goto st58;
-	goto st0;
-st64:
-	if ( ++p == pe )
-		goto _test_eof64;
-case 64:
-	if ( (*p) == 46 )
-		goto st56;
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st65;
-	goto st0;
-st65:
-	if ( ++p == pe )
-		goto _test_eof65;
-case 65:
-	if ( (*p) == 46 )
-		goto st56;
-	goto st0;
-st66:
-	if ( ++p == pe )
-		goto _test_eof66;
-case 66:
-	switch( (*p) ) {
-		case 46: goto st54;
-		case 58: goto st21;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st67;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st19;
-	} else
-		goto st19;
-	goto st0;
-st67:
-	if ( ++p == pe )
-		goto _test_eof67;
-case 67:
-	switch( (*p) ) {
-		case 46: goto st54;
-		case 58: goto st21;
-		case 93: goto st137;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st20;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st20;
-	} else
-		goto st20;
-	goto st0;
-tr11:
-#line 140 "src/uri.rl"
-	{ password.start = p; }
-#line 166 "src/uri.rl"
-	{ service.start = p; }
-#line 161 "src/uri.rl"
-	{ dport.start   = p; port = 0; }
-#line 162 "src/uri.rl"
-	{ port = port * 10 + (int)(*p - '0'); }
-	goto st147;
-tr164:
-#line 162 "src/uri.rl"
-	{ port = port * 10 + (int)(*p - '0'); }
-	goto st147;
-st147:
-	if ( ++p == pe )
-		goto _test_eof147;
-case 147:
-#line 2164 "src/uri.cc"
-	if ( (*p) == 64 )
-		goto tr14;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr164;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st4;
-	} else
-		goto st4;
-	goto st0;
-tr12:
-#line 140 "src/uri.rl"
-	{ password.start = p; }
-#line 166 "src/uri.rl"
-	{ service.start = p; }
-	goto st148;
-st148:
-	if ( ++p == pe )
-		goto _test_eof148;
-case 148:
-#line 2186 "src/uri.cc"
-	if ( (*p) == 64 )
-		goto tr14;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st4;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st149;
-	} else
-		goto st149;
-	goto st0;
-st149:
-	if ( ++p == pe )
-		goto _test_eof149;
-case 149:
-	if ( (*p) == 64 )
-		goto tr14;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st4;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st150;
-	} else
-		goto st150;
-	goto st0;
-st150:
-	if ( ++p == pe )
-		goto _test_eof150;
-case 150:
-	if ( (*p) == 64 )
-		goto tr14;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st4;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st151;
-	} else
-		goto st151;
-	goto st0;
-st151:
-	if ( ++p == pe )
-		goto _test_eof151;
-case 151:
-	if ( (*p) == 64 )
-		goto tr14;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st4;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st152;
-	} else
-		goto st152;
-	goto st0;
-st152:
-	if ( ++p == pe )
-		goto _test_eof152;
-case 152:
-	if ( (*p) == 64 )
-		goto tr14;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st4;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st153;
-	} else
-		goto st153;
-	goto st0;
-st153:
-	if ( ++p == pe )
-		goto _test_eof153;
-case 153:
-	if ( (*p) == 64 )
-		goto tr14;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st4;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st154;
-	} else
-		goto st154;
-	goto st0;
-st154:
-	if ( ++p == pe )
-		goto _test_eof154;
-case 154:
-	if ( (*p) == 64 )
-		goto tr14;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st4;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st155;
-	} else
-		goto st155;
-	goto st0;
-st155:
-	if ( ++p == pe )
-		goto _test_eof155;
-case 155:
-	if ( (*p) == 64 )
-		goto tr14;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st4;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st156;
-	} else
-		goto st156;
-	goto st0;
-st156:
-	if ( ++p == pe )
-		goto _test_eof156;
-case 156:
-	if ( (*p) == 64 )
-		goto tr14;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st4;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st157;
-	} else
-		goto st157;
-	goto st0;
-st157:
-	if ( ++p == pe )
-		goto _test_eof157;
-case 157:
-	if ( (*p) == 64 )
-		goto tr14;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st4;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st158;
-	} else
-		goto st158;
-	goto st0;
-st158:
-	if ( ++p == pe )
-		goto _test_eof158;
-case 158:
-	if ( (*p) == 64 )
-		goto tr14;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st4;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st159;
-	} else
-		goto st159;
-	goto st0;
-st159:
-	if ( ++p == pe )
-		goto _test_eof159;
-case 159:
-	if ( (*p) == 64 )
-		goto tr14;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st4;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st160;
-	} else
-		goto st160;
-	goto st0;
-st160:
-	if ( ++p == pe )
-		goto _test_eof160;
-case 160:
-	if ( (*p) == 64 )
-		goto tr14;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st4;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st161;
-	} else
-		goto st161;
-	goto st0;
-st161:
-	if ( ++p == pe )
-		goto _test_eof161;
-case 161:
-	if ( (*p) == 64 )
-		goto tr14;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st4;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st162;
-	} else
-		goto st162;
-	goto st0;
-st162:
-	if ( ++p == pe )
-		goto _test_eof162;
-case 162:
-	if ( (*p) == 64 )
-		goto tr14;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st4;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st163;
-	} else
-		goto st163;
-	goto st0;
-st163:
-	if ( ++p == pe )
-		goto _test_eof163;
-case 163:
-	if ( (*p) == 64 )
-		goto tr14;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st4;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st4;
-	} else
-		goto st4;
-	goto st0;
-tr3:
-#line 136 "src/uri.rl"
-	{ login.start  = p; }
-#line 157 "src/uri.rl"
-	{ host.start   = p; }
-#line 144 "src/uri.rl"
-	{ ip4.start = p; }
-#line 171 "src/uri.rl"
-	{ sport.start   = p; port = 0; }
-#line 172 "src/uri.rl"
-	{ port = port * 10 + (int)(*p - '0'); }
-	goto st164;
-st164:
-	if ( ++p == pe )
-		goto _test_eof164;
-case 164:
-#line 2439 "src/uri.cc"
-	switch( (*p) ) {
-		case 46: goto st114;
-		case 58: goto tr134;
-		case 63: goto st0;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr180;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st128;
-	} else
-		goto st128;
-	goto st74;
-tr180:
-#line 172 "src/uri.rl"
-	{ port = port * 10 + (int)(*p - '0'); }
-	goto st165;
-st165:
-	if ( ++p == pe )
-		goto _test_eof165;
-case 165:
-#line 2462 "src/uri.cc"
-	switch( (*p) ) {
-		case 46: goto st114;
-		case 58: goto tr134;
-		case 63: goto st0;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr181;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st128;
-	} else
-		goto st128;
-	goto st74;
-tr181:
-#line 172 "src/uri.rl"
-	{ port = port * 10 + (int)(*p - '0'); }
-	goto st166;
-st166:
-	if ( ++p == pe )
-		goto _test_eof166;
-case 166:
-#line 2485 "src/uri.cc"
-	switch( (*p) ) {
-		case 46: goto st114;
-		case 58: goto tr134;
-		case 63: goto st0;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr182;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st128;
-	} else
-		goto st128;
-	goto st74;
-tr182:
-#line 172 "src/uri.rl"
-	{ port = port * 10 + (int)(*p - '0'); }
-	goto st167;
-st167:
-	if ( ++p == pe )
-		goto _test_eof167;
-case 167:
-#line 2508 "src/uri.cc"
-	switch( (*p) ) {
-		case 58: goto tr134;
-		case 63: goto st0;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr182;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st128;
-	} else
-		goto st128;
-	goto st74;
-tr5:
-#line 132 "src/uri.rl"
-	{ schema.start = p; }
-#line 136 "src/uri.rl"
-	{ login.start  = p; }
-#line 157 "src/uri.rl"
-	{ host.start   = p; }
-	goto st168;
-st168:
-	if ( ++p == pe )
-		goto _test_eof168;
-case 168:
-#line 2534 "src/uri.cc"
-	switch( (*p) ) {
-		case 58: goto tr183;
-		case 63: goto st0;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st128;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st168;
-	} else
-		goto st168;
-	goto st74;
-tr183:
-#line 137 "src/uri.rl"
-	{ login.end    = p; }
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-	goto st68;
-st68:
-	if ( ++p == pe )
-		goto _test_eof68;
-case 68:
-#line 2558 "src/uri.cc"
-	switch( (*p) ) {
-		case 47: goto st69;
-		case 48: goto tr10;
-	}
-	if ( (*p) < 65 ) {
-		if ( 49 <= (*p) && (*p) <= 57 )
-			goto tr11;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr12;
-	} else
-		goto tr12;
-	goto st0;
-st69:
-	if ( ++p == pe )
-		goto _test_eof69;
-case 69:
-	if ( (*p) == 47 )
-		goto st70;
-	goto st0;
-st70:
-	if ( ++p == pe )
-		goto _test_eof70;
-case 70:
-	switch( (*p) ) {
-		case 58: goto st0;
-		case 63: goto st0;
-		case 91: goto tr85;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr83;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr84;
-	} else
-		goto tr84;
-	goto tr82;
-tr7:
-#line 132 "src/uri.rl"
-	{ schema.start = p; }
-#line 136 "src/uri.rl"
-	{ login.start  = p; }
-#line 157 "src/uri.rl"
-	{ host.start   = p; }
-	goto st169;
-st169:
-	if ( ++p == pe )
-		goto _test_eof169;
-case 169:
-#line 2609 "src/uri.cc"
-	switch( (*p) ) {
-		case 58: goto tr183;
-		case 63: goto st0;
-		case 110: goto st170;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st128;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st168;
-	} else
-		goto st168;
-	goto st74;
-st170:
-	if ( ++p == pe )
-		goto _test_eof170;
-case 170:
-	switch( (*p) ) {
-		case 58: goto tr183;
-		case 63: goto st0;
-		case 105: goto st171;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st128;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st168;
-	} else
-		goto st168;
-	goto st74;
-st171:
-	if ( ++p == pe )
-		goto _test_eof171;
-case 171:
-	switch( (*p) ) {
-		case 58: goto tr183;
-		case 63: goto st0;
-		case 120: goto st172;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st128;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st168;
-	} else
-		goto st168;
-	goto st74;
-st172:
-	if ( ++p == pe )
-		goto _test_eof172;
-case 172:
-	switch( (*p) ) {
-		case 58: goto tr188;
-		case 63: goto st0;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st128;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st168;
-	} else
-		goto st168;
-	goto st74;
-tr188:
-#line 137 "src/uri.rl"
-	{ login.end    = p; }
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-	goto st71;
-st71:
-	if ( ++p == pe )
-		goto _test_eof71;
-case 71:
-#line 2687 "src/uri.cc"
-	switch( (*p) ) {
-		case 47: goto st72;
-		case 48: goto tr10;
-	}
-	if ( (*p) < 65 ) {
-		if ( 49 <= (*p) && (*p) <= 57 )
-			goto tr11;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr12;
-	} else
-		goto tr12;
-	goto st0;
-st72:
-	if ( ++p == pe )
-		goto _test_eof72;
-case 72:
-	if ( (*p) == 47 )
-		goto st73;
-	goto st0;
-st73:
-	if ( ++p == pe )
-		goto _test_eof73;
-case 73:
-	switch( (*p) ) {
-		case 58: goto tr90;
-		case 63: goto tr90;
-		case 91: goto tr92;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr89;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr91;
-	} else
-		goto tr91;
-	goto tr88;
-tr88:
-#line 180 "src/uri.rl"
-	{ path.start = p; }
-#line 133 "src/uri.rl"
-	{ schema.end   = p - 3; }
-#line 157 "src/uri.rl"
-	{ host.start   = p; }
-	goto st173;
-tr232:
-#line 180 "src/uri.rl"
-	{ path.start = p; }
-#line 157 "src/uri.rl"
-	{ host.start   = p; }
-	goto st173;
-st173:
-	if ( ++p == pe )
-		goto _test_eof173;
-case 173:
-#line 2744 "src/uri.cc"
-	switch( (*p) ) {
-		case 58: goto tr190;
-		case 63: goto st175;
-	}
-	goto st173;
-tr190:
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-	goto st174;
-tr222:
-#line 145 "src/uri.rl"
-	{ ip4.end   = p; }
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-	goto st174;
-tr285:
-#line 154 "src/uri.rl"
-	{ ip6.end   = p - 1; }
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-	goto st174;
-st174:
-	if ( ++p == pe )
-		goto _test_eof174;
-case 174:
-#line 2770 "src/uri.cc"
-	if ( (*p) < 65 ) {
-		if ( 49 <= (*p) && (*p) <= 57 )
-			goto tr192;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr193;
-	} else
-		goto tr193;
-	goto st175;
-tr90:
-#line 180 "src/uri.rl"
-	{ path.start = p; }
-	goto st175;
-st175:
-	if ( ++p == pe )
-		goto _test_eof175;
-case 175:
-#line 2788 "src/uri.cc"
-	goto st175;
-tr192:
-#line 166 "src/uri.rl"
-	{ service.start = p; }
-#line 161 "src/uri.rl"
-	{ dport.start   = p; port = 0; }
-#line 162 "src/uri.rl"
-	{ port = port * 10 + (int)(*p - '0'); }
-	goto st176;
-tr194:
-#line 162 "src/uri.rl"
-	{ port = port * 10 + (int)(*p - '0'); }
-	goto st176;
-st176:
-	if ( ++p == pe )
-		goto _test_eof176;
-case 176:
-#line 2806 "src/uri.cc"
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto tr194;
-	goto st175;
-tr193:
-#line 166 "src/uri.rl"
-	{ service.start = p; }
-	goto st177;
-st177:
-	if ( ++p == pe )
-		goto _test_eof177;
-case 177:
-#line 2818 "src/uri.cc"
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st178;
-	} else if ( (*p) >= 65 )
-		goto st178;
-	goto st175;
-st178:
-	if ( ++p == pe )
-		goto _test_eof178;
-case 178:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st179;
-	} else if ( (*p) >= 65 )
-		goto st179;
-	goto st175;
-st179:
-	if ( ++p == pe )
-		goto _test_eof179;
-case 179:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st180;
-	} else if ( (*p) >= 65 )
-		goto st180;
-	goto st175;
-st180:
-	if ( ++p == pe )
-		goto _test_eof180;
-case 180:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st181;
-	} else if ( (*p) >= 65 )
-		goto st181;
-	goto st175;
-st181:
-	if ( ++p == pe )
-		goto _test_eof181;
-case 181:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st182;
-	} else if ( (*p) >= 65 )
-		goto st182;
-	goto st175;
-st182:
-	if ( ++p == pe )
-		goto _test_eof182;
-case 182:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st183;
-	} else if ( (*p) >= 65 )
-		goto st183;
-	goto st175;
-st183:
-	if ( ++p == pe )
-		goto _test_eof183;
-case 183:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st184;
-	} else if ( (*p) >= 65 )
-		goto st184;
-	goto st175;
-st184:
-	if ( ++p == pe )
-		goto _test_eof184;
-case 184:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st185;
-	} else if ( (*p) >= 65 )
-		goto st185;
-	goto st175;
-st185:
-	if ( ++p == pe )
-		goto _test_eof185;
-case 185:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st186;
-	} else if ( (*p) >= 65 )
-		goto st186;
-	goto st175;
-st186:
-	if ( ++p == pe )
-		goto _test_eof186;
-case 186:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st187;
-	} else if ( (*p) >= 65 )
-		goto st187;
-	goto st175;
-st187:
-	if ( ++p == pe )
-		goto _test_eof187;
-case 187:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st188;
-	} else if ( (*p) >= 65 )
-		goto st188;
-	goto st175;
-st188:
-	if ( ++p == pe )
-		goto _test_eof188;
-case 188:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st189;
-	} else if ( (*p) >= 65 )
-		goto st189;
-	goto st175;
-st189:
-	if ( ++p == pe )
-		goto _test_eof189;
-case 189:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st190;
-	} else if ( (*p) >= 65 )
-		goto st190;
-	goto st175;
-st190:
-	if ( ++p == pe )
-		goto _test_eof190;
-case 190:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st191;
-	} else if ( (*p) >= 65 )
-		goto st191;
-	goto st175;
-st191:
-	if ( ++p == pe )
-		goto _test_eof191;
-case 191:
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st192;
-	} else if ( (*p) >= 65 )
-		goto st192;
-	goto st175;
-st192:
-	if ( ++p == pe )
-		goto _test_eof192;
-case 192:
-	goto st175;
-tr89:
-#line 136 "src/uri.rl"
-	{ login.start  = p; }
-#line 180 "src/uri.rl"
-	{ path.start = p; }
-#line 133 "src/uri.rl"
-	{ schema.end   = p - 3; }
-#line 157 "src/uri.rl"
-	{ host.start   = p; }
-#line 144 "src/uri.rl"
-	{ ip4.start = p; }
-	goto st193;
-st193:
-	if ( ++p == pe )
-		goto _test_eof193;
-case 193:
-#line 2986 "src/uri.cc"
-	switch( (*p) ) {
-		case 46: goto st194;
-		case 58: goto tr212;
-		case 63: goto st175;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st206;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st208;
-	} else
-		goto st208;
-	goto st173;
-st194:
-	if ( ++p == pe )
-		goto _test_eof194;
-case 194:
-	switch( (*p) ) {
-		case 58: goto tr190;
-		case 63: goto st175;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st195;
-	goto st173;
-st195:
-	if ( ++p == pe )
-		goto _test_eof195;
-case 195:
-	switch( (*p) ) {
-		case 46: goto st196;
-		case 58: goto tr190;
-		case 63: goto st175;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st204;
-	goto st173;
-st196:
-	if ( ++p == pe )
-		goto _test_eof196;
-case 196:
-	switch( (*p) ) {
-		case 58: goto tr190;
-		case 63: goto st175;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st197;
-	goto st173;
-st197:
-	if ( ++p == pe )
-		goto _test_eof197;
-case 197:
-	switch( (*p) ) {
-		case 46: goto st198;
-		case 58: goto tr190;
-		case 63: goto st175;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st202;
-	goto st173;
-st198:
-	if ( ++p == pe )
-		goto _test_eof198;
-case 198:
-	switch( (*p) ) {
-		case 58: goto tr190;
-		case 63: goto st175;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st199;
-	goto st173;
-st199:
-	if ( ++p == pe )
-		goto _test_eof199;
-case 199:
-	switch( (*p) ) {
-		case 58: goto tr222;
-		case 63: goto st175;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st200;
-	goto st173;
-st200:
-	if ( ++p == pe )
-		goto _test_eof200;
-case 200:
-	switch( (*p) ) {
-		case 58: goto tr222;
-		case 63: goto st175;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st201;
-	goto st173;
-st201:
-	if ( ++p == pe )
-		goto _test_eof201;
-case 201:
-	switch( (*p) ) {
-		case 58: goto tr222;
-		case 63: goto st175;
-	}
-	goto st173;
-st202:
-	if ( ++p == pe )
-		goto _test_eof202;
-case 202:
-	switch( (*p) ) {
-		case 46: goto st198;
-		case 58: goto tr190;
-		case 63: goto st175;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st203;
-	goto st173;
-st203:
-	if ( ++p == pe )
-		goto _test_eof203;
-case 203:
-	switch( (*p) ) {
-		case 46: goto st198;
-		case 58: goto tr190;
-		case 63: goto st175;
-	}
-	goto st173;
-st204:
-	if ( ++p == pe )
-		goto _test_eof204;
-case 204:
-	switch( (*p) ) {
-		case 46: goto st196;
-		case 58: goto tr190;
-		case 63: goto st175;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st205;
-	goto st173;
-st205:
-	if ( ++p == pe )
-		goto _test_eof205;
-case 205:
-	switch( (*p) ) {
-		case 46: goto st196;
-		case 58: goto tr190;
-		case 63: goto st175;
-	}
-	goto st173;
-st206:
-	if ( ++p == pe )
-		goto _test_eof206;
-case 206:
-	switch( (*p) ) {
-		case 46: goto st194;
-		case 58: goto tr212;
-		case 63: goto st175;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st207;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st208;
-	} else
-		goto st208;
-	goto st173;
-st207:
-	if ( ++p == pe )
-		goto _test_eof207;
-case 207:
-	switch( (*p) ) {
-		case 46: goto st194;
-		case 58: goto tr212;
-		case 63: goto st175;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st208;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st208;
-	} else
-		goto st208;
-	goto st173;
-tr91:
-#line 136 "src/uri.rl"
-	{ login.start  = p; }
-#line 180 "src/uri.rl"
-	{ path.start = p; }
-#line 133 "src/uri.rl"
-	{ schema.end   = p - 3; }
-#line 157 "src/uri.rl"
-	{ host.start   = p; }
-	goto st208;
-st208:
-	if ( ++p == pe )
-		goto _test_eof208;
-case 208:
-#line 3183 "src/uri.cc"
-	switch( (*p) ) {
-		case 58: goto tr212;
-		case 63: goto st175;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st208;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st208;
-	} else
-		goto st208;
-	goto st173;
-tr212:
-#line 137 "src/uri.rl"
-	{ login.end    = p; }
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-	goto st209;
-st209:
-	if ( ++p == pe )
-		goto _test_eof209;
-case 209:
-#line 3207 "src/uri.cc"
-	if ( (*p) == 48 )
-		goto tr227;
-	if ( (*p) < 65 ) {
-		if ( 49 <= (*p) && (*p) <= 57 )
-			goto tr228;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr229;
-	} else
-		goto tr229;
-	goto st175;
-tr227:
-#line 140 "src/uri.rl"
-	{ password.start = p; }
-	goto st210;
-st210:
-	if ( ++p == pe )
-		goto _test_eof210;
-case 210:
-#line 3227 "src/uri.cc"
-	if ( (*p) == 64 )
-		goto tr231;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st210;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st210;
-	} else
-		goto st210;
-	goto st175;
-tr231:
-#line 141 "src/uri.rl"
-	{ password.end   = p; }
-	goto st211;
-st211:
-	if ( ++p == pe )
-		goto _test_eof211;
-case 211:
-#line 3247 "src/uri.cc"
-	switch( (*p) ) {
-		case 58: goto tr90;
-		case 63: goto tr90;
-		case 91: goto tr234;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto tr233;
-	goto tr232;
-tr233:
-#line 180 "src/uri.rl"
-	{ path.start = p; }
-#line 157 "src/uri.rl"
-	{ host.start   = p; }
-#line 144 "src/uri.rl"
-	{ ip4.start = p; }
-	goto st212;
-st212:
-	if ( ++p == pe )
-		goto _test_eof212;
-case 212:
-#line 3268 "src/uri.cc"
-	switch( (*p) ) {
-		case 46: goto st194;
-		case 58: goto tr190;
-		case 63: goto st175;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st213;
-	goto st173;
-st213:
-	if ( ++p == pe )
-		goto _test_eof213;
-case 213:
-	switch( (*p) ) {
-		case 46: goto st194;
-		case 58: goto tr190;
-		case 63: goto st175;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st214;
-	goto st173;
-st214:
-	if ( ++p == pe )
-		goto _test_eof214;
-case 214:
-	switch( (*p) ) {
-		case 46: goto st194;
-		case 58: goto tr190;
-		case 63: goto st175;
-	}
-	goto st173;
-tr92:
-#line 180 "src/uri.rl"
-	{ path.start = p; }
-#line 133 "src/uri.rl"
-	{ schema.end   = p - 3; }
-#line 157 "src/uri.rl"
-	{ host.start   = p; }
-#line 153 "src/uri.rl"
-	{ ip6.start = p + 1; }
-	goto st215;
-tr234:
-#line 180 "src/uri.rl"
-	{ path.start = p; }
-#line 157 "src/uri.rl"
-	{ host.start   = p; }
-#line 153 "src/uri.rl"
-	{ ip6.start = p + 1; }
-	goto st215;
-st215:
-	if ( ++p == pe )
-		goto _test_eof215;
-case 215:
-#line 3321 "src/uri.cc"
-	switch( (*p) ) {
-		case 58: goto tr238;
-		case 63: goto st175;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st216;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st216;
-	} else
-		goto st216;
-	goto st173;
-st216:
-	if ( ++p == pe )
-		goto _test_eof216;
-case 216:
-	switch( (*p) ) {
-		case 58: goto tr240;
-		case 63: goto st175;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st217;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st217;
-	} else
-		goto st217;
-	goto st173;
-st217:
-	if ( ++p == pe )
-		goto _test_eof217;
-case 217:
-	switch( (*p) ) {
-		case 58: goto tr240;
-		case 63: goto st175;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st218;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st218;
-	} else
-		goto st218;
-	goto st173;
-st218:
-	if ( ++p == pe )
-		goto _test_eof218;
-case 218:
-	switch( (*p) ) {
-		case 58: goto tr240;
-		case 63: goto st175;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st219;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st219;
-	} else
-		goto st219;
-	goto st173;
-st219:
-	if ( ++p == pe )
-		goto _test_eof219;
-case 219:
-	switch( (*p) ) {
-		case 58: goto tr240;
-		case 63: goto st175;
-	}
-	goto st173;
-tr240:
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-	goto st220;
-st220:
-	if ( ++p == pe )
-		goto _test_eof220;
-case 220:
-#line 3403 "src/uri.cc"
-	switch( (*p) ) {
-		case 48: goto st221;
-		case 58: goto st225;
-		case 93: goto st260;
-	}
-	if ( (*p) < 71 ) {
-		if ( (*p) > 57 ) {
-			if ( 65 <= (*p) && (*p) <= 70 )
-				goto tr246;
-		} else if ( (*p) >= 49 )
-			goto tr244;
-	} else if ( (*p) > 90 ) {
-		if ( (*p) > 102 ) {
-			if ( 103 <= (*p) && (*p) <= 122 )
-				goto tr193;
-		} else if ( (*p) >= 97 )
-			goto tr246;
-	} else
-		goto tr193;
-	goto st175;
-st221:
-	if ( ++p == pe )
-		goto _test_eof221;
-case 221:
-	switch( (*p) ) {
-		case 58: goto st225;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st222;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st222;
-	} else
-		goto st222;
-	goto st175;
-st222:
-	if ( ++p == pe )
-		goto _test_eof222;
-case 222:
-	switch( (*p) ) {
-		case 58: goto st225;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st223;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st223;
-	} else
-		goto st223;
-	goto st175;
-st223:
-	if ( ++p == pe )
-		goto _test_eof223;
-case 223:
-	switch( (*p) ) {
-		case 58: goto st225;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st224;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st224;
-	} else
-		goto st224;
-	goto st175;
-st224:
-	if ( ++p == pe )
-		goto _test_eof224;
-case 224:
-	switch( (*p) ) {
-		case 58: goto st225;
-		case 93: goto st260;
-	}
-	goto st175;
-st225:
-	if ( ++p == pe )
-		goto _test_eof225;
-case 225:
-	switch( (*p) ) {
-		case 58: goto st230;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st226;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st226;
-	} else
-		goto st226;
-	goto st175;
-st226:
-	if ( ++p == pe )
-		goto _test_eof226;
-case 226:
-	switch( (*p) ) {
-		case 58: goto st230;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st227;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st227;
-	} else
-		goto st227;
-	goto st175;
-st227:
-	if ( ++p == pe )
-		goto _test_eof227;
-case 227:
-	switch( (*p) ) {
-		case 58: goto st230;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st228;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st228;
-	} else
-		goto st228;
-	goto st175;
-st228:
-	if ( ++p == pe )
-		goto _test_eof228;
-case 228:
-	switch( (*p) ) {
-		case 58: goto st230;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st229;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st229;
-	} else
-		goto st229;
-	goto st175;
-st229:
-	if ( ++p == pe )
-		goto _test_eof229;
-case 229:
-	switch( (*p) ) {
-		case 58: goto st230;
-		case 93: goto st260;
-	}
-	goto st175;
-st230:
-	if ( ++p == pe )
-		goto _test_eof230;
-case 230:
-	switch( (*p) ) {
-		case 58: goto st235;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st231;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st231;
-	} else
-		goto st231;
-	goto st175;
-st231:
-	if ( ++p == pe )
-		goto _test_eof231;
-case 231:
-	switch( (*p) ) {
-		case 58: goto st235;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st232;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st232;
-	} else
-		goto st232;
-	goto st175;
-st232:
-	if ( ++p == pe )
-		goto _test_eof232;
-case 232:
-	switch( (*p) ) {
-		case 58: goto st235;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st233;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st233;
-	} else
-		goto st233;
-	goto st175;
-st233:
-	if ( ++p == pe )
-		goto _test_eof233;
-case 233:
-	switch( (*p) ) {
-		case 58: goto st235;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st234;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st234;
-	} else
-		goto st234;
-	goto st175;
-st234:
-	if ( ++p == pe )
-		goto _test_eof234;
-case 234:
-	switch( (*p) ) {
-		case 58: goto st235;
-		case 93: goto st260;
-	}
-	goto st175;
-st235:
-	if ( ++p == pe )
-		goto _test_eof235;
-case 235:
-	switch( (*p) ) {
-		case 58: goto st240;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st236;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st236;
-	} else
-		goto st236;
-	goto st175;
-st236:
-	if ( ++p == pe )
-		goto _test_eof236;
-case 236:
-	switch( (*p) ) {
-		case 58: goto st240;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st237;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st237;
-	} else
-		goto st237;
-	goto st175;
-st237:
-	if ( ++p == pe )
-		goto _test_eof237;
-case 237:
-	switch( (*p) ) {
-		case 58: goto st240;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st238;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st238;
-	} else
-		goto st238;
-	goto st175;
-st238:
-	if ( ++p == pe )
-		goto _test_eof238;
-case 238:
-	switch( (*p) ) {
-		case 58: goto st240;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st239;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st239;
-	} else
-		goto st239;
-	goto st175;
-st239:
-	if ( ++p == pe )
-		goto _test_eof239;
-case 239:
-	switch( (*p) ) {
-		case 58: goto st240;
-		case 93: goto st260;
-	}
-	goto st175;
-st240:
-	if ( ++p == pe )
-		goto _test_eof240;
-case 240:
-	switch( (*p) ) {
-		case 58: goto st245;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st241;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st241;
-	} else
-		goto st241;
-	goto st175;
-st241:
-	if ( ++p == pe )
-		goto _test_eof241;
-case 241:
-	switch( (*p) ) {
-		case 58: goto st245;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st242;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st242;
-	} else
-		goto st242;
-	goto st175;
-st242:
-	if ( ++p == pe )
-		goto _test_eof242;
-case 242:
-	switch( (*p) ) {
-		case 58: goto st245;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st243;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st243;
-	} else
-		goto st243;
-	goto st175;
-st243:
-	if ( ++p == pe )
-		goto _test_eof243;
-case 243:
-	switch( (*p) ) {
-		case 58: goto st245;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st244;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st244;
-	} else
-		goto st244;
-	goto st175;
-st244:
-	if ( ++p == pe )
-		goto _test_eof244;
-case 244:
-	switch( (*p) ) {
-		case 58: goto st245;
-		case 93: goto st260;
-	}
-	goto st175;
-st245:
-	if ( ++p == pe )
-		goto _test_eof245;
-case 245:
-	switch( (*p) ) {
-		case 58: goto st250;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st246;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st246;
-	} else
-		goto st246;
-	goto st175;
-st246:
-	if ( ++p == pe )
-		goto _test_eof246;
-case 246:
-	switch( (*p) ) {
-		case 58: goto st250;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st247;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st247;
-	} else
-		goto st247;
-	goto st175;
-st247:
-	if ( ++p == pe )
-		goto _test_eof247;
-case 247:
-	switch( (*p) ) {
-		case 58: goto st250;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st248;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st248;
-	} else
-		goto st248;
-	goto st175;
-st248:
-	if ( ++p == pe )
-		goto _test_eof248;
-case 248:
-	switch( (*p) ) {
-		case 58: goto st250;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st249;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st249;
-	} else
-		goto st249;
-	goto st175;
-st249:
-	if ( ++p == pe )
-		goto _test_eof249;
-case 249:
-	switch( (*p) ) {
-		case 58: goto st250;
-		case 93: goto st260;
-	}
-	goto st175;
-st250:
-	if ( ++p == pe )
-		goto _test_eof250;
-case 250:
-	switch( (*p) ) {
-		case 58: goto st255;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st251;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st251;
-	} else
-		goto st251;
-	goto st175;
-st251:
-	if ( ++p == pe )
-		goto _test_eof251;
-case 251:
-	switch( (*p) ) {
-		case 58: goto st255;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st252;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st252;
-	} else
-		goto st252;
-	goto st175;
-st252:
-	if ( ++p == pe )
-		goto _test_eof252;
-case 252:
-	switch( (*p) ) {
-		case 58: goto st255;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st253;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st253;
-	} else
-		goto st253;
-	goto st175;
-st253:
-	if ( ++p == pe )
-		goto _test_eof253;
-case 253:
-	switch( (*p) ) {
-		case 58: goto st255;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st254;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st254;
-	} else
-		goto st254;
-	goto st175;
-st254:
-	if ( ++p == pe )
-		goto _test_eof254;
-case 254:
-	switch( (*p) ) {
-		case 58: goto st255;
-		case 93: goto st260;
-	}
-	goto st175;
-st255:
-	if ( ++p == pe )
-		goto _test_eof255;
-case 255:
-	if ( (*p) == 93 )
-		goto st260;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st256;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st256;
-	} else
-		goto st256;
-	goto st175;
-st256:
-	if ( ++p == pe )
-		goto _test_eof256;
-case 256:
-	if ( (*p) == 93 )
-		goto st260;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st257;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st257;
-	} else
-		goto st257;
-	goto st175;
-st257:
-	if ( ++p == pe )
-		goto _test_eof257;
-case 257:
-	if ( (*p) == 93 )
-		goto st260;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st258;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st258;
-	} else
-		goto st258;
-	goto st175;
-st258:
-	if ( ++p == pe )
-		goto _test_eof258;
-case 258:
-	if ( (*p) == 93 )
-		goto st260;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st259;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st259;
-	} else
-		goto st259;
-	goto st175;
-st259:
-	if ( ++p == pe )
-		goto _test_eof259;
-case 259:
-	if ( (*p) == 93 )
-		goto st260;
-	goto st175;
-st260:
-	if ( ++p == pe )
-		goto _test_eof260;
-case 260:
-	if ( (*p) == 58 )
-		goto tr285;
-	goto st175;
-tr244:
-#line 166 "src/uri.rl"
-	{ service.start = p; }
-#line 161 "src/uri.rl"
-	{ dport.start   = p; port = 0; }
-#line 162 "src/uri.rl"
-	{ port = port * 10 + (int)(*p - '0'); }
-	goto st261;
-st261:
-	if ( ++p == pe )
-		goto _test_eof261;
-case 261:
-#line 4032 "src/uri.cc"
-	switch( (*p) ) {
-		case 58: goto st225;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr286;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st222;
-	} else
-		goto st222;
-	goto st175;
-tr286:
-#line 162 "src/uri.rl"
-	{ port = port * 10 + (int)(*p - '0'); }
-	goto st262;
-st262:
-	if ( ++p == pe )
-		goto _test_eof262;
-case 262:
-#line 4054 "src/uri.cc"
-	switch( (*p) ) {
-		case 58: goto st225;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr287;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st223;
-	} else
-		goto st223;
-	goto st175;
-tr287:
-#line 162 "src/uri.rl"
-	{ port = port * 10 + (int)(*p - '0'); }
-	goto st263;
-st263:
-	if ( ++p == pe )
-		goto _test_eof263;
-case 263:
-#line 4076 "src/uri.cc"
-	switch( (*p) ) {
-		case 58: goto st225;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr288;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st224;
-	} else
-		goto st224;
-	goto st175;
-tr288:
-#line 162 "src/uri.rl"
-	{ port = port * 10 + (int)(*p - '0'); }
-	goto st264;
-st264:
-	if ( ++p == pe )
-		goto _test_eof264;
-case 264:
-#line 4098 "src/uri.cc"
-	switch( (*p) ) {
-		case 58: goto st225;
-		case 93: goto st260;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto tr194;
-	goto st175;
-tr246:
-#line 166 "src/uri.rl"
-	{ service.start = p; }
-	goto st265;
-st265:
-	if ( ++p == pe )
-		goto _test_eof265;
-case 265:
-#line 4114 "src/uri.cc"
-	switch( (*p) ) {
-		case 58: goto st225;
-		case 93: goto st260;
-	}
-	if ( (*p) < 71 ) {
-		if ( (*p) > 57 ) {
-			if ( 65 <= (*p) && (*p) <= 70 )
-				goto st266;
-		} else if ( (*p) >= 48 )
-			goto st222;
-	} else if ( (*p) > 90 ) {
-		if ( (*p) > 102 ) {
-			if ( 103 <= (*p) && (*p) <= 122 )
-				goto st178;
-		} else if ( (*p) >= 97 )
-			goto st266;
-	} else
-		goto st178;
-	goto st175;
-st266:
-	if ( ++p == pe )
-		goto _test_eof266;
-case 266:
-	switch( (*p) ) {
-		case 58: goto st225;
-		case 93: goto st260;
-	}
-	if ( (*p) < 71 ) {
-		if ( (*p) > 57 ) {
-			if ( 65 <= (*p) && (*p) <= 70 )
-				goto st267;
-		} else if ( (*p) >= 48 )
-			goto st223;
-	} else if ( (*p) > 90 ) {
-		if ( (*p) > 102 ) {
-			if ( 103 <= (*p) && (*p) <= 122 )
-				goto st179;
-		} else if ( (*p) >= 97 )
-			goto st267;
-	} else
-		goto st179;
-	goto st175;
-st267:
-	if ( ++p == pe )
-		goto _test_eof267;
-case 267:
-	switch( (*p) ) {
-		case 58: goto st225;
-		case 93: goto st260;
-	}
-	if ( (*p) < 71 ) {
-		if ( (*p) > 57 ) {
-			if ( 65 <= (*p) && (*p) <= 70 )
-				goto st268;
-		} else if ( (*p) >= 48 )
-			goto st224;
-	} else if ( (*p) > 90 ) {
-		if ( (*p) > 102 ) {
-			if ( 103 <= (*p) && (*p) <= 122 )
-				goto st180;
-		} else if ( (*p) >= 97 )
-			goto st268;
-	} else
-		goto st180;
-	goto st175;
-st268:
-	if ( ++p == pe )
-		goto _test_eof268;
-case 268:
-	switch( (*p) ) {
-		case 58: goto st225;
-		case 93: goto st260;
-	}
-	if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st181;
-	} else if ( (*p) >= 65 )
-		goto st181;
-	goto st175;
-tr238:
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-	goto st269;
-st269:
-	if ( ++p == pe )
-		goto _test_eof269;
-case 269:
-#line 4202 "src/uri.cc"
-	switch( (*p) ) {
-		case 48: goto st221;
-		case 58: goto st270;
-		case 93: goto st260;
-	}
-	if ( (*p) < 71 ) {
-		if ( (*p) > 57 ) {
-			if ( 65 <= (*p) && (*p) <= 70 )
-				goto tr246;
-		} else if ( (*p) >= 49 )
-			goto tr244;
-	} else if ( (*p) > 90 ) {
-		if ( (*p) > 102 ) {
-			if ( 103 <= (*p) && (*p) <= 122 )
-				goto tr193;
-		} else if ( (*p) >= 97 )
-			goto tr246;
-	} else
-		goto tr193;
-	goto st175;
-st270:
-	if ( ++p == pe )
-		goto _test_eof270;
-case 270:
-	switch( (*p) ) {
-		case 58: goto st230;
-		case 70: goto st271;
-		case 93: goto st260;
-		case 102: goto st271;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st226;
-	} else if ( (*p) > 69 ) {
-		if ( 97 <= (*p) && (*p) <= 101 )
-			goto st226;
-	} else
-		goto st226;
-	goto st175;
-st271:
-	if ( ++p == pe )
-		goto _test_eof271;
-case 271:
-	switch( (*p) ) {
-		case 58: goto st230;
-		case 70: goto st272;
-		case 93: goto st260;
-		case 102: goto st272;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st227;
-	} else if ( (*p) > 69 ) {
-		if ( 97 <= (*p) && (*p) <= 101 )
-			goto st227;
-	} else
-		goto st227;
-	goto st175;
-st272:
-	if ( ++p == pe )
-		goto _test_eof272;
-case 272:
-	switch( (*p) ) {
-		case 58: goto st230;
-		case 70: goto st273;
-		case 93: goto st260;
-		case 102: goto st273;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st228;
-	} else if ( (*p) > 69 ) {
-		if ( 97 <= (*p) && (*p) <= 101 )
-			goto st228;
-	} else
-		goto st228;
-	goto st175;
-st273:
-	if ( ++p == pe )
-		goto _test_eof273;
-case 273:
-	switch( (*p) ) {
-		case 58: goto st230;
-		case 70: goto st274;
-		case 93: goto st260;
-		case 102: goto st274;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st229;
-	} else if ( (*p) > 69 ) {
-		if ( 97 <= (*p) && (*p) <= 101 )
-			goto st229;
-	} else
-		goto st229;
-	goto st175;
-st274:
-	if ( ++p == pe )
-		goto _test_eof274;
-case 274:
-	switch( (*p) ) {
-		case 58: goto st275;
-		case 93: goto st260;
-	}
-	goto st175;
-st275:
-	if ( ++p == pe )
-		goto _test_eof275;
-case 275:
-	switch( (*p) ) {
-		case 58: goto st235;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr298;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st231;
-	} else
-		goto st231;
-	goto st175;
-tr298:
-#line 144 "src/uri.rl"
-	{ ip4.start = p; }
-	goto st276;
-st276:
-	if ( ++p == pe )
-		goto _test_eof276;
-case 276:
-#line 4333 "src/uri.cc"
-	switch( (*p) ) {
-		case 46: goto st277;
-		case 58: goto st235;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st290;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st232;
-	} else
-		goto st232;
-	goto st175;
-st277:
-	if ( ++p == pe )
-		goto _test_eof277;
-case 277:
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st278;
-	goto st175;
-st278:
-	if ( ++p == pe )
-		goto _test_eof278;
-case 278:
-	if ( (*p) == 46 )
-		goto st279;
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st288;
-	goto st175;
-st279:
-	if ( ++p == pe )
-		goto _test_eof279;
-case 279:
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st280;
-	goto st175;
-st280:
-	if ( ++p == pe )
-		goto _test_eof280;
-case 280:
-	if ( (*p) == 46 )
-		goto st281;
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st286;
-	goto st175;
-st281:
-	if ( ++p == pe )
-		goto _test_eof281;
-case 281:
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st282;
-	goto st175;
-st282:
-	if ( ++p == pe )
-		goto _test_eof282;
-case 282:
-	if ( (*p) == 93 )
-		goto tr309;
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st283;
-	goto st175;
-st283:
-	if ( ++p == pe )
-		goto _test_eof283;
-case 283:
-	if ( (*p) == 93 )
-		goto tr309;
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st284;
-	goto st175;
-st284:
-	if ( ++p == pe )
-		goto _test_eof284;
-case 284:
-	if ( (*p) == 93 )
-		goto tr309;
-	goto st175;
-tr309:
-#line 145 "src/uri.rl"
-	{ ip4.end   = p; }
-	goto st285;
-st285:
-	if ( ++p == pe )
-		goto _test_eof285;
-case 285:
-#line 4420 "src/uri.cc"
-	if ( (*p) == 58 )
-		goto tr190;
-	goto st175;
-st286:
-	if ( ++p == pe )
-		goto _test_eof286;
-case 286:
-	if ( (*p) == 46 )
-		goto st281;
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st287;
-	goto st175;
-st287:
-	if ( ++p == pe )
-		goto _test_eof287;
-case 287:
-	if ( (*p) == 46 )
-		goto st281;
-	goto st175;
-st288:
-	if ( ++p == pe )
-		goto _test_eof288;
-case 288:
-	if ( (*p) == 46 )
-		goto st279;
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st289;
-	goto st175;
-st289:
-	if ( ++p == pe )
-		goto _test_eof289;
-case 289:
-	if ( (*p) == 46 )
-		goto st279;
-	goto st175;
-st290:
-	if ( ++p == pe )
-		goto _test_eof290;
-case 290:
-	switch( (*p) ) {
-		case 46: goto st277;
-		case 58: goto st235;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st291;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st233;
-	} else
-		goto st233;
-	goto st175;
-st291:
-	if ( ++p == pe )
-		goto _test_eof291;
-case 291:
-	switch( (*p) ) {
-		case 46: goto st277;
-		case 58: goto st235;
-		case 93: goto st260;
-	}
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st234;
-	} else if ( (*p) > 70 ) {
-		if ( 97 <= (*p) && (*p) <= 102 )
-			goto st234;
-	} else
-		goto st234;
-	goto st175;
-tr228:
-#line 140 "src/uri.rl"
-	{ password.start = p; }
-#line 166 "src/uri.rl"
-	{ service.start = p; }
-#line 161 "src/uri.rl"
-	{ dport.start   = p; port = 0; }
-#line 162 "src/uri.rl"
-	{ port = port * 10 + (int)(*p - '0'); }
-	goto st292;
-tr314:
-#line 162 "src/uri.rl"
-	{ port = port * 10 + (int)(*p - '0'); }
-	goto st292;
-st292:
-	if ( ++p == pe )
-		goto _test_eof292;
-case 292:
-#line 4510 "src/uri.cc"
-	if ( (*p) == 64 )
-		goto tr231;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr314;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st210;
-	} else
-		goto st210;
-	goto st175;
-tr229:
-#line 140 "src/uri.rl"
-	{ password.start = p; }
-#line 166 "src/uri.rl"
-	{ service.start = p; }
-	goto st293;
-st293:
-	if ( ++p == pe )
-		goto _test_eof293;
-case 293:
-#line 4532 "src/uri.cc"
-	if ( (*p) == 64 )
-		goto tr231;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st210;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st294;
-	} else
-		goto st294;
-	goto st175;
-st294:
-	if ( ++p == pe )
-		goto _test_eof294;
-case 294:
-	if ( (*p) == 64 )
-		goto tr231;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st210;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st295;
-	} else
-		goto st295;
-	goto st175;
-st295:
-	if ( ++p == pe )
-		goto _test_eof295;
-case 295:
-	if ( (*p) == 64 )
-		goto tr231;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st210;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st296;
-	} else
-		goto st296;
-	goto st175;
-st296:
-	if ( ++p == pe )
-		goto _test_eof296;
-case 296:
-	if ( (*p) == 64 )
-		goto tr231;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st210;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st297;
-	} else
-		goto st297;
-	goto st175;
-st297:
-	if ( ++p == pe )
-		goto _test_eof297;
-case 297:
-	if ( (*p) == 64 )
-		goto tr231;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st210;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st298;
-	} else
-		goto st298;
-	goto st175;
-st298:
-	if ( ++p == pe )
-		goto _test_eof298;
-case 298:
-	if ( (*p) == 64 )
-		goto tr231;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st210;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st299;
-	} else
-		goto st299;
-	goto st175;
-st299:
-	if ( ++p == pe )
-		goto _test_eof299;
-case 299:
-	if ( (*p) == 64 )
-		goto tr231;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st210;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st300;
-	} else
-		goto st300;
-	goto st175;
-st300:
-	if ( ++p == pe )
-		goto _test_eof300;
-case 300:
-	if ( (*p) == 64 )
-		goto tr231;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st210;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st301;
-	} else
-		goto st301;
-	goto st175;
-st301:
-	if ( ++p == pe )
-		goto _test_eof301;
-case 301:
-	if ( (*p) == 64 )
-		goto tr231;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st210;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st302;
-	} else
-		goto st302;
-	goto st175;
-st302:
-	if ( ++p == pe )
-		goto _test_eof302;
-case 302:
-	if ( (*p) == 64 )
-		goto tr231;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st210;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st303;
-	} else
-		goto st303;
-	goto st175;
-st303:
-	if ( ++p == pe )
-		goto _test_eof303;
-case 303:
-	if ( (*p) == 64 )
-		goto tr231;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st210;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st304;
-	} else
-		goto st304;
-	goto st175;
-st304:
-	if ( ++p == pe )
-		goto _test_eof304;
-case 304:
-	if ( (*p) == 64 )
-		goto tr231;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st210;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st305;
-	} else
-		goto st305;
-	goto st175;
-st305:
-	if ( ++p == pe )
-		goto _test_eof305;
-case 305:
-	if ( (*p) == 64 )
-		goto tr231;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st210;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st306;
-	} else
-		goto st306;
-	goto st175;
-st306:
-	if ( ++p == pe )
-		goto _test_eof306;
-case 306:
-	if ( (*p) == 64 )
-		goto tr231;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st210;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st307;
-	} else
-		goto st307;
-	goto st175;
-st307:
-	if ( ++p == pe )
-		goto _test_eof307;
-case 307:
-	if ( (*p) == 64 )
-		goto tr231;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st210;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st308;
-	} else
-		goto st308;
-	goto st175;
-st308:
-	if ( ++p == pe )
-		goto _test_eof308;
-case 308:
-	if ( (*p) == 64 )
-		goto tr231;
-	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto st210;
-	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto st210;
-	} else
-		goto st210;
-	goto st175;
-	}
-	_test_eof74: cs = 74; goto _test_eof; 
-	_test_eof2: cs = 2; goto _test_eof; 
-	_test_eof75: cs = 75; goto _test_eof; 
-	_test_eof76: cs = 76; goto _test_eof; 
-	_test_eof77: cs = 77; goto _test_eof; 
-	_test_eof78: cs = 78; goto _test_eof; 
-	_test_eof79: cs = 79; goto _test_eof; 
-	_test_eof80: cs = 80; goto _test_eof; 
-	_test_eof81: cs = 81; goto _test_eof; 
-	_test_eof82: cs = 82; goto _test_eof; 
-	_test_eof83: cs = 83; goto _test_eof; 
-	_test_eof84: cs = 84; goto _test_eof; 
-	_test_eof85: cs = 85; goto _test_eof; 
-	_test_eof86: cs = 86; goto _test_eof; 
-	_test_eof87: cs = 87; goto _test_eof; 
-	_test_eof88: cs = 88; goto _test_eof; 
-	_test_eof89: cs = 89; goto _test_eof; 
-	_test_eof90: cs = 90; goto _test_eof; 
-	_test_eof91: cs = 91; goto _test_eof; 
-	_test_eof92: cs = 92; goto _test_eof; 
-	_test_eof93: cs = 93; goto _test_eof; 
-	_test_eof94: cs = 94; goto _test_eof; 
-	_test_eof95: cs = 95; goto _test_eof; 
-	_test_eof96: cs = 96; goto _test_eof; 
-	_test_eof97: cs = 97; goto _test_eof; 
-	_test_eof98: cs = 98; goto _test_eof; 
-	_test_eof99: cs = 99; goto _test_eof; 
-	_test_eof100: cs = 100; goto _test_eof; 
-	_test_eof101: cs = 101; goto _test_eof; 
-	_test_eof102: cs = 102; goto _test_eof; 
-	_test_eof103: cs = 103; goto _test_eof; 
-	_test_eof104: cs = 104; goto _test_eof; 
-	_test_eof105: cs = 105; goto _test_eof; 
-	_test_eof106: cs = 106; goto _test_eof; 
-	_test_eof107: cs = 107; goto _test_eof; 
-	_test_eof108: cs = 108; goto _test_eof; 
-	_test_eof109: cs = 109; goto _test_eof; 
-	_test_eof110: cs = 110; goto _test_eof; 
-	_test_eof111: cs = 111; goto _test_eof; 
-	_test_eof112: cs = 112; goto _test_eof; 
-	_test_eof113: cs = 113; goto _test_eof; 
-	_test_eof114: cs = 114; goto _test_eof; 
-	_test_eof115: cs = 115; goto _test_eof; 
-	_test_eof116: cs = 116; goto _test_eof; 
-	_test_eof117: cs = 117; goto _test_eof; 
-	_test_eof118: cs = 118; goto _test_eof; 
-	_test_eof119: cs = 119; goto _test_eof; 
-	_test_eof120: cs = 120; goto _test_eof; 
-	_test_eof121: cs = 121; goto _test_eof; 
-	_test_eof122: cs = 122; goto _test_eof; 
-	_test_eof123: cs = 123; goto _test_eof; 
-	_test_eof124: cs = 124; goto _test_eof; 
-	_test_eof125: cs = 125; goto _test_eof; 
-	_test_eof126: cs = 126; goto _test_eof; 
-	_test_eof127: cs = 127; goto _test_eof; 
-	_test_eof128: cs = 128; goto _test_eof; 
-	_test_eof3: cs = 3; goto _test_eof; 
-	_test_eof4: cs = 4; goto _test_eof; 
-	_test_eof5: cs = 5; goto _test_eof; 
-	_test_eof129: cs = 129; goto _test_eof; 
-	_test_eof130: cs = 130; goto _test_eof; 
-	_test_eof131: cs = 131; goto _test_eof; 
-	_test_eof132: cs = 132; goto _test_eof; 
-	_test_eof133: cs = 133; goto _test_eof; 
-	_test_eof134: cs = 134; goto _test_eof; 
-	_test_eof135: cs = 135; goto _test_eof; 
-	_test_eof136: cs = 136; goto _test_eof; 
-	_test_eof6: cs = 6; goto _test_eof; 
-	_test_eof7: cs = 7; goto _test_eof; 
-	_test_eof8: cs = 8; goto _test_eof; 
-	_test_eof9: cs = 9; goto _test_eof; 
-	_test_eof10: cs = 10; goto _test_eof; 
-	_test_eof11: cs = 11; goto _test_eof; 
-	_test_eof12: cs = 12; goto _test_eof; 
-	_test_eof13: cs = 13; goto _test_eof; 
-	_test_eof14: cs = 14; goto _test_eof; 
-	_test_eof15: cs = 15; goto _test_eof; 
-	_test_eof16: cs = 16; goto _test_eof; 
-	_test_eof17: cs = 17; goto _test_eof; 
-	_test_eof18: cs = 18; goto _test_eof; 
-	_test_eof19: cs = 19; goto _test_eof; 
-	_test_eof20: cs = 20; goto _test_eof; 
-	_test_eof21: cs = 21; goto _test_eof; 
-	_test_eof22: cs = 22; goto _test_eof; 
-	_test_eof23: cs = 23; goto _test_eof; 
-	_test_eof24: cs = 24; goto _test_eof; 
-	_test_eof25: cs = 25; goto _test_eof; 
-	_test_eof26: cs = 26; goto _test_eof; 
-	_test_eof27: cs = 27; goto _test_eof; 
-	_test_eof28: cs = 28; goto _test_eof; 
-	_test_eof29: cs = 29; goto _test_eof; 
-	_test_eof30: cs = 30; goto _test_eof; 
-	_test_eof31: cs = 31; goto _test_eof; 
-	_test_eof32: cs = 32; goto _test_eof; 
-	_test_eof33: cs = 33; goto _test_eof; 
-	_test_eof34: cs = 34; goto _test_eof; 
-	_test_eof35: cs = 35; goto _test_eof; 
-	_test_eof36: cs = 36; goto _test_eof; 
-	_test_eof37: cs = 37; goto _test_eof; 
-	_test_eof38: cs = 38; goto _test_eof; 
-	_test_eof39: cs = 39; goto _test_eof; 
-	_test_eof40: cs = 40; goto _test_eof; 
-	_test_eof41: cs = 41; goto _test_eof; 
-	_test_eof42: cs = 42; goto _test_eof; 
-	_test_eof43: cs = 43; goto _test_eof; 
-	_test_eof44: cs = 44; goto _test_eof; 
-	_test_eof45: cs = 45; goto _test_eof; 
-	_test_eof137: cs = 137; goto _test_eof; 
-	_test_eof138: cs = 138; goto _test_eof; 
-	_test_eof139: cs = 139; goto _test_eof; 
-	_test_eof140: cs = 140; goto _test_eof; 
-	_test_eof141: cs = 141; goto _test_eof; 
-	_test_eof142: cs = 142; goto _test_eof; 
-	_test_eof143: cs = 143; goto _test_eof; 
-	_test_eof144: cs = 144; goto _test_eof; 
-	_test_eof145: cs = 145; goto _test_eof; 
-	_test_eof46: cs = 46; goto _test_eof; 
-	_test_eof47: cs = 47; goto _test_eof; 
-	_test_eof48: cs = 48; goto _test_eof; 
-	_test_eof49: cs = 49; goto _test_eof; 
-	_test_eof50: cs = 50; goto _test_eof; 
-	_test_eof51: cs = 51; goto _test_eof; 
-	_test_eof52: cs = 52; goto _test_eof; 
-	_test_eof53: cs = 53; goto _test_eof; 
-	_test_eof54: cs = 54; goto _test_eof; 
-	_test_eof55: cs = 55; goto _test_eof; 
-	_test_eof56: cs = 56; goto _test_eof; 
-	_test_eof57: cs = 57; goto _test_eof; 
-	_test_eof58: cs = 58; goto _test_eof; 
-	_test_eof59: cs = 59; goto _test_eof; 
-	_test_eof60: cs = 60; goto _test_eof; 
-	_test_eof61: cs = 61; goto _test_eof; 
-	_test_eof146: cs = 146; goto _test_eof; 
-	_test_eof62: cs = 62; goto _test_eof; 
-	_test_eof63: cs = 63; goto _test_eof; 
-	_test_eof64: cs = 64; goto _test_eof; 
-	_test_eof65: cs = 65; goto _test_eof; 
-	_test_eof66: cs = 66; goto _test_eof; 
-	_test_eof67: cs = 67; goto _test_eof; 
-	_test_eof147: cs = 147; goto _test_eof; 
-	_test_eof148: cs = 148; goto _test_eof; 
-	_test_eof149: cs = 149; goto _test_eof; 
-	_test_eof150: cs = 150; goto _test_eof; 
-	_test_eof151: cs = 151; goto _test_eof; 
-	_test_eof152: cs = 152; goto _test_eof; 
-	_test_eof153: cs = 153; goto _test_eof; 
-	_test_eof154: cs = 154; goto _test_eof; 
-	_test_eof155: cs = 155; goto _test_eof; 
-	_test_eof156: cs = 156; goto _test_eof; 
-	_test_eof157: cs = 157; goto _test_eof; 
-	_test_eof158: cs = 158; goto _test_eof; 
-	_test_eof159: cs = 159; goto _test_eof; 
-	_test_eof160: cs = 160; goto _test_eof; 
-	_test_eof161: cs = 161; goto _test_eof; 
-	_test_eof162: cs = 162; goto _test_eof; 
-	_test_eof163: cs = 163; goto _test_eof; 
-	_test_eof164: cs = 164; goto _test_eof; 
-	_test_eof165: cs = 165; goto _test_eof; 
-	_test_eof166: cs = 166; goto _test_eof; 
-	_test_eof167: cs = 167; goto _test_eof; 
-	_test_eof168: cs = 168; goto _test_eof; 
-	_test_eof68: cs = 68; goto _test_eof; 
-	_test_eof69: cs = 69; goto _test_eof; 
-	_test_eof70: cs = 70; goto _test_eof; 
-	_test_eof169: cs = 169; goto _test_eof; 
-	_test_eof170: cs = 170; goto _test_eof; 
-	_test_eof171: cs = 171; goto _test_eof; 
-	_test_eof172: cs = 172; goto _test_eof; 
-	_test_eof71: cs = 71; goto _test_eof; 
-	_test_eof72: cs = 72; goto _test_eof; 
-	_test_eof73: cs = 73; goto _test_eof; 
-	_test_eof173: cs = 173; goto _test_eof; 
-	_test_eof174: cs = 174; goto _test_eof; 
-	_test_eof175: cs = 175; goto _test_eof; 
-	_test_eof176: cs = 176; goto _test_eof; 
-	_test_eof177: cs = 177; goto _test_eof; 
-	_test_eof178: cs = 178; goto _test_eof; 
-	_test_eof179: cs = 179; goto _test_eof; 
-	_test_eof180: cs = 180; goto _test_eof; 
-	_test_eof181: cs = 181; goto _test_eof; 
-	_test_eof182: cs = 182; goto _test_eof; 
-	_test_eof183: cs = 183; goto _test_eof; 
-	_test_eof184: cs = 184; goto _test_eof; 
-	_test_eof185: cs = 185; goto _test_eof; 
-	_test_eof186: cs = 186; goto _test_eof; 
-	_test_eof187: cs = 187; goto _test_eof; 
-	_test_eof188: cs = 188; goto _test_eof; 
-	_test_eof189: cs = 189; goto _test_eof; 
-	_test_eof190: cs = 190; goto _test_eof; 
-	_test_eof191: cs = 191; goto _test_eof; 
-	_test_eof192: cs = 192; goto _test_eof; 
-	_test_eof193: cs = 193; goto _test_eof; 
-	_test_eof194: cs = 194; goto _test_eof; 
-	_test_eof195: cs = 195; goto _test_eof; 
-	_test_eof196: cs = 196; goto _test_eof; 
-	_test_eof197: cs = 197; goto _test_eof; 
-	_test_eof198: cs = 198; goto _test_eof; 
-	_test_eof199: cs = 199; goto _test_eof; 
-	_test_eof200: cs = 200; goto _test_eof; 
-	_test_eof201: cs = 201; goto _test_eof; 
-	_test_eof202: cs = 202; goto _test_eof; 
-	_test_eof203: cs = 203; goto _test_eof; 
-	_test_eof204: cs = 204; goto _test_eof; 
-	_test_eof205: cs = 205; goto _test_eof; 
-	_test_eof206: cs = 206; goto _test_eof; 
-	_test_eof207: cs = 207; goto _test_eof; 
-	_test_eof208: cs = 208; goto _test_eof; 
-	_test_eof209: cs = 209; goto _test_eof; 
-	_test_eof210: cs = 210; goto _test_eof; 
-	_test_eof211: cs = 211; goto _test_eof; 
-	_test_eof212: cs = 212; goto _test_eof; 
-	_test_eof213: cs = 213; goto _test_eof; 
-	_test_eof214: cs = 214; goto _test_eof; 
-	_test_eof215: cs = 215; goto _test_eof; 
-	_test_eof216: cs = 216; goto _test_eof; 
-	_test_eof217: cs = 217; goto _test_eof; 
-	_test_eof218: cs = 218; goto _test_eof; 
-	_test_eof219: cs = 219; goto _test_eof; 
-	_test_eof220: cs = 220; goto _test_eof; 
-	_test_eof221: cs = 221; goto _test_eof; 
-	_test_eof222: cs = 222; goto _test_eof; 
-	_test_eof223: cs = 223; goto _test_eof; 
-	_test_eof224: cs = 224; goto _test_eof; 
-	_test_eof225: cs = 225; goto _test_eof; 
-	_test_eof226: cs = 226; goto _test_eof; 
-	_test_eof227: cs = 227; goto _test_eof; 
-	_test_eof228: cs = 228; goto _test_eof; 
-	_test_eof229: cs = 229; goto _test_eof; 
-	_test_eof230: cs = 230; goto _test_eof; 
-	_test_eof231: cs = 231; goto _test_eof; 
-	_test_eof232: cs = 232; goto _test_eof; 
-	_test_eof233: cs = 233; goto _test_eof; 
-	_test_eof234: cs = 234; goto _test_eof; 
-	_test_eof235: cs = 235; goto _test_eof; 
-	_test_eof236: cs = 236; goto _test_eof; 
-	_test_eof237: cs = 237; goto _test_eof; 
-	_test_eof238: cs = 238; goto _test_eof; 
-	_test_eof239: cs = 239; goto _test_eof; 
-	_test_eof240: cs = 240; goto _test_eof; 
-	_test_eof241: cs = 241; goto _test_eof; 
-	_test_eof242: cs = 242; goto _test_eof; 
-	_test_eof243: cs = 243; goto _test_eof; 
-	_test_eof244: cs = 244; goto _test_eof; 
-	_test_eof245: cs = 245; goto _test_eof; 
-	_test_eof246: cs = 246; goto _test_eof; 
-	_test_eof247: cs = 247; goto _test_eof; 
-	_test_eof248: cs = 248; goto _test_eof; 
-	_test_eof249: cs = 249; goto _test_eof; 
-	_test_eof250: cs = 250; goto _test_eof; 
-	_test_eof251: cs = 251; goto _test_eof; 
-	_test_eof252: cs = 252; goto _test_eof; 
-	_test_eof253: cs = 253; goto _test_eof; 
-	_test_eof254: cs = 254; goto _test_eof; 
-	_test_eof255: cs = 255; goto _test_eof; 
-	_test_eof256: cs = 256; goto _test_eof; 
-	_test_eof257: cs = 257; goto _test_eof; 
-	_test_eof258: cs = 258; goto _test_eof; 
-	_test_eof259: cs = 259; goto _test_eof; 
-	_test_eof260: cs = 260; goto _test_eof; 
-	_test_eof261: cs = 261; goto _test_eof; 
-	_test_eof262: cs = 262; goto _test_eof; 
-	_test_eof263: cs = 263; goto _test_eof; 
-	_test_eof264: cs = 264; goto _test_eof; 
-	_test_eof265: cs = 265; goto _test_eof; 
-	_test_eof266: cs = 266; goto _test_eof; 
-	_test_eof267: cs = 267; goto _test_eof; 
-	_test_eof268: cs = 268; goto _test_eof; 
-	_test_eof269: cs = 269; goto _test_eof; 
-	_test_eof270: cs = 270; goto _test_eof; 
-	_test_eof271: cs = 271; goto _test_eof; 
-	_test_eof272: cs = 272; goto _test_eof; 
-	_test_eof273: cs = 273; goto _test_eof; 
-	_test_eof274: cs = 274; goto _test_eof; 
-	_test_eof275: cs = 275; goto _test_eof; 
-	_test_eof276: cs = 276; goto _test_eof; 
-	_test_eof277: cs = 277; goto _test_eof; 
-	_test_eof278: cs = 278; goto _test_eof; 
-	_test_eof279: cs = 279; goto _test_eof; 
-	_test_eof280: cs = 280; goto _test_eof; 
-	_test_eof281: cs = 281; goto _test_eof; 
-	_test_eof282: cs = 282; goto _test_eof; 
-	_test_eof283: cs = 283; goto _test_eof; 
-	_test_eof284: cs = 284; goto _test_eof; 
-	_test_eof285: cs = 285; goto _test_eof; 
-	_test_eof286: cs = 286; goto _test_eof; 
-	_test_eof287: cs = 287; goto _test_eof; 
-	_test_eof288: cs = 288; goto _test_eof; 
-	_test_eof289: cs = 289; goto _test_eof; 
-	_test_eof290: cs = 290; goto _test_eof; 
-	_test_eof291: cs = 291; goto _test_eof; 
-	_test_eof292: cs = 292; goto _test_eof; 
-	_test_eof293: cs = 293; goto _test_eof; 
-	_test_eof294: cs = 294; goto _test_eof; 
-	_test_eof295: cs = 295; goto _test_eof; 
-	_test_eof296: cs = 296; goto _test_eof; 
-	_test_eof297: cs = 297; goto _test_eof; 
-	_test_eof298: cs = 298; goto _test_eof; 
-	_test_eof299: cs = 299; goto _test_eof; 
-	_test_eof300: cs = 300; goto _test_eof; 
-	_test_eof301: cs = 301; goto _test_eof; 
-	_test_eof302: cs = 302; goto _test_eof; 
-	_test_eof303: cs = 303; goto _test_eof; 
-	_test_eof304: cs = 304; goto _test_eof; 
-	_test_eof305: cs = 305; goto _test_eof; 
-	_test_eof306: cs = 306; goto _test_eof; 
-	_test_eof307: cs = 307; goto _test_eof; 
-	_test_eof308: cs = 308; goto _test_eof; 
-
-	_test_eof: {}
-	if ( p == eof )
-	{
-	switch ( cs ) {
-	case 74: 
-	case 92: 
-	case 113: 
-	case 114: 
-	case 115: 
-	case 116: 
-	case 117: 
-	case 118: 
-	case 122: 
-	case 123: 
-	case 124: 
-	case 125: 
-	case 126: 
-	case 127: 
-	case 128: 
-	case 129: 
-	case 130: 
-	case 131: 
-	case 132: 
-	case 133: 
-	case 134: 
-	case 135: 
-	case 136: 
-	case 146: 
-	case 168: 
-	case 169: 
-	case 170: 
-	case 171: 
-	case 172: 
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-	break;
-	case 76: 
-	case 77: 
-	case 78: 
-	case 79: 
-	case 80: 
-	case 81: 
-	case 82: 
-	case 83: 
-	case 84: 
-	case 85: 
-	case 86: 
-	case 87: 
-	case 88: 
-	case 89: 
-	case 90: 
-	case 91: 
-	case 142: 
-	case 143: 
-	case 144: 
-	case 145: 
-	case 148: 
-	case 149: 
-	case 150: 
-	case 151: 
-	case 152: 
-	case 153: 
-	case 154: 
-	case 155: 
-	case 156: 
-	case 157: 
-	case 158: 
-	case 159: 
-	case 160: 
-	case 161: 
-	case 162: 
-	case 163: 
-#line 167 "src/uri.rl"
-	{ service.end   = p; }
-	break;
-	case 94: 
-	case 95: 
-#line 177 "src/uri.rl"
-	{ path.end   = p; }
-	break;
-	case 174: 
-	case 175: 
-	case 209: 
-	case 210: 
-	case 211: 
-	case 220: 
-	case 221: 
-	case 222: 
-	case 223: 
-	case 224: 
-	case 225: 
-	case 226: 
-	case 227: 
-	case 228: 
-	case 229: 
-	case 230: 
-	case 231: 
-	case 232: 
-	case 233: 
-	case 234: 
-	case 235: 
-	case 236: 
-	case 237: 
-	case 238: 
-	case 239: 
-	case 240: 
-	case 241: 
-	case 242: 
-	case 243: 
-	case 244: 
-	case 245: 
-	case 246: 
-	case 247: 
-	case 248: 
-	case 249: 
-	case 250: 
-	case 251: 
-	case 252: 
-	case 253: 
-	case 254: 
-	case 255: 
-	case 256: 
-	case 257: 
-	case 258: 
-	case 259: 
-	case 269: 
-	case 270: 
-	case 271: 
-	case 272: 
-	case 273: 
-	case 274: 
-	case 275: 
-	case 276: 
-	case 277: 
-	case 278: 
-	case 279: 
-	case 280: 
-	case 281: 
-	case 282: 
-	case 283: 
-	case 284: 
-	case 286: 
-	case 287: 
-	case 288: 
-	case 289: 
-	case 290: 
-	case 291: 
-#line 181 "src/uri.rl"
-	{ path.end   = p; }
-	break;
-	case 119: 
-	case 120: 
-	case 121: 
-#line 145 "src/uri.rl"
-	{ ip4.end   = p; }
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-	break;
-	case 137: 
-#line 154 "src/uri.rl"
-	{ ip6.end   = p - 1; }
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-	break;
-	case 164: 
-	case 165: 
-	case 166: 
-	case 167: 
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-#line 173 "src/uri.rl"
-	{ sport.end     = p; }
-	break;
-	case 93: 
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-#line 177 "src/uri.rl"
-	{ path.end   = p; }
-	break;
-	case 75: 
-	case 138: 
-	case 139: 
-	case 140: 
-	case 141: 
-	case 147: 
-#line 163 "src/uri.rl"
-	{ dport.end	 = p; }
-#line 167 "src/uri.rl"
-	{ service.end   = p; }
-	break;
-	case 97: 
-	case 98: 
-	case 99: 
-	case 100: 
-	case 101: 
-	case 102: 
-	case 103: 
-	case 104: 
-	case 105: 
-	case 106: 
-	case 107: 
-	case 108: 
-	case 109: 
-	case 110: 
-	case 111: 
-	case 112: 
-#line 167 "src/uri.rl"
-	{ service.end   = p; }
-#line 177 "src/uri.rl"
-	{ path.end   = p; }
-	break;
-	case 173: 
-	case 193: 
-	case 194: 
-	case 195: 
-	case 196: 
-	case 197: 
-	case 198: 
-	case 202: 
-	case 203: 
-	case 204: 
-	case 205: 
-	case 206: 
-	case 207: 
-	case 208: 
-	case 212: 
-	case 213: 
-	case 214: 
-	case 215: 
-	case 216: 
-	case 217: 
-	case 218: 
-	case 219: 
-	case 285: 
-#line 181 "src/uri.rl"
-	{ path.end   = p; }
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-	break;
-	case 177: 
-	case 178: 
-	case 179: 
-	case 180: 
-	case 181: 
-	case 182: 
-	case 183: 
-	case 184: 
-	case 185: 
-	case 186: 
-	case 187: 
-	case 188: 
-	case 189: 
-	case 190: 
-	case 191: 
-	case 192: 
-	case 265: 
-	case 266: 
-	case 267: 
-	case 268: 
-	case 293: 
-	case 294: 
-	case 295: 
-	case 296: 
-	case 297: 
-	case 298: 
-	case 299: 
-	case 300: 
-	case 301: 
-	case 302: 
-	case 303: 
-	case 304: 
-	case 305: 
-	case 306: 
-	case 307: 
-	case 308: 
-#line 181 "src/uri.rl"
-	{ path.end   = p; }
-#line 167 "src/uri.rl"
-	{ service.end   = p; }
-	break;
-	case 96: 
-#line 163 "src/uri.rl"
-	{ dport.end	 = p; }
-#line 167 "src/uri.rl"
-	{ service.end   = p; }
-#line 177 "src/uri.rl"
-	{ path.end   = p; }
-	break;
-	case 199: 
-	case 200: 
-	case 201: 
-#line 181 "src/uri.rl"
-	{ path.end   = p; }
-#line 145 "src/uri.rl"
-	{ ip4.end   = p; }
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-	break;
-	case 260: 
-#line 181 "src/uri.rl"
-	{ path.end   = p; }
-#line 154 "src/uri.rl"
-	{ ip6.end   = p - 1; }
-#line 158 "src/uri.rl"
-	{ host.end     = p; }
-	break;
-	case 176: 
-	case 261: 
-	case 262: 
-	case 263: 
-	case 264: 
-	case 292: 
-#line 181 "src/uri.rl"
-	{ path.end   = p; }
-#line 163 "src/uri.rl"
-	{ dport.end	 = p; }
-#line 167 "src/uri.rl"
-	{ service.end   = p; }
-	break;
-#line 5397 "src/uri.cc"
-	}
-	}
-
-	_out: {}
-	}
-
-#line 198 "src/uri.rl"
-
-
-	(void)uri_first_final;
-	(void)uri_error;
-	(void)uri_en_main;
-
-	if (login.start && login.end && password.start && password.end) {
-		snprintf(uri->login, sizeof(uri->login),
-			 "%.*s", (int) (login.end - login.start), login.start);
-		snprintf(uri->password, sizeof(uri->password),
-			 "%.*s", (int) (password.end - password.start),
-			 password.start);
-	}
-
-	if (path.start && path.end) {
-		struct sockaddr_un *un = (struct sockaddr_un *)&uri->addr;
-		uri->addr_len = sizeof(*un);
-		un->sun_family = AF_UNIX;
-		if (path.end - path.start >= sizeof(un->sun_path))
-			return -1;
-
-		snprintf(un->sun_path, sizeof(un->sun_path),
-			 "%.*s", (int) (path.end - path.start), path.start);
-		snprintf(uri->schema, sizeof(uri->schema), "unix");
-		return 0;
-	}
-
-	if (schema.start && schema.end) {
-		snprintf(uri->schema, sizeof(uri->schema),
-			 "%.*s", (int) (schema.end - schema.start), schema.start);
-	} else {
-		snprintf(uri->schema, sizeof(uri->schema), "tcp");
-	}
-
-
-	/* only port was defined */
-	if (sport.start && sport.end) {
-		struct sockaddr_in *in = (struct sockaddr_in *)&uri->addr;
-		uri->addr_len = sizeof(*in);
-
-		in->sin_family = AF_INET;
-		in->sin_port = htons(port);
-		in->sin_addr.s_addr = INADDR_ANY;
-		return 0;
-	}
-
-
-	if (!(dport.start && dport.end)) {
-		port = 0;
-		if (service.start && service.end) {
-			if (service.end - service.start >= NI_MAXSERV)
-				return -1;
-			char sname[NI_MAXSERV];
-			snprintf(sname, sizeof(sname), "%.*s",
-				 (int) (service.end - service.start),
-                 service.start);
-			struct servent *s = getservbyname(sname, NULL);
-			if (!s)
-				return -1;
-			port = ntohs(s->s_port);
-		}
-	}
-
-
-	/* IPv4 uri */
-	if (ip4.start && ip4.end) {
-		struct sockaddr_in *in =
-			(struct sockaddr_in *)&uri->addr;
-		uri->addr_len = sizeof(*in);
-
-		in->sin_family = AF_INET;
-		in->sin_port = htons(port);
-
-		char sip4[3 * 4 + 3 + 1];
-		memset(sip4, 0, sizeof(sip4));
-		snprintf(sip4, sizeof(sip4), "%.*s", (int) (ip4.end - ip4.start),
-			 ip4.start);
-		if (inet_aton(sip4, &in->sin_addr))
-			return 0;
-		return -1;
-	}
-
-	/* IPv6 uri */
-	if (ip6.start && ip6.end) {
-		struct sockaddr_in6 *in6 =
-			(struct sockaddr_in6 *)&uri->addr;
-		uri->addr_len = sizeof(*in6);
-
-
-		char sip6[8 * 4 + 7 + 1];
-		memset(sip6, 0, sizeof(sip6));
-		snprintf(sip6, sizeof(sip6), "%.*s", (int) (ip6.end - ip6.start),
-			 ip6.start);
-
-		in6->sin6_family = AF_INET6;
-		in6->sin6_port = htonl(port);
-
-		if (inet_pton(AF_INET6, sip6, (void *)&in6->sin6_addr))
-			return 0;
-
-		return -1;
-	}
-
-
-	if (!host.start || !host.end)
-		return -1;
-
-	if (host.end - host.start >= NI_MAXHOST)
-		return -1;
-
-	char shost[NI_MAXHOST];
-	char sservice[NI_MAXSERV];
-	snprintf(shost, sizeof(shost), "%.*s", (int) (host.end - host.start),
-		 host.start);
-	if (service.end) {
-		snprintf(sservice, sizeof(sservice), "%.*s",
-			 (int) (service.end - service.start), service.start);
-	} else {
-		sservice[0] = '\0';
-	}
-
-	struct addrinfo hints, *res;
-	memset(&hints, 0, sizeof(hints));
-	hints.ai_protocol = getprotobyname("tcp")->p_proto;
-
-	if (getaddrinfo(shost, sservice, &hints, &res) != 0)
-		return -1;
-
-	uri->addr_len = res->ai_addrlen;
-	memcpy((void *)&uri->addr, (void *)res->ai_addr, res->ai_addrlen);
-	freeaddrinfo(res);
-	return 0;
-}
-
-/* vim: set ft=ragel: */
diff --git a/src/uri.h b/src/uri.h
index 377b4a3cb0f02a4b8c2097a9122c472604996c61..8bdf34e13d2a84c14ba8e092a38ab77272f2e49e 100644
--- a/src/uri.h
+++ b/src/uri.h
@@ -28,43 +28,47 @@
  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include <sys/types.h>		/* for netinet/ip.h on BSD */
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netdb.h>
-#include <sys/un.h>
 
-enum { URI_STR_LEN = 32 };
+#include <stddef.h>
+#include <netdb.h> /* NI_MAXHOST, NI_MAXSERV */
+#include <limits.h> /* _POSIX_PATH_MAX */
 
-/** A parsed representation of an URI */
-struct uri {
-
-	union {
-		struct sockaddr addr;
-		struct sockaddr_in in;
-		struct sockaddr_un un;
-		struct sockaddr_in6 in6;
-		struct sockaddr_storage addr_storage;
-	};
-	socklen_t addr_len;
+#if defined(__cplusplus)
+extern "C" {
+#endif /* defined(__cplusplus) */
 
-	char schema[URI_STR_LEN];
-	char login[URI_STR_LEN];
-	char password[URI_STR_LEN];
+struct uri {
+	const char *scheme;
+	size_t scheme_len;
+	const char *login;
+	size_t login_len;
+	const char *password;
+	size_t password_len;
+	const char *host;
+	size_t host_len;
+	const char *service;
+	size_t service_len;
+	const char *path;
+	size_t path_len;
+	const char *query;
+	size_t query_len;
+	const char *fragment;
+	size_t fragment_len;
+	int host_hint;
 };
 
-/**
- * Parse a string and fill uri struct.
- * @retval 0 success
- * @retval -1 error
- */
+#define URI_HOST_UNIX "unix/"
+#define URI_MAXHOST NI_MAXHOST
+#define URI_MAXSERVICE _POSIX_PATH_MAX /* _POSIX_PATH_MAX always > NI_MAXSERV */
+
 int
 uri_parse(struct uri *uri, const char *str);
 
-/** Convert an uri to string */
-const char *
-uri_to_string(const struct uri * uri);
+char *
+uri_format(const struct uri *uri);
 
+#if defined(__cplusplus)
+} /* extern "C" */
+#endif /* defined(__cplusplus) */
 
 #endif /* TARANTOOL_URI_H_INCLUDED */
diff --git a/src/uri.rl b/src/uri.rl
index ddde079ba3305719cc95d224ba9acaa56b42b6c9..151341bfb1e2ab966c80f1c756cfe1ba78c124f3 100644
--- a/src/uri.rl
+++ b/src/uri.rl
@@ -28,305 +28,193 @@
  */
 #include "uri.h"
 #include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include <sys/socket.h>
-#include <netinet/ip.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/un.h>
-#include <netdb.h>
-
-const char *
-uri_to_string(const struct uri * uri)
-{
-	static __thread char
-		str[NI_MAXSERV + NI_MAXHOST + sizeof(uri->schema)];
-
-	if (!uri || !uri->addr_len) {
-		snprintf(str, sizeof(str), "unknown address");
-		return str;
-	}
-
-	switch (uri->addr.sa_family) {
-	case AF_INET6:
-	case AF_INET:
-	{
-		char shost[NI_MAXHOST];
-		char sservice[NI_MAXSERV];
-		getnameinfo(
-			    (struct sockaddr *)&uri->addr,
-			    uri->addr_len,
-			    shost, sizeof(shost),
-			    sservice, sizeof(sservice),
-			    NI_NUMERICHOST|NI_NUMERICSERV);
-		if (uri->addr.sa_family == AF_INET) {
-			if (strncmp(uri->schema, "tcp", 3) == 0) {
-				snprintf(str, sizeof(str), "%s:%s",
-					 shost, sservice);
-			} else {
-				snprintf(str, sizeof(str), "%s://%s:%s",
-					 uri->schema, shost, sservice);
-			}
-		} else {
-			if (strncmp(uri->schema, "tcp", 3) == 0) {
-				snprintf(str, sizeof(str), "%s:%s",
-					 shost, sservice);
-			} else {
-				snprintf(str, sizeof(str), "%s://[%s]:%s",
-					 uri->schema, shost, sservice);
-			}
-		}
-                break;
-	}
-	case AF_UNIX:
-	{
-		struct sockaddr_un *un =
-			(struct sockaddr_un *)&uri->addr;
-		snprintf(str, sizeof(str), "unix://%.*s",
-			 (int) sizeof(un->sun_path), un->sun_path);
-	        break;
-	}
-	default:
-		snprintf(str, sizeof(str), "unknown address");
-	        break;
-	}
-	return str;
-}
-
+#include <stdio.h> /* snprintf */
 int
 uri_parse(struct uri *uri, const char *p)
 {
-	(void) uri;
 	const char *pe = p + strlen(p);
 	const char *eof = pe;
 	int cs;
 	memset(uri, 0, sizeof(*uri));
 
-	struct {
-		const char *start;
-		const char *end;
-	}	schema		= { 0, 0 },
-		host		= { 0, 0 },
-		service		= { 0, 0 },
-		sport		= { 0, 0 },
-		login		= { 0, 0 },
-		password	= { 0, 0 },
-		ip4		= { 0, 0 },
-		ip6		= { 0, 0 },
-		path		= { 0, 0 },
-		dport		= { 0, 0 }
-	;
-
-	unsigned port = 0;
+	if (p == pe)
+		return -1;
+
+	const char *s = NULL, *login = NULL, *scheme = NULL;
+	size_t login_len = 0, scheme_len = 0;
 
 	%%{
 		machine uri;
 		write data;
 
-		hex1_4 = ([0-9a-fA-F]{1,4});
-
+		#
+		# Line by line translation of RFC3986
+		# http://tools.ietf.org/html/rfc3986#appendix-A
+		#
+
+		gen_delims = (":" | "/" | "?" | "#" | "[" | "]" | "@");
+		sub_delims = ("!" | "$" | "&" | "'" | "(" | ")"
+				 | "*" | "+" | "," | ";" | "=");
+
+		reserved = (gen_delims | sub_delims);
+		unreserved = alpha | digit | "-" | "_" | "~" | ".";
+		pct_encoded = ("%%" | ("%" xdigit xdigit?)
+				   | ("%u" xdigit xdigit xdigit xdigit));
+
+		pchar_nc = unreserved | pct_encoded | sub_delims | "@";
+		pchar = pchar_nc | ":";
+
+		query = (pchar | "/" | "?")*
+			>{ s = p; }
+			%{ uri->query = s; uri->query_len = p - s; };
+
+		fragment = (pchar | "/" | "?")*
+			>{ s = p; }
+			%{ uri->fragment = s; uri->fragment_len = p - s; };
+
+		segment = pchar*;
+		segment_nz = pchar+;
+		segment_nz_nc = pchar_nc+;
+
+		path_abempty  = ( "/" segment )*;
+		path_absolute = ("/" ( segment_nz ( "/" segment )* )?);
+		path_noscheme = (segment_nz_nc ( "/" segment )*);
+		path_rootless = (pchar_nc ( "/" segment )*);
+		path_empty    = "";
+
+		path = path_abempty    # begins with "/" or is empty
+		     | path_absolute   # begins with "/" but not "//"
+		     | path_noscheme   # begins with a non-colon segment
+		     | path_rootless   # begins with a segment
+		     | path_empty;     # zero characters
+
+		reg_name = (unreserved | pct_encoded | sub_delims)+
+			>{ s = p; }
+			%{ uri->host = s; uri->host_len = p - s;};
+
+		hex1_4 = ([0-9a-fa-f]{1,4});
+
+		ip4addr = ((digit{1,3}) (("." digit{1,3}){3}));
+		ip4 = ip4addr
+			>{ s = p; }
+			%{ uri->host = s; uri->host_len = p - s;
+			   uri->host_hint = 1; };
+
+		ip6	= ("[" (
+				((hex1_4?) ((":" (hex1_4?)){1,8})) |
+				("::" [ff][ff][ff][ff] ":" ip4addr))
+			>{ s = p; }
+			%{ uri->host = s; uri->host_len = p - s;
+				   uri->host_hint = 2; }
+			   "]");
+
+		action unix{
+			/*
+			 * This action is also called for path_* terms.
+			 * I absolutely have no idea why.
+			 */
+			if (uri->host_hint != 3) {
+				uri->host_hint = 3;
+				uri->host = URI_HOST_UNIX;
+				uri->host_len = strlen(URI_HOST_UNIX);
+				uri->service = s; uri->service_len = p - s;
+				/* a workaround for grammar limitations */
+				uri->path = NULL;
+				uri->path_len = 0;
+			};
+		}
+		# Non-standard: "unix/" support
+		unix = ("unix/:" %{ s = p;} path) %unix;
 
-		schema		= ((alpha+) "://")
-			>{ schema.start = p; }
-		    %{ schema.end   = p - 3; };
+		service = (digit+ | alpha*)
+			>{ s = p; }
+			%{ uri->service = s; uri->service_len = p - s; };
 
-		login		= (alnum+)
-			>{ login.start  = p; }
-		    %{ login.end    = p; };
+		host =  (ip4 | ip6 | reg_name);
 
-		password	= (alnum+)
-			>{ password.start = p; }
-		    %{ password.end   = p; };
+		login = (unreserved | pct_encoded | sub_delims )+
+			>{ s = p; }
+			%{ login = s; login_len = p - s; };
 
-		ip4	= ((digit{1,3}) (("." digit{1,3}){3}))
-			>{ ip4.start = p; }
-		    %{ ip4.end   = p; };
+		password = (unreserved | pct_encoded | sub_delims )+
+			>{ s = p; }
+			%{ uri->password = s; uri->password_len = p - s; };
 
-		ip4_6	= ("[::" [fF][fF][fF][fF] ":" ip4 "]");
+		# Non-standard: split userinfo to login and password
+		userinfo = login (":" password)?
+			%{ uri->login = login; uri->login_len = login_len; };
 
-		ip6	= ("["
-			   (hex1_4?)
-			   ((":" (hex1_4?)){1,8})
-			   "]")
-			>{ ip6.start = p + 1; }
-		    %{ ip6.end   = p - 1; };
+		# Non-standard: use service instead of port here + support unix
+		authority = (userinfo "@")? ((host (":" service)?) | (unix  ":"));
 
-		host		= (ip4_6 | ip4 | ip6 | ([^:?]+))
-			>{ host.start   = p; }
-		    %{ host.end     = p; };
+		scheme = alpha > { s = p; }
+			 (alpha | digit | "+" | "-" | ".")*
+			%{scheme = s; scheme_len = p - s; };
 
-		dport		= ([1-9] (digit*))
-			>{ dport.start   = p; port = 0; }
-		    ${ port = port * 10 + (int)(*p - '0'); }
-		    %{ dport.end	 = p; };
+		# relative_part = "//" authority > { s  =  p } path_abempty |
+		#	 path_absolute |
+		#	 path_noscheme |
+		#	 path_empty;
 
-		service		= (dport | (alpha{1,16}))
-			>{ service.start = p; }
-		    %{ service.end   = p; };
+		# Non-standard: allow URI without scheme
+		hier_part_noscheme = (((authority %{ s = p; } path_abempty?
+					  | path_absolute?
+					  | path_rootless?
+					  | path_empty?
+				) %{ uri->path = s; uri->path_len = p - s; }) |
+				unix);
 
+		hier_part = "//"
+			>{ uri->scheme = scheme; uri->scheme_len = scheme_len;}
+			hier_part_noscheme;
 
-		port		= ([1-9] digit*)
-			>{ sport.start   = p; port = 0; }
-		    ${ port = port * 10 + (int)(*p - '0'); }
-		    %{ sport.end     = p; };
+		# relative_ref = relative_part ("?" >{ s = p; } query)?
+		#	("#" >{ s = p; } fragment)?;
 
-		abspath		= ("/" any+)
-			>{ path.start = p; }
-		    %{ path.end   = p; };
+		# absolute_URI = scheme ":" hier_part ("?" >{ s = p; } query);
 
-		file		= (any+)
-			>{ path.start = p; }
-		    %{ path.end   = p; };
+		PORT = digit+
+			>{ uri->service = p; }
+			%{ uri->service_len = p - uri->service;
+			   uri->host = NULL; uri->host_len = 0; };
 
+		PATH = ((userinfo "@")? %{ s = p; } path_absolute %unix);
 
-		main := (
-		    ("unix://"
-		      ((login ":" password "@") ?) file) |
+		URI = ((scheme ":" hier_part) | hier_part_noscheme)
+			("?" >{ s = p; } query)? ("#" >{ s = p; } fragment)?;
 
-		     ((schema)?
-			((login ":" password "@")?)
-			host
-			((":" service)?))		    |
+		# Non-RFC: support port and absolute path
+		main := URI | PORT | PATH;
 
-		     port				    |
-		     abspath
-		);
 		write init;
 		write exec;
 	}%%
 
-	(void)uri_first_final;
-	(void)uri_error;
-	(void)uri_en_main;
-
-	if (login.start && login.end && password.start && password.end) {
-		snprintf(uri->login, sizeof(uri->login),
-			 "%.*s", (int) (login.end - login.start), login.start);
-		snprintf(uri->password, sizeof(uri->password),
-			 "%.*s", (int) (password.end - password.start),
-			 password.start);
-	}
-
-	if (path.start && path.end) {
-		struct sockaddr_un *un = (struct sockaddr_un *)&uri->addr;
-		uri->addr_len = sizeof(*un);
-		un->sun_family = AF_UNIX;
-		if (path.end - path.start >= sizeof(un->sun_path))
-			return -1;
-
-		snprintf(un->sun_path, sizeof(un->sun_path),
-			 "%.*s", (int) (path.end - path.start), path.start);
-		snprintf(uri->schema, sizeof(uri->schema), "unix");
-		return 0;
-	}
-
-	if (schema.start && schema.end) {
-		snprintf(uri->schema, sizeof(uri->schema),
-			 "%.*s", (int) (schema.end - schema.start), schema.start);
-	} else {
-		snprintf(uri->schema, sizeof(uri->schema), "tcp");
-	}
-
-
-	/* only port was defined */
-	if (sport.start && sport.end) {
-		struct sockaddr_in *in = (struct sockaddr_in *)&uri->addr;
-		uri->addr_len = sizeof(*in);
-
-		in->sin_family = AF_INET;
-		in->sin_port = htons(port);
-		in->sin_addr.s_addr = INADDR_ANY;
-		return 0;
-	}
-
-
-	if (!(dport.start && dport.end)) {
-		port = 0;
-		if (service.start && service.end) {
-			if (service.end - service.start >= NI_MAXSERV)
-				return -1;
-			char sname[NI_MAXSERV];
-			snprintf(sname, sizeof(sname), "%.*s",
-				 (int) (service.end - service.start),
-                 service.start);
-			struct servent *s = getservbyname(sname, NULL);
-			if (!s)
-				return -1;
-			port = ntohs(s->s_port);
-		}
-	}
-
-
-	/* IPv4 uri */
-	if (ip4.start && ip4.end) {
-		struct sockaddr_in *in =
-			(struct sockaddr_in *)&uri->addr;
-		uri->addr_len = sizeof(*in);
-
-		in->sin_family = AF_INET;
-		in->sin_port = htons(port);
-
-		char sip4[3 * 4 + 3 + 1];
-		memset(sip4, 0, sizeof(sip4));
-		snprintf(sip4, sizeof(sip4), "%.*s", (int) (ip4.end - ip4.start),
-			 ip4.start);
-		if (inet_aton(sip4, &in->sin_addr))
-			return 0;
+	if (uri->path_len == 0)
+		uri->path = NULL;
+	if (uri->service_len == 0)
+		uri->service = NULL;
+	if (uri->service_len >= URI_MAXSERVICE)
 		return -1;
-	}
-
-	/* IPv6 uri */
-	if (ip6.start && ip6.end) {
-		struct sockaddr_in6 *in6 =
-			(struct sockaddr_in6 *)&uri->addr;
-		uri->addr_len = sizeof(*in6);
-
-
-		char sip6[8 * 4 + 7 + 1];
-		memset(sip6, 0, sizeof(sip6));
-		snprintf(sip6, sizeof(sip6), "%.*s", (int) (ip6.end - ip6.start),
-			 ip6.start);
-
-		in6->sin6_family = AF_INET6;
-		in6->sin6_port = htonl(port);
-
-		if (inet_pton(AF_INET6, sip6, (void *)&in6->sin6_addr))
-			return 0;
-
-		return -1;
-	}
-
-
-	if (!host.start || !host.end)
+	if (uri->host_len >= URI_MAXHOST)
 		return -1;
 
-	if (host.end - host.start >= NI_MAXHOST)
-		return -1;
-
-	char shost[NI_MAXHOST];
-	char sservice[NI_MAXSERV];
-	snprintf(shost, sizeof(shost), "%.*s", (int) (host.end - host.start),
-		 host.start);
-	if (service.end) {
-		snprintf(sservice, sizeof(sservice), "%.*s",
-			 (int) (service.end - service.start), service.start);
-	} else {
-		sservice[0] = '\0';
-	}
-
-	struct addrinfo hints, *res;
-	memset(&hints, 0, sizeof(hints));
-	hints.ai_protocol = getprotobyname("tcp")->p_proto;
-
-	if (getaddrinfo(shost, sservice, &hints, &res) != 0)
-		return -1;
+	(void)uri_first_final;
+	(void)uri_error;
+	(void)uri_en_main;
+	(void)eof;
 
-	uri->addr_len = res->ai_addrlen;
-	memcpy((void *)&uri->addr, (void *)res->ai_addr, res->ai_addrlen);
-	freeaddrinfo(res);
-	return 0;
+	return cs >= uri_first_final ? 0 : -1;
 }
 
+char *
+uri_format(const struct uri *uri)
+{
+	static char buf[1024];
+	/* very primitive implementation suitable for our needs */
+	snprintf(buf, sizeof(buf), "%.*s:%.*s",
+		 (int) uri->host_len, uri->host != NULL ? uri->host : "*",
+		 (int) uri->service_len, uri->service);
+	return buf;
+}
 /* vim: set ft=ragel: */
diff --git a/src/util.cc b/src/util.cc
index 6f30246714bc5ec326ab80fce74530f10adcb6aa..f0cd3ca37cf1eb6a557f4322f97eaf9d8589a3c2 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -314,7 +314,7 @@ backtrace_foreach(backtrace_cb cb, void *frame_, void *stack, size_t stack_size,
 	}
 }
 
-void
+extern "C" void
 print_backtrace()
 {
 	void *frame = __builtin_frame_address(0);
diff --git a/test/app/cfg.result b/test/app/cfg.result
index 5ded3d0573975846c06847d6428e2e2ed3fafa9f..38f4a9c0db8c3de4ad176a7e8d11d5b527ce1b80 100644
--- a/test/app/cfg.result
+++ b/test/app/cfg.result
@@ -1,2 +1,10 @@
-false	[string "-- load_cfg.lua - internal file..."]:137: Please call box.cfg{} first
-true	table
+TAP version 13
+1..8
+ok - exception on unconfigured box
+ok - configured box
+ok - cfg.wal_mode default value
+ok - cfg.wal_mode default value
+ok - cfg.wal_mode change
+ok - cfg.wal_mode default value
+ok - cfg.wal_mode change
+ok - cfg.wal_mode default value
diff --git a/test/app/cfg.test.lua b/test/app/cfg.test.lua
index bce98a2db290b603bec2a20e71572090c8a3ea2a..d768107c2cae79144649420f3a1ae68ca9b86e91 100755
--- a/test/app/cfg.test.lua
+++ b/test/app/cfg.test.lua
@@ -1,19 +1,48 @@
 #!/usr/bin/env tarantool
 
+local tap = require('tap')
+local test = tap.test('cfg')
+test:plan(8)
+
 --------------------------------------------------------------------------------
 -- All box members must raise an exception on access if box.cfg{} wasn't called
 --------------------------------------------------------------------------------
 
 local box = require('box')
-local function test()
+local function testfun()
     return type(box.space)
 end
 
-print(pcall(test))
+local status, result = pcall(testfun)
+
+test:ok(not status and result:match('Please call box.cfg{}'),
+    'exception on unconfigured box')
+
 box.cfg{
     logger="tarantool.log",
     slab_alloc_arena=0.1,
+    wal_mode = "", -- "" means default value
 }
-print(pcall(test))
 
+status, result = pcall(testfun)
+test:ok(status and result == 'table', 'configured box')
+
+--------------------------------------------------------------------------------
+-- gh-534: Segmentation fault after two bad wal_mode settings
+--------------------------------------------------------------------------------
+
+test:is(box.cfg.wal_mode, "write", "cfg.wal_mode default value")
+box.cfg{wal_mode = ""}
+test:is(box.cfg.wal_mode, "write", "cfg.wal_mode default value")
+box.cfg{wal_mode = "none"}
+test:is(box.cfg.wal_mode, "none", "cfg.wal_mode change")
+-- "" or NULL resets option to default value
+box.cfg{wal_mode = ""}
+test:is(box.cfg.wal_mode, "write", "cfg.wal_mode default value")
+box.cfg{wal_mode = "none"}
+test:is(box.cfg.wal_mode, "none", "cfg.wal_mode change")
+box.cfg{wal_mode = require('msgpack').NULL}
+test:is(box.cfg.wal_mode, "write", "cfg.wal_mode default value")
+
+test:check()
 os.exit(0)
diff --git a/test/app/console.result b/test/app/console.result
index e7f5b5ca465f82e795277c588e439b323a4cc9e4..40596ba7e469aa898ae91efc7b5cbc639a151dfa 100644
--- a/test/app/console.result
+++ b/test/app/console.result
@@ -1,6 +1,7 @@
 TAP version 13
-1..18
+1..26
 ok - console.listen started
+ok - Handshake
 ok - connect to console
 ok - eval
 ok - state.socker:peer().host
@@ -11,6 +12,7 @@ ok - get delimiter is ';'
 ok - clear delimiter
 ok - remote network error
 ok - remote access denied
+ok - remote access denied
 ok - remote connect
 ok - remote eval
 ok - remote state.remote.host
@@ -18,3 +20,9 @@ ok - remote state.remote.port
 ok - remote state.prompt
 ok - remote disconnect
 ok - console.listen stopped
+ok - console.listen uri support
+ok - console.listen uri support
+ok - console.listen uri support
+ok - console.listen uri support
+ok - console.listen uri support
+ok - console.listen uri support
diff --git a/test/app/console.test.lua b/test/app/console.test.lua
index 516d4eb46d5595ca9e8f4565909da04e110888e5..5a611cc4e4b7c7961534b53c1d136311cdcef5f1 100755
--- a/test/app/console.test.lua
+++ b/test/app/console.test.lua
@@ -12,7 +12,7 @@ os.remove(CONSOLE_SOCKET)
 os.remove(IPROTO_SOCKET)
 
 box.cfg{
-    listen='unix://'..IPROTO_SOCKET;
+    listen=IPROTO_SOCKET;
     slab_alloc_arena=0.1,
     logger="tarantool.log",
 }
@@ -22,12 +22,14 @@ local EOL = "\n%.%.%.\n"
 
 test = tap.test("console")
 
-test:plan(18)
+test:plan(26)
 
 -- Start console and connect to it
 local server = console.listen(CONSOLE_SOCKET)
 test:ok(server ~= nil, "console.listen started")
 local client = socket.tcp_connect("unix/", CONSOLE_SOCKET)
+local handshake = client:read{chunk = 128}
+test:ok(string.match(handshake, '^Tarantool .*console') ~= nil, 'Handshake')
 test:ok(client ~= nil, "connect to console")
 
 -- Execute some command
@@ -55,22 +57,30 @@ client:write("require('console').delimiter('');\n")
 test:is(yaml.decode(client:read(EOL)), '', "clear delimiter")
 
 -- Connect to iproto console (CALL)
-client:write(string.format("require('console').connect('unix/', '/')\n"))
+client:write(string.format("require('console').connect('/')\n"))
 -- error: Connection is not established
 test:ok(yaml.decode(client:read(EOL))[1].error:find('not established'),
     'remote network error')
 
-client:write(string.format("require('console').connect('unix/', '%s')\n",
+client:write(string.format("require('console').connect('%s')\n",
     IPROTO_SOCKET))
 -- error: Execute access denied for user 'guest' to function 'dostring
 test:ok(yaml.decode(client:read(EOL))[1].error:find('access denied'),
     'remote access denied')
 
+-- create user
+box.schema.user.create('test', { password = 'pass' })
+client:write(string.format("require('console').connect('test:pass@%s')\n",
+    IPROTO_SOCKET))
+-- error: Execute access denied for user 'tester' to function 'dostring
+test:ok(yaml.decode(client:read(EOL))[1].error:find('access denied'),
+    'remote access denied')
+
 -- Add permissions to execute `dostring` for `guest`
 box.schema.func.create('dostring')
-box.schema.user.grant('guest', 'execute', 'function', 'dostring')
+box.schema.user.grant('test', 'execute', 'function', 'dostring')
 
-client:write(string.format("require('console').connect('unix/', '%s')\n",
+client:write(string.format("require('console').connect('test:pass@%s')\n",
     IPROTO_SOCKET))
 test:is(yaml.decode(client:read(EOL)), '', "remote connect")
 
@@ -102,11 +112,24 @@ server:close()
 -- Check that admon console has been stopped
 test:isnil(socket.tcp_connect("unix/", CONSOLE_SOCKET), "console.listen stopped")
 
-test:check()
-
 -- Stop iproto (not implemented yet)
 -- box.cfg{listen = nil}
-
-os.remove(CONSOLE_SOCKET)
 os.remove(IPROTO_SOCKET)
+
+local s = console.listen('127.0.0.1:0')
+addr = s:name()
+test:is(addr.family, 'AF_INET', 'console.listen uri support')
+test:is(addr.host, '127.0.0.1', 'console.listen uri support')
+test:isnt(addr.port, 0, 'console.listen uri support')
+s:close()
+
+local s = console.listen('console://unix/:'..CONSOLE_SOCKET)
+addr = s:name()
+test:is(addr.family, 'AF_UNIX', 'console.listen uri support')
+test:is(addr.host, 'unix/', 'console.listen uri support')
+test:is(addr.port, CONSOLE_SOCKET, 'console.listen uri support')
+s:close()
+
+test:check()
+
 os.exit(0)
diff --git a/test/app/float_value.result b/test/app/float_value.result
index b7300c58a9b73fe818e6f67ac9632e5acc1b01f6..c3cfdb6c80f7d36870ddc5f0a736d81db0f93c16 100644
--- a/test/app/float_value.result
+++ b/test/app/float_value.result
@@ -11,15 +11,16 @@ box.cfg
 10	logger_nonblock:true
 11	snap_dir:.
 12	coredump:false
-13	wal_mode:write
-14	panic_on_snap_error:true
-15	panic_on_wal_error:false
-16	too_long_threshold:0.01
-17	readahead:16320
-18	wal_dir:.
-19	snapshot_period:0
-20	slab_alloc_minimal:64
-21	wal_dir_rescan_delay:0.1
+13	sophia_dir:./sophia
+14	wal_mode:write
+15	panic_on_snap_error:true
+16	panic_on_wal_error:false
+17	too_long_threshold:0.01
+18	slab_alloc_minimal:64
+19	wal_dir:.
+20	readahead:16320
+21	snapshot_period:0
+22	wal_dir_rescan_delay:0.1
 ------------------------------------------------------
 Check that too_long_threshold = 0.01
 0.01
diff --git a/test/app/init_script.result b/test/app/init_script.result
index 428c555e57d1ac4846ccc775d649197822b143fd..321c3db21f233e79288fe4232befc003a183ddfa 100644
--- a/test/app/init_script.result
+++ b/test/app/init_script.result
@@ -6,7 +6,7 @@ box.cfg
 1	snapshot_count:6
 2	pid_file:box.pid
 3	slab_alloc_factor:2
-4	slab_alloc_minimal:64
+4	rows_per_wal:500000
 5	background:false
 6	logger:tarantool.log
 7	slab_alloc_arena:0.1
@@ -15,15 +15,16 @@ box.cfg
 10	logger_nonblock:true
 11	snap_dir:.
 12	coredump:false
-13	wal_mode:write
-14	panic_on_snap_error:true
-15	panic_on_wal_error:false
-16	too_long_threshold:0.5
-17	readahead:16320
-18	rows_per_wal:500000
+13	sophia_dir:./sophia
+14	wal_mode:write
+15	panic_on_snap_error:true
+16	panic_on_wal_error:false
+17	too_long_threshold:0.5
+18	slab_alloc_minimal:64
 19	wal_dir:.
-20	snapshot_period:0
-21	wal_dir_rescan_delay:0.1
+20	readahead:16320
+21	snapshot_period:0
+22	wal_dir_rescan_delay:0.1
 --
 -- Test insert from detached fiber
 --
diff --git a/test/app/uri.result b/test/app/uri.result
new file mode 100644
index 0000000000000000000000000000000000000000..d1ab78669126331ee3f54316ce3c162bd26322fa
--- /dev/null
+++ b/test/app/uri.result
@@ -0,0 +1,25 @@
+TAP version 13
+# uri
+1..1
+    # parse
+    1..17
+    ok - scheme
+    ok - login
+    ok - password
+    ok - host
+    ok - service
+    ok - path
+    ok - query
+    ok - fragment
+    ok - ipv4
+    ok - ipv4
+    ok - ipv6
+    ok - ipv6
+    ok - unix
+    ok - unix
+    ok - unix
+    ok - invalid uri
+    ok - invalid uri
+    # parse: end
+ok - parse
+# uri: end
diff --git a/test/app/uri.test.lua b/test/app/uri.test.lua
new file mode 100755
index 0000000000000000000000000000000000000000..96f2f7a5e215b52b4407c0eb872a3084db5ce29b
--- /dev/null
+++ b/test/app/uri.test.lua
@@ -0,0 +1,46 @@
+#!/usr/bin/env tarantool
+
+local tap = require('tap')
+local uri = require('uri')
+
+local function test_parse(test)
+    -- Tests for uri.parse() Lua bindings.
+    -- Parser itself is tested by test/unit/uri unit test.
+    test:plan(17)
+
+    local u
+
+    u = uri.parse("scheme://login:password@host:service"..
+        "/path1/path2/path3?q1=v1&q2=v2#fragment")
+    test:is(u.scheme, "scheme", "scheme")
+    test:is(u.login, "login", "login")
+    test:is(u.password, "password", "password")
+    test:is(u.host, "host", "host")
+    test:is(u.service, "service", "service")
+    test:is(u.path, "/path1/path2/path3", "path")
+    test:is(u.query, "q1=v1&q2=v2", "query")
+    test:is(u.fragment, "fragment", "fragment")
+
+    u = uri.parse('127.0.0.1')
+    test:is(u.host, '127.0.0.1', 'ipv4')
+    test:is(u.ipv4, '127.0.0.1', 'ipv4')
+
+    u = uri.parse('[2a00:1148:b0ba:2016:12bf:48ff:fe78:fd10]')
+    test:is(u.host, '2a00:1148:b0ba:2016:12bf:48ff:fe78:fd10', 'ipv6')
+    test:is(u.ipv6, '2a00:1148:b0ba:2016:12bf:48ff:fe78:fd10', 'ipv6')
+
+    u = uri.parse('/tmp/unix.sock')
+    test:is(u.host, 'unix/', 'unix')
+    test:is(u.service, '/tmp/unix.sock', 'unix')
+    test:is(u.unix, '/tmp/unix.sock', 'unix')
+
+    u = uri.parse("")
+    test:isnil(u, "invalid uri", u)
+    u = uri.parse("://")
+    test:isnil(u, "invalid uri", u)
+end
+
+tap.test("uri", function(test)
+    test:plan(1)
+    test:test("parse", test_parse)
+end)
diff --git a/test/big/lua.result b/test/big/lua.result
index 63e45db0529297a79fd7d07730ad5dba6dca4ba7..2d7a81ec4793d50821db2b144c028ca8c9c4494b 100644
--- a/test/big/lua.result
+++ b/test/big/lua.result
@@ -734,7 +734,7 @@ t:find(2, '2')
 ...
 t:find(89, '2')
 ---
-- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next'''
+- error: '[string "-- tuple.lua (internal file)..."]:86: error: invalid key to ''next'''
 ...
 t:findall(4, '3')
 ---
diff --git a/test/box/access.result b/test/box/access.result
index eaf920e8f612ae728e6f467e72eba74730d87ed7..7ad11d39e9fed0a5ee2de6ac5226c74d2e5d3dc8 100644
--- a/test/box/access.result
+++ b/test/box/access.result
@@ -156,7 +156,14 @@ box.schema.user.drop('Петя_Иванов')
 ---
 ...
 -- gh-300: misleading error message if a function does not exist
-c = (require 'net.box'):new("127.0.0.1", box.cfg.listen)
+LISTEN = require('uri').parse(box.cfg.listen)
+---
+...
+LISTEN ~= nil
+---
+- true
+...
+c = (require 'net.box'):new(LISTEN.host, LISTEN.service)
 ---
 ...
 c:call('nosuchfunction')
diff --git a/test/box/access.test.lua b/test/box/access.test.lua
index cc7ff3a2b4c6202749f1cf5157c2fa783bcf3cb2..8569e0ec32e5093cffe4a40b75c1dc6541e17ccf 100644
--- a/test/box/access.test.lua
+++ b/test/box/access.test.lua
@@ -74,7 +74,9 @@ box.schema.user.create('Петя_Иванов')
 box.schema.user.drop('Петя_Иванов')
 
 -- gh-300: misleading error message if a function does not exist
-c = (require 'net.box'):new("127.0.0.1", box.cfg.listen)
+LISTEN = require('uri').parse(box.cfg.listen)
+LISTEN ~= nil
+c = (require 'net.box'):new(LISTEN.host, LISTEN.service)
 
 c:call('nosuchfunction')
 function nosuchfunction() end
diff --git a/test/box/access_bin.result b/test/box/access_bin.result
index 23aa5b2d6f54fc0b81d192f24bec291cd079f5c2..e9f6c586f8e8277036ac79b9356e7add9c755b2a 100644
--- a/test/box/access_bin.result
+++ b/test/box/access_bin.result
@@ -11,7 +11,14 @@ session = box.session
 net = { box = require('net.box') }
 ---
 ...
-c = net.box:new(0, box.cfg.listen)
+LISTEN = require('uri').parse(box.cfg.listen)
+---
+...
+LISTEN ~= nil
+---
+- true
+...
+c = net.box:new(LISTEN.host, LISTEN.service)
 ---
 ...
 c:call("dostring", "session.su('admin')")
@@ -45,7 +52,7 @@ box.schema.func.create('setuid_func')
 box.schema.user.grant('guest', 'execute', 'function', 'setuid_func')
 ---
 ...
-c = net.box:new(0, box.cfg.listen)
+c = net.box:new(LISTEN.host, LISTEN.service)
 ---
 ...
 c:call("setuid_func")
@@ -95,3 +102,48 @@ setuid_space:drop()
 ---
 ...
 --
+-- gh-530 "assertion failed"
+-- If a user is dropped, its session should not be usable
+-- any more
+--
+test = box.schema.space.create('test')
+---
+...
+test:create_index('primary')
+---
+...
+box.schema.user.create('test', {password='test'})
+---
+...
+box.schema.user.grant('test', 'read,write', 'space','test')
+---
+...
+box.schema.user.grant('test', 'read', 'space', '_space')
+---
+...
+box.schema.user.grant('test', 'read', 'space', '_index')
+---
+...
+net = require('net.box')
+---
+...
+c = net.new(LISTEN.host, LISTEN.service, {user = 'test', password='test'})
+---
+...
+c.space.test:insert{1}
+---
+- [1]
+...
+box.schema.user.drop('test')
+---
+...
+c.space.test:insert{1}
+---
+- error: User '3' is not found
+...
+c:close()
+---
+...
+test:drop()
+---
+...
diff --git a/test/box/access_bin.test.lua b/test/box/access_bin.test.lua
index f9841d7ea50220baa1ddb83ccf11d29607c37b0c..7ff79d2bb53c448ae0f5df8cfdfe8b95481af5b1 100644
--- a/test/box/access_bin.test.lua
+++ b/test/box/access_bin.test.lua
@@ -5,7 +5,9 @@
 box.schema.user.grant('guest','read,write,execute','universe')
 session = box.session
 net = { box = require('net.box') }
-c = net.box:new(0, box.cfg.listen)
+LISTEN = require('uri').parse(box.cfg.listen)
+LISTEN ~= nil
+c = net.box:new(LISTEN.host, LISTEN.service)
 c:call("dostring", "session.su('admin')")
 c:call("dostring", "return session.user()")
 c:close()
@@ -18,7 +20,7 @@ setuid_space:create_index('primary')
 setuid_func = function() return box.space.setuid_space:auto_increment{} end
 box.schema.func.create('setuid_func')
 box.schema.user.grant('guest', 'execute', 'function', 'setuid_func')
-c = net.box:new(0, box.cfg.listen)
+c = net.box:new(LISTEN.host, LISTEN.service)
 c:call("setuid_func")
 session.su('guest')
 setuid_func()
@@ -34,3 +36,21 @@ c:close()
 box.schema.func.drop('setuid_func')
 setuid_space:drop()
 --
+-- gh-530 "assertion failed"
+-- If a user is dropped, its session should not be usable
+-- any more
+--
+test = box.schema.space.create('test')
+test:create_index('primary')
+box.schema.user.create('test', {password='test'})
+box.schema.user.grant('test', 'read,write', 'space','test')
+box.schema.user.grant('test', 'read', 'space', '_space')
+box.schema.user.grant('test', 'read', 'space', '_index')
+net = require('net.box')
+c = net.new(LISTEN.host, LISTEN.service, {user = 'test', password='test'})
+c.space.test:insert{1}
+box.schema.user.drop('test')
+c.space.test:insert{1}
+c:close()
+test:drop()
+
diff --git a/test/box/admin.result b/test/box/admin.result
index bdd175de0cabf49b3009591b3ef4dae5aed94bb6..82da4e86bf979f63ca17ab5c6b2ea3b94ec767f7 100644
--- a/test/box/admin.result
+++ b/test/box/admin.result
@@ -21,7 +21,7 @@ box.cfg
 - snapshot_count: 6
   too_long_threshold: 0.5
   slab_alloc_factor: 2
-  slab_alloc_minimal: 64
+  rows_per_wal: 50
   background: false
   slab_alloc_arena: 0.1
   log_level: 5
@@ -29,14 +29,15 @@ box.cfg
   logger_nonblock: true
   snap_dir: .
   coredump: false
+  sophia_dir: ./sophia
   wal_mode: write
   panic_on_snap_error: true
   panic_on_wal_error: false
   pid_file: tarantool.pid
-  readahead: 16320
+  slab_alloc_minimal: 64
   wal_dir: .
+  readahead: 16320
   snapshot_period: 0
-  rows_per_wal: 50
   wal_dir_rescan_delay: 0.1
 ...
 space:insert{1, 'tuple'}
diff --git a/test/box/alter_limits.result b/test/box/alter_limits.result
index 8a64a0270eb9ea246df9d8a74aa6445d33acf323..10bf75b93b1f2adddb6b2fb14ffec0a384f0bba1 100644
--- a/test/box/alter_limits.result
+++ b/test/box/alter_limits.result
@@ -1189,6 +1189,21 @@ s_nil.index.secondary:count(1)
 ---
 - 0
 ...
+-- gh-503 if_not_exits option in create index
+i1 = s_empty:create_index("test")
+---
+...
+i2 = s_empty:create_index("test")
+---
+- error: Index 'test' already exists
+...
+i3 = s_empty:create_index("test", { if_not_exists = true } )
+---
+...
+i3:select{}
+---
+- []
+...
 -- cleanup
 s_empty:drop()
 ---
diff --git a/test/box/alter_limits.test.lua b/test/box/alter_limits.test.lua
index 1406fec524dd76b1c4e1e354fdb551d12712eb1f..73f87152d589d17a09ee24f953e0a326f21887aa 100644
--- a/test/box/alter_limits.test.lua
+++ b/test/box/alter_limits.test.lua
@@ -419,6 +419,12 @@ r_empty.index.secondary:count(1)
 r_full.index.secondary:count(1)
 s_nil.index.secondary:count(1)
 
+-- gh-503 if_not_exits option in create index
+i1 = s_empty:create_index("test")
+i2 = s_empty:create_index("test")
+i3 = s_empty:create_index("test", { if_not_exists = true } )
+i3:select{}
+
 -- cleanup
 s_empty:drop()
 s_full:drop()
diff --git a/test/box/bad_trigger.result b/test/box/bad_trigger.result
index f44644d9f8c100cd2fbf57b4bb3d56fcb4847eb2..5740f76833df897d234d482b85063b3b325d19f3 100644
--- a/test/box/bad_trigger.result
+++ b/test/box/bad_trigger.result
@@ -1,7 +1,7 @@
- 
+
  #
  # if on_connect() trigger raises an exception, the connection is dropped
- # 
+ #
  
 function f1() nosuchfunction() end
 ---
diff --git a/test/box/bad_trigger.test.py b/test/box/bad_trigger.test.py
index ebbed28bf956dc93ef8450aa8bb093c36b635036..b7337cdf61c6dade851eb05a9af917b45d9275e6 100644
--- a/test/box/bad_trigger.test.py
+++ b/test/box/bad_trigger.test.py
@@ -1,14 +1,15 @@
 from lib.box_connection import BoxConnection
+from lib.tarantool_connection import TarantoolConnection
 from tarantool import NetworkError
 from tarantool.const import IPROTO_GREETING_SIZE, IPROTO_CODE, IPROTO_ERROR, \
     REQUEST_TYPE_ERROR
 import socket
 import msgpack
 
-print """ 
+print """
  #
  # if on_connect() trigger raises an exception, the connection is dropped
- # 
+ #
  """
 
 server.admin("function f1() nosuchfunction() end")
@@ -16,8 +17,9 @@ server.admin("box.session.on_connect(f1)")
 
 unpacker = msgpack.Unpacker(use_list = False)
 
-s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-s.connect(('localhost', server.sql.port))
+conn = TarantoolConnection(server.sql.host, server.sql.port)
+conn.connect()
+s = conn.socket
 
 # Read greeting
 print 'greeting: ', len(s.recv(IPROTO_GREETING_SIZE)) == IPROTO_GREETING_SIZE
diff --git a/test/box/box.net.box.result b/test/box/box.net.box.result
index f3e7a5da7c3f5043ed9d8cb67621005ec39ee638..1c0b7af47d7b1574ee1aa4bb4903967f6061bd97 100644
--- a/test/box/box.net.box.result
+++ b/test/box/box.net.box.result
@@ -7,10 +7,13 @@ fiber = require 'fiber'
 log = require 'log'
 ---
 ...
+msgpack = require 'msgpack'
+---
+...
 box.schema.user.grant('guest', 'read,write,execute', 'universe')
 ---
 ...
-port = box.cfg.listen
+LISTEN = require('uri').parse(box.cfg.listen)
 ---
 ...
 space = box.schema.create_space('net_box_test_space')
@@ -23,7 +26,7 @@ space:create_index('primary', { type = 'tree' })
 log.info("create connection")
 ---
 ...
-cn = remote:new('127.0.0.1', port)
+cn = remote:new(LISTEN.host, LISTEN.service)
 ---
 ...
 cn:_wait_state({'active', 'error'}, 1)
@@ -138,7 +141,7 @@ cn.space.net_box_test_space:insert{234, 1,2,3}
 ...
 cn.space.net_box_test_space.insert{234, 1,2,3}
 ---
-- error: 'builtin/net.box.lua:239: Use space:method(...) instead space.method(...)'
+- error: 'builtin/net.box.lua:229: Use space:method(...) instead space.method(...)'
 ...
 cn.space.net_box_test_space:replace{354, 1,2,3}
 ---
@@ -298,7 +301,7 @@ cn:call('test_foo')
 - error: Connection is not established
 ...
 -- -- 2 reconnect
-cn = remote:new('127.0.0.1', port, { reconnect_after = .1 })
+cn = remote:new(LISTEN.host, LISTEN.service, { reconnect_after = .1 })
 ---
 ...
 cn:_wait_state({'active'}, 1)
@@ -342,8 +345,24 @@ cn:_select(space.id, 0, {}, { iterator = 'ALL' })
 - - [234, 1, 2, 3]
   - [354, 1, 2, 4]
 ...
+-- send broken packet (remote server will close socket)
+cn.s:syswrite(msgpack.encode(1) .. msgpack.encode('abc'))
+---
+- 5
+...
+fiber.sleep(.2)
+---
+...
+cn.state
+---
+- active
+...
+cn:ping()
+---
+- true
+...
 -- -- dot-new-method
-cn1 = remote.new('127.0.0.1', port)
+cn1 = remote.new(LISTEN.host, LISTEN.service)
 ---
 ...
 cn1:_select(space.id, 0, {}, { iterator = 'ALL' })
@@ -420,7 +439,7 @@ cn.proto.b64decode('gJLoc!!!!!!!')
 ---
 - !!binary gJLo
 ...
-cn = remote:new('127.0.0.1', port, { user = 'netbox', password = '123', wait_connected = true })
+cn = remote:new(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123', wait_connected = true })
 ---
 ...
 cn:is_connected()
@@ -441,7 +460,7 @@ box.schema.user.create('netbox', { password  = 'test' })
 box.schema.user.grant('netbox', 'read, write, execute', 'universe');
 ---
 ...
-cn = remote:new('127.0.0.1', port, { user = 'netbox', password = 'test' })
+cn = remote:new(LISTEN.host, LISTEN.service, { user = 'netbox', password = 'test' })
 ---
 ...
 cn.state
@@ -476,11 +495,11 @@ cn:timeout(.01):call('ret_after', 1)
 ---
 - error: Timeout exceeded
 ...
-cn = remote:timeout(0.0000000001):new('127.0.0.1', port, { user = 'netbox', password = '123' })
+cn = remote:timeout(0.0000000001):new(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' })
 ---
 - error: Timeout exceeded
 ...
-cn = remote:timeout(1):new('127.0.0.1', port, { user = 'netbox', password = '123' })
+cn = remote:timeout(1):new(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' })
 ---
 ...
 remote.self:ping()
@@ -499,3 +518,119 @@ remote.self:timeout(123).space.net_box_test_space:select{234}
 space:drop()
 ---
 ...
+-- admin console tests
+function console_test(...) return { ... } end
+---
+...
+function console_test_error(...) error(string.format(...)) end
+---
+...
+function console_unpack_test(...) return ... end
+---
+...
+ADMIN = require('uri').parse(os.getenv('ADMIN'))
+---
+...
+cn = remote:new(LISTEN.host, LISTEN.service)
+---
+...
+cnc = remote:new(ADMIN.host, ADMIN.service)
+---
+...
+cnc.console
+---
+- true
+...
+cn:call('console_test', 1, 2, 3, 'string', nil)
+---
+- - [1, 2, 3, 'string']
+...
+cnc:call('console_test', 1, 2, 3, 'string', nil)
+---
+- - [1, 2, 3, 'string']
+...
+cn:call('console_test_error', 'error %d', 123)
+---
+- error: '[string "function console_test_error(...) error(string..."]:1: error 123'
+...
+cnc:call('console_test_error', 'error %d', 123)
+---
+- error: '[string "function console_test_error(...) error(string..."]:1: error 123'
+...
+cn:call('console_unpack_test', 1)
+---
+- - [1]
+...
+cnc:call('console_unpack_test', 1)
+---
+- - [1]
+...
+cn:call('123')
+---
+- error: Procedure '123' is not defined
+...
+cnc:call('123')
+---
+- error: '[string "123()"]:1: unexpected symbol near ''123'''
+...
+-- #545 user or password is not defined
+remote:new(LISTEN.host, LISTEN.service, { user = 'test' })
+---
+- error: 'net.box: password is not defined'
+...
+remote:new(LISTEN.host, LISTEN.service, { password = 'test' })
+---
+- error: 'net.box: user is not defined'
+...
+-- #544 usage for remote[point]method
+cn:call('console_test')
+---
+- - []
+...
+cn.call('console_test')
+---
+- error: 'usage: remote:call(proc_name, ...)'
+...
+cn.ping()
+---
+- error: 'usage: remote:ping()'
+...
+remote.self:call('console_test')
+---
+- []
+...
+remote.self.call('console_test')
+---
+- error: 'usage: remote:call(proc_name, ...)'
+...
+-- uri as the first argument
+uri = string.format('%s:%s@%s:%s', 'netbox', 'test', LISTEN.host, LISTEN.service)
+---
+...
+cn = remote.new(uri)
+---
+...
+cn:ping()
+---
+- true
+...
+cn:close()
+---
+...
+uri = string.format('%s@%s:%s', 'netbox', LISTEN.host, LISTEN.service)
+---
+...
+remote.new(uri)
+---
+- error: 'net.box: password is not defined'
+...
+cn = remote.new(uri, { password = 'test' })
+---
+...
+cn:ping()
+---
+- true
+...
+cn:close()
+---
+...
diff --git a/test/box/box.net.box.test.lua b/test/box/box.net.box.test.lua
index 647a62c6bc2bdac682ab6e6e872d167628e41f45..e1b7396b052abe0e74b7ac37f9759e8433b61377 100644
--- a/test/box/box.net.box.test.lua
+++ b/test/box/box.net.box.test.lua
@@ -1,15 +1,16 @@
 remote = require 'net.box'
 fiber = require 'fiber'
 log = require 'log'
+msgpack = require 'msgpack'
 
 box.schema.user.grant('guest', 'read,write,execute', 'universe')
-port = box.cfg.listen
+LISTEN = require('uri').parse(box.cfg.listen)
 space = box.schema.create_space('net_box_test_space')
 space:create_index('primary', { type = 'tree' })
 
 -- low level connection
 log.info("create connection")
-cn = remote:new('127.0.0.1', port)
+cn = remote:new(LISTEN.host, LISTEN.service)
 cn:_wait_state({'active', 'error'}, 1)
 log.info("state is %s", cn.state)
 
@@ -105,7 +106,7 @@ cn:ping()
 cn:call('test_foo')
 
 -- -- 2 reconnect
-cn = remote:new('127.0.0.1', port, { reconnect_after = .1 })
+cn = remote:new(LISTEN.host, LISTEN.service, { reconnect_after = .1 })
 cn:_wait_state({'active'}, 1)
 cn.space ~= nil
 
@@ -119,9 +120,16 @@ cn.space.net_box_test_space:select({}, { iterator = 'ALL' })
 cn:_fatal 'Test error'
 cn:_select(space.id, 0, {}, { iterator = 'ALL' })
 
+-- send broken packet (remote server will close socket)
+cn.s:syswrite(msgpack.encode(1) .. msgpack.encode('abc'))
+fiber.sleep(.2)
+
+cn.state
+cn:ping()
+
 -- -- dot-new-method
 
-cn1 = remote.new('127.0.0.1', port)
+cn1 = remote.new(LISTEN.host, LISTEN.service)
 cn1:_select(space.id, 0, {}, { iterator = 'ALL' })
 
 -- -- error while waiting for response
@@ -151,7 +159,7 @@ res[1][2] == string.rep('a', 50000)
 cn.proto.b64decode('gJLocxbO32VmfO8x04xRVxKfgwzmNVM2t6a1ME8XsD0=')
 cn.proto.b64decode('gJLoc!!!!!!!')
 
-cn = remote:new('127.0.0.1', port, { user = 'netbox', password = '123', wait_connected = true })
+cn = remote:new(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123', wait_connected = true })
 cn:is_connected()
 cn.error
 cn.state
@@ -159,7 +167,7 @@ cn.state
 box.schema.user.create('netbox', { password  = 'test' })
 box.schema.user.grant('netbox', 'read, write, execute', 'universe');
 
-cn = remote:new('127.0.0.1', port, { user = 'netbox', password = 'test' })
+cn = remote:new(LISTEN.host, LISTEN.service, { user = 'netbox', password = 'test' })
 cn.state
 cn.error
 cn:ping()
@@ -172,8 +180,8 @@ cn:call('ret_after', .01)
 cn:timeout(1):call('ret_after', .01)
 cn:timeout(.01):call('ret_after', 1)
 
-cn = remote:timeout(0.0000000001):new('127.0.0.1', port, { user = 'netbox', password = '123' })
-cn = remote:timeout(1):new('127.0.0.1', port, { user = 'netbox', password = '123' })
+cn = remote:timeout(0.0000000001):new(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' })
+cn = remote:timeout(1):new(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' })
 
 
 
@@ -187,3 +195,60 @@ remote.self:timeout(123).space.net_box_test_space:select{234}
 -- cleanup database after tests
 space:drop()
 
+
+-- admin console tests
+function console_test(...) return { ... } end
+function console_test_error(...) error(string.format(...)) end
+function console_unpack_test(...) return ... end
+
+
+ADMIN = require('uri').parse(os.getenv('ADMIN'))
+
+cn = remote:new(LISTEN.host, LISTEN.service)
+cnc = remote:new(ADMIN.host, ADMIN.service)
+cnc.console
+
+cn:call('console_test', 1, 2, 3, 'string', nil)
+cnc:call('console_test', 1, 2, 3, 'string', nil)
+
+cn:call('console_test_error', 'error %d', 123)
+cnc:call('console_test_error', 'error %d', 123)
+
+
+cn:call('console_unpack_test', 1)
+cnc:call('console_unpack_test', 1)
+
+
+
+
+cn:call('123')
+cnc:call('123')
+
+
+-- #545 user or password is not defined
+remote:new(LISTEN.host, LISTEN.service, { user = 'test' })
+remote:new(LISTEN.host, LISTEN.service, { password = 'test' })
+
+-- #544 usage for remote[point]method
+cn:call('console_test')
+cn.call('console_test')
+
+cn.ping()
+
+remote.self:call('console_test')
+remote.self.call('console_test')
+
+
+-- uri as the first argument
+uri = string.format('%s:%s@%s:%s', 'netbox', 'test', LISTEN.host, LISTEN.service)
+
+cn = remote.new(uri)
+cn:ping()
+cn:close()
+
+uri = string.format('%s@%s:%s', 'netbox', LISTEN.host, LISTEN.service)
+remote.new(uri)
+cn = remote.new(uri, { password = 'test' })
+cn:ping()
+cn:close()
+
diff --git a/test/box/bsdsocket.result b/test/box/bsdsocket.result
index ccc0973dea38030d9b48b65242cb2c55859ef2ea..b2122b38bd5b489c9c19d317676ca476041fd71d 100644
--- a/test/box/bsdsocket.result
+++ b/test/box/bsdsocket.result
@@ -22,6 +22,9 @@ log = require 'log'
 errno = require 'errno'
 ---
 ...
+fio = require 'fio'
+---
+...
 type(socket)
 ---
 - table
@@ -59,18 +62,26 @@ for k in pairs(getmetatable(s).__index) do
 end;
 ---
 ...
---# setopt delimiter ''
-port = string.gsub(box.cfg.listen, '^.*:', '')
+s:close()
 ---
+- true
 ...
-s:nonblock(false)
+--# setopt delimiter ''
+s:close()
+
 ---
 - false
 ...
-s:sysconnect('127.0.0.1', port)
+LISTEN = require('uri').parse(box.cfg.listen)
+---
+...
+LISTEN ~= nil
 ---
 - true
 ...
+s = socket.tcp_connect(LISTEN.host, LISTEN.service)
+---
+...
 s:nonblock(true)
 ---
 - true
@@ -268,7 +279,7 @@ s:getsockopt('SOL_SOCKET', 'SO_DEBUG')
 ...
 s:setsockopt('SOL_SOCKET', 'SO_ACCEPTCONN', 1)
 ---
-- error: 'builtin/socket.lua:341: Socket option SO_ACCEPTCONN is read only'
+- error: 'builtin/socket.lua:343: Socket option SO_ACCEPTCONN is read only'
 ...
 s:getsockopt('SOL_SOCKET', 'SO_RCVBUF') > 32
 ---
@@ -349,8 +360,19 @@ sc:write('Hello, world')
 ---
 - true
 ...
-sa = s:accept()
+sa, addr = s:accept()
+---
+...
+addr2 = sa:name()
+---
+...
+addr2.host == addr.host
+---
+- true
+...
+addr2.family == addr.family
 ---
+- true
 ...
 sa:nonblock(1)
 ---
@@ -1209,9 +1231,13 @@ os.remove(path)
 ---
 - true
 ...
-server = socket.tcp_server('unix/', path, function(s) s:write('Hello, world') end)
+server, addr = socket.tcp_server('unix/', path, function(s) s:write('Hello, world') end)
 ---
 ...
+type(addr)
+---
+- table
+...
 server ~= nil
 ---
 - true
@@ -1230,11 +1256,83 @@ client:read(123)
 ---
 - Hello, world
 ...
-server:stop()
+server:close()
 ---
 - true
 ...
-os.remove(path)
+-- unix socket automatically removed
+fio.stat(path) == nil
+---
+- true
+...
+--# setopt delimiter ';'
+server, addr = socket.tcp_server('localhost', 0, { handler = function(s)
+    s:read(2)
+    s:write('Hello, world')
+end, name = 'testserv'});
+---
+...
+--# setopt delimiter ''
+type(addr)
+---
+- table
+...
+server ~= nil
+---
+- true
+...
+addr2 = server:name()
+---
+...
+addr.host == addr2.host
+---
+- true
+...
+addr.family == addr2.family
+---
+- true
+...
+fiber.sleep(.5)
+---
+...
+client = socket.tcp_connect(addr2.host, addr2.port)
+---
+...
+client ~= nil
+---
+- true
+...
+-- Check that listen and client fibers have appropriate names
+cnt = 0
+---
+...
+--# setopt delimiter ';'
+for i=100,200 do
+    local f = fiber.find(i)
+    if f and f:name():match('^testserv/') then
+        cnt = cnt + 1
+    end
+end;
+---
+...
+--# setopt delimiter ''
+cnt
+---
+- 2
+...
+client:write('hi')
+---
+- true
+...
+client:read(123)
+---
+- Hello, world
+...
+client:close()
+---
+- true
+...
+server:close()
 ---
 - true
 ...
@@ -1275,11 +1373,7 @@ client:read{ line = { "\n\n", "\r\n\r\n" } }
 ---
 - "Hello\r\n\r\n"
 ...
-server:stop()
----
-- true
-...
-os.remove(path)
+server:close()
 ---
 - true
 ...
@@ -1339,3 +1433,50 @@ yaml.decode(yaml.encode(s)).fd == s:fd()
 s = nil
 ---
 ...
+-- start AF_UNIX server with dead socket exists
+path = '/tmp/tarantool-test-socket'
+---
+...
+s = socket('AF_UNIX', 'SOCK_STREAM', 0)
+---
+...
+s:bind('unix/', path)
+---
+- true
+...
+s:close()
+---
+- true
+...
+s = socket('AF_UNIX', 'SOCK_STREAM', 0)
+---
+...
+{ s:bind('unix/', path), errno.strerror() }
+---
+- - false
+  - Address already in use
+...
+s:close()
+---
+- true
+...
+s = socket.tcp_server('unix/', path, function() end)
+---
+...
+s ~= nil
+---
+- true
+...
+s:close()
+---
+- true
+...
+fio.stat(path) == nil
+---
+- true
+...
+{ socket.tcp_connect('abrakadabra#123') == nil, errno.strerror() }
+---
+- - true
+  - Invalid argument
+...
diff --git a/test/box/bsdsocket.test.lua b/test/box/bsdsocket.test.lua
index 7ead95599262bb1498d51354ba5cd88928b7ed1b..8fc124573ef7a22ad677a899eef160ccb1f812e0 100644
--- a/test/box/bsdsocket.test.lua
+++ b/test/box/bsdsocket.test.lua
@@ -6,6 +6,7 @@ fiber = require 'fiber'
 msgpack = require 'msgpack'
 log = require 'log'
 errno = require 'errno'
+fio = require 'fio'
 type(socket)
 
 socket('PF_INET', 'SOCK_STREAM', 'tcp121222');
@@ -23,12 +24,12 @@ for k in pairs(getmetatable(s).__index) do
         error("Arguments is not checked for "..k)
     end
 end;
+s:close()
 --# setopt delimiter ''
 
-port = string.gsub(box.cfg.listen, '^.*:', '')
-
-s:nonblock(false)
-s:sysconnect('127.0.0.1', port)
+LISTEN = require('uri').parse(box.cfg.listen)
+LISTEN ~= nil
+s = socket.tcp_connect(LISTEN.host, LISTEN.service)
 s:nonblock(true)
 s:nonblock()
 s:nonblock(false)
@@ -114,7 +115,10 @@ sc:writable(10)
 sc:write('Hello, world')
 
 
-sa = s:accept()
+sa, addr = s:accept()
+addr2 = sa:name()
+addr2.host == addr.host
+addr2.family == addr.family
 sa:nonblock(1)
 sa:read(8)
 sa:read(3)
@@ -404,37 +408,59 @@ s:close()
 os.remove(path)
 
 
-server = socket.tcp_server('unix/', path, function(s) s:write('Hello, world') end)
+server, addr = socket.tcp_server('unix/', path, function(s) s:write('Hello, world') end)
+type(addr)
 server ~= nil
 fiber.sleep(.5)
 client = socket.tcp_connect('unix/', path)
 client ~= nil
 client:read(123)
-server:stop()
-os.remove(path)
+server:close()
+-- unix socket automatically removed
+fio.stat(path) == nil
 
+--# setopt delimiter ';'
+server, addr = socket.tcp_server('localhost', 0, { handler = function(s)
+    s:read(2)
+    s:write('Hello, world')
+end, name = 'testserv'});
+--# setopt delimiter ''
+type(addr)
+server ~= nil
+addr2 = server:name()
+addr.host == addr2.host
+addr.family == addr2.family
+fiber.sleep(.5)
+client = socket.tcp_connect(addr2.host, addr2.port)
+client ~= nil
+-- Check that listen and client fibers have appropriate names
+cnt = 0
+--# setopt delimiter ';'
+for i=100,200 do
+    local f = fiber.find(i)
+    if f and f:name():match('^testserv/') then
+        cnt = cnt + 1
+    end
+end;
+--# setopt delimiter ''
+cnt
+client:write('hi')
+client:read(123)
+client:close()
+server:close()
 
 longstring = string.rep("abc", 65535)
 server = socket.tcp_server('unix/', path, function(s) s:write(longstring) end)
-
 client = socket.tcp_connect('unix/', path)
 client:read(#longstring) == longstring
-
 client = socket.tcp_connect('unix/', path)
 client:read(#longstring + 1) == longstring
-
 client = socket.tcp_connect('unix/', path)
 client:read(#longstring - 1) == string.sub(longstring, 1, #longstring - 1)
-
-
 longstring = "Hello\r\n\r\nworld\n\n"
-
 client = socket.tcp_connect('unix/', path)
 client:read{ line = { "\n\n", "\r\n\r\n" } }
-
-
-server:stop()
-os.remove(path)
+server:close()
 
 
 -- Test that socket is closed on GC
@@ -456,3 +482,20 @@ s.waiters
 json.decode(json.encode(s)).fd == s:fd()
 yaml.decode(yaml.encode(s)).fd == s:fd()
 s = nil
+
+-- start AF_UNIX server with dead socket exists
+path = '/tmp/tarantool-test-socket'
+s = socket('AF_UNIX', 'SOCK_STREAM', 0)
+s:bind('unix/', path)
+s:close()
+
+s = socket('AF_UNIX', 'SOCK_STREAM', 0)
+{ s:bind('unix/', path), errno.strerror() }
+s:close()
+
+s = socket.tcp_server('unix/', path, function() end)
+s ~= nil
+s:close()
+fio.stat(path) == nil
+
+{ socket.tcp_connect('abrakadabra#123') == nil, errno.strerror() }
diff --git a/test/box/cfg.result b/test/box/cfg.result
index f08d7e79efa89372d846a4ea3447610016101b5d..6255ecf21bc9c468f64457ac52de01800a8b8e89 100644
--- a/test/box/cfg.result
+++ b/test/box/cfg.result
@@ -2,7 +2,7 @@
 --# push filter 'admin: .*' to 'admin: <uri>'
 box.cfg.nosuchoption = 1
 ---
-- error: '[string "-- load_cfg.lua - internal file..."]:202: Attempt to modify a read-only
+- error: '[string "-- load_cfg.lua - internal file..."]:195: Attempt to modify a read-only
     table'
 ...
 t = {} for k,v in pairs(box.cfg) do if type(v) ~= 'table' and type(v) ~= 'function' then table.insert(t, k..': '..tostring(v)) end end
@@ -13,7 +13,7 @@ t
 - - 'snapshot_count: 6'
   - 'too_long_threshold: 0.5'
   - 'slab_alloc_factor: 2'
-  - 'slab_alloc_minimal: 64'
+  - 'rows_per_wal: 50'
   - 'background: false'
   - 'slab_alloc_arena: 0.1'
   - 'log_level: 5'
@@ -21,14 +21,15 @@ t
   - 'logger_nonblock: true'
   - 'snap_dir: .'
   - 'coredump: false'
+  - 'sophia_dir: ./sophia'
   - 'wal_mode: write'
   - 'panic_on_snap_error: true'
   - 'panic_on_wal_error: false'
   - 'pid_file: tarantool.pid'
-  - 'readahead: 16320'
+  - 'slab_alloc_minimal: 64'
   - 'wal_dir: .'
+  - 'readahead: 16320'
   - 'snapshot_period: 0'
-  - 'rows_per_wal: 50'
   - 'wal_dir_rescan_delay: 0.1'
 ...
 -- must be read-only
@@ -43,7 +44,7 @@ t
 - - 'snapshot_count: 6'
   - 'too_long_threshold: 0.5'
   - 'slab_alloc_factor: 2'
-  - 'slab_alloc_minimal: 64'
+  - 'rows_per_wal: 50'
   - 'background: false'
   - 'slab_alloc_arena: 0.1'
   - 'log_level: 5'
@@ -51,14 +52,37 @@ t
   - 'logger_nonblock: true'
   - 'snap_dir: .'
   - 'coredump: false'
+  - 'sophia_dir: ./sophia'
   - 'wal_mode: write'
   - 'panic_on_snap_error: true'
   - 'panic_on_wal_error: false'
   - 'pid_file: tarantool.pid'
-  - 'readahead: 16320'
+  - 'slab_alloc_minimal: 64'
   - 'wal_dir: .'
+  - 'readahead: 16320'
   - 'snapshot_period: 0'
-  - 'rows_per_wal: 50'
   - 'wal_dir_rescan_delay: 0.1'
 ...
+-- check that cfg with unexpected parameter fails.
+box.cfg{sherlock = 'holmes'}
+---
+- error: '[string "-- load_cfg.lua - internal file..."]:121: Error: cfg parameter
+    ''sherlock'' is unexpected'
+...
+-- check that cfg with unexpected type of parameter failes
+box.cfg{listen = {}}
+---
+- error: '[string "-- load_cfg.lua - internal file..."]:136: Error: cfg parameter
+    ''listen'' should be one of types: string, number'
+...
+box.cfg{wal_dir = 0}
+---
+- error: '[string "-- load_cfg.lua - internal file..."]:130: Error: cfg parameter
+    ''wal_dir'' should be of type string'
+...
+box.cfg{coredump = 'true'}
+---
+- error: '[string "-- load_cfg.lua - internal file..."]:130: Error: cfg parameter
+    ''coredump'' should be of type boolean'
+...
 --# clear filter
diff --git a/test/box/cfg.test.lua b/test/box/cfg.test.lua
index ee99deae794a6f606d6711abe6d65f4d19adb0d6..9d4e87075df1a961723c3e1a9badf8d65257f974 100644
--- a/test/box/cfg.test.lua
+++ b/test/box/cfg.test.lua
@@ -7,4 +7,13 @@ t
 box.cfg()
 t = {} for k,v in pairs(box.cfg) do if type(v) ~= 'table' and type(v) ~= 'function' then table.insert(t, k..': '..tostring(v)) end end
 t
+
+-- check that cfg with unexpected parameter fails.
+box.cfg{sherlock = 'holmes'}
+
+-- check that cfg with unexpected type of parameter failes
+box.cfg{listen = {}}
+box.cfg{wal_dir = 0}
+box.cfg{coredump = 'true'}
+
 --# clear filter
diff --git a/test/box/digest.result b/test/box/digest.result
index 4ee42a1f2098208c350c09789214312c3d4a3e99..0113ed92b6cd092d4543bde83331d1a09f28dce3 100644
--- a/test/box/digest.result
+++ b/test/box/digest.result
@@ -149,6 +149,64 @@ digest.crc32_update(digest.crc32('abc'), 'cde')
 ---
 - 3628146660
 ...
+digest.base64_encode('12345')
+---
+- MTIzNDU=
+...
+digest.base64_decode('MTIzNDU=')
+---
+- '12345'
+...
+digest.base64_encode('asdfl asdf adfa zxc vzxcvz llll')
+---
+- YXNkZmwgYXNkZiBhZGZhIHp4YyB2enhjdnogbGxsbA==
+...
+digest.base64_decode('YXNkZmwgYXNkZiBhZGZhIHp4YyB2enhjdnogbGxsbA==')
+---
+- asdfl asdf adfa zxc vzxcvz llll
+...
+digest.base64_encode('11 00 11 00 abcdef ABCDEF 00 11 00 11')
+---
+- MTEgMDAgMTEgMDAgYWJjZGVmIEFCQ0RFRiAwMCAxMSAwMCAxMQ==
+...
+digest.base64_decode('MTEgMDAgMTEgMDAgYWJjZGVmIEFCQ0RFRiAwMCAxMSAwMCAxMQ==')
+---
+- 11 00 11 00 abcdef ABCDEF 00 11 00 11
+...
+s = string.rep('a', 54 * 2) -- two lines in base64
+---
+...
+b = digest.base64_encode(s)
+---
+...
+b
+---
+- 'YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh
+
+  YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh
+
+'
+...
+digest.base64_decode(b) == s
+---
+- true
+...
+digest.base64_decode(nil)
+---
+- error: 'builtin/digest.lua:88: Usage: digest.base64_decode(string)'
+...
+digest.base64_encode(nil)
+---
+- error: 'builtin/digest.lua:77: Usage: digest.base64_encode(string)'
+...
+digest.base64_encode(123)
+---
+- error: 'builtin/digest.lua:77: Usage: digest.base64_encode(string)'
+...
+digest.base64_decode(123)
+---
+- error: 'builtin/digest.lua:88: Usage: digest.base64_decode(string)'
+...
 digest = nil
 ---
 ...
diff --git a/test/box/digest.test.lua b/test/box/digest.test.lua
index 96f3b5c6d2aa1fb014a79a2e900d50bb1cbb05f4..6475bf6b650136b9cd62cc81a0d1b134d9989b7d 100644
--- a/test/box/digest.test.lua
+++ b/test/box/digest.test.lua
@@ -43,4 +43,20 @@ digest.crc32_update(4294967295, 'abc')
 
 digest.crc32('abccde')
 digest.crc32_update(digest.crc32('abc'), 'cde')
+
+digest.base64_encode('12345')
+digest.base64_decode('MTIzNDU=')
+digest.base64_encode('asdfl asdf adfa zxc vzxcvz llll')
+digest.base64_decode('YXNkZmwgYXNkZiBhZGZhIHp4YyB2enhjdnogbGxsbA==')
+digest.base64_encode('11 00 11 00 abcdef ABCDEF 00 11 00 11')
+digest.base64_decode('MTEgMDAgMTEgMDAgYWJjZGVmIEFCQ0RFRiAwMCAxMSAwMCAxMQ==')
+s = string.rep('a', 54 * 2) -- two lines in base64
+b = digest.base64_encode(s)
+b
+digest.base64_decode(b) == s
+digest.base64_decode(nil)
+digest.base64_encode(nil)
+digest.base64_encode(123)
+digest.base64_decode(123)
+
 digest = nil
diff --git a/test/box/fiber.result b/test/box/fiber.result
index 58656e42e8ad628672c8a494ceafa4e72ecfe505..13a1aa6044ed9b8a51b2f6744deef3477548b8f8 100644
--- a/test/box/fiber.result
+++ b/test/box/fiber.result
@@ -726,6 +726,44 @@ done
 ---
 - true
 ...
+-- # gh-536: fiber.info() doesn't list fibers with default names
+--
+function loop() while true do fiber.sleep(10) end end
+---
+...
+f1 = fiber.create(loop)
+---
+...
+f2 = fiber.create(loop)
+---
+...
+f3 = fiber.create(loop)
+---
+...
+info = fiber.info()
+---
+...
+info[f1:id()] ~= nil
+---
+- true
+...
+info[f2:id()] ~= nil
+---
+- true
+...
+info[f3:id()] ~= nil
+---
+- true
+...
+f1:cancel()
+---
+...
+f2:cancel()
+---
+...
+f3:cancel()
+---
+...
 fiber = nil
 ---
 ...
diff --git a/test/box/fiber.test.lua b/test/box/fiber.test.lua
index 8c80a81c45e15cd3e8f1b1aa5c21a671947e5974..258561e06c04dc5b89bbe9f055cd63c2dcb2b8c4 100644
--- a/test/box/fiber.test.lua
+++ b/test/box/fiber.test.lua
@@ -296,4 +296,20 @@ end;
 f = fiber.create(test)
 done
 
+-- # gh-536: fiber.info() doesn't list fibers with default names
+--
+function loop() while true do fiber.sleep(10) end end
+f1 = fiber.create(loop)
+f2 = fiber.create(loop)
+f3 = fiber.create(loop)
+
+info = fiber.info()
+info[f1:id()] ~= nil
+info[f2:id()] ~= nil
+info[f3:id()] ~= nil
+
+f1:cancel()
+f2:cancel()
+f3:cancel()
+
 fiber = nil
diff --git a/test/box/fio.result b/test/box/fio.result
index 1485c63ad1689a6263814b9a4919af3b1314692a..301874a6dfd5bcae89e7bac05406b7f1f0306d51 100644
--- a/test/box/fio.result
+++ b/test/box/fio.result
@@ -286,3 +286,24 @@ fio.unlink(nil)
 ---
 - false
 ...
+-- dirname
+fio.dirname('abc')
+---
+- .
+...
+fio.dirname('/abc')
+---
+- /
+...
+fio.dirname('/abc/cde')
+---
+- /abc
+...
+fio.dirname('/abc/cde/')
+---
+- /abc
+...
+fio.dirname('/')
+---
+- /
+...
diff --git a/test/box/fio.test.lua b/test/box/fio.test.lua
index c97c15965a5d0f12d9d25e1c279a69bb2e5c0d54..2a18ee6df2479a0d0f98c6b6cf1c2907b76460ab 100644
--- a/test/box/fio.test.lua
+++ b/test/box/fio.test.lua
@@ -97,3 +97,11 @@ fio.rmdir(tmpdir)
 
 fio.unlink()
 fio.unlink(nil)
+
+-- dirname
+
+fio.dirname('abc')
+fio.dirname('/abc')
+fio.dirname('/abc/cde')
+fio.dirname('/abc/cde/')
+fio.dirname('/')
diff --git a/test/box/iproto.test.py b/test/box/iproto.test.py
index cde404f3256f3220b3ef20a5410b2ed7a638c0bb..c4c60e52bc91ea2fb1a122b306305856c22e7b1b 100644
--- a/test/box/iproto.test.py
+++ b/test/box/iproto.test.py
@@ -7,6 +7,7 @@ from tarantool.const import *
 from tarantool import Connection
 from tarantool.request import Request, RequestInsert, RequestSelect
 from tarantool.response import Response
+from lib.tarantool_connection import TarantoolConnection
 
 admin("box.schema.user.grant('guest', 'read,write,execute', 'universe')")
 
@@ -17,8 +18,9 @@ print """
 """
 
 # opeing new connection to tarantool/box
-s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-s.connect(('localhost', server.sql.port))
+conn = TarantoolConnection(server.sql.host, server.sql.port)
+conn.connect()
+s = conn.socket
 
 print """
 # Test bug #899343 (server assertion failure on incorrect packet)
diff --git a/test/box/misc.result b/test/box/misc.result
index 651ae9f1b75a0d42dc9afe54cf5d2b4b269b7687..f779861515522d17820dbd8a4bfdf29d885ac32b 100644
--- a/test/box/misc.result
+++ b/test/box/misc.result
@@ -24,6 +24,7 @@ t
   - info
   - internal
   - rollback
+  - runtime
   - schema
   - session
   - slab
@@ -154,6 +155,14 @@ t;
   - arena_size
   - slabs
 ...
+box.runtime.info().used > 0;
+---
+- true
+...
+box.runtime.info().maxalloc > 0;
+---
+- true
+...
 --
 -- gh-502: box.slab.info() excessively sparse array
 --
@@ -173,11 +182,11 @@ end;
 t;
 ---
 - - 'box.error.EXACT_MATCH : 19'
-  - 'box.error.SECONDARY : 7'
+  - 'box.error.NO_SUCH_TRIGGER : 34'
   - 'box.error.CLUSTER_ID_IS_RO : 65'
   - 'box.error.INDEX_TYPE : 13'
   - 'box.error.CLUSTER_ID_MISMATCH : 63'
-  - 'box.error.FIELD_TYPE : 23'
+  - 'box.error.MEMORY_ISSUE : 2'
   - 'box.error.KEY_PART_TYPE : 18'
   - 'box.error.CREATE_FUNCTION : 50'
   - 'box.error.SOPHIA : 60'
@@ -200,11 +209,12 @@ t;
   - 'box.error.CREATE_USER : 43'
   - 'box.error.CREATE_SPACE : 9'
   - 'box.error.UNKNOWN_SCHEMA_OBJECT : 49'
+  - 'box.error.PROC_LUA : 32'
   - 'box.error.CREATE_ROLE : 84'
   - 'box.error.ROLE_EXISTS : 83'
   - 'box.error.NO_SUCH_ROLE : 82'
   - 'box.error.NO_ACTIVE_TRANSACTION : 80'
-  - 'box.error.SPLICE : 25'
+  - 'box.error.TUPLE_FOUND : 3'
   - 'box.error.FIELD_TYPE_MISMATCH : 24'
   - 'box.error.UNSUPPORTED : 5'
   - 'box.error.INVALID_MSGPACK : 20'
@@ -212,7 +222,7 @@ t;
   - 'box.error.ALTER_SPACE : 12'
   - 'box.error.ACTIVE_TRANSACTION : 79'
   - 'box.error.NO_CONNECTION : 77'
-  - 'box.error.DROP_SPACE : 11'
+  - 'box.error.FIELD_TYPE : 23'
   - 'box.error.INVALID_XLOG_NAME : 75'
   - 'box.error.INVALID_XLOG : 74'
   - 'box.error.REPLICA_MAX : 73'
@@ -226,34 +236,34 @@ t;
   - 'box.error.INVALID_ORDER : 68'
   - 'box.error.CFG : 59'
   - 'box.error.SPACE_FIELD_COUNT : 38'
-  - 'box.error.SPACE_ACCESS_DENIED : 55'
+  - 'box.error.UNKNOWN : 0'
   - 'box.error.NO_SUCH_FIELD : 37'
   - 'box.error.LOCAL_SERVER_IS_NOT_ACTIVE : 61'
   - 'box.error.RELOAD_CFG : 58'
   - 'box.error.PROC_RET : 21'
   - 'box.error.INJECTION : 8'
-  - 'box.error.PROC_LUA : 32'
+  - 'box.error.FUNCTION_MAX : 54'
   - 'box.error.ILLEGAL_PARAMS : 1'
-  - 'box.error.TUPLE_NOT_ARRAY : 22'
   - 'box.error.TUPLE_FORMAT_LIMIT : 16'
+  - 'box.error.USER_MAX : 56'
   - 'box.error.INVALID_UUID : 64'
-  - 'box.error.UNKNOWN : 0'
+  - 'box.error.SPLICE : 25'
   - 'box.error.TIMEOUT : 78'
-  - 'box.error.TUPLE_FOUND : 3'
-  - 'box.error.MEMORY_ISSUE : 2'
-  - 'box.error.NO_SUCH_TRIGGER : 34'
+  - 'box.error.MORE_THAN_ONE_TUPLE : 41'
+  - 'box.error.NO_SUCH_SPACE : 36'
+  - 'box.error.INDEX_EXISTS : 85'
   - 'box.error.UPDATE_FIELD : 29'
   - 'box.error.ARG_TYPE : 26'
-  - 'box.error.NO_SUCH_SPACE : 36'
   - 'box.error.INDEX_FIELD_COUNT : 39'
-  - 'box.error.MORE_THAN_ONE_TUPLE : 41'
+  - 'box.error.READONLY : 7'
   - 'box.error.DROP_PRIMARY_KEY : 17'
+  - 'box.error.DROP_SPACE : 11'
   - 'box.error.UNKNOWN_REQUEST_TYPE : 48'
   - 'box.error.INVALID_XLOG_ORDER : 76'
-  - 'box.error.FUNCTION_MAX : 54'
+  - 'box.error.SPACE_ACCESS_DENIED : 55'
   - 'box.error.NO_SUCH_USER : 45'
-  - 'box.error.USER_MAX : 56'
   - 'box.error.UNKNOWN_UPDATE_OP : 28'
+  - 'box.error.TUPLE_NOT_ARRAY : 22'
   - 'box.error.NO_SUCH_PROC : 33'
   - 'box.error.FUNCTION_ACCESS_DENIED : 53'
 ...
diff --git a/test/box/misc.test.lua b/test/box/misc.test.lua
index dd7c2ddb984a11ca9c3b678882f026014d7aef23..10edd169c8516ee26cee0b29bcb0373a693787ef 100644
--- a/test/box/misc.test.lua
+++ b/test/box/misc.test.lua
@@ -61,6 +61,8 @@ for k, v in pairs(box.slab.info()) do
     table.insert(t, k)
 end;
 t;
+box.runtime.info().used > 0;
+box.runtime.info().maxalloc > 0;
 
 --
 -- gh-502: box.slab.info() excessively sparse array
diff --git a/test/box/protocol.result b/test/box/protocol.result
index fbbe9a349d1bfb0d36868ed35a4e8568f23f3d3a..f1e99fccb70c88b6891e9fa4be66a9540d47fd2b 100644
--- a/test/box/protocol.result
+++ b/test/box/protocol.result
@@ -13,10 +13,14 @@ space:create_index('primary', { type = 'tree'})
 for i=1,5 do space:insert{i} end
 ---
 ...
-port = string.gsub(box.cfg.listen, '^.*:', '')
+LISTEN = require('uri').parse(box.cfg.listen)
 ---
 ...
-conn = (require 'net.box'):new('127.0.0.1', tonumber(port))
+LISTEN ~= nil
+---
+- true
+...
+conn = (require 'net.box'):new(LISTEN.host, LISTEN.service)
 ---
 ...
 conn.space[space.id]:select(3, { iterator = 'GE' })
diff --git a/test/box/protocol.test.lua b/test/box/protocol.test.lua
index 975fb20ffa50199fbf1bf2e2e16568e5ff6e01ad..fa75d8d8cd854e8020ccfb2ae59dc567fcd1f6f1 100644
--- a/test/box/protocol.test.lua
+++ b/test/box/protocol.test.lua
@@ -8,8 +8,9 @@ space = box.schema.create_space('tweedledum')
 space:create_index('primary', { type = 'tree'})
 for i=1,5 do space:insert{i} end
 
-port = string.gsub(box.cfg.listen, '^.*:', '')
-conn = (require 'net.box'):new('127.0.0.1', tonumber(port))
+LISTEN = require('uri').parse(box.cfg.listen)
+LISTEN ~= nil
+conn = (require 'net.box'):new(LISTEN.host, LISTEN.service)
 conn.space[space.id]:select(3, { iterator = 'GE' })
 conn.space[space.id]:select(3, { iterator = 'LE' })
 conn.space[space.id]:select(3, { iterator = 'GT' })
diff --git a/test/box/session.result b/test/box/session.result
index b0610ea741b85f00382872938bfcf11f28861874..96469ca9389aae39fe99580b2ec388a3bc57bc05 100644
--- a/test/box/session.result
+++ b/test/box/session.result
@@ -128,7 +128,10 @@ session.on_disconnect(dec)
 active_connections = 0
 ---
 ...
-c = net.box:new(0, box.cfg.listen)
+LISTEN = require('uri').parse(box.cfg.listen)
+---
+...
+c = net.box:new(LISTEN.host, LISTEN.service)
 ---
 ...
 while active_connections < 1 do fiber.sleep(0.001) end
@@ -138,7 +141,7 @@ active_connections
 ---
 - 1
 ...
-c1 = net.box:new(0, box.cfg.listen)
+c1 = net.box:new(LISTEN.host, LISTEN.service)
 ---
 ...
 while active_connections < 2 do fiber.sleep(0.001) end
@@ -183,7 +186,7 @@ session.on_disconnect(audit_disconnect)
 box.schema.user.grant('guest', 'read,write,execute', 'universe')
 ---
 ...
-a = net.box:new('127.0.0.1', box.cfg.listen)
+a = net.box:new(LISTEN.host, LISTEN.service)
 ---
 ...
 a:call('dostring', 'return space:get{session.id()}[1] == session.id()')[1][1]
diff --git a/test/box/session.test.lua b/test/box/session.test.lua
index 9be90f703391a53abcb661a3562237698bfbd292..95152624feb1015433c4c135a6500a97510228ed 100644
--- a/test/box/session.test.lua
+++ b/test/box/session.test.lua
@@ -51,10 +51,11 @@ net = { box = require('net.box') }
 session.on_connect(inc)
 session.on_disconnect(dec)
 active_connections = 0
-c = net.box:new(0, box.cfg.listen)
+LISTEN = require('uri').parse(box.cfg.listen)
+c = net.box:new(LISTEN.host, LISTEN.service)
 while active_connections < 1 do fiber.sleep(0.001) end
 active_connections
-c1 = net.box:new(0, box.cfg.listen)
+c1 = net.box:new(LISTEN.host, LISTEN.service)
 while active_connections < 2 do fiber.sleep(0.001) end
 active_connections
 c:close()
@@ -72,7 +73,7 @@ session.on_connect(audit_connect)
 session.on_disconnect(audit_disconnect)
 
 box.schema.user.grant('guest', 'read,write,execute', 'universe')
-a = net.box:new('127.0.0.1', box.cfg.listen)
+a = net.box:new(LISTEN.host, LISTEN.service)
 a:call('dostring', 'return space:get{session.id()}[1] == session.id()')[1][1]
 a:close()
 
diff --git a/test/box/snap_daemon.result b/test/box/snapshot_daemon.result
similarity index 93%
rename from test/box/snap_daemon.result
rename to test/box/snapshot_daemon.result
index e411a87accc3ec5ed842a16873eb06664735ddf5..57e0fd3d52964518cf632195051ce6f36021c963 100644
--- a/test/box/snap_daemon.result
+++ b/test/box/snapshot_daemon.result
@@ -43,7 +43,7 @@ end
 
 ---
 ...
-space = box.schema.create_space('snap_daemon')
+space = box.schema.create_space('snapshot_daemon')
 ---
 ...
 space:create_index('pk', { type = 'tree', parts = { 1, 'num' }})
@@ -112,3 +112,7 @@ PERIOD
 ---
 - 0.03
 ...
+box.cfg{ snapshot_count = .2 }
+---
+- error: snapshot_count must be integer
+...
diff --git a/test/box/snap_daemon.test.lua b/test/box/snapshot_daemon.test.lua
similarity index 94%
rename from test/box/snap_daemon.test.lua
rename to test/box/snapshot_daemon.test.lua
index bdfcc649274af25bdb9f564dfe1e17d884d62f4a..45aeb441fc5981d1527210571af289b486396613 100644
--- a/test/box/snap_daemon.test.lua
+++ b/test/box/snapshot_daemon.test.lua
@@ -23,7 +23,7 @@ end
 --# setopt delimiter ''
 
 
-space = box.schema.create_space('snap_daemon')
+space = box.schema.create_space('snapshot_daemon')
 space:create_index('pk', { type = 'tree', parts = { 1, 'num' }})
 
 
@@ -70,3 +70,5 @@ box.cfg{snapshot_period = 3600 * 4, snapshot_count = 4 }
 space:drop()
 
 PERIOD
+
+box.cfg{ snapshot_count = .2 }
diff --git a/test/box/sophia.result b/test/box/sophia.result
deleted file mode 100644
index 2126bd3e3885dbc3c12b27201503586d0da574fc..0000000000000000000000000000000000000000
--- a/test/box/sophia.result
+++ /dev/null
@@ -1,335 +0,0 @@
-os.execute("rm -rf sophia")
----
-- 0
-...
-space = box.schema.create_space('tweedledum', { id = 123, engine = 'sophia' })
----
-...
-space:create_index('primary', { type = 'tree', parts = {1, 'num'} })
----
-...
-for v=1, 10 do space:insert({v}) end
----
-...
-t = space.index[0]:select({}, {iterator = box.index.ALL})
----
-...
-t
----
-- - [1]
-  - [2]
-  - [3]
-  - [4]
-  - [5]
-  - [6]
-  - [7]
-  - [8]
-  - [9]
-  - [10]
-...
-t = space.index[0]:select({}, {iterator = box.index.GE})
----
-...
-t
----
-- - [1]
-  - [2]
-  - [3]
-  - [4]
-  - [5]
-  - [6]
-  - [7]
-  - [8]
-  - [9]
-  - [10]
-...
-t = space.index[0]:select(4, {iterator = box.index.GE})
----
-...
-t
----
-- - [4]
-  - [5]
-  - [6]
-  - [7]
-  - [8]
-  - [9]
-  - [10]
-...
-t = space.index[0]:select({}, {iterator = box.index.LE})
----
-...
-t
----
-- - [10]
-  - [9]
-  - [8]
-  - [7]
-  - [6]
-  - [5]
-  - [4]
-  - [3]
-  - [2]
-  - [1]
-...
-t = space.index[0]:select(7, {iterator = box.index.LE})
----
-...
-t
----
-- - [7]
-  - [6]
-  - [5]
-  - [4]
-  - [3]
-  - [2]
-  - [1]
-...
-t = {}
----
-...
-for v=1, 10 do table.insert(t, space:get({v})) end
----
-...
-t
----
-- - [1]
-  - [2]
-  - [3]
-  - [4]
-  - [5]
-  - [6]
-  - [7]
-  - [8]
-  - [9]
-  - [10]
-...
-space:drop()
----
-...
-box.snapshot()
----
-- ok
-...
---
--- gh-283: Sophia: hang after three creates and drops
---
-s = box.schema.create_space('space0', {id = 33, engine='sophia'})
----
-...
-i = s:create_index('space0', {type = 'tree', parts = {1, 'STR'}})
----
-...
-s:insert{'a', 'b', 'c'}
----
-- ['a', 'b', 'c']
-...
-s:drop()
----
-...
-s = box.schema.create_space('space0', {id = 33, engine='sophia'})
----
-...
-i = s:create_index('space0', {type = 'tree', parts = {1, 'STR'}})
----
-...
-s:insert{'a', 'b', 'c'}
----
-- ['a', 'b', 'c']
-...
-t = s.index[0]:select({}, {iterator = box.index.ALL})
----
-...
-t
----
-- - ['a', 'b', 'c']
-...
-s:drop()
----
-...
-s = box.schema.create_space('space0', {id = 33, engine='sophia'})
----
-...
-i = s:create_index('space0', {type = 'tree', parts = {1, 'STR'}})
----
-...
-s:insert{'a', 'b', 'c'}
----
-- ['a', 'b', 'c']
-...
-t = s.index[0]:select({}, {iterator = box.index.ALL})
----
-...
-t
----
-- - ['a', 'b', 'c']
-...
-s:drop()
----
-...
---
--- gh-280: Sophia: crash if insert without index
---
-s = box.schema.create_space('test', {engine='sophia'})
----
-...
-s:insert{'a'}
----
-- error: 'No index #0 is defined in space ''test'''
-...
-s:drop()
----
-...
----
---- gh-431: Sophia: assertion if box.begin
----
-box.cfg{}
----
-...
-s = box.schema.create_space('tester',{engine='sophia'})
----
-...
-s:create_index('sophia_index', {})
----
-...
-s:insert{10000, 'Hilton'}
----
-- [10000, 'Hilton']
-...
-box.begin()
----
-...
-s:delete{10000} -- exception
----
-- error: sophia does not support transactions
-...
-box.rollback()
----
-...
-s:select{10000}
----
-- - [10000, 'Hilton']
-...
-s:drop()
----
-...
----
---- gh-456: Sophia: index size() is unsupported
----
-box.cfg{}
----
-...
-s = box.schema.create_space('tester',{engine='sophia'})
----
-...
-s:create_index('sophia_index', {})
----
-...
-s.index[0]:len() -- exception
----
-- error: SophiaIndex does not support size operation
-...
-box.error()
----
-- error: SophiaIndex does not support size operation
-...
-s:drop()
----
-...
----
---- gh-436: No error when creating temporary sophia space
----
-box.cfg{}
----
-...
-s = box.schema.create_space('tester',{engine='sophia', temporary=true})
----
-- error: 'Can''t modify space 512: space does not support temporary flag'
-...
----
---- gh-432: Sophia: ignored limit
----
-s = box.schema.create_space('tester',{id = 89, engine='sophia'})
----
-...
-s:create_index('sophia_index', {})
----
-...
-for v=1, 100 do s:insert({v}) end
----
-...
-t = s:select({''},{iterator='GT', limit =1})
----
-- error: 'Supplied key type of part 0 does not match index part type: expected NUM'
-...
-t
----
-- - ['a', 'b', 'c']
-...
-t = s:select({},{iterator='GT', limit =1})
----
-...
-t
----
-- - [1]
-...
-s:drop()
----
-...
-s = box.schema.create_space('tester', {id = 90, engine='sophia'})
----
-...
-s:create_index('sophia_index', {type = 'tree', parts = {1, 'STR'}})
----
-...
-for v=1, 100 do s:insert({tostring(v)}) end
----
-...
-t = s:select({''},{iterator='GT', limit =1})
----
-...
-t
----
-- - ['1']
-...
-t = s:select({},{iterator='GT', limit =1})
----
-...
-t
----
-- - ['1']
-...
-s:drop()
----
-...
----
---- gh-282: Sophia: truncate() does nothing
----
-s = box.schema.create_space('name_of_space', {id = 33, engine='sophia'})
----
-...
-i = s:create_index('name_of_index', {type = 'tree', parts = {1, 'STR'}})
----
-...
-s:insert{'a', 'b', 'c'}
----
-- ['a', 'b', 'c']
-...
-box.space['name_of_space']:select{'a'}
----
-- - ['a', 'b', 'c']
-...
-box.space['name_of_space']:truncate()
----
-...
-box.space['name_of_space']:select{'a'}
----
-- []
-...
-s:drop()
----
-...
-os.execute("rm -rf sophia")
----
-- 0
-...
diff --git a/test/box/stat.result b/test/box/stat.result
index ad1ea78af49b1ab993cefa331cfa834eb59e5d12..9a7d80f3ec8bc3c7ca54e63c41ba464e648c2433 100644
--- a/test/box/stat.result
+++ b/test/box/stat.result
@@ -50,7 +50,7 @@ box.stat.REPLACE.total
 ...
 box.stat.SELECT.total
 ---
-- 2
+- 3
 ...
 --# stop server default
 --# start server default
diff --git a/test/box/tuple.result b/test/box/tuple.result
index 53077ca336610fd08a89dcab5ff3e9bc09cc2611..3cf34faca9948f9068f1f645e04423bc4fd7596b 100644
--- a/test/box/tuple.result
+++ b/test/box/tuple.result
@@ -377,15 +377,15 @@ t:next(3)
 ...
 t:next(4)
 ---
-- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next'''
+- error: '[string "-- tuple.lua (internal file)..."]:86: error: invalid key to ''next'''
 ...
 t:next(-1)
 ---
-- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next'''
+- error: '[string "-- tuple.lua (internal file)..."]:86: error: invalid key to ''next'''
 ...
 t:next("fdsaf")
 ---
-- error: '[string "-- tuple.lua (internal file)..."]:52: error: invalid key to ''next'''
+- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next'''
 ...
 box.tuple.new({'x', 'y', 'z'}):next()
 ---
@@ -397,7 +397,7 @@ t=space:insert{1953719668}
 ...
 t:next(1684234849)
 ---
-- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next'''
+- error: '[string "-- tuple.lua (internal file)..."]:86: error: invalid key to ''next'''
 ...
 t:next(1)
 ---
@@ -553,7 +553,7 @@ r = {}
 ...
 for _state, val in t:pairs(10) do table.insert(r, val) end
 ---
-- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next'''
+- error: '[string "-- tuple.lua (internal file)..."]:86: error: invalid key to ''next'''
 ...
 r
 ---
@@ -639,19 +639,19 @@ t:findall(1, 'xxxxx')
 ...
 t:find(100, 'a')
 ---
-- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next'''
+- error: '[string "-- tuple.lua (internal file)..."]:86: error: invalid key to ''next'''
 ...
 t:findall(100, 'a')
 ---
-- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next'''
+- error: '[string "-- tuple.lua (internal file)..."]:86: error: invalid key to ''next'''
 ...
 t:find(100, 'xxxxx')
 ---
-- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next'''
+- error: '[string "-- tuple.lua (internal file)..."]:86: error: invalid key to ''next'''
 ...
 t:findall(100, 'xxxxx')
 ---
-- error: '[string "-- tuple.lua (internal file)..."]:69: error: invalid key to ''next'''
+- error: '[string "-- tuple.lua (internal file)..."]:86: error: invalid key to ''next'''
 ...
 ---
 -- Lua type coercion
@@ -737,6 +737,42 @@ t:findall(-9223372036854775807LL)
 - - 11
 ...
 --------------------------------------------------------------------------------
+-- test tuple:update
+--------------------------------------------------------------------------------
+-- see box/update.test.lua for more test cases
+t = box.tuple.new({'a', 'b', 'c', 'd', 'e'})
+---
+...
+t:update()
+---
+- error: '[string "-- tuple.lua (internal file)..."]:152: Usage: tuple:update({ {
+    op, field, arg}+ })'
+...
+t:update(10)
+---
+- error: '[string "-- tuple.lua (internal file)..."]:152: Usage: tuple:update({ {
+    op, field, arg}+ })'
+...
+t:update({})
+---
+- error: Illegal parameters, no operations for update
+...
+t:update({{ '!', -1, 'f'}})
+---
+- ['a', 'b', 'c', 'd', 'e', 'f']
+...
+t:update({{ '#', 4, 1}})
+---
+- ['a', 'b', 'c', 'e']
+...
+t
+---
+- ['a', 'b', 'c', 'd', 'e']
+...
+t = nil
+---
+...
+--------------------------------------------------------------------------------
 -- test msgpack.encode + tuple
 --------------------------------------------------------------------------------
 msgpack = require('msgpack')
diff --git a/test/box/tuple.test.lua b/test/box/tuple.test.lua
index 78a70b4c5bc60e376a12a8f45a253a18db958310..cb8f126f3d96ffd141119d63a28a4cac81b72d6f 100644
--- a/test/box/tuple.test.lua
+++ b/test/box/tuple.test.lua
@@ -230,6 +230,22 @@ t:findall(9223372036854775807ULL)
 t:find(-9223372036854775807LL)
 t:findall(-9223372036854775807LL)
 
+--------------------------------------------------------------------------------
+-- test tuple:update
+--------------------------------------------------------------------------------
+
+-- see box/update.test.lua for more test cases
+
+t = box.tuple.new({'a', 'b', 'c', 'd', 'e'})
+t:update()
+t:update(10)
+t:update({})
+t:update({{ '!', -1, 'f'}})
+t:update({{ '#', 4, 1}})
+
+t
+t = nil
+
 --------------------------------------------------------------------------------
 -- test msgpack.encode + tuple
 --------------------------------------------------------------------------------
diff --git a/test/lib/admin_connection.py b/test/lib/admin_connection.py
index 14d2e908027773a4cc29607a5fb9077a097bbeb5..5841a12e2a2742630101a5bb8b15e2e24f0d21c5 100644
--- a/test/lib/admin_connection.py
+++ b/test/lib/admin_connection.py
@@ -56,3 +56,9 @@ class AdminConnection(TarantoolConnection):
             if not silent:
                 sys.stdout.write(res.replace("\r\n", "\n"))
         return res
+
+    def connect(self):
+        super(AdminConnection, self).connect()
+        handshake = self.socket.recv(128)
+        if not re.search(r'^Tarantool.*console.*', str(handshake)):
+            raise RuntimeError('Broken tarantool console handshake')
diff --git a/test/lib/preprocessor.py b/test/lib/preprocessor.py
index 8f536568d0ea86a77069ac872f2a369539dbf712..f5f63678679fd15f8f0aaf3d9d257cce2b2960ff 100644
--- a/test/lib/preprocessor.py
+++ b/test/lib/preprocessor.py
@@ -30,8 +30,8 @@ class TestState(object):
         # curcon is an array since we may have many connections
         self.curcon = [self.connections['default']]
         nmsp = Namespace()
-        setattr(nmsp, 'admin', default_server.admin.port)
-        setattr(nmsp, 'listen', default_server.sql.port)
+        setattr(nmsp, 'admin', default_server.admin.uri)
+        setattr(nmsp, 'listen', default_server.sql.uri)
         setattr(self.environ, 'default', nmsp)
 
     def parse_preprocessor(self, string):
diff --git a/test/lib/server.py b/test/lib/server.py
index d7f8420abf5cce5f8a899a0e30abcb1086a64467..5aed7f27a4f043480c1dacd8d5794908b699efb7 100644
--- a/test/lib/server.py
+++ b/test/lib/server.py
@@ -15,8 +15,7 @@ import ConfigParser
 def check_port(port):
     """Check if the port we're connecting to is available"""
     try:
-        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        sock.connect(("localhost", port))
+        sock = socket.create_connection(("localhost", port))
     except socket.error as e:
         return
     raise RuntimeError("The server is already running on port {0}".format(port))
diff --git a/test/lib/sql_ast.py b/test/lib/sql_ast.py
index 3b0741745ef0322407fda3bda7c365f811ea66a9..f49a42ac6f8bb2ada158b1dcabb4cbfe01bcff38 100644
--- a/test/lib/sql_ast.py
+++ b/test/lib/sql_ast.py
@@ -25,7 +25,7 @@ ER = {
      4: "ER_TUPLE_NOT_FOUND"    ,
      5: "ER_UNSUPPORTED"        ,
      6: "ER_NONMASTER"          ,
-     7: "ER_SECONDARY"          ,
+     7: "ER_READONLY"           ,
      8: "ER_INJECTION"          ,
      9: "ER_CREATE_SPACE"       ,
     10: "ER_SPACE_EXISTS"       ,
diff --git a/test/lib/tarantool-python b/test/lib/tarantool-python
index df94b88d87c249e41cdf45dd74b13a2949be24f0..b2bcd37691d3f4664bd34646078b02709fa102cd 160000
--- a/test/lib/tarantool-python
+++ b/test/lib/tarantool-python
@@ -1 +1 @@
-Subproject commit df94b88d87c249e41cdf45dd74b13a2949be24f0
+Subproject commit b2bcd37691d3f4664bd34646078b02709fa102cd
diff --git a/test/lib/tarantool_connection.py b/test/lib/tarantool_connection.py
index 873c1db09d874eb602abd2b82a73dbbc6e906b0e..5278809c10e72512cfb41ea95eb753da4633bbe6 100644
--- a/test/lib/tarantool_connection.py
+++ b/test/lib/tarantool_connection.py
@@ -27,6 +27,14 @@ import errno
 import re
 
 class TarantoolConnection(object):
+
+    @property
+    def uri(self):
+        if self.host == 'unix/' or re.search(r'^/', str(self.port)):
+            return self.port
+        else:
+            return self.host+':'+str(self.port)
+
     def __init__(self, host, port):
         self.host = host
         self.port = port
@@ -37,9 +45,8 @@ class TarantoolConnection(object):
             self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
             self.socket.connect(self.port)
         else:
-            self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+            self.socket = socket.create_connection((self.host, self.port))
             self.socket.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)
-            self.socket.connect((self.host, self.port))
         self.is_connected = True
 
     def disconnect(self):
diff --git a/test/lib/tarantool_server.py b/test/lib/tarantool_server.py
index 332d37cbfd996000cb9c4c950c361d366d5ffe17..114f505fbaff71e0aa8b38c274c9c803fa4e4b26 100644
--- a/test/lib/tarantool_server.py
+++ b/test/lib/tarantool_server.py
@@ -36,8 +36,7 @@ color_stdout = Colorer()
 def check_port(port, rais=True):
     try:
         if isinstance(port, (int, long)):
-            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-            sock.connect(("localhost", port))
+            sock = socket.create_connection(("localhost", port))
         else:
             sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
             sock.connect(port)
@@ -464,10 +463,10 @@ class TarantoolServer(Server):
 
         check_port(self.admin.port)
 
-        os.putenv("LISTEN", str(self.sql.port))
-        os.putenv("ADMIN", str(self.admin.port))
+        os.putenv("LISTEN", self.sql.uri)
+        os.putenv("ADMIN", self.admin.uri)
         if self.rpl_master:
-            os.putenv("MASTER", "127.0.0.1:"+str(self.rpl_master.sql.port))
+            os.putenv("MASTER", self.rpl_master.sql.uri)
         args = self.prepare_args()
         self.logfile_pos = self.logfile
         self.process = subprocess.Popen(args,
diff --git a/test/replication/cluster.result b/test/replication/cluster.result
new file mode 100644
index 0000000000000000000000000000000000000000..efd3543df86a852b77e870b0f8e630b23e4610df
--- /dev/null
+++ b/test/replication/cluster.result
@@ -0,0 +1,36 @@
+box.space._cluster:replace{1, '8c7ff474-65f9-4abe-81a4-a3e1019bb1ae'}
+---
+- [1, '8c7ff474-65f9-4abe-81a4-a3e1019bb1ae']
+...
+box.info.server.uuid
+---
+- 8c7ff474-65f9-4abe-81a4-a3e1019bb1ae
+...
+check log line for 'server uuid changed to 8c7ff474-65f9-4abe-81a4-a3e1019bb1ae'
+
+'server uuid changed to 8c7ff474-65f9-4abe-81a4-a3e1019bb1ae' exists in server log
+
+box.info.server.uuid
+---
+- 8c7ff474-65f9-4abe-81a4-a3e1019bb1ae
+...
+box.snapshot()
+---
+- ok
+...
+box.info.server.uuid
+---
+- 8c7ff474-65f9-4abe-81a4-a3e1019bb1ae
+...
+box.space._cluster:delete(1)
+---
+- error: Can't reset server id
+...
+box.space._cluster:update(1, {{'=', 1, 10}})
+---
+- error: Can't reset server id
+...
+box.space._cluster:replace{1, require('uuid').NULL:str()}
+---
+- error: 'Invalid UUID: 00000000-0000-0000-0000-000000000000'
+...
diff --git a/test/replication/cluster.test.py b/test/replication/cluster.test.py
new file mode 100644
index 0000000000000000000000000000000000000000..b909a00082b2c665a038f96b30b6f7ccf375214a
--- /dev/null
+++ b/test/replication/cluster.test.py
@@ -0,0 +1,48 @@
+import re
+import yaml
+
+#
+# gh-434: Assertion if replace _cluster tuple
+#
+
+new_uuid = '8c7ff474-65f9-4abe-81a4-a3e1019bb1ae'
+
+# Requires panic_on_wal_error = false
+server.admin("box.space._cluster:replace{{1, '{}'}}".format(new_uuid))
+server.admin("box.info.server.uuid")
+
+# Check log message
+server.stop()
+f = open(server.logfile, "r")
+f.seek(0, 2)
+server.start()
+
+check="server uuid changed to " + new_uuid
+print "check log line for '%s'" % check
+print
+line = f.readline()
+while line:
+    if re.search(r'(%s)' % check, line):
+        print "'%s' exists in server log" % check
+        break
+    line = f.readline()
+print
+f.close()
+server.admin("box.info.server.uuid")
+
+# Check that new UUID has been saved in snapshot
+server.admin("box.snapshot()")
+server.restart()
+
+server.admin("box.info.server.uuid")
+
+# Can't reset server id
+server.admin("box.space._cluster:delete(1)")
+server.admin("box.space._cluster:update(1, {{'=', 1, 10}})")
+
+# Invalid UUID
+server.admin("box.space._cluster:replace{1, require('uuid').NULL:str()}")
+
+# Cleanup
+server.stop()
+server.deploy()
diff --git a/test/replication/hot_standby.result b/test/replication/hot_standby.result
index 65676c970e8ca4bc47d827bf854fb6ac33a1e5fb..d2b066d47a98c1c6fc952afcf7743f088c45fd28 100644
--- a/test/replication/hot_standby.result
+++ b/test/replication/hot_standby.result
@@ -12,7 +12,7 @@ box.schema.user.grant('guest', 'read,write,execute', 'universe')
 fiber = require('fiber');
 ---
 ...
-while box.info.server == nil do fiber.sleep(0.01) end;
+while box.info.server.id == 0 do fiber.sleep(0.01) end;
 ---
 ...
 while box.space['_priv']:len() < 1 do fiber.sleep(0.001) end;
@@ -64,7 +64,14 @@ end;
 --# set connection default
 -- set begin lsn on master, replica and hot_standby.
 --# set variable replica_port to 'replica.listen'
-a = (require 'net.box'):new('127.0.0.1', replica_port)
+REPLICA = require('uri').parse(tostring(replica_port))
+---
+...
+REPLICA ~= nil
+---
+- true
+...
+a = (require 'net.box'):new(REPLICA.host, REPLICA.service)
 ---
 ...
 a:call('_set_pri_lsn', box.info.server.id, box.info.server.lsn)
@@ -132,7 +139,14 @@ while box.info.status ~= 'running' do fiber.sleep(0.001) end
 -- hot_standby.listen is garbage, since hot_standby.lua
 -- uses MASTER environment variable for its listen
 --# set variable hot_standby_port to 'hot_standby.master'
-a = (require 'net.box'):new('127.0.0.1', hot_standby_port)
+HOT_STANDBY = require('uri').parse(tostring(hot_standby_port))
+---
+...
+HOT_STANDBY ~= nil
+---
+- true
+...
+a = (require 'net.box'):new(HOT_STANDBY.host, HOT_STANDBY.service)
 ---
 ...
 a:call('_set_pri_lsn', box.info.server.id, box.info.server.lsn)
diff --git a/test/replication/hot_standby.test.lua b/test/replication/hot_standby.test.lua
index e52f915b86fa06c02bfd5b890db023638db34a42..560207fb6b5dd5f2b9495272dc252a75a29a32f8 100644
--- a/test/replication/hot_standby.test.lua
+++ b/test/replication/hot_standby.test.lua
@@ -9,7 +9,7 @@ box.schema.user.grant('guest', 'read,write,execute', 'universe')
 --# setopt delimiter ';'
 --# set connection default, hot_standby, replica
 fiber = require('fiber');
-while box.info.server == nil do fiber.sleep(0.01) end;
+while box.info.server.id == 0 do fiber.sleep(0.01) end;
 while box.space['_priv']:len() < 1 do fiber.sleep(0.001) end;
 do
     local pri_id = ''
@@ -56,7 +56,9 @@ end;
 
 -- set begin lsn on master, replica and hot_standby.
 --# set variable replica_port to 'replica.listen'
-a = (require 'net.box'):new('127.0.0.1', replica_port)
+REPLICA = require('uri').parse(tostring(replica_port))
+REPLICA ~= nil
+a = (require 'net.box'):new(REPLICA.host, REPLICA.service)
 a:call('_set_pri_lsn', box.info.server.id, box.info.server.lsn)
 a:close()
 
@@ -78,7 +80,9 @@ while box.info.status ~= 'running' do fiber.sleep(0.001) end
 -- hot_standby.listen is garbage, since hot_standby.lua
 -- uses MASTER environment variable for its listen
 --# set variable hot_standby_port to 'hot_standby.master'
-a = (require 'net.box'):new('127.0.0.1', hot_standby_port)
+HOT_STANDBY = require('uri').parse(tostring(hot_standby_port))
+HOT_STANDBY ~= nil
+a = (require 'net.box'):new(HOT_STANDBY.host, HOT_STANDBY.service)
 a:call('_set_pri_lsn', box.info.server.id, box.info.server.lsn)
 a:close()
 
diff --git a/test/replication/readonly.result b/test/replication/readonly.result
new file mode 100644
index 0000000000000000000000000000000000000000..9a3b22b210fa4119b55ef7fd00086806a7e14693
--- /dev/null
+++ b/test/replication/readonly.result
@@ -0,0 +1,41 @@
+box.schema.user.grant('guest', 'read,write,execute', 'universe')
+---
+...
+box.info.server.id
+---
+- 2
+...
+box.info.server.ro
+---
+- false
+...
+box.info.server.lsn
+---
+- 0
+...
+-------------------------------------------------------------
+replica is read-only until receive self server_id in _cluster
+-------------------------------------------------------------
+box.cfg{replication_source = ""}
+---
+...
+box.info.server.id
+---
+- 0
+...
+box.info.server.ro
+---
+- true
+...
+box.info.server.lsn
+---
+- -1
+...
+space = box.schema.create_space("ro")
+---
+- error: Can't modify data because this server in read-only mode.
+...
+box.info.vclock[2]
+---
+- null
+...
diff --git a/test/replication/readonly.test.py b/test/replication/readonly.test.py
new file mode 100644
index 0000000000000000000000000000000000000000..24789c51a77e804d1b4b369e189a7d2e7bc5251c
--- /dev/null
+++ b/test/replication/readonly.test.py
@@ -0,0 +1,46 @@
+import os
+from glob import iglob as glob
+from lib.tarantool_server import TarantoolServer
+
+# master server
+master = server
+master_id = master.get_param('server')['id']
+
+master.admin("box.schema.user.grant('guest', 'read,write,execute', 'universe')")
+
+replica = TarantoolServer(server.ini)
+replica.script = 'replication/replica.lua'
+replica.vardir = os.path.join(server.vardir, 'replica')
+replica.rpl_master = master
+replica.deploy()
+replica.wait_lsn(master_id, master.get_lsn(master_id))
+replica_id = replica.get_param('server')['id']
+replica.admin('box.info.server.id')
+replica.admin('box.info.server.ro')
+replica.admin('box.info.server.lsn')
+replica.stop()
+
+print '-------------------------------------------------------------'
+print 'replica is read-only until receive self server_id in _cluster'
+print '-------------------------------------------------------------'
+
+# Remove xlog retrived by SUBSCRIBE
+filename = str(0).zfill(20) + ".xlog"
+wal = os.path.join(replica.vardir, filename)
+os.remove(wal)
+
+# Start replica without master
+server.stop()
+replica.start()
+replica.admin('box.cfg{replication_source = ""}')
+
+# Check that replica in read-only mode
+replica.admin('box.info.server.id')
+replica.admin('box.info.server.ro')
+replica.admin('box.info.server.lsn')
+replica.admin('space = box.schema.create_space("ro")')
+replica.admin('box.info.vclock[%d]' % replica_id)
+
+replica.stop()
+replica.cleanup(True)
+server.deploy()
diff --git a/test/replication/swap.result b/test/replication/swap.result
index 5badc7052d0fff463c4f1fca6ffc8953d3e48e84..7264bc985d053c0fb122f80eeda232b9e9e736eb 100644
--- a/test/replication/swap.result
+++ b/test/replication/swap.result
@@ -4,7 +4,7 @@ box.schema.user.create('test', { password = 'pass123456'})
 box.schema.user.grant('test', 'read,write,execute', 'universe')
 ---
 ...
-while box.info.server == nil do require('fiber').sleep(0.01) end
+while box.info.server.id == 0 do require('fiber').sleep(0.01) end
 ---
 ...
 while box.space['_priv']:len() < 1 do require('fiber').sleep(0.01) end
diff --git a/test/replication/swap.test.py b/test/replication/swap.test.py
index 49088df3f94ba61fb7a623c70903340463802149..74cd85a7b37e7d7042bb79fc03c6f29b04ba8c02 100644
--- a/test/replication/swap.test.py
+++ b/test/replication/swap.test.py
@@ -7,7 +7,6 @@ import yaml
 REPEAT = 20
 ID_BEGIN = 0
 ID_STEP = 5
-HOST = '127.0.0.1'
 LOGIN = 'test'
 PASSWORD = 'pass123456'
 
@@ -24,7 +23,7 @@ master = server
 master.admin("box.schema.user.create('%s', { password = '%s'})" % (LOGIN, PASSWORD))
 master.admin("box.schema.user.grant('%s', 'read,write,execute', 'universe')" % LOGIN)
 master.sql.py_con.authenticate(LOGIN, PASSWORD)
-master.uri = '%s:%s@%s:%s' % (LOGIN, PASSWORD, HOST, master.sql.port)
+master.uri = '%s:%s@%s' % (LOGIN, PASSWORD, master.sql.uri)
 os.putenv('MASTER', master.uri)
 
 # replica server
@@ -32,8 +31,8 @@ replica = TarantoolServer()
 replica.script = "replication/replica.lua"
 replica.vardir = os.path.join(server.vardir, 'replica')
 replica.deploy()
-replica.admin("while box.info.server == nil do require('fiber').sleep(0.01) end")
-replica.uri = '%s:%s@%s:%s' % (LOGIN, PASSWORD, HOST, replica.sql.port)
+replica.admin("while box.info.server.id == 0 do require('fiber').sleep(0.01) end")
+replica.uri = '%s:%s@%s' % (LOGIN, PASSWORD, replica.sql.uri)
 replica.admin("while box.space['_priv']:len() < 1 do require('fiber').sleep(0.01) end")
 replica.sql.py_con.authenticate(LOGIN, PASSWORD)
 
@@ -42,7 +41,7 @@ master.admin("s:create_index('primary', {type = 'hash'})")
 
 ### gh-343: replica.cc must not add login and password to proc title
 #status = replica.get_param("status")
-#host_port = "%s:%s" % (HOST, master.sql.port)
+#host_port = "%s:%s" % master.sql.uri
 #m = re.search(r'replica/(.*)/.*', status)
 #if not m or m.group(1) != host_port:
 #    print 'invalid box.info.status', status, 'expected host:port', host_port
diff --git a/test/sophia/box.lua b/test/sophia/box.lua
new file mode 100644
index 0000000000000000000000000000000000000000..c9e32af1c76f0ff7bc75aa7409cf1f262d39e14a
--- /dev/null
+++ b/test/sophia/box.lua
@@ -0,0 +1,23 @@
+#!/usr/bin/env tarantool
+os = require('os')
+
+box.cfg{
+    listen              = os.getenv("LISTEN"),
+    slab_alloc_arena    = 0.1,
+    pid_file            = "tarantool.pid",
+    rows_per_wal        = 50,
+    sophia_dir          = "sophia_test"
+}
+
+require('console').listen(os.getenv('ADMIN'))
+
+function sophia_printdir()
+	f = io.popen("ls -1 sophia_test")
+	ls = f:read("*all")
+	unused = f:close()
+	return ls
+end
+
+function sophia_rmdir(dir)
+	os.execute("rm -rf sophia_test")
+end
diff --git a/test/sophia/crud.result b/test/sophia/crud.result
new file mode 100644
index 0000000000000000000000000000000000000000..52822918ea54bc3c82205c05c31912985589da3d
--- /dev/null
+++ b/test/sophia/crud.result
@@ -0,0 +1,1178 @@
+sophia_rmdir()
+---
+...
+-- insert
+space = box.schema.create_space('test', { engine = 'sophia', id = 100 })
+---
+...
+space:create_index('primary', { type = 'tree', parts = {1, 'num'} })
+---
+...
+for key = 1, 132 do space:insert({key}) end
+---
+...
+t = {}
+---
+...
+for key = 1, 132 do table.insert(t, space:get({key})) end
+---
+...
+t
+---
+- - [1]
+  - [2]
+  - [3]
+  - [4]
+  - [5]
+  - [6]
+  - [7]
+  - [8]
+  - [9]
+  - [10]
+  - [11]
+  - [12]
+  - [13]
+  - [14]
+  - [15]
+  - [16]
+  - [17]
+  - [18]
+  - [19]
+  - [20]
+  - [21]
+  - [22]
+  - [23]
+  - [24]
+  - [25]
+  - [26]
+  - [27]
+  - [28]
+  - [29]
+  - [30]
+  - [31]
+  - [32]
+  - [33]
+  - [34]
+  - [35]
+  - [36]
+  - [37]
+  - [38]
+  - [39]
+  - [40]
+  - [41]
+  - [42]
+  - [43]
+  - [44]
+  - [45]
+  - [46]
+  - [47]
+  - [48]
+  - [49]
+  - [50]
+  - [51]
+  - [52]
+  - [53]
+  - [54]
+  - [55]
+  - [56]
+  - [57]
+  - [58]
+  - [59]
+  - [60]
+  - [61]
+  - [62]
+  - [63]
+  - [64]
+  - [65]
+  - [66]
+  - [67]
+  - [68]
+  - [69]
+  - [70]
+  - [71]
+  - [72]
+  - [73]
+  - [74]
+  - [75]
+  - [76]
+  - [77]
+  - [78]
+  - [79]
+  - [80]
+  - [81]
+  - [82]
+  - [83]
+  - [84]
+  - [85]
+  - [86]
+  - [87]
+  - [88]
+  - [89]
+  - [90]
+  - [91]
+  - [92]
+  - [93]
+  - [94]
+  - [95]
+  - [96]
+  - [97]
+  - [98]
+  - [99]
+  - [100]
+  - [101]
+  - [102]
+  - [103]
+  - [104]
+  - [105]
+  - [106]
+  - [107]
+  - [108]
+  - [109]
+  - [110]
+  - [111]
+  - [112]
+  - [113]
+  - [114]
+  - [115]
+  - [116]
+  - [117]
+  - [118]
+  - [119]
+  - [120]
+  - [121]
+  - [122]
+  - [123]
+  - [124]
+  - [125]
+  - [126]
+  - [127]
+  - [128]
+  - [129]
+  - [130]
+  - [131]
+  - [132]
+...
+-- replace/get
+for key = 1, 132 do space:replace({key, key}) end
+---
+...
+t = {}
+---
+...
+for key = 1, 132 do table.insert(t, space:get({key})) end
+---
+...
+t
+---
+- - [1, 1]
+  - [2, 2]
+  - [3, 3]
+  - [4, 4]
+  - [5, 5]
+  - [6, 6]
+  - [7, 7]
+  - [8, 8]
+  - [9, 9]
+  - [10, 10]
+  - [11, 11]
+  - [12, 12]
+  - [13, 13]
+  - [14, 14]
+  - [15, 15]
+  - [16, 16]
+  - [17, 17]
+  - [18, 18]
+  - [19, 19]
+  - [20, 20]
+  - [21, 21]
+  - [22, 22]
+  - [23, 23]
+  - [24, 24]
+  - [25, 25]
+  - [26, 26]
+  - [27, 27]
+  - [28, 28]
+  - [29, 29]
+  - [30, 30]
+  - [31, 31]
+  - [32, 32]
+  - [33, 33]
+  - [34, 34]
+  - [35, 35]
+  - [36, 36]
+  - [37, 37]
+  - [38, 38]
+  - [39, 39]
+  - [40, 40]
+  - [41, 41]
+  - [42, 42]
+  - [43, 43]
+  - [44, 44]
+  - [45, 45]
+  - [46, 46]
+  - [47, 47]
+  - [48, 48]
+  - [49, 49]
+  - [50, 50]
+  - [51, 51]
+  - [52, 52]
+  - [53, 53]
+  - [54, 54]
+  - [55, 55]
+  - [56, 56]
+  - [57, 57]
+  - [58, 58]
+  - [59, 59]
+  - [60, 60]
+  - [61, 61]
+  - [62, 62]
+  - [63, 63]
+  - [64, 64]
+  - [65, 65]
+  - [66, 66]
+  - [67, 67]
+  - [68, 68]
+  - [69, 69]
+  - [70, 70]
+  - [71, 71]
+  - [72, 72]
+  - [73, 73]
+  - [74, 74]
+  - [75, 75]
+  - [76, 76]
+  - [77, 77]
+  - [78, 78]
+  - [79, 79]
+  - [80, 80]
+  - [81, 81]
+  - [82, 82]
+  - [83, 83]
+  - [84, 84]
+  - [85, 85]
+  - [86, 86]
+  - [87, 87]
+  - [88, 88]
+  - [89, 89]
+  - [90, 90]
+  - [91, 91]
+  - [92, 92]
+  - [93, 93]
+  - [94, 94]
+  - [95, 95]
+  - [96, 96]
+  - [97, 97]
+  - [98, 98]
+  - [99, 99]
+  - [100, 100]
+  - [101, 101]
+  - [102, 102]
+  - [103, 103]
+  - [104, 104]
+  - [105, 105]
+  - [106, 106]
+  - [107, 107]
+  - [108, 108]
+  - [109, 109]
+  - [110, 110]
+  - [111, 111]
+  - [112, 112]
+  - [113, 113]
+  - [114, 114]
+  - [115, 115]
+  - [116, 116]
+  - [117, 117]
+  - [118, 118]
+  - [119, 119]
+  - [120, 120]
+  - [121, 121]
+  - [122, 122]
+  - [123, 123]
+  - [124, 124]
+  - [125, 125]
+  - [126, 126]
+  - [127, 127]
+  - [128, 128]
+  - [129, 129]
+  - [130, 130]
+  - [131, 131]
+  - [132, 132]
+...
+-- update/get
+for key = 1, 132 do space:update({key}, {{'+', 2, key}}) end
+---
+...
+t = {}
+---
+...
+for key = 1, 132 do table.insert(t, space:get({key})) end
+---
+...
+t
+---
+- - [1, 2]
+  - [2, 4]
+  - [3, 6]
+  - [4, 8]
+  - [5, 10]
+  - [6, 12]
+  - [7, 14]
+  - [8, 16]
+  - [9, 18]
+  - [10, 20]
+  - [11, 22]
+  - [12, 24]
+  - [13, 26]
+  - [14, 28]
+  - [15, 30]
+  - [16, 32]
+  - [17, 34]
+  - [18, 36]
+  - [19, 38]
+  - [20, 40]
+  - [21, 42]
+  - [22, 44]
+  - [23, 46]
+  - [24, 48]
+  - [25, 50]
+  - [26, 52]
+  - [27, 54]
+  - [28, 56]
+  - [29, 58]
+  - [30, 60]
+  - [31, 62]
+  - [32, 64]
+  - [33, 66]
+  - [34, 68]
+  - [35, 70]
+  - [36, 72]
+  - [37, 74]
+  - [38, 76]
+  - [39, 78]
+  - [40, 80]
+  - [41, 82]
+  - [42, 84]
+  - [43, 86]
+  - [44, 88]
+  - [45, 90]
+  - [46, 92]
+  - [47, 94]
+  - [48, 96]
+  - [49, 98]
+  - [50, 100]
+  - [51, 102]
+  - [52, 104]
+  - [53, 106]
+  - [54, 108]
+  - [55, 110]
+  - [56, 112]
+  - [57, 114]
+  - [58, 116]
+  - [59, 118]
+  - [60, 120]
+  - [61, 122]
+  - [62, 124]
+  - [63, 126]
+  - [64, 128]
+  - [65, 130]
+  - [66, 132]
+  - [67, 134]
+  - [68, 136]
+  - [69, 138]
+  - [70, 140]
+  - [71, 142]
+  - [72, 144]
+  - [73, 146]
+  - [74, 148]
+  - [75, 150]
+  - [76, 152]
+  - [77, 154]
+  - [78, 156]
+  - [79, 158]
+  - [80, 160]
+  - [81, 162]
+  - [82, 164]
+  - [83, 166]
+  - [84, 168]
+  - [85, 170]
+  - [86, 172]
+  - [87, 174]
+  - [88, 176]
+  - [89, 178]
+  - [90, 180]
+  - [91, 182]
+  - [92, 184]
+  - [93, 186]
+  - [94, 188]
+  - [95, 190]
+  - [96, 192]
+  - [97, 194]
+  - [98, 196]
+  - [99, 198]
+  - [100, 200]
+  - [101, 202]
+  - [102, 204]
+  - [103, 206]
+  - [104, 208]
+  - [105, 210]
+  - [106, 212]
+  - [107, 214]
+  - [108, 216]
+  - [109, 218]
+  - [110, 220]
+  - [111, 222]
+  - [112, 224]
+  - [113, 226]
+  - [114, 228]
+  - [115, 230]
+  - [116, 232]
+  - [117, 234]
+  - [118, 236]
+  - [119, 238]
+  - [120, 240]
+  - [121, 242]
+  - [122, 244]
+  - [123, 246]
+  - [124, 248]
+  - [125, 250]
+  - [126, 252]
+  - [127, 254]
+  - [128, 256]
+  - [129, 258]
+  - [130, 260]
+  - [131, 262]
+  - [132, 264]
+...
+-- delete/get
+for key = 1, 132 do space:delete({key}) end
+---
+...
+for key = 1, 132 do assert(space:get({key}) == nil) end
+---
+...
+-- select
+for key = 1, 96 do space:insert({key}) end
+---
+...
+index = space.index[0]
+---
+...
+index:select({}, {iterator = box.index.ALL})
+---
+- - [1]
+  - [2]
+  - [3]
+  - [4]
+  - [5]
+  - [6]
+  - [7]
+  - [8]
+  - [9]
+  - [10]
+  - [11]
+  - [12]
+  - [13]
+  - [14]
+  - [15]
+  - [16]
+  - [17]
+  - [18]
+  - [19]
+  - [20]
+  - [21]
+  - [22]
+  - [23]
+  - [24]
+  - [25]
+  - [26]
+  - [27]
+  - [28]
+  - [29]
+  - [30]
+  - [31]
+  - [32]
+  - [33]
+  - [34]
+  - [35]
+  - [36]
+  - [37]
+  - [38]
+  - [39]
+  - [40]
+  - [41]
+  - [42]
+  - [43]
+  - [44]
+  - [45]
+  - [46]
+  - [47]
+  - [48]
+  - [49]
+  - [50]
+  - [51]
+  - [52]
+  - [53]
+  - [54]
+  - [55]
+  - [56]
+  - [57]
+  - [58]
+  - [59]
+  - [60]
+  - [61]
+  - [62]
+  - [63]
+  - [64]
+  - [65]
+  - [66]
+  - [67]
+  - [68]
+  - [69]
+  - [70]
+  - [71]
+  - [72]
+  - [73]
+  - [74]
+  - [75]
+  - [76]
+  - [77]
+  - [78]
+  - [79]
+  - [80]
+  - [81]
+  - [82]
+  - [83]
+  - [84]
+  - [85]
+  - [86]
+  - [87]
+  - [88]
+  - [89]
+  - [90]
+  - [91]
+  - [92]
+  - [93]
+  - [94]
+  - [95]
+  - [96]
+...
+index:select({}, {iterator = box.index.GE})
+---
+- - [1]
+  - [2]
+  - [3]
+  - [4]
+  - [5]
+  - [6]
+  - [7]
+  - [8]
+  - [9]
+  - [10]
+  - [11]
+  - [12]
+  - [13]
+  - [14]
+  - [15]
+  - [16]
+  - [17]
+  - [18]
+  - [19]
+  - [20]
+  - [21]
+  - [22]
+  - [23]
+  - [24]
+  - [25]
+  - [26]
+  - [27]
+  - [28]
+  - [29]
+  - [30]
+  - [31]
+  - [32]
+  - [33]
+  - [34]
+  - [35]
+  - [36]
+  - [37]
+  - [38]
+  - [39]
+  - [40]
+  - [41]
+  - [42]
+  - [43]
+  - [44]
+  - [45]
+  - [46]
+  - [47]
+  - [48]
+  - [49]
+  - [50]
+  - [51]
+  - [52]
+  - [53]
+  - [54]
+  - [55]
+  - [56]
+  - [57]
+  - [58]
+  - [59]
+  - [60]
+  - [61]
+  - [62]
+  - [63]
+  - [64]
+  - [65]
+  - [66]
+  - [67]
+  - [68]
+  - [69]
+  - [70]
+  - [71]
+  - [72]
+  - [73]
+  - [74]
+  - [75]
+  - [76]
+  - [77]
+  - [78]
+  - [79]
+  - [80]
+  - [81]
+  - [82]
+  - [83]
+  - [84]
+  - [85]
+  - [86]
+  - [87]
+  - [88]
+  - [89]
+  - [90]
+  - [91]
+  - [92]
+  - [93]
+  - [94]
+  - [95]
+  - [96]
+...
+index:select(4,  {iterator = box.index.GE})
+---
+- - [4]
+  - [5]
+  - [6]
+  - [7]
+  - [8]
+  - [9]
+  - [10]
+  - [11]
+  - [12]
+  - [13]
+  - [14]
+  - [15]
+  - [16]
+  - [17]
+  - [18]
+  - [19]
+  - [20]
+  - [21]
+  - [22]
+  - [23]
+  - [24]
+  - [25]
+  - [26]
+  - [27]
+  - [28]
+  - [29]
+  - [30]
+  - [31]
+  - [32]
+  - [33]
+  - [34]
+  - [35]
+  - [36]
+  - [37]
+  - [38]
+  - [39]
+  - [40]
+  - [41]
+  - [42]
+  - [43]
+  - [44]
+  - [45]
+  - [46]
+  - [47]
+  - [48]
+  - [49]
+  - [50]
+  - [51]
+  - [52]
+  - [53]
+  - [54]
+  - [55]
+  - [56]
+  - [57]
+  - [58]
+  - [59]
+  - [60]
+  - [61]
+  - [62]
+  - [63]
+  - [64]
+  - [65]
+  - [66]
+  - [67]
+  - [68]
+  - [69]
+  - [70]
+  - [71]
+  - [72]
+  - [73]
+  - [74]
+  - [75]
+  - [76]
+  - [77]
+  - [78]
+  - [79]
+  - [80]
+  - [81]
+  - [82]
+  - [83]
+  - [84]
+  - [85]
+  - [86]
+  - [87]
+  - [88]
+  - [89]
+  - [90]
+  - [91]
+  - [92]
+  - [93]
+  - [94]
+  - [95]
+  - [96]
+...
+index:select({}, {iterator = box.index.GT})
+---
+- - [1]
+  - [2]
+  - [3]
+  - [4]
+  - [5]
+  - [6]
+  - [7]
+  - [8]
+  - [9]
+  - [10]
+  - [11]
+  - [12]
+  - [13]
+  - [14]
+  - [15]
+  - [16]
+  - [17]
+  - [18]
+  - [19]
+  - [20]
+  - [21]
+  - [22]
+  - [23]
+  - [24]
+  - [25]
+  - [26]
+  - [27]
+  - [28]
+  - [29]
+  - [30]
+  - [31]
+  - [32]
+  - [33]
+  - [34]
+  - [35]
+  - [36]
+  - [37]
+  - [38]
+  - [39]
+  - [40]
+  - [41]
+  - [42]
+  - [43]
+  - [44]
+  - [45]
+  - [46]
+  - [47]
+  - [48]
+  - [49]
+  - [50]
+  - [51]
+  - [52]
+  - [53]
+  - [54]
+  - [55]
+  - [56]
+  - [57]
+  - [58]
+  - [59]
+  - [60]
+  - [61]
+  - [62]
+  - [63]
+  - [64]
+  - [65]
+  - [66]
+  - [67]
+  - [68]
+  - [69]
+  - [70]
+  - [71]
+  - [72]
+  - [73]
+  - [74]
+  - [75]
+  - [76]
+  - [77]
+  - [78]
+  - [79]
+  - [80]
+  - [81]
+  - [82]
+  - [83]
+  - [84]
+  - [85]
+  - [86]
+  - [87]
+  - [88]
+  - [89]
+  - [90]
+  - [91]
+  - [92]
+  - [93]
+  - [94]
+  - [95]
+  - [96]
+...
+index:select(4,  {iterator = box.index.GT})
+---
+- - [5]
+  - [6]
+  - [7]
+  - [8]
+  - [9]
+  - [10]
+  - [11]
+  - [12]
+  - [13]
+  - [14]
+  - [15]
+  - [16]
+  - [17]
+  - [18]
+  - [19]
+  - [20]
+  - [21]
+  - [22]
+  - [23]
+  - [24]
+  - [25]
+  - [26]
+  - [27]
+  - [28]
+  - [29]
+  - [30]
+  - [31]
+  - [32]
+  - [33]
+  - [34]
+  - [35]
+  - [36]
+  - [37]
+  - [38]
+  - [39]
+  - [40]
+  - [41]
+  - [42]
+  - [43]
+  - [44]
+  - [45]
+  - [46]
+  - [47]
+  - [48]
+  - [49]
+  - [50]
+  - [51]
+  - [52]
+  - [53]
+  - [54]
+  - [55]
+  - [56]
+  - [57]
+  - [58]
+  - [59]
+  - [60]
+  - [61]
+  - [62]
+  - [63]
+  - [64]
+  - [65]
+  - [66]
+  - [67]
+  - [68]
+  - [69]
+  - [70]
+  - [71]
+  - [72]
+  - [73]
+  - [74]
+  - [75]
+  - [76]
+  - [77]
+  - [78]
+  - [79]
+  - [80]
+  - [81]
+  - [82]
+  - [83]
+  - [84]
+  - [85]
+  - [86]
+  - [87]
+  - [88]
+  - [89]
+  - [90]
+  - [91]
+  - [92]
+  - [93]
+  - [94]
+  - [95]
+  - [96]
+...
+index:select({}, {iterator = box.index.LE})
+---
+- - [96]
+  - [95]
+  - [94]
+  - [93]
+  - [92]
+  - [91]
+  - [90]
+  - [89]
+  - [88]
+  - [87]
+  - [86]
+  - [85]
+  - [84]
+  - [83]
+  - [82]
+  - [81]
+  - [80]
+  - [79]
+  - [78]
+  - [77]
+  - [76]
+  - [75]
+  - [74]
+  - [73]
+  - [72]
+  - [71]
+  - [70]
+  - [69]
+  - [68]
+  - [67]
+  - [66]
+  - [65]
+  - [64]
+  - [63]
+  - [62]
+  - [61]
+  - [60]
+  - [59]
+  - [58]
+  - [57]
+  - [56]
+  - [55]
+  - [54]
+  - [53]
+  - [52]
+  - [51]
+  - [50]
+  - [49]
+  - [48]
+  - [47]
+  - [46]
+  - [45]
+  - [44]
+  - [43]
+  - [42]
+  - [41]
+  - [40]
+  - [39]
+  - [38]
+  - [37]
+  - [36]
+  - [35]
+  - [34]
+  - [33]
+  - [32]
+  - [31]
+  - [30]
+  - [29]
+  - [28]
+  - [27]
+  - [26]
+  - [25]
+  - [24]
+  - [23]
+  - [22]
+  - [21]
+  - [20]
+  - [19]
+  - [18]
+  - [17]
+  - [16]
+  - [15]
+  - [14]
+  - [13]
+  - [12]
+  - [11]
+  - [10]
+  - [9]
+  - [8]
+  - [7]
+  - [6]
+  - [5]
+  - [4]
+  - [3]
+  - [2]
+  - [1]
+...
+index:select(7,  {iterator = box.index.LE})
+---
+- - [7]
+  - [6]
+  - [5]
+  - [4]
+  - [3]
+  - [2]
+  - [1]
+...
+index:select({}, {iterator = box.index.LT})
+---
+- - [96]
+  - [95]
+  - [94]
+  - [93]
+  - [92]
+  - [91]
+  - [90]
+  - [89]
+  - [88]
+  - [87]
+  - [86]
+  - [85]
+  - [84]
+  - [83]
+  - [82]
+  - [81]
+  - [80]
+  - [79]
+  - [78]
+  - [77]
+  - [76]
+  - [75]
+  - [74]
+  - [73]
+  - [72]
+  - [71]
+  - [70]
+  - [69]
+  - [68]
+  - [67]
+  - [66]
+  - [65]
+  - [64]
+  - [63]
+  - [62]
+  - [61]
+  - [60]
+  - [59]
+  - [58]
+  - [57]
+  - [56]
+  - [55]
+  - [54]
+  - [53]
+  - [52]
+  - [51]
+  - [50]
+  - [49]
+  - [48]
+  - [47]
+  - [46]
+  - [45]
+  - [44]
+  - [43]
+  - [42]
+  - [41]
+  - [40]
+  - [39]
+  - [38]
+  - [37]
+  - [36]
+  - [35]
+  - [34]
+  - [33]
+  - [32]
+  - [31]
+  - [30]
+  - [29]
+  - [28]
+  - [27]
+  - [26]
+  - [25]
+  - [24]
+  - [23]
+  - [22]
+  - [21]
+  - [20]
+  - [19]
+  - [18]
+  - [17]
+  - [16]
+  - [15]
+  - [14]
+  - [13]
+  - [12]
+  - [11]
+  - [10]
+  - [9]
+  - [8]
+  - [7]
+  - [6]
+  - [5]
+  - [4]
+  - [3]
+  - [2]
+  - [1]
+...
+index:select(7,  {iterator = box.index.LT})
+---
+- - [6]
+  - [5]
+  - [4]
+  - [3]
+  - [2]
+  - [1]
+...
+-- random
+dofile('index_random_test.lua')
+---
+...
+index_random_test(space, 'primary')
+---
+- true
+...
+space:drop()
+---
+...
+--
+sophia_rmdir()
+---
+...
diff --git a/test/sophia/crud.test.lua b/test/sophia/crud.test.lua
new file mode 100644
index 0000000000000000000000000000000000000000..191a58057830fb0de8478d8a21cbcf01e88b9e29
--- /dev/null
+++ b/test/sophia/crud.test.lua
@@ -0,0 +1,55 @@
+
+sophia_rmdir()
+
+-- insert
+
+space = box.schema.create_space('test', { engine = 'sophia', id = 100 })
+space:create_index('primary', { type = 'tree', parts = {1, 'num'} })
+for key = 1, 132 do space:insert({key}) end
+t = {}
+for key = 1, 132 do table.insert(t, space:get({key})) end
+t
+
+-- replace/get
+
+for key = 1, 132 do space:replace({key, key}) end
+t = {}
+for key = 1, 132 do table.insert(t, space:get({key})) end
+t
+
+-- update/get
+
+for key = 1, 132 do space:update({key}, {{'+', 2, key}}) end
+t = {}
+for key = 1, 132 do table.insert(t, space:get({key})) end
+t
+
+-- delete/get
+
+for key = 1, 132 do space:delete({key}) end
+for key = 1, 132 do assert(space:get({key}) == nil) end
+
+-- select
+
+for key = 1, 96 do space:insert({key}) end
+index = space.index[0]
+index:select({}, {iterator = box.index.ALL})
+index:select({}, {iterator = box.index.GE})
+index:select(4,  {iterator = box.index.GE})
+index:select({}, {iterator = box.index.GT})
+index:select(4,  {iterator = box.index.GT})
+index:select({}, {iterator = box.index.LE})
+index:select(7,  {iterator = box.index.LE})
+index:select({}, {iterator = box.index.LT})
+index:select(7,  {iterator = box.index.LT})
+
+-- random
+
+dofile('index_random_test.lua')
+index_random_test(space, 'primary')
+
+space:drop()
+
+--
+
+sophia_rmdir()
diff --git a/test/sophia/dml.result b/test/sophia/dml.result
new file mode 100644
index 0000000000000000000000000000000000000000..69b0f8746bf5b7d9d09d73126652466522b10167
--- /dev/null
+++ b/test/sophia/dml.result
@@ -0,0 +1,171 @@
+sophia_rmdir()
+---
+...
+-- space create/drop
+space = box.schema.create_space('test', { id = 100, engine = 'sophia' })
+---
+...
+sophia_printdir()
+---
+- 
+...
+space:drop()
+---
+...
+sophia_printdir()
+---
+- 
+...
+-- index create/drop
+space = box.schema.create_space('test', { id = 101, engine = 'sophia' })
+---
+...
+space:create_index('primary')
+---
+...
+sophia_printdir()
+---
+- '101
+
+'
+...
+space:drop()
+---
+...
+sophia_printdir()
+---
+- 
+...
+-- index create/drop alter
+space = box.schema.create_space('test', { id = 102, engine = 'sophia' })
+---
+...
+space:create_index('primary')
+---
+...
+sophia_printdir()
+---
+- '102
+
+'
+...
+_index = box.space[box.schema.INDEX_ID]
+---
+...
+_index:delete{102, 0}
+---
+- [102, 0, 'primary', 'tree', 1, 1, 0, 'num']
+...
+sophia_printdir()
+---
+- 
+...
+space:drop()
+---
+...
+-- index create/drop tree string
+space = box.schema.create_space('test', { id = 103, engine = 'sophia' })
+---
+...
+space:create_index('primary', {type = 'tree', parts = {1, 'STR'}})
+---
+...
+space:insert({'test'})
+---
+- ['test']
+...
+sophia_printdir()
+---
+- '103
+
+'
+...
+space:drop()
+---
+...
+-- index create/drop tree num
+space = box.schema.create_space('test', { id = 104, engine = 'sophia' })
+---
+...
+space:create_index('primary', {type = 'tree', parts = {1, 'num'}})
+---
+...
+space:insert({13})
+---
+- [13]
+...
+sophia_printdir()
+---
+- '104
+
+'
+...
+space:drop()
+---
+...
+-- index create hash 
+space = box.schema.create_space('test', { id = 105, engine = 'sophia' })
+---
+...
+space:create_index('primary', {type = 'hash'})
+---
+- error: Unsupported index type supplied for index 0 in space 105
+...
+space:drop()
+---
+...
+-- secondary index create
+space = box.schema.create_space('test', { id = 106, engine = 'sophia' })
+---
+...
+space:create_index('primary')
+---
+...
+space:create_index('secondary')
+---
+- error: 'Can''t create or modify index 1 in space 106: Sophia TREE secondary indexes
+    are not supported'
+...
+space:drop()
+---
+...
+sophia_printdir()
+---
+- 
+...
+-- index size
+space = box.schema.create_space('test', { id = 107, engine = 'sophia' })
+---
+...
+space:create_index('primary')
+---
+...
+primary = space.index[0]
+---
+...
+primary:len()
+---
+- 0
+...
+space:insert({13})
+---
+- [13]
+...
+space:insert({14})
+---
+- [14]
+...
+space:insert({15})
+---
+- [15]
+...
+primary:len()
+---
+- 3
+...
+space:drop()
+---
+...
+sophia_rmdir()
+---
+...
diff --git a/test/sophia/dml.test.lua b/test/sophia/dml.test.lua
new file mode 100644
index 0000000000000000000000000000000000000000..56ca115287d3c6edca13fda99bc4e70c403e45c4
--- /dev/null
+++ b/test/sophia/dml.test.lua
@@ -0,0 +1,71 @@
+
+sophia_rmdir()
+
+-- space create/drop
+
+space = box.schema.create_space('test', { id = 100, engine = 'sophia' })
+sophia_printdir()
+space:drop()
+sophia_printdir()
+
+-- index create/drop
+
+space = box.schema.create_space('test', { id = 101, engine = 'sophia' })
+space:create_index('primary')
+sophia_printdir()
+space:drop()
+sophia_printdir()
+
+-- index create/drop alter
+
+space = box.schema.create_space('test', { id = 102, engine = 'sophia' })
+space:create_index('primary')
+sophia_printdir()
+_index = box.space[box.schema.INDEX_ID]
+_index:delete{102, 0}
+sophia_printdir()
+space:drop()
+
+-- index create/drop tree string
+
+space = box.schema.create_space('test', { id = 103, engine = 'sophia' })
+space:create_index('primary', {type = 'tree', parts = {1, 'STR'}})
+space:insert({'test'})
+sophia_printdir()
+space:drop()
+
+-- index create/drop tree num
+
+space = box.schema.create_space('test', { id = 104, engine = 'sophia' })
+space:create_index('primary', {type = 'tree', parts = {1, 'num'}})
+space:insert({13})
+sophia_printdir()
+space:drop()
+
+-- index create hash 
+
+space = box.schema.create_space('test', { id = 105, engine = 'sophia' })
+space:create_index('primary', {type = 'hash'})
+space:drop()
+
+-- secondary index create
+
+space = box.schema.create_space('test', { id = 106, engine = 'sophia' })
+space:create_index('primary')
+space:create_index('secondary')
+space:drop()
+sophia_printdir()
+
+-- index size
+
+space = box.schema.create_space('test', { id = 107, engine = 'sophia' })
+space:create_index('primary')
+primary = space.index[0]
+primary:len()
+space:insert({13})
+space:insert({14})
+space:insert({15})
+primary:len()
+space:drop()
+
+sophia_rmdir()
diff --git a/test/box/sophia.test.lua b/test/sophia/gh.result
similarity index 64%
rename from test/box/sophia.test.lua
rename to test/sophia/gh.result
index d91a685e0711acee86fef224471b92fb8374a0c1..7debe9511955e359d13fe24eb09354eca7aebd68 100644
--- a/test/box/sophia.test.lua
+++ b/test/sophia/gh.result
@@ -1,127 +1,183 @@
-os.execute("rm -rf sophia")
-
-space = box.schema.create_space('tweedledum', { id = 123, engine = 'sophia' })
-space:create_index('primary', { type = 'tree', parts = {1, 'num'} })
-
-for v=1, 10 do space:insert({v}) end
-
-t = space.index[0]:select({}, {iterator = box.index.ALL})
-t
-
-t = space.index[0]:select({}, {iterator = box.index.GE})
-t
-
-t = space.index[0]:select(4, {iterator = box.index.GE})
-t
-
-t = space.index[0]:select({}, {iterator = box.index.LE})
-t
-
-t = space.index[0]:select(7, {iterator = box.index.LE})
-t
-
-t = {}
-for v=1, 10 do table.insert(t, space:get({v})) end
-t
-
-space:drop()
-box.snapshot()
-
---
+sophia_rmdir()
+---
+...
 -- gh-283: Sophia: hang after three creates and drops
---
-
 s = box.schema.create_space('space0', {id = 33, engine='sophia'})
+---
+...
 i = s:create_index('space0', {type = 'tree', parts = {1, 'STR'}})
+---
+...
 s:insert{'a', 'b', 'c'}
+---
+- ['a', 'b', 'c']
+...
 s:drop()
-
+---
+...
 s = box.schema.create_space('space0', {id = 33, engine='sophia'})
+---
+...
 i = s:create_index('space0', {type = 'tree', parts = {1, 'STR'}})
+---
+...
 s:insert{'a', 'b', 'c'}
+---
+- ['a', 'b', 'c']
+...
 t = s.index[0]:select({}, {iterator = box.index.ALL})
+---
+...
 t
+---
+- - ['a', 'b', 'c']
+...
 s:drop()
-
+---
+...
 s = box.schema.create_space('space0', {id = 33, engine='sophia'})
+---
+...
 i = s:create_index('space0', {type = 'tree', parts = {1, 'STR'}})
+---
+...
 s:insert{'a', 'b', 'c'}
+---
+- ['a', 'b', 'c']
+...
 t = s.index[0]:select({}, {iterator = box.index.ALL})
+---
+...
 t
+---
+- - ['a', 'b', 'c']
+...
 s:drop()
-
---
+---
+...
 -- gh-280: Sophia: crash if insert without index
---
-
 s = box.schema.create_space('test', {engine='sophia'})
+---
+...
 s:insert{'a'}
-s:drop()
-
 ---
---- gh-431: Sophia: assertion if box.begin
+- error: 'No index #0 is defined in space ''test'''
+...
+s:drop()
 ---
-
-box.cfg{}
+...
+-- gh-431: Sophia: assertion if box.begin
 s = box.schema.create_space('tester',{engine='sophia'})
+---
+...
 s:create_index('sophia_index', {})
+---
+...
 s:insert{10000, 'Hilton'}
+---
+- [10000, 'Hilton']
+...
 box.begin()
+---
+...
 s:delete{10000} -- exception
+---
+- error: sophia does not support transactions
+...
 box.rollback()
-s:select{10000}
-s:drop()
-
 ---
---- gh-456: Sophia: index size() is unsupported
+...
+s:select{10000}
 ---
-
-box.cfg{}
-s = box.schema.create_space('tester',{engine='sophia'})
-s:create_index('sophia_index', {})
-s.index[0]:len() -- exception
-box.error()
+- - [10000, 'Hilton']
+...
 s:drop()
-
----
---- gh-436: No error when creating temporary sophia space
 ---
-
-box.cfg{}
+...
+-- gh-436: No error when creating temporary sophia space
 s = box.schema.create_space('tester',{engine='sophia', temporary=true})
-
 ---
---- gh-432: Sophia: ignored limit
----
-
+- error: 'Can''t modify space 512: space does not support temporary flag'
+...
+-- gh-432: Sophia: ignored limit
 s = box.schema.create_space('tester',{id = 89, engine='sophia'})
+---
+...
 s:create_index('sophia_index', {})
+---
+...
 for v=1, 100 do s:insert({v}) end
+---
+...
 t = s:select({''},{iterator='GT', limit =1})
+---
+- error: 'Supplied key type of part 0 does not match index part type: expected NUM'
+...
 t
+---
+- - ['a', 'b', 'c']
+...
 t = s:select({},{iterator='GT', limit =1})
+---
+...
 t
+---
+- - [1]
+...
 s:drop()
-
+---
+...
 s = box.schema.create_space('tester', {id = 90, engine='sophia'})
+---
+...
 s:create_index('sophia_index', {type = 'tree', parts = {1, 'STR'}})
+---
+...
 for v=1, 100 do s:insert({tostring(v)}) end
+---
+...
 t = s:select({''},{iterator='GT', limit =1})
+---
+...
 t
+---
+- - ['1']
+...
 t = s:select({},{iterator='GT', limit =1})
+---
+...
 t
-s:drop()
-
 ---
---- gh-282: Sophia: truncate() does nothing
+- - ['1']
+...
+s:drop()
 ---
-
+...
+-- gh-282: Sophia: truncate() does nothing
 s = box.schema.create_space('name_of_space', {id = 33, engine='sophia'})
+---
+...
 i = s:create_index('name_of_index', {type = 'tree', parts = {1, 'STR'}})
+---
+...
 s:insert{'a', 'b', 'c'}
+---
+- ['a', 'b', 'c']
+...
 box.space['name_of_space']:select{'a'}
+---
+- - ['a', 'b', 'c']
+...
 box.space['name_of_space']:truncate()
+---
+...
 box.space['name_of_space']:select{'a'}
+---
+- []
+...
 s:drop()
-
-os.execute("rm -rf sophia")
+---
+...
+sophia_rmdir()
+---
+...
diff --git a/test/sophia/gh.test.lua b/test/sophia/gh.test.lua
new file mode 100644
index 0000000000000000000000000000000000000000..790863b4d17aee01ae13a365d1f4ff4f0924de0f
--- /dev/null
+++ b/test/sophia/gh.test.lua
@@ -0,0 +1,76 @@
+
+sophia_rmdir()
+
+-- gh-283: Sophia: hang after three creates and drops
+
+s = box.schema.create_space('space0', {id = 33, engine='sophia'})
+i = s:create_index('space0', {type = 'tree', parts = {1, 'STR'}})
+s:insert{'a', 'b', 'c'}
+s:drop()
+
+s = box.schema.create_space('space0', {id = 33, engine='sophia'})
+i = s:create_index('space0', {type = 'tree', parts = {1, 'STR'}})
+s:insert{'a', 'b', 'c'}
+t = s.index[0]:select({}, {iterator = box.index.ALL})
+t
+s:drop()
+
+s = box.schema.create_space('space0', {id = 33, engine='sophia'})
+i = s:create_index('space0', {type = 'tree', parts = {1, 'STR'}})
+s:insert{'a', 'b', 'c'}
+t = s.index[0]:select({}, {iterator = box.index.ALL})
+t
+s:drop()
+
+-- gh-280: Sophia: crash if insert without index
+
+s = box.schema.create_space('test', {engine='sophia'})
+s:insert{'a'}
+s:drop()
+
+-- gh-431: Sophia: assertion if box.begin
+
+s = box.schema.create_space('tester',{engine='sophia'})
+s:create_index('sophia_index', {})
+s:insert{10000, 'Hilton'}
+box.begin()
+s:delete{10000} -- exception
+box.rollback()
+s:select{10000}
+s:drop()
+
+-- gh-436: No error when creating temporary sophia space
+
+s = box.schema.create_space('tester',{engine='sophia', temporary=true})
+
+-- gh-432: Sophia: ignored limit
+
+s = box.schema.create_space('tester',{id = 89, engine='sophia'})
+s:create_index('sophia_index', {})
+for v=1, 100 do s:insert({v}) end
+t = s:select({''},{iterator='GT', limit =1})
+t
+t = s:select({},{iterator='GT', limit =1})
+t
+s:drop()
+
+s = box.schema.create_space('tester', {id = 90, engine='sophia'})
+s:create_index('sophia_index', {type = 'tree', parts = {1, 'STR'}})
+for v=1, 100 do s:insert({tostring(v)}) end
+t = s:select({''},{iterator='GT', limit =1})
+t
+t = s:select({},{iterator='GT', limit =1})
+t
+s:drop()
+
+-- gh-282: Sophia: truncate() does nothing
+
+s = box.schema.create_space('name_of_space', {id = 33, engine='sophia'})
+i = s:create_index('name_of_index', {type = 'tree', parts = {1, 'STR'}})
+s:insert{'a', 'b', 'c'}
+box.space['name_of_space']:select{'a'}
+box.space['name_of_space']:truncate()
+box.space['name_of_space']:select{'a'}
+s:drop()
+
+sophia_rmdir()
diff --git a/test/sophia/index_random_test.lua b/test/sophia/index_random_test.lua
new file mode 100644
index 0000000000000000000000000000000000000000..00838e83e1d78527af6fbb6041899831fdcc368b
--- /dev/null
+++ b/test/sophia/index_random_test.lua
@@ -0,0 +1,33 @@
+
+function index_random_test(space, index_no)
+	local COUNT = 1028
+	-- clear the space
+	space:truncate()
+	-- randomize
+	math.randomseed(os.time())
+	-- insert values into the index
+	for k=1,COUNT,1 do space:insert{k}  end
+	local rnd_start = math.random(4294967296)
+	-- try to get all values from the index using index.random
+	local tuples = {}
+	local found = 0
+	while found < COUNT do
+		local rnd = math.random(4294967296)
+		if rnd == rnd_start then
+			error('too many iterations')
+			return nil
+		end
+		local tuple = space.index[index_no]:random(rnd)
+		if tuple == nil then
+			error('nil returned')
+			return nil
+		end
+		local k = tuple[1]
+		if tuples[k] == nil then
+			found = found + 1
+		end
+		tuples[k] = 1
+	end
+
+	return true
+end
diff --git a/test/sophia/recover.result b/test/sophia/recover.result
new file mode 100644
index 0000000000000000000000000000000000000000..4903baa4388743108b9dc90789309e54c050a27b
--- /dev/null
+++ b/test/sophia/recover.result
@@ -0,0 +1,30 @@
+sophia_rmdir()
+---
+...
+-- snapshot
+space = box.schema.create_space('test', { id = 100, engine = 'sophia' })
+---
+...
+space:create_index('primary')
+---
+...
+sophia_printdir()
+---
+- '100
+
+'
+...
+box.snapshot()
+---
+- ok
+...
+space:drop()
+---
+...
+box.snapshot()
+---
+- ok
+...
+sophia_rmdir()
+---
+...
diff --git a/test/sophia/recover.test.lua b/test/sophia/recover.test.lua
new file mode 100644
index 0000000000000000000000000000000000000000..ffea2d43ca920888f7cbd065477306ab3d28ab6e
--- /dev/null
+++ b/test/sophia/recover.test.lua
@@ -0,0 +1,13 @@
+
+sophia_rmdir()
+
+-- snapshot
+
+space = box.schema.create_space('test', { id = 100, engine = 'sophia' })
+space:create_index('primary')
+sophia_printdir()
+box.snapshot()
+space:drop()
+box.snapshot()
+
+sophia_rmdir()
diff --git a/test/sophia/suite.ini b/test/sophia/suite.ini
new file mode 100644
index 0000000000000000000000000000000000000000..ddf62d5dadc3cadb5233e84cb7d7eed7348221ba
--- /dev/null
+++ b/test/sophia/suite.ini
@@ -0,0 +1,9 @@
+[default]
+core = tarantool
+description = sophia integration tests
+script = box.lua
+disabled =
+valgrind_disabled =
+release_disabled =
+lua_libs = index_random_test.lua
+use_unix_sockets = True
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index dc1ae0a7765590755fa51deae03b855f99289f04..32306d8db765db812ed0f6190d3d4700bd21a375 100644
--- a/test/unit/CMakeLists.txt
+++ b/test/unit/CMakeLists.txt
@@ -7,7 +7,7 @@ include_directories(${PROJECT_BINARY_DIR}/src)
 include_directories(${PROJECT_SOURCE_DIR}/src/lib)
 include_directories(${CMAKE_SOURCE_DIR}/third_party)
 add_executable(rlist.test rlist.c test.c ${CMAKE_SOURCE_DIR}/src/lib/salad/rlist.c)
-add_executable(uri.test uri.cc test.c ${CMAKE_SOURCE_DIR}/src/uri.cc)
+add_executable(uri.test uri.c test.c ${CMAKE_SOURCE_DIR}/src/uri.c)
 add_executable(fiob.test test.c fiob.c ${CMAKE_SOURCE_DIR}/src/fiob.c)
 add_executable(queue.test queue.c)
 add_executable(mhash.test mhash.c)
diff --git a/test/unit/fiob.skipcond b/test/unit/fiob.skipcond
new file mode 100644
index 0000000000000000000000000000000000000000..d246d3b7c4bf083f7654bd631877fc1579adaedf
--- /dev/null
+++ b/test/unit/fiob.skipcond
@@ -0,0 +1,17 @@
+# vim: set ft=python :
+import re
+import os
+import os.path
+import tempfile
+
+dir = tempfile.mkdtemp()
+file = os.path.join(dir, 'test-o-direct')
+
+try:
+    fh = os.open(file, os.O_CREAT | os.O_DIRECT | os.O_TRUNC | os.O_RDWR)
+    os.unlink(file)
+    os.rmdir(dir)
+except:
+    self.skip = 1
+
+
diff --git a/test/unit/uri.c b/test/unit/uri.c
new file mode 100644
index 0000000000000000000000000000000000000000..b978a12233d7fb5dd181878f468160aec878dd49
--- /dev/null
+++ b/test/unit/uri.c
@@ -0,0 +1,222 @@
+#include "test.h"
+#include <uri.h>
+#include <string.h>
+
+int
+test(const char *s, const char *scheme, const char *login, const char *password,
+     const char *host, const char *service, const char *path,
+     const char *query, const char *fragment, int host_hint)
+{
+	plan(10);
+
+	struct uri uri;
+	is(uri_parse(&uri, s), 0, "%s: parse", s);
+	/* fprintf(stdout, #key ": %p %d %.*s\n", uri.key,
+	   (int) uri.key ## _len, (int) uri.key ## _len, uri.key); */
+
+#define chk(key) do { \
+	ok((key && uri.key && strlen(key) == uri.key ## _len && \
+	   memcmp(key, uri.key, uri.key ## _len) == 0) || \
+	   (!key && !uri.key), "%s: " #key, s); } while (0);
+
+	chk(scheme);
+	chk(login);
+	chk(password);
+	chk(host);
+	chk(service);
+	chk(path);
+	chk(query);
+	chk(fragment);
+	is(uri.host_hint, host_hint, "%s: host_hint", s);
+
+#undef chk
+	return check_plan();
+}
+
+int
+test_invalid()
+{
+	plan(2);
+
+	/* Invalid */
+	struct uri u;
+	isnt(uri_parse(&u, ""), 0 , "empty is invalid");
+	isnt(uri_parse(&u, "://"), 0 , ":// is invalid");
+
+	return check_plan();
+}
+
+int
+main(void)
+{
+	plan(60);
+
+	/* General */
+	test("host", NULL, NULL, NULL, "host", NULL, NULL, NULL, NULL, 0);
+	test("host/", NULL, NULL, NULL, "host", NULL, "/", NULL, NULL, 0);
+	test("host/path1/path2/path3", NULL, NULL, NULL, "host", NULL,
+	     "/path1/path2/path3", NULL, NULL, 0);
+	test("host/path1/path2/path3?q1=v1&q2=v2#fragment", NULL, NULL,
+	     NULL, "host", NULL, "/path1/path2/path3",
+	     "q1=v1&q2=v2", "fragment", 0);
+
+	test("host:service", NULL, NULL, NULL, "host", "service", NULL, NULL,
+	     NULL, 0);
+
+	test("host:service/", NULL, NULL, NULL, "host", "service", "/", NULL,
+	     NULL, 0);
+
+	test("host:service/path1/path2/path3", NULL, NULL, NULL, "host",
+	     "service", "/path1/path2/path3", NULL, NULL, 0);
+	test("host:service/path1/path2/path3?q1=v1&q2=v2#fragment", NULL, NULL,
+	     NULL, "host", "service", "/path1/path2/path3",
+	     "q1=v1&q2=v2", "fragment", 0);
+
+	test("login@host", NULL, "login", NULL, "host", NULL, NULL, NULL,
+	     NULL, 0);
+	test("login@host/", NULL, "login", NULL, "host", NULL, "/", NULL,
+	     NULL, 0);
+	test("login@host/path1/path2/path3", NULL, "login", NULL, "host", NULL,
+	     "/path1/path2/path3", NULL, NULL, 0);
+	test("login@host/path1/path2/path3?q1=v1&q2=v2#fragment", NULL, "login",
+	     NULL, "host", NULL, "/path1/path2/path3",
+	     "q1=v1&q2=v2", "fragment", 0);
+
+	test("login:password@host", NULL, "login", "password", "host", NULL,
+	     NULL, NULL, NULL, 0);
+	test("login:password@host/", NULL, "login", "password", "host", NULL,
+	     "/", NULL, NULL, 0);
+	test("login:password@host/path1/path2/path3", NULL, "login", "password",
+	     "host", NULL, "/path1/path2/path3", NULL, NULL, 0);
+	test("login:password@host/path1/path2/path3?q1=v1&q2=v2#fragment",
+	     NULL, "login", "password", "host", NULL, "/path1/path2/path3",
+	     "q1=v1&q2=v2", "fragment", 0);
+
+	test("login:password@host:service", NULL, "login", "password", "host",
+	     "service", NULL, NULL, NULL, 0);
+	test("login:password@host:service/", NULL, "login", "password", "host",
+	     "service", "/", NULL, NULL, 0);
+	test("login:password@host:service/path1/path2/path3", NULL, "login",
+	     "password", "host", "service", "/path1/path2/path3", NULL,
+	     NULL, 0);
+	test("login:password@host:service/path1/path2/path3?q1=v1&q2=v2"
+	     "#fragment", NULL, "login", "password", "host", "service",
+	     "/path1/path2/path3", "q1=v1&q2=v2", "fragment", 0);
+
+	test("scheme://login:password@host:service", "scheme", "login",
+	     "password", "host", "service", NULL, NULL, NULL, 0);
+	test("scheme://login:password@host:service/", "scheme", "login",
+	     "password", "host", "service", "/", NULL, NULL, 0);
+	test("scheme://login:password@host:service/path1/path2/path3", "scheme",
+	     "login", "password", "host", "service", "/path1/path2/path3",
+	     NULL, NULL, 0);
+	test("scheme://login:password@host:service/path1/path2/path3?"
+	     "q1=v1&q2=v2#fragment", "scheme", "login", "password", "host",
+	     "service", "/path1/path2/path3", "q1=v1&q2=v2", "fragment", 0);
+
+	test("host/path", NULL, NULL, NULL, "host", NULL, "/path", NULL,
+	     NULL, 0);
+	test("host//", NULL, NULL, NULL, "host", NULL, "//", NULL, NULL, 0);
+	test("host//path", NULL, NULL, NULL, "host", NULL, "//path", NULL,
+	     NULL, 0);
+	test("host/;abc?q", NULL, NULL, NULL, "host", NULL, "/;abc", "q",
+	     NULL, 0);
+
+	test("scheme://login:password@host:service/@path1/:path2?"
+	     "q1=v1&q2=v2#fragment", "scheme", "login", "password", "host",
+	     "service", "/@path1/:path2", "q1=v1&q2=v2", "fragment", 0);
+	test("host/~user", NULL, NULL, NULL, "host", NULL, "/~user", NULL,
+	     NULL, 0);
+
+	/* Host */
+	test("try.tarantool.org", NULL, NULL, NULL, "try.tarantool.org", NULL,
+	     NULL, NULL, NULL, 0);
+
+	test("try.tarantool.org", NULL, NULL, NULL, "try.tarantool.org", NULL,
+	     NULL, NULL, NULL, 0);
+
+	test("www.llanfairpwllgwyngyllgogerychwyrndrobwyll-"
+	     "llantysiliogogogoch.com", NULL, NULL, NULL,
+	     "www.llanfairpwllgwyngyllgogerychwyrndrobwyll-"
+	     "llantysiliogogogoch.com", NULL, NULL, NULL, NULL, 0);
+
+	/* IPv4 / IPv6 addreses */
+	test("0.0.0.0", NULL, NULL, NULL, "0.0.0.0", NULL, NULL, NULL, NULL, 1);
+	test("127.0.0.1", NULL, NULL, NULL, "127.0.0.1", NULL, NULL, NULL,
+	     NULL, 1);
+	test("127.0.0.1:3313", NULL, NULL, NULL, "127.0.0.1", "3313", NULL,
+	     NULL, NULL, 1);
+
+	test("scheme://login:password@127.0.0.1:3313", "scheme", "login",
+	     "password", "127.0.0.1", "3313", NULL, NULL, NULL, 1);
+
+	test("[2001::11a3:09d7::1]", NULL, NULL, NULL, "2001::11a3:09d7::1",
+	     NULL, NULL, NULL, NULL, 2);
+	test("scheme://login:password@[2001::11a3:09d7::1]:3313", "scheme",
+	     "login", "password", "2001::11a3:09d7::1", "3313", NULL, NULL,
+	     NULL, 2);
+	test("scheme://[2001:0db8:11a3:09d7::1]", "scheme", NULL, NULL,
+	     "2001:0db8:11a3:09d7::1", NULL, NULL, NULL, NULL, 2);
+
+	test("[::ffff:11.2.3.4]", NULL, NULL, NULL, "::ffff:11.2.3.4",
+	     NULL, NULL, NULL, NULL, 2);
+	test("scheme://login:password@[::ffff:11.2.3.4]:3313", "scheme",
+	     "login", "password", "::ffff:11.2.3.4", "3313", NULL, NULL,
+	     NULL, 2);
+
+	/* Port */
+	test("1", NULL, NULL, NULL, NULL, "1", NULL, NULL, NULL, 0);
+	test("10", NULL, NULL, NULL, NULL, "10", NULL, NULL, NULL, 0);
+	test("331", NULL, NULL, NULL, NULL, "331", NULL, NULL, NULL,0);
+	test("3313", NULL, NULL, NULL, NULL, "3313", NULL, NULL, NULL, 0);
+
+	/* Unix */
+	test("/", NULL, NULL, NULL, "unix/", "/", NULL, NULL, NULL, 3);
+	test("/path1/path2/path3", NULL, NULL, NULL, "unix/",
+	     "/path1/path2/path3", NULL, NULL, NULL, 3);
+	test("login:password@/path1/path2/path3", NULL, "login", "password",
+	     "unix/", "/path1/path2/path3", NULL, NULL, NULL, 3);
+	test("unix/:/path1/path2/path3", NULL, NULL, NULL, "unix/",
+	     "/path1/path2/path3", NULL, NULL, NULL, 3);
+	test("unix/:/path1/path2/path3:", NULL, NULL, NULL, "unix/",
+	     "/path1/path2/path3", NULL, NULL, NULL, 3);
+	test("unix/:/path1/path2/path3:/", NULL, NULL, NULL, "unix/",
+	     "/path1/path2/path3", "/", NULL, NULL, 3);
+	test("unix/:/path1/path2/path3?q1=v1&q2=v2#fragment", NULL, NULL, NULL,
+	     "unix/", "/path1/path2/path3", NULL, "q1=v1&q2=v2", "fragment", 3);
+	test("unix/:/path1/path2/path3:/p1/p2?q1=v1&q2=v2#fragment",
+	     NULL, NULL, NULL, "unix/", "/path1/path2/path3", "/p1/p2",
+	     "q1=v1&q2=v2", "fragment", 3);
+#if 0
+	/* Broken due to grammar limitations. */
+	test("login:password@unix/:/path1/path2/path3", NULL, "login",
+	     "password", "unix/", "/path1/path2/path3", NULL, NULL, NULL, 3);
+#endif
+	test("scheme://login:password@unix/:/tmp/unix.sock:/path1/path2/path3",
+	     "scheme", "login", "password", "unix/", "/tmp/unix.sock",
+	     "/path1/path2/path3", NULL, NULL, 3);
+	test("unix/:./relative/path.sock:/test", NULL, NULL, NULL, "unix/",
+	     "./relative/path.sock", "/test", NULL, NULL, 3);
+	test("scheme://unix/:./relative/path.sock:/test", "scheme", NULL, NULL,
+	     "unix/", "./relative/path.sock", "/test", NULL, NULL, 3);
+
+	/* Web */
+	test("http://tarantool.org/dist/master/debian/pool/main/t/tarantool/"
+	     "tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz",
+	     "http", NULL, NULL, "tarantool.org", NULL,
+	     "/dist/master/debian/pool/main/t/tarantool/"
+	     "tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz",
+	     NULL, NULL, 0);
+
+	test("https://www.google.com/search?"
+	     "safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool"
+	     "&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl",
+	     "https", NULL, NULL, "www.google.com", NULL, "/search",
+	     "safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool"
+	     "&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl",
+	     NULL, 0);
+
+	test_invalid();
+
+	return check_plan();
+}
diff --git a/test/unit/uri.cc b/test/unit/uri.cc
deleted file mode 100644
index d07b410c777e072263b40eb6a0765ebb405a6f69..0000000000000000000000000000000000000000
--- a/test/unit/uri.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-#include "test.h"
-#include <uri.h>
-#include <string.h>
-
-#define PLAN	40
-
-int
-main(void)
-{
-	plan(PLAN);
-
-	struct uri uri;
-
-	is(uri_parse(&uri, "/file"), 0, "/file");
-	is(strcmp(uri_to_string(&uri), "unix:///file"), 0,
-				"to_string");
-	is(strcmp(uri.schema, "unix"), 0, "unix://");
-
-
-	is(uri_parse(&uri, "unix://file"), 0, "unix://file");
-	is(strcmp(uri_to_string(&uri), "unix://file"), 0,
-							"to_string");
-	is(strcmp(uri.schema, "unix"), 0, "unix://");
-
-
-	is(uri_parse(&uri, "123"), 0, "123");
-	is(strcmp(uri.schema, "tcp"), 0, "tcp://");
-	is(strcmp(uri_to_string(&uri), "0.0.0.0:123"), 0,
-		"to_string");
-
-
-
-	is(uri_parse(&uri, "http://11.2.3.4:123"), 0,
-		"http://11.2.3.4:123");
-	is(strcmp(uri.schema, "http"), 0, "http://");
-	is(strcmp(uri_to_string(&uri), "http://11.2.3.4:123"), 0,
-		"to_string");
-
-	is(uri_parse(&uri, "http://[::fFff:11.2.3.4]:123"), 0,
-		"http://11.2.3.4:123");
-	is(strcmp(uri.schema, "http"), 0, "http://");
-	is(strcmp(uri_to_string(&uri), "http://11.2.3.4:123"), 0,
-		"to_string");
-	is(uri_parse(&uri, "http://user:pass@127.0.0.1:12345"), 0,
-		"http://user:pass@127.0.0.1:12345");
-	is(strcmp(uri.login, "user"), 0, "user");
-	is(strcmp(uri.password, "pass"), 0, "pass");
-	is(strcmp(uri.schema, "http"), 0, "http");
-
-
-	is(uri_parse(&uri, "schema://[2001:0db8:11a3:09d7::1]"),
-	   0, "schema://[2001:0db8:11a3:09d7::1]");
-	is(strcmp(uri_to_string(&uri),
-		"schema://[2001:db8:11a3:9d7::1]:0"), 0, "to_string");
-
-
-	isnt(uri_parse(&uri, "schema://[2001::11a3:09d7::1]"),
-	     0, "invalid schema://[2001::11a3:09d7::1]");
-
-
-
-
-	is(uri_parse(&uri, "128.0.0.1"), 0, "127.0.0.1");
-	is(strcmp(uri_to_string(&uri), "128.0.0.1:0"), 0,
-		"to_string");
-
-	is(uri_parse(&uri, "128.0.0.1:22"), 0, "127.0.0.1:22");
-	is(strcmp(uri_to_string(&uri), "128.0.0.1:22"), 0,
-		"to_string");
-
-	is(uri_parse(&uri, "login:password@127.0.0.1"), 0,
-	   "login:password@127.0.0.1");
-	is(strcmp(uri.login, "login"), 0, "login");
-	is(strcmp(uri.password, "password"), 0, "password");
-	is(strcmp(uri.schema, "tcp"), 0, "default schema");
-
-	is(uri_parse(&uri, "unix://login:password@/path/to"), 0,
-	   "unix://login:password@/path/to");
-	is(strcmp(uri.login, "login"), 0, "login");
-	is(strcmp(uri.password, "password"), 0, "password");
-	is(strcmp(uri.schema, "unix"), 0, "unix");
-	is(strcmp(uri_to_string(&uri), "unix:///path/to"), 0,
-		"to_string");
-
-	isnt(uri_parse(&uri, "tcp://abc.cde:90"), 0, "invalid uri");
-
-	is(uri_parse(&uri, "http://127.0.0.1:http"), 0,
-	   "valid uri");
-	is(strcmp(uri_to_string(&uri), "http://127.0.0.1:80"), 0,
-	   "service to port number");
-
-	is(uri_parse(&uri, "mail.ru:https"), 0, "valid uri");
-
-	isnt(strstr(uri_to_string(&uri), ":443"), 0,
-		"service converted");
-
-	return check_plan();
-}
diff --git a/test/unit/uri.result b/test/unit/uri.result
index 751cc2083c973c2a58075ea17d8b6c07a5a55dff..7218a95036131d2b4315ffccf3b86a3b749689ed 100644
--- a/test/unit/uri.result
+++ b/test/unit/uri.result
@@ -1,41 +1,713 @@
-1..40
-ok 1 - /file
-ok 2 - to_string
-ok 3 - unix://
-ok 4 - unix://file
-ok 5 - to_string
-ok 6 - unix://
-ok 7 - 123
-ok 8 - tcp://
-ok 9 - to_string
-ok 10 - http://11.2.3.4:123
-ok 11 - http://
-ok 12 - to_string
-ok 13 - http://11.2.3.4:123
-ok 14 - http://
-ok 15 - to_string
-ok 16 - http://user:pass@127.0.0.1:12345
-ok 17 - user
-ok 18 - pass
-ok 19 - http
-ok 20 - schema://[2001:0db8:11a3:09d7::1]
-ok 21 - to_string
-ok 22 - invalid schema://[2001::11a3:09d7::1]
-ok 23 - 127.0.0.1
-ok 24 - to_string
-ok 25 - 127.0.0.1:22
-ok 26 - to_string
-ok 27 - login:password@127.0.0.1
-ok 28 - login
-ok 29 - password
-ok 30 - default schema
-ok 31 - unix://login:password@/path/to
-ok 32 - login
-ok 33 - password
-ok 34 - unix
-ok 35 - to_string
-ok 36 - invalid uri
-ok 37 - valid uri
-ok 38 - service to port number
-ok 39 - valid uri
-ok 40 - service converted
+1..60
+    1..10
+    ok 1 - host: parse
+    ok 2 - host: scheme
+    ok 3 - host: login
+    ok 4 - host: password
+    ok 5 - host: host
+    ok 6 - host: service
+    ok 7 - host: path
+    ok 8 - host: query
+    ok 9 - host: fragment
+    ok 10 - host: host_hint
+ok 1 - subtests
+    1..10
+    ok 1 - host/: parse
+    ok 2 - host/: scheme
+    ok 3 - host/: login
+    ok 4 - host/: password
+    ok 5 - host/: host
+    ok 6 - host/: service
+    ok 7 - host/: path
+    ok 8 - host/: query
+    ok 9 - host/: fragment
+    ok 10 - host/: host_hint
+ok 2 - subtests
+    1..10
+    ok 1 - host/path1/path2/path3: parse
+    ok 2 - host/path1/path2/path3: scheme
+    ok 3 - host/path1/path2/path3: login
+    ok 4 - host/path1/path2/path3: password
+    ok 5 - host/path1/path2/path3: host
+    ok 6 - host/path1/path2/path3: service
+    ok 7 - host/path1/path2/path3: path
+    ok 8 - host/path1/path2/path3: query
+    ok 9 - host/path1/path2/path3: fragment
+    ok 10 - host/path1/path2/path3: host_hint
+ok 3 - subtests
+    1..10
+    ok 1 - host/path1/path2/path3?q1=v1&q2=v2#fragment: parse
+    ok 2 - host/path1/path2/path3?q1=v1&q2=v2#fragment: scheme
+    ok 3 - host/path1/path2/path3?q1=v1&q2=v2#fragment: login
+    ok 4 - host/path1/path2/path3?q1=v1&q2=v2#fragment: password
+    ok 5 - host/path1/path2/path3?q1=v1&q2=v2#fragment: host
+    ok 6 - host/path1/path2/path3?q1=v1&q2=v2#fragment: service
+    ok 7 - host/path1/path2/path3?q1=v1&q2=v2#fragment: path
+    ok 8 - host/path1/path2/path3?q1=v1&q2=v2#fragment: query
+    ok 9 - host/path1/path2/path3?q1=v1&q2=v2#fragment: fragment
+    ok 10 - host/path1/path2/path3?q1=v1&q2=v2#fragment: host_hint
+ok 4 - subtests
+    1..10
+    ok 1 - host:service: parse
+    ok 2 - host:service: scheme
+    ok 3 - host:service: login
+    ok 4 - host:service: password
+    ok 5 - host:service: host
+    ok 6 - host:service: service
+    ok 7 - host:service: path
+    ok 8 - host:service: query
+    ok 9 - host:service: fragment
+    ok 10 - host:service: host_hint
+ok 5 - subtests
+    1..10
+    ok 1 - host:service/: parse
+    ok 2 - host:service/: scheme
+    ok 3 - host:service/: login
+    ok 4 - host:service/: password
+    ok 5 - host:service/: host
+    ok 6 - host:service/: service
+    ok 7 - host:service/: path
+    ok 8 - host:service/: query
+    ok 9 - host:service/: fragment
+    ok 10 - host:service/: host_hint
+ok 6 - subtests
+    1..10
+    ok 1 - host:service/path1/path2/path3: parse
+    ok 2 - host:service/path1/path2/path3: scheme
+    ok 3 - host:service/path1/path2/path3: login
+    ok 4 - host:service/path1/path2/path3: password
+    ok 5 - host:service/path1/path2/path3: host
+    ok 6 - host:service/path1/path2/path3: service
+    ok 7 - host:service/path1/path2/path3: path
+    ok 8 - host:service/path1/path2/path3: query
+    ok 9 - host:service/path1/path2/path3: fragment
+    ok 10 - host:service/path1/path2/path3: host_hint
+ok 7 - subtests
+    1..10
+    ok 1 - host:service/path1/path2/path3?q1=v1&q2=v2#fragment: parse
+    ok 2 - host:service/path1/path2/path3?q1=v1&q2=v2#fragment: scheme
+    ok 3 - host:service/path1/path2/path3?q1=v1&q2=v2#fragment: login
+    ok 4 - host:service/path1/path2/path3?q1=v1&q2=v2#fragment: password
+    ok 5 - host:service/path1/path2/path3?q1=v1&q2=v2#fragment: host
+    ok 6 - host:service/path1/path2/path3?q1=v1&q2=v2#fragment: service
+    ok 7 - host:service/path1/path2/path3?q1=v1&q2=v2#fragment: path
+    ok 8 - host:service/path1/path2/path3?q1=v1&q2=v2#fragment: query
+    ok 9 - host:service/path1/path2/path3?q1=v1&q2=v2#fragment: fragment
+    ok 10 - host:service/path1/path2/path3?q1=v1&q2=v2#fragment: host_hint
+ok 8 - subtests
+    1..10
+    ok 1 - login@host: parse
+    ok 2 - login@host: scheme
+    ok 3 - login@host: login
+    ok 4 - login@host: password
+    ok 5 - login@host: host
+    ok 6 - login@host: service
+    ok 7 - login@host: path
+    ok 8 - login@host: query
+    ok 9 - login@host: fragment
+    ok 10 - login@host: host_hint
+ok 9 - subtests
+    1..10
+    ok 1 - login@host/: parse
+    ok 2 - login@host/: scheme
+    ok 3 - login@host/: login
+    ok 4 - login@host/: password
+    ok 5 - login@host/: host
+    ok 6 - login@host/: service
+    ok 7 - login@host/: path
+    ok 8 - login@host/: query
+    ok 9 - login@host/: fragment
+    ok 10 - login@host/: host_hint
+ok 10 - subtests
+    1..10
+    ok 1 - login@host/path1/path2/path3: parse
+    ok 2 - login@host/path1/path2/path3: scheme
+    ok 3 - login@host/path1/path2/path3: login
+    ok 4 - login@host/path1/path2/path3: password
+    ok 5 - login@host/path1/path2/path3: host
+    ok 6 - login@host/path1/path2/path3: service
+    ok 7 - login@host/path1/path2/path3: path
+    ok 8 - login@host/path1/path2/path3: query
+    ok 9 - login@host/path1/path2/path3: fragment
+    ok 10 - login@host/path1/path2/path3: host_hint
+ok 11 - subtests
+    1..10
+    ok 1 - login@host/path1/path2/path3?q1=v1&q2=v2#fragment: parse
+    ok 2 - login@host/path1/path2/path3?q1=v1&q2=v2#fragment: scheme
+    ok 3 - login@host/path1/path2/path3?q1=v1&q2=v2#fragment: login
+    ok 4 - login@host/path1/path2/path3?q1=v1&q2=v2#fragment: password
+    ok 5 - login@host/path1/path2/path3?q1=v1&q2=v2#fragment: host
+    ok 6 - login@host/path1/path2/path3?q1=v1&q2=v2#fragment: service
+    ok 7 - login@host/path1/path2/path3?q1=v1&q2=v2#fragment: path
+    ok 8 - login@host/path1/path2/path3?q1=v1&q2=v2#fragment: query
+    ok 9 - login@host/path1/path2/path3?q1=v1&q2=v2#fragment: fragment
+    ok 10 - login@host/path1/path2/path3?q1=v1&q2=v2#fragment: host_hint
+ok 12 - subtests
+    1..10
+    ok 1 - login:password@host: parse
+    ok 2 - login:password@host: scheme
+    ok 3 - login:password@host: login
+    ok 4 - login:password@host: password
+    ok 5 - login:password@host: host
+    ok 6 - login:password@host: service
+    ok 7 - login:password@host: path
+    ok 8 - login:password@host: query
+    ok 9 - login:password@host: fragment
+    ok 10 - login:password@host: host_hint
+ok 13 - subtests
+    1..10
+    ok 1 - login:password@host/: parse
+    ok 2 - login:password@host/: scheme
+    ok 3 - login:password@host/: login
+    ok 4 - login:password@host/: password
+    ok 5 - login:password@host/: host
+    ok 6 - login:password@host/: service
+    ok 7 - login:password@host/: path
+    ok 8 - login:password@host/: query
+    ok 9 - login:password@host/: fragment
+    ok 10 - login:password@host/: host_hint
+ok 14 - subtests
+    1..10
+    ok 1 - login:password@host/path1/path2/path3: parse
+    ok 2 - login:password@host/path1/path2/path3: scheme
+    ok 3 - login:password@host/path1/path2/path3: login
+    ok 4 - login:password@host/path1/path2/path3: password
+    ok 5 - login:password@host/path1/path2/path3: host
+    ok 6 - login:password@host/path1/path2/path3: service
+    ok 7 - login:password@host/path1/path2/path3: path
+    ok 8 - login:password@host/path1/path2/path3: query
+    ok 9 - login:password@host/path1/path2/path3: fragment
+    ok 10 - login:password@host/path1/path2/path3: host_hint
+ok 15 - subtests
+    1..10
+    ok 1 - login:password@host/path1/path2/path3?q1=v1&q2=v2#fragment: parse
+    ok 2 - login:password@host/path1/path2/path3?q1=v1&q2=v2#fragment: scheme
+    ok 3 - login:password@host/path1/path2/path3?q1=v1&q2=v2#fragment: login
+    ok 4 - login:password@host/path1/path2/path3?q1=v1&q2=v2#fragment: password
+    ok 5 - login:password@host/path1/path2/path3?q1=v1&q2=v2#fragment: host
+    ok 6 - login:password@host/path1/path2/path3?q1=v1&q2=v2#fragment: service
+    ok 7 - login:password@host/path1/path2/path3?q1=v1&q2=v2#fragment: path
+    ok 8 - login:password@host/path1/path2/path3?q1=v1&q2=v2#fragment: query
+    ok 9 - login:password@host/path1/path2/path3?q1=v1&q2=v2#fragment: fragment
+    ok 10 - login:password@host/path1/path2/path3?q1=v1&q2=v2#fragment: host_hint
+ok 16 - subtests
+    1..10
+    ok 1 - login:password@host:service: parse
+    ok 2 - login:password@host:service: scheme
+    ok 3 - login:password@host:service: login
+    ok 4 - login:password@host:service: password
+    ok 5 - login:password@host:service: host
+    ok 6 - login:password@host:service: service
+    ok 7 - login:password@host:service: path
+    ok 8 - login:password@host:service: query
+    ok 9 - login:password@host:service: fragment
+    ok 10 - login:password@host:service: host_hint
+ok 17 - subtests
+    1..10
+    ok 1 - login:password@host:service/: parse
+    ok 2 - login:password@host:service/: scheme
+    ok 3 - login:password@host:service/: login
+    ok 4 - login:password@host:service/: password
+    ok 5 - login:password@host:service/: host
+    ok 6 - login:password@host:service/: service
+    ok 7 - login:password@host:service/: path
+    ok 8 - login:password@host:service/: query
+    ok 9 - login:password@host:service/: fragment
+    ok 10 - login:password@host:service/: host_hint
+ok 18 - subtests
+    1..10
+    ok 1 - login:password@host:service/path1/path2/path3: parse
+    ok 2 - login:password@host:service/path1/path2/path3: scheme
+    ok 3 - login:password@host:service/path1/path2/path3: login
+    ok 4 - login:password@host:service/path1/path2/path3: password
+    ok 5 - login:password@host:service/path1/path2/path3: host
+    ok 6 - login:password@host:service/path1/path2/path3: service
+    ok 7 - login:password@host:service/path1/path2/path3: path
+    ok 8 - login:password@host:service/path1/path2/path3: query
+    ok 9 - login:password@host:service/path1/path2/path3: fragment
+    ok 10 - login:password@host:service/path1/path2/path3: host_hint
+ok 19 - subtests
+    1..10
+    ok 1 - login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: parse
+    ok 2 - login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: scheme
+    ok 3 - login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: login
+    ok 4 - login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: password
+    ok 5 - login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: host
+    ok 6 - login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: service
+    ok 7 - login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: path
+    ok 8 - login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: query
+    ok 9 - login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: fragment
+    ok 10 - login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: host_hint
+ok 20 - subtests
+    1..10
+    ok 1 - scheme://login:password@host:service: parse
+    ok 2 - scheme://login:password@host:service: scheme
+    ok 3 - scheme://login:password@host:service: login
+    ok 4 - scheme://login:password@host:service: password
+    ok 5 - scheme://login:password@host:service: host
+    ok 6 - scheme://login:password@host:service: service
+    ok 7 - scheme://login:password@host:service: path
+    ok 8 - scheme://login:password@host:service: query
+    ok 9 - scheme://login:password@host:service: fragment
+    ok 10 - scheme://login:password@host:service: host_hint
+ok 21 - subtests
+    1..10
+    ok 1 - scheme://login:password@host:service/: parse
+    ok 2 - scheme://login:password@host:service/: scheme
+    ok 3 - scheme://login:password@host:service/: login
+    ok 4 - scheme://login:password@host:service/: password
+    ok 5 - scheme://login:password@host:service/: host
+    ok 6 - scheme://login:password@host:service/: service
+    ok 7 - scheme://login:password@host:service/: path
+    ok 8 - scheme://login:password@host:service/: query
+    ok 9 - scheme://login:password@host:service/: fragment
+    ok 10 - scheme://login:password@host:service/: host_hint
+ok 22 - subtests
+    1..10
+    ok 1 - scheme://login:password@host:service/path1/path2/path3: parse
+    ok 2 - scheme://login:password@host:service/path1/path2/path3: scheme
+    ok 3 - scheme://login:password@host:service/path1/path2/path3: login
+    ok 4 - scheme://login:password@host:service/path1/path2/path3: password
+    ok 5 - scheme://login:password@host:service/path1/path2/path3: host
+    ok 6 - scheme://login:password@host:service/path1/path2/path3: service
+    ok 7 - scheme://login:password@host:service/path1/path2/path3: path
+    ok 8 - scheme://login:password@host:service/path1/path2/path3: query
+    ok 9 - scheme://login:password@host:service/path1/path2/path3: fragment
+    ok 10 - scheme://login:password@host:service/path1/path2/path3: host_hint
+ok 23 - subtests
+    1..10
+    ok 1 - scheme://login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: parse
+    ok 2 - scheme://login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: scheme
+    ok 3 - scheme://login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: login
+    ok 4 - scheme://login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: password
+    ok 5 - scheme://login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: host
+    ok 6 - scheme://login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: service
+    ok 7 - scheme://login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: path
+    ok 8 - scheme://login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: query
+    ok 9 - scheme://login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: fragment
+    ok 10 - scheme://login:password@host:service/path1/path2/path3?q1=v1&q2=v2#fragment: host_hint
+ok 24 - subtests
+    1..10
+    ok 1 - host/path: parse
+    ok 2 - host/path: scheme
+    ok 3 - host/path: login
+    ok 4 - host/path: password
+    ok 5 - host/path: host
+    ok 6 - host/path: service
+    ok 7 - host/path: path
+    ok 8 - host/path: query
+    ok 9 - host/path: fragment
+    ok 10 - host/path: host_hint
+ok 25 - subtests
+    1..10
+    ok 1 - host//: parse
+    ok 2 - host//: scheme
+    ok 3 - host//: login
+    ok 4 - host//: password
+    ok 5 - host//: host
+    ok 6 - host//: service
+    ok 7 - host//: path
+    ok 8 - host//: query
+    ok 9 - host//: fragment
+    ok 10 - host//: host_hint
+ok 26 - subtests
+    1..10
+    ok 1 - host//path: parse
+    ok 2 - host//path: scheme
+    ok 3 - host//path: login
+    ok 4 - host//path: password
+    ok 5 - host//path: host
+    ok 6 - host//path: service
+    ok 7 - host//path: path
+    ok 8 - host//path: query
+    ok 9 - host//path: fragment
+    ok 10 - host//path: host_hint
+ok 27 - subtests
+    1..10
+    ok 1 - host/;abc?q: parse
+    ok 2 - host/;abc?q: scheme
+    ok 3 - host/;abc?q: login
+    ok 4 - host/;abc?q: password
+    ok 5 - host/;abc?q: host
+    ok 6 - host/;abc?q: service
+    ok 7 - host/;abc?q: path
+    ok 8 - host/;abc?q: query
+    ok 9 - host/;abc?q: fragment
+    ok 10 - host/;abc?q: host_hint
+ok 28 - subtests
+    1..10
+    ok 1 - scheme://login:password@host:service/@path1/:path2?q1=v1&q2=v2#fragment: parse
+    ok 2 - scheme://login:password@host:service/@path1/:path2?q1=v1&q2=v2#fragment: scheme
+    ok 3 - scheme://login:password@host:service/@path1/:path2?q1=v1&q2=v2#fragment: login
+    ok 4 - scheme://login:password@host:service/@path1/:path2?q1=v1&q2=v2#fragment: password
+    ok 5 - scheme://login:password@host:service/@path1/:path2?q1=v1&q2=v2#fragment: host
+    ok 6 - scheme://login:password@host:service/@path1/:path2?q1=v1&q2=v2#fragment: service
+    ok 7 - scheme://login:password@host:service/@path1/:path2?q1=v1&q2=v2#fragment: path
+    ok 8 - scheme://login:password@host:service/@path1/:path2?q1=v1&q2=v2#fragment: query
+    ok 9 - scheme://login:password@host:service/@path1/:path2?q1=v1&q2=v2#fragment: fragment
+    ok 10 - scheme://login:password@host:service/@path1/:path2?q1=v1&q2=v2#fragment: host_hint
+ok 29 - subtests
+    1..10
+    ok 1 - host/~user: parse
+    ok 2 - host/~user: scheme
+    ok 3 - host/~user: login
+    ok 4 - host/~user: password
+    ok 5 - host/~user: host
+    ok 6 - host/~user: service
+    ok 7 - host/~user: path
+    ok 8 - host/~user: query
+    ok 9 - host/~user: fragment
+    ok 10 - host/~user: host_hint
+ok 30 - subtests
+    1..10
+    ok 1 - try.tarantool.org: parse
+    ok 2 - try.tarantool.org: scheme
+    ok 3 - try.tarantool.org: login
+    ok 4 - try.tarantool.org: password
+    ok 5 - try.tarantool.org: host
+    ok 6 - try.tarantool.org: service
+    ok 7 - try.tarantool.org: path
+    ok 8 - try.tarantool.org: query
+    ok 9 - try.tarantool.org: fragment
+    ok 10 - try.tarantool.org: host_hint
+ok 31 - subtests
+    1..10
+    ok 1 - try.tarantool.org: parse
+    ok 2 - try.tarantool.org: scheme
+    ok 3 - try.tarantool.org: login
+    ok 4 - try.tarantool.org: password
+    ok 5 - try.tarantool.org: host
+    ok 6 - try.tarantool.org: service
+    ok 7 - try.tarantool.org: path
+    ok 8 - try.tarantool.org: query
+    ok 9 - try.tarantool.org: fragment
+    ok 10 - try.tarantool.org: host_hint
+ok 32 - subtests
+    1..10
+    ok 1 - www.llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch.com: parse
+    ok 2 - www.llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch.com: scheme
+    ok 3 - www.llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch.com: login
+    ok 4 - www.llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch.com: password
+    ok 5 - www.llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch.com: host
+    ok 6 - www.llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch.com: service
+    ok 7 - www.llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch.com: path
+    ok 8 - www.llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch.com: query
+    ok 9 - www.llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch.com: fragment
+    ok 10 - www.llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch.com: host_hint
+ok 33 - subtests
+    1..10
+    ok 1 - 0.0.0.0: parse
+    ok 2 - 0.0.0.0: scheme
+    ok 3 - 0.0.0.0: login
+    ok 4 - 0.0.0.0: password
+    ok 5 - 0.0.0.0: host
+    ok 6 - 0.0.0.0: service
+    ok 7 - 0.0.0.0: path
+    ok 8 - 0.0.0.0: query
+    ok 9 - 0.0.0.0: fragment
+    ok 10 - 0.0.0.0: host_hint
+ok 34 - subtests
+    1..10
+    ok 1 - 127.0.0.1: parse
+    ok 2 - 127.0.0.1: scheme
+    ok 3 - 127.0.0.1: login
+    ok 4 - 127.0.0.1: password
+    ok 5 - 127.0.0.1: host
+    ok 6 - 127.0.0.1: service
+    ok 7 - 127.0.0.1: path
+    ok 8 - 127.0.0.1: query
+    ok 9 - 127.0.0.1: fragment
+    ok 10 - 127.0.0.1: host_hint
+ok 35 - subtests
+    1..10
+    ok 1 - 127.0.0.1:3313: parse
+    ok 2 - 127.0.0.1:3313: scheme
+    ok 3 - 127.0.0.1:3313: login
+    ok 4 - 127.0.0.1:3313: password
+    ok 5 - 127.0.0.1:3313: host
+    ok 6 - 127.0.0.1:3313: service
+    ok 7 - 127.0.0.1:3313: path
+    ok 8 - 127.0.0.1:3313: query
+    ok 9 - 127.0.0.1:3313: fragment
+    ok 10 - 127.0.0.1:3313: host_hint
+ok 36 - subtests
+    1..10
+    ok 1 - scheme://login:password@127.0.0.1:3313: parse
+    ok 2 - scheme://login:password@127.0.0.1:3313: scheme
+    ok 3 - scheme://login:password@127.0.0.1:3313: login
+    ok 4 - scheme://login:password@127.0.0.1:3313: password
+    ok 5 - scheme://login:password@127.0.0.1:3313: host
+    ok 6 - scheme://login:password@127.0.0.1:3313: service
+    ok 7 - scheme://login:password@127.0.0.1:3313: path
+    ok 8 - scheme://login:password@127.0.0.1:3313: query
+    ok 9 - scheme://login:password@127.0.0.1:3313: fragment
+    ok 10 - scheme://login:password@127.0.0.1:3313: host_hint
+ok 37 - subtests
+    1..10
+    ok 1 - [2001::11a3:09d7::1]: parse
+    ok 2 - [2001::11a3:09d7::1]: scheme
+    ok 3 - [2001::11a3:09d7::1]: login
+    ok 4 - [2001::11a3:09d7::1]: password
+    ok 5 - [2001::11a3:09d7::1]: host
+    ok 6 - [2001::11a3:09d7::1]: service
+    ok 7 - [2001::11a3:09d7::1]: path
+    ok 8 - [2001::11a3:09d7::1]: query
+    ok 9 - [2001::11a3:09d7::1]: fragment
+    ok 10 - [2001::11a3:09d7::1]: host_hint
+ok 38 - subtests
+    1..10
+    ok 1 - scheme://login:password@[2001::11a3:09d7::1]:3313: parse
+    ok 2 - scheme://login:password@[2001::11a3:09d7::1]:3313: scheme
+    ok 3 - scheme://login:password@[2001::11a3:09d7::1]:3313: login
+    ok 4 - scheme://login:password@[2001::11a3:09d7::1]:3313: password
+    ok 5 - scheme://login:password@[2001::11a3:09d7::1]:3313: host
+    ok 6 - scheme://login:password@[2001::11a3:09d7::1]:3313: service
+    ok 7 - scheme://login:password@[2001::11a3:09d7::1]:3313: path
+    ok 8 - scheme://login:password@[2001::11a3:09d7::1]:3313: query
+    ok 9 - scheme://login:password@[2001::11a3:09d7::1]:3313: fragment
+    ok 10 - scheme://login:password@[2001::11a3:09d7::1]:3313: host_hint
+ok 39 - subtests
+    1..10
+    ok 1 - scheme://[2001:0db8:11a3:09d7::1]: parse
+    ok 2 - scheme://[2001:0db8:11a3:09d7::1]: scheme
+    ok 3 - scheme://[2001:0db8:11a3:09d7::1]: login
+    ok 4 - scheme://[2001:0db8:11a3:09d7::1]: password
+    ok 5 - scheme://[2001:0db8:11a3:09d7::1]: host
+    ok 6 - scheme://[2001:0db8:11a3:09d7::1]: service
+    ok 7 - scheme://[2001:0db8:11a3:09d7::1]: path
+    ok 8 - scheme://[2001:0db8:11a3:09d7::1]: query
+    ok 9 - scheme://[2001:0db8:11a3:09d7::1]: fragment
+    ok 10 - scheme://[2001:0db8:11a3:09d7::1]: host_hint
+ok 40 - subtests
+    1..10
+    ok 1 - [::ffff:11.2.3.4]: parse
+    ok 2 - [::ffff:11.2.3.4]: scheme
+    ok 3 - [::ffff:11.2.3.4]: login
+    ok 4 - [::ffff:11.2.3.4]: password
+    ok 5 - [::ffff:11.2.3.4]: host
+    ok 6 - [::ffff:11.2.3.4]: service
+    ok 7 - [::ffff:11.2.3.4]: path
+    ok 8 - [::ffff:11.2.3.4]: query
+    ok 9 - [::ffff:11.2.3.4]: fragment
+    ok 10 - [::ffff:11.2.3.4]: host_hint
+ok 41 - subtests
+    1..10
+    ok 1 - scheme://login:password@[::ffff:11.2.3.4]:3313: parse
+    ok 2 - scheme://login:password@[::ffff:11.2.3.4]:3313: scheme
+    ok 3 - scheme://login:password@[::ffff:11.2.3.4]:3313: login
+    ok 4 - scheme://login:password@[::ffff:11.2.3.4]:3313: password
+    ok 5 - scheme://login:password@[::ffff:11.2.3.4]:3313: host
+    ok 6 - scheme://login:password@[::ffff:11.2.3.4]:3313: service
+    ok 7 - scheme://login:password@[::ffff:11.2.3.4]:3313: path
+    ok 8 - scheme://login:password@[::ffff:11.2.3.4]:3313: query
+    ok 9 - scheme://login:password@[::ffff:11.2.3.4]:3313: fragment
+    ok 10 - scheme://login:password@[::ffff:11.2.3.4]:3313: host_hint
+ok 42 - subtests
+    1..10
+    ok 1 - 1: parse
+    ok 2 - 1: scheme
+    ok 3 - 1: login
+    ok 4 - 1: password
+    ok 5 - 1: host
+    ok 6 - 1: service
+    ok 7 - 1: path
+    ok 8 - 1: query
+    ok 9 - 1: fragment
+    ok 10 - 1: host_hint
+ok 43 - subtests
+    1..10
+    ok 1 - 10: parse
+    ok 2 - 10: scheme
+    ok 3 - 10: login
+    ok 4 - 10: password
+    ok 5 - 10: host
+    ok 6 - 10: service
+    ok 7 - 10: path
+    ok 8 - 10: query
+    ok 9 - 10: fragment
+    ok 10 - 10: host_hint
+ok 44 - subtests
+    1..10
+    ok 1 - 331: parse
+    ok 2 - 331: scheme
+    ok 3 - 331: login
+    ok 4 - 331: password
+    ok 5 - 331: host
+    ok 6 - 331: service
+    ok 7 - 331: path
+    ok 8 - 331: query
+    ok 9 - 331: fragment
+    ok 10 - 331: host_hint
+ok 45 - subtests
+    1..10
+    ok 1 - 3313: parse
+    ok 2 - 3313: scheme
+    ok 3 - 3313: login
+    ok 4 - 3313: password
+    ok 5 - 3313: host
+    ok 6 - 3313: service
+    ok 7 - 3313: path
+    ok 8 - 3313: query
+    ok 9 - 3313: fragment
+    ok 10 - 3313: host_hint
+ok 46 - subtests
+    1..10
+    ok 1 - /: parse
+    ok 2 - /: scheme
+    ok 3 - /: login
+    ok 4 - /: password
+    ok 5 - /: host
+    ok 6 - /: service
+    ok 7 - /: path
+    ok 8 - /: query
+    ok 9 - /: fragment
+    ok 10 - /: host_hint
+ok 47 - subtests
+    1..10
+    ok 1 - /path1/path2/path3: parse
+    ok 2 - /path1/path2/path3: scheme
+    ok 3 - /path1/path2/path3: login
+    ok 4 - /path1/path2/path3: password
+    ok 5 - /path1/path2/path3: host
+    ok 6 - /path1/path2/path3: service
+    ok 7 - /path1/path2/path3: path
+    ok 8 - /path1/path2/path3: query
+    ok 9 - /path1/path2/path3: fragment
+    ok 10 - /path1/path2/path3: host_hint
+ok 48 - subtests
+    1..10
+    ok 1 - login:password@/path1/path2/path3: parse
+    ok 2 - login:password@/path1/path2/path3: scheme
+    ok 3 - login:password@/path1/path2/path3: login
+    ok 4 - login:password@/path1/path2/path3: password
+    ok 5 - login:password@/path1/path2/path3: host
+    ok 6 - login:password@/path1/path2/path3: service
+    ok 7 - login:password@/path1/path2/path3: path
+    ok 8 - login:password@/path1/path2/path3: query
+    ok 9 - login:password@/path1/path2/path3: fragment
+    ok 10 - login:password@/path1/path2/path3: host_hint
+ok 49 - subtests
+    1..10
+    ok 1 - unix/:/path1/path2/path3: parse
+    ok 2 - unix/:/path1/path2/path3: scheme
+    ok 3 - unix/:/path1/path2/path3: login
+    ok 4 - unix/:/path1/path2/path3: password
+    ok 5 - unix/:/path1/path2/path3: host
+    ok 6 - unix/:/path1/path2/path3: service
+    ok 7 - unix/:/path1/path2/path3: path
+    ok 8 - unix/:/path1/path2/path3: query
+    ok 9 - unix/:/path1/path2/path3: fragment
+    ok 10 - unix/:/path1/path2/path3: host_hint
+ok 50 - subtests
+    1..10
+    ok 1 - unix/:/path1/path2/path3:: parse
+    ok 2 - unix/:/path1/path2/path3:: scheme
+    ok 3 - unix/:/path1/path2/path3:: login
+    ok 4 - unix/:/path1/path2/path3:: password
+    ok 5 - unix/:/path1/path2/path3:: host
+    ok 6 - unix/:/path1/path2/path3:: service
+    ok 7 - unix/:/path1/path2/path3:: path
+    ok 8 - unix/:/path1/path2/path3:: query
+    ok 9 - unix/:/path1/path2/path3:: fragment
+    ok 10 - unix/:/path1/path2/path3:: host_hint
+ok 51 - subtests
+    1..10
+    ok 1 - unix/:/path1/path2/path3:/: parse
+    ok 2 - unix/:/path1/path2/path3:/: scheme
+    ok 3 - unix/:/path1/path2/path3:/: login
+    ok 4 - unix/:/path1/path2/path3:/: password
+    ok 5 - unix/:/path1/path2/path3:/: host
+    ok 6 - unix/:/path1/path2/path3:/: service
+    ok 7 - unix/:/path1/path2/path3:/: path
+    ok 8 - unix/:/path1/path2/path3:/: query
+    ok 9 - unix/:/path1/path2/path3:/: fragment
+    ok 10 - unix/:/path1/path2/path3:/: host_hint
+ok 52 - subtests
+    1..10
+    ok 1 - unix/:/path1/path2/path3?q1=v1&q2=v2#fragment: parse
+    ok 2 - unix/:/path1/path2/path3?q1=v1&q2=v2#fragment: scheme
+    ok 3 - unix/:/path1/path2/path3?q1=v1&q2=v2#fragment: login
+    ok 4 - unix/:/path1/path2/path3?q1=v1&q2=v2#fragment: password
+    ok 5 - unix/:/path1/path2/path3?q1=v1&q2=v2#fragment: host
+    ok 6 - unix/:/path1/path2/path3?q1=v1&q2=v2#fragment: service
+    ok 7 - unix/:/path1/path2/path3?q1=v1&q2=v2#fragment: path
+    ok 8 - unix/:/path1/path2/path3?q1=v1&q2=v2#fragment: query
+    ok 9 - unix/:/path1/path2/path3?q1=v1&q2=v2#fragment: fragment
+    ok 10 - unix/:/path1/path2/path3?q1=v1&q2=v2#fragment: host_hint
+ok 53 - subtests
+    1..10
+    ok 1 - unix/:/path1/path2/path3:/p1/p2?q1=v1&q2=v2#fragment: parse
+    ok 2 - unix/:/path1/path2/path3:/p1/p2?q1=v1&q2=v2#fragment: scheme
+    ok 3 - unix/:/path1/path2/path3:/p1/p2?q1=v1&q2=v2#fragment: login
+    ok 4 - unix/:/path1/path2/path3:/p1/p2?q1=v1&q2=v2#fragment: password
+    ok 5 - unix/:/path1/path2/path3:/p1/p2?q1=v1&q2=v2#fragment: host
+    ok 6 - unix/:/path1/path2/path3:/p1/p2?q1=v1&q2=v2#fragment: service
+    ok 7 - unix/:/path1/path2/path3:/p1/p2?q1=v1&q2=v2#fragment: path
+    ok 8 - unix/:/path1/path2/path3:/p1/p2?q1=v1&q2=v2#fragment: query
+    ok 9 - unix/:/path1/path2/path3:/p1/p2?q1=v1&q2=v2#fragment: fragment
+    ok 10 - unix/:/path1/path2/path3:/p1/p2?q1=v1&q2=v2#fragment: host_hint
+ok 54 - subtests
+    1..10
+    ok 1 - scheme://login:password@unix/:/tmp/unix.sock:/path1/path2/path3: parse
+    ok 2 - scheme://login:password@unix/:/tmp/unix.sock:/path1/path2/path3: scheme
+    ok 3 - scheme://login:password@unix/:/tmp/unix.sock:/path1/path2/path3: login
+    ok 4 - scheme://login:password@unix/:/tmp/unix.sock:/path1/path2/path3: password
+    ok 5 - scheme://login:password@unix/:/tmp/unix.sock:/path1/path2/path3: host
+    ok 6 - scheme://login:password@unix/:/tmp/unix.sock:/path1/path2/path3: service
+    ok 7 - scheme://login:password@unix/:/tmp/unix.sock:/path1/path2/path3: path
+    ok 8 - scheme://login:password@unix/:/tmp/unix.sock:/path1/path2/path3: query
+    ok 9 - scheme://login:password@unix/:/tmp/unix.sock:/path1/path2/path3: fragment
+    ok 10 - scheme://login:password@unix/:/tmp/unix.sock:/path1/path2/path3: host_hint
+ok 55 - subtests
+    1..10
+    ok 1 - unix/:./relative/path.sock:/test: parse
+    ok 2 - unix/:./relative/path.sock:/test: scheme
+    ok 3 - unix/:./relative/path.sock:/test: login
+    ok 4 - unix/:./relative/path.sock:/test: password
+    ok 5 - unix/:./relative/path.sock:/test: host
+    ok 6 - unix/:./relative/path.sock:/test: service
+    ok 7 - unix/:./relative/path.sock:/test: path
+    ok 8 - unix/:./relative/path.sock:/test: query
+    ok 9 - unix/:./relative/path.sock:/test: fragment
+    ok 10 - unix/:./relative/path.sock:/test: host_hint
+ok 56 - subtests
+    1..10
+    ok 1 - scheme://unix/:./relative/path.sock:/test: parse
+    ok 2 - scheme://unix/:./relative/path.sock:/test: scheme
+    ok 3 - scheme://unix/:./relative/path.sock:/test: login
+    ok 4 - scheme://unix/:./relative/path.sock:/test: password
+    ok 5 - scheme://unix/:./relative/path.sock:/test: host
+    ok 6 - scheme://unix/:./relative/path.sock:/test: service
+    ok 7 - scheme://unix/:./relative/path.sock:/test: path
+    ok 8 - scheme://unix/:./relative/path.sock:/test: query
+    ok 9 - scheme://unix/:./relative/path.sock:/test: fragment
+    ok 10 - scheme://unix/:./relative/path.sock:/test: host_hint
+ok 57 - subtests
+    1..10
+    ok 1 - http://tarantool.org/dist/master/debian/pool/main/t/tarantool/tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz: parse
+    ok 2 - http://tarantool.org/dist/master/debian/pool/main/t/tarantool/tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz: scheme
+    ok 3 - http://tarantool.org/dist/master/debian/pool/main/t/tarantool/tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz: login
+    ok 4 - http://tarantool.org/dist/master/debian/pool/main/t/tarantool/tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz: password
+    ok 5 - http://tarantool.org/dist/master/debian/pool/main/t/tarantool/tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz: host
+    ok 6 - http://tarantool.org/dist/master/debian/pool/main/t/tarantool/tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz: service
+    ok 7 - http://tarantool.org/dist/master/debian/pool/main/t/tarantool/tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz: path
+    ok 8 - http://tarantool.org/dist/master/debian/pool/main/t/tarantool/tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz: query
+    ok 9 - http://tarantool.org/dist/master/debian/pool/main/t/tarantool/tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz: fragment
+    ok 10 - http://tarantool.org/dist/master/debian/pool/main/t/tarantool/tarantool_1.6.3+314+g91066ee+20140910+1434.orig.tar.gz: host_hint
+ok 58 - subtests
+    1..10
+    ok 1 - https://www.google.com/search?safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl: parse
+    ok 2 - https://www.google.com/search?safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl: scheme
+    ok 3 - https://www.google.com/search?safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl: login
+    ok 4 - https://www.google.com/search?safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl: password
+    ok 5 - https://www.google.com/search?safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl: host
+    ok 6 - https://www.google.com/search?safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl: service
+    ok 7 - https://www.google.com/search?safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl: path
+    ok 8 - https://www.google.com/search?safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl: query
+    ok 9 - https://www.google.com/search?safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl: fragment
+    ok 10 - https://www.google.com/search?safe=off&site=&tbm=isch&source=hp&biw=1918&bih=1109&q=Tarantool&oq=Tarantool&gs_l=img.3..0i24l3j0i10i24j0i24&gws_rd=ssl: host_hint
+ok 59 - subtests
+    1..2
+    ok 1 - empty is invalid
+    ok 2 - :// is invalid
+ok 60 - subtests
diff --git a/third_party/base64.c b/third_party/base64.c
index e2fb9785c43ce65a76c2077455a1e18a0b4126a1..49a4f2492d28ab85fee030b550cd3c0f84978c38 100644
--- a/third_party/base64.c
+++ b/third_party/base64.c
@@ -35,6 +35,9 @@
 
 /* {{{ encode */
 
+extern inline int
+base64_bufsize(int binsize);
+
 enum base64_encodestep { step_A, step_B, step_C };
 
 struct base64_encodestate {
diff --git a/third_party/base64.h b/third_party/base64.h
index d590820ddb775f816cce7ef9941d47cd8cd70890..a52a5e91f7e767a3694f2efb9a70271279230187 100644
--- a/third_party/base64.h
+++ b/third_party/base64.h
@@ -39,7 +39,7 @@ extern "C" {
 
 #define BASE64_CHARS_PER_LINE 72
 
-static inline int
+inline int
 base64_bufsize(int binsize)
 {
 	int datasize = binsize * 4/3 + 4;
diff --git a/third_party/sophia b/third_party/sophia
index 3889eb4777fdff520c140467eab477c0af3ca7c9..6c6c69d376d8452a7dfefd2086c4934065ab89cc 160000
--- a/third_party/sophia
+++ b/third_party/sophia
@@ -1 +1 @@
-Subproject commit 3889eb4777fdff520c140467eab477c0af3ca7c9
+Subproject commit 6c6c69d376d8452a7dfefd2086c4934065ab89cc