diff --git a/src/Makefile.am b/src/Makefile.am
index 0f10b2496d328284cdcdea0a908fb35a01a687ca..452e31f1c3248ebe9528b5068431f317cbb9ccf8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,7 +1,6 @@
 ACLOCAL_AMFLAGS = -I ../m4
-
-libexec_PROGRAMS = knot-zcompile unittests-libknot
-sbin_PROGRAMS = 
+libexec_PROGRAMS = unittests unittests-xfr unittests-zscanner
+sbin_PROGRAMS = knotc knotd
 dist_man_MANS = knot.conf.5 knotc.8 knotd.8
 
 # $(YACC) will generate header file
@@ -10,26 +9,69 @@ AM_YFLAGS = -d
 libknotd_la_YFLAGS = -pcf_ -d
 libknotd_la_LFLAGS = # TODO: reentrant parser, prefix
 
-zscanner/scanner.c: zscanner/scanner.rl zscanner/scanner_body.rl
-	$(RAGEL) -s -o zscanner/scanner.c zscanner/scanner.rl
+BUILT_SOURCES =					\
+	tests/sample_conf.rc			\
+	zparser.h				\
+	zparser.c				\
+	zlexer.c				\
+	libknotd_la-cf-lex.c			\
+	libknotd_la-cf-parse.c			\
+	libknotd_la-cf-parse.h
 
-knot_zcompile_SOURCES =				\
-	knot/server/zones.c			\
-	knot/server/zones.h			\
-	libknot/packet/packet.h			\
-	libknot/packet/packet.c			\
-	libknot/packet/query.c			
-	libknot/packet/query.h			\
-	libknot/packet/response.h		\
-	libknot/packet/response.c		\
-	libknot/rrset.c				\
-	libknot/rrset.h				\
-	common/slab/slab.c			\
-	knot/main.c				\
-	zcompile/zcompile-error.c		\
-	zcompile/zcompile.c			\
-	zscanner/test/processing.h		\
-	zscanner/test/processing.c		\
+CLEANFILES =					\
+	tests/sample_conf.rc			\
+	zparser.h				\
+	zparser.c				\
+	zlexer.c				\
+	libknotd_la-cf-lex.c			\
+	libknotd_la-cf-parse.c			\
+	libknotd_la-cf-parse.h
+
+knotc_SOURCES =					\
+	knot/ctl/knotc_main.c
+
+unittests_SOURCES =				\
+	tests/common/acl_tests.c		\
+	tests/common/acl_tests.h		\
+	tests/common/base32hex_tests.c		\
+	tests/common/base32hex_tests.h		\
+	tests/common/base64_tests.c		\
+	tests/common/base64_tests.h		\
+	tests/common/events_tests.c		\
+	tests/common/events_tests.h		\
+	tests/common/skiplist_tests.c		\
+	tests/common/skiplist_tests.h		\
+	tests/common/slab_tests.c		\
+	tests/common/slab_tests.h		\
+	tests/common/fdset_tests.c		\
+	tests/common/fdset_tests.h		\
+	tests/knot/conf_tests.c			\
+	tests/knot/conf_tests.h			\
+	tests/knot/dthreads_tests.c		\
+	tests/knot/dthreads_tests.h		\
+	tests/knot/journal_tests.c		\
+	tests/knot/journal_tests.h		\
+	tests/knot/server_tests.c		\
+	tests/knot/server_tests.h		\
+	tests/unittests_main.c
+
+unittests_xfr_SOURCES = 			\
+	tests/xfr_tests.c			\
+	tests/xfr_tests.h
+
+nodist_unittests_SOURCES =			\
+	tests/libknot/parsed_data.rc		\
+	tests/libknot/raw_data_queries.rc	\
+	tests/libknot/raw_data.rc		\
+	tests/libknot/parsed_data_queries.rc	\
+	tests/sample_conf.rc
+
+knotd_SOURCES =					\
+	knot/main.c
+
+noinst_LTLIBRARIES = libknot.la libknotd.la libknots.la libzscanner.la
+
+libknot_la_SOURCES =				\
 	libknot/util/utils.c			\
 	libknot/util/debug.c			\
 	libknot/util/debug.h			\
@@ -37,8 +79,12 @@ knot_zcompile_SOURCES =				\
 	libknot/util/tolower.h			\
 	libknot/util/tolower.c			\
 	libknot/util/wire.h			\
