diff --git a/.gitignore b/.gitignore
index b1904b76a24db1535a27320153af8adeff34ebff..9735242a6cbad83662468a98bd055a429ae77591 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,7 +51,6 @@
 /m4/lt~obsolete.m4
 # Binaries
 /src/tests/unittests
-/src/tests/unittests_xfr
 /src/zscanner/zscanner-tool
 /src/knotc
 /src/knotd
@@ -73,4 +72,3 @@ src/zscanner/test/cases/06-0_INCLUDE.in
 src/zscanner/test/cases/06-3_INCLUDE.in
 src/zscanner/test/cases/06-4_INCLUDE.in
 src/zscanner/test/run_tests.sh
-/knot-*/
diff --git a/Knot.files b/Knot.files
index eedbed47969f81fa327a60734de841b7683c8fc3..c3d9f1fd2be1b4e5c69f37b9674e4f9ad56b02bf 100644
--- a/Knot.files
+++ b/Knot.files
@@ -20,8 +20,6 @@ doc/troubleshooting.texi
 man/Makefile.am
 samples/Makefile.am
 src/Makefile.am
-src/Makefile.am
-src/Makefile.am
 src/common/acl.c
 src/common/acl.h
 src/common/atomic.h
@@ -243,8 +241,6 @@ src/tests/libknot/wire_tests.h
 src/tests/libknot/ztree_tests.c
 src/tests/libknot/ztree_tests.h
 src/tests/unittests_main.c
-src/tests/xfr_tests.c
-src/tests/xfr_tests.h
 src/utils/common/exec.c
 src/utils/common/exec.h
 src/utils/common/msg.c
diff --git a/configure.ac b/configure.ac
index 294f04eb1d4daa0761329353c7a611058863f77a..a43761fb103d60969cfdc60db70f500e524de5ca 100644
--- a/configure.ac
+++ b/configure.ac
@@ -9,6 +9,10 @@ AC_CONFIG_HEADERS([src/config.h])
 AC_CONFIG_MACRO_DIR([m4])
 AC_USE_SYSTEM_EXTENSIONS([_GNU_SOURCE])
 
+# Automatically update release date based on configure.ac date
+release_date=`doc/mdate-sh configure.ac`
+AC_SUBST([RELEASE_DATE], $release_date)
+
 # Check SSE, SSE2 and SSE3 support
 AX_EXT
 CFLAGS="$CFLAGS $SIMD_FLAGS"
@@ -64,7 +68,7 @@ AC_PROG_INSTALL
 # Check for Ragel
 AC_PATH_PROG([RAGEL], [ragel], [true])
 AM_CONDITIONAL([HAVE_RAGEL], test "$RAGEL" != "true")
-  
+
 # Set FSM type for Ragel
 AC_SUBST([FSM_TYPE], [-T0])
 AC_ARG_ENABLE([fastparser],
@@ -140,6 +144,11 @@ AC_ARG_ENABLE([recvmmsg],
     fi
     ])
 
