diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index fc83ef126591539af8c8af6f38d96d15d19c06d6..082de681c698f1dad91f0d957051b56a542f93b7 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -35,14 +35,14 @@ add_custom_target(generate_lua_sources
     DEPENDS ${lua_sources})
 set_property(DIRECTORY PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${lua_sources})
 
-add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/src/port_uri.cc
+add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/src/uri.cc
 	WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
-	COMMAND ragel -G2 src/port_uri.rl -o src/port_uri.cc
-	DEPENDS ${CMAKE_SOURCE_DIR}/src/port_uri.rl)
+	COMMAND ragel -G2 src/uri.rl -o src/uri.cc
+	DEPENDS ${CMAKE_SOURCE_DIR}/src/uri.rl)
 execute_process(COMMAND ${CMAKE_COMMAND} -E touch_nocreate
-    ${CMAKE_SOURCE_DIR}/src/port_uri.cc)
-add_custom_target(generate_port_uri_cc
-    DEPENDS ${CMAKE_SOURCE_DIR}/src/port_uri.cc)
+    ${CMAKE_SOURCE_DIR}/src/uri.cc)
+add_custom_target(generate_uri_cc
+    DEPENDS ${CMAKE_SOURCE_DIR}/src/uri.cc)
 
 set (common_sources
      memory.cc
@@ -81,7 +81,7 @@ set (common_sources
      fiob.c
      tt_uuid.c
      ffisyms.cc
-     port_uri.cc
+     uri.cc
      lua/init.cc
      lua/fiber.cc
      lua/trigger.cc
diff --git a/src/box/alter.cc b/src/box/alter.cc
index 6899fee6b92f53c7c14bfc88f6302fe13aba1a8c..9cd4f59aa737ae3e36b1f4641c8eb3f7c7f80a3b 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -461,10 +461,10 @@ alter_space_do(struct txn *txn, struct alter_space *alter,
 	 */
 	struct trigger *on_commit =
 		txn_alter_trigger_new(alter_space_commit, alter);
-	trigger_set(&txn->on_commit, on_commit);
+	trigger_add(&txn->on_commit, on_commit);
 	struct trigger *on_rollback =
 		txn_alter_trigger_new(alter_space_rollback, alter);
-	trigger_set(&txn->on_rollback, on_rollback);
+	trigger_add(&txn->on_rollback, on_rollback);
 }
 
 /* }}}  */
@@ -727,7 +727,13 @@ on_rollback_in_old_space(struct trigger *trigger, void *event)
 	struct txn *txn = (struct txn *) event;
 	Index *new_index = (Index *) trigger->data;
 	/* Remove the failed tuple from the new index. */
-	new_index->replace(txn->new_tuple, txn->old_tuple, DUP_INSERT);
+	struct txn_stmt *stmt;
+	rlist_foreach_entry(stmt, &txn->stmts, next) {
+		if (stmt->space->def.id != new_index->key_def->space_id)
+			continue;
+		new_index->replace(stmt->new_tuple, stmt->old_tuple,
+				   DUP_INSERT);
+	}
 }
 
 /**
@@ -738,16 +744,22 @@ static void
 on_replace_in_old_space(struct trigger *trigger, void *event)
 {
 	struct txn *txn = (struct txn *) event;
+	struct txn_stmt *stmt = txn_stmt(txn);
 	Index *new_index = (Index *) trigger->data;
 	/*
-	 * First set rollback trigger, then do replace, since
+	 * First set a rollback trigger, then do replace, since
 	 * creating the trigger may fail.
 	 */
 	struct trigger *on_rollback =
 		add2index_trigger_new(on_rollback_in_old_space, new_index);
-	trigger_set(&txn->on_rollback, on_rollback);
-	/* Put the tuple into thew new index. */
-	(void) new_index->replace(txn->old_tuple, txn->new_tuple,
+	/*
+	 * In a multi-statement transaction the same space
+	 * may be modified many times, but we need only one
+	 * on_rollback trigger.
+	 */
+	trigger_add_unique(&txn->on_rollback, on_rollback);
+	/* Put the tuple into the new index. */
+	(void) new_index->replace(stmt->old_tuple, stmt->new_tuple,
 				  DUP_INSERT);
 }
 
@@ -839,7 +851,7 @@ AddIndex::alter(struct alter_space *alter)
 	struct tuple *tuple;
 	struct tuple_format *format = alter->new_space->format;
 	char *field_map = ((char *) region_alloc(&fiber()->gc,
-					   format->field_map_size) +
+						 format->field_map_size) +
 			   format->field_map_size);
 	while ((tuple = it->next(it))) {
 		/*
@@ -857,7 +869,7 @@ AddIndex::alter(struct alter_space *alter)
 	}
 	on_replace = add2index_trigger_new(on_replace_in_old_space,
 					   new_index);
-	trigger_set(&alter->old_space->on_replace, on_replace);
+	trigger_add(&alter->old_space->on_replace, on_replace);
 }
 
 AddIndex::~AddIndex()
@@ -882,9 +894,10 @@ AddIndex::~AddIndex()
 static void
 on_drop_space(struct trigger * /* trigger */, void *event)
 {
-	struct txn *txn = (struct txn *) event;
-	uint32_t id = tuple_field_u32(txn->old_tuple ?
-				      txn->old_tuple : txn->new_tuple, ID);
+	struct txn_stmt *stmt = txn_stmt((struct txn *) event);
+	uint32_t id = tuple_field_u32(stmt->old_tuple ?
+				      stmt->old_tuple : stmt->new_tuple,
+				      ID);
 	struct space *space = space_cache_delete(id);
 	space_delete(space);
 }
@@ -949,8 +962,10 @@ static void
 on_replace_dd_space(struct trigger * /* trigger */, void *event)
 {
 	struct txn *txn = (struct txn *) event;
-	struct tuple *old_tuple = txn->old_tuple;
-	struct tuple *new_tuple = txn->new_tuple;
+	txn_check_autocommit(txn, "Space _space");
+	struct txn_stmt *stmt = txn_stmt(txn);
+	struct tuple *old_tuple = stmt->old_tuple;
+	struct tuple *new_tuple = stmt->new_tuple;
 	/*
 	 * Things to keep in mind:
 	 * - old_tuple is set only in case of UPDATE.  For INSERT
@@ -982,7 +997,7 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event)
 		 * so it's safe to simply drop the space on
 		 * rollback.
 		 */
-		trigger_set(&txn->on_rollback, &drop_space_trigger);
+		trigger_add(&txn->on_rollback, &drop_space_trigger);
 	} else if (new_tuple == NULL) { /* DELETE */
 		access_check_ddl(old_space->def.uid);
 		/* Verify that the space is empty (has no indexes) */
@@ -1001,7 +1016,7 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event)
 		 * dd_space_delete() can't fail, any such
 		 * failure would have to abort the server.
 		 */
-		trigger_set(&txn->on_commit, &drop_space_trigger);
+		trigger_add(&txn->on_commit, &drop_space_trigger);
 	} else { /* UPDATE, REPLACE */
 		assert(old_space != NULL && new_tuple != NULL);
 		/*
@@ -1010,7 +1025,7 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event)
 		 */
 		struct alter_space *alter = alter_space_new();
 		auto scoped_guard =
-		        make_scoped_guard([=] {alter_space_delete(alter);});
+			make_scoped_guard([=] {alter_space_delete(alter);});
 		ModifySpace *modify =
 			AlterSpaceOp::create<ModifySpace>();
 		alter_space_add_op(alter, modify);
@@ -1061,8 +1076,10 @@ static void
 on_replace_dd_index(struct trigger * /* trigger */, void *event)
 {
 	struct txn *txn = (struct txn *) event;
-	struct tuple *old_tuple = txn->old_tuple;
-	struct tuple *new_tuple = txn->new_tuple;
+	txn_check_autocommit(txn, "Space _index");
+	struct txn_stmt *stmt = txn_stmt(txn);
+	struct tuple *old_tuple = stmt->old_tuple;
+	struct tuple *new_tuple = stmt->new_tuple;
 	uint32_t id = tuple_field_u32(old_tuple ? old_tuple : new_tuple, ID);
 	uint32_t iid = tuple_field_u32(old_tuple ? old_tuple : new_tuple,
 				       INDEX_ID);
@@ -1202,8 +1219,10 @@ static void
 user_cache_remove_user(struct trigger * /* trigger */, void *event)
 {
 	struct txn *txn = (struct txn *) event;
-	uint32_t uid = tuple_field_u32(txn->old_tuple ?
-				       txn->old_tuple : txn->new_tuple, ID);
+	struct txn_stmt *stmt = txn_stmt(txn);
+	uint32_t uid = tuple_field_u32(stmt->old_tuple ?
+				       stmt->old_tuple : stmt->new_tuple,
+				       ID);
 	user_cache_delete(uid);
 }
 
@@ -1214,8 +1233,9 @@ static void
 user_cache_replace_user(struct trigger * /* trigger */, void *event)
 {
 	struct txn *txn = (struct txn *) event;
+	struct txn_stmt *stmt = txn_stmt(txn);
 	struct user user;
-	user_create_from_tuple(&user, txn->new_tuple);
+	user_create_from_tuple(&user, stmt->new_tuple);
 	user_cache_replace(&user);
 }
 
@@ -1229,8 +1249,10 @@ static void
 on_replace_dd_user(struct trigger * /* trigger */, void *event)
 {
 	struct txn *txn = (struct txn *) event;
-	struct tuple *old_tuple = txn->old_tuple;
-	struct tuple *new_tuple = txn->new_tuple;
+	struct txn_stmt *stmt = txn_stmt(txn);
+	txn_check_autocommit(txn, "Space _user");
+	struct tuple *old_tuple = stmt->old_tuple;
+	struct tuple *new_tuple = stmt->new_tuple;
 
 	uint32_t uid = tuple_field_u32(old_tuple ?
 				       old_tuple : new_tuple, ID);
@@ -1239,7 +1261,7 @@ on_replace_dd_user(struct trigger * /* trigger */, void *event)
 		struct user user;
 		user_create_from_tuple(&user, new_tuple);
 		(void) user_cache_replace(&user);
-		trigger_set(&txn->on_rollback, &drop_user_trigger);
+		trigger_add(&txn->on_rollback, &drop_user_trigger);
 	} else if (new_tuple == NULL) { /* DELETE */
 		access_check_ddl(old_user->owner);
 		/* Can't drop guest or super user */
@@ -1256,7 +1278,7 @@ on_replace_dd_user(struct trigger * /* trigger */, void *event)
 			tnt_raise(ClientError, ER_DROP_USER,
 				  old_user->name, "the user has objects");
 		}
-		trigger_set(&txn->on_commit, &drop_user_trigger);
+		trigger_add(&txn->on_commit, &drop_user_trigger);
 	} else { /* UPDATE, REPLACE */
 		assert(old_user != NULL && new_tuple != NULL);
 		/*
@@ -1266,7 +1288,7 @@ on_replace_dd_user(struct trigger * /* trigger */, void *event)
 		 */
 		struct user user;
 		user_create_from_tuple(&user, new_tuple);
-		trigger_set(&txn->on_commit, &modify_user_trigger);
+		trigger_add(&txn->on_commit, &modify_user_trigger);
 	}
 }
 
@@ -1291,9 +1313,10 @@ func_def_create_from_tuple(struct func_def *func, struct tuple *tuple)
 static void
 func_cache_remove_func(struct trigger * /* trigger */, void *event)
 {
-	struct txn *txn = (struct txn *) event;
-	uint32_t fid = tuple_field_u32(txn->old_tuple ?
-				       txn->old_tuple : txn->new_tuple, ID);
+	struct txn_stmt *stmt = txn_stmt((struct txn *) event);
+	uint32_t fid = tuple_field_u32(stmt->old_tuple ?
+				       stmt->old_tuple : stmt->new_tuple,
+				       ID);
 	func_cache_delete(fid);
 }
 
@@ -1304,9 +1327,9 @@ static struct trigger drop_func_trigger =
 static void
 func_cache_replace_func(struct trigger * /* trigger */, void *event)
 {
-	struct txn *txn = (struct txn *) event;
+	struct txn_stmt *stmt = txn_stmt((struct txn*) event);
 	struct func_def func;
-	func_def_create_from_tuple(&func, txn->new_tuple);
+	func_def_create_from_tuple(&func, stmt->new_tuple);
 	func_cache_replace(&func);
 }
 
@@ -1320,10 +1343,12 @@ static struct trigger modify_func_trigger =
 static void
 on_replace_dd_func(struct trigger * /* trigger */, void *event)
 {
-	struct func_def func;
 	struct txn *txn = (struct txn *) event;
-	struct tuple *old_tuple = txn->old_tuple;
-	struct tuple *new_tuple = txn->new_tuple;
+	txn_check_autocommit(txn, "Space _func");
+	struct txn_stmt *stmt = txn_stmt(txn);
+	struct tuple *old_tuple = stmt->old_tuple;
+	struct tuple *new_tuple = stmt->new_tuple;
+	struct func_def func;
 
 	uint32_t fid = tuple_field_u32(old_tuple ?
 				       old_tuple : new_tuple, ID);
@@ -1331,7 +1356,7 @@ on_replace_dd_func(struct trigger * /* trigger */, void *event)
 	if (new_tuple != NULL && old_func == NULL) { /* INSERT */
 		func_def_create_from_tuple(&func, new_tuple);
 		func_cache_replace(&func);
-		trigger_set(&txn->on_rollback, &drop_func_trigger);
+		trigger_add(&txn->on_rollback, &drop_func_trigger);
 	} else if (new_tuple == NULL) {         /* DELETE */
 		func_def_create_from_tuple(&func, old_tuple);
 		/*
@@ -1345,11 +1370,11 @@ on_replace_dd_func(struct trigger * /* trigger */, void *event)
 				  (unsigned) func.uid,
 				  "function has grants");
 		}
-		trigger_set(&txn->on_commit, &drop_func_trigger);
+		trigger_add(&txn->on_commit, &drop_func_trigger);
 	} else {                                /* UPDATE, REPLACE */
 		func_def_create_from_tuple(&func, new_tuple);
 		access_check_ddl(func.uid);
-		trigger_set(&txn->on_commit, &modify_func_trigger);
+		trigger_add(&txn->on_commit, &modify_func_trigger);
 	}
 }
 