-	libknot/nameserver/name-server.h	\
-	libknot/nameserver/name-server.c	\
+	libknot/packet/query.c			\
+	libknot/packet/response.c		\
+	libknot/packet/packet.c			\
+	libknot/packet/packet.h			\
+	libknot/packet/query.h			\
+	libknot/packet/response.h		\
 	libknot/zone/zone.c			\
 	libknot/zone/zone-contents.c		\
 	libknot/zone/zone-tree.c		\
@@ -46,37 +92,50 @@ knot_zcompile_SOURCES =				\
 	libknot/zone/node.h			\
 	libknot/zone/zone.h			\
 	libknot/zone/zone-contents.h		\
+	libknot/zone/zonedb.c			\
+	libknot/zone/zonedb.h			\
 	libknot/zone/node.c			\
 	libknot/zone/dname-table.h		\
 	libknot/zone/dname-table.c		\
-	libknot/zone/zonedb.h			\
-	libknot/zone/zonedb.c			\
-	libknot/updates/changesets.c		\
+	libknot/zone/zone-diff.h		\
+	libknot/zone/zone-diff.c		\
+	zcompile/zcompile.h			\
+	zcompile/zcompile.c			\
+	libknot/hash/hash-functions.c		\
+	libknot/hash/cuckoo-hash-table.c	\
+	libknot/hash/universal-system.c		\
+	libknot/hash/universal-system.h		\
+	libknot/hash/cuckoo-hash-table.h	\
+	libknot/hash/hash-functions.h		\
+	libknot/nameserver/name-server.h	\
+	libknot/nameserver/name-server.c	\
 	libknot/updates/changesets.h		\
-	libknot/updates/xfr-in.c		\
+	libknot/updates/changesets.c		\
 	libknot/updates/xfr-in.h		\
+	libknot/updates/xfr-in.c		\
 	libknot/updates/ddns.h			\
 	libknot/updates/ddns.c			\
+	libknot/edns.c				\
+	libknot/rrset.c				\
 	libknot/dname.c				\
-	libknot/dname.h				\
-	libknot/nsec3.h				\
 	libknot/nsec3.c				\
+	libknot/consts.h			\
 	libknot/edns.h				\
-	libknot/edns.c				\
+	libknot/libknot.h			\
+	libknot/dname.h				\
+	libknot/rrset.h				\
+	libknot/nsec3.h				\
 	libknot/tsig.h				\
 	libknot/tsig.c				\
 	libknot/tsig-op.h			\
-	libknot/tsig-op.c			\
+	libknot/tsig-op.c
+
+libknots_la_SOURCES =				\
+	common/slab/slab.c			\
 	common/slab/slab.h			\
 	common/libtap/tap.c			\
 	common/libtap/tap.h			\
 	common/libtap/tap_unit.h		\
-	common/hattrie/ahtable.c		\
-	common/hattrie/ahtable.h		\
-	common/hattrie/hat-trie.c		\
-	common/hattrie/hat-trie.h		\
-	common/hattrie/murmurhash3.c		\
-	common/hattrie/murmurhash3.h		\
 	common/mempattern.h			\
 	common/mempattern.c			\
 	common/descriptor_new.h			\
@@ -125,179 +184,81 @@ knot_zcompile_SOURCES =				\
 	common/fdset_kqueue.c			\
 	common/fdset_epoll.h			\
 	common/fdset_epoll.c			\
-	knot/server/journal.h			\
+	common/log.c				\
+	common/log.h				\
+	common/hattrie/ahtable.c		\
+	common/hattrie/ahtable.h		\
+	common/hattrie/hat-trie.c		\
+	common/hattrie/hat-trie.h		\
+	common/hattrie/murmurhash3.c		\
+	common/hattrie/murmurhash3.h
+
+
+libknotd_la_SOURCES =				\
+	knot/stat/gatherer.c			\
+	knot/stat/stat.c			\
+	knot/stat/gatherer.h			\
+	knot/stat/stat.h			\
+	knot/common.h				\
+	knot/other/debug.h			\
+	knot/conf/cf-parse.y			\
+	knot/conf/cf-lex.l			\
+	knot/conf/conf.c			\
+	knot/conf/logconf.c			\
+	knot/conf/logconf.h			\
+	knot/conf/conf.h			\
+	knot/ctl/process.c			\
+	knot/ctl/process.h			\
+	knot/ctl/remote.c			\
+	knot/ctl/remote.h			\
+	knot/server/dthreads.c			\
 	knot/server/journal.c			\
 	knot/server/socket.c			\
-	knot/server/socket.h			\
-	knot/server/notify.h			\
-	knot/server/notify.c			\
-	knot/server/dthreads.c			\
-	knot/server/dthreads.h			\
-	knot/server/tcp-handler.c		\
-	knot/server/tcp-handler.h		\
+	knot/server/server.c			\
 	knot/server/udp-handler.c		\
+	knot/server/tcp-handler.c		\
+	knot/server/xfr-handler.c		\
+	knot/server/zones.c			\
+	knot/server/socket.h			\
 	knot/server/udp-handler.h		\
+	knot/server/tcp-handler.h		\
 	knot/server/xfr-handler.h		\
-	knot/server/xfr-handler.c		\
-	knot/server/server.h			\
-	knot/server/server.c			\
-	knot/ctl/process.c			\
-	knot/ctl/process.h			\
-	knot/ctl/remote.c			\
-	knot/ctl/remote.h			\
-	knot/conf/conf.c			\
-	knot/conf/conf.h			\
-	knot/conf/logconf.c			\
-	knot/conf/logconf.h			\
-	knot/conf/cf-parse.y			\
-	knot/conf/cf-lex.l			\
-	common/log.c				\
-	common/log.h				\
+	knot/server/dthreads.h			\
+	knot/server/journal.h			\
+	knot/server/zones.h			\
+	knot/server/notify.h			\
+	knot/server/notify.c			\
+	knot/server/zones.h			\
+	knot/zone/semantic-check.c		\
+	knot/zone/semantic-check.h		\
+	knot/server/server.h
+
+zscanner/scanner.c: zscanner/scanner.rl zscanner/scanner_body.rl
+	$(RAGEL) -s -o zscanner/scanner.c zscanner/scanner.rl
+
+unittests_zscanner_SOURCES =			\
+	zscanner/test/zscanner_test.c		\
+	zscanner/test/tests.h			\
+	zscanner/test/tests.c			\
+	zscanner/test/processing.h		\
+	zscanner/test/processing.c
+
+libzscanner_la_SOURCES =			\
 	zscanner/file_loader.h			\
 	zscanner/file_loader.c			\
 	zscanner/scanner.h			\
 	zscanner/scanner.c			\
 	zscanner/scanner_functions.h		\
 	zscanner/scanner_functions.c
-	
-unittests_libknot_SOURCES =			\
-knot/server/zones.c			\
-knot/server/zones.h			\
-libknot/packet/packet.h			\
-libknot/packet/packet.c			\
-libknot/packet/query.c			\
-libknot/packet/query.h			\
-libknot/packet/response.h		\
-libknot/packet/response.c		\
-libknot/rrset.c				\
-libknot/rrset.h				\
-common/slab/slab.c			\
-zcompile/zcompile-error.c		\
-zcompile/zcompile.c			\
-zscanner/test/processing.h		\
-zscanner/test/processing.c		\
-libknot/util/utils.c			\
-libknot/util/debug.c			\
-libknot/util/debug.h			\
-libknot/util/utils.h			\
-libknot/util/tolower.h			\
-libknot/util/tolower.c			\
-libknot/util/wire.h			\
-libknot/nameserver/name-server.h	\
-libknot/nameserver/name-server.c	\
-libknot/zone/zone.c			\
-libknot/zone/zone-contents.c		\
-libknot/zone/zone-tree.c		\
-libknot/zone/zone-tree.h		\
-libknot/zone/node.h			\
-libknot/zone/zone.h			\
-libknot/zone/zone-contents.h		\
-libknot/zone/node.c			\
-libknot/zone/dname-table.h		\
-libknot/zone/dname-table.c		\
-libknot/zone/zonedb.h			\
-libknot/zone/zonedb.c			\
-libknot/dname.c				\
-libknot/dname.h				\
-libknot/nsec3.h				\
-libknot/nsec3.c				\
-libknot/edns.h				\
-libknot/edns.c				\
-libknot/tsig.h				\
-libknot/tsig.c				\
-libknot/tsig-op.h			\
-libknot/tsig-op.c			\
-common/slab/slab.h			\
-common/libtap/tap.c			\
-common/libtap/tap.h			\
-common/libtap/tap_unit.h		\
-common/hattrie/ahtable.c		\
-common/hattrie/ahtable.h		\
-common/hattrie/hat-trie.c		\
-common/hattrie/hat-trie.h		\
-common/hattrie/murmurhash3.c		\
-common/hattrie/murmurhash3.h		\
-common/mempattern.h			\
-common/mempattern.c			\
-common/descriptor_new.h			\
-common/descriptor_new.c			\
-common/lists.c				\
-common/base64.c				\
-common/base64.h				\
-common/lists.h				\
-common/heap.h				\
-common/heap.c				\
-common/print.c				\
-common/print.h				\
-common/skip-list.c			\
-common/base32hex.c			\
-common/skip-list.h			\
-common/general-tree.h			\
-common/general-tree.c			\
-common/tree.h				\
-common/base32hex.h			\
-common/evqueue.h			\
-common/evqueue.c			\
-common/evsched.h			\
-common/evsched.c			\
-common/acl.h				\
-common/acl.c				\
-common/sockaddr.h			\
-common/sockaddr.c			\
-common/crc.h				\
-common/ref.h				\
-common/ref.c				\
-common/errors.h				\
-common/errors.c				\
-common/errcode.h			\
-common/errcode.c			\
-common/dSFMT.h				\
-common/dSFMT-params.h			\
-common/dSFMT-params521.h		\
-common/dSFMT.c				\
-common/prng.h				\
-common/prng.c				\
-common/fdset.h				\
-common/fdset.c				\
-common/fdset_poll.h			\
-common/fdset_poll.c			\
-common/fdset_kqueue.h			\
-common/fdset_kqueue.c			\
-common/fdset_epoll.h			\
-common/fdset_epoll.c			\
-knot/server/journal.h			\
-knot/server/journal.c			\
-knot/server/socket.c			\
-knot/server/socket.h			\
-knot/server/notify.h			\
-knot/server/notify.c			\
-knot/server/dthreads.c			\
-knot/server/dthreads.h			\
-knot/server/tcp-handler.c		\
-knot/server/tcp-handler.h		\
-knot/server/udp-handler.c		\
-knot/server/udp-handler.h		\
-knot/conf/conf.c			\
-knot/conf/conf.h			\
-knot/conf/logconf.c			\
-knot/conf/logconf.h			\
-knot/conf/cf-parse.y			\
-knot/conf/cf-lex.l			\
-common/log.c				\
-common/log.h				\
-zscanner/file_loader.h			\
-zscanner/file_loader.c			\
-zscanner/scanner.h			\
-zscanner/scanner.c			\
-zscanner/scanner_functions.h		\
-zscanner/scanner_functions.c		\
-	tests/libknot/libknot/rrset_tests.c	\
-	tests/libknot/libknot/rrset_tests.h	\
-	tests/libknot/unittests_libknot.c
-
-knot_zcompile_LDADD = @LIBOBJS@
 