+# Enable integrity check
+AC_ARG_ENABLE([integrity-check],
+    AS_HELP_STRING([--enable-integrity-check], [enable integrity check in knotd via SIGUSR1]),
+    [AC_DEFINE([INTEGRITY_CHECK], [1], [integrity check in knotd])])
+
 # Check for link time optimizations support and predictive commoning
 AC_ARG_ENABLE([lto],
     AS_HELP_STRING([--enable-lto=yes|no], [enable link-time optimizations, enable if not broken for some extra speed [default=no]]),
@@ -163,16 +172,22 @@ AX_CHECK_COMPILE_FLAG("-fno-strict-aliasing", [CFLAGS="$CFLAGS -fno-strict-alias
 # Default directories
 run_dir="${localstatedir}/run/knot"
 AC_ARG_WITH([rundir],
-        AC_HELP_STRING([--with-rundir=path], [Path to run-time variable data (pid, sockets...). [default=`eval echo ${localstatedir}`/run/knot]]),
+        AC_HELP_STRING([--with-rundir=path], [Path to run-time variable data (pid, sockets...). [default=LOCALSTATEDIR/run/knot]]),
         [run_dir=$withval])
 AC_SUBST(run_dir)
 
-storage_dir="${sharedstatedir}/knot"
+storage_dir="${localstatedir}/lib/knot"
 AC_ARG_WITH([storage],
-        AC_HELP_STRING([--with-storage=path], [Default storage directory (slave zones, persistent data). [default=$(sharedstatedir)/knot]]),
+        AC_HELP_STRING([--with-storage=path], [Default storage directory (slave zones, persistent data). [default=LOCALSTATEDIR/lib/knot]]),
         [storage_dir=$withval])
 AC_SUBST(storage_dir)
 
+config_dir="${sysconfdir}/knot"
+AC_ARG_WITH([configdir],
+        AC_HELP_STRING([--with-configdir=path], [Default directory for configuration. [default=SYSCONFDIR/knot]]),
+        [config_dir=$withval])
+AC_SUBST(config_dir)
+
 # Checks for libraries.
 # FIXME: Replace `main' with a function in `-lm':
 
diff --git a/doc/configuration.texi b/doc/configuration.texi
index 1f1a5cab3680c03254b61333fac1c4db09d00545..5dd55497d9ab49448a623169a2e80a2b028cd2fd 100644
--- a/doc/configuration.texi
+++ b/doc/configuration.texi
@@ -57,8 +57,8 @@ Now let's go step by step through this minimal configuration file:
 
 @item
 In @code{system} statement we have configured @code{storage}
-directory where Knot DNS will store compiled zone files,
-PID file and for slave zone also their journal files. (See @ref{system} and @ref{storage})
+directory where Knot DNS will store slave zones and journal files.
+(See @ref{system} and @ref{storage})
 
 @item
 The @code{interfaces} statement defines interfaces where Knot
diff --git a/doc/knot.texi b/doc/knot.texi
index f4eaa5613732938e164a69980b47ac35872efd54..4398432fded0249335da471a418b001dbd6bdf7d 100644
--- a/doc/knot.texi
+++ b/doc/knot.texi
@@ -172,6 +172,7 @@ Statement Definition and Usage
 * nsid::
 * storage::
 * rundir::
+* pidfile::
 * workers::
 * user::
 * max-conn-idle::
diff --git a/doc/reference.texi b/doc/reference.texi
index 57324b75e21f8fc9624d7d9ed5a0f4a3ddefb2a1..734495632fab6887a9fa5f1916aba2bca2b7e7e2 100644
--- a/doc/reference.texi
+++ b/doc/reference.texi
@@ -40,6 +40,7 @@ else.
   [ @code{nsid} ( @code{"}@kbd{string}@code{"} | @kbd{hex_string} )@code{;} ]
   [ @code{storage} @code{"}@kbd{string}@code{";} ]
   [ @code{rundir} @code{"}@kbd{string}@code{";} ]
+  [ @code{pidfile} @code{"}@kbd{string}@code{";} ]
   [ @code{workers} @kbd{integer}@code{;} ]
   [ @code{user} @kbd{string}[@code{.}@kbd{string}]@code{;} ]
   [ @code{max-conn-idle} ( @kbd{integer} | @kbd{integer}(@code{s} | @code{m} | @code{h} | @code{d})@code{;} ) ]
@@ -62,6 +63,7 @@ else.
 * nsid::
 * storage::
 * rundir::
+* pidfile::
 * workers::
 * user::
 * max-conn-idle::
@@ -139,9 +141,8 @@ system @{
 @subsubsection storage
 @vindex storage
 
-The working directory of Knot DNS, it is used to store compiled zone files and
-other persistent data.
-Default: @file{$@{sharedstatedir@}/knot}, configured with @code{--with-storage=path}
+The working directory of Knot DNS, it is used to store zone files and journal files.
+Default: @file{$@{localstatedir@}/lib/knot}, configured with @code{--with-storage=path}
 
 @example
 system @{
@@ -162,6 +163,20 @@ system @{
 @}
 @end example
 
+@node pidfile
+@subsubsection pidfile
+@vindex pidfile
+
+Specifies a custom PID file location.
+
+Default value: @file{knot.pid} in @code{rundir} directory.
+
+@example
+system @{
+  pidfile "/var/run/knot/knot_dmz.pid";
+@}
+@end example
+
 @node workers
 @subsubsection workers
 @vindex workers
diff --git a/doc/running.texi b/doc/running.texi
index 1a98a072aa331a8224dd1ba05ee3eee5ee86b6fc..cfa88109c33642fc3b7b5f09ef8130997d646ec6 100644
--- a/doc/running.texi
+++ b/doc/running.texi
@@ -37,7 +37,8 @@ Usage: knotc [parameters] <action> [action_args]
 
 Parameters:
  -c [file], --config=[file] Select configuration file.
- -s [server]                Remote UNIX socket/IP address (default $@{rundir@}/knot.sock).
+ -s [server]                Remote UNIX socket/IP address
+                              (default $@{rundir@}/knot.sock).
  -p [port]                  Remote server port (only for IP).
  -y [[hmac:]name:key]       Use key_id specified on the command line.
  -k [file]                  Use key file (as in config section 'keys').
@@ -61,24 +62,34 @@ Actions:
  zonestatus                 Show status of configured zones.
  checkconf                  Check current server configuration.
  checkzone [zone]           Check zone (all if not specified).
- memstats [zone]            Estimate memory consumption for zone (all if not specified).
+ memstats [zone]            Estimate memory consumption for zone
+                              (all if not specified).
 @end example
 
-Also, the server needs to create several files in order to run properly.
-Zones and related data are stored in the directory described by @code{storage} (@pxref{storage}).
+Also, the server needs to create several files in order to run properly. These
+files are stored in the folowing directories.
+
+@code{storage} (@pxref{storage}):
+
 @itemize @bullet
+@item
+@emph{Zone files} - default directory for storing zone files. This can be overriden
+using absolute zone file location. 
+
 @item
 @emph{Journal files} - each zone has a journal file to store differences for IXFR and
-dynamic updates. Journal for zone @code{example.com} will be
-placed in @file{STORAGE/example.com.diff.db}.
+dynamic updates. Journal for zone @code{example.com} will be placed in @file{example.com.diff.db}.
+@end itemize
+
+@code{rundir} (@pxref{rundir}):
 
+@itemize @bullet
 @item
-@emph{PID file} - is created automatically in @code{rundir} (@pxref{rundir}) when
-the server is run in background.
+@emph{PID file} - is created automatically when the server is run in background.
 
 @item
-@emph{Control sockets} - as a default, UNIX sockets are created in @code{rundir} (@pxref{rundir}),
-but can be overriden.
+@emph{Control sockets} - as a default, UNIX sockets are created here,
+but this can be overriden.
 @end itemize
 
 @node Running a slave server
diff --git a/man/kdig.1.in b/man/kdig.1.in
index b4d58be235c1db0f8ba6e1f6a85227816f2983b3..4679abfb0911a902225d79d1313ea2110fb05ba2 100644
--- a/man/kdig.1.in
+++ b/man/kdig.1.in
@@ -1,4 +1,4 @@
-.TH "kdig" "1" "April 2013" "CZ.NIC Labs" "Knot DNS, version @VERSION@"
+.TH "kdig" "1" "@RELEASE_DATE@" "CZ.NIC Labs" "Knot DNS, version @VERSION@"
 .SH NAME
 .TP 5
 .B kdig
diff --git a/man/khost.1.in b/man/khost.1.in
index 805d96c5093ebf6bc52712f32af8173bbb020b62..e25ba359d06882f465ef072427ac1107f518e5e7 100644
--- a/man/khost.1.in
+++ b/man/khost.1.in
@@ -1,4 +1,4 @@
-.TH "khost" "1" "April 2013" "CZ.NIC Labs" "Knot DNS, version @VERSION@"
+.TH "khost" "1" "@RELEASE_DATE@" "CZ.NIC Labs" "Knot DNS, version @VERSION@"
 .SH NAME
 .TP 6
 .B khost
diff --git a/man/knot.conf.5.in b/man/knot.conf.5.in
index 2821673cbcac56fe9c09fe3256e5bc446d06fe53..2ccc7678e2ad550b854eaa94a9b68292f0b09373 100644
--- a/man/knot.conf.5.in
+++ b/man/knot.conf.5.in
@@ -1,4 +1,4 @@
-.TH "knot.conf" "5" "September 2012" "CZ.NIC Labs" "Knot DNS, version @VERSION@"
+.TH "knot.conf" "5" "@RELEASE_DATE@" "CZ.NIC Labs" "Knot DNS, version @VERSION@"
 .SH "NAME"
 .LP
 .B knot.conf
diff --git a/man/knotc.8.in b/man/knotc.8.in
index 441f15625a6e497c486526af857837efee54588a..343fd023395e57031e9d78602d35f40eaaae8f40 100644
--- a/man/knotc.8.in
+++ b/man/knotc.8.in
@@ -1,4 +1,4 @@
-.TH knotc "8" "September 2012" "CZ.NIC Labs" "Knot DNS, version @VERSION@"
+.TH knotc "8" "@RELEASE_DATE@" "CZ.NIC Labs" "Knot DNS, version @VERSION@"
 .SH NAME
 .B knotc
 \- Knot DNS control utility
diff --git a/man/knotd.8.in b/man/knotd.8.in
index 83088c5f7a291159a2aa43eebfbf0d2b30c14c1b..d587315fee29041e7abc71c0e788e4bac0bc7935 100644
--- a/man/knotd.8.in
+++ b/man/knotd.8.in
@@ -1,4 +1,4 @@
-.TH "knotd" "8" "September 2012" "CZ.NIC Labs" "Knot DNS, version @VERSION@"
+.TH "knotd" "8" "@RELEASE_DATE@" "CZ.NIC Labs" "Knot DNS, version @VERSION@"
 .SH NAME
 .B knotd
 \- Knot DNS daemon
diff --git a/man/knsupdate.1.in b/man/knsupdate.1.in
index 24ebbb9a1988e50ca8c0605acb59ac34735d3c86..b7857dfc53648222c7e9f3513fea01298be1b7a6 100644
--- a/man/knsupdate.1.in
+++ b/man/knsupdate.1.in
@@ -1,4 +1,4 @@
-.TH "knsupdate" "1" "April 2013" "CZ.NIC Labs" "Knot DNS, version @VERSION@"
+.TH "knsupdate" "1" "@RELEASE_DATE@" "CZ.NIC Labs" "Knot DNS, version @VERSION@"
 .SH NAME
 .TP 10
 .B knsupdate
diff --git a/samples/Makefile.am b/samples/Makefile.am
index 755ef078f299d8559eb94eae29aa5891e8df6e6a..73f8760ce99981df11de00cbc3a0ae3c4e4fbc6e 100644
--- a/samples/Makefile.am
+++ b/samples/Makefile.am
@@ -3,7 +3,10 @@ edit = sed \
 	-e 's|@package[@]|$(PACKAGE_NAME)|g' \
 	-e 's|@localstatedir[@]|$(localstatedir)|g' \
 	-e 's|@prefix[@]|$(prefix)|g' \
-	-e 's|@sysconfdir[@]|$(sysconfdir)|g'
+	-e 's|@sysconfdir[@]|$(sysconfdir)|g' \
+	-e 's|@config_dir[@]|$(config_dir)|g' \
+	-e 's|@storage_dir[@]|$(storage_dir)|g' \
+	-e 's|@run_dir[@]|$(run_dir)|g'
 
 knot.sample.conf: knot.sample.conf.in
 	rm -f $@ $@.tmp
@@ -15,16 +18,16 @@ knot.sample.conf: knot.sample.conf.in
 EXTRA_DIST = knot.sample.conf.in knot.full.conf knot.keys.conf example.com.zone
 
 install-data-local: knot.sample.conf
-	[ -d $(DESTDIR)/$(sysconfdir) ] || \
-	  $(INSTALL) -d $(DESTDIR)/$(sysconfdir)
-	[ -f $(DESTDIR)/$(sysconfdir)/knot.sample.conf ] || \
-	  $(INSTALL_DATA) knot.sample.conf $(srcdir)/example.com.zone $(DESTDIR)/$(sysconfdir)
+	[ -d $(DESTDIR)/$(config_dir) ] || \
+	  $(INSTALL) -d $(DESTDIR)/$(config_dir)
+	[ -f $(DESTDIR)/$(config_dir)/knot.sample.conf ] || \
+	  $(INSTALL_DATA) knot.sample.conf $(srcdir)/example.com.zone $(DESTDIR)/$(config_dir)
 
 uninstall-local:
-	[ -f $(DESTDIR)/$(sysconfdir)/knot.sample.conf ] && \
-	  rm -f $(DESTDIR)/$(sysconfdir)/knot.sample.conf
-	[ -f $(DESTDIR)/$(sysconfdir)/example.com.zone ] && \
-	  rm -f $(DESTDIR)/$(sysconfdir)/example.com.zone
+	[ -f $(DESTDIR)/$(config_dir)/knot.sample.conf ] && \
+	  rm -f $(DESTDIR)/$(config_dir)/knot.sample.conf
+	[ -f $(DESTDIR)/$(config_dir)/example.com.zone ] && \
+	  rm -f $(DESTDIR)/$(config_dir)/example.com.zone
 
 clean-local:
 	rm -f knot.sample.conf
diff --git a/samples/knot.full.conf b/samples/knot.full.conf
index 36289789f4f4b26d2484dc7431373a23e24d7823..49edf13aa3cbeeca02e214e89f155e442cad2d8d 100644
--- a/samples/knot.full.conf
+++ b/samples/knot.full.conf
@@ -28,12 +28,12 @@ system {
   # Or hexstring 0x01ab00
   nsid "myserver0";
 
-  # Working directory of the server
-  # Used to store compiled zones and PID file
-  # default: ${sharedstatedir}/knot, configured with --with-storage
+  # This is a default directory to place slave zone files, journals etc.
+  # default: ${localstatedir}/lib/knot, configured with --with-storage
   storage "/var/lib/knot";
 
   # Directory for storing run-time data
+  # e.g. PID file and control sockets
   # default: ${localstatedir}/run/knot, configured with --with-rundir
   rundir "/var/run/knot";
 
diff --git a/samples/knot.sample.conf.in b/samples/knot.sample.conf.in
index 6530d1f57238913b43138a8d9b7e75e01ed678d5..a8021c4aa11261c888722956fd3fcbe62cd8fbd7 100644
--- a/samples/knot.sample.conf.in
+++ b/samples/knot.sample.conf.in
@@ -13,14 +13,14 @@ system {
   # May also specify user.group (e.g. knot.knot)
   user knot.knot;
 
-  # Working directory of the server
-  # Used to store compiled zones and PID file
-  # default: ${sharedstatedir}/knot, configured with --with-storage
-  # storage "/var/lib/knot";
+  # This is a default directory to place slave zone files, journals etc.
+  # default: ${localstatedir}/lib/knot, configured with --with-storage
+  # storage "@storage_dir@";
 
   # Directory for storing run-time data
+  # e.g. PID file and control sockets
   # default: ${localstatedir}/run/knot, configured with --with-rundir
-  # rundir "/var/run/knot";
+  # rundir "@run_dir@";
 }
 
 interfaces {
@@ -36,7 +36,7 @@ interfaces {
 
 control {
   # Specifies interface, syntax is exactly the same as in 'interfaces' section
-  # Default: $(run_dir)/knot.sock
+  # Default: knot.sock (relative to rundir)
   listen-on "knot.sock";
 
   # As an alternative, you can use an IPv4/v6 address and port
@@ -61,14 +61,14 @@ control {
 zones {
 #  Example master zone
 #  example.com {
-#    file "@sysconfdir@/example.com.zone";
+#    file "@config_dir@/example.com.zone";
 #    xfr-out slave0;
 #    notify-out slave0;
 #  }
 #
 #  Example slave zone
 #  example.net {
-#    file "@localstatedir@/example.net.zone
+#    file "@storage_dir@/example.net.zone
 #    xfr-in master0;
 #    notify-in master0;
 #  }
diff --git a/src/Makefile.am b/src/Makefile.am
index f94c63af72c84eac65dfa0eb7f933a2dc004bbc9..29881bd1d71ad499419b87eecd454c0e801bca12 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -7,8 +7,8 @@ noinst_LTLIBRARIES = libknot.la libknotd.la libknots.la
 
 # $(YACC) will generate header file
 AM_CPPFLAGS = -I$(top_srcdir)/src/libknot -DSYSCONFDIR='"$(sysconfdir)"' \
-	-DSBINDIR='"$(sbindir)"' -DSTORAGE_DIR='"${storage_dir}"' \
-	-DRUN_DIR='"${run_dir}"'
+	-DSBINDIR='"$(sbindir)"' -DCONFIG_DIR='"${config_dir}"' \
+	-DSTORAGE_DIR='"${storage_dir}"' -DRUN_DIR='"${run_dir}"'
 AM_YFLAGS = -d
 libknotd_la_YFLAGS = -pcf_ -d
 libknotd_la_LFLAGS = # TODO: reentrant parser, prefix
@@ -283,5 +283,6 @@ knsupdate_LDADD = libknotd.la libknot.la libknots.la zscanner/libzscanner.la @LI
 
 # Create storage and run-time directories
 install-data-hook:
+	$(INSTALL) -d $(DESTDIR)/@config_dir@
 	$(INSTALL) -d $(DESTDIR)/@run_dir@
 	$(INSTALL) -d $(DESTDIR)/@storage_dir@
diff --git a/src/common/evqueue.c b/src/common/evqueue.c
index 097d177deb2c8c2af7167eff051ba97dcbd622e2..4b895549cd746a77855ee64862fb8885debefb89 100644
--- a/src/common/evqueue.c
+++ b/src/common/evqueue.c
@@ -22,9 +22,6 @@
 #include "common/evqueue.h"
 #include "common/fdset.h"
 
-/*! \brief Singleton application-wide event queue. */
-evqueue_t *s_evqueue = 0;
-
 evqueue_t *evqueue_new()
 {
 	evqueue_t* q = malloc(sizeof(evqueue_t));
diff --git a/src/common/evqueue.h b/src/common/evqueue.h
index ffb3860bb78cfab788184f0a259c9e3a98a010c0..794b2d53d994c6744be32ca4e8bf383eaa6ab282 100644
--- a/src/common/evqueue.h
+++ b/src/common/evqueue.h
@@ -178,23 +178,6 @@ int evqueue_get(evqueue_t *q, event_t *ev);
  */
 int evqueue_add(evqueue_t *q, const event_t *ev);
 
-/* Singleton event queue pointer. */
-extern evqueue_t *s_evqueue;
-
-/*!
- * \brief Event queue singleton.
- */
-static inline evqueue_t *evqueue() {
-	return s_evqueue;
-}
-
-/*!
- * \brief Set event queue singleton.
- */
-static inline void evqueue_set(evqueue_t *q) {
-	s_evqueue = q;
-}
-
 #endif /* _KNOTD_COMMON_EVQUEUE_H_ */
 
 /*! @} */
diff --git a/src/knot/conf/cf-parse.y b/src/knot/conf/cf-parse.y
index 663adad2e59c87515b8c9c566ad999ce8968cee2..3d94a11d17b20963e16c1a205916ff3ffd2eb190 100644
--- a/src/knot/conf/cf-parse.y
+++ b/src/knot/conf/cf-parse.y
@@ -531,11 +531,7 @@ system:
  | system NSID TEXT ';' { new_config->nsid = $3.t; new_config->nsid_len = strlen(new_config->nsid); }
  | system STORAGE TEXT ';' { new_config->storage = $3.t; }
  | system RUNDIR TEXT ';' { new_config->rundir = $3.t; }
- | system PIDFILE TEXT ';' {
-      fprintf(stderr, "warning: Config option 'system.pidfile' is deprecated "
-	         "and has no effect. Use 'rundir' instead.\n");
-      free($3.t);
- }
+ | system PIDFILE TEXT ';' { new_config->pidfile = $3.t; }
  | system KEY TSIG_ALGO_NAME TEXT ';' {
      fprintf(stderr, "warning: Config option 'system.key' is deprecated "
 		     "and has no effect.\n");
diff --git a/src/knot/conf/conf.c b/src/knot/conf/conf.c
index 9ed354aab3aaa1bf2c0eaf0a6da3ce5690f632f4..0c75b8b457443e0f892cb73f101c8f80bbc8f12a 100644
--- a/src/knot/conf/conf.c
+++ b/src/knot/conf/conf.c
@@ -680,6 +680,10 @@ void conf_truncate(conf_t *conf, int unload_hooks)
 		free(conf->rundir);
 		conf->rundir = 0;
 	}
+	if (conf->pidfile) {
+		free(conf->pidfile);
+		conf->pidfile = 0;
+	}
 	if (conf->nsid) {
 		free(conf->nsid);
 		conf->nsid = 0;
diff --git a/src/knot/conf/conf.h b/src/knot/conf/conf.h
index 57b250e2c938bd3c592e59c548e2b82679812a11..30075c3be6a8e8d2edb8f79e2de2291a1c1ed0a5 100644
--- a/src/knot/conf/conf.h
+++ b/src/knot/conf/conf.h
@@ -194,7 +194,8 @@ typedef struct conf_t {
 	char *hostname; /*!< Host name to return on CH TXT hostname.{bind,server} */
 	char *version;  /*!< Version for CH TXT version.{bind|server} */
 	char *storage;  /*!< Persistent storage path for databases and such. */
-	char *rundir;  /*!< Run-time directory path. */
+	char *rundir;   /*!< Run-time directory path. */
+	char *pidfile;  /*!< PID file location. */
 	char *nsid;     /*!< Server's NSID. */
 	size_t nsid_len;/*!< Server's NSID length. */
 	int   workers;  /*!< Number of workers per interface. */
diff --git a/src/knot/ctl/process.c b/src/knot/ctl/process.c
index f5db3ca062d6eb16ff3e50c88bab5d0c78cd88c0..564fff2eddd086730f79ab289e0a43b0e5b655c4 100644
--- a/src/knot/ctl/process.c
+++ b/src/knot/ctl/process.c
@@ -39,8 +39,12 @@ char* pid_filename()
 
 	/* Read configuration. */
 	char* ret = NULL;
-	if (conf() && conf()->rundir != NULL) {
-		ret = strcdup(conf()->rundir, "/knot.pid");
+
+	if (conf()) {
+		if (conf()->pidfile != NULL)
+			ret = strdup(conf()->pidfile);
+		else if (conf()->rundir != NULL)
+			ret = strcdup(conf()->rundir, "/knot.pid");
 	}
 
 	rcu_read_unlock();
diff --git a/src/knot/ctl/remote.c b/src/knot/ctl/remote.c
index 685a48b6235ae2b8c8907f7dc6c9904670393c60..2234bca20e13e13f7793f42c4745f4a6c7e90c2d 100644
--- a/src/knot/ctl/remote.c
+++ b/src/knot/ctl/remote.c
@@ -402,14 +402,15 @@ int remote_unbind(int r)
 
 int remote_poll(int r)
 {
-	if (r < 0) {
-		return -1;
-	}
-
 	/* Wait for events. */
 	fd_set rfds;
 	FD_ZERO(&rfds);
-	FD_SET(r, &rfds);
+	if (r > -1) {
+		FD_SET(r, &rfds);
+	} else {
+		r = -1; /* Make sure n == r + 1 == 0 */
+	}
+
 	return fdset_pselect(r + 1, &rfds, NULL, NULL, NULL, NULL);
 }
 
diff --git a/src/knot/main.c b/src/knot/main.c
index 874b08215e869e2031b72213efe18bcc9a0fd73d..685d5f247658f5a795ca85e7349262c189d2372d 100644
--- a/src/knot/main.c
+++ b/src/knot/main.c
@@ -42,9 +42,14 @@
 /* Signal flags. */
 static volatile short sig_req_stop = 0;
 static volatile short sig_req_reload = 0;
-static volatile short sig_req_refresh = 0;
 static volatile short sig_stopping = 0;
 
+#ifdef INTEGRITY_CHECK
+static volatile short sig_integrity_check = 0;
+int check_iteration = 0;
+char *zone = NULL;
+#endif /* INTEGRITY_CHECK */
+
 // Cleanup handler
 static int do_cleanup(server_t *server, char *configf, char *pidf);
 
@@ -57,12 +62,6 @@ void interrupt_handle(int s)
 		return;
 	}
 
-	// Refresh
-	if (s == SIGUSR2) {
-		sig_req_refresh = 1;
-		return;
-	}
-
 	// Stop server
 	if (s == SIGINT || s == SIGTERM) {
 		if (sig_stopping == 0) {
@@ -72,6 +71,14 @@ void interrupt_handle(int s)
 			exit(1);
 		}
 	}
+
+#ifdef INTEGRITY_CHECK
+	// Start zone integrity check
+	if (s == SIGUSR1) {
+		sig_integrity_check = 1;
+		return;
+	}
+#endif /* INTEGRITY_CHECK */
 }
 
 void help(void)
@@ -80,6 +87,10 @@ void help(void)
 	       PACKAGE_NAME);
 	printf("\nParameters:\n"
 	       " -c, --config [file] Select configuration file.\n"
+#ifdef INTEGRITY_CHECK
+	       " -z, --zone [zone]   Set zone to check. Send SIGUSR1 to trigger\n"
+	       "                     integrity check.\n"
+#endif /* INTEGRITY_CHECK */
 	       " -d, --daemonize     Run server as a daemon.\n"
 	       " -v, --verbose       Verbose mode - additional runtime information.\n"
 	       " -V, --version       Print version of the server.\n"
@@ -97,6 +108,9 @@ int main(int argc, char **argv)
 	/* Long options. */
 	struct option opts[] = {
 		{"config",    required_argument, 0, 'c'},
+#ifdef INTEGRITY_CHECK
+		{"zone",      required_argument, 0, 'z'},
+#endif /* INTEGRITY_CHECK */
 		{"daemonize", no_argument,       0, 'd'},
 		{"verbose",   no_argument,       0, 'v'},
 		{"version",   no_argument,       0, 'V'},
@@ -104,12 +118,25 @@ int main(int argc, char **argv)
 		{0, 0, 0, 0}
 	};
 
+#ifndef INTEGRITY_CHECK
 	while ((c = getopt_long(argc, argv, "c:dvVh", opts, &li)) != -1) {
+#else
+	while ((c = getopt_long(argc, argv, "c:z:dvVh", opts, &li)) != -1) {
+#endif /* INTEGRITY_CHECK */
 		switch (c)
 		{
 		case 'c':
 			config_fn = strdup(optarg);
 			break;
+#ifdef INTEGRITY_CHECK
+		case 'z':
+			if (optarg[strlen(optarg) - 1] != '.') {
+				zone = strcdup(optarg, ".");
+			} else {
+				zone = strdup(optarg);
+			}
+			break;
+#endif /* INTEGRITY_CHECK */
 		case 'd':
 			daemonize = 1;
 			break;
@@ -151,9 +178,6 @@ int main(int argc, char **argv)
 	sigaction(SIGPIPE, &emptyset, NULL); // Mask
 	rcu_register_thread();
 
-	// Setup event queue
-	evqueue_set(evqueue_new());
-
 	// Initialize log
 	log_init();
 
@@ -296,7 +320,9 @@ int main(int argc, char **argv)
 		sigaction(SIGTERM, &sa, NULL);
 		sigaction(SIGHUP,  &sa, NULL);
 		sigaction(SIGPIPE, &sa, NULL);
-		sigaction(SIGUSR2, &sa, NULL);
+#ifdef INTEGRITY_CHECK
+		sigaction(SIGUSR1, &sa, NULL);
+#endif /* INTEGRITY_CHECK */
 		sa.sa_flags = 0;
 		pthread_sigmask(SIG_BLOCK, &sa.sa_mask, NULL);
 
@@ -315,9 +341,6 @@ int main(int argc, char **argv)
 					ctl_if->address, (char*)buf);
 			remote = remote_bind(ctl_if);
 		}
-		if (remote < 0)
-			remote = evqueue()->fds[EVQUEUE_READFD];
-
 
 		/* Run event loop. */
 		for(;;) {
@@ -348,28 +371,40 @@ int main(int argc, char **argv)
 				sig_req_reload = 0;
 				server_reload(server, config_fn);
 			}
-			if (sig_req_refresh) {
-				log_server_info("Refreshing slave zones...\n");
-				sig_req_reload = 0;
-				int cf_ret = server_refresh(server);
-				if (cf_ret != KNOT_EOK) {
-					log_server_error("Couldn't refresh "
-					                 "slave zones - %s",
-					                 knot_strerror(cf_ret));
-				}
-
+#ifdef INTEGRITY_CHECK
+			if (zone == NULL)
+				sig_integrity_check = 0;
+			if (sig_integrity_check) {
+				log_server_info("Starting integrity check of "
+				                "zone: %s\n", zone);
+				knot_dname_t *zdn =
+					knot_dname_new_from_str(zone,
+					                        strlen(zone),
+					                        NULL);
+				knot_zone_t *z =
+					knot_zonedb_find_zone(server->nameserver->zone_db,
+					                      zdn);
+				int ic_ret =
+					knot_zone_contents_integrity_check(z->contents);
+				log_server_info("Integrity check: %d errors "
+				                "discovered.\n", ic_ret);
+				knot_dname_free(&zdn);
+				log_server_info("Integrity check %d finished.\n",
+				                check_iteration);
+				++check_iteration;
 			}
+#endif /* INTEGRITY_CHECK */
 		}
 		pthread_sigmask(SIG_UNBLOCK, &sa.sa_mask, NULL);
 
 		/* Close remote control interface */
 		if (remote > -1) {
 			close(remote);
-		}
 
-		/* Remove control socket.  */
-		if (remote > -1 && conf()->ctl.iface->family == AF_UNIX) {
-			unlink(conf()->ctl.iface->address);
+			/* Remove control socket.  */
+			conf_iface_t *ctl_if = conf()->ctl.iface;
+			if (ctl_if && ctl_if->family == AF_UNIX)
+				unlink(conf()->ctl.iface->address);
 		}
 
 		if ((server_wait(server)) != KNOT_EOK) {
@@ -394,6 +429,10 @@ int main(int argc, char **argv)
 		log_server_warning("Failed to remove PID file.\n");
 	do_cleanup(server, config_fn, pidf);
 
+#ifdef INTEGRITY_CHECK
+	free(zone);
+#endif /* INTEGRITY_CHECK */
+
 	if (!daemonize) {
 		fflush(stdout);
 		fflush(stderr);
@@ -422,8 +461,5 @@ static int do_cleanup(server_t *server, char *configf, char *pidf)
 	/* Unhook from RCU */
 	rcu_unregister_thread();
 
-	/* Free event loop. */
-	evqueue_t *q = evqueue();
-	evqueue_free(&q);
 	return 1;
 }
diff --git a/src/knot/zone/zone-load.c b/src/knot/zone/zone-load.c
index 19f65fb0b5a1291acce11d7ce9c241361c12cbc4..71974fc37aa3e3ee83cce5b48771ee4c3b7aac53 100644
--- a/src/knot/zone/zone-load.c
+++ b/src/knot/zone/zone-load.c
@@ -55,7 +55,7 @@ static int rrset_list_add(rrset_list_t **head, knot_rrset_t *rrsig)
 		tmp->data = rrsig;
 		*head = tmp;
 	}
-	
+
 	dbg_zp_verb("zp: rrset_add: Added RRSIG %p to list.\n", rrsig);
 
 	return KNOT_EOK;
@@ -80,7 +80,7 @@ static void rrset_list_delete(rrset_list_t **head)
 	}
 
 	*head = NULL;
-	
+
 	dbg_zp("zp: list_delete: List deleleted.\n");
 }
 
@@ -121,9 +121,9 @@ static int find_rrset_for_rrsig_in_node(knot_zone_contents_t *zone,
 			return KNOT_ERROR;
 		}
 	}
-	
+
 	assert(tmp_rrset);
-	
+
 	if (tmp_rrset->ttl != rrsig->ttl) {
 		char *name = knot_dname_to_str(tmp_rrset->owner);
 		assert(name);
@@ -165,7 +165,7 @@ static knot_node_t *create_node(knot_zone_contents_t *zone,
 		                 knot_strerror(ret));
 		return NULL;
 	}
-	
+
 	assert(current_rrset->owner == node->owner);
 
 	return node;
@@ -223,7 +223,7 @@ static size_t calculate_item_size(const knot_rrset_t *rrset,
 			        scanner->r_data_blocks[i];
 		}
 	}
-	
+
 	return size;
 }
 
@@ -233,16 +233,16 @@ static int add_rdata_to_rr(knot_rrset_t *rrset, const scanner_t *scanner)
 		dbg_zp("zp: add_rdata_to_rr: No RRSet.\n");
 		return KNOT_EINVAL;
 	}
-	
+
 	parser_context_t *parser = scanner->data;
-	
+
 	const rdata_descriptor_t *desc =
 		get_rdata_descriptor(knot_rrset_type(rrset));
 	assert(desc);
-	
+
 	dbg_zp_detail("zp: add_rdata_to_rr: Adding type %d, RRSet has %d RRs.\n",
 	              rrset->type, rrset->rdata_count);
-	
+
 	size_t rdlen = calculate_item_size(rrset, scanner);
 	size_t offset = 0;
 	uint8_t *rdata = knot_rrset_create_rdata(rrset, rdlen);
@@ -250,7 +250,7 @@ static int add_rdata_to_rr(knot_rrset_t *rrset, const scanner_t *scanner)
 		dbg_zp("zp: create_rdata: Could not create RR.\n");
 		return KNOT_ENOMEM;
 	}
-	
+
 	for (int i = 0; desc->block_types[i] != KNOT_RDATA_WF_END; i++) {
 		int item = desc->block_types[i];
 		if (descriptor_item_is_dname(item)) {
@@ -293,7 +293,7 @@ dbg_zp_exec_detail(
 			          scanner->r_data_blocks[i];
 		}
 	}
-	
+
 	return KNOT_EOK;
 }
 
@@ -309,23 +309,23 @@ static void process_rr(const scanner_t *scanner)
 	knot_zone_contents_t *contents = parser->current_zone;
 	knot_dname_t *current_owner = NULL;
 	knot_rrset_t *current_rrset = NULL;
-    	if (parser->last_node &&
-    	    (scanner->r_owner_length == parser->last_node->owner->size) &&
-    	    (strncmp((char *)parser->last_node->owner->name,
-    	            (char *)scanner->r_owner, scanner->r_owner_length) == 0)) {
-    		// no need to create new dname;
-    		current_owner = parser->last_node->owner;
+	if (parser->last_node &&
+	    (scanner->r_owner_length == parser->last_node->owner->size) &&
+	    (strncmp((char *)parser->last_node->owner->name,
+	            (char *)scanner->r_owner, scanner->r_owner_length) == 0)) {
+		// no need to create new dname;
+		current_owner = parser->last_node->owner;
 		knot_dname_retain(current_owner);
-    	} else {
-    		current_owner = 
-    			knot_dname_new_from_wire(scanner->r_owner,
-    			                         scanner->r_owner_length,
-    			                         NULL);
-	    	if (current_owner == NULL) {
+	} else {
+		current_owner =
+			knot_dname_new_from_wire(scanner->r_owner,
+			                         scanner->r_owner_length,
+			                         NULL);
+		if (current_owner == NULL) {
 			parser->ret = KNOT_ERROR;
 			return;
 		}
-        	knot_dname_to_lower(current_owner);
+		knot_dname_to_lower(current_owner);
 		/*!< \todo
 		 * If name is already in the table, we might not need to create
 		 * dname object, just compare wires.
@@ -333,30 +333,30 @@ static void process_rr(const scanner_t *scanner)
 		knot_zone_contents_insert_dname_into_table(&current_owner,
 		                                           parser->lookup_tree);
 	}
-	
+
 	/*!< \todo Do not create RRSet each time - merging needs to be sorted though. */
 	current_rrset = knot_rrset_new(current_owner,
 	               scanner->r_type,
 	               scanner->r_class,
 	               scanner->r_ttl);
 	knot_dname_release(current_owner);
-	
+
 	assert(current_owner);
 	assert(current_rrset);
 	parser->current_rrset = current_rrset;
-	
+
 	int ret = add_rdata_to_rr(current_rrset, scanner);
 	if (ret != KNOT_EOK) {
 		log_zone_error("Cannot add RDATA to zone, load failed.\n");
 		parser->ret = ret;
 		return;
 	}
-	
+
 	dbg_zp_verb("zp: process_rr: Processing type: %d.\n",
 	            parser->current_rrset->type);
 
 	assert(current_rrset->rdata_count);
-	
+
 	/* Node add/get functions. */
 	int (*node_add_func)(knot_zone_contents_t *, knot_node_t *, int,
 	                     uint8_t);
@@ -431,12 +431,12 @@ static void process_rr(const scanner_t *scanner)
 				                       parser->last_node);
 				rrset_list_delete(&parser->node_rrsigs);
 			}
-			
+
 			/* The node might however been created previously. */
 			parser->last_node =
 				knot_zone_contents_get_node(contents,
 					knot_rrset_owner(current_rrset));
-			
+
 			if (parser->last_node == NULL) {
 				/* Try NSEC3 tree. */
 				if (current_rrset->type == KNOT_RRTYPE_NSEC3 ||
@@ -448,7 +448,7 @@ static void process_rr(const scanner_t *scanner)
 								current_rrset));
 				}
 			}
-			
+
 			if (parser->last_node == NULL) {
 				/* Still NULL, node has to be created. */
 				if ((parser->last_node = create_node(contents,
@@ -472,12 +472,12 @@ static void process_rr(const scanner_t *scanner)
 			parser->ret = KNOT_ERROR;
 			return;
 		}
-		
+
 		dbg_zp_verb("zp: process_rr: RRSIG proccesed successfully.\n");
 		parser->ret = KNOT_EOK;
 		return;
 	}
-	
+
 	/*! \todo Move RRSIG and RRSet handling to funtions. */
 	assert(current_rrset->type != KNOT_RRTYPE_RRSIG);
 
@@ -520,13 +520,13 @@ static void process_rr(const scanner_t *scanner)
 			return;
 		}
 	}
-	
+
 	if (current_rrset->type != KNOT_RRTYPE_RRSIG) {
 		/*
 		 * If there's already an RRSet of this type in a node, check
-		 * that TTLs are the same, if not, give warning a change TTL. 
+		 * that TTLs are the same, if not, give warning a change TTL.
 		 */
-		const knot_rrset_t *rrset_in_node =        
+		const knot_rrset_t *rrset_in_node =
 			knot_node_rrset(node, current_rrset->type);
 		if (rrset_in_node &&
 		    current_rrset->ttl != rrset_in_node->ttl) {
@@ -536,7 +536,7 @@ static void process_rr(const scanner_t *scanner)
 			/* Actual change will happen in merge. */
 		}
 	}
-	
+
 	ret = knot_zone_contents_add_rrset(contents, current_rrset,
 	                                   &node,
 	                                   KNOT_RRSET_DUPL_MERGE);
@@ -568,40 +568,40 @@ static void process_rr(const scanner_t *scanner)
 		parser->ret = KNOT_EMALF;
 		return;
 	}
-	
+
 	parser->last_node = node;
-	
+
 	dbg_zp_verb("zp: process_rr: RRSet %p processed successfully.\n",
 	            parser->current_rrset);
 	parser->ret = KNOT_EOK;
 }
 
-int knot_zload_open(zloader_t **dst, const char *source, const char *origin, 
+int knot_zload_open(zloader_t **dst, const char *source, const char *origin,
                     int semantic_checks)
 {
 	if (!dst || !source || !origin) {
 		dbg_zload("zload: open: Bad arguments.\n");
 		return KNOT_EINVAL;
 	}
-	
+
 	*dst = NULL;
-	
+
 	/* Check zone file. */
 	struct stat st;
 	if (stat(source, &st) < 0) {
 		return knot_map_errno(errno);
 	}
-	
+
 	/* Create context. */
 	parser_context_t *context = xmalloc(sizeof(parser_context_t));
-	
+
 	/* Create trie for DNAME duplicits. */
 	context->lookup_tree = hattrie_create();
 	if (context->lookup_tree == NULL) {
 		free(context);
 		return KNOT_ENOMEM;
 	}
-	
+
 	context->origin_from_config =
 		knot_dname_new_from_str(origin, strlen(origin), NULL);
 	assert(context->origin_from_config);
@@ -616,7 +616,7 @@ int knot_zload_open(zloader_t **dst, const char *source, const char *origin,
 	context->current_zone = knot_zone_get_contents(zone);
 	context->node_rrsigs = NULL;
 	context->ret = KNOT_EOK;
-	
+
 	/* Create file loader. */
 	file_loader_t *loader = file_loader_create(source, origin,
 	                                           KNOT_CLASS_IN, 3600,
@@ -628,17 +628,17 @@ int knot_zload_open(zloader_t **dst, const char *source, const char *origin,
 		free(context);
 		return KNOT_ERROR;
 	}
-	
+
 	/* Allocate new loader. */
 	zloader_t *zl = xmalloc(sizeof(zloader_t));
-	
+
 	zl->source = strdup(source);
 	zl->origin = strdup(origin);
 	zl->file_loader = loader;
 	zl->context = context;
 	zl->semantic_checks = semantic_checks;
 	*dst = zl;
-	
+
 	/* Log all information for now - possibly more config options. */
 	zl->err_handler = handler_new(1, 1, 1, 1, 1);
 	if (zl->err_handler == NULL) {
@@ -647,9 +647,9 @@ int knot_zload_open(zloader_t **dst, const char *source, const char *origin,
 		                 "Semantic check skipped for zone %s\n",
 		                 origin);
 	}
-	
+
 	context->err_handler = zl->err_handler;
-	
+
 	return KNOT_EOK;
 }
 
@@ -660,7 +660,7 @@ knot_zone_t *knot_zload_load(zloader_t *loader)
 		dbg_zload("zload: load: NULL loader!\n");
 		return NULL;
 	}
-	
+
 	parser_context_t *c = loader->context;
 	assert(c);
 	int ret = file_loader_process(loader->file_loader);
@@ -681,7 +681,7 @@ knot_zone_t *knot_zload_load(zloader_t *loader)
 		knot_zone_deep_free(&zone_to_free);
 		return NULL;
 	}
-	
+
 	if (loader->file_loader->scanner->error_counter > 0) {
 		log_zone_error("Zone could not be loaded due to %"PRIu64" errors"
 		               " encountered.\n",
@@ -691,7 +691,7 @@ knot_zone_t *knot_zload_load(zloader_t *loader)
 		knot_zone_deep_free(&zone_to_free);
 		return NULL;
 	}
-	
+
 	if (knot_zone_contents_apex(c->current_zone) == NULL ||
 	    knot_node_rrset(knot_zone_contents_apex(c->current_zone), KNOT_RRTYPE_SOA) == NULL) {
 		log_zone_error("No SOA record in the zone file.\n");
@@ -700,13 +700,13 @@ knot_zone_t *knot_zload_load(zloader_t *loader)
 		knot_zone_deep_free(&zone_to_free);
 		return NULL;
 	}
-	
+
 	knot_node_t *first_nsec3_node = NULL;
 	knot_node_t *last_nsec3_node = NULL;
 	rrset_list_delete(&c->node_rrsigs);
 	knot_zone_contents_adjust(c->current_zone, &first_nsec3_node,
 	                          &last_nsec3_node, 0);
-	
+
 	if (loader->semantic_checks) {
 		int check_level = 1;
 		const knot_rrset_t *soa_rr =
@@ -729,7 +729,7 @@ knot_zone_t *knot_zload_load(zloader_t *loader)
 		log_zone_info("Semantic checks completed for zone=%s\n", zname);
 		free(zname);
 	}
-	
+
 	return c->current_zone->zone;
 }
 
@@ -738,9 +738,9 @@ void knot_zload_close(zloader_t *loader)
 	if (!loader) {
 		return;
 	}
-	
+
 	hattrie_free(loader->context->lookup_tree);
-	
+
 	file_loader_free(loader->file_loader);
 
 	free(loader->source);
diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
index 3606215fa9bbfa922c775cd6e755b8697962de83..f4b5c5d37293c20d7f0812139037b1687d735b45 100644
--- a/src/tests/Makefile.am
+++ b/src/tests/Makefile.am
@@ -3,8 +3,7 @@ ACLOCAL_AMFLAGS = -I $(top_srcdir)/m4
 AM_CPPFLAGS = -I$(top_srcdir)/src/libknot -I$(top_srcdir)/src -DSYSCONFDIR='"$(sysconfdir)"' -DSBINDIR='"$(sbindir)"'
 
 check_PROGRAMS = 			\
-	unittests			\
-	unittests_xfr
+	unittests
 
 TESTS = unittests
 
@@ -61,12 +60,7 @@ unittests_SOURCES =			\
 	libknot/sign_tests.h		\
 	unittests_main.c
 
-unittests_xfr_SOURCES = 		\
-	xfr_tests.c			\
-	xfr_tests.h
-
 unittests_LDADD = ../libknotd.la ../libknots.la @LIBOBJS@
-unittests_xfr_LDADD = ../libknotd.la ../libknot.la ../libknots.la @LIBOBJS@
 
 sample_conf.rc: files/sample_conf
 	$(top_srcdir)/resource.sh $(srcdir)/files/sample_conf >$@
diff --git a/src/tests/README b/src/tests/README
deleted file mode 100644
index 1d9748b1542b4f701680cb261c11fe4e0f651eae..0000000000000000000000000000000000000000
--- a/src/tests/README
+++ /dev/null
@@ -1,4 +0,0 @@
-Unit testing
-------------
-
-Make assembles "unittest" binary with all of the planned tests included.
diff --git a/src/tests/xfr_tests.c b/src/tests/xfr_tests.c
deleted file mode 100644
index fee09f2680d8e44d98da2f3199e1d5468f6bff87..0000000000000000000000000000000000000000
--- a/src/tests/xfr_tests.c
+++ /dev/null
@@ -1,384 +0,0 @@
-/*  Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * This test is basically a copy of the whole server, with following exceptions:
- * - signal handler now handles one more signal
- *    SIGUSR1 is used to signal this
- *    binary that an integrity check should be done
-*/
-
-#include <config.h>
-#include <time.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <getopt.h>
-#include <assert.h>
-
-#include "knot/knot.h"
-#include "knot/server/server.h"
-#include "knot/ctl/process.h"
-#include "knot/conf/conf.h"
-#include "knot/conf/logconf.h"
-#include "common/evqueue.h"
-#include "knot/server/zones.h"
-
-/*----------------------------------------------------------------------------*/
-
-/* Signal flags. */
-static volatile short sig_req_stop = 0;
-static volatile short sig_req_reload = 0;
-static volatile short sig_stopping = 0;
-static volatile short sig_integrity_check = 0;
-
-
-// SIGINT signal handler
-void interrupt_handle(int s)
-{
-	// Reload configuration
-	if (s == SIGHUP) {
-		sig_req_reload = 1;
-		return;
-	}
-
-	// Stop server
-	if (s == SIGINT || s == SIGTERM) {
-		if (sig_stopping == 0) {
-			sig_req_stop = 1;
-			sig_stopping = 1;
-		} else {
-			log_server_notice("OK! Exiting immediately.\n");
-			exit(1);
-		}
-	}
-
-	// Start zone integrity check
-	if (s == SIGUSR1) {
-		sig_integrity_check = 1;
-		return;
-	}
-}
-
-void help(int argc, char **argv)
-{
-	printf("Usage: %sd [parameters]\n",
-	       PACKAGE_NAME);
-	printf("Parameters:\n"
-	       " -c, --config [file] Select configuration file.\n"
-	       " -z, --zone [origin] Inspected zone origin.\n"
-	       " -d, --daemonize     Run server as a daemon.\n"
-	       " -v, --verbose       Verbose mode - additional runtime information.\n"
-	       " -V, --version       Print version of the server.\n"
-	       " -h, --help          Print help and usage.\n"
-	       "Send SIGUSR1 to trigger integrity check.\n");
-}
-
-int main(int argc, char **argv)
-{
-	// Parse command line arguments
-	int check_iteration = 0;
-	int c = 0, li = 0;
-	int verbose = 0;
-	int daemonize = 0;
-	char *config_fn = NULL;
-	char *zone = NULL;
-
-	/* Long options. */
-	struct option opts[] = {
-		{"config",    required_argument, 0, 'c'},
-		{"zone",      required_argument, 0, 'z'},
-		{"daemonize", no_argument,       0, 'd'},
-		{"verbose",   no_argument,       0, 'v'},
-		{"version",   no_argument,       0, 'V'},
-		{"help",      no_argument,       0, 'h'},
-		{0, 0, 0, 0}
-	};
-
-	while ((c = getopt_long(argc, argv, "c:z:dvVh", opts, &li)) != -1) {
-		switch (c)
-		{
-		case 'c':
-			config_fn = strdup(optarg);
-			break;
-		case 'd':
-			daemonize = 1;
-			break;
-		case 'v':
-			verbose = 1;
-			break;
-		case 'V':
-			printf("%s, version %s\n", "Knot DNS", PACKAGE_VERSION);
-			return 0;
-		case 'z':
-			if (optarg[strlen(optarg) - 1] != '.') {
-				zone = strcdup(optarg, ".");
-			} else {
-				zone = strdup(optarg);
-			}
-			break;
-		case 'h':
-		case '?':
-		default:
-			help(argc, argv);
-			return 1;
-		}
-	}
-
-	// Now check if we want to daemonize
-	if (daemonize) {
-		if (daemon(1, 0) != 0) {
-			free(zone);
-			free(config_fn);
-			fprintf(stderr, "Daemonization failed, "
-					"shutting down...\n");
-			return 1;
-		}
-	}
-
-	// Register service and signal handler
-	struct sigaction emptyset;
-	memset(&emptyset, 0, sizeof(struct sigaction));
-	emptyset.sa_handler = interrupt_handle;
-	sigemptyset(&emptyset.sa_mask);
-	emptyset.sa_flags = 0;
-	sigaction(SIGALRM, &emptyset, NULL); // Interrupt
-
-	// Setup event queue
-	evqueue_set(evqueue_new());
-
-	// Initialize log
-	log_init();
-
-	// Verbose mode
-	if (verbose) {
-		int mask = LOG_MASK(LOG_INFO)|LOG_MASK(LOG_DEBUG);
-		log_levels_add(LOGT_STDOUT, LOG_ANY, mask);
-	}
-
-	// Initialize pseudorandom number generator
-	srand(time(0));
-
-	// Create server
-	server_t *server = server_create();
-
-	// Initialize configuration
-	rcu_read_lock();
-	conf_add_hook(conf(), CONF_LOG, log_conf_hook, 0);
-	conf_add_hook(conf(), CONF_LOG, zones_ns_conf_hook, server->nameserver);
-	conf_add_hook(conf(), CONF_LOG, server_conf_hook, server);
-	rcu_read_unlock();
-
-	// Find implicit configuration file
-	if (!config_fn) {
-		config_fn = conf_find_default();
-	}
-
-	// Find absolute path for config file
-	if (config_fn[0] != '/')
-	{
-		// Get absolute path to cwd
-		size_t cwbuflen = 64;
-		char *cwbuf = malloc((cwbuflen + 2) * sizeof(char));
-		while (getcwd(cwbuf, cwbuflen) == 0) {
-			cwbuflen *= 2;
-			cwbuf = realloc(cwbuf, (cwbuflen + 2) * sizeof(char));
-		}
-		cwbuflen = strlen(cwbuf);
-
-		// Append ending slash
-		if (cwbuf[cwbuflen - 1] != '/') {
-			cwbuf = strncat(cwbuf, "/", 1);
-		}
-
-		// Assemble path to config file
-		char *abs_cfg = strcdup(cwbuf, config_fn);
-		free(config_fn);
-		free(cwbuf);
-		config_fn = abs_cfg;
-	}
-
-	// Open configuration
-	log_server_info("Reading configuration '%s' ...\n", config_fn);
-	int conf_ret = conf_open(config_fn);
-	if (conf_ret != KNOT_EOK) {
-		if (conf_ret == KNOT_ENOENT) {
-			log_server_error("Couldn't open configuration file "
-					 "'%s'.\n", config_fn);
-		} else {
-			log_server_error("Failed to load configuration '%s'.\n",
-				config_fn);
-		}
-		server_destroy(&server);
-		free(config_fn);
-		return 1;
-	} else {
-		log_server_info("Configured %d interfaces and %d zones.\n",
-				conf()->ifaces_count, conf()->zones_count);
-	}
-	log_server_info("\n");
-
-	// Create server instance
-	char* pidfile = pid_filename();
-
-	// Run server
-	int res = 0;
-	log_server_info("Starting server...\n");
-	if ((res = server_start(server)) == KNOT_EOK) {
-
-		// Save PID
-		int has_pid = 1;
-		int rc = pid_write(pidfile);
-		if (rc < 0) {
-			has_pid = 0;
-			log_server_warning("Failed to create "
-					   "PID file '%s'.\n", pidfile);
-		}
-
-		// Change directory if daemonized
-		if (daemonize) {
-			log_server_info("Server started as a daemon, "
-					"PID = %ld\n", (long)getpid());
-			res = chdir("/");
-		} else {
-			log_server_info("Server started in foreground, "
-					"PID = %ld\n", (long)getpid());
-		}
-		if (has_pid) {
-			log_server_info("PID stored in %s\n", pidfile);
-		} else {
-			log_server_warning("Server running without PID file.\n");
-		}
-		size_t zcount = server->nameserver->zone_db->zone_count;
-		if (!zcount) {
-			log_server_warning("Server started, but no zones served.\n");
-		}
-
-		// Setup signal handler
-		struct sigaction sa;
-		memset(&sa, 0, sizeof(sa));
-		sa.sa_handler = interrupt_handle;
-		sigemptyset(&sa.sa_mask);
-		sigaction(SIGINT,  &sa, NULL);
-		sigaction(SIGTERM, &sa, NULL);
-		sigaction(SIGHUP,  &sa, NULL);
-		sigaction(SIGUSR1,  &sa, NULL);
-		sa.sa_flags = 0;
-		pthread_sigmask(SIG_BLOCK, &sa.sa_mask, NULL);
-
-		/* Run event loop. */
-		for(;;) {
-			pthread_sigmask(SIG_UNBLOCK, &sa.sa_mask, NULL);
-			int ret = evqueue_poll(evqueue(), 0, 0);
-			pthread_sigmask(SIG_BLOCK, &sa.sa_mask, NULL);
-
-			/* Interrupts. */
-			/*! \todo More robust way to exit evloop.
-			 *        Event loop should exit with a special
-			 *        event.
-			 */
-			if (sig_req_stop) {
-				sig_req_stop = 0;
-				server_stop(server);
-				break;
-			}
-			if (sig_req_reload) {
-				log_server_info("Reloading configuration...\n");
-				sig_req_reload = 0;
-				int cf_ret = conf_open(config_fn);
-				switch (cf_ret) {
-				case KNOT_EOK:
-					log_server_info("Configuration "
-							"reloaded.\n");
-					break;
-				case KNOT_ENOENT:
-					log_server_error("Configuration "
-							 "file '%s' "
-							 "not found.\n",
-							 conf()->filename);
-					break;
-				default:
-					log_server_error("Configuration "
-							 "reload failed.\n");
-					break;
-				}
-			}
-			if (zone == NULL) sig_integrity_check = 0;
-			if (sig_integrity_check) {
-				log_server_info("Starting integrity check of zone: %s\n", zone);
-				knot_dname_t* zdn = knot_dname_new_from_str(zone, strlen(zone), NULL);
-				assert(zdn);
-				knot_zone_t *z = knot_zonedb_find_zone(server->nameserver->zone_db, zdn);
-				int ic_ret = knot_zone_contents_integrity_check(z->contents);
-				log_server_info("Integrity check: %d errors discovered.\n", ic_ret);
-				knot_dname_free(&zdn);
-				log_server_info("Integrity check %d finished.\n", check_iteration);
-				++check_iteration;
-			}
-
-			/* Events. */
-			if (ret > 0) {
-				event_t ev;
-				if (evqueue_get(evqueue(), &ev) == 0) {
-					dbg_server_verb("Event: "
-					                "received new event.\n");
-					if (ev.cb) {
-						ev.cb(&ev);
-					}
-				}
-			}
-		}
-		pthread_sigmask(SIG_UNBLOCK, &sa.sa_mask, NULL);
-
-		if ((res = server_wait(server)) != KNOT_EOK) {
-			log_server_error("An error occured while "
-					 "waiting for server to finish.\n");
-		} else {
-			log_server_info("Server finished.\n");
-		}
-
-	} else {
-		log_server_fatal("An error occured while "
-				 "starting the server.\n");
-	}
-
-	// Stop server and close log
-	server_destroy(&server);
-
-	// Remove PID file
-	if (pid_remove(pidfile) < 0) {
-		log_server_warning("Failed to remove PID file.\n");
-	}
-
-	log_server_info("Shut down.\n");
-	log_close();
-	free(pidfile);
-
-	// Destroy event loop
-	evqueue_t *q = evqueue();
-	evqueue_free(&q);
-
-	// Free default config filename if exists
-	free(zone);
-	free(config_fn);
-
-	if (!daemonize) {
-		fflush(stdout);
-		fflush(stderr);
-	}
-
-	return res;
-}
diff --git a/src/tests/xfr_tests.h b/src/tests/xfr_tests.h
deleted file mode 100644
index 29de11dd17d097c0defc00e3acb62336c9e2f49f..0000000000000000000000000000000000000000
--- a/src/tests/xfr_tests.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef XFR_TESTS_H
-#define XFR_TESTS_H
-
-class xfr_tests
-{
-public:
-    xfr_tests();
-};
-
-#endif // XFR_TESTS_H