@@ -1463,8 +1488,9 @@ static void
 revoke_priv(struct trigger * /* trigger */, void *event)
 {
 	struct txn *txn = (struct txn *) event;
-	struct tuple *tuple = (txn->new_tuple ?
-			       txn->new_tuple : txn->old_tuple);
+	struct txn_stmt *stmt = txn_stmt(txn);
+	struct tuple *tuple = (stmt->new_tuple ?
+			       stmt->new_tuple : stmt->old_tuple);
 	struct priv_def priv;
 	priv_def_create_from_tuple(&priv, tuple);
 	priv.access = 0;
@@ -1478,9 +1504,9 @@ static struct trigger revoke_priv_trigger =
 static void
 modify_priv(struct trigger * /* trigger */, void *event)
 {
-	struct txn *txn = (struct txn *) event;
+	struct txn_stmt *stmt = txn_stmt((struct txn *) event);
 	struct priv_def priv;
-	priv_def_create_from_tuple(&priv, txn->new_tuple);
+	priv_def_create_from_tuple(&priv, stmt->new_tuple);
 	grant_or_revoke(&priv);
 }
 
@@ -1494,25 +1520,26 @@ static struct trigger modify_priv_trigger =
 static void
 on_replace_dd_priv(struct trigger * /* trigger */, void *event)
 {
-	struct priv_def priv;
 	struct txn *txn = (struct txn *) event;
-	struct tuple *old_tuple = txn->old_tuple;
-	struct tuple *new_tuple = txn->new_tuple;
+	txn_check_autocommit(txn, "Space _priv");
+	struct tuple *old_tuple = txn_stmt(txn)->old_tuple;
+	struct tuple *new_tuple = txn_stmt(txn)->new_tuple;
+	struct priv_def priv;
 
 	if (new_tuple != NULL && old_tuple == NULL) {	/* grant */
 		priv_def_create_from_tuple(&priv, new_tuple);
 		priv_def_check(&priv);
 		grant_or_revoke(&priv);
-		trigger_set(&txn->on_rollback, &revoke_priv_trigger);
+		trigger_add(&txn->on_rollback, &revoke_priv_trigger);
 	} else if (new_tuple == NULL) {                /* revoke */
 		assert(old_tuple);
 		priv_def_create_from_tuple(&priv, old_tuple);
 		access_check_ddl(priv.grantor_id);
-		trigger_set(&txn->on_commit, &revoke_priv_trigger);
+		trigger_add(&txn->on_commit, &revoke_priv_trigger);
 	} else {                                       /* modify */
 		priv_def_create_from_tuple(&priv, new_tuple);
 		priv_def_check(&priv);
-		trigger_set(&txn->on_commit, &modify_priv_trigger);
+		trigger_add(&txn->on_commit, &modify_priv_trigger);
 	}
 }
 
@@ -1547,8 +1574,10 @@ static void
 on_replace_dd_schema(struct trigger * /* trigger */, void *event)
 {
 	struct txn *txn = (struct txn *) event;
-	struct tuple *old_tuple = txn->old_tuple;
-	struct tuple *new_tuple = txn->new_tuple;
+	txn_check_autocommit(txn, "Space _schema");
+	struct txn_stmt *stmt = txn_stmt(txn);
+	struct tuple *old_tuple = stmt->old_tuple;
+	struct tuple *new_tuple = stmt->new_tuple;
 	const char *key = tuple_field_cstr(new_tuple ?
 					   new_tuple : old_tuple, 0);
 	if (strcmp(key, "cluster") == 0) {
@@ -1568,9 +1597,10 @@ static void
 on_commit_dd_cluster(struct trigger *trigger, void *event)
 {
 	(void) trigger;
-	struct txn *txn = (struct txn *) event;
-	uint32_t id = tuple_field_u32(txn->new_tuple, 0);
-	tt_uuid uuid = tuple_field_uuid(txn->new_tuple, 1);
+	struct txn_stmt *stmt = txn_stmt((struct txn *) event);
+	struct tuple *new_tuple = stmt->new_tuple;
+	uint32_t id = tuple_field_u32(new_tuple, 0);
+	tt_uuid uuid = tuple_field_uuid(new_tuple, 1);
 
 	cluster_add_server(&uuid, id);
 }
@@ -1601,7 +1631,9 @@ on_replace_dd_cluster(struct trigger *trigger, void *event)
 {
 	(void) trigger;
 	struct txn *txn = (struct txn *) event;
-	struct tuple *new_tuple = txn->new_tuple;
+	txn_check_autocommit(txn, "Space _cluster");
+	struct txn_stmt *stmt = txn_stmt(txn);
+	struct tuple *new_tuple = stmt->new_tuple;
 	if (new_tuple == NULL)
 		tnt_raise(ClientError, ER_SERVER_ID_IS_RO);
 
@@ -1615,7 +1647,7 @@ on_replace_dd_cluster(struct trigger *trigger, void *event)
 		tnt_raise(ClientError, ER_INVALID_UUID,
 			  tt_uuid_str(&server_uuid));
 
-	trigger_set(&txn->on_commit, &commit_cluster_trigger);
+	trigger_add(&txn->on_commit, &commit_cluster_trigger);
 }
 
 /* }}} cluster configuration */
diff --git a/src/box/box.cc b/src/box/box.cc
index ef048d4a7cf8abe98d1e4d3f5599bc20ec873752..3146eef088ccddca6cdb7906ddf7993afdd6f525 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -89,7 +89,7 @@ process_rw(struct port *port, struct request *request)
 static void
 process_ro(struct port *port, struct request *request)
 {
-	if (!iproto_request_is_select(request->type))
+	if (!iproto_type_is_select(request->type))
 		tnt_raise(LoggedError, ER_SECONDARY);
 	return process_rw(port, request);
 }
@@ -113,8 +113,8 @@ box_check_replication_source(const char *source)
 {
 	if (source == NULL)
 		return;
-	struct port_uri uri;
-	if (port_uri_parse(&uri, source)) {
+	struct uri uri;
+	if (uri_parse(&uri, source)) {
 		tnt_raise(ClientError, ER_CFG,
 			  "incorrect replication source");
 	}
@@ -135,12 +135,6 @@ box_check_config()
 {
 	box_check_wal_mode(cfg_gets("wal_mode"));
 
-	/* check primary port */
-	int primary_port = cfg_geti("primary_port");
-	if (primary_port < 0 || primary_port >= USHRT_MAX)
-		tnt_raise(ClientError, ER_CFG,
-			  "invalid primary port value");
-
 	/* check rows_per_wal configuration */
 	if (cfg_geti("rows_per_wal") <= 1) {
 		tnt_raise(ClientError, ER_CFG,
@@ -231,7 +225,7 @@ box_leave_local_standby_mode(void *data __attribute__((unused)))
 	}
 
 	recovery_finalize(recovery_state);
-	stat_cleanup(stat_base, IPROTO_DML_REQUEST_MAX);
+	stat_cleanup(stat_base, IPROTO_TYPE_DML_MAX);
 
 	box_set_wal_mode(cfg_gets("wal_mode"));
 
@@ -254,8 +248,7 @@ box_leave_local_standby_mode(void *data __attribute__((unused)))
  * no boundary or misuse checks.
  */
 void
-boxk(enum iproto_request_type type, uint32_t space_id,
-     const char *format, ...)
+boxk(enum iproto_type type, uint32_t space_id, const char *format, ...)
 {
 	struct request req;
 	va_list ap;
@@ -391,8 +384,7 @@ box_init()
 			     cfg_geti("panic_on_snap_error"),
 			     cfg_geti("panic_on_wal_error"));
 
-	stat_base = stat_register(iproto_request_type_strs,
-				  IPROTO_DML_REQUEST_MAX);
+	stat_base = stat_register(iproto_type_strs, IPROTO_TYPE_DML_MAX);
 
 	if (recovery_has_data(recovery_state)) {
 		/* Process existing snapshot */
@@ -417,18 +409,18 @@ box_init()
 			      cfg_getd("wal_dir_rescan_delay"));
 	title("hot_standby", NULL);
 
-	const char *primary_port = cfg_gets("primary_port");
-	const char *admin_port = cfg_gets("admin_port");
+	const char *listen = cfg_gets("listen");
+	const char *admin = cfg_gets("admin");
 
 	/*
 	 * application server configuration).
 	 */
-	if (!primary_port && !admin_port)
+	if (!listen && !admin)
 		box_leave_local_standby_mode(NULL);
 	else {
 		void (*on_bind)(void *) = NULL;
-		if (primary_port) {
-			iproto_init(primary_port);
+		if (listen) {
+			iproto_init(listen);
 		} else {
 			/*
 			 * If no prmary port is given, leave local
@@ -438,8 +430,8 @@ box_init()
 			 */
 			on_bind = box_leave_local_standby_mode;
 		}
-		if (admin_port)
-			admin_init(admin_port, on_bind);
+		if (admin)
+			admin_init(admin, on_bind);
 	}
 	if (cfg_getd("io_collect_interval") > 0) {
 		ev_set_io_collect_interval(loop(),
diff --git a/src/box/engine_sophia.cc b/src/box/engine_sophia.cc
index 3a06c76c0582600a10716d9c40cd508cd6cfa791..e595b3b8398c766a7e5f4fe7d20b82ebdfe087cb 100644
--- a/src/box/engine_sophia.cc
+++ b/src/box/engine_sophia.cc
@@ -175,6 +175,11 @@ SophiaFactory::keydefCheck(struct key_def *key_def)
 void
 SophiaFactory::txnFinish(struct txn *txn)
 {
-	if (txn->new_tuple)
-		tuple_ref(txn->new_tuple, -1);
+	/**
+	 * @todo: support multi-statement transactions
+	 * here when sophia supports them.
+	 */
+	struct txn_stmt *stmt = txn_stmt(txn);
+	if (stmt->new_tuple)
+		tuple_ref(stmt->new_tuple, -1);
 }
diff --git a/src/box/lua/call.cc b/src/box/lua/call.cc
index 2566692685b4cc765a8b13321f01b78bb6cfc285..3c6929f8ece83f63c7284a7fbed3242a63a24c5c 100644
--- a/src/box/lua/call.cc
+++ b/src/box/lua/call.cc
@@ -227,7 +227,7 @@ lbox_process(lua_State *L)
 
 void
 lbox_request_create(struct request *request,
-		    struct lua_State *L, enum iproto_request_type type,
+		    struct lua_State *L, enum iproto_type type,
 		    int key, int tuple)
 {
 	request_create(request, type);
@@ -382,7 +382,7 @@ lbox_raise(lua_State *L)
 	if (lua_gettop(L) < 2)
 		luaL_error(L, "box.raise(): bad arguments");
 	uint32_t code = lua_tointeger(L, 1);
-	if (!code)
+	if (code >= tnt_error_codes_enum_MAX)
 		luaL_error(L, "box.raise(): unknown error code");
 	const char *str = lua_tostring(L, 2);
 	tnt_raise(ClientError, str, code);
diff --git a/src/box/lua/load_cfg.lua b/src/box/lua/load_cfg.lua
index 02deb93aa92f36f7624927e3686047265490f7e0..6780aea771bf923c8c0c5fe1e69dd477e5a4d267 100644
--- a/src/box/lua/load_cfg.lua
+++ b/src/box/lua/load_cfg.lua
@@ -11,7 +11,7 @@ void box_set_too_long_threshold(double threshold);
 void box_set_snap_io_rate_limit(double limit);
 ]])
 
-local function normalize_port_uri(port)
+local function normalize_uri(port)
     if port == nil then
         return nil
     end
@@ -20,14 +20,14 @@ end
 
 -- arguments that can be number or string
 local wrapper_cfg = {
-    admin_port          = normalize_port_uri,
-    primary_port        = normalize_port_uri,
+    admin              = normalize_uri,
+    listen             = normalize_uri,
 }
 
 -- all available options
 local default_cfg = {
-    admin_port          = nil,
-    primary_port        = nil,
+    admin               = nil,
+    listen              = nil,
     slab_alloc_arena    = 1.0,
     slab_alloc_minimal  = 64,
     slab_alloc_factor   = 2.0,
diff --git a/src/box/lua/space.cc b/src/box/lua/space.cc
index 34bc808dfd4fb91dbd7094292152381125a88dae..3ba4207d3a1bf25baa6db07e38b1acffe53cd585 100644
--- a/src/box/lua/space.cc
+++ b/src/box/lua/space.cc
@@ -48,16 +48,16 @@ extern "C" {
 static void
 lbox_space_on_replace_trigger(struct trigger *trigger, void *event)
 {
-	struct txn *txn = (struct txn *) event;
+	struct txn_stmt *stmt = txn_stmt((struct txn *) event);
 	lua_State *L = lua_newthread(tarantool_L);
 	LuarefGuard coro_guard(tarantool_L);
 
 	lua_rawgeti(L, LUA_REGISTRYINDEX, (intptr_t) trigger->data);
 
-	lbox_pushtuple(L, txn->old_tuple);
-	lbox_pushtuple(L, txn->new_tuple);
+	lbox_pushtuple(L, stmt->old_tuple);
+	lbox_pushtuple(L, stmt->new_tuple);
 	/* @todo: maybe the space object has to be here */
-	lua_pushstring(L, txn->space->def.name);
+	lua_pushstring(L, stmt->space->def.name);
 
 	lbox_call(L, 3, 0);
 }
diff --git a/src/box/recovery.cc b/src/box/recovery.cc
index 25074974cd7cabec671895f18429c5afd0d6e4be..18e262595bd18d18aa19c3ff5240e207d55aa2ab 100644
--- a/src/box/recovery.cc
+++ b/src/box/recovery.cc
@@ -1126,8 +1126,7 @@ snapshot_write_row(struct log_io *l, struct iproto_header *row)
 	 * WAL. @sa the place which skips old rows in
 	 * recovery_process().
 	 */
-	if (iproto_request_is_dml(row->type))
-		row->lsn = ++l->rows;
+	row->lsn = ++l->rows;
 	row->sync = 0; /* don't write sync to wal */
 
 	struct iovec iov[XLOG_ROW_IOVMAX];
diff --git a/src/box/replica.cc b/src/box/replica.cc
index b8f6c73864aa1a27ca7fc40d2e672b5b010a86eb..b9c6a7be293d7e5053451a34d135a9f30da979f1 100644
--- a/src/box/replica.cc
+++ b/src/box/replica.cc
@@ -59,13 +59,11 @@ remote_read_row(struct ev_io *coio, struct iobuf *iobuf,
 			  "invalid fixed header");
 	}
 
-	const char *data = in->pos;
-	uint32_t len = mp_decode_uint(&data);
+	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");
 	}
-	in->pos += IPROTO_FIXHEADER_SIZE;
 
 	/* Read header and body */
 	ssize_t to_read = len - ibuf_size(in);
@@ -91,7 +89,7 @@ remote_connect(struct recovery_state *r, struct ev_io *coio,
 
 	evio_socket(coio, AF_INET, SOCK_STREAM, IPPROTO_TCP);
 
-	struct port_uri *uri = &r->remote.uri;
+	struct uri *uri = &r->remote.uri;
 
 	coio_connect(coio, &uri->addr, uri->addr_len);
 	coio_readn(coio, greeting, sizeof(greeting));
@@ -106,7 +104,8 @@ remote_connect(struct recovery_state *r, struct ev_io *coio,
 	iproto_encode_auth(&row, greeting, uri->login, uri->password);
 	remote_write_row(coio, &row);
 	remote_read_row(coio, iobuf, &row);
-	iproto_decode_error(&row); /* auth failed */
+	if (row.type != IPROTO_OK)
+		iproto_decode_error(&row); /* auth failed */
 
 	/* auth successed */
 	say_info("authenticated");
@@ -142,14 +141,14 @@ replica_bootstrap(struct recovery_state *r)
 	while (true) {
 		remote_read_row(&coio, iobuf, &row);
 
-		if (iproto_request_is_dml(row.type)) {
-			/* Regular snapshot row  (IPROTO_INSERT) */
-			recovery_process(r, &row);
-		} else if (row.type == IPROTO_JOIN) {
+		if (row.type == IPROTO_OK) {
 			/* End of stream */
 			say_info("done");
 			break;
-		} else {
+		} else if (iproto_type_is_dml(row.type)) {
+			/* Regular snapshot row  (IPROTO_INSERT) */
+			recovery_process(r, &row);
+		} else /* error or unexpected packet */ {
 			iproto_decode_error(&row);  /* rethrow error */
 		}
 	}
@@ -157,7 +156,7 @@ replica_bootstrap(struct recovery_state *r)
 	/* Decode end of stream packet */
 	struct vclock vclock;
 	vclock_create(&vclock);
-	assert(row.type == IPROTO_JOIN);
+	assert(row.type == IPROTO_OK);
 	iproto_decode_eos(&row, &vclock);
 
 	/* Replace server vclock using data from snapshot */
@@ -169,7 +168,7 @@ replica_bootstrap(struct recovery_state *r)
 static void
 remote_set_status(struct remote *remote, const char *status)
 {
-	title("replica", "%s/%s", port_uri_to_string(&remote->uri), status);
+	title("replica", "%s/%s", uri_to_string(&remote->uri), status);
 }
 
 static void
@@ -207,7 +206,7 @@ pull_from_remote(va_list ap)
 			}
 			err = "can't read row";
 			remote_read_row(&coio, iobuf, &row);
-			if (!iproto_request_is_dml(row.type))
+			if (!iproto_type_is_dml(row.type))
 				iproto_decode_error(&row);  /* error */
 			fiber_setcancellable(false);
 			err = NULL;
@@ -264,7 +263,7 @@ recovery_follow_remote(struct recovery_state *r)
 	assert(r->remote.reader == NULL);
 	assert(recovery_has_remote(r));
 
-	const char *uri = port_uri_to_string(&r->remote.uri);
+	const char *uri = uri_to_string(&r->remote.uri);
 	say_crit("starting replication from %s", uri);
 	snprintf(name, sizeof(name), "replica/%s", uri);
 
@@ -299,7 +298,7 @@ recovery_set_remote(struct recovery_state *r, const char *uri)
 	 * @todo: as long as DNS is involved, this may fail even
 	 * on a valid uri. Don't panic in this case.
 	 */
-	if (port_uri_parse(&r->remote.uri, uri))
+	if (uri_parse(&r->remote.uri, uri))
 		panic("Can't parse uri: %s", uri);
 	snprintf(r->remote.source,
 		 sizeof(r->remote.source), "%s", uri);
diff --git a/src/box/replica.h b/src/box/replica.h
index af7076d348895a35d0da44570e39b76111a3863b..bf6dbeb0117a1754d285eeca074b1b8ff3552e84 100644
--- a/src/box/replica.h
+++ b/src/box/replica.h
@@ -30,13 +30,13 @@
  */
 #include <netinet/in.h>
 #include "tarantool_ev.h"
-#include <port_uri.h>
+#include <uri.h>
 
 enum { REMOTE_SOURCE_MAXLEN = 64 };
 
 /** Master connection */
 struct remote {
-	struct port_uri uri;
+	struct uri uri;
 	struct fiber *reader;
 	ev_tstamp recovery_lag, recovery_last_update_tstamp;
 	char source[REMOTE_SOURCE_MAXLEN];
diff --git a/src/box/replication.cc b/src/box/replication.cc
index 8b410d13f09d47c5979b0ca100743d97a6856716..d91788d5eefc4a84c3448a4e5f74b48c69765421 100644
--- a/src/box/replication.cc
+++ b/src/box/replication.cc
@@ -629,6 +629,7 @@ replication_relay_recv(ev_loop * /* loop */, struct ev_io *w, int __attribute__(
 static void
 replication_relay_send_row(void * /* param */, struct iproto_header *packet)
 {
+	assert(iproto_type_is_dml(packet->type));
 	struct recovery_state *r = recovery_state;
 
 	/* Don't duplicate data */
@@ -639,14 +640,12 @@ replication_relay_send_row(void * /* param */, struct iproto_header *packet)
 		sio_writev_all(relay.sock, iov, iovcnt);
 	}
 
-	if (iproto_request_is_dml(packet->type)) {
-		/*
-		 * Update local vclock. During normal operation wal_write()
-		 * updates local vclock. In relay mode we have to update
-		 * it here.
-		 */
-		vclock_follow(&r->vclock, packet->server_id, packet->lsn);
-	}
+	/*
+	 * Update local vclock. During normal operation wal_write()
+	 * updates local vclock. In relay mode we have to update
+	 * it here.
+	 */
+	vclock_follow(&r->vclock, packet->server_id, packet->lsn);
 }
 
 static void
diff --git a/src/box/request.cc b/src/box/request.cc
index 5c8deca376917dcd866752c308105ce077d971cc..289a6ba3b4cb0c3b6d95e98af72d9f25ceb11ca1 100644
--- a/src/box/request.cc
+++ b/src/box/request.cc
@@ -50,7 +50,7 @@ dup_replace_mode(uint32_t op)
 static void
 execute_replace(struct request *request, struct port *port)
 {
-	struct txn *txn = txn_begin();
+	struct txn *txn = txn_begin_stmt(request);
 	struct space *space = space_cache_find(request->space_id);
 
 	space_check_access(space, PRIV_W);
@@ -60,15 +60,14 @@ execute_replace(struct request *request, struct port *port)
 	space_validate_tuple(space, new_tuple);
 	enum dup_replace_mode mode = dup_replace_mode(request->type);
 
-	txn_add_redo(txn, request);
 	txn_replace(txn, space, NULL, new_tuple, mode);
-	txn_commit(txn, port);
+	txn_commit_stmt(txn, port);
 }
 
 static void
 execute_update(struct request *request, struct port *port)
 {
-	struct txn *txn = txn_begin();
+	struct txn *txn = txn_begin_stmt(request);
 
 	/* Parse UPDATE request. */
 	/** Search key  and key part count. */
@@ -82,9 +81,8 @@ execute_update(struct request *request, struct port *port)
 	primary_key_validate(pk->key_def, key, part_count);
 	struct tuple *old_tuple = pk->findByKey(key, part_count);
 
-	txn_add_redo(txn, request);
 	if (old_tuple == NULL) {
-		txn_commit(txn, port);
+		txn_commit_stmt(txn, port);
 		return;
 	}
 
@@ -98,13 +96,13 @@ execute_update(struct request *request, struct port *port)
 	TupleGuard guard(new_tuple);
 	space_validate_tuple(space, new_tuple);
 	txn_replace(txn, space, old_tuple, new_tuple, DUP_INSERT);
-	txn_commit(txn, port);
+	txn_commit_stmt(txn, port);
 }
 
 static void
 execute_delete(struct request *request, struct port *port)
 {
-	struct txn *txn = txn_begin();
+	struct txn *txn = txn_begin_stmt(request);
 	(void) port;
 	struct space *space = space_cache_find(request->space_id);
 	space_check_access(space, PRIV_W);
@@ -116,17 +114,15 @@ execute_delete(struct request *request, struct port *port)
 	primary_key_validate(pk->key_def, key, part_count);
 	struct tuple *old_tuple = pk->findByKey(key, part_count);
 
-	txn_add_redo(txn, request);
 	if (old_tuple != NULL)
 		txn_replace(txn, space, old_tuple, NULL, DUP_REPLACE_OR_INSERT);
-	txn_commit(txn, port);
+	txn_commit_stmt(txn, port);
 }
 
 
 static void
 execute_select(struct request *request, struct port *port)
 {
-	struct txn *txn = txn_begin();
 	struct space *space = space_cache_find(request->space_id);
 	space_check_access(space, PRIV_R);
 	Index *index = index_find(space, request->index_id);
@@ -159,7 +155,6 @@ execute_select(struct request *request, struct port *port)
 			break;
 		port_add_tuple(port, tuple);
 	}
-	txn_commit(txn, port);
 }
 
 void
@@ -172,17 +167,11 @@ execute_auth(struct request *request, struct port * /* port */)
 
 /** }}} */
 
-void
-request_check_type(uint32_t type)
-{
-	if (type < IPROTO_SELECT || type >= IPROTO_DML_REQUEST_MAX)
-		tnt_raise(LoggedError, ER_UNKNOWN_REQUEST_TYPE, type);
-}
-
 void
 request_create(struct request *request, uint32_t type)
 {
-	request_check_type(type);
+	if (!iproto_type_is_dml(type))
+		tnt_raise(LoggedError, ER_UNKNOWN_REQUEST_TYPE, type);
 	static const request_execute_f execute_map[] = {
 		NULL, execute_select, execute_replace, execute_replace,
 		execute_update, execute_delete, box_lua_call,
diff --git a/src/box/schema.cc b/src/box/schema.cc
index 4abe1906d36e1c416ae907f725d39a91081f1bf6..a1b5c2e819a7b16ea615d77d1993da66b4353ea9 100644
--- a/src/box/schema.cc
+++ b/src/box/schema.cc
@@ -187,7 +187,7 @@ sc_space_new(struct space_def *space_def,
 	struct space *space = space_new(space_def, &key_list);
 	(void) space_cache_replace(space);
 	if (trigger)
-		trigger_set(&space->on_replace, trigger);
+		trigger_add(&space->on_replace, trigger);
 	/*
 	 * Data dictionary spaces are fully built since:
 	 * - they contain data right from the start
diff --git a/src/box/txn.cc b/src/box/txn.cc
index 52ab7b7a421519b7ecdb00597eeeb7ccde3157d0..4713ea4cdfe766eddb01b96ed7408462974a24b7 100644
--- a/src/box/txn.cc
+++ b/src/box/txn.cc
@@ -39,19 +39,10 @@
 
 double too_long_threshold;
 
-void
-port_send_tuple(struct port *port, struct txn *txn)
+static void
+txn_add_redo(struct txn_stmt *stmt, struct request *request)
 {
-	struct tuple *tuple;
-	if ((tuple = txn->new_tuple) || (tuple = txn->old_tuple))
-		port_add_tuple(port, tuple);
-}
-
-
-void
-txn_add_redo(struct txn *txn, struct request *request)
-{
-	txn->row = request->header;
+	stmt->row = request->header;
 	if (recovery_state->wal_mode == WAL_NONE || request->header != NULL)
 		return;
 
@@ -60,7 +51,7 @@ txn_add_redo(struct txn *txn, struct request *request)
 		region_alloc0(&fiber()->gc, sizeof(struct iproto_header));
 	row->type = request->type;
 	row->bodycnt = request_encode(request, row->body);
-	txn->row = row;
+	stmt->row = row;
 }
 
 void
@@ -68,18 +59,20 @@ txn_replace(struct txn *txn, struct space *space,
 	    struct tuple *old_tuple, struct tuple *new_tuple,
 	    enum dup_replace_mode mode)
 {
+	struct txn_stmt *stmt;
+	stmt = txn_stmt(txn);
 	assert(old_tuple || new_tuple);
 	/*
 	 * Remember the old tuple only if we replaced it
 	 * successfully, to not remove a tuple inserted by
 	 * another transaction in rollback().
 	 */
-	txn->old_tuple = space_replace(space, old_tuple, new_tuple, mode);
+	stmt->old_tuple = space_replace(space, old_tuple, new_tuple, mode);
 	if (new_tuple) {
-		txn->new_tuple = new_tuple;
-		tuple_ref(txn->new_tuple, 1);
+		stmt->new_tuple = new_tuple;
+		tuple_ref(stmt->new_tuple, 1);
 	}
-	txn->space = space;
+	stmt->space = space;
 	/*
 	 * Run on_replace triggers. For now, disallow mutation
 	 * of tuples in the trigger.
@@ -88,64 +81,97 @@ txn_replace(struct txn *txn, struct space *space,
 		trigger_run(&space->on_replace, txn);
 }
 
+/** Initialize a new stmt object within txn. */
+static struct txn_stmt *
+txn_stmt_new(struct txn *txn)
+{
+	assert(txn->n_stmts == 0 || !txn->autocommit);
+	struct txn_stmt *stmt;
+	if (txn->n_stmts++ == 1) {
+		stmt = &txn->stmt;
+	} else {
+		stmt = (struct txn_stmt *)
+			region_alloc0(&fiber()->gc, sizeof(struct txn_stmt));
+	}
+	rlist_add_tail_entry(&txn->stmts, stmt, next);
+	return stmt;
+}
+
 struct txn *
-txn_begin()
+txn_begin(bool autocommit)
 {
 	assert(! in_txn());
 	struct txn *txn = (struct txn *)
 		region_alloc0(&fiber()->gc, sizeof(*txn));
+	rlist_create(&txn->stmts);
 	rlist_create(&txn->on_commit);
 	rlist_create(&txn->on_rollback);
+	txn->autocommit = autocommit;
 	in_txn() = txn;
 	return txn;
 }
 
-/**
- * txn_finish() follows txn_commit() on success.
- * It's moved to a separate call to be able to send
- * old tuple to the user before it's deleted.
- */
-void
-txn_finish(struct txn *txn)
+struct txn *
+txn_begin_stmt(struct request *request)
 {
-	assert(txn == in_txn());
-	if (txn->old_tuple)
-		tuple_ref(txn->old_tuple, -1);
-	if (txn->space)
-		txn->space->engine->factory->txnFinish(txn);
-	TRASH(txn);
-	/** Free volatile txn memory. */
-	fiber_gc();
-	in_txn() = NULL;
+	struct txn *txn = in_txn();
+	if (txn == NULL)
+		txn = txn_begin(true);
+	struct txn_stmt *stmt = txn_stmt_new(txn);
+	txn_add_redo(stmt, request);
+	return txn;
 }
 
+void
+txn_commit_stmt(struct txn *txn, struct port *port)
+{
+	struct txn_stmt *stmt;
+	struct tuple *tuple;
+	stmt = txn_stmt(txn);
+	if ((tuple = stmt->new_tuple) || (tuple = stmt->old_tuple))
+		port_add_tuple(port, tuple);
+	if (txn->autocommit)
+		txn_commit(txn);
+}
 
 void
-txn_commit(struct txn *txn, struct port *port)
+txn_commit(struct txn *txn)
 {
 	assert(txn == in_txn());
-	if ((txn->old_tuple || txn->new_tuple) &&
-	    !space_is_temporary(txn->space)) {
+	struct txn_stmt *stmt;
+	rlist_foreach_entry(stmt, &txn->stmts, next) {
+		if ((!stmt->old_tuple && !stmt->new_tuple) ||
+		    space_is_temporary(stmt->space))
+			continue;
+
 		int res = 0;
 		/* txn_commit() must be done after txn_add_redo() */
 		assert(recovery_state->wal_mode == WAL_NONE ||
-		       txn->row != NULL);
+		       stmt->row != NULL);
 		ev_tstamp start = ev_now(loop()), stop;
-		res = wal_write(recovery_state, txn->row);
+		res = wal_write(recovery_state, stmt->row);
 		stop = ev_now(loop());
 
-		if (stop - start > too_long_threshold && txn->row != NULL) {
+		if (stop - start > too_long_threshold && stmt->row != NULL) {
 			say_warn("too long %s: %.3f sec",
-				iproto_request_name(txn->row->type),
-					stop - start);
+				 iproto_type_name(stmt->row->type),
+				 stop - start);
 		}
 
 		if (res)
 			tnt_raise(LoggedError, ER_WAL_IO);
 	}
 	trigger_run(&txn->on_commit, txn); /* must not throw. */
-	port_send_tuple(port, txn);
-	txn_finish(txn);
+	rlist_foreach_entry(stmt, &txn->stmts, next) {
+		if (stmt->old_tuple)
+			tuple_ref(stmt->old_tuple, -1);
+		if (stmt->space)
+			stmt->space->engine->factory->txnFinish(txn);
+	}
+	TRASH(txn);
+	/** Free volatile txn memory. */
+	fiber_gc();
+	in_txn() = NULL;
 }
 
 void
@@ -154,15 +180,29 @@ txn_rollback()
 	struct txn *txn = in_txn();
 	if (txn == NULL)
 		return;
-	if (txn->old_tuple || txn->new_tuple) {
-		space_replace(txn->space, txn->new_tuple,
-			      txn->old_tuple, DUP_INSERT);
-		trigger_run(&txn->on_rollback, txn); /* must not throw. */
-		if (txn->new_tuple)
-			tuple_ref(txn->new_tuple, -1);
+	struct txn_stmt *stmt;
+	rlist_foreach_entry_reverse(stmt, &txn->stmts, next) {
+		if (stmt->old_tuple || stmt->new_tuple) {
+			space_replace(stmt->space, stmt->new_tuple,
+				      stmt->old_tuple, DUP_INSERT);
+		}
+	}
+	trigger_run(&txn->on_rollback, txn); /* must not throw. */
+	rlist_foreach_entry(stmt, &txn->stmts, next) {
+		if (stmt->new_tuple)
+			tuple_ref(stmt->new_tuple, -1);
 	}
 	TRASH(txn);
 	/** Free volatile txn memory. */
 	fiber_gc();
 	in_txn() = NULL;
 }
+
+void
+txn_check_autocommit(struct txn *txn, const char *where)
+{
+	if (txn->autocommit == false) {
+		tnt_raise(ClientError, ER_UNSUPPORTED,
+			  where, "multi-statement transactions");
+	}
+}
diff --git a/src/box/txn.h b/src/box/txn.h
index 73a4db31f05a6227e919b25ecf70f5bcd4f5ed9b..06cd9c20ba9a631cfee9375817764771b09bdbe3 100644
--- a/src/box/txn.h
+++ b/src/box/txn.h
@@ -35,30 +35,92 @@ extern double too_long_threshold;
 struct tuple;
 struct space;
 
-struct txn {
-	/* Undo info. */
+/**
+ * A single statement of a multi-statement
+ * transaction: undo and redo info.
+ */
+struct txn_stmt {
+	/** Doubly linked list of all statements. */
+	struct rlist next;
+
+	/** Undo info. */
 	struct space *space;
 	struct tuple *old_tuple;
 	struct tuple *new_tuple;
 
-	struct rlist on_commit;
-	struct rlist on_rollback;
-
-	/* Redo log row: binary packet */
+	/** Redo info: the binary log row */
 	struct iproto_header *row;
 };
 
-/* pointer to the current multithreaded transaction (if any) */
+struct txn {
+	/** Pre-allocated first statement. */
+	struct txn_stmt stmt;
+	/** List of statements in a transaction. */
+	struct rlist stmts;
+	 /** Commit and rollback triggers */
+	struct rlist on_commit, on_rollback;
+	/** Total number of statements in this txn. */
+	int n_stmts;
+	/**
+	 * True if this transaction is running in autocommit mode
+	 * (statement end causes an automatic transaction commit).
+	 */
+	bool autocommit;
+};
+
+/* Pointer to the current transaction (if any) */
 #define in_txn() (fiber()->session->txn)
 
-struct txn *txn_begin();
-void txn_commit(struct txn *txn, struct port *port);
-void txn_finish(struct txn *txn);
-void txn_rollback();
+/**
+ * Start a new statement. If no current transaction,
+ * start a new transaction with autocommit = true.
+ */
+struct txn *
+txn_begin_stmt(struct request *request);
+
+/**
+ * End a statement. In autocommit mode, end
+ * the current transaction as well.
+ */
+void
+txn_commit_stmt(struct txn *txn, struct port *port);
+
+/**
+ * Start a transaction explicitly.
+ * @pre no transaction is active
+ */
+struct txn *
+txn_begin(bool autocommit);
+
+/**
+ * Commit a transaction.
+ * @pre txn == in_txn()
+ */
+void
+txn_commit(struct txn *txn);
+
+/** Rollback a transaction, if any. */
+void
+txn_rollback();
+
+/**
+ * Raise an error if this is a multi-statement
+ * transaction: DDL can not be part of a multi-statement
+ * transaction and must be run in autocommit mode.
+ */
+void
+txn_check_autocommit(struct txn *txn, const char *where);
+
+void
+txn_replace(struct txn *txn, struct space *space,
+	    struct tuple *old_tuple, struct tuple *new_tuple,
+	    enum dup_replace_mode mode);
 
-void txn_replace(struct txn *txn, struct space *space,
-		 struct tuple *old_tuple, struct tuple *new_tuple,
-		 enum dup_replace_mode mode);
-void txn_add_redo(struct txn *txn, struct request *request);
+/** Last statement of the transaction. */
+static inline struct txn_stmt *
+txn_stmt(struct txn *txn)
+{
+	return rlist_last_entry(&txn->stmts, struct txn_stmt, next);
+}
 
 #endif /* TARANTOOL_BOX_TXN_H_INCLUDED */
diff --git a/src/errcode.h b/src/errcode.h
index c3bc75e4a2eb770ccd9194b4cdf48e4409bb00cf..06034cd8e9b4df65011b9aaed14af6260a0c506a 100644
--- a/src/errcode.h
+++ b/src/errcode.h
@@ -49,7 +49,7 @@ enum { TNT_ERRMSG_MAX = 512 };
  */
 
 #define ERROR_CODES(_)					    \
-	/*  0 */_(ER_OK,			0, "OK") \
+	/*  0 */_(ER_UNKNOWN,			2, "Unknown error") \
 	/*  1 */_(ER_ILLEGAL_PARAMS,		2, "Illegal parameters, %s") \
 	/*  2 */_(ER_MEMORY_ISSUE,		1, "Failed to allocate %u bytes in %s for %s") \
 	/*  3 */_(ER_TUPLE_FOUND,		2, "Duplicate key exists in unique index %u") \
@@ -149,20 +149,7 @@ static inline const char *tnt_errcode_str(uint32_t errcode)
 	return tnt_error_codes[errcode].errstr;
 }
 
-
-/** Return a 4-byte numeric error code, with status flags. */
-
-
-static inline uint32_t tnt_errcode_val(uint32_t errcode)
-{
-	uint32_t errflags = errcode < tnt_error_codes_enum_MAX ?
-		tnt_error_codes[errcode].errflags : 2; /* non-recoverable */
-	return (errcode << 8) | errflags;
-}
-
-
 /** Return a description of the error. */
-
 static inline const char *tnt_errcode_desc(uint32_t errcode)
 {
 	if (errcode >= tnt_error_codes_enum_MAX)
diff --git a/src/evio.cc b/src/evio.cc
index ed71e6b52e66d2bd4d7255c3df89accc461e5b2f..2d4f8249aa6c72d4ba69421c20941cc6639f0ba4 100644
--- a/src/evio.cc
+++ b/src/evio.cc
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  */
 #include "evio.h"
-#include "port_uri.h"
+#include "uri.h"
 #include "scoped_guard.h"
 #include <stdio.h>
 #include <netinet/in.h>
@@ -228,7 +228,7 @@ evio_service_bind_and_listen(struct evio_service *service)
 			return -1;
 		}
 		say_info("bound to %s port %s", evio_service_name(service),
-			port_uri_to_string(&service->port));
+			uri_to_string(&service->port));
 
 		/* Invoke on_bind callback if it is set. */
 		if (service->on_bind)
@@ -273,7 +273,7 @@ evio_service_init(ev_loop *loop,
 	service->loop = loop;
 
 
-	if (port_uri_parse(&service->port, uri))
+	if (uri_parse(&service->port, uri))
 		tnt_raise(SocketError, -1,
 			  "invalid address for bind: %s", uri);
 
@@ -303,7 +303,7 @@ evio_service_start(struct evio_service *service)
 		say_warn("%s port %s is already in use, will "
 			 "retry binding after %lf seconds.",
 			 evio_service_name(service),
-			 port_uri_to_string(&service->port), BIND_RETRY_DELAY);
+			 uri_to_string(&service->port), BIND_RETRY_DELAY);
 
 		ev_timer_set(&service->timer,
 			     BIND_RETRY_DELAY, BIND_RETRY_DELAY);
diff --git a/src/evio.h b/src/evio.h
index 3043718a0cd908d85511e380d31d375bb56e54be..2ecdd547887865b1ddb12d680f189321cfef14c9 100644
--- a/src/evio.h
+++ b/src/evio.h
@@ -35,7 +35,7 @@
 #include <stdbool.h>
 #include "tarantool_ev.h"
 #include "sio.h"
-#include "port_uri.h"
+#include "uri.h"
 /**
  * Exception-aware way to add a listening socket to the event
  * loop. Callbacks are invoked on bind and accept events.
@@ -65,7 +65,7 @@ struct evio_service
 	char name[SERVICE_NAME_MAXLEN];
 
 	/** Interface/port to bind to */
-	struct port_uri port;
+	struct uri port;
 
 	/** A callback invoked upon a successful bind, optional.
 	 * If on_bind callback throws an exception, it's
diff --git a/src/iproto.cc b/src/iproto.cc
index 1ac623a71ca0343364282f08ceb782960ce026db..f6a14bcdc731dd376cb88a473373d26748903255 100644
--- a/src/iproto.cc
+++ b/src/iproto.cc
@@ -471,18 +471,12 @@ iproto_enqueue_batch(struct iproto_connection *con, struct ibuf *in)
 		const char *pos = reqstart;
 		/* Read request length. */
 		if (mp_typeof(*pos) != MP_UINT) {
-error:
 			tnt_raise(ClientError, ER_INVALID_MSGPACK,
 				  "packet length");
 		}
 		if (mp_check_uint(pos, in->end) >= 0)
 			break;
 		uint32_t len = mp_decode_uint(&pos);
-		/* Skip optional request padding. */
-		if (pos < in->end && mp_typeof(*pos) == MP_STR &&
-		    mp_check(&pos, in->end)) {
-			goto error;
-		}
 		const char *reqend = pos + len;
 		if (reqend > in->end)
 			break;
@@ -499,7 +493,7 @@ iproto_enqueue_batch(struct iproto_connection *con, struct ibuf *in)
 		 * as well as in->pos must not be advanced, to
 		 * stay in sync.
 		 */
-		if (iproto_request_is_dml(ireq->header.type)) {
+		if (iproto_type_is_dml(ireq->header.type)) {
 			if (ireq->header.bodycnt == 0) {
 				tnt_raise(ClientError, ER_INVALID_MSGPACK,
 					  "request type");
diff --git a/src/iproto_constants.cc b/src/iproto_constants.cc
index 5b63996b8fa93a605a41407c77f383011f13a7de..b9207d9eb92d475dc26f3b7e27f490404f809edb 100644
--- a/src/iproto_constants.cc
+++ b/src/iproto_constants.cc
@@ -93,7 +93,7 @@ const unsigned char iproto_key_type[IPROTO_KEY_MAX] =
 	/* }}} */
 };
 
-const char *iproto_request_type_strs[] =
+const char *iproto_type_strs[] =
 {
 	NULL,
 	"SELECT",
@@ -106,7 +106,7 @@ const char *iproto_request_type_strs[] =
 };
 
 #define bit(c) (1ULL<<IPROTO_##c)
-const uint64_t iproto_body_key_map[IPROTO_DML_REQUEST_MAX + 1] = {
+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 */
@@ -297,19 +297,11 @@ iproto_row_encode(const struct iproto_header *row,
 		len += out[i].iov_len;
 
 	/* Encode length */
+	assert(IPROTO_FIXHEADER_SIZE == mp_sizeof_uint(UINT32_MAX));
 	char *data = fixheader;
-	data = mp_encode_uint(data, len);
-	/* Encode padding */
-	ssize_t padding = IPROTO_FIXHEADER_SIZE - (data - fixheader);
-	if (padding > 0) {
-		data = mp_encode_strl(data, padding - 1);
-#if defined(NDEBUG)
-		data += padding - 1;
-#else
-		while (--padding > 0)
-			*(data++) = 0; /* valgrind */
-#endif
-	}
+	*(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;
@@ -357,9 +349,8 @@ iproto_encode_auth(struct iproto_header *packet, const char *greeting,
 void
 iproto_decode_error(struct iproto_header *row)
 {
-	uint32_t code = row->type >> 8;
-	if (likely(code == 0))
-		return;
+	uint32_t code = row->type & (IPROTO_TYPE_ERROR - 1);
+
 	char error[TNT_ERRMSG_MAX] = { 0 };
 	const char *pos;
 	uint32_t map_size;
@@ -535,5 +526,5 @@ iproto_encode_eos(struct iproto_header *row, const struct vclock *vclock)
 	row->body[0].iov_base = buf;
 	row->body[0].iov_len = (data - buf);
 	row->bodycnt = 1;
-	row->type = IPROTO_JOIN;
+	row->type = IPROTO_OK;
 }
diff --git a/src/iproto_constants.h b/src/iproto_constants.h
index f768cde68654a987c378e96c684adec113f4d5f0..0f79ed989b7f6c642847f2ea0d87a42509cdef46 100644
--- a/src/iproto_constants.h
+++ b/src/iproto_constants.h
@@ -105,7 +105,13 @@ iproto_key_bit(unsigned char key)
 
 extern const unsigned char iproto_key_type[IPROTO_KEY_MAX];
 
-enum iproto_request_type {
+/**
+ * IPROTO command codes
+ */
+enum iproto_type {
+	/* command is successful */
+	IPROTO_OK = 0,
+	/* dml command codes */
 	IPROTO_SELECT = 1,
 	IPROTO_INSERT = 2,
 	IPROTO_REPLACE = 3,
@@ -113,36 +119,46 @@ enum iproto_request_type {
 	IPROTO_DELETE = 5,
 	IPROTO_CALL = 6,
 	IPROTO_AUTH = 7,
-	IPROTO_DML_REQUEST_MAX = 8,
+	IPROTO_TYPE_DML_MAX = IPROTO_AUTH + 1,
+	/* admin command codes */
 	IPROTO_PING = 64,
 	IPROTO_JOIN = 65,
-	IPROTO_SUBSCRIBE = 66
+	IPROTO_SUBSCRIBE = 66,
+	IPROTO_TYPE_ADMIN_MAX = IPROTO_SUBSCRIBE + 1,
+	/* command failed = (IPROTO_TYPE_ERROR | ER_XXX from errcode.h) */
+	IPROTO_TYPE_ERROR = 1 << 15
 };
 
-extern const char *iproto_request_type_strs[];
+extern const char *iproto_type_strs[];
 /** Key names. */
 extern const char *iproto_key_strs[];
 /** A map of mandatory members of an iproto DML request. */
 extern const uint64_t iproto_body_key_map[];
 
 static inline const char *
-iproto_request_name(uint32_t type)
+iproto_type_name(uint32_t type)
 {
-	if (type >= IPROTO_DML_REQUEST_MAX)
+	if (type >= IPROTO_TYPE_DML_MAX)
 		return "unknown";
-	return iproto_request_type_strs[type];
+	return iproto_type_strs[type];
 }
 
 static inline bool
-iproto_request_is_select(uint32_t type)
+iproto_type_is_select(uint32_t type)
 {
 	return type <= IPROTO_SELECT || type == IPROTO_CALL;
 }
 
 static inline bool
-iproto_request_is_dml(uint32_t type)
+iproto_type_is_dml(uint32_t type)
 {
-	return type < IPROTO_DML_REQUEST_MAX;
+	return type >= IPROTO_SELECT && type < IPROTO_TYPE_DML_MAX;
+}
+
+static inline bool
+iproto_type_is_error(uint32_t type)
+{
+	return (type & IPROTO_TYPE_ERROR) != 0;
 }
 
 enum {
@@ -177,6 +193,13 @@ 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);
diff --git a/src/iproto_port.cc b/src/iproto_port.cc
index a51bf1f6f7674b7bbd0af9c5f592ac3b7e97a5c1..5a2f0ce1de764f2b8a8fee7d8c80ca2371eee83f 100644
--- a/src/iproto_port.cc
+++ b/src/iproto_port.cc
@@ -80,7 +80,7 @@ iproto_reply_error(struct obuf *out, const ClientError *e, uint64_t sync)
 
 	uint32_t len = sizeof(header) - 5 + sizeof(body) + msg_len;
 	header.v_len = mp_bswap_u32(len);
-	header.v_code = mp_bswap_u32(tnt_errcode_val(e->errcode()));
+	header.v_code = mp_bswap_u32(iproto_encode_error(e->errcode()));
 	header.v_sync = mp_bswap_u64(sync);
 
 	body.v_data_len = mp_bswap_u32(msg_len);
diff --git a/src/lua/box_net_box.lua b/src/lua/box_net_box.lua
index 2f2a936772a3e79a5b5fdba7fceab743dde2d4b1..ae76dc81bb1d713496fd05b3bdd623d06b85d887 100644
--- a/src/lua/box_net_box.lua
+++ b/src/lua/box_net_box.lua
@@ -9,8 +9,8 @@ local ffi = require 'ffi'
 local digest = require 'digest'
 local yaml = require 'yaml'
 
-local CODE              = 0
-local PING              = 64
+-- packet codes
+local OK                = 0
 local SELECT            = 1
 local INSERT            = 2
 local REPLACE           = 3
@@ -18,6 +18,10 @@ local UPDATE            = 4
 local DELETE            = 5
 local CALL              = 6
 local AUTH              = 7
+local PING              = 64
+local ERROR_TYPE        = 65536
+
+-- packet keys
 local TYPE              = 0x00
 local SYNC              = 0x01
 local SPACE_ID          = 0x10
@@ -375,7 +379,7 @@ local remote_methods = {
             return false
         end
 
-        if res.hdr[CODE] == 0 then
+        if res.hdr[TYPE] == OK then
             return true
         end
         return false
@@ -470,8 +474,7 @@ local remote_methods = {
         for sync, channel in pairs(waiters) do
             channel:put{
                 hdr = {
-                    [TYPE] = ERROR,
-                    [CODE] = box.error.NO_CONNECTION,
+                    [TYPE] = bit.bor(ERROR_TYPE, box.error.NO_CONNECTION),
                     [SYNC] = sync
                 },
                 body = {
@@ -644,7 +647,7 @@ local remote_methods = {
         local auth_res = self:_request_internal('auth',
             false, self.opts.user, self.opts.password, self.handshake)
 
-        if auth_res.hdr[CODE] ~= 0 then
+        if auth_res.hdr[TYPE] ~= OK then
             self:_fatal(auth_res.body[ERROR])
             return
         end
@@ -853,7 +856,7 @@ local remote_methods = {
                 box.raise(box.error.TIMEOUT, 'Timeout exceeded')
             else
                 return {
-                    hdr = { [CODE] = box.error.TIMEOUT },
+                    hdr = { [TYPE] = bit.bor(ERROR_TYPE, box.error.TIMEOUT) },
                     body = { [ERROR] = 'Timeout exceeded' }
                 }
             end
@@ -893,14 +896,15 @@ local remote_methods = {
                 box.raise(box.error.TIMEOUT, 'Timeout exceeded')
             else
                 return {
-                    hdr = { [CODE] = box.error.TIMEOUT },
+                    hdr = { [TYPE] = bit.bor(ERROR_TYPE, box.error.TIMEOUT) },
                     body = { [ERROR] = 'Timeout exceeded' }
                 }
             end
         end
 
-        if raise and response.hdr[CODE] ~= 0 then
-            box.raise(response.hdr[CODE], response.body[ERROR])
+        if raise and response.hdr[TYPE] ~= OK then
+            local errcode = bit.band(response.hdr[TYPE], ERROR - 1)
+            box.raise(errcode, response.body[ERROR])
         end
 
         if response.body[DATA] ~= nil then
diff --git a/src/lua/trigger.cc b/src/lua/trigger.cc
index 86506156f18d03efb34fd5a1c56a561e169578e9..6ffa2a5ed23a049ba78178ffab7a72303f561f8d 100644
--- a/src/lua/trigger.cc
+++ b/src/lua/trigger.cc
@@ -101,7 +101,7 @@ lbox_trigger_reset(struct lua_State *L, int top,
 				luaL_error(L, "failed to allocate trigger");
 			trg->run = run;
 			trg->destroy = lbox_trigger_destroy;
-			trigger_set(list, trg);
+			trigger_add(list, trg);
 		}
 		/*
 		 * Make the new trigger occupy the top
diff --git a/src/tarantool.cc b/src/tarantool.cc
index bc9700996019cc263b3e59c061d4690060439d27..d9ca591089eb6e8cd3fc14305de7798182e63183 100644
--- a/src/tarantool.cc
+++ b/src/tarantool.cc
@@ -109,27 +109,6 @@ title(const char *role, const char *fmt, ...)
 		bufptr += snprintf(bufptr, bufend - bufptr, "%s", s);
 	}
 
-#if 0
-	/**
-	 * The below code is broken for two reasons:
-	 * - primary_port and admin_port are no longer integers,
-	 *   but strings
-	 * - title is used in forks, and cfg_geti doesn't work
-	 *   in a fork, since Lua interpreter state is not
-	 *   fork-safe. And it is not fork-safe because it
-	 *   refers to tuple objects, which are not fork-safe.
-	 */
-	int ports[] = { cfg_geti("primary_port"), cfg_geti("admin_port") };
-	int *pptr = ports;
-	const char *names[] = { "pri", "adm", NULL };
-	const char **nptr = names;
-
-	for (; *nptr; nptr++, pptr++)
-		if (*pptr)
-			bufptr += snprintf(bufptr, bufend - bufptr,
-					   " %s: %i", *nptr, *pptr);
-#endif
-
 	set_proc_title(buf);
 }
 
diff --git a/src/trigger.h b/src/trigger.h
index 9bf3439cbdeded75652e6e6a50044f866fce1876..d230c3d88a1694407a007039c1cd3f5ea65f7580 100644
--- a/src/trigger.h
+++ b/src/trigger.h
@@ -61,7 +61,7 @@ trigger_run(struct rlist *list, void *event)
 }
 
 static inline void
-trigger_set(struct rlist *list, struct trigger *trigger)
+trigger_add(struct rlist *list, struct trigger *trigger)
 {
 	/*
 	 * New triggers are pushed to the beginning of the list.
@@ -75,6 +75,17 @@ trigger_set(struct rlist *list, struct trigger *trigger)
 	rlist_add_entry(list, trigger, link);
 }
 
+static inline void
+trigger_add_unique(struct rlist *list, struct trigger *trigger)
+{
+	struct trigger *trg;
+	rlist_foreach_entry(trg, list, link) {
+		if (trg->data == trigger->data && trg->run == trigger->run)
+			return;
+	}
+	trigger_add(list, trigger);
+}
+
 static inline void
 trigger_clear(struct trigger *trigger)
 {
diff --git a/src/port_uri.cc b/src/uri.cc
similarity index 93%
rename from src/port_uri.cc
rename to src/uri.cc
index 5f1e0efb0213ecde8b2c2a984a58ffc21441106b..d970ef6ee7c4298af81a356ef1d1c84e854848fb 100644
--- a/src/port_uri.cc
+++ b/src/uri.cc
@@ -1,5 +1,5 @@
 
-#line 1 "src/port_uri.rl"
+#line 1 "src/uri.rl"
 /*
  * Redistribution and use in source and binary forms, with or
  * without modification, are permitted provided that the following
@@ -28,7 +28,7 @@
  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include "port_uri.h"
+#include "uri.h"
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -41,7 +41,7 @@
 #include <netdb.h>
 
 const char *
-port_uri_to_string(const struct port_uri * uri)
+uri_to_string(const struct uri * uri)
 {
 	static __thread char
 		str[NI_MAXSERV + NI_MAXHOST + sizeof(uri->schema)];
@@ -98,7 +98,7 @@ port_uri_to_string(const struct port_uri * uri)
 }
 
 int
-port_uri_parse(struct port_uri *uri, const char *p)
+uri_parse(struct uri *uri, const char *p)
 {
 	(void) uri;
 	const char *pe = p + strlen(p);
@@ -124,20 +124,20 @@ port_uri_parse(struct port_uri *uri, const char *p)
 	unsigned port = 0;
 
 	
-#line 128 "src/port_uri.cc"
-static const int port_uri_start = 1;
-static const int port_uri_first_final = 74;
-static const int port_uri_error = 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 port_uri_en_main = 1;
+static const int uri_en_main = 1;
 
 
-#line 136 "src/port_uri.cc"
+#line 136 "src/uri.cc"
 	{
-	cs = port_uri_start;
+	cs = uri_start;
 	}
 
-#line 141 "src/port_uri.cc"
+#line 141 "src/uri.cc"
 	{
 	if ( p == pe )
 		goto _test_eof;
@@ -162,46 +162,46 @@ case 1:
 		goto tr5;
 	goto tr0;
 tr0:
-#line 157 "src/port_uri.rl"
+#line 157 "src/uri.rl"
 	{ host.start   = p; }
 	goto st74;
 tr82:
-#line 133 "src/port_uri.rl"
+#line 133 "src/uri.rl"
 	{ schema.end   = p - 3; }
-#line 157 "src/port_uri.rl"
+#line 157 "src/uri.rl"
 	{ host.start   = p; }
 	goto st74;
 st74:
 	if ( ++p == pe )
 		goto _test_eof74;
 case 74:
-#line 179 "src/port_uri.cc"
+#line 179 "src/uri.cc"
 	switch( (*p) ) {
 		case 58: goto tr94;
 		case 63: goto st0;
 	}
 	goto st74;
 tr94:
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
 	goto st2;
 tr144:
-#line 145 "src/port_uri.rl"
+#line 145 "src/uri.rl"
 	{ ip4.end   = p; }
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
 	goto st2;
 tr157:
-#line 154 "src/port_uri.rl"
+#line 154 "src/uri.rl"
 	{ ip6.end   = p - 1; }
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
 	goto st2;
 st2:
 	if ( ++p == pe )
 		goto _test_eof2;
 case 2:
-#line 205 "src/port_uri.cc"
+#line 205 "src/uri.cc"
 	if ( (*p) < 65 ) {
 		if ( 49 <= (*p) && (*p) <= 57 )
 			goto tr8;
@@ -215,34 +215,34 @@ case 2:
 cs = 0;
 	goto _out;
 tr8:
-#line 166 "src/port_uri.rl"
+#line 166 "src/uri.rl"
 	{ service.start = p; }
-#line 161 "src/port_uri.rl"
+#line 161 "src/uri.rl"
 	{ dport.start   = p; port = 0; }
-#line 162 "src/port_uri.rl"
+#line 162 "src/uri.rl"
 	{ port = port * 10 + (int)(*p - '0'); }
 	goto st75;
 tr95:
-#line 162 "src/port_uri.rl"
+#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/port_uri.cc"
+#line 234 "src/uri.cc"
 	if ( 48 <= (*p) && (*p) <= 57 )
 		goto tr95;
 	goto st0;
 tr9:
-#line 166 "src/port_uri.rl"
+#line 166 "src/uri.rl"
 	{ service.start = p; }
 	goto st76;
 st76:
 	if ( ++p == pe )
 		goto _test_eof76;
 case 76:
-#line 246 "src/port_uri.cc"
+#line 246 "src/uri.cc"
 	if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
 			goto st77;
@@ -395,16 +395,16 @@ case 90:
 case 91:
 	goto st0;
 tr1:
-#line 157 "src/port_uri.rl"
+#line 157 "src/uri.rl"
 	{ host.start   = p; }
-#line 176 "src/port_uri.rl"
+#line 176 "src/uri.rl"
 	{ path.start = p; }
 	goto st92;
 st92:
 	if ( ++p == pe )
 		goto _test_eof92;
 case 92:
-#line 408 "src/port_uri.cc"
+#line 408 "src/uri.cc"
 	switch( (*p) ) {
 		case 58: goto tr112;
 		case 63: goto st95;
@@ -420,14 +420,14 @@ case 93:
 	}
 	goto st93;
 tr112:
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
 	goto st94;
 st94:
 	if ( ++p == pe )
 		goto _test_eof94;
 case 94:
-#line 431 "src/port_uri.cc"
+#line 431 "src/uri.cc"
 	if ( (*p) < 65 ) {
 		if ( 49 <= (*p) && (*p) <= 57 )
 			goto tr114;
@@ -443,34 +443,34 @@ case 94:
 case 95:
 	goto st95;
 tr114:
-#line 166 "src/port_uri.rl"
+#line 166 "src/uri.rl"
 	{ service.start = p; }
-#line 161 "src/port_uri.rl"
+#line 161 "src/uri.rl"
 	{ dport.start   = p; port = 0; }
-#line 162 "src/port_uri.rl"
+#line 162 "src/uri.rl"
 	{ port = port * 10 + (int)(*p - '0'); }
 	goto st96;
 tr116:
-#line 162 "src/port_uri.rl"
+#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/port_uri.cc"
+#line 462 "src/uri.cc"
 	if ( 48 <= (*p) && (*p) <= 57 )
 		goto tr116;
 	goto st95;
 tr115:
-#line 166 "src/port_uri.rl"
+#line 166 "src/uri.rl"
 	{ service.start = p; }
 	goto st97;
 st97:
 	if ( ++p == pe )
 		goto _test_eof97;
 case 97:
-#line 474 "src/port_uri.cc"
+#line 474 "src/uri.cc"
 	if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
 			goto st98;
@@ -623,28 +623,28 @@ case 111:
 case 112:
 	goto st95;
 tr2:
-#line 136 "src/port_uri.rl"
+#line 136 "src/uri.rl"
 	{ login.start  = p; }
-#line 157 "src/port_uri.rl"
+#line 157 "src/uri.rl"
 	{ host.start   = p; }
-#line 144 "src/port_uri.rl"
+#line 144 "src/uri.rl"
 	{ ip4.start = p; }
 	goto st113;
 tr83:
-#line 133 "src/port_uri.rl"
+#line 133 "src/uri.rl"
 	{ schema.end   = p - 3; }
-#line 136 "src/port_uri.rl"
+#line 136 "src/uri.rl"
 	{ login.start  = p; }
-#line 157 "src/port_uri.rl"
+#line 157 "src/uri.rl"
 	{ host.start   = p; }
-#line 144 "src/port_uri.rl"
+#line 144 "src/uri.rl"
 	{ ip4.start = p; }
 	goto st113;
 st113:
 	if ( ++p == pe )
 		goto _test_eof113;
 case 113:
-#line 648 "src/port_uri.cc"
+#line 648 "src/uri.cc"
 	switch( (*p) ) {
 		case 46: goto st114;
 		case 58: goto tr134;
@@ -828,18 +828,18 @@ case 127:
 		goto st128;
 	goto st74;
 tr84:
-#line 133 "src/port_uri.rl"
+#line 133 "src/uri.rl"
 	{ schema.end   = p - 3; }
-#line 136 "src/port_uri.rl"
+#line 136 "src/uri.rl"
 	{ login.start  = p; }
-#line 157 "src/port_uri.rl"
+#line 157 "src/uri.rl"
 	{ host.start   = p; }
 	goto st128;
 st128:
 	if ( ++p == pe )
 		goto _test_eof128;
 case 128:
-#line 843 "src/port_uri.cc"
+#line 843 "src/uri.cc"
 	switch( (*p) ) {
 		case 58: goto tr134;
 		case 63: goto st0;
@@ -854,16 +854,16 @@ case 128:
 		goto st128;
 	goto st74;
 tr134:
-#line 137 "src/port_uri.rl"
+#line 137 "src/uri.rl"
 	{ login.end    = p; }
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
 	goto st3;
 st3:
 	if ( ++p == pe )
 		goto _test_eof3;
 case 3:
-#line 867 "src/port_uri.cc"
+#line 867 "src/uri.cc"
 	if ( (*p) == 48 )
 		goto tr10;
 	if ( (*p) < 65 ) {
@@ -876,14 +876,14 @@ case 3:
 		goto tr12;
 	goto st0;
 tr10:
-#line 140 "src/port_uri.rl"
+#line 140 "src/uri.rl"
 	{ password.start = p; }
 	goto st4;
 st4:
 	if ( ++p == pe )
 		goto _test_eof4;
 case 4:
-#line 887 "src/port_uri.cc"
+#line 887 "src/uri.cc"
 	if ( (*p) == 64 )
 		goto tr14;
 	if ( (*p) < 65 ) {
@@ -896,14 +896,14 @@ case 4:
 		goto st4;
 	goto st0;
 tr14:
-#line 141 "src/port_uri.rl"
+#line 141 "src/uri.rl"
 	{ password.end   = p; }
 	goto st5;
 st5:
 	if ( ++p == pe )
 		goto _test_eof5;
 case 5:
-#line 907 "src/port_uri.cc"
+#line 907 "src/uri.cc"
 	switch( (*p) ) {
 		case 58: goto st0;
 		case 63: goto st0;
@@ -913,16 +913,16 @@ case 5:
 		goto tr15;
 	goto tr0;
 tr15:
-#line 157 "src/port_uri.rl"
+#line 157 "src/uri.rl"
 	{ host.start   = p; }
-#line 144 "src/port_uri.rl"
+#line 144 "src/uri.rl"
 	{ ip4.start = p; }
 	goto st129;
 st129:
 	if ( ++p == pe )
 		goto _test_eof129;
 case 129:
-#line 926 "src/port_uri.cc"
+#line 926 "src/uri.cc"
 	switch( (*p) ) {
 		case 46: goto st114;
 		case 58: goto tr94;
@@ -954,24 +954,24 @@ case 131:
 	}
 	goto st74;
 tr6:
-#line 157 "src/port_uri.rl"
+#line 157 "src/uri.rl"
 	{ host.start   = p; }
-#line 153 "src/port_uri.rl"
+#line 153 "src/uri.rl"
 	{ ip6.start = p + 1; }
 	goto st132;
 tr85:
-#line 133 "src/port_uri.rl"
+#line 133 "src/uri.rl"
 	{ schema.end   = p - 3; }
-#line 157 "src/port_uri.rl"
+#line 157 "src/uri.rl"
 	{ host.start   = p; }
-#line 153 "src/port_uri.rl"
+#line 153 "src/uri.rl"
 	{ ip6.start = p + 1; }
 	goto st132;
 st132:
 	if ( ++p == pe )
 		goto _test_eof132;
 case 132:
-#line 975 "src/port_uri.cc"
+#line 975 "src/uri.cc"
 	switch( (*p) ) {
 		case 58: goto tr152;
 		case 63: goto st0;
@@ -1046,14 +1046,14 @@ case 136:
 	}
 	goto st74;
 tr154:
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
 	goto st6;
 st6:
 	if ( ++p == pe )
 		goto _test_eof6;
 case 6:
-#line 1057 "src/port_uri.cc"
+#line 1057 "src/uri.cc"
 	switch( (*p) ) {
 		case 48: goto st7;
 		case 58: goto st11;
@@ -1671,18 +1671,18 @@ case 137:
 		goto tr157;
 	goto st0;
 tr17:
-#line 166 "src/port_uri.rl"
+#line 166 "src/uri.rl"
 	{ service.start = p; }
-#line 161 "src/port_uri.rl"
+#line 161 "src/uri.rl"
 	{ dport.start   = p; port = 0; }
-#line 162 "src/port_uri.rl"
+#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/port_uri.cc"
+#line 1686 "src/uri.cc"
 	switch( (*p) ) {
 		case 58: goto st11;
 		case 93: goto st137;
@@ -1697,14 +1697,14 @@ case 138:
 		goto st8;
 	goto st0;
 tr158:
-#line 162 "src/port_uri.rl"
+#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/port_uri.cc"
+#line 1708 "src/uri.cc"
 	switch( (*p) ) {
 		case 58: goto st11;
 		case 93: goto st137;
@@ -1719,14 +1719,14 @@ case 139:
 		goto st9;
 	goto st0;
 tr159:
-#line 162 "src/port_uri.rl"
+#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/port_uri.cc"
+#line 1730 "src/uri.cc"
 	switch( (*p) ) {
 		case 58: goto st11;
 		case 93: goto st137;
@@ -1741,14 +1741,14 @@ case 140:
 		goto st10;
 	goto st0;
 tr160:
-#line 162 "src/port_uri.rl"
+#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/port_uri.cc"
+#line 1752 "src/uri.cc"
 	switch( (*p) ) {
 		case 58: goto st11;
 		case 93: goto st137;
@@ -1757,14 +1757,14 @@ case 141:
 		goto tr95;
 	goto st0;
 tr19:
-#line 166 "src/port_uri.rl"
+#line 166 "src/uri.rl"
 	{ service.start = p; }
 	goto st142;
 st142:
 	if ( ++p == pe )
 		goto _test_eof142;
 case 142:
-#line 1768 "src/port_uri.cc"
+#line 1768 "src/uri.cc"
 	switch( (*p) ) {
 		case 58: goto st11;
 		case 93: goto st137;
@@ -1845,14 +1845,14 @@ case 145:
 		goto st80;
 	goto st0;
 tr152:
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
 	goto st46;
 st46:
 	if ( ++p == pe )
 		goto _test_eof46;
 case 46:
-#line 1856 "src/port_uri.cc"
+#line 1856 "src/uri.cc"
 	switch( (*p) ) {
 		case 48: goto st7;
 		case 58: goto st47;
@@ -1976,14 +1976,14 @@ case 52:
 		goto st17;
 	goto st0;
 tr64:
-#line 144 "src/port_uri.rl"
+#line 144 "src/uri.rl"
 	{ ip4.start = p; }
 	goto st53;
 st53:
 	if ( ++p == pe )
 		goto _test_eof53;
 case 53:
-#line 1987 "src/port_uri.cc"
+#line 1987 "src/uri.cc"
 	switch( (*p) ) {
 		case 46: goto st54;
 		case 58: goto st21;
@@ -2063,14 +2063,14 @@ case 61:
 		goto tr75;
 	goto st0;
 tr75:
-#line 145 "src/port_uri.rl"
+#line 145 "src/uri.rl"
 	{ ip4.end   = p; }
 	goto st146;
 st146:
 	if ( ++p == pe )
 		goto _test_eof146;
 case 146:
-#line 2074 "src/port_uri.cc"
+#line 2074 "src/uri.cc"
 	if ( (*p) == 58 )
 		goto tr94;
 	goto st0;
@@ -2143,24 +2143,24 @@ case 67:
 		goto st20;
 	goto st0;
 tr11:
-#line 140 "src/port_uri.rl"
+#line 140 "src/uri.rl"
 	{ password.start = p; }
-#line 166 "src/port_uri.rl"
+#line 166 "src/uri.rl"
 	{ service.start = p; }
-#line 161 "src/port_uri.rl"
+#line 161 "src/uri.rl"
 	{ dport.start   = p; port = 0; }
-#line 162 "src/port_uri.rl"
+#line 162 "src/uri.rl"
 	{ port = port * 10 + (int)(*p - '0'); }
 	goto st147;
 tr164:
-#line 162 "src/port_uri.rl"
+#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/port_uri.cc"
+#line 2164 "src/uri.cc"
 	if ( (*p) == 64 )
 		goto tr14;
 	if ( (*p) < 65 ) {
@@ -2173,16 +2173,16 @@ case 147:
 		goto st4;
 	goto st0;
 tr12:
-#line 140 "src/port_uri.rl"
+#line 140 "src/uri.rl"
 	{ password.start = p; }
-#line 166 "src/port_uri.rl"
+#line 166 "src/uri.rl"
 	{ service.start = p; }
 	goto st148;
 st148:
 	if ( ++p == pe )
 		goto _test_eof148;
 case 148:
-#line 2186 "src/port_uri.cc"
+#line 2186 "src/uri.cc"
 	if ( (*p) == 64 )
 		goto tr14;
 	if ( (*p) < 65 ) {
@@ -2420,22 +2420,22 @@ case 163:
 		goto st4;
 	goto st0;
 tr3:
-#line 136 "src/port_uri.rl"
+#line 136 "src/uri.rl"
 	{ login.start  = p; }
-#line 157 "src/port_uri.rl"
+#line 157 "src/uri.rl"
 	{ host.start   = p; }
-#line 144 "src/port_uri.rl"
+#line 144 "src/uri.rl"
 	{ ip4.start = p; }
-#line 171 "src/port_uri.rl"
+#line 171 "src/uri.rl"
 	{ sport.start   = p; port = 0; }
-#line 172 "src/port_uri.rl"
+#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/port_uri.cc"
+#line 2439 "src/uri.cc"
 	switch( (*p) ) {
 		case 46: goto st114;
 		case 58: goto tr134;
@@ -2451,14 +2451,14 @@ case 164:
 		goto st128;
 	goto st74;
 tr180:
-#line 172 "src/port_uri.rl"
+#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/port_uri.cc"
+#line 2462 "src/uri.cc"
 	switch( (*p) ) {
 		case 46: goto st114;
 		case 58: goto tr134;
@@ -2474,14 +2474,14 @@ case 165:
 		goto st128;
 	goto st74;
 tr181:
-#line 172 "src/port_uri.rl"
+#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/port_uri.cc"
+#line 2485 "src/uri.cc"
 	switch( (*p) ) {
 		case 46: goto st114;
 		case 58: goto tr134;
@@ -2497,14 +2497,14 @@ case 166:
 		goto st128;
 	goto st74;
 tr182:
-#line 172 "src/port_uri.rl"
+#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/port_uri.cc"
+#line 2508 "src/uri.cc"
 	switch( (*p) ) {
 		case 58: goto tr134;
 		case 63: goto st0;
@@ -2519,18 +2519,18 @@ case 167:
 		goto st128;
 	goto st74;
 tr5:
-#line 132 "src/port_uri.rl"
+#line 132 "src/uri.rl"
 	{ schema.start = p; }
-#line 136 "src/port_uri.rl"
+#line 136 "src/uri.rl"
 	{ login.start  = p; }
-#line 157 "src/port_uri.rl"
+#line 157 "src/uri.rl"
 	{ host.start   = p; }
 	goto st168;
 st168:
 	if ( ++p == pe )
 		goto _test_eof168;
 case 168:
-#line 2534 "src/port_uri.cc"
+#line 2534 "src/uri.cc"
 	switch( (*p) ) {
 		case 58: goto tr183;
 		case 63: goto st0;
@@ -2545,16 +2545,16 @@ case 168:
 		goto st168;
 	goto st74;
 tr183:
-#line 137 "src/port_uri.rl"
+#line 137 "src/uri.rl"
 	{ login.end    = p; }
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
 	goto st68;
 st68:
 	if ( ++p == pe )
 		goto _test_eof68;
 case 68:
-#line 2558 "src/port_uri.cc"
+#line 2558 "src/uri.cc"
 	switch( (*p) ) {
 		case 47: goto st69;
 		case 48: goto tr10;
@@ -2594,18 +2594,18 @@ case 70:
 		goto tr84;
 	goto tr82;
 tr7:
-#line 132 "src/port_uri.rl"
+#line 132 "src/uri.rl"
 	{ schema.start = p; }
-#line 136 "src/port_uri.rl"
+#line 136 "src/uri.rl"
 	{ login.start  = p; }
-#line 157 "src/port_uri.rl"
+#line 157 "src/uri.rl"
 	{ host.start   = p; }
 	goto st169;
 st169:
 	if ( ++p == pe )
 		goto _test_eof169;
 case 169:
-#line 2609 "src/port_uri.cc"
+#line 2609 "src/uri.cc"
 	switch( (*p) ) {
 		case 58: goto tr183;
 		case 63: goto st0;
@@ -2674,16 +2674,16 @@ case 172:
 		goto st168;
 	goto st74;
 tr188:
-#line 137 "src/port_uri.rl"
+#line 137 "src/uri.rl"
 	{ login.end    = p; }
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
 	goto st71;
 st71:
 	if ( ++p == pe )
 		goto _test_eof71;
 case 71:
-#line 2687 "src/port_uri.cc"
+#line 2687 "src/uri.cc"
 	switch( (*p) ) {
 		case 47: goto st72;
 		case 48: goto tr10;
@@ -2723,50 +2723,50 @@ case 73:
 		goto tr91;
 	goto tr88;
 tr88:
-#line 180 "src/port_uri.rl"
+#line 180 "src/uri.rl"
 	{ path.start = p; }
-#line 133 "src/port_uri.rl"
+#line 133 "src/uri.rl"
 	{ schema.end   = p - 3; }
-#line 157 "src/port_uri.rl"
+#line 157 "src/uri.rl"
 	{ host.start   = p; }
 	goto st173;
 tr232:
-#line 180 "src/port_uri.rl"
+#line 180 "src/uri.rl"
 	{ path.start = p; }
-#line 157 "src/port_uri.rl"
+#line 157 "src/uri.rl"
 	{ host.start   = p; }
 	goto st173;
 st173:
 	if ( ++p == pe )
 		goto _test_eof173;
 case 173:
-#line 2744 "src/port_uri.cc"
+#line 2744 "src/uri.cc"
 	switch( (*p) ) {
 		case 58: goto tr190;
 		case 63: goto st175;
 	}
 	goto st173;
 tr190:
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
 	goto st174;
 tr222:
-#line 145 "src/port_uri.rl"
+#line 145 "src/uri.rl"
 	{ ip4.end   = p; }
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
 	goto st174;
 tr285:
-#line 154 "src/port_uri.rl"
+#line 154 "src/uri.rl"
 	{ ip6.end   = p - 1; }
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
 	goto st174;
 st174:
 	if ( ++p == pe )
 		goto _test_eof174;
 case 174:
-#line 2770 "src/port_uri.cc"
+#line 2770 "src/uri.cc"
 	if ( (*p) < 65 ) {
 		if ( 49 <= (*p) && (*p) <= 57 )
 			goto tr192;
@@ -2777,44 +2777,44 @@ case 174:
 		goto tr193;
 	goto st175;
 tr90:
-#line 180 "src/port_uri.rl"
+#line 180 "src/uri.rl"
 	{ path.start = p; }
 	goto st175;
 st175:
 	if ( ++p == pe )
 		goto _test_eof175;
 case 175:
-#line 2788 "src/port_uri.cc"
+#line 2788 "src/uri.cc"
 	goto st175;
 tr192:
-#line 166 "src/port_uri.rl"
+#line 166 "src/uri.rl"
 	{ service.start = p; }
-#line 161 "src/port_uri.rl"
+#line 161 "src/uri.rl"
 	{ dport.start   = p; port = 0; }
-#line 162 "src/port_uri.rl"
+#line 162 "src/uri.rl"
 	{ port = port * 10 + (int)(*p - '0'); }
 	goto st176;
 tr194:
-#line 162 "src/port_uri.rl"
+#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/port_uri.cc"
+#line 2806 "src/uri.cc"
 	if ( 48 <= (*p) && (*p) <= 57 )
 		goto tr194;
 	goto st175;
 tr193:
-#line 166 "src/port_uri.rl"
+#line 166 "src/uri.rl"
 	{ service.start = p; }
 	goto st177;
 st177:
 	if ( ++p == pe )
 		goto _test_eof177;
 case 177:
-#line 2818 "src/port_uri.cc"
+#line 2818 "src/uri.cc"
 	if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
 			goto st178;
@@ -2967,22 +2967,22 @@ case 191:
 case 192:
 	goto st175;
 tr89:
-#line 136 "src/port_uri.rl"
+#line 136 "src/uri.rl"
 	{ login.start  = p; }
-#line 180 "src/port_uri.rl"
+#line 180 "src/uri.rl"
 	{ path.start = p; }
-#line 133 "src/port_uri.rl"
+#line 133 "src/uri.rl"
 	{ schema.end   = p - 3; }
-#line 157 "src/port_uri.rl"
+#line 157 "src/uri.rl"
 	{ host.start   = p; }
-#line 144 "src/port_uri.rl"
+#line 144 "src/uri.rl"
 	{ ip4.start = p; }
 	goto st193;
 st193:
 	if ( ++p == pe )
 		goto _test_eof193;
 case 193:
-#line 2986 "src/port_uri.cc"
+#line 2986 "src/uri.cc"
 	switch( (*p) ) {
 		case 46: goto st194;
 		case 58: goto tr212;
@@ -3166,20 +3166,20 @@ case 207:
 		goto st208;
 	goto st173;
 tr91:
-#line 136 "src/port_uri.rl"
+#line 136 "src/uri.rl"
 	{ login.start  = p; }
-#line 180 "src/port_uri.rl"
+#line 180 "src/uri.rl"
 	{ path.start = p; }
-#line 133 "src/port_uri.rl"
+#line 133 "src/uri.rl"
 	{ schema.end   = p - 3; }
-#line 157 "src/port_uri.rl"
+#line 157 "src/uri.rl"
 	{ host.start   = p; }
 	goto st208;
 st208:
 	if ( ++p == pe )
 		goto _test_eof208;
 case 208:
-#line 3183 "src/port_uri.cc"
+#line 3183 "src/uri.cc"
 	switch( (*p) ) {
 		case 58: goto tr212;
 		case 63: goto st175;
@@ -3194,16 +3194,16 @@ case 208:
 		goto st208;
 	goto st173;
 tr212:
-#line 137 "src/port_uri.rl"
+#line 137 "src/uri.rl"
 	{ login.end    = p; }
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
 	goto st209;
 st209:
 	if ( ++p == pe )
 		goto _test_eof209;
 case 209:
-#line 3207 "src/port_uri.cc"
+#line 3207 "src/uri.cc"
 	if ( (*p) == 48 )
 		goto tr227;
 	if ( (*p) < 65 ) {
@@ -3216,14 +3216,14 @@ case 209:
 		goto tr229;
 	goto st175;
 tr227:
-#line 140 "src/port_uri.rl"
+#line 140 "src/uri.rl"
 	{ password.start = p; }
 	goto st210;
 st210:
 	if ( ++p == pe )
 		goto _test_eof210;
 case 210:
-#line 3227 "src/port_uri.cc"
+#line 3227 "src/uri.cc"
 	if ( (*p) == 64 )
 		goto tr231;
 	if ( (*p) < 65 ) {
@@ -3236,14 +3236,14 @@ case 210:
 		goto st210;
 	goto st175;
 tr231:
-#line 141 "src/port_uri.rl"
+#line 141 "src/uri.rl"
 	{ password.end   = p; }
 	goto st211;
 st211:
 	if ( ++p == pe )
 		goto _test_eof211;
 case 211:
-#line 3247 "src/port_uri.cc"
+#line 3247 "src/uri.cc"
 	switch( (*p) ) {
 		case 58: goto tr90;
 		case 63: goto tr90;
@@ -3253,18 +3253,18 @@ case 211:
 		goto tr233;
 	goto tr232;
 tr233:
-#line 180 "src/port_uri.rl"
+#line 180 "src/uri.rl"
 	{ path.start = p; }
-#line 157 "src/port_uri.rl"
+#line 157 "src/uri.rl"
 	{ host.start   = p; }
-#line 144 "src/port_uri.rl"
+#line 144 "src/uri.rl"
 	{ ip4.start = p; }
 	goto st212;
 st212:
 	if ( ++p == pe )
 		goto _test_eof212;
 case 212:
-#line 3268 "src/port_uri.cc"
+#line 3268 "src/uri.cc"
 	switch( (*p) ) {
 		case 46: goto st194;
 		case 58: goto tr190;
@@ -3296,28 +3296,28 @@ case 214:
 	}
 	goto st173;
 tr92:
-#line 180 "src/port_uri.rl"
+#line 180 "src/uri.rl"
 	{ path.start = p; }
-#line 133 "src/port_uri.rl"
+#line 133 "src/uri.rl"
 	{ schema.end   = p - 3; }
-#line 157 "src/port_uri.rl"
+#line 157 "src/uri.rl"
 	{ host.start   = p; }
-#line 153 "src/port_uri.rl"
+#line 153 "src/uri.rl"
 	{ ip6.start = p + 1; }
 	goto st215;
 tr234:
-#line 180 "src/port_uri.rl"
+#line 180 "src/uri.rl"
 	{ path.start = p; }
-#line 157 "src/port_uri.rl"
+#line 157 "src/uri.rl"
 	{ host.start   = p; }
-#line 153 "src/port_uri.rl"
+#line 153 "src/uri.rl"
 	{ ip6.start = p + 1; }
 	goto st215;
 st215:
 	if ( ++p == pe )
 		goto _test_eof215;
 case 215:
-#line 3321 "src/port_uri.cc"
+#line 3321 "src/uri.cc"
 	switch( (*p) ) {
 		case 58: goto tr238;
 		case 63: goto st175;
@@ -3392,14 +3392,14 @@ case 219:
 	}
 	goto st173;
 tr240:
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
 	goto st220;
 st220:
 	if ( ++p == pe )
 		goto _test_eof220;
 case 220:
-#line 3403 "src/port_uri.cc"
+#line 3403 "src/uri.cc"
 	switch( (*p) ) {
 		case 48: goto st221;
 		case 58: goto st225;
@@ -4017,18 +4017,18 @@ case 260:
 		goto tr285;
 	goto st175;
 tr244:
-#line 166 "src/port_uri.rl"
+#line 166 "src/uri.rl"
 	{ service.start = p; }
-#line 161 "src/port_uri.rl"
+#line 161 "src/uri.rl"
 	{ dport.start   = p; port = 0; }
-#line 162 "src/port_uri.rl"
+#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/port_uri.cc"
+#line 4032 "src/uri.cc"
 	switch( (*p) ) {
 		case 58: goto st225;
 		case 93: goto st260;
@@ -4043,14 +4043,14 @@ case 261:
 		goto st222;
 	goto st175;
 tr286:
-#line 162 "src/port_uri.rl"
+#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/port_uri.cc"
+#line 4054 "src/uri.cc"
 	switch( (*p) ) {
 		case 58: goto st225;
 		case 93: goto st260;
@@ -4065,14 +4065,14 @@ case 262:
 		goto st223;
 	goto st175;
 tr287:
-#line 162 "src/port_uri.rl"
+#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/port_uri.cc"
+#line 4076 "src/uri.cc"
 	switch( (*p) ) {
 		case 58: goto st225;
 		case 93: goto st260;
@@ -4087,14 +4087,14 @@ case 263:
 		goto st224;
 	goto st175;
 tr288:
-#line 162 "src/port_uri.rl"
+#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/port_uri.cc"
+#line 4098 "src/uri.cc"
 	switch( (*p) ) {
 		case 58: goto st225;
 		case 93: goto st260;
@@ -4103,14 +4103,14 @@ case 264:
 		goto tr194;
 	goto st175;
 tr246:
-#line 166 "src/port_uri.rl"
+#line 166 "src/uri.rl"
 	{ service.start = p; }
 	goto st265;
 st265:
 	if ( ++p == pe )
 		goto _test_eof265;
 case 265:
-#line 4114 "src/port_uri.cc"
+#line 4114 "src/uri.cc"
 	switch( (*p) ) {
 		case 58: goto st225;
 		case 93: goto st260;
@@ -4191,14 +4191,14 @@ case 268:
 		goto st181;
 	goto st175;
 tr238:
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
 	goto st269;
 st269:
 	if ( ++p == pe )
 		goto _test_eof269;
 case 269:
-#line 4202 "src/port_uri.cc"
+#line 4202 "src/uri.cc"
 	switch( (*p) ) {
 		case 48: goto st221;
 		case 58: goto st270;
@@ -4322,14 +4322,14 @@ case 275:
 		goto st231;
 	goto st175;
 tr298:
-#line 144 "src/port_uri.rl"
+#line 144 "src/uri.rl"
 	{ ip4.start = p; }
 	goto st276;
 st276:
 	if ( ++p == pe )
 		goto _test_eof276;
 case 276:
-#line 4333 "src/port_uri.cc"
+#line 4333 "src/uri.cc"
 	switch( (*p) ) {
 		case 46: goto st277;
 		case 58: goto st235;
@@ -4409,14 +4409,14 @@ case 284:
 		goto tr309;
 	goto st175;
 tr309:
-#line 145 "src/port_uri.rl"
+#line 145 "src/uri.rl"
 	{ ip4.end   = p; }
 	goto st285;
 st285:
 	if ( ++p == pe )
 		goto _test_eof285;
 case 285:
-#line 4420 "src/port_uri.cc"
+#line 4420 "src/uri.cc"
 	if ( (*p) == 58 )
 		goto tr190;
 	goto st175;
@@ -4489,24 +4489,24 @@ case 291:
 		goto st234;
 	goto st175;
 tr228:
-#line 140 "src/port_uri.rl"
+#line 140 "src/uri.rl"
 	{ password.start = p; }
-#line 166 "src/port_uri.rl"
+#line 166 "src/uri.rl"
 	{ service.start = p; }
-#line 161 "src/port_uri.rl"
+#line 161 "src/uri.rl"
 	{ dport.start   = p; port = 0; }
-#line 162 "src/port_uri.rl"
+#line 162 "src/uri.rl"
 	{ port = port * 10 + (int)(*p - '0'); }
 	goto st292;
 tr314:
-#line 162 "src/port_uri.rl"
+#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/port_uri.cc"
+#line 4510 "src/uri.cc"
 	if ( (*p) == 64 )
 		goto tr231;
 	if ( (*p) < 65 ) {
@@ -4519,16 +4519,16 @@ case 292:
 		goto st210;
 	goto st175;
 tr229:
-#line 140 "src/port_uri.rl"
+#line 140 "src/uri.rl"
 	{ password.start = p; }
-#line 166 "src/port_uri.rl"
+#line 166 "src/uri.rl"
 	{ service.start = p; }
 	goto st293;
 st293:
 	if ( ++p == pe )
 		goto _test_eof293;
 case 293:
-#line 4532 "src/port_uri.cc"
+#line 4532 "src/uri.cc"
 	if ( (*p) == 64 )
 		goto tr231;
 	if ( (*p) < 65 ) {
@@ -5107,7 +5107,7 @@ case 308:
 	case 170: 
 	case 171: 
 	case 172: 
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
 	break;
 	case 76: 
@@ -5146,12 +5146,12 @@ case 308:
 	case 161: 
 	case 162: 
 	case 163: 
-#line 167 "src/port_uri.rl"
+#line 167 "src/uri.rl"
 	{ service.end   = p; }
 	break;
 	case 94: 
 	case 95: 
-#line 177 "src/port_uri.rl"
+#line 177 "src/uri.rl"
 	{ path.end   = p; }
 	break;
 	case 174: 
@@ -5221,36 +5221,36 @@ case 308:
 	case 289: 
 	case 290: 
 	case 291: 
-#line 181 "src/port_uri.rl"
+#line 181 "src/uri.rl"
 	{ path.end   = p; }
 	break;
 	case 119: 
 	case 120: 
 	case 121: 
-#line 145 "src/port_uri.rl"
+#line 145 "src/uri.rl"
 	{ ip4.end   = p; }
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
 	break;
 	case 137: 
-#line 154 "src/port_uri.rl"
+#line 154 "src/uri.rl"
 	{ ip6.end   = p - 1; }
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
 	break;
 	case 164: 
 	case 165: 
 	case 166: 
 	case 167: 
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
-#line 173 "src/port_uri.rl"
+#line 173 "src/uri.rl"
 	{ sport.end     = p; }
 	break;
 	case 93: 
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
-#line 177 "src/port_uri.rl"
+#line 177 "src/uri.rl"
 	{ path.end   = p; }
 	break;
 	case 75: 
@@ -5259,9 +5259,9 @@ case 308:
 	case 140: 
 	case 141: 
 	case 147: 
-#line 163 "src/port_uri.rl"
+#line 163 "src/uri.rl"
 	{ dport.end	 = p; }
-#line 167 "src/port_uri.rl"
+#line 167 "src/uri.rl"
 	{ service.end   = p; }
 	break;
 	case 97: 
@@ -5280,9 +5280,9 @@ case 308:
 	case 110: 
 	case 111: 
 	case 112: 
-#line 167 "src/port_uri.rl"
+#line 167 "src/uri.rl"
 	{ service.end   = p; }
-#line 177 "src/port_uri.rl"
+#line 177 "src/uri.rl"
 	{ path.end   = p; }
 	break;
 	case 173: 
@@ -5308,9 +5308,9 @@ case 308:
 	case 218: 
 	case 219: 
 	case 285: 
-#line 181 "src/port_uri.rl"
+#line 181 "src/uri.rl"
 	{ path.end   = p; }
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
 	break;
 	case 177: 
@@ -5349,35 +5349,35 @@ case 308:
 	case 306: 
 	case 307: 
 	case 308: 
-#line 181 "src/port_uri.rl"
+#line 181 "src/uri.rl"
 	{ path.end   = p; }
-#line 167 "src/port_uri.rl"
+#line 167 "src/uri.rl"
 	{ service.end   = p; }
 	break;
 	case 96: 
-#line 163 "src/port_uri.rl"
+#line 163 "src/uri.rl"
 	{ dport.end	 = p; }
-#line 167 "src/port_uri.rl"
+#line 167 "src/uri.rl"
 	{ service.end   = p; }
-#line 177 "src/port_uri.rl"
+#line 177 "src/uri.rl"
 	{ path.end   = p; }
 	break;
 	case 199: 
 	case 200: 
 	case 201: 
-#line 181 "src/port_uri.rl"
+#line 181 "src/uri.rl"
 	{ path.end   = p; }
-#line 145 "src/port_uri.rl"
+#line 145 "src/uri.rl"
 	{ ip4.end   = p; }
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
 	break;
 	case 260: 
-#line 181 "src/port_uri.rl"
+#line 181 "src/uri.rl"
 	{ path.end   = p; }
-#line 154 "src/port_uri.rl"
+#line 154 "src/uri.rl"
 	{ ip6.end   = p - 1; }
-#line 158 "src/port_uri.rl"
+#line 158 "src/uri.rl"
 	{ host.end     = p; }
 	break;
 	case 176: 
@@ -5386,26 +5386,26 @@ case 308:
 	case 263: 
 	case 264: 
 	case 292: 
-#line 181 "src/port_uri.rl"
+#line 181 "src/uri.rl"
 	{ path.end   = p; }
-#line 163 "src/port_uri.rl"
+#line 163 "src/uri.rl"
 	{ dport.end	 = p; }
-#line 167 "src/port_uri.rl"
+#line 167 "src/uri.rl"
 	{ service.end   = p; }
 	break;
-#line 5397 "src/port_uri.cc"
+#line 5397 "src/uri.cc"
 	}
 	}
 
 	_out: {}
 	}
 
-#line 198 "src/port_uri.rl"
+#line 198 "src/uri.rl"
 
 
-	(void)port_uri_first_final;
-	(void)port_uri_error;
-	(void)port_uri_en_main;
+	(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),
diff --git a/src/port_uri.h b/src/uri.h
similarity index 81%
rename from src/port_uri.h
rename to src/uri.h
index aba0a77404fc5c32ee44b3688e973e3fd66856dc..377b4a3cb0f02a4b8c2097a9122c472604996c61 100644
--- a/src/port_uri.h
+++ b/src/uri.h
@@ -1,5 +1,5 @@
-#ifndef TARANTOOL_PORT_URI_H_INCLUDED
-#define TARANTOOL_PORT_URI_H_INCLUDED
+#ifndef TARANTOOL_URI_H_INCLUDED
+#define TARANTOOL_URI_H_INCLUDED
 /*
  * Redistribution and use in source and binary forms, with or
  * without modification, are permitted provided that the following
@@ -35,10 +35,10 @@
 #include <netdb.h>
 #include <sys/un.h>
 
-enum { PORT_URI_STR_LEN = 32 };
+enum { URI_STR_LEN = 32 };
 
 /** A parsed representation of an URI */
-struct port_uri {
+struct uri {
 
 	union {
 		struct sockaddr addr;
@@ -49,22 +49,22 @@ struct port_uri {
 	};
 	socklen_t addr_len;
 
-	char schema[PORT_URI_STR_LEN];
-	char login[PORT_URI_STR_LEN];
-	char password[PORT_URI_STR_LEN];
+	char schema[URI_STR_LEN];
+	char login[URI_STR_LEN];
+	char password[URI_STR_LEN];
 };
 
 /**
- * Parse a string and fill port_uri struct.
+ * Parse a string and fill uri struct.
  * @retval 0 success
  * @retval -1 error
  */
 int
-port_uri_parse(struct port_uri *uri, const char *str);
+uri_parse(struct uri *uri, const char *str);
 
 /** Convert an uri to string */
 const char *
-port_uri_to_string(const struct port_uri * uri);
+uri_to_string(const struct uri * uri);
 
 
-#endif /* TARANTOOL_PORT_URI_H_INCLUDED */
+#endif /* TARANTOOL_URI_H_INCLUDED */
diff --git a/src/port_uri.rl b/src/uri.rl
similarity index 97%
rename from src/port_uri.rl
rename to src/uri.rl
index 5d99f7636440f61361874dfab2bc91d80bd81a28..ddde079ba3305719cc95d224ba9acaa56b42b6c9 100644
--- a/src/port_uri.rl
+++ b/src/uri.rl
@@ -26,7 +26,7 @@
  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include "port_uri.h"
+#include "uri.h"
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -39,7 +39,7 @@
 #include <netdb.h>
 
 const char *
-port_uri_to_string(const struct port_uri * uri)
+uri_to_string(const struct uri * uri)
 {
 	static __thread char
 		str[NI_MAXSERV + NI_MAXHOST + sizeof(uri->schema)];
@@ -96,7 +96,7 @@ port_uri_to_string(const struct port_uri * uri)
 }
 
 int
-port_uri_parse(struct port_uri *uri, const char *p)
+uri_parse(struct uri *uri, const char *p)
 {
 	(void) uri;
 	const char *pe = p + strlen(p);
@@ -122,7 +122,7 @@ port_uri_parse(struct port_uri *uri, const char *p)
 	unsigned port = 0;
 
 	%%{
-		machine port_uri;
+		machine uri;
 		write data;
 
 		hex1_4 = ([0-9a-fA-F]{1,4});
@@ -197,9 +197,9 @@ port_uri_parse(struct port_uri *uri, const char *p)
 		write exec;
 	}%%
 
-	(void)port_uri_first_final;
-	(void)port_uri_error;
-	(void)port_uri_en_main;
+	(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),
diff --git a/test/app/float_value.result b/test/app/float_value.result
index 8f1a02c5dcf05f6ab969b99751dd612a0123de28..e6c4ad1368da5444942e9d4c048530e8dce8584a 100644
--- a/test/app/float_value.result
+++ b/test/app/float_value.result
@@ -2,7 +2,7 @@ box.cfg
 1	pid_file:box.pid
 2	slab_alloc_factor:2
 3	rows_per_wal:50
-4	admin_port:3313
+4	background:false
 5	logger:tarantool.log
 6	slab_alloc_arena:0.1
 7	wal_dir:.
@@ -13,10 +13,10 @@ box.cfg
 12	panic_on_snap_error:true
 13	panic_on_wal_error:false
 14	log_level:5
-15	readahead:16320
-16	too_long_threshold:0.01
-17	slab_alloc_minimal:64
-18	background:false
+15	admin:3313
+16	readahead:16320
+17	too_long_threshold:0.01
+18	slab_alloc_minimal:64
 19	wal_dir_rescan_delay:0.1
 ------------------------------------------------------
 Check that too_long_threshold = 0.01
diff --git a/test/app/float_value.test.lua b/test/app/float_value.test.lua
index ef17df5b375cd24ab74dfcbc3055f3d5f87b1dbf..bd39a55f03723e32792a80b1d89c7195f50bd0df 100755
--- a/test/app/float_value.test.lua
+++ b/test/app/float_value.test.lua
@@ -3,7 +3,7 @@
 -- Test floating points values (too_long_treshold) with fractional part
 --
 box.cfg{
-    admin_port = 3313,
+    admin = 3313,
     slab_alloc_arena = 0.1,
     pid_file = "box.pid",
     rows_per_wal = 50,
diff --git a/test/app/init_script.result b/test/app/init_script.result
index e3644e2e1716757d08752da26302118a8b60090b..beb33411320862e570ea8084e9673d68885817d2 100644
--- a/test/app/init_script.result
+++ b/test/app/init_script.result
@@ -6,22 +6,22 @@ box.cfg
 1	too_long_threshold:0.5
 2	slab_alloc_factor:2
 3	slab_alloc_minimal:64
-4	admin_port:3313
+4	background:false
 5	logger:tarantool.log
-6	primary_port:3314
+6	slab_alloc_arena:1
 7	wal_dir:.
-8	logger_nonblock:true
-9	snap_dir:.
-10	coredump:false
-11	wal_mode:write
-12	log_level:5
+8	listen:3314
+9	logger_nonblock:true
+10	snap_dir:.
+11	coredump:false
+12	wal_mode:write
 13	panic_on_snap_error:true
 14	panic_on_wal_error:false
-15	rows_per_wal:500000
-16	readahead:16320
-17	pid_file:box.pid
-18	background:false
-19	slab_alloc_arena:1
+15	pid_file:box.pid
+16	admin:3313
+17	rows_per_wal:500000
+18	readahead:16320
+19	log_level:5
 20	wal_dir_rescan_delay:0.1
 --
 -- Test insert from detached fiber
diff --git a/test/app/init_script.test.lua b/test/app/init_script.test.lua
index cd64a605f901a8f352aec62282c9649e0a29f6c0..41b523858abc6b5ef004e55987ad4c19450d03cf 100755
--- a/test/app/init_script.test.lua
+++ b/test/app/init_script.test.lua
@@ -3,8 +3,8 @@
 -- Testing init script
 --
 box.cfg{
-    admin_port = 3313,
-    primary_port = 3314,
+    admin  = 3313,
+    listen = 3314,
     pid_file = "box.pid",
     logger="tarantool.log"
 }
diff --git a/test/big/big.lua b/test/big/big.lua
index 2cb5be418382fe47fd897a144710d07e130a812f..62cdeea836d58e5bf1d549fa604319e78e184906 100644
--- a/test/big/big.lua
+++ b/test/big/big.lua
@@ -1,8 +1,8 @@
 #!/usr/bin/env tarantool
 
 box.cfg{
-    primary_port        = os.getenv("PRIMARY_PORT"),
-    admin_port          = os.getenv("ADMIN_PORT"),
+    listen              = os.getenv("LISTEN"),
+    admin               = os.getenv("ADMIN"),
     slab_alloc_arena    = 0.1,
     pid_file            = "tarantool.pid",
     rows_per_wal        = 50
diff --git a/test/box/access.result b/test/box/access.result
index 0f4d7614979ba1cce1dbac0b0ab7eef1c1396d86..207457a2fab55ee68b3732b7c0b727dab64be8c5 100644
--- a/test/box/access.result
+++ b/test/box/access.result
@@ -156,7 +156,7 @@ 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.primary_port)
+c = (require 'net.box'):new("127.0.0.1", box.cfg.listen)
 ---
 ...
 c:call('nosuchfunction')
diff --git a/test/box/access.test.lua b/test/box/access.test.lua
index 7a1f5119b4c22a3f469193a4dd4b41467cc0c0ba..3b41ced8c11c290901b4948ca066620661c08271 100644
--- a/test/box/access.test.lua
+++ b/test/box/access.test.lua
@@ -74,7 +74,7 @@ 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.primary_port)
+c = (require 'net.box'):new("127.0.0.1", box.cfg.listen)
 
 c:call('nosuchfunction')
 function nosuchfunction() end
diff --git a/test/box/admin.result b/test/box/admin.result
index 498e699f825166cef1d9839abbaf5b758469c5af..c59aa4046808594b58992ae4e767d80e19c1690c 100644
--- a/test/box/admin.result
+++ b/test/box/admin.result
@@ -6,8 +6,8 @@ space = box.schema.create_space('tweedledum', { id = 0 })
 space:create_index('primary', { type = 'hash' })
 ---
 ...
---# push filter 'primary_port: .*' to 'primary_port: <number>'
---# push filter 'admin_port: .*' to 'admin_port: <number>'
+--# push filter 'listen: .*' to 'listen: <uri>'
+--# push filter 'admin: .*' to 'admin: <uri>'
 help()
 ---
 - - Help topics:
@@ -22,21 +22,21 @@ box.cfg
 - too_long_threshold: 0.5
   slab_alloc_factor: 2
   rows_per_wal: 50
-  admin_port: <number>
+  background: false
   slab_alloc_arena: 0.1
   wal_dir: .
+  listen: <uri>
   logger_nonblock: true
   snap_dir: .
   coredump: false
   wal_mode: write
-  log_level: 5
   panic_on_snap_error: true
   panic_on_wal_error: false
+  log_level: 5
+  admin: <uri>
   readahead: 16320
-  primary_port: <number>
   pid_file: tarantool.pid
   slab_alloc_minimal: 64
-  background: false
   wal_dir_rescan_delay: 0.1
 ...
 space:insert{1, 'tuple'}
diff --git a/test/box/admin.test.lua b/test/box/admin.test.lua
index 833819b918b01720f00854305496fe9e1eb0a87c..506d46006cdf1b07534de7767dc2370631b26753 100644
--- a/test/box/admin.test.lua
+++ b/test/box/admin.test.lua
@@ -4,8 +4,8 @@
 space = box.schema.create_space('tweedledum', { id = 0 })
 space:create_index('primary', { type = 'hash' })
 
---# push filter 'primary_port: .*' to 'primary_port: <number>'
---# push filter 'admin_port: .*' to 'admin_port: <number>'
+--# push filter 'listen: .*' to 'listen: <uri>'
+--# push filter 'admin: .*' to 'admin: <uri>'
 help()
 box.cfg
 space:insert{1, 'tuple'}
diff --git a/test/box/bad_trigger.result b/test/box/bad_trigger.result
index 085f824ca86d657289c27709b2b194e54525cb9f..7ed20dea803cd9add6f6387813660c3f17eccc2a 100644
--- a/test/box/bad_trigger.result
+++ b/test/box/bad_trigger.result
@@ -11,7 +11,7 @@ require('session').on_connect(f1)
 ...
 greeting:  True
 fixheader:  True
-error code: 8194
+error code 32
 error message:  [string "function f1() nosuchfunction() end"]:1: attempt to call global 'nosuchfunction' (a nil value)
 eof: True
 require('session').on_connect(nil, f1)
diff --git a/test/box/bad_trigger.test.py b/test/box/bad_trigger.test.py
index b1676c42a1193655af7005c638faa3d2c3e87912..f6bbaad7c67f2caed3f02580f589bc4dd65df6ef 100644
--- a/test/box/bad_trigger.test.py
+++ b/test/box/bad_trigger.test.py
@@ -1,6 +1,7 @@
 from lib.box_connection import BoxConnection
 from tarantool import NetworkError
-from tarantool.const import IPROTO_GREETING_SIZE, IPROTO_CODE, IPROTO_ERROR
+from tarantool.const import IPROTO_GREETING_SIZE, IPROTO_CODE, IPROTO_ERROR, \
+    REQUEST_TYPE_ERROR
 import socket
 import msgpack
 
@@ -33,7 +34,7 @@ unpacker.feed(packet)
 # Parse packet
 header = unpacker.unpack()
 body = unpacker.unpack()
-print 'error code:', header[IPROTO_CODE]
+print 'error code', (header[IPROTO_CODE] & (REQUEST_TYPE_ERROR - 1))
 print 'error message: ', body[IPROTO_ERROR]
 print 'eof:', len(s.recv(1024)) == 0
 s.close()
diff --git a/test/box/box.lua b/test/box/box.lua
index 911fe7022fc1522a4f2789e28516a7b320818865..2fefb66c2132fc1fa8a3f9ed64ac9e482487038e 100644
--- a/test/box/box.lua
+++ b/test/box/box.lua
@@ -2,8 +2,8 @@
 os = require('os')
 
 box.cfg{
-    primary_port        = os.getenv("PRIMARY_PORT"),
-    admin_port          = os.getenv("ADMIN_PORT"),
+    listen              = os.getenv("LISTEN"),
+    admin               = os.getenv("ADMIN"),
     slab_alloc_arena    = 0.1,
     pid_file            = "tarantool.pid",
     rows_per_wal        = 50
diff --git a/test/box/box.net.box.result b/test/box/box.net.box.result
index f112b865d8d03267b5d1303b8264183cb2d395e2..d410e5032e755b06a6705e0299ae6f795228a505 100644
--- a/test/box/box.net.box.result
+++ b/test/box/box.net.box.result
@@ -10,7 +10,7 @@ log = require 'log'
 box.schema.user.grant('guest', 'read,write,execute', 'universe')
 ---
 ...
-port = box.cfg.primary_port
+port = box.cfg.listen
 ---
 ...
 space = box.schema.create_space('net_box_test_space')
diff --git a/test/box/box.net.box.test.lua b/test/box/box.net.box.test.lua
index 953e964a5f95145af2d1d8a7085a1ee8d8ecce6e..68e9356a6d511351462d71633864ec8ad3576bd9 100644
--- a/test/box/box.net.box.test.lua
+++ b/test/box/box.net.box.test.lua
@@ -3,7 +3,7 @@ fiber = require 'fiber'
 log = require 'log'
 
 box.schema.user.grant('guest', 'read,write,execute', 'universe')
-port = box.cfg.primary_port
+port = box.cfg.listen
 space = box.schema.create_space('net_box_test_space')
 space:create_index('primary', { type = 'tree' })
 
diff --git a/test/box/bsdsocket.result b/test/box/bsdsocket.result
index 5a93269d223fe9e7259e689f435ea5eb783a7156..4c9fb2fdf41e4f2fa5a6ca4aa621c356acdf862f 100644
--- a/test/box/bsdsocket.result
+++ b/test/box/bsdsocket.result
@@ -43,14 +43,14 @@ type(s:error())
 ---
 - nil
 ...
-primary_port = string.gsub(box.cfg.primary_port, '^.*:', '')
+port = string.gsub(box.cfg.listen, '^.*:', '')
 ---
 ...
 s:nonblock(false)
 ---
 - false
 ...
-s:sysconnect('127.0.0.1', primary_port)
+s:sysconnect('127.0.0.1', port)
 ---
 - true
 ...
@@ -807,7 +807,7 @@ socket.tcp_connect('127.0.0.1', 80, 0.00000000001)
 - null
 ...
 -- close
-s = socket.tcp_connect('127.0.0.1', primary_port)
+s = socket.tcp_connect('127.0.0.1', port)
 ---
 ...
 string.sub(s:read(128), 1, 9)
diff --git a/test/box/bsdsocket.test.lua b/test/box/bsdsocket.test.lua
index ba0155af47dbe64c967e400c660149ba8696b308..43a87179bbe9e9a82696edb1c82dbc0f84ac47a6 100644
--- a/test/box/bsdsocket.test.lua
+++ b/test/box/bsdsocket.test.lua
@@ -14,10 +14,10 @@ type(s)
 s:errno()
 type(s:error())
 
-primary_port = string.gsub(box.cfg.primary_port, '^.*:', '')
+port = string.gsub(box.cfg.listen, '^.*:', '')
 
 s:nonblock(false)
-s:sysconnect('127.0.0.1', primary_port)
+s:sysconnect('127.0.0.1', port)
 s:nonblock(true)
 s:nonblock()
 s:nonblock(false)
@@ -258,7 +258,7 @@ socket.tcp_connect('127.0.0.1', 80, 0.00000000001)
 
 -- close
 
-s = socket.tcp_connect('127.0.0.1', primary_port)
+s = socket.tcp_connect('127.0.0.1', port)
 string.sub(s:read(128), 1, 9)
 sa = { fh = 512 } setmetatable(sa, getmetatable(s))
 tostring(sa)
diff --git a/test/box/call.result b/test/box/call.result
index 85128be8445e3e45f84b9430bcbb8533f011b301..9682d126ae08f73d33afabfd9275a7715fcab54f 100644
--- a/test/box/call.result
+++ b/test/box/call.result
@@ -48,8 +48,8 @@ call f1()
 call dostring('box.raise(33333, "Hey!")')
 ---
 - error:
-    errcode: ER_UNKNOWN (33333)
-    errmsg: Hey!
+    errcode: ER_PROC_LUA
+    errmsg: [string "box.raise(33333, "Hey!")"]:1: box.raise(): unknown error code
 ...
 
 # A test case for Bug#103491
diff --git a/test/box/cfg.result b/test/box/cfg.result
index 2d9d9ba67c1c98a153b0c64a9e3ef50fe70a0fbe..04c0a7f051d4a8d7af2574b17904bb9279c7a069 100644
--- a/test/box/cfg.result
+++ b/test/box/cfg.result
@@ -1,5 +1,5 @@
---# push filter 'primary_port: .*' to 'primary_port: <number>'
---# push filter 'admin_port: .*' to 'admin_port: <number>'
+--# push filter 'listen: .*' to 'primary: <uri>'
+--# push filter 'admin: .*' to 'admin: <uri>'
 box.cfg.nosuchoption = 1
 ---
 - error: '[string "-- load_cfg.lua - internal file..."]:127: Attempt to modify a read-only
@@ -13,21 +13,21 @@ t
 - - 'too_long_threshold: 0.5'
   - 'slab_alloc_factor: 2'
   - 'rows_per_wal: 50'
-  - 'admin_port: <number>
+  - 'background: false'
   - 'slab_alloc_arena: 0.1'
   - 'wal_dir: .'
+  - 'primary: <uri>
   - 'logger_nonblock: true'
   - 'snap_dir: .'
   - 'coredump: false'
   - 'wal_mode: write'
-  - 'log_level: 5'
   - 'panic_on_snap_error: true'
   - 'panic_on_wal_error: false'
+  - 'log_level: 5'
+  - 'admin: <uri>
   - 'readahead: 16320'
-  - 'primary_port: <number>
   - 'pid_file: tarantool.pid'
   - 'slab_alloc_minimal: 64'
-  - 'background: false'
   - 'wal_dir_rescan_delay: 0.1'
 ...
 -- must be read-only
@@ -42,21 +42,21 @@ t
 - - 'too_long_threshold: 0.5'
   - 'slab_alloc_factor: 2'
   - 'rows_per_wal: 50'
-  - 'admin_port: <number>
+  - 'background: false'
   - 'slab_alloc_arena: 0.1'
   - 'wal_dir: .'
+  - 'primary: <uri>
   - 'logger_nonblock: true'
   - 'snap_dir: .'
   - 'coredump: false'
   - 'wal_mode: write'
-  - 'log_level: 5'
   - 'panic_on_snap_error: true'
   - 'panic_on_wal_error: false'
+  - 'log_level: 5'
+  - 'admin: <uri>
   - 'readahead: 16320'
-  - 'primary_port: <number>
   - 'pid_file: tarantool.pid'
   - 'slab_alloc_minimal: 64'
-  - 'background: false'
   - 'wal_dir_rescan_delay: 0.1'
 ...
 --# clear filter
diff --git a/test/box/cfg.test.lua b/test/box/cfg.test.lua
index ccacd0ee6228323619fbeff792ec6bb777c1c5df..ee99deae794a6f606d6711abe6d65f4d19adb0d6 100644
--- a/test/box/cfg.test.lua
+++ b/test/box/cfg.test.lua
@@ -1,5 +1,5 @@
---# push filter 'primary_port: .*' to 'primary_port: <number>'
---# push filter 'admin_port: .*' to 'admin_port: <number>'
+--# push filter 'listen: .*' to 'primary: <uri>'
+--# push filter 'admin: .*' to 'admin: <uri>'
 box.cfg.nosuchoption = 1
 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
diff --git a/test/box/configuration.test.py b/test/box/configuration.test.py
index 3489b2ba77486e4cba7c5686749fbff2f5ba4585..d311508eb170e41b805fc1d4228516ffd6065367 100644
--- a/test/box/configuration.test.py
+++ b/test/box/configuration.test.py
@@ -24,8 +24,8 @@ server.cfgfile_source = old_cfgfile
 old_script = server.script
 server.script = "box/lua/test_init.lua"
 server.deploy()
-sys.stdout.push_filter("admin_port: .*", "admin_port: <number>")
-sys.stdout.push_filter("primary_port: .*", "primary_port: <number>")
+sys.stdout.push_filter("admin: .*", "admin: <uri>")
+sys.stdout.push_filter("listen: .*", "listen: <uri>")
 admin("print_config()")
 sys.stdout.pop_filter()
 sys.stdout.pop_filter()
diff --git a/test/box/misc.result b/test/box/misc.result
index 0e61e0aaa0fcd8aba6aca5db026e36089123ba83..c16ca13c18ca4c32d936d5b64b186031ba68d9af 100644
--- a/test/box/misc.result
+++ b/test/box/misc.result
@@ -45,11 +45,11 @@ t = nil
 ...
 box.raise(123, 'test')
 ---
-- error: test
+- error: 'box.raise(): unknown error code'
 ...
 box.raise(0, 'the other test')
 ---
-- error: 'box.raise(): unknown error code'
+- error: the other test
 ...
 box.raise(12, 345)
 ---
@@ -204,7 +204,7 @@ t;
   - 'box.error.ALTER_SPACE : 12'
   - 'box.error.SPLICE : 25'
   - 'box.error.NO_CONNECTION : 77'
-  - 'box.error.TUPLE_FOUND : 3'
+  - 'box.error.DROP_SPACE : 11'
   - 'box.error.INVALID_XLOG_NAME : 75'
   - 'box.error.INVALID_XLOG : 74'
   - 'box.error.REPLICA_MAX : 73'
@@ -229,16 +229,16 @@ t;
   - 'box.error.TUPLE_NOT_ARRAY : 22'
   - 'box.error.TUPLE_FORMAT_LIMIT : 16'
   - 'box.error.INVALID_UUID : 64'
-  - 'box.error.DROP_SPACE : 11'
+  - 'box.error.UNKNOWN : 0'
   - 'box.error.TIMEOUT : 78'
-  - 'box.error.MORE_THAN_ONE_TUPLE : 41'
+  - 'box.error.TUPLE_FOUND : 3'
   - 'box.error.MEMORY_ISSUE : 2'
   - 'box.error.NO_SUCH_TRIGGER : 34'
   - 'box.error.UPDATE_FIELD : 29'
   - 'box.error.ARG_TYPE : 26'
   - 'box.error.NO_SUCH_SPACE : 36'
   - 'box.error.INDEX_FIELD_COUNT : 39'
-  - 'box.error.OK : 0'
+  - 'box.error.MORE_THAN_ONE_TUPLE : 41'
   - 'box.error.DROP_PRIMARY_KEY : 17'
   - 'box.error.UNKNOWN_REQUEST_TYPE : 48'
   - 'box.error.INVALID_XLOG_ORDER : 76'
diff --git a/test/box/protocol.result b/test/box/protocol.result
index 829f15f04265bc470eeae42314fa0cea6552a8fe..fbbe9a349d1bfb0d36868ed35a4e8568f23f3d3a 100644
--- a/test/box/protocol.result
+++ b/test/box/protocol.result
@@ -13,10 +13,10 @@ space:create_index('primary', { type = 'tree'})
 for i=1,5 do space:insert{i} end
 ---
 ...
-primary_port = string.gsub(box.cfg.primary_port, '^.*:', '')
+port = string.gsub(box.cfg.listen, '^.*:', '')
 ---
 ...
-conn = (require 'net.box'):new('127.0.0.1', tonumber(primary_port))
+conn = (require 'net.box'):new('127.0.0.1', tonumber(port))
 ---
 ...
 conn.space[space.id]:select(3, { iterator = 'GE' })
diff --git a/test/box/protocol.test.lua b/test/box/protocol.test.lua
index cf1247521035c0b9c1bd628f70ff6cfcf5c6329a..975fb20ffa50199fbf1bf2e2e16568e5ff6e01ad 100644
--- a/test/box/protocol.test.lua
+++ b/test/box/protocol.test.lua
@@ -8,8 +8,8 @@ space = box.schema.create_space('tweedledum')
 space:create_index('primary', { type = 'tree'})
 for i=1,5 do space:insert{i} end
 
-primary_port = string.gsub(box.cfg.primary_port, '^.*:', '')
-conn = (require 'net.box'):new('127.0.0.1', tonumber(primary_port))
+port = string.gsub(box.cfg.listen, '^.*:', '')
+conn = (require 'net.box'):new('127.0.0.1', tonumber(port))
 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/socket.result b/test/box/socket.result
index 38dc37efa0056f889cecece2e831789ac1a49dc4..56b3945ee127fa8e4dfe8d6e67c5ebe30c1889ef 100644
--- a/test/box/socket.result
+++ b/test/box/socket.result
@@ -902,7 +902,7 @@ ping
 s:close()
 ---
 ...
- replies = 0 packet = require('msgpack').encode({[0] = 64, [1] = 0}) packet = require('msgpack').encode(packet:len())..packet function bug1160869()     local s = socket.tcp()     s:connect('127.0.0.1', string.gsub(box.cfg.primary_port, '^.*:', ''))     s:recv(128)     require('fiber').wrap(function()         while true do             _, status =  s:recv(18)             if status == "eof" then                 error("unexpected eof")             end             replies = replies + 1         end     end)     return s:send(packet) end 
+ replies = 0 packet = require('msgpack').encode({[0] = 64, [1] = 0}) packet = require('msgpack').encode(packet:len())..packet function bug1160869()     local s = socket.tcp()     s:connect('127.0.0.1', string.gsub(box.cfg.listen, '^.*:', ''))     s:recv(128)     require('fiber').wrap(function()         while true do             _, status =  s:recv(18)             if status == "eof" then                 error("unexpected eof")             end             replies = replies + 1         end     end)     return s:send(packet) end 
 ---
 ...
 bug1160869()
@@ -924,7 +924,7 @@ replies
 ---
 - 3
 ...
- s = nil syncno = 0 reps = 0 packet = require('msgpack').encode({[0] = 64, [1] = 0}) packet = require('msgpack').encode(packet:len())..packet function iostart()     if s ~= nil then         return     end     s = socket.tcp()     s:connect('127.0.0.1', string.gsub(box.cfg.primary_port, '^.*:', ''))     s:recv(128)     require('fiber').wrap(function()         while true do             s:recv(18)             if status == "eof" then                 error("unexpected eof")             end             reps = reps + 1         end     end) end  function iotest()     iostart()     syncno = syncno + 1     packet = require('msgpack').encode({[0] = 64, [1] = syncno})     packet = require('msgpack').encode(packet:len())..packet     return s:send(packet) end 
+ s = nil syncno = 0 reps = 0 packet = require('msgpack').encode({[0] = 64, [1] = 0}) packet = require('msgpack').encode(packet:len())..packet function iostart()     if s ~= nil then         return     end     s = socket.tcp()     s:connect('127.0.0.1', string.gsub(box.cfg.listen, '^.*:', ''))     s:recv(128)     require('fiber').wrap(function()         while true do             s:recv(18)             if status == "eof" then                 error("unexpected eof")             end             reps = reps + 1         end     end) end  function iotest()     iostart()     syncno = syncno + 1     packet = require('msgpack').encode({[0] = 64, [1] = syncno})     packet = require('msgpack').encode(packet:len())..packet     return s:send(packet) end 
 ---
 ...
 iotest()
diff --git a/test/box/socket.test.py b/test/box/socket.test.py
index 09605f622192769b0ba720680510f034f560daf1..f9b2b4b043eb8553633a3ff41594aa05c33bad8b 100644
--- a/test/box/socket.test.py
+++ b/test/box/socket.test.py
@@ -516,7 +516,7 @@ packet = require('msgpack').encode({[0] = 64, [1] = 0})
 packet = require('msgpack').encode(packet:len())..packet
 function bug1160869()
     local s = socket.tcp()
-    s:connect('127.0.0.1', string.gsub(box.cfg.primary_port, '^.*:', ''))
+    s:connect('127.0.0.1', string.gsub(box.cfg.listen, '^.*:', ''))
     s:recv(128)
     require('fiber').wrap(function()
         while true do
@@ -549,7 +549,7 @@ function iostart()
         return
     end
     s = socket.tcp()
-    s:connect('127.0.0.1', string.gsub(box.cfg.primary_port, '^.*:', ''))
+    s:connect('127.0.0.1', string.gsub(box.cfg.listen, '^.*:', ''))
     s:recv(128)
     require('fiber').wrap(function()
         while true do
diff --git a/test/lib/preprocessor.py b/test/lib/preprocessor.py
index bf565ab31d0d1f606f05b9f8ba53b1b85e2a7295..ca979a41b987f2aadba58f0cd84dca3130478efd 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_port', default_server.admin.port)
-        setattr(nmsp, 'primary_port', default_server.sql.port)
+        setattr(nmsp, 'admin', default_server.admin.port)
+        setattr(nmsp, 'listen', default_server.sql.port)
         setattr(self.environ, 'default', nmsp)
 
     def parse_preprocessor(self, string):
@@ -143,10 +143,10 @@ class TestState(object):
             self.servers[sname] = temp
             self.servers[sname].deploy(silent=True)
             nmsp = Namespace()
-            setattr(nmsp, 'admin_port', temp.admin.port)
-            setattr(nmsp, 'primary_port', temp.sql.port)
+            setattr(nmsp, 'admin', temp.admin.port)
+            setattr(nmsp, 'listen', temp.sql.port)
             if temp.rpl_master:
-                setattr(nmsp, 'master_port', temp.rpl_master.sql.port)
+                setattr(nmsp, 'master', temp.rpl_master.sql.port)
             setattr(self.environ, sname, nmsp)
         elif ctype == 'start':
             if sname not in self.servers:
diff --git a/test/lib/sql_ast.py b/test/lib/sql_ast.py
index 1887f9aba3c0f984c43b184b8e207261cff3ec38..3b0741745ef0322407fda3bda7c365f811ea66a9 100644
--- a/test/lib/sql_ast.py
+++ b/test/lib/sql_ast.py
@@ -167,10 +167,11 @@ class StatementSelect(Statement):
             self.key = [self.key]
         self.offset = 0
         self.limit = limit
+        self.iterator = 0
 
     def pack(self, connection):
         return RequestSelect(connection, self.space_no, self.index_no,
-                self.key, self.offset, self.limit)
+                self.key, self.offset, self.limit, self.iterator)
 
     def unpack(self, response):
         if response.return_code:
diff --git a/test/lib/tarantool-python b/test/lib/tarantool-python
index 0f9d99ecb770586ca011800a6e3921c3353c7459..df94b88d87c249e41cdf45dd74b13a2949be24f0 160000
--- a/test/lib/tarantool-python
+++ b/test/lib/tarantool-python
@@ -1 +1 @@
-Subproject commit 0f9d99ecb770586ca011800a6e3921c3353c7459
+Subproject commit df94b88d87c249e41cdf45dd74b13a2949be24f0
diff --git a/test/lib/tarantool_server.py b/test/lib/tarantool_server.py
index 8c27d430913f733ccfe8ddfb87c9c610453b036e..b47d48dffa54ca79757db1a4094b4e97d54d2991 100644
--- a/test/lib/tarantool_server.py
+++ b/test/lib/tarantool_server.py
@@ -464,10 +464,10 @@ class TarantoolServer(Server):
 
         check_port(self.admin.port)
 
-        os.putenv("PRIMARY_PORT", str(self.sql.port))
-        os.putenv("ADMIN_PORT", str(self.admin.port))
+        os.putenv("LISTEN", str(self.sql.port))
+        os.putenv("ADMIN", str(self.admin.port))
         if self.rpl_master:
-            os.putenv("MASTER_PORT", "127.0.0.1:"+str(self.rpl_master.sql.port))
+            os.putenv("MASTER", "127.0.0.1:"+str(self.rpl_master.sql.port))
         args = self.prepare_args()
         self.logfile_pos = self.logfile
         self.process = subprocess.Popen(args,
diff --git a/test/module/box.lua b/test/module/box.lua
index cf371180709c764c55c4c78846a1f01c5699f434..08d6b6e3d907e510ceee18fc1054c10aad5dde97 100644
--- a/test/module/box.lua
+++ b/test/module/box.lua
@@ -1,7 +1,7 @@
 #!/usr/bin/env tarantool
 box.cfg{
-    primary_port        = os.getenv("PRIMARY_PORT"),
-    admin_port          = os.getenv("ADMIN_PORT"),
+    listen              = os.getenv("LISTEN"),
+    admin               = os.getenv("ADMIN"),
     slab_alloc_arena    = 0.1,
     pid_file            = "tarantool.pid",
     rows_per_wal        = 50
diff --git a/test/replication/consistent.test.lua b/test/replication/consistent.test.lua
index 9cd4d4efbca70e7e983b27d936923c6b0b87d54c..a756258b8956bb6857496aac03be510ba6731a4c 100644
--- a/test/replication/consistent.test.lua
+++ b/test/replication/consistent.test.lua
@@ -35,7 +35,7 @@ do
 end;
 --# setopt delimiter ''
 --# set connection default
---# set variable replica_port to 'replica.primary_port'
+--# set variable replica_port to 'replica.listen'
 
 -- set begin lsn on master and replica.
 begin_lsn = box.info.lsn
diff --git a/test/replication/hot_standby.lua b/test/replication/hot_standby.lua
index 279e0f8b8b85e3cdb666b87c0b99bf1f382e9f1c..ffc2071338db2e829b6f352ead95c147156f9bbc 100644
--- a/test/replication/hot_standby.lua
+++ b/test/replication/hot_standby.lua
@@ -1,8 +1,8 @@
 #!/usr/bin/env tarantool
 os = require('os')
 box.cfg({
-    primary_port        = os.getenv("MASTER_PORT"),
-    admin_port          = os.getenv("ADMIN_PORT"),
+    listen              = os.getenv("MASTER"),
+    admin               = os.getenv("ADMIN"),
     slab_alloc_arena    = 0.1,
     pid_file            = "tarantool.pid",
     logger              = "tarantool.log",
diff --git a/test/replication/hot_standby.result b/test/replication/hot_standby.result
index fa9fe598473f4b7660b849e3951be45b65392773..24ed629b95eb11755ad2d986e90664219b916d96 100644
--- a/test/replication/hot_standby.result
+++ b/test/replication/hot_standby.result
@@ -57,7 +57,7 @@ end;
 --# setopt delimiter ''
 --# set connection default
 -- set begin lsn on master, replica and hot_standby.
---# set variable replica_port to 'replica.primary_port'
+--# set variable replica_port to 'replica.listen'
 a = (require 'net.box'):new('127.0.0.1', replica_port)
 ---
 ...
@@ -121,9 +121,9 @@ _select(1, 10)
 require('fiber').sleep(0.2)
 ---
 ...
--- hot_standby.primary_port is garbage, since hot_standby.lua
--- uses MASTER_PORT environment variable for its primary_port
---# set variable hot_standby_port to 'hot_standby.master_port'
+-- 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)
 ---
 ...
diff --git a/test/replication/hot_standby.test.lua b/test/replication/hot_standby.test.lua
index 8847b10eeb3977f86fc2a8c41230479d51fbc7a7..997dbd1395da4394267c58d64ecfab1a345450c3 100644
--- a/test/replication/hot_standby.test.lua
+++ b/test/replication/hot_standby.test.lua
@@ -53,7 +53,7 @@ end;
 --# set connection default
 
 -- set begin lsn on master, replica and hot_standby.
---# set variable replica_port to 'replica.primary_port'
+--# set variable replica_port to 'replica.listen'
 a = (require 'net.box'):new('127.0.0.1', replica_port)
 a:call('_set_pri_lsn', box.info.node.id, box.info.node.lsn)
 a:close()
@@ -71,9 +71,9 @@ _select(1, 10)
 --# stop server default
 require('fiber').sleep(0.2)
 
--- hot_standby.primary_port is garbage, since hot_standby.lua
--- uses MASTER_PORT environment variable for its primary_port
---# set variable hot_standby_port to 'hot_standby.master_port'
+-- 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)
 a:call('_set_pri_lsn', box.info.node.id, box.info.node.lsn)
 a:close()
diff --git a/test/replication/master.lua b/test/replication/master.lua
index 027352b10913a1b0f8eceda8a8cd04591bb5e1c9..3031d326f7ff4243f3184fa1523c0548ecebe3e1 100644
--- a/test/replication/master.lua
+++ b/test/replication/master.lua
@@ -1,8 +1,8 @@
 #!/usr/bin/env tarantool
 os = require('os')
 box.cfg({
-    primary_port        = os.getenv("PRIMARY_PORT"),
-    admin_port          = os.getenv("ADMIN_PORT"),
+    listen              = os.getenv("LISTEN"),
+    admin               = os.getenv("ADMIN"),
     slab_alloc_arena    = 0.1,
     pid_file            = "tarantool.pid",
     logger              = "| cat - >> tarantool.log",
diff --git a/test/replication/replica.lua b/test/replication/replica.lua
index 1be8b25dde4567d72667181f9f32487a47d93712..1ba51679c8bafeda5620d9d6caaa06d7d282234c 100644
--- a/test/replication/replica.lua
+++ b/test/replication/replica.lua
@@ -1,12 +1,12 @@
 #!/usr/bin/env tarantool
 
-print('MASTER_PORT: ',os.getenv("MASTER_PORT"))
+print('MASTER: ',os.getenv("MASTER"))
 print('MASTER_URI: ',os.getenv("MASTER_URI"))
 
 box.cfg({
-    primary_port        = os.getenv("PRIMARY_PORT"),
-    admin_port          = os.getenv("ADMIN_PORT"),
-    replication_source  = os.getenv("MASTER_PORT"),
+    listen              = os.getenv("LISTEN"),
+    admin               = os.getenv("ADMIN"),
+    replication_source  = os.getenv("MASTER"),
     slab_alloc_arena    = 0.1,
     pid_file            = "tarantool.pid",
     logger              = "tarantool.log",
diff --git a/test/replication/swap.test.py b/test/replication/swap.test.py
index 8709ab8e650df82722e8c06987eac69fde6676fa..451bf93a2c2cf0ff2b22d5441e5315bb3ab1f65e 100644
--- a/test/replication/swap.test.py
+++ b/test/replication/swap.test.py
@@ -25,7 +25,7 @@ master.admin("box.schema.user.create('%s', { password = '%s'})" % (LOGIN, PASSWO
 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)
-os.putenv('MASTER_PORT', master.uri)
+os.putenv('MASTER', master.uri)
 
 # replica server
 replica = TarantoolServer()
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index 3c485d9594250179e3a4c1e257803cd67851dfc8..a30f2d8ff108677ba4fb81e80b020f1e0bfc127b 100644
--- a/test/unit/CMakeLists.txt
+++ b/test/unit/CMakeLists.txt
@@ -8,11 +8,11 @@ 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_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/src/port_uri.cc
+add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/src/uri.cc
 	WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
-	COMMAND ragel -G2 src/port_uri.rl -o src/port_uri.cc
-	DEPENDS ${CMAKE_SOURCE_DIR}/src/port_uri.rl)
-add_executable(port_uri.test port_uri.cc test.c ${CMAKE_SOURCE_DIR}/src/port_uri.cc)
+	COMMAND ragel -G2 src/uri.rl -o src/uri.cc
+	DEPENDS ${CMAKE_SOURCE_DIR}/src/uri.rl)
+add_executable(uri.test uri.cc test.c ${CMAKE_SOURCE_DIR}/src/uri.cc)
 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/bps_tree.cc b/test/unit/bps_tree.cc
index 57275b43970b43985ee01b5b5ef280bdb3f86102..c73eca0ad381f208b6a51e9da4c208e82a390a3e 100644
--- a/test/unit/bps_tree.cc
+++ b/test/unit/bps_tree.cc
@@ -2,6 +2,7 @@
 #include <stdint.h>
 #include <stdio.h>
 #include <stdbool.h>
+#include <inttypes.h>
 
 #include "unit.h"
 #include "sptree.h"
@@ -13,7 +14,8 @@
 
 SPTREE_DEF(test, realloc, qsort_arg);
 
-typedef long type_t;
+typedef int64_t type_t;
+#define TYPE_F "%" PRId64
 
 static int
 compare(type_t a, type_t b);
@@ -93,7 +95,7 @@ simple_check()
 			fail("element already in tree (1)", "true");
 		bps_tree_test_insert(&tree, v, 0);
 		if (bps_tree_test_debug_check(&tree)) {
-			bps_tree_test_print(&tree, "%ld");
+			bps_tree_test_print(&tree, TYPE_F);
 			fail("debug check nonzero", "true");
 		}
 	}
@@ -106,7 +108,7 @@ simple_check()
 			fail("element in tree (1)", "false");
 		bps_tree_test_delete(&tree, v);
 		if (bps_tree_test_debug_check(&tree)) {
-			bps_tree_test_print(&tree, "%ld");
+			bps_tree_test_print(&tree, TYPE_F);
 			fail("debug check nonzero", "true");
 		}
 	}
@@ -120,7 +122,7 @@ simple_check()
 			fail("element already in tree (2)", "true");
 		bps_tree_test_insert(&tree, v, 0);
 		if (bps_tree_test_debug_check(&tree)) {
-			bps_tree_test_print(&tree, "%ld");
+			bps_tree_test_print(&tree, TYPE_F);
 			fail("debug check nonzero", "true");
 		}
 	}
@@ -133,7 +135,7 @@ simple_check()
 			fail("element in tree (2)", "false");
 		bps_tree_test_delete(&tree, v);
 		if (bps_tree_test_debug_check(&tree)) {
-			bps_tree_test_print(&tree, "%ld");
+			bps_tree_test_print(&tree, TYPE_F);
 			fail("debug check nonzero", "true");
 		}
 	}
@@ -147,7 +149,7 @@ simple_check()
 			fail("element already in tree (3)", "true");
 		bps_tree_test_insert(&tree, v, 0);
 		if (bps_tree_test_debug_check(&tree)) {
-			bps_tree_test_print(&tree, "%ld");
+			bps_tree_test_print(&tree, TYPE_F);
 			fail("debug check nonzero", "true");
 		}
 	}
@@ -160,7 +162,7 @@ simple_check()
 			fail("element in tree (3)", "false");
 		bps_tree_test_delete(&tree, v);
 		if (bps_tree_test_debug_check(&tree)) {
-			bps_tree_test_print(&tree, "%ld");
+			bps_tree_test_print(&tree, TYPE_F);
 			fail("debug check nonzero", "true");
 		}
 	}
@@ -175,7 +177,7 @@ simple_check()
 		bps_tree_test_insert(&tree, v, 0);
 		if (bps_tree_test_debug_check(&tree)) {
 			fail("debug check nonzero", "true");
-			bps_tree_test_print(&tree, "%ld");
+			bps_tree_test_print(&tree, TYPE_F);
 		}
 	}
 	if (bps_tree_test_size(&tree) != rounds)
@@ -187,7 +189,7 @@ simple_check()
 			fail("element in tree (4)", "false");
 		bps_tree_test_delete(&tree, v);
 		if (bps_tree_test_debug_check(&tree)) {
-			bps_tree_test_print(&tree, "%ld");
+			bps_tree_test_print(&tree, TYPE_F);
 			fail("debug check nonzero", "true");
 		}
 	}
@@ -554,13 +556,13 @@ printing_test()
 
 	for (type_t i = 0; i < rounds; i++) {
 		type_t v = rounds + i;
-		printf("Inserting %ld\n", v);
+		printf("Inserting " TYPE_F "\n", v);
 		bps_tree_test_insert(&tree, v, 0);
-		bps_tree_test_print(&tree, "%ld");
+		bps_tree_test_print(&tree, TYPE_F);
 		v = rounds - i - 1;
-		printf("Inserting %ld\n", v);
+		printf("Inserting " TYPE_F "\n", v);
 		bps_tree_test_insert(&tree, v, 0);
-		bps_tree_test_print(&tree, "%ld");
+		bps_tree_test_print(&tree, TYPE_F);
 	}
 
 	bps_tree_test_destroy(&tree);
@@ -583,31 +585,31 @@ white_box_test()
 	for (type_t i = 0; i < 14; i++) {
 		bps_tree_test_insert(&tree, i, 0);
 	}
-	bps_tree_test_print(&tree, "%ld");
+	bps_tree_test_print(&tree, TYPE_F);
 
 	printf("split now:\n");
 	bps_tree_test_insert(&tree, 14, 0);
-	bps_tree_test_print(&tree, "%ld");
+	bps_tree_test_print(&tree, TYPE_F);
 
 	printf("full 2 leafs:\n");
 	for (type_t i = 15; i < 28; i++) {
 		bps_tree_test_insert(&tree, i, 0);
 	}
-	bps_tree_test_print(&tree, "%ld");
+	bps_tree_test_print(&tree, TYPE_F);
 
 	printf("split now:\n");
 	bps_tree_test_insert(&tree, 28, 0);
-	bps_tree_test_print(&tree, "%ld");
+	bps_tree_test_print(&tree, TYPE_F);
 
 	printf("full 3 leafs:\n");
 	for (type_t i = 29; i < 42; i++) {
 		bps_tree_test_insert(&tree, i, 0);
 	}
-	bps_tree_test_print(&tree, "%ld");
+	bps_tree_test_print(&tree, TYPE_F);
 
 	printf("split now:\n");
 	bps_tree_test_insert(&tree, 42, 0);
-	bps_tree_test_print(&tree, "%ld");
+	bps_tree_test_print(&tree, TYPE_F);
 
 	bps_tree_test_destroy(&tree);
 	bps_tree_test_create(&tree, 0, extent_alloc, extent_free);
@@ -616,11 +618,11 @@ white_box_test()
 		arr[i] = i;
 	bps_tree_test_build(&tree, arr, 140);
 	printf("full 10 leafs:\n");
-	bps_tree_test_print(&tree, "%ld");
+	bps_tree_test_print(&tree, TYPE_F);
 
 	printf("2-level split now:\n");
 	bps_tree_test_insert(&tree, 140, 0);
-	bps_tree_test_print(&tree, "%ld");
+	bps_tree_test_print(&tree, TYPE_F);
 
 	bps_tree_test_destroy(&tree);
 
diff --git a/test/unit/port_uri.cc b/test/unit/port_uri.cc
deleted file mode 100644
index aa50ad077c92ce1919e71138f68ffe2fe37c087d..0000000000000000000000000000000000000000
--- a/test/unit/port_uri.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-#include "test.h"
-#include <port_uri.h>
-#include <string.h>
-
-#define PLAN	40
-
-int
-main(void)
-{
-	plan(PLAN);
-
-	struct port_uri uri;
-
-	is(port_uri_parse(&uri, "/file"), 0, "/file");
-	is(strcmp(port_uri_to_string(&uri), "unix:///file"), 0,
-				"to_string");
-	is(strcmp(uri.schema, "unix"), 0, "unix://");
-
-
-	is(port_uri_parse(&uri, "unix://file"), 0, "unix://file");
-	is(strcmp(port_uri_to_string(&uri), "unix://file"), 0,
-							"to_string");
-	is(strcmp(uri.schema, "unix"), 0, "unix://");
-
-
-	is(port_uri_parse(&uri, "123"), 0, "123");
-	is(strcmp(uri.schema, "tcp"), 0, "tcp://");
-	is(strcmp(port_uri_to_string(&uri), "0.0.0.0:123"), 0,
-		"to_string");
-
-
-
-	is(port_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(port_uri_to_string(&uri), "http://11.2.3.4:123"), 0,
-		"to_string");
-
-	is(port_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(port_uri_to_string(&uri), "http://11.2.3.4:123"), 0,
-		"to_string");
-	is(port_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(port_uri_parse(&uri, "schema://[2001:0db8:11a3:09d7::1]"),
-	   0, "schema://[2001:0db8:11a3:09d7::1]");
-	is(strcmp(port_uri_to_string(&uri),
-		"schema://[2001:db8:11a3:9d7::1]:0"), 0, "to_string");
-
-
-	isnt(port_uri_parse(&uri, "schema://[2001::11a3:09d7::1]"),
-	     0, "invalid schema://[2001::11a3:09d7::1]");
-
-
-
-
-	is(port_uri_parse(&uri, "128.0.0.1"), 0, "127.0.0.1");
-	is(strcmp(port_uri_to_string(&uri), "128.0.0.1:0"), 0,
-		"to_string");
-
-	is(port_uri_parse(&uri, "128.0.0.1:22"), 0, "127.0.0.1:22");
-	is(strcmp(port_uri_to_string(&uri), "128.0.0.1:22"), 0,
-		"to_string");
-
-	is(port_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(port_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(port_uri_to_string(&uri), "unix:///path/to"), 0,
-		"to_string");
-
-	isnt(port_uri_parse(&uri, "tcp://abc.cde:90"), 0, "invalid uri");
-
-	is(port_uri_parse(&uri, "http://127.0.0.1:http"), 0,
-	   "valid uri");
-	is(strcmp(port_uri_to_string(&uri), "http://127.0.0.1:80"), 0,
-	   "service to port number");
-
-	is(port_uri_parse(&uri, "mail.ru:https"), 0, "valid uri");
-
-	isnt(strstr(port_uri_to_string(&uri), ":443"), 0,
-		"service converted");
-
-	return check_plan();
-}
diff --git a/test/unit/uri.cc b/test/unit/uri.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d07b410c777e072263b40eb6a0765ebb405a6f69
--- /dev/null
+++ b/test/unit/uri.cc
@@ -0,0 +1,98 @@
+#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/port_uri.result b/test/unit/uri.result
similarity index 100%
rename from test/unit/port_uri.result
rename to test/unit/uri.result
diff --git a/test/wal/wal.lua b/test/wal/wal.lua
index 78ba7b29ff33f3b9d87626079aa2f736f34e7d90..9ef4a7971e6aa9ef505c68264d14bc486f7b6fb4 100644
--- a/test/wal/wal.lua
+++ b/test/wal/wal.lua
@@ -1,7 +1,7 @@
 #!/usr/bin/env tarantool
 box.cfg{
-    primary_port        = os.getenv("PRIMARY_PORT"),
-    admin_port          = os.getenv("ADMIN_PORT"),
+    listen              = os.getenv("LISTEN"),
+    admin              = os.getenv("ADMIN"),
     slab_alloc_arena    = 0.1,
     pid_file            = "tarantool.pid",
     wal_mode            = "none"