-unittests_libknot_LDADD = @LIBOBJS@
+libknotd_la_LIBADD = libknot.la libknots.la @LIBOBJS@
+libknots_la_LIBADD = libzscanner.la @LIBOBJS@
+libzscanner_la_LIBADD = @LIBOBJS@
+knotd_LDADD = libknotd.la libknot.la libknots.la @LIBOBJS@
+knotc_LDADD = libknotd.la libknot.la libknots.la @LIBOBJS@
+unittests_LDADD = libknotd.la libknots.la @LIBOBJS@
+unittests_xfr_LDADD = libknotd.la libknot.la libknots.la @LIBOBJS@
+unittests_zscanner_LDADD = libknots.la libknot.la libknotd.la libzscanner.la @LIBOBJS@
 
 # automake complains on % rules:
 #   `%'-style pattern rules are a GNU make extension
@@ -305,4 +266,3 @@ unittests_libknot_LDADD = @LIBOBJS@
 tests/sample_conf.rc: tests/files/sample_conf
 	../resource.sh tests/files/sample_conf >$@
 
-
diff --git a/src/knot/ctl/knotc_main.c b/src/knot/ctl/knotc_main.c
index eccc94cfc4bf83a2752bddaa7aa7dd29590aeba4..8dbef8b9a414e1941c0640aaaa085777ec7cb516 100644
--- a/src/knot/ctl/knotc_main.c
+++ b/src/knot/ctl/knotc_main.c
@@ -33,6 +33,7 @@
 #endif
 
 #include "knot/common.h"
+#include "common/descriptor_new.h"
 #include "knot/ctl/process.h"
 #include "knot/ctl/remote.h"
 #include "knot/conf/conf.h"
@@ -164,21 +165,23 @@ static int check_zone(const char *db, const char *source)
 	}
 
 	/* Read zonedb header. */
