diff --git a/.gitignore b/.gitignore
index a3e789eeaf8bf254633d5f5b90f5fa0b688f954a..c6cb5692c43ae14dea5ddbb73be0f7e7f158817d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,6 +39,7 @@ src/unittests
 src/unittests-libknot
 src/unittests-libknot-realdata
 src/unittests-zcompile
+src/unittests-zscanner
 src/knotc
 src/knotd
 src/knot-zcompile
diff --git a/configure.ac b/configure.ac
index 4f74b354b56116effde1bfaac0fde9ded2933981..9163af6cc9a93f123c22ceb3cab0a63dcb5f716b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -50,6 +50,9 @@ AS_IF([test "x$YACC_BISON" != "xbison"],
     [AC_MSG_ERROR([GNU bison needed for reentrant parsers, set the \$YACC variable before running configure])])
 AC_PROG_INSTALL
 
+# Check for Ragel
+AC_PATH_PROG(RAGEL, ragel)
+
 # Set compiler compatibility flags
 AC_PROG_CPP_WERROR
 AC_PROG_CC_C99
diff --git a/src/Makefile.am b/src/Makefile.am
index c7f0f09dba3ffb1e63f94c7e13d3edf842f51c6b..e69e3ca55eac3a1bddd11fcfa2d8708580a25a63 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,5 +1,5 @@
 ACLOCAL_AMFLAGS = -I ../m4
-libexec_PROGRAMS = knot-zcompile unittests unittests-zcompile unittests-xfr khost knsupdate
+libexec_PROGRAMS = knot-zcompile unittests unittests-zcompile unittests-xfr unittests-zscanner khost knsupdate
 sbin_PROGRAMS = knotc knotd
 dist_man_MANS = knot.conf.5 knotc.8 knotd.8
 
@@ -123,7 +123,7 @@ nodist_unittests_SOURCES =			\
 knotd_SOURCES =					\
 	knot/main.c
 
-noinst_LTLIBRARIES = libknot.la libknotd.la libknots.la
+noinst_LTLIBRARIES = libknot.la libknotd.la libknots.la libzscanner.la
 
 libknot_la_SOURCES =				\
 	libknot/util/utils.c			\
@@ -194,6 +194,8 @@ libknots_la_SOURCES =				\
 	common/libtap/tap_unit.h		\
 	common/mempattern.h			\
 	common/mempattern.c			\
+	common/descriptor_new.h			\
+	common/descriptor_new.c			\
 	common/lists.c				\
 	common/base64.c				\
 	common/base64.h				\
@@ -224,22 +226,22 @@ libknots_la_SOURCES =				\
 	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			\
+	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			\
 	common/log.c				\
-	common/log.h			
+	common/log.h
 
 libknotd_la_SOURCES =				\
 	knot/stat/gatherer.c			\
@@ -286,8 +288,27 @@ libknotd_la_SOURCES =				\
 	knot/zone/zone-dump.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
+
 libknotd_la_LIBADD = libknot.la libknots.la @LIBOBJS@
 libknots_la_LIBADD = @LIBOBJS@
+libzscanner_la_LIBADD = libknots.la
 knotd_LDADD = libknotd.la libknot.la libknots.la @LIBOBJS@
 knotc_LDADD = libknotd.la libknot.la libknots.la @LIBOBJS@
 khost_LDADD = libknotd.la libknot.la libknots.la @LIBOBJS@
@@ -296,6 +317,7 @@ knot_zcompile_LDADD = libknots.la libknot.la libknotd.la @LIBOBJS@
 unittests_LDADD = libknotd.la libknots.la @LIBOBJS@
 unittests_zcompile_LDADD = libknot.la libknots.la libknotd.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
diff --git a/src/common/descriptor_new.c b/src/common/descriptor_new.c
new file mode 100644
index 0000000000000000000000000000000000000000..be8b3c42794f2b33240e7567fc4e0c9e11c25c7a
--- /dev/null
+++ b/src/common/descriptor_new.c
@@ -0,0 +1,107 @@
+/*  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/>.
+ */
+
+#include "common/descriptor_new.h"
+
+/*!
+ * \brief RR type descriptors.
+ */
+static const rdata_descriptor_t rdata_descriptors[] = {
+	[0]			 = { { KNOT_RDATA_WF_REMAINDER,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_A]          = { { 4, KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_NS]         = { { KNOT_RDATA_WF_COMPRESSED_DNAME,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_CNAME]      = { { KNOT_RDATA_WF_COMPRESSED_DNAME,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_SOA]        = { { KNOT_RDATA_WF_COMPRESSED_DNAME,
+				       KNOT_RDATA_WF_COMPRESSED_DNAME,
+				       20, KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_PTR]        = { { KNOT_RDATA_WF_COMPRESSED_DNAME,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_HINFO]      = { { KNOT_RDATA_WF_REMAINDER,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_MINFO]      = { { KNOT_RDATA_WF_COMPRESSED_DNAME,
+				       KNOT_RDATA_WF_COMPRESSED_DNAME,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_MX]         = { { 2, KNOT_RDATA_WF_COMPRESSED_DNAME,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_TXT]        = { { KNOT_RDATA_WF_REMAINDER,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_RP]         = { { KNOT_RDATA_WF_COMPRESSED_DNAME,
+				       KNOT_RDATA_WF_COMPRESSED_DNAME,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_AFSDB]      = { { 2, KNOT_RDATA_WF_COMPRESSED_DNAME,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_RT]         = { { 2, KNOT_RDATA_WF_COMPRESSED_DNAME,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_KEY]        = { { KNOT_RDATA_WF_REMAINDER,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_AAAA]       = { { 16, KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_LOC]        = { { 16, KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_SRV]        = { { 6, KNOT_RDATA_WF_UNCOMPRESSED_DNAME,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_NAPTR]      = { { KNOT_RDATA_WF_NAPTR_HEADER,
+				       KNOT_RDATA_WF_UNCOMPRESSED_DNAME,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_KX]         = { { 2, KNOT_RDATA_WF_COMPRESSED_DNAME,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_CERT]       = { { KNOT_RDATA_WF_REMAINDER,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_DNAME]      = { { KNOT_RDATA_WF_UNCOMPRESSED_DNAME,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_OPT]        = { { KNOT_RDATA_WF_REMAINDER,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_APL]        = { { KNOT_RDATA_WF_REMAINDER,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_DS]         = { { KNOT_RDATA_WF_REMAINDER,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_SSHFP]      = { { KNOT_RDATA_WF_REMAINDER,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_IPSECKEY]   = { { KNOT_RDATA_WF_REMAINDER,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_RRSIG]      = { { 18, KNOT_RDATA_WF_LITERAL_DNAME,
+				       KNOT_RDATA_WF_REMAINDER,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_NSEC]       = { { KNOT_RDATA_WF_LITERAL_DNAME,
+				       KNOT_RDATA_WF_REMAINDER,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_DNSKEY]     = { { KNOT_RDATA_WF_REMAINDER,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_DHCID]      = { { KNOT_RDATA_WF_REMAINDER,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_NSEC3]      = { { KNOT_RDATA_WF_REMAINDER,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_NSEC3PARAM] = { { KNOT_RDATA_WF_REMAINDER,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_TLSA]       = { { KNOT_RDATA_WF_REMAINDER,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_SPF]        = { { KNOT_RDATA_WF_REMAINDER,
+				       KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_TSIG]       = { { KNOT_RDATA_WF_UNCOMPRESSED_DNAME,
+				       KNOT_RDATA_WF_REMAINDER,
+				       KNOT_RDATA_WF_END } },
+};
+
+const rdata_descriptor_t *get_rdata_descriptor(const uint16_t type)
+{
+	if (type <= KNOT_RRTYPE_TSIG) {
+		return &rdata_descriptors[type];
+	} else {
+		return &rdata_descriptors[0];
+	}
+}
+
diff --git a/src/common/descriptor_new.h b/src/common/descriptor_new.h
new file mode 100644
index 0000000000000000000000000000000000000000..e6ec6dd483e387db1adcf3679f865fa28c2141f0
--- /dev/null
+++ b/src/common/descriptor_new.h
@@ -0,0 +1,132 @@
+/*  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/>.
+ */
+/*!
+ * \file descriptor_new.h
+ *
+ * \author Jan Kadlec <jan.kadlec@nic.cz>
+ *
+ * @{
+ */
+
+#ifndef _KNOT_DESCRIPTOR_NEW_H_
+#define _KNOT_DESCRIPTOR_NEW_H_
+
+#include <stdint.h>
+
+#define KNOT_MAX_RDATA_BLOCKS	8
+
+/*!
+ * \brief Resource record class codes.
+ */
+enum knot_rr_class {
+	KNOT_CLASS_IN   =   1,
+	KNOT_CLASS_NONE = 254,
+	KNOT_CLASS_ANY  = 255,
+};
+
+/*!
+ * \brief Resource record type constants.
+ */
+enum knot_rr_type {
+	KNOT_RRTYPE_A          =   1, /*!< An IPv4 host address. */
+	KNOT_RRTYPE_NS         =   2, /*!< An authoritative name server. */
+
+	KNOT_RRTYPE_CNAME      =   5, /*!< The canonical name for an alias. */
+	KNOT_RRTYPE_SOA        =   6, /*!< The start of a zone of authority. */
+
+	KNOT_RRTYPE_PTR        =  12, /*!< A domain name pointer. */
+	KNOT_RRTYPE_HINFO      =  13, /*!< A host information. */
+	KNOT_RRTYPE_MINFO      =  14, /*!< A mailbox information. */
+	KNOT_RRTYPE_MX         =  15, /*!< Mail exchange. */
+	KNOT_RRTYPE_TXT        =  16, /*!< Text strings. */
+	KNOT_RRTYPE_RP         =  17, /*!< For responsible person. */
+	KNOT_RRTYPE_AFSDB      =  18, /*!< For AFS Data Base location. */
+
+	KNOT_RRTYPE_RT         =  21, /*!< For route through. */
+
+	KNOT_RRTYPE_KEY        =  25, /*!< For security key. */
+
+	KNOT_RRTYPE_AAAA       =  28, /*!< IPv6 address. */
+	KNOT_RRTYPE_LOC        =  29, /*!< Location information. */
+
+	KNOT_RRTYPE_SRV        =  33, /*!< Server selection. */
+
+	KNOT_RRTYPE_NAPTR      =  35, /*!< Naming authority pointer . */
+	KNOT_RRTYPE_KX         =  36, /*!< Key exchanger. */
+	KNOT_RRTYPE_CERT       =  37, /*!< Certificate record. */
+
+	KNOT_RRTYPE_DNAME      =  39, /*!< Delegation name. */
+
+	KNOT_RRTYPE_OPT        =  41, /*!< Option for EDNS*/
+	KNOT_RRTYPE_APL        =  42, /*!< Address prefix list. */
+	KNOT_RRTYPE_DS         =  43, /*!< Delegation signer. */
+	KNOT_RRTYPE_SSHFP      =  44, /*!< SSH public key fingerprint. */
+	KNOT_RRTYPE_IPSECKEY   =  45, /*!< IPSEC key. */
+	KNOT_RRTYPE_RRSIG      =  46, /*!< DNSSEC signature. */
+	KNOT_RRTYPE_NSEC       =  47, /*!< Next-secure record. */
+	KNOT_RRTYPE_DNSKEY     =  48, /*!< DNS key. */
+	KNOT_RRTYPE_DHCID      =  49, /*!< DHCP identifier. */
+	KNOT_RRTYPE_NSEC3      =  50, /*!< NSEC version 3. */
+	KNOT_RRTYPE_NSEC3PARAM =  51, /*!< NSEC3 parameters. */
+	KNOT_RRTYPE_TLSA       =  52, /*!< DANE. */
+
+	KNOT_RRTYPE_SPF        =  99, /*!< Sender policy framework. */
+
+	KNOT_RRTYPE_TSIG       = 250, /*!< Transaction signature. */
+	KNOT_RRTYPE_IXFR       = 251, /*!< Incremental zone transfer. */
+	KNOT_RRTYPE_AXFR       = 252, /*!< Authoritative zone transfer. */
+
+	KNOT_RRTYPE_ANY        = 255, /*!< Any record. */
+};
+
+/*!
+ * \brief Constants characterising the wire format of RDATA items.
+ */
+enum knot_rdata_wireformat {
+	/*!< Possibly compressed dname. */
+	KNOT_RDATA_WF_COMPRESSED_DNAME   = -10,
+	/*!< Uncompressed dname. */
+	KNOT_RDATA_WF_UNCOMPRESSED_DNAME,
+	/*!< Dname with preserved letter cases. */
+	KNOT_RDATA_WF_LITERAL_DNAME,
+	/*!< Initial part of NAPTR record before dname. */
+	KNOT_RDATA_WF_NAPTR_HEADER,
+	/*!< Uninteresting final part of a record. */
+	KNOT_RDATA_WF_REMAINDER,
+	/*!< The last descriptor in array. */
+	KNOT_RDATA_WF_END                =   0,
+};
+
+/*!
+ * \brief Structure describing rdata.
+ */
+typedef struct {
+	int block_types[KNOT_MAX_RDATA_BLOCKS];
+} rdata_descriptor_t;
+
+/*!
+ * \brief Gets rdata descriptor for given RR name.
+ *
+ * \param name Mnemonic of RR type whose descriptor should be returned.
+ *
+ * \return RR descriptor for given name, NULL descriptor if
+ *         unknown type.
+ */
+const rdata_descriptor_t *get_rdata_descriptor(const uint16_t type);
+
+#endif // _KNOT_DESCRIPTOR_NEW_H_
+
+/*! @} */
diff --git a/src/common/errcode.c b/src/common/errcode.c
index ff9be63ec78714505249f1f319df82e96f9798e3..885fbb71421f3b3ecc45dd682646c8865b25153c 100644
--- a/src/common/errcode.c
+++ b/src/common/errcode.c
@@ -69,7 +69,67 @@ const error_table_t knot_error_msgs[] = {
 	{KNOT_EIXFRSPACE, "IXFR reply did not fit in."},
 	{KNOT_ECNAME, "CNAME loop found in zone."},
 	{KNOT_ENODIFF, "Cannot create zone diff."},
-	{KNOT_EDSDIGESTLEN, "DS digest length does not match digest type." },
+	{KNOT_EDSDIGESTLEN, "DS digest length does not match digest type."},
 
-	{KNOT_ERROR, 0}
+	/* Zone file loader errors. */
+	{FLOADER_EFSTAT, "Fstat error!"},
+	{FLOADER_EDIRECTORY, "Zone file is a directory!"},
+	{FLOADER_EEMPTY, "Empty zone file!"},
+	{FLOADER_EDEFAULTS, "Zone defaults processing error!"},
+	{FLOADER_EMMAP, "Mmap error!"},
+	{FLOADER_EMUNMAP, "Munmap error!"},
+	{FLOADER_ESCANNER, "Zone processing error!"},
+
+	/* Zone scanner errors. */
+	{ZSCANNER_UNCOVERED_STATE, "General scanner error!"},
+	{ZSCANNER_ELEFT_PARENTHESIS, "Too many left parentheses!"},
+	{ZSCANNER_ERIGHT_PARENTHESIS, "Too many right parentheses!"},
+	{ZSCANNER_EUNSUPPORTED_TYPE, "Unsupported record type!"},
+	{ZSCANNER_EBAD_PREVIOUS_OWNER, "Previous owner is invalid!"},
+	{ZSCANNER_EBAD_DNAME_CHAR, "Bad domain name character!"},
+	{ZSCANNER_EBAD_OWNER, "Owner is invalid!"},
+	{ZSCANNER_ELABEL_OVERFLOW, "Maximal domain name label length has exceeded!"},
+	{ZSCANNER_EDNAME_OVERFLOW, "Maximal domain name length has exceeded!"},
+	{ZSCANNER_EBAD_NUMBER, "Bad number!"},
+	{ZSCANNER_ENUMBER64_OVERFLOW, "Number is too big!"},
+	{ZSCANNER_ENUMBER32_OVERFLOW, "Number is bigger than 32 bits!"},
+	{ZSCANNER_ENUMBER16_OVERFLOW, "Number is bigger than 16 bits!"},
+	{ZSCANNER_ENUMBER8_OVERFLOW, "Number is bigger than 8 bits!"},
+	{ZSCANNER_EFLOAT_OVERFLOW, "Float number overflow!"},
+	{ZSCANNER_ERDATA_OVERFLOW, "Maximal record data length has exceeded!"},
+	{ZSCANNER_EITEM_OVERFLOW, "Maximal item length has exceeded!"},
+	{ZSCANNER_EBAD_ADDRESS_CHAR, "Bad address character!"},
+	{ZSCANNER_EBAD_IPV4, "Bad IPv4 address!"},
+	{ZSCANNER_EBAD_IPV6, "Bad IPv6 address!"},
+	{ZSCANNER_EBAD_GATEWAY, "Bad gateway!"},
+	{ZSCANNER_EBAD_GATEWAY_KEY, "Bad gateway key!"},
+	{ZSCANNER_EBAD_APL, "Bad adress prefix list!"},
+	{ZSCANNER_EBAD_RDATA, "Bad record data!"},
+	{ZSCANNER_EBAD_HEX_RDATA, "Bad record data in hex format!"},
+	{ZSCANNER_EBAD_HEX_CHAR, "Bad hexadecimal character!"},
+	{ZSCANNER_EBAD_BASE64_CHAR, "Bad Base64 character!"},
+	{ZSCANNER_EBAD_BASE32HEX_CHAR, "Bad Base32hex character!"},
+	{ZSCANNER_EBAD_REST, "Unexpected data!"},
+	{ZSCANNER_EBAD_TIMESTAMP_CHAR, "Bad timestamp character!"},
+	{ZSCANNER_EBAD_TIMESTAMP_LENGTH, "Bad timestamp length!"},
+	{ZSCANNER_EBAD_TIMESTAMP, "Bad timestamp!"},
+	{ZSCANNER_EBAD_DATE, "Bad date!"},
+	{ZSCANNER_EBAD_TIME, "Bad time!"},
+	{ZSCANNER_EBAD_TIME_UNIT, "Bad time unit!"},
+	{ZSCANNER_EBAD_BITMAP, "Bad bitmap!"},
+	{ZSCANNER_ETEXT_OVERFLOW, "Text is too long!"},
+	{ZSCANNER_EBAD_TEXT_CHAR, "Bad text character!"},
+	{ZSCANNER_EBAD_TEXT, "Bad text string!"},
+	{ZSCANNER_EBAD_DIRECTIVE, "Bad directive!"},
+	{ZSCANNER_EBAD_TTL, "Bad zone TTL!"},
+	{ZSCANNER_EBAD_ORIGIN, "Bad zone origin!"},
+	{ZSCANNER_EBAD_INCLUDE_FILENAME, "Bad filename in include directive!"},
+	{ZSCANNER_EBAD_INCLUDE_ORIGIN, "Bad origin in include directive!"},
+	{ZSCANNER_EUNPROCESSED_INCLUDE, "Include file processing error!"},
+	{ZSCANNER_EUNOPENED_INCLUDE, "Include file opening error!"},
+	{ZSCANNER_EBAD_RDATA_LENGTH, "The rdata length statement is incorrect!"},
+	{ZSCANNER_ECANNOT_TEXT_DATA, "Unable to process text form for this type!"},
+	{ZSCANNER_EBAD_HEX_DATA, "Bad hexadecimal rdata format!"},
+	{ZSCANNER_EBAD_LOC_DATA, "Bad zone location data!"},
+	{ZSCANNER_EUNKNOWN_BLOCK, "Unknown rdata block!"},
 };
diff --git a/src/common/errcode.h b/src/common/errcode.h
index 0693a0d086048e44b122bafb18d1ba4ca4ff6dea..17d38cb89ab14e94f7fdd7213558b9c06784b037 100644
--- a/src/common/errcode.h
+++ b/src/common/errcode.h
@@ -83,7 +83,69 @@ enum knot_error {
 	KNOT_EIXFRSPACE,      /*!< IXFR reply did not fit in. */
 	KNOT_ECNAME,          /*!< CNAME loop found in zone. */
 	KNOT_ENODIFF,         /*!< No zone diff can be created. */
-	KNOT_EDSDIGESTLEN     /*!< DS digest length does not match digest type. */
+	KNOT_EDSDIGESTLEN,    /*!< DS digest length does not match digest type. */
+
+	/* Zone file loader errors. */
+	FLOADER_EFSTAT,
+	FLOADER_EDIRECTORY,
+	FLOADER_EEMPTY,
+	FLOADER_EDEFAULTS,
+	FLOADER_EMMAP,
+	FLOADER_EMUNMAP,
+	FLOADER_ESCANNER,
+
+	/* Zone scanner errors. */
+	ZSCANNER_UNCOVERED_STATE,
+	ZSCANNER_ELEFT_PARENTHESIS,
+	ZSCANNER_ERIGHT_PARENTHESIS,
+	ZSCANNER_EUNSUPPORTED_TYPE,
+	ZSCANNER_EBAD_PREVIOUS_OWNER,
+	ZSCANNER_EBAD_DNAME_CHAR,
+	ZSCANNER_EBAD_OWNER,
+	ZSCANNER_ELABEL_OVERFLOW,
+	ZSCANNER_EDNAME_OVERFLOW,
+	ZSCANNER_EBAD_NUMBER,
+	ZSCANNER_ENUMBER64_OVERFLOW,
+	ZSCANNER_ENUMBER32_OVERFLOW,
+	ZSCANNER_ENUMBER16_OVERFLOW,
+	ZSCANNER_ENUMBER8_OVERFLOW,
+	ZSCANNER_EFLOAT_OVERFLOW,
+	ZSCANNER_ERDATA_OVERFLOW,
+	ZSCANNER_EITEM_OVERFLOW,
+	ZSCANNER_EBAD_ADDRESS_CHAR,
+	ZSCANNER_EBAD_IPV4,
+	ZSCANNER_EBAD_IPV6,
+	ZSCANNER_EBAD_GATEWAY,
+	ZSCANNER_EBAD_GATEWAY_KEY,
+	ZSCANNER_EBAD_APL,
+	ZSCANNER_EBAD_RDATA,
+	ZSCANNER_EBAD_HEX_RDATA,
+	ZSCANNER_EBAD_HEX_CHAR,
+	ZSCANNER_EBAD_BASE64_CHAR,
+	ZSCANNER_EBAD_BASE32HEX_CHAR,
+	ZSCANNER_EBAD_REST,
+	ZSCANNER_EBAD_TIMESTAMP_CHAR,
+	ZSCANNER_EBAD_TIMESTAMP_LENGTH,
+	ZSCANNER_EBAD_TIMESTAMP,
+	ZSCANNER_EBAD_DATE,
+	ZSCANNER_EBAD_TIME,
+	ZSCANNER_EBAD_TIME_UNIT,
+	ZSCANNER_EBAD_BITMAP,
+	ZSCANNER_ETEXT_OVERFLOW,
+	ZSCANNER_EBAD_TEXT_CHAR,
+	ZSCANNER_EBAD_TEXT,
+	ZSCANNER_EBAD_DIRECTIVE,
+	ZSCANNER_EBAD_TTL,
+	ZSCANNER_EBAD_ORIGIN,
+	ZSCANNER_EBAD_INCLUDE_FILENAME,
+	ZSCANNER_EBAD_INCLUDE_ORIGIN,
+	ZSCANNER_EUNPROCESSED_INCLUDE,
+	ZSCANNER_EUNOPENED_INCLUDE,
+	ZSCANNER_EBAD_RDATA_LENGTH,
+	ZSCANNER_ECANNOT_TEXT_DATA,
+	ZSCANNER_EBAD_HEX_DATA,
+	ZSCANNER_EBAD_LOC_DATA,
+	ZSCANNER_EUNKNOWN_BLOCK,
 };
 
 /*! \brief Table linking error messages to error codes. */
diff --git a/src/zscanner/NOTES b/src/zscanner/NOTES
new file mode 100644
index 0000000000000000000000000000000000000000..ba7d69f16c49703b0064b2a796984b46ed602abd
--- /dev/null
+++ b/src/zscanner/NOTES
@@ -0,0 +1,13 @@
+- the newline character is appended to each zone file during processing (for simplicity)
+- the class IN is supported only (CLASS12345 notation is not supported too)
+- domain names can contain alphanumeric, '-', '_' and '/' characters
+- \x and \DDD notations are allowed in domain names and text strings only
+- @ can be used instead of domain names anywhere (excluding directives)
+- directive $INCLUDE is allowed in included zone files (BEWARE of recursion)
+- relative file path is relative to parent zone file
+- blank zone file causes error (same rule is for included zone file)
+- the line numbers of multiline records are the numbers of the last lines with appropriate record parts
+- items parts lengths must be multiples of 2 for HEX, 4 for base64 and 8 for base32hex blocks (but DHCID example from RFC is more general!)
+- NSEC3 hash is with padding (but RFC 5155 section 3.3 says "unpadded")
+- date version of timestamp in RRSIG is limited to the end of the year 2105 (for better checking of 32bit integer)
+- algorithm, certificate and flags (in KEY) mnemonics aren't supported
diff --git a/src/zscanner/file_loader.c b/src/zscanner/file_loader.c
new file mode 100644
index 0000000000000000000000000000000000000000..01a3d98b990696089a740ab0ede1a55bdb2174c4
--- /dev/null
+++ b/src/zscanner/file_loader.c
@@ -0,0 +1,250 @@
+/*  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/>.
+ */
+
+#include "zscanner/file_loader.h"
+
+#include <inttypes.h>			// PRIu64
+#include <unistd.h>			// sysconf
+#include <stdio.h>			// sprintf
+#include <stdlib.h>			// free
+#include <stdbool.h>			// bool
+#include <string.h>			// strlen
+#include <fcntl.h>			// open
+#include <sys/stat.h>			// fstat
+#include <sys/mman.h>			// mmap
+
+#include "common/errcode.h"		// error codes
+
+/*! \brief Mmap block size in bytes. */
+#define BLOCK_SIZE      30000000
+
+/*!
+ * \brief Processes zone settings block.
+ *
+ * Before zone file processing via scanner it's necessary to process first
+ * settings block using this function. Settings block contains ORIGIN and
+ * TTL directive.
+ *
+ * \param fl		File loader structure.
+ *
+ * \retval  0		if success.
+ * \retval -1		if error.
+ */
+static int load_settings(file_loader_t *fl)
+{
+	int		ret;
+	char		*settings_name;
+	scanner_t	*settings_scanner;
+
+	// Creating name for zone defaults.
+	settings_name = malloc(strlen(fl->file_name) + 100);
+	sprintf(settings_name, "ZONE DEFAULTS <%s>", fl->file_name);
+
+	// Temporary scanner for zone settings.
+	settings_scanner = scanner_create(settings_name);
+
+	// Use parent processing functions.
+	settings_scanner->process_record = fl->scanner->process_record;
+	settings_scanner->process_error  = fl->scanner->process_error;
+
+	// Scanning zone settings.
+	ret = scanner_process(fl->settings_buffer,
+			      fl->settings_buffer + fl->settings_length,
+			      true,
+			      settings_scanner);
+
+	// If no error occured, then copy scanned settings to actual context.
+	if (ret == 0) {
+		memcpy(fl->scanner->zone_origin,
+		       settings_scanner->zone_origin,
+		       settings_scanner->zone_origin_length);
+		fl->scanner->zone_origin_length =
+			settings_scanner->zone_origin_length;
+		fl->scanner->default_ttl = settings_scanner->default_ttl;
+	}
+
+	// Destroying temporary scanner.
+	scanner_free(settings_scanner);
+
+	free(settings_name);
+
+	return ret;
+}
+
+file_loader_t* file_loader_create(const char	 *file_name,
+				  const char	 *zone_origin,
+				  const uint16_t default_class,
+				  const uint32_t default_ttl,
+				  void (*process_record)(const scanner_t *),
+				  void (*process_error)(const scanner_t *),
+				  void *data)
+{
+	int ret;
+
+	// Creating zeroed structure.
+	file_loader_t *fl = calloc(1, sizeof(file_loader_t));
+
+	if (fl == NULL) {
+		return NULL;
+	}
+
+	// Copying file name.
+	fl->file_name = strdup(file_name);
+
+	// Opening zone file.
+	fl->fd = open(fl->file_name, O_RDONLY);
+
+	if (fl->fd == -1) {
+		free(fl->file_name);
+		free(fl);
+		return NULL;
+	}
+
+	// Creating zone scanner.
+	fl->scanner = scanner_create(file_name);
+
+	// Setting processing functions and data pointer.
+	fl->scanner->process_record = process_record;
+	fl->scanner->process_error  = process_error;
+	fl->scanner->data = data;
+
+	// Default class initialization.
+	fl->scanner->default_class = default_class;
+
+	// Filling zone settings buffer.
+	ret = snprintf(fl->settings_buffer,
+		       sizeof(fl->settings_buffer),
+		       "$ORIGIN %s\n"
+		       "$TTL %u\n",
+		       zone_origin, default_ttl);
+
+	if (ret > 0) {
+		fl->settings_length = ret;
+	} else {
+		file_loader_free(fl);
+		return NULL;
+	}
+
+	return fl;
+}
+
+void file_loader_free(file_loader_t *fl)
+{
+	close(fl->fd);
+	free(fl->file_name);
+	scanner_free(fl->scanner);
+	free(fl);
+}
+
+int file_loader_process(file_loader_t *fl)
+{
+	int		ret;
+	char		*data;		// Mmaped data.
+	bool		is_last_block;
+	long		page_size;
+	uint64_t	n_blocks;
+	uint64_t	block_id;
+	uint64_t	default_block_size;
+	uint64_t	scanner_start;	// Current block start to scan.
+	uint64_t	block_size;	// Current block size to scan.
+	struct stat	file_stat;
+
+	// Last block - secure termination of zone file.
+	char *zone_termination = "\n";
+
+	// Getting OS page size.
+	page_size = sysconf(_SC_PAGESIZE);
+
+	// Getting file information.
+	if (fstat(fl->fd, &file_stat) == -1) {
+		return FLOADER_EFSTAT;
+	}
+
+	// Check for directory.
+	if (S_ISDIR(file_stat.st_mode)) {
+		return FLOADER_EDIRECTORY;
+	}
+
+	// Check for empty file.
+	if (file_stat.st_size == 0) {
+		return FLOADER_EEMPTY;
+	}
+
+	// Block size adjustment to multiple of page size.
+	default_block_size = (BLOCK_SIZE / page_size) * page_size;
+
+	// Number of blocks which cover the whole file (ceiling operation).
+	n_blocks = 1 + ((file_stat.st_size - 1) / default_block_size);
+
+	// Process settings using scanner (like initial ORIGIN and TTL).
+	ret = load_settings(fl);
+
+	if (ret != 0) {
+		return FLOADER_EDEFAULTS;
+	}
+
+	// Loop over zone file blocks.
+	for (block_id = 0; block_id < n_blocks; block_id++) {
+		scanner_start = block_id * default_block_size;
+		is_last_block = false;
+		block_size = default_block_size;
+
+		// The last block is probably shorter.
+		if (block_id == (n_blocks - 1)) {
+			block_size = file_stat.st_size - scanner_start;
+			is_last_block = true;
+		}
+
+		// Zone file block mapping.
+		data = mmap(0,
+			    block_size,
+			    PROT_READ,
+			    MAP_SHARED,
+			    fl->fd,
+			    scanner_start);
+
+		if (data == MAP_FAILED) {
+			return FLOADER_EMMAP;
+		}
+
+		// Scan zone file.
+		ret = scanner_process(data,
+				      data + block_size,
+				      false,
+				      fl->scanner);
+
+		// Artificial last block containing newline char only.
+		if (is_last_block == true && fl->scanner->stop == 0) {
+			ret = scanner_process(zone_termination,
+		  			      zone_termination + 1,
+					      true,
+					      fl->scanner);
+		}
+
+		// Zone file block unmapping.
+		if (munmap(data, block_size) == -1) {
+			return FLOADER_EMUNMAP;
+		}
+	}
+
+	// Check for scanner return.
+	if (ret != 0) {
+		return FLOADER_ESCANNER;
+	}
+
+	return KNOT_EOK;
+}
+
diff --git a/src/zscanner/file_loader.h b/src/zscanner/file_loader.h
new file mode 100644
index 0000000000000000000000000000000000000000..f500ea1d917767c353692b94f421056164091f82
--- /dev/null
+++ b/src/zscanner/file_loader.h
@@ -0,0 +1,105 @@
+/*  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/>.
+ */
+/*!
+ * \file file_loader.h
+ *
+ * \author Daniel Salzman <daniel.salzman@nic.cz>
+ *
+ * \brief Zone file loader.
+ *
+ * \addtogroup zone_scanner
+ * @{
+ */
+
+#ifndef _ZSCANNER__FILE_LOADER_H_
+#define _ZSCANNER__FILE_LOADER_H_
+
+#include <stdint.h>			// uint32_t
+
+#include "common/descriptor_new.h"	// KNOT_CLASS_IN
+#include "zscanner/scanner.h"		// scanner_t
+
+/*! \brief Settings block size in bytes. */
+#define SETTINGS_BUFFER_LENGTH		 1024
+/*! \brief Default ttl value. */
+#define DEFAULT_TTL			 3600
+/*! \brief Default class value. */
+#define DEFAULT_CLASS		KNOT_CLASS_IN
+
+/*! \brief Structure for zone file loader (each included file has one). */
+typedef struct {
+	/*!< File descriptor. */
+	int	  fd;
+	/*!< Zone file name this loader belongs to. */
+	char	  *file_name;
+	/*!< Zone scanner context stucture. */
+	scanner_t *scanner;
+	/*!< Zone settings buffer. */
+	char	  settings_buffer[SETTINGS_BUFFER_LENGTH];
+	/*!< Length of zone settings buffer. */
+	uint32_t  settings_length;
+} file_loader_t;
+
+/*!
+ * \brief Creates file loader structure.
+ *
+ * \param file_name		Name of file to process.
+ * \param zone_origin		Initial zone origin (used in settings block).
+ * \param default_class		Default class value.
+ * \param default_ttl		Default ttl value (used in settings block).
+ * \param process_record	Processing callback function.
+ * \param process_error 	Error callback function.
+ * \param data			Arbitrary data useful in callback functions.
+ *
+ * \retval file_loader		if success.
+ * \retval 0			if error.
+ */
+file_loader_t* file_loader_create(const char	 *file_name,
+				  const char	 *zone_origin,
+				  const uint16_t default_class,
+				  const uint32_t default_ttl,
+				  void (*process_record)(const scanner_t *),
+				  void (*process_error)(const scanner_t *),
+				  void *data);
+
+/*!
+ * \brief Destroys file loader structure.
+ *
+ * \param file_loader	File loader structure.
+ */
+void file_loader_free(file_loader_t *file_loader);
+
+/*!
+ * \brief Processes zone file.
+ *
+ * Launches zone file processing using zone scanner. For each correctly
+ * recognized record data process_record callback function is called. If any
+ * syntax error occures, then process_error callback function is called.
+ *
+ * \note Zone scanner error code and other information are stored in
+ * fl.scanner context.
+ *
+ * \param file_loader	File loader structure.
+ *
+ * \retval KNOT_EOK	if success.
+ * \retval error_code   if error.
+ */
+int file_loader_process(file_loader_t *file_loader);
+
+
+#endif // _ZSCANNER__FILE_LOADER_H_
+
+/*! @} */
diff --git a/src/zscanner/scanner.c b/src/zscanner/scanner.c
new file mode 100644
index 0000000000000000000000000000000000000000..4257e4c3bdeca06870f7f41c6f0b64fa61bb0145
--- /dev/null
+++ b/src/zscanner/scanner.c
@@ -0,0 +1,6863 @@
+
+#line 1 "zscanner/scanner.rl"
+/*  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/>.
+ */
+
+#include "zscanner/scanner.h"
+
+#include <stdint.h>			// uint32_t
+#include <stdlib.h>			// calloc
+#include <stdio.h>			// sprintf
+#include <libgen.h>			// dirname
+#include <stdbool.h>			// bool
+#include <math.h>			// pow
+#include <string.h>			// strdup
+#include <sys/socket.h>			// AF_INET (BSD)
+#include <netinet/in.h>			// in_addr (BSD)
+
+#include "common/errcode.h"		// error codes
+#include "common/descriptor_new.h"	// KNOT_RRTYPE_A
+#include "zscanner/file_loader.h"	// file_loader
+#include "zscanner/scanner_functions.h"	// Base64
+
+/*! \brief Shorthand for setting warning data. */
+#define SCANNER_WARNING(code) { s->error_code = code; }
+/*! \brief Shorthand for setting error data. */
+#define SCANNER_ERROR(code)   { s->error_code = code; s->stop = true; }
+
+/*!
+ * \brief Writes record type number to r_data.
+ *
+ * \param type		Type number.
+ * \param rdata_tail	Position where to write type number to.
+ */
+static inline void type_num(const uint16_t type, uint8_t **rdata_tail)
+{
+	*((uint16_t *)*rdata_tail) = htons(type);
+	*rdata_tail += 2;
+}
+
+/*!
+ * \brief Sets bit to bitmap window.
+ *
+ * \param type		Type number.
+ * \param s		Scanner context.
+ */
+static inline void window_add_bit(const uint16_t type, scanner_t *s) {
+	uint8_t win      = type / 256;
+	uint8_t bit_pos  = type % 256;
+	uint8_t byte_pos = bit_pos / 8;
+
+	((s->windows[win]).bitmap)[byte_pos] |= 128 >> (bit_pos % 8);
+
+	if ((s->windows[win]).length < byte_pos + 1) {
+		(s->windows[win]).length = byte_pos + 1;
+	}
+
+	if (s->last_window < win) {
+		s->last_window = win;
+	}
+}
+
+// Include scanner file (in Ragel).
+
+#line 78 "zscanner/scanner.c"
+static const unsigned char _zone_scanner_actions[] = {
+	0, 1, 0, 1, 1, 1, 2, 1, 
+	3, 1, 4, 1, 6, 1, 9, 1, 
+	10, 1, 11, 1, 13, 1, 14, 1, 
+	16, 1, 19, 1, 20, 1, 22, 1, 
+	23, 1, 26, 1, 27, 1, 28, 1, 
+	30, 1, 31, 1, 40, 1, 41, 1, 
+	42, 1, 44, 1, 46, 1, 47, 1, 
+	48, 1, 49, 1, 51, 1, 53, 1, 
+	54, 1, 56, 1, 58, 1, 60, 1, 
+	61, 1, 65, 1, 66, 1, 69, 1, 
+	70, 1, 72, 1, 73, 1, 76, 1, 
+	78, 1, 79, 1, 80, 1, 81, 1, 
+	82, 1, 83, 1, 84, 1, 85, 1, 
+	87, 1, 89, 1, 91, 1, 95, 1, 
+	96, 1, 100, 1, 101, 1, 105, 1, 
+	106, 1, 107, 1, 108, 1, 109, 1, 
+	110, 1, 111, 1, 112, 1, 113, 1, 
+	114, 1, 115, 1, 116, 1, 117, 1, 
+	118, 1, 120, 1, 121, 1, 122, 1, 
+	123, 1, 127, 1, 128, 1, 129, 1, 
+	130, 1, 131, 1, 132, 1, 133, 1, 
+	134, 1, 135, 1, 136, 1, 137, 1, 
+	138, 1, 139, 1, 140, 1, 141, 1, 
+	142, 1, 143, 1, 144, 1, 145, 1, 
+	146, 1, 147, 1, 148, 1, 149, 1, 
+	150, 1, 151, 1, 152, 1, 153, 1, 
+	154, 1, 155, 1, 156, 1, 157, 1, 
+	158, 1, 159, 1, 160, 1, 161, 1, 
+	162, 1, 163, 1, 164, 1, 165, 1, 
+	166, 1, 167, 1, 168, 1, 169, 1, 
+	170, 1, 171, 1, 172, 1, 173, 1, 
+	174, 1, 175, 1, 176, 1, 177, 1, 
+	178, 1, 179, 1, 180, 1, 181, 1, 
+	182, 1, 183, 1, 184, 1, 185, 1, 
+	186, 1, 187, 1, 188, 1, 189, 1, 
+	190, 1, 191, 1, 192, 1, 194, 1, 
+	196, 1, 197, 1, 198, 1, 199, 1, 
+	206, 1, 207, 1, 212, 1, 214, 1, 
+	215, 1, 216, 1, 217, 1, 219, 2, 
+	0, 44, 2, 1, 0, 2, 1, 27, 
+	2, 1, 215, 2, 1, 252, 2, 2, 
+	27, 2, 2, 217, 2, 3, 27, 2, 
+	3, 217, 2, 4, 65, 2, 4, 69, 
+	2, 5, 6, 2, 9, 10, 2, 12, 
+	13, 2, 14, 10, 2, 14, 11, 2, 
+	15, 20, 2, 15, 69, 2, 15, 76, 
+	2, 16, 0, 2, 16, 2, 2, 16, 
+	3, 2, 16, 75, 2, 18, 0, 2, 
+	19, 9, 2, 22, 63, 2, 22, 100, 
+	2, 22, 111, 2, 23, 0, 2, 23, 
+	1, 2, 23, 2, 2, 23, 3, 2, 
+	23, 24, 2, 23, 195, 2, 25, 21, 
+	2, 26, 1, 2, 26, 2, 2, 26, 
+	3, 2, 26, 85, 2, 26, 217, 2, 
+	27, 1, 2, 27, 2, 2, 27, 3, 
+	2, 28, 4, 2, 28, 214, 2, 28, 
+	219, 2, 29, 21, 2, 30, 0, 2, 
+	30, 1, 2, 30, 2, 2, 30, 3, 
+	2, 30, 24, 2, 31, 36, 2, 32, 
+	31, 2, 33, 65, 2, 33, 212, 2, 
+	33, 214, 2, 33, 219, 2, 37, 200, 
+	2, 37, 201, 2, 37, 202, 2, 37, 
+	203, 2, 37, 204, 2, 37, 205, 2, 
+	40, 1, 2, 40, 2, 2, 40, 3, 
+	2, 41, 1, 2, 41, 2, 2, 41, 
+	3, 2, 41, 24, 2, 42, 0, 2, 
+	42, 1, 2, 42, 2, 2, 42, 3, 
+	2, 43, 213, 2, 44, 1, 2, 44, 
+	2, 2, 44, 3, 2, 51, 2, 2, 
+	51, 3, 2, 51, 42, 2, 51, 85, 
+	2, 52, 53, 2, 54, 1, 2, 54, 
+	2, 2, 54, 3, 2, 55, 214, 2, 
+	56, 0, 2, 57, 58, 2, 59, 60, 
+	2, 61, 0, 2, 61, 56, 2, 67, 
+	19, 2, 71, 63, 2, 72, 2, 2, 
+	72, 3, 2, 73, 4, 2, 74, 19, 
+	2, 76, 4, 2, 80, 1, 2, 80, 
+	27, 2, 82, 83, 2, 84, 1, 2, 
+	84, 2, 2, 84, 3, 2, 85, 1, 
+	2, 85, 2, 2, 85, 3, 2, 85, 
+	217, 2, 86, 87, 2, 88, 214, 2, 
+	89, 90, 2, 91, 92, 2, 93, 94, 
+	2, 93, 95, 2, 93, 96, 2, 97, 
+	98, 2, 99, 214, 2, 102, 214, 2, 
+	103, 0, 2, 119, 214, 2, 124, 214, 
+	2, 125, 214, 2, 126, 214, 2, 127, 
+	1, 2, 127, 2, 2, 127, 3, 2, 
+	128, 1, 2, 128, 2, 2, 128, 3, 
+	2, 129, 1, 2, 129, 2, 2, 129, 
+	3, 2, 130, 1, 2, 130, 2, 2, 
+	130, 3, 2, 131, 1, 2, 131, 2, 
+	2, 131, 3, 2, 132, 1, 2, 132, 
+	2, 2, 132, 3, 2, 133, 1, 2, 
+	133, 2, 2, 133, 3, 2, 134, 1, 
+	2, 134, 2, 2, 134, 3, 2, 135, 
+	1, 2, 135, 2, 2, 135, 3, 2, 
+	136, 1, 2, 136, 2, 2, 136, 3, 
+	2, 137, 1, 2, 137, 2, 2, 137, 
+	3, 2, 138, 1, 2, 138, 2, 2, 
+	138, 3, 2, 139, 1, 2, 139, 2, 
+	2, 139, 3, 2, 140, 1, 2, 140, 
+	2, 2, 140, 3, 2, 141, 1, 2, 
+	141, 2, 2, 141, 3, 2, 142, 1, 
+	2, 142, 2, 2, 142, 3, 2, 143, 
+	1, 2, 143, 2, 2, 143, 3, 2, 
+	144, 1, 2, 144, 2, 2, 144, 3, 
+	2, 145, 1, 2, 145, 2, 2, 145, 
+	3, 2, 146, 1, 2, 146, 2, 2, 
+	146, 3, 2, 147, 1, 2, 147, 2, 
+	2, 147, 3, 2, 148, 1, 2, 148, 
+	2, 2, 148, 3, 2, 149, 1, 2, 
+	149, 2, 2, 149, 3, 2, 150, 1, 
+	2, 150, 2, 2, 150, 3, 2, 151, 
+	1, 2, 151, 2, 2, 151, 3, 2, 
+	152, 1, 2, 152, 2, 2, 152, 3, 
+	2, 153, 1, 2, 153, 2, 2, 153, 
+	3, 2, 154, 1, 2, 154, 2, 2, 
+	154, 3, 2, 155, 1, 2, 155, 2, 
+	2, 155, 3, 2, 156, 1, 2, 156, 
+	2, 2, 156, 3, 2, 157, 1, 2, 
+	157, 2, 2, 157, 3, 2, 158, 1, 
+	2, 158, 2, 2, 158, 3, 2, 159, 
+	1, 2, 159, 2, 2, 159, 3, 2, 
+	160, 1, 2, 160, 2, 2, 160, 3, 
+	2, 161, 1, 2, 161, 2, 2, 161, 
+	3, 2, 162, 1, 2, 162, 2, 2, 
+	162, 3, 2, 163, 1, 2, 163, 2, 
+	2, 163, 3, 2, 164, 1, 2, 164, 
+	2, 2, 164, 3, 2, 165, 1, 2, 
+	165, 2, 2, 165, 3, 2, 166, 1, 
+	2, 166, 2, 2, 166, 3, 2, 167, 
+	1, 2, 167, 2, 2, 167, 3, 2, 
+	168, 1, 2, 168, 2, 2, 168, 3, 
+	2, 169, 1, 2, 169, 2, 2, 169, 
+	3, 2, 170, 1, 2, 170, 2, 2, 
+	170, 3, 2, 171, 1, 2, 171, 2, 
+	2, 171, 3, 2, 172, 1, 2, 172, 
+	2, 2, 172, 3, 2, 173, 1, 2, 
+	173, 2, 2, 173, 3, 2, 174, 1, 
+	2, 174, 2, 2, 174, 3, 2, 175, 
+	1, 2, 175, 2, 2, 175, 3, 2, 
+	176, 1, 2, 176, 2, 2, 176, 3, 
+	2, 177, 1, 2, 177, 2, 2, 177, 
+	3, 2, 178, 1, 2, 178, 2, 2, 
+	178, 3, 2, 179, 1, 2, 179, 2, 
+	2, 179, 3, 2, 180, 1, 2, 180, 
+	2, 2, 180, 3, 2, 181, 1, 2, 
+	181, 2, 2, 181, 3, 2, 182, 1, 
+	2, 182, 2, 2, 182, 3, 2, 183, 
+	1, 2, 183, 2, 2, 183, 3, 2, 
+	184, 1, 2, 184, 2, 2, 184, 3, 
+	2, 185, 1, 2, 185, 2, 2, 185, 
+	3, 2, 186, 1, 2, 186, 2, 2, 
+	186, 3, 2, 187, 1, 2, 187, 2, 
+	2, 187, 3, 2, 188, 1, 2, 188, 
+	2, 2, 188, 3, 2, 189, 1, 2, 
+	189, 2, 2, 189, 3, 2, 190, 1, 
+	2, 190, 2, 2, 190, 3, 2, 191, 
+	1, 2, 191, 2, 2, 191, 3, 2, 
+	192, 1, 2, 192, 2, 2, 192, 3, 
+	2, 193, 0, 2, 196, 1, 2, 196, 
+	2, 2, 196, 3, 2, 197, 1, 2, 
+	197, 2, 2, 197, 3, 2, 198, 1, 
+	2, 198, 2, 2, 198, 3, 2, 199, 
+	1, 2, 199, 2, 2, 199, 3, 2, 
+	206, 1, 2, 206, 2, 2, 206, 3, 
+	2, 207, 1, 2, 207, 2, 2, 207, 
+	3, 2, 210, 0, 2, 211, 214, 2, 
+	214, 4, 2, 215, 1, 2, 215, 27, 
+	2, 217, 2, 2, 217, 3, 2, 218, 
+	215, 2, 219, 4, 2, 219, 214, 2, 
+	220, 213, 2, 221, 213, 2, 222, 213, 
+	2, 223, 213, 2, 224, 213, 2, 225, 
+	213, 2, 226, 213, 2, 227, 213, 2, 
+	228, 213, 2, 229, 213, 2, 230, 213, 
+	2, 231, 213, 2, 232, 213, 2, 233, 
+	213, 2, 234, 213, 2, 235, 213, 2, 
+	236, 213, 2, 237, 213, 2, 238, 213, 
+	2, 239, 213, 2, 240, 213, 2, 241, 
+	213, 2, 242, 213, 2, 243, 213, 2, 
+	244, 213, 2, 245, 213, 2, 246, 213, 
+	2, 247, 213, 2, 248, 213, 2, 249, 
+	213, 2, 250, 213, 2, 251, 213, 2, 
+	252, 1, 3, 0, 44, 1, 3, 0, 
+	44, 2, 3, 0, 44, 3, 3, 1, 
+	77, 0, 3, 1, 103, 0, 3, 1, 
+	193, 0, 3, 1, 210, 0, 3, 1, 
+	215, 27, 3, 1, 215, 252, 3, 1, 
+	217, 252, 3, 1, 252, 27, 3, 7, 
+	1, 8, 3, 11, 17, 0, 3, 16, 
+	75, 2, 3, 16, 75, 3, 3, 19, 
+	9, 10, 3, 23, 1, 0, 3, 23, 
+	24, 1, 3, 23, 24, 2, 3, 23, 
+	24, 3, 3, 26, 1, 85, 3, 26, 
+	2, 85, 3, 26, 2, 217, 3, 26, 
+	3, 85, 3, 26, 3, 217, 3, 26, 
+	85, 217, 3, 26, 218, 215, 3, 26, 
+	220, 213, 3, 28, 81, 4, 3, 28, 
+	214, 4, 3, 28, 219, 4, 3, 28, 
+	219, 214, 3, 30, 1, 0, 3, 30, 
+	24, 1, 3, 30, 24, 2, 3, 30, 
+	24, 3, 3, 30, 24, 195, 3, 32, 
+	31, 215, 3, 33, 124, 214, 3, 33, 
+	126, 214, 3, 33, 219, 4, 3, 33, 
+	219, 214, 3, 35, 37, 200, 3, 35, 
+	37, 201, 3, 35, 37, 202, 3, 35, 
+	37, 203, 3, 35, 37, 204, 3, 35, 
+	37, 205, 3, 37, 200, 1, 3, 37, 
+	200, 2, 3, 37, 200, 3, 3, 37, 
+	201, 1, 3, 37, 201, 2, 3, 37, 
+	201, 3, 3, 37, 202, 1, 3, 37, 
+	202, 2, 3, 37, 202, 3, 3, 37, 
+	203, 1, 3, 37, 203, 2, 3, 37, 
+	203, 3, 3, 37, 204, 1, 3, 37, 
+	204, 2, 3, 37, 204, 3, 3, 37, 
+	205, 1, 3, 37, 205, 2, 3, 37, 
+	205, 3, 3, 41, 24, 1, 3, 41, 
+	24, 2, 3, 41, 24, 3, 3, 43, 
+	213, 1, 3, 43, 213, 2, 3, 43, 
+	213, 3, 3, 43, 213, 215, 3, 45, 
+	33, 65, 3, 45, 33, 214, 3, 45, 
+	33, 219, 3, 50, 32, 31, 3, 51, 
+	42, 0, 3, 51, 42, 1, 3, 51, 
+	42, 2, 3, 51, 42, 3, 3, 51, 
+	85, 1, 3, 51, 85, 2, 3, 51, 
+	85, 3, 3, 61, 56, 0, 3, 62, 
+	57, 58, 3, 64, 0, 1, 3, 67, 
+	19, 9, 3, 68, 0, 1, 3, 74, 
+	19, 9, 3, 77, 0, 1, 3, 80, 
+	25, 21, 3, 80, 27, 1, 3, 80, 
+	27, 2, 3, 80, 27, 3, 3, 82, 
+	25, 21, 3, 82, 83, 215, 3, 85, 
+	2, 217, 3, 85, 3, 217, 3, 88, 
+	99, 214, 3, 88, 124, 214, 3, 89, 
+	90, 0, 3, 89, 90, 1, 3, 89, 
+	90, 2, 3, 89, 90, 3, 3, 91, 
+	92, 0, 3, 91, 92, 1, 3, 91, 
+	92, 2, 3, 91, 92, 3, 3, 97, 
+	98, 0, 3, 97, 98, 1, 3, 97, 
+	98, 2, 3, 97, 98, 3, 3, 102, 
+	104, 212, 3, 124, 125, 214, 3, 159, 
+	193, 0, 3, 160, 193, 0, 3, 161, 
+	193, 0, 3, 162, 193, 0, 3, 163, 
+	193, 0, 3, 164, 193, 0, 3, 165, 
+	193, 0, 3, 166, 193, 0, 3, 167, 
+	193, 0, 3, 168, 193, 0, 3, 169, 
+	193, 0, 3, 170, 193, 0, 3, 171, 
+	193, 0, 3, 172, 193, 0, 3, 173, 
+	193, 0, 3, 174, 193, 0, 3, 175, 
+	193, 0, 3, 176, 193, 0, 3, 177, 
+	193, 0, 3, 178, 193, 0, 3, 179, 
+	193, 0, 3, 180, 193, 0, 3, 181, 
+	193, 0, 3, 182, 193, 0, 3, 183, 
+	193, 0, 3, 184, 193, 0, 3, 185, 
+	193, 0, 3, 186, 193, 0, 3, 187, 
+	193, 0, 3, 188, 193, 0, 3, 189, 
+	193, 0, 3, 190, 193, 0, 3, 191, 
+	193, 0, 3, 192, 193, 0, 3, 209, 
+	32, 31, 3, 214, 4, 81, 3, 215, 
+	25, 21, 3, 215, 252, 1, 3, 217, 
+	252, 1, 3, 219, 214, 4, 3, 220, 
+	213, 1, 3, 220, 213, 2, 3, 220, 
+	213, 3, 3, 220, 213, 215, 3, 220, 
+	213, 217, 3, 221, 213, 1, 3, 221, 
+	213, 2, 3, 221, 213, 3, 3, 221, 
+	213, 215, 3, 222, 213, 1, 3, 222, 
+	213, 2, 3, 222, 213, 3, 3, 222, 
+	213, 215, 3, 223, 213, 1, 3, 223, 
+	213, 2, 3, 223, 213, 3, 3, 223, 
+	213, 215, 3, 224, 213, 1, 3, 224, 
+	213, 2, 3, 224, 213, 3, 3, 224, 
+	213, 215, 3, 225, 213, 1, 3, 225, 
+	213, 2, 3, 225, 213, 3, 3, 225, 
+	213, 215, 3, 226, 213, 1, 3, 226, 
+	213, 2, 3, 226, 213, 3, 3, 226, 
+	213, 215, 3, 227, 213, 1, 3, 227, 
+	213, 2, 3, 227, 213, 3, 3, 227, 
+	213, 215, 3, 228, 213, 1, 3, 228, 
+	213, 2, 3, 228, 213, 3, 3, 228, 
+	213, 215, 3, 229, 213, 1, 3, 229, 
+	213, 2, 3, 229, 213, 3, 3, 229, 
+	213, 215, 3, 230, 213, 1, 3, 230, 
+	213, 2, 3, 230, 213, 3, 3, 230, 
+	213, 215, 3, 231, 213, 1, 3, 231, 
+	213, 2, 3, 231, 213, 3, 3, 231, 
+	213, 215, 3, 232, 213, 1, 3, 232, 
+	213, 2, 3, 232, 213, 3, 3, 232, 
+	213, 215, 3, 233, 213, 1, 3, 233, 
+	213, 2, 3, 233, 213, 3, 3, 233, 
+	213, 215, 3, 234, 213, 1, 3, 234, 
+	213, 2, 3, 234, 213, 3, 3, 234, 
+	213, 215, 3, 235, 213, 1, 3, 235, 
+	213, 2, 3, 235, 213, 3, 3, 235, 
+	213, 215, 3, 236, 213, 1, 3, 236, 
+	213, 2, 3, 236, 213, 3, 3, 236, 
+	213, 215, 3, 237, 213, 1, 3, 237, 
+	213, 2, 3, 237, 213, 3, 3, 237, 
+	213, 215, 3, 238, 213, 1, 3, 238, 
+	213, 2, 3, 238, 213, 3, 3, 238, 
+	213, 215, 3, 239, 213, 1, 3, 239, 
+	213, 2, 3, 239, 213, 3, 3, 239, 
+	213, 215, 3, 240, 213, 1, 3, 240, 
+	213, 2, 3, 240, 213, 3, 3, 240, 
+	213, 215, 3, 241, 213, 1, 3, 241, 
+	213, 2, 3, 241, 213, 3, 3, 241, 
+	213, 215, 3, 242, 213, 1, 3, 242, 
+	213, 2, 3, 242, 213, 3, 3, 242, 
+	213, 215, 3, 243, 213, 1, 3, 243, 
+	213, 2, 3, 243, 213, 3, 3, 243, 
+	213, 215, 3, 244, 213, 1, 3, 244, 
+	213, 2, 3, 244, 213, 3, 3, 244, 
+	213, 215, 3, 245, 213, 1, 3, 245, 
+	213, 2, 3, 245, 213, 3, 3, 245, 
+	213, 215, 3, 246, 213, 1, 3, 246, 
+	213, 2, 3, 246, 213, 3, 3, 246, 
+	213, 215, 3, 247, 213, 1, 3, 247, 
+	213, 2, 3, 247, 213, 3, 3, 247, 
+	213, 215, 3, 248, 213, 1, 3, 248, 
+	213, 2, 3, 248, 213, 3, 3, 248, 
+	213, 215, 3, 249, 213, 1, 3, 249, 
+	213, 2, 3, 249, 213, 3, 3, 249, 
+	213, 215, 3, 250, 213, 1, 3, 250, 
+	213, 2, 3, 250, 213, 3, 3, 250, 
+	213, 215, 3, 251, 213, 1, 3, 251, 
+	213, 2, 3, 251, 213, 3, 3, 251, 
+	213, 215, 3, 252, 1, 27, 4, 5, 
+	7, 1, 8, 4, 14, 11, 17, 0, 
+	4, 16, 68, 0, 1, 4, 26, 1, 
+	217, 252, 4, 26, 1, 218, 215, 4, 
+	26, 1, 220, 213, 4, 26, 2, 85, 
+	217, 4, 26, 2, 218, 215, 4, 26, 
+	2, 220, 213, 4, 26, 3, 85, 217, 
+	4, 26, 3, 218, 215, 4, 26, 3, 
+	220, 213, 4, 26, 220, 213, 215, 4, 
+	26, 220, 213, 217, 4, 28, 33, 219, 
+	4, 4, 28, 45, 33, 219, 4, 28, 
+	219, 214, 4, 4, 32, 31, 25, 21, 
+	4, 33, 219, 214, 4, 4, 35, 32, 
+	31, 36, 4, 35, 37, 200, 1, 4, 
+	35, 37, 200, 2, 4, 35, 37, 200, 
+	3, 4, 35, 37, 201, 1, 4, 35, 
+	37, 201, 2, 4, 35, 37, 201, 3, 
+	4, 35, 37, 202, 1, 4, 35, 37, 
+	202, 2, 4, 35, 37, 202, 3, 4, 
+	35, 37, 203, 1, 4, 35, 37, 203, 
+	2, 4, 35, 37, 203, 3, 4, 35, 
+	37, 204, 1, 4, 35, 37, 204, 2, 
+	4, 35, 37, 204, 3, 4, 35, 37, 
+	205, 1, 4, 35, 37, 205, 2, 4, 
+	35, 37, 205, 3, 4, 37, 202, 210, 
+	0, 4, 37, 203, 210, 0, 4, 37, 
+	204, 210, 0, 4, 37, 205, 210, 0, 
+	4, 38, 34, 32, 31, 4, 39, 34, 
+	32, 31, 4, 43, 213, 1, 215, 4, 
+	45, 33, 4, 65, 4, 51, 50, 32, 
+	31, 4, 51, 64, 0, 1, 4, 67, 
+	19, 9, 10, 4, 72, 77, 0, 1, 
+	4, 74, 19, 9, 10, 4, 82, 83, 
+	25, 21, 4, 85, 1, 217, 252, 4, 
+	88, 124, 125, 214, 4, 89, 90, 1, 
+	0, 4, 91, 92, 1, 0, 4, 97, 
+	98, 1, 0, 4, 159, 1, 193, 0, 
+	4, 160, 1, 193, 0, 4, 161, 1, 
+	193, 0, 4, 162, 1, 193, 0, 4, 
+	163, 1, 193, 0, 4, 164, 1, 193, 
+	0, 4, 165, 1, 193, 0, 4, 166, 
+	1, 193, 0, 4, 167, 1, 193, 0, 
+	4, 168, 1, 193, 0, 4, 169, 1, 
+	193, 0, 4, 170, 1, 193, 0, 4, 
+	171, 1, 193, 0, 4, 172, 1, 193, 
+	0, 4, 173, 1, 193, 0, 4, 174, 
+	1, 193, 0, 4, 175, 1, 193, 0, 
+	4, 176, 1, 193, 0, 4, 177, 1, 
+	193, 0, 4, 178, 1, 193, 0, 4, 
+	179, 1, 193, 0, 4, 180, 1, 193, 
+	0, 4, 181, 1, 193, 0, 4, 182, 
+	1, 193, 0, 4, 183, 1, 193, 0, 
+	4, 184, 1, 193, 0, 4, 185, 1, 
+	193, 0, 4, 186, 1, 193, 0, 4, 
+	187, 1, 193, 0, 4, 188, 1, 193, 
+	0, 4, 189, 1, 193, 0, 4, 190, 
+	1, 193, 0, 4, 191, 1, 193, 0, 
+	4, 192, 1, 193, 0, 4, 220, 213, 
+	1, 215, 4, 220, 213, 2, 217, 4, 
+	220, 213, 3, 217, 4, 220, 213, 217, 
+	215, 4, 221, 213, 1, 215, 4, 222, 
+	213, 1, 215, 4, 223, 213, 1, 215, 
+	4, 224, 213, 1, 215, 4, 225, 213, 
+	1, 215, 4, 226, 213, 1, 215, 4, 
+	227, 213, 1, 215, 4, 228, 213, 1, 
+	215, 4, 229, 213, 1, 215, 4, 230, 
+	213, 1, 215, 4, 231, 213, 1, 215, 
+	4, 232, 213, 1, 215, 4, 233, 213, 
+	1, 215, 4, 234, 213, 1, 215, 4, 
+	235, 213, 1, 215, 4, 236, 213, 1, 
+	215, 4, 237, 213, 1, 215, 4, 238, 
+	213, 1, 215, 4, 239, 213, 1, 215, 
+	4, 240, 213, 1, 215, 4, 241, 213, 
+	1, 215, 4, 242, 213, 1, 215, 4, 
+	243, 213, 1, 215, 4, 244, 213, 1, 
+	215, 4, 245, 213, 1, 215, 4, 246, 
+	213, 1, 215, 4, 247, 213, 1, 215, 
+	4, 248, 213, 1, 215, 4, 249, 213, 
+	1, 215, 4, 250, 213, 1, 215, 4, 
+	251, 213, 1, 215, 5, 16, 75, 77, 
+	0, 1, 5, 26, 1, 85, 217, 252, 
+	5, 26, 1, 220, 213, 215, 5, 26, 
+	2, 220, 213, 217, 5, 26, 3, 220, 
+	213, 217, 5, 26, 220, 213, 217, 215, 
+	5, 28, 33, 219, 214, 4, 5, 32, 
+	31, 215, 25, 21, 5, 35, 37, 202, 
+	210, 0, 5, 35, 37, 203, 210, 0, 
+	5, 35, 37, 204, 210, 0, 5, 35, 
+	37, 205, 210, 0, 5, 37, 202, 1, 
+	210, 0, 5, 37, 203, 1, 210, 0, 
+	5, 37, 204, 1, 210, 0, 5, 37, 
+	205, 1, 210, 0, 5, 45, 33, 219, 
+	214, 4, 5, 82, 83, 215, 25, 21, 
+	5, 208, 38, 34, 32, 31, 5, 220, 
+	213, 1, 217, 252, 6, 26, 1, 220, 
+	213, 217, 252, 6, 28, 45, 33, 219, 
+	214, 4, 6, 35, 37, 202, 1, 210, 
+	0, 6, 35, 37, 203, 1, 210, 0, 
+	6, 35, 37, 204, 1, 210, 0, 6, 
+	35, 37, 205, 1, 210, 0, 6, 220, 
+	213, 1, 217, 215, 252, 6, 220, 213, 
+	217, 215, 252, 1, 7, 26, 1, 220, 
+	213, 217, 215, 252
+};
+
+static const short _zone_scanner_cond_offsets[] = {
+	0, 0, 2, 4, 6, 8, 10, 12, 
+	14, 14, 14, 16, 19, 21, 24, 26, 
+	28, 30, 30, 30, 30, 32, 37, 37, 
+	37, 37, 39, 39, 39, 39, 39, 41, 
+	41, 41, 41, 43, 43, 43, 43, 45, 
+	47, 47, 47, 47, 47, 49, 49, 51, 
+	53, 53, 53, 53, 53, 53, 53, 53, 
+	55, 55, 55, 57, 59, 59, 59, 61, 
+	61, 61, 61, 61, 63, 65, 65, 65, 
+	65, 65, 67, 69, 69, 71, 73, 73, 
+	73, 73, 73, 75, 75, 75, 77, 77, 
+	79, 79, 79, 79, 81, 83, 83, 83, 
+	85, 85, 87, 87, 89, 89, 89, 89, 
+	91, 91, 91, 91, 93, 93, 95, 95, 
+	95, 95, 97, 100, 102, 102, 104, 106, 
+	108, 110, 110, 112, 115, 115, 115, 115, 
+	115, 115, 115, 115, 115, 115, 117, 119, 
+	122, 124, 126, 129, 131, 131, 133, 136, 
+	138, 140, 142, 144, 146, 149, 151, 153, 
+	155, 157, 159, 161, 163, 165, 167, 169, 
+	171, 173, 175, 177, 179, 182, 184, 184, 
+	184, 184, 184, 184, 184, 184, 184, 184, 
+	186, 188, 190, 193, 195, 197, 199, 201, 
+	203, 205, 207, 209, 211, 213, 215, 217, 
+	219, 221, 223, 225, 230, 235, 240, 240, 
+	240, 242, 242, 242, 242, 244, 244, 246, 
+	249, 251, 253, 258, 263, 266, 271, 273, 
+	275, 277, 279, 281, 283, 285, 287, 289, 
+	291, 293, 295, 298, 301, 303, 306, 306, 
+	306, 306, 306, 306, 306, 306, 306, 306, 
+	306, 306, 306, 306, 306, 306, 306, 306, 
+	306, 307, 307, 307, 307, 307, 308, 310, 
+	312, 314, 316, 316, 318, 318, 320, 323, 
+	325, 327, 327, 329, 331, 331, 331, 331, 
+	331, 331, 331, 333, 336, 338, 340, 342, 
+	344, 344, 346, 348, 348, 348, 348, 348, 
+	348, 348, 350, 353, 355, 358, 361, 361, 
+	361, 361, 361, 363, 366, 366, 368, 370, 
+	372, 372, 372, 374, 377, 377, 377, 377, 
+	379, 379, 379, 379, 381, 381, 381, 381, 
+	381, 383, 383, 383, 383, 385, 385, 385, 
+	385, 387, 389, 389, 389, 389, 389, 391, 
+	391, 391, 391, 391, 391, 391, 391, 393, 
+	393, 393, 395, 397, 397, 397, 399, 399, 
+	399, 399, 399, 401, 403, 403, 403, 403, 
+	403, 405, 407, 407, 409, 411, 411, 411, 
+	411, 411, 413, 413, 413, 415, 415, 417, 
+	417, 417, 417, 419, 421, 421, 421, 423, 
+	423, 425, 425, 427, 427, 427, 427, 429, 
+	429, 429, 429, 431, 431, 433, 433, 433, 
+	433, 435, 435, 435, 435, 437, 437, 439, 
+	441, 443, 445, 447, 447, 449, 452, 455, 
+	458, 460, 462, 464, 466, 466, 468, 471, 
+	474, 476, 479, 479, 479, 479, 479, 479, 
+	481, 483, 485, 487, 489, 491, 493, 495, 
+	497, 499, 501, 503, 503, 503, 503, 503, 
+	506, 508, 508, 510, 513, 515, 515, 517, 
+	520, 522, 522, 524, 527, 530, 533, 533, 
+	535, 537, 537, 540, 540, 542, 544, 544, 
+	547, 547, 549, 551, 551, 554, 554, 556, 
+	558, 561, 561, 561, 561, 563, 565, 567, 
+	569, 571, 573, 575, 577, 579, 581, 583, 
+	585, 587, 589, 591, 593, 593, 595, 597, 
+	599, 601, 603, 605, 607, 609, 612, 614, 
+	616, 619, 621, 623, 625, 628, 630, 632, 
+	634, 637, 639, 641, 643, 646, 648, 651, 
+	653, 655, 658, 661, 664, 666, 669, 671, 
+	673, 676, 679, 679, 681, 683, 685, 687, 
+	689, 691, 691, 694, 697, 700, 700, 702, 
+	704, 706, 708, 710, 712, 714, 716, 718, 
+	720, 720, 723, 726, 729, 732, 735, 735, 
+	737, 739, 741, 743, 745, 747, 749, 752, 
+	755, 758, 760, 760, 760, 760, 760, 760, 
+	762, 765, 765, 765, 765, 765, 767, 769, 
+	771, 773, 775, 777, 777, 779, 782, 785, 
+	788, 791, 791, 793, 795, 797, 799, 799, 
+	801, 804, 807, 810, 810, 812, 814, 816, 
+	818, 820, 822, 828, 839, 841, 844, 850, 
+	853, 864, 867, 870, 873, 875, 877, 879, 
+	881, 887, 890, 893, 895, 897, 899, 901, 
+	907, 910, 913, 915, 917, 919, 921, 927, 
+	930, 933, 936, 936, 938, 940, 942, 944, 
+	946, 948, 950, 952, 954, 956, 958, 960, 
+	962, 964, 966, 968, 970, 973, 976, 979, 
+	982, 985, 988, 991, 994, 994, 994, 996, 
+	996, 996, 996, 998, 998, 1000, 1000, 1000, 
+	1000, 1002, 1002, 1002, 1002, 1004, 1004, 1004, 
+	1004, 1004, 1006, 1006, 1006, 1006, 1008, 1008, 
+	1008, 1008, 1010, 1012, 1012, 1012, 1012, 1012, 
+	1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 
+	1016, 1016, 1016, 1018, 1020, 1020, 1020, 1022, 
+	1022, 1022, 1022, 1022, 1024, 1026, 1026, 1026, 
+	1026, 1026, 1028, 1030, 1030, 1032, 1034, 1034, 
+	1034, 1034, 1034, 1036, 1036, 1036, 1038, 1038, 
+	1040, 1040, 1040, 1040, 1042, 1044, 1044, 1044, 
+	1046, 1046, 1048, 1048, 1050, 1050, 1050, 1050, 
+	1052, 1052, 1052, 1052, 1054, 1054, 1056, 1056, 
+	1056, 1056, 1058, 1058, 1058, 1058, 1058, 1060, 
+	1062, 1064, 1066, 1068, 1070, 1072, 1075, 1078, 
+	1081, 1081, 1083, 1083, 1085, 1087, 1089, 1091, 
+	1093, 1095, 1097, 1099, 1099, 1099, 1099, 1099, 
+	1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 
+	1099, 1099, 1102, 1102, 1104, 1107, 1110, 1113, 
+	1113, 1115, 1117, 1119, 1121, 1123, 1125, 1125, 
+	1125, 1125, 1128, 1131, 1134, 1134, 1136, 1138, 
+	1140, 1142, 1144, 1146, 1146, 1148, 1151, 1154, 
+	1157, 1160, 1162, 1164, 1166, 1168, 1170, 1172, 
+	1174, 1176, 1178, 1180, 1180, 1180, 1180, 1180, 
+	1180, 1180, 1180, 1182, 1182, 1184, 1187, 1187, 
+	1189, 1192, 1192, 1194, 1197, 1199, 1199, 1201, 
+	1204, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 
+	1207, 1209, 1212, 1212, 1212, 1214, 1217, 1219, 
+	1222, 1224, 1227, 1229, 1232, 1232, 1232, 1232, 
+	1232, 1234, 1237, 1237, 1239, 1242, 1242, 1244, 
+	1247, 1247, 1253, 1256, 1267, 1270, 1281, 1284, 
+	1284, 1284, 1284, 1284, 1284, 1284, 1284, 1286
+};
+
+static const char _zone_scanner_cond_lengths[] = {
+	0, 2, 2, 2, 2, 2, 2, 2, 
+	0, 0, 2, 3, 2, 3, 2, 2, 
+	2, 0, 0, 0, 2, 5, 0, 0, 
+	0, 2, 0, 0, 0, 0, 2, 0, 
+	0, 0, 2, 0, 0, 0, 2, 2, 
+	0, 0, 0, 0, 2, 0, 2, 2, 
+	0, 0, 0, 0, 0, 0, 0, 2, 
+	0, 0, 2, 2, 0, 0, 2, 0, 
+	0, 0, 0, 2, 2, 0, 0, 0, 
+	0, 2, 2, 0, 2, 2, 0, 0, 
+	0, 0, 2, 0, 0, 2, 0, 2, 
+	0, 0, 0, 2, 2, 0, 0, 2, 
+	0, 2, 0, 2, 0, 0, 0, 2, 
+	0, 0, 0, 2, 0, 2, 0, 0, 
+	0, 2, 3, 2, 0, 2, 2, 2, 
+	2, 0, 2, 3, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 2, 2, 3, 
+	2, 2, 3, 2, 0, 2, 3, 2, 
+	2, 2, 2, 2, 3, 2, 2, 2, 
+	2, 2, 2, 2, 2, 2, 2, 2, 
+	2, 2, 2, 2, 3, 2, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 2, 
+	2, 2, 3, 2, 2, 2, 2, 2, 
+	2, 2, 2, 2, 2, 2, 2, 2, 
+	2, 2, 2, 5, 5, 5, 0, 0, 
+	2, 0, 0, 0, 2, 0, 2, 3, 
+	2, 2, 5, 5, 3, 5, 2, 2, 
+	2, 2, 2, 2, 2, 2, 2, 2, 
+	2, 2, 3, 3, 2, 3, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	1, 0, 0, 0, 0, 1, 2, 2, 
+	2, 2, 0, 2, 0, 2, 3, 2, 
+	2, 0, 2, 2, 0, 0, 0, 0, 
+	0, 0, 2, 3, 2, 2, 2, 2, 
+	0, 2, 2, 0, 0, 0, 0, 0, 
+	0, 2, 3, 2, 3, 3, 0, 0, 
+	0, 0, 2, 3, 0, 2, 2, 2, 
+	0, 0, 2, 3, 0, 0, 0, 2, 
+	0, 0, 0, 2, 0, 0, 0, 0, 
+	2, 0, 0, 0, 2, 0, 0, 0, 
+	2, 2, 0, 0, 0, 0, 2, 0, 
+	0, 0, 0, 0, 0, 0, 2, 0, 
+	0, 2, 2, 0, 0, 2, 0, 0, 
+	0, 0, 2, 2, 0, 0, 0, 0, 
+	2, 2, 0, 2, 2, 0, 0, 0, 
+	0, 2, 0, 0, 2, 0, 2, 0, 
+	0, 0, 2, 2, 0, 0, 2, 0, 
+	2, 0, 2, 0, 0, 0, 2, 0, 
+	0, 0, 2, 0, 2, 0, 0, 0, 
+	2, 0, 0, 0, 2, 0, 2, 2, 
+	2, 2, 2, 0, 2, 3, 3, 3, 
+	2, 2, 2, 2, 0, 2, 3, 3, 
+	2, 3, 0, 0, 0, 0, 0, 2, 
+	2, 2, 2, 2, 2, 2, 2, 2, 
+	2, 2, 2, 0, 0, 0, 0, 3, 
+	2, 0, 2, 3, 2, 0, 2, 3, 
+	2, 0, 2, 3, 3, 3, 0, 2, 
+	2, 0, 3, 0, 2, 2, 0, 3, 
+	0, 2, 2, 0, 3, 0, 2, 2, 
+	3, 0, 0, 0, 2, 2, 2, 2, 
+	2, 2, 2, 2, 2, 2, 2, 2, 
+	2, 2, 2, 2, 0, 2, 2, 2, 
+	2, 2, 2, 2, 2, 3, 2, 2, 
+	3, 2, 2, 2, 3, 2, 2, 2, 
+	3, 2, 2, 2, 3, 2, 3, 2, 
+	2, 3, 3, 3, 2, 3, 2, 2, 
+	3, 3, 0, 2, 2, 2, 2, 2, 
+	2, 0, 3, 3, 3, 0, 2, 2, 
+	2, 2, 2, 2, 2, 2, 2, 2, 
+	0, 3, 3, 3, 3, 3, 0, 2, 
+	2, 2, 2, 2, 2, 2, 3, 3, 
+	3, 2, 0, 0, 0, 0, 0, 2, 
+	3, 0, 0, 0, 0, 2, 2, 2, 
+	2, 2, 2, 0, 2, 3, 3, 3, 
+	3, 0, 2, 2, 2, 2, 0, 2, 
+	3, 3, 3, 0, 2, 2, 2, 2, 
+	2, 2, 6, 11, 2, 3, 6, 3, 
+	11, 3, 3, 3, 2, 2, 2, 2, 
+	6, 3, 3, 2, 2, 2, 2, 6, 
+	3, 3, 2, 2, 2, 2, 6, 3, 
+	3, 3, 0, 2, 2, 2, 2, 2, 
+	2, 2, 2, 2, 2, 2, 2, 2, 
+	2, 2, 2, 2, 3, 3, 3, 3, 
+	3, 3, 3, 3, 0, 0, 2, 0, 
+	0, 0, 2, 0, 2, 0, 0, 0, 
+	2, 0, 0, 0, 2, 0, 0, 0, 
+	0, 2, 0, 0, 0, 2, 0, 0, 
+	0, 2, 2, 0, 0, 0, 0, 2, 
+	0, 0, 0, 0, 0, 0, 0, 2, 
+	0, 0, 2, 2, 0, 0, 2, 0, 
+	0, 0, 0, 2, 2, 0, 0, 0, 
+	0, 2, 2, 0, 2, 2, 0, 0, 
+	0, 0, 2, 0, 0, 2, 0, 2, 
+	0, 0, 0, 2, 2, 0, 0, 2, 
+	0, 2, 0, 2, 0, 0, 0, 2, 
+	0, 0, 0, 2, 0, 2, 0, 0, 
+	0, 2, 0, 0, 0, 0, 2, 2, 
+	2, 2, 2, 2, 2, 3, 3, 3, 
+	0, 2, 0, 2, 2, 2, 2, 2, 
+	2, 2, 2, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 3, 0, 2, 3, 3, 3, 0, 
+	2, 2, 2, 2, 2, 2, 0, 0, 
+	0, 3, 3, 3, 0, 2, 2, 2, 
+	2, 2, 2, 0, 2, 3, 3, 3, 
+	3, 2, 2, 2, 2, 2, 2, 2, 
+	2, 2, 2, 0, 0, 0, 0, 0, 
+	0, 0, 2, 0, 2, 3, 0, 2, 
+	3, 0, 2, 3, 2, 0, 2, 3, 
+	3, 0, 0, 0, 0, 0, 0, 0, 
+	2, 3, 0, 0, 2, 3, 2, 3, 
+	2, 3, 2, 3, 0, 0, 0, 0, 
+	2, 3, 0, 2, 3, 0, 2, 3, 
+	0, 6, 3, 11, 3, 11, 3, 0, 
+	0, 0, 0, 0, 0, 0, 2, 3
+};
+
+static const short _zone_scanner_cond_keys[] = {
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	-128, 9, 10, 10, 11, 127, 10, 10, 
+	59, 59, -128, 9, 10, 10, 11, 127, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	-128, 9, 10, 10, 11, 58, 59, 59, 
+	60, 127, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, -128, 9, 10, 10, 11, 127, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	-128, 9, 10, 10, 11, 127, 10, 10, 
+	59, 59, 10, 10, 59, 59, -128, 9, 
+	10, 10, 11, 127, 10, 10, 59, 59, 
+	10, 10, 59, 59, -128, 9, 10, 10, 
+	11, 127, 10, 10, 59, 59, 10, 10, 
+	59, 59, -128, 9, 10, 10, 11, 127, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, -128, 9, 10, 10, 
+	11, 127, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, -128, 9, 
+	10, 10, 11, 127, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, -128, 9, 10, 10, 
+	11, 127, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, -128, 9, 10, 10, 11, 58, 
+	59, 59, 60, 127, -128, 9, 10, 10, 
+	11, 58, 59, 59, 60, 127, -128, 9, 
+	10, 10, 11, 58, 59, 59, 60, 127, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, -128, 9, 10, 10, 
+	11, 127, 10, 10, 59, 59, 10, 10, 
+	59, 59, -128, 9, 10, 10, 11, 58, 
+	59, 59, 60, 127, -128, 9, 10, 10, 
+	11, 58, 59, 59, 60, 127, -128, 9, 
+	10, 10, 11, 127, -128, 9, 10, 10, 
+	11, 58, 59, 59, 60, 127, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, -128, 9, 
+	10, 10, 11, 127, -128, 9, 10, 10, 
+	11, 127, 10, 10, 59, 59, -128, 9, 
+	10, 10, 11, 127, 10, 10, 10, 10, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	-128, 9, 10, 10, 11, 127, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, -128, 9, 10, 10, 11, 127, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, -128, 9, 10, 10, 
+	11, 127, 10, 10, 59, 59, -128, 9, 
+	10, 10, 11, 127, -128, 9, 10, 10, 
+	11, 127, 10, 10, 59, 59, -128, 9, 
+	10, 10, 11, 127, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, -128, 9, 10, 10, 
+	11, 127, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, -128, 9, 10, 10, 11, 127, 
+	-128, 9, 10, 10, 11, 127, -128, 9, 
+	10, 10, 11, 127, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	-128, 9, 10, 10, 11, 127, -128, 9, 
+	10, 10, 11, 127, 10, 10, 59, 59, 
+	-128, 9, 10, 10, 11, 127, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, -128, 9, 
+	10, 10, 11, 127, 10, 10, 59, 59, 
+	10, 10, 59, 59, -128, 9, 10, 10, 
+	11, 127, 10, 10, 59, 59, 10, 10, 
+	59, 59, -128, 9, 10, 10, 11, 127, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	-128, 9, 10, 10, 11, 127, -128, 9, 
+	10, 10, 11, 127, -128, 9, 10, 10, 
+	11, 127, 10, 10, 59, 59, 10, 10, 
+	59, 59, -128, 9, 10, 10, 11, 127, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	-128, 9, 10, 10, 11, 127, 10, 10, 
+	59, 59, 10, 10, 59, 59, -128, 9, 
+	10, 10, 11, 127, 10, 10, 59, 59, 
+	10, 10, 59, 59, -128, 9, 10, 10, 
+	11, 127, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, -128, 9, 10, 10, 11, 127, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	-128, 9, 10, 10, 11, 127, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, -128, 9, 10, 10, 11, 127, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, -128, 9, 10, 10, 
+	11, 127, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, -128, 9, 
+	10, 10, 11, 127, 10, 10, 59, 59, 
+	-128, 9, 10, 10, 11, 127, 10, 10, 
+	59, 59, 10, 10, 59, 59, -128, 9, 
+	10, 10, 11, 127, -128, 9, 10, 10, 
+	11, 127, -128, 9, 10, 10, 11, 127, 
+	10, 10, 59, 59, -128, 9, 10, 10, 
+	11, 127, 10, 10, 59, 59, 10, 10, 
+	59, 59, -128, 9, 10, 10, 11, 127, 
+	-128, 9, 10, 10, 11, 127, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, -128, 9, 
+	10, 10, 11, 127, -128, 9, 10, 10, 
+	11, 127, -128, 9, 10, 10, 11, 127, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	-128, 9, 10, 10, 11, 127, -128, 9, 
+	10, 10, 11, 127, -128, 9, 10, 10, 
+	11, 127, -128, 9, 10, 10, 11, 127, 
+	-128, 9, 10, 10, 11, 127, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, -128, 9, 10, 10, 11, 127, 
+	-128, 9, 10, 10, 11, 127, -128, 9, 
+	10, 10, 11, 127, 10, 10, 59, 59, 
+	10, 10, 59, 59, -128, 9, 10, 10, 
+	11, 127, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, -128, 9, 
+	10, 10, 11, 127, -128, 9, 10, 10, 
+	11, 127, -128, 9, 10, 10, 11, 127, 
+	-128, 9, 10, 10, 11, 127, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, -128, 9, 10, 10, 11, 127, 
+	-128, 9, 10, 10, 11, 127, -128, 9, 
+	10, 10, 11, 127, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 9, 9, 10, 10, 
+	32, 32, 40, 40, 41, 41, 59, 59, 
+	9, 9, 10, 10, 32, 32, 40, 40, 
+	41, 41, 43, 43, 47, 47, 48, 57, 
+	59, 59, 65, 90, 97, 122, 10, 10, 
+	59, 59, -128, 9, 10, 10, 11, 127, 
+	9, 9, 10, 10, 32, 32, 40, 40, 
+	41, 41, 59, 59, -128, 9, 10, 10, 
+	11, 127, 9, 9, 10, 10, 32, 32, 
+	40, 40, 41, 41, 43, 43, 47, 47, 
+	48, 57, 59, 59, 65, 90, 97, 122, 
+	-128, 9, 10, 10, 11, 127, -128, 9, 
+	10, 10, 11, 127, -128, 9, 10, 10, 
+	11, 127, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 9, 9, 10, 10, 32, 32, 
+	40, 40, 41, 41, 59, 59, -128, 9, 
+	10, 10, 11, 127, -128, 9, 10, 10, 
+	11, 127, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 9, 9, 10, 10, 32, 32, 
+	40, 40, 41, 41, 59, 59, -128, 9, 
+	10, 10, 11, 127, -128, 9, 10, 10, 
+	11, 127, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 9, 9, 10, 10, 32, 32, 
+	40, 40, 41, 41, 59, 59, -128, 9, 
+	10, 10, 11, 127, -128, 9, 10, 10, 
+	11, 127, -128, 9, 10, 10, 11, 127, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, -128, 9, 10, 10, 
+	11, 127, -128, 9, 10, 10, 11, 127, 
+	-128, 9, 10, 10, 11, 127, -128, 9, 
+	10, 10, 11, 127, -128, 9, 10, 10, 
+	11, 127, -128, 9, 10, 10, 11, 127, 
+	-128, 9, 10, 10, 11, 127, -128, 9, 
+	10, 10, 11, 127, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	-128, 9, 10, 10, 11, 127, -128, 9, 
+	10, 10, 11, 127, -128, 9, 10, 10, 
+	11, 127, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, -128, 9, 
+	10, 10, 11, 127, 10, 10, 59, 59, 
+	-128, 9, 10, 10, 11, 127, -128, 9, 
+	10, 10, 11, 127, -128, 9, 10, 10, 
+	11, 127, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, 10, 10, 59, 59, 10, 10, 
+	59, 59, -128, 9, 10, 10, 11, 127, 
+	-128, 9, 10, 10, 11, 127, -128, 9, 
+	10, 10, 11, 127, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	-128, 9, 10, 10, 11, 127, -128, 9, 
+	10, 10, 11, 127, -128, 9, 10, 10, 
+	11, 127, -128, 9, 10, 10, 11, 127, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	10, 10, 59, 59, 10, 10, 59, 59, 
+	-128, 9, 10, 10, 11, 127, 10, 10, 
+	59, 59, -128, 9, 10, 10, 11, 127, 
+	10, 10, 59, 59, -128, 9, 10, 10, 
+	11, 127, 10, 10, 59, 59, 10, 10, 
+	59, 59, -128, 9, 10, 10, 11, 127, 
+	-128, 9, 10, 10, 11, 127, 10, 10, 
+	59, 59, -128, 9, 10, 10, 11, 127, 
+	10, 10, 59, 59, -128, 9, 10, 10, 
+	11, 127, 10, 10, 59, 59, -128, 9, 
+	10, 10, 11, 127, 10, 10, 59, 59, 
+	-128, 9, 10, 10, 11, 127, 10, 10, 
+	59, 59, -128, 9, 10, 10, 11, 127, 
+	10, 10, 59, 59, -128, 9, 10, 10, 
+	11, 127, 10, 10, 59, 59, -128, 9, 
+	10, 10, 11, 127, 10, 10, 59, 59, 
+	-128, 9, 10, 10, 11, 127, 9, 9, 
+	10, 10, 32, 32, 40, 40, 41, 41, 
+	59, 59, -128, 9, 10, 10, 11, 127, 
+	9, 9, 10, 10, 32, 32, 40, 40, 
+	41, 41, 43, 43, 47, 47, 48, 57, 
+	59, 59, 65, 90, 97, 122, -128, 9, 
+	10, 10, 11, 127, 9, 9, 10, 10, 
+	32, 32, 40, 40, 41, 41, 43, 43, 
+	47, 47, 48, 57, 59, 59, 65, 90, 
+	97, 122, -128, 9, 10, 10, 11, 127, 
+	10, 10, 59, 59, -128, 9, 10, 10, 
+	11, 127, 0
+};
+
+static const char _zone_scanner_cond_spaces[] = {
+	0, 0, 0, 0, 0, 0, 5, 5, 
+	5, 5, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 5, 5, 0, 0, 0, 
+	5, 5, 0, 0, 0, 0, 5, 5, 
+	0, 0, 0, 0, 0, 5, 5, 5, 
+	5, 5, 5, 5, 5, 5, 5, 5, 
+	5, 0, 0, 0, 0, 5, 5, 5, 
+	5, 5, 5, 5, 5, 5, 5, 5, 
+	5, 5, 5, 5, 5, 5, 5, 5, 
+	5, 5, 5, 5, 5, 5, 5, 5, 
+	5, 5, 5, 5, 5, 5, 5, 5, 
+	5, 5, 5, 5, 5, 5, 5, 5, 
+	5, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	5, 5, 5, 5, 5, 5, 5, 5, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 5, 5, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 5, 5, 5, 5, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	5, 5, 5, 5, 5, 5, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 2, 2, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 5, 5, 0, 0, 0, 5, 5, 
+	5, 5, 5, 5, 5, 5, 0, 0, 
+	0, 5, 5, 5, 5, 5, 5, 5, 
+	5, 5, 5, 5, 5, 5, 5, 5, 
+	5, 5, 5, 5, 5, 5, 5, 5, 
+	5, 5, 5, 5, 5, 5, 5, 5, 
+	5, 5, 5, 5, 5, 5, 5, 5, 
+	5, 5, 5, 5, 5, 5, 5, 5, 
+	5, 5, 5, 5, 5, 5, 5, 5, 
+	5, 5, 5, 5, 5, 5, 5, 0, 
+	0, 0, 0, 0, 0, 0, 0, 5, 
+	5, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 5, 5, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 5, 5, 5, 5, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 5, 5, 5, 5, 5, 5, 5, 
+	5, 5, 5, 5, 5, 5, 5, 5, 
+	5, 0, 0, 0, 5, 5, 5, 5, 
+	0, 0, 0, 5, 5, 5, 5, 5, 
+	5, 0, 0, 0, 5, 5, 5, 5, 
+	5, 5, 0, 0, 0, 5, 5, 5, 
+	5, 5, 5, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 1, 1, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 5, 5, 
+	5, 5, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 5, 5, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 5, 
+	5, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 8, 11, 
+	8, 8, 8, 11, 3, 6, 3, 3, 
+	3, 3, 3, 3, 6, 3, 3, 1, 
+	1, 6, 6, 6, 4, 9, 4, 4, 
+	4, 9, 7, 7, 7, 8, 11, 8, 
+	8, 8, 3, 3, 3, 11, 3, 3, 
+	10, 10, 10, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 8, 11, 8, 8, 8, 11, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 8, 11, 8, 
+	8, 8, 11, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 8, 11, 8, 8, 8, 11, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	1, 1, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 1, 1, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 1, 1, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 5, 5, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 5, 5, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 5, 5, 
+	5, 5, 5, 5, 0, 0, 5, 5, 
+	0, 0, 0, 5, 5, 0, 0, 0, 
+	5, 5, 0, 0, 0, 0, 0, 5, 
+	5, 0, 0, 0, 0, 0, 0, 5, 
+	5, 0, 0, 0, 5, 5, 0, 0, 
+	0, 5, 5, 0, 0, 0, 5, 5, 
+	0, 0, 0, 5, 5, 0, 0, 0, 
+	5, 5, 0, 0, 0, 5, 5, 0, 
+	0, 0, 5, 5, 0, 0, 0, 4, 
+	9, 4, 4, 4, 9, 7, 7, 7, 
+	3, 6, 3, 3, 3, 3, 3, 3, 
+	6, 3, 3, 6, 6, 6, 8, 11, 
+	8, 8, 8, 3, 3, 3, 11, 3, 
+	3, 10, 10, 10, 5, 5, 0, 0, 
+	0, 0
+};
+
+static const short _zone_scanner_key_offsets[] = {
+	0, 0, 36, 54, 86, 102, 119, 127, 
+	135, 136, 137, 145, 148, 167, 173, 221, 
+	241, 275, 279, 281, 283, 293, 307, 309, 
+	311, 313, 323, 329, 331, 333, 335, 345, 
+	349, 351, 353, 363, 365, 367, 369, 379, 
+	389, 391, 393, 395, 397, 407, 411, 417, 
+	449, 451, 453, 455, 457, 459, 461, 463, 
+	473, 477, 479, 489, 499, 501, 503, 513, 
+	517, 519, 521, 523, 533, 543, 547, 549, 
+	551, 553, 563, 575, 577, 588, 600, 602, 
+	604, 606, 608, 618, 620, 622, 632, 638, 
+	648, 650, 652, 654, 664, 674, 682, 684, 
+	694, 696, 706, 708, 718, 720, 722, 724, 
+	734, 740, 742, 744, 754, 756, 766, 768, 
+	770, 772, 784, 787, 823, 827, 833, 867, 
+	885, 893, 905, 913, 916, 917, 923, 925, 
+	927, 929, 931, 933, 935, 941, 947, 981, 
+	984, 1002, 1036, 1039, 1047, 1059, 1067, 1070, 
+	1086, 1132, 1150, 1169, 1205, 1211, 1225, 1239, 
+	1287, 1299, 1313, 1323, 1335, 1347, 1357, 1369, 
+	1381, 1391, 1405, 1421, 1435, 1441, 1455, 1457, 
+	1459, 1461, 1463, 1465, 1471, 1473, 1475, 1481, 
+	1489, 1509, 1545, 1551, 1569, 1617, 1629, 1643, 
+	1653, 1665, 1677, 1687, 1699, 1711, 1721, 1735, 
+	1751, 1765, 1780, 1816, 1830, 1844, 1858, 1860, 
+	1862, 1872, 1874, 1876, 1878, 1888, 1890, 1900, 
+	1906, 1920, 1934, 1950, 1964, 1967, 1981, 1991, 
+	2003, 2011, 2021, 2031, 2039, 2049, 2059, 2067, 
+	2079, 2093, 2105, 2111, 2117, 2127, 2133, 2134, 
+	2135, 2146, 2153, 2169, 2184, 2186, 2188, 2190, 
+	2205, 2211, 2217, 2223, 2235, 2237, 2239, 2241, 
+	2253, 2259, 2265, 2267, 2269, 2271, 2277, 2283, 
+	2291, 2311, 2319, 2320, 2330, 2342, 2352, 2355, 
+	2361, 2377, 2378, 2396, 2404, 2405, 2414, 2416, 
+	2418, 2420, 2429, 2437, 2440, 2446, 2458, 2466, 
+	2484, 2485, 2503, 2511, 2512, 2521, 2523, 2525, 
+	2527, 2536, 2544, 2550, 2566, 2569, 2572, 2579, 
+	2586, 2594, 2602, 2619, 2622, 2623, 2633, 2669, 
+	2685, 2687, 2689, 2699, 2702, 2706, 2708, 2710, 
+	2720, 2722, 2724, 2726, 2736, 2742, 2744, 2746, 
+	2748, 2758, 2762, 2764, 2766, 2776, 2778, 2780, 
+	2782, 2792, 2802, 2804, 2806, 2808, 2810, 2820, 
+	2822, 2824, 2826, 2828, 2830, 2832, 2834, 2844, 
+	2848, 2850, 2860, 2870, 2872, 2874, 2884, 2888, 
+	2890, 2892, 2894, 2904, 2914, 2918, 2920, 2922, 
+	2924, 2934, 2946, 2948, 2959, 2971, 2973, 2975, 
+	2977, 2979, 2989, 2991, 2993, 3003, 3009, 3019, 
+	3021, 3023, 3025, 3035, 3045, 3053, 3055, 3065, 
+	3067, 3077, 3079, 3089, 3091, 3093, 3095, 3105, 
+	3111, 3113, 3115, 3125, 3127, 3137, 3139, 3141, 
+	3143, 3155, 3157, 3159, 3161, 3171, 3173, 3183, 
+	3189, 3197, 3205, 3217, 3223, 3239, 3242, 3245, 
+	3248, 3254, 3263, 3273, 3285, 3291, 3307, 3310, 
+	3313, 3321, 3324, 3327, 3336, 3345, 3351, 3360, 
+	3366, 3381, 3387, 3395, 3403, 3411, 3429, 3437, 
+	3455, 3463, 3481, 3489, 3507, 3515, 3527, 3535, 
+	3538, 3546, 3558, 3566, 3569, 3577, 3589, 3597, 
+	3600, 3608, 3620, 3628, 3631, 3634, 3637, 3643, 
+	3649, 3661, 3667, 3670, 3679, 3685, 3700, 3706, 
+	3709, 3711, 3719, 3734, 3740, 3743, 3749, 3759, 
+	3775, 3778, 3785, 3798, 3800, 3808, 3818, 3826, 
+	3836, 3845, 3853, 3859, 3867, 3875, 3885, 3893, 
+	3903, 3912, 3920, 3926, 3935, 3937, 3951, 3963, 
+	3977, 3989, 4003, 4015, 4029, 4039, 4042, 4055, 
+	4068, 4071, 4084, 4097, 4107, 4110, 4123, 4136, 
+	4146, 4149, 4162, 4175, 4185, 4188, 4194, 4197, 
+	4205, 4213, 4216, 4219, 4222, 4228, 4231, 4239, 
+	4247, 4250, 4253, 4255, 4263, 4271, 4279, 4287, 
+	4295, 4310, 4316, 4319, 4322, 4325, 4327, 4335, 
+	4343, 4351, 4363, 4369, 4381, 4387, 4399, 4405, 
+	4420, 4426, 4429, 4432, 4435, 4438, 4441, 4443, 
+	4451, 4459, 4467, 4475, 4483, 4496, 4498, 4501, 
+	4504, 4507, 4520, 4522, 4523, 4526, 4529, 4531, 
+	4543, 4546, 4547, 4554, 4561, 4563, 4571, 4579, 
+	4587, 4595, 4603, 4615, 4621, 4637, 4640, 4643, 
+	4646, 4649, 4651, 4659, 4667, 4675, 4687, 4693, 
+	4709, 4712, 4715, 4718, 4720, 4728, 4738, 4744, 
+	4752, 4760, 4767, 4801, 4814, 4816, 4819, 4833, 
+	4836, 4877, 4886, 4889, 4892, 4898, 4906, 4914, 
+	4923, 4960, 4963, 4966, 4972, 4980, 4988, 5001, 
+	5042, 5045, 5048, 5054, 5062, 5070, 5085, 5119, 
+	5122, 5125, 5128, 5154, 5166, 5174, 5182, 5190, 
+	5198, 5206, 5214, 5222, 5230, 5238, 5246, 5254, 
+	5262, 5277, 5283, 5296, 5298, 5301, 5304, 5307, 
+	5310, 5313, 5316, 5319, 5322, 5324, 5326, 5332, 
+	5334, 5336, 5338, 5344, 5346, 5352, 5356, 5358, 
+	5360, 5366, 5368, 5370, 5372, 5378, 5384, 5386, 
+	5388, 5390, 5396, 5400, 5402, 5404, 5410, 5412, 
+	5414, 5416, 5422, 5428, 5430, 5432, 5434, 5436, 
+	5442, 5444, 5446, 5448, 5450, 5452, 5454, 5456, 
+	5462, 5466, 5468, 5474, 5480, 5482, 5484, 5490, 
+	5494, 5496, 5498, 5500, 5506, 5512, 5516, 5518, 
+	5520, 5522, 5528, 5536, 5538, 5545, 5553, 5555, 
+	5557, 5559, 5561, 5567, 5569, 5571, 5577, 5583, 
+	5589, 5591, 5593, 5595, 5601, 5607, 5615, 5617, 
+	5623, 5625, 5631, 5633, 5639, 5641, 5643, 5645, 
+	5651, 5657, 5659, 5661, 5667, 5669, 5675, 5677, 
+	5679, 5681, 5689, 5698, 5704, 5710, 5712, 5720, 
+	5728, 5736, 5744, 5752, 5765, 5767, 5770, 5773, 
+	5776, 5783, 5785, 5787, 5795, 5803, 5811, 5819, 
+	5827, 5840, 5846, 5858, 5864, 5871, 5877, 5884, 
+	5891, 5897, 5904, 5916, 5922, 5923, 5924, 5925, 
+	5926, 5927, 5930, 5936, 5948, 5951, 5954, 5957, 
+	5959, 5967, 5975, 5983, 5991, 5999, 6012, 6018, 
+	6024, 6036, 6039, 6042, 6045, 6047, 6055, 6063, 
+	6071, 6079, 6087, 6099, 6105, 6121, 6124, 6127, 
+	6130, 6133, 6151, 6184, 6228, 6274, 6292, 6338, 
+	6356, 6389, 6450, 6511, 6511, 6511, 6511, 6523, 
+	6523, 6523, 6523, 6539, 6539, 6556, 6559, 6559, 
+	6595, 6598, 6598, 6614, 6617, 6629, 6629, 6645, 
+	6648, 6651, 6651, 6651, 6651, 6651, 6651, 6651, 
+	6651, 6667, 6670, 6670, 6670, 6680, 6683, 6695, 
+	6698, 6710, 6713, 6725, 6728, 6728, 6728, 6728, 
+	6728, 6741, 6744, 6744, 6760, 6763, 6763, 6779, 
+	6782, 6782, 6796, 6799, 6812, 6815, 6856, 6865, 
+	6865, 6865, 6865, 6865, 6865, 6865, 6865, 6881
+};
+
+static const short _zone_scanner_trans_keys[] = {
+	9, 32, 40, 41, 65, 67, 68, 72, 
+	73, 75, 76, 77, 78, 80, 82, 83, 
+	84, 97, 99, 100, 104, 105, 107, 108, 
+	109, 110, 112, 114, 115, 116, 778, 827, 
+	1034, 1083, 48, 57, 9, 32, 40, 41, 
+	68, 72, 77, 83, 87, 100, 104, 109, 
+	115, 119, 1034, 1083, 48, 57, 9, 32, 
+	40, 41, 65, 67, 68, 72, 73, 75, 
+	76, 77, 78, 80, 82, 83, 84, 97, 
+	99, 100, 104, 105, 107, 108, 109, 110, 
+	112, 114, 115, 116, 1034, 1083, 9, 32, 
+	40, 41, 65, 70, 80, 97, 102, 112, 
+	2058, 2107, 2314, 2363, 2570, 2619, 9, 32, 
+	40, 41, 92, 2058, 2107, 2314, 2363, 2570, 
+	2619, -128, 8, 11, 58, 60, 127, 9, 
+	32, 40, 41, 778, 827, 1034, 1083, 9, 
+	32, 40, 41, 778, 827, 1034, 1083, 10, 
+	35, 9, 32, 40, 41, 778, 827, 1034, 
+	1083, 1034, 896, 1151, 9, 32, 40, 41, 
+	92, 1802, 1851, 2058, 2107, 2314, 2363, 2570, 
+	2619, -128, 8, 11, 58, 60, 127, 778, 
+	1034, 640, 895, 896, 1151, 9, 32, 40, 
+	41, 58, 65, 67, 68, 72, 73, 75, 
+	76, 77, 78, 80, 82, 83, 84, 92, 
+	97, 99, 100, 104, 105, 107, 108, 109, 
+	110, 112, 114, 115, 116, 1802, 1851, 2058, 
+	2107, 2314, 2363, 2570, 2619, -128, 8, 11, 
+	47, 48, 57, 60, 127, 9, 32, 40, 
+	41, 68, 72, 77, 83, 87, 100, 104, 
+	109, 115, 119, 778, 827, 1034, 1083, 48, 
+	57, 9, 32, 40, 41, 65, 67, 68, 
+	72, 73, 75, 76, 77, 78, 80, 82, 
+	83, 84, 97, 99, 100, 104, 105, 107, 
+	108, 109, 110, 112, 114, 115, 116, 778, 
+	827, 1034, 1083, 69, 78, 101, 110, 82, 
+	114, 84, 116, 9, 32, 40, 41, 2058, 
+	2107, 2314, 2363, 2570, 2619, 777, 778, 800, 
+	808, 809, 827, 1033, 1034, 1056, 1064, 1065, 
+	1083, 896, 1151, 65, 97, 77, 109, 69, 
+	101, 9, 32, 40, 41, 2058, 2107, 2314, 
+	2363, 2570, 2619, 72, 78, 83, 104, 110, 
+	115, 67, 99, 73, 105, 68, 100, 9, 
+	32, 40, 41, 2058, 2107, 2314, 2363, 2570, 
+	2619, 65, 83, 97, 115, 77, 109, 69, 
+	101, 9, 32, 40, 41, 2058, 2107, 2314, 
+	2363, 2570, 2619, 75, 107, 69, 101, 89, 
+	121, 9, 32, 40, 41, 2058, 2107, 2314, 
+	2363, 2570, 2619, 9, 32, 40, 41, 2058, 
+	2107, 2314, 2363, 2570, 2619, 73, 105, 78, 
+	110, 70, 102, 79, 111, 9, 32, 40, 
+	41, 2058, 2107, 2314, 2363, 2570, 2619, 78, 
+	80, 110, 112, 9, 32, 40, 41, 1034, 
+	1083, 9, 32, 40, 41, 65, 67, 68, 
+	72, 73, 75, 76, 77, 78, 80, 82, 
+	83, 84, 97, 99, 100, 104, 105, 107, 
+	108, 109, 110, 112, 114, 115, 116, 1034, 
+	1083, 80, 112, 83, 115, 69, 101, 67, 
+	99, 75, 107, 69, 101, 89, 121, 9, 
+	32, 40, 41, 2058, 2107, 2314, 2363, 2570, 
+	2619, 69, 88, 101, 120, 89, 121, 9, 
+	32, 40, 41, 2058, 2107, 2314, 2363, 2570, 
+	2619, 9, 32, 40, 41, 2058, 2107, 2314, 
+	2363, 2570, 2619, 79, 111, 67, 99, 9, 
+	32, 40, 41, 2058, 2107, 2314, 2363, 2570, 
+	2619, 73, 88, 105, 120, 78, 110, 70, 
+	102, 79, 111, 9, 32, 40, 41, 2058, 
+	2107, 2314, 2363, 2570, 2619, 9, 32, 40, 
+	41, 2058, 2107, 2314, 2363, 2570, 2619, 65, 
+	83, 97, 115, 80, 112, 84, 116, 82, 
+	114, 9, 32, 40, 41, 2058, 2107, 2314, 
+	2363, 2570, 2619, 9, 32, 40, 41, 69, 
+	101, 2058, 2107, 2314, 2363, 2570, 2619, 67, 
+	99, 9, 32, 40, 41, 51, 2058, 2107, 
+	2314, 2363, 2570, 2619, 9, 32, 40, 41, 
+	80, 112, 2058, 2107, 2314, 2363, 2570, 2619, 
+	65, 97, 82, 114, 65, 97, 77, 109, 
+	9, 32, 40, 41, 2058, 2107, 2314, 2363, 
+	2570, 2619, 84, 116, 82, 114, 9, 32, 
+	40, 41, 2058, 2107, 2314, 2363, 2570, 2619, 
+	80, 82, 84, 112, 114, 116, 9, 32, 
+	40, 41, 2058, 2107, 2314, 2363, 2570, 2619, 
+	83, 115, 73, 105, 71, 103, 9, 32, 
+	40, 41, 2058, 2107, 2314, 2363, 2570, 2619, 
+	9, 32, 40, 41, 2058, 2107, 2314, 2363, 
+	2570, 2619, 79, 80, 82, 83, 111, 112, 
+	114, 115, 65, 97, 9, 32, 40, 41, 
+	2058, 2107, 2314, 2363, 2570, 2619, 70, 102, 
+	9, 32, 40, 41, 2058, 2107, 2314, 2363, 
+	2570, 2619, 86, 118, 9, 32, 40, 41, 
+	2058, 2107, 2314, 2363, 2570, 2619, 72, 104, 
+	70, 102, 80, 112, 9, 32, 40, 41, 
+	2058, 2107, 2314, 2363, 2570, 2619, 76, 88, 
+	89, 108, 120, 121, 83, 115, 65, 97, 
+	9, 32, 40, 41, 2058, 2107, 2314, 2363, 
+	2570, 2619, 84, 116, 9, 32, 40, 41, 
+	2058, 2107, 2314, 2363, 2570, 2619, 80, 112, 
+	69, 101, 48, 57, 9, 32, 40, 41, 
+	2058, 2107, 2314, 2363, 2570, 2619, 48, 57, 
+	1034, 896, 1151, 9, 32, 40, 41, 65, 
+	67, 68, 72, 73, 75, 76, 77, 78, 
+	80, 82, 83, 84, 97, 99, 100, 104, 
+	105, 107, 108, 109, 110, 112, 114, 115, 
+	116, 778, 827, 1034, 1083, 48, 57, 78, 
+	80, 110, 112, 9, 32, 40, 41, 1034, 
+	1083, 9, 32, 40, 41, 65, 67, 68, 
+	72, 73, 75, 76, 77, 78, 80, 82, 
+	83, 84, 97, 99, 100, 104, 105, 107, 
+	108, 109, 110, 112, 114, 115, 116, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 68, 
+	72, 77, 83, 87, 100, 104, 109, 115, 
+	119, 1034, 1083, 48, 57, 9, 32, 40, 
+	41, 1034, 1083, 48, 57, 68, 72, 77, 
+	83, 87, 100, 104, 109, 115, 119, 48, 
+	57, 9, 32, 40, 41, 1034, 1083, 48, 
+	57, 1034, 896, 1151, 10, 73, 79, 84, 
+	105, 111, 116, 78, 110, 67, 99, 76, 
+	108, 85, 117, 68, 100, 69, 101, 32, 
+	59, 9, 10, 40, 41, 9, 32, 40, 
+	41, 1034, 1083, 9, 32, 40, 41, 65, 
+	67, 68, 72, 73, 75, 76, 77, 78, 
+	80, 82, 83, 84, 97, 99, 100, 104, 
+	105, 107, 108, 109, 110, 112, 114, 115, 
+	116, 1034, 1083, 48, 57, 1034, 896, 1151, 
+	9, 32, 40, 41, 68, 72, 77, 83, 
+	87, 100, 104, 109, 115, 119, 1034, 1083, 
+	48, 57, 9, 32, 40, 41, 65, 67, 
+	68, 72, 73, 75, 76, 77, 78, 80, 
+	82, 83, 84, 97, 99, 100, 104, 105, 
+	107, 108, 109, 110, 112, 114, 115, 116, 
+	1034, 1083, 48, 57, 1034, 896, 1151, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 68, 
+	72, 77, 83, 87, 100, 104, 109, 115, 
+	119, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 1034, 896, 1151, 9, 32, 
+	40, 41, 65, 70, 80, 97, 102, 112, 
+	2058, 2107, 2314, 2363, 2570, 2619, 9, 32, 
+	40, 41, 58, 65, 67, 68, 72, 73, 
+	75, 76, 77, 78, 80, 82, 83, 84, 
+	92, 97, 99, 100, 104, 105, 107, 108, 
+	109, 110, 112, 114, 115, 116, 2058, 2107, 
+	2314, 2363, 2570, 2619, -128, 8, 11, 47, 
+	48, 57, 60, 127, 9, 32, 40, 41, 
+	65, 70, 80, 97, 102, 112, 1802, 1851, 
+	2058, 2107, 2314, 2363, 2570, 2619, 9, 32, 
+	40, 41, 92, 1802, 1851, 2058, 2107, 2314, 
+	2363, 2570, 2619, -128, 8, 11, 58, 60, 
+	127, 9, 32, 40, 41, 65, 67, 68, 
+	72, 73, 75, 76, 77, 78, 80, 82, 
+	83, 84, 97, 99, 100, 104, 105, 107, 
+	108, 109, 110, 112, 114, 115, 116, 778, 
+	827, 1034, 1083, 48, 57, 778, 1034, 640, 
+	895, 896, 1151, 9, 32, 40, 41, 778, 
+	827, 1034, 1083, -128, 8, 11, 58, 60, 
+	127, 9, 32, 40, 41, 778, 827, 1034, 
+	1083, -128, 8, 11, 58, 60, 127, 9, 
+	32, 40, 41, 58, 65, 67, 68, 72, 
+	73, 75, 76, 77, 78, 80, 82, 83, 
+	84, 92, 97, 99, 100, 104, 105, 107, 
+	108, 109, 110, 112, 114, 115, 116, 1802, 
+	1851, 2058, 2107, 2314, 2363, 2570, 2619, -128, 
+	8, 11, 47, 48, 57, 60, 127, 9, 
+	32, 40, 41, 69, 78, 101, 110, 778, 
+	827, 1034, 1083, 9, 32, 40, 41, 72, 
+	78, 83, 104, 110, 115, 778, 827, 1034, 
+	1083, 9, 32, 40, 41, 73, 105, 778, 
+	827, 1034, 1083, 9, 32, 40, 41, 78, 
+	80, 110, 112, 778, 827, 1034, 1083, 9, 
+	32, 40, 41, 69, 88, 101, 120, 778, 
+	827, 1034, 1083, 9, 32, 40, 41, 79, 
+	111, 778, 827, 1034, 1083, 9, 32, 40, 
+	41, 73, 88, 105, 120, 778, 827, 1034, 
+	1083, 9, 32, 40, 41, 65, 83, 97, 
+	115, 778, 827, 1034, 1083, 9, 32, 40, 
+	41, 84, 116, 778, 827, 1034, 1083, 9, 
+	32, 40, 41, 80, 82, 84, 112, 114, 
+	116, 778, 827, 1034, 1083, 9, 32, 40, 
+	41, 79, 80, 82, 83, 111, 112, 114, 
+	115, 778, 827, 1034, 1083, 9, 32, 40, 
+	41, 76, 88, 89, 108, 120, 121, 778, 
+	827, 1034, 1083, 778, 1034, 640, 895, 896, 
+	1151, 9, 32, 40, 41, 73, 79, 84, 
+	105, 111, 116, 778, 827, 1034, 1083, 82, 
+	114, 73, 105, 71, 103, 73, 105, 78, 
+	110, 32, 59, 9, 10, 40, 41, 84, 
+	116, 76, 108, 32, 59, 9, 10, 40, 
+	41, 9, 32, 40, 41, 778, 827, 1034, 
+	1083, 9, 32, 40, 41, 68, 72, 77, 
+	83, 87, 100, 104, 109, 115, 119, 778, 
+	827, 1034, 1083, 48, 57, 9, 32, 40, 
+	41, 65, 67, 68, 72, 73, 75, 76, 
+	77, 78, 80, 82, 83, 84, 97, 99, 
+	100, 104, 105, 107, 108, 109, 110, 112, 
+	114, 115, 116, 778, 827, 1034, 1083, 48, 
+	57, 778, 1034, 640, 895, 896, 1151, 9, 
+	32, 40, 41, 65, 70, 80, 97, 102, 
+	112, 1802, 1851, 2058, 2107, 2314, 2363, 2570, 
+	2619, 9, 32, 40, 41, 58, 65, 67, 
+	68, 72, 73, 75, 76, 77, 78, 80, 
+	82, 83, 84, 92, 97, 99, 100, 104, 
+	105, 107, 108, 109, 110, 112, 114, 115, 
+	116, 1802, 1851, 2058, 2107, 2314, 2363, 2570, 
+	2619, -128, 8, 11, 47, 48, 57, 60, 
+	127, 9, 32, 40, 41, 69, 78, 101, 
+	110, 778, 827, 1034, 1083, 9, 32, 40, 
+	41, 72, 78, 83, 104, 110, 115, 778, 
+	827, 1034, 1083, 9, 32, 40, 41, 73, 
+	105, 778, 827, 1034, 1083, 9, 32, 40, 
+	41, 78, 80, 110, 112, 778, 827, 1034, 
+	1083, 9, 32, 40, 41, 69, 88, 101, 
+	120, 778, 827, 1034, 1083, 9, 32, 40, 
+	41, 79, 111, 778, 827, 1034, 1083, 9, 
+	32, 40, 41, 73, 88, 105, 120, 778, 
+	827, 1034, 1083, 9, 32, 40, 41, 65, 
+	83, 97, 115, 778, 827, 1034, 1083, 9, 
+	32, 40, 41, 84, 116, 778, 827, 1034, 
+	1083, 9, 32, 40, 41, 80, 82, 84, 
+	112, 114, 116, 778, 827, 1034, 1083, 9, 
+	32, 40, 41, 79, 80, 82, 83, 111, 
+	112, 114, 115, 778, 827, 1034, 1083, 9, 
+	32, 40, 41, 76, 88, 89, 108, 120, 
+	121, 778, 827, 1034, 1083, 9, 32, 35, 
+	40, 41, 778, 827, 1034, 1083, -128, 8, 
+	11, 58, 60, 127, 9, 32, 40, 41, 
+	65, 67, 68, 72, 73, 75, 76, 77, 
+	78, 80, 82, 83, 84, 97, 99, 100, 
+	104, 105, 107, 108, 109, 110, 112, 114, 
+	115, 116, 778, 827, 1034, 1083, 48, 57, 
+	777, 778, 800, 808, 809, 827, 1033, 1034, 
+	1056, 1064, 1065, 1083, 896, 1151, 777, 778, 
+	800, 808, 809, 827, 1033, 1034, 1056, 1064, 
+	1065, 1083, 896, 1151, 777, 778, 800, 808, 
+	809, 1033, 1034, 1056, 1064, 1065, 640, 895, 
+	896, 1151, 65, 97, 65, 97, 9, 32, 
+	40, 41, 2058, 2107, 2314, 2363, 2570, 2619, 
+	83, 115, 68, 100, 66, 98, 9, 32, 
+	40, 41, 2058, 2107, 2314, 2363, 2570, 2619, 
+	76, 108, 9, 32, 40, 41, 2058, 2107, 
+	2314, 2363, 2570, 2619, 778, 1034, 640, 895, 
+	896, 1151, 9, 32, 40, 41, 778, 827, 
+	1034, 1083, -128, 8, 11, 58, 60, 127, 
+	9, 32, 40, 41, 778, 827, 1034, 1083, 
+	-128, 8, 11, 58, 60, 127, 777, 778, 
+	800, 808, 809, 827, 1033, 1034, 1056, 1064, 
+	1065, 1083, 640, 895, 896, 1151, 777, 778, 
+	800, 808, 809, 1033, 1034, 1056, 1064, 1065, 
+	640, 895, 896, 1151, 1034, 896, 1151, 777, 
+	778, 800, 808, 809, 827, 1033, 1034, 1056, 
+	1064, 1065, 1083, 896, 1151, 9, 32, 40, 
+	41, 69, 78, 101, 110, 1034, 1083, 9, 
+	32, 40, 41, 72, 78, 83, 104, 110, 
+	115, 1034, 1083, 9, 32, 40, 41, 73, 
+	105, 1034, 1083, 9, 32, 40, 41, 78, 
+	80, 110, 112, 1034, 1083, 9, 32, 40, 
+	41, 69, 88, 101, 120, 1034, 1083, 9, 
+	32, 40, 41, 79, 111, 1034, 1083, 9, 
+	32, 40, 41, 73, 88, 105, 120, 1034, 
+	1083, 9, 32, 40, 41, 65, 83, 97, 
+	115, 1034, 1083, 9, 32, 40, 41, 84, 
+	116, 1034, 1083, 9, 32, 40, 41, 80, 
+	82, 84, 112, 114, 116, 1034, 1083, 9, 
+	32, 40, 41, 79, 80, 82, 83, 111, 
+	112, 114, 115, 1034, 1083, 9, 32, 40, 
+	41, 76, 88, 89, 108, 120, 121, 1034, 
+	1083, 778, 1034, 640, 895, 896, 1151, 778, 
+	1034, 640, 895, 896, 1151, 9, 32, 40, 
+	41, 78, 80, 110, 112, 1034, 1083, 778, 
+	1034, 640, 895, 896, 1151, 10, 10, 42, 
+	46, 64, 92, 95, 45, 57, 65, 90, 
+	97, 122, 32, 46, 59, 9, 10, 40, 
+	41, 32, 42, 45, 59, 92, 95, 9, 
+	10, 40, 41, 47, 57, 65, 90, 97, 
+	122, 32, 46, 59, 92, 95, 9, 10, 
+	40, 41, 45, 57, 65, 90, 97, 122, 
+	48, 57, 48, 57, 48, 57, 32, 46, 
+	59, 92, 95, 9, 10, 40, 41, 45, 
+	57, 65, 90, 97, 122, 32, 59, 9, 
+	10, 40, 41, 32, 59, 9, 10, 40, 
+	41, 34, 92, 33, 58, 60, 126, 32, 
+	33, 59, 92, 9, 10, 35, 39, 40, 
+	41, 42, 126, 48, 57, 48, 57, 48, 
+	57, 32, 33, 59, 92, 9, 10, 35, 
+	39, 40, 41, 42, 126, 9, 34, 92, 
+	522, 32, 126, 32, 59, 9, 10, 40, 
+	41, 48, 57, 48, 57, 48, 57, 9, 
+	34, 92, 522, 32, 126, 9, 32, 40, 
+	41, 1034, 1083, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 68, 
+	72, 77, 83, 87, 100, 104, 109, 115, 
+	119, 778, 827, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 778, 827, 1034, 1083, 10, 
+	9, 32, 40, 41, 778, 827, 1034, 1083, 
+	48, 57, 68, 72, 77, 83, 87, 100, 
+	104, 109, 115, 119, 48, 57, 9, 32, 
+	40, 41, 778, 827, 1034, 1083, 48, 57, 
+	1034, 896, 1151, 9, 32, 40, 41, 1034, 
+	1083, 9, 32, 40, 41, 42, 46, 92, 
+	95, 1034, 1083, 45, 57, 65, 90, 97, 
+	122, 46, 9, 32, 40, 41, 42, 45, 
+	92, 95, 778, 827, 1034, 1083, 47, 57, 
+	65, 90, 97, 122, 9, 32, 40, 41, 
+	778, 827, 1034, 1083, 10, 46, 92, 95, 
+	45, 57, 65, 90, 97, 122, 48, 57, 
+	48, 57, 48, 57, 46, 92, 95, 45, 
+	57, 65, 90, 97, 122, 9, 32, 40, 
+	41, 778, 827, 1034, 1083, 1034, 896, 1151, 
+	9, 32, 40, 41, 1034, 1083, 9, 32, 
+	40, 41, 1034, 1083, -128, 8, 11, 58, 
+	60, 127, 9, 32, 40, 41, 778, 827, 
+	1034, 1083, 9, 32, 40, 41, 42, 46, 
+	92, 95, 778, 827, 1034, 1083, 45, 57, 
+	65, 90, 97, 122, 46, 9, 32, 40, 
+	41, 42, 45, 92, 95, 778, 827, 1034, 
+	1083, 47, 57, 65, 90, 97, 122, 9, 
+	32, 40, 41, 778, 827, 1034, 1083, 10, 
+	46, 92, 95, 45, 57, 65, 90, 97, 
+	122, 48, 57, 48, 57, 48, 57, 46, 
+	92, 95, 45, 57, 65, 90, 97, 122, 
+	9, 32, 40, 41, 778, 827, 1034, 1083, 
+	778, 1034, 640, 895, 896, 1151, 9, 32, 
+	40, 41, 42, 46, 92, 95, 1034, 1083, 
+	45, 57, 65, 90, 97, 122, 1034, 896, 
+	1151, 1034, 896, 1151, 43, 47, 57, 65, 
+	90, 97, 122, 43, 47, 57, 65, 90, 
+	97, 122, 43, 61, 47, 57, 65, 90, 
+	97, 122, 43, 61, 47, 57, 65, 90, 
+	97, 122, 9, 32, 40, 41, 43, 2058, 
+	2107, 2314, 2363, 2570, 2619, 47, 57, 65, 
+	90, 97, 122, 1034, 896, 1151, 61, 9, 
+	32, 40, 41, 2058, 2107, 2314, 2363, 2570, 
+	2619, 9, 32, 40, 41, 65, 67, 68, 
+	72, 73, 75, 76, 77, 78, 80, 82, 
+	83, 84, 97, 99, 100, 104, 105, 107, 
+	108, 109, 110, 112, 114, 115, 116, 2058, 
+	2107, 2314, 2363, 2570, 2619, 9, 32, 40, 
+	41, 65, 70, 80, 97, 102, 112, 2058, 
+	2107, 2314, 2363, 2570, 2619, 65, 97, 65, 
+	97, 9, 32, 40, 41, 2058, 2107, 2314, 
+	2363, 2570, 2619, 1034, 896, 1151, 69, 78, 
+	101, 110, 82, 114, 84, 116, 9, 32, 
+	40, 41, 2058, 2107, 2314, 2363, 2570, 2619, 
+	65, 97, 77, 109, 69, 101, 9, 32, 
+	40, 41, 2058, 2107, 2314, 2363, 2570, 2619, 
+	72, 78, 83, 104, 110, 115, 67, 99, 
+	73, 105, 68, 100, 9, 32, 40, 41, 
+	2058, 2107, 2314, 2363, 2570, 2619, 65, 83, 
+	97, 115, 77, 109, 69, 101, 9, 32, 
+	40, 41, 2058, 2107, 2314, 2363, 2570, 2619, 
+	75, 107, 69, 101, 89, 121, 9, 32, 
+	40, 41, 2058, 2107, 2314, 2363, 2570, 2619, 
+	9, 32, 40, 41, 2058, 2107, 2314, 2363, 
+	2570, 2619, 73, 105, 78, 110, 70, 102, 
+	79, 111, 9, 32, 40, 41, 2058, 2107, 
+	2314, 2363, 2570, 2619, 80, 112, 83, 115, 
+	69, 101, 67, 99, 75, 107, 69, 101, 
+	89, 121, 9, 32, 40, 41, 2058, 2107, 
+	2314, 2363, 2570, 2619, 69, 88, 101, 120, 
+	89, 121, 9, 32, 40, 41, 2058, 2107, 
+	2314, 2363, 2570, 2619, 9, 32, 40, 41, 
+	2058, 2107, 2314, 2363, 2570, 2619, 79, 111, 
+	67, 99, 9, 32, 40, 41, 2058, 2107, 
+	2314, 2363, 2570, 2619, 73, 88, 105, 120, 
+	78, 110, 70, 102, 79, 111, 9, 32, 
+	40, 41, 2058, 2107, 2314, 2363, 2570, 2619, 
+	9, 32, 40, 41, 2058, 2107, 2314, 2363, 
+	2570, 2619, 65, 83, 97, 115, 80, 112, 
+	84, 116, 82, 114, 9, 32, 40, 41, 
+	2058, 2107, 2314, 2363, 2570, 2619, 9, 32, 
+	40, 41, 69, 101, 2058, 2107, 2314, 2363, 
+	2570, 2619, 67, 99, 9, 32, 40, 41, 
+	51, 2058, 2107, 2314, 2363, 2570, 2619, 9, 
+	32, 40, 41, 80, 112, 2058, 2107, 2314, 
+	2363, 2570, 2619, 65, 97, 82, 114, 65, 
+	97, 77, 109, 9, 32, 40, 41, 2058, 
+	2107, 2314, 2363, 2570, 2619, 84, 116, 82, 
+	114, 9, 32, 40, 41, 2058, 2107, 2314, 
+	2363, 2570, 2619, 80, 82, 84, 112, 114, 
+	116, 9, 32, 40, 41, 2058, 2107, 2314, 
+	2363, 2570, 2619, 83, 115, 73, 105, 71, 
+	103, 9, 32, 40, 41, 2058, 2107, 2314, 
+	2363, 2570, 2619, 9, 32, 40, 41, 2058, 
+	2107, 2314, 2363, 2570, 2619, 79, 80, 82, 
+	83, 111, 112, 114, 115, 65, 97, 9, 
+	32, 40, 41, 2058, 2107, 2314, 2363, 2570, 
+	2619, 70, 102, 9, 32, 40, 41, 2058, 
+	2107, 2314, 2363, 2570, 2619, 86, 118, 9, 
+	32, 40, 41, 2058, 2107, 2314, 2363, 2570, 
+	2619, 72, 104, 70, 102, 80, 112, 9, 
+	32, 40, 41, 2058, 2107, 2314, 2363, 2570, 
+	2619, 76, 88, 89, 108, 120, 121, 83, 
+	115, 65, 97, 9, 32, 40, 41, 2058, 
+	2107, 2314, 2363, 2570, 2619, 84, 116, 9, 
+	32, 40, 41, 2058, 2107, 2314, 2363, 2570, 
+	2619, 80, 112, 69, 101, 48, 57, 9, 
+	32, 40, 41, 2058, 2107, 2314, 2363, 2570, 
+	2619, 48, 57, 83, 115, 68, 100, 66, 
+	98, 9, 32, 40, 41, 2058, 2107, 2314, 
+	2363, 2570, 2619, 76, 108, 9, 32, 40, 
+	41, 2058, 2107, 2314, 2363, 2570, 2619, 9, 
+	32, 40, 41, 1034, 1083, 9, 32, 40, 
+	41, 1034, 1083, 48, 57, 9, 32, 40, 
+	41, 1034, 1083, 48, 57, 9, 32, 40, 
+	41, 1034, 1083, 48, 57, 65, 70, 97, 
+	102, 48, 57, 65, 70, 97, 102, 9, 
+	32, 40, 41, 2058, 2107, 2314, 2363, 2570, 
+	2619, 48, 57, 65, 70, 97, 102, 1034, 
+	896, 1151, 1034, 896, 1151, 1034, 896, 1151, 
+	9, 32, 40, 41, 1034, 1083, 9, 32, 
+	40, 41, 48, 1034, 1083, 49, 57, 9, 
+	32, 40, 41, 778, 827, 1034, 1083, 48, 
+	57, 9, 32, 40, 41, 1034, 1083, 48, 
+	57, 65, 70, 97, 102, 48, 57, 65, 
+	70, 97, 102, 9, 32, 40, 41, 2058, 
+	2107, 2314, 2363, 2570, 2619, 48, 57, 65, 
+	70, 97, 102, 1034, 896, 1151, 1034, 896, 
+	1151, 9, 32, 40, 41, 1034, 1083, 48, 
+	57, 1034, 896, 1151, 46, 48, 57, 32, 
+	46, 59, 9, 10, 40, 41, 48, 57, 
+	42, 92, 95, 45, 57, 64, 90, 97, 
+	122, 32, 59, 9, 10, 40, 41, 42, 
+	92, 95, 45, 57, 64, 90, 97, 122, 
+	9, 32, 40, 41, 1034, 1083, 9, 32, 
+	40, 41, 42, 92, 95, 1034, 1083, 45, 
+	57, 64, 90, 97, 122, 9, 32, 40, 
+	41, 1034, 1083, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 68, 
+	72, 77, 83, 87, 100, 104, 109, 115, 
+	119, 1034, 1083, 48, 57, 9, 32, 40, 
+	41, 1034, 1083, 48, 57, 9, 32, 40, 
+	41, 68, 72, 77, 83, 87, 100, 104, 
+	109, 115, 119, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 68, 72, 77, 83, 87, 
+	100, 104, 109, 115, 119, 1034, 1083, 48, 
+	57, 9, 32, 40, 41, 1034, 1083, 48, 
+	57, 32, 59, 68, 72, 77, 83, 87, 
+	100, 104, 109, 115, 119, 9, 10, 40, 
+	41, 48, 57, 32, 59, 9, 10, 40, 
+	41, 48, 57, 68, 72, 77, 83, 87, 
+	100, 104, 109, 115, 119, 48, 57, 32, 
+	59, 9, 10, 40, 41, 48, 57, 1034, 
+	896, 1151, 9, 32, 40, 41, 1034, 1083, 
+	48, 57, 68, 72, 77, 83, 87, 100, 
+	104, 109, 115, 119, 48, 57, 9, 32, 
+	40, 41, 1034, 1083, 48, 57, 1034, 896, 
+	1151, 9, 32, 40, 41, 1034, 1083, 48, 
+	57, 68, 72, 77, 83, 87, 100, 104, 
+	109, 115, 119, 48, 57, 9, 32, 40, 
+	41, 1034, 1083, 48, 57, 1034, 896, 1151, 
+	9, 32, 40, 41, 1034, 1083, 48, 57, 
+	68, 72, 77, 83, 87, 100, 104, 109, 
+	115, 119, 48, 57, 9, 32, 40, 41, 
+	1034, 1083, 48, 57, 1034, 896, 1151, 1034, 
+	896, 1151, 1034, 896, 1151, 32, 59, 9, 
+	10, 40, 41, 9, 32, 40, 41, 1034, 
+	1083, 9, 32, 40, 41, 1034, 1083, -128, 
+	8, 11, 58, 60, 127, 32, 59, 9, 
+	10, 40, 41, 1034, 896, 1151, 42, 92, 
+	95, 45, 57, 64, 90, 97, 122, 9, 
+	32, 40, 41, 1034, 1083, 9, 32, 40, 
+	41, 42, 92, 95, 1034, 1083, 45, 57, 
+	64, 90, 97, 122, 32, 59, 9, 10, 
+	40, 41, 1034, 896, 1151, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 42, 92, 95, 1034, 1083, 
+	45, 57, 64, 90, 97, 122, 32, 59, 
+	9, 10, 40, 41, 1034, 896, 1151, 32, 
+	59, 9, 10, 40, 41, 9, 32, 40, 
+	41, 2058, 2107, 2314, 2363, 2570, 2619, 9, 
+	32, 40, 41, 2058, 2107, 2314, 2363, 2570, 
+	2619, -128, 8, 11, 58, 60, 127, 1034, 
+	896, 1151, 46, 48, 58, 65, 70, 97, 
+	102, 32, 46, 59, 9, 10, 40, 41, 
+	48, 58, 65, 70, 97, 102, 48, 57, 
+	9, 32, 40, 41, 1034, 1083, 48, 57, 
+	9, 32, 40, 41, 78, 83, 1034, 1083, 
+	48, 57, 9, 32, 40, 41, 1034, 1083, 
+	48, 57, 9, 32, 40, 41, 78, 83, 
+	1034, 1083, 48, 57, 9, 32, 40, 41, 
+	46, 1034, 1083, 48, 57, 9, 32, 40, 
+	41, 78, 83, 1034, 1083, 9, 32, 40, 
+	41, 1034, 1083, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 69, 
+	87, 1034, 1083, 48, 57, 9, 32, 40, 
+	41, 1034, 1083, 48, 57, 9, 32, 40, 
+	41, 69, 87, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 46, 1034, 1083, 48, 57, 
+	9, 32, 40, 41, 69, 87, 1034, 1083, 
+	9, 32, 40, 41, 1034, 1083, 9, 32, 
+	40, 41, 45, 1034, 1083, 48, 57, 48, 
+	57, 9, 32, 40, 41, 46, 109, 2058, 
+	2107, 2314, 2363, 2570, 2619, 48, 57, 9, 
+	32, 40, 41, 2058, 2107, 2314, 2363, 2570, 
+	2619, 48, 57, 9, 32, 40, 41, 46, 
+	109, 2058, 2107, 2314, 2363, 2570, 2619, 48, 
+	57, 9, 32, 40, 41, 2058, 2107, 2314, 
+	2363, 2570, 2619, 48, 57, 9, 32, 40, 
+	41, 46, 109, 2058, 2107, 2314, 2363, 2570, 
+	2619, 48, 57, 9, 32, 40, 41, 2058, 
+	2107, 2314, 2363, 2570, 2619, 48, 57, 9, 
+	32, 40, 41, 46, 109, 2058, 2107, 2314, 
+	2363, 2570, 2619, 48, 57, 9, 32, 40, 
+	41, 2058, 2107, 2314, 2363, 2570, 2619, 1034, 
+	896, 1151, 9, 32, 40, 41, 109, 2058, 
+	2107, 2314, 2363, 2570, 2619, 48, 57, 9, 
+	32, 40, 41, 109, 2058, 2107, 2314, 2363, 
+	2570, 2619, 48, 57, 1034, 896, 1151, 9, 
+	32, 40, 41, 109, 2058, 2107, 2314, 2363, 
+	2570, 2619, 48, 57, 9, 32, 40, 41, 
+	109, 2058, 2107, 2314, 2363, 2570, 2619, 48, 
+	57, 9, 32, 40, 41, 2058, 2107, 2314, 
+	2363, 2570, 2619, 1034, 896, 1151, 9, 32, 
+	40, 41, 109, 2058, 2107, 2314, 2363, 2570, 
+	2619, 48, 57, 9, 32, 40, 41, 109, 
+	2058, 2107, 2314, 2363, 2570, 2619, 48, 57, 
+	9, 32, 40, 41, 2058, 2107, 2314, 2363, 
+	2570, 2619, 1034, 896, 1151, 9, 32, 40, 
+	41, 109, 2058, 2107, 2314, 2363, 2570, 2619, 
+	48, 57, 9, 32, 40, 41, 109, 2058, 
+	2107, 2314, 2363, 2570, 2619, 48, 57, 9, 
+	32, 40, 41, 2058, 2107, 2314, 2363, 2570, 
+	2619, 1034, 896, 1151, 9, 32, 40, 41, 
+	1034, 1083, 1034, 896, 1151, 9, 32, 40, 
+	41, 1034, 1083, 48, 57, 9, 32, 40, 
+	41, 1034, 1083, 48, 57, 1034, 896, 1151, 
+	1034, 896, 1151, 1034, 896, 1151, 9, 32, 
+	40, 41, 1034, 1083, 1034, 896, 1151, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 1034, 
+	896, 1151, 1034, 896, 1151, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 42, 92, 95, 1034, 1083, 
+	45, 57, 64, 90, 97, 122, 32, 59, 
+	9, 10, 40, 41, 1034, 896, 1151, 1034, 
+	896, 1151, 1034, 896, 1151, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, -128, 8, 11, 
+	58, 60, 127, 9, 32, 40, 41, 1034, 
+	1083, 9, 32, 40, 41, 1034, 1083, -128, 
+	8, 11, 58, 60, 127, 9, 32, 40, 
+	41, 1034, 1083, 9, 32, 40, 41, 1034, 
+	1083, -128, 8, 11, 58, 60, 127, 9, 
+	32, 40, 41, 1034, 1083, 9, 32, 40, 
+	41, 42, 92, 95, 1034, 1083, 45, 57, 
+	64, 90, 97, 122, 32, 59, 9, 10, 
+	40, 41, 1034, 896, 1151, 1034, 896, 1151, 
+	1034, 896, 1151, 1034, 896, 1151, 1034, 896, 
+	1151, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 43, 
+	1034, 1083, 47, 57, 65, 90, 97, 122, 
+	1546, 1595, 1034, 896, 1151, 1034, 896, 1151, 
+	1034, 896, 1151, 9, 32, 33, 40, 41, 
+	49, 50, 2058, 2107, 2314, 2363, 2570, 2619, 
+	49, 50, 58, 46, 48, 57, 47, 46, 
+	57, 48, 57, 9, 32, 40, 41, 2058, 
+	2107, 2314, 2363, 2570, 2619, 48, 57, 1034, 
+	896, 1151, 58, 46, 48, 58, 65, 70, 
+	97, 102, 47, 46, 58, 65, 70, 97, 
+	102, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 65, 70, 97, 102, 48, 
+	57, 65, 70, 97, 102, 9, 32, 40, 
+	41, 2058, 2107, 2314, 2363, 2570, 2619, 48, 
+	57, 65, 70, 97, 102, 1034, 896, 1151, 
+	1034, 896, 1151, 1034, 896, 1151, 1034, 896, 
+	1151, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 65, 70, 97, 102, 48, 
+	57, 65, 70, 97, 102, 9, 32, 40, 
+	41, 2058, 2107, 2314, 2363, 2570, 2619, 48, 
+	57, 65, 70, 97, 102, 1034, 896, 1151, 
+	1034, 896, 1151, 1034, 896, 1151, 48, 57, 
+	9, 32, 40, 41, 1034, 1083, 48, 57, 
+	9, 32, 40, 41, 48, 49, 50, 51, 
+	1034, 1083, 9, 32, 40, 41, 1034, 1083, 
+	9, 32, 40, 41, 1034, 1083, 48, 57, 
+	9, 32, 40, 41, 1034, 1083, 48, 57, 
+	9, 32, 40, 41, 46, 1034, 1083, 6153, 
+	6176, 6184, 6185, 6409, 6432, 6440, 6441, 6665, 
+	6688, 6696, 6697, 9482, 9531, 9738, 9787, 10250, 
+	10299, 10506, 10555, 10762, 10811, 11274, 11323, 11530, 
+	11579, 11786, 11835, 12298, 12347, 12554, 12603, 12810, 
+	12859, 3081, 3104, 3112, 3113, 3115, 4106, 4155, 
+	3119, 3129, 3137, 3162, 3169, 3194, 1546, 1595, 
+	4106, 3968, 4223, 4617, 4640, 4648, 4649, 13578, 
+	13627, 13834, 13883, 14346, 14395, 14602, 14651, 14858, 
+	14907, 5642, 5504, 5759, 3115, 6153, 6176, 6184, 
+	6185, 6409, 6432, 6440, 6441, 6665, 6688, 6696, 
+	6697, 9482, 9531, 9738, 9787, 10250, 10299, 10506, 
+	10555, 10762, 10811, 11274, 11323, 11530, 11579, 11786, 
+	11835, 12298, 12347, 12554, 12603, 12810, 12859, 3119, 
+	3129, 3137, 3162, 3169, 3194, 7690, 8202, 8714, 
+	7552, 7807, 8064, 8319, 8576, 8831, 1034, 896, 
+	1151, 1034, 896, 1151, 9, 32, 40, 41, 
+	1034, 1083, 9, 32, 40, 41, 1034, 1083, 
+	48, 57, 9, 32, 40, 41, 1034, 1083, 
+	48, 57, 9, 32, 40, 41, 46, 1034, 
+	1083, 48, 57, 46, 6153, 6176, 6184, 6185, 
+	6409, 6432, 6440, 6441, 6665, 6688, 6696, 6697, 
+	9482, 9531, 9738, 9787, 10250, 10299, 10506, 10555, 
+	10762, 10811, 11274, 11323, 11530, 11579, 11786, 11835, 
+	12298, 12347, 12554, 12603, 12810, 12859, 48, 57, 
+	1034, 896, 1151, 1034, 896, 1151, 9, 32, 
+	40, 41, 1034, 1083, 9, 32, 40, 41, 
+	1034, 1083, 48, 57, 9, 32, 40, 41, 
+	1034, 1083, 48, 57, 9, 32, 40, 41, 
+	46, 1034, 1083, 48, 58, 65, 70, 97, 
+	102, 46, 6153, 6176, 6184, 6185, 6409, 6432, 
+	6440, 6441, 6665, 6688, 6696, 6697, 9482, 9531, 
+	9738, 9787, 10250, 10299, 10506, 10555, 10762, 10811, 
+	11274, 11323, 11530, 11579, 11786, 11835, 12298, 12347, 
+	12554, 12603, 12810, 12859, 48, 58, 65, 70, 
+	97, 102, 1034, 896, 1151, 1034, 896, 1151, 
+	9, 32, 40, 41, 1034, 1083, 9, 32, 
+	40, 41, 1034, 1083, 48, 57, 9, 32, 
+	40, 41, 1034, 1083, 48, 57, 9, 32, 
+	40, 41, 42, 92, 95, 1034, 1083, 45, 
+	57, 64, 90, 97, 122, 6153, 6176, 6184, 
+	6185, 6409, 6432, 6440, 6441, 6665, 6688, 6696, 
+	6697, 9482, 9531, 9738, 9787, 10250, 10299, 10506, 
+	10555, 10762, 10811, 11274, 11323, 11530, 11579, 11786, 
+	11835, 12298, 12347, 12554, 12603, 12810, 12859, 1034, 
+	896, 1151, 1034, 896, 1151, 1034, 896, 1151, 
+	65, 67, 68, 72, 73, 75, 76, 77, 
+	78, 80, 82, 83, 84, 97, 99, 100, 
+	104, 105, 107, 108, 109, 110, 112, 114, 
+	115, 116, 9, 32, 40, 41, 65, 70, 
+	80, 97, 102, 112, 1034, 1083, 9, 32, 
+	40, 41, 1034, 1083, 48, 57, 9, 32, 
+	40, 41, 1034, 1083, 48, 57, 9, 32, 
+	40, 41, 1034, 1083, 48, 57, 9, 32, 
+	40, 41, 1034, 1083, 48, 57, 9, 32, 
+	40, 41, 1034, 1083, 48, 57, 9, 32, 
+	40, 41, 1034, 1083, 48, 57, 9, 32, 
+	40, 41, 1034, 1083, 48, 57, 9, 32, 
+	40, 41, 1034, 1083, 48, 57, 9, 32, 
+	40, 41, 1034, 1083, 48, 57, 9, 32, 
+	40, 41, 1034, 1083, 48, 57, 9, 32, 
+	40, 41, 1034, 1083, 48, 57, 9, 32, 
+	40, 41, 1034, 1083, 48, 57, 9, 32, 
+	40, 41, 42, 92, 95, 1034, 1083, 45, 
+	57, 64, 90, 97, 122, 9, 32, 40, 
+	41, 1034, 1083, 9, 32, 40, 41, 43, 
+	1034, 1083, 47, 57, 65, 90, 97, 122, 
+	1546, 1595, 1034, 896, 1151, 1034, 896, 1151, 
+	1034, 896, 1151, 1034, 896, 1151, 1034, 896, 
+	1151, 1034, 896, 1151, 1034, 896, 1151, 1034, 
+	896, 1151, 65, 97, 65, 97, 9, 32, 
+	40, 41, 1034, 1083, 83, 115, 68, 100, 
+	66, 98, 9, 32, 40, 41, 1034, 1083, 
+	76, 108, 9, 32, 40, 41, 1034, 1083, 
+	69, 78, 101, 110, 82, 114, 84, 116, 
+	9, 32, 40, 41, 1034, 1083, 65, 97, 
+	77, 109, 69, 101, 9, 32, 40, 41, 
+	1034, 1083, 72, 78, 83, 104, 110, 115, 
+	67, 99, 73, 105, 68, 100, 9, 32, 
+	40, 41, 1034, 1083, 65, 83, 97, 115, 
+	77, 109, 69, 101, 9, 32, 40, 41, 
+	1034, 1083, 75, 107, 69, 101, 89, 121, 
+	9, 32, 40, 41, 1034, 1083, 9, 32, 
+	40, 41, 1034, 1083, 73, 105, 78, 110, 
+	70, 102, 79, 111, 9, 32, 40, 41, 
+	1034, 1083, 80, 112, 83, 115, 69, 101, 
+	67, 99, 75, 107, 69, 101, 89, 121, 
+	9, 32, 40, 41, 1034, 1083, 69, 88, 
+	101, 120, 89, 121, 9, 32, 40, 41, 
+	1034, 1083, 9, 32, 40, 41, 1034, 1083, 
+	79, 111, 67, 99, 9, 32, 40, 41, 
+	1034, 1083, 73, 88, 105, 120, 78, 110, 
+	70, 102, 79, 111, 9, 32, 40, 41, 
+	1034, 1083, 9, 32, 40, 41, 1034, 1083, 
+	65, 83, 97, 115, 80, 112, 84, 116, 
+	82, 114, 9, 32, 40, 41, 1034, 1083, 
+	9, 32, 40, 41, 69, 101, 1034, 1083, 
+	67, 99, 9, 32, 40, 41, 51, 1034, 
+	1083, 9, 32, 40, 41, 80, 112, 1034, 
+	1083, 65, 97, 82, 114, 65, 97, 77, 
+	109, 9, 32, 40, 41, 1034, 1083, 84, 
+	116, 82, 114, 9, 32, 40, 41, 1034, 
+	1083, 80, 82, 84, 112, 114, 116, 9, 
+	32, 40, 41, 1034, 1083, 83, 115, 73, 
+	105, 71, 103, 9, 32, 40, 41, 1034, 
+	1083, 9, 32, 40, 41, 1034, 1083, 79, 
+	80, 82, 83, 111, 112, 114, 115, 65, 
+	97, 9, 32, 40, 41, 1034, 1083, 70, 
+	102, 9, 32, 40, 41, 1034, 1083, 86, 
+	118, 9, 32, 40, 41, 1034, 1083, 72, 
+	104, 70, 102, 80, 112, 9, 32, 40, 
+	41, 1034, 1083, 76, 88, 89, 108, 120, 
+	121, 83, 115, 65, 97, 9, 32, 40, 
+	41, 1034, 1083, 84, 116, 9, 32, 40, 
+	41, 1034, 1083, 80, 112, 69, 101, 48, 
+	57, 9, 32, 40, 41, 1034, 1083, 48, 
+	57, 42, 92, 95, 45, 57, 64, 90, 
+	97, 122, 32, 59, 9, 10, 40, 41, 
+	32, 59, 9, 10, 40, 41, 48, 57, 
+	9, 32, 40, 41, 1034, 1083, 48, 57, 
+	9, 32, 40, 41, 1034, 1083, 48, 57, 
+	9, 32, 40, 41, 1034, 1083, 48, 57, 
+	9, 32, 40, 41, 1034, 1083, 48, 57, 
+	9, 32, 40, 41, 1034, 1083, 48, 57, 
+	9, 32, 40, 41, 43, 1034, 1083, 47, 
+	57, 65, 90, 97, 122, 1546, 1595, 1034, 
+	896, 1151, 1034, 896, 1151, 1034, 896, 1151, 
+	43, 47, 57, 65, 90, 97, 122, 1546, 
+	1595, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 1034, 
+	1083, 48, 57, 9, 32, 40, 41, 45, 
+	1034, 1083, 48, 57, 65, 70, 97, 102, 
+	9, 32, 40, 41, 1034, 1083, 9, 32, 
+	40, 41, 1034, 1083, 48, 57, 65, 86, 
+	97, 118, 48, 57, 65, 86, 97, 118, 
+	61, 48, 57, 65, 86, 97, 118, 48, 
+	57, 65, 86, 97, 118, 61, 48, 57, 
+	65, 86, 97, 118, 61, 48, 57, 65, 
+	86, 97, 118, 48, 57, 65, 86, 97, 
+	118, 61, 48, 57, 65, 86, 97, 118, 
+	32, 59, 9, 10, 40, 41, 48, 57, 
+	65, 86, 97, 118, 32, 59, 9, 10, 
+	40, 41, 61, 61, 61, 61, 61, 1034, 
+	896, 1151, 48, 57, 65, 70, 97, 102, 
+	9, 32, 40, 41, 1034, 1083, 48, 57, 
+	65, 70, 97, 102, 1034, 896, 1151, 1034, 
+	896, 1151, 1034, 896, 1151, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 45, 1034, 1083, 48, 57, 
+	65, 70, 97, 102, 32, 59, 9, 10, 
+	40, 41, 48, 57, 65, 70, 97, 102, 
+	32, 59, 9, 10, 40, 41, 48, 57, 
+	65, 70, 97, 102, 1034, 896, 1151, 1034, 
+	896, 1151, 1034, 896, 1151, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 9, 
+	32, 40, 41, 1034, 1083, 48, 57, 65, 
+	70, 97, 102, 48, 57, 65, 70, 97, 
+	102, 9, 32, 40, 41, 2058, 2107, 2314, 
+	2363, 2570, 2619, 48, 57, 65, 70, 97, 
+	102, 1034, 896, 1151, 1034, 896, 1151, 1034, 
+	896, 1151, 1034, 896, 1151, 9, 32, 36, 
+	40, 41, 42, 92, 95, 778, 827, 1034, 
+	1083, 45, 57, 64, 90, 97, 122, 9, 
+	32, 36, 40, 41, 42, 58, 92, 95, 
+	1802, 1851, 2058, 2107, 2314, 2363, 2570, 2619, 
+	-128, 8, 11, 44, 45, 57, 60, 63, 
+	64, 90, 91, 96, 97, 122, 123, 127, 
+	9, 32, 36, 40, 41, 42, 65, 67, 
+	68, 72, 73, 75, 76, 77, 78, 80, 
+	82, 83, 84, 92, 95, 97, 99, 100, 
+	104, 105, 107, 108, 109, 110, 112, 114, 
+	115, 116, 778, 827, 1034, 1083, 45, 57, 
+	64, 90, 98, 122, 9, 32, 36, 40, 
+	41, 42, 65, 67, 68, 72, 73, 75, 
+	76, 77, 78, 80, 82, 83, 84, 92, 
+	95, 97, 99, 100, 104, 105, 107, 108, 
+	109, 110, 112, 114, 115, 116, 778, 827, 
+	1034, 1083, 45, 47, 48, 57, 64, 90, 
+	98, 122, 9, 32, 36, 40, 41, 42, 
+	92, 95, 778, 827, 1034, 1083, 45, 57, 
+	64, 90, 97, 122, 9, 32, 36, 40, 
+	41, 42, 65, 67, 68, 72, 73, 75, 
+	76, 77, 78, 80, 82, 83, 84, 92, 
+	95, 97, 99, 100, 104, 105, 107, 108, 
+	109, 110, 112, 114, 115, 116, 778, 827, 
+	1034, 1083, 45, 47, 48, 57, 64, 90, 
+	98, 122, 9, 32, 36, 40, 41, 42, 
+	92, 95, 778, 827, 1034, 1083, 45, 57, 
+	64, 90, 97, 122, 9, 32, 36, 40, 
+	41, 42, 58, 92, 95, 1802, 1851, 2058, 
+	2107, 2314, 2363, 2570, 2619, -128, 8, 11, 
+	44, 45, 57, 60, 63, 64, 90, 91, 
+	96, 97, 122, 123, 127, 9, 32, 36, 
+	40, 41, 42, 58, 65, 67, 68, 72, 
+	73, 75, 76, 77, 78, 80, 82, 83, 
+	84, 92, 95, 97, 99, 100, 104, 105, 
+	107, 108, 109, 110, 112, 114, 115, 116, 
+	1802, 1851, 2058, 2107, 2314, 2363, 2570, 2619, 
+	-128, 8, 11, 44, 45, 47, 48, 57, 
+	60, 63, 64, 90, 91, 96, 98, 122, 
+	123, 127, 9, 32, 36, 40, 41, 42, 
+	58, 65, 67, 68, 72, 73, 75, 76, 
+	77, 78, 80, 82, 83, 84, 92, 95, 
+	97, 99, 100, 104, 105, 107, 108, 109, 
+	110, 112, 114, 115, 116, 1802, 1851, 2058, 
+	2107, 2314, 2363, 2570, 2619, -128, 8, 11, 
+	44, 45, 47, 48, 57, 60, 63, 64, 
+	90, 91, 96, 98, 122, 123, 127, 32, 
+	33, 59, 92, 9, 10, 35, 39, 40, 
+	41, 42, 126, 9, 32, 40, 41, 42, 
+	46, 92, 95, 1034, 1083, 45, 57, 65, 
+	90, 97, 122, 9, 32, 40, 41, 43, 
+	2058, 2107, 2314, 2363, 2570, 2619, 47, 57, 
+	65, 90, 97, 122, 1034, 896, 1151, 9, 
+	32, 40, 41, 65, 67, 68, 72, 73, 
+	75, 76, 77, 78, 80, 82, 83, 84, 
+	97, 99, 100, 104, 105, 107, 108, 109, 
+	110, 112, 114, 115, 116, 2058, 2107, 2314, 
+	2363, 2570, 2619, 1034, 896, 1151, 9, 32, 
+	40, 41, 2058, 2107, 2314, 2363, 2570, 2619, 
+	48, 57, 65, 70, 97, 102, 1034, 896, 
+	1151, 9, 32, 40, 41, 1034, 1083, 48, 
+	57, 65, 70, 97, 102, 9, 32, 40, 
+	41, 2058, 2107, 2314, 2363, 2570, 2619, 48, 
+	57, 65, 70, 97, 102, 1034, 896, 1151, 
+	1034, 896, 1151, 9, 32, 40, 41, 2058, 
+	2107, 2314, 2363, 2570, 2619, -128, 8, 11, 
+	58, 60, 127, 1034, 896, 1151, 9, 32, 
+	40, 41, 2058, 2107, 2314, 2363, 2570, 2619, 
+	1034, 896, 1151, 9, 32, 40, 41, 2058, 
+	2107, 2314, 2363, 2570, 2619, 48, 57, 1034, 
+	896, 1151, 9, 32, 40, 41, 2058, 2107, 
+	2314, 2363, 2570, 2619, 48, 57, 1034, 896, 
+	1151, 9, 32, 40, 41, 2058, 2107, 2314, 
+	2363, 2570, 2619, 48, 57, 1034, 896, 1151, 
+	9, 32, 33, 40, 41, 49, 50, 2058, 
+	2107, 2314, 2363, 2570, 2619, 1034, 896, 1151, 
+	9, 32, 40, 41, 2058, 2107, 2314, 2363, 
+	2570, 2619, 48, 57, 65, 70, 97, 102, 
+	1034, 896, 1151, 9, 32, 40, 41, 2058, 
+	2107, 2314, 2363, 2570, 2619, 48, 57, 65, 
+	70, 97, 102, 1034, 896, 1151, 4617, 4640, 
+	4648, 4649, 13578, 13627, 13834, 13883, 14346, 14395, 
+	14602, 14651, 14858, 14907, 5642, 5504, 5759, 3081, 
+	3104, 3112, 3113, 3115, 4106, 4155, 3119, 3129, 
+	3137, 3162, 3169, 3194, 4106, 3968, 4223, 3115, 
+	6153, 6176, 6184, 6185, 6409, 6432, 6440, 6441, 
+	6665, 6688, 6696, 6697, 9482, 9531, 9738, 9787, 
+	10250, 10299, 10506, 10555, 10762, 10811, 11274, 11323, 
+	11530, 11579, 11786, 11835, 12298, 12347, 12554, 12603, 
+	12810, 12859, 3119, 3129, 3137, 3162, 3169, 3194, 
+	7690, 8202, 8714, 7552, 7807, 8064, 8319, 8576, 
+	8831, 9, 32, 40, 41, 2058, 2107, 2314, 
+	2363, 2570, 2619, 48, 57, 65, 70, 97, 
+	102, 1034, 896, 1151, 0
+};
+
+static const char _zone_scanner_single_lengths[] = {
+	0, 34, 16, 32, 16, 11, 8, 8, 
+	1, 1, 8, 1, 13, 2, 40, 18, 
+	34, 4, 2, 2, 10, 12, 2, 2, 
+	2, 10, 6, 2, 2, 2, 10, 4, 
+	2, 2, 10, 2, 2, 2, 10, 10, 
+	2, 2, 2, 2, 10, 4, 6, 32, 
+	2, 2, 2, 2, 2, 2, 2, 10, 
+	4, 2, 10, 10, 2, 2, 10, 4, 
+	2, 2, 2, 10, 10, 4, 2, 2, 
+	2, 10, 12, 2, 11, 12, 2, 2, 
+	2, 2, 10, 2, 2, 10, 6, 10, 
+	2, 2, 2, 10, 10, 8, 2, 10, 
+	2, 10, 2, 10, 2, 2, 2, 10, 
+	6, 2, 2, 10, 2, 10, 2, 2, 
+	0, 10, 1, 34, 4, 6, 32, 16, 
+	6, 10, 6, 1, 1, 6, 2, 2, 
+	2, 2, 2, 2, 2, 6, 32, 1, 
+	16, 32, 1, 6, 10, 6, 1, 16, 
+	38, 18, 13, 34, 2, 8, 8, 40, 
+	12, 14, 10, 12, 12, 10, 12, 12, 
+	10, 14, 16, 14, 2, 14, 2, 2, 
+	2, 2, 2, 2, 2, 2, 2, 8, 
+	18, 34, 2, 18, 40, 12, 14, 10, 
+	12, 12, 10, 12, 12, 10, 14, 16, 
+	14, 9, 34, 12, 12, 10, 2, 2, 
+	10, 2, 2, 2, 10, 2, 10, 2, 
+	8, 8, 12, 10, 1, 12, 10, 12, 
+	8, 10, 10, 8, 10, 10, 8, 12, 
+	14, 12, 2, 2, 10, 2, 1, 1, 
+	5, 3, 6, 5, 0, 0, 0, 5, 
+	2, 2, 2, 4, 0, 0, 0, 4, 
+	4, 2, 0, 0, 0, 4, 6, 6, 
+	18, 8, 1, 8, 10, 8, 1, 6, 
+	10, 1, 12, 8, 1, 3, 0, 0, 
+	0, 3, 8, 1, 6, 6, 8, 12, 
+	1, 12, 8, 1, 3, 0, 0, 0, 
+	3, 8, 2, 10, 1, 1, 1, 1, 
+	2, 2, 11, 1, 1, 10, 36, 16, 
+	2, 2, 10, 1, 4, 2, 2, 10, 
+	2, 2, 2, 10, 6, 2, 2, 2, 
+	10, 4, 2, 2, 10, 2, 2, 2, 
+	10, 10, 2, 2, 2, 2, 10, 2, 
+	2, 2, 2, 2, 2, 2, 10, 4, 
+	2, 10, 10, 2, 2, 10, 4, 2, 
+	2, 2, 10, 10, 4, 2, 2, 2, 
+	10, 12, 2, 11, 12, 2, 2, 2, 
+	2, 10, 2, 2, 10, 6, 10, 2, 
+	2, 2, 10, 10, 8, 2, 10, 2, 
+	10, 2, 10, 2, 2, 2, 10, 6, 
+	2, 2, 10, 2, 10, 2, 2, 0, 
+	10, 2, 2, 2, 10, 2, 10, 6, 
+	6, 6, 6, 0, 10, 1, 1, 1, 
+	6, 7, 8, 6, 0, 10, 1, 1, 
+	6, 1, 1, 3, 3, 2, 3, 6, 
+	9, 6, 6, 6, 6, 16, 6, 16, 
+	6, 16, 6, 12, 2, 10, 2, 1, 
+	6, 10, 6, 1, 6, 10, 6, 1, 
+	6, 10, 6, 1, 1, 1, 2, 6, 
+	6, 2, 1, 3, 6, 9, 2, 1, 
+	0, 6, 9, 2, 1, 2, 10, 10, 
+	1, 1, 3, 0, 6, 8, 6, 8, 
+	7, 8, 6, 6, 6, 8, 6, 8, 
+	7, 8, 6, 7, 0, 12, 10, 12, 
+	10, 12, 10, 12, 10, 1, 11, 11, 
+	1, 11, 11, 10, 1, 11, 11, 10, 
+	1, 11, 11, 10, 1, 6, 1, 6, 
+	6, 1, 1, 1, 6, 1, 6, 6, 
+	1, 1, 0, 6, 6, 6, 6, 6, 
+	9, 2, 1, 1, 1, 0, 6, 6, 
+	6, 6, 6, 6, 6, 6, 6, 9, 
+	2, 1, 1, 1, 1, 1, 0, 6, 
+	6, 6, 6, 6, 7, 2, 1, 1, 
+	1, 13, 2, 1, 1, 1, 0, 10, 
+	1, 1, 1, 1, 0, 6, 6, 6, 
+	6, 6, 6, 0, 10, 1, 1, 1, 
+	1, 0, 6, 6, 6, 6, 0, 10, 
+	1, 1, 1, 0, 6, 10, 6, 6, 
+	6, 7, 34, 7, 2, 1, 14, 1, 
+	35, 3, 1, 1, 6, 6, 6, 7, 
+	35, 1, 1, 6, 6, 6, 7, 35, 
+	1, 1, 6, 6, 6, 9, 34, 1, 
+	1, 1, 26, 12, 6, 6, 6, 6, 
+	6, 6, 6, 6, 6, 6, 6, 6, 
+	9, 6, 7, 2, 1, 1, 1, 1, 
+	1, 1, 1, 1, 2, 2, 6, 2, 
+	2, 2, 6, 2, 6, 4, 2, 2, 
+	6, 2, 2, 2, 6, 6, 2, 2, 
+	2, 6, 4, 2, 2, 6, 2, 2, 
+	2, 6, 6, 2, 2, 2, 2, 6, 
+	2, 2, 2, 2, 2, 2, 2, 6, 
+	4, 2, 6, 6, 2, 2, 6, 4, 
+	2, 2, 2, 6, 6, 4, 2, 2, 
+	2, 6, 8, 2, 7, 8, 2, 2, 
+	2, 2, 6, 2, 2, 6, 6, 6, 
+	2, 2, 2, 6, 6, 8, 2, 6, 
+	2, 6, 2, 6, 2, 2, 2, 6, 
+	6, 2, 2, 6, 2, 6, 2, 2, 
+	0, 6, 3, 2, 2, 0, 6, 6, 
+	6, 6, 6, 7, 2, 1, 1, 1, 
+	1, 2, 0, 6, 6, 6, 6, 6, 
+	7, 6, 6, 0, 1, 0, 1, 1, 
+	0, 1, 2, 2, 1, 1, 1, 1, 
+	1, 1, 0, 6, 1, 1, 1, 0, 
+	6, 6, 6, 6, 6, 7, 2, 0, 
+	2, 1, 1, 1, 0, 6, 6, 6, 
+	6, 6, 6, 0, 10, 1, 1, 1, 
+	1, 12, 17, 38, 38, 12, 38, 12, 
+	17, 43, 43, 0, 0, 0, 4, 0, 
+	0, 0, 10, 0, 11, 1, 0, 36, 
+	1, 0, 10, 1, 6, 0, 10, 1, 
+	1, 0, 0, 0, 0, 0, 0, 0, 
+	10, 1, 0, 0, 10, 1, 10, 1, 
+	10, 1, 10, 1, 0, 0, 0, 0, 
+	13, 1, 0, 10, 1, 0, 10, 1, 
+	0, 14, 1, 7, 1, 35, 3, 0, 
+	0, 0, 0, 0, 0, 0, 10, 1
+};
+
+static const char _zone_scanner_range_lengths[] = {
+	0, 1, 1, 0, 0, 3, 0, 0, 
+	0, 0, 0, 1, 3, 2, 4, 1, 
+	0, 0, 0, 0, 0, 1, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	1, 1, 1, 1, 0, 0, 1, 1, 
+	1, 1, 1, 1, 0, 0, 0, 0, 
+	0, 0, 0, 0, 2, 0, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 0, 
+	4, 0, 3, 1, 2, 3, 3, 4, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 2, 0, 0, 0, 
+	0, 0, 0, 2, 0, 0, 2, 0, 
+	1, 1, 2, 0, 4, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 3, 1, 1, 1, 2, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 2, 
+	3, 3, 2, 2, 1, 1, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 2, 2, 0, 2, 0, 0, 
+	3, 2, 5, 5, 1, 1, 1, 5, 
+	2, 2, 2, 4, 1, 1, 1, 4, 
+	1, 2, 1, 1, 1, 1, 0, 1, 
+	1, 0, 0, 1, 1, 1, 1, 0, 
+	3, 0, 3, 0, 0, 3, 1, 1, 
+	1, 3, 0, 1, 0, 3, 0, 3, 
+	0, 3, 0, 0, 3, 1, 1, 1, 
+	3, 0, 2, 3, 1, 1, 3, 3, 
+	3, 3, 3, 1, 0, 0, 0, 0, 
+	0, 0, 0, 1, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 1, 
+	1, 0, 0, 0, 0, 0, 0, 0, 
+	1, 1, 3, 3, 3, 1, 1, 1, 
+	0, 1, 1, 3, 3, 3, 1, 1, 
+	1, 1, 1, 3, 3, 2, 3, 0, 
+	3, 0, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 3, 3, 1, 3, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 2, 0, 
+	3, 2, 1, 3, 0, 3, 2, 1, 
+	1, 1, 3, 2, 1, 2, 0, 3, 
+	1, 3, 5, 1, 1, 1, 1, 1, 
+	1, 0, 0, 1, 1, 1, 1, 1, 
+	1, 0, 0, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 0, 1, 1, 1, 
+	1, 1, 1, 0, 1, 1, 1, 0, 
+	1, 1, 1, 0, 1, 0, 1, 1, 
+	1, 1, 1, 1, 0, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	3, 2, 1, 1, 1, 1, 1, 1, 
+	1, 3, 0, 3, 0, 3, 0, 3, 
+	2, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 3, 0, 1, 1, 
+	1, 0, 0, 0, 1, 1, 1, 1, 
+	1, 0, 3, 3, 1, 1, 1, 1, 
+	1, 1, 3, 3, 3, 1, 1, 1, 
+	1, 1, 1, 1, 1, 3, 3, 3, 
+	1, 1, 1, 1, 1, 0, 0, 1, 
+	1, 0, 0, 3, 0, 1, 0, 1, 
+	3, 3, 1, 1, 0, 1, 1, 1, 
+	1, 1, 1, 0, 1, 1, 3, 3, 
+	1, 1, 0, 1, 1, 3, 0, 1, 
+	1, 1, 0, 0, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	3, 0, 3, 0, 1, 1, 1, 1, 
+	1, 1, 1, 1, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	1, 1, 3, 2, 2, 1, 1, 1, 
+	1, 1, 1, 3, 0, 1, 1, 1, 
+	3, 0, 1, 1, 1, 1, 1, 1, 
+	3, 0, 3, 3, 3, 3, 3, 3, 
+	3, 3, 5, 2, 0, 0, 0, 0, 
+	0, 1, 3, 3, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 3, 2, 3, 
+	5, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 3, 3, 3, 1, 1, 1, 
+	1, 3, 8, 3, 4, 3, 4, 3, 
+	8, 9, 9, 0, 0, 0, 4, 0, 
+	0, 0, 3, 0, 3, 1, 0, 0, 
+	1, 0, 3, 1, 3, 0, 3, 1, 
+	1, 0, 0, 0, 0, 0, 0, 0, 
+	3, 1, 0, 0, 0, 1, 1, 1, 
+	1, 1, 1, 1, 0, 0, 0, 0, 
+	0, 1, 0, 3, 1, 0, 3, 1, 
+	0, 0, 1, 3, 1, 3, 3, 0, 
+	0, 0, 0, 0, 0, 0, 3, 1
+};
+
+static const short _zone_scanner_index_offsets[] = {
+	0, 0, 36, 54, 87, 104, 119, 128, 
+	137, 139, 141, 150, 153, 170, 175, 220, 
+	240, 275, 280, 283, 286, 297, 311, 314, 
+	317, 320, 331, 338, 341, 344, 347, 358, 
+	363, 366, 369, 380, 383, 386, 389, 400, 
+	411, 414, 417, 420, 423, 434, 439, 446, 
+	479, 482, 485, 488, 491, 494, 497, 500, 
+	511, 516, 519, 530, 541, 544, 547, 558, 
+	563, 566, 569, 572, 583, 594, 599, 602, 
+	605, 608, 619, 632, 635, 647, 660, 663, 
+	666, 669, 672, 683, 686, 689, 700, 707, 
+	718, 721, 724, 727, 738, 749, 758, 761, 
+	772, 775, 786, 789, 800, 803, 806, 809, 
+	820, 827, 830, 833, 844, 847, 858, 861, 
+	864, 866, 878, 881, 917, 922, 929, 963, 
+	981, 989, 1001, 1009, 1012, 1014, 1021, 1024, 
+	1027, 1030, 1033, 1036, 1039, 1044, 1051, 1085, 
+	1088, 1106, 1140, 1143, 1151, 1163, 1171, 1174, 
+	1191, 1234, 1253, 1270, 1306, 1311, 1323, 1335, 
+	1380, 1393, 1408, 1419, 1432, 1445, 1456, 1469, 
+	1482, 1493, 1508, 1525, 1540, 1545, 1560, 1563, 
+	1566, 1569, 1572, 1575, 1580, 1583, 1586, 1591, 
+	1600, 1620, 1656, 1661, 1680, 1725, 1738, 1753, 
+	1764, 1777, 1790, 1801, 1814, 1827, 1838, 1853, 
+	1870, 1885, 1898, 1934, 1948, 1962, 1975, 1978, 
+	1981, 1992, 1995, 1998, 2001, 2012, 2015, 2026, 
+	2031, 2043, 2055, 2070, 2083, 2086, 2100, 2111, 
+	2124, 2133, 2144, 2155, 2164, 2175, 2186, 2195, 
+	2208, 2223, 2236, 2241, 2246, 2257, 2262, 2264, 
+	2266, 2275, 2281, 2293, 2304, 2306, 2308, 2310, 
+	2321, 2326, 2331, 2336, 2345, 2347, 2349, 2351, 
+	2360, 2366, 2371, 2373, 2375, 2377, 2383, 2390, 
+	2398, 2418, 2427, 2429, 2439, 2451, 2461, 2464, 
+	2471, 2485, 2487, 2503, 2512, 2514, 2521, 2523, 
+	2525, 2527, 2534, 2543, 2546, 2553, 2563, 2572, 
+	2588, 2590, 2606, 2615, 2617, 2624, 2626, 2628, 
+	2630, 2637, 2646, 2651, 2665, 2668, 2671, 2676, 
+	2681, 2687, 2693, 2708, 2711, 2713, 2724, 2761, 
+	2778, 2781, 2784, 2795, 2798, 2803, 2806, 2809, 
+	2820, 2823, 2826, 2829, 2840, 2847, 2850, 2853, 
+	2856, 2867, 2872, 2875, 2878, 2889, 2892, 2895, 
+	2898, 2909, 2920, 2923, 2926, 2929, 2932, 2943, 
+	2946, 2949, 2952, 2955, 2958, 2961, 2964, 2975, 
+	2980, 2983, 2994, 3005, 3008, 3011, 3022, 3027, 
+	3030, 3033, 3036, 3047, 3058, 3063, 3066, 3069, 
+	3072, 3083, 3096, 3099, 3111, 3124, 3127, 3130, 
+	3133, 3136, 3147, 3150, 3153, 3164, 3171, 3182, 
+	3185, 3188, 3191, 3202, 3213, 3222, 3225, 3236, 
+	3239, 3250, 3253, 3264, 3267, 3270, 3273, 3284, 
+	3291, 3294, 3297, 3308, 3311, 3322, 3325, 3328, 
+	3330, 3342, 3345, 3348, 3351, 3362, 3365, 3376, 
+	3383, 3391, 3399, 3409, 3413, 3427, 3430, 3433, 
+	3436, 3443, 3452, 3462, 3472, 3476, 3490, 3493, 
+	3496, 3504, 3507, 3510, 3517, 3524, 3529, 3536, 
+	3543, 3556, 3563, 3571, 3579, 3587, 3605, 3613, 
+	3631, 3639, 3657, 3665, 3681, 3687, 3699, 3705, 
+	3708, 3716, 3728, 3736, 3739, 3747, 3759, 3767, 
+	3770, 3778, 3790, 3798, 3801, 3804, 3807, 3812, 
+	3819, 3829, 3834, 3837, 3844, 3851, 3864, 3869, 
+	3872, 3874, 3882, 3895, 3900, 3903, 3908, 3919, 
+	3933, 3936, 3941, 3950, 3952, 3960, 3970, 3978, 
+	3988, 3997, 4006, 4013, 4021, 4029, 4039, 4047, 
+	4057, 4066, 4075, 4082, 4091, 4093, 4107, 4119, 
+	4133, 4145, 4159, 4171, 4185, 4196, 4199, 4212, 
+	4225, 4228, 4241, 4254, 4265, 4268, 4281, 4294, 
+	4305, 4308, 4321, 4334, 4345, 4348, 4355, 4358, 
+	4366, 4374, 4377, 4380, 4383, 4390, 4393, 4401, 
+	4409, 4412, 4415, 4417, 4425, 4433, 4441, 4449, 
+	4457, 4470, 4475, 4478, 4481, 4484, 4486, 4494, 
+	4502, 4510, 4520, 4527, 4537, 4544, 4554, 4561, 
+	4574, 4579, 4582, 4585, 4588, 4591, 4594, 4596, 
+	4604, 4612, 4620, 4628, 4636, 4647, 4650, 4653, 
+	4656, 4659, 4673, 4676, 4678, 4681, 4684, 4686, 
+	4698, 4701, 4703, 4708, 4713, 4715, 4723, 4731, 
+	4739, 4747, 4755, 4765, 4769, 4783, 4786, 4789, 
+	4792, 4795, 4797, 4805, 4813, 4821, 4831, 4835, 
+	4849, 4852, 4855, 4858, 4860, 4868, 4879, 4886, 
+	4894, 4902, 4910, 4945, 4956, 4959, 4962, 4977, 
+	4980, 5019, 5026, 5029, 5032, 5039, 5047, 5055, 
+	5064, 5101, 5104, 5107, 5114, 5122, 5130, 5141, 
+	5180, 5183, 5186, 5193, 5201, 5209, 5222, 5257, 
+	5260, 5263, 5266, 5293, 5306, 5314, 5322, 5330, 
+	5338, 5346, 5354, 5362, 5370, 5378, 5386, 5394, 
+	5402, 5415, 5422, 5433, 5436, 5439, 5442, 5445, 
+	5448, 5451, 5454, 5457, 5460, 5463, 5466, 5473, 
+	5476, 5479, 5482, 5489, 5492, 5499, 5504, 5507, 
+	5510, 5517, 5520, 5523, 5526, 5533, 5540, 5543, 
+	5546, 5549, 5556, 5561, 5564, 5567, 5574, 5577, 
+	5580, 5583, 5590, 5597, 5600, 5603, 5606, 5609, 
+	5616, 5619, 5622, 5625, 5628, 5631, 5634, 5637, 
+	5644, 5649, 5652, 5659, 5666, 5669, 5672, 5679, 
+	5684, 5687, 5690, 5693, 5700, 5707, 5712, 5715, 
+	5718, 5721, 5728, 5737, 5740, 5748, 5757, 5760, 
+	5763, 5766, 5769, 5776, 5779, 5782, 5789, 5796, 
+	5803, 5806, 5809, 5812, 5819, 5826, 5835, 5838, 
+	5845, 5848, 5855, 5858, 5865, 5868, 5871, 5874, 
+	5881, 5888, 5891, 5894, 5901, 5904, 5911, 5914, 
+	5917, 5919, 5927, 5934, 5939, 5944, 5946, 5954, 
+	5962, 5970, 5978, 5986, 5997, 6000, 6003, 6006, 
+	6009, 6014, 6017, 6019, 6027, 6035, 6043, 6051, 
+	6059, 6070, 6077, 6087, 6091, 6096, 6100, 6105, 
+	6110, 6114, 6119, 6127, 6132, 6134, 6136, 6138, 
+	6140, 6142, 6145, 6149, 6159, 6162, 6165, 6168, 
+	6170, 6178, 6186, 6194, 6202, 6210, 6221, 6226, 
+	6230, 6238, 6241, 6244, 6247, 6249, 6257, 6265, 
+	6273, 6281, 6289, 6299, 6303, 6317, 6320, 6323, 
+	6326, 6329, 6345, 6371, 6413, 6456, 6472, 6515, 
+	6531, 6557, 6610, 6663, 6664, 6665, 6666, 6675, 
+	6676, 6677, 6678, 6692, 6693, 6708, 6711, 6712, 
+	6749, 6752, 6753, 6767, 6770, 6780, 6781, 6795, 
+	6798, 6801, 6802, 6803, 6804, 6805, 6806, 6807, 
+	6808, 6822, 6825, 6826, 6827, 6838, 6841, 6853, 
+	6856, 6868, 6871, 6883, 6886, 6887, 6888, 6889, 
+	6890, 6904, 6907, 6908, 6922, 6925, 6926, 6940, 
+	6943, 6944, 6959, 6962, 6973, 6976, 7015, 7022, 
+	7023, 7024, 7025, 7026, 7027, 7028, 7029, 7043
+};
+
+static const short _zone_scanner_indicies[] = {
+	1, 1, 2, 3, 5, 6, 7, 8, 
+	9, 10, 11, 12, 13, 14, 15, 16, 
+	17, 5, 6, 7, 8, 9, 10, 11, 
+	12, 13, 14, 15, 16, 17, 18, 19, 
+	20, 21, 4, 0, 23, 23, 24, 25, 
+	27, 28, 29, 30, 31, 27, 28, 29, 
+	30, 31, 32, 33, 26, 22, 35, 35, 
+	36, 37, 38, 39, 40, 41, 42, 43, 
+	44, 45, 46, 47, 48, 49, 50, 38, 
+	39, 40, 41, 42, 43, 44, 45, 46, 
+	47, 48, 49, 50, 51, 52, 34, 54, 
+	54, 55, 56, 57, 58, 59, 57, 58, 
+	59, 60, 61, 62, 62, 63, 64, 53, 
+	66, 66, 68, 69, 70, 71, 72, 73, 
+	73, 74, 75, 65, 65, 65, 67, 77, 
+	77, 78, 79, 80, 81, 80, 81, 76, 
+	83, 83, 84, 85, 86, 87, 86, 87, 
+	82, 86, 87, 89, 88, 83, 83, 84, 
+	85, 86, 87, 86, 87, 76, 71, 72, 
+	67, 90, 90, 91, 92, 70, 86, 87, 
+	86, 93, 94, 95, 86, 96, 65, 65, 
+	65, 76, 86, 97, 87, 93, 76, 98, 
+	98, 100, 101, 65, 103, 104, 105, 106, 
+	107, 108, 109, 110, 111, 112, 113, 114, 
+	115, 70, 103, 104, 105, 106, 107, 108, 
+	109, 110, 111, 112, 113, 114, 115, 18, 
+	19, 116, 117, 118, 119, 120, 121, 65, 
+	65, 102, 65, 99, 123, 123, 124, 125, 
+	27, 28, 29, 30, 31, 27, 28, 29, 
+	30, 31, 80, 81, 126, 127, 26, 122, 
+	129, 129, 130, 131, 38, 39, 40, 41, 
+	42, 43, 44, 45, 46, 47, 48, 49, 
+	50, 38, 39, 40, 41, 42, 43, 44, 
+	45, 46, 47, 48, 49, 50, 86, 87, 
+	132, 133, 128, 134, 135, 134, 135, 34, 
+	136, 136, 34, 137, 137, 34, 138, 138, 
+	139, 140, 141, 142, 143, 143, 144, 145, 
+	53, 83, 86, 83, 84, 85, 87, 146, 
+	86, 146, 147, 148, 93, 72, 76, 149, 
+	149, 34, 150, 150, 34, 151, 151, 34, 
+	152, 152, 153, 154, 155, 156, 157, 157, 
+	158, 159, 53, 160, 161, 162, 160, 161, 
+	162, 34, 163, 163, 34, 164, 164, 34, 
+	165, 165, 34, 166, 166, 167, 168, 169, 
+	170, 171, 171, 172, 173, 53, 174, 175, 
+	174, 175, 34, 176, 176, 34, 177, 177, 
+	34, 178, 178, 179, 180, 181, 182, 183, 
+	183, 184, 185, 53, 186, 186, 34, 187, 
+	187, 34, 188, 188, 34, 189, 189, 190, 
+	191, 192, 193, 194, 194, 195, 196, 53, 
+	197, 197, 198, 199, 200, 201, 202, 202, 
+	203, 204, 53, 205, 205, 34, 206, 206, 
+	34, 207, 207, 34, 208, 208, 34, 209, 
+	209, 210, 211, 212, 213, 214, 214, 215, 
+	216, 53, 217, 218, 217, 218, 34, 219, 
+	219, 220, 221, 222, 223, 34, 224, 224, 
+	225, 226, 227, 228, 229, 230, 231, 232, 
+	233, 234, 235, 236, 237, 238, 239, 227, 
+	228, 229, 230, 231, 232, 233, 234, 235, 
+	236, 237, 238, 239, 240, 241, 34, 218, 
+	218, 34, 242, 242, 34, 243, 243, 34, 
+	244, 244, 34, 245, 245, 34, 246, 246, 
+	34, 247, 247, 34, 248, 248, 249, 250, 
+	251, 252, 253, 253, 254, 255, 53, 256, 
+	257, 256, 257, 34, 258, 258, 34, 259, 
+	259, 260, 261, 262, 263, 264, 264, 265, 
+	266, 53, 267, 267, 268, 269, 270, 271, 
+	272, 272, 273, 274, 53, 275, 275, 34, 
+	276, 276, 34, 277, 277, 278, 279, 280, 
+	281, 282, 282, 283, 284, 53, 285, 286, 
+	285, 286, 34, 287, 287, 34, 288, 288, 
+	34, 289, 289, 34, 290, 290, 291, 292, 
+	293, 294, 295, 295, 296, 297, 53, 298, 
+	298, 299, 300, 301, 302, 303, 303, 304, 
+	305, 53, 306, 307, 306, 307, 34, 308, 
+	308, 34, 309, 309, 34, 310, 310, 34, 
+	311, 311, 312, 313, 314, 315, 316, 316, 
+	317, 318, 53, 319, 319, 320, 321, 322, 
+	322, 323, 324, 325, 325, 326, 327, 53, 
+	328, 328, 34, 329, 329, 330, 331, 332, 
+	333, 334, 335, 335, 336, 337, 53, 338, 
+	338, 339, 340, 341, 341, 342, 343, 344, 
+	344, 345, 346, 53, 347, 347, 34, 348, 
+	348, 34, 349, 349, 34, 350, 350, 34, 
+	351, 351, 352, 353, 354, 355, 356, 356, 
+	357, 358, 53, 359, 359, 34, 360, 360, 
+	34, 361, 361, 362, 363, 364, 365, 366, 
+	366, 367, 368, 53, 369, 370, 371, 369, 
+	370, 371, 34, 372, 372, 373, 374, 375, 
+	376, 377, 377, 378, 379, 53, 380, 380, 
+	34, 381, 381, 34, 382, 382, 34, 383, 
+	383, 384, 385, 386, 387, 388, 388, 389, 
+	390, 53, 391, 391, 392, 393, 394, 395, 
+	396, 396, 397, 398, 53, 399, 400, 401, 
+	402, 399, 400, 401, 402, 34, 403, 403, 
+	34, 404, 404, 405, 406, 407, 408, 409, 
+	409, 410, 411, 53, 412, 412, 34, 413, 
+	413, 414, 415, 416, 417, 418, 418, 419, 
+	420, 53, 421, 421, 34, 422, 422, 423, 
+	424, 425, 426, 427, 427, 428, 429, 53, 
+	430, 430, 34, 431, 431, 34, 432, 432, 
+	34, 433, 433, 434, 435, 436, 437, 438, 
+	438, 439, 440, 53, 441, 442, 443, 441, 
+	442, 443, 34, 444, 444, 34, 445, 445, 
+	34, 446, 446, 447, 448, 449, 450, 451, 
+	451, 452, 453, 53, 454, 454, 34, 455, 
+	455, 456, 457, 458, 459, 460, 460, 461, 
+	462, 53, 463, 463, 34, 464, 464, 34, 
+	466, 465, 468, 468, 469, 470, 472, 473, 
+	474, 474, 475, 476, 471, 467, 240, 241, 
+	34, 477, 477, 478, 479, 5, 6, 7, 
+	8, 9, 10, 11, 12, 13, 14, 15, 
+	16, 17, 5, 6, 7, 8, 9, 10, 
+	11, 12, 13, 14, 15, 16, 17, 18, 
+	19, 480, 481, 4, 0, 482, 218, 482, 
+	218, 34, 483, 483, 484, 485, 486, 487, 
+	34, 488, 488, 489, 490, 492, 493, 494, 
+	495, 496, 497, 498, 499, 500, 501, 502, 
+	503, 504, 492, 493, 494, 495, 496, 497, 
+	498, 499, 500, 501, 502, 503, 504, 505, 
+	506, 491, 465, 507, 507, 508, 509, 511, 
+	512, 513, 514, 515, 511, 512, 513, 514, 
+	515, 516, 517, 510, 22, 507, 507, 508, 
+	509, 516, 517, 518, 22, 520, 521, 522, 
+	523, 524, 520, 521, 522, 523, 524, 519, 
+	22, 525, 525, 526, 527, 529, 530, 528, 
+	22, 505, 506, 34, 18, 19, 532, 533, 
+	534, 532, 533, 534, 531, 535, 535, 531, 
+	536, 536, 531, 537, 537, 531, 538, 538, 
+	531, 539, 539, 531, 540, 540, 531, 541, 
+	541, 541, 541, 531, 543, 543, 544, 545, 
+	546, 547, 542, 548, 548, 549, 550, 5, 
+	6, 7, 8, 9, 10, 11, 12, 13, 
+	14, 15, 16, 17, 5, 6, 7, 8, 
+	9, 10, 11, 12, 13, 14, 15, 16, 
+	17, 551, 552, 4, 465, 551, 552, 553, 
+	555, 555, 556, 557, 27, 28, 29, 30, 
+	31, 27, 28, 29, 30, 31, 558, 559, 
+	26, 554, 560, 560, 561, 562, 5, 6, 
+	7, 8, 9, 10, 11, 12, 13, 14, 
+	15, 16, 17, 5, 6, 7, 8, 9, 
+	10, 11, 12, 13, 14, 15, 16, 17, 
+	563, 564, 4, 465, 563, 564, 34, 23, 
+	23, 24, 25, 32, 33, 565, 22, 567, 
+	568, 569, 570, 571, 567, 568, 569, 570, 
+	571, 566, 22, 572, 572, 573, 574, 576, 
+	577, 575, 22, 51, 52, 34, 579, 579, 
+	580, 581, 57, 58, 59, 57, 58, 59, 
+	582, 583, 62, 62, 584, 585, 578, 586, 
+	586, 587, 588, 65, 103, 104, 105, 106, 
+	107, 108, 109, 110, 111, 112, 113, 114, 
+	115, 70, 103, 104, 105, 106, 107, 108, 
+	109, 110, 111, 112, 113, 114, 115, 589, 
+	590, 73, 73, 591, 592, 65, 65, 102, 
+	65, 467, 594, 594, 595, 596, 57, 58, 
+	59, 57, 58, 59, 80, 81, 597, 598, 
+	599, 600, 601, 602, 593, 603, 603, 604, 
+	605, 70, 86, 87, 97, 93, 94, 95, 
+	606, 96, 65, 65, 65, 76, 607, 607, 
+	608, 609, 5, 6, 7, 8, 9, 10, 
+	11, 12, 13, 14, 15, 16, 17, 5, 
+	6, 7, 8, 9, 10, 11, 12, 13, 
+	14, 15, 16, 17, 86, 87, 610, 611, 
+	4, 0, 86, 610, 87, 611, 82, 612, 
+	612, 613, 614, 86, 87, 86, 87, 87, 
+	87, 87, 76, 612, 612, 613, 614, 86, 
+	87, 86, 87, 87, 87, 87, 82, 615, 
+	615, 616, 617, 65, 103, 104, 105, 106, 
+	107, 108, 109, 110, 111, 112, 113, 114, 
+	115, 70, 103, 104, 105, 106, 107, 108, 
+	109, 110, 111, 112, 113, 114, 115, 86, 
+	87, 610, 618, 94, 95, 610, 619, 65, 
+	65, 102, 65, 99, 77, 77, 78, 79, 
+	134, 135, 134, 135, 80, 81, 80, 81, 
+	593, 77, 77, 78, 79, 160, 161, 162, 
+	160, 161, 162, 80, 81, 80, 81, 593, 
+	77, 77, 78, 79, 205, 205, 80, 81, 
+	80, 81, 593, 77, 77, 78, 79, 482, 
+	218, 482, 218, 80, 81, 80, 81, 593, 
+	77, 77, 78, 79, 256, 257, 256, 257, 
+	80, 81, 80, 81, 593, 77, 77, 78, 
+	79, 275, 275, 80, 81, 80, 81, 593, 
+	77, 77, 78, 79, 285, 286, 285, 286, 
+	80, 81, 80, 81, 593, 77, 77, 78, 
+	79, 306, 307, 306, 307, 80, 81, 80, 
+	81, 593, 77, 77, 78, 79, 359, 359, 
+	80, 81, 80, 81, 593, 77, 77, 78, 
+	79, 369, 370, 371, 369, 370, 371, 80, 
+	81, 80, 81, 593, 77, 77, 78, 79, 
+	399, 400, 401, 402, 399, 400, 401, 402, 
+	80, 81, 80, 81, 593, 77, 77, 78, 
+	79, 441, 442, 443, 441, 442, 443, 80, 
+	81, 80, 81, 593, 86, 620, 87, 618, 
+	76, 77, 77, 78, 79, 532, 533, 534, 
+	532, 533, 534, 80, 81, 80, 81, 621, 
+	622, 622, 531, 623, 623, 531, 624, 624, 
+	531, 625, 625, 531, 626, 626, 531, 627, 
+	627, 627, 627, 531, 628, 628, 531, 629, 
+	629, 531, 630, 630, 630, 630, 531, 632, 
+	632, 633, 634, 80, 81, 635, 636, 631, 
+	638, 638, 639, 640, 27, 28, 29, 30, 
+	31, 27, 28, 29, 30, 31, 80, 81, 
+	641, 642, 26, 637, 643, 643, 644, 645, 
+	5, 6, 7, 8, 9, 10, 11, 12, 
+	13, 14, 15, 16, 17, 5, 6, 7, 
+	8, 9, 10, 11, 12, 13, 14, 15, 
+	16, 17, 86, 87, 646, 647, 4, 0, 
+	86, 646, 87, 647, 128, 649, 649, 650, 
+	651, 57, 58, 59, 57, 58, 59, 80, 
+	81, 652, 653, 599, 600, 654, 655, 648, 
+	656, 656, 657, 658, 65, 103, 104, 105, 
+	106, 107, 108, 109, 110, 111, 112, 113, 
+	114, 115, 70, 103, 104, 105, 106, 107, 
+	108, 109, 110, 111, 112, 113, 114, 115, 
+	86, 87, 620, 618, 94, 95, 659, 619, 
+	65, 65, 102, 65, 99, 632, 632, 633, 
+	634, 134, 135, 134, 135, 80, 81, 635, 
+	636, 648, 632, 632, 633, 634, 160, 161, 
+	162, 160, 161, 162, 80, 81, 635, 636, 
+	648, 632, 632, 633, 634, 205, 205, 80, 
+	81, 635, 636, 648, 632, 632, 633, 634, 
+	482, 218, 482, 218, 80, 81, 635, 636, 
+	648, 632, 632, 633, 634, 256, 257, 256, 
+	257, 80, 81, 635, 636, 648, 632, 632, 
+	633, 634, 275, 275, 80, 81, 635, 636, 
+	648, 632, 632, 633, 634, 285, 286, 285, 
+	286, 80, 81, 635, 636, 648, 632, 632, 
+	633, 634, 306, 307, 306, 307, 80, 81, 
+	635, 636, 648, 632, 632, 633, 634, 359, 
+	359, 80, 81, 635, 636, 648, 632, 632, 
+	633, 634, 369, 370, 371, 369, 370, 371, 
+	80, 81, 635, 636, 648, 632, 632, 633, 
+	634, 399, 400, 401, 402, 399, 400, 401, 
+	402, 80, 81, 635, 636, 648, 632, 632, 
+	633, 634, 441, 442, 443, 441, 442, 443, 
+	80, 81, 635, 636, 648, 660, 660, 89, 
+	662, 663, 88, 88, 664, 665, 88, 88, 
+	88, 661, 666, 666, 667, 668, 5, 6, 
+	7, 8, 9, 10, 11, 12, 13, 14, 
+	15, 16, 17, 5, 6, 7, 8, 9, 
+	10, 11, 12, 13, 14, 15, 16, 17, 
+	80, 81, 669, 670, 4, 99, 77, 80, 
+	77, 78, 79, 81, 671, 669, 671, 672, 
+	673, 670, 552, 76, 83, 86, 83, 84, 
+	85, 87, 674, 610, 674, 675, 676, 611, 
+	552, 82, 612, 86, 612, 613, 614, 677, 
+	610, 677, 678, 679, 87, 618, 76, 680, 
+	680, 34, 681, 681, 34, 682, 682, 683, 
+	684, 685, 686, 687, 687, 688, 689, 53, 
+	690, 690, 34, 691, 691, 34, 692, 692, 
+	34, 693, 693, 694, 695, 696, 697, 698, 
+	698, 699, 700, 53, 701, 701, 34, 702, 
+	702, 703, 704, 705, 706, 707, 707, 708, 
+	709, 53, 18, 116, 19, 117, 76, 710, 
+	710, 711, 712, 86, 87, 86, 87, 19, 
+	19, 19, 76, 710, 710, 711, 712, 86, 
+	87, 86, 87, 19, 19, 19, 82, 710, 
+	86, 710, 711, 712, 87, 713, 610, 713, 
+	714, 715, 618, 19, 117, 76, 612, 86, 
+	612, 613, 614, 716, 86, 716, 717, 718, 
+	87, 93, 76, 589, 590, 67, 83, 86, 
+	83, 84, 85, 87, 719, 610, 719, 720, 
+	721, 618, 590, 76, 543, 543, 544, 545, 
+	134, 135, 134, 135, 546, 547, 722, 543, 
+	543, 544, 545, 160, 161, 162, 160, 161, 
+	162, 546, 547, 722, 543, 543, 544, 545, 
+	205, 205, 546, 547, 722, 543, 543, 544, 
+	545, 482, 218, 482, 218, 546, 547, 722, 
+	543, 543, 544, 545, 256, 257, 256, 257, 
+	546, 547, 722, 543, 543, 544, 545, 275, 
+	275, 546, 547, 722, 543, 543, 544, 545, 
+	285, 286, 285, 286, 546, 547, 722, 543, 
+	543, 544, 545, 306, 307, 306, 307, 546, 
+	547, 722, 543, 543, 544, 545, 359, 359, 
+	546, 547, 722, 543, 543, 544, 545, 369, 
+	370, 371, 369, 370, 371, 546, 547, 722, 
+	543, 543, 544, 545, 399, 400, 401, 402, 
+	399, 400, 401, 402, 546, 547, 722, 543, 
+	543, 544, 545, 441, 442, 443, 441, 442, 
+	443, 546, 547, 722, 18, 20, 19, 21, 
+	82, 18, 480, 19, 481, 128, 543, 543, 
+	544, 545, 217, 218, 217, 218, 546, 547, 
+	722, 86, 132, 87, 133, 128, 724, 723, 
+	726, 725, 728, 730, 731, 732, 729, 729, 
+	729, 729, 727, 733, 734, 733, 733, 733, 
+	727, 735, 736, 737, 735, 738, 737, 735, 
+	735, 737, 737, 737, 727, 733, 734, 733, 
+	740, 739, 733, 733, 739, 739, 739, 727, 
+	741, 739, 743, 742, 744, 742, 745, 747, 
+	745, 748, 746, 745, 745, 746, 746, 746, 
+	742, 735, 735, 735, 735, 727, 749, 749, 
+	749, 749, 727, 752, 753, 751, 751, 750, 
+	754, 751, 754, 753, 754, 751, 755, 751, 
+	750, 756, 751, 758, 757, 759, 757, 760, 
+	761, 760, 763, 760, 761, 762, 761, 757, 
+	764, 765, 766, 764, 764, 750, 754, 754, 
+	754, 754, 767, 768, 764, 769, 757, 770, 
+	757, 771, 772, 773, 771, 771, 757, 775, 
+	775, 776, 777, 778, 779, 774, 775, 775, 
+	776, 777, 778, 779, 781, 780, 783, 783, 
+	784, 785, 787, 788, 789, 790, 791, 787, 
+	788, 789, 790, 791, 792, 793, 792, 793, 
+	786, 782, 783, 783, 784, 785, 792, 793, 
+	792, 793, 794, 792, 793, 783, 783, 784, 
+	785, 792, 793, 792, 793, 795, 782, 798, 
+	799, 800, 801, 802, 798, 799, 800, 801, 
+	802, 797, 796, 803, 803, 804, 805, 807, 
+	808, 807, 808, 806, 782, 778, 779, 774, 
+	810, 810, 811, 812, 813, 814, 809, 810, 
+	810, 811, 812, 815, 817, 818, 816, 813, 
+	814, 816, 816, 816, 809, 819, 809, 821, 
+	821, 822, 823, 824, 825, 826, 825, 827, 
+	828, 827, 828, 825, 825, 825, 820, 829, 
+	829, 830, 831, 832, 833, 832, 833, 820, 
+	832, 833, 819, 835, 834, 834, 834, 834, 
+	809, 836, 834, 838, 837, 839, 837, 841, 
+	842, 840, 840, 840, 840, 837, 821, 821, 
+	822, 823, 827, 828, 827, 828, 820, 813, 
+	814, 809, 843, 843, 844, 845, 846, 847, 
+	553, 843, 843, 844, 845, 846, 847, 848, 
+	848, 848, 849, 851, 851, 852, 853, 854, 
+	855, 854, 856, 850, 858, 858, 859, 860, 
+	861, 863, 864, 862, 865, 866, 865, 867, 
+	862, 862, 862, 857, 869, 868, 870, 870, 
+	871, 872, 873, 874, 875, 874, 876, 877, 
+	876, 877, 874, 874, 874, 857, 878, 878, 
+	879, 880, 865, 866, 865, 866, 82, 865, 
+	866, 869, 882, 881, 881, 881, 881, 868, 
+	883, 881, 885, 884, 886, 884, 888, 889, 
+	887, 887, 887, 887, 884, 870, 870, 871, 
+	872, 876, 877, 876, 877, 857, 865, 890, 
+	866, 867, 82, 891, 891, 892, 893, 861, 
+	863, 864, 862, 894, 895, 862, 862, 862, 
+	868, 894, 895, 553, 846, 847, 553, 897, 
+	897, 897, 897, 896, 898, 898, 898, 898, 
+	896, 899, 900, 899, 899, 899, 896, 901, 
+	902, 901, 901, 901, 896, 902, 902, 903, 
+	904, 897, 905, 906, 907, 907, 908, 909, 
+	897, 897, 897, 896, 905, 906, 896, 902, 
+	896, 911, 911, 912, 913, 914, 915, 916, 
+	916, 917, 918, 910, 919, 919, 920, 921, 
+	922, 923, 924, 925, 926, 927, 928, 929, 
+	930, 931, 932, 933, 934, 922, 923, 924, 
+	925, 926, 927, 928, 929, 930, 931, 932, 
+	933, 934, 935, 936, 937, 937, 938, 939, 
+	910, 940, 940, 941, 942, 943, 944, 945, 
+	943, 944, 945, 946, 947, 948, 948, 949, 
+	950, 910, 951, 951, 910, 952, 952, 910, 
+	953, 953, 954, 955, 956, 957, 958, 958, 
+	959, 960, 910, 935, 936, 910, 961, 962, 
+	961, 962, 910, 963, 963, 910, 964, 964, 
+	910, 965, 965, 966, 967, 968, 969, 970, 
+	970, 971, 972, 910, 973, 973, 910, 974, 
+	974, 910, 975, 975, 910, 976, 976, 977, 
+	978, 979, 980, 981, 981, 982, 983, 910, 
+	984, 985, 986, 984, 985, 986, 910, 987, 
+	987, 910, 988, 988, 910, 989, 989, 910, 
+	990, 990, 991, 992, 993, 994, 995, 995, 
+	996, 997, 910, 998, 999, 998, 999, 910, 
+	1000, 1000, 910, 1001, 1001, 910, 1002, 1002, 
+	1003, 1004, 1005, 1006, 1007, 1007, 1008, 1009, 
+	910, 1010, 1010, 910, 1011, 1011, 910, 1012, 
+	1012, 910, 1013, 1013, 1014, 1015, 1016, 1017, 
+	1018, 1018, 1019, 1020, 910, 1021, 1021, 1022, 
+	1023, 1024, 1025, 1026, 1026, 1027, 1028, 910, 
+	1029, 1029, 910, 1030, 1030, 910, 1031, 1031, 
+	910, 1032, 1032, 910, 1033, 1033, 1034, 1035, 
+	1036, 1037, 1038, 1038, 1039, 1040, 910, 1041, 
+	1041, 910, 1042, 1042, 910, 1043, 1043, 910, 
+	1044, 1044, 910, 1045, 1045, 910, 1046, 1046, 
+	910, 1047, 1047, 910, 1048, 1048, 1049, 1050, 
+	1051, 1052, 1053, 1053, 1054, 1055, 910, 1056, 
+	1057, 1056, 1057, 910, 1058, 1058, 910, 1059, 
+	1059, 1060, 1061, 1062, 1063, 1064, 1064, 1065, 
+	1066, 910, 1067, 1067, 1068, 1069, 1070, 1071, 
+	1072, 1072, 1073, 1074, 910, 1075, 1075, 910, 
+	1076, 1076, 910, 1077, 1077, 1078, 1079, 1080, 
+	1081, 1082, 1082, 1083, 1084, 910, 1085, 1086, 
+	1085, 1086, 910, 1087, 1087, 910, 1088, 1088, 
+	910, 1089, 1089, 910, 1090, 1090, 1091, 1092, 
+	1093, 1094, 1095, 1095, 1096, 1097, 910, 1098, 
+	1098, 1099, 1100, 1101, 1102, 1103, 1103, 1104, 
+	1105, 910, 1106, 1107, 1106, 1107, 910, 1108, 
+	1108, 910, 1109, 1109, 910, 1110, 1110, 910, 
+	1111, 1111, 1112, 1113, 1114, 1115, 1116, 1116, 
+	1117, 1118, 910, 1119, 1119, 1120, 1121, 1122, 
+	1122, 1123, 1124, 1125, 1125, 1126, 1127, 910, 
+	1128, 1128, 910, 1129, 1129, 1130, 1131, 1132, 
+	1133, 1134, 1135, 1135, 1136, 1137, 910, 1138, 
+	1138, 1139, 1140, 1141, 1141, 1142, 1143, 1144, 
+	1144, 1145, 1146, 910, 1147, 1147, 910, 1148, 
+	1148, 910, 1149, 1149, 910, 1150, 1150, 910, 
+	1151, 1151, 1152, 1153, 1154, 1155, 1156, 1156, 
+	1157, 1158, 910, 1159, 1159, 910, 1160, 1160, 
+	910, 1161, 1161, 1162, 1163, 1164, 1165, 1166, 
+	1166, 1167, 1168, 910, 1169, 1170, 1171, 1169, 
+	1170, 1171, 910, 1172, 1172, 1173, 1174, 1175, 
+	1176, 1177, 1177, 1178, 1179, 910, 1180, 1180, 
+	910, 1181, 1181, 910, 1182, 1182, 910, 1183, 
+	1183, 1184, 1185, 1186, 1187, 1188, 1188, 1189, 
+	1190, 910, 1191, 1191, 1192, 1193, 1194, 1195, 
+	1196, 1196, 1197, 1198, 910, 1199, 1200, 1201, 
+	1202, 1199, 1200, 1201, 1202, 910, 1203, 1203, 
+	910, 1204, 1204, 1205, 1206, 1207, 1208, 1209, 
+	1209, 1210, 1211, 910, 1212, 1212, 910, 1213, 
+	1213, 1214, 1215, 1216, 1217, 1218, 1218, 1219, 
+	1220, 910, 1221, 1221, 910, 1222, 1222, 1223, 
+	1224, 1225, 1226, 1227, 1227, 1228, 1229, 910, 
+	1230, 1230, 910, 1231, 1231, 910, 1232, 1232, 
+	910, 1233, 1233, 1234, 1235, 1236, 1237, 1238, 
+	1238, 1239, 1240, 910, 1241, 1242, 1243, 1241, 
+	1242, 1243, 910, 1244, 1244, 910, 1245, 1245, 
+	910, 1246, 1246, 1247, 1248, 1249, 1250, 1251, 
+	1251, 1252, 1253, 910, 1254, 1254, 910, 1255, 
+	1255, 1256, 1257, 1258, 1259, 1260, 1260, 1261, 
+	1262, 910, 1263, 1263, 910, 1264, 1264, 910, 
+	1265, 910, 1266, 1266, 1267, 1268, 1270, 1271, 
+	1272, 1272, 1273, 1274, 1269, 910, 1275, 1275, 
+	910, 1276, 1276, 910, 1277, 1277, 910, 1278, 
+	1278, 1279, 1280, 1281, 1282, 1283, 1283, 1284, 
+	1285, 910, 1286, 1286, 910, 1287, 1287, 1288, 
+	1289, 1290, 1291, 1292, 1292, 1293, 1294, 910, 
+	1296, 1296, 1297, 1298, 1299, 1300, 1295, 1296, 
+	1296, 1297, 1298, 1299, 1300, 1302, 1301, 1303, 
+	1303, 1304, 1305, 1307, 1308, 1306, 1301, 1310, 
+	1310, 1311, 1312, 1314, 1315, 1313, 1313, 1313, 
+	1309, 1316, 1316, 1316, 1309, 1317, 1317, 1318, 
+	1319, 1320, 1321, 1322, 1322, 1323, 1324, 1313, 
+	1313, 1313, 1309, 1320, 1321, 1309, 1314, 1315, 
+	1295, 1299, 1300, 1295, 1325, 1325, 1326, 1327, 
+	1328, 1329, 1295, 1325, 1325, 1326, 1327, 1330, 
+	1328, 1329, 1331, 1301, 1332, 1332, 1333, 1334, 
+	1336, 1336, 1337, 1338, 1335, 1301, 1339, 1339, 
+	1340, 1341, 1343, 1344, 1342, 1342, 1342, 1309, 
+	1345, 1345, 1345, 1309, 1346, 1346, 1347, 1348, 
+	1349, 1350, 1351, 1351, 1352, 1353, 1342, 1342, 
+	1342, 1309, 1349, 1350, 1309, 1343, 1344, 1295, 
+	1354, 1354, 1355, 1356, 1357, 1358, 1335, 1301, 
+	1328, 1329, 1295, 1360, 1360, 1359, 1361, 1362, 
+	1361, 1361, 1361, 1362, 1359, 1363, 1363, 1363, 
+	1363, 1363, 1363, 67, 1364, 1364, 1364, 1364, 
+	67, 1365, 1365, 1365, 1365, 1365, 1365, 67, 
+	1366, 1366, 1367, 1368, 1369, 1370, 67, 1371, 
+	1371, 1372, 1373, 1374, 1374, 1374, 1375, 1376, 
+	1374, 1374, 1374, 67, 1377, 1377, 1378, 1379, 
+	1380, 1381, 67, 1383, 1383, 1384, 1385, 1387, 
+	1388, 1386, 1382, 1389, 1389, 1390, 1391, 1393, 
+	1394, 1392, 1382, 1395, 1395, 1396, 1397, 1399, 
+	1400, 1398, 1382, 1402, 1402, 1403, 1404, 1406, 
+	1407, 1408, 1409, 1410, 1406, 1407, 1408, 1409, 
+	1410, 1411, 1412, 1405, 1401, 1413, 1413, 1414, 
+	1415, 1417, 1418, 1416, 1382, 1419, 1419, 1420, 
+	1421, 1423, 1424, 1425, 1426, 1427, 1423, 1424, 
+	1425, 1426, 1427, 1428, 1429, 1422, 1401, 1430, 
+	1430, 1431, 1432, 1434, 1435, 1433, 1382, 1436, 
+	1436, 1437, 1438, 1440, 1441, 1442, 1443, 1444, 
+	1440, 1441, 1442, 1443, 1444, 1445, 1446, 1439, 
+	1401, 1447, 1447, 1448, 1449, 1451, 1452, 1450, 
+	1382, 1453, 1453, 1455, 1456, 1457, 1458, 1459, 
+	1455, 1456, 1457, 1458, 1459, 1453, 1453, 1454, 
+	1401, 1453, 1453, 1453, 1453, 1460, 1401, 1462, 
+	1463, 1464, 1465, 1466, 1462, 1463, 1464, 1465, 
+	1466, 1461, 1401, 1467, 1467, 1467, 1467, 1468, 
+	1401, 1451, 1452, 67, 1436, 1436, 1437, 1438, 
+	1445, 1446, 1469, 1401, 1471, 1472, 1473, 1474, 
+	1475, 1471, 1472, 1473, 1474, 1475, 1470, 1401, 
+	1476, 1476, 1477, 1478, 1480, 1481, 1479, 1401, 
+	1434, 1435, 67, 1419, 1419, 1420, 1421, 1428, 
+	1429, 1482, 1401, 1484, 1485, 1486, 1487, 1488, 
+	1484, 1485, 1486, 1487, 1488, 1483, 1401, 1489, 
+	1489, 1490, 1491, 1493, 1494, 1492, 1401, 1417, 
+	1418, 67, 1402, 1402, 1403, 1404, 1411, 1412, 
+	1495, 1401, 1497, 1498, 1499, 1500, 1501, 1497, 
+	1498, 1499, 1500, 1501, 1496, 1401, 1502, 1502, 
+	1503, 1504, 1506, 1507, 1505, 1401, 1399, 1400, 
+	67, 1387, 1388, 67, 1375, 1376, 67, 67, 
+	67, 67, 67, 1508, 1509, 1509, 1510, 1511, 
+	1512, 1513, 67, 1515, 1515, 1516, 1517, 1518, 
+	1519, 1514, 1514, 1514, 67, 1520, 1520, 1520, 
+	1520, 67, 1518, 1519, 67, 1521, 1521, 1521, 
+	1521, 1521, 1521, 67, 1522, 1522, 1523, 1524, 
+	1525, 1526, 67, 1527, 1527, 1528, 1529, 1530, 
+	1530, 1530, 1531, 1532, 1530, 1530, 1530, 67, 
+	1533, 1533, 1533, 1533, 67, 1531, 1532, 67, 
+	1534, 1382, 1535, 1535, 1536, 1537, 1539, 1540, 
+	1538, 1382, 1541, 1541, 1542, 1543, 1544, 1544, 
+	1544, 1545, 1546, 1544, 1544, 1544, 67, 1547, 
+	1547, 1547, 1547, 67, 1545, 1546, 67, 67, 
+	67, 67, 67, 1548, 1549, 1549, 1550, 1551, 
+	1552, 1553, 1554, 1554, 1555, 1556, 67, 1557, 
+	1557, 1558, 1559, 1560, 1561, 1562, 1562, 1563, 
+	1564, 1548, 1548, 1548, 67, 1560, 1561, 67, 
+	1565, 1565, 1565, 1565, 1359, 1566, 1567, 1566, 
+	1566, 1566, 1567, 1567, 1567, 1359, 1569, 1568, 
+	1570, 1570, 1571, 1572, 1574, 1575, 1573, 1568, 
+	1576, 1576, 1577, 1578, 1580, 1581, 1582, 1583, 
+	1579, 1568, 1584, 1584, 1585, 1586, 1588, 1589, 
+	1587, 1568, 1590, 1590, 1591, 1592, 1580, 1581, 
+	1594, 1595, 1593, 1568, 1596, 1596, 1597, 1598, 
+	1599, 1601, 1602, 1600, 1568, 1603, 1603, 1604, 
+	1605, 1580, 1581, 1606, 1607, 1568, 1608, 1608, 
+	1609, 1610, 1611, 1612, 1568, 1608, 1608, 1609, 
+	1610, 1611, 1612, 1613, 1568, 1614, 1614, 1615, 
+	1616, 1618, 1619, 1617, 1568, 1620, 1620, 1621, 
+	1622, 1624, 1625, 1626, 1627, 1623, 1568, 1628, 
+	1628, 1629, 1630, 1632, 1633, 1631, 1568, 1634, 
+	1634, 1635, 1636, 1624, 1625, 1638, 1639, 1637, 
+	1568, 1640, 1640, 1641, 1642, 1643, 1645, 1646, 
+	1644, 1568, 1647, 1647, 1648, 1649, 1624, 1625, 
+	1650, 1651, 1568, 1652, 1652, 1653, 1654, 1655, 
+	1656, 1568, 1652, 1652, 1653, 1654, 1657, 1655, 
+	1656, 1658, 1568, 1659, 1568, 1660, 1660, 1661, 
+	1662, 1663, 1665, 1666, 1667, 1668, 1668, 1669, 
+	1670, 1664, 1568, 1671, 1671, 1672, 1673, 1675, 
+	1676, 1677, 1677, 1678, 1679, 1674, 1568, 1680, 
+	1680, 1681, 1682, 1683, 1685, 1686, 1687, 1688, 
+	1688, 1689, 1690, 1684, 1568, 1691, 1691, 1692, 
+	1693, 1695, 1696, 1677, 1677, 1697, 1698, 1694, 
+	1568, 1699, 1699, 1700, 1701, 1702, 1704, 1705, 
+	1706, 1707, 1707, 1708, 1709, 1703, 1568, 1710, 
+	1710, 1711, 1712, 1714, 1715, 1677, 1677, 1716, 
+	1717, 1713, 1568, 1718, 1718, 1719, 1720, 1721, 
+	1718, 1723, 1724, 1725, 1725, 1726, 1727, 1722, 
+	1568, 1728, 1728, 1729, 1730, 1731, 1732, 1677, 
+	1677, 1733, 1734, 1568, 1731, 1732, 1568, 1735, 
+	1735, 1736, 1737, 1735, 1739, 1740, 1741, 1741, 
+	1742, 1743, 1738, 1568, 1718, 1718, 1719, 1720, 
+	1718, 1723, 1724, 1725, 1725, 1726, 1727, 1744, 
+	1568, 1714, 1715, 1568, 1745, 1745, 1746, 1747, 
+	1749, 1750, 1751, 1752, 1752, 1753, 1754, 1748, 
+	1568, 1699, 1699, 1700, 1701, 1704, 1705, 1706, 
+	1707, 1707, 1708, 1709, 1755, 1568, 1710, 1710, 
+	1711, 1712, 1714, 1715, 1677, 1677, 1716, 1717, 
+	1568, 1695, 1696, 1568, 1756, 1756, 1757, 1758, 
+	1760, 1761, 1762, 1763, 1763, 1764, 1765, 1759, 
+	1568, 1680, 1680, 1681, 1682, 1685, 1686, 1687, 
+	1688, 1688, 1689, 1690, 1766, 1568, 1691, 1691, 
+	1692, 1693, 1695, 1696, 1677, 1677, 1697, 1698, 
+	1568, 1675, 1676, 1568, 1767, 1767, 1768, 1769, 
+	1771, 1772, 1773, 1774, 1774, 1775, 1776, 1770, 
+	1568, 1660, 1660, 1661, 1662, 1665, 1666, 1667, 
+	1668, 1668, 1669, 1670, 1777, 1568, 1671, 1671, 
+	1672, 1673, 1675, 1676, 1677, 1677, 1678, 1679, 
+	1568, 1655, 1656, 1568, 1778, 1778, 1779, 1780, 
+	1781, 1782, 1568, 1650, 1651, 1568, 1783, 1783, 
+	1784, 1785, 1787, 1788, 1786, 1568, 1640, 1640, 
+	1641, 1642, 1645, 1646, 1789, 1568, 1638, 1639, 
+	1568, 1626, 1627, 1568, 1611, 1612, 1568, 1790, 
+	1790, 1791, 1792, 1793, 1794, 1568, 1606, 1607, 
+	1568, 1795, 1795, 1796, 1797, 1799, 1800, 1798, 
+	1568, 1596, 1596, 1597, 1598, 1601, 1602, 1801, 
+	1568, 1594, 1595, 1568, 1582, 1583, 1568, 1802, 
+	1382, 1803, 1803, 1804, 1805, 1807, 1808, 1806, 
+	1382, 1809, 1809, 1810, 1811, 1813, 1814, 1812, 
+	1382, 1815, 1815, 1816, 1817, 1819, 1820, 1818, 
+	1382, 1821, 1821, 1822, 1823, 1825, 1826, 1824, 
+	1382, 1827, 1827, 1828, 1829, 1831, 1832, 1830, 
+	1382, 1833, 1833, 1834, 1835, 1836, 1836, 1836, 
+	1837, 1838, 1836, 1836, 1836, 67, 1839, 1839, 
+	1839, 1839, 67, 1837, 1838, 67, 1825, 1826, 
+	67, 1813, 1814, 67, 1840, 1382, 1841, 1841, 
+	1842, 1843, 1845, 1846, 1844, 1382, 1847, 1847, 
+	1848, 1849, 1851, 1852, 1850, 1382, 1853, 1853, 
+	1854, 1855, 1857, 1858, 1856, 1382, 1860, 1860, 
+	1861, 1862, 1863, 1864, 1859, 1859, 1859, 67, 
+	1865, 1865, 1866, 1867, 1868, 1869, 67, 1871, 
+	1871, 1872, 1873, 1874, 1875, 1870, 1870, 1870, 
+	67, 1876, 1876, 1877, 1878, 1879, 1880, 67, 
+	1882, 1882, 1883, 1884, 1885, 1886, 1881, 1881, 
+	1881, 67, 1887, 1887, 1888, 1889, 1890, 1891, 
+	67, 1892, 1892, 1893, 1894, 1895, 1895, 1895, 
+	1896, 1897, 1895, 1895, 1895, 67, 1898, 1898, 
+	1898, 1898, 67, 1896, 1897, 67, 1885, 1886, 
+	67, 1874, 1875, 67, 1863, 1864, 67, 1851, 
+	1852, 67, 1899, 1382, 1900, 1900, 1901, 1902, 
+	1904, 1905, 1903, 1382, 1906, 1906, 1907, 1908, 
+	1910, 1911, 1909, 1382, 1912, 1912, 1913, 1914, 
+	1916, 1917, 1915, 1382, 1918, 1918, 1919, 1920, 
+	1922, 1923, 1921, 1382, 1924, 1924, 1925, 1926, 
+	1928, 1929, 1927, 1382, 1930, 1930, 1931, 1932, 
+	1933, 1934, 1935, 1933, 1933, 1933, 67, 1936, 
+	1936, 67, 1934, 1935, 67, 1922, 1923, 67, 
+	1910, 1911, 67, 1938, 1938, 1939, 1940, 1941, 
+	1942, 1943, 1944, 1945, 1946, 1946, 1947, 1948, 
+	1937, 1949, 1950, 1937, 1951, 1937, 1953, 1953, 
+	1952, 1955, 1954, 1952, 1956, 1937, 1957, 1957, 
+	1958, 1959, 1961, 1962, 1963, 1963, 1964, 1965, 
+	1960, 1937, 1944, 1945, 67, 1966, 1937, 1967, 
+	1967, 1967, 1967, 1952, 1969, 1968, 1968, 1968, 
+	1952, 1970, 1382, 1971, 1971, 1972, 1973, 1975, 
+	1976, 1974, 1382, 1977, 1977, 1978, 1979, 1981, 
+	1982, 1980, 1382, 1983, 1983, 1984, 1985, 1987, 
+	1988, 1986, 1382, 1989, 1989, 1990, 1991, 1993, 
+	1994, 1992, 1382, 1995, 1995, 1996, 1997, 1999, 
+	2000, 1998, 1382, 2002, 2002, 2003, 2004, 2006, 
+	2007, 2005, 2005, 2005, 2001, 2008, 2008, 2008, 
+	2001, 2009, 2009, 2010, 2011, 2012, 2013, 2014, 
+	2014, 2015, 2016, 2005, 2005, 2005, 2001, 2012, 
+	2013, 2001, 2006, 2007, 67, 1993, 1994, 67, 
+	1981, 1982, 67, 2017, 1382, 2018, 2018, 2019, 
+	2020, 2022, 2023, 2021, 1382, 2024, 2024, 2025, 
+	2026, 2028, 2029, 2027, 1382, 2030, 2030, 2031, 
+	2032, 2034, 2035, 2033, 1382, 2036, 2036, 2037, 
+	2038, 2040, 2041, 2039, 2039, 2039, 2001, 2042, 
+	2042, 2042, 2001, 2043, 2043, 2044, 2045, 2046, 
+	2047, 2048, 2048, 2049, 2050, 2039, 2039, 2039, 
+	2001, 2046, 2047, 2001, 2040, 2041, 67, 2028, 
+	2029, 67, 2051, 1382, 2052, 2052, 2053, 2054, 
+	2056, 2057, 2055, 1382, 2059, 2059, 2060, 2061, 
+	2062, 2063, 2064, 2065, 2066, 2067, 2058, 2068, 
+	2068, 2069, 2070, 2071, 2072, 2058, 2068, 2068, 
+	2069, 2070, 2071, 2072, 2074, 2073, 2075, 2075, 
+	2076, 2077, 2079, 2080, 2078, 2073, 2081, 2081, 
+	2082, 2083, 2084, 2085, 2086, 2058, 2088, 2088, 
+	2089, 2090, 2091, 2091, 2092, 2093, 2094, 2094, 
+	2095, 2096, 2097, 2097, 2097, 2097, 2098, 2099, 
+	2097, 2097, 2100, 2101, 2102, 2103, 2097, 2097, 
+	2104, 2105, 2106, 2107, 2097, 2097, 2108, 2109, 
+	2087, 2088, 2088, 2089, 2090, 2111, 2098, 2099, 
+	2111, 2111, 2111, 2110, 2097, 2097, 2110, 2098, 
+	2099, 2110, 2091, 2091, 2092, 2093, 2097, 2097, 
+	2097, 2097, 2102, 2103, 2097, 2097, 2104, 2105, 
+	2110, 2102, 2103, 2110, 2111, 2088, 2088, 2089, 
+	2090, 2091, 2091, 2092, 2093, 2094, 2094, 2095, 
+	2096, 2097, 2097, 2097, 2097, 2098, 2099, 2097, 
+	2097, 2100, 2101, 2102, 2103, 2097, 2097, 2104, 
+	2105, 2106, 2107, 2097, 2097, 2108, 2109, 2111, 
+	2111, 2111, 2110, 2098, 2102, 2106, 2099, 2103, 
+	2107, 2110, 2085, 2086, 2058, 2071, 2072, 2058, 
+	2112, 2112, 2113, 2114, 2115, 2116, 2058, 2112, 
+	2112, 2113, 2114, 2115, 2116, 2117, 2073, 2118, 
+	2118, 2119, 2120, 2122, 2123, 2121, 2073, 2125, 
+	2125, 2126, 2127, 2128, 2129, 2130, 2128, 2124, 
+	2132, 2133, 2133, 2134, 2135, 2136, 2136, 2137, 
+	2138, 2139, 2139, 2140, 2141, 2142, 2142, 2142, 
+	2142, 2143, 2144, 2142, 2142, 2145, 2146, 2147, 
+	2148, 2142, 2142, 2149, 2150, 2151, 2152, 2142, 
+	2142, 2153, 2154, 2132, 2131, 2129, 2130, 2058, 
+	2115, 2116, 2058, 2155, 2155, 2156, 2157, 2158, 
+	2159, 2058, 2155, 2155, 2156, 2157, 2158, 2159, 
+	2160, 2073, 2161, 2161, 2162, 2163, 2165, 2166, 
+	2164, 2073, 2167, 2167, 2168, 2169, 2170, 2171, 
+	2172, 2170, 2170, 2170, 2124, 2173, 2174, 2174, 
+	2175, 2176, 2177, 2177, 2178, 2179, 2180, 2180, 
+	2181, 2182, 2183, 2183, 2183, 2183, 2184, 2185, 
+	2183, 2183, 2186, 2187, 2188, 2189, 2183, 2183, 
+	2190, 2191, 2192, 2193, 2183, 2183, 2194, 2195, 
+	2173, 2173, 2173, 2131, 2171, 2172, 2058, 2158, 
+	2159, 2058, 2196, 2196, 2197, 2198, 2199, 2200, 
+	2058, 2196, 2196, 2197, 2198, 2199, 2200, 2201, 
+	2073, 2202, 2202, 2203, 2204, 2206, 2207, 2205, 
+	2073, 2208, 2208, 2209, 2210, 2211, 2211, 2211, 
+	2212, 2213, 2211, 2211, 2211, 2058, 2214, 2214, 
+	2215, 2216, 2217, 2217, 2218, 2219, 2220, 2220, 
+	2221, 2222, 2223, 2223, 2223, 2223, 2224, 2225, 
+	2223, 2223, 2226, 2227, 2228, 2229, 2223, 2223, 
+	2230, 2231, 2232, 2233, 2223, 2223, 2234, 2235, 
+	2087, 2212, 2213, 2058, 2199, 2200, 2058, 2066, 
+	2067, 67, 2237, 2238, 2239, 2240, 2241, 2242, 
+	2243, 2244, 2245, 2246, 2247, 2248, 2249, 2237, 
+	2238, 2239, 2240, 2241, 2242, 2243, 2244, 2245, 
+	2246, 2247, 2248, 2249, 2236, 2250, 2250, 2251, 
+	2252, 2253, 2254, 2255, 2253, 2254, 2255, 2256, 
+	2257, 2236, 2258, 2258, 2259, 2260, 2262, 2263, 
+	2261, 1382, 2264, 2264, 2265, 2266, 2268, 2269, 
+	2267, 1382, 2270, 2270, 2271, 2272, 2274, 2275, 
+	2273, 1382, 2276, 2276, 2277, 2278, 2280, 2281, 
+	2279, 1382, 2282, 2282, 2283, 2284, 2286, 2287, 
+	2285, 1382, 2288, 2288, 2289, 2290, 2292, 2293, 
+	2291, 1382, 2295, 2295, 2296, 2297, 2299, 2300, 
+	2298, 2294, 2301, 2301, 2302, 2303, 2305, 2306, 
+	2304, 2294, 2307, 2307, 2308, 2309, 2311, 2312, 
+	2310, 2294, 2313, 2313, 2314, 2315, 2317, 2318, 
+	2316, 2294, 2319, 2319, 2320, 2321, 2323, 2324, 
+	2322, 1382, 2325, 2325, 2326, 2327, 2329, 2330, 
+	2328, 1382, 2331, 2331, 2332, 2333, 2334, 2334, 
+	2334, 2335, 2336, 2334, 2334, 2334, 67, 2337, 
+	2337, 2338, 2339, 2340, 2341, 67, 2342, 2342, 
+	2343, 2344, 2345, 2346, 2347, 2345, 2345, 2345, 
+	67, 2348, 2348, 67, 2346, 2347, 67, 2335, 
+	2336, 67, 2323, 2324, 67, 2311, 2312, 67, 
+	2299, 2300, 67, 2286, 2287, 67, 2274, 2275, 
+	67, 2262, 2263, 67, 2349, 2349, 2236, 2350, 
+	2350, 2236, 2351, 2351, 2352, 2353, 2354, 2355, 
+	2236, 2356, 2356, 2236, 2357, 2357, 2236, 2358, 
+	2358, 2236, 2359, 2359, 2360, 2361, 2362, 2363, 
+	2236, 2364, 2364, 2236, 2365, 2365, 2366, 2367, 
+	2368, 2369, 2236, 2370, 2371, 2370, 2371, 2236, 
+	2372, 2372, 2236, 2373, 2373, 2236, 2374, 2374, 
+	2375, 2376, 2377, 2378, 2236, 2379, 2379, 2236, 
+	2380, 2380, 2236, 2381, 2381, 2236, 2382, 2382, 
+	2383, 2384, 2385, 2386, 2236, 2387, 2388, 2389, 
+	2387, 2388, 2389, 2236, 2390, 2390, 2236, 2391, 
+	2391, 2236, 2392, 2392, 2236, 2393, 2393, 2394, 
+	2395, 2396, 2397, 2236, 2398, 2399, 2398, 2399, 
+	2236, 2400, 2400, 2236, 2401, 2401, 2236, 2402, 
+	2402, 2403, 2404, 2405, 2406, 2236, 2407, 2407, 
+	2236, 2408, 2408, 2236, 2409, 2409, 2236, 2410, 
+	2410, 2411, 2412, 2413, 2414, 2236, 2415, 2415, 
+	2416, 2417, 2418, 2419, 2236, 2420, 2420, 2236, 
+	2421, 2421, 2236, 2422, 2422, 2236, 2423, 2423, 
+	2236, 2424, 2424, 2425, 2426, 2427, 2428, 2236, 
+	2429, 2429, 2236, 2430, 2430, 2236, 2431, 2431, 
+	2236, 2432, 2432, 2236, 2433, 2433, 2236, 2434, 
+	2434, 2236, 2435, 2435, 2236, 2436, 2436, 2437, 
+	2438, 2439, 2440, 2236, 2441, 2442, 2441, 2442, 
+	2236, 2443, 2443, 2236, 2444, 2444, 2445, 2446, 
+	2447, 2448, 2236, 2449, 2449, 2450, 2451, 2452, 
+	2453, 2236, 2454, 2454, 2236, 2455, 2455, 2236, 
+	2456, 2456, 2457, 2458, 2459, 2460, 2236, 2461, 
+	2462, 2461, 2462, 2236, 2463, 2463, 2236, 2464, 
+	2464, 2236, 2465, 2465, 2236, 2466, 2466, 2467, 
+	2468, 2469, 2470, 2236, 2471, 2471, 2472, 2473, 
+	2474, 2475, 2236, 2476, 2477, 2476, 2477, 2236, 
+	2478, 2478, 2236, 2479, 2479, 2236, 2480, 2480, 
+	2236, 2481, 2481, 2482, 2483, 2484, 2485, 2236, 
+	2486, 2486, 2487, 2488, 2489, 2489, 2490, 2491, 
+	2236, 2492, 2492, 2236, 2493, 2493, 2494, 2495, 
+	2496, 2497, 2498, 2236, 2499, 2499, 2500, 2501, 
+	2502, 2502, 2503, 2504, 2236, 2505, 2505, 2236, 
+	2506, 2506, 2236, 2507, 2507, 2236, 2508, 2508, 
+	2236, 2509, 2509, 2510, 2511, 2512, 2513, 2236, 
+	2514, 2514, 2236, 2515, 2515, 2236, 2516, 2516, 
+	2517, 2518, 2519, 2520, 2236, 2521, 2522, 2523, 
+	2521, 2522, 2523, 2236, 2524, 2524, 2525, 2526, 
+	2527, 2528, 2236, 2529, 2529, 2236, 2530, 2530, 
+	2236, 2531, 2531, 2236, 2532, 2532, 2533, 2534, 
+	2535, 2536, 2236, 2537, 2537, 2538, 2539, 2540, 
+	2541, 2236, 2542, 2543, 2544, 2545, 2542, 2543, 
+	2544, 2545, 2236, 2546, 2546, 2236, 2547, 2547, 
+	2548, 2549, 2550, 2551, 2236, 2552, 2552, 2236, 
+	2553, 2553, 2554, 2555, 2556, 2557, 2236, 2558, 
+	2558, 2236, 2559, 2559, 2560, 2561, 2562, 2563, 
+	2236, 2564, 2564, 2236, 2565, 2565, 2236, 2566, 
+	2566, 2236, 2567, 2567, 2568, 2569, 2570, 2571, 
+	2236, 2572, 2573, 2574, 2572, 2573, 2574, 2236, 
+	2575, 2575, 2236, 2576, 2576, 2236, 2577, 2577, 
+	2578, 2579, 2580, 2581, 2236, 2582, 2582, 2236, 
+	2583, 2583, 2584, 2585, 2586, 2587, 2236, 2588, 
+	2588, 2236, 2589, 2589, 2236, 2591, 2590, 2592, 
+	2592, 2593, 2594, 2596, 2597, 2595, 2590, 2598, 
+	2598, 2598, 2598, 2598, 2598, 67, 2599, 2599, 
+	2599, 2599, 67, 2600, 2600, 2600, 2600, 67, 
+	2601, 1382, 2602, 2602, 2603, 2604, 2606, 2607, 
+	2605, 1382, 2608, 2608, 2609, 2610, 2612, 2613, 
+	2611, 1382, 2614, 2614, 2615, 2616, 2618, 2619, 
+	2617, 1382, 2620, 2620, 2621, 2622, 2624, 2625, 
+	2623, 1382, 2626, 2626, 2627, 2628, 2630, 2631, 
+	2629, 1382, 2632, 2632, 2633, 2634, 2635, 2636, 
+	2637, 2635, 2635, 2635, 67, 2638, 2638, 67, 
+	2636, 2637, 67, 2624, 2625, 67, 2612, 2613, 
+	67, 2639, 2639, 2639, 2639, 67, 2640, 2640, 
+	67, 2641, 1382, 2642, 2642, 2643, 2644, 2646, 
+	2647, 2645, 1382, 2648, 2648, 2649, 2650, 2652, 
+	2653, 2651, 1382, 2654, 2654, 2655, 2656, 2658, 
+	2659, 2657, 1382, 2660, 2660, 2661, 2662, 2664, 
+	2665, 2663, 1382, 2666, 2666, 2667, 2668, 2670, 
+	2671, 2669, 1382, 2672, 2672, 2673, 2674, 2675, 
+	2677, 2678, 2676, 2676, 2676, 2001, 2679, 2679, 
+	2680, 2681, 2682, 2683, 2001, 2685, 2685, 2686, 
+	2687, 2689, 2690, 2688, 2688, 2688, 2684, 2691, 
+	2691, 2691, 2684, 2693, 2692, 2692, 2692, 2684, 
+	2694, 2694, 2694, 2684, 2696, 2695, 2695, 2695, 
+	2684, 2698, 2697, 2697, 2697, 2684, 2699, 2699, 
+	2699, 2684, 2701, 2700, 2700, 2700, 2684, 2702, 
+	2702, 2702, 2702, 2703, 2703, 2703, 2684, 2704, 
+	2704, 2704, 2704, 67, 2705, 2684, 2701, 2684, 
+	2698, 2684, 2706, 2684, 2696, 2684, 2689, 2690, 
+	67, 2707, 2707, 2707, 2001, 2679, 2679, 2680, 
+	2681, 2682, 2683, 2708, 2708, 2708, 2001, 2677, 
+	2678, 67, 2664, 2665, 67, 2652, 2653, 67, 
+	2709, 1382, 2710, 2710, 2711, 2712, 2714, 2715, 
+	2713, 1382, 2716, 2716, 2717, 2718, 2720, 2721, 
+	2719, 1382, 2722, 2722, 2723, 2724, 2726, 2727, 
+	2725, 1382, 2728, 2728, 2729, 2730, 2732, 2733, 
+	2731, 1382, 2734, 2734, 2735, 2736, 2738, 2739, 
+	2737, 1382, 2740, 2740, 2741, 2742, 2743, 2745, 
+	2746, 2744, 2744, 2744, 2001, 2747, 2747, 2747, 
+	2747, 2001, 2748, 2748, 2748, 2001, 2747, 2747, 
+	2747, 2747, 2749, 2749, 2749, 2001, 2745, 2746, 
+	67, 2732, 2733, 67, 2720, 2721, 67, 2750, 
+	1382, 2751, 2751, 2752, 2753, 2755, 2756, 2754, 
+	1382, 2757, 2757, 2758, 2759, 2761, 2762, 2760, 
+	1382, 2763, 2763, 2764, 2765, 2767, 2768, 2766, 
+	1382, 2769, 2769, 2770, 2771, 2773, 2774, 2772, 
+	1382, 2775, 2775, 2776, 2777, 2779, 2780, 2778, 
+	1382, 2781, 2781, 2782, 2783, 2785, 2786, 2784, 
+	2784, 2784, 2001, 2787, 2787, 2787, 2001, 2788, 
+	2788, 2789, 2790, 2791, 2792, 2793, 2793, 2794, 
+	2795, 2784, 2784, 2784, 2001, 2791, 2792, 2001, 
+	2785, 2786, 67, 2773, 2774, 67, 2761, 2762, 
+	67, 2797, 2797, 2798, 2799, 2800, 2801, 2801, 
+	2801, 18, 19, 2802, 2803, 2801, 2801, 2801, 
+	2796, 2804, 2804, 2805, 2806, 2807, 2808, 65, 
+	2809, 2808, 18, 19, 2810, 2811, 118, 119, 
+	2812, 2813, 65, 65, 2808, 65, 2808, 65, 
+	2808, 65, 631, 2815, 2815, 2798, 2816, 2817, 
+	2801, 2818, 2819, 2820, 2821, 2822, 2823, 2824, 
+	2825, 2826, 2827, 2828, 2829, 2830, 2801, 2801, 
+	2818, 2819, 2820, 2821, 2822, 2823, 2824, 2825, 
+	2826, 2827, 2828, 2829, 2830, 18, 19, 2831, 
+	2832, 2801, 2801, 2801, 2814, 2815, 2815, 2798, 
+	2816, 2817, 2801, 2835, 2836, 2837, 2838, 2839, 
+	2840, 2841, 2842, 2843, 2844, 2845, 2846, 2847, 
+	2801, 2801, 2835, 2836, 2837, 2838, 2839, 2840, 
+	2841, 2842, 2843, 2844, 2845, 2846, 2847, 18, 
+	19, 2831, 2832, 2801, 2834, 2801, 2801, 2833, 
+	2849, 2849, 2850, 2851, 2852, 2853, 2853, 2853, 
+	2854, 2855, 2856, 2857, 2853, 2853, 2853, 2848, 
+	2797, 2797, 2798, 2858, 2859, 2801, 2835, 2836, 
+	2837, 2838, 2839, 2840, 2841, 2842, 2843, 2844, 
+	2845, 2846, 2847, 2801, 2801, 2835, 2836, 2837, 
+	2838, 2839, 2840, 2841, 2842, 2843, 2844, 2845, 
+	2846, 2847, 18, 19, 2860, 2803, 2801, 2834, 
+	2801, 2801, 2833, 2861, 2861, 2798, 2862, 2863, 
+	2801, 2801, 2801, 86, 87, 2864, 2865, 2801, 
+	2801, 2801, 631, 2866, 2866, 2805, 2867, 2868, 
+	2808, 65, 2809, 2808, 86, 87, 2864, 2869, 
+	94, 95, 2864, 2870, 65, 65, 2808, 65, 
+	2808, 65, 2808, 65, 631, 2804, 2804, 2805, 
+	2806, 2807, 2808, 65, 2873, 2874, 2875, 2876, 
+	2877, 2878, 2879, 2880, 2881, 2882, 2883, 2884, 
+	2885, 2809, 2808, 2873, 2874, 2875, 2876, 2877, 
+	2878, 2879, 2880, 2881, 2882, 2883, 2884, 2885, 
+	18, 19, 2810, 2811, 118, 119, 2812, 2813, 
+	65, 65, 2808, 2872, 65, 2808, 65, 2808, 
+	65, 2871, 2866, 2866, 2805, 2867, 2868, 2808, 
+	65, 2873, 2874, 2875, 2876, 2877, 2878, 2879, 
+	2880, 2881, 2882, 2883, 2884, 2885, 2809, 2808, 
+	2873, 2874, 2875, 2876, 2877, 2878, 2879, 2880, 
+	2881, 2882, 2883, 2884, 2885, 86, 87, 2886, 
+	2869, 94, 95, 2886, 2870, 65, 65, 2808, 
+	2872, 65, 2808, 65, 2808, 65, 2871, 553, 
+	553, 553, 754, 751, 754, 753, 754, 751, 
+	755, 751, 750, 553, 553, 553, 891, 891, 
+	892, 893, 861, 863, 864, 862, 894, 895, 
+	862, 862, 862, 868, 553, 902, 902, 903, 
+	904, 897, 905, 906, 907, 907, 908, 909, 
+	897, 897, 897, 896, 905, 906, 896, 553, 
+	919, 919, 920, 921, 922, 923, 924, 925, 
+	926, 927, 928, 929, 930, 931, 932, 933, 
+	934, 922, 923, 924, 925, 926, 927, 928, 
+	929, 930, 931, 932, 933, 934, 935, 936, 
+	937, 937, 938, 939, 910, 935, 936, 910, 
+	553, 1317, 1317, 1318, 1319, 1320, 1321, 1322, 
+	1322, 1323, 1324, 1313, 1313, 1313, 1309, 1320, 
+	1321, 1309, 1339, 1339, 1340, 1341, 1343, 1344, 
+	1342, 1342, 1342, 1309, 1295, 1346, 1346, 1347, 
+	1348, 1349, 1350, 1351, 1351, 1352, 1353, 1342, 
+	1342, 1342, 1309, 1349, 1350, 1309, 1343, 1344, 
+	1295, 553, 553, 553, 553, 553, 553, 553, 
+	1557, 1557, 1558, 1559, 1560, 1561, 1562, 1562, 
+	1563, 1564, 1548, 1548, 1548, 67, 1560, 1561, 
+	67, 553, 553, 1728, 1728, 1729, 1730, 1731, 
+	1732, 1677, 1677, 1733, 1734, 1568, 1731, 1732, 
+	1568, 1710, 1710, 1711, 1712, 1714, 1715, 1677, 
+	1677, 1716, 1717, 1713, 1568, 1714, 1715, 1568, 
+	1691, 1691, 1692, 1693, 1695, 1696, 1677, 1677, 
+	1697, 1698, 1694, 1568, 1695, 1696, 1568, 1671, 
+	1671, 1672, 1673, 1675, 1676, 1677, 1677, 1678, 
+	1679, 1674, 1568, 1675, 1676, 1568, 553, 553, 
+	553, 553, 1938, 1938, 1939, 1940, 1941, 1942, 
+	1943, 1944, 1945, 1946, 1946, 1947, 1948, 1937, 
+	1944, 1945, 67, 553, 2009, 2009, 2010, 2011, 
+	2012, 2013, 2014, 2014, 2015, 2016, 2005, 2005, 
+	2005, 2001, 2012, 2013, 2001, 553, 2043, 2043, 
+	2044, 2045, 2046, 2047, 2048, 2048, 2049, 2050, 
+	2039, 2039, 2039, 2001, 2046, 2047, 2001, 553, 
+	2091, 2091, 2092, 2093, 2097, 2097, 2097, 2097, 
+	2102, 2103, 2097, 2097, 2104, 2105, 2110, 2102, 
+	2103, 2110, 2088, 2088, 2089, 2090, 2111, 2098, 
+	2099, 2111, 2111, 2111, 2110, 2098, 2099, 2110, 
+	2111, 2088, 2088, 2089, 2090, 2091, 2091, 2092, 
+	2093, 2094, 2094, 2095, 2096, 2097, 2097, 2097, 
+	2097, 2098, 2099, 2097, 2097, 2100, 2101, 2102, 
+	2103, 2097, 2097, 2104, 2105, 2106, 2107, 2097, 
+	2097, 2108, 2109, 2111, 2111, 2111, 2110, 2098, 
+	2102, 2106, 2099, 2103, 2107, 2110, 553, 553, 
+	553, 553, 553, 553, 553, 2788, 2788, 2789, 
+	2790, 2791, 2792, 2793, 2793, 2794, 2795, 2784, 
+	2784, 2784, 2001, 2791, 2792, 2001, 0
+};
+
+static const short _zone_scanner_trans_targs[] = {
+	0, 1, 1, 1, 2, 4, 17, 26, 
+	40, 116, 56, 60, 63, 69, 83, 86, 
+	93, 104, 849, 124, 854, 226, 0, 3, 
+	3, 3, 2, 139, 139, 139, 139, 139, 
+	3, 142, 0, 3, 3, 3, 4, 17, 
+	26, 40, 45, 56, 60, 63, 69, 83, 
+	86, 93, 104, 3, 142, 0, 5, 5, 
+	5, 198, 201, 205, 5, 11, 10, 12, 
+	21, 6, 5, 0, 5, 5, 9, 5, 
+	11, 10, 12, 21, 0, 7, 7, 7, 
+	849, 8, 0, 7, 7, 7, 849, 8, 
+	6, 10, 12, 12, 12, 13, 855, 149, 
+	211, 850, 14, 0, 14, 14, 15, 145, 
+	152, 153, 154, 155, 156, 157, 158, 159, 
+	160, 161, 162, 163, 857, 207, 855, 208, 
+	858, 210, 0, 16, 16, 16, 851, 229, 
+	0, 16, 16, 16, 851, 229, 18, 22, 
+	19, 20, 5, 5, 5, 5, 11, 10, 
+	12, 21, 21, 21, 21, 23, 24, 25, 
+	5, 5, 5, 5, 11, 10, 12, 21, 
+	27, 31, 39, 28, 29, 30, 5, 5, 
+	5, 5, 11, 10, 12, 21, 32, 35, 
+	33, 34, 5, 5, 5, 5, 11, 10, 
+	12, 21, 36, 37, 38, 5, 5, 5, 
+	5, 11, 10, 12, 21, 5, 5, 5, 
+	5, 11, 10, 12, 21, 41, 42, 43, 
+	44, 5, 5, 5, 5, 11, 10, 12, 
+	21, 46, 49, 47, 47, 47, 47, 114, 
+	47, 47, 47, 4, 17, 26, 40, 48, 
+	56, 60, 63, 69, 83, 86, 93, 104, 
+	47, 114, 50, 51, 52, 53, 54, 55, 
+	5, 5, 5, 5, 11, 10, 12, 21, 
+	57, 59, 58, 5, 5, 5, 5, 11, 
+	10, 12, 21, 5, 5, 5, 5, 11, 
+	10, 12, 21, 61, 62, 5, 5, 5, 
+	5, 11, 10, 12, 21, 64, 68, 65, 
+	66, 67, 5, 5, 5, 5, 11, 10, 
+	12, 21, 5, 5, 5, 5, 11, 10, 
+	12, 21, 70, 74, 71, 72, 73, 5, 
+	5, 5, 5, 11, 10, 12, 21, 5, 
+	5, 5, 75, 5, 11, 10, 12, 21, 
+	76, 5, 5, 5, 77, 5, 11, 10, 
+	12, 21, 5, 5, 5, 78, 5, 11, 
+	10, 12, 21, 79, 80, 81, 82, 5, 
+	5, 5, 5, 11, 10, 12, 21, 84, 
+	85, 5, 5, 5, 5, 11, 10, 12, 
+	21, 87, 88, 92, 5, 5, 5, 5, 
+	11, 10, 12, 21, 89, 90, 91, 5, 
+	5, 5, 5, 11, 10, 12, 21, 5, 
+	5, 5, 5, 11, 10, 12, 21, 94, 
+	96, 98, 100, 95, 5, 5, 5, 5, 
+	11, 10, 12, 21, 97, 5, 5, 5, 
+	5, 11, 10, 12, 21, 99, 5, 5, 
+	5, 5, 11, 10, 12, 21, 101, 102, 
+	103, 5, 5, 5, 5, 11, 10, 12, 
+	21, 105, 108, 110, 106, 107, 5, 5, 
+	5, 5, 11, 10, 12, 21, 109, 5, 
+	5, 5, 5, 11, 10, 12, 21, 111, 
+	112, 0, 113, 0, 5, 5, 5, 113, 
+	5, 11, 10, 12, 21, 115, 115, 115, 
+	852, 227, 117, 118, 118, 118, 118, 123, 
+	118, 118, 118, 119, 4, 17, 26, 40, 
+	48, 56, 60, 63, 69, 83, 86, 93, 
+	104, 118, 123, 47, 47, 47, 119, 120, 
+	120, 120, 120, 120, 47, 114, 121, 121, 
+	122, 122, 122, 122, 122, 47, 47, 47, 
+	121, 47, 114, 0, 126, 166, 172, 127, 
+	128, 129, 130, 131, 132, 853, 0, 134, 
+	134, 134, 134, 135, 134, 134, 134, 134, 
+	135, 0, 0, 137, 137, 137, 137, 138, 
+	137, 137, 137, 137, 138, 140, 140, 141, 
+	141, 141, 141, 141, 3, 3, 3, 140, 
+	3, 142, 0, 144, 144, 144, 144, 212, 
+	151, 213, 144, 144, 144, 144, 212, 151, 
+	213, 0, 146, 146, 146, 850, 13, 855, 
+	149, 856, 211, 146, 146, 146, 856, 147, 
+	147, 147, 854, 148, 150, 150, 150, 151, 
+	151, 151, 164, 197, 857, 0, 167, 168, 
+	169, 170, 171, 853, 173, 174, 853, 0, 
+	147, 147, 147, 854, 148, 0, 177, 177, 
+	177, 852, 178, 177, 177, 177, 852, 178, 
+	0, 180, 180, 180, 857, 164, 858, 197, 
+	180, 180, 180, 858, 194, 0, 194, 194, 
+	194, 195, 147, 147, 147, 854, 148, 196, 
+	196, 196, 196, 196, 196, 197, 197, 197, 
+	199, 200, 5, 5, 5, 5, 11, 10, 
+	12, 21, 202, 203, 204, 5, 5, 5, 
+	5, 11, 10, 12, 21, 206, 5, 5, 
+	5, 5, 11, 10, 12, 21, 209, 209, 
+	209, 210, 210, 210, 211, 211, 211, 213, 
+	213, 213, 0, 231, 859, 231, 859, 0, 
+	233, 235, 240, 241, 236, 860, 234, 860, 
+	233, 235, 236, 235, 236, 237, 0, 238, 
+	239, 860, 235, 234, 236, 860, 0, 243, 
+	248, 244, 861, 862, 245, 0, 246, 247, 
+	861, 243, 862, 244, 248, 249, 250, 0, 
+	251, 252, 253, 248, 249, 250, 0, 255, 
+	255, 255, 255, 262, 0, 256, 0, 257, 
+	257, 257, 256, 259, 259, 259, 259, 259, 
+	863, 258, 0, 260, 0, 260, 261, 261, 
+	261, 261, 261, 257, 257, 257, 260, 863, 
+	258, 0, 264, 264, 264, 264, 275, 265, 
+	269, 274, 270, 266, 0, 267, 267, 267, 
+	265, 269, 270, 864, 268, 267, 267, 267, 
+	864, 268, 269, 270, 271, 0, 272, 273, 
+	269, 266, 270, 277, 277, 277, 277, 293, 
+	278, 0, 0, 279, 279, 279, 865, 283, 
+	290, 0, 279, 279, 279, 280, 284, 289, 
+	285, 865, 283, 290, 0, 281, 282, 282, 
+	282, 280, 284, 285, 865, 283, 282, 282, 
+	282, 284, 285, 286, 0, 287, 288, 284, 
+	281, 285, 866, 291, 291, 291, 291, 292, 
+	0, 295, 296, 297, 300, 298, 298, 298, 
+	298, 298, 299, 867, 868, 869, 0, 302, 
+	302, 302, 302, 307, 870, 871, 872, 302, 
+	302, 302, 303, 308, 316, 330, 335, 343, 
+	347, 350, 356, 370, 373, 380, 391, 302, 
+	307, 870, 871, 872, 302, 302, 302, 304, 
+	401, 405, 302, 307, 870, 871, 872, 305, 
+	306, 302, 302, 302, 302, 307, 870, 871, 
+	872, 309, 312, 310, 311, 302, 302, 302, 
+	302, 307, 870, 871, 872, 313, 314, 315, 
+	302, 302, 302, 302, 307, 870, 871, 872, 
+	317, 321, 329, 318, 319, 320, 302, 302, 
+	302, 302, 307, 870, 871, 872, 322, 325, 
+	323, 324, 302, 302, 302, 302, 307, 870, 
+	871, 872, 326, 327, 328, 302, 302, 302, 
+	302, 307, 870, 871, 872, 302, 302, 302, 
+	302, 307, 870, 871, 872, 331, 332, 333, 
+	334, 302, 302, 302, 302, 307, 870, 871, 
+	872, 336, 337, 338, 339, 340, 341, 342, 
+	302, 302, 302, 302, 307, 870, 871, 872, 
+	344, 346, 345, 302, 302, 302, 302, 307, 
+	870, 871, 872, 302, 302, 302, 302, 307, 
+	870, 871, 872, 348, 349, 302, 302, 302, 
+	302, 307, 870, 871, 872, 351, 355, 352, 
+	353, 354, 302, 302, 302, 302, 307, 870, 
+	871, 872, 302, 302, 302, 302, 307, 870, 
+	871, 872, 357, 361, 358, 359, 360, 302, 
+	302, 302, 302, 307, 870, 871, 872, 302, 
+	302, 302, 362, 302, 307, 870, 871, 872, 
+	363, 302, 302, 302, 364, 302, 307, 870, 
+	871, 872, 302, 302, 302, 365, 302, 307, 
+	870, 871, 872, 366, 367, 368, 369, 302, 
+	302, 302, 302, 307, 870, 871, 872, 371, 
+	372, 302, 302, 302, 302, 307, 870, 871, 
+	872, 374, 375, 379, 302, 302, 302, 302, 
+	307, 870, 871, 872, 376, 377, 378, 302, 
+	302, 302, 302, 307, 870, 871, 872, 302, 
+	302, 302, 302, 307, 870, 871, 872, 381, 
+	383, 385, 387, 382, 302, 302, 302, 302, 
+	307, 870, 871, 872, 384, 302, 302, 302, 
+	302, 307, 870, 871, 872, 386, 302, 302, 
+	302, 302, 307, 870, 871, 872, 388, 389, 
+	390, 302, 302, 302, 302, 307, 870, 871, 
+	872, 392, 395, 397, 393, 394, 302, 302, 
+	302, 302, 307, 870, 871, 872, 396, 302, 
+	302, 302, 302, 307, 870, 871, 872, 398, 
+	399, 400, 302, 302, 302, 400, 302, 307, 
+	870, 871, 872, 402, 403, 404, 302, 302, 
+	302, 302, 307, 870, 871, 872, 406, 302, 
+	302, 302, 302, 307, 870, 871, 872, 0, 
+	408, 408, 408, 408, 415, 0, 409, 410, 
+	410, 410, 409, 410, 414, 0, 410, 410, 
+	410, 411, 410, 414, 412, 412, 412, 412, 
+	412, 413, 873, 874, 875, 417, 417, 417, 
+	417, 425, 418, 424, 876, 876, 876, 424, 
+	877, 876, 880, 419, 419, 419, 420, 419, 
+	423, 421, 421, 421, 421, 421, 422, 877, 
+	878, 879, 419, 419, 419, 419, 423, 0, 
+	427, 881, 427, 429, 882, 431, 432, 432, 
+	432, 432, 461, 432, 432, 432, 433, 432, 
+	461, 434, 434, 434, 434, 460, 0, 434, 
+	434, 434, 435, 434, 460, 436, 436, 436, 
+	435, 436, 459, 436, 436, 436, 437, 436, 
+	459, 0, 438, 438, 438, 437, 456, 456, 
+	456, 456, 456, 438, 455, 438, 438, 438, 
+	439, 438, 455, 440, 440, 440, 439, 452, 
+	452, 452, 452, 452, 440, 451, 440, 440, 
+	440, 441, 440, 451, 442, 442, 442, 441, 
+	448, 448, 448, 448, 448, 442, 447, 442, 
+	442, 442, 443, 442, 447, 883, 443, 444, 
+	444, 444, 444, 444, 445, 445, 446, 446, 
+	446, 446, 446, 883, 445, 449, 449, 450, 
+	450, 450, 450, 450, 442, 442, 442, 449, 
+	442, 447, 453, 453, 454, 454, 454, 454, 
+	454, 440, 440, 440, 453, 440, 451, 457, 
+	457, 458, 458, 458, 458, 458, 438, 438, 
+	438, 457, 438, 455, 463, 464, 464, 464, 
+	464, 466, 465, 464, 464, 464, 464, 466, 
+	884, 468, 469, 469, 469, 469, 471, 469, 
+	469, 469, 470, 469, 471, 885, 473, 474, 
+	474, 474, 473, 474, 476, 474, 474, 474, 
+	475, 474, 476, 886, 478, 479, 479, 479, 
+	479, 480, 887, 888, 889, 479, 479, 479, 
+	479, 480, 887, 888, 889, 482, 890, 482, 
+	0, 484, 485, 485, 485, 484, 485, 537, 
+	485, 485, 485, 486, 490, 532, 485, 537, 
+	487, 487, 487, 486, 487, 536, 487, 487, 
+	487, 488, 487, 536, 489, 489, 489, 534, 
+	488, 489, 533, 489, 489, 489, 489, 533, 
+	491, 491, 491, 491, 531, 492, 493, 493, 
+	493, 492, 493, 530, 493, 493, 493, 494, 
+	498, 525, 493, 530, 495, 495, 495, 494, 
+	495, 529, 495, 495, 495, 496, 495, 529, 
+	497, 497, 497, 527, 496, 497, 526, 497, 
+	497, 497, 497, 526, 499, 499, 499, 499, 
+	524, 500, 501, 501, 502, 502, 502, 521, 
+	501, 523, 502, 520, 891, 898, 899, 502, 
+	502, 502, 503, 502, 520, 891, 898, 899, 
+	504, 504, 504, 517, 503, 519, 504, 516, 
+	891, 896, 897, 504, 504, 504, 505, 504, 
+	516, 896, 897, 506, 506, 506, 513, 505, 
+	515, 506, 512, 891, 894, 895, 506, 506, 
+	506, 507, 506, 512, 894, 895, 508, 508, 
+	508, 510, 507, 508, 509, 891, 892, 893, 
+	508, 508, 508, 508, 509, 892, 893, 508, 
+	508, 508, 511, 508, 509, 891, 892, 893, 
+	511, 506, 506, 506, 514, 515, 506, 512, 
+	891, 894, 895, 514, 504, 504, 504, 518, 
+	519, 504, 516, 891, 896, 897, 518, 502, 
+	502, 502, 522, 523, 502, 520, 891, 898, 
+	899, 522, 499, 499, 499, 499, 524, 497, 
+	497, 497, 528, 497, 526, 528, 491, 491, 
+	491, 491, 531, 489, 489, 489, 535, 489, 
+	533, 535, 539, 540, 540, 540, 539, 540, 
+	548, 540, 540, 540, 541, 540, 548, 542, 
+	542, 542, 541, 542, 547, 542, 542, 542, 
+	543, 542, 547, 544, 544, 544, 543, 544, 
+	546, 544, 544, 544, 545, 544, 546, 900, 
+	550, 551, 551, 551, 550, 551, 565, 551, 
+	551, 551, 552, 551, 565, 553, 553, 553, 
+	552, 553, 564, 554, 553, 553, 553, 553, 
+	564, 555, 555, 555, 555, 563, 556, 555, 
+	555, 555, 555, 563, 557, 557, 557, 557, 
+	562, 558, 557, 557, 557, 557, 562, 559, 
+	559, 559, 559, 561, 559, 559, 559, 560, 
+	559, 561, 901, 567, 568, 568, 568, 567, 
+	568, 576, 568, 568, 568, 569, 568, 576, 
+	570, 570, 570, 569, 570, 575, 570, 570, 
+	570, 571, 570, 575, 572, 572, 572, 571, 
+	572, 574, 572, 572, 572, 573, 572, 574, 
+	902, 0, 577, 578, 577, 577, 579, 585, 
+	577, 584, 903, 904, 905, 579, 585, 580, 
+	0, 581, 581, 582, 583, 577, 577, 577, 
+	583, 577, 584, 903, 904, 905, 586, 587, 
+	587, 582, 589, 590, 590, 590, 589, 590, 
+	600, 590, 590, 590, 591, 590, 600, 592, 
+	592, 592, 591, 592, 599, 592, 592, 592, 
+	593, 592, 599, 594, 594, 594, 593, 594, 
+	598, 0, 594, 594, 594, 595, 594, 598, 
+	596, 596, 596, 596, 596, 597, 906, 907, 
+	908, 602, 603, 603, 603, 602, 603, 610, 
+	603, 603, 603, 604, 603, 610, 605, 605, 
+	605, 604, 605, 609, 605, 605, 605, 606, 
+	605, 609, 607, 607, 607, 607, 607, 608, 
+	909, 910, 911, 612, 613, 613, 613, 612, 
+	613, 649, 0, 613, 613, 613, 614, 628, 
+	635, 642, 613, 649, 615, 615, 615, 615, 
+	627, 0, 616, 617, 617, 617, 616, 617, 
+	626, 617, 617, 617, 618, 617, 626, 0, 
+	619, 619, 619, 622, 622, 622, 624, 624, 
+	624, 912, 619, 621, 915, 916, 622, 623, 
+	913, 914, 624, 625, 917, 918, 0, 620, 
+	629, 629, 629, 629, 634, 630, 631, 631, 
+	631, 630, 631, 633, 0, 631, 631, 631, 
+	632, 631, 633, 0, 632, 619, 619, 619, 
+	622, 622, 622, 624, 624, 624, 912, 619, 
+	621, 915, 916, 622, 623, 913, 914, 624, 
+	625, 917, 918, 636, 636, 636, 636, 641, 
+	637, 638, 638, 638, 637, 638, 640, 638, 
+	638, 638, 639, 638, 640, 639, 619, 619, 
+	619, 622, 622, 622, 624, 624, 624, 912, 
+	619, 621, 915, 916, 622, 623, 913, 914, 
+	624, 625, 917, 918, 643, 643, 643, 643, 
+	648, 644, 645, 645, 645, 644, 645, 647, 
+	645, 645, 645, 646, 645, 647, 619, 619, 
+	619, 622, 622, 622, 624, 624, 624, 912, 
+	619, 621, 915, 916, 622, 623, 913, 914, 
+	624, 625, 917, 918, 0, 651, 685, 693, 
+	707, 712, 720, 724, 727, 733, 747, 750, 
+	757, 768, 652, 652, 652, 676, 679, 683, 
+	652, 675, 652, 652, 652, 653, 652, 675, 
+	654, 654, 654, 653, 654, 674, 654, 654, 
+	654, 655, 654, 674, 656, 656, 656, 655, 
+	656, 673, 656, 656, 656, 657, 656, 673, 
+	658, 658, 658, 657, 658, 672, 0, 658, 
+	658, 658, 659, 658, 672, 660, 660, 660, 
+	659, 660, 671, 660, 660, 660, 661, 660, 
+	671, 662, 662, 662, 661, 662, 670, 662, 
+	662, 662, 663, 662, 670, 664, 664, 664, 
+	663, 664, 669, 664, 664, 664, 665, 664, 
+	669, 666, 666, 666, 666, 668, 666, 666, 
+	666, 667, 666, 668, 919, 677, 678, 652, 
+	652, 652, 652, 675, 680, 681, 682, 652, 
+	652, 652, 652, 675, 684, 652, 652, 652, 
+	652, 675, 686, 689, 687, 688, 652, 652, 
+	652, 652, 675, 690, 691, 692, 652, 652, 
+	652, 652, 675, 694, 698, 706, 695, 696, 
+	697, 652, 652, 652, 652, 675, 699, 702, 
+	700, 701, 652, 652, 652, 652, 675, 703, 
+	704, 705, 652, 652, 652, 652, 675, 652, 
+	652, 652, 652, 675, 708, 709, 710, 711, 
+	652, 652, 652, 652, 675, 713, 714, 715, 
+	716, 717, 718, 719, 652, 652, 652, 652, 
+	675, 721, 723, 722, 652, 652, 652, 652, 
+	675, 652, 652, 652, 652, 675, 725, 726, 
+	652, 652, 652, 652, 675, 728, 732, 729, 
+	730, 731, 652, 652, 652, 652, 675, 652, 
+	652, 652, 652, 675, 734, 738, 735, 736, 
+	737, 652, 652, 652, 652, 675, 652, 652, 
+	652, 739, 652, 675, 740, 652, 652, 652, 
+	741, 652, 675, 652, 652, 652, 742, 652, 
+	675, 743, 744, 745, 746, 652, 652, 652, 
+	652, 675, 748, 749, 652, 652, 652, 652, 
+	675, 751, 752, 756, 652, 652, 652, 652, 
+	675, 753, 754, 755, 652, 652, 652, 652, 
+	675, 652, 652, 652, 652, 675, 758, 760, 
+	762, 764, 759, 652, 652, 652, 652, 675, 
+	761, 652, 652, 652, 652, 675, 763, 652, 
+	652, 652, 652, 675, 765, 766, 767, 652, 
+	652, 652, 652, 675, 769, 772, 774, 770, 
+	771, 652, 652, 652, 652, 675, 773, 652, 
+	652, 652, 652, 675, 775, 776, 0, 777, 
+	652, 652, 652, 777, 652, 675, 779, 780, 
+	920, 782, 783, 783, 783, 782, 783, 791, 
+	783, 783, 783, 784, 783, 791, 785, 785, 
+	785, 784, 785, 790, 785, 785, 785, 786, 
+	785, 790, 787, 787, 787, 786, 787, 789, 
+	787, 787, 787, 788, 787, 789, 921, 793, 
+	922, 795, 796, 796, 796, 795, 796, 822, 
+	796, 796, 796, 797, 796, 822, 798, 798, 
+	798, 797, 798, 821, 798, 798, 798, 799, 
+	798, 821, 800, 800, 800, 799, 800, 820, 
+	800, 800, 800, 801, 818, 800, 820, 802, 
+	802, 802, 802, 817, 0, 802, 802, 802, 
+	803, 802, 817, 804, 805, 815, 806, 807, 
+	814, 808, 812, 809, 810, 810, 811, 803, 
+	923, 813, 816, 819, 818, 824, 825, 825, 
+	825, 824, 825, 835, 825, 825, 825, 826, 
+	825, 835, 827, 827, 827, 826, 827, 834, 
+	827, 827, 827, 828, 827, 834, 829, 829, 
+	829, 828, 829, 833, 829, 829, 829, 830, 
+	831, 829, 833, 924, 832, 831, 837, 838, 
+	838, 838, 837, 838, 848, 838, 838, 838, 
+	839, 838, 848, 840, 840, 840, 839, 840, 
+	847, 840, 840, 840, 841, 840, 847, 842, 
+	842, 842, 841, 842, 846, 842, 842, 842, 
+	843, 842, 846, 844, 844, 844, 844, 844, 
+	845, 925, 926, 927, 0, 1, 125, 1, 
+	1, 133, 854, 226, 14, 165, 14, 14, 
+	175, 193, 857, 207, 858, 210, 0, 115, 
+	115, 115, 143, 214, 215, 216, 228, 218, 
+	219, 220, 221, 222, 223, 224, 225, 852, 
+	227, 0, 136, 143, 214, 215, 216, 217, 
+	218, 219, 220, 221, 222, 223, 224, 225, 
+	0, 1, 125, 1, 1, 133, 849, 124, 
+	854, 226, 1, 1, 854, 147, 147, 147, 
+	854, 148, 151, 151, 151, 164, 197, 0, 
+	176, 179, 181, 182, 183, 184, 185, 186, 
+	187, 188, 189, 190, 191, 192, 854
+};
+
+static const short _zone_scanner_trans_actions[] = {
+	1626, 0, 5, 7, 470, 617, 617, 617, 
+	617, 617, 617, 617, 617, 617, 617, 617, 
+	617, 617, 3, 0, 3, 0, 1766, 101, 
+	632, 635, 41, 55, 53, 51, 0, 57, 
+	629, 101, 309, 0, 5, 7, 95, 95, 
+	95, 95, 95, 95, 95, 95, 95, 95, 
+	95, 95, 95, 3, 0, 1364, 1367, 2090, 
+	2094, 0, 0, 0, 2086, 1367, 2098, 3061, 
+	2098, 303, 0, 301, 5, 7, 0, 3, 
+	0, 303, 320, 303, 1343, 307, 1352, 1355, 
+	2078, 307, 9, 0, 5, 7, 1463, 0, 
+	1358, 305, 0, 5, 7, 0, 2074, 303, 
+	303, 323, 0, 2696, 5, 7, 1614, 1850, 
+	1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 
+	1850, 1850, 1850, 1850, 3, 0, 1346, 303, 
+	320, 303, 3332, 638, 1854, 1858, 2866, 638, 
+	1361, 0, 5, 7, 323, 0, 0, 0, 
+	0, 0, 1421, 2382, 2386, 2378, 1421, 2390, 
+	3166, 2390, 0, 5, 7, 0, 0, 0, 
+	1373, 2126, 2130, 2122, 1373, 2134, 3086, 2134, 
+	0, 0, 0, 0, 0, 0, 1448, 2526, 
+	2530, 2522, 1448, 2534, 3211, 2534, 0, 0, 
+	0, 0, 1424, 2398, 2402, 2394, 1424, 2406, 
+	3171, 2406, 0, 0, 0, 1445, 2510, 2514, 
+	2506, 1445, 2518, 3206, 2518, 1430, 2430, 2434, 
+	2426, 1430, 2438, 3181, 2438, 0, 0, 0, 
+	0, 1382, 2174, 2178, 2170, 1382, 2182, 3101, 
+	2182, 0, 0, 99, 623, 626, 620, 99, 
+	0, 5, 7, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	3, 0, 0, 0, 0, 0, 0, 0, 
+	1436, 2462, 2466, 2458, 1436, 2470, 3191, 2470, 
+	0, 0, 0, 1403, 2286, 2290, 2282, 1403, 
+	2294, 3136, 2294, 1418, 2366, 2370, 2362, 1418, 
+	2374, 3161, 2374, 0, 0, 1409, 2318, 2322, 
+	2314, 1409, 2326, 3146, 2326, 0, 0, 0, 
+	0, 0, 1385, 2190, 2194, 2186, 1385, 2198, 
+	3106, 2198, 1388, 2206, 2210, 2202, 1388, 2214, 
+	3111, 2214, 0, 0, 0, 0, 0, 1415, 
+	2350, 2354, 2346, 1415, 2358, 3156, 2358, 1370, 
+	2110, 2114, 0, 2106, 1370, 2118, 3081, 2118, 
+	0, 1442, 2494, 2498, 0, 2490, 1442, 2502, 
+	3201, 2502, 1451, 2542, 2546, 0, 2538, 1451, 
+	2550, 3216, 2550, 0, 0, 0, 0, 1454, 
+	2558, 2562, 2554, 1454, 2566, 3221, 2566, 0, 
+	0, 1379, 2158, 2162, 2154, 1379, 2166, 3096, 
+	2166, 0, 0, 0, 1394, 2238, 2242, 2234, 
+	1394, 2246, 3121, 2246, 0, 0, 0, 1439, 
+	2478, 2482, 2474, 1439, 2486, 3196, 2486, 1400, 
+	2270, 2274, 2266, 1400, 2278, 3131, 2278, 0, 
+	0, 0, 0, 0, 1376, 2142, 2146, 2138, 
+	1376, 2150, 3091, 2150, 0, 1460, 2590, 2594, 
+	2586, 1460, 2598, 3231, 2598, 0, 1412, 2334, 
+	2338, 2330, 1412, 2342, 3151, 2342, 0, 0, 
+	0, 1433, 2446, 2450, 2442, 1433, 2454, 3186, 
+	2454, 0, 0, 0, 0, 0, 1457, 2574, 
+	2578, 2570, 1457, 2582, 3226, 2582, 0, 1391, 
+	2222, 2226, 2218, 1391, 2230, 3116, 2230, 0, 
+	0, 482, 470, 1630, 536, 1746, 1750, 41, 
+	1742, 536, 1754, 2826, 1754, 0, 5, 7, 
+	3, 0, 0, 99, 623, 626, 620, 99, 
+	0, 5, 7, 470, 97, 97, 97, 97, 
+	97, 97, 97, 97, 97, 97, 97, 97, 
+	97, 3, 0, 101, 632, 635, 41, 55, 
+	53, 51, 0, 57, 629, 101, 1770, 41, 
+	55, 53, 51, 0, 57, 557, 1794, 1798, 
+	2836, 1790, 557, 93, 89, 89, 89, 0, 
+	0, 0, 0, 0, 0, 87, 37, 33, 
+	419, 422, 416, 33, 0, 5, 7, 3, 
+	0, 0, 2681, 425, 1550, 1558, 1546, 425, 
+	0, 5, 7, 3, 0, 1770, 41, 55, 
+	53, 51, 0, 57, 557, 1794, 1798, 2836, 
+	1790, 557, 1590, 1574, 2646, 2661, 2631, 1574, 
+	3248, 2666, 0, 5, 7, 3, 0, 320, 
+	303, 2082, 2102, 3066, 3071, 3350, 2102, 3405, 
+	3076, 3398, 3076, 0, 5, 7, 1498, 0, 
+	5, 7, 323, 0, 0, 5, 7, 0, 
+	5, 7, 0, 303, 323, 2066, 0, 0, 
+	0, 0, 0, 79, 0, 0, 75, 1582, 
+	428, 1554, 1562, 2621, 428, 3363, 1566, 2636, 
+	2651, 3242, 1566, 0, 5, 7, 323, 0, 
+	2686, 2671, 3254, 3260, 3356, 2671, 3412, 3266, 
+	0, 5, 7, 1498, 1570, 443, 2641, 2656, 
+	2626, 1570, 307, 329, 335, 1502, 307, 307, 
+	1352, 1355, 0, 5, 7, 0, 5, 7, 
+	0, 0, 1406, 2302, 2306, 2298, 1406, 2310, 
+	3141, 2310, 0, 0, 0, 1397, 2254, 2258, 
+	2250, 1397, 2262, 3126, 2262, 0, 1427, 2414, 
+	2418, 2410, 1427, 2422, 3176, 2422, 0, 5, 
+	7, 0, 5, 7, 0, 5, 7, 0, 
+	5, 7, 446, 344, 2606, 11, 1510, 27, 
+	1526, 1526, 25, 0, 383, 1514, 17, 368, 
+	347, 347, 13, 15, 0, 350, 359, 19, 
+	19, 2611, 353, 356, 21, 380, 578, 65, 
+	0, 0, 1, 575, 581, 1806, 69, 69, 
+	584, 587, 1802, 71, 65, 0, 0, 67, 
+	581, 69, 69, 587, 71, 71, 73, 0, 
+	5, 7, 3, 0, 473, 470, 2831, 0, 
+	5, 7, 41, 55, 53, 51, 0, 57, 
+	1810, 0, 338, 1770, 1758, 41, 55, 53, 
+	51, 0, 57, 59, 548, 551, 2836, 2841, 
+	59, 77, 0, 5, 7, 3, 0, 2846, 
+	2846, 590, 1814, 17, 341, 23, 371, 374, 
+	347, 347, 13, 2616, 23, 0, 5, 7, 
+	1818, 0, 15, 0, 350, 362, 19, 19, 
+	353, 356, 21, 0, 5, 7, 3, 0, 
+	593, 83, 602, 81, 596, 599, 2851, 81, 
+	81, 608, 0, 5, 7, 2856, 2856, 605, 
+	1822, 1826, 0, 0, 85, 17, 377, 1518, 
+	1522, 347, 347, 13, 3236, 377, 0, 5, 
+	7, 15, 0, 350, 365, 19, 19, 353, 
+	356, 21, 1478, 0, 5, 7, 3, 0, 
+	125, 117, 119, 121, 0, 123, 0, 5, 
+	7, 3, 0, 1, 314, 1, 285, 283, 
+	1274, 1277, 1271, 283, 2058, 3056, 2058, 0, 
+	5, 7, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 3, 
+	0, 1280, 1486, 1280, 219, 986, 989, 0, 
+	0, 0, 983, 219, 1930, 2896, 1930, 0, 
+	0, 245, 1103, 1106, 1100, 245, 1982, 2961, 
+	1982, 0, 0, 0, 0, 255, 1148, 1151, 
+	1145, 255, 2002, 2986, 2002, 0, 0, 0, 
+	223, 1004, 1007, 1001, 223, 1938, 2906, 1938, 
+	0, 0, 0, 0, 0, 0, 273, 1229, 
+	1232, 1226, 273, 2038, 3031, 2038, 0, 0, 
+	0, 0, 257, 1157, 1160, 1154, 257, 2006, 
+	2991, 2006, 0, 0, 0, 271, 1220, 1223, 
+	1217, 271, 2034, 3026, 2034, 261, 1175, 1178, 
+	1172, 261, 2014, 3001, 2014, 0, 0, 0, 
+	0, 229, 1031, 1034, 1028, 229, 1950, 2921, 
+	1950, 0, 0, 0, 0, 0, 0, 0, 
+	265, 1193, 1196, 1190, 265, 2022, 3011, 2022, 
+	0, 0, 0, 243, 1094, 1097, 1091, 243, 
+	1978, 2956, 1978, 253, 1139, 1142, 1136, 253, 
+	1998, 2981, 1998, 0, 0, 247, 1112, 1115, 
+	1109, 247, 1986, 2966, 1986, 0, 0, 0, 
+	0, 0, 231, 1040, 1043, 1037, 231, 1954, 
+	2926, 1954, 233, 1049, 1052, 1046, 233, 1958, 
+	2931, 1958, 0, 0, 0, 0, 0, 251, 
+	1130, 1133, 1127, 251, 1994, 2976, 1994, 221, 
+	995, 998, 0, 992, 221, 1934, 2901, 1934, 
+	0, 269, 1211, 1214, 0, 1208, 269, 2030, 
+	3021, 2030, 275, 1238, 1241, 0, 1235, 275, 
+	2042, 3036, 2042, 0, 0, 0, 0, 277, 
+	1247, 1250, 1244, 277, 2046, 3041, 2046, 0, 
+	0, 227, 1022, 1025, 1019, 227, 1946, 2916, 
+	1946, 0, 0, 0, 237, 1067, 1070, 1064, 
+	237, 1966, 2941, 1966, 0, 0, 0, 267, 
+	1202, 1205, 1199, 267, 2026, 3016, 2026, 241, 
+	1085, 1088, 1082, 241, 1974, 2951, 1974, 0, 
+	0, 0, 0, 0, 225, 1013, 1016, 1010, 
+	225, 1942, 2911, 1942, 0, 281, 1265, 1268, 
+	1262, 281, 2054, 3051, 2054, 0, 249, 1121, 
+	1124, 1118, 249, 1990, 2971, 1990, 0, 0, 
+	0, 263, 1184, 1187, 1181, 263, 2018, 3006, 
+	2018, 0, 0, 0, 0, 0, 279, 1256, 
+	1259, 1253, 279, 2050, 3046, 2050, 0, 235, 
+	1058, 1061, 1055, 235, 1962, 2936, 1962, 0, 
+	0, 470, 217, 977, 980, 41, 974, 217, 
+	1926, 2891, 1926, 0, 0, 0, 239, 1076, 
+	1079, 1073, 239, 1970, 2946, 1970, 0, 259, 
+	1166, 1169, 1163, 259, 2010, 2996, 2010, 299, 
+	0, 5, 7, 3, 0, 476, 470, 49, 
+	542, 545, 41, 539, 49, 1918, 0, 5, 
+	7, 113, 3, 0, 115, 0, 5, 7, 
+	3, 0, 671, 1482, 671, 0, 5, 7, 
+	3, 0, 470, 470, 311, 1470, 1474, 41, 
+	1, 1466, 311, 0, 5, 7, 113, 3, 
+	0, 115, 0, 5, 7, 3, 0, 671, 
+	1482, 671, 49, 542, 545, 539, 49, 644, 
+	641, 1870, 103, 449, 452, 449, 464, 1602, 
+	1606, 1598, 464, 0, 5, 7, 449, 3, 
+	0, 464, 1602, 1606, 1598, 464, 479, 0, 
+	5, 7, 470, 3, 0, 47, 530, 533, 
+	41, 527, 47, 0, 5, 7, 470, 3, 
+	0, 1762, 47, 530, 533, 41, 55, 53, 
+	51, 0, 57, 527, 47, 0, 5, 7, 
+	470, 3, 0, 47, 530, 533, 41, 55, 
+	53, 51, 0, 57, 527, 47, 0, 5, 
+	7, 470, 3, 0, 47, 530, 533, 41, 
+	55, 53, 51, 0, 57, 527, 47, 0, 
+	5, 7, 470, 3, 0, 524, 41, 55, 
+	53, 51, 0, 57, 1770, 41, 55, 53, 
+	51, 0, 57, 1774, 2836, 1770, 41, 55, 
+	53, 51, 0, 57, 554, 1782, 1786, 2836, 
+	1778, 554, 1770, 41, 55, 53, 51, 0, 
+	57, 554, 1782, 1786, 2836, 1778, 554, 1770, 
+	41, 55, 53, 51, 0, 57, 554, 1782, 
+	1786, 2836, 1778, 554, 386, 31, 401, 404, 
+	398, 31, 386, 0, 5, 7, 3, 0, 
+	395, 449, 464, 1602, 1606, 1598, 464, 0, 
+	5, 7, 449, 3, 0, 452, 470, 521, 
+	1734, 1738, 41, 1730, 521, 0, 5, 7, 
+	449, 3, 0, 452, 386, 31, 401, 404, 
+	398, 31, 395, 1530, 395, 0, 5, 7, 
+	3, 0, 1, 314, 1, 641, 1886, 103, 
+	1340, 2062, 287, 1286, 1289, 41, 1283, 287, 
+	0, 5, 7, 470, 0, 0, 3, 0, 
+	291, 1304, 1307, 41, 1301, 291, 0, 5, 
+	7, 2821, 3, 0, 485, 1662, 1666, 0, 
+	41, 1658, 485, 0, 5, 7, 3, 0, 
+	0, 5, 7, 3, 0, 470, 289, 1295, 
+	1298, 41, 1292, 289, 0, 5, 7, 470, 
+	0, 0, 3, 0, 293, 1313, 1316, 41, 
+	1310, 293, 0, 5, 7, 2821, 3, 0, 
+	488, 1674, 1678, 0, 41, 1670, 488, 0, 
+	5, 7, 3, 0, 0, 5, 7, 3, 
+	0, 0, 2816, 3344, 491, 1686, 1690, 0, 
+	41, 491, 1682, 491, 2796, 3308, 2796, 0, 
+	5, 7, 2816, 3, 0, 1337, 1490, 1337, 
+	494, 1698, 1702, 0, 41, 494, 1694, 494, 
+	2801, 3314, 2801, 0, 5, 7, 2816, 3, 
+	0, 1490, 1337, 497, 1710, 1714, 0, 41, 
+	497, 1706, 497, 2806, 3320, 2806, 0, 5, 
+	7, 2816, 3, 0, 1490, 1337, 500, 1722, 
+	1726, 0, 41, 1718, 500, 2811, 3326, 2811, 
+	0, 5, 7, 3, 0, 1490, 1337, 1654, 
+	2786, 2791, 2701, 2781, 1654, 3302, 3391, 3302, 
+	467, 1650, 2771, 2776, 2701, 1650, 2766, 1650, 
+	3296, 3384, 3296, 467, 1646, 2756, 2761, 2701, 
+	1646, 2751, 1646, 3290, 3377, 3290, 467, 1642, 
+	2741, 2746, 2701, 1642, 2736, 1642, 3284, 3370, 
+	3284, 467, 297, 1331, 1334, 1328, 297, 1638, 
+	2726, 2731, 2701, 2721, 1638, 467, 295, 1322, 
+	1325, 1319, 295, 1634, 2711, 2716, 2701, 2706, 
+	1634, 467, 470, 45, 515, 518, 41, 512, 
+	45, 0, 5, 7, 470, 3, 0, 45, 
+	515, 518, 41, 512, 45, 0, 5, 7, 
+	470, 3, 0, 521, 1734, 1738, 41, 1730, 
+	521, 0, 5, 7, 449, 3, 0, 452, 
+	470, 45, 515, 518, 41, 512, 45, 0, 
+	5, 7, 470, 3, 0, 45, 515, 518, 
+	41, 512, 45, 386, 0, 5, 7, 3, 
+	0, 31, 401, 404, 398, 31, 386, 0, 
+	5, 7, 3, 0, 31, 401, 404, 398, 
+	31, 386, 0, 5, 7, 3, 0, 407, 
+	1538, 1542, 1534, 407, 0, 5, 7, 449, 
+	3, 0, 452, 470, 45, 515, 518, 41, 
+	512, 45, 0, 5, 7, 470, 3, 0, 
+	45, 515, 518, 41, 512, 45, 0, 5, 
+	7, 470, 3, 0, 43, 506, 509, 41, 
+	503, 43, 0, 5, 7, 127, 3, 0, 
+	1, 665, 0, 653, 5, 7, 656, 659, 
+	3, 0, 1, 314, 1, 109, 111, 0, 
+	1862, 641, 103, 105, 470, 662, 1910, 1914, 
+	41, 1906, 662, 1902, 2886, 1902, 0, 641, 
+	103, 107, 470, 45, 515, 518, 41, 512, 
+	45, 0, 5, 7, 470, 3, 0, 43, 
+	506, 509, 41, 503, 43, 0, 5, 7, 
+	470, 3, 0, 43, 506, 509, 41, 503, 
+	43, 668, 0, 5, 7, 113, 3, 0, 
+	115, 0, 5, 7, 3, 0, 1, 314, 
+	1, 470, 43, 506, 509, 41, 503, 43, 
+	0, 5, 7, 470, 3, 0, 43, 506, 
+	509, 41, 503, 43, 0, 5, 7, 113, 
+	3, 0, 115, 0, 5, 7, 3, 0, 
+	1, 314, 1, 470, 43, 506, 509, 41, 
+	503, 43, 677, 0, 5, 7, 145, 147, 
+	149, 151, 3, 0, 0, 5, 7, 3, 
+	0, 1618, 470, 43, 506, 509, 41, 503, 
+	43, 0, 5, 7, 0, 3, 0, 1922, 
+	0, 5, 7, 0, 5, 7, 0, 5, 
+	7, 1, 3, 0, 314, 1, 3, 0, 
+	314, 1, 3, 0, 314, 1, 680, 127, 
+	0, 5, 7, 3, 0, 470, 43, 506, 
+	509, 41, 503, 43, 1866, 0, 5, 7, 
+	641, 3, 0, 2871, 103, 647, 1878, 1882, 
+	647, 1878, 1882, 647, 1878, 1882, 1870, 1874, 
+	647, 2876, 1870, 1874, 647, 2876, 1870, 1874, 
+	647, 2876, 1870, 0, 5, 7, 3, 0, 
+	470, 43, 506, 509, 41, 503, 43, 0, 
+	5, 7, 641, 3, 0, 103, 650, 1894, 
+	1898, 650, 1894, 1898, 650, 1894, 1898, 1886, 
+	1890, 650, 2881, 1886, 1890, 650, 2881, 1886, 
+	1890, 650, 2881, 1886, 0, 5, 7, 3, 
+	0, 470, 43, 506, 509, 41, 503, 43, 
+	0, 5, 7, 449, 3, 0, 39, 458, 
+	461, 39, 458, 461, 39, 458, 461, 452, 
+	455, 39, 1594, 452, 455, 39, 1594, 452, 
+	455, 39, 1594, 452, 683, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 153, 689, 692, 0, 0, 0, 
+	686, 153, 0, 5, 7, 470, 3, 0, 
+	43, 506, 509, 41, 503, 43, 0, 5, 
+	7, 470, 3, 0, 43, 506, 509, 41, 
+	503, 43, 0, 5, 7, 470, 3, 0, 
+	47, 530, 533, 41, 527, 47, 572, 0, 
+	5, 7, 560, 3, 0, 63, 566, 569, 
+	61, 563, 63, 0, 5, 7, 560, 3, 
+	0, 63, 566, 569, 61, 563, 63, 0, 
+	5, 7, 470, 3, 0, 521, 1734, 1738, 
+	41, 1730, 521, 0, 5, 7, 449, 3, 
+	0, 464, 1602, 1606, 1598, 464, 0, 5, 
+	7, 127, 3, 0, 1, 0, 0, 179, 
+	806, 809, 803, 179, 0, 0, 0, 173, 
+	779, 782, 776, 173, 0, 193, 869, 872, 
+	866, 193, 0, 0, 0, 0, 189, 851, 
+	854, 848, 189, 0, 0, 0, 157, 707, 
+	710, 704, 157, 0, 0, 0, 0, 0, 
+	0, 207, 932, 935, 929, 207, 0, 0, 
+	0, 0, 191, 860, 863, 857, 191, 0, 
+	0, 0, 205, 923, 926, 920, 205, 195, 
+	878, 881, 875, 195, 0, 0, 0, 0, 
+	163, 734, 737, 731, 163, 0, 0, 0, 
+	0, 0, 0, 0, 199, 896, 899, 893, 
+	199, 0, 0, 0, 177, 797, 800, 794, 
+	177, 187, 842, 845, 839, 187, 0, 0, 
+	181, 815, 818, 812, 181, 0, 0, 0, 
+	0, 0, 165, 743, 746, 740, 165, 167, 
+	752, 755, 749, 167, 0, 0, 0, 0, 
+	0, 185, 833, 836, 830, 185, 155, 698, 
+	701, 0, 695, 155, 0, 203, 914, 917, 
+	0, 911, 203, 209, 941, 944, 0, 938, 
+	209, 0, 0, 0, 0, 211, 950, 953, 
+	947, 211, 0, 0, 161, 725, 728, 722, 
+	161, 0, 0, 0, 171, 770, 773, 767, 
+	171, 0, 0, 0, 201, 905, 908, 902, 
+	201, 175, 788, 791, 785, 175, 0, 0, 
+	0, 0, 0, 159, 716, 719, 713, 159, 
+	0, 215, 968, 971, 965, 215, 0, 183, 
+	824, 827, 821, 183, 0, 0, 0, 197, 
+	887, 890, 884, 197, 0, 0, 0, 0, 
+	0, 213, 959, 962, 956, 213, 0, 169, 
+	761, 764, 758, 169, 0, 0, 1622, 470, 
+	45, 515, 518, 41, 512, 45, 449, 1610, 
+	1, 470, 45, 515, 518, 41, 512, 45, 
+	0, 5, 7, 470, 3, 0, 43, 506, 
+	509, 41, 503, 43, 0, 5, 7, 470, 
+	3, 0, 43, 506, 509, 41, 503, 43, 
+	0, 5, 7, 127, 3, 0, 1, 127, 
+	1, 470, 43, 506, 509, 41, 503, 43, 
+	0, 5, 7, 470, 3, 0, 43, 506, 
+	509, 41, 503, 43, 0, 5, 7, 470, 
+	3, 0, 45, 515, 518, 41, 512, 45, 
+	0, 5, 7, 29, 389, 3, 0, 31, 
+	401, 404, 398, 31, 674, 0, 5, 7, 
+	392, 3, 0, 131, 133, 0, 135, 137, 
+	0, 139, 0, 141, 143, 0, 410, 129, 
+	1, 0, 0, 115, 113, 470, 43, 506, 
+	509, 41, 503, 43, 0, 5, 7, 470, 
+	3, 0, 43, 506, 509, 41, 503, 43, 
+	0, 5, 7, 470, 3, 0, 45, 515, 
+	518, 41, 512, 45, 0, 5, 7, 29, 
+	389, 3, 0, 395, 115, 113, 470, 43, 
+	506, 509, 41, 503, 43, 0, 5, 7, 
+	470, 3, 0, 43, 506, 509, 41, 503, 
+	43, 0, 5, 7, 470, 3, 0, 43, 
+	506, 509, 41, 503, 43, 0, 5, 7, 
+	113, 3, 0, 115, 0, 5, 7, 3, 
+	0, 1, 314, 1, 440, 35, 0, 434, 
+	437, 413, 431, 35, 35, 303, 326, 332, 
+	2070, 413, 317, 35, 1494, 1349, 1586, 35, 
+	326, 332, 1846, 1846, 1846, 1846, 1846, 1846, 
+	1846, 1846, 1846, 1846, 1846, 1846, 1846, 317, 
+	35, 2676, 2691, 2861, 2861, 2861, 2861, 2861, 
+	2861, 2861, 2861, 2861, 2861, 2861, 2861, 2861, 
+	1578, 614, 91, 1838, 1842, 1830, 611, 91, 
+	1834, 614, 326, 332, 317, 35, 326, 332, 
+	2602, 35, 35, 326, 332, 35, 1349, 3272, 
+	3278, 3338, 3338, 3338, 3338, 3338, 3338, 3338, 
+	3338, 3338, 3338, 3338, 3338, 3338, 1506
+};
+
+static const short _zone_scanner_eof_actions[] = {
+	0, 1626, 1766, 309, 1364, 301, 1343, 9, 
+	9, 301, 1343, 301, 1343, 1343, 2696, 3332, 
+	1361, 309, 309, 309, 1364, 1343, 309, 309, 
+	309, 1364, 309, 309, 309, 309, 1364, 309, 
+	309, 309, 1364, 309, 309, 309, 1364, 1364, 
+	309, 309, 309, 309, 1364, 309, 309, 309, 
+	309, 309, 309, 309, 309, 309, 309, 1364, 
+	309, 309, 1364, 1364, 309, 309, 1364, 309, 
+	309, 309, 309, 1364, 1364, 309, 309, 309, 
+	309, 1364, 1364, 309, 1364, 1364, 309, 309, 
+	309, 309, 1364, 309, 309, 1364, 309, 1364, 
+	309, 309, 309, 1364, 1364, 309, 309, 1364, 
+	309, 1364, 309, 1364, 309, 309, 309, 1364, 
+	309, 309, 309, 1364, 309, 1364, 309, 309, 
+	482, 1630, 309, 1626, 309, 309, 482, 1766, 
+	1766, 1766, 1766, 309, 9, 93, 93, 93, 
+	93, 93, 93, 93, 93, 37, 482, 0, 
+	2681, 482, 309, 1766, 1766, 1766, 309, 1590, 
+	1630, 2082, 1343, 1626, 9, 1343, 9, 2696, 
+	2082, 2082, 2082, 2082, 2082, 2082, 2082, 2082, 
+	2082, 2082, 2082, 2082, 1343, 2066, 93, 93, 
+	93, 93, 93, 93, 93, 93, 93, 1582, 
+	3363, 1626, 1361, 2686, 2696, 2686, 2686, 2686, 
+	2686, 2686, 2686, 2686, 2686, 2686, 2686, 2686, 
+	2686, 443, 2696, 1343, 9, 1343, 309, 309, 
+	1364, 309, 309, 309, 1364, 309, 1364, 1343, 
+	1343, 9, 1343, 1343, 301, 1343, 446, 446, 
+	446, 446, 446, 446, 446, 446, 446, 446, 
+	446, 446, 9, 1361, 446, 1361, 0, 0, 
+	27, 27, 27, 27, 359, 359, 359, 359, 
+	27, 27, 578, 578, 1806, 1806, 1806, 1806, 
+	578, 67, 1806, 1806, 1806, 1806, 73, 473, 
+	2831, 338, 338, 2831, 1758, 2831, 73, 77, 
+	77, 77, 341, 341, 341, 77, 362, 362, 
+	362, 362, 341, 77, 0, 83, 602, 608, 
+	85, 608, 9, 9, 85, 365, 365, 365, 
+	365, 608, 9, 85, 0, 0, 125, 125, 
+	125, 125, 125, 125, 125, 285, 285, 285, 
+	285, 285, 285, 285, 285, 285, 285, 285, 
+	285, 285, 285, 285, 285, 285, 285, 285, 
+	285, 285, 285, 285, 285, 285, 285, 285, 
+	285, 285, 285, 285, 285, 285, 285, 285, 
+	285, 285, 285, 285, 285, 285, 285, 285, 
+	285, 285, 285, 285, 285, 285, 285, 285, 
+	285, 285, 285, 285, 285, 285, 285, 285, 
+	285, 285, 285, 285, 285, 285, 285, 285, 
+	285, 285, 285, 285, 285, 285, 285, 285, 
+	285, 285, 285, 285, 285, 285, 285, 285, 
+	285, 285, 285, 285, 285, 285, 285, 285, 
+	285, 285, 285, 285, 285, 285, 285, 285, 
+	285, 285, 285, 285, 285, 285, 285, 299, 
+	476, 476, 1918, 1918, 1918, 1918, 299, 299, 
+	299, 476, 476, 1918, 1918, 1918, 1918, 299, 
+	476, 299, 644, 644, 301, 301, 301, 301, 
+	301, 301, 479, 479, 479, 1762, 479, 1762, 
+	479, 1762, 479, 1762, 1762, 1762, 1762, 301, 
+	1762, 1762, 1762, 301, 1762, 1762, 1762, 301, 
+	1762, 1762, 1762, 301, 301, 301, 301, 301, 
+	301, 301, 301, 301, 301, 301, 301, 301, 
+	479, 479, 301, 301, 301, 301, 301, 301, 
+	301, 644, 644, 1340, 1340, 1340, 1340, 1340, 
+	1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 
+	1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 
+	1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 
+	1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 
+	1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 
+	1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340, 
+	1340, 1340, 479, 479, 479, 479, 479, 479, 
+	301, 301, 301, 301, 301, 479, 479, 479, 
+	479, 301, 301, 301, 301, 301, 301, 301, 
+	301, 301, 301, 301, 301, 301, 479, 479, 
+	479, 479, 479, 479, 301, 301, 301, 301, 
+	301, 665, 665, 665, 1862, 1862, 665, 665, 
+	301, 665, 1862, 1862, 479, 479, 479, 479, 
+	479, 479, 668, 668, 668, 668, 301, 301, 
+	301, 479, 479, 479, 479, 668, 668, 668, 
+	668, 301, 301, 479, 479, 677, 677, 1618, 
+	1618, 677, 1922, 680, 680, 680, 680, 680, 
+	680, 680, 677, 677, 677, 1618, 1618, 1866, 
+	2871, 677, 677, 677, 1618, 1618, 1866, 2871, 
+	677, 677, 677, 1618, 1618, 677, 1922, 677, 
+	677, 301, 683, 683, 479, 479, 479, 479, 
+	479, 479, 572, 572, 572, 572, 479, 479, 
+	301, 301, 301, 301, 301, 301, 301, 301, 
+	301, 301, 301, 301, 683, 683, 683, 683, 
+	683, 683, 683, 683, 683, 683, 683, 683, 
+	683, 683, 683, 683, 683, 683, 683, 683, 
+	683, 683, 683, 683, 683, 683, 683, 683, 
+	683, 683, 683, 683, 683, 683, 683, 683, 
+	683, 683, 683, 683, 683, 683, 683, 683, 
+	683, 683, 683, 683, 683, 683, 683, 683, 
+	683, 683, 683, 683, 683, 683, 683, 683, 
+	683, 683, 683, 683, 683, 683, 683, 683, 
+	683, 683, 683, 683, 683, 683, 683, 683, 
+	683, 683, 683, 683, 683, 683, 683, 683, 
+	683, 683, 683, 683, 683, 683, 683, 683, 
+	683, 683, 683, 683, 683, 683, 683, 683, 
+	1622, 1622, 301, 301, 301, 479, 479, 479, 
+	479, 479, 479, 301, 301, 301, 301, 301, 
+	301, 301, 479, 479, 479, 479, 479, 479, 
+	668, 668, 674, 674, 674, 674, 674, 674, 
+	674, 674, 674, 301, 674, 674, 674, 674, 
+	674, 301, 668, 668, 301, 301, 301, 479, 
+	479, 479, 479, 479, 479, 668, 668, 668, 
+	668, 301, 301, 301, 479, 479, 479, 479, 
+	479, 479, 668, 668, 668, 668, 301, 301, 
+	301, 0, 0, 0, 0, 91, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static const int zone_scanner_start = 849;
+static const int zone_scanner_first_final = 849;
+static const int zone_scanner_error = 0;
+
+static const int zone_scanner_en_err_line = 230;
+static const int zone_scanner_en_dname_ = 232;
+static const int zone_scanner_en_text_ = 242;
+static const int zone_scanner_en_default_ttl_ = 254;
+static const int zone_scanner_en_zone_origin_ = 263;
+static const int zone_scanner_en_include_file_ = 276;
+static const int zone_scanner_en_base64_ = 294;
+static const int zone_scanner_en_bitmap_ = 301;
+static const int zone_scanner_en_nonempty_hex_r_data = 407;
+static const int zone_scanner_en_hex_r_data = 416;
+static const int zone_scanner_en_r_data_a = 426;
+static const int zone_scanner_en_r_data_ns = 428;
+static const int zone_scanner_en_r_data_soa = 430;
+static const int zone_scanner_en_r_data_hinfo = 462;
+static const int zone_scanner_en_r_data_minfo = 467;
+static const int zone_scanner_en_r_data_mx = 472;
+static const int zone_scanner_en_r_data_txt = 477;
+static const int zone_scanner_en_r_data_aaaa = 481;
+static const int zone_scanner_en_r_data_loc = 483;
+static const int zone_scanner_en_r_data_srv = 538;
+static const int zone_scanner_en_r_data_naptr = 549;
+static const int zone_scanner_en_r_data_cert = 566;
+static const int zone_scanner_en_r_data_apl = 577;
+static const int zone_scanner_en_r_data_ds = 588;
+static const int zone_scanner_en_r_data_sshfp = 601;
+static const int zone_scanner_en_r_data_ipseckey = 611;
+static const int zone_scanner_en_r_data_rrsig = 650;
+static const int zone_scanner_en_r_data_nsec = 778;
+static const int zone_scanner_en_r_data_dnskey = 781;
+static const int zone_scanner_en_r_data_dhcid = 792;
+static const int zone_scanner_en_r_data_nsec3 = 794;
+static const int zone_scanner_en_r_data_nsec3param = 823;
+static const int zone_scanner_en_r_data_tlsa = 836;
+static const int zone_scanner_en_main = 849;
+
+
+#line 80 "zscanner/scanner.rl"
+
+
+scanner_t* scanner_create(const char *file_name)
+{
+	scanner_t *s = calloc(1, sizeof(scanner_t));
+	if (s == NULL) {
+		return NULL;
+	}
+
+	s->file_name = strdup(file_name);
+	s->line_counter = 1;
+
+	// Nonzero initial scanner state.
+	s->cs = zone_scanner_start;
+
+	return s;
+}
+
+void scanner_free(scanner_t *s)
+{
+	free(s->file_name);
+	free(s);
+}
+
+int scanner_process(char      *start,
+		    char      *end,
+		    bool      is_last_block,
+		    scanner_t *s)
+{
+	// Necessary scanner variables.
+	int  stack[RAGEL_STACK_SIZE];
+	char *p = start, *pe = end, *eof = NULL;
+
+	// Auxiliary variables which are used in scanner body.
+	struct in_addr  addr4;
+	struct in6_addr addr6;
+	uint32_t timestamp;
+	int16_t  window;
+	int	 ret;
+
+	// Next 2 variables are for better performance.
+	// Restoring r_data pointer to next free space.
+	uint8_t *rdata_tail = s->r_data + s->r_data_tail;
+	// Initialization of the last r_data byte.
+	uint8_t *rdata_stop = s->r_data + MAX_RDATA_LENGTH - 1;
+
+	// Restoring scanner states.
+	int cs  = s->cs;
+	int top = s->top;
+	memcpy(stack, s->stack, sizeof(stack));
+
+	// End of file check.
+	if (is_last_block == true) {
+		eof = pe;
+	}
+
+	// Writing scanner body (in C).
+	
+#line 4409 "zscanner/scanner.c"
+	{
+	int _klen;
+	unsigned int _trans;
+	short _widec;
+	const unsigned char *_acts;
+	unsigned int _nacts;
+	const short *_keys;
+
+	if ( p == pe )
+		goto _test_eof;
+	if ( cs == 0 )
+		goto _out;
+_resume:
+	_widec = (*p);
+	_klen = _zone_scanner_cond_lengths[cs];
+	_keys = _zone_scanner_cond_keys + (_zone_scanner_cond_offsets[cs]*2);
+	if ( _klen > 0 ) {
+		const short *_lower = _keys;
+		const short *_mid;
+		const short *_upper = _keys + (_klen<<1) - 2;
+		while (1) {
+			if ( _upper < _lower )
+				break;
+
+			_mid = _lower + (((_upper-_lower) >> 1) & ~1);
+			if ( _widec < _mid[0] )
+				_upper = _mid - 2;
+			else if ( _widec > _mid[1] )
+				_lower = _mid + 2;
+			else {
+				switch ( _zone_scanner_cond_spaces[_zone_scanner_cond_offsets[cs] + ((_mid - _keys)>>1)] ) {
+	case 0: {
+		_widec = (short)(640 + ((*p) - -128));
+		if ( 
+#line 54 "zscanner/scanner_body.rl"
+ s->multiline  ) _widec += 256;
+		break;
+	}
+	case 1: {
+		_widec = (short)(1152 + ((*p) - -128));
+		if ( 
+#line 63 "zscanner/scanner_body.rl"
+ !s->multiline  ) _widec += 256;
+		break;
+	}
+	case 2: {
+		_widec = (short)(128 + ((*p) - -128));
+		if ( 
+#line 560 "zscanner/scanner_body.rl"
+ s->multiline  ) _widec += 256;
+		break;
+	}
+	case 3: {
+		_widec = (short)(2688 + ((*p) - -128));
+		if ( 
+#line 1125 "zscanner/scanner_body.rl"
+ s->number64 != 0  ) _widec += 256;
+		break;
+	}
+	case 4: {
+		_widec = (short)(4224 + ((*p) - -128));
+		if ( 
+#line 1126 "zscanner/scanner_body.rl"
+ s->number64 == 0  ) _widec += 256;
+		break;
+	}
+	case 5: {
+		_widec = (short)(1664 + ((*p) - -128));
+		if ( 
+#line 54 "zscanner/scanner_body.rl"
+ s->multiline  ) _widec += 256;
+		if ( 
+#line 63 "zscanner/scanner_body.rl"
+ !s->multiline  ) _widec += 512;
+		break;
+	}
+	case 6: {
+		_widec = (short)(3200 + ((*p) - -128));
+		if ( 
+#line 54 "zscanner/scanner_body.rl"
+ s->multiline  ) _widec += 256;
+		if ( 
+#line 1125 "zscanner/scanner_body.rl"
+ s->number64 != 0  ) _widec += 512;
+		break;
+	}
+	case 7: {
+		_widec = (short)(4736 + ((*p) - -128));
+		if ( 
+#line 54 "zscanner/scanner_body.rl"
+ s->multiline  ) _widec += 256;
+		if ( 
+#line 1126 "zscanner/scanner_body.rl"
+ s->number64 == 0  ) _widec += 512;
+		break;
+	}
+	case 8: {
+		_widec = (short)(5760 + ((*p) - -128));
+		if ( 
+#line 1125 "zscanner/scanner_body.rl"
+ s->number64 != 0  ) _widec += 256;
+		if ( 
+#line 1126 "zscanner/scanner_body.rl"
+ s->number64 == 0  ) _widec += 512;
+		break;
+	}
+	case 9: {
+		_widec = (short)(12928 + ((*p) - -128));
+		if ( 
+#line 54 "zscanner/scanner_body.rl"
+ s->multiline  ) _widec += 256;
+		if ( 
+#line 63 "zscanner/scanner_body.rl"
+ !s->multiline  ) _widec += 512;
+		if ( 
+#line 1126 "zscanner/scanner_body.rl"
+ s->number64 == 0  ) _widec += 1024;
+		break;
+	}
+	case 10: {
+		_widec = (short)(6784 + ((*p) - -128));
+		if ( 
+#line 54 "zscanner/scanner_body.rl"
+ s->multiline  ) _widec += 256;
+		if ( 
+#line 1125 "zscanner/scanner_body.rl"
+ s->number64 != 0  ) _widec += 512;
+		if ( 
+#line 1126 "zscanner/scanner_body.rl"
+ s->number64 == 0  ) _widec += 1024;
+		break;
+	}
+	case 11: {
+		_widec = (short)(8832 + ((*p) - -128));
+		if ( 
+#line 54 "zscanner/scanner_body.rl"
+ s->multiline  ) _widec += 256;
+		if ( 
+#line 63 "zscanner/scanner_body.rl"
+ !s->multiline  ) _widec += 512;
+		if ( 
+#line 1125 "zscanner/scanner_body.rl"
+ s->number64 != 0  ) _widec += 1024;
+		if ( 
+#line 1126 "zscanner/scanner_body.rl"
+ s->number64 == 0  ) _widec += 2048;
+		break;
+	}
+				}
+				break;
+			}
+		}
+	}
+
+	_keys = _zone_scanner_trans_keys + _zone_scanner_key_offsets[cs];
+	_trans = _zone_scanner_index_offsets[cs];
+
+	_klen = _zone_scanner_single_lengths[cs];
+	if ( _klen > 0 ) {
+		const short *_lower = _keys;
+		const short *_mid;
+		const short *_upper = _keys + _klen - 1;
+		while (1) {
+			if ( _upper < _lower )
+				break;
+
+			_mid = _lower + ((_upper-_lower) >> 1);
+			if ( _widec < *_mid )
+				_upper = _mid - 1;
+			else if ( _widec > *_mid )
+				_lower = _mid + 1;
+			else {
+				_trans += (unsigned int)(_mid - _keys);
+				goto _match;
+			}
+		}
+		_keys += _klen;
+		_trans += _klen;
+	}
+
+	_klen = _zone_scanner_range_lengths[cs];
+	if ( _klen > 0 ) {
+		const short *_lower = _keys;
+		const short *_mid;
+		const short *_upper = _keys + (_klen<<1) - 2;
+		while (1) {
+			if ( _upper < _lower )
+				break;
+
+			_mid = _lower + (((_upper-_lower) >> 1) & ~1);
+			if ( _widec < _mid[0] )
+				_upper = _mid - 2;
+			else if ( _widec > _mid[1] )
+				_lower = _mid + 2;
+			else {
+				_trans += (unsigned int)((_mid - _keys)>>1);
+				goto _match;
+			}
+		}
+		_trans += _klen;
+	}
+
+_match:
+	_trans = _zone_scanner_indicies[_trans];
+	cs = _zone_scanner_trans_targs[_trans];
+
+	if ( _zone_scanner_trans_actions[_trans] == 0 )
+		goto _again;
+
+	_acts = _zone_scanner_actions + _zone_scanner_trans_actions[_trans];
+	_nacts = (unsigned int) *_acts++;
+	while ( _nacts-- > 0 )
+	{
+		switch ( *_acts++ )
+		{
+	case 0:
+#line 20 "zscanner/scanner_body.rl"
+	{
+		p--; {cs = stack[--top]; goto _again;}
+	}
+	break;
+	case 1:
+#line 25 "zscanner/scanner_body.rl"
+	{
+		s->line_counter++;
+	}
+	break;
+	case 2:
+#line 29 "zscanner/scanner_body.rl"
+	{
+		if (s->multiline == true) {
+			SCANNER_ERROR(ZSCANNER_ELEFT_PARENTHESIS);
+			p--; {cs = 230; goto _again;}
+		}
+		s->multiline = true;
+	}
+	break;
+	case 3:
+#line 36 "zscanner/scanner_body.rl"
+	{
+		if (s->multiline == false) {
+			SCANNER_ERROR(ZSCANNER_ERIGHT_PARENTHESIS);
+			p--; {cs = 230; goto _again;}
+		}
+		s->multiline = false;
+	}
+	break;
+	case 4:
+#line 44 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_REST);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 5:
+#line 67 "zscanner/scanner_body.rl"
+	{
+		s->buffer_length = 0;
+	}
+	break;
+	case 6:
+#line 70 "zscanner/scanner_body.rl"
+	{
+		if (s->buffer_length < sizeof(s->buffer) - 1) {
+			s->buffer[s->buffer_length++] = (*p);
+		}
+	}
+	break;
+	case 7:
+#line 75 "zscanner/scanner_body.rl"
+	{
+		// Ending string in buffer.
+		s->buffer[s->buffer_length++] = 0;
+
+		// Error counter incrementation.
+		s->error_counter++;
+
+		// Initialization of fcall stack.
+		top = 0;
+
+		// Process error message.
+		s->process_error(s);
+
+		// Reset.
+		s->error_code = KNOT_EOK;
+		s->multiline = false;
+
+		// In case of serious error, stop scanner.
+		if (s->stop == true) {
+			return -1;
+		}
+	}
+	break;
+	case 8:
+#line 100 "zscanner/scanner_body.rl"
+	{ {cs = 849; goto _again;} }
+	break;
+	case 9:
+#line 104 "zscanner/scanner_body.rl"
+	{
+		s->item_length = 0;
+		s->item_length_position = s->dname_tmp_length++;
+	}
+	break;
+	case 10:
+#line 108 "zscanner/scanner_body.rl"
+	{
+		if (s->item_length < MAX_LABEL_LENGTH) {
+			(s->dname)[s->dname_tmp_length++] = (*p);
+			s->item_length++;
+		} else {
+			SCANNER_WARNING(ZSCANNER_ELABEL_OVERFLOW);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 11:
+#line 117 "zscanner/scanner_body.rl"
+	{
+		if (s->dname_tmp_length < MAX_DNAME_LENGTH) {
+			(s->dname)[s->item_length_position] =
+				(uint8_t)(s->item_length);
+		} else {
+			SCANNER_WARNING(ZSCANNER_EDNAME_OVERFLOW);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 12:
+#line 127 "zscanner/scanner_body.rl"
+	{
+		if (s->item_length < MAX_LABEL_LENGTH) {
+			(s->dname)[s->dname_tmp_length] = 0;
+			s->item_length++;
+		} else {
+			SCANNER_WARNING(ZSCANNER_ELABEL_OVERFLOW);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 13:
+#line 136 "zscanner/scanner_body.rl"
+	{
+		(s->dname)[s->dname_tmp_length] *= 10;
+		(s->dname)[s->dname_tmp_length] += digit_to_num[(uint8_t)(*p)];
+	}
+	break;
+	case 14:
+#line 140 "zscanner/scanner_body.rl"
+	{
+		(s->dname)[s->dname_tmp_length] =
+			(s->dname)[s->dname_tmp_length];
+		s->dname_tmp_length++;
+	}
+	break;
+	case 15:
+#line 145 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 16:
+#line 164 "zscanner/scanner_body.rl"
+	{
+		(s->dname)[s->dname_tmp_length++] = 0;
+	}
+	break;
+	case 17:
+#line 167 "zscanner/scanner_body.rl"
+	{
+		memcpy(s->dname + s->dname_tmp_length,
+		       s->zone_origin,
+		       s->zone_origin_length);
+
+		s->dname_tmp_length += s->zone_origin_length;
+
+		if (s->dname_tmp_length > MAX_DNAME_LENGTH) {
+			SCANNER_WARNING(ZSCANNER_EDNAME_OVERFLOW);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 18:
+#line 179 "zscanner/scanner_body.rl"
+	{
+		memcpy(s->dname,
+		       s->zone_origin,
+		       s->zone_origin_length);
+
+		s->dname_tmp_length = s->zone_origin_length;
+	}
+	break;
+	case 19:
+#line 187 "zscanner/scanner_body.rl"
+	{
+		s->item_length_position = 0;
+		s->dname_tmp_length = 0;
+	}
+	break;
+	case 20:
+#line 191 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_DNAME_CHAR);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 21:
+#line 203 "zscanner/scanner_body.rl"
+	{ p--; {stack[top++] = cs; cs = 232; goto _again;} }
+	break;
+	case 22:
+#line 207 "zscanner/scanner_body.rl"
+	{
+		s->item_length_location = rdata_tail++;
+	}
+	break;
+	case 23:
+#line 210 "zscanner/scanner_body.rl"
+	{
+		s->item_length = rdata_tail - s->item_length_location - 1;
+
+		if (s->item_length <= MAX_ITEM_LENGTH) {
+			*(s->item_length_location) = (uint8_t)(s->item_length);
+		} else {
+			SCANNER_WARNING(ZSCANNER_EITEM_OVERFLOW);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 24:
+#line 221 "zscanner/scanner_body.rl"
+	{
+		s->r_data_blocks[++(s->r_data_blocks_count)] =
+			rdata_tail - s->r_data;
+	}
+	break;
+	case 25:
+#line 231 "zscanner/scanner_body.rl"
+	{
+		s->dname = s->r_owner;
+		s->r_owner_length = 0;
+	}
+	break;
+	case 26:
+#line 235 "zscanner/scanner_body.rl"
+	{
+		s->r_owner_length = s->dname_tmp_length;
+	}
+	break;
+	case 27:
+#line 238 "zscanner/scanner_body.rl"
+	{
+		if (s->r_owner_length == 0) {
+			SCANNER_WARNING(ZSCANNER_EBAD_PREVIOUS_OWNER);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 28:
+#line 244 "zscanner/scanner_body.rl"
+	{
+		s->r_owner_length = 0;
+		SCANNER_WARNING(ZSCANNER_EBAD_OWNER);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 29:
+#line 256 "zscanner/scanner_body.rl"
+	{
+		s->dname = rdata_tail;
+	}
+	break;
+	case 30:
+#line 259 "zscanner/scanner_body.rl"
+	{
+		rdata_tail += s->dname_tmp_length;
+	}
+	break;
+	case 31:
+#line 267 "zscanner/scanner_body.rl"
+	{
+		// Overflow check: 10*(s->number64) + fc - ASCII_0 <= UINT64_MAX
+		if ((s->number64 < (UINT64_MAX / 10)) ||   // Dominant fast check.
+			((s->number64 == (UINT64_MAX / 10)) && // Marginal case.
+			 ((*p) <= (UINT64_MAX % 10) + ASCII_0)
+			)
+		   ) {
+			s->number64 *= 10;
+			s->number64 += digit_to_num[(uint8_t)(*p)];
+		} else {
+			SCANNER_WARNING(ZSCANNER_ENUMBER64_OVERFLOW);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 32:
+#line 284 "zscanner/scanner_body.rl"
+	{
+		s->number64 = 0;
+	}
+	break;
+	case 33:
+#line 287 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 34:
+#line 295 "zscanner/scanner_body.rl"
+	{
+		s->decimal_counter = 0;
+	}
+	break;
+	case 35:
+#line 298 "zscanner/scanner_body.rl"
+	{
+		s->number64_tmp = s->number64;
+	}
+	break;
+	case 36:
+#line 301 "zscanner/scanner_body.rl"
+	{
+		s->decimal_counter++;
+	}
+	break;
+	case 37:
+#line 305 "zscanner/scanner_body.rl"
+	{
+		if (s->decimal_counter == 0 && s->number64 < UINT32_MAX) {
+			s->number64 *= pow(10, s->decimals);
+		} else if (s->decimal_counter <= s->decimals &&
+				 s->number64_tmp < UINT32_MAX) {
+			s->number64 *= pow(10, s->decimals - s->decimal_counter);
+			s->number64 += s->number64_tmp * pow(10, s->decimals);
+		} else {
+			SCANNER_WARNING(ZSCANNER_EFLOAT_OVERFLOW);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 38:
+#line 322 "zscanner/scanner_body.rl"
+	{
+		s->decimals = 2;
+	}
+	break;
+	case 39:
+#line 325 "zscanner/scanner_body.rl"
+	{
+		s->decimals = 3;
+	}
+	break;
+	case 40:
+#line 334 "zscanner/scanner_body.rl"
+	{
+		if (s->number64 <= UINT8_MAX) {
+			*rdata_tail = (uint8_t)(s->number64);
+			rdata_tail += 1;
+		} else {
+			SCANNER_WARNING(ZSCANNER_ENUMBER8_OVERFLOW);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 41:
+#line 343 "zscanner/scanner_body.rl"
+	{
+		if (s->number64 <= UINT16_MAX) {
+			*((uint16_t *)rdata_tail) = htons((uint16_t)(s->number64));
+			rdata_tail += 2;
+		} else {
+			SCANNER_WARNING(ZSCANNER_ENUMBER16_OVERFLOW);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 42:
+#line 352 "zscanner/scanner_body.rl"
+	{
+		if (s->number64 <= UINT32_MAX) {
+			*((uint32_t *)rdata_tail) = htonl((uint32_t)(s->number64));
+			rdata_tail += 4;
+		} else {
+			SCANNER_WARNING(ZSCANNER_ENUMBER32_OVERFLOW);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 43:
+#line 362 "zscanner/scanner_body.rl"
+	{
+		if (s->number64 <= UINT16_MAX) {
+			s->r_type = (uint16_t)(s->number64);
+		} else {
+			SCANNER_WARNING(ZSCANNER_ENUMBER16_OVERFLOW);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 44:
+#line 371 "zscanner/scanner_body.rl"
+	{
+		if (s->number64 <= UINT16_MAX) {
+			s->r_data_length = (uint16_t)(s->number64);
+		} else {
+			SCANNER_WARNING(ZSCANNER_ENUMBER16_OVERFLOW);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 45:
+#line 388 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_TIME_UNIT);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 46:
+#line 395 "zscanner/scanner_body.rl"
+	{ if (s->number64 <= (UINT32_MAX / 60)) {
+	                  s->number64 *= 60;
+	              } else {
+	                  SCANNER_WARNING(ZSCANNER_ENUMBER32_OVERFLOW);
+	                  p--; {cs = 230; goto _again;}
+	              }
+	            }
+	break;
+	case 47:
+#line 402 "zscanner/scanner_body.rl"
+	{ if (s->number64 <= (UINT32_MAX / 3600)) {
+	                  s->number64 *= 3600;
+	              } else {
+	                  SCANNER_WARNING(ZSCANNER_ENUMBER32_OVERFLOW);
+	                  p--; {cs = 230; goto _again;}
+	              }
+	            }
+	break;
+	case 48:
+#line 409 "zscanner/scanner_body.rl"
+	{ if (s->number64 <= (UINT32_MAX / 86400)) {
+	                  s->number64 *= 86400;
+	              } else {
+	                  SCANNER_WARNING(ZSCANNER_ENUMBER32_OVERFLOW);
+	                  p--; {cs = 230; goto _again;}
+	              }
+	            }
+	break;
+	case 49:
+#line 416 "zscanner/scanner_body.rl"
+	{ if (s->number64 <= (UINT32_MAX / 604800)) {
+	                  s->number64 *= 604800;
+	              } else {
+	                  SCANNER_WARNING(ZSCANNER_ENUMBER32_OVERFLOW);
+	                  p--; {cs = 230; goto _again;}
+	              }
+	            }
+	break;
+	case 50:
+#line 426 "zscanner/scanner_body.rl"
+	{
+		s->number64_tmp = s->number64;
+	}
+	break;
+	case 51:
+#line 429 "zscanner/scanner_body.rl"
+	{
+		if (s->number64 + s->number64_tmp < UINT32_MAX) {
+			s->number64 += s->number64_tmp;
+		} else {
+			SCANNER_WARNING(ZSCANNER_ENUMBER32_OVERFLOW);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 52:
+#line 447 "zscanner/scanner_body.rl"
+	{
+		s->buffer_length = 0;
+	}
+	break;
+	case 53:
+#line 450 "zscanner/scanner_body.rl"
+	{
+		if (s->buffer_length < MAX_RDATA_LENGTH) {
+			s->buffer[s->buffer_length++] = (*p);
+		} else {
+			SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 54:
+#line 458 "zscanner/scanner_body.rl"
+	{
+		s->buffer[s->buffer_length] = 0;
+
+		if (s->buffer_length == 14) { // Date; 14 = len("YYYYMMDDHHmmSS").
+			ret = date_to_timestamp(s->buffer, &timestamp);
+
+			if (ret == KNOT_EOK) {
+				*((uint32_t *)rdata_tail) = htonl(timestamp);
+				rdata_tail += 4;
+			} else {
+				SCANNER_WARNING(ret);
+				p--; {cs = 230; goto _again;}
+			}
+		} else if (s->buffer_length <= 10) { // Timestamp format.
+			errno = 0;
+			s->number64 = strtoul((char *)(s->buffer), NULL,  10);
+
+			if (errno != 0) {
+				SCANNER_WARNING(ZSCANNER_EBAD_TIMESTAMP);
+				p--; {cs = 230; goto _again;}
+			}
+
+			if (s->number64 <= UINT32_MAX) {
+				*((uint32_t *)rdata_tail) = htonl((uint32_t)s->number64);
+				rdata_tail += 4;
+			} else {
+				SCANNER_WARNING(ZSCANNER_ENUMBER32_OVERFLOW);
+				p--; {cs = 230; goto _again;}
+			}
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_TIMESTAMP_LENGTH);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 55:
+#line 492 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_TIMESTAMP_CHAR);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 56:
+#line 502 "zscanner/scanner_body.rl"
+	{
+		if (rdata_tail <= rdata_stop) {
+			*(rdata_tail++) = (*p);
+		} else {
+			SCANNER_WARNING(ZSCANNER_ETEXT_OVERFLOW);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 57:
+#line 510 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_TEXT_CHAR);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 58:
+#line 514 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_TEXT);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 59:
+#line 519 "zscanner/scanner_body.rl"
+	{
+		if (rdata_tail <= rdata_stop) {
+			*rdata_tail = 0;
+			s->item_length++;
+		} else {
+			SCANNER_WARNING(ZSCANNER_ETEXT_OVERFLOW);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 60:
+#line 528 "zscanner/scanner_body.rl"
+	{
+		if ((*rdata_tail < (UINT8_MAX / 10)) ||   // Dominant fast check.
+			((*rdata_tail == (UINT8_MAX / 10)) && // Marginal case.
+			 ((*p) <= (UINT8_MAX % 10) + ASCII_0)
+			)
+		   ) {
+			*rdata_tail *= 10;
+			*rdata_tail += digit_to_num[(uint8_t)(*p)];
+		} else {
+			SCANNER_WARNING(ZSCANNER_ENUMBER8_OVERFLOW);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 61:
+#line 541 "zscanner/scanner_body.rl"
+	{
+		rdata_tail++;
+	}
+	break;
+	case 62:
+#line 544 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 63:
+#line 566 "zscanner/scanner_body.rl"
+	{ p--; {stack[top++] = cs; cs = 242; goto _again;} }
+	break;
+	case 64:
+#line 576 "zscanner/scanner_body.rl"
+	{
+		if (s->number64 <= UINT32_MAX) {
+			s->default_ttl = (uint32_t)(s->number64);
+		} else {
+			SCANNER_ERROR(ZSCANNER_ENUMBER32_OVERFLOW);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 65:
+#line 584 "zscanner/scanner_body.rl"
+	{
+		SCANNER_ERROR(ZSCANNER_EBAD_TTL);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 66:
+#line 591 "zscanner/scanner_body.rl"
+	{ p--; {stack[top++] = cs; cs = 254; goto _again;} }
+	break;
+	case 67:
+#line 595 "zscanner/scanner_body.rl"
+	{
+		s->dname = s->zone_origin;
+	}
+	break;
+	case 68:
+#line 598 "zscanner/scanner_body.rl"
+	{
+		s->zone_origin_length = s->dname_tmp_length;
+	}
+	break;
+	case 69:
+#line 601 "zscanner/scanner_body.rl"
+	{
+		SCANNER_ERROR(ZSCANNER_EBAD_ORIGIN);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 70:
+#line 608 "zscanner/scanner_body.rl"
+	{ p--; {stack[top++] = cs; cs = 263; goto _again;} }
+	break;
+	case 71:
+#line 612 "zscanner/scanner_body.rl"
+	{
+		rdata_tail = s->r_data;
+	}
+	break;
+	case 72:
+#line 615 "zscanner/scanner_body.rl"
+	{
+		*rdata_tail = 0; // Ending filename string.
+		strcpy((char*)(s->include_filename), (char*)(s->r_data));
+
+		// Check for correct string copy.
+		if (strlen(s->include_filename) != rdata_tail - s->r_data) {
+			SCANNER_ERROR(ZSCANNER_EBAD_INCLUDE_FILENAME);
+			p--; {cs = 230; goto _again;}
+		}
+
+		// For detection whether origin is not present.
+		s->dname = NULL;
+	}
+	break;
+	case 73:
+#line 628 "zscanner/scanner_body.rl"
+	{
+		SCANNER_ERROR(ZSCANNER_EBAD_INCLUDE_FILENAME);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 74:
+#line 633 "zscanner/scanner_body.rl"
+	{
+		s->dname = s->r_data;
+	}
+	break;
+	case 75:
+#line 636 "zscanner/scanner_body.rl"
+	{
+		s->r_data_length = s->dname_tmp_length;
+	}
+	break;
+	case 76:
+#line 639 "zscanner/scanner_body.rl"
+	{
+		SCANNER_ERROR(ZSCANNER_EBAD_INCLUDE_ORIGIN);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 77:
+#line 644 "zscanner/scanner_body.rl"
+	{
+		char text_origin[MAX_DNAME_LENGTH];
+
+		// Origin conversion from wire to text form.
+		if (s->dname == NULL) { // Use current origin.
+			wire_dname_to_str(s->zone_origin,
+			                  s->zone_origin_length,
+					  text_origin);
+		} else { // Use specified origin.
+			wire_dname_to_str(s->r_data,
+			                  s->r_data_length,
+					  text_origin);
+		}
+
+		if (s->include_filename[0] != '/') { // Relative file path..
+			// Get absolute path of the current zone file.
+			if (realpath(s->file_name, (char*)(s->buffer)) != NULL) {
+				char *full_current_zone_file_name =
+					strdup((char*)(s->buffer));
+
+				// Creating full include file name.
+				sprintf((char*)(s->buffer), "%s/%s",
+				        dirname(full_current_zone_file_name),
+				        s->include_filename);
+
+				free(full_current_zone_file_name);
+			} else {
+				SCANNER_ERROR(ZSCANNER_EUNPROCESSED_INCLUDE);
+				p--; {cs = 230; goto _again;}
+			}
+		} else {
+			strcpy((char*)(s->buffer), (char*)(s->include_filename));
+		}
+
+		// Create new file loader for included zone file.
+		file_loader_t *fl = file_loader_create((char*)(s->buffer),
+		                                       text_origin,
+		                                       DEFAULT_CLASS,
+		                                       DEFAULT_TTL,
+		                                       s->process_record,
+		                                       s->process_error,
+		                                       s->data);
+		if (fl != NULL) {
+			// Process included zone file.
+			ret = file_loader_process(fl);
+			file_loader_free(fl);
+
+			if (ret != 0) {
+				SCANNER_ERROR(ZSCANNER_EUNPROCESSED_INCLUDE);
+				p--; {cs = 230; goto _again;}
+			}
+		} else {
+			SCANNER_ERROR(ZSCANNER_EUNOPENED_INCLUDE);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 78:
+#line 708 "zscanner/scanner_body.rl"
+	{ p--; {stack[top++] = cs; cs = 276; goto _again;} }
+	break;
+	case 79:
+#line 714 "zscanner/scanner_body.rl"
+	{
+		s->stop = true;
+	}
+	break;
+	case 80:
+#line 718 "zscanner/scanner_body.rl"
+	{
+		s->stop = false;
+	}
+	break;
+	case 81:
+#line 721 "zscanner/scanner_body.rl"
+	{
+		SCANNER_ERROR(ZSCANNER_EBAD_DIRECTIVE);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 82:
+#line 733 "zscanner/scanner_body.rl"
+	{
+		s->r_class = s->default_class;
+	}
+	break;
+	case 83:
+#line 737 "zscanner/scanner_body.rl"
+	{
+		s->r_ttl = s->default_ttl;
+	}
+	break;
+	case 84:
+#line 741 "zscanner/scanner_body.rl"
+	{
+		s->r_class = KNOT_CLASS_IN;
+	}
+	break;
+	case 85:
+#line 745 "zscanner/scanner_body.rl"
+	{
+		if (s->number64 <= UINT32_MAX) {
+			s->r_ttl = (uint32_t)(s->number64);
+		} else {
+			SCANNER_WARNING(ZSCANNER_ENUMBER32_OVERFLOW);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 86:
+#line 760 "zscanner/scanner_body.rl"
+	{
+		s->buffer_length = 0;
+	}
+	break;
+	case 87:
+#line 763 "zscanner/scanner_body.rl"
+	{
+		if (s->buffer_length < MAX_RDATA_LENGTH) {
+			s->buffer[s->buffer_length++] = (*p);
+		}
+		else {
+			SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 88:
+#line 772 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_ADDRESS_CHAR);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 89:
+#line 777 "zscanner/scanner_body.rl"
+	{
+		s->buffer[s->buffer_length] = 0;
+
+		if (inet_pton(AF_INET, (char *)s->buffer, &addr4) <= 0) {
+			SCANNER_WARNING(ZSCANNER_EBAD_IPV4);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 90:
+#line 785 "zscanner/scanner_body.rl"
+	{
+		memcpy(rdata_tail, &(addr4.s_addr), INET4_ADDR_LENGTH);
+		rdata_tail += INET4_ADDR_LENGTH;
+	}
+	break;
+	case 91:
+#line 790 "zscanner/scanner_body.rl"
+	{
+		s->buffer[s->buffer_length] = 0;
+
+		if (inet_pton(AF_INET6, (char *)s->buffer, &addr6) <= 0) {
+			SCANNER_WARNING(ZSCANNER_EBAD_IPV6);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 92:
+#line 798 "zscanner/scanner_body.rl"
+	{
+		memcpy(rdata_tail, &(addr6.s6_addr), INET6_ADDR_LENGTH);
+		rdata_tail += INET6_ADDR_LENGTH;
+	}
+	break;
+	case 93:
+#line 815 "zscanner/scanner_body.rl"
+	{
+		memset(&(s->apl), 0, sizeof(s->apl));
+	}
+	break;
+	case 94:
+#line 818 "zscanner/scanner_body.rl"
+	{
+		s->apl.excl_flag = 128; // dec 128  = bin 10000000.
+	}
+	break;
+	case 95:
+#line 821 "zscanner/scanner_body.rl"
+	{
+		s->apl.addr_family = 1;
+	}
+	break;
+	case 96:
+#line 824 "zscanner/scanner_body.rl"
+	{
+		s->apl.addr_family = 2;
+	}
+	break;
+	case 97:
+#line 827 "zscanner/scanner_body.rl"
+	{
+		if ((s->apl.addr_family == 1 && s->number64 <= 32) ||
+		    (s->apl.addr_family == 2 && s->number64 <= 128)) {
+			s->apl.prefix_length = (uint8_t)(s->number64);
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_APL);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 98:
+#line 836 "zscanner/scanner_body.rl"
+	{
+		// Write address family.
+		*((uint16_t *)rdata_tail) = htons(s->apl.addr_family);
+		rdata_tail += 2;
+		// Write prefix length in bites.
+		*(rdata_tail) = s->apl.prefix_length;
+		rdata_tail += 1;
+		// Computed maximal prefix length in bytes (real can be smaller).
+		s->number64 = (s->apl.prefix_length + 7) / 8;
+		if (s->number64 > 127) { // At most 7 bits.
+			SCANNER_WARNING(ZSCANNER_EBAD_APL);
+			p--; {cs = 230; goto _again;}
+		}
+		// Copy address to buffer.
+		switch (s->apl.addr_family) {
+		case 1:
+			memcpy(s->buffer, &(addr4.s_addr), INET4_ADDR_LENGTH);
+			break;
+		case 2:
+			memcpy(s->buffer, &(addr6.s6_addr), INET6_ADDR_LENGTH);
+			break;
+		default:
+			SCANNER_WARNING(ZSCANNER_EBAD_APL);
+			p--; {cs = 230; goto _again;}
+		}
+		// Find real prefix (without trailing zeroes).
+		while (s->number64 > 0 ) {
+			if ((s->buffer[s->number64 - 1] & 255) != 0) {
+				// Apply mask on last byte if not precise prefix.
+				// (Bind does't do this).
+				s->buffer[s->number64 - 1] &=
+					((uint8_t)255 << (s->number64 * 8 -
+					                  s->apl.prefix_length));
+				break;
+			}
+			s->number64--;
+		}
+		// Write negation flag + prefix length in bytes.
+		*(rdata_tail) = (uint8_t)(s->number64) + s->apl.excl_flag;
+		rdata_tail += 1;
+		// Write address prefix.
+		memcpy(rdata_tail, s->buffer, s->number64);
+		rdata_tail += s->number64;
+	}
+	break;
+	case 99:
+#line 880 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_APL);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 100:
+#line 898 "zscanner/scanner_body.rl"
+	{
+		if (rdata_tail <= rdata_stop) {
+			*rdata_tail = first_hex_to_num[(uint8_t)(*p)];
+		} else {
+		   SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+		   p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 101:
+#line 906 "zscanner/scanner_body.rl"
+	{
+		*rdata_tail += second_hex_to_num[(uint8_t)(*p)];
+		rdata_tail++;
+	}
+	break;
+	case 102:
+#line 910 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_HEX_CHAR);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 103:
+#line 924 "zscanner/scanner_body.rl"
+	{
+		if ((rdata_tail - s->r_data) != s->r_data_length) {
+			SCANNER_WARNING(ZSCANNER_EBAD_RDATA_LENGTH);
+			p--; {cs = 230; goto _again;}
+		}
+
+		ret = find_rdata_blocks(s);
+		if (ret != KNOT_EOK) {
+			SCANNER_WARNING(ret);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 104:
+#line 937 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_HEX_RDATA);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 105:
+#line 947 "zscanner/scanner_body.rl"
+	{
+		if (rdata_tail <= rdata_stop) {
+			*rdata_tail = first_base64_to_num[(uint8_t)(*p)];
+		} else {
+		   SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+		   p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 106:
+#line 955 "zscanner/scanner_body.rl"
+	{
+		*(rdata_tail++) += second_left_base64_to_num[(uint8_t)(*p)];
+
+		if (rdata_tail <= rdata_stop) {
+			*rdata_tail = second_right_base64_to_num[(uint8_t)(*p)];
+		} else {
+		   SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+		   p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 107:
+#line 965 "zscanner/scanner_body.rl"
+	{
+		*(rdata_tail++) += third_left_base64_to_num[(uint8_t)(*p)];
+
+		if (rdata_tail <= rdata_stop) {
+			*rdata_tail = third_right_base64_to_num[(uint8_t)(*p)];
+		} else {
+		   SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+		   p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 108:
+#line 975 "zscanner/scanner_body.rl"
+	{
+		*(rdata_tail++) += fourth_base64_to_num[(uint8_t)(*p)];
+	}
+	break;
+	case 109:
+#line 979 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_BASE64_CHAR);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 110:
+#line 1001 "zscanner/scanner_body.rl"
+	{ p--; {stack[top++] = cs; cs = 294; goto _again;} }
+	break;
+	case 111:
+#line 1005 "zscanner/scanner_body.rl"
+	{
+		if (rdata_tail <= rdata_stop) {
+			*rdata_tail = first_base32hex_to_num[(uint8_t)(*p)];
+		} else {
+		   SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+		   p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 112:
+#line 1013 "zscanner/scanner_body.rl"
+	{
+		*(rdata_tail++) += second_left_base32hex_to_num[(uint8_t)(*p)];
+
+		if (rdata_tail <= rdata_stop) {
+			*rdata_tail = second_right_base32hex_to_num[(uint8_t)(*p)];
+		} else {
+		   SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+		   p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 113:
+#line 1023 "zscanner/scanner_body.rl"
+	{
+		*rdata_tail += third_base32hex_to_num[(uint8_t)(*p)];
+	}
+	break;
+	case 114:
+#line 1026 "zscanner/scanner_body.rl"
+	{
+		*(rdata_tail++) += fourth_left_base32hex_to_num[(uint8_t)(*p)];
+
+		if (rdata_tail <= rdata_stop) {
+			*rdata_tail = fourth_right_base32hex_to_num[(uint8_t)(*p)];
+		} else {
+		   SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+		   p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 115:
+#line 1036 "zscanner/scanner_body.rl"
+	{
+		*(rdata_tail++) += fifth_left_base32hex_to_num[(uint8_t)(*p)];
+
+		if (rdata_tail <= rdata_stop) {
+			*rdata_tail = fifth_right_base32hex_to_num[(uint8_t)(*p)];
+		} else {
+		   SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+		   p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 116:
+#line 1046 "zscanner/scanner_body.rl"
+	{
+		*rdata_tail += sixth_base32hex_to_num[(uint8_t)(*p)];
+	}
+	break;
+	case 117:
+#line 1049 "zscanner/scanner_body.rl"
+	{
+		*(rdata_tail++) += seventh_left_base32hex_to_num[(uint8_t)(*p)];
+
+		if (rdata_tail <= rdata_stop) {
+			*rdata_tail = seventh_right_base32hex_to_num[(uint8_t)(*p)];
+		} else {
+		   SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+		   p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 118:
+#line 1059 "zscanner/scanner_body.rl"
+	{
+		*(rdata_tail++) += eighth_base32hex_to_num[(uint8_t)(*p)];
+	}
+	break;
+	case 119:
+#line 1063 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_BASE32HEX_CHAR);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 120:
+#line 1098 "zscanner/scanner_body.rl"
+	{
+		*(rdata_tail++) = 0;
+	}
+	break;
+	case 121:
+#line 1101 "zscanner/scanner_body.rl"
+	{
+		*(rdata_tail++) = 1;
+	}
+	break;
+	case 122:
+#line 1104 "zscanner/scanner_body.rl"
+	{
+		*(rdata_tail++) = 2;
+	}
+	break;
+	case 123:
+#line 1107 "zscanner/scanner_body.rl"
+	{
+		*(rdata_tail++) = 3;
+	}
+	break;
+	case 124:
+#line 1110 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_GATEWAY);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 125:
+#line 1114 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_GATEWAY_KEY);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 126:
+#line 1132 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EUNSUPPORTED_TYPE);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 127:
+#line 1138 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_A, &rdata_tail); }
+	break;
+	case 128:
+#line 1139 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_NS, &rdata_tail); }
+	break;
+	case 129:
+#line 1140 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_CNAME, &rdata_tail); }
+	break;
+	case 130:
+#line 1141 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_SOA, &rdata_tail); }
+	break;
+	case 131:
+#line 1142 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_PTR, &rdata_tail); }
+	break;
+	case 132:
+#line 1143 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_HINFO, &rdata_tail); }
+	break;
+	case 133:
+#line 1144 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_MINFO, &rdata_tail); }
+	break;
+	case 134:
+#line 1145 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_MX, &rdata_tail); }
+	break;
+	case 135:
+#line 1146 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_TXT, &rdata_tail); }
+	break;
+	case 136:
+#line 1147 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_RP, &rdata_tail); }
+	break;
+	case 137:
+#line 1148 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_AFSDB, &rdata_tail); }
+	break;
+	case 138:
+#line 1149 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_RT, &rdata_tail); }
+	break;
+	case 139:
+#line 1150 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_KEY, &rdata_tail); }
+	break;
+	case 140:
+#line 1151 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_AAAA, &rdata_tail); }
+	break;
+	case 141:
+#line 1152 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_LOC, &rdata_tail); }
+	break;
+	case 142:
+#line 1153 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_SRV, &rdata_tail); }
+	break;
+	case 143:
+#line 1154 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_NAPTR, &rdata_tail); }
+	break;
+	case 144:
+#line 1155 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_KX, &rdata_tail); }
+	break;
+	case 145:
+#line 1156 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_CERT, &rdata_tail); }
+	break;
+	case 146:
+#line 1157 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_DNAME, &rdata_tail); }
+	break;
+	case 147:
+#line 1158 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_APL, &rdata_tail); }
+	break;
+	case 148:
+#line 1159 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_DS, &rdata_tail); }
+	break;
+	case 149:
+#line 1160 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_SSHFP, &rdata_tail); }
+	break;
+	case 150:
+#line 1161 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_IPSECKEY, &rdata_tail); }
+	break;
+	case 151:
+#line 1162 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_RRSIG, &rdata_tail); }
+	break;
+	case 152:
+#line 1163 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_NSEC, &rdata_tail); }
+	break;
+	case 153:
+#line 1164 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_DNSKEY, &rdata_tail); }
+	break;
+	case 154:
+#line 1165 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_DHCID, &rdata_tail); }
+	break;
+	case 155:
+#line 1166 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_NSEC3, &rdata_tail); }
+	break;
+	case 156:
+#line 1167 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_NSEC3PARAM, &rdata_tail); }
+	break;
+	case 157:
+#line 1168 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_TLSA, &rdata_tail); }
+	break;
+	case 158:
+#line 1169 "zscanner/scanner_body.rl"
+	{ type_num(KNOT_RRTYPE_SPF, &rdata_tail); }
+	break;
+	case 159:
+#line 1175 "zscanner/scanner_body.rl"
+	{
+		if (s->number64 <= UINT16_MAX) {
+			window_add_bit(s->number64, s);
+		} else {
+			SCANNER_WARNING(ZSCANNER_ENUMBER16_OVERFLOW);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 160:
+#line 1188 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_A, s); }
+	break;
+	case 161:
+#line 1189 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_NS, s); }
+	break;
+	case 162:
+#line 1190 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_CNAME, s); }
+	break;
+	case 163:
+#line 1191 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_SOA, s); }
+	break;
+	case 164:
+#line 1192 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_PTR, s); }
+	break;
+	case 165:
+#line 1193 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_HINFO, s); }
+	break;
+	case 166:
+#line 1194 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_MINFO, s); }
+	break;
+	case 167:
+#line 1195 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_MX, s); }
+	break;
+	case 168:
+#line 1196 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_TXT, s); }
+	break;
+	case 169:
+#line 1197 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_RP, s); }
+	break;
+	case 170:
+#line 1198 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_AFSDB, s); }
+	break;
+	case 171:
+#line 1199 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_RT, s); }
+	break;
+	case 172:
+#line 1200 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_KEY, s); }
+	break;
+	case 173:
+#line 1201 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_AAAA, s); }
+	break;
+	case 174:
+#line 1202 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_LOC, s); }
+	break;
+	case 175:
+#line 1203 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_SRV, s); }
+	break;
+	case 176:
+#line 1204 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_NAPTR, s); }
+	break;
+	case 177:
+#line 1205 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_KX, s); }
+	break;
+	case 178:
+#line 1206 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_CERT, s); }
+	break;
+	case 179:
+#line 1207 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_DNAME, s); }
+	break;
+	case 180:
+#line 1208 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_APL, s); }
+	break;
+	case 181:
+#line 1209 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_DS, s); }
+	break;
+	case 182:
+#line 1210 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_SSHFP, s); }
+	break;
+	case 183:
+#line 1211 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_IPSECKEY, s); }
+	break;
+	case 184:
+#line 1212 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_RRSIG, s); }
+	break;
+	case 185:
+#line 1213 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_NSEC, s); }
+	break;
+	case 186:
+#line 1214 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_DNSKEY, s); }
+	break;
+	case 187:
+#line 1215 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_DHCID, s); }
+	break;
+	case 188:
+#line 1216 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_NSEC3, s); }
+	break;
+	case 189:
+#line 1217 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_NSEC3PARAM, s); }
+	break;
+	case 190:
+#line 1218 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_TLSA, s); }
+	break;
+	case 191:
+#line 1219 "zscanner/scanner_body.rl"
+	{ window_add_bit(KNOT_RRTYPE_SPF, s); }
+	break;
+	case 192:
+#line 1223 "zscanner/scanner_body.rl"
+	{
+		memset(s->windows, 0, sizeof(s->windows));
+		s->last_window = -1;
+	}
+	break;
+	case 193:
+#line 1227 "zscanner/scanner_body.rl"
+	{
+		for (window = 0; window <= s->last_window; window++) {
+			if ((s->windows[window]).length > 0) {
+				if (rdata_tail + 2 + (s->windows[window]).length <= rdata_stop)
+				{
+					// Window number.
+					*rdata_tail = (uint8_t)window;
+					rdata_tail += 1;
+					// Bitmap length.
+					*rdata_tail = (s->windows[window]).length;
+					rdata_tail += 1;
+					// Copying bitmap.
+					memcpy(rdata_tail,
+					       (s->windows[window]).bitmap,
+					       (s->windows[window]).length);
+					rdata_tail += (s->windows[window]).length;
+				} else {
+					SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+					p--; {cs = 230; goto _again;}
+				}
+			}
+		}
+	}
+	break;
+	case 194:
+#line 1250 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_BITMAP);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 195:
+#line 1258 "zscanner/scanner_body.rl"
+	{ p--; {stack[top++] = cs; cs = 301; goto _again;} }
+	break;
+	case 196:
+#line 1262 "zscanner/scanner_body.rl"
+	{
+		if (s->number64 <= 90) {
+			s->loc.d1 = (uint32_t)(s->number64);
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 197:
+#line 1270 "zscanner/scanner_body.rl"
+	{
+		if (s->number64 <= 180) {
+			s->loc.d2 = (uint32_t)(s->number64);
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 198:
+#line 1278 "zscanner/scanner_body.rl"
+	{
+		if (s->number64 <= 59) {
+			s->loc.m1 = (uint32_t)(s->number64);
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 199:
+#line 1286 "zscanner/scanner_body.rl"
+	{
+		if (s->number64 <= 59) {
+			s->loc.m2 = (uint32_t)(s->number64);
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 200:
+#line 1294 "zscanner/scanner_body.rl"
+	{
+		if (s->number64 <= 59999) {
+			s->loc.s1 = (uint32_t)(s->number64);
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 201:
+#line 1302 "zscanner/scanner_body.rl"
+	{
+		if (s->number64 <= 59999) {
+			s->loc.s2 = (uint32_t)(s->number64);
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 202:
+#line 1310 "zscanner/scanner_body.rl"
+	{
+		if ((s->loc.alt_sign ==  1 && s->number64 <= 4284967295) ||
+		    (s->loc.alt_sign == -1 && s->number64 <=   10000000))
+		{
+			s->loc.alt = (uint32_t)(s->number64);
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 203:
+#line 1320 "zscanner/scanner_body.rl"
+	{
+		if (s->number64 <= 9000000000ULL) {
+			s->loc.siz = s->number64;
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 204:
+#line 1328 "zscanner/scanner_body.rl"
+	{
+		if (s->number64 <= 9000000000ULL) {
+			s->loc.hp = s->number64;
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 205:
+#line 1336 "zscanner/scanner_body.rl"
+	{
+		if (s->number64 <= 9000000000ULL) {
+			s->loc.vp = s->number64;
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+			p--; {cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 206:
+#line 1344 "zscanner/scanner_body.rl"
+	{
+		s->loc.lat_sign = -1;
+	}
+	break;
+	case 207:
+#line 1347 "zscanner/scanner_body.rl"
+	{
+		s->loc.long_sign = -1;
+	}
+	break;
+	case 208:
+#line 1350 "zscanner/scanner_body.rl"
+	{
+		s->loc.alt_sign = -1;
+	}
+	break;
+	case 209:
+#line 1367 "zscanner/scanner_body.rl"
+	{
+		memset(&(s->loc), 0, sizeof(s->loc));
+		// Defaults.
+		s->loc.siz = 100;
+		s->loc.vp  = 1000;
+		s->loc.hp  = 1000000;
+		s->loc.lat_sign  = 1;
+		s->loc.long_sign = 1;
+		s->loc.alt_sign  = 1;
+	}
+	break;
+	case 210:
+#line 1377 "zscanner/scanner_body.rl"
+	{
+		// Write version.
+		*(rdata_tail) = 0;
+		rdata_tail += 1;
+		// Write size.
+		*(rdata_tail) = loc64to8(s->loc.siz);
+		rdata_tail += 1;
+		// Write horizontal precision.
+		*(rdata_tail) = loc64to8(s->loc.hp);
+		rdata_tail += 1;
+		// Write vertical precision.
+		*(rdata_tail) = loc64to8(s->loc.vp);
+		rdata_tail += 1;
+		// Write latitude.
+		*((uint32_t *)rdata_tail) = htonl(LOC_LAT_ZERO + s->loc.lat_sign *
+			(3600000 * s->loc.d1 + 60000 * s->loc.m1 + s->loc.s1));
+		rdata_tail += 4;
+		// Write longitude.
+		*((uint32_t *)rdata_tail) = htonl(LOC_LONG_ZERO + s->loc.long_sign *
+			(3600000 * s->loc.d2 + 60000 * s->loc.m2 + s->loc.s2));
+		rdata_tail += 4;
+		// Write altitude.
+		*((uint32_t *)rdata_tail) = htonl(LOC_ALT_ZERO + s->loc.alt_sign *
+			(s->loc.alt));
+		rdata_tail += 4;
+	}
+	break;
+	case 211:
+#line 1403 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_LOC_DATA);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 212:
+#line 1416 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_HEX_RDATA);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 213:
+#line 1433 "zscanner/scanner_body.rl"
+	{
+		s->r_data_blocks[0] = 0;
+		s->r_data_blocks_count = 0;
+		rdata_tail = s->r_data;
+	}
+	break;
+	case 214:
+#line 1438 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_RDATA);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 215:
+#line 1540 "zscanner/scanner_body.rl"
+	{
+		p--;
+		switch (s->r_type) {
+		case KNOT_RRTYPE_A:
+			{stack[top++] = cs; cs = 426; goto _again;}
+		case KNOT_RRTYPE_NS:
+		case KNOT_RRTYPE_CNAME:
+		case KNOT_RRTYPE_PTR:
+		case KNOT_RRTYPE_DNAME:
+			{stack[top++] = cs; cs = 428; goto _again;}
+		case KNOT_RRTYPE_SOA:
+			{stack[top++] = cs; cs = 430; goto _again;}
+		case KNOT_RRTYPE_HINFO:
+			{stack[top++] = cs; cs = 462; goto _again;}
+		case KNOT_RRTYPE_MINFO:
+		case KNOT_RRTYPE_RP:
+			{stack[top++] = cs; cs = 467; goto _again;}
+		case KNOT_RRTYPE_MX:
+		case KNOT_RRTYPE_AFSDB:
+		case KNOT_RRTYPE_RT:
+		case KNOT_RRTYPE_KX:
+			{stack[top++] = cs; cs = 472; goto _again;}
+		case KNOT_RRTYPE_TXT:
+		case KNOT_RRTYPE_SPF:
+			{stack[top++] = cs; cs = 477; goto _again;}
+		case KNOT_RRTYPE_AAAA:
+			{stack[top++] = cs; cs = 481; goto _again;}
+		case KNOT_RRTYPE_LOC:
+			{stack[top++] = cs; cs = 483; goto _again;}
+		case KNOT_RRTYPE_SRV:
+			{stack[top++] = cs; cs = 538; goto _again;}
+		case KNOT_RRTYPE_NAPTR:
+			{stack[top++] = cs; cs = 549; goto _again;}
+		case KNOT_RRTYPE_CERT:
+			{stack[top++] = cs; cs = 566; goto _again;}
+		case KNOT_RRTYPE_APL:
+			{stack[top++] = cs; cs = 577; goto _again;}
+		case KNOT_RRTYPE_DS:
+			{stack[top++] = cs; cs = 588; goto _again;}
+		case KNOT_RRTYPE_SSHFP:
+			{stack[top++] = cs; cs = 601; goto _again;}
+		case KNOT_RRTYPE_IPSECKEY:
+			{stack[top++] = cs; cs = 611; goto _again;}
+		case KNOT_RRTYPE_RRSIG:
+			{stack[top++] = cs; cs = 650; goto _again;}
+		case KNOT_RRTYPE_NSEC:
+			{stack[top++] = cs; cs = 778; goto _again;}
+		case KNOT_RRTYPE_KEY:
+		case KNOT_RRTYPE_DNSKEY:
+			{stack[top++] = cs; cs = 781; goto _again;}
+		case KNOT_RRTYPE_DHCID:
+			{stack[top++] = cs; cs = 792; goto _again;}
+		case KNOT_RRTYPE_NSEC3:
+			{stack[top++] = cs; cs = 794; goto _again;}
+		case KNOT_RRTYPE_NSEC3PARAM:
+			{stack[top++] = cs; cs = 823; goto _again;}
+		case KNOT_RRTYPE_TLSA:
+			{stack[top++] = cs; cs = 836; goto _again;}
+		default:
+			SCANNER_WARNING(ZSCANNER_ECANNOT_TEXT_DATA);
+			{cs = 230; goto _again;}
+		}
+	}
+	break;
+	case 216:
+#line 1603 "zscanner/scanner_body.rl"
+	{
+		switch (s->r_type) {
+		// Next types must not have empty rdata.
+		case KNOT_RRTYPE_A:
+		case KNOT_RRTYPE_NS:
+		case KNOT_RRTYPE_CNAME:
+		case KNOT_RRTYPE_PTR:
+		case KNOT_RRTYPE_DNAME:
+		case KNOT_RRTYPE_SOA:
+		case KNOT_RRTYPE_HINFO:
+		case KNOT_RRTYPE_MINFO:
+		case KNOT_RRTYPE_MX:
+		case KNOT_RRTYPE_AFSDB:
+		case KNOT_RRTYPE_RT:
+		case KNOT_RRTYPE_KX:
+		case KNOT_RRTYPE_TXT:
+		case KNOT_RRTYPE_SPF:
+		case KNOT_RRTYPE_RP:
+		case KNOT_RRTYPE_AAAA:
+		case KNOT_RRTYPE_LOC:
+		case KNOT_RRTYPE_SRV:
+		case KNOT_RRTYPE_NAPTR:
+		case KNOT_RRTYPE_CERT:
+		case KNOT_RRTYPE_DS:
+		case KNOT_RRTYPE_SSHFP:
+		case KNOT_RRTYPE_IPSECKEY:
+		case KNOT_RRTYPE_RRSIG:
+		case KNOT_RRTYPE_NSEC:
+		case KNOT_RRTYPE_KEY:
+		case KNOT_RRTYPE_DNSKEY:
+		case KNOT_RRTYPE_DHCID:
+		case KNOT_RRTYPE_NSEC3:
+		case KNOT_RRTYPE_NSEC3PARAM:
+		case KNOT_RRTYPE_TLSA:
+			{stack[top++] = cs; cs = 407; goto _again;}
+		// Next types can have empty rdata.
+		case KNOT_RRTYPE_APL:
+		default:
+			{stack[top++] = cs; cs = 416; goto _again;}
+		}
+	}
+	break;
+	case 217:
+#line 1645 "zscanner/scanner_body.rl"
+	{
+		s->r_data_blocks[++(s->r_data_blocks_count)] =
+			(uint16_t)(rdata_tail - s->r_data);
+	}
+	break;
+	case 218:
+#line 1653 "zscanner/scanner_body.rl"
+	{ p--; }
+	break;
+	case 219:
+#line 1660 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EUNSUPPORTED_TYPE);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 220:
+#line 1666 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_A; }
+	break;
+	case 221:
+#line 1667 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_NS; }
+	break;
+	case 222:
+#line 1668 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_CNAME; }
+	break;
+	case 223:
+#line 1669 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_SOA; }
+	break;
+	case 224:
+#line 1670 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_PTR; }
+	break;
+	case 225:
+#line 1671 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_HINFO; }
+	break;
+	case 226:
+#line 1672 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_MINFO; }
+	break;
+	case 227:
+#line 1673 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_MX; }
+	break;
+	case 228:
+#line 1674 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_TXT; }
+	break;
+	case 229:
+#line 1675 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_RP; }
+	break;
+	case 230:
+#line 1676 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_AFSDB; }
+	break;
+	case 231:
+#line 1677 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_RT; }
+	break;
+	case 232:
+#line 1678 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_KEY; }
+	break;
+	case 233:
+#line 1679 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_AAAA; }
+	break;
+	case 234:
+#line 1680 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_LOC; }
+	break;
+	case 235:
+#line 1681 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_SRV; }
+	break;
+	case 236:
+#line 1682 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_NAPTR; }
+	break;
+	case 237:
+#line 1683 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_KX; }
+	break;
+	case 238:
+#line 1684 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_CERT; }
+	break;
+	case 239:
+#line 1685 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_DNAME; }
+	break;
+	case 240:
+#line 1686 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_APL; }
+	break;
+	case 241:
+#line 1687 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_DS; }
+	break;
+	case 242:
+#line 1688 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_SSHFP; }
+	break;
+	case 243:
+#line 1689 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_IPSECKEY; }
+	break;
+	case 244:
+#line 1690 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_RRSIG; }
+	break;
+	case 245:
+#line 1691 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_NSEC; }
+	break;
+	case 246:
+#line 1692 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_DNSKEY; }
+	break;
+	case 247:
+#line 1693 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_DHCID; }
+	break;
+	case 248:
+#line 1694 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_NSEC3; }
+	break;
+	case 249:
+#line 1695 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_NSEC3PARAM; }
+	break;
+	case 250:
+#line 1696 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_TLSA; }
+	break;
+	case 251:
+#line 1697 "zscanner/scanner_body.rl"
+	{ s->r_type = KNOT_RRTYPE_SPF; }
+	break;
+	case 252:
+#line 1703 "zscanner/scanner_body.rl"
+	{
+		if (rdata_tail - s->r_data > UINT16_MAX) {
+			SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+			p--; {cs = 230; goto _again;}
+		}
+		s->r_data_length = rdata_tail - s->r_data;
+
+		s->process_record(s);
+	}
+	break;
+#line 6586 "zscanner/scanner.c"
+		}
+	}
+
+_again:
+	if ( cs == 0 )
+		goto _out;
+	if ( ++p != pe )
+		goto _resume;
+	_test_eof: {}
+	if ( p == eof )
+	{
+	const unsigned char *__acts = _zone_scanner_actions + _zone_scanner_eof_actions[cs];
+	unsigned int __nacts = (unsigned int) *__acts++;
+	while ( __nacts-- > 0 ) {
+		switch ( *__acts++ ) {
+	case 4:
+#line 44 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_REST);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 15:
+#line 145 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 20:
+#line 191 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_DNAME_CHAR);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 28:
+#line 244 "zscanner/scanner_body.rl"
+	{
+		s->r_owner_length = 0;
+		SCANNER_WARNING(ZSCANNER_EBAD_OWNER);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 33:
+#line 287 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 45:
+#line 388 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_TIME_UNIT);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 55:
+#line 492 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_TIMESTAMP_CHAR);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 57:
+#line 510 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_TEXT_CHAR);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 58:
+#line 514 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_TEXT);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 62:
+#line 544 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 65:
+#line 584 "zscanner/scanner_body.rl"
+	{
+		SCANNER_ERROR(ZSCANNER_EBAD_TTL);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 69:
+#line 601 "zscanner/scanner_body.rl"
+	{
+		SCANNER_ERROR(ZSCANNER_EBAD_ORIGIN);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 73:
+#line 628 "zscanner/scanner_body.rl"
+	{
+		SCANNER_ERROR(ZSCANNER_EBAD_INCLUDE_FILENAME);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 76:
+#line 639 "zscanner/scanner_body.rl"
+	{
+		SCANNER_ERROR(ZSCANNER_EBAD_INCLUDE_ORIGIN);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 80:
+#line 718 "zscanner/scanner_body.rl"
+	{
+		s->stop = false;
+	}
+	break;
+	case 81:
+#line 721 "zscanner/scanner_body.rl"
+	{
+		SCANNER_ERROR(ZSCANNER_EBAD_DIRECTIVE);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 88:
+#line 772 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_ADDRESS_CHAR);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 99:
+#line 880 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_APL);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 102:
+#line 910 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_HEX_CHAR);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 104:
+#line 937 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_HEX_RDATA);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 109:
+#line 979 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_BASE64_CHAR);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 119:
+#line 1063 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_BASE32HEX_CHAR);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 124:
+#line 1110 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_GATEWAY);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 125:
+#line 1114 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_GATEWAY_KEY);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 126:
+#line 1132 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EUNSUPPORTED_TYPE);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 194:
+#line 1250 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_BITMAP);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 211:
+#line 1403 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_LOC_DATA);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 212:
+#line 1416 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_HEX_RDATA);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 214:
+#line 1438 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EBAD_RDATA);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+	case 219:
+#line 1660 "zscanner/scanner_body.rl"
+	{
+		SCANNER_WARNING(ZSCANNER_EUNSUPPORTED_TYPE);
+		p--; {cs = 230; goto _again;}
+	}
+	break;
+#line 6812 "zscanner/scanner.c"
+		}
+	}
+	}
+
+	_out: {}
+	}
+
+#line 138 "zscanner/scanner.rl"
+
+	// Check if scanner state machine is in uncovered state.
+	if (cs == zone_scanner_error) {
+		SCANNER_ERROR(ZSCANNER_UNCOVERED_STATE);
+		s->error_counter++;
+
+		// Fill error context data.
+		for (s->buffer_length = 0;
+		     ((p + s->buffer_length) < pe) &&
+		     (s->buffer_length < sizeof(s->buffer) - 1);
+		     s->buffer_length++)
+		{
+			// Only rest of the current line.
+			if (*(p + s->buffer_length) == '\n') {
+				break;
+			}
+			s->buffer[s->buffer_length] = *(p + s->buffer_length);
+		}
+
+		// Ending string in buffer.
+		s->buffer[s->buffer_length++] = 0;
+
+		// Processing error.
+		s->process_error(s);
+
+		return -1;
+	}
+
+	// Storing scanner states.
+	s->cs  = cs;
+	s->top = top;
+	memcpy(s->stack, stack, sizeof(stack));
+
+	// Storing r_data pointer.
+	s->r_data_tail = rdata_tail - s->r_data;
+
+	// Check if any errors has occured.
+	if (s->error_counter > 0) {
+		return -1;
+	}
+
+	return 0;
+}
+
diff --git a/src/zscanner/scanner.h b/src/zscanner/scanner.h
new file mode 100644
index 0000000000000000000000000000000000000000..06b6a2e74d2c06d17a54b76c1474ce967b3089c3
--- /dev/null
+++ b/src/zscanner/scanner.h
@@ -0,0 +1,266 @@
+/*  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/>.
+ */
+/*!
+ * \file scanner.h
+ *
+ * \author Daniel Salzman <daniel.salzman@nic.cz>
+ *
+ * \brief Zone scanner.
+ *
+ * \addtogroup zone_scanner
+ * @{
+ */
+
+#ifndef _ZSCANNER__SCANNER_H_
+#define _ZSCANNER__SCANNER_H_
+
+#include <stdint.h>			// uint32_t
+#include <stdbool.h>			// bool
+#include <arpa/inet.h>			// htons
+
+/*! \brief Maximal length of rdata. */
+#define MAX_RDATA_LENGTH	       65535
+/*! \brief Maximal length of rdata item. */
+#define MAX_ITEM_LENGTH			 255
+/*! \brief Maximal length of domain name. */
+#define MAX_DNAME_LENGTH		 255
+/*! \brief Maximal length of domain name label. */
+#define MAX_LABEL_LENGTH		  63
+/*! \brief Maximal number or rdata items. */
+#define MAX_RDATA_ITEMS			  64
+
+/*! \brief Number of bitmap windows. */
+#define BITMAP_WINDOWS			 256
+
+/*! \brief Length of ipv4 address in wire format. */
+#define INET4_ADDR_LENGTH		   4
+/*! \brief Length of ipv6 address in wire format. */
+#define INET6_ADDR_LENGTH		  16
+
+/*! \brief Ragel call stack size (see Ragel internals). */
+#define RAGEL_STACK_SIZE		  16
+
+/*! \brief ASCII value of '0' character. */
+#define ASCII_0				  48
+
+/*! \brief Latitude value for equator (2^31). */
+#define LOC_LAT_ZERO	(uint32_t)2147483648
+/*! \brief Longitude value for meridian (2^31). */
+#define LOC_LONG_ZERO	(uint32_t)2147483648
+/*! \brief Zero level altitude value. */
+#define LOC_ALT_ZERO	  (uint32_t)10000000
+
+/*! \brief Auxiliary structure for storing bitmap window items (see RFC4034). */
+typedef struct {
+	uint8_t bitmap[32];
+	uint8_t length;
+} window_t;
+
+/*! \brief Auxiliary structure for storing one APL record (see RFC3123). */
+typedef struct {
+	uint8_t  excl_flag;
+	uint16_t addr_family;
+	uint8_t  prefix_length;
+} apl_t;
+
+/*! \brief Auxiliary structure for storing LOC information (see RFC1876). */
+typedef struct {
+	uint32_t d1, d2;
+	uint32_t m1, m2;
+	uint32_t s1, s2;
+	uint32_t alt;
+	uint64_t siz, hp, vp;
+	int8_t   lat_sign, long_sign, alt_sign;
+} loc_t;
+
+/*!
+ * \brief Context structure for Ragel scanner.
+ *
+ * This structure contains folowing items:
+ *  - Copies of Ragel internal variables. The scanner is called many times
+ *    for each block of zone file. So it is necessary to preserve internal
+ *    values between subsequent scanner callings.
+ *  - Auxiliary variables which are used during processing zone data.
+ *  - Zone file and error information.
+ *  - Pointers to callback functions and pointer to any arbitrary data which
+ *    can be used in callback functions.
+ *  - Output variables containing all parts of zone record. These data are
+ *    usefull during processing via callback function.
+ */
+typedef struct scanner scanner_t; // Forward declaration due to arguments.
+struct scanner {
+	/*! Current state (Ragel internals). */
+	int	 cs;
+	/*! Stack top (Ragel internals). */
+	int	 top;
+	/*! Call stack (Ragel internals). */
+	int	 stack[RAGEL_STACK_SIZE];
+
+	/*! Zone file name. */
+	char     *file_name;
+	/*! Zone file line counter. */
+	uint64_t line_counter;
+
+	/*! Last occured error/warning code. */
+	int      error_code;
+	/*! Errors/warnings counter. */
+	uint64_t error_counter;
+	/*!
+	 * Indicates serious warning which is considered as an error and
+	 * forces zone processing to stop.
+	 */
+	bool     stop;
+
+	/*! Callback function for correct zone record. */
+	void (*process_record)(const scanner_t *);
+	/*! Callback function for wrong situations. */
+	void (*process_error)(const scanner_t *);
+	/*! Arbitrary data useful inside callback functions. */
+	void *data;
+
+	/*! Indicates whether current record is multiline. */
+	bool     multiline;
+	/*! Auxiliary number for all numeric operations. */
+	uint64_t number64;
+	/*! Auxiliary variable for time and other numeric operations. */
+	uint64_t number64_tmp;
+	/*! Auxiliary variable for float numeric operations. */
+	uint32_t decimals;
+	/*! Auxiliary variable for float numeric operations. */
+	uint32_t decimal_counter;
+
+	/*! Auxiliary variable for item length (label, base64, ...). */
+	uint32_t item_length;
+	/*! Auxiliary index for item length position in array. */
+	uint32_t item_length_position;
+	/*! Auxiliary pointer to item length. */
+	uint8_t *item_length_location;
+	/*! Auxiliary buffer for data storing. */
+	uint8_t  buffer[MAX_RDATA_LENGTH];
+	/*! Auxiliary buffer length. */
+	uint32_t buffer_length;
+	/*! Auxiliary buffer for current included file name. */
+	char     include_filename[MAX_RDATA_LENGTH + 1];
+
+	/*! Auxiliary array of bitmap window blocks. */
+	window_t windows[BITMAP_WINDOWS];
+	/*! Last window block which is used (-1 means no window). */
+	int16_t  last_window;
+	/*! Auxiliary apl structure. */
+	apl_t    apl;
+	/*! Auxiliary loc structure. */
+	loc_t    loc;
+
+	/*! Pointer to the actual dname storage (origin/owner/rdata). */
+	uint8_t  *dname;
+	/*! Pointer to the actual dname length storage. */
+	uint32_t *dname_length;
+	/*!
+	 * Temporary dname length which is copied to dname_length after
+	 * dname processing.
+	 */
+	uint32_t dname_tmp_length;
+	/*! Position of the last free r_data byte. */
+	uint32_t r_data_tail;
+
+	/*! Wire format of the current origin (ORIGIN directive sets this). */
+	uint8_t  zone_origin[MAX_DNAME_LENGTH];
+	/*! Length of the current origin. */
+	uint32_t zone_origin_length;
+	/*! Value of the default class. */
+	uint16_t default_class;
+	/*! Value of the current default ttl (TTL directive sets this). */
+	uint32_t default_ttl;
+
+	/*!
+	 * Owner of the current record.
+	 *
+	 * \note The double length of the r_owner is due to dname length
+	 *       check is after concatenation of relative and origin dnames.
+	 */
+	uint8_t  r_owner[2 * MAX_DNAME_LENGTH];
+	/*! Length of the current record owner. */
+	uint32_t r_owner_length;
+	/*! Class of the current record. */
+	uint16_t r_class;
+	/*! TTL of the current record. */
+	uint32_t r_ttl;
+	/*! Type of the current record data. */
+	uint16_t r_type;
+	/*! Current rdata. */
+	uint8_t  r_data[MAX_RDATA_LENGTH];
+	/*! Length of the current rdata. */
+	uint32_t r_data_length;
+	/*! Indexes of the current rdata blocks. */
+	uint16_t r_data_blocks[MAX_RDATA_ITEMS];
+	/*! Number or the current rdata blocks. */
+	uint32_t r_data_blocks_count;
+
+	/*
+	 * Example: a. IN 60 MX 1 b.
+	 *
+	 *          r_owner = 016100
+	 *          r_owner_length = 3
+	 *          r_class = 1
+	 *          r_ttl = 60
+	 *          r_type = 15
+	 *          r_data = 0001016200
+	 *          r_data_length = 5
+	 *          r_data_blocks_count = 2
+	 *          r_data_blocks = [0, 2, 5]
+	 */
+};
+
+/*!
+ * \brief Creates zone scanner structure.
+ *
+ * \param file_name	Zone file name.
+ *
+ * \retval scanner	if success.
+ * \retval 0		if error.
+ */
+scanner_t* scanner_create(const char *file_name);
+
+/*!
+ * \brief Destroys zone scanner structure.
+ *
+ * \param scanner	Zone scanner structure.
+ */
+void scanner_free(scanner_t *scanner);
+
+/*!
+ * \brief Executes zone scanner on data block.
+ *
+ * \note Zone scanner error code and other information are stored in
+ *       the scanner structure.
+ *
+ * \param start		First byte of the zone data to scan.
+ * \param end		Last byte of the zone data to scan.
+ * \param is_last_block	Indicates if current block is last.
+ * \param scanner	Zone scanner structure.
+ *
+ * \retval  0		if success.
+ * \retval -1		if error.
+ */
+int scanner_process(char      *start,
+		    char      *end,
+		    bool      is_last_block,
+		    scanner_t *scanner);
+
+
+#endif // _ZSCANNER__SCANNER_H_
+
+/*! @} */
diff --git a/src/zscanner/scanner.rl b/src/zscanner/scanner.rl
new file mode 100644
index 0000000000000000000000000000000000000000..00cea8d9db3ddf92ea7189140f5fb0d84a538964
--- /dev/null
+++ b/src/zscanner/scanner.rl
@@ -0,0 +1,181 @@
+/*  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/>.
+ */
+
+#include "zscanner/scanner.h"
+
+#include <stdint.h>			// uint32_t
+#include <stdlib.h>			// calloc
+#include <stdio.h>			// sprintf
+#include <libgen.h>			// dirname
+#include <stdbool.h>			// bool
+#include <math.h>			// pow
+#include <string.h>			// strdup
+#include <sys/socket.h>			// AF_INET (BSD)
+#include <netinet/in.h>			// in_addr (BSD)
+
+#include "common/errcode.h"		// error codes
+#include "common/descriptor_new.h"	// KNOT_RRTYPE_A
+#include "zscanner/file_loader.h"	// file_loader
+#include "zscanner/scanner_functions.h"	// Base64
+
+/*! \brief Shorthand for setting warning data. */
+#define SCANNER_WARNING(code) { s->error_code = code; }
+/*! \brief Shorthand for setting error data. */
+#define SCANNER_ERROR(code)   { s->error_code = code; s->stop = true; }
+
+/*!
+ * \brief Writes record type number to r_data.
+ *
+ * \param type		Type number.
+ * \param rdata_tail	Position where to write type number to.
+ */
+static inline void type_num(const uint16_t type, uint8_t **rdata_tail)
+{
+	*((uint16_t *)*rdata_tail) = htons(type);
+	*rdata_tail += 2;
+}
+
+/*!
+ * \brief Sets bit to bitmap window.
+ *
+ * \param type		Type number.
+ * \param s		Scanner context.
+ */
+static inline void window_add_bit(const uint16_t type, scanner_t *s) {
+	uint8_t win      = type / 256;
+	uint8_t bit_pos  = type % 256;
+	uint8_t byte_pos = bit_pos / 8;
+
+	((s->windows[win]).bitmap)[byte_pos] |= 128 >> (bit_pos % 8);
+
+	if ((s->windows[win]).length < byte_pos + 1) {
+		(s->windows[win]).length = byte_pos + 1;
+	}
+
+	if (s->last_window < win) {
+		s->last_window = win;
+	}
+}
+
+// Include scanner file (in Ragel).
+%%{
+	machine zone_scanner;
+
+	include "scanner_body.rl";
+
+	write data;
+}%%
+
+scanner_t* scanner_create(const char *file_name)
+{
+	scanner_t *s = calloc(1, sizeof(scanner_t));
+	if (s == NULL) {
+		return NULL;
+	}
+
+	s->file_name = strdup(file_name);
+	s->line_counter = 1;
+
+	// Nonzero initial scanner state.
+	s->cs = zone_scanner_start;
+
+	return s;
+}
+
+void scanner_free(scanner_t *s)
+{
+	free(s->file_name);
+	free(s);
+}
+
+int scanner_process(char      *start,
+		    char      *end,
+		    bool      is_last_block,
+		    scanner_t *s)
+{
+	// Necessary scanner variables.
+	int  stack[RAGEL_STACK_SIZE];
+	char *p = start, *pe = end, *eof = NULL;
+
+	// Auxiliary variables which are used in scanner body.
+	struct in_addr  addr4;
+	struct in6_addr addr6;
+	uint32_t timestamp;
+	int16_t  window;
+	int	 ret;
+
+	// Next 2 variables are for better performance.
+	// Restoring r_data pointer to next free space.
+	uint8_t *rdata_tail = s->r_data + s->r_data_tail;
+	// Initialization of the last r_data byte.
+	uint8_t *rdata_stop = s->r_data + MAX_RDATA_LENGTH - 1;
+
+	// Restoring scanner states.
+	int cs  = s->cs;
+	int top = s->top;
+	memcpy(stack, s->stack, sizeof(stack));
+
+	// End of file check.
+	if (is_last_block == true) {
+		eof = pe;
+	}
+
+	// Writing scanner body (in C).
+	%% write exec;
+
+	// Check if scanner state machine is in uncovered state.
+	if (cs == zone_scanner_error) {
+		SCANNER_ERROR(ZSCANNER_UNCOVERED_STATE);
+		s->error_counter++;
+
+		// Fill error context data.
+		for (s->buffer_length = 0;
+		     ((p + s->buffer_length) < pe) &&
+		     (s->buffer_length < sizeof(s->buffer) - 1);
+		     s->buffer_length++)
+		{
+			// Only rest of the current line.
+			if (*(p + s->buffer_length) == '\n') {
+				break;
+			}
+			s->buffer[s->buffer_length] = *(p + s->buffer_length);
+		}
+
+		// Ending string in buffer.
+		s->buffer[s->buffer_length++] = 0;
+
+		// Processing error.
+		s->process_error(s);
+
+		return -1;
+	}
+
+	// Storing scanner states.
+	s->cs  = cs;
+	s->top = top;
+	memcpy(s->stack, stack, sizeof(stack));
+
+	// Storing r_data pointer.
+	s->r_data_tail = rdata_tail - s->r_data;
+
+	// Check if any errors has occured.
+	if (s->error_counter > 0) {
+		return -1;
+	}
+
+	return 0;
+}
+
diff --git a/src/zscanner/scanner_body.rl b/src/zscanner/scanner_body.rl
new file mode 100644
index 0000000000000000000000000000000000000000..0c5162c8126f5da5a6791035584da33e008d1635
--- /dev/null
+++ b/src/zscanner/scanner_body.rl
@@ -0,0 +1,1731 @@
+/*  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/>.
+ */
+%%{
+	machine zone_scanner;
+
+	# Comeback function to calling state machine.
+	action _ret {
+		fhold; fret;
+	}
+
+	# BEGIN - Blank space processing
+	action _newline {
+		s->line_counter++;
+	}
+
+	action _check_multiline_begin {
+		if (s->multiline == true) {
+			SCANNER_ERROR(ZSCANNER_ELEFT_PARENTHESIS);
+			fhold; fgoto err_line;
+		}
+		s->multiline = true;
+	}
+	action _check_multiline_end {
+		if (s->multiline == false) {
+			SCANNER_ERROR(ZSCANNER_ERIGHT_PARENTHESIS);
+			fhold; fgoto err_line;
+		}
+		s->multiline = false;
+	}
+
+	action _rest_error {
+		SCANNER_WARNING(ZSCANNER_EBAD_REST);
+		fhold; fgoto err_line;
+	}
+
+	newline = '\n' $_newline;
+	comment = ';' . (^newline)*;
+
+	# White space separation. With respect to parentheses and included comments.
+	sep = ( [ \t]                                       # Blank characters.
+	      | (comment? . newline) when { s->multiline }  # Comment in multiline.
+	      | '(' $_check_multiline_begin                 # Start of multiline.
+	      | ')' $_check_multiline_end                   # End of multiline.
+	      )+;                                           # Apply more times.
+
+	rest = (sep? :> comment?) $!_rest_error; # Useless text after record.
+
+	# Artificial machines which are used for next state transition only!
+	all_wchar = [ \t\n;()];
+	end_wchar = [\n;] when { !s->multiline }; # For noncontinuous ending tokens.
+	# END
+
+	# BEGIN - Error line processing
+	action _err_line_init {
+		s->buffer_length = 0;
+	}
+	action _err_line {
+		if (s->buffer_length < sizeof(s->buffer) - 1) {
+			s->buffer[s->buffer_length++] = fc;
+		}
+	}
+	action _err_line_exit {
+		// Ending string in buffer.
+		s->buffer[s->buffer_length++] = 0;
+
+		// Error counter incrementation.
+		s->error_counter++;
+
+		// Initialization of fcall stack.
+		top = 0;
+
+		// Process error message.
+		s->process_error(s);
+
+		// Reset.
+		s->error_code = KNOT_EOK;
+		s->multiline = false;
+
+		// In case of serious error, stop scanner.
+		if (s->stop == true) {
+			return -1;
+		}
+	}
+
+	# Fill rest of the line to buffer and skip to main loop.
+	err_line := (^newline $_err_line)* >_err_line_init
+	            %_err_line_exit . newline @{ fgoto main; };
+	# END
+
+	# BEGIN - Domain name labels processing
+	action _label_init {
+		s->item_length = 0;
+		s->item_length_position = s->dname_tmp_length++;
+	}
+	action _label_char {
+		if (s->item_length < MAX_LABEL_LENGTH) {
+			(s->dname)[s->dname_tmp_length++] = fc;
+			s->item_length++;
+		} else {
+			SCANNER_WARNING(ZSCANNER_ELABEL_OVERFLOW);
+			fhold; fgoto err_line;
+		}
+	}
+	action _label_exit {
+		if (s->dname_tmp_length < MAX_DNAME_LENGTH) {
+			(s->dname)[s->item_length_position] =
+				(uint8_t)(s->item_length);
+		} else {
+			SCANNER_WARNING(ZSCANNER_EDNAME_OVERFLOW);
+			fhold; fgoto err_line;
+		}
+	}
+
+	action _label_dec_init {
+		if (s->item_length < MAX_LABEL_LENGTH) {
+			(s->dname)[s->dname_tmp_length] = 0;
+			s->item_length++;
+		} else {
+			SCANNER_WARNING(ZSCANNER_ELABEL_OVERFLOW);
+			fhold; fgoto err_line;
+		}
+	}
+	action _label_dec {
+		(s->dname)[s->dname_tmp_length] *= 10;
+		(s->dname)[s->dname_tmp_length] += digit_to_num[(uint8_t)fc];
+	}
+	action _label_dec_exit {
+		(s->dname)[s->dname_tmp_length] =
+			(s->dname)[s->dname_tmp_length];
+		s->dname_tmp_length++;
+	}
+	action _label_dec_error {
+		SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+		fhold; fgoto err_line;
+	}
+
+	label_char =
+	    ( (alnum | [\-_/]) $_label_char                 # One common char.
+	    | ('\\' . ^digit)  @_label_char                 # One "\x" char.
+	    | ('\\'            %_label_dec_init             # Initial "\" char.
+	       . digit {3}     $_label_dec %_label_dec_exit # "DDD" rest.
+	                       $!_label_dec_error
+	      )
+	    );
+
+	label  = (label_char+ | ('*' $_label_char)) >_label_init %_label_exit;
+	labels = (label . '.')* . label;
+	# END
+
+	# BEGIN - Domain name processing.
+	action _absolute_dname_exit {
+		(s->dname)[s->dname_tmp_length++] = 0;
+	}
+	action _relative_dname_exit {
+		memcpy(s->dname + s->dname_tmp_length,
+		       s->zone_origin,
+		       s->zone_origin_length);
+
+		s->dname_tmp_length += s->zone_origin_length;
+
+		if (s->dname_tmp_length > MAX_DNAME_LENGTH) {
+			SCANNER_WARNING(ZSCANNER_EDNAME_OVERFLOW);
+			fhold; fgoto err_line;
+		}
+	}
+	action _origin_dname_exit {
+		memcpy(s->dname,
+		       s->zone_origin,
+		       s->zone_origin_length);
+
+		s->dname_tmp_length = s->zone_origin_length;
+	}
+
+	action _dname_init {
+		s->item_length_position = 0;
+		s->dname_tmp_length = 0;
+	}
+	action _dname_error {
+		SCANNER_WARNING(ZSCANNER_EBAD_DNAME_CHAR);
+		fhold; fgoto err_line;
+	}
+
+	relative_dname = (labels       ) >_dname_init %_relative_dname_exit;
+	absolute_dname = (labels? . '.') >_dname_init %_absolute_dname_exit;
+
+	dname_ := ( relative_dname
+	          | absolute_dname
+	          | '@' %_origin_dname_exit
+	          ) $!_dname_error %_ret . all_wchar;
+	dname = (alnum | [\-_/\\] | [*.@]) ${ fhold; fcall dname_; };
+	# END
+
+	# BEGIN - Common r_data item processing
+	action _item_length_init {
+		s->item_length_location = rdata_tail++;
+	}
+	action _item_length_exit {
+		s->item_length = rdata_tail - s->item_length_location - 1;
+
+		if (s->item_length <= MAX_ITEM_LENGTH) {
+			*(s->item_length_location) = (uint8_t)(s->item_length);
+		} else {
+			SCANNER_WARNING(ZSCANNER_EITEM_OVERFLOW);
+			fhold; fgoto err_line;
+		}
+	}
+
+	action _separate {
+		s->r_data_blocks[++(s->r_data_blocks_count)] =
+			rdata_tail - s->r_data;
+	}
+
+	# Rdata blocks dividing.
+	blk_sep = zlen >_separate;
+	# END
+
+	# BEGIN - Owner processing
+	action _r_owner_init {
+		s->dname = s->r_owner;
+		s->r_owner_length = 0;
+	}
+	action _r_owner_exit {
+		s->r_owner_length = s->dname_tmp_length;
+	}
+	action _r_owner_empty_exit {
+		if (s->r_owner_length == 0) {
+			SCANNER_WARNING(ZSCANNER_EBAD_PREVIOUS_OWNER);
+			fhold; fgoto err_line;
+		}
+	}
+	action _r_owner_error {
+		s->r_owner_length = 0;
+		SCANNER_WARNING(ZSCANNER_EBAD_OWNER);
+		fhold; fgoto err_line;
+	}
+
+	r_owner = ( dname >_r_owner_init %_r_owner_exit
+	          | zlen  %_r_owner_empty_exit # Empty owner - use the previous one.
+	          ) $!_r_owner_error;
+	# END
+
+	# BEGIN - domain name in record data processing
+	action _r_dname_init {
+		s->dname = rdata_tail;
+	}
+	action _r_dname_exit {
+		rdata_tail += s->dname_tmp_length;
+	}
+
+	r_dname = dname >_r_dname_init %_r_dname_exit;
+	# END
+
+	# BEGIN - Number processing
+	action _number_digit {
+		// Overflow check: 10*(s->number64) + fc - ASCII_0 <= UINT64_MAX
+		if ((s->number64 < (UINT64_MAX / 10)) ||   // Dominant fast check.
+			((s->number64 == (UINT64_MAX / 10)) && // Marginal case.
+			 (fc <= (UINT64_MAX % 10) + ASCII_0)
+			)
+		   ) {
+			s->number64 *= 10;
+			s->number64 += digit_to_num[(uint8_t)fc];
+		} else {
+			SCANNER_WARNING(ZSCANNER_ENUMBER64_OVERFLOW);
+			fhold; fgoto err_line;
+		}
+	}
+
+	number_digit = [0-9] $_number_digit;
+
+	action _number_init {
+		s->number64 = 0;
+	}
+	action _number_error {
+		SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+		fhold; fgoto err_line;
+	}
+
+	# General integer number that cover all necessary integer ranges.
+	number = number_digit+ >_number_init;
+
+	action _float_init {
+		s->decimal_counter = 0;
+	}
+	action _decimal_init {
+		s->number64_tmp = s->number64;
+	}
+	action _decimal_digit {
+		s->decimal_counter++;
+	}
+
+	action _float_exit {
+		if (s->decimal_counter == 0 && s->number64 < UINT32_MAX) {
+			s->number64 *= pow(10, s->decimals);
+		} else if (s->decimal_counter <= s->decimals &&
+				 s->number64_tmp < UINT32_MAX) {
+			s->number64 *= pow(10, s->decimals - s->decimal_counter);
+			s->number64 += s->number64_tmp * pow(10, s->decimals);
+		} else {
+			SCANNER_WARNING(ZSCANNER_EFLOAT_OVERFLOW);
+			fhold; fgoto err_line;
+		}
+	}
+
+	# Next float can't be used directly (doesn't contain decimals init)!
+	float = (number . ('.' . number? >_decimal_init $_decimal_digit)?)
+			>_float_init %_float_exit;
+
+	action _float2_init {
+		s->decimals = 2;
+	}
+	action _float3_init {
+		s->decimals = 3;
+	}
+
+	# Float number (in hundredths)with 2 possible decimal digits.
+	float2  = float >_float2_init;
+	# Float number (in thousandths) with 3 possible decimal digits.
+	float3  = float >_float3_init;
+
+	action _num8_write {
+		if (s->number64 <= UINT8_MAX) {
+			*rdata_tail = (uint8_t)(s->number64);
+			rdata_tail += 1;
+		} else {
+			SCANNER_WARNING(ZSCANNER_ENUMBER8_OVERFLOW);
+			fhold; fgoto err_line;
+		}
+	}
+	action _num16_write {
+		if (s->number64 <= UINT16_MAX) {
+			*((uint16_t *)rdata_tail) = htons((uint16_t)(s->number64));
+			rdata_tail += 2;
+		} else {
+			SCANNER_WARNING(ZSCANNER_ENUMBER16_OVERFLOW);
+			fhold; fgoto err_line;
+		}
+	}
+	action _num32_write {
+		if (s->number64 <= UINT32_MAX) {
+			*((uint32_t *)rdata_tail) = htonl((uint32_t)(s->number64));
+			rdata_tail += 4;
+		} else {
+			SCANNER_WARNING(ZSCANNER_ENUMBER32_OVERFLOW);
+			fhold; fgoto err_line;
+		}
+	}
+
+	action _type_number_exit {
+		if (s->number64 <= UINT16_MAX) {
+			s->r_type = (uint16_t)(s->number64);
+		} else {
+			SCANNER_WARNING(ZSCANNER_ENUMBER16_OVERFLOW);
+			fhold; fgoto err_line;
+		}
+	}
+
+	action _length_number_exit {
+		if (s->number64 <= UINT16_MAX) {
+			s->r_data_length = (uint16_t)(s->number64);
+		} else {
+			SCANNER_WARNING(ZSCANNER_ENUMBER16_OVERFLOW);
+			fhold; fgoto err_line;
+		}
+	}
+	num8  = number %_num8_write  $!_number_error;
+	num16 = number %_num16_write $!_number_error;
+	num32 = number %_num32_write $!_number_error;
+
+	type_number   = number %_type_number_exit $!_number_error;
+	length_number = number %_length_number_exit $!_number_error;
+	# END
+
+	# BEGIN - Time processing
+	action _time_unit_error {
+		SCANNER_WARNING(ZSCANNER_EBAD_TIME_UNIT);
+		fhold; fgoto err_line;
+	}
+
+	time_unit =
+	    ( 's'i
+	    | 'm'i ${ if (s->number64 <= (UINT32_MAX / 60)) {
+	                  s->number64 *= 60;
+	              } else {
+	                  SCANNER_WARNING(ZSCANNER_ENUMBER32_OVERFLOW);
+	                  fhold; fgoto err_line;
+	              }
+	            }
+	    | 'h'i ${ if (s->number64 <= (UINT32_MAX / 3600)) {
+	                  s->number64 *= 3600;
+	              } else {
+	                  SCANNER_WARNING(ZSCANNER_ENUMBER32_OVERFLOW);
+	                  fhold; fgoto err_line;
+	              }
+	            }
+	    | 'd'i ${ if (s->number64 <= (UINT32_MAX / 86400)) {
+	                  s->number64 *= 86400;
+	              } else {
+	                  SCANNER_WARNING(ZSCANNER_ENUMBER32_OVERFLOW);
+	                  fhold; fgoto err_line;
+	              }
+	            }
+	    | 'w'i ${ if (s->number64 <= (UINT32_MAX / 604800)) {
+	                  s->number64 *= 604800;
+	              } else {
+	                  SCANNER_WARNING(ZSCANNER_ENUMBER32_OVERFLOW);
+	                  fhold; fgoto err_line;
+	              }
+	            }
+	    ) $!_time_unit_error;
+
+
+	action _time_block_init {
+		s->number64_tmp = s->number64;
+	}
+	action _time_block_exit {
+		if (s->number64 + s->number64_tmp < UINT32_MAX) {
+			s->number64 += s->number64_tmp;
+		} else {
+			SCANNER_WARNING(ZSCANNER_ENUMBER32_OVERFLOW);
+			fhold; fgoto err_line;
+		}
+	}
+
+	time_block = (number . time_unit) >_time_block_init %_time_block_exit;
+
+	# Time is either a number or a sequence of time blocks (1w1h1m)
+	time = (number . (time_unit . (time_block)*)?) $!_number_error;
+
+	time32 = time %_num32_write;
+	# END
+
+	# BEGIN - Timestamp processing
+	action _timestamp_init {
+		s->buffer_length = 0;
+	}
+	action _timestamp {
+		if (s->buffer_length < MAX_RDATA_LENGTH) {
+			s->buffer[s->buffer_length++] = fc;
+		} else {
+			SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+			fhold; fgoto err_line;
+		}
+	}
+	action _timestamp_exit {
+		s->buffer[s->buffer_length] = 0;
+
+		if (s->buffer_length == 14) { // Date; 14 = len("YYYYMMDDHHmmSS").
+			ret = date_to_timestamp(s->buffer, &timestamp);
+
+			if (ret == KNOT_EOK) {
+				*((uint32_t *)rdata_tail) = htonl(timestamp);
+				rdata_tail += 4;
+			} else {
+				SCANNER_WARNING(ret);
+				fhold; fgoto err_line;
+			}
+		} else if (s->buffer_length <= 10) { // Timestamp format.
+			errno = 0;
+			s->number64 = strtoul((char *)(s->buffer), NULL,  10);
+
+			if (errno != 0) {
+				SCANNER_WARNING(ZSCANNER_EBAD_TIMESTAMP);
+				fhold; fgoto err_line;
+			}
+
+			if (s->number64 <= UINT32_MAX) {
+				*((uint32_t *)rdata_tail) = htonl((uint32_t)s->number64);
+				rdata_tail += 4;
+			} else {
+				SCANNER_WARNING(ZSCANNER_ENUMBER32_OVERFLOW);
+				fhold; fgoto err_line;
+			}
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_TIMESTAMP_LENGTH);
+			fhold; fgoto err_line;
+		}
+	}
+	action _timestamp_error {
+		SCANNER_WARNING(ZSCANNER_EBAD_TIMESTAMP_CHAR);
+		fhold; fgoto err_line;
+	}
+
+	timestamp = digit+ >_timestamp_init $_timestamp
+	            %_timestamp_exit $!_timestamp_error;
+	# END
+
+	# BEGIN - Text processing
+	action _text_char {
+		if (rdata_tail <= rdata_stop) {
+			*(rdata_tail++) = fc;
+		} else {
+			SCANNER_WARNING(ZSCANNER_ETEXT_OVERFLOW);
+			fhold; fgoto err_line;
+		}
+	}
+	action _text_char_error {
+		SCANNER_WARNING(ZSCANNER_EBAD_TEXT_CHAR);
+		fhold; fgoto err_line;
+	}
+	action _text_error {
+		SCANNER_WARNING(ZSCANNER_EBAD_TEXT);
+		fhold; fgoto err_line;
+	}
+
+	action _text_dec_init {
+		if (rdata_tail <= rdata_stop) {
+			*rdata_tail = 0;
+			s->item_length++;
+		} else {
+			SCANNER_WARNING(ZSCANNER_ETEXT_OVERFLOW);
+			fhold; fgoto err_line;
+		}
+	}
+	action _text_dec {
+		if ((*rdata_tail < (UINT8_MAX / 10)) ||   // Dominant fast check.
+			((*rdata_tail == (UINT8_MAX / 10)) && // Marginal case.
+			 (fc <= (UINT8_MAX % 10) + ASCII_0)
+			)
+		   ) {
+			*rdata_tail *= 10;
+			*rdata_tail += digit_to_num[(uint8_t)fc];
+		} else {
+			SCANNER_WARNING(ZSCANNER_ENUMBER8_OVERFLOW);
+			fhold; fgoto err_line;
+		}
+	}
+	action _text_dec_exit {
+		rdata_tail++;
+	}
+	action _text_dec_error {
+		SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+		fhold; fgoto err_line;
+	}
+
+	text_char =
+		( (33..126 - [\\;\"]) $_text_char          # One printable char.
+		| ('\\' . ^digit)     @_text_char          # One "\x" char.
+		| ('\\'               %_text_dec_init      # Initial "\" char.
+		   . digit {3}        $_text_dec %_text_dec_exit # "DDD" rest.
+		                      $!_text_dec_error
+		  )
+		) $!_text_char_error;
+
+	quoted_text_char =
+		( text_char
+		| ([ \t;] | [\n] when { s->multiline }) $_text_char
+		) $!_text_char_error;
+
+	# Text string machine instantiation (for smaller code).
+	text_ := (('\"' . quoted_text_char* . '\"') | text_char+)
+		 $!_text_error %_ret . all_wchar;
+	text = ^all_wchar ${ fhold; fcall text_; };
+
+	# Text string with forward 1-byte length.
+	text_string = text >_item_length_init %_item_length_exit;
+
+	# Text string array as one rdata item.
+	text_array = (text_string . (sep . text_string)* . sep?);
+	# END
+
+	# BEGIN - TTL directive processing
+	action _default_ttl_exit {
+		if (s->number64 <= UINT32_MAX) {
+			s->default_ttl = (uint32_t)(s->number64);
+		} else {
+			SCANNER_ERROR(ZSCANNER_ENUMBER32_OVERFLOW);
+			fhold; fgoto err_line;
+		}
+	}
+	action _default_ttl_error {
+		SCANNER_ERROR(ZSCANNER_EBAD_TTL);
+		fhold; fgoto err_line;
+	}
+
+	default_ttl_ := (sep . time . rest) $!_default_ttl_error
+	                %_default_ttl_exit %_ret . newline;
+	default_ttl = all_wchar ${ fhold; fcall default_ttl_; };
+	# END
+
+	# BEGIN - ORIGIN directive processing
+	action _zone_origin_init {
+		s->dname = s->zone_origin;
+	}
+	action _zone_origin_exit {
+		s->zone_origin_length = s->dname_tmp_length;
+	}
+	action _zone_origin_error {
+		SCANNER_ERROR(ZSCANNER_EBAD_ORIGIN);
+		fhold; fgoto err_line;
+	}
+
+	zone_origin_ := (sep . absolute_dname >_zone_origin_init . rest)
+	                $!_zone_origin_error %_zone_origin_exit %_ret . newline;
+	zone_origin = all_wchar ${ fhold; fcall zone_origin_; };
+	# END
+
+	# BEGIN - INCLUDE directive processing
+	action _incl_filename_init {
+		rdata_tail = s->r_data;
+	}
+	action _incl_filename_exit {
+		*rdata_tail = 0; // Ending filename string.
+		strcpy((char*)(s->include_filename), (char*)(s->r_data));
+
+		// Check for correct string copy.
+		if (strlen(s->include_filename) != rdata_tail - s->r_data) {
+			SCANNER_ERROR(ZSCANNER_EBAD_INCLUDE_FILENAME);
+			fhold; fgoto err_line;
+		}
+
+		// For detection whether origin is not present.
+		s->dname = NULL;
+	}
+	action _incl_filename_error {
+		SCANNER_ERROR(ZSCANNER_EBAD_INCLUDE_FILENAME);
+		fhold; fgoto err_line;
+	}
+
+	action _incl_origin_init {
+		s->dname = s->r_data;
+	}
+	action _incl_origin_exit {
+		s->r_data_length = s->dname_tmp_length;
+	}
+	action _incl_origin_error {
+		SCANNER_ERROR(ZSCANNER_EBAD_INCLUDE_ORIGIN);
+		fhold; fgoto err_line;
+	}
+
+	action _include_exit {
+		char text_origin[MAX_DNAME_LENGTH];
+
+		// Origin conversion from wire to text form.
+		if (s->dname == NULL) { // Use current origin.
+			wire_dname_to_str(s->zone_origin,
+			                  s->zone_origin_length,
+					  text_origin);
+		} else { // Use specified origin.
+			wire_dname_to_str(s->r_data,
+			                  s->r_data_length,
+					  text_origin);
+		}
+
+		if (s->include_filename[0] != '/') { // Relative file path..
+			// Get absolute path of the current zone file.
+			if (realpath(s->file_name, (char*)(s->buffer)) != NULL) {
+				char *full_current_zone_file_name =
+					strdup((char*)(s->buffer));
+
+				// Creating full include file name.
+				sprintf((char*)(s->buffer), "%s/%s",
+				        dirname(full_current_zone_file_name),
+				        s->include_filename);
+
+				free(full_current_zone_file_name);
+			} else {
+				SCANNER_ERROR(ZSCANNER_EUNPROCESSED_INCLUDE);
+				fhold; fgoto err_line;
+			}
+		} else {
+			strcpy((char*)(s->buffer), (char*)(s->include_filename));
+		}
+
+		// Create new file loader for included zone file.
+		file_loader_t *fl = file_loader_create((char*)(s->buffer),
+		                                       text_origin,
+		                                       DEFAULT_CLASS,
+		                                       DEFAULT_TTL,
+		                                       s->process_record,
+		                                       s->process_error,
+		                                       s->data);
+		if (fl != NULL) {
+			// Process included zone file.
+			ret = file_loader_process(fl);
+			file_loader_free(fl);
+
+			if (ret != 0) {
+				SCANNER_ERROR(ZSCANNER_EUNPROCESSED_INCLUDE);
+				fhold; fgoto err_line;
+			}
+		} else {
+			SCANNER_ERROR(ZSCANNER_EUNOPENED_INCLUDE);
+			fhold; fgoto err_line;
+		}
+	}
+
+	include_file_ :=
+		(sep . text >_incl_filename_init %_incl_filename_exit
+		 $!_incl_filename_error .
+	         (sep . absolute_dname >_incl_origin_init %_incl_origin_exit
+	          $!_incl_origin_error
+		 )? . rest
+	        ) %_include_exit %_ret newline;
+	include_file = all_wchar ${ fhold; fcall include_file_; };
+	# END
+
+	# BEGIN - Directive switch
+	# Each error/warning in directive should stop processing.
+	# Some internal errors cause warning only. This causes stop processing.
+	action _directive_init {
+		s->stop = true;
+	}
+	# Remove stop processing flag.
+	action _directive_exit {
+		s->stop = false;
+	}
+	action _directive_error {
+		SCANNER_ERROR(ZSCANNER_EBAD_DIRECTIVE);
+		fhold; fgoto err_line;
+	}
+
+	directive = '$' . ( ("TTL"i     . default_ttl)
+	                  | ("ORIGIN"i  . zone_origin)
+	                  | ("INCLUDE"i . include_file)
+	                  ) >_directive_init %_directive_exit $!_directive_error;
+	# END
+
+	# BEGIN - RRecord class and ttl processing
+	action _default_r_class_exit {
+		s->r_class = s->default_class;
+	}
+
+	action _default_r_ttl_exit {
+		s->r_ttl = s->default_ttl;
+	}
+
+	action _r_class_in_exit {
+		s->r_class = KNOT_CLASS_IN;
+	}
+
+	action _r_ttl_exit {
+		if (s->number64 <= UINT32_MAX) {
+			s->r_ttl = (uint32_t)(s->number64);
+		} else {
+			SCANNER_WARNING(ZSCANNER_ENUMBER32_OVERFLOW);
+			fhold; fgoto err_line;
+		}
+	}
+
+	r_class = "IN"i %_r_class_in_exit;
+
+	r_ttl = time %_r_ttl_exit;
+	# END
+
+	# BEGIN - IPv4 and IPv6 address processing
+	action _addr_init {
+		s->buffer_length = 0;
+	}
+	action _addr {
+		if (s->buffer_length < MAX_RDATA_LENGTH) {
+			s->buffer[s->buffer_length++] = fc;
+		}
+		else {
+			SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+			fhold; fgoto err_line;
+		}
+	}
+	action _addr_error {
+		SCANNER_WARNING(ZSCANNER_EBAD_ADDRESS_CHAR);
+		fhold; fgoto err_line;
+	}
+
+	action _ipv4_addr_exit {
+		s->buffer[s->buffer_length] = 0;
+
+		if (inet_pton(AF_INET, (char *)s->buffer, &addr4) <= 0) {
+			SCANNER_WARNING(ZSCANNER_EBAD_IPV4);
+			fhold; fgoto err_line;
+		}
+	}
+	action _ipv4_addr_write {
+		memcpy(rdata_tail, &(addr4.s_addr), INET4_ADDR_LENGTH);
+		rdata_tail += INET4_ADDR_LENGTH;
+	}
+
+	action _ipv6_addr_exit {
+		s->buffer[s->buffer_length] = 0;
+
+		if (inet_pton(AF_INET6, (char *)s->buffer, &addr6) <= 0) {
+			SCANNER_WARNING(ZSCANNER_EBAD_IPV6);
+			fhold; fgoto err_line;
+		}
+	}
+	action _ipv6_addr_write {
+		memcpy(rdata_tail, &(addr6.s6_addr), INET6_ADDR_LENGTH);
+		rdata_tail += INET6_ADDR_LENGTH;
+	}
+
+	# Address parsers only.
+	ipv4_addr = (digit  | '.')+  >_addr_init $_addr %_ipv4_addr_exit
+	            $!_addr_error;
+	ipv6_addr = (xdigit | [.:])+ >_addr_init $_addr %_ipv6_addr_exit
+	            $!_addr_error;
+
+	# Write parsed address to r_data.
+	ipv4_addr_write = ipv4_addr %_ipv4_addr_write;
+	ipv6_addr_write = ipv6_addr %_ipv6_addr_write;
+	# END
+
+	# BEGIN - apl record processing
+	action _apl_init {
+		memset(&(s->apl), 0, sizeof(s->apl));
+	}
+	action _apl_excl_flag {
+		s->apl.excl_flag = 128; // dec 128  = bin 10000000.
+	}
+	action _apl_addr_1 {
+		s->apl.addr_family = 1;
+	}
+	action _apl_addr_2 {
+		s->apl.addr_family = 2;
+	}
+	action _apl_prefix_length {
+		if ((s->apl.addr_family == 1 && s->number64 <= 32) ||
+		    (s->apl.addr_family == 2 && s->number64 <= 128)) {
+			s->apl.prefix_length = (uint8_t)(s->number64);
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_APL);
+			fhold; fgoto err_line;
+		}
+	}
+	action _apl_exit {
+		// Write address family.
+		*((uint16_t *)rdata_tail) = htons(s->apl.addr_family);
+		rdata_tail += 2;
+		// Write prefix length in bites.
+		*(rdata_tail) = s->apl.prefix_length;
+		rdata_tail += 1;
+		// Computed maximal prefix length in bytes (real can be smaller).
+		s->number64 = (s->apl.prefix_length + 7) / 8;
+		if (s->number64 > 127) { // At most 7 bits.
+			SCANNER_WARNING(ZSCANNER_EBAD_APL);
+			fhold; fgoto err_line;
+		}
+		// Copy address to buffer.
+		switch (s->apl.addr_family) {
+		case 1:
+			memcpy(s->buffer, &(addr4.s_addr), INET4_ADDR_LENGTH);
+			break;
+		case 2:
+			memcpy(s->buffer, &(addr6.s6_addr), INET6_ADDR_LENGTH);
+			break;
+		default:
+			SCANNER_WARNING(ZSCANNER_EBAD_APL);
+			fhold; fgoto err_line;
+		}
+		// Find real prefix (without trailing zeroes).
+		while (s->number64 > 0 ) {
+			if ((s->buffer[s->number64 - 1] & 255) != 0) {
+				// Apply mask on last byte if not precise prefix.
+				// (Bind does't do this).
+				s->buffer[s->number64 - 1] &=
+					((uint8_t)255 << (s->number64 * 8 -
+					                  s->apl.prefix_length));
+				break;
+			}
+			s->number64--;
+		}
+		// Write negation flag + prefix length in bytes.
+		*(rdata_tail) = (uint8_t)(s->number64) + s->apl.excl_flag;
+		rdata_tail += 1;
+		// Write address prefix.
+		memcpy(rdata_tail, s->buffer, s->number64);
+		rdata_tail += s->number64;
+	}
+	action _apl_error {
+		SCANNER_WARNING(ZSCANNER_EBAD_APL);
+		fhold; fgoto err_line;
+	}
+
+	apl = ('!'? $_apl_excl_flag .
+	       ( ('1' $_apl_addr_1 . ':' . ipv4_addr . '/' . number
+	          %_apl_prefix_length)
+	       | ('2' $_apl_addr_2 . ':' . ipv6_addr . '/' . number
+	          %_apl_prefix_length)
+	       )
+	      ) >_apl_init %_apl_exit $!_apl_error;
+
+	# Array of APL records (can be empty).
+	apl_array = apl? . (sep . apl)* . sep?;
+	# END
+
+	# BEGIN - Hexadecimal string array processing
+	action _first_hex_char {
+		if (rdata_tail <= rdata_stop) {
+			*rdata_tail = first_hex_to_num[(uint8_t)fc];
+		} else {
+		   SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+		   fhold; fgoto err_line;
+		}
+	}
+	action _second_hex_char {
+		*rdata_tail += second_hex_to_num[(uint8_t)fc];
+		rdata_tail++;
+	}
+	action _hex_char_error {
+		SCANNER_WARNING(ZSCANNER_EBAD_HEX_CHAR);
+		fhold; fgoto err_line;
+	}
+
+	hex_char  = (xdigit $_first_hex_char . xdigit $_second_hex_char);
+
+	# Hex array with possibility of inside white spaces and multiline.
+	hex_array = (hex_char+ . sep?)+ $!_hex_char_error;
+
+	# Continuous hex array (or "-") with forward length processing.
+	salt = (hex_char+ | '-') >_item_length_init %_item_length_exit
+	       $!_hex_char_error;
+
+	action _type_data_exit {
+		if ((rdata_tail - s->r_data) != s->r_data_length) {
+			SCANNER_WARNING(ZSCANNER_EBAD_RDATA_LENGTH);
+			fhold; fgoto err_line;
+		}
+
+		ret = find_rdata_blocks(s);
+		if (ret != KNOT_EOK) {
+			SCANNER_WARNING(ret);
+			fhold; fgoto err_line;
+		}
+	}
+
+	action _type_data_error {
+		SCANNER_WARNING(ZSCANNER_EBAD_HEX_RDATA);
+		fhold; fgoto err_line;
+	}
+
+	# Hex array with control to forward length statement.
+	type_data = hex_array %_type_data_exit $!_type_data_error;
+	# END
+
+	# BEGIN - Base64 processing (RFC 4648)
+	action _first_base64_char {
+		if (rdata_tail <= rdata_stop) {
+			*rdata_tail = first_base64_to_num[(uint8_t)fc];
+		} else {
+		   SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+		   fhold; fgoto err_line;
+		}
+	}
+	action _second_base64_char {
+		*(rdata_tail++) += second_left_base64_to_num[(uint8_t)fc];
+
+		if (rdata_tail <= rdata_stop) {
+			*rdata_tail = second_right_base64_to_num[(uint8_t)fc];
+		} else {
+		   SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+		   fhold; fgoto err_line;
+		}
+	}
+	action _third_base64_char {
+		*(rdata_tail++) += third_left_base64_to_num[(uint8_t)fc];
+
+		if (rdata_tail <= rdata_stop) {
+			*rdata_tail = third_right_base64_to_num[(uint8_t)fc];
+		} else {
+		   SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+		   fhold; fgoto err_line;
+		}
+	}
+	action _fourth_base64_char {
+		*(rdata_tail++) += fourth_base64_to_num[(uint8_t)fc];
+	}
+
+	action _base64_char_error {
+		SCANNER_WARNING(ZSCANNER_EBAD_BASE64_CHAR);
+		fhold; fgoto err_line;
+	}
+
+	base64_char = alnum | [+/];
+	base64_padd = '=';
+	base64_quartet =
+	    ( base64_char          $_first_base64_char  . # A
+	      base64_char          $_second_base64_char . # AB
+	      ( ( base64_char      $_third_base64_char  . # ABC
+	          ( base64_char    $_fourth_base64_char   # ABCD
+	          | base64_padd{1}                        # ABC=
+	          )
+	        )
+	      | base64_padd{2}                            # AB==
+	      )
+	    );
+
+	# Base64 array with possibility of inside white spaces and multiline.
+	base64_ := (base64_quartet+ . sep?)+ $!_base64_char_error
+	           %_ret . end_wchar;
+	base64 = base64_char ${ fhold; fcall base64_; };
+	# END
+
+	# BEGIN - Base32hex processing (RFC 4648)
+	action _first_base32hex_char {
+		if (rdata_tail <= rdata_stop) {
+			*rdata_tail = first_base32hex_to_num[(uint8_t)fc];
+		} else {
+		   SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+		   fhold; fgoto err_line;
+		}
+	}
+	action _second_base32hex_char {
+		*(rdata_tail++) += second_left_base32hex_to_num[(uint8_t)fc];
+
+		if (rdata_tail <= rdata_stop) {
+			*rdata_tail = second_right_base32hex_to_num[(uint8_t)fc];
+		} else {
+		   SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+		   fhold; fgoto err_line;
+		}
+	}
+	action _third_base32hex_char {
+		*rdata_tail += third_base32hex_to_num[(uint8_t)fc];
+	}
+	action _fourth_base32hex_char {
+		*(rdata_tail++) += fourth_left_base32hex_to_num[(uint8_t)fc];
+
+		if (rdata_tail <= rdata_stop) {
+			*rdata_tail = fourth_right_base32hex_to_num[(uint8_t)fc];
+		} else {
+		   SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+		   fhold; fgoto err_line;
+		}
+	}
+	action _fifth_base32hex_char {
+		*(rdata_tail++) += fifth_left_base32hex_to_num[(uint8_t)fc];
+
+		if (rdata_tail <= rdata_stop) {
+			*rdata_tail = fifth_right_base32hex_to_num[(uint8_t)fc];
+		} else {
+		   SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+		   fhold; fgoto err_line;
+		}
+	}
+	action _sixth_base32hex_char {
+		*rdata_tail += sixth_base32hex_to_num[(uint8_t)fc];
+	}
+	action _seventh_base32hex_char {
+		*(rdata_tail++) += seventh_left_base32hex_to_num[(uint8_t)fc];
+
+		if (rdata_tail <= rdata_stop) {
+			*rdata_tail = seventh_right_base32hex_to_num[(uint8_t)fc];
+		} else {
+		   SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+		   fhold; fgoto err_line;
+		}
+	}
+	action _eighth_base32hex_char {
+		*(rdata_tail++) += eighth_base32hex_to_num[(uint8_t)fc];
+	}
+
+	action _base32hex_char_error {
+		SCANNER_WARNING(ZSCANNER_EBAD_BASE32HEX_CHAR);
+		fhold; fgoto err_line;
+	}
+
+	base32hex_char = [0-9a-vA-V];
+	base32hex_padd = '=';
+	base32hex_octet =
+	    ( base32hex_char                  $_first_base32hex_char   . # A
+	      base32hex_char                  $_second_base32hex_char  . # AB
+	      ( ( base32hex_char              $_third_base32hex_char   . # ABC
+	          base32hex_char              $_fourth_base32hex_char  . # ABCD
+	          ( ( base32hex_char          $_fifth_base32hex_char   . # ABCDE
+	              ( ( base32hex_char      $_sixth_base32hex_char   . # ABCDEF
+	                  base32hex_char      $_seventh_base32hex_char . # ABCDEFG
+	                  ( base32hex_char    $_eighth_base32hex_char    # ABCDEFGH
+	                  | base32hex_padd{1}                            # ABCDEFG=
+			  )
+			)
+	              | base32hex_padd{3}                                # ABCDE===
+	              )
+	            )
+	          | base32hex_padd{4}                                    # ABCD====
+	          )
+	        )
+	      | base32hex_padd{6}                                        # AB======
+	      )
+	    );
+
+	# Continuous base32hex (with padding!) array with forward length processing.
+	hash = base32hex_octet+ >_item_length_init %_item_length_exit
+	       $!_base32hex_char_error;
+	# END
+
+	# BEGIN - Gateway
+	action _write_0 {
+		*(rdata_tail++) = 0;
+	}
+	action _write_1 {
+		*(rdata_tail++) = 1;
+	}
+	action _write_2 {
+		*(rdata_tail++) = 2;
+	}
+	action _write_3 {
+		*(rdata_tail++) = 3;
+	}
+	action _gateway_error {
+		SCANNER_WARNING(ZSCANNER_EBAD_GATEWAY);
+		fhold; fgoto err_line;
+	}
+	action _gateway_key_error {
+		SCANNER_WARNING(ZSCANNER_EBAD_GATEWAY_KEY);
+		fhold; fgoto err_line;
+	}
+
+	gateway = (( ('0' $_write_0 . sep . num8 . sep . '.')
+	           | ('1' $_write_1 . sep . num8 . sep . ipv4_addr_write)
+	           | ('2' $_write_2 . sep . num8 . sep . ipv6_addr_write)
+	           | ('3' $_write_3 . sep . num8 . sep . r_dname)
+	           ) $!_gateway_error .
+	           # If algorithm is 0 then key isn't present and vice versa.
+	           ( ((sep . base64) when { s->number64 != 0 })
+	           | ((sep?)         when { s->number64 == 0 }) # remove blank space
+	           ) $!_gateway_key_error
+	          );
+	# END
+
+	# BEGIN - Type processing
+	action _type_error {
+		SCANNER_WARNING(ZSCANNER_EUNSUPPORTED_TYPE);
+		fhold; fgoto err_line;
+	}
+
+	type_num =
+	    ( "A"i          %{ type_num(KNOT_RRTYPE_A, &rdata_tail); }
+	    | "NS"i         %{ type_num(KNOT_RRTYPE_NS, &rdata_tail); }
+	    | "CNAME"i      %{ type_num(KNOT_RRTYPE_CNAME, &rdata_tail); }
+	    | "SOA"i        %{ type_num(KNOT_RRTYPE_SOA, &rdata_tail); }
+	    | "PTR"i        %{ type_num(KNOT_RRTYPE_PTR, &rdata_tail); }
+	    | "HINFO"i      %{ type_num(KNOT_RRTYPE_HINFO, &rdata_tail); }
+	    | "MINFO"i      %{ type_num(KNOT_RRTYPE_MINFO, &rdata_tail); }
+	    | "MX"i         %{ type_num(KNOT_RRTYPE_MX, &rdata_tail); }
+	    | "TXT"i        %{ type_num(KNOT_RRTYPE_TXT, &rdata_tail); }
+	    | "RP"i         %{ type_num(KNOT_RRTYPE_RP, &rdata_tail); }
+	    | "AFSDB"i      %{ type_num(KNOT_RRTYPE_AFSDB, &rdata_tail); }
+	    | "RT"i         %{ type_num(KNOT_RRTYPE_RT, &rdata_tail); }
+	    | "KEY"i        %{ type_num(KNOT_RRTYPE_KEY, &rdata_tail); }
+	    | "AAAA"i       %{ type_num(KNOT_RRTYPE_AAAA, &rdata_tail); }
+	    | "LOC"i        %{ type_num(KNOT_RRTYPE_LOC, &rdata_tail); }
+	    | "SRV"i        %{ type_num(KNOT_RRTYPE_SRV, &rdata_tail); }
+	    | "NAPTR"i      %{ type_num(KNOT_RRTYPE_NAPTR, &rdata_tail); }
+	    | "KX"i         %{ type_num(KNOT_RRTYPE_KX, &rdata_tail); }
+	    | "CERT"i       %{ type_num(KNOT_RRTYPE_CERT, &rdata_tail); }
+	    | "DNAME"i      %{ type_num(KNOT_RRTYPE_DNAME, &rdata_tail); }
+	    | "APL"i        %{ type_num(KNOT_RRTYPE_APL, &rdata_tail); }
+	    | "DS"i         %{ type_num(KNOT_RRTYPE_DS, &rdata_tail); }
+	    | "SSHFP"i      %{ type_num(KNOT_RRTYPE_SSHFP, &rdata_tail); }
+	    | "IPSECKEY"i   %{ type_num(KNOT_RRTYPE_IPSECKEY, &rdata_tail); }
+	    | "RRSIG"i      %{ type_num(KNOT_RRTYPE_RRSIG, &rdata_tail); }
+	    | "NSEC"i       %{ type_num(KNOT_RRTYPE_NSEC, &rdata_tail); }
+	    | "DNSKEY"i     %{ type_num(KNOT_RRTYPE_DNSKEY, &rdata_tail); }
+	    | "DHCID"i      %{ type_num(KNOT_RRTYPE_DHCID, &rdata_tail); }
+	    | "NSEC3"i      %{ type_num(KNOT_RRTYPE_NSEC3, &rdata_tail); }
+	    | "NSEC3PARAM"i %{ type_num(KNOT_RRTYPE_NSEC3PARAM, &rdata_tail); }
+	    | "TLSA"i       %{ type_num(KNOT_RRTYPE_TLSA, &rdata_tail); }
+	    | "SPF"i        %{ type_num(KNOT_RRTYPE_SPF, &rdata_tail); }
+	    | "TYPE"i      . num16 # TYPE0-TYPE65535.
+	    ) $!_type_error;
+	# END
+
+	# BEGIN - Bitmap processing
+	action _type_bitmap_exit {
+		if (s->number64 <= UINT16_MAX) {
+			window_add_bit(s->number64, s);
+		} else {
+			SCANNER_WARNING(ZSCANNER_ENUMBER16_OVERFLOW);
+			fhold; fgoto err_line;
+		}
+	}
+
+	# TYPE0-TYPE65535.
+	type_bitmap = number %_type_bitmap_exit;
+
+	type_bit =
+	    ( "A"i          %{ window_add_bit(KNOT_RRTYPE_A, s); }
+	    | "NS"i         %{ window_add_bit(KNOT_RRTYPE_NS, s); }
+	    | "CNAME"i      %{ window_add_bit(KNOT_RRTYPE_CNAME, s); }
+	    | "SOA"i        %{ window_add_bit(KNOT_RRTYPE_SOA, s); }
+	    | "PTR"i        %{ window_add_bit(KNOT_RRTYPE_PTR, s); }
+	    | "HINFO"i      %{ window_add_bit(KNOT_RRTYPE_HINFO, s); }
+	    | "MINFO"i      %{ window_add_bit(KNOT_RRTYPE_MINFO, s); }
+	    | "MX"i         %{ window_add_bit(KNOT_RRTYPE_MX, s); }
+	    | "TXT"i        %{ window_add_bit(KNOT_RRTYPE_TXT, s); }
+	    | "RP"i         %{ window_add_bit(KNOT_RRTYPE_RP, s); }
+	    | "AFSDB"i      %{ window_add_bit(KNOT_RRTYPE_AFSDB, s); }
+	    | "RT"i         %{ window_add_bit(KNOT_RRTYPE_RT, s); }
+	    | "KEY"i        %{ window_add_bit(KNOT_RRTYPE_KEY, s); }
+	    | "AAAA"i       %{ window_add_bit(KNOT_RRTYPE_AAAA, s); }
+	    | "LOC"i        %{ window_add_bit(KNOT_RRTYPE_LOC, s); }
+	    | "SRV"i        %{ window_add_bit(KNOT_RRTYPE_SRV, s); }
+	    | "NAPTR"i      %{ window_add_bit(KNOT_RRTYPE_NAPTR, s); }
+	    | "KX"i         %{ window_add_bit(KNOT_RRTYPE_KX, s); }
+	    | "CERT"i       %{ window_add_bit(KNOT_RRTYPE_CERT, s); }
+	    | "DNAME"i      %{ window_add_bit(KNOT_RRTYPE_DNAME, s); }
+	    | "APL"i        %{ window_add_bit(KNOT_RRTYPE_APL, s); }
+	    | "DS"i         %{ window_add_bit(KNOT_RRTYPE_DS, s); }
+	    | "SSHFP"i      %{ window_add_bit(KNOT_RRTYPE_SSHFP, s); }
+	    | "IPSECKEY"i   %{ window_add_bit(KNOT_RRTYPE_IPSECKEY, s); }
+	    | "RRSIG"i      %{ window_add_bit(KNOT_RRTYPE_RRSIG, s); }
+	    | "NSEC"i       %{ window_add_bit(KNOT_RRTYPE_NSEC, s); }
+	    | "DNSKEY"i     %{ window_add_bit(KNOT_RRTYPE_DNSKEY, s); }
+	    | "DHCID"i      %{ window_add_bit(KNOT_RRTYPE_DHCID, s); }
+	    | "NSEC3"i      %{ window_add_bit(KNOT_RRTYPE_NSEC3, s); }
+	    | "NSEC3PARAM"i %{ window_add_bit(KNOT_RRTYPE_NSEC3PARAM, s); }
+	    | "TLSA"i       %{ window_add_bit(KNOT_RRTYPE_TLSA, s); }
+	    | "SPF"i        %{ window_add_bit(KNOT_RRTYPE_SPF, s); }
+	    | "TYPE"i      . type_bitmap # TYPE0-TYPE65535.
+	    );
+
+	action _bitmap_init {
+		memset(s->windows, 0, sizeof(s->windows));
+		s->last_window = -1;
+	}
+	action _bitmap_exit {
+		for (window = 0; window <= s->last_window; window++) {
+			if ((s->windows[window]).length > 0) {
+				if (rdata_tail + 2 + (s->windows[window]).length <= rdata_stop)
+				{
+					// Window number.
+					*rdata_tail = (uint8_t)window;
+					rdata_tail += 1;
+					// Bitmap length.
+					*rdata_tail = (s->windows[window]).length;
+					rdata_tail += 1;
+					// Copying bitmap.
+					memcpy(rdata_tail,
+					       (s->windows[window]).bitmap,
+					       (s->windows[window]).length);
+					rdata_tail += (s->windows[window]).length;
+				} else {
+					SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+					fhold; fgoto err_line;
+				}
+			}
+		}
+	}
+	action _bitmap_error {
+		SCANNER_WARNING(ZSCANNER_EBAD_BITMAP);
+		fhold; fgoto err_line;
+	}
+
+	# Blank bitmap is allowed too.
+	bitmap_ := ((sep . type_bit)* . sep?) >_bitmap_init
+	           %_bitmap_exit %_ret $!_bitmap_error . end_wchar;
+	bitmap = all_wchar ${ fhold; fcall bitmap_; };
+	# END
+
+	# BEGIN - Location processing
+	action _d1_exit {
+		if (s->number64 <= 90) {
+			s->loc.d1 = (uint32_t)(s->number64);
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+			fhold; fgoto err_line;
+		}
+	}
+	action _d2_exit {
+		if (s->number64 <= 180) {
+			s->loc.d2 = (uint32_t)(s->number64);
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+			fhold; fgoto err_line;
+		}
+	}
+	action _m1_exit {
+		if (s->number64 <= 59) {
+			s->loc.m1 = (uint32_t)(s->number64);
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+			fhold; fgoto err_line;
+		}
+	}
+	action _m2_exit {
+		if (s->number64 <= 59) {
+			s->loc.m2 = (uint32_t)(s->number64);
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+			fhold; fgoto err_line;
+		}
+	}
+	action _s1_exit {
+		if (s->number64 <= 59999) {
+			s->loc.s1 = (uint32_t)(s->number64);
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+			fhold; fgoto err_line;
+		}
+	}
+	action _s2_exit {
+		if (s->number64 <= 59999) {
+			s->loc.s2 = (uint32_t)(s->number64);
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+			fhold; fgoto err_line;
+		}
+	}
+	action _alt_exit {
+		if ((s->loc.alt_sign ==  1 && s->number64 <= 4284967295) ||
+		    (s->loc.alt_sign == -1 && s->number64 <=   10000000))
+		{
+			s->loc.alt = (uint32_t)(s->number64);
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+			fhold; fgoto err_line;
+		}
+	}
+	action _siz_exit {
+		if (s->number64 <= 9000000000ULL) {
+			s->loc.siz = s->number64;
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+			fhold; fgoto err_line;
+		}
+	}
+	action _hp_exit {
+		if (s->number64 <= 9000000000ULL) {
+			s->loc.hp = s->number64;
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+			fhold; fgoto err_line;
+		}
+	}
+	action _vp_exit {
+		if (s->number64 <= 9000000000ULL) {
+			s->loc.vp = s->number64;
+		} else {
+			SCANNER_WARNING(ZSCANNER_EBAD_NUMBER);
+			fhold; fgoto err_line;
+		}
+	}
+	action _lat_sign {
+		s->loc.lat_sign = -1;
+	}
+	action _long_sign {
+		s->loc.long_sign = -1;
+	}
+	action _alt_sign {
+		s->loc.alt_sign = -1;
+	}
+
+	d1  = number %_d1_exit;
+	d2  = number %_d2_exit;
+	m1  = number %_m1_exit;
+	m2  = number %_m2_exit;
+	s1  = float3 %_s1_exit;
+	s2  = float3 %_s2_exit;
+	siz = float2 %_siz_exit;
+	hp  = float2 %_hp_exit;
+	vp  = float2 %_vp_exit;
+	alt = ('-' %_alt_sign)? . float2 %_alt_exit;
+	lat_sign  = 'N' | 'S' %_lat_sign;
+	long_sign = 'E' | 'W' %_long_sign;
+
+	action _loc_init {
+		memset(&(s->loc), 0, sizeof(s->loc));
+		// Defaults.
+		s->loc.siz = 100;
+		s->loc.vp  = 1000;
+		s->loc.hp  = 1000000;
+		s->loc.lat_sign  = 1;
+		s->loc.long_sign = 1;
+		s->loc.alt_sign  = 1;
+	}
+	action _loc_exit {
+		// Write version.
+		*(rdata_tail) = 0;
+		rdata_tail += 1;
+		// Write size.
+		*(rdata_tail) = loc64to8(s->loc.siz);
+		rdata_tail += 1;
+		// Write horizontal precision.
+		*(rdata_tail) = loc64to8(s->loc.hp);
+		rdata_tail += 1;
+		// Write vertical precision.
+		*(rdata_tail) = loc64to8(s->loc.vp);
+		rdata_tail += 1;
+		// Write latitude.
+		*((uint32_t *)rdata_tail) = htonl(LOC_LAT_ZERO + s->loc.lat_sign *
+			(3600000 * s->loc.d1 + 60000 * s->loc.m1 + s->loc.s1));
+		rdata_tail += 4;
+		// Write longitude.
+		*((uint32_t *)rdata_tail) = htonl(LOC_LONG_ZERO + s->loc.long_sign *
+			(3600000 * s->loc.d2 + 60000 * s->loc.m2 + s->loc.s2));
+		rdata_tail += 4;
+		// Write altitude.
+		*((uint32_t *)rdata_tail) = htonl(LOC_ALT_ZERO + s->loc.alt_sign *
+			(s->loc.alt));
+		rdata_tail += 4;
+	}
+	action _loc_error {
+		SCANNER_WARNING(ZSCANNER_EBAD_LOC_DATA);
+		fhold; fgoto err_line;
+	}
+
+	loc = (d1 . sep . (m1 . sep . (s1 . sep)?)? . lat_sign  . sep .
+	       d2 . sep . (m2 . sep . (s2 . sep)?)? . long_sign . sep .
+	       alt 'm'? . (sep . siz 'm'? . (sep . hp 'm'? . (sep . vp 'm'?)?)?)? .
+	       sep?
+	      ) >_loc_init %_loc_exit $!_loc_error;
+	# END
+
+	# BEGIN - Hexadecimal rdata processing
+	action _hex_r_data_error {
+		SCANNER_WARNING(ZSCANNER_EBAD_HEX_RDATA);
+		fhold; fgoto err_line;
+	}
+
+	nonempty_hex_r_data :=
+		(sep . length_number . sep . type_data)
+		$!_hex_r_data_error %_ret . end_wchar;
+
+	hex_r_data :=
+		(sep .
+		 ( ('0'                             %_ret . all_wchar)
+		 | (length_number . sep . type_data %_ret . end_wchar)
+		 )
+		) $!_hex_r_data_error;
+
+	# BEGIN - Rdata processing
+	action _r_data_init {
+		s->r_data_blocks[0] = 0;
+		s->r_data_blocks_count = 0;
+		rdata_tail = s->r_data;
+	}
+	action _r_data_error {
+		SCANNER_WARNING(ZSCANNER_EBAD_RDATA);
+		fhold; fgoto err_line;
+	}
+
+	r_data_a :=
+		(ipv4_addr_write)
+		$!_r_data_error %_ret . all_wchar;
+
+	r_data_ns :=
+		(r_dname)
+		$!_r_data_error %_ret . all_wchar;
+
+	r_data_soa :=
+		(r_dname . blk_sep .  sep . r_dname . blk_sep .  sep . num32 .
+		 sep . time32 . sep . time32 . sep . time32 . sep . time32)
+		$!_r_data_error %_ret . all_wchar;
+
+	r_data_hinfo :=
+		(text_string . sep . text_string)
+		$!_r_data_error %_ret . all_wchar;
+
+	r_data_minfo :=
+		(r_dname . blk_sep .  sep . r_dname)
+		$!_r_data_error %_ret . all_wchar;
+
+	r_data_mx :=
+		(num16 . blk_sep .  sep . r_dname)
+		$!_r_data_error %_ret . all_wchar;
+
+	r_data_txt :=
+		(text_array)
+		$!_r_data_error %_ret . end_wchar;
+
+	r_data_aaaa :=
+		(ipv6_addr_write)
+		$!_r_data_error %_ret . all_wchar;
+
+	r_data_loc :=
+		(loc)
+		$!_r_data_error %_ret . end_wchar;
+
+	r_data_srv :=
+		(num16 . sep . num16 . sep . num16 . blk_sep .  sep . r_dname)
+		$!_r_data_error %_ret . all_wchar;
+
+	r_data_naptr :=
+		(num16 . sep . num16 . sep . text_string . sep . text_string .
+		 sep . text_string . blk_sep .  sep . r_dname)
+		$!_r_data_error %_ret . all_wchar;
+
+	r_data_cert :=
+		(num16 . sep . num16 . sep . num8 . sep . base64)
+		$!_r_data_error %_ret . end_wchar;
+
+	r_data_apl :=
+		(apl_array)
+		$!_r_data_error %_ret . end_wchar;
+
+	r_data_ds :=
+		(num16 . sep . num8 . sep . num8 . sep . hex_array)
+		$!_r_data_error %_ret . end_wchar;
+
+	r_data_sshfp :=
+		(num8 . sep . num8 . sep . hex_array)
+		$!_r_data_error %_ret . end_wchar;
+
+	r_data_ipseckey :=
+		(num8 . sep . gateway)
+		$!_r_data_error %_ret . end_wchar;
+
+	r_data_rrsig :=
+		(type_num . sep . num8 . sep . num8 . sep . num32 . sep .
+		 timestamp . sep . timestamp . sep . num16 . blk_sep .  sep .
+		 r_dname . blk_sep . sep . base64)
+		$!_r_data_error %_ret . end_wchar;
+
+	r_data_nsec :=
+		(r_dname . blk_sep . bitmap)
+		$!_r_data_error %_ret . all_wchar;
+
+	r_data_dnskey :=
+		(num16 . sep . num8 . sep . num8 . sep . base64)
+		$!_r_data_error %_ret . end_wchar;
+
+	r_data_dhcid :=
+		(base64)
+		$!_r_data_error %_ret . end_wchar;
+
+	r_data_nsec3 :=
+		(num8 . sep . num8 . sep . num16 . sep . salt . sep .
+		 hash . bitmap)
+		$!_r_data_error %_ret . all_wchar;
+
+	r_data_nsec3param :=
+		(num8 . sep . num8 . sep . num16 . sep . salt)
+		$!_r_data_error %_ret . all_wchar;
+
+	r_data_tlsa :=
+		(num8 . sep . num8 . sep . num8 . sep . hex_array)
+		$!_r_data_error %_ret . end_wchar;
+
+	action _text_r_data {
+		fhold;
+		switch (s->r_type) {
+		case KNOT_RRTYPE_A:
+			fcall r_data_a;
+		case KNOT_RRTYPE_NS:
+		case KNOT_RRTYPE_CNAME:
+		case KNOT_RRTYPE_PTR:
+		case KNOT_RRTYPE_DNAME:
+			fcall r_data_ns;
+		case KNOT_RRTYPE_SOA:
+			fcall r_data_soa;
+		case KNOT_RRTYPE_HINFO:
+			fcall r_data_hinfo;
+		case KNOT_RRTYPE_MINFO:
+		case KNOT_RRTYPE_RP:
+			fcall r_data_minfo;
+		case KNOT_RRTYPE_MX:
+		case KNOT_RRTYPE_AFSDB:
+		case KNOT_RRTYPE_RT:
+		case KNOT_RRTYPE_KX:
+			fcall r_data_mx;
+		case KNOT_RRTYPE_TXT:
+		case KNOT_RRTYPE_SPF:
+			fcall r_data_txt;
+		case KNOT_RRTYPE_AAAA:
+			fcall r_data_aaaa;
+		case KNOT_RRTYPE_LOC:
+			fcall r_data_loc;
+		case KNOT_RRTYPE_SRV:
+			fcall r_data_srv;
+		case KNOT_RRTYPE_NAPTR:
+			fcall r_data_naptr;
+		case KNOT_RRTYPE_CERT:
+			fcall r_data_cert;
+		case KNOT_RRTYPE_APL:
+			fcall r_data_apl;
+		case KNOT_RRTYPE_DS:
+			fcall r_data_ds;
+		case KNOT_RRTYPE_SSHFP:
+			fcall r_data_sshfp;
+		case KNOT_RRTYPE_IPSECKEY:
+			fcall r_data_ipseckey;
+		case KNOT_RRTYPE_RRSIG:
+			fcall r_data_rrsig;
+		case KNOT_RRTYPE_NSEC:
+			fcall r_data_nsec;
+		case KNOT_RRTYPE_KEY:
+		case KNOT_RRTYPE_DNSKEY:
+			fcall r_data_dnskey;
+		case KNOT_RRTYPE_DHCID:
+			fcall r_data_dhcid;
+		case KNOT_RRTYPE_NSEC3:
+			fcall r_data_nsec3;
+		case KNOT_RRTYPE_NSEC3PARAM:
+			fcall r_data_nsec3param;
+		case KNOT_RRTYPE_TLSA:
+			fcall r_data_tlsa;
+		default:
+			SCANNER_WARNING(ZSCANNER_ECANNOT_TEXT_DATA);
+			fgoto err_line;
+		}
+	}
+	action _hex_r_data {
+		switch (s->r_type) {
+		// Next types must not have empty rdata.
+		case KNOT_RRTYPE_A:
+		case KNOT_RRTYPE_NS:
+		case KNOT_RRTYPE_CNAME:
+		case KNOT_RRTYPE_PTR:
+		case KNOT_RRTYPE_DNAME:
+		case KNOT_RRTYPE_SOA:
+		case KNOT_RRTYPE_HINFO:
+		case KNOT_RRTYPE_MINFO:
+		case KNOT_RRTYPE_MX:
+		case KNOT_RRTYPE_AFSDB:
+		case KNOT_RRTYPE_RT:
+		case KNOT_RRTYPE_KX:
+		case KNOT_RRTYPE_TXT:
+		case KNOT_RRTYPE_SPF:
+		case KNOT_RRTYPE_RP:
+		case KNOT_RRTYPE_AAAA:
+		case KNOT_RRTYPE_LOC:
+		case KNOT_RRTYPE_SRV:
+		case KNOT_RRTYPE_NAPTR:
+		case KNOT_RRTYPE_CERT:
+		case KNOT_RRTYPE_DS:
+		case KNOT_RRTYPE_SSHFP:
+		case KNOT_RRTYPE_IPSECKEY:
+		case KNOT_RRTYPE_RRSIG:
+		case KNOT_RRTYPE_NSEC:
+		case KNOT_RRTYPE_KEY:
+		case KNOT_RRTYPE_DNSKEY:
+		case KNOT_RRTYPE_DHCID:
+		case KNOT_RRTYPE_NSEC3:
+		case KNOT_RRTYPE_NSEC3PARAM:
+		case KNOT_RRTYPE_TLSA:
+			fcall nonempty_hex_r_data;
+		// Next types can have empty rdata.
+		case KNOT_RRTYPE_APL:
+		default:
+			fcall hex_r_data;
+		}
+	}
+
+	action _text_r_data_exit {
+		s->r_data_blocks[++(s->r_data_blocks_count)] =
+			(uint16_t)(rdata_tail - s->r_data);
+	}
+
+	# rdata can be in text or hex format with leading "\#" string
+	r_data =
+		( sep  . ^('\\' | all_wchar)     $_text_r_data %_text_r_data_exit
+		| sep  . '\\' . ^'#' ${ fhold; } $_text_r_data %_text_r_data_exit
+		| sep  . '\\' .  '#'             $_hex_r_data   # Hex format.
+		| sep? . end_wchar               $_text_r_data  # Empty rdata.
+		) >_r_data_init $!_r_data_error;
+	# END
+
+	# BEGIN - Record type processing
+	action _r_type_error {
+		SCANNER_WARNING(ZSCANNER_EUNSUPPORTED_TYPE);
+		fhold; fgoto err_line;
+	}
+
+	r_type =
+		( "A"i          %{ s->r_type = KNOT_RRTYPE_A; }
+		| "NS"i         %{ s->r_type = KNOT_RRTYPE_NS; }
+		| "CNAME"i      %{ s->r_type = KNOT_RRTYPE_CNAME; }
+		| "SOA"i        %{ s->r_type = KNOT_RRTYPE_SOA; }
+		| "PTR"i        %{ s->r_type = KNOT_RRTYPE_PTR; }
+		| "HINFO"i      %{ s->r_type = KNOT_RRTYPE_HINFO; }
+		| "MINFO"i      %{ s->r_type = KNOT_RRTYPE_MINFO; }
+		| "MX"i         %{ s->r_type = KNOT_RRTYPE_MX; }
+		| "TXT"i        %{ s->r_type = KNOT_RRTYPE_TXT; }
+		| "RP"i         %{ s->r_type = KNOT_RRTYPE_RP; }
+		| "AFSDB"i      %{ s->r_type = KNOT_RRTYPE_AFSDB; }
+		| "RT"i         %{ s->r_type = KNOT_RRTYPE_RT; }
+		| "KEY"i        %{ s->r_type = KNOT_RRTYPE_KEY; }
+		| "AAAA"i       %{ s->r_type = KNOT_RRTYPE_AAAA; }
+		| "LOC"i        %{ s->r_type = KNOT_RRTYPE_LOC; }
+		| "SRV"i        %{ s->r_type = KNOT_RRTYPE_SRV; }
+		| "NAPTR"i      %{ s->r_type = KNOT_RRTYPE_NAPTR; }
+		| "KX"i         %{ s->r_type = KNOT_RRTYPE_KX; }
+		| "CERT"i       %{ s->r_type = KNOT_RRTYPE_CERT; }
+		| "DNAME"i      %{ s->r_type = KNOT_RRTYPE_DNAME; }
+		| "APL"i        %{ s->r_type = KNOT_RRTYPE_APL; }
+		| "DS"i         %{ s->r_type = KNOT_RRTYPE_DS; }
+		| "SSHFP"i      %{ s->r_type = KNOT_RRTYPE_SSHFP; }
+		| "IPSECKEY"i   %{ s->r_type = KNOT_RRTYPE_IPSECKEY; }
+		| "RRSIG"i      %{ s->r_type = KNOT_RRTYPE_RRSIG; }
+		| "NSEC"i       %{ s->r_type = KNOT_RRTYPE_NSEC; }
+		| "DNSKEY"i     %{ s->r_type = KNOT_RRTYPE_DNSKEY; }
+		| "DHCID"i      %{ s->r_type = KNOT_RRTYPE_DHCID; }
+		| "NSEC3"i      %{ s->r_type = KNOT_RRTYPE_NSEC3; }
+		| "NSEC3PARAM"i %{ s->r_type = KNOT_RRTYPE_NSEC3PARAM; }
+		| "TLSA"i       %{ s->r_type = KNOT_RRTYPE_TLSA; }
+		| "SPF"i        %{ s->r_type = KNOT_RRTYPE_SPF; }
+		| "TYPE"i      . type_number
+		) $!_r_type_error;
+	# END
+
+	# BEGIN - The highest level processing
+	action _record_exit {
+		if (rdata_tail - s->r_data > UINT16_MAX) {
+			SCANNER_WARNING(ZSCANNER_ERDATA_OVERFLOW);
+			fhold; fgoto err_line;
+		}
+		s->r_data_length = rdata_tail - s->r_data;
+
+		s->process_record(s);
+	}
+
+	# Resource record.
+	record =
+		r_owner . sep .
+		( (r_class . sep . ((r_ttl   . sep) | (zlen %_default_r_ttl_exit  )))
+		| (r_ttl   . sep . ((r_class . sep) | (zlen %_default_r_class_exit)))
+		| zlen %_default_r_class_exit %_default_r_ttl_exit
+		) $!_r_type_error .
+		r_type . r_data .
+		rest %_record_exit .
+		newline;
+
+	# Blank spaces with comments.
+	blank = rest . newline;
+
+	# Main processing loop.
+	main := (record | directive | blank)*;
+	# END
+}%%
+
diff --git a/src/zscanner/scanner_functions.c b/src/zscanner/scanner_functions.c
new file mode 100644
index 0000000000000000000000000000000000000000..d24b59b6fc55faec2fe502c4568a9dc3702a623f
--- /dev/null
+++ b/src/zscanner/scanner_functions.c
@@ -0,0 +1,984 @@
+/*  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/>.
+ */
+
+#include "zscanner/scanner_functions.h"
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "common/errcode.h"
+#include "common/descriptor_new.h"
+#include "zscanner/scanner.h"
+
+const uint8_t digit_to_num[] = {
+    ['0'] = 0, ['1'] = 1, ['2'] = 2, ['3'] = 3, ['4'] = 4,
+    ['5'] = 5, ['6'] = 6, ['7'] = 7, ['8'] = 8, ['9'] = 9,
+};
+
+/*
+ * Hex transformation:
+ *          1        2
+ *      12345678 12345678
+ * in:    AAAA     BBBB
+ * out: AAAABBBB
+ */
+
+const uint8_t first_hex_to_num[] = {
+    ['0'] = ( 0 * 16), ['6'] = ( 6 * 16), ['C'] = (12 * 16), ['b'] = (11 * 16),
+    ['1'] = ( 1 * 16), ['7'] = ( 7 * 16), ['D'] = (13 * 16), ['c'] = (12 * 16),
+    ['2'] = ( 2 * 16), ['8'] = ( 8 * 16), ['E'] = (14 * 16), ['d'] = (13 * 16),
+    ['3'] = ( 3 * 16), ['9'] = ( 9 * 16), ['F'] = (15 * 16), ['e'] = (14 * 16),
+    ['4'] = ( 4 * 16), ['A'] = (10 * 16), ['a'] = (10 * 16), ['f'] = (15 * 16),
+    ['5'] = ( 5 * 16), ['B'] = (11 * 16),
+};
+
+const uint8_t second_hex_to_num[] = {
+    ['0'] =  0, ['4'] =  4, ['8'] =  8, ['C'] = 12, ['a'] = 10, ['d'] = 13,
+    ['1'] =  1, ['5'] =  5, ['9'] =  9, ['D'] = 13, ['b'] = 11, ['e'] = 14,
+    ['2'] =  2, ['6'] =  6, ['A'] = 10, ['E'] = 14, ['c'] = 12, ['f'] = 15,
+    ['3'] =  3, ['7'] =  7, ['B'] = 11, ['F'] = 15,
+};
+
+/*
+ * Base64 transformation:
+ *          1        2        3        4
+ *      12345678 12345678 12345678 12345678
+ * in:  00AAAAAA 00BBBBBB 00CCCCCC 00DDDDDD
+ * out: AAAAAABB BBBBCCCC CCDDDDDD
+ */
+
+// 0x3F = 00111111
+const uint8_t first_base64_to_num[] = {
+    ['A'] = (( 0 & 0x3F) << 2), ['g'] = ((32 & 0x3F) << 2),
+    ['B'] = (( 1 & 0x3F) << 2), ['h'] = ((33 & 0x3F) << 2),
+    ['C'] = (( 2 & 0x3F) << 2), ['i'] = ((34 & 0x3F) << 2),
+    ['D'] = (( 3 & 0x3F) << 2), ['j'] = ((35 & 0x3F) << 2),
+    ['E'] = (( 4 & 0x3F) << 2), ['k'] = ((36 & 0x3F) << 2),
+    ['F'] = (( 5 & 0x3F) << 2), ['l'] = ((37 & 0x3F) << 2),
+    ['G'] = (( 6 & 0x3F) << 2), ['m'] = ((38 & 0x3F) << 2),
+    ['H'] = (( 7 & 0x3F) << 2), ['n'] = ((39 & 0x3F) << 2),
+    ['I'] = (( 8 & 0x3F) << 2), ['o'] = ((40 & 0x3F) << 2),
+    ['J'] = (( 9 & 0x3F) << 2), ['p'] = ((41 & 0x3F) << 2),
+    ['K'] = ((10 & 0x3F) << 2), ['q'] = ((42 & 0x3F) << 2),
+    ['L'] = ((11 & 0x3F) << 2), ['r'] = ((43 & 0x3F) << 2),
+    ['M'] = ((12 & 0x3F) << 2), ['s'] = ((44 & 0x3F) << 2),
+    ['N'] = ((13 & 0x3F) << 2), ['t'] = ((45 & 0x3F) << 2),
+    ['O'] = ((14 & 0x3F) << 2), ['u'] = ((46 & 0x3F) << 2),
+    ['P'] = ((15 & 0x3F) << 2), ['v'] = ((47 & 0x3F) << 2),
+    ['Q'] = ((16 & 0x3F) << 2), ['w'] = ((48 & 0x3F) << 2),
+    ['R'] = ((17 & 0x3F) << 2), ['x'] = ((49 & 0x3F) << 2),
+    ['S'] = ((18 & 0x3F) << 2), ['y'] = ((50 & 0x3F) << 2),
+    ['T'] = ((19 & 0x3F) << 2), ['z'] = ((51 & 0x3F) << 2),
+    ['U'] = ((20 & 0x3F) << 2), ['0'] = ((52 & 0x3F) << 2),
+    ['V'] = ((21 & 0x3F) << 2), ['1'] = ((53 & 0x3F) << 2),
+    ['W'] = ((22 & 0x3F) << 2), ['2'] = ((54 & 0x3F) << 2),
+    ['X'] = ((23 & 0x3F) << 2), ['3'] = ((55 & 0x3F) << 2),
+    ['Y'] = ((24 & 0x3F) << 2), ['4'] = ((56 & 0x3F) << 2),
+    ['Z'] = ((25 & 0x3F) << 2), ['5'] = ((57 & 0x3F) << 2),
+    ['a'] = ((26 & 0x3F) << 2), ['6'] = ((58 & 0x3F) << 2),
+    ['b'] = ((27 & 0x3F) << 2), ['7'] = ((59 & 0x3F) << 2),
+    ['c'] = ((28 & 0x3F) << 2), ['8'] = ((60 & 0x3F) << 2),
+    ['d'] = ((29 & 0x3F) << 2), ['9'] = ((61 & 0x3F) << 2),
+    ['e'] = ((30 & 0x3F) << 2), ['+'] = ((62 & 0x3F) << 2),
+    ['f'] = ((31 & 0x3F) << 2), ['/'] = ((63 & 0x3F) << 2),
+};
+
+// 0x30 = 00110000
+const uint8_t second_left_base64_to_num[] = {
+    ['A'] = (( 0 & 0x30) >> 4), ['g'] = ((32 & 0x30) >> 4),
+    ['B'] = (( 1 & 0x30) >> 4), ['h'] = ((33 & 0x30) >> 4),
+    ['C'] = (( 2 & 0x30) >> 4), ['i'] = ((34 & 0x30) >> 4),
+    ['D'] = (( 3 & 0x30) >> 4), ['j'] = ((35 & 0x30) >> 4),
+    ['E'] = (( 4 & 0x30) >> 4), ['k'] = ((36 & 0x30) >> 4),
+    ['F'] = (( 5 & 0x30) >> 4), ['l'] = ((37 & 0x30) >> 4),
+    ['G'] = (( 6 & 0x30) >> 4), ['m'] = ((38 & 0x30) >> 4),
+    ['H'] = (( 7 & 0x30) >> 4), ['n'] = ((39 & 0x30) >> 4),
+    ['I'] = (( 8 & 0x30) >> 4), ['o'] = ((40 & 0x30) >> 4),
+    ['J'] = (( 9 & 0x30) >> 4), ['p'] = ((41 & 0x30) >> 4),
+    ['K'] = ((10 & 0x30) >> 4), ['q'] = ((42 & 0x30) >> 4),
+    ['L'] = ((11 & 0x30) >> 4), ['r'] = ((43 & 0x30) >> 4),
+    ['M'] = ((12 & 0x30) >> 4), ['s'] = ((44 & 0x30) >> 4),
+    ['N'] = ((13 & 0x30) >> 4), ['t'] = ((45 & 0x30) >> 4),
+    ['O'] = ((14 & 0x30) >> 4), ['u'] = ((46 & 0x30) >> 4),
+    ['P'] = ((15 & 0x30) >> 4), ['v'] = ((47 & 0x30) >> 4),
+    ['Q'] = ((16 & 0x30) >> 4), ['w'] = ((48 & 0x30) >> 4),
+    ['R'] = ((17 & 0x30) >> 4), ['x'] = ((49 & 0x30) >> 4),
+    ['S'] = ((18 & 0x30) >> 4), ['y'] = ((50 & 0x30) >> 4),
+    ['T'] = ((19 & 0x30) >> 4), ['z'] = ((51 & 0x30) >> 4),
+    ['U'] = ((20 & 0x30) >> 4), ['0'] = ((52 & 0x30) >> 4),
+    ['V'] = ((21 & 0x30) >> 4), ['1'] = ((53 & 0x30) >> 4),
+    ['W'] = ((22 & 0x30) >> 4), ['2'] = ((54 & 0x30) >> 4),
+    ['X'] = ((23 & 0x30) >> 4), ['3'] = ((55 & 0x30) >> 4),
+    ['Y'] = ((24 & 0x30) >> 4), ['4'] = ((56 & 0x30) >> 4),
+    ['Z'] = ((25 & 0x30) >> 4), ['5'] = ((57 & 0x30) >> 4),
+    ['a'] = ((26 & 0x30) >> 4), ['6'] = ((58 & 0x30) >> 4),
+    ['b'] = ((27 & 0x30) >> 4), ['7'] = ((59 & 0x30) >> 4),
+    ['c'] = ((28 & 0x30) >> 4), ['8'] = ((60 & 0x30) >> 4),
+    ['d'] = ((29 & 0x30) >> 4), ['9'] = ((61 & 0x30) >> 4),
+    ['e'] = ((30 & 0x30) >> 4), ['+'] = ((62 & 0x30) >> 4),
+    ['f'] = ((31 & 0x30) >> 4), ['/'] = ((63 & 0x30) >> 4),
+};
+
+// 0x0F = 00001111
+const uint8_t second_right_base64_to_num[] = {
+    ['A'] = (( 0 & 0x0F) << 4), ['g'] = ((32 & 0x0F) << 4),
+    ['B'] = (( 1 & 0x0F) << 4), ['h'] = ((33 & 0x0F) << 4),
+    ['C'] = (( 2 & 0x0F) << 4), ['i'] = ((34 & 0x0F) << 4),
+    ['D'] = (( 3 & 0x0F) << 4), ['j'] = ((35 & 0x0F) << 4),
+    ['E'] = (( 4 & 0x0F) << 4), ['k'] = ((36 & 0x0F) << 4),
+    ['F'] = (( 5 & 0x0F) << 4), ['l'] = ((37 & 0x0F) << 4),
+    ['G'] = (( 6 & 0x0F) << 4), ['m'] = ((38 & 0x0F) << 4),
+    ['H'] = (( 7 & 0x0F) << 4), ['n'] = ((39 & 0x0F) << 4),
+    ['I'] = (( 8 & 0x0F) << 4), ['o'] = ((40 & 0x0F) << 4),
+    ['J'] = (( 9 & 0x0F) << 4), ['p'] = ((41 & 0x0F) << 4),
+    ['K'] = ((10 & 0x0F) << 4), ['q'] = ((42 & 0x0F) << 4),
+    ['L'] = ((11 & 0x0F) << 4), ['r'] = ((43 & 0x0F) << 4),
+    ['M'] = ((12 & 0x0F) << 4), ['s'] = ((44 & 0x0F) << 4),
+    ['N'] = ((13 & 0x0F) << 4), ['t'] = ((45 & 0x0F) << 4),
+    ['O'] = ((14 & 0x0F) << 4), ['u'] = ((46 & 0x0F) << 4),
+    ['P'] = ((15 & 0x0F) << 4), ['v'] = ((47 & 0x0F) << 4),
+    ['Q'] = ((16 & 0x0F) << 4), ['w'] = ((48 & 0x0F) << 4),
+    ['R'] = ((17 & 0x0F) << 4), ['x'] = ((49 & 0x0F) << 4),
+    ['S'] = ((18 & 0x0F) << 4), ['y'] = ((50 & 0x0F) << 4),
+    ['T'] = ((19 & 0x0F) << 4), ['z'] = ((51 & 0x0F) << 4),
+    ['U'] = ((20 & 0x0F) << 4), ['0'] = ((52 & 0x0F) << 4),
+    ['V'] = ((21 & 0x0F) << 4), ['1'] = ((53 & 0x0F) << 4),
+    ['W'] = ((22 & 0x0F) << 4), ['2'] = ((54 & 0x0F) << 4),
+    ['X'] = ((23 & 0x0F) << 4), ['3'] = ((55 & 0x0F) << 4),
+    ['Y'] = ((24 & 0x0F) << 4), ['4'] = ((56 & 0x0F) << 4),
+    ['Z'] = ((25 & 0x0F) << 4), ['5'] = ((57 & 0x0F) << 4),
+    ['a'] = ((26 & 0x0F) << 4), ['6'] = ((58 & 0x0F) << 4),
+    ['b'] = ((27 & 0x0F) << 4), ['7'] = ((59 & 0x0F) << 4),
+    ['c'] = ((28 & 0x0F) << 4), ['8'] = ((60 & 0x0F) << 4),
+    ['d'] = ((29 & 0x0F) << 4), ['9'] = ((61 & 0x0F) << 4),
+    ['e'] = ((30 & 0x0F) << 4), ['+'] = ((62 & 0x0F) << 4),
+    ['f'] = ((31 & 0x0F) << 4), ['/'] = ((63 & 0x0F) << 4),
+};
+
+// 0x3C = 00111100
+const uint8_t third_left_base64_to_num[] = {
+    ['A'] = (( 0 & 0x3C) >> 2), ['g'] = ((32 & 0x3C) >> 2),
+    ['B'] = (( 1 & 0x3C) >> 2), ['h'] = ((33 & 0x3C) >> 2),
+    ['C'] = (( 2 & 0x3C) >> 2), ['i'] = ((34 & 0x3C) >> 2),
+    ['D'] = (( 3 & 0x3C) >> 2), ['j'] = ((35 & 0x3C) >> 2),
+    ['E'] = (( 4 & 0x3C) >> 2), ['k'] = ((36 & 0x3C) >> 2),
+    ['F'] = (( 5 & 0x3C) >> 2), ['l'] = ((37 & 0x3C) >> 2),
+    ['G'] = (( 6 & 0x3C) >> 2), ['m'] = ((38 & 0x3C) >> 2),
+    ['H'] = (( 7 & 0x3C) >> 2), ['n'] = ((39 & 0x3C) >> 2),
+    ['I'] = (( 8 & 0x3C) >> 2), ['o'] = ((40 & 0x3C) >> 2),
+    ['J'] = (( 9 & 0x3C) >> 2), ['p'] = ((41 & 0x3C) >> 2),
+    ['K'] = ((10 & 0x3C) >> 2), ['q'] = ((42 & 0x3C) >> 2),
+    ['L'] = ((11 & 0x3C) >> 2), ['r'] = ((43 & 0x3C) >> 2),
+    ['M'] = ((12 & 0x3C) >> 2), ['s'] = ((44 & 0x3C) >> 2),
+    ['N'] = ((13 & 0x3C) >> 2), ['t'] = ((45 & 0x3C) >> 2),
+    ['O'] = ((14 & 0x3C) >> 2), ['u'] = ((46 & 0x3C) >> 2),
+    ['P'] = ((15 & 0x3C) >> 2), ['v'] = ((47 & 0x3C) >> 2),
+    ['Q'] = ((16 & 0x3C) >> 2), ['w'] = ((48 & 0x3C) >> 2),
+    ['R'] = ((17 & 0x3C) >> 2), ['x'] = ((49 & 0x3C) >> 2),
+    ['S'] = ((18 & 0x3C) >> 2), ['y'] = ((50 & 0x3C) >> 2),
+    ['T'] = ((19 & 0x3C) >> 2), ['z'] = ((51 & 0x3C) >> 2),
+    ['U'] = ((20 & 0x3C) >> 2), ['0'] = ((52 & 0x3C) >> 2),
+    ['V'] = ((21 & 0x3C) >> 2), ['1'] = ((53 & 0x3C) >> 2),
+    ['W'] = ((22 & 0x3C) >> 2), ['2'] = ((54 & 0x3C) >> 2),
+    ['X'] = ((23 & 0x3C) >> 2), ['3'] = ((55 & 0x3C) >> 2),
+    ['Y'] = ((24 & 0x3C) >> 2), ['4'] = ((56 & 0x3C) >> 2),
+    ['Z'] = ((25 & 0x3C) >> 2), ['5'] = ((57 & 0x3C) >> 2),
+    ['a'] = ((26 & 0x3C) >> 2), ['6'] = ((58 & 0x3C) >> 2),
+    ['b'] = ((27 & 0x3C) >> 2), ['7'] = ((59 & 0x3C) >> 2),
+    ['c'] = ((28 & 0x3C) >> 2), ['8'] = ((60 & 0x3C) >> 2),
+    ['d'] = ((29 & 0x3C) >> 2), ['9'] = ((61 & 0x3C) >> 2),
+    ['e'] = ((30 & 0x3C) >> 2), ['+'] = ((62 & 0x3C) >> 2),
+    ['f'] = ((31 & 0x3C) >> 2), ['/'] = ((63 & 0x3C) >> 2),
+};
+
+// 0x03 = 00000011
+const uint8_t third_right_base64_to_num[] = {
+    ['A'] = (( 0 & 0x03) << 6), ['g'] = ((32 & 0x03) << 6),
+    ['B'] = (( 1 & 0x03) << 6), ['h'] = ((33 & 0x03) << 6),
+    ['C'] = (( 2 & 0x03) << 6), ['i'] = ((34 & 0x03) << 6),
+    ['D'] = (( 3 & 0x03) << 6), ['j'] = ((35 & 0x03) << 6),
+    ['E'] = (( 4 & 0x03) << 6), ['k'] = ((36 & 0x03) << 6),
+    ['F'] = (( 5 & 0x03) << 6), ['l'] = ((37 & 0x03) << 6),
+    ['G'] = (( 6 & 0x03) << 6), ['m'] = ((38 & 0x03) << 6),
+    ['H'] = (( 7 & 0x03) << 6), ['n'] = ((39 & 0x03) << 6),
+    ['I'] = (( 8 & 0x03) << 6), ['o'] = ((40 & 0x03) << 6),
+    ['J'] = (( 9 & 0x03) << 6), ['p'] = ((41 & 0x03) << 6),
+    ['K'] = ((10 & 0x03) << 6), ['q'] = ((42 & 0x03) << 6),
+    ['L'] = ((11 & 0x03) << 6), ['r'] = ((43 & 0x03) << 6),
+    ['M'] = ((12 & 0x03) << 6), ['s'] = ((44 & 0x03) << 6),
+    ['N'] = ((13 & 0x03) << 6), ['t'] = ((45 & 0x03) << 6),
+    ['O'] = ((14 & 0x03) << 6), ['u'] = ((46 & 0x03) << 6),
+    ['P'] = ((15 & 0x03) << 6), ['v'] = ((47 & 0x03) << 6),
+    ['Q'] = ((16 & 0x03) << 6), ['w'] = ((48 & 0x03) << 6),
+    ['R'] = ((17 & 0x03) << 6), ['x'] = ((49 & 0x03) << 6),
+    ['S'] = ((18 & 0x03) << 6), ['y'] = ((50 & 0x03) << 6),
+    ['T'] = ((19 & 0x03) << 6), ['z'] = ((51 & 0x03) << 6),
+    ['U'] = ((20 & 0x03) << 6), ['0'] = ((52 & 0x03) << 6),
+    ['V'] = ((21 & 0x03) << 6), ['1'] = ((53 & 0x03) << 6),
+    ['W'] = ((22 & 0x03) << 6), ['2'] = ((54 & 0x03) << 6),
+    ['X'] = ((23 & 0x03) << 6), ['3'] = ((55 & 0x03) << 6),
+    ['Y'] = ((24 & 0x03) << 6), ['4'] = ((56 & 0x03) << 6),
+    ['Z'] = ((25 & 0x03) << 6), ['5'] = ((57 & 0x03) << 6),
+    ['a'] = ((26 & 0x03) << 6), ['6'] = ((58 & 0x03) << 6),
+    ['b'] = ((27 & 0x03) << 6), ['7'] = ((59 & 0x03) << 6),
+    ['c'] = ((28 & 0x03) << 6), ['8'] = ((60 & 0x03) << 6),
+    ['d'] = ((29 & 0x03) << 6), ['9'] = ((61 & 0x03) << 6),
+    ['e'] = ((30 & 0x03) << 6), ['+'] = ((62 & 0x03) << 6),
+    ['f'] = ((31 & 0x03) << 6), ['/'] = ((63 & 0x03) << 6),
+};
+
+// 0x3F = 00111111
+const uint8_t fourth_base64_to_num[] = {
+    ['A'] = (( 0 & 0x3F) << 0), ['g'] = ((32 & 0x3F) << 0),
+    ['B'] = (( 1 & 0x3F) << 0), ['h'] = ((33 & 0x3F) << 0),
+    ['C'] = (( 2 & 0x3F) << 0), ['i'] = ((34 & 0x3F) << 0),
+    ['D'] = (( 3 & 0x3F) << 0), ['j'] = ((35 & 0x3F) << 0),
+    ['E'] = (( 4 & 0x3F) << 0), ['k'] = ((36 & 0x3F) << 0),
+    ['F'] = (( 5 & 0x3F) << 0), ['l'] = ((37 & 0x3F) << 0),
+    ['G'] = (( 6 & 0x3F) << 0), ['m'] = ((38 & 0x3F) << 0),
+    ['H'] = (( 7 & 0x3F) << 0), ['n'] = ((39 & 0x3F) << 0),
+    ['I'] = (( 8 & 0x3F) << 0), ['o'] = ((40 & 0x3F) << 0),
+    ['J'] = (( 9 & 0x3F) << 0), ['p'] = ((41 & 0x3F) << 0),
+    ['K'] = ((10 & 0x3F) << 0), ['q'] = ((42 & 0x3F) << 0),
+    ['L'] = ((11 & 0x3F) << 0), ['r'] = ((43 & 0x3F) << 0),
+    ['M'] = ((12 & 0x3F) << 0), ['s'] = ((44 & 0x3F) << 0),
+    ['N'] = ((13 & 0x3F) << 0), ['t'] = ((45 & 0x3F) << 0),
+    ['O'] = ((14 & 0x3F) << 0), ['u'] = ((46 & 0x3F) << 0),
+    ['P'] = ((15 & 0x3F) << 0), ['v'] = ((47 & 0x3F) << 0),
+    ['Q'] = ((16 & 0x3F) << 0), ['w'] = ((48 & 0x3F) << 0),
+    ['R'] = ((17 & 0x3F) << 0), ['x'] = ((49 & 0x3F) << 0),
+    ['S'] = ((18 & 0x3F) << 0), ['y'] = ((50 & 0x3F) << 0),
+    ['T'] = ((19 & 0x3F) << 0), ['z'] = ((51 & 0x3F) << 0),
+    ['U'] = ((20 & 0x3F) << 0), ['0'] = ((52 & 0x3F) << 0),
+    ['V'] = ((21 & 0x3F) << 0), ['1'] = ((53 & 0x3F) << 0),
+    ['W'] = ((22 & 0x3F) << 0), ['2'] = ((54 & 0x3F) << 0),
+    ['X'] = ((23 & 0x3F) << 0), ['3'] = ((55 & 0x3F) << 0),
+    ['Y'] = ((24 & 0x3F) << 0), ['4'] = ((56 & 0x3F) << 0),
+    ['Z'] = ((25 & 0x3F) << 0), ['5'] = ((57 & 0x3F) << 0),
+    ['a'] = ((26 & 0x3F) << 0), ['6'] = ((58 & 0x3F) << 0),
+    ['b'] = ((27 & 0x3F) << 0), ['7'] = ((59 & 0x3F) << 0),
+    ['c'] = ((28 & 0x3F) << 0), ['8'] = ((60 & 0x3F) << 0),
+    ['d'] = ((29 & 0x3F) << 0), ['9'] = ((61 & 0x3F) << 0),
+    ['e'] = ((30 & 0x3F) << 0), ['+'] = ((62 & 0x3F) << 0),
+    ['f'] = ((31 & 0x3F) << 0), ['/'] = ((63 & 0x3F) << 0),
+};
+
+/*
+ * Base32hex transformation (with lower-case):
+ *          1        2        3        4        5        6        7        8
+ *      12345678 12345678 12345678 12345678 12345678 12345678 12345678 12345678
+ * in:  000AAAAA 000BBBBB 000CCCCC 000DDDDD 000EEEEE 000FFFFF 000GGGGG 000HHHHH
+ * out  AAAAABBB BBCCCCCD DDDDEEEE EFFFFFGG GGGHHHHH
+ */
+
+// 0x1F = 00011111
+const uint8_t first_base32hex_to_num[] = {
+    ['0'] = (( 0 & 0x1F) << 3), ['R'] = ((27 & 0x1F) << 3),
+    ['1'] = (( 1 & 0x1F) << 3), ['S'] = ((28 & 0x1F) << 3),
+    ['2'] = (( 2 & 0x1F) << 3), ['T'] = ((29 & 0x1F) << 3),
+    ['3'] = (( 3 & 0x1F) << 3), ['U'] = ((30 & 0x1F) << 3),
+    ['4'] = (( 4 & 0x1F) << 3), ['V'] = ((31 & 0x1F) << 3),
+    ['5'] = (( 5 & 0x1F) << 3), ['a'] = ((10 & 0x1F) << 3),
+    ['6'] = (( 6 & 0x1F) << 3), ['b'] = ((11 & 0x1F) << 3),
+    ['7'] = (( 7 & 0x1F) << 3), ['c'] = ((12 & 0x1F) << 3),
+    ['8'] = (( 8 & 0x1F) << 3), ['d'] = ((13 & 0x1F) << 3),
+    ['9'] = (( 9 & 0x1F) << 3), ['e'] = ((14 & 0x1F) << 3),
+    ['A'] = ((10 & 0x1F) << 3), ['f'] = ((15 & 0x1F) << 3),
+    ['B'] = ((11 & 0x1F) << 3), ['g'] = ((16 & 0x1F) << 3),
+    ['C'] = ((12 & 0x1F) << 3), ['h'] = ((17 & 0x1F) << 3),
+    ['D'] = ((13 & 0x1F) << 3), ['i'] = ((18 & 0x1F) << 3),
+    ['E'] = ((14 & 0x1F) << 3), ['j'] = ((19 & 0x1F) << 3),
+    ['F'] = ((15 & 0x1F) << 3), ['k'] = ((20 & 0x1F) << 3),
+    ['G'] = ((16 & 0x1F) << 3), ['l'] = ((21 & 0x1F) << 3),
+    ['H'] = ((17 & 0x1F) << 3), ['m'] = ((22 & 0x1F) << 3),
+    ['I'] = ((18 & 0x1F) << 3), ['n'] = ((23 & 0x1F) << 3),
+    ['J'] = ((19 & 0x1F) << 3), ['o'] = ((24 & 0x1F) << 3),
+    ['K'] = ((20 & 0x1F) << 3), ['p'] = ((25 & 0x1F) << 3),
+    ['L'] = ((21 & 0x1F) << 3), ['q'] = ((26 & 0x1F) << 3),
+    ['M'] = ((22 & 0x1F) << 3), ['r'] = ((27 & 0x1F) << 3),
+    ['N'] = ((23 & 0x1F) << 3), ['s'] = ((28 & 0x1F) << 3),
+    ['O'] = ((24 & 0x1F) << 3), ['t'] = ((29 & 0x1F) << 3),
+    ['P'] = ((25 & 0x1F) << 3), ['u'] = ((30 & 0x1F) << 3),
+    ['Q'] = ((26 & 0x1F) << 3), ['v'] = ((31 & 0x1F) << 3),
+};
+
+// 0x1C = 00011100
+const uint8_t second_left_base32hex_to_num[] = {
+    ['0'] = (( 0 & 0x1C) >> 2), ['R'] = ((27 & 0x1C) >> 2),
+    ['1'] = (( 1 & 0x1C) >> 2), ['S'] = ((28 & 0x1C) >> 2),
+    ['2'] = (( 2 & 0x1C) >> 2), ['T'] = ((29 & 0x1C) >> 2),
+    ['3'] = (( 3 & 0x1C) >> 2), ['U'] = ((30 & 0x1C) >> 2),
+    ['4'] = (( 4 & 0x1C) >> 2), ['V'] = ((31 & 0x1C) >> 2),
+    ['5'] = (( 5 & 0x1C) >> 2), ['a'] = ((10 & 0x1C) >> 2),
+    ['6'] = (( 6 & 0x1C) >> 2), ['b'] = ((11 & 0x1C) >> 2),
+    ['7'] = (( 7 & 0x1C) >> 2), ['c'] = ((12 & 0x1C) >> 2),
+    ['8'] = (( 8 & 0x1C) >> 2), ['d'] = ((13 & 0x1C) >> 2),
+    ['9'] = (( 9 & 0x1C) >> 2), ['e'] = ((14 & 0x1C) >> 2),
+    ['A'] = ((10 & 0x1C) >> 2), ['f'] = ((15 & 0x1C) >> 2),
+    ['B'] = ((11 & 0x1C) >> 2), ['g'] = ((16 & 0x1C) >> 2),
+    ['C'] = ((12 & 0x1C) >> 2), ['h'] = ((17 & 0x1C) >> 2),
+    ['D'] = ((13 & 0x1C) >> 2), ['i'] = ((18 & 0x1C) >> 2),
+    ['E'] = ((14 & 0x1C) >> 2), ['j'] = ((19 & 0x1C) >> 2),
+    ['F'] = ((15 & 0x1C) >> 2), ['k'] = ((20 & 0x1C) >> 2),
+    ['G'] = ((16 & 0x1C) >> 2), ['l'] = ((21 & 0x1C) >> 2),
+    ['H'] = ((17 & 0x1C) >> 2), ['m'] = ((22 & 0x1C) >> 2),
+    ['I'] = ((18 & 0x1C) >> 2), ['n'] = ((23 & 0x1C) >> 2),
+    ['J'] = ((19 & 0x1C) >> 2), ['o'] = ((24 & 0x1C) >> 2),
+    ['K'] = ((20 & 0x1C) >> 2), ['p'] = ((25 & 0x1C) >> 2),
+    ['L'] = ((21 & 0x1C) >> 2), ['q'] = ((26 & 0x1C) >> 2),
+    ['M'] = ((22 & 0x1C) >> 2), ['r'] = ((27 & 0x1C) >> 2),
+    ['N'] = ((23 & 0x1C) >> 2), ['s'] = ((28 & 0x1C) >> 2),
+    ['O'] = ((24 & 0x1C) >> 2), ['t'] = ((29 & 0x1C) >> 2),
+    ['P'] = ((25 & 0x1C) >> 2), ['u'] = ((30 & 0x1C) >> 2),
+    ['Q'] = ((26 & 0x1C) >> 2), ['v'] = ((31 & 0x1C) >> 2),
+};
+
+// 0x03 = 00000011
+const uint8_t second_right_base32hex_to_num[] = {
+    ['0'] = (( 0 & 0x03) << 6), ['R'] = ((27 & 0x03) << 6),
+    ['1'] = (( 1 & 0x03) << 6), ['S'] = ((28 & 0x03) << 6),
+    ['2'] = (( 2 & 0x03) << 6), ['T'] = ((29 & 0x03) << 6),
+    ['3'] = (( 3 & 0x03) << 6), ['U'] = ((30 & 0x03) << 6),
+    ['4'] = (( 4 & 0x03) << 6), ['V'] = ((31 & 0x03) << 6),
+    ['5'] = (( 5 & 0x03) << 6), ['a'] = ((10 & 0x03) << 6),
+    ['6'] = (( 6 & 0x03) << 6), ['b'] = ((11 & 0x03) << 6),
+    ['7'] = (( 7 & 0x03) << 6), ['c'] = ((12 & 0x03) << 6),
+    ['8'] = (( 8 & 0x03) << 6), ['d'] = ((13 & 0x03) << 6),
+    ['9'] = (( 9 & 0x03) << 6), ['e'] = ((14 & 0x03) << 6),
+    ['A'] = ((10 & 0x03) << 6), ['f'] = ((15 & 0x03) << 6),
+    ['B'] = ((11 & 0x03) << 6), ['g'] = ((16 & 0x03) << 6),
+    ['C'] = ((12 & 0x03) << 6), ['h'] = ((17 & 0x03) << 6),
+    ['D'] = ((13 & 0x03) << 6), ['i'] = ((18 & 0x03) << 6),
+    ['E'] = ((14 & 0x03) << 6), ['j'] = ((19 & 0x03) << 6),
+    ['F'] = ((15 & 0x03) << 6), ['k'] = ((20 & 0x03) << 6),
+    ['G'] = ((16 & 0x03) << 6), ['l'] = ((21 & 0x03) << 6),
+    ['H'] = ((17 & 0x03) << 6), ['m'] = ((22 & 0x03) << 6),
+    ['I'] = ((18 & 0x03) << 6), ['n'] = ((23 & 0x03) << 6),
+    ['J'] = ((19 & 0x03) << 6), ['o'] = ((24 & 0x03) << 6),
+    ['K'] = ((20 & 0x03) << 6), ['p'] = ((25 & 0x03) << 6),
+    ['L'] = ((21 & 0x03) << 6), ['q'] = ((26 & 0x03) << 6),
+    ['M'] = ((22 & 0x03) << 6), ['r'] = ((27 & 0x03) << 6),
+    ['N'] = ((23 & 0x03) << 6), ['s'] = ((28 & 0x03) << 6),
+    ['O'] = ((24 & 0x03) << 6), ['t'] = ((29 & 0x03) << 6),
+    ['P'] = ((25 & 0x03) << 6), ['u'] = ((30 & 0x03) << 6),
+    ['Q'] = ((26 & 0x03) << 6), ['v'] = ((31 & 0x03) << 6),
+};
+
+// 0x1F = 00011111
+const uint8_t third_base32hex_to_num[] = {
+    ['0'] = (( 0 & 0x1F) << 1), ['R'] = ((27 & 0x1F) << 1),
+    ['1'] = (( 1 & 0x1F) << 1), ['S'] = ((28 & 0x1F) << 1),
+    ['2'] = (( 2 & 0x1F) << 1), ['T'] = ((29 & 0x1F) << 1),
+    ['3'] = (( 3 & 0x1F) << 1), ['U'] = ((30 & 0x1F) << 1),
+    ['4'] = (( 4 & 0x1F) << 1), ['V'] = ((31 & 0x1F) << 1),
+    ['5'] = (( 5 & 0x1F) << 1), ['a'] = ((10 & 0x1F) << 1),
+    ['6'] = (( 6 & 0x1F) << 1), ['b'] = ((11 & 0x1F) << 1),
+    ['7'] = (( 7 & 0x1F) << 1), ['c'] = ((12 & 0x1F) << 1),
+    ['8'] = (( 8 & 0x1F) << 1), ['d'] = ((13 & 0x1F) << 1),
+    ['9'] = (( 9 & 0x1F) << 1), ['e'] = ((14 & 0x1F) << 1),
+    ['A'] = ((10 & 0x1F) << 1), ['f'] = ((15 & 0x1F) << 1),
+    ['B'] = ((11 & 0x1F) << 1), ['g'] = ((16 & 0x1F) << 1),
+    ['C'] = ((12 & 0x1F) << 1), ['h'] = ((17 & 0x1F) << 1),
+    ['D'] = ((13 & 0x1F) << 1), ['i'] = ((18 & 0x1F) << 1),
+    ['E'] = ((14 & 0x1F) << 1), ['j'] = ((19 & 0x1F) << 1),
+    ['F'] = ((15 & 0x1F) << 1), ['k'] = ((20 & 0x1F) << 1),
+    ['G'] = ((16 & 0x1F) << 1), ['l'] = ((21 & 0x1F) << 1),
+    ['H'] = ((17 & 0x1F) << 1), ['m'] = ((22 & 0x1F) << 1),
+    ['I'] = ((18 & 0x1F) << 1), ['n'] = ((23 & 0x1F) << 1),
+    ['J'] = ((19 & 0x1F) << 1), ['o'] = ((24 & 0x1F) << 1),
+    ['K'] = ((20 & 0x1F) << 1), ['p'] = ((25 & 0x1F) << 1),
+    ['L'] = ((21 & 0x1F) << 1), ['q'] = ((26 & 0x1F) << 1),
+    ['M'] = ((22 & 0x1F) << 1), ['r'] = ((27 & 0x1F) << 1),
+    ['N'] = ((23 & 0x1F) << 1), ['s'] = ((28 & 0x1F) << 1),
+    ['O'] = ((24 & 0x1F) << 1), ['t'] = ((29 & 0x1F) << 1),
+    ['P'] = ((25 & 0x1F) << 1), ['u'] = ((30 & 0x1F) << 1),
+    ['Q'] = ((26 & 0x1F) << 1), ['v'] = ((31 & 0x1F) << 1),
+};
+
+// 0x10 = 00010000
+const uint8_t fourth_left_base32hex_to_num[] = {
+    ['0'] = (( 0 & 0x10) >> 4), ['R'] = ((27 & 0x10) >> 4),
+    ['1'] = (( 1 & 0x10) >> 4), ['S'] = ((28 & 0x10) >> 4),
+    ['2'] = (( 2 & 0x10) >> 4), ['T'] = ((29 & 0x10) >> 4),
+    ['3'] = (( 3 & 0x10) >> 4), ['U'] = ((30 & 0x10) >> 4),
+    ['4'] = (( 4 & 0x10) >> 4), ['V'] = ((31 & 0x10) >> 4),
+    ['5'] = (( 5 & 0x10) >> 4), ['a'] = ((10 & 0x10) >> 4),
+    ['6'] = (( 6 & 0x10) >> 4), ['b'] = ((11 & 0x10) >> 4),
+    ['7'] = (( 7 & 0x10) >> 4), ['c'] = ((12 & 0x10) >> 4),
+    ['8'] = (( 8 & 0x10) >> 4), ['d'] = ((13 & 0x10) >> 4),
+    ['9'] = (( 9 & 0x10) >> 4), ['e'] = ((14 & 0x10) >> 4),
+    ['A'] = ((10 & 0x10) >> 4), ['f'] = ((15 & 0x10) >> 4),
+    ['B'] = ((11 & 0x10) >> 4), ['g'] = ((16 & 0x10) >> 4),
+    ['C'] = ((12 & 0x10) >> 4), ['h'] = ((17 & 0x10) >> 4),
+    ['D'] = ((13 & 0x10) >> 4), ['i'] = ((18 & 0x10) >> 4),
+    ['E'] = ((14 & 0x10) >> 4), ['j'] = ((19 & 0x10) >> 4),
+    ['F'] = ((15 & 0x10) >> 4), ['k'] = ((20 & 0x10) >> 4),
+    ['G'] = ((16 & 0x10) >> 4), ['l'] = ((21 & 0x10) >> 4),
+    ['H'] = ((17 & 0x10) >> 4), ['m'] = ((22 & 0x10) >> 4),
+    ['I'] = ((18 & 0x10) >> 4), ['n'] = ((23 & 0x10) >> 4),
+    ['J'] = ((19 & 0x10) >> 4), ['o'] = ((24 & 0x10) >> 4),
+    ['K'] = ((20 & 0x10) >> 4), ['p'] = ((25 & 0x10) >> 4),
+    ['L'] = ((21 & 0x10) >> 4), ['q'] = ((26 & 0x10) >> 4),
+    ['M'] = ((22 & 0x10) >> 4), ['r'] = ((27 & 0x10) >> 4),
+    ['N'] = ((23 & 0x10) >> 4), ['s'] = ((28 & 0x10) >> 4),
+    ['O'] = ((24 & 0x10) >> 4), ['t'] = ((29 & 0x10) >> 4),
+    ['P'] = ((25 & 0x10) >> 4), ['u'] = ((30 & 0x10) >> 4),
+    ['Q'] = ((26 & 0x10) >> 4), ['v'] = ((31 & 0x10) >> 4),
+};
+
+// 0x0F = 00001111
+const uint8_t fourth_right_base32hex_to_num[] = {
+    ['0'] = (( 0 & 0x0F) << 4), ['R'] = ((27 & 0x0F) << 4),
+    ['1'] = (( 1 & 0x0F) << 4), ['S'] = ((28 & 0x0F) << 4),
+    ['2'] = (( 2 & 0x0F) << 4), ['T'] = ((29 & 0x0F) << 4),
+    ['3'] = (( 3 & 0x0F) << 4), ['U'] = ((30 & 0x0F) << 4),
+    ['4'] = (( 4 & 0x0F) << 4), ['V'] = ((31 & 0x0F) << 4),
+    ['5'] = (( 5 & 0x0F) << 4), ['a'] = ((10 & 0x0F) << 4),
+    ['6'] = (( 6 & 0x0F) << 4), ['b'] = ((11 & 0x0F) << 4),
+    ['7'] = (( 7 & 0x0F) << 4), ['c'] = ((12 & 0x0F) << 4),
+    ['8'] = (( 8 & 0x0F) << 4), ['d'] = ((13 & 0x0F) << 4),
+    ['9'] = (( 9 & 0x0F) << 4), ['e'] = ((14 & 0x0F) << 4),
+    ['A'] = ((10 & 0x0F) << 4), ['f'] = ((15 & 0x0F) << 4),
+    ['B'] = ((11 & 0x0F) << 4), ['g'] = ((16 & 0x0F) << 4),
+    ['C'] = ((12 & 0x0F) << 4), ['h'] = ((17 & 0x0F) << 4),
+    ['D'] = ((13 & 0x0F) << 4), ['i'] = ((18 & 0x0F) << 4),
+    ['E'] = ((14 & 0x0F) << 4), ['j'] = ((19 & 0x0F) << 4),
+    ['F'] = ((15 & 0x0F) << 4), ['k'] = ((20 & 0x0F) << 4),
+    ['G'] = ((16 & 0x0F) << 4), ['l'] = ((21 & 0x0F) << 4),
+    ['H'] = ((17 & 0x0F) << 4), ['m'] = ((22 & 0x0F) << 4),
+    ['I'] = ((18 & 0x0F) << 4), ['n'] = ((23 & 0x0F) << 4),
+    ['J'] = ((19 & 0x0F) << 4), ['o'] = ((24 & 0x0F) << 4),
+    ['K'] = ((20 & 0x0F) << 4), ['p'] = ((25 & 0x0F) << 4),
+    ['L'] = ((21 & 0x0F) << 4), ['q'] = ((26 & 0x0F) << 4),
+    ['M'] = ((22 & 0x0F) << 4), ['r'] = ((27 & 0x0F) << 4),
+    ['N'] = ((23 & 0x0F) << 4), ['s'] = ((28 & 0x0F) << 4),
+    ['O'] = ((24 & 0x0F) << 4), ['t'] = ((29 & 0x0F) << 4),
+    ['P'] = ((25 & 0x0F) << 4), ['u'] = ((30 & 0x0F) << 4),
+    ['Q'] = ((26 & 0x0F) << 4), ['v'] = ((31 & 0x0F) << 4),
+};
+
+// 0x1E = 00011110
+const uint8_t fifth_left_base32hex_to_num[] = {
+    ['0'] = (( 0 & 0x1E) >> 1), ['R'] = ((27 & 0x1E) >> 1),
+    ['1'] = (( 1 & 0x1E) >> 1), ['S'] = ((28 & 0x1E) >> 1),
+    ['2'] = (( 2 & 0x1E) >> 1), ['T'] = ((29 & 0x1E) >> 1),
+    ['3'] = (( 3 & 0x1E) >> 1), ['U'] = ((30 & 0x1E) >> 1),
+    ['4'] = (( 4 & 0x1E) >> 1), ['V'] = ((31 & 0x1E) >> 1),
+    ['5'] = (( 5 & 0x1E) >> 1), ['a'] = ((10 & 0x1E) >> 1),
+    ['6'] = (( 6 & 0x1E) >> 1), ['b'] = ((11 & 0x1E) >> 1),
+    ['7'] = (( 7 & 0x1E) >> 1), ['c'] = ((12 & 0x1E) >> 1),
+    ['8'] = (( 8 & 0x1E) >> 1), ['d'] = ((13 & 0x1E) >> 1),
+    ['9'] = (( 9 & 0x1E) >> 1), ['e'] = ((14 & 0x1E) >> 1),
+    ['A'] = ((10 & 0x1E) >> 1), ['f'] = ((15 & 0x1E) >> 1),
+    ['B'] = ((11 & 0x1E) >> 1), ['g'] = ((16 & 0x1E) >> 1),
+    ['C'] = ((12 & 0x1E) >> 1), ['h'] = ((17 & 0x1E) >> 1),
+    ['D'] = ((13 & 0x1E) >> 1), ['i'] = ((18 & 0x1E) >> 1),
+    ['E'] = ((14 & 0x1E) >> 1), ['j'] = ((19 & 0x1E) >> 1),
+    ['F'] = ((15 & 0x1E) >> 1), ['k'] = ((20 & 0x1E) >> 1),
+    ['G'] = ((16 & 0x1E) >> 1), ['l'] = ((21 & 0x1E) >> 1),
+    ['H'] = ((17 & 0x1E) >> 1), ['m'] = ((22 & 0x1E) >> 1),
+    ['I'] = ((18 & 0x1E) >> 1), ['n'] = ((23 & 0x1E) >> 1),
+    ['J'] = ((19 & 0x1E) >> 1), ['o'] = ((24 & 0x1E) >> 1),
+    ['K'] = ((20 & 0x1E) >> 1), ['p'] = ((25 & 0x1E) >> 1),
+    ['L'] = ((21 & 0x1E) >> 1), ['q'] = ((26 & 0x1E) >> 1),
+    ['M'] = ((22 & 0x1E) >> 1), ['r'] = ((27 & 0x1E) >> 1),
+    ['N'] = ((23 & 0x1E) >> 1), ['s'] = ((28 & 0x1E) >> 1),
+    ['O'] = ((24 & 0x1E) >> 1), ['t'] = ((29 & 0x1E) >> 1),
+    ['P'] = ((25 & 0x1E) >> 1), ['u'] = ((30 & 0x1E) >> 1),
+    ['Q'] = ((26 & 0x1E) >> 1), ['v'] = ((31 & 0x1E) >> 1),
+};
+
+// 0x01 = 00000001
+const uint8_t fifth_right_base32hex_to_num[] = {
+    ['0'] = (( 0 & 0x01) << 7), ['R'] = ((27 & 0x01) << 7),
+    ['1'] = (( 1 & 0x01) << 7), ['S'] = ((28 & 0x01) << 7),
+    ['2'] = (( 2 & 0x01) << 7), ['T'] = ((29 & 0x01) << 7),
+    ['3'] = (( 3 & 0x01) << 7), ['U'] = ((30 & 0x01) << 7),
+    ['4'] = (( 4 & 0x01) << 7), ['V'] = ((31 & 0x01) << 7),
+    ['5'] = (( 5 & 0x01) << 7), ['a'] = ((10 & 0x01) << 7),
+    ['6'] = (( 6 & 0x01) << 7), ['b'] = ((11 & 0x01) << 7),
+    ['7'] = (( 7 & 0x01) << 7), ['c'] = ((12 & 0x01) << 7),
+    ['8'] = (( 8 & 0x01) << 7), ['d'] = ((13 & 0x01) << 7),
+    ['9'] = (( 9 & 0x01) << 7), ['e'] = ((14 & 0x01) << 7),
+    ['A'] = ((10 & 0x01) << 7), ['f'] = ((15 & 0x01) << 7),
+    ['B'] = ((11 & 0x01) << 7), ['g'] = ((16 & 0x01) << 7),
+    ['C'] = ((12 & 0x01) << 7), ['h'] = ((17 & 0x01) << 7),
+    ['D'] = ((13 & 0x01) << 7), ['i'] = ((18 & 0x01) << 7),
+    ['E'] = ((14 & 0x01) << 7), ['j'] = ((19 & 0x01) << 7),
+    ['F'] = ((15 & 0x01) << 7), ['k'] = ((20 & 0x01) << 7),
+    ['G'] = ((16 & 0x01) << 7), ['l'] = ((21 & 0x01) << 7),
+    ['H'] = ((17 & 0x01) << 7), ['m'] = ((22 & 0x01) << 7),
+    ['I'] = ((18 & 0x01) << 7), ['n'] = ((23 & 0x01) << 7),
+    ['J'] = ((19 & 0x01) << 7), ['o'] = ((24 & 0x01) << 7),
+    ['K'] = ((20 & 0x01) << 7), ['p'] = ((25 & 0x01) << 7),
+    ['L'] = ((21 & 0x01) << 7), ['q'] = ((26 & 0x01) << 7),
+    ['M'] = ((22 & 0x01) << 7), ['r'] = ((27 & 0x01) << 7),
+    ['N'] = ((23 & 0x01) << 7), ['s'] = ((28 & 0x01) << 7),
+    ['O'] = ((24 & 0x01) << 7), ['t'] = ((29 & 0x01) << 7),
+    ['P'] = ((25 & 0x01) << 7), ['u'] = ((30 & 0x01) << 7),
+    ['Q'] = ((26 & 0x01) << 7), ['v'] = ((31 & 0x01) << 7),
+};
+
+// 0x1F = 00011111
+const uint8_t sixth_base32hex_to_num[] = {
+    ['0'] = (( 0 & 0x1F) << 2), ['R'] = ((27 & 0x1F) << 2),
+    ['1'] = (( 1 & 0x1F) << 2), ['S'] = ((28 & 0x1F) << 2),
+    ['2'] = (( 2 & 0x1F) << 2), ['T'] = ((29 & 0x1F) << 2),
+    ['3'] = (( 3 & 0x1F) << 2), ['U'] = ((30 & 0x1F) << 2),
+    ['4'] = (( 4 & 0x1F) << 2), ['V'] = ((31 & 0x1F) << 2),
+    ['5'] = (( 5 & 0x1F) << 2), ['a'] = ((10 & 0x1F) << 2),
+    ['6'] = (( 6 & 0x1F) << 2), ['b'] = ((11 & 0x1F) << 2),
+    ['7'] = (( 7 & 0x1F) << 2), ['c'] = ((12 & 0x1F) << 2),
+    ['8'] = (( 8 & 0x1F) << 2), ['d'] = ((13 & 0x1F) << 2),
+    ['9'] = (( 9 & 0x1F) << 2), ['e'] = ((14 & 0x1F) << 2),
+    ['A'] = ((10 & 0x1F) << 2), ['f'] = ((15 & 0x1F) << 2),
+    ['B'] = ((11 & 0x1F) << 2), ['g'] = ((16 & 0x1F) << 2),
+    ['C'] = ((12 & 0x1F) << 2), ['h'] = ((17 & 0x1F) << 2),
+    ['D'] = ((13 & 0x1F) << 2), ['i'] = ((18 & 0x1F) << 2),
+    ['E'] = ((14 & 0x1F) << 2), ['j'] = ((19 & 0x1F) << 2),
+    ['F'] = ((15 & 0x1F) << 2), ['k'] = ((20 & 0x1F) << 2),
+    ['G'] = ((16 & 0x1F) << 2), ['l'] = ((21 & 0x1F) << 2),
+    ['H'] = ((17 & 0x1F) << 2), ['m'] = ((22 & 0x1F) << 2),
+    ['I'] = ((18 & 0x1F) << 2), ['n'] = ((23 & 0x1F) << 2),
+    ['J'] = ((19 & 0x1F) << 2), ['o'] = ((24 & 0x1F) << 2),
+    ['K'] = ((20 & 0x1F) << 2), ['p'] = ((25 & 0x1F) << 2),
+    ['L'] = ((21 & 0x1F) << 2), ['q'] = ((26 & 0x1F) << 2),
+    ['M'] = ((22 & 0x1F) << 2), ['r'] = ((27 & 0x1F) << 2),
+    ['N'] = ((23 & 0x1F) << 2), ['s'] = ((28 & 0x1F) << 2),
+    ['O'] = ((24 & 0x1F) << 2), ['t'] = ((29 & 0x1F) << 2),
+    ['P'] = ((25 & 0x1F) << 2), ['u'] = ((30 & 0x1F) << 2),
+    ['Q'] = ((26 & 0x1F) << 2), ['v'] = ((31 & 0x1F) << 2),
+};
+
+// 0x18 = 00011000
+const uint8_t seventh_left_base32hex_to_num[] = {
+    ['0'] = (( 0 & 0x18) >> 3), ['R'] = ((27 & 0x18) >> 3),
+    ['1'] = (( 1 & 0x18) >> 3), ['S'] = ((28 & 0x18) >> 3),
+    ['2'] = (( 2 & 0x18) >> 3), ['T'] = ((29 & 0x18) >> 3),
+    ['3'] = (( 3 & 0x18) >> 3), ['U'] = ((30 & 0x18) >> 3),
+    ['4'] = (( 4 & 0x18) >> 3), ['V'] = ((31 & 0x18) >> 3),
+    ['5'] = (( 5 & 0x18) >> 3), ['a'] = ((10 & 0x18) >> 3),
+    ['6'] = (( 6 & 0x18) >> 3), ['b'] = ((11 & 0x18) >> 3),
+    ['7'] = (( 7 & 0x18) >> 3), ['c'] = ((12 & 0x18) >> 3),
+    ['8'] = (( 8 & 0x18) >> 3), ['d'] = ((13 & 0x18) >> 3),
+    ['9'] = (( 9 & 0x18) >> 3), ['e'] = ((14 & 0x18) >> 3),
+    ['A'] = ((10 & 0x18) >> 3), ['f'] = ((15 & 0x18) >> 3),
+    ['B'] = ((11 & 0x18) >> 3), ['g'] = ((16 & 0x18) >> 3),
+    ['C'] = ((12 & 0x18) >> 3), ['h'] = ((17 & 0x18) >> 3),
+    ['D'] = ((13 & 0x18) >> 3), ['i'] = ((18 & 0x18) >> 3),
+    ['E'] = ((14 & 0x18) >> 3), ['j'] = ((19 & 0x18) >> 3),
+    ['F'] = ((15 & 0x18) >> 3), ['k'] = ((20 & 0x18) >> 3),
+    ['G'] = ((16 & 0x18) >> 3), ['l'] = ((21 & 0x18) >> 3),
+    ['H'] = ((17 & 0x18) >> 3), ['m'] = ((22 & 0x18) >> 3),
+    ['I'] = ((18 & 0x18) >> 3), ['n'] = ((23 & 0x18) >> 3),
+    ['J'] = ((19 & 0x18) >> 3), ['o'] = ((24 & 0x18) >> 3),
+    ['K'] = ((20 & 0x18) >> 3), ['p'] = ((25 & 0x18) >> 3),
+    ['L'] = ((21 & 0x18) >> 3), ['q'] = ((26 & 0x18) >> 3),
+    ['M'] = ((22 & 0x18) >> 3), ['r'] = ((27 & 0x18) >> 3),
+    ['N'] = ((23 & 0x18) >> 3), ['s'] = ((28 & 0x18) >> 3),
+    ['O'] = ((24 & 0x18) >> 3), ['t'] = ((29 & 0x18) >> 3),
+    ['P'] = ((25 & 0x18) >> 3), ['u'] = ((30 & 0x18) >> 3),
+    ['Q'] = ((26 & 0x18) >> 3), ['v'] = ((31 & 0x18) >> 3),
+};
+
+// 0x07 = 00000111
+const uint8_t seventh_right_base32hex_to_num[] = {
+    ['0'] = (( 0 & 0x07) << 5), ['R'] = ((27 & 0x07) << 5),
+    ['1'] = (( 1 & 0x07) << 5), ['S'] = ((28 & 0x07) << 5),
+    ['2'] = (( 2 & 0x07) << 5), ['T'] = ((29 & 0x07) << 5),
+    ['3'] = (( 3 & 0x07) << 5), ['U'] = ((30 & 0x07) << 5),
+    ['4'] = (( 4 & 0x07) << 5), ['V'] = ((31 & 0x07) << 5),
+    ['5'] = (( 5 & 0x07) << 5), ['a'] = ((10 & 0x07) << 5),
+    ['6'] = (( 6 & 0x07) << 5), ['b'] = ((11 & 0x07) << 5),
+    ['7'] = (( 7 & 0x07) << 5), ['c'] = ((12 & 0x07) << 5),
+    ['8'] = (( 8 & 0x07) << 5), ['d'] = ((13 & 0x07) << 5),
+    ['9'] = (( 9 & 0x07) << 5), ['e'] = ((14 & 0x07) << 5),
+    ['A'] = ((10 & 0x07) << 5), ['f'] = ((15 & 0x07) << 5),
+    ['B'] = ((11 & 0x07) << 5), ['g'] = ((16 & 0x07) << 5),
+    ['C'] = ((12 & 0x07) << 5), ['h'] = ((17 & 0x07) << 5),
+    ['D'] = ((13 & 0x07) << 5), ['i'] = ((18 & 0x07) << 5),
+    ['E'] = ((14 & 0x07) << 5), ['j'] = ((19 & 0x07) << 5),
+    ['F'] = ((15 & 0x07) << 5), ['k'] = ((20 & 0x07) << 5),
+    ['G'] = ((16 & 0x07) << 5), ['l'] = ((21 & 0x07) << 5),
+    ['H'] = ((17 & 0x07) << 5), ['m'] = ((22 & 0x07) << 5),
+    ['I'] = ((18 & 0x07) << 5), ['n'] = ((23 & 0x07) << 5),
+    ['J'] = ((19 & 0x07) << 5), ['o'] = ((24 & 0x07) << 5),
+    ['K'] = ((20 & 0x07) << 5), ['p'] = ((25 & 0x07) << 5),
+    ['L'] = ((21 & 0x07) << 5), ['q'] = ((26 & 0x07) << 5),
+    ['M'] = ((22 & 0x07) << 5), ['r'] = ((27 & 0x07) << 5),
+    ['N'] = ((23 & 0x07) << 5), ['s'] = ((28 & 0x07) << 5),
+    ['O'] = ((24 & 0x07) << 5), ['t'] = ((29 & 0x07) << 5),
+    ['P'] = ((25 & 0x07) << 5), ['u'] = ((30 & 0x07) << 5),
+    ['Q'] = ((26 & 0x07) << 5), ['v'] = ((31 & 0x07) << 5),
+};
+
+// 0x1F = 00011111
+const uint8_t eighth_base32hex_to_num[] = {
+    ['0'] = (( 0 & 0x1F) << 0), ['R'] = ((27 & 0x1F) << 0),
+    ['1'] = (( 1 & 0x1F) << 0), ['S'] = ((28 & 0x1F) << 0),
+    ['2'] = (( 2 & 0x1F) << 0), ['T'] = ((29 & 0x1F) << 0),
+    ['3'] = (( 3 & 0x1F) << 0), ['U'] = ((30 & 0x1F) << 0),
+    ['4'] = (( 4 & 0x1F) << 0), ['V'] = ((31 & 0x1F) << 0),
+    ['5'] = (( 5 & 0x1F) << 0), ['a'] = ((10 & 0x1F) << 0),
+    ['6'] = (( 6 & 0x1F) << 0), ['b'] = ((11 & 0x1F) << 0),
+    ['7'] = (( 7 & 0x1F) << 0), ['c'] = ((12 & 0x1F) << 0),
+    ['8'] = (( 8 & 0x1F) << 0), ['d'] = ((13 & 0x1F) << 0),
+    ['9'] = (( 9 & 0x1F) << 0), ['e'] = ((14 & 0x1F) << 0),
+    ['A'] = ((10 & 0x1F) << 0), ['f'] = ((15 & 0x1F) << 0),
+    ['B'] = ((11 & 0x1F) << 0), ['g'] = ((16 & 0x1F) << 0),
+    ['C'] = ((12 & 0x1F) << 0), ['h'] = ((17 & 0x1F) << 0),
+    ['D'] = ((13 & 0x1F) << 0), ['i'] = ((18 & 0x1F) << 0),
+    ['E'] = ((14 & 0x1F) << 0), ['j'] = ((19 & 0x1F) << 0),
+    ['F'] = ((15 & 0x1F) << 0), ['k'] = ((20 & 0x1F) << 0),
+    ['G'] = ((16 & 0x1F) << 0), ['l'] = ((21 & 0x1F) << 0),
+    ['H'] = ((17 & 0x1F) << 0), ['m'] = ((22 & 0x1F) << 0),
+    ['I'] = ((18 & 0x1F) << 0), ['n'] = ((23 & 0x1F) << 0),
+    ['J'] = ((19 & 0x1F) << 0), ['o'] = ((24 & 0x1F) << 0),
+    ['K'] = ((20 & 0x1F) << 0), ['p'] = ((25 & 0x1F) << 0),
+    ['L'] = ((21 & 0x1F) << 0), ['q'] = ((26 & 0x1F) << 0),
+    ['M'] = ((22 & 0x1F) << 0), ['r'] = ((27 & 0x1F) << 0),
+    ['N'] = ((23 & 0x1F) << 0), ['s'] = ((28 & 0x1F) << 0),
+    ['O'] = ((24 & 0x1F) << 0), ['t'] = ((29 & 0x1F) << 0),
+    ['P'] = ((25 & 0x1F) << 0), ['u'] = ((30 & 0x1F) << 0),
+    ['Q'] = ((26 & 0x1F) << 0), ['v'] = ((31 & 0x1F) << 0),
+};
+
+// Without leap day 29. 2.
+static const uint8_t days_in_months[] = {
+    [ 1] = 31, [ 2] = 28, [ 3] = 31, [ 4] = 30, [ 5] = 31, [ 6] = 30,
+    [ 7] = 31, [ 8] = 31, [ 9] = 30, [10] = 31, [11] = 30, [12] = 31,
+};
+
+// Without leap day 29. 2.
+static const uint16_t days_across_months[] = {
+    [ 1] =   0, [ 2] =  31, [ 3] =  59, [ 4] =  90, [ 5] = 120, [ 6] = 151,
+    [ 7] = 181, [ 8] = 212, [ 9] = 243, [10] = 273, [11] = 304, [12] = 334,
+};
+
+// 0 ~ 1970 ... 135 ~ 2105
+static const uint8_t is_leap_year[] = {
+    [  1] = 0, [  2] = 1, [  3] = 0, [  4] = 0, [  5] = 0,
+    [  6] = 1, [  7] = 0, [  8] = 0, [  9] = 0, [ 10] = 1,
+    [ 11] = 0, [ 12] = 0, [ 13] = 0, [ 14] = 1, [ 15] = 0,
+    [ 16] = 0, [ 17] = 0, [ 18] = 1, [ 19] = 0, [ 20] = 0,
+    [ 21] = 0, [ 22] = 1, [ 23] = 0, [ 24] = 0, [ 25] = 0,
+    [ 26] = 1, [ 27] = 0, [ 28] = 0, [ 29] = 0, [ 30] = 1,
+    [ 31] = 0, [ 32] = 0, [ 33] = 0, [ 34] = 1, [ 35] = 0,
+    [ 36] = 0, [ 37] = 0, [ 38] = 1, [ 39] = 0, [ 40] = 0,
+    [ 41] = 0, [ 42] = 1, [ 43] = 0, [ 44] = 0, [ 45] = 0,
+    [ 46] = 1, [ 47] = 0, [ 48] = 0, [ 49] = 0, [ 50] = 1,
+    [ 51] = 0, [ 52] = 0, [ 53] = 0, [ 54] = 1, [ 55] = 0,
+    [ 56] = 0, [ 57] = 0, [ 58] = 1, [ 59] = 0, [ 60] = 0,
+    [ 61] = 0, [ 62] = 1, [ 63] = 0, [ 64] = 0, [ 65] = 0,
+    [ 66] = 1, [ 67] = 0, [ 68] = 0, [ 69] = 0, [ 70] = 1,
+    [ 71] = 0, [ 72] = 0, [ 73] = 0, [ 74] = 1, [ 75] = 0,
+    [ 76] = 0, [ 77] = 0, [ 78] = 1, [ 79] = 0, [ 80] = 0,
+    [ 81] = 0, [ 82] = 1, [ 83] = 0, [ 84] = 0, [ 85] = 0,
+    [ 86] = 1, [ 87] = 0, [ 88] = 0, [ 89] = 0, [ 90] = 1,
+    [ 91] = 0, [ 92] = 0, [ 93] = 0, [ 94] = 1, [ 95] = 0,
+    [ 96] = 0, [ 97] = 0, [ 98] = 1, [ 99] = 0, [100] = 0,
+    [101] = 0, [102] = 1, [103] = 0, [104] = 0, [105] = 0,
+    [106] = 1, [107] = 0, [108] = 0, [109] = 0, [110] = 1,
+    [111] = 0, [112] = 0, [113] = 0, [114] = 1, [115] = 0,
+    [116] = 0, [117] = 0, [118] = 1, [119] = 0, [120] = 0,
+    [121] = 0, [122] = 1, [123] = 0, [124] = 0, [125] = 0,
+    [126] = 1, [127] = 0, [128] = 0, [129] = 0, [130] = 0,
+    [131] = 0, [132] = 0, [133] = 0, [134] = 1, [135] = 0,
+};
+
+// 0 ~ 1970 ... 135 ~ 2105
+static const uint16_t days_across_years[] = {
+    [  1] =   365, [  2] =   730, [  3] =  1096, [  4] =  1461, [  5] =  1826,
+    [  6] =  2191, [  7] =  2557, [  8] =  2922, [  9] =  3287, [ 10] =  3652,
+    [ 11] =  4018, [ 12] =  4383, [ 13] =  4748, [ 14] =  5113, [ 15] =  5479,
+    [ 16] =  5844, [ 17] =  6209, [ 18] =  6574, [ 19] =  6940, [ 20] =  7305,
+    [ 21] =  7670, [ 22] =  8035, [ 23] =  8401, [ 24] =  8766, [ 25] =  9131,
+    [ 26] =  9496, [ 27] =  9862, [ 28] = 10227, [ 29] = 10592, [ 30] = 10957,
+    [ 31] = 11323, [ 32] = 11688, [ 33] = 12053, [ 34] = 12418, [ 35] = 12784,
+    [ 36] = 13149, [ 37] = 13514, [ 38] = 13879, [ 39] = 14245, [ 40] = 14610,
+    [ 41] = 14975, [ 42] = 15340, [ 43] = 15706, [ 44] = 16071, [ 45] = 16436,
+    [ 46] = 16801, [ 47] = 17167, [ 48] = 17532, [ 49] = 17897, [ 50] = 18262,
+    [ 51] = 18628, [ 52] = 18993, [ 53] = 19358, [ 54] = 19723, [ 55] = 20089,
+    [ 56] = 20454, [ 57] = 20819, [ 58] = 21184, [ 59] = 21550, [ 60] = 21915,
+    [ 61] = 22280, [ 62] = 22645, [ 63] = 23011, [ 64] = 23376, [ 65] = 23741,
+    [ 66] = 24106, [ 67] = 24472, [ 68] = 24837, [ 69] = 25202, [ 70] = 25567,
+    [ 71] = 25933, [ 72] = 26298, [ 73] = 26663, [ 74] = 27028, [ 75] = 27394,
+    [ 76] = 27759, [ 77] = 28124, [ 78] = 28489, [ 79] = 28855, [ 80] = 29220,
+    [ 81] = 29585, [ 82] = 29950, [ 83] = 30316, [ 84] = 30681, [ 85] = 31046,
+    [ 86] = 31411, [ 87] = 31777, [ 88] = 32142, [ 89] = 32507, [ 90] = 32872,
+    [ 91] = 33238, [ 92] = 33603, [ 93] = 33968, [ 94] = 34333, [ 95] = 34699,
+    [ 96] = 35064, [ 97] = 35429, [ 98] = 35794, [ 99] = 36160, [100] = 36525,
+    [101] = 36890, [102] = 37255, [103] = 37621, [104] = 37986, [105] = 38351,
+    [106] = 38716, [107] = 39082, [108] = 39447, [109] = 39812, [110] = 40177,
+    [111] = 40543, [112] = 40908, [113] = 41273, [114] = 41638, [115] = 42004,
+    [116] = 42369, [117] = 42734, [118] = 43099, [119] = 43465, [120] = 43830,
+    [121] = 44195, [122] = 44560, [123] = 44926, [124] = 45291, [125] = 45656,
+    [126] = 46021, [127] = 46387, [128] = 46752, [129] = 47117, [130] = 47482,
+    [131] = 47847, [132] = 48212, [133] = 48577, [134] = 48942, [135] = 49308,
+};
+
+int date_to_timestamp(uint8_t *buff, uint32_t *timestamp)
+{
+	uint32_t year, month, day, hour, minute, second;
+	uint32_t leap_day = 0;
+
+	year   = 1000 * (buff[ 0] - '0') + 100 * (buff[ 1] - '0') +
+	           10 * (buff[ 2] - '0') +       (buff[ 3] - '0');
+	month  =   10 * (buff[ 4] - '0') +       (buff[ 5] - '0');
+	day    =   10 * (buff[ 6] - '0') +       (buff[ 7] - '0');
+	hour   =   10 * (buff[ 8] - '0') +       (buff[ 9] - '0');
+	minute =   10 * (buff[10] - '0') +       (buff[11] - '0');
+	second =   10 * (buff[12] - '0') +       (buff[13] - '0');
+
+	if (year < 1970 || year > 2105 || month < 1 || month > 12 || day < 1) {
+		return ZSCANNER_EBAD_DATE;
+	} else {
+		year -= 1970;
+	}
+
+	if (is_leap_year[year]) {
+		if (month > 2) {
+			leap_day = 1; // Add one day in case of leap year.
+		} else if (month == 2 && day > (days_in_months[month] + 1)) {
+			return ZSCANNER_EBAD_DATE;
+		}
+	} else if (day > days_in_months[month]){
+		return ZSCANNER_EBAD_DATE;
+	}
+
+	if (hour > 23 || minute > 59 || second > 59) {
+		return ZSCANNER_EBAD_TIME;
+	}
+
+	*timestamp = hour * 3600 + minute * 60 + second +
+		     (days_across_years[year] +
+		     days_across_months[month] +
+		     day - 1 + leap_day) * 86400;
+
+	return KNOT_EOK;
+}
+
+void wire_dname_to_str(const uint8_t  *data,
+		       const uint32_t data_len,
+		       char *text)
+{
+	uint32_t i = 0, text_len = 0;
+
+	if (data == NULL || data_len == 0 || text == NULL) {
+		return;
+	}
+
+	uint8_t label_len = data[0];
+
+	// Loop over data characters.
+	for (i = 1; i < data_len; i++) {
+		// Replace label length with dot.
+		if (label_len == 0) {
+			label_len = data[i];
+			text[text_len++] = '.';
+			continue;
+		}
+
+		// Just in case use \123 notation.
+		text[text_len++] = '\\';
+		text[text_len++] = (data[i] / 100)      + ASCII_0;
+		text[text_len++] = (data[i] /  10) % 10 + ASCII_0;
+		text[text_len++] = (data[i]      ) % 10 + ASCII_0;
+
+		label_len--;
+	}
+
+	// Add trailing dot for root domain.
+	if (data_len == 1 && label_len == 0) {
+		text[text_len++] = '.';
+	}
+
+	// Ending text string.
+	text[text_len] = 0;
+}
+
+uint8_t loc64to8(uint64_t number)
+{
+	uint8_t exponent = 0;
+
+	while (number > 9) {
+		number /= 10;
+		exponent++;
+	}
+	// First 4 bits are mantisa, second 4 bits are exponent.
+	return ((uint8_t)number << 4) + (exponent & 15);
+}
+
+/*!
+ * \brief Returns domain name length in wire-format.
+ *
+ * \param data		Data array.
+ * \param data_len	Length of data array.
+ *
+ * \retval >0		if success.
+ * \retval 0		if error.
+ */
+static uint32_t get_dname_length(const uint8_t  *data,
+				 const uint32_t data_len)
+{
+	uint8_t  label_len = data[0];
+	uint32_t dname_len = 0;
+
+	while (label_len > 0) {
+		// Label overflow check.
+		if (label_len > MAX_LABEL_LENGTH) {
+			return 0;
+		}
+
+		dname_len += 1 + label_len;
+
+		// Data overflow check.
+		if (dname_len > data_len) {
+			return 0;
+		}
+
+		label_len = data[dname_len];
+        }
+
+	dname_len++; // Last label length byte.
+
+	// Dname overflow check.
+	if (dname_len <= MAX_DNAME_LENGTH) {
+		return dname_len;
+	} else {
+		return 0;
+	}
+}
+
+/*!
+ * \brief Returns length of the leading NAPTR block in wire-format.
+ *
+ * \param data		Data array.
+ * \param data_len	Length of data array.
+ *
+ * \retval >0		if success.
+ * \retval 0		if error.
+ */
+static uint32_t get_naptr_header_length(const uint8_t  *data,
+					const uint32_t data_len)
+{
+	uint32_t naptr_len = 0;
+
+	// 2B order + 2B preference.
+	naptr_len += 2 + 2;
+
+	// Flags - text string with forward 1B length.
+	naptr_len += data[naptr_len] + 1;
+
+	// Services - text string with forward 1B length.
+	naptr_len += data[naptr_len] + 1;
+
+	// Regexp - text string with forward 1B length.
+	naptr_len += data[naptr_len] + 1;
+
+	// Data overflow check.
+	if (naptr_len <= data_len) {
+		return naptr_len;
+	} else {
+		return 0;
+	}
+}
+
+/*!
+ * \brief Returns block length in wire-format.
+ *
+ * \param data		Data array.
+ * \param data_len	Length of data array.
+ * \param offset	Start of the block in data array.
+ * \param type		Record type.
+ *
+ * \retval >=0		if success.
+ * \retval <0		if error.
+ */
+static int32_t get_block_length(const uint8_t  *data,
+				const uint32_t data_len,
+				const uint32_t offset,
+				const int      type)
+{
+	uint32_t ret;
+
+	switch (type) {
+	case KNOT_RDATA_WF_COMPRESSED_DNAME:
+	case KNOT_RDATA_WF_UNCOMPRESSED_DNAME:
+	case KNOT_RDATA_WF_LITERAL_DNAME:
+		ret = get_dname_length(data + offset, data_len - offset);
+
+		if (ret > 0) {
+			return ret;
+		} else {
+			return -1;
+		}
+	case KNOT_RDATA_WF_NAPTR_HEADER:
+		ret = get_naptr_header_length(data + offset, data_len - offset);
+
+                if (ret > 0) {
+                        return ret;
+                } else {
+                        return -1;
+                }
+	case KNOT_RDATA_WF_REMAINDER:
+		return data_len - offset;
+	default:
+		return 0;
+	}
+}
+
+int find_rdata_blocks(scanner_t *s)
+{
+	uint32_t ret;
+	uint32_t position = 0;
+
+	// Initialization of block items.
+	s->r_data_blocks_count = 0;
+	s->r_data_blocks[0] = 0;
+
+	// Getting appropriate descriptor array.
+	const rdata_descriptor_t *descriptor = get_rdata_descriptor(s->r_type);
+	const int *type = descriptor->block_types;
+
+	// Loop over descriptor array.
+	while (*type != KNOT_RDATA_WF_END) {
+		if (*type > KNOT_RDATA_WF_END) {
+			position += *type;
+		} else {
+			ret = get_block_length(s->r_data,
+					       s->r_data_length,
+					       position,
+					       *type);
+			if (ret < 0) {
+				return ZSCANNER_EUNKNOWN_BLOCK;
+			}
+
+			position += ret;
+		}
+		s->r_data_blocks[++(s->r_data_blocks_count)] = position;
+		type++;
+	}
+
+	// Checking processed rdata length.
+	if (s->r_data_blocks[s->r_data_blocks_count] != s->r_data_length) {
+		return ZSCANNER_EBAD_HEX_RDATA;
+	}
+	else {
+		return KNOT_EOK;
+	}
+}
+
diff --git a/src/zscanner/scanner_functions.h b/src/zscanner/scanner_functions.h
new file mode 100644
index 0000000000000000000000000000000000000000..5d219d7143efa18cb1fffc39b202657291b9bc09
--- /dev/null
+++ b/src/zscanner/scanner_functions.h
@@ -0,0 +1,127 @@
+/*  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/>.
+ */
+/*!
+ * \file scanner_functions.h
+ *
+ * \author Daniel Salzman <daniel.salzman@nic.cz>
+ *
+ * \brief Zone scanner auxiliary functions.
+ *
+ * \addtogroup zone_scanner
+ * @{
+ */
+
+#ifndef _ZSCANNER__SCANNER_FUNCTIONS_H_
+#define _ZSCANNER__SCANNER_FUNCTIONS_H_
+
+#include <stdint.h>
+
+#include "zscanner/scanner.h"
+
+/*! \brief Transforms digit char to number. */
+extern const uint8_t digit_to_num[];
+
+/*! \brief Transforms first hex char to the part of the total number. */
+extern const uint8_t first_hex_to_num[];
+/*! \brief Transforms second hex char to the part of the total number. */
+extern const uint8_t second_hex_to_num[];
+
+/*! \brief Transforms first Base64 char. */
+extern const uint8_t first_base64_to_num[];
+/*! \brief Transforms left part of the second Base64 char. */
+extern const uint8_t second_left_base64_to_num[];
+/*! \brief Transforms left part of the second Base64 char. */
+extern const uint8_t second_right_base64_to_num[];
+/*! \brief Transforms left part of the third Base64 char. */
+extern const uint8_t third_left_base64_to_num[];
+/*! \brief Transforms left part of the third Base64 char. */
+extern const uint8_t third_right_base64_to_num[];
+/*! \brief Transforms fourth Base64 char. */
+extern const uint8_t fourth_base64_to_num[];
+
+/*! \brief Transforms first Base32hex char. */
+extern const uint8_t first_base32hex_to_num[];
+/*! \brief Transforms left part of the second Base32hex char. */
+extern const uint8_t second_left_base32hex_to_num[];
+/*! \brief Transforms right part of the second Base32hex char. */
+extern const uint8_t second_right_base32hex_to_num[];
+/*! \brief Transforms third Base32hex char. */
+extern const uint8_t third_base32hex_to_num[];
+/*! \brief Transforms left part of the fourth Base32hex char. */
+extern const uint8_t fourth_left_base32hex_to_num[];
+/*! \brief Transforms right part of the fourth Base32hex char. */
+extern const uint8_t fourth_right_base32hex_to_num[];
+/*! \brief Transforms left part of the fifth Base32hex char. */
+extern const uint8_t fifth_left_base32hex_to_num[];
+/*! \brief Transforms right part of the fifth Base32hex char. */
+extern const uint8_t fifth_right_base32hex_to_num[];
+/*! \brief Transforms sixth Base32hex char. */
+extern const uint8_t sixth_base32hex_to_num[];
+/*! \brief Transforms left part of the seventh Base32hex char. */
+extern const uint8_t seventh_left_base32hex_to_num[];
+/*! \brief Transforms right part of the seventh Base32hex char. */
+extern const uint8_t seventh_right_base32hex_to_num[];
+/*! \brief Transforms eighth Base32hex char. */
+extern const uint8_t eighth_base32hex_to_num[];
+
+/*!
+ * \brief Converts YYYYMMDDHHMMSS time string to unsigned 32-bit timestamp.
+ *
+ * \param buff		Buffer containing time string.
+ * \param timestamp	Computed timestamp.
+ *
+ * \retval KNOT_EOK	if success.
+ * \retval error_code	if error.
+ */
+int date_to_timestamp(uint8_t *buff, uint32_t *timestamp);
+
+/*!
+ * \brief Converts wire-format dname to text dname.
+ *
+ * \param data		Buffer containg wire-format dname.
+ * \param data_len	Length of the buffer.
+ * \param text		Text output.
+ */
+void wire_dname_to_str(const uint8_t  *data,
+		       const uint32_t data_len,
+		       char *text);
+
+/*!
+ * \brief Converts unsigned integer to mantisa*10^(exponent).
+ *
+ * Given number is encoded as two 4-bit numbers. First part is mantisa [0-9],
+ * second part is decimal exponent [0-15]. Result is concatenation of these
+ * two blocks.
+ *
+ * \param number	Number to convert.
+ *
+ * \retval number	encoded number.
+ */
+uint8_t loc64to8(uint64_t number);
+
+/*!
+ * \brief Finds rdata blocks according to rdata descriptors.
+ *
+ * \param s		Zone scanner.
+ *
+ * \retval KNOT_EOK	if success.
+ * \retval error_code	if error.
+ */
+int find_rdata_blocks(scanner_t *s);
+
+#endif // _ZSCANNER__SCANNER_FUNCTIONS_H_
+
+/*! @} */
diff --git a/src/zscanner/test/processing.c b/src/zscanner/test/processing.c
new file mode 100644
index 0000000000000000000000000000000000000000..05982be8ddc704a590aa4703c01f6f4090f082eb
--- /dev/null
+++ b/src/zscanner/test/processing.c
@@ -0,0 +1,204 @@
+/*  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/>.
+ */
+
+#include "zscanner/scanner_functions.h"
+
+#include <inttypes.h>			// PRIu64
+#include <stdio.h>			// printf
+#include <arpa/inet.h>			// ntohs
+
+#include "common/errcode.h"		// knot_strerror
+#include "util/descriptor.h"		// knot_rrtype_to_string
+#include "zscanner/scanner.h"		// scanner_t
+
+#define ERROR_CODE_TO_STRING(code) [code - ZSCANNER_UNCOVERED_STATE] = #code
+const char *error_names[] = {
+	ERROR_CODE_TO_STRING(ZSCANNER_UNCOVERED_STATE),
+	ERROR_CODE_TO_STRING(ZSCANNER_ELEFT_PARENTHESIS),
+	ERROR_CODE_TO_STRING(ZSCANNER_ERIGHT_PARENTHESIS),
+	ERROR_CODE_TO_STRING(ZSCANNER_EUNSUPPORTED_TYPE),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_PREVIOUS_OWNER),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_DNAME_CHAR),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_OWNER),
+	ERROR_CODE_TO_STRING(ZSCANNER_ELABEL_OVERFLOW),
+	ERROR_CODE_TO_STRING(ZSCANNER_EDNAME_OVERFLOW),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_NUMBER),
+	ERROR_CODE_TO_STRING(ZSCANNER_ENUMBER64_OVERFLOW),
+	ERROR_CODE_TO_STRING(ZSCANNER_ENUMBER32_OVERFLOW),
+	ERROR_CODE_TO_STRING(ZSCANNER_ENUMBER16_OVERFLOW),
+	ERROR_CODE_TO_STRING(ZSCANNER_ENUMBER8_OVERFLOW),
+	ERROR_CODE_TO_STRING(ZSCANNER_EFLOAT_OVERFLOW),
+	ERROR_CODE_TO_STRING(ZSCANNER_ERDATA_OVERFLOW),
+	ERROR_CODE_TO_STRING(ZSCANNER_EITEM_OVERFLOW),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_ADDRESS_CHAR),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_IPV4),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_IPV6),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_GATEWAY),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_GATEWAY_KEY),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_APL),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_RDATA),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_HEX_RDATA),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_HEX_CHAR),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_BASE64_CHAR),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_BASE32HEX_CHAR),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_REST),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_TIMESTAMP_CHAR),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_TIMESTAMP_LENGTH),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_TIMESTAMP),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_DATE),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_TIME),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_TIME_UNIT),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_BITMAP),
+	ERROR_CODE_TO_STRING(ZSCANNER_ETEXT_OVERFLOW),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_TEXT_CHAR),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_TEXT),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_DIRECTIVE),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_TTL),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_ORIGIN),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_INCLUDE_FILENAME),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_INCLUDE_ORIGIN),
+	ERROR_CODE_TO_STRING(ZSCANNER_EUNPROCESSED_INCLUDE),
+	ERROR_CODE_TO_STRING(ZSCANNER_EUNOPENED_INCLUDE),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_RDATA_LENGTH),
+	ERROR_CODE_TO_STRING(ZSCANNER_ECANNOT_TEXT_DATA),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_HEX_RDATA),
+	ERROR_CODE_TO_STRING(ZSCANNER_EBAD_LOC_DATA),
+	ERROR_CODE_TO_STRING(ZSCANNER_EUNKNOWN_BLOCK),
+};
+#define ERROR_CODE_NAME(code) error_names[code - ZSCANNER_UNCOVERED_STATE]
+
+const char *separator = "------\n";
+
+static void print_wire_dname(const uint8_t *dname, uint32_t dname_length)
+{
+	uint32_t label_length = 0, i = 0;
+
+	for (i = 0; i < dname_length; i++) {
+		if (label_length == 0) {
+			label_length = dname[i];
+			printf("(%u)", label_length);
+			continue;
+		}
+		printf("%c", (char)dname[i]);
+		label_length--;
+	}
+}
+
+void empty_process_record(const scanner_t *s) { };
+
+void empty_process_error(const scanner_t *s) { };
+
+void debug_process_error(const scanner_t *s)
+{
+	if (s->stop == true) {
+		printf("LINE(%03"PRIu64") ERROR(%s) FILE(%s) NEAR(%s)\n",
+		       s->line_counter,
+		       knot_strerror(s->error_code),
+		       s->file_name,
+		       s->buffer);
+	} else {
+		printf("LINE(%03"PRIu64") WARNING(%s) FILE(%s) NEAR(%s)\n",
+		       s->line_counter,
+		       knot_strerror(s->error_code),
+		       s->file_name,
+		       s->buffer);
+	}
+	fflush(stdout);
+}
+
+void debug_process_record(const scanner_t *s)
+{
+	uint32_t block, block_length, i;
+
+	char rclass[32];
+	char rtype[32];
+
+	knot_rrclass_to_string(s->r_class, rclass, sizeof(rclass));
+	knot_rrtype_to_string(s->r_type, rtype, sizeof(rtype));
+
+	printf("LINE(%03"PRIu64") %s %u %*s ",
+	       s->line_counter, rclass, s->r_ttl, 5, rtype);
+
+	print_wire_dname(s->r_owner, s->r_owner_length);
+
+	printf("  #%u/%uB:", s->r_data_blocks_count, s->r_data_length);
+
+	for (block = 1; block <= s->r_data_blocks_count; block++) {
+		block_length =
+			s->r_data_blocks[block] - s->r_data_blocks[block - 1];
+		printf(" (%u)", block_length);
+
+		for (i = s->r_data_blocks[block - 1];
+		     i < s->r_data_blocks[block];
+		     i++) {
+			printf("%02X", (s->r_data)[i]);
+		}
+	}
+	printf("\n");
+	fflush(stdout);
+}
+
+void test_process_error(const scanner_t *s)
+{
+	if (s->stop == true) {
+		printf("ERROR=%s\n%s", ERROR_CODE_NAME(s->error_code), separator);
+	} else {
+		printf("WARNG=%s\n%s", ERROR_CODE_NAME(s->error_code), separator);
+	}
+	fflush(stdout);
+}
+
+void test_process_record(const scanner_t *s)
+{
+	uint32_t block, i;
+
+	printf("OWNER=");
+	for (i = 0; i < s->r_owner_length; i++) {
+		printf("%02x", s->r_owner[i]);
+	}
+	printf("\n");
+	printf("CLASS=%04X\n", s->r_class);
+	printf("RRTTL=%08X\n", s->r_ttl);
+	printf("RTYPE=%04X\n", s->r_type);
+	printf("RDATA=");
+	for (block = 1; block <= s->r_data_blocks_count; block++) {
+		if (block > 1) {
+			printf(" ");
+		}
+
+		for (i = s->r_data_blocks[block - 1];
+		     i < s->r_data_blocks[block];
+		     i++) {
+			printf("%02X", (s->r_data)[i]);
+		}
+	}
+	printf("\n%s", separator);
+	fflush(stdout);
+}
+
+void dump_rdata(const scanner_t *s)
+{
+	uint32_t block, i;
+
+	for (block = 1; block <= s->r_data_blocks_count; block++) {
+		for (i = s->r_data_blocks[block - 1];
+		     i < s->r_data_blocks[block];
+		     i++) {
+			printf("%c", (s->r_data)[i]);
+		}
+	}
+}
+
diff --git a/src/zscanner/test/processing.h b/src/zscanner/test/processing.h
new file mode 100644
index 0000000000000000000000000000000000000000..312a893c332e41ed4b231ad35ea82f7af4c6ba88
--- /dev/null
+++ b/src/zscanner/test/processing.h
@@ -0,0 +1,48 @@
+/*  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/>.
+ */
+/*!
+ * \file test_functions.h
+ *
+ * \author Daniel Salzman <daniel.salzman@nic.cz>
+ *
+ * \brief Zone scanner test functions.
+ *
+ * \addtogroup zone_scanner_test
+ * @{
+ */
+
+#ifndef _ZSCANNER__TEST_FUNCTIONS_H_
+#define _ZSCANNER__TEST_FUNCTIONS_H_
+
+#include "zscanner/scanner.h"
+
+void empty_process_record(const scanner_t *scanner);
+
+void empty_process_error(const scanner_t *scanner);
+
+void debug_process_error(const scanner_t *scanner);
+
+void debug_process_record(const scanner_t *scanner);
+
+void test_process_error(const scanner_t *scanner);
+
+void test_process_record(const scanner_t *scanner);
+
+void dump_rdata(const scanner_t *scanner);
+
+#endif // _ZSCANNER__TEST_FUNCTIONS_H_
+
+/*! @} */
diff --git a/src/zscanner/test/run_tests.sh b/src/zscanner/test/run_tests.sh
new file mode 100755
index 0000000000000000000000000000000000000000..9d8ac86edcf2077687fb1d516f528dccb21ed328
--- /dev/null
+++ b/src/zscanner/test/run_tests.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+TESTS_DIR="./tests"
+OUTS_DIR="/tmp/zscanner_tests"
+TEST_BIN="../../unittests-zscanner -m 2"
+
+SEPARATION="========================================================="
+
+mkdir -p ${OUTS_DIR}/${TESTS_DIR}
+cp -r ${TESTS_DIR}/includes ${OUTS_DIR}
+
+echo ${SEPARATION}
+
+for file in `find ${TESTS_DIR} -name "*.in" | sort`; do
+	fileout=`echo "${file}" | sed 's/.in/.out/'`
+	${TEST_BIN} . ${file} > ${OUTS_DIR}/${fileout}
+	echo ${fileout}
+	diff ${OUTS_DIR}/${fileout} ${fileout}
+	echo ${SEPARATION}
+done
diff --git a/src/zscanner/test/tests.c b/src/zscanner/test/tests.c
new file mode 100644
index 0000000000000000000000000000000000000000..4bc1dfcf1a7a4e4e3b2c22c110785a693b121165
--- /dev/null
+++ b/src/zscanner/test/tests.c
@@ -0,0 +1,74 @@
+/*  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/>.
+ */
+
+#include "zscanner/test/tests.h"
+
+#include <inttypes.h>			// PRIu64
+#include <stdio.h>			// printf
+#include <time.h>			// mktime
+#include <stdlib.h>			// printf
+#include "../scanner_functions.h"	// date_to_timestamp
+
+int test__date_to_timestamp()
+{
+	time_t    ref_timestamp, max_timestamp;
+	uint32_t  test_timestamp;
+	uint8_t   buffer[16];
+	struct tm tm;
+
+	// Set UTC for strftime.
+	putenv("TZ=UTC");
+	tzset();
+
+	// Get maximal allowed timestamp.
+	strptime("21051231235959", "%Y%m%d%H%M%S", &tm);
+	max_timestamp = mktime(&tm);
+
+	// Testing loop over whole input interval.
+	for (ref_timestamp = 0;
+	     ref_timestamp < max_timestamp;
+	     ref_timestamp += 30) {
+		// Get reference (correct) timestamp.
+		strftime((char*)buffer, sizeof(buffer), "%Y%m%d%H%M%S",
+			 gmtime(&ref_timestamp));
+
+		// Get testing timestamp.
+		date_to_timestamp(buffer, &test_timestamp);
+
+		// Some continuous loging.
+		if (ref_timestamp % 10000000 == 0) {
+			printf("%s = %"PRIu64"\n", buffer, ref_timestamp);
+		}
+
+		// Comparing results.
+		if (ref_timestamp != test_timestamp) {
+			if (ref_timestamp > test_timestamp) { 
+				printf("%s = %"PRIu64", in - out = %"PRIu64"\n",
+				       buffer, ref_timestamp,
+				       ref_timestamp - test_timestamp);
+			} else {
+				printf("%s = %"PRIu64", out - in = %"PRIu64"\n",
+				       buffer, ref_timestamp,
+				       test_timestamp - ref_timestamp);
+			}
+
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
diff --git a/src/zscanner/test/tests.h b/src/zscanner/test/tests.h
new file mode 100644
index 0000000000000000000000000000000000000000..ab5f42637462ff6ffc7ab82e9a7984229ac0e1bf
--- /dev/null
+++ b/src/zscanner/test/tests.h
@@ -0,0 +1,34 @@
+/*  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/>.
+ */
+/*!
+ * \file tests.h
+ *
+ * \author Daniel Salzman <daniel.salzman@nic.cz>
+ *
+ * \brief Zone scanner test functions.
+ *
+ * \addtogroup zone_scanner_test
+ * @{
+ */
+
+#ifndef _ZSCANNER__TESTS_H_
+#define _ZSCANNER__TESTS_H_
+
+int test__date_to_timestamp();
+
+#endif // _ZSCANNER__TESTS_H_
+
+/*! @} */
diff --git a/src/zscanner/test/tests/00_general.in b/src/zscanner/test/tests/00_general.in
new file mode 100644
index 0000000000000000000000000000000000000000..4946599f39ae5b41b484631323348921c5563401
--- /dev/null
+++ b/src/zscanner/test/tests/00_general.in
@@ -0,0 +1,24 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+t01	IN	10	NS	@	; All items are mentioned
+	IN	10	NS	@	; Same as above without OWNER
+t02	20	IN	NS	@	; Switched CLASS and TTL
+	20	IN	NS	@	; Same as above without OWNER
+t03		30	NS	@	; Missing CLASS
+		30	NS	@	; Same as above without OWNER
+t04	IN		NS	@	; Missing TTL
+	IN		NS	@	; Same as above without OWNER
+t05			NS	@	; Missing CLASS and TTL
+			NS	@	; Same as above without OWNER
+
+@	( )		NS	(	; Multiline 1/5
+	)	()	(		; Multiline 2/5
+
+				@	; Multiline 4/5
+		)	( 
+)					; Multiline 6/6
+
+; KO
+@			NS ((@))	; Nested parentheses - ERROR = STOP PROCESSING!
diff --git a/src/zscanner/test/tests/00_general.out b/src/zscanner/test/tests/00_general.out
new file mode 100644
index 0000000000000000000000000000000000000000..c9c6a43e44fa722ad70e8019a68106578dc93cdb
--- /dev/null
+++ b/src/zscanner/test/tests/00_general.out
@@ -0,0 +1,68 @@
+OWNER=0374303100
+CLASS=0001
+RRTTL=0000000A
+RTYPE=0002
+RDATA=00
+------
+OWNER=0374303100
+CLASS=0001
+RRTTL=0000000A
+RTYPE=0002
+RDATA=00
+------
+OWNER=0374303200
+CLASS=0001
+RRTTL=00000014
+RTYPE=0002
+RDATA=00
+------
+OWNER=0374303200
+CLASS=0001
+RRTTL=00000014
+RTYPE=0002
+RDATA=00
+------
+OWNER=0374303300
+CLASS=0001
+RRTTL=0000001E
+RTYPE=0002
+RDATA=00
+------
+OWNER=0374303300
+CLASS=0001
+RRTTL=0000001E
+RTYPE=0002
+RDATA=00
+------
+OWNER=0374303400
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=0374303400
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=0374303500
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=0374303500
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+ERROR=ZSCANNER_ELEFT_PARENTHESIS
+------
diff --git a/src/zscanner/test/tests/01_owner.in b/src/zscanner/test/tests/01_owner.in
new file mode 100644
index 0000000000000000000000000000000000000000..a749b5171e8b3e5d3d8c057a25cb32ec371d23fe
--- /dev/null
+++ b/src/zscanner/test/tests/01_owner.in
@@ -0,0 +1,34 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+.		NS	@	; The simplest owner
+tld.		NS	@	; FQD tld owner
+tld		NS	@	; Relative form
+		NS	@	; The previous owner
+*.		NS	@	; FQD with asterisk
+*		NS	@	; Alone asterisk
+*.*		NS	@	; More asterisks
+@		NS	@	; Use origin
+0123456789	NS	@	; Digits
+_a_.-b-c-./d/.	NS	@	; Allowed characters '_' '-' '/' anywhere
+ABCDEFGHIJKLMNOPQRSTUVWXYZ	NS	@	; All upper-case letters
+abcdefghijklmnopqrstuvwxyz	NS	@	; All lower-case letters
+\0320\ \\\"\.\@\*.tld.		NS	@	; Label with special chars
+b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.	NS	@	; IPv6 reverse
+12345678901234567890123456789012345678901234567890123456789012\051.tld.		NS	@	; Label of maximal length
+123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.	NS	@	; Domain name of maximal length
+123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901	NS	@	; Domain name of maximal length (after appending origin)
+
+; KO
+&	NS	@	; Bad (unslashed) character
+a*a	NS	@	; * char can substitute whole label only
+	NS	@	; Bad previous
+.a	NS	@	; Leading dot
+@@	NS	@	; Double @@
+..	NS	@	; Missing label between dots
+\1	NS	@	; Slash notation requires 3 digits
+\12	NS	@	; Slash notation requires 3 digits
+12345678901234567890123456789012345678901234567890123456789012\0514.tld.	NS	@	; Label exceeded maximal length
+123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012.	NS	@	; Domain name exceeded maximal length
+123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012	NS	@	; Domain name exceeded maximal length (after appending origin)
diff --git a/src/zscanner/test/tests/01_owner.out b/src/zscanner/test/tests/01_owner.out
new file mode 100644
index 0000000000000000000000000000000000000000..99d93bb66aa4961ed1396a234311f3558ec9a838
--- /dev/null
+++ b/src/zscanner/test/tests/01_owner.out
@@ -0,0 +1,124 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=03746c6400
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=03746c6400
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=03746c6400
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=012a00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=012a00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=012a012a00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=0a3031323334353637383900
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=035f615f052d622d632d032f642f00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=1a4142434445464748494a4b4c4d4e4f505152535455565758595a00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=1a6162636465666768696a6b6c6d6e6f707172737475767778797a00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=082030205c222e402a03746c6400
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=0162016101390138013701360135013001300130013001300130013001300130013001300130013001300130013001300138016201640130013101300130013203697036046172706100
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=3f31323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323303746c6400
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=3f3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333f3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333f3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333d3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303100
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=3f3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333f3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333f3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333d3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303100
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+WARNG=ZSCANNER_EBAD_OWNER
+------
+WARNG=ZSCANNER_EBAD_DNAME_CHAR
+------
+WARNG=ZSCANNER_EBAD_PREVIOUS_OWNER
+------
+WARNG=ZSCANNER_EBAD_DNAME_CHAR
+------
+WARNG=ZSCANNER_EBAD_DNAME_CHAR
+------
+WARNG=ZSCANNER_EBAD_DNAME_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_ELABEL_OVERFLOW
+------
+WARNG=ZSCANNER_EDNAME_OVERFLOW
+------
+WARNG=ZSCANNER_EDNAME_OVERFLOW
+------
diff --git a/src/zscanner/test/tests/02_class.in b/src/zscanner/test/tests/02_class.in
new file mode 100644
index 0000000000000000000000000000000000000000..c4347e710c2b0c5c576af0f7143672e7216ac8d2
--- /dev/null
+++ b/src/zscanner/test/tests/02_class.in
@@ -0,0 +1,10 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	IN	NS	@	; The only accepted class IN
+@	in	NS	@	; Class in lower-case
+
+; KO
+@	CH	NS	@	; Unsupported class
+@	CLASS1	NS	@	; Unsupported notation
diff --git a/src/zscanner/test/tests/02_class.out b/src/zscanner/test/tests/02_class.out
new file mode 100644
index 0000000000000000000000000000000000000000..6002cc3f4576cd53474076481944e326dbe7f09c
--- /dev/null
+++ b/src/zscanner/test/tests/02_class.out
@@ -0,0 +1,16 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+WARNG=ZSCANNER_EUNSUPPORTED_TYPE
+------
+WARNG=ZSCANNER_EUNSUPPORTED_TYPE
+------
diff --git a/src/zscanner/test/tests/03_rrttl.in b/src/zscanner/test/tests/03_rrttl.in
new file mode 100644
index 0000000000000000000000000000000000000000..7c57d734b646b1e3ec89696c7aa3460c8b5eea1f
--- /dev/null
+++ b/src/zscanner/test/tests/03_rrttl.in
@@ -0,0 +1,26 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	0		NS	@	; Minimal ttl
+@	3600		NS	@	; Inner value
+@	4294967295	NS	@	; Maximal ttl
+@	1S		NS	@	; 1 second (upper-case)
+@	1s		NS	@	; 1 second (lower-case)
+@	1M		NS	@	; 1 minute (upper-case)
+@	1m		NS	@	; 1 minute (lower-case)
+@	1H		NS	@	; 1 hour (upper-case)
+@	1h		NS	@	; 1 hour (lower-case)
+@	1D		NS	@	; 1 day (upper-case)
+@	1d		NS	@	; 1 day (lower-case)
+@	1W		NS	@	; 1 week (upper-case)
+@	1w		NS	@	; 1 week (lower-case)
+@	1w1d1h1m1s	NS	@	; More time units
+@	1s1m1m		NS	@	; Same time units, non decreasing order
+
+; KO
+@	-1		NS	@	; Negative ttl
+@	4294967296	NS	@	; 32bit overflow
+@	100000000W	NS	@	; 32bit overflow
+@	4294967295s1w	NS	@	; 32bit overflow
+@	1x		NS	@	; Unknown time unit
diff --git a/src/zscanner/test/tests/03_rrttl.out b/src/zscanner/test/tests/03_rrttl.out
new file mode 100644
index 0000000000000000000000000000000000000000..bdc0b6e357d124f7f8505fc171e0f61bf72d9ea8
--- /dev/null
+++ b/src/zscanner/test/tests/03_rrttl.out
@@ -0,0 +1,100 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000000
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000E10
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=FFFFFFFF
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=0000003C
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=0000003C
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000E10
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000E10
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00015180
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00015180
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00093A80
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00093A80
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=000A9A4D
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000079
+RTYPE=0002
+RDATA=00
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_ENUMBER32_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER32_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER32_OVERFLOW
+------
+WARNG=ZSCANNER_EBAD_TIME_UNIT
+------
diff --git a/src/zscanner/test/tests/04-0_ORIGIN.in b/src/zscanner/test/tests/04-0_ORIGIN.in
new file mode 100644
index 0000000000000000000000000000000000000000..4d65ec4a51a86d49f1c8bd70dd49a5477847629b
--- /dev/null
+++ b/src/zscanner/test/tests/04-0_ORIGIN.in
@@ -0,0 +1,29 @@
+$TTL	1
+
+; OK
+$ORIGIN .		; Root domain
+@	NS	@	; Use origin
+a.	NS	@	; Absolute dname
+a	NS	@	; Relative dname
+$ORIGIN tld.		; 1. level domain
+@	NS	@	; Use origin
+a.	NS	@	; Absolute dname
+a	NS	@	; Relative dname
+$ORIGIN second.tld.	; 2. level domain
+@	NS	@	; Use origin
+a.	NS	@	; Absolute dname
+a	NS	@	; Relative dname
+$ORIGIN \0320\ \\\"\.\@\*.tld.	; Label with special chars
+@	NS	@	; Use origin
+$ORIGIN b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.	; IPv6 reverse
+@	NS	@	; Use origin
+$ORIGIN 12345678901234567890123456789012345678901234567890123456789012\051.tld.		; Label of maximal length
+@	NS	@	; Use origin
+$ORIGIN 123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.	; Domain name of maximal length
+@	NS	@	; Use origin
+$origin .		; Lower-case
+@	NS	@	; Use origin
+
+; KO
+$ORIGIN 		; Empty input
+.	NS	.	; Is OK, but shouldn't be processed due to previous error stop!
diff --git a/src/zscanner/test/tests/04-0_ORIGIN.out b/src/zscanner/test/tests/04-0_ORIGIN.out
new file mode 100644
index 0000000000000000000000000000000000000000..48bda7962b0c8c0ca7ba64225282581d6a18daa1
--- /dev/null
+++ b/src/zscanner/test/tests/04-0_ORIGIN.out
@@ -0,0 +1,86 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=016100
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=016100
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=03746c6400
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=03746C6400
+------
+OWNER=016100
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=03746C6400
+------
+OWNER=016103746c6400
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=03746C6400
+------
+OWNER=067365636f6e6403746c6400
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=067365636F6E6403746C6400
+------
+OWNER=016100
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=067365636F6E6403746C6400
+------
+OWNER=0161067365636f6e6403746c6400
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=067365636F6E6403746C6400
+------
+OWNER=082030205c222e402a03746c6400
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=082030205C222E402A03746C6400
+------
+OWNER=0162016101390138013701360135013001300130013001300130013001300130013001300130013001300130013001300138016201640130013101300130013203697036046172706100
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=0162016101390138013701360135013001300130013001300130013001300130013001300130013001300130013001300138016201640130013101300130013203697036046172706100
+------
+OWNER=3f31323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323303746c6400
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=3F31323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323303746C6400
+------
+OWNER=3f3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333f3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333f3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333d3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303100
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=3F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333D3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303100
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+ERROR=ZSCANNER_EBAD_ORIGIN
+------
diff --git a/src/zscanner/test/tests/04-1_ORIGIN.in b/src/zscanner/test/tests/04-1_ORIGIN.in
new file mode 100644
index 0000000000000000000000000000000000000000..871c0645e4b24c8642391dea5a6083e0f7f4cc03
--- /dev/null
+++ b/src/zscanner/test/tests/04-1_ORIGIN.in
@@ -0,0 +1,4 @@
+$TTL	1
+
+; KO
+$ORIGIN tld		; Not FQD
diff --git a/src/zscanner/test/tests/04-1_ORIGIN.out b/src/zscanner/test/tests/04-1_ORIGIN.out
new file mode 100644
index 0000000000000000000000000000000000000000..43d27c37a7f30d712df536ff1455b03582bb349d
--- /dev/null
+++ b/src/zscanner/test/tests/04-1_ORIGIN.out
@@ -0,0 +1,2 @@
+ERROR=ZSCANNER_EBAD_ORIGIN
+------
diff --git a/src/zscanner/test/tests/04-2_ORIGIN.in b/src/zscanner/test/tests/04-2_ORIGIN.in
new file mode 100644
index 0000000000000000000000000000000000000000..8dd2e20261c1b5ce5e97690ad5ff25b2e9364e01
--- /dev/null
+++ b/src/zscanner/test/tests/04-2_ORIGIN.in
@@ -0,0 +1,4 @@
+$TTL	1
+
+; KO
+$ORIGIN %		; Bad (unslashed) character
diff --git a/src/zscanner/test/tests/04-2_ORIGIN.out b/src/zscanner/test/tests/04-2_ORIGIN.out
new file mode 100644
index 0000000000000000000000000000000000000000..43d27c37a7f30d712df536ff1455b03582bb349d
--- /dev/null
+++ b/src/zscanner/test/tests/04-2_ORIGIN.out
@@ -0,0 +1,2 @@
+ERROR=ZSCANNER_EBAD_ORIGIN
+------
diff --git a/src/zscanner/test/tests/04-3_ORIGIN.in b/src/zscanner/test/tests/04-3_ORIGIN.in
new file mode 100644
index 0000000000000000000000000000000000000000..26d187269cfb5eb8e1b76a833dd96f0ac724f0ac
--- /dev/null
+++ b/src/zscanner/test/tests/04-3_ORIGIN.in
@@ -0,0 +1,4 @@
+$TTL	1
+
+; KO
+$ORIGIN ..		; Missing label between dots
diff --git a/src/zscanner/test/tests/04-3_ORIGIN.out b/src/zscanner/test/tests/04-3_ORIGIN.out
new file mode 100644
index 0000000000000000000000000000000000000000..16950a81d61f451a546bffb38c7e866ba13c1585
--- /dev/null
+++ b/src/zscanner/test/tests/04-3_ORIGIN.out
@@ -0,0 +1,2 @@
+ERROR=ZSCANNER_EBAD_REST
+------
diff --git a/src/zscanner/test/tests/04-4_ORIGIN.in b/src/zscanner/test/tests/04-4_ORIGIN.in
new file mode 100644
index 0000000000000000000000000000000000000000..0be4721ff461bf402435b7e0936dcf602cf6e63b
--- /dev/null
+++ b/src/zscanner/test/tests/04-4_ORIGIN.in
@@ -0,0 +1,4 @@
+$TTL	1
+
+; KO
+$ORIGIN \1		; Slash notation requires 3 digits
diff --git a/src/zscanner/test/tests/04-4_ORIGIN.out b/src/zscanner/test/tests/04-4_ORIGIN.out
new file mode 100644
index 0000000000000000000000000000000000000000..f30b92943b61d5a6b0809852b8cf1e8c71517835
--- /dev/null
+++ b/src/zscanner/test/tests/04-4_ORIGIN.out
@@ -0,0 +1,2 @@
+ERROR=ZSCANNER_EBAD_NUMBER
+------
diff --git a/src/zscanner/test/tests/04-5_ORIGIN.in b/src/zscanner/test/tests/04-5_ORIGIN.in
new file mode 100644
index 0000000000000000000000000000000000000000..170d465f85c09d75602d2f754626eccd6a007c95
--- /dev/null
+++ b/src/zscanner/test/tests/04-5_ORIGIN.in
@@ -0,0 +1,4 @@
+$TTL	1
+
+; KO
+$ORIGIN \12		; Slash notation requires 3 digits
diff --git a/src/zscanner/test/tests/04-5_ORIGIN.out b/src/zscanner/test/tests/04-5_ORIGIN.out
new file mode 100644
index 0000000000000000000000000000000000000000..f30b92943b61d5a6b0809852b8cf1e8c71517835
--- /dev/null
+++ b/src/zscanner/test/tests/04-5_ORIGIN.out
@@ -0,0 +1,2 @@
+ERROR=ZSCANNER_EBAD_NUMBER
+------
diff --git a/src/zscanner/test/tests/04-6_ORIGIN.in b/src/zscanner/test/tests/04-6_ORIGIN.in
new file mode 100644
index 0000000000000000000000000000000000000000..db9652d8b6871d52400150a60f0a95dd991e23a2
--- /dev/null
+++ b/src/zscanner/test/tests/04-6_ORIGIN.in
@@ -0,0 +1,4 @@
+$TTL	1
+
+; KO
+$ORIGIN .tld		; Leading dot
diff --git a/src/zscanner/test/tests/04-6_ORIGIN.out b/src/zscanner/test/tests/04-6_ORIGIN.out
new file mode 100644
index 0000000000000000000000000000000000000000..16950a81d61f451a546bffb38c7e866ba13c1585
--- /dev/null
+++ b/src/zscanner/test/tests/04-6_ORIGIN.out
@@ -0,0 +1,2 @@
+ERROR=ZSCANNER_EBAD_REST
+------
diff --git a/src/zscanner/test/tests/04-7_ORIGIN.in b/src/zscanner/test/tests/04-7_ORIGIN.in
new file mode 100644
index 0000000000000000000000000000000000000000..556646c85573dd63e92e482067bff1a1feebd1e5
--- /dev/null
+++ b/src/zscanner/test/tests/04-7_ORIGIN.in
@@ -0,0 +1,4 @@
+$TTL	1
+
+; KO
+$ORIGIN tld. x		; Unexpected item
diff --git a/src/zscanner/test/tests/04-7_ORIGIN.out b/src/zscanner/test/tests/04-7_ORIGIN.out
new file mode 100644
index 0000000000000000000000000000000000000000..16950a81d61f451a546bffb38c7e866ba13c1585
--- /dev/null
+++ b/src/zscanner/test/tests/04-7_ORIGIN.out
@@ -0,0 +1,2 @@
+ERROR=ZSCANNER_EBAD_REST
+------
diff --git a/src/zscanner/test/tests/04-8_ORIGIN.in b/src/zscanner/test/tests/04-8_ORIGIN.in
new file mode 100644
index 0000000000000000000000000000000000000000..445cbec7d56394a6650b40671041b924103a7411
--- /dev/null
+++ b/src/zscanner/test/tests/04-8_ORIGIN.in
@@ -0,0 +1,4 @@
+$TTL	1
+
+; KO
+$ORIGIN 12345678901234567890123456789012345678901234567890123456789012\0514.tld.	; Label exceeded maximal length
diff --git a/src/zscanner/test/tests/04-8_ORIGIN.out b/src/zscanner/test/tests/04-8_ORIGIN.out
new file mode 100644
index 0000000000000000000000000000000000000000..ee4139a93e4fd37ed32e56257c776dc633df8b5c
--- /dev/null
+++ b/src/zscanner/test/tests/04-8_ORIGIN.out
@@ -0,0 +1,2 @@
+ERROR=ZSCANNER_ELABEL_OVERFLOW
+------
diff --git a/src/zscanner/test/tests/04-9_ORIGIN.in b/src/zscanner/test/tests/04-9_ORIGIN.in
new file mode 100644
index 0000000000000000000000000000000000000000..e0a4b95827258da7398d5c2263b4bfb40c35649f
--- /dev/null
+++ b/src/zscanner/test/tests/04-9_ORIGIN.in
@@ -0,0 +1,4 @@
+$TTL	1
+
+; KO
+$ORIGIN 123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012.	; Domain name exceeded maximal length
diff --git a/src/zscanner/test/tests/04-9_ORIGIN.out b/src/zscanner/test/tests/04-9_ORIGIN.out
new file mode 100644
index 0000000000000000000000000000000000000000..2ed0a4c1ad533f763fd79006e41bcdcc566b8d42
--- /dev/null
+++ b/src/zscanner/test/tests/04-9_ORIGIN.out
@@ -0,0 +1,2 @@
+ERROR=ZSCANNER_EDNAME_OVERFLOW
+------
diff --git a/src/zscanner/test/tests/05-0_TTL.in b/src/zscanner/test/tests/05-0_TTL.in
new file mode 100644
index 0000000000000000000000000000000000000000..baa8f38d2c6e88b4aa6db396909ac9091a82efdb
--- /dev/null
+++ b/src/zscanner/test/tests/05-0_TTL.in
@@ -0,0 +1,36 @@
+$ORIGIN	.
+
+; OK
+$TTL	0		; Minimal ttl
+@	NS	@	; Use ttl
+$TTL	3600		; Inner value
+@	NS	@	; Use ttl
+$TTL	4294967295	; Maximal ttl
+@	NS	@	; Use ttl
+$TTL	1S		; 1 second (upper-case)
+@	NS	@	; Use ttl
+$TTL	1s		; 1 second (lower-case)
+@	NS	@	; Use ttl
+$TTL	1M		; 1 minute (upper-case)
+@	NS	@	; Use ttl
+$TTL	1m		; 1 minute (lower-case)
+@	NS	@	; Use ttl
+$TTL	1H		; 1 hour (upper-case)
+@	NS	@	; Use ttl
+$TTL	1h		; 1 hour (lower-case)
+@	NS	@	; Use ttl
+$TTL	1D		; 1 day (upper-case)
+@	NS	@	; Use ttl
+$TTL	1d		; 1 day (lower-case)
+@	NS	@	; Use ttl
+$TTL	1W		; 1 week (upper-case)
+@	NS	@	; Use ttl
+$TTL	1w		; 1 week (lower-case)
+@	NS	@	; Use ttl
+$TTL	1w1d1h1m1s	; More time units
+@	NS	@	; Use ttl
+$TTL	1s1m1m		; Same time units, non decreasing order
+@	NS	@	; Use ttl
+
+; KO
+$TTL	-1		; Negative ttl
diff --git a/src/zscanner/test/tests/05-0_TTL.out b/src/zscanner/test/tests/05-0_TTL.out
new file mode 100644
index 0000000000000000000000000000000000000000..5e87bb03917ccf3f268f8d56ac1b4df9afe79e6b
--- /dev/null
+++ b/src/zscanner/test/tests/05-0_TTL.out
@@ -0,0 +1,92 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000000
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000E10
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=FFFFFFFF
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=0000003C
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=0000003C
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000E10
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000E10
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00015180
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00015180
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00093A80
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00093A80
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=000A9A4D
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000079
+RTYPE=0002
+RDATA=00
+------
+ERROR=ZSCANNER_EBAD_NUMBER
+------
diff --git a/src/zscanner/test/tests/05-1_TTL.in b/src/zscanner/test/tests/05-1_TTL.in
new file mode 100644
index 0000000000000000000000000000000000000000..519fe79cc8ad072352b78365de2e8601c322e22e
--- /dev/null
+++ b/src/zscanner/test/tests/05-1_TTL.in
@@ -0,0 +1,4 @@
+$ORIGIN	.
+
+; KO
+$TTL	4294967296	; 32bit overflow
diff --git a/src/zscanner/test/tests/05-1_TTL.out b/src/zscanner/test/tests/05-1_TTL.out
new file mode 100644
index 0000000000000000000000000000000000000000..bbdc638fcdae7b2cf387b4b4970424daaf8d1bdb
--- /dev/null
+++ b/src/zscanner/test/tests/05-1_TTL.out
@@ -0,0 +1,2 @@
+ERROR=ZSCANNER_ENUMBER32_OVERFLOW
+------
diff --git a/src/zscanner/test/tests/05-2_TTL.in b/src/zscanner/test/tests/05-2_TTL.in
new file mode 100644
index 0000000000000000000000000000000000000000..ed112daa4de61a2d1413a0b14474f6bef62f650c
--- /dev/null
+++ b/src/zscanner/test/tests/05-2_TTL.in
@@ -0,0 +1,4 @@
+$ORIGIN	.
+
+; KO
+$TTL	100000000W	; 32bit overflow
diff --git a/src/zscanner/test/tests/05-2_TTL.out b/src/zscanner/test/tests/05-2_TTL.out
new file mode 100644
index 0000000000000000000000000000000000000000..bbdc638fcdae7b2cf387b4b4970424daaf8d1bdb
--- /dev/null
+++ b/src/zscanner/test/tests/05-2_TTL.out
@@ -0,0 +1,2 @@
+ERROR=ZSCANNER_ENUMBER32_OVERFLOW
+------
diff --git a/src/zscanner/test/tests/05-3_TTL.in b/src/zscanner/test/tests/05-3_TTL.in
new file mode 100644
index 0000000000000000000000000000000000000000..d96c9ba7c09150dc972ecb264cf210069ffe34c6
--- /dev/null
+++ b/src/zscanner/test/tests/05-3_TTL.in
@@ -0,0 +1,4 @@
+$ORIGIN	.
+
+; KO
+$TTL	4294967295s1w	; 32bit overflow
diff --git a/src/zscanner/test/tests/05-3_TTL.out b/src/zscanner/test/tests/05-3_TTL.out
new file mode 100644
index 0000000000000000000000000000000000000000..bbdc638fcdae7b2cf387b4b4970424daaf8d1bdb
--- /dev/null
+++ b/src/zscanner/test/tests/05-3_TTL.out
@@ -0,0 +1,2 @@
+ERROR=ZSCANNER_ENUMBER32_OVERFLOW
+------
diff --git a/src/zscanner/test/tests/05-4_TTL.in b/src/zscanner/test/tests/05-4_TTL.in
new file mode 100644
index 0000000000000000000000000000000000000000..efaf4d0f5d8a27aca8d461b53c75faf5bcfddd55
--- /dev/null
+++ b/src/zscanner/test/tests/05-4_TTL.in
@@ -0,0 +1,4 @@
+$ORIGIN	.
+
+; KO
+$TTL	1x		; Unknown time unit
diff --git a/src/zscanner/test/tests/05-4_TTL.out b/src/zscanner/test/tests/05-4_TTL.out
new file mode 100644
index 0000000000000000000000000000000000000000..d0a0c651b0af2d365ccd674867cb22f935009468
--- /dev/null
+++ b/src/zscanner/test/tests/05-4_TTL.out
@@ -0,0 +1,2 @@
+ERROR=ZSCANNER_EBAD_TIME_UNIT
+------
diff --git a/src/zscanner/test/tests/06-0_INCLUDE.in b/src/zscanner/test/tests/06-0_INCLUDE.in
new file mode 100644
index 0000000000000000000000000000000000000000..4641ae1654f00e744df3d9c40eacdda50d8f4165
--- /dev/null
+++ b/src/zscanner/test/tests/06-0_INCLUDE.in
@@ -0,0 +1,30 @@
+$ORIGIN .
+$TTL	1
+
+; OK
+0.	NS	@
+
+$INCLUDE ./includes/include1				; Relative path without origin
+1.	NS	@
+
+$INCLUDE "./includes/include2"	.			; Quoted filename and the simplest origin
+2.	NS	@
+
+$INCLUDE ./includes/include\050	tld.			; Simple origin
+3.	NS	@
+
+$INCLUDE \./includes/include2	_a_.-b-c-./d/.		; Slashed character in file name, allowed characters in origin
+4.	NS	@
+
+$INCLUDE ./includes/include2	\0320\ \\\"\.\@\*.tld.	; Origin with special chars
+5.	NS	@
+
+$INCLUDE /tmp/zscanner_tests/includes/include2		; Absolute path without origin
+6.	NS	@
+
+$INCLUDE /tmp/zscanner_tests/includes/include2	tld.	; Absolute path with origin
+7.	NS	@
+
+; KO
+$INCLUDE						; Empty parameters
+
diff --git a/src/zscanner/test/tests/06-0_INCLUDE.out b/src/zscanner/test/tests/06-0_INCLUDE.out
new file mode 100644
index 0000000000000000000000000000000000000000..44ef30edd00520bc86246c3944dba121f984967d
--- /dev/null
+++ b/src/zscanner/test/tests/06-0_INCLUDE.out
@@ -0,0 +1,140 @@
+OWNER=013000
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=016100
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=016105746c64316100
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=05746C64316100
+------
+OWNER=016105746c64316200
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=05746C64316200
+------
+OWNER=013100
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=016200
+CLASS=0001
+RRTTL=00000E10
+RTYPE=0002
+RDATA=00
+------
+OWNER=016205746c64316100
+CLASS=0001
+RRTTL=00000E10
+RTYPE=0002
+RDATA=05746C64316100
+------
+OWNER=013200
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=016203746c6400
+CLASS=0001
+RRTTL=00000E10
+RTYPE=0002
+RDATA=03746C6400
+------
+OWNER=016205746c64316100
+CLASS=0001
+RRTTL=00000E10
+RTYPE=0002
+RDATA=05746C64316100
+------
+OWNER=013300
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=0162035f615f052d622d632d032f642f00
+CLASS=0001
+RRTTL=00000E10
+RTYPE=0002
+RDATA=035F615F052D622D632D032F642F00
+------
+OWNER=016205746c64316100
+CLASS=0001
+RRTTL=00000E10
+RTYPE=0002
+RDATA=05746C64316100
+------
+OWNER=013400
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=0162082030205c222e402a03746c6400
+CLASS=0001
+RRTTL=00000E10
+RTYPE=0002
+RDATA=082030205C222E402A03746C6400
+------
+OWNER=016205746c64316100
+CLASS=0001
+RRTTL=00000E10
+RTYPE=0002
+RDATA=05746C64316100
+------
+OWNER=013500
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=016200
+CLASS=0001
+RRTTL=00000E10
+RTYPE=0002
+RDATA=00
+------
+OWNER=016205746c64316100
+CLASS=0001
+RRTTL=00000E10
+RTYPE=0002
+RDATA=05746C64316100
+------
+OWNER=013600
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=016203746c6400
+CLASS=0001
+RRTTL=00000E10
+RTYPE=0002
+RDATA=03746C6400
+------
+OWNER=016205746c64316100
+CLASS=0001
+RRTTL=00000E10
+RTYPE=0002
+RDATA=05746C64316100
+------
+OWNER=013700
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+ERROR=ZSCANNER_EBAD_INCLUDE_FILENAME
+------
diff --git a/src/zscanner/test/tests/06-1_INCLUDE.in b/src/zscanner/test/tests/06-1_INCLUDE.in
new file mode 100644
index 0000000000000000000000000000000000000000..699ad7641841914aa7a343a10213c88640e2c00f
--- /dev/null
+++ b/src/zscanner/test/tests/06-1_INCLUDE.in
@@ -0,0 +1,6 @@
+$ORIGIN .
+$TTL	1
+
+; KO
+$INCLUDE ./includes/include1	a	; Origin is not FQD
+
diff --git a/src/zscanner/test/tests/06-1_INCLUDE.out b/src/zscanner/test/tests/06-1_INCLUDE.out
new file mode 100644
index 0000000000000000000000000000000000000000..25883e7fdb0e73f72fcea517bef12ddd949c832e
--- /dev/null
+++ b/src/zscanner/test/tests/06-1_INCLUDE.out
@@ -0,0 +1,2 @@
+ERROR=ZSCANNER_EBAD_INCLUDE_ORIGIN
+------
diff --git a/src/zscanner/test/tests/06-2_INCLUDE.in b/src/zscanner/test/tests/06-2_INCLUDE.in
new file mode 100644
index 0000000000000000000000000000000000000000..f32385532075d71bb7e3d6f02db4322d9f32f35b
--- /dev/null
+++ b/src/zscanner/test/tests/06-2_INCLUDE.in
@@ -0,0 +1,6 @@
+$ORIGIN .
+$TTL	1
+
+; KO
+$INCLUDE ./includes/include1	%	; Bad origin
+
diff --git a/src/zscanner/test/tests/06-2_INCLUDE.out b/src/zscanner/test/tests/06-2_INCLUDE.out
new file mode 100644
index 0000000000000000000000000000000000000000..25883e7fdb0e73f72fcea517bef12ddd949c832e
--- /dev/null
+++ b/src/zscanner/test/tests/06-2_INCLUDE.out
@@ -0,0 +1,2 @@
+ERROR=ZSCANNER_EBAD_INCLUDE_ORIGIN
+------
diff --git a/src/zscanner/test/tests/06-3_INCLUDE.in b/src/zscanner/test/tests/06-3_INCLUDE.in
new file mode 100644
index 0000000000000000000000000000000000000000..0e4a5c13ef61c9afa9b42a7476b4e86b56f8557a
--- /dev/null
+++ b/src/zscanner/test/tests/06-3_INCLUDE.in
@@ -0,0 +1,6 @@
+$ORIGIN .
+$TTL	1
+
+; KO
+$INCLUDE /tmp/zscanner_tests/		; Given file is a directory
+
diff --git a/src/zscanner/test/tests/06-3_INCLUDE.out b/src/zscanner/test/tests/06-3_INCLUDE.out
new file mode 100644
index 0000000000000000000000000000000000000000..6a45d67c1e46a7ca1836b07b6d51e09ded09e279
--- /dev/null
+++ b/src/zscanner/test/tests/06-3_INCLUDE.out
@@ -0,0 +1,2 @@
+ERROR=ZSCANNER_EUNPROCESSED_INCLUDE
+------
diff --git a/src/zscanner/test/tests/06-4_INCLUDE.in b/src/zscanner/test/tests/06-4_INCLUDE.in
new file mode 100644
index 0000000000000000000000000000000000000000..118546e2467e06c41cbc2473a78736a97eb46244
--- /dev/null
+++ b/src/zscanner/test/tests/06-4_INCLUDE.in
@@ -0,0 +1,6 @@
+$ORIGIN .
+$TTL	1
+
+; KO
+$INCLUDE /tmp/zscanner_tests/_		; File doesn't exist
+
diff --git a/src/zscanner/test/tests/06-4_INCLUDE.out b/src/zscanner/test/tests/06-4_INCLUDE.out
new file mode 100644
index 0000000000000000000000000000000000000000..2d4fff27e52259df131e2225d55f29bd9f74cb31
--- /dev/null
+++ b/src/zscanner/test/tests/06-4_INCLUDE.out
@@ -0,0 +1,2 @@
+ERROR=ZSCANNER_EUNOPENED_INCLUDE
+------
diff --git a/src/zscanner/test/tests/06-5_INCLUDE.in b/src/zscanner/test/tests/06-5_INCLUDE.in
new file mode 100644
index 0000000000000000000000000000000000000000..1d658120cd20ed0508597f1d49959efd20d0f1f2
--- /dev/null
+++ b/src/zscanner/test/tests/06-5_INCLUDE.in
@@ -0,0 +1,5 @@
+$ORIGIN .
+$TTL	1
+
+; KO
+$INCLUDE ./includes/include3		; Blank include file
diff --git a/src/zscanner/test/tests/06-5_INCLUDE.out b/src/zscanner/test/tests/06-5_INCLUDE.out
new file mode 100644
index 0000000000000000000000000000000000000000..6a45d67c1e46a7ca1836b07b6d51e09ded09e279
--- /dev/null
+++ b/src/zscanner/test/tests/06-5_INCLUDE.out
@@ -0,0 +1,2 @@
+ERROR=ZSCANNER_EUNPROCESSED_INCLUDE
+------
diff --git a/src/zscanner/test/tests/06-6_INCLUDE.in b/src/zscanner/test/tests/06-6_INCLUDE.in
new file mode 100644
index 0000000000000000000000000000000000000000..cbfda6493c31885c4055b4895418e2836e1ededa
--- /dev/null
+++ b/src/zscanner/test/tests/06-6_INCLUDE.in
@@ -0,0 +1,5 @@
+$ORIGIN .
+$TTL	1
+
+; KO
+$INCLUDE ./includes/include4		; Include file contains warning
diff --git a/src/zscanner/test/tests/06-6_INCLUDE.out b/src/zscanner/test/tests/06-6_INCLUDE.out
new file mode 100644
index 0000000000000000000000000000000000000000..80f23edb15ecc886bad7396b2871ef2b15a8f0a5
--- /dev/null
+++ b/src/zscanner/test/tests/06-6_INCLUDE.out
@@ -0,0 +1,4 @@
+WARNG=ZSCANNER_EBAD_RDATA
+------
+ERROR=ZSCANNER_EUNPROCESSED_INCLUDE
+------
diff --git a/src/zscanner/test/tests/06-7_INCLUDE.in b/src/zscanner/test/tests/06-7_INCLUDE.in
new file mode 100644
index 0000000000000000000000000000000000000000..24deef71fa173efffcf1917b6ddf2f0a47f3f872
--- /dev/null
+++ b/src/zscanner/test/tests/06-7_INCLUDE.in
@@ -0,0 +1,5 @@
+$ORIGIN .
+$TTL	1
+
+; KO
+$INCLUDE ./includes/include5		; Include file contains error
diff --git a/src/zscanner/test/tests/06-7_INCLUDE.out b/src/zscanner/test/tests/06-7_INCLUDE.out
new file mode 100644
index 0000000000000000000000000000000000000000..c94b02fb940d7426c2e5da4db77af3e9e4ceb1d3
--- /dev/null
+++ b/src/zscanner/test/tests/06-7_INCLUDE.out
@@ -0,0 +1,4 @@
+ERROR=ZSCANNER_EBAD_NUMBER
+------
+ERROR=ZSCANNER_EUNPROCESSED_INCLUDE
+------
diff --git a/src/zscanner/test/tests/06-8_INCLUDE.in b/src/zscanner/test/tests/06-8_INCLUDE.in
new file mode 100644
index 0000000000000000000000000000000000000000..c856668a7547f67db979818ecb61c539b75f893a
--- /dev/null
+++ b/src/zscanner/test/tests/06-8_INCLUDE.in
@@ -0,0 +1,5 @@
+$ORIGIN .
+$TTL	1
+
+; KO
+$INCLUDE ./includes/include6		; Include file contains include
diff --git a/src/zscanner/test/tests/06-8_INCLUDE.out b/src/zscanner/test/tests/06-8_INCLUDE.out
new file mode 100644
index 0000000000000000000000000000000000000000..5f18a939d649889d73cdd6172f2c6be0478a08f5
--- /dev/null
+++ b/src/zscanner/test/tests/06-8_INCLUDE.out
@@ -0,0 +1,12 @@
+OWNER=016200
+CLASS=0001
+RRTTL=00000E10
+RTYPE=0002
+RDATA=00
+------
+OWNER=016205746c64316100
+CLASS=0001
+RRTTL=00000E10
+RTYPE=0002
+RDATA=05746C64316100
+------
diff --git a/src/zscanner/test/tests/10_A.in b/src/zscanner/test/tests/10_A.in
new file mode 100644
index 0000000000000000000000000000000000000000..69ae11d90ea12daf74f130380cb99f2234e57f87
--- /dev/null
+++ b/src/zscanner/test/tests/10_A.in
@@ -0,0 +1,22 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	A	0.0.0.0		; Minimal ipv4 address
+@	A	255.255.255.255	; Maximal ipv4 address
+@	A	\# 4 00000000	; Hexadecimal rdata
+@	TYPE1	\# 4 00000000	; TYPE + Hexadecimal rdata
+@	TYPE1	0.0.0.0		; TYPE
+@	a	0.0.0.0		; Type in lower-case
+
+; KO
+@	A
+@	A			; Empty rdata
+@	A	\# 0		; Hex empty rdata
+@	A	\#		; Missing hex length
+@	A	0.0.0.256	; 8bit overflow
+@	A	0.0.0		; Short address
+@	A	0.0.0.A		; Bad character
+@	A	0.0.0.0 1.1.1.1	; Unexpected item
+@	A	\# 5 0000000000	; Too long rdata
+@	A	\# 5 00000000	; Bad rdata length
diff --git a/src/zscanner/test/tests/10_A.out b/src/zscanner/test/tests/10_A.out
new file mode 100644
index 0000000000000000000000000000000000000000..c36823c14b44e7a13eec5a18a928288f2e18d33c
--- /dev/null
+++ b/src/zscanner/test/tests/10_A.out
@@ -0,0 +1,56 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0001
+RDATA=00000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0001
+RDATA=FFFFFFFF
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0001
+RDATA=00000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0001
+RDATA=00000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0001
+RDATA=00000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0001
+RDATA=00000000
+------
+WARNG=ZSCANNER_EBAD_ADDRESS_CHAR
+------
+WARNG=ZSCANNER_EBAD_ADDRESS_CHAR
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_IPV4
+------
+WARNG=ZSCANNER_EBAD_IPV4
+------
+WARNG=ZSCANNER_EBAD_ADDRESS_CHAR
+------
+WARNG=ZSCANNER_EBAD_REST
+------
+WARNG=ZSCANNER_EBAD_HEX_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
diff --git a/src/zscanner/test/tests/11_AAAA.in b/src/zscanner/test/tests/11_AAAA.in
new file mode 100644
index 0000000000000000000000000000000000000000..c43d375c444612920f0435f20340336c7492cc54
--- /dev/null
+++ b/src/zscanner/test/tests/11_AAAA.in
@@ -0,0 +1,24 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	AAAA	0:0:0:0:0:0:0:0					; Minimal ipv6 address
+@	AAAA	FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF		; Maximal ipv6 address
+@	AAAA	\# 16 00000000 00000000 00000000 00000000	; Hexadecimal rdata
+@	TYPE28	\# 16 00000000 00000000 00000000 00000000	; TYPE + Hexadecimal rdata
+@	TYPE28	0:0:0:0:0:0:0:0		; TYPE
+@	AAAA	0::1.2.3.4		; ipv6 address based on ipv4 address
+@	AAAA	::			; Double colon
+@	aaAA	::			; Type in lower-case
+
+; KO
+@	AAAA
+@	AAAA				; Empty rdata
+@	AAAA	\# 0			; Hex empty rdata
+@	AAAA	\#			; Missing hex length
+@	AAAA	0::FFFFF		; 16bit overflow
+@	AAAA	0:0:0:0:0:0:0		; Short address
+@	AAAA	0:0:0:0:0:0:0:X		; Bad character
+@	AAAA	:: ::			; Unexpected item
+@	AAAA	\# 17 00000000 00000000 00000000 00000000 00	; Too long rdata
+@	AAAA	\# 17 00000000 00000000 00000000 00000000	; Bad rdata length
diff --git a/src/zscanner/test/tests/11_AAAA.out b/src/zscanner/test/tests/11_AAAA.out
new file mode 100644
index 0000000000000000000000000000000000000000..c4006bf3c024e897cdd01157c20c6632b4bde276
--- /dev/null
+++ b/src/zscanner/test/tests/11_AAAA.out
@@ -0,0 +1,68 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001C
+RDATA=00000000000000000000000000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001C
+RDATA=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001C
+RDATA=00000000000000000000000000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001C
+RDATA=00000000000000000000000000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001C
+RDATA=00000000000000000000000000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001C
+RDATA=00000000000000000000000001020304
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001C
+RDATA=00000000000000000000000000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001C
+RDATA=00000000000000000000000000000000
+------
+WARNG=ZSCANNER_EBAD_ADDRESS_CHAR
+------
+WARNG=ZSCANNER_EBAD_ADDRESS_CHAR
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_IPV6
+------
+WARNG=ZSCANNER_EBAD_IPV6
+------
+WARNG=ZSCANNER_EBAD_ADDRESS_CHAR
+------
+WARNG=ZSCANNER_EBAD_REST
+------
+WARNG=ZSCANNER_EBAD_HEX_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
diff --git a/src/zscanner/test/tests/12_TXT.in b/src/zscanner/test/tests/12_TXT.in
new file mode 100644
index 0000000000000000000000000000000000000000..36519ff70b12de58bda07261e20535f755ca6359
--- /dev/null
+++ b/src/zscanner/test/tests/12_TXT.in
@@ -0,0 +1,39 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	TXT	""				; Blank string
+@	TXT	a				; One char string
+@	TXT	\ 				; One space char
+@	TXT	"\ "				; One space char in quotes
+@	TXT	\021				; One unprintable char
+@	TXT	"\\ \""				; Special chars
+@	TXT	"" "test1" "\255" test2		; Array of text strings
+@	TXT	"" "" ""			; Array of blank strings
+@	TXT	first \# "\#"			; Array with special string
+@	TXT	\0320\ \\\"\.\@\*.tld.		; Special domain as a string
+@	TXT	" !\"#$%&'()*+,-./0123456789:;<=>?@"	; First part of all printables
+@	TXT	"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`"	; Second part of all printables
+@	TXT	"abcdefghijklmnopqrstuvwxyz{|}~"	; Third part of all printables
+@	TXT	\# 1 00				; Hexadecimal rdata
+@	TYPE16	\# 1 00				; TYPE + Hexadecimal rdata
+@	TYPE16	""				; TYPE
+@	TXT	(				; Special multi-line string
+"first
+second"
+third						; Second string
+)
+@	TXT	"abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMN1234\053"	; Text string of maximal length (255 chars)
+@	txt	""				; Type in lower-case
+
+; KO
+@	TXT
+@	TXT			; Empty rdata
+@	TXT	\# 0		; Hex empty rdata
+@	TXT	\#		; Missing hex length
+@	TXT	\# second	; Hex notation with second text string
+@	TXT	\01		; Missing digit in decimal notation
+@	TXT	\256		; 8bit overflow in decimal notation
+@	TXT	\# 2 ""		; Bad length
+@	TXT	"""		; '"' char without forward slash
+@	TXT	"abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMN1234\0536"	; Maximal length overflow
diff --git a/src/zscanner/test/tests/12_TXT.out b/src/zscanner/test/tests/12_TXT.out
new file mode 100644
index 0000000000000000000000000000000000000000..ba573eda2be92f64992ba72f69740fe6cbdd7b16
--- /dev/null
+++ b/src/zscanner/test/tests/12_TXT.out
@@ -0,0 +1,134 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0010
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0010
+RDATA=0161
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0010
+RDATA=0120
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0010
+RDATA=0120
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0010
+RDATA=0115
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0010
+RDATA=035C2022
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0010
+RDATA=0005746573743101FF057465737432
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0010
+RDATA=000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0010
+RDATA=05666972737401230123
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0010
+RDATA=0D2030205C222E402A2E746C642E
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0010
+RDATA=21202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F40
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0010
+RDATA=204142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F60
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0010
+RDATA=1E6162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0010
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0010
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0010
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0010
+RDATA=0C66697273740A7365636F6E64057468697264
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0010
+RDATA=FF6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E3132333435
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0010
+RDATA=00
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_ENUMBER8_OVERFLOW
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_TEXT
+------
+WARNG=ZSCANNER_EITEM_OVERFLOW
+------
diff --git a/src/zscanner/test/tests/13_SPF.in b/src/zscanner/test/tests/13_SPF.in
new file mode 100644
index 0000000000000000000000000000000000000000..0ad6c84b50020b7bc2b16cb4165f688030c03e35
--- /dev/null
+++ b/src/zscanner/test/tests/13_SPF.in
@@ -0,0 +1,14 @@
+$ORIGIN	.
+$TTL	1
+
+; The SPF is the same as the TXT, so there are the differences and basics only.
+
+; OK
+@	SPF	"" "test1" "\255" test2		; Array of text strings
+@	SPF	\# 1 00				; Hexadecimal rdata
+@	TYPE99	\# 1 00				; TYPE + Hexadecimal rdata
+@	TYPE99	""				; TYPE
+@	spf	""				; Type in lower-case
+
+; KO
+@	SPF
diff --git a/src/zscanner/test/tests/13_SPF.out b/src/zscanner/test/tests/13_SPF.out
new file mode 100644
index 0000000000000000000000000000000000000000..273e92e834743f0bb37280ea8385cbdaf269fe92
--- /dev/null
+++ b/src/zscanner/test/tests/13_SPF.out
@@ -0,0 +1,32 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0063
+RDATA=0005746573743101FF057465737432
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0063
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0063
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0063
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0063
+RDATA=00
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
diff --git a/src/zscanner/test/tests/14_NS.in b/src/zscanner/test/tests/14_NS.in
new file mode 100644
index 0000000000000000000000000000000000000000..fe51ef2388aadbd1f6cb85d9654b4f89541727de
--- /dev/null
+++ b/src/zscanner/test/tests/14_NS.in
@@ -0,0 +1,41 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	NS	.				; The simplest owner
+@	NS	tld.				; FQD tld owner
+@	NS	tld				; Relative form
+@	NS	*.				; FQD with asterisk
+@	NS	*				; Alone asterisk
+@	NS	*.*				; More asterisks
+@	NS	@				; Use origin
+@	NS	0123456789			; Digits
+@	NS	_a_.-b-c-./d/.			; Allowed characters '_' '-' '/' anywhere
+@	NS	ABCDEFGHIJKLMNOPQRSTUVWXYZ	; All upper-case letters
+@	NS	abcdefghijklmnopqrstuvwxyz	; All lower-case letters
+@	NS	\0320\ \\\"\.\@\*.tld.		; Label with special chars
+@	NS	b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.	; IPv6 reverse
+@	NS	123456789012345678901234567890123456789012345678901234567890123.tld.		; Label of maximal length
+@	NS	123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.	; Domain name of maximal length
+@	NS	123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901	; Domain name of maximal length (after appending origin)
+@	TYPE2	\# 1 00				; TYPE + Hexadecimal rdata
+@	TYPE2	@				; TYPE
+@	ns	@				; Type in lower-case
+
+; KO
+@	NS
+@	NS					; Empty rdata
+@	NS	\# 0				; Hex empty rdata
+@	NS	\#				; Missing hex length
+@	NS	&				; Bad (unslashed) character
+@	NS	a*a				; * char can substitute whole label only
+@	NS	@@				; Double @@
+@	NS	..				; Missing label between dots
+@	NS	\1				; Slash notation requires 3 digits
+@	NS	\12				; Slash notation requires 3 digits
+@	NS	1234567890123456789012345678901234567890123456789012345678901234.tld.	; Label exceeded maximal length
+@	NS	123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012.	; Domain name exceeded maximal length
+@	NS	123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012	; Domain name exceeded maximal length (after appending origin)
+@	NS	. x				; Unexpected item
+@	NS	\# 2 0001			; Too long rdata
+@	NS	\# 2 00				; Bad rdata length
diff --git a/src/zscanner/test/tests/14_NS.out b/src/zscanner/test/tests/14_NS.out
new file mode 100644
index 0000000000000000000000000000000000000000..08c0104c59c3fac8f48fe64d83187272b0255508
--- /dev/null
+++ b/src/zscanner/test/tests/14_NS.out
@@ -0,0 +1,146 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=03746C6400
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=03746C6400
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=012A00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=012A00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=012A012A00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=0A3031323334353637383900
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=035F615F052D622D632D032F642F00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=1A4142434445464748494A4B4C4D4E4F505152535455565758595A00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=1A6162636465666768696A6B6C6D6E6F707172737475767778797A00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=082030205C222E402A03746C6400
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=0162016101390138013701360135013001300130013001300130013001300130013001300130013001300130013001300138016201640130013101300130013203697036046172706100
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=3F31323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323303746C6400
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=3F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333D3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303100
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=3F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333D3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303100
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0002
+RDATA=00
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_DNAME_CHAR
+------
+WARNG=ZSCANNER_EBAD_DNAME_CHAR
+------
+WARNG=ZSCANNER_EBAD_DNAME_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_ELABEL_OVERFLOW
+------
+WARNG=ZSCANNER_EDNAME_OVERFLOW
+------
+WARNG=ZSCANNER_EDNAME_OVERFLOW
+------
+WARNG=ZSCANNER_EBAD_REST
+------
+WARNG=ZSCANNER_EBAD_HEX_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
diff --git a/src/zscanner/test/tests/15_CNAME.in b/src/zscanner/test/tests/15_CNAME.in
new file mode 100644
index 0000000000000000000000000000000000000000..806b8f9ae391ce026f626131a450f7bb52bf383c
--- /dev/null
+++ b/src/zscanner/test/tests/15_CNAME.in
@@ -0,0 +1,14 @@
+$ORIGIN	.
+$TTL	1
+
+; The CNAME is the same as the NS, so there are the differences and basics only.
+
+; OK
+@	CNAME	test.example.com		; Relative dname
+@	CNAME	\# 1 00				; Hexadecimal rdata
+@	TYPE5	\# 1 00				; TYPE + Hexadecimal rdata
+@	TYPE5	@				; TYPE
+@	cname	@				; Type in lower-case
+
+; KO
+@	CNAME
diff --git a/src/zscanner/test/tests/15_CNAME.out b/src/zscanner/test/tests/15_CNAME.out
new file mode 100644
index 0000000000000000000000000000000000000000..a5411265c72ab552fe7addf6c6c9fe3834a08062
--- /dev/null
+++ b/src/zscanner/test/tests/15_CNAME.out
@@ -0,0 +1,32 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0005
+RDATA=0474657374076578616D706C6503636F6D00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0005
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0005
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0005
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0005
+RDATA=00
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
diff --git a/src/zscanner/test/tests/16_PTR.in b/src/zscanner/test/tests/16_PTR.in
new file mode 100644
index 0000000000000000000000000000000000000000..3694e7da39fdf9abfe7cb327effd2bf030ad9300
--- /dev/null
+++ b/src/zscanner/test/tests/16_PTR.in
@@ -0,0 +1,14 @@
+$ORIGIN	.
+$TTL	1
+
+; The PTR is the same as the NS, so there are the differences and basics only.
+
+; OK
+@	PTR	test.example.com		; Relative dname
+@	PTR	\# 1 00				; Hexadecimal rdata
+@	TYPE12	\# 1 00				; TYPE + Hexadecimal rdata
+@	TYPE12	@				; TYPE
+@	ptr	@				; Type in lower-case
+
+; KO
+@	PTR
diff --git a/src/zscanner/test/tests/16_PTR.out b/src/zscanner/test/tests/16_PTR.out
new file mode 100644
index 0000000000000000000000000000000000000000..d983296202190202b1b8260ef5816b99c0c77749
--- /dev/null
+++ b/src/zscanner/test/tests/16_PTR.out
@@ -0,0 +1,32 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000C
+RDATA=0474657374076578616D706C6503636F6D00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000C
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000C
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000C
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000C
+RDATA=00
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
diff --git a/src/zscanner/test/tests/17_DNAME.in b/src/zscanner/test/tests/17_DNAME.in
new file mode 100644
index 0000000000000000000000000000000000000000..5e9ba71dbb81e703dd68ddb44fdbca1e542ceefc
--- /dev/null
+++ b/src/zscanner/test/tests/17_DNAME.in
@@ -0,0 +1,14 @@
+$ORIGIN	.
+$TTL	1
+
+; The DNAME is the same as the NS, so there are the differences and basics only.
+
+; OK
+@	DNAME	test.example.com		; Relative dname
+@	DNAME	\# 1 00				; Hexadecimal rdata
+@	TYPE39	\# 1 00				; TYPE + Hexadecimal rdata
+@	TYPE39	@				; TYPE
+@	dname	@				; Type in lower-case
+
+; KO
+@	DNAME
diff --git a/src/zscanner/test/tests/17_DNAME.out b/src/zscanner/test/tests/17_DNAME.out
new file mode 100644
index 0000000000000000000000000000000000000000..ee6797248587c0478d5a786af5d2a7deaadf7d3d
--- /dev/null
+++ b/src/zscanner/test/tests/17_DNAME.out
@@ -0,0 +1,32 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0027
+RDATA=0474657374076578616D706C6503636F6D00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0027
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0027
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0027
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0027
+RDATA=00
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
diff --git a/src/zscanner/test/tests/18_MX.in b/src/zscanner/test/tests/18_MX.in
new file mode 100644
index 0000000000000000000000000000000000000000..52bf995662049083539cae97e0a849d646a290aa
--- /dev/null
+++ b/src/zscanner/test/tests/18_MX.in
@@ -0,0 +1,26 @@
+$ORIGIN	.
+$TTL	1
+
+; For more tests on dname see NS test (same processing)
+
+; OK
+@	MX	0	@		; Minimal priority
+@	MX	65535	@		; Maximal priority
+@	MX	1	mail		; Relative dname
+@	MX	1	mail.tld.	; Absolute dname
+@	MX	\# 3 0001 00		; Hexadecimal rdata
+@	TYPE15	\# 3 0001 00		; TYPE + Hexadecimal rdata
+@	TYPE15	1	@		; TYPE
+@	mx	1	@		; Type in lower-case
+
+; KO
+@	MX
+@	MX				; Empty rdata
+@	MX	\# 0			; Hex empty rdata
+@	MX	\#			; Missing hex length
+@	MX	-1	@		; Negative number
+@	MX	65536	@		; 16bit overflow
+@	MX	1	$		; Bad dname
+@	MX	0	@ x		; Unexpected item
+@	MX	\# 4 0001 0001		; Too long rdata
+@	MX	\# 4 0001 00		; Bad rdata length
diff --git a/src/zscanner/test/tests/18_MX.out b/src/zscanner/test/tests/18_MX.out
new file mode 100644
index 0000000000000000000000000000000000000000..50b1b7008d6232d37643289b595e84cae4f6425c
--- /dev/null
+++ b/src/zscanner/test/tests/18_MX.out
@@ -0,0 +1,68 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000F
+RDATA=0000 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000F
+RDATA=FFFF 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000F
+RDATA=0001 046D61696C00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000F
+RDATA=0001 046D61696C03746C6400
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000F
+RDATA=0001 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000F
+RDATA=0001 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000F
+RDATA=0001 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000F
+RDATA=0001 00
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_ENUMBER16_OVERFLOW
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_REST
+------
+WARNG=ZSCANNER_EBAD_HEX_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
diff --git a/src/zscanner/test/tests/19_AFSDB.in b/src/zscanner/test/tests/19_AFSDB.in
new file mode 100644
index 0000000000000000000000000000000000000000..be569e49f2cfbcbaadc6547eb4ca8a6b3e1231df
--- /dev/null
+++ b/src/zscanner/test/tests/19_AFSDB.in
@@ -0,0 +1,14 @@
+$ORIGIN	.
+$TTL	1
+
+; The AFSDB is the same as the MX, so there are the differences and basics only.
+
+; OK
+@	AFSDB	1	mail		; Relative dname
+@	AFSDB	\# 3 0001 00		; Hexadecimal rdata
+@	TYPE18	\# 3 0001 00		; TYPE + Hexadecimal rdata
+@	TYPE18	1	@		; TYPE
+@	afsdb	1	@		; Type in lower-case
+
+; KO
+@	AFSDB
diff --git a/src/zscanner/test/tests/19_AFSDB.out b/src/zscanner/test/tests/19_AFSDB.out
new file mode 100644
index 0000000000000000000000000000000000000000..957abc704810510033a494336b0300e602b7df54
--- /dev/null
+++ b/src/zscanner/test/tests/19_AFSDB.out
@@ -0,0 +1,32 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0012
+RDATA=0001 046D61696C00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0012
+RDATA=0001 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0012
+RDATA=0001 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0012
+RDATA=0001 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0012
+RDATA=0001 00
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
diff --git a/src/zscanner/test/tests/20_RT.in b/src/zscanner/test/tests/20_RT.in
new file mode 100644
index 0000000000000000000000000000000000000000..3bc774d0ca00b9c8413ae1593d43c7206be6ea9f
--- /dev/null
+++ b/src/zscanner/test/tests/20_RT.in
@@ -0,0 +1,14 @@
+$ORIGIN	.
+$TTL	1
+
+; The RT is the same as the MX, so there are the differences and basics only.
+
+; OK
+@	RT	1	mail		; Relative dname
+@	RT	\# 3 0001 00		; Hexadecimal rdata
+@	TYPE21	\# 3 0001 00		; TYPE + Hexadecimal rdata
+@	TYPE21	1	@		; TYPE
+@	rt	1	@		; Type in lower-case
+
+; KO
+@	RT
diff --git a/src/zscanner/test/tests/20_RT.out b/src/zscanner/test/tests/20_RT.out
new file mode 100644
index 0000000000000000000000000000000000000000..490ab2aba8140d3d8b35c2bf02f3e081ba339eb8
--- /dev/null
+++ b/src/zscanner/test/tests/20_RT.out
@@ -0,0 +1,32 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0015
+RDATA=0001 046D61696C00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0015
+RDATA=0001 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0015
+RDATA=0001 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0015
+RDATA=0001 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0015
+RDATA=0001 00
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
diff --git a/src/zscanner/test/tests/21_KX.in b/src/zscanner/test/tests/21_KX.in
new file mode 100644
index 0000000000000000000000000000000000000000..529480db709de10c90fb9bfbf6389b3d60ba1c5f
--- /dev/null
+++ b/src/zscanner/test/tests/21_KX.in
@@ -0,0 +1,14 @@
+$ORIGIN	.
+$TTL	1
+
+; The KX is the same as the MX, so there are the differences and basics only.
+
+; OK
+@	KX	1	mail		; Relative dname
+@	KX	\# 3 0001 00		; Hexadecimal rdata
+@	TYPE36	\# 3 0001 00		; TYPE + Hexadecimal rdata
+@	TYPE36	1	@		; TYPE
+@	kx	1	@		; Type in lower-case
+
+; KO
+@	KX
diff --git a/src/zscanner/test/tests/21_KX.out b/src/zscanner/test/tests/21_KX.out
new file mode 100644
index 0000000000000000000000000000000000000000..1c5f323e9a9a0a13333056f223389c70be1a8768
--- /dev/null
+++ b/src/zscanner/test/tests/21_KX.out
@@ -0,0 +1,32 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0024
+RDATA=0001 046D61696C00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0024
+RDATA=0001 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0024
+RDATA=0001 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0024
+RDATA=0001 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0024
+RDATA=0001 00
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
diff --git a/src/zscanner/test/tests/22_HINFO.in b/src/zscanner/test/tests/22_HINFO.in
new file mode 100644
index 0000000000000000000000000000000000000000..8939e2d407462e1b05de690132c5d7c59d06bf18
--- /dev/null
+++ b/src/zscanner/test/tests/22_HINFO.in
@@ -0,0 +1,29 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	HINFO	"" ""				; Blank string
+@	HINFO	a b				; One char string
+@	HINFO	\  \ 				; One space char
+@	HINFO	"\ " "\ "			; One space char in quotes
+@	HINFO	\021 \022			; One unprintable char
+@	HINFO	"\\ \""	"\\ \""			; Special chars
+@	HINFO	first \#			; Array with special string
+@	HINFO	\# 2 00	00			; Hexadecimal rdata
+@	TYPE13	\# 2 00	00			; TYPE + Hexadecimal rdata
+@	TYPE13	"" ""				; TYPE
+@	HINFO	"abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMN1234\053" ""	; Text string of maximal length (255 chars)
+@	hinfo	"" ""				; Type in lower-case
+
+; KO
+@	HINFO
+@	HINFO			; Empty rdata
+@	HINFO	\# 0		; Hex empty rdata
+@	HINFO	\#		; Missing hex length
+@	HINFO	\# second	; Hex notation with second text string
+@	HINFO	\01 ""		; Missing digit in decimal notation
+@	HINFO	\256 ""		; 8bit overflow in decimal notation
+@	HINFO	\# 3 0000	; Bad rdata length
+@	HINFO	""" ""		; '"' char without forward slash
+@	HINFO	"" "" ""	; Unexpected item
+@	HINFO	"abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMN1234\0536" ""	; Maximal length overflow
diff --git a/src/zscanner/test/tests/22_HINFO.out b/src/zscanner/test/tests/22_HINFO.out
new file mode 100644
index 0000000000000000000000000000000000000000..66863ef8f7484958a9566a41afc9b6df9f13d3e4
--- /dev/null
+++ b/src/zscanner/test/tests/22_HINFO.out
@@ -0,0 +1,94 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000D
+RDATA=0000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000D
+RDATA=01610162
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000D
+RDATA=01200120
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000D
+RDATA=01200120
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000D
+RDATA=01150116
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000D
+RDATA=035C2022035C2022
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000D
+RDATA=0566697273740123
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000D
+RDATA=0000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000D
+RDATA=0000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000D
+RDATA=0000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000D
+RDATA=FF6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E313233343500
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000D
+RDATA=0000
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_ENUMBER8_OVERFLOW
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
+WARNG=ZSCANNER_EBAD_TEXT
+------
+WARNG=ZSCANNER_EBAD_REST
+------
+WARNG=ZSCANNER_EITEM_OVERFLOW
+------
diff --git a/src/zscanner/test/tests/23_MINFO.in b/src/zscanner/test/tests/23_MINFO.in
new file mode 100644
index 0000000000000000000000000000000000000000..4f0076513451ce174ce62404c7b90918829c42ca
--- /dev/null
+++ b/src/zscanner/test/tests/23_MINFO.in
@@ -0,0 +1,21 @@
+$ORIGIN	.
+$TTL	1
+
+; For more tests on dname see NS test (same processing)
+
+; OK
+@	MINFO	.	.		; The simplest dnames
+@	MINFO	@	@		; Use origin
+@	MINFO	mail	mail.tld.	; Relative and absolute dnames
+@	MINFO	\# 2 00 00		; Hexadecimal rdata
+@	TYPE14	\# 2 00 00		; TYPE + Hexadecimal rdata
+@	TYPE14	@	@		; TYPE
+@	minfo	@	@		; Type in lower-case
+
+; KO
+@	MINFO
+@	MINFO				; Empty rdata
+@	MINFO	\# 0			; Hex empty rdata
+@	MINFO	\#			; Missing hex length
+@	MINFO	\# 3 00 0001		; Too long rdata
+@	MINFO	\# 3 00 00		; Bad rdata length
diff --git a/src/zscanner/test/tests/23_MINFO.out b/src/zscanner/test/tests/23_MINFO.out
new file mode 100644
index 0000000000000000000000000000000000000000..026a7d23220af1773839f16153926e41bf8d2ffa
--- /dev/null
+++ b/src/zscanner/test/tests/23_MINFO.out
@@ -0,0 +1,54 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000E
+RDATA=00 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000E
+RDATA=00 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000E
+RDATA=046D61696C00 046D61696C03746C6400
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000E
+RDATA=00 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000E
+RDATA=00 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000E
+RDATA=00 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=000E
+RDATA=00 00
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_HEX_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
diff --git a/src/zscanner/test/tests/24_RP.in b/src/zscanner/test/tests/24_RP.in
new file mode 100644
index 0000000000000000000000000000000000000000..a70d7926cff4da4b627b849c1bd33700b0396b54
--- /dev/null
+++ b/src/zscanner/test/tests/24_RP.in
@@ -0,0 +1,14 @@
+$ORIGIN	.
+$TTL	1
+
+; The RP is the same as the MINFO, so there are the differences and basics only.
+
+; OK
+@	RP	mail	mail.tld.	; Relative and absolute dnames
+@	RP	\# 2 00 00		; Hexadecimal rdata
+@	TYPE17	\# 2 00 00		; TYPE + Hexadecimal rdata
+@	TYPE17	@	@		; TYPE
+@	rp	@	@		; Type in lower-case
+
+; KO
+@	RP
diff --git a/src/zscanner/test/tests/24_RP.out b/src/zscanner/test/tests/24_RP.out
new file mode 100644
index 0000000000000000000000000000000000000000..0565c7df9b1d0b585821ac2fba103f2d8d83d3a0
--- /dev/null
+++ b/src/zscanner/test/tests/24_RP.out
@@ -0,0 +1,32 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0011
+RDATA=046D61696C00 046D61696C03746C6400
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0011
+RDATA=00 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0011
+RDATA=00 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0011
+RDATA=00 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0011
+RDATA=00 00
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
diff --git a/src/zscanner/test/tests/25_SOA.in b/src/zscanner/test/tests/25_SOA.in
new file mode 100644
index 0000000000000000000000000000000000000000..197cb20c62a5aebe7d1ea6ebac62a71bf8c14872
--- /dev/null
+++ b/src/zscanner/test/tests/25_SOA.in
@@ -0,0 +1,36 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	SOA	@	@	0	0 0 0 0		; The simplest variant
+@	SOA	tld.	tld	0	0 0 0 0 	; Absolute and relative dnames.
+@	SOA	@	@	4294967295 0 0 0 0	; Maximal serial
+@	SOA	@	@	0 4294967295 4294967295 4294967295 4294967295	; Maximal times
+@	SOA	@	@	0	1d 1h 1m 1s	; Time units
+@	TYPE6	\# 22 00 00 0000000000000000000000000000000000000000	; TYPE + Hexadecimal rdata
+@	TYPE6	@	@       0       0 0 0 0		; TYPE
+@	SOA	ns.tld. first\.second.tld. (		; Multiline record
+	2007120710
+	1w2d3h4m5s
+	2h
+	3m
+	4s
+)
+@	soa	@	@       0       0 0 0 0		; Type in lower-case
+
+; KO
+@	SOA
+@	SOA						; Empty rdata
+@	SOA	\# 0					; Hex empty rdata
+@	SOA	\#					; Missing hex length
+@	SOA	@	@	1h	0 0 0 0		; Bad number
+@	SOA	@	@	4294967296 0 0 0 0	; Serial overflow
+@	SOA	@	@	0 4294967296 0 0 0	; Refresh overflow
+@	SOA	@	@	0 0 4294967296 0 0	; Retry overflow
+@	SOA	@	@	0 0 0 4294967296 0	; Expire overflow
+@	SOA	@	@	0 0 0 0 4294967296	; Minimum overflow
+@	SOA	@	@	0 0 0 0 0 x		; Unexpected item
+@	SOA	\# 23 0001 00 0000000000000000000000000000000000000000	; Too long rdata (mname)
+@	SOA	\# 23 00 0001 0000000000000000000000000000000000000000	; Too long rdata (rname)
+@	SOA	\# 23 00 00 000000000000000000000000000000000000000000	; Too long rdata
+@	SOA	\# 23 00 00   0000000000000000000000000000000000000000	; Bad rdata length
diff --git a/src/zscanner/test/tests/25_SOA.out b/src/zscanner/test/tests/25_SOA.out
new file mode 100644
index 0000000000000000000000000000000000000000..0833c68b7bfda78b70a576b05c403541ecb8255b
--- /dev/null
+++ b/src/zscanner/test/tests/25_SOA.out
@@ -0,0 +1,84 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0006
+RDATA=00 00 0000000000000000000000000000000000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0006
+RDATA=03746C6400 03746C6400 0000000000000000000000000000000000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0006
+RDATA=00 00 FFFFFFFF00000000000000000000000000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0006
+RDATA=00 00 00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0006
+RDATA=00 00 000000000001518000000E100000003C00000001
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0006
+RDATA=00 00 0000000000000000000000000000000000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0006
+RDATA=00 00 0000000000000000000000000000000000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0006
+RDATA=026E7303746C6400 0C66697273742E7365636F6E6403746C6400 77A23B46000C08A500001C20000000B400000004
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0006
+RDATA=00 00 0000000000000000000000000000000000000000
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_ENUMBER32_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER32_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER32_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER32_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER32_OVERFLOW
+------
+WARNG=ZSCANNER_EBAD_REST
+------
+WARNG=ZSCANNER_EBAD_HEX_RDATA
+------
+WARNG=ZSCANNER_EBAD_HEX_RDATA
+------
+WARNG=ZSCANNER_EBAD_HEX_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
diff --git a/src/zscanner/test/tests/26_SRV.in b/src/zscanner/test/tests/26_SRV.in
new file mode 100644
index 0000000000000000000000000000000000000000..8d9e42a47d3d582dc16ccc0ce0c351ab397347dd
--- /dev/null
+++ b/src/zscanner/test/tests/26_SRV.in
@@ -0,0 +1,28 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	SRV	0	0	0	@			; The simplest variant
+_ldap._tcp.test.tld.	SRV	0	0	0	@ 	; Underscores in owner
+@	SRV	65535	65535	65535	@			; Maximal numbers
+@	SRV	0	0	0	\0320\ \\\"\.\@\*.tld.	; Dname with specials
+@	TYPE33	\# 7 000000000000 00				; TYPE + Hexadecimal rdata
+@	TYPE33	0	0	0	@			; TYPE
+@	srv	0	0	0	@			; Type in lower-case
+
+; KO
+@	SRV
+@	SRV						; Empty rdata
+@	SRV	\# 0					; Hex empty rdata
+@	SRV	\#					; Missing hex length
+@	SRV	1h	0	0	@		; Bad priority
+@	SRV	0	1h	0	@		; Bad weight
+@	SRV	0	0	1h	@		; Bad port
+@	SRV	0	0	0	%		; Bad target
+@	SRV	65536	0	0	@		; Priority overflow
+@	SRV	0	65536	0	@		; Weight overflow
+@	SRV	0	0	65536	@		; Port overflow
+@	SRV	0	0	0	@ x		; Unexpected item
+@	SRV	0	0	0			; Missing item
+@	SRV	\# 7 00000000000000 00			; Too long rdata
+@	SRV	\# 8 000000000000 00			; Bad rdata length
diff --git a/src/zscanner/test/tests/26_SRV.out b/src/zscanner/test/tests/26_SRV.out
new file mode 100644
index 0000000000000000000000000000000000000000..a9fe2677ea59749fa7b3f90a4a3f8cdb2c509200
--- /dev/null
+++ b/src/zscanner/test/tests/26_SRV.out
@@ -0,0 +1,72 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0021
+RDATA=000000000000 00
+------
+OWNER=055f6c646170045f746370047465737403746c6400
+CLASS=0001
+RRTTL=00000001
+RTYPE=0021
+RDATA=000000000000 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0021
+RDATA=FFFFFFFFFFFF 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0021
+RDATA=000000000000 082030205C222E402A03746C6400
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0021
+RDATA=000000000000 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0021
+RDATA=000000000000 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0021
+RDATA=000000000000 00
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_ENUMBER16_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER16_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER16_OVERFLOW
+------
+WARNG=ZSCANNER_EBAD_REST
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
diff --git a/src/zscanner/test/tests/27_NAPTR.in b/src/zscanner/test/tests/27_NAPTR.in
new file mode 100644
index 0000000000000000000000000000000000000000..022f1aa5e4f63d7e65ec73bccb0d74e58867b11b
--- /dev/null
+++ b/src/zscanner/test/tests/27_NAPTR.in
@@ -0,0 +1,23 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	NAPTR	0	0	""	""	""	@	; The simplest variant
+@	NAPTR	65535	65535	""	""	""	@	; Maximal numbers
+@	NAPTR	65535	65535	""	""	"!^urn:cid:.+@([^\.]+\.)(.*)$!\\2!i"	@	; Regexp example
+@	NAPTR	0	0	""	""	""	\0320\ \\\"\.\@\*.tld.	; Dname with specials
+@	TYPE35	\# 8 00000000000000 00				; TYPE + Hexadecimal rdata
+@	TYPE35	0	0	""	""	""	@	; TYPE
+@	naptr	0	0	""	""	""	@	; Type in lower-case
+
+; KO
+@	NAPTR
+@	NAPTR							; Empty rdata
+@	NAPTR	\# 0						; Hex empty rdata
+@	NAPTR	\#						; Missing hex length
+@	NAPTR	65536	0	""	""	""	@	; Order overflow
+@	NAPTR	0	65536	""	""	""	@	; Preference overflow
+@	NAPTR	0	0	""	""	""	@  x	; Unexpected item
+@	NAPTR	0	0	""	""	""		; Missing item
+@	NAPTR	\# 8 0000000000000000 00			; Too long rdata
+@	NAPTR	\# 7 00000000000000 00				; Bad rdata length
diff --git a/src/zscanner/test/tests/27_NAPTR.out b/src/zscanner/test/tests/27_NAPTR.out
new file mode 100644
index 0000000000000000000000000000000000000000..f101d191aa9641aab54327a107c6ab8a75bd4360
--- /dev/null
+++ b/src/zscanner/test/tests/27_NAPTR.out
@@ -0,0 +1,62 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0023
+RDATA=00000000000000 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0023
+RDATA=FFFFFFFF000000 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0023
+RDATA=FFFFFFFF00001F215E75726E3A6369643A2E2B40285B5E2E5D2B2E29282E2A2924215C322169 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0023
+RDATA=00000000000000 082030205C222E402A03746C6400
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0023
+RDATA=00000000000000 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0023
+RDATA=00000000000000 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0023
+RDATA=00000000000000 00
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_ENUMBER16_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER16_OVERFLOW
+------
+WARNG=ZSCANNER_EBAD_REST
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
diff --git a/src/zscanner/test/tests/28_TYPE.in b/src/zscanner/test/tests/28_TYPE.in
new file mode 100644
index 0000000000000000000000000000000000000000..f8189e86d946524340c855d3b803a099cc345a55
--- /dev/null
+++ b/src/zscanner/test/tests/28_TYPE.in
@@ -0,0 +1,27 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	TYPE0		\# 0			; Minimal type number
+@	TYPE65535	\# 0			; Maximal type number
+@	TYPE55555	\# 0			; Without hex rdata
+@	TYPE55555	\# 1 00			; Without hex rdata
+@	TYPE1		\# 4 00000000		; Known type
+@	TYPE1		0.0.0.0			; Known type in text format
+@	TYPE55555	(			; Multiline begin
+	\#
+	5
+	0102 03
+	04 05
+	)					; Multiline end
+@	type55555	\# 0			; Type in lower-case
+
+; KO
+@	TYPE55555
+@	TYPE55555				; Without text rdata
+@	TYPE65536				; Type number overflow
+@	TYPE65535x				; Bad type
+@	TYPE55555	\#			; Missing hex length
+@	TYPE55555	\# 1 0000		; Too long rdata
+@	TYPE55555	\# 2 00			; Bad rdata length
+@	TYPE55555	\# 1 00 x		; Unexpected data
diff --git a/src/zscanner/test/tests/28_TYPE.out b/src/zscanner/test/tests/28_TYPE.out
new file mode 100644
index 0000000000000000000000000000000000000000..8f6e10ecd039246974fdb380d826e2a4b12b41d5
--- /dev/null
+++ b/src/zscanner/test/tests/28_TYPE.out
@@ -0,0 +1,64 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0000
+RDATA=
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=FFFF
+RDATA=
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=D903
+RDATA=
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=D903
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0001
+RDATA=00000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0001
+RDATA=00000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=D903
+RDATA=0102030405
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=D903
+RDATA=
+------
+WARNG=ZSCANNER_ECANNOT_TEXT_DATA
+------
+WARNG=ZSCANNER_ECANNOT_TEXT_DATA
+------
+WARNG=ZSCANNER_ENUMBER16_OVERFLOW
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
diff --git a/src/zscanner/test/tests/29_CERT.in b/src/zscanner/test/tests/29_CERT.in
new file mode 100644
index 0000000000000000000000000000000000000000..781556a67e78579f07238acdf767ce4b2f642112
--- /dev/null
+++ b/src/zscanner/test/tests/29_CERT.in
@@ -0,0 +1,34 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	CERT	0	0	0	AA==		; The simplest variant
+@	CERT	65535	65535	255	AA==		; Maximal numbers
+@	CERT	0	0	0	Zm8=		; One char padding
+@	CERT	0	0	0	Zm9v		; Without padding
+@	CERT	0	0	0	Zm9vYg==	; Two base64 blocks 
+@	CERT	0	0	0	Zm9v YmE=	; Two base64 blocks with blank space between them
+@	TYPE37	\# 6 000000000000			; TYPE + Hexadecimal rdata
+@	TYPE37	0	0	0	AA==		; TYPE
+@	cert	0	0	0	AA==		; Type in lower-case
+
+; KO
+@	CERT
+@	CERT						; Empty rdata
+@	CERT	\# 0					; Hex empty rdata
+@	CERT	\#					; Missing hex length
+@	CERT	65536	0	0	AA==		; Type overflow
+@	CERT	0	65536	0	AA==		; Key tag overflow
+@	CERT	0	0	256	AA==		; Algorithm overflow
+@	CERT	0	0	0	A		; Continuous block length must be multiple of 4
+@	CERT	0	0	0	AB		; Continuous block length must be multiple of 4
+@	CERT	0	0	0	ABC		; Continuous block length must be multiple of 4
+@	CERT	0	0	0	AA ==		; Continuous block length must be multiple of 4
+@	CERT	0	0	0	A===		; Bad padding
+@	CERT	0	0	0	=		; Bad padding
+@	CERT	0	0	0	==		; Bad padding
+@	CERT	0	0	0	===		; Bad padding
+@	CERT	0	0	0	====		; Bad padding
+@	CERT	0	0	0			; Missing item
+@	CERT	\# 6 00000000000000			; Too long rdata
+@	CERT	\# 7 000000000000			; Bad rdata length
diff --git a/src/zscanner/test/tests/29_CERT.out b/src/zscanner/test/tests/29_CERT.out
new file mode 100644
index 0000000000000000000000000000000000000000..c0042f34e5948f78e7efc1cb87ef908ad3176070
--- /dev/null
+++ b/src/zscanner/test/tests/29_CERT.out
@@ -0,0 +1,92 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0025
+RDATA=000000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0025
+RDATA=FFFFFFFFFF00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0025
+RDATA=0000000000666F
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0025
+RDATA=0000000000666F6F
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0025
+RDATA=0000000000666F6F62
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0025
+RDATA=0000000000666F6F6261
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0025
+RDATA=000000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0025
+RDATA=000000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0025
+RDATA=000000000000
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_ENUMBER16_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER16_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER8_OVERFLOW
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
diff --git a/src/zscanner/test/tests/30_KEY.in b/src/zscanner/test/tests/30_KEY.in
new file mode 100644
index 0000000000000000000000000000000000000000..8d57bf5f49a654c26620bd0212640cf5a14c8202
--- /dev/null
+++ b/src/zscanner/test/tests/30_KEY.in
@@ -0,0 +1,34 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	KEY	0	0	0	AA==		; The simplest variant
+@	KEY	65535	255	255	AA==		; Maximal numbers
+@	KEY	0	0	0	Zm8=		; One char padding
+@	KEY	0	0	0	Zm9v		; Without padding
+@	KEY	0	0	0	Zm9vYg==	; Two base64 blocks 
+@	KEY	0	0	0	Zm9v YmE=	; Two base64 blocks with blank space between them
+@	TYPE25	\# 5 0000000000				; TYPE + Hexadecimal rdata
+@	TYPE25	0	0	0	AA==		; TYPE
+@	key	0	0	0	AA==		; Type in lower-case
+
+; KO
+@	KEY
+@	KEY						; Empty rdata
+@	KEY	\# 0					; Hex empty rdata
+@	KEY	\#					; Missing hex length
+@	KEY	65536	0	0	AA==		; Type overflow
+@	KEY	0	256	0	AA==		; Key tag overflow
+@	KEY	0	0	256	AA==		; Algorithm overflow
+@	KEY	0	0	0	A		; Continuous block length must be multiple of 4
+@	KEY	0	0	0	AB		; Continuous block length must be multiple of 4
+@	KEY	0	0	0	ABC		; Continuous block length must be multiple of 4
+@	KEY	0	0	0	AA ==		; Continuous block length must be multiple of 4
+@	KEY	0	0	0	A===		; Bad padding
+@	KEY	0	0	0	=		; Bad padding
+@	KEY	0	0	0	==		; Bad padding
+@	KEY	0	0	0	===		; Bad padding
+@	KEY	0	0	0	====		; Bad padding
+@	KEY	0	0	0			; Missing item
+@	KEY	\# 5 000000000000			; Too long rdata
+@	KEY	\# 6 0000000000				; Bad rdata length
diff --git a/src/zscanner/test/tests/30_KEY.out b/src/zscanner/test/tests/30_KEY.out
new file mode 100644
index 0000000000000000000000000000000000000000..aa721d25b14d00219c56deaaacbbbc5c44b8d162
--- /dev/null
+++ b/src/zscanner/test/tests/30_KEY.out
@@ -0,0 +1,92 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0019
+RDATA=0000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0019
+RDATA=FFFFFFFF00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0019
+RDATA=00000000666F
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0019
+RDATA=00000000666F6F
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0019
+RDATA=00000000666F6F62
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0019
+RDATA=00000000666F6F6261
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0019
+RDATA=0000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0019
+RDATA=0000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0019
+RDATA=0000000000
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_ENUMBER16_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER8_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER8_OVERFLOW
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
diff --git a/src/zscanner/test/tests/31_DNSKEY.in b/src/zscanner/test/tests/31_DNSKEY.in
new file mode 100644
index 0000000000000000000000000000000000000000..665d9c8bf3c2714bec0ae63107898a844fb5c4af
--- /dev/null
+++ b/src/zscanner/test/tests/31_DNSKEY.in
@@ -0,0 +1,34 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	DNSKEY	0	0	0	AA==		; The simplest variant
+@	DNSKEY	65535	255	255	AA==		; Maximal numbers
+@	DNSKEY	0	0	0	Zm8=		; One char padding
+@	DNSKEY	0	0	0	Zm9v		; Without padding
+@	DNSKEY	0	0	0	Zm9vYg==	; Two base64 blocks 
+@	DNSKEY	0	0	0	Zm9v YmE=	; Two base64 blocks with blank space between them
+@	TYPE48	\# 5 0000000000				; TYPE + Hexadecimal rdata
+@	TYPE48	0	0	0	AA==		; TYPE
+@	dnskey	0	0	0	AA==		; Type in lower-case
+
+; KO
+@	DNSKEY
+@	DNSKEY						; Empty rdata
+@	DNSKEY	\# 0					; Hex empty rdata
+@	DNSKEY	\#					; Missing hex length
+@	DNSKEY	65536	0	0	AA==		; Type overflow
+@	DNSKEY	0	256	0	AA==		; Key tag overflow
+@	DNSKEY	0	0	256	AA==		; Algorithm overflow
+@	DNSKEY	0	0	0	A		; Continuous block length must be multiple of 4
+@	DNSKEY	0	0	0	AB		; Continuous block length must be multiple of 4
+@	DNSKEY	0	0	0	ABC		; Continuous block length must be multiple of 4
+@	DNSKEY	0	0	0	AA ==		; Continuous block length must be multiple of 4
+@	DNSKEY	0	0	0	A===		; Bad padding
+@	DNSKEY	0	0	0	=		; Bad padding
+@	DNSKEY	0	0	0	==		; Bad padding
+@	DNSKEY	0	0	0	===		; Bad padding
+@	DNSKEY	0	0	0	====		; Bad padding
+@	DNSKEY	0	0	0			; Missing item
+@	DNSKEY	\# 5 000000000000			; Too long rdata
+@	DNSKEY	\# 6 0000000000				; Bad rdata length
diff --git a/src/zscanner/test/tests/31_DNSKEY.out b/src/zscanner/test/tests/31_DNSKEY.out
new file mode 100644
index 0000000000000000000000000000000000000000..99167d7d7176cd5f216a0dfa6734bb406c0396a0
--- /dev/null
+++ b/src/zscanner/test/tests/31_DNSKEY.out
@@ -0,0 +1,92 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0030
+RDATA=0000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0030
+RDATA=FFFFFFFF00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0030
+RDATA=00000000666F
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0030
+RDATA=00000000666F6F
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0030
+RDATA=00000000666F6F62
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0030
+RDATA=00000000666F6F6261
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0030
+RDATA=0000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0030
+RDATA=0000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0030
+RDATA=0000000000
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_ENUMBER16_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER8_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER8_OVERFLOW
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
diff --git a/src/zscanner/test/tests/32_APL.in b/src/zscanner/test/tests/32_APL.in
new file mode 100644
index 0000000000000000000000000000000000000000..ee93bcb754f89b2dfeadf3b4bd0fe2746a449bb8
--- /dev/null
+++ b/src/zscanner/test/tests/32_APL.in
@@ -0,0 +1,30 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	APL				; The simplest variant - blank list
+@	APL	1:0.0.0.0/0		; Minimal ipv4 prefix length
+@	APL	1:255.255.255.255/32	; Maximal ipv4 prefix length
+@	APL	1:255.255.255.255/30	; Prefix length isn't multiple of 8
+@	APL	2:0::0/0		; Minimal ipv6 prefix length
+@	APL	2:0::0/128		; Maximal ipv6 prefix length
+@	APL	2:FFFF:FFFF:FFFF::/2	; Trailing zeroes test
+@	APL	!1:0.0.0.0/0		; Negation flag
+@	APL	1:0.0.0.0/0 1:255.255.255.255/32	; More APLs
+@	TYPE42	\# 4 00010000		; TYPE + Hexadecimal rdata
+@	TYPE42	1:0.0.0.0/0		; TYPE
+@	APL	\# 0			; Zero length rdata
+@	apl	1:0.0.0.0/0		; Type in lower-case
+
+; KO
+@	APL	0:0.0.0.0/32		; Bad address family
+@	APL	x:0.0.0.0/32		; Bad address family 
+@	APL	!x:0.0.0.0/32		; Bad address family 
+@	APL	1:0.0.0.0/33		; Prefix length is too long
+@	APL	2:0::0/129		; Prefix length is too long
+@	APL	2::/0			; Bad ipv6 address
+@	APL	2:0::0/x		; Bad prefix length
+@	APL	1:0.0.0.0/		; Missing prefix length
+@	APL	\#			; Missing hex length
+@	APL	\# 4 0001000000		; Too long rdata
+@	APL	\# 5 00000000		; Bad rdata length
diff --git a/src/zscanner/test/tests/32_APL.out b/src/zscanner/test/tests/32_APL.out
new file mode 100644
index 0000000000000000000000000000000000000000..1471082e5351d6ee90eed03c5672ea4c91ef4d7c
--- /dev/null
+++ b/src/zscanner/test/tests/32_APL.out
@@ -0,0 +1,100 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002A
+RDATA=
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002A
+RDATA=00010000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002A
+RDATA=00012004FFFFFFFF
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002A
+RDATA=00011E04FFFFFFFC
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002A
+RDATA=00020000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002A
+RDATA=00028000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002A
+RDATA=00020201C0
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002A
+RDATA=00010080
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002A
+RDATA=0001000000012004FFFFFFFF
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002A
+RDATA=00010000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002A
+RDATA=00010000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002A
+RDATA=
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002A
+RDATA=00010000
+------
+WARNG=ZSCANNER_EBAD_APL
+------
+WARNG=ZSCANNER_EBAD_APL
+------
+WARNG=ZSCANNER_EBAD_APL
+------
+WARNG=ZSCANNER_EBAD_APL
+------
+WARNG=ZSCANNER_EBAD_APL
+------
+WARNG=ZSCANNER_EBAD_IPV6
+------
+WARNG=ZSCANNER_EBAD_APL
+------
+WARNG=ZSCANNER_EBAD_APL
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
diff --git a/src/zscanner/test/tests/33_DS.in b/src/zscanner/test/tests/33_DS.in
new file mode 100644
index 0000000000000000000000000000000000000000..db6c0ded925099d65acc3cbd8492f876a8f58ecf
--- /dev/null
+++ b/src/zscanner/test/tests/33_DS.in
@@ -0,0 +1,25 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	DS	0	0	0	00		; The simplest variant
+@	DS	65535	255	255	00		; Maximal numbers
+@	DS	0	0	0	01 02 0304	; Hex block with blank spaces between them
+@	TYPE43	\# 5 0000000000				; TYPE + Hexadecimal rdata
+@	TYPE43	0	0	0	00		; TYPE
+@	ds	0	0	0	00		; Type in lower-case
+
+; KO
+@	DS
+@	DS						; Empty rdata
+@	DS	\# 0					; Hex empty rdata
+@	DS	\#					; Missing hex length
+@	DS	65536	0	0	00		; Key tag overflow
+@	DS	0	256	0	00		; Algorithm overflow
+@	DS	0	0	256	00		; Digest type overflow
+@	DS	0	0	0	0		; Continuous block length must be multiple of 2
+@	DS	0	0	0	00 0		; Continuous block length must be multiple of 2
+@	DS	0	0	0	XX		; Bad hex character
+@	DS	0	0	0			; Missing item
+@	DS	\# 5 000000000000			; Too long rdata
+@	DS	\# 6 0000000000				; Bad rdata length
diff --git a/src/zscanner/test/tests/33_DS.out b/src/zscanner/test/tests/33_DS.out
new file mode 100644
index 0000000000000000000000000000000000000000..2b57fb55697f320154291e9846a7845df1eb5032
--- /dev/null
+++ b/src/zscanner/test/tests/33_DS.out
@@ -0,0 +1,62 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002B
+RDATA=0000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002B
+RDATA=FFFFFFFF00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002B
+RDATA=0000000001020304
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002B
+RDATA=0000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002B
+RDATA=0000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002B
+RDATA=0000000000
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_ENUMBER16_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER8_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER8_OVERFLOW
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
diff --git a/src/zscanner/test/tests/34_SSHFP.in b/src/zscanner/test/tests/34_SSHFP.in
new file mode 100644
index 0000000000000000000000000000000000000000..b8b502d988ba41da69b29f0a31d1f2316a3229e5
--- /dev/null
+++ b/src/zscanner/test/tests/34_SSHFP.in
@@ -0,0 +1,24 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	SSHFP	0	0	00		; The simplest variant
+@	SSHFP	255	255	00		; Maximal numbers
+@	SSHFP	0	0	01 02 0304	; Hex block with blank spaces between them
+@	TYPE44	\# 3 000000			; TYPE + Hexadecimal rdata
+@	TYPE44	0	0	00		; TYPE
+@	sshfp	0	0	00		; Type in lower-case
+
+; KO
+@	SSHFP
+@	SSHFP					; Empty rdata
+@	SSHFP	\# 0				; Hex empty rdata
+@	SSHFP	\#				; Missing hex length
+@	SSHFP	256	0	00		; Algorithm overflow
+@	SSHFP	0	256	00		; Fp type overflow
+@	SSHFP	0	0	0		; Continuous block length must be multiple of 2
+@	SSHFP	0	0	00 0		; Continuous block length must be multiple of 2
+@	SSHFP	0	0	XX		; Bad hex character
+@	SSHFP	0	0			; Missing item
+@	SSHFP	\# 3 00000000			; Too long rdata
+@	SSHFP	\# 4 000000			; Bad rdata length
diff --git a/src/zscanner/test/tests/34_SSHFP.out b/src/zscanner/test/tests/34_SSHFP.out
new file mode 100644
index 0000000000000000000000000000000000000000..787074b91f0b5bc89b985957380727bd214857bc
--- /dev/null
+++ b/src/zscanner/test/tests/34_SSHFP.out
@@ -0,0 +1,60 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002C
+RDATA=000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002C
+RDATA=FFFF00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002C
+RDATA=000001020304
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002C
+RDATA=000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002C
+RDATA=000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002C
+RDATA=000000
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_ENUMBER8_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER8_OVERFLOW
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
diff --git a/src/zscanner/test/tests/35_IPSECKEY.in b/src/zscanner/test/tests/35_IPSECKEY.in
new file mode 100644
index 0000000000000000000000000000000000000000..c0e06f8b3e4c01f4bf15956f4275658ecd6d823a
--- /dev/null
+++ b/src/zscanner/test/tests/35_IPSECKEY.in
@@ -0,0 +1,32 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	IPSECKEY	0	0	0	.			; The simplest variant - no gw, no key
+@	IPSECKEY	255	3	255	.	AA==		; Maximal numbers
+@	IPSECKEY	0	1	0	0.0.0.0			; IPv4 address
+@	IPSECKEY	0	2	0	::			; IPv6 address
+@	IPSECKEY	0	3	0	\0320\ \\\"\.\@\*.tld.	; Special chars in domain name
+@	IPSECKEY	0	0	1	.	Zm8=            ; One char padding
+@	IPSECKEY	0	0	1	.	Zm9v            ; Without padding
+@	IPSECKEY	0	0	1	.	Zm9vYg==        ; Two base64 blocks
+@	IPSECKEY	0	0	1	.	Zm9v YmE=       ; Two base64 blocks with blank space between them
+@	TYPE45	\# 3 000000						; TYPE + Hexadecimal rdata
+@	TYPE45		0	0	1	.	AA==		; TYPE
+@	ipseckey	0	0	1	.	AA==		; Type in lower-case
+
+; KO
+@	IPSECKEY
+@	IPSECKEY							; Empty rdata
+@	IPSECKEY	\# 0						; Hex empty rdata
+@	IPSECKEY	\#						; Missing hex length
+@	IPSECKEY	256	0	0	.			; Precedence overflow
+@	IPSECKEY	0	4	0	.			; Unknown gateway
+@	IPSECKEY	0	0	256	.	AA==		; Algorithm overflow
+@	IPSECKEY	0	0	0	.	AA==		; If alg is 0 then key shouldn't be given
+@	IPSECKEY	0	0	0	a%			; Bad domain name char
+@	IPSECKEY	0	0	1	.	A		; Continuous block length must be multiple of 4
+@	IPSECKEY	0	0	1	.	=		; Bad padding
+@	IPSECKEY	0	0					; Missing item
+@	IPSECKEY	\# 3 00000000					; Too long rdata
+@	IPSECKEY	\# 4 000000					; Bad rdata length
diff --git a/src/zscanner/test/tests/35_IPSECKEY.out b/src/zscanner/test/tests/35_IPSECKEY.out
new file mode 100644
index 0000000000000000000000000000000000000000..6865bc72c8b9fe0e47df7cd2248f0a0a2b84a898
--- /dev/null
+++ b/src/zscanner/test/tests/35_IPSECKEY.out
@@ -0,0 +1,100 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002D
+RDATA=000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002D
+RDATA=FF03FF0000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002D
+RDATA=00010000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002D
+RDATA=00020000000000000000000000000000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002D
+RDATA=000300082030205C222E402A03746C6400
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002D
+RDATA=000001666F
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002D
+RDATA=000001666F6F
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002D
+RDATA=000001666F6F62
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002D
+RDATA=000001666F6F6261
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002D
+RDATA=000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002D
+RDATA=00000100
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002D
+RDATA=00000100
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_ENUMBER8_OVERFLOW
+------
+WARNG=ZSCANNER_EBAD_GATEWAY
+------
+WARNG=ZSCANNER_ENUMBER8_OVERFLOW
+------
+WARNG=ZSCANNER_EBAD_GATEWAY_KEY
+------
+WARNG=ZSCANNER_EBAD_GATEWAY
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_GATEWAY_KEY
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
diff --git a/src/zscanner/test/tests/36_RRSIG.in b/src/zscanner/test/tests/36_RRSIG.in
new file mode 100644
index 0000000000000000000000000000000000000000..cd0ae66e8b95abe73b929bd7278c3a25eb2a948b
--- /dev/null
+++ b/src/zscanner/test/tests/36_RRSIG.in
@@ -0,0 +1,47 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	RRSIG	TYPE0	0	0	0	0	0	0	.	AA==	; The simplest variant
+@	RRSIG	A	2	3	4	5	6	7	\008.	CQ==	; Human visual test - block numbering
+@	RRSIG	TYPE65535	255	255	4294967295	4294967295	4294967295	65535	.	AA==	; Maximal numbers
+@	RRSIG	A	0	0	0	19700101000000	0	0	.	AA==	; Minimal date format	
+@	RRSIG	A	0	0	0	0	21051231235959	0	.	AA==	; Maximal date format (zscanner limit)
+@	RRSIG	TYPE0	0	0	0	0	0	0	\0320\ \\\"\.\@\*.tld.	AA==	; Special chars in domain name
+@	RRSIG	A	0	0	0	0	0	0	.	Zm8=		; One char padding
+@	RRSIG	A	0	0	0	0	0	0	.	Zm9v		; Without padding
+@	RRSIG	A	0	0	0	0	0	0	.	Zm9vYg==	; Two base64 blocks 
+@	RRSIG	A	0	0	0	0	0	0	.	Zm9v YmE=	; Two base64 blocks with blank space between them
+@	TYPE46	\# 20 000100000000000000000000000000000000 00 00			; TYPE + Hexadecimal rdata
+@	TYPE46	A       0       0       0       0       0       0       .       AA==	; TYPE
+@	rrsig	A       0       0       0       0       0       0       .       AA==	; Type in lower-case
+
+; KO
+@	RRSIG
+@	RRSIG										; Empty rdata
+@	RRSIG	\# 0									; Hex empty rdata
+@	RRSIG	\#									; Missing hex length
+@	RRSIG	X	0	0	0	0	0	0	.	AA==	; Unknown type
+@	RRSIG	TYPE65536	0	0	0	0	0	0	.	AA==	; Type overflow
+@	RRSIG	A	256	0	0	0	0	0		.	AA==	; Algorithm overflow
+@	RRSIG	A	0	256	0	0	0	0		.	AA==	; Labels overflow
+@	RRSIG	A	0	0	4294967296	0	0	0	.	AA==	; TTL overflow
+@	RRSIG	A	0	0	0	9294967296	0	0	.	AA==	; Sig. exp. overflow
+@	RRSIG	A	0	0	0	0	4294967296	0	.	AA==	; Sig. inc. overflow
+@	RRSIG	A	0	0	0	0	0	65536		.	AA==	; Key tag overflow
+@	RRSIG	A	0	0	0	0	21060101000000	0	.	AA==	; Date overflow
+@	RRSIG	A	0	0	0	0	2106010100000x	0	.	AA==	; Bad timestamp char
+@	RRSIG	A	0	0	0	0	210601010000000	0	.	AA==	; Bad timestamp length
+@	RRSIG	A	0	0	0	0	0	0	a%	AA==	; Bad domain char
+@	RRSIG	A	0	0	0	0	0	0	.	A	; Continuous block length must be multiple of 4	
+@	RRSIG	A	0	0	0	0	0	0	.	AB	; Continuous block length must be multiple of 4
+@	RRSIG	A	0	0	0	0	0	0	.	ABC	; Continuous block length must be multiple of 4
+@	RRSIG	A	0	0	0	0	0	0	.	AA ==	; Continuous block length must be multiple of 4
+@	RRSIG	A	0	0	0	0	0	0	.	A===	; Bad padding	
+@	RRSIG	A	0	0	0	0	0	0	.	=	; Bad padding
+@	RRSIG	A	0	0	0	0	0	0	.	==	; Bad padding
+@	RRSIG	A	0	0	0	0	0	0	.	===	; Bad padding
+@	RRSIG	A	0	0	0	0	0	0	.	====	; Bad padding
+@	RRSIG	A	0	0	0	0	0	0	.		; Missing item
+@	RRSIG	\# 20 000100000000000000000000000000000000 00 0000			; Too long rdata
+@	RRSIG	\# 21 000100000000000000000000000000000000 00 00			; Bad rdata length
diff --git a/src/zscanner/test/tests/36_RRSIG.out b/src/zscanner/test/tests/36_RRSIG.out
new file mode 100644
index 0000000000000000000000000000000000000000..7d1af4e822f8fdaddbda983733576fb8e964ecdf
--- /dev/null
+++ b/src/zscanner/test/tests/36_RRSIG.out
@@ -0,0 +1,134 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002E
+RDATA=000000000000000000000000000000000000 00 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002E
+RDATA=000102030000000400000005000000060007 010800 09
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002E
+RDATA=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 00 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002E
+RDATA=000100000000000000000000000000000000 00 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002E
+RDATA=000100000000000000000000FFCEDD7F0000 00 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002E
+RDATA=000000000000000000000000000000000000 082030205C222E402A03746C6400 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002E
+RDATA=000100000000000000000000000000000000 00 666F
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002E
+RDATA=000100000000000000000000000000000000 00 666F6F
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002E
+RDATA=000100000000000000000000000000000000 00 666F6F62
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002E
+RDATA=000100000000000000000000000000000000 00 666F6F6261
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002E
+RDATA=000100000000000000000000000000000000 00 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002E
+RDATA=000100000000000000000000000000000000 00 00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002E
+RDATA=000100000000000000000000000000000000 00 00
+------
+WARNG=ZSCANNER_EUNSUPPORTED_TYPE
+------
+WARNG=ZSCANNER_EUNSUPPORTED_TYPE
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EUNSUPPORTED_TYPE
+------
+WARNG=ZSCANNER_ENUMBER16_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER8_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER8_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER32_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER32_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER32_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER16_OVERFLOW
+------
+WARNG=ZSCANNER_EBAD_DATE
+------
+WARNG=ZSCANNER_EBAD_TIMESTAMP_CHAR
+------
+WARNG=ZSCANNER_EBAD_TIMESTAMP_LENGTH
+------
+WARNG=ZSCANNER_EBAD_DNAME_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
diff --git a/src/zscanner/test/tests/37_NSEC.in b/src/zscanner/test/tests/37_NSEC.in
new file mode 100644
index 0000000000000000000000000000000000000000..e424816d62b632ba0da3889adfb7d4219a88df57
--- /dev/null
+++ b/src/zscanner/test/tests/37_NSEC.in
@@ -0,0 +1,23 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	NSEC	.					; The simplest variant - without bitmap
+@	NSEC	\0320\ \\\"\.\@\*.tld.			; Special chars in domain name
+@	NSEC	.	TYPE0				; Minimal type number
+@	NSEC	.	TYPE65535			; Maximal type number
+@	NSEC	.	TYPE0 A NS			; First bitmap window
+@	NSEC	.	TYPE0 TYPE256 TYPE512 TYPE32768	; First, second, third and 128. bitmap window
+@	TYPE47	\# 1 00					; TYPE + Hexadecimal rdata
+@	TYPE47	.					; TYPE
+@	nsec	.					; Type in lower-case
+
+; KO
+@	NSEC
+@	NSEC						; Empty rdata
+@	NSEC	\# 0					; Hex empty rdata
+@	NSEC	\#					; Missing hex length
+@	NSEC	.	TYPE65536			; Type number overflow
+@	NSEC	.	X				; Unknown type
+@	NSEC	\# 1 0000				; Too long rdata
+@	NSEC	\# 2 00					; Bad rdata length
diff --git a/src/zscanner/test/tests/37_NSEC.out b/src/zscanner/test/tests/37_NSEC.out
new file mode 100644
index 0000000000000000000000000000000000000000..b6e57a4b5e1125fd61216cd3f064219cb17585c9
--- /dev/null
+++ b/src/zscanner/test/tests/37_NSEC.out
@@ -0,0 +1,70 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002F
+RDATA=00 
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002F
+RDATA=082030205C222E402A03746C6400 
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002F
+RDATA=00 000180
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002F
+RDATA=00 FF200000000000000000000000000000000000000000000000000000000000000001
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002F
+RDATA=00 0001E0
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002F
+RDATA=00 000180010180020180800180
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002F
+RDATA=00 
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002F
+RDATA=00 
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=002F
+RDATA=00 
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_ENUMBER16_OVERFLOW
+------
+WARNG=ZSCANNER_EBAD_BITMAP
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
diff --git a/src/zscanner/test/tests/38_DHCID.in b/src/zscanner/test/tests/38_DHCID.in
new file mode 100644
index 0000000000000000000000000000000000000000..9a1033d7c74f1424e72fe588de3037ab29aa6683
--- /dev/null
+++ b/src/zscanner/test/tests/38_DHCID.in
@@ -0,0 +1,29 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	DHCID	AA==		; The simplest variant
+@	DHCID	Zm8=		; One char padding
+@	DHCID	Zm9v		; Without padding
+@	DHCID	Zm9vYg==	; Two base64 blocks 
+@	DHCID	Zm9v YmE=	; Two base64 blocks with blank space between them
+@	TYPE49	\# 1 00		; TYPE + Hexadecimal rdata
+@	TYPE49	AA==		; TYPE
+@	dhcid	AA==		; Type in lower-case
+
+; KO
+@	DHCID
+@	DHCID			; Empty rdata
+@	DHCID	\# 0		; Hex empty rdata
+@	DHCID	\#		; Missing hex length
+@	DHCID	A		; Continuous block length must be multiple of 4
+@	DHCID	AB		; Continuous block length must be multiple of 4
+@	DHCID	ABC		; Continuous block length must be multiple of 4
+@	DHCID	AA ==		; Continuous block length must be multiple of 4
+@	DHCID	A===		; Bad padding
+@	DHCID	=		; Bad padding
+@	DHCID	==		; Bad padding
+@	DHCID	===		; Bad padding
+@	DHCID	====		; Bad padding
+@	DHCID	\# 1 0000	; Too long rdata
+@	DHCID	\# 2 00		; Bad rdata length
diff --git a/src/zscanner/test/tests/38_DHCID.out b/src/zscanner/test/tests/38_DHCID.out
new file mode 100644
index 0000000000000000000000000000000000000000..41774e3ee37da9d4a9af1379877d5c96da438d73
--- /dev/null
+++ b/src/zscanner/test/tests/38_DHCID.out
@@ -0,0 +1,78 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0031
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0031
+RDATA=666F
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0031
+RDATA=666F6F
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0031
+RDATA=666F6F62
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0031
+RDATA=666F6F6261
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0031
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0031
+RDATA=00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0031
+RDATA=00
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE64_CHAR
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
diff --git a/src/zscanner/test/tests/39_NSEC3.in b/src/zscanner/test/tests/39_NSEC3.in
new file mode 100644
index 0000000000000000000000000000000000000000..ba8bdcb25e2bddae3f20d51e394e9f916f9458b2
--- /dev/null
+++ b/src/zscanner/test/tests/39_NSEC3.in
@@ -0,0 +1,49 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	NSEC3	0	0	0	-	00======		; The simplest variant - without bitmap
+@	NSEC3	255	255	65535	-	00======		; Maximal numbers
+@	NSEC3	0	0	0	00FF	00======		; Hex string
+@	NSEC3	0	0	0	-	00======		; Eight char padding
+@	NSEC3	0	0	0	-	CPNG====		; Four char padding
+@	NSEC3	0	0	0	-	CPNMU===		; Three char padding
+@	NSEC3	0	0	0	-	CPNMUOG=		; One char padding
+@	NSEC3	0	0	0	-	CPNMUOJ1		; Without padding
+@	NSEC3	0	0	0	-	CPNMUOJ1E8======	; Two base32hex blocks
+@	NSEC3	0	0	0	-	00======	TYPE0		; Minimal type number
+@	NSEC3	0	0	0	-	00======	TYPE65535	; Maximal type number
+@	NSEC3	0	0	0	-	00======	TYPE0 A NS	; First bitmap window
+@	NSEC3	0	0	0	-	00======	TYPE0 TYPE256 TYPE512 TYPE32768	; First, second, third and 128. bitmap window
+@	TYPE50	\# 7 00000000000100					; TYPE + Hexadecimal rdata
+@	TYPE50	0	0	0	-       00======		; TYPE
+@	nsec3	0	0	0	-       00======		; Type in lower-case
+
+; KO
+@	NSEC3
+@	NSEC3								; Empty rdata
+@	NSEC3	\# 0							; Hex empty rdata
+@	NSEC3	\#							; Missing hex length
+@	NSEC3	256	0	0	-	00======		; Algorithm overflow
+@	NSEC3	0	256	0	-	00======		; Flags overflow
+@	NSEC3	0	0	65536	-	00======		; Iterations overflow
+@	NSEC3	0	0	0	0	00======		; Hex block must be multiple of 2
+@	NSEC3	0	0	0	0X	00======		; Bad hex char
+@	NSEC3	0	0	0	00 FF	00======		; Hex string with blank space inside
+@	NSEC3	0	0	0	-	1			; Continuous block length must be multiple of 8
+@	NSEC3	0	0	0	-	12			; Continuous block length must be multiple of 8
+@	NSEC3	0	0	0	-	123			; Continuous block length must be multiple of 8
+@	NSEC3	0	0	0	-	1234			; Continuous block length must be multiple of 8
+@	NSEC3	0	0	0	-	12345			; Continuous block length must be multiple of 8
+@	NSEC3	0	0	0	-	123456			; Continuous block length must be multiple of 8
+@	NSEC3	0	0	0	-	1234567			; Continuous block length must be multiple of 8
+@	NSEC3	0	0	0	-	123456 78		; Continuous block length must be multiple of 8
+@	NSEC3	0	0	0	-	========		; Bad padding
+@	NSEC3	0	0	0	-	1=======		; Bad padding
+@	NSEC3	0	0	0	-	123=====		; Bad padding
+@	NSEC3	0	0	0	-	123456==		; Bad padding
+@	NSEC3	0	0	0	-	CPNMUOJ1  E8======	; Two base32hex blocks with blank space between them
+@	NSEC3	0	0	0	-	00======	TYPE65536	; Type number overflow
+@	NSEC3	0	0	0	-	00======	X		; Unknown type
+@	NSEC3	\# 7 0000000000010000					; Too long rdata
+@	NSEC3	\# 8 00000000000100					; Bad rdata length
diff --git a/src/zscanner/test/tests/39_NSEC3.out b/src/zscanner/test/tests/39_NSEC3.out
new file mode 100644
index 0000000000000000000000000000000000000000..ef533f58778075183c5f153337fff37d1a7ee55f
--- /dev/null
+++ b/src/zscanner/test/tests/39_NSEC3.out
@@ -0,0 +1,150 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0032
+RDATA=00000000000100
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0032
+RDATA=FFFFFFFF000100
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0032
+RDATA=000000000200FF0100
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0032
+RDATA=00000000000100
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0032
+RDATA=000000000002666F
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0032
+RDATA=000000000003666F6F
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0032
+RDATA=000000000004666F6F62
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0032
+RDATA=000000000005666F6F6261
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0032
+RDATA=000000000006666F6F626172
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0032
+RDATA=00000000000100000180
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0032
+RDATA=00000000000100FF200000000000000000000000000000000000000000000000000000000000000001
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0032
+RDATA=000000000001000001E0
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0032
+RDATA=00000000000100000180010180020180800180
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0032
+RDATA=00000000000100
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0032
+RDATA=00000000000100
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0032
+RDATA=00000000000100
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_ENUMBER8_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER8_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER16_OVERFLOW
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE32HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE32HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE32HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE32HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE32HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE32HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE32HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE32HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE32HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE32HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE32HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE32HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_BASE32HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_BITMAP
+------
+WARNG=ZSCANNER_ENUMBER16_OVERFLOW
+------
+WARNG=ZSCANNER_EBAD_BITMAP
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
diff --git a/src/zscanner/test/tests/40_NSEC3PARAM.in b/src/zscanner/test/tests/40_NSEC3PARAM.in
new file mode 100644
index 0000000000000000000000000000000000000000..b397591e514ab9fd002c201da3c52902fe5bb309
--- /dev/null
+++ b/src/zscanner/test/tests/40_NSEC3PARAM.in
@@ -0,0 +1,26 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	NSEC3PARAM	0	0	0	-		; The simplest variant
+@	NSEC3PARAM	255	255	65535	-		; Maximal numbers
+@	NSEC3PARAM	0	0	0	0102FF		; Hex string
+@	TYPE51	\# 5 0000000000					; TYPE + Hexadecimal rdata
+@	TYPE51		0       0       0       -		; TYPE
+@	nsec3param	0       0       0       -		; Type in lower-case
+
+; KO
+@	NSEC3PARAM
+@	NSEC3PARAM						; Empty rdata
+@	NSEC3PARAM	\# 0					; Hex empty rdata
+@	NSEC3PARAM	\#					; Missing hex length
+@	NSEC3PARAM	256	0	0	00		; Algorithm overflow
+@	NSEC3PARAM	0	256	0	00		; Flags overflow
+@	NSEC3PARAM	0	0	65536	00		; Iterations overflow
+@	NSEC3PARAM	0	0	0	0		; Hex block length must be multiple of 2
+@	NSEC3PARAM	0	0	0	0x		; Bad hex char
+@	NSEC3PARAM	0	0	0	00 00		; Hex block must not contain blank spaces
+@	NSEC3PARAM	0	0	0	00 x		; Unexpected item
+@	NSEC3PARAM	0	0	0			; Missing item
+@	NSEC3PARAM	\# 5 000000000000			; Too long rdata
+@	NSEC3PARAM	\# 6 0000000000				; Bad rdata length
diff --git a/src/zscanner/test/tests/40_NSEC3PARAM.out b/src/zscanner/test/tests/40_NSEC3PARAM.out
new file mode 100644
index 0000000000000000000000000000000000000000..85f9f74f76816115404d169d00d37add1bbf52cf
--- /dev/null
+++ b/src/zscanner/test/tests/40_NSEC3PARAM.out
@@ -0,0 +1,64 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0033
+RDATA=0000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0033
+RDATA=FFFFFFFF00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0033
+RDATA=00000000030102FF
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0033
+RDATA=0000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0033
+RDATA=0000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0033
+RDATA=0000000000
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_ENUMBER8_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER8_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER16_OVERFLOW
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_REST
+------
+WARNG=ZSCANNER_EBAD_REST
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
diff --git a/src/zscanner/test/tests/41_TLSA.in b/src/zscanner/test/tests/41_TLSA.in
new file mode 100644
index 0000000000000000000000000000000000000000..d28f426ee73b64eab1acb240c92fc301c4be1c92
--- /dev/null
+++ b/src/zscanner/test/tests/41_TLSA.in
@@ -0,0 +1,24 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	TLSA	0	0	0	00		; The simplest variant
+@	TLSA	255	255	255	00		; Maximal numbers
+@	TLSA	0	0	0	0102 00 FF	; Hex string with blank spaces inside
+@	TYPE52	\# 4 00000000				; TYPE + Hexadecimal rdata
+@	TYPE52	0       0       0       00		; TYPE
+@	tlsa	0       0       0       00		; Type in lower-case
+
+; KO
+@	TLSA
+@	TLSA						; Empty rdata
+@	TLSA	\# 0					; Hex empty rdata
+@	TLSA	\#					; Missing hex length
+@	TLSA	256	0	0	00		; Algorithm overflow
+@	TLSA	0	256	0	00		; Flags overflow
+@	TLSA	0	0	256	00		; Iterations overflow
+@	TLSA	0	0	0	0		; Hex block length must be multiple of 2
+@	TLSA	0	0	0	0x		; Bad hex char
+@	TLSA	0	0	0			; Missing item
+@	TLSA	\# 4 0000000000				; Too long rdata
+@	TLSA	\# 5 00000000				; Bad rdata length
diff --git a/src/zscanner/test/tests/41_TLSA.out b/src/zscanner/test/tests/41_TLSA.out
new file mode 100644
index 0000000000000000000000000000000000000000..ebe5eaa31653c9daf549eac62b95501fec9facb5
--- /dev/null
+++ b/src/zscanner/test/tests/41_TLSA.out
@@ -0,0 +1,60 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0034
+RDATA=00000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0034
+RDATA=FFFFFF00
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0034
+RDATA=000000010200FF
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0034
+RDATA=00000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0034
+RDATA=00000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=0034
+RDATA=00000000
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_ENUMBER8_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER8_OVERFLOW
+------
+WARNG=ZSCANNER_ENUMBER8_OVERFLOW
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
diff --git a/src/zscanner/test/tests/42_LOC.in b/src/zscanner/test/tests/42_LOC.in
new file mode 100644
index 0000000000000000000000000000000000000000..7aae50f7dc3d23d08c79f15b6e5093bef05e53a0
--- /dev/null
+++ b/src/zscanner/test/tests/42_LOC.in
@@ -0,0 +1,67 @@
+$ORIGIN	.
+$TTL	1
+
+; OK
+@	LOC	1     N 1     E	0			; The simplest case
+@	LOC	0 1   N 1     E 0			; Combination of parameters 
+@	LOC	0 0 1 N 1     E 0			; Combination of parameters
+@	LOC	1     N 0 1   E 0			; Combination of parameters
+@	LOC	1     N 0 0 1 E 0			; Combination of parameters
+@	LOC	1     N 0 0 1 E 0m			; Combination of parameters
+@	LOC	1     N 1     E 0 1			; Combination of parameters
+@	LOC	1     N 1     E 0 1m			; Combination of parameters
+@	LOC	1     N 1     E 0 0 1			; Combination of parameters
+@	LOC	1     N 1     E 0 0 1m			; Combination of parameters
+@	LOC	1     N 1     E 0 0 0 1			; Combination of parameters
+@	LOC	1     N 1     E 0 0 0 1m		; Combination of parameters
+@	LOC	0 0 0 N 0 0 0 E	-100000.00 0 0 0	; Minimal values
+@	LOC	90 59 59.999 S 180 59 59.999 W 42849672.95m 90000000.00m 90000000.00m 90000000.00m	; Maximal values
+@	LOC	0     S 0 0 0.001 W 0			; Float dd.ddd test
+@	LOC	0     S 0 0 0.01  W 0			; Float dd.ddd test
+@	LOC	0     S 0 0 0.1   W 0			; Float dd.ddd test
+@	LOC	0     S 0 0 1.0   W 0			; Float dd.ddd test
+@	LOC	0     S 0 0 10    W 0			; Float dd.ddd test
+@	LOC	0     S 0     W 0 0.01			; Number to [mantisa,exponent] test
+@	LOC	0     S 0     W 0 0.10			; Number to [mantisa,exponent] test 
+@	LOC	0     S 0     W 0 1.0			; Number to [mantisa,exponent] test
+@	LOC	0     S 0     W 0 10			; Number to [mantisa,exponent] test
+@	LOC	0     S 0     W 0 100			; Number to [mantisa,exponent] test
+@	LOC	0     S 0     W 0 1000			; Number to [mantisa,exponent] test
+@	LOC	0     S 0     W 0 10000			; Number to [mantisa,exponent] test
+@	LOC	0     S 0     W 0 100000		; Number to [mantisa,exponent] test
+@	LOC	0     S 0     W 0 1000000		; Number to [mantisa,exponent] test
+@	LOC	0     S 0     W 0 10000000		; Number to [mantisa,exponent] test
+@	LOC	\# 16 00 00 00 00 00000000 00000000 00000000	; Hexadecimal rdata
+@	TYPE29	\# 16 00 00 00 00 00000000 00000000 00000000	; TYPE + Hexadecimal rdata
+@	TYPE29	0     N 0     E 0			; TYPE
+@	loc	0     N 0     E 0			; Type in lower-case
+
+; KO
+@	LOC
+@	LOC						; Empty rdata
+@	LOC	\# 0					; Hex empty rdata
+@	LOC	\#					; Missing hex length
+@	LOC	91 0 0 N 0 0 0 E 0 0 0 0		; Degree overflow
+@	LOC	0 60 0 N 0 0 0 E 0 0 0 0		; Minute overflow
+@	LOC	0 0 60 0 N 0 0 0 E 0 0 0 0		; Second overflow
+@	LOC	0 0 0 N 181 0 0 E 0 0 0 0		; Degree overflow
+@	LOC	0 0 0 N 0 60 0 E 0 0 0 0		; Minute overflow
+@	LOC	0 0 0 N 0 0 60 E 0 0 0 0		; Second overflow
+@	LOC	0 0 0 N 0 0 0 E 42849672.96 0 0 0	; Altitude overflow
+@	LOC	0 0 0 N 0 0 0 E 42849673 0 0 0		; Altitude overflow
+@	LOC	0 0 0 N 0 0 0 E -100000.01 0 0 0	; Altitude underflow
+@	LOC	0 0 0 N 0 0 0 E -100001 0 0 0		; Altitude underflow
+@	LOC	0 0 0 N 0 0 0 E 0 90000000.01 0 0	; Size overflow
+@	LOC	0 0 0 N 0 0 0 E 0 90000001 0 0		; Size overflow
+@	LOC	0 0 0 N 0 0 0 E 0 0 90000000.01 0	; HP overflow
+@	LOC	0 0 0 N 0 0 0 E 0 0 90000001 0		; HP overflow
+@	LOC	0 0 0 N 0 0 0 E 0 0 0 90000000.01	; VP overflow
+@	LOC	0 0 0 N 0 0 0 E 0 0 0 90000001		; VP overflow
+@	LOC	1       1     E	0			; Missing N or S
+@	LOC	1     x 1     E	0			; Bad letter
+@	LOC	1     N 1      	0			; Missing E or W
+@	LOC	1     N 1     x	0			; Bad letter
+@	LOC	1     N 1     E				; Missing altitude
+@	LOC	0 0 0 N 0 0 0 E 0 0 0 0 x		; Unexpected item
+@	LOC	\# 16 00 00 00 00 00000000 00000000 00000000 00	; Too long rdata
+@	LOC	\# 17 00 00 00 00 00000000 00000000 00000000	; Bad rdata length
diff --git a/src/zscanner/test/tests/42_LOC.out b/src/zscanner/test/tests/42_LOC.out
new file mode 100644
index 0000000000000000000000000000000000000000..ab939eb2083b31bbec2680b80d9992024935a135
--- /dev/null
+++ b/src/zscanner/test/tests/42_LOC.out
@@ -0,0 +1,254 @@
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=001216138036EE808036EE8000989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=001216138000EA608036EE8000989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=00121613800003E88036EE8000989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=001216138036EE808000EA6000989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=001216138036EE80800003E800989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=001216138036EE80800003E800989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=001216138036EE808036EE8000989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=001216138036EE808036EE8000989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=000012138036EE808036EE8000989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=000012138036EE808036EE8000989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=000000128036EE808036EE8000989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=000000128036EE808036EE8000989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=00000000800000008000000000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=009999996C79388159295F81FFFFFFFF
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=00121613800000007FFFFFFF00989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=00121613800000007FFFFFF600989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=00121613800000007FFFFF9C00989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=00121613800000007FFFFC1800989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=00121613800000007FFFD8F000989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=00101613800000008000000000989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=00111613800000008000000000989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=00121613800000008000000000989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=00131613800000008000000000989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=00141613800000008000000000989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=00151613800000008000000000989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=00161613800000008000000000989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=00171613800000008000000000989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=00181613800000008000000000989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=00191613800000008000000000989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=00000000000000000000000000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=00000000000000000000000000000000
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=00121613800000008000000000989680
+------
+OWNER=00
+CLASS=0001
+RRTTL=00000001
+RTYPE=001D
+RDATA=00121613800000008000000000989680
+------
+WARNG=ZSCANNER_EBAD_LOC_DATA
+------
+WARNG=ZSCANNER_EBAD_LOC_DATA
+------
+WARNG=ZSCANNER_EBAD_HEX_CHAR
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_NUMBER
+------
+WARNG=ZSCANNER_EBAD_LOC_DATA
+------
+WARNG=ZSCANNER_EBAD_LOC_DATA
+------
+WARNG=ZSCANNER_EBAD_LOC_DATA
+------
+WARNG=ZSCANNER_EBAD_LOC_DATA
+------
+WARNG=ZSCANNER_EBAD_LOC_DATA
+------
+WARNG=ZSCANNER_EBAD_LOC_DATA
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
+WARNG=ZSCANNER_EBAD_RDATA_LENGTH
+------
diff --git a/src/zscanner/test/tests/includes/include1 b/src/zscanner/test/tests/includes/include1
new file mode 100644
index 0000000000000000000000000000000000000000..9de185968184289b43bb5f24577276260303e196
--- /dev/null
+++ b/src/zscanner/test/tests/includes/include1
@@ -0,0 +1,9 @@
+$TTL	1
+
+a	NS	@
+
+$ORIGIN	tld1a.
+a	NS	@
+
+$ORIGIN	tld1b.
+a	NS	@
diff --git a/src/zscanner/test/tests/includes/include2 b/src/zscanner/test/tests/includes/include2
new file mode 100644
index 0000000000000000000000000000000000000000..1e14e96018358875a2f4342b0ec161aa624400ab
--- /dev/null
+++ b/src/zscanner/test/tests/includes/include2
@@ -0,0 +1,6 @@
+$TTL	1H
+
+b	NS	@
+
+$ORIGIN	tld1a.
+b	NS	@
diff --git a/src/zscanner/test/tests/includes/include3 b/src/zscanner/test/tests/includes/include3
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/zscanner/test/tests/includes/include4 b/src/zscanner/test/tests/includes/include4
new file mode 100644
index 0000000000000000000000000000000000000000..7e8d5e29e8f14805ef031f3f0e4ce240b86048ba
--- /dev/null
+++ b/src/zscanner/test/tests/includes/include4
@@ -0,0 +1 @@
+a	NS	; Missing data
diff --git a/src/zscanner/test/tests/includes/include5 b/src/zscanner/test/tests/includes/include5
new file mode 100644
index 0000000000000000000000000000000000000000..ac98e01b6d073e5817a8988195a9d77cc4301bf8
--- /dev/null
+++ b/src/zscanner/test/tests/includes/include5
@@ -0,0 +1 @@
+$TTL	x	; Bad number
diff --git a/src/zscanner/test/tests/includes/include6 b/src/zscanner/test/tests/includes/include6
new file mode 100644
index 0000000000000000000000000000000000000000..b5e8cb84b23fea245bbf785f2324a7b0a492ecff
--- /dev/null
+++ b/src/zscanner/test/tests/includes/include6
@@ -0,0 +1 @@
+$INCLUDE include2	; Include in include
diff --git a/src/zscanner/test/zscanner_test.c b/src/zscanner/test/zscanner_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..0853784c0ebd6d80dffad1a174b7a2ae206ad416
--- /dev/null
+++ b/src/zscanner/test/zscanner_test.c
@@ -0,0 +1,160 @@
+/*  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/>.
+*/
+
+#include <inttypes.h>			// PRIu64
+#include <stdio.h>			// printf
+#include <stdlib.h>			// atoi
+#include <getopt.h>			// getopt
+
+#include "common/errcode.h"		// knot_strerror
+#include "zscanner/file_loader.h"	// file_loader
+#include "zscanner/test/processing.h"	// processing functions
+#include "zscanner/test/tests.h"	// test functions
+
+#define DEFAULT_MODE	1
+
+/*! \brief Prints help. */
+void help(int argc, char **argv)
+{
+	printf("\nZone scanner testing tool.\n"
+	       "Usage: %s [parameters] origin zonefile\n", argv[0]);
+	printf("Parameters:\n"
+	       " -m [0,1,2]   Processing mode.\n"
+	       "     0        Empty output.\n"
+	       "     1        Debug output (DEFAULT).\n"
+	       "     2        Test output.\n"
+	       " -t           Launch unit tests.\n"
+	       " -h           Print this help.\n");
+}
+
+int main(int argc, char *argv[])
+{
+	// Parsed command line arguments.
+	int c = 0, li = 0;
+	int ret, mode = DEFAULT_MODE, test = 0;
+	file_loader_t *fl;
+	const char *origin;
+	const char *zone_file;
+
+	// Command line long options.
+	struct option opts[] = {
+		{"mode",	required_argument, 0, 'm'},
+		{"test",	no_argument,	   0, 't'},
+		{"help",	no_argument,	   0, 'h'},
+		{0, 		0, 		   0, 0}
+	};
+
+	// Command line options processing.
+	while ((c = getopt_long(argc, argv, "m:th", opts, &li)) != -1) {
+		switch (c) {
+		case 'm':
+			mode = atoi(optarg);
+			break;
+		case 't':
+			test = 1;
+			break;
+		case 'h': // Fall through.
+		default:
+			help(argc, argv);
+			return EXIT_FAILURE;
+		}
+	}
+
+	if (test == 1) {
+		test__date_to_timestamp();
+	} else {
+		// Check if there are 2 remaining non-options.
+		if (argc - optind != 2) {
+			help(argc, argv);
+			return EXIT_FAILURE;
+		}
+
+		zone_file = argv[optind];
+		origin = argv[optind + 1];
+
+		// Create appropriate file loader.
+		switch (mode) {
+		case 0:
+			fl = file_loader_create(origin,
+						zone_file,
+						DEFAULT_CLASS,
+						DEFAULT_TTL,
+						&empty_process_record,
+						&empty_process_error,
+						NULL);
+			break;
+		case 1:
+			fl = file_loader_create(origin,
+						zone_file,
+						DEFAULT_CLASS,
+						DEFAULT_TTL,
+						&debug_process_record,
+						&debug_process_error,
+						NULL);
+			break;
+		case 2:
+			fl = file_loader_create(origin,
+						zone_file,
+						DEFAULT_CLASS,
+						DEFAULT_TTL,
+						&test_process_record,
+						&test_process_error,
+						NULL);
+			break;
+		default:
+			printf("Bad mode number!\n");
+			help(argc, argv);
+			return EXIT_FAILURE;
+		}
+
+		// Check file loader.
+		if (fl != NULL) {
+			ret = file_loader_process(fl);
+
+			switch (ret) {
+			case KNOT_EOK:
+				if (mode == DEFAULT_MODE) {
+					printf("Zone file has been processed "
+					       "successfully\n");
+				}
+				file_loader_free(fl);
+				break;
+
+			case FLOADER_ESCANNER:
+				if (mode == DEFAULT_MODE) {
+					printf("Zone processing has stopped with "
+					       "%"PRIu64" warnings/errors!\n",
+					       fl->scanner->error_counter);
+				}
+				file_loader_free(fl);
+				return EXIT_FAILURE;
+
+			default:
+				if (mode == DEFAULT_MODE) {
+					printf("%s\n", knot_strerror(ret));
+				}
+				file_loader_free(fl);
+				return EXIT_FAILURE;
+			}
+		} else {
+			printf("File open error!\n");
+			return EXIT_FAILURE;
+		}
+	}
+
+	return EXIT_SUCCESS;
+}
+