-	zloader_t *zl = 0;
-	knot_zload_open(&zl, db);
-	if (!zl) {
-		return KNOT_ERROR;
-	}
-
-	/* Check source files and mtime. */
-	int ret = KNOT_ERROR;
-	int src_changed = strcmp(source, zl->source) != 0;
-	if (!src_changed && !knot_zload_needs_update(zl)) {
-		ret = KNOT_EOK;
-	}
-
-	knot_zload_close(zl);
-	return ret;
+	assert(0); // TODO replace with checking actual zone file.
+//	zloader_t *zl = 0;
+//	knot_zload_open(&zl, db);
+//	if (!zl) {
+//		return KNOT_ERROR;
+//	}
+
+//	/* Check source files and mtime. */
+//	int ret = KNOT_ERROR;
+//	int src_changed = strcmp(source, zl->source) != 0;
+//	if (!src_changed && !knot_zload_needs_update(zl)) {
+//		ret = KNOT_EOK;
+//	}
+
+//	knot_zload_close(zl);
+//	return ret;
+	return KNOT_EOK;
 }
 
 /*! \brief Zone compiler task. */
@@ -272,22 +275,13 @@ static int cmd_remote_print_reply(const knot_rrset_t *rr)
 		return KNOT_EMALF;
 	}
 	
-	const knot_rdata_t *rd = knot_rrset_rdata(rr);
-	while (rd != NULL) {
-		/* Skip empty nodes. */
-		if (knot_rdata_item_count(rd) < 1) {
-			rd = knot_rrset_rdata_next(rr, rd);
-			continue;
-		}
-
+	for (uint16_t i = 0; i < knot_rrset_rdata_rr_count(rr); i++) {
 		/* Parse TXT. */
-		char* txt = remote_parse_txt(rd);
+		char* txt = remote_parse_txt(rr, i);
 		if (txt) {
 			log_server_info("Server reply: %s\n", txt);
 		}
 		free(txt);
-
-		rd = knot_rrset_rdata_next(rr, rd);
 	}
 	
 	return KNOT_EOK;
@@ -353,24 +347,21 @@ static int cmd_remote(const char *cmd, uint16_t rrt, int argc, char *argv[])
 	}
 	
 	/* Build query data. */
-	knot_rdata_t *rd = NULL;
 	knot_rrset_t *rr = remote_build_rr("data.", rrt);
 	for (int i = 0; i < argc; ++i) {
 		switch(rrt) {
 		case KNOT_RRTYPE_CNAME:
-			rd = remote_create_cname(argv[i]);
+			remote_create_cname(rr, argv[i]);
 			break;
 		case KNOT_RRTYPE_TXT:
 		default:
-			rd = remote_create_txt(argv[i]);
+			remote_create_txt(rr, argv[i]);
 			break;
 		}
-		knot_rrset_add_rdata(rr, rd);
-		rd = NULL;
 	}
 	remote_query_append(qr, rr);
 	if (knot_packet_to_wire(qr, &buf, &buflen) != KNOT_EOK) {
-		knot_rrset_deep_free(&rr, 1, 1, 1);
+		knot_rrset_deep_free(&rr, 1, 1);
 		knot_packet_free(&qr);
 		return 1;
 	}
@@ -399,7 +390,7 @@ static int cmd_remote(const char *cmd, uint16_t rrt, int argc, char *argv[])
 	}
 	
 	/* Cleanup. */
-	knot_rrset_deep_free(&rr, 1, 1, 1);
+	knot_rrset_deep_free(&rr, 1, 1);
 	
 	/* Close connection. */
 	socket_close(s);
diff --git a/src/knot/ctl/remote.c b/src/knot/ctl/remote.c
index 902093f5fafb449fdfbb8821543cdac5868e525f..1cbd19b71a158c56d05f57d7c4f962c2ad9bd417 100644
--- a/src/knot/ctl/remote.c
+++ b/src/knot/ctl/remote.c
@@ -659,7 +659,7 @@ int remote_create_cname(knot_rrset_t *rr, const char *d)
 	return KNOT_EOK;
 }
 
-char* remote_parse_txt(const knot_rrset_t *rr)
+char* remote_parse_txt(const knot_rrset_t *rr, size_t rr_pos)
 {
 	if (!rr || knot_rrset_rdata_rr_count(rr) < 1) {
 		return NULL;
diff --git a/src/knot/ctl/remote.h b/src/knot/ctl/remote.h
index 4ca8681054eea8a8fc8006c8b6e341ce3ef91398..412ab616ec89832067b95aa7f693756a5648017b 100644
--- a/src/knot/ctl/remote.h
+++ b/src/knot/ctl/remote.h
@@ -189,7 +189,7 @@ int remote_create_cname(knot_rrset_t *rr, const char *d);
  * \param rd TXT rdata.
  * \return Parsed string or NULL.
  */
-char* remote_parse_txt(const knot_rrset_t *rrset);
+char* remote_parse_txt(const knot_rrset_t *rrset, size_t rr_pos);
 
 /*!
  * \brief Create dname from str and make sure the name is FQDN.