diff --git a/.gitignore b/.gitignore
index bd147dd7cb723722356fe4fd64495a5383e41190..96c13d2fc0fc2445f70197f7a293f133dcb179c9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -67,3 +67,7 @@ parsetab.py
 /doc/sphinx/_doclib/_inc_bin.cfg-app.rst
 /doc/sphinx/_doclib/_inc_bin.cfg-daemon.rst
 /doc/sphinx/_doclib/_inc_bin.cfg-script.rst
+
+# Ignore local lightweight chroot.
+/chroot/
+
diff --git a/Makefile b/Makefile
index 3cf7b0812051cb7c943286a62ea669a21918f063..e7898b2bc2c3700b7c6384580f948a180072f9d3 100644
--- a/Makefile
+++ b/Makefile
@@ -96,6 +96,7 @@ help:
 	@echo "  $(BLUE)$(BOLD)HELPER TARGETS$(NC)"
 	@echo "  $(BLUE)$(BOLD)──────────────$(NC)"
 	@echo "  * $(GREEN)deps-prerequisites$(NC): check for development prerequisites"
+	@echo "  * $(GREEN)deps-lwchroot$(NC): creating local lightweight chroot subdirectory structure"
 	@echo "  * $(GREEN)deps-python$(NC): install Python dependencies"
 	@echo "  * $(GREEN)deps-python-dev$(NC): install Python development dependencies"
 	@echo "  * $(GREEN)deps-python-upgrade$(NC): upgrade Python dependencies to latest versions"
@@ -107,9 +108,12 @@ help:
 	@echo "  * $(GREEN)deps-postgresql$(NC): configure required PostgreSQL user accounts and databases"
 	@echo "  * $(GREEN)deps-translations$(NC): compile all available translations"
 	@echo ""
-	@echo "  * $(GREEN)run-webui-dev$(NC): run development web server with development configuration on  on $(DEV_SERVER):$(DEV_PORT)"
+	@echo "  * $(GREEN)run-mentat-dev$(NC): run development version of Mentat system"
+	@echo "  * $(GREEN)run-webui-dev$(NC): run development web server with development configuration on $(DEV_SERVER):$(DEV_PORT)"
 	@echo "  * $(GREEN)run-mailserver-dev$(NC): run development mail server on $(DEV_MAIL_SERVER):$(DEV_MAIL_PORT)"
 	@echo ""
+	@echo "  * $(GREEN)ctrl-mentat-dev COMMAND=cmd$(NC): execute mentat-controller.py with given command $(FAINT)cmd$(NC)"
+	@echo ""
 	@echo "  * $(GREEN)clean-pycs$(NC): clean up Python compiled files"
 	@echo "  * $(GREEN)clean-build-python$(NC): clean up Python build directories"
 	@echo "  * $(GREEN)clean-build-debian$(NC):  clean up Debian build directories"
@@ -187,6 +191,18 @@ develop: FORCE
 	@echo "\n$(GREEN)*** Installing project into virtual environment in editable mode ***$(NC)\n"
 	@. $(VENV_PATH)/bin/activate && $(PIP) install -e ".[dev]"
 
+	@echo "\n$(GREEN)*** Creating local lightweight chroot directory structure ***$(NC)\n"
+	mkdir -p ./chroot/etc
+	mkdir -p ./chroot/var/mentat/backups
+	mkdir -p ./chroot/var/mentat/cache
+	mkdir -p ./chroot/var/mentat/charts
+	mkdir -p ./chroot/var/mentat/log
+	mkdir -p ./chroot/var/mentat/reports
+	mkdir -p ./chroot/var/mentat/rrds
+	mkdir -p ./chroot/var/mentat/run
+	mkdir -p ./chroot/var/mentat/spool;
+	-ln -s $(shell realpath ./conf) $(shell realpath ./chroot/etc)/mentat
+
 	@echo "\n$(CYAN)Your development environment is ready in `. $(VENV_PATH)/bin/activate && python -c 'import sys; print(sys.prefix)'`.$(NC)\n"
 	@echo "Please activate it manually with following command:\n"
 	@echo "\t$(ORANGE). $(VENV_PATH)/bin/activate$(NC)\n"
@@ -196,7 +212,7 @@ develop: FORCE
 #
 # Install and configure project dependencies.
 #
-deps: deps-prerequisites deps-python deps-python-dev deps-webui deps-geoip deps-negistry deps-postgresql translations-compile
+deps: deps-prerequisites deps-lwchroot deps-python deps-python-dev deps-webui deps-geoip deps-negistry deps-postgresql translations-compile
 
 #
 # Cleanup development and build environment.
@@ -248,6 +264,22 @@ deps-prerequisites: FORCE
 	done
 	@echo ""
 
+#
+# Install project`s lightweight chroot.
+#
+deps-lwchroot: FORCE
+	@echo "\n$(GREEN)*** Creating local lightweight chroot subdirectory structure ***$(NC)\n"
+	mkdir -p ./chroot/etc
+	mkdir -p ./chroot/var/mentat/backups
+	mkdir -p ./chroot/var/mentat/cache
+	mkdir -p ./chroot/var/mentat/charts
+	mkdir -p ./chroot/var/mentat/log
+	mkdir -p ./chroot/var/mentat/reports
+	mkdir -p ./chroot/var/mentat/rrds
+	mkdir -p ./chroot/var/mentat/run
+	mkdir -p ./chroot/var/mentat/spool;
+	-ln -s $(shell realpath ./conf) $(shell realpath ./chroot/etc)/mentat
+
 #
 # Install project`s Python dependencies using pip requirements file. The dependencies
 # are already listed in setup.py file and pip can install them automatically. It
@@ -339,15 +371,23 @@ deps-postgresql: FORCE
 #-------------------------------------------------------------------------------
 
 
+run-mentat-dev:
+	@echo "\n$(GREEN)*** Running development version of Mentat system ***$(NC)\n"
+	APP_ROOT_PATH=$(shell realpath ./chroot) mentat-controller.py --command start
+
 run-webui-dev:
 	@echo "\n$(GREEN)*** Running development web server with development configuration on $(DEV_SERVER):$(DEV_PORT) ***$(NC)\n"
-	FLASK_ENV=development FLASK_CONFIG=development FLASK_CONFIG_FILE=$(shell realpath ./hawat.local.conf) hawat-cli run --host $(DEV_SERVER) --port $(DEV_PORT)
+	APP_ROOT_PATH=$(shell realpath ./chroot) FLASK_ENV=development FLASK_CONFIG=development FLASK_CONFIG_FILE=$(shell realpath ./hawat.local.conf) hawat-cli run --host $(DEV_SERVER) --port $(DEV_PORT)
 
 run-mailserver-dev:
 	@echo "\n$(GREEN)*** Running development mail server on $(DEV_MAIL_SERVER):$(DEV_MAIL_PORT) ***$(NC)\n"
 	$(PYTHON) -m smtpd -n -c DebuggingServer $(DEV_MAIL_SERVER):$(DEV_MAIL_PORT)
 
 
+ctrl-mentat-dev:
+	-APP_ROOT_PATH=$(shell realpath ./chroot) mentat-controller.py --command $(COMMAND)
+
+
 #-------------------------------------------------------------------------------
 
 
diff --git a/conf/core/common.json.conf b/conf/core/common.json.conf
new file mode 100644
index 0000000000000000000000000000000000000000..4dbf4b6a1e014b6594e44165fd25f445811d2048
--- /dev/null
+++ b/conf/core/common.json.conf
@@ -0,0 +1,23 @@
+#-------------------------------------------------------------------------------
+#
+# COMMON MENTAT SYSTEM CONFIGURATIONS
+#
+#-------------------------------------------------------------------------------
+
+{
+	# Name/uid of the user.
+    #   default: null
+    #   type:    string or integer
+    #
+    #"user": "mentat",
+
+    # Name/gid of the group.
+    #   default: null
+    #   type:    string or integer
+    #
+    #"group": "mentat",
+
+    # This is a dummy last configuration so that the user does not have to fix
+    # the commas in the whole configuration file after each change.
+    "_dummy_": "_dummy_"
+}
diff --git a/conf/mentat-backup.py.conf b/conf/mentat-backup.py.conf
index b0a9b354e9b92eaa4a1938a45644cfb045323e45..3f7afab15550ebb7a802a0f304745b26aee9d0e9 100644
--- a/conf/mentat-backup.py.conf
+++ b/conf/mentat-backup.py.conf
@@ -15,19 +15,19 @@
     #
     "no_upload": true,
 
-    # Mame of the mount point directory.
-    #   default: "/media/du-store"
+    # Name of the local mount point directory for remote storage.
+    #   default: "/media/ds-store"
     #   type:    string
     #
-    #"mount_point": "/media/du-store",
+    #"mount_point": "/media/ds-store",
 
-    # Name of the temporary file directory.
-    #   default: "/var/tmp"
+    # Name of the local temporary file directory.
+    #   default: "/var/mentat/tmp"
     #   type:    string
     #
-    #"temp_dir": "/var/tmp",
+    #"temp_dir": "/var/mentat/tmp",
 
-    # Name of the database backup directory.
+    # Name of the local database backup directory.
     #   default: "/var/mentat/backups"
     #   type:    string
     #
@@ -159,11 +159,15 @@
     #   default: null
     #   type:    string or integer
     #
-    "user": "mentat",
+    #"user": "mentat",
 
     # Name/gid of the group.
     #   default: null
     #   type:    string or integer
     #
-    "group": "mentat"
+    #"group": "mentat",
+
+    # This is a dummy last configuration so that the user does not have to fix
+    # the commas in the whole configuration file after each change.
+    "_dummy_": "_dummy_"
 }
diff --git a/conf/mentat-cleanup.py.conf b/conf/mentat-cleanup.py.conf
index 23c70cc2a5ce11af89e5f6fc4998389813355004..6a3f3c1e09e3d359664a7c45174ca260ef2da23f 100644
--- a/conf/mentat-cleanup.py.conf
+++ b/conf/mentat-cleanup.py.conf
@@ -236,11 +236,15 @@
     #   default: null
     #   type:    string or integer
     #
-    "user": "mentat",
+    #"user": "mentat",
 
     # Name/gid of the group.
     #   default: null
     #   type:    string or integer
     #
-    "group": "mentat"
+    #"group": "mentat",
+
+    # This is a dummy last configuration so that the user does not have to fix
+    # the commas in the whole configuration file after each change.
+    "_dummy_": "_dummy_"
 }
diff --git a/conf/mentat-controller.py.conf b/conf/mentat-controller.py.conf
index 669b60d7c4300815dd35cdbeb8b89225e297b82a..6688d42a3e8528e88547499741ccce06f5e9f092 100644
--- a/conf/mentat-controller.py.conf
+++ b/conf/mentat-controller.py.conf
@@ -86,6 +86,23 @@
             ]
         }
 
+        #
+        # [CHAIN A|ENTRY]: Message inspection module - event classifications
+        #
+        #{
+        #    "exec": "mentat-inspector.py",
+        #    # Enable multiple instances working the same queue directory
+        #    #"paralel": true,
+        #    # In case of paralel mode, you MUST set the required number of instances
+        #    #"count": 3,
+        #    "args": [
+        #        # Enable debug information before daemonization
+        #        #"--debug"
+        #        # Force logging level ['debug', 'info', 'warning', 'error', 'critical']
+        #        #"--log-level=debug"
+        #    ]
+        #}
+
         #
         # [CHAIN B|ENTRY|FINAL]: Additional message inspection module
         #
@@ -133,5 +150,9 @@
 
         # Check database of Mentat system for various anomalies.
         { "name": "mentat-watchdog-events-py" }
-    ]
+    ],
+
+    # This is a dummy last configuration so that the user does not have to fix
+    # the commas in the whole configuration file after each change.
+    "_dummy_": "_dummy_"
 }
diff --git a/conf/mentat-dbmngr.py.conf b/conf/mentat-dbmngr.py.conf
index 8ee74e04e2c83d6590bdd718c7f64514ef0434bf..c38a5676c8d819b1b7e83a0968dbb1dc1a91362c 100644
--- a/conf/mentat-dbmngr.py.conf
+++ b/conf/mentat-dbmngr.py.conf
@@ -153,11 +153,15 @@
     #   default: null
     #   type:    string or integer
     #
-    "user": "mentat",
+    #"user": "mentat",
 
     # Name/gid of the group.
     #   default: null
     #   type:    string or integer
     #
-    "group": "mentat"
+    #"group": "mentat",
+
+    # This is a dummy last configuration so that the user does not have to fix
+    # the commas in the whole configuration file after each change.
+    "_dummy_": "_dummy_"
 }
diff --git a/conf/mentat-enricher.py.conf b/conf/mentat-enricher.py.conf
index 4cec0c8c23e07a619f15a21d9899e323b5cac930..10305f52cdf38beb0d5df29d2247cd1acedbe2ed 100644
--- a/conf/mentat-enricher.py.conf
+++ b/conf/mentat-enricher.py.conf
@@ -141,16 +141,16 @@
     #---------------------------------------------------------------------------
 
     # Name of the input queue directory.
-    #   default: "/var/mentat/spool/mentat-enricher.py"
+    #   default: "mentat-enricher.py"
     #   type:    string
     #
-    #"queue_in_dir": "/var/mentat/spool/mentat-enricher.py",
+    #"queue_in_dir": "mentat-enricher.py",
 
     # Name of the output queue directory.
     #   default: null
     #   type:    string
     #
-    "queue_out_dir": "/var/mentat/spool/mentat-storage.py",
+    "queue_out_dir": "mentat-storage.py",
 
     # Limit on the number of the files for the output queue directory.
     #   default: 10000
@@ -290,11 +290,15 @@
     #   default: null
     #   type:    string or integer
     #
-    "user": "mentat",
+    #"user": "mentat",
 
     # Name/gid of the group.
     #   default: null
     #   type:    string or integer
     #
-    "group": "mentat"
+    #"group": "mentat",
+
+    # This is a dummy last configuration so that the user does not have to fix
+    # the commas in the whole configuration file after each change.
+    "_dummy_": "_dummy_"
 }
diff --git a/conf/mentat-ideagen.py.conf b/conf/mentat-ideagen.py.conf
index fe99a116fff3076dc27d23d6c71c73aa620dce46..dd28ea661959e51568ac2bcc3ccebd664238840c 100644
--- a/conf/mentat-ideagen.py.conf
+++ b/conf/mentat-ideagen.py.conf
@@ -35,16 +35,16 @@
     #"back_off": 60,
 
     # Name of the target queue directory.
-    #   default: "/var/tmp"
+    #   default: "/var/mentat/spool/mentat-inspector.py/incoming"
     #   type:    string
     #
-    "queue_dir": "/var/mentat/spool/mentat-inspector.py/incoming",
+    #"queue_dir": "/var/mentat/spool/mentat-inspector.py/incoming",
 
     # Name of the temporary file directory.
-    #   default: "/var/tmp"
+    #   default: "/var/mentat/spool/mentat-inspector.py/tmp"
     #   type:    string
     #
-    #"temp_dir": "/var/tmp",
+    #"temp_dir": "/var/mentat/spool/mentat-inspector.py/tmp",
 
     # Name of the template file for generating messages.
     #   default: "msg.01.idea.j2"
@@ -172,13 +172,13 @@
     #   default: null
     #   type:    string or integer
     #
-    "user": "mentat",
+    #"user": "mentat",
 
     # Name/gid of the group.
     #   default: null
     #   type:    string or integer
     #
-    "group": "mentat",
+    #"group": "mentat",
 
     #---------------------------------------------------------------------------
     # Lists for IDEA message pseudo random generation.
@@ -415,5 +415,9 @@
         "Tarpit",
         "Recon",
         "Monitor"
-    ]
+    ],
+
+    # This is a dummy last configuration so that the user does not have to fix
+    # the commas in the whole configuration file after each change.
+    "_dummy_": "_dummy_"
 }
diff --git a/conf/mentat-informant.py.conf b/conf/mentat-informant.py.conf
index 49c1aba81389d597a6e31a80c38a294987ba9880..8ed6dbc78fa749f21fea9db2e5dc654315b865a7 100644
--- a/conf/mentat-informant.py.conf
+++ b/conf/mentat-informant.py.conf
@@ -201,11 +201,15 @@
     #   default: null
     #   type:    string or integer
     #
-    "user": "mentat",
+    #"user": "mentat",
 
     # Name/gid of the group.
     #   default: null
     #   type:    string or integer
     #
-    "group": "mentat"
+    #"group": "mentat",
+
+    # This is a dummy last configuration so that the user does not have to fix
+    # the commas in the whole configuration file after each change.
+    "_dummy_": "_dummy_"
 }
diff --git a/conf/mentat-inspector-b.py.conf b/conf/mentat-inspector-b.py.conf
index f9670040b6de7534443303f89c611f2eebcdf32b..f9427ec823982d4b7c3f63b4947aac859c0b2876 100644
--- a/conf/mentat-inspector-b.py.conf
+++ b/conf/mentat-inspector-b.py.conf
@@ -154,16 +154,16 @@
     #---------------------------------------------------------------------------
 
     # Name of the input queue directory.
-    #   default: "/var/mentat/spool/mentat-inspector.py"
+    #   default: "mentat-inspector-b.py"
     #   type:    string
     #
-    "queue_in_dir": "/var/mentat/spool/mentat-inspector-b.py",
+    #"queue_in_dir": "mentat-inspector-b.py",
 
     # Name of the output queue directory.
     #   default: null
     #   type:    string
     #
-    "queue_out_dir": "/var/mentat/spool/mentat-enricher.py",
+    "queue_out_dir": "mentat-enricher.py",
 
     # Limit on the number of the files for the output queue directory.
     #   default: 10000
@@ -303,11 +303,15 @@
     #   default: null
     #   type:    string or integer
     #
-    "user": "mentat",
+    #"user": "mentat",
 
     # Name/gid of the group.
     #   default: null
     #   type:    string or integer
     #
-    "group": "mentat"
+    #"group": "mentat",
+
+    # This is a dummy last configuration so that the user does not have to fix
+    # the commas in the whole configuration file after each change.
+    "_dummy_": "_dummy_"
 }
diff --git a/conf/mentat-inspector-c.py.conf b/conf/mentat-inspector-c.py.conf
index c4ae8eda713d18201ce3879d8dde209d333dded1..7afffddf5b7ccaaff50737e404a25b74df977870 100644
--- a/conf/mentat-inspector-c.py.conf
+++ b/conf/mentat-inspector-c.py.conf
@@ -117,16 +117,16 @@
     #---------------------------------------------------------------------------
 
     # Name of the input queue directory.
-    #   default: "/var/mentat/spool/mentat-inspector.py"
+    #   default: "mentat-inspector-c.py"
     #   type:    string
     #
-    #"queue_in_dir": "/var/mentat/spool/mentat-inspector.py",
+    #"queue_in_dir": "mentat-inspector-c.py",
 
     # Name of the output queue directory.
     #   default: null
     #   type:    string
     #
-    "queue_out_dir": "/var/mentat/spool/mentat-enricher.py",
+    "queue_out_dir": "mentat-enricher.py",
 
     # Limit on the number of the files for the output queue directory.
     #   default: 10000
@@ -266,11 +266,15 @@
     #   default: null
     #   type:    string or integer
     #
-    "user": "mentat",
+    #"user": "mentat",
 
     # Name/gid of the group.
     #   default: null
     #   type:    string or integer
     #
-    "group": "mentat"
+    #"group": "mentat",
+
+    # This is a dummy last configuration so that the user does not have to fix
+    # the commas in the whole configuration file after each change.
+    "_dummy_": "_dummy_"
 }
diff --git a/conf/mentat-inspector.py.conf b/conf/mentat-inspector.py.conf
index a675a7db3503089d9d4c380e20ee4e14372df250..139066abf028f50e98029cbbafbc25c89bc6345c 100644
--- a/conf/mentat-inspector.py.conf
+++ b/conf/mentat-inspector.py.conf
@@ -217,16 +217,16 @@
     #---------------------------------------------------------------------------
 
     # Name of the input queue directory.
-    #   default: "/var/mentat/spool/mentat-inspector.py"
+    #   default: "mentat-inspector.py"
     #   type:    string
     #
-    "queue_in_dir": "/var/mentat/spool/mentat-inspector.py",
+    #"queue_in_dir": "mentat-inspector.py",
 
     # Name of the output queue directory.
     #   default: null
     #   type:    string
     #
-    "queue_out_dir": "/var/mentat/spool/mentat-inspector-b.py",
+    "queue_out_dir": "mentat-inspector-b.py",
 
     # Limit on the number of the files for the output queue directory.
     #   default: 10000
@@ -366,11 +366,15 @@
     #   default: null
     #   type:    string or integer
     #
-    "user": "mentat",
+    #"user": "mentat",
 
     # Name/gid of the group.
     #   default: null
     #   type:    string or integer
     #
-    "group": "mentat"
+    #"group": "mentat",
+
+    # This is a dummy last configuration so that the user does not have to fix
+    # the commas in the whole configuration file after each change.
+    "_dummy_": "_dummy_"
 }
diff --git a/conf/mentat-netmngr.py.conf b/conf/mentat-netmngr.py.conf
index 35511083214039383dde2980ca1fedbf8fbfac77..ec4545baf14917482b476d5335e0b46c0b4791f2 100644
--- a/conf/mentat-netmngr.py.conf
+++ b/conf/mentat-netmngr.py.conf
@@ -140,11 +140,15 @@
     #   default: null
     #   type:    string or integer
     #
-    "user": "mentat",
+    #"user": "mentat",
 
     # Name/gid of the group.
     #   default: null
     #   type:    string or integer
     #
-    "group": "mentat"
+    #"group": "mentat",
+
+    # This is a dummy last configuration so that the user does not have to fix
+    # the commas in the whole configuration file after each change.
+    "_dummy_": "_dummy_"
 }
diff --git a/conf/mentat-precache.py.conf b/conf/mentat-precache.py.conf
index eccfc6524703bc605018af9b706df820a85e8f67..aaab73035d7663e2fb07370e31f9b1e0056d9729 100644
--- a/conf/mentat-precache.py.conf
+++ b/conf/mentat-precache.py.conf
@@ -150,11 +150,15 @@
     #   default: null
     #   type:    string or integer
     #
-    "user": "mentat",
+    #"user": "mentat",
 
     # Name/gid of the group.
     #   default: null
     #   type:    string or integer
     #
-    "group": "mentat"
+    #"group": "mentat",
+
+    # This is a dummy last configuration so that the user does not have to fix
+    # the commas in the whole configuration file after each change.
+    "_dummy_": "_dummy_"
 }
diff --git a/conf/mentat-reporter.py.conf b/conf/mentat-reporter.py.conf
index 087c72fbe18c4397ee49ce8be2302fbf815199a0..5bbc6241756dd17bff86f08e265a838f8b10d924 100644
--- a/conf/mentat-reporter.py.conf
+++ b/conf/mentat-reporter.py.conf
@@ -246,11 +246,15 @@
     #   default: null
     #   type:    string or integer
     #
-    "user": "mentat",
+    #"user": "mentat",
 
     # Name/gid of the group.
     #   default: null
     #   type:    string or integer
     #
-    "group": "mentat"
+    #"group": "mentat",
+
+    # This is a dummy last configuration so that the user does not have to fix
+    # the commas in the whole configuration file after each change.
+    "_dummy_": "_dummy_"
 }
diff --git a/conf/mentat-sampler.py.conf b/conf/mentat-sampler.py.conf
index 2d06fb24ecfffea3cf92013db92f7c5e24aa373c..8629a05654dd7076c14129a08324e827d7b19c60 100644
--- a/conf/mentat-sampler.py.conf
+++ b/conf/mentat-sampler.py.conf
@@ -22,16 +22,16 @@
     #---------------------------------------------------------------------------
 
     # Name of the input queue directory.
-    #   default: "/var/mentat/spool/mentat-sampler.py"
+    #   default: "mentat-sampler.py"
     #   type:    string
     #
-    #"queue_in_dir": "/var/mentat/spool/mentat-sampler.py",
+    #"queue_in_dir": "mentat-sampler.py",
 
     # Name of the output queue directory.
     #   default: null
     #   type:    string
     #
-    "queue_out_dir": "/var/mentat/spool/mentat-inspector.py",
+    "queue_out_dir": "mentat-inspector.py",
 
     # Limit on the number of the files for the output queue directory.
     #   default: 10000
@@ -171,11 +171,15 @@
     #   default: null
     #   type:    string or integer
     #
-    "user": "mentat",
+    #"user": "mentat",
 
     # Name/gid of the group.
     #   default: null
     #   type:    string or integer
     #
-    "group": "mentat"
+    #"group": "mentat",
+
+    # This is a dummy last configuration so that the user does not have to fix
+    # the commas in the whole configuration file after each change.
+    "_dummy_": "_dummy_"
 }
diff --git a/conf/mentat-statistician.py.conf b/conf/mentat-statistician.py.conf
index 92910dd1737082d3cd7fc3893231ec554b0887b7..a479183bf04031ab14eae61faa846436697447bf 100644
--- a/conf/mentat-statistician.py.conf
+++ b/conf/mentat-statistician.py.conf
@@ -119,11 +119,15 @@
     #   default: null
     #   type:    string or integer
     #
-    "user": "mentat",
+    #"user": "mentat",
 
     # Name/gid of the group.
     #   default: null
     #   type:    string or integer
     #
-    "group": "mentat"
+    #"group": "mentat",
+
+    # This is a dummy last configuration so that the user does not have to fix
+    # the commas in the whole configuration file after each change.
+    "_dummy_": "_dummy_"
 }
diff --git a/conf/mentat-storage.py.conf b/conf/mentat-storage.py.conf
index ea66cec2910e97ea95a08fb7b84636f85940c610..e24e84bc8173040622fe56803aa04cfd780248a8 100644
--- a/conf/mentat-storage.py.conf
+++ b/conf/mentat-storage.py.conf
@@ -10,10 +10,10 @@
     #---------------------------------------------------------------------------
 
     # Name of the input queue directory.
-    #   default: "/var/mentat/spool/mentat-storage.py"
+    #   default: "mentat-storage.py"
     #   type:    string
     #
-    #"queue_in_dir": "/var/mentat/spool/mentat-storage.py",
+    #"queue_in_dir": "mentat-storage.py",
 
     # Name of the output queue directory.
     #   default: null
@@ -159,11 +159,15 @@
     #   default: null
     #   type:    string or integer
     #
-    "user": "mentat",
+    #"user": "mentat",
 
     # Name/gid of the group.
     #   default: null
     #   type:    string or integer
     #
-    "group": "mentat"
+    #"group": "mentat",
+
+    # This is a dummy last configuration so that the user does not have to fix
+    # the commas in the whole configuration file after each change.
+    "_dummy_": "_dummy_"
 }
diff --git a/doc/sphinx/_doclib/development.rst b/doc/sphinx/_doclib/development.rst
index 6f44c97772999c0a4df65cb5709574388f23430d..0cfa511626b96ae8d06ec306a9778da35d81e994 100644
--- a/doc/sphinx/_doclib/development.rst
+++ b/doc/sphinx/_doclib/development.rst
@@ -198,6 +198,49 @@ targets::
 	(venv) $ make deps-webui-upgrade
 
 
+Running development version of Mentat system
+````````````````````````````````````````````````````````````````````````````````
+
+Mentat system can be executed from within the Git repository. We worked hard to
+make sure it will not wander around your filesystem. The key to make everything
+work is the environment variable ``APP_ROOT_PATH``, which controls the base root
+of the application. It is basically a soft implementation of a very lightweight
+chroot. Application can adjust various filesystem paths to the value of this
+variable. During the preparation of development environment a local ``./chroot``
+subdirectory was prepared automatically for you. You may use it in a following
+fashion::
+
+	# A: Use it manually, be carefull to provide the APP_ROOR_PATH as absolute path:
+	(venv) $ APP_ROOT_PATH=$(realpath ./chroot) mentat-controller.py --command start
+
+	# B: For your convenience there is also a makefile target:
+	(venv) $ make run-mentat-dev
+
+For your convenience there is a very handy makefile target ``ctrl-mentat-dev``,
+which is capable of passing commands to your local development instance of
+:ref:`section-bin-mentat-controller`. You may use it in a following fashion::
+
+	# This:
+	(venv) $ make ctrl-mentat-dev COMMAND=start
+	# Is same as this:
+	(venv) $ APP_ROOT_PATH=$(realpath ./chroot) mentat-controller.py --command start
+
+	# This:
+	(venv) $ make ctrl-mentat-dev COMMAND=status
+	# Is same as this:
+	(venv) $ APP_ROOT_PATH=$(realpath ./chroot) mentat-controller.py --command status
+
+	# This:
+	(venv) $ make ctrl-mentat-dev COMMAND=stop
+	# Is same as this:
+	(venv) $ APP_ROOT_PATH=$(realpath ./chroot) mentat-controller.py --command stop
+
+Make sure to read following documentation sections to understand the usage of the
+Mentat system and its various components:
+
+* :ref:`section-quickstart`
+
+
 Running development web server
 ````````````````````````````````````````````````````````````````````````````````
 
@@ -206,11 +249,11 @@ microframework, that comes with built-in webserver for development. It can be
 launched in following ways::
 
 	# A: You may use the Flask built-in command in a following way:
-	(venv) $ FLASK_APP=hawat FLASK_ENV=development FLASK_CONFIG=development FLASK_CONFIG_FILE=$(realpath ./hawat.local.conf) flask run
+	(venv) $ APP_ROOT_PATH=$(realpath ./chroot) FLASK_APP=hawat FLASK_ENV=development FLASK_CONFIG=development FLASK_CONFIG_FILE=$(realpath ./hawat.local.conf) flask run
 
 	# B: You may custom command line interface to launch webserver in development
 	# mode and with development configuration:
-	(venv) $ FLASK_ENV=development FLASK_CONFIG=development FLASK_CONFIG_FILE=$(realpath ./hawat.local.conf) hawat-cli run
+	(venv) $ APP_ROOT_PATH=$(realpath ./chroot) FLASK_ENV=development FLASK_CONFIG=development FLASK_CONFIG_FILE=$(realpath ./hawat.local.conf) hawat-cli run
 
 	# C: Use following makefile target to do the same as the three above with less
 	# typing:
diff --git a/hawat.local.conf b/hawat.local.conf
index ee83f97575bee4d08608eec0f208f757c1a68e64..633a68e4e0587296452cbc4e19f3b722ecdbf22b 100644
--- a/hawat.local.conf
+++ b/hawat.local.conf
@@ -3,5 +3,4 @@ MAIL_SERVER = 'localhost'
 MAIL_PORT = 8025
 MAIL_DEFAULT_SENDER = 'mentat@cesnet.cz'
 HAWAT_LOG_DEFAULT_LEVEL = 'debug'
-HAWAT_LOG_FILE = '/var/tmp/mentat-hawat.py.log'
 HAWAT_LOG_FILE_LEVEL = 'debug'
diff --git a/lib/hawat/config.py b/lib/hawat/config.py
index 3a83cafb21166504a8f7a1d5541a9d91c6139f4c..eba27cc61b3046060af2fdd09f3d2b91d92d7c6a 100644
--- a/lib/hawat/config.py
+++ b/lib/hawat/config.py
@@ -43,6 +43,7 @@ __author__ = "Jan Mach <jan.mach@cesnet.cz>"
 __credits__ = "Pavel Kácha <pavel.kacha@cesnet.cz>, Andrea Kropáčová <andrea.kropacova@cesnet.cz>"
 
 
+import os
 import socket
 import collections
 
@@ -55,6 +56,8 @@ from flask_babel import lazy_gettext
 # Custom modules.
 #
 import pyzenkit.jsonconf
+import pyzenkit.utils
+import mentat.const
 import hawat.const
 
 
@@ -208,23 +211,29 @@ class Config:  # pylint: disable=locally-disabled,too-few-public-methods
     ]
     """Configuration of application menu skeleton."""
 
-    MENTAT_CORE = pyzenkit.jsonconf.config_load_dir('/etc/mentat/core')
+    MENTAT_CORE = pyzenkit.jsonconf.config_load_dir(
+        pyzenkit.utils.get_resource_path(mentat.const.PATH_CFG_CORE)
+    )
     """Mentat core system configurations."""
 
     MENTAT_PATHS = {
-        'path_bin': '/usr/local/bin',
-        'path_cfg': '/etc/mentat',
-        'path_log': '/var/mentat/log',
-        'path_run': '/var/mentat/run',
-        'path_tmp': '/tmp',
-        'path_crn': '/etc/cron.d'
+        'path_crn': pyzenkit.utils.get_resource_path(mentat.const.PATH_CRN),
+        'path_cfg': pyzenkit.utils.get_resource_path(mentat.const.PATH_CFG),
+        'path_var': pyzenkit.utils.get_resource_path(mentat.const.PATH_VAR),
+        'path_log': pyzenkit.utils.get_resource_path(mentat.const.PATH_LOG),
+        'path_run': pyzenkit.utils.get_resource_path(mentat.const.PATH_RUN),
+        'path_tmp': pyzenkit.utils.get_resource_path(mentat.const.PATH_TMP),
     }
     """Paths to various directories."""
 
-    MENTAT_CACHE_DIR = '/var/mentat/cache'
+    MENTAT_CACHE_DIR = pyzenkit.utils.get_resource_path(
+        os.path.join(mentat.const.PATH_VAR, 'cache')
+    )
     """Path to Mentat cache directory."""
 
-    MENTAT_CONTROLLER_CFG = '/etc/mentat/mentat-controller.py.conf'
+    MENTAT_CONTROLLER_CFG = pyzenkit.utils.get_resource_path(
+        os.path.join(mentat.const.PATH_CFG, 'mentat-controller.py.conf')
+    )
     """path to configuration file of mentat-controller.py module."""
 
     HAWAT_ADMINS = ['root@{}'.format(socket.getfqdn())]
@@ -233,7 +242,9 @@ class Config:  # pylint: disable=locally-disabled,too-few-public-methods
     HAWAT_LOG_DEFAULT_LEVEL = 'info'
     """Default logging level, case insensitive. One of the values ``DEBUG``, ``INFO``, ``WARNING``, ``ERROR``, ``CRITICAL``."""
 
-    HAWAT_LOG_FILE = '/var/mentat/log/mentat-hawat.py.log'
+    HAWAT_LOG_FILE = pyzenkit.utils.get_resource_path(
+        os.path.join(mentat.const.PATH_LOG, 'mentat-hawat.py.log')
+    )
     """Log file settings for logging framework."""
 
     HAWAT_LOG_FILE_LEVEL = 'info'
@@ -301,9 +312,6 @@ class DevelopmentConfig(Config):  # pylint: disable=locally-disabled,too-few-pub
     HAWAT_LOGIN_VIEW = 'auth_dev.login'
     """Overwrite default :py:const:`hawat.config.Config.HAWAT_LOGIN_VIEW`."""
 
-    HAWAT_LOG_FILE = '/var/tmp/mentat-hawat.py.log'
-    """Overwrite default :py:const:`hawat.config.Config.HAWAT_LOG_FILE`."""
-
 
 class TestingConfig(Config):  # pylint: disable=locally-disabled,too-few-public-methods
     """
diff --git a/lib/mentat/const.py b/lib/mentat/const.py
index 50204f7eca031d325db717704cc3b2e6acb35ef1..58704987ccfd1dbb0dc0ab8c2ba5674d183bf6fd 100644
--- a/lib/mentat/const.py
+++ b/lib/mentat/const.py
@@ -32,14 +32,25 @@ def tr_(val):
 
 #-------------------------------------------------------------------------------
 
+PATH_BIN      = 'usr/local/bin'
+PATH_CRN      = 'etc/cron.d'
+PATH_CFG      = 'etc/mentat'
+PATH_CFG_CORE = os.path.join(PATH_CFG, 'core')
+PATH_VAR      = 'var/mentat'
+PATH_LOG      = os.path.join(PATH_VAR, 'log')
+PATH_RUN      = os.path.join(PATH_VAR, 'run')
+PATH_TMP      = os.path.join(PATH_VAR, 'tmp')
+
+#-------------------------------------------------------------------------------
+
 DFLT_EVENT_START = 'start'
 """Default name for the *start* event."""
-DFLT_EVENT_RELOAD = 'reload'
-"""Default name for the *reload* event."""
 DFLT_EVENT_LOG_STATISTICS = 'log_statistics'
 """Default name for the *log_statistics* event."""
 DFLT_EVENT_SAVE_RUNLOG = 'save_runlog'
 """Default name for the *save_runlog* event."""
+DFLT_EVENT_RELOAD = 'reload'
+"""Default name for the *reload* event."""
 
 DFLT_INTERVAL_RELOAD = 300
 """Default time interval in seconds for reloading internal caches."""
@@ -196,9 +207,11 @@ NAGIOS_PLUGIN_RC_WARNING  = 1
 NAGIOS_PLUGIN_RC_CRITICAL = 2
 NAGIOS_PLUGIN_RC_UNKNOWN  = 3
 
+
 RE_REPORT_FILE_TIMESTAMP = re.compile(r"^[^\d]*([\d]{8})")
 """Regular expression for parsing out the report timestamp from attachment file name."""
 
+
 def construct_report_dirpath(basedirpath, filename, check = False):
     r"""
     Construct target report directory path based on given base path and file name.
diff --git a/lib/mentat/daemon/base.py b/lib/mentat/daemon/base.py
new file mode 100644
index 0000000000000000000000000000000000000000..6e78fc5c8f8f77c73ce075b840145a7e63b60b5a
--- /dev/null
+++ b/lib/mentat/daemon/base.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#-------------------------------------------------------------------------------
+# This file is part of Mentat system (https://mentat.cesnet.cz/).
+#
+# Copyright (C) since 2011 CESNET, z.s.p.o (http://www.ces.net/)
+# Use of this source is governed by the MIT license, see LICENSE file.
+#-------------------------------------------------------------------------------
+
+
+"""
+This module provides base implementation of all Mentat daemons.
+"""
+
+
+__author__ = "Jan Mach <jan.mach@cesnet.cz>"
+__credits__ = "Pavel Kácha <pavel.kacha@cesnet.cz>, Andrea Kropáčová <andrea.kropacova@cesnet.cz>"
+
+
+#
+# Custom libraries.
+#
+import pyzenkit.baseapp
+import pyzenkit.zendaemon
+import mentat.const
+
+
+DEFAULT_EVENTS_SCHEDULED = [
+    (mentat.const.DFLT_EVENT_START,)
+]
+DEFAULT_EVENTS_SCHEDULED_AFTER = [
+    (mentat.const.DFLT_INTERVAL_STATISTICS, mentat.const.DFLT_EVENT_LOG_STATISTICS),
+    (mentat.const.DFLT_INTERVAL_RUNLOG,     mentat.const.DFLT_EVENT_SAVE_RUNLOG)
+]
+
+class MentatBaseDaemon(pyzenkit.zendaemon.ZenDaemon):
+    """
+    This module provides base implementation of generic *pipe-like* message processing
+    daemon.
+    """
+
+    def __init__(self, **kwargs):
+        #
+        # Configure required script paths.
+        #
+        kwargs.setdefault('path_cfg', mentat.const.PATH_CFG)
+        kwargs.setdefault('path_var', mentat.const.PATH_VAR)
+        kwargs.setdefault('path_log', mentat.const.PATH_LOG)
+        kwargs.setdefault('path_run', mentat.const.PATH_RUN)
+        kwargs.setdefault('path_tmp', mentat.const.PATH_TMP)
+
+        #
+        # Override default configurations.
+        #
+        kwargs.setdefault(
+            'default_config_dir',
+            self.get_resource_path(mentat.const.PATH_CFG_CORE)
+        )
+        kwargs.setdefault(
+            'default_stats_interval',
+            mentat.const.DFLT_INTERVAL_STATISTICS
+        )
+        kwargs.setdefault(
+            'default_runlog_interval',
+            mentat.const.DFLT_INTERVAL_RUNLOG
+        )
+
+        #
+        # Schedule initial events.
+        #
+        kwargs.setdefault('schedule',       DEFAULT_EVENTS_SCHEDULED)
+        kwargs.setdefault('schedule_after', DEFAULT_EVENTS_SCHEDULED_AFTER)
+
+        super().__init__(**kwargs)
diff --git a/lib/mentat/daemon/piper.py b/lib/mentat/daemon/piper.py
index 2399004b9a10308feee19c2238ccd348b0a8081b..00566b2c9060d4282ded95572ba5f64b00d736fd 100644
--- a/lib/mentat/daemon/piper.py
+++ b/lib/mentat/daemon/piper.py
@@ -109,12 +109,13 @@ import os
 #
 import pyzenkit.baseapp
 import pyzenkit.zendaemon
+import mentat.daemon.base
 import mentat.const
 import mentat.dirq
 import mentat.daemon.component.filer
 
 
-class PiperDaemon(pyzenkit.zendaemon.ZenDaemon):
+class PiperDaemon(mentat.daemon.base.MentatBaseDaemon):
     """
     This module provides base implementation of generic *pipe-like* message processing
     daemon.
@@ -129,6 +130,14 @@ class PiperDaemon(pyzenkit.zendaemon.ZenDaemon):
     CONFIG_QUEUE_OUT_LIMIT = 'queue_out_limit'
     CONFIG_QUEUE_OUT_WAIT  = 'queue_out_wait'
 
+    def __init__(self, **kwargs):
+        #
+        # Override default configurations.
+        #
+        kwargs.setdefault('default_queue_out_dir', None)
+
+        super().__init__(**kwargs)
+
     def _init_argparser(self, **kwargs):
         """
         Initialize piper daemon command line argument parser. This method overrides the
@@ -150,10 +159,30 @@ class PiperDaemon(pyzenkit.zendaemon.ZenDaemon):
         #
         arggroup_daemon = argparser.add_argument_group('common piper daemon arguments')
 
-        arggroup_daemon.add_argument('--queue-in-dir',    help='name of the input queue directory', type = str, default = None)
-        arggroup_daemon.add_argument('--queue-out-dir',   help='name of the output queue directory', type = str, default = None)
-        arggroup_daemon.add_argument('--queue-out-limit', help='limit on the number of the files for the output queue directory', type = int, default = None)
-        arggroup_daemon.add_argument('--queue-out-wait',  help='waiting time when the output queue limit is reached in seconds', type = int, default = None)
+        arggroup_daemon.add_argument(
+            '--queue-in-dir',
+            type = str,
+            default = None,
+            help = 'name of the input queue directory'
+        )
+        arggroup_daemon.add_argument(
+            '--queue-out-dir',
+            type = str,
+            default = None,
+            help = 'name of the output queue directory',
+        )
+        arggroup_daemon.add_argument(
+            '--queue-out-limit',
+            type = int,
+            default = None,
+            help = 'limit on the number of the files for the output queue directory'
+        )
+        arggroup_daemon.add_argument(
+            '--queue-out-wait',
+            type = int,
+            default = None,
+            help = 'waiting time when the output queue limit is reached in seconds'
+        )
 
         return argparser
 
@@ -172,10 +201,10 @@ class PiperDaemon(pyzenkit.zendaemon.ZenDaemon):
         :rtype: dict
         """
         cfgs = (
-            (self.CONFIG_QUEUE_IN_DIR,    os.path.join(self.paths['run'], "{}.queue".format(self.name))),
-            (self.CONFIG_QUEUE_OUT_DIR,   False),
-            (self.CONFIG_QUEUE_OUT_LIMIT, 10000),
-            (self.CONFIG_QUEUE_OUT_WAIT,  30),
+            (self.CONFIG_QUEUE_IN_DIR,    self.name),
+            (self.CONFIG_QUEUE_OUT_DIR,   None),
+            (self.CONFIG_QUEUE_OUT_LIMIT, mentat.const.DFLT_QUEUE_SIZE_LIMIT),
+            (self.CONFIG_QUEUE_OUT_WAIT,  mentat.const.DFLT_QUEUE_CHECK_INTERVAL),
         ) + cfgs
         return super()._init_config(cfgs, **kwargs)
 
@@ -203,12 +232,24 @@ class PiperDaemon(pyzenkit.zendaemon.ZenDaemon):
         super()._configure_postprocess()
 
         ccfg = {}
-        ccfg[mentat.dirq.DirectoryQueue.CONFIG_DIR_QUEUE]      = self.c(self.CONFIG_QUEUE_IN_DIR)
-        ccfg[mentat.dirq.DirectoryQueue.CONFIG_DIR_NEXT_QUEUE] = self.c(self.CONFIG_QUEUE_OUT_DIR)
+        ccfg[mentat.dirq.DirectoryQueue.CONFIG_DIR_QUEUE] = self._get_queue_dir_path(
+            self.c(self.CONFIG_QUEUE_IN_DIR)
+        )
+        ccfg[mentat.dirq.DirectoryQueue.CONFIG_DIR_NEXT_QUEUE] = self._get_queue_dir_path(
+            self.c(self.CONFIG_QUEUE_OUT_DIR)
+        )
         ccfg[mentat.daemon.component.filer.FilerDaemonComponent.CONFIG_QUEUE_OUT_LIMIT] = self.c(self.CONFIG_QUEUE_OUT_LIMIT)
         ccfg[mentat.daemon.component.filer.FilerDaemonComponent.CONFIG_QUEUE_OUT_WAIT]  = self.c(self.CONFIG_QUEUE_OUT_WAIT)
         self.config[self.CORE][self.CORE_FILEQUEUE] = ccfg
 
+    def _get_queue_dir_path(self, queue_dir):
+        if not queue_dir:
+            return queue_dir
+        queue_dir = str(queue_dir)
+        if not os.path.dirname(queue_dir):
+            return os.path.join(self.paths[self.PATH_VAR], 'spool', queue_dir)
+        return queue_dir
+
 
 class DemoPrintComponent(pyzenkit.zendaemon.ZenDaemonComponent):
     """
@@ -258,11 +299,12 @@ class DemoPiperDaemon(PiperDaemon):
             #
             # Configure required deamon paths.
             #
-            path_bin = '/tmp',
-            path_cfg = '/tmp',
-            path_log = '/tmp',
-            path_tmp = '/tmp',
-            path_run = '/tmp',
+            path_bin = 'tmp',
+            path_cfg = 'tmp',
+            path_var = 'tmp',
+            path_log = 'tmp',
+            path_tmp = 'tmp',
+            path_run = 'tmp',
 
             #
             # Override default configurations.
@@ -284,7 +326,7 @@ class DemoPiperDaemon(PiperDaemon):
             ],
             schedule_after = [
                 (mentat.const.DFLT_INTERVAL_STATISTICS, mentat.const.DFLT_EVENT_LOG_STATISTICS),
-                (mentat.const.DFLT_INTERVAL_RUNLOG, mentat.const.DFLT_EVENT_SAVE_RUNLOG)
+                (mentat.const.DFLT_INTERVAL_RUNLOG,     mentat.const.DFLT_EVENT_SAVE_RUNLOG)
             ],
 
             #
diff --git a/lib/mentat/dirq.py b/lib/mentat/dirq.py
index d26555f0e00d17dec59ef17490d07d1fb9d88425..8f0f38f705f138f094ec6c9960bda9da80bf5737 100644
--- a/lib/mentat/dirq.py
+++ b/lib/mentat/dirq.py
@@ -229,7 +229,7 @@ class DirectoryQueue:
         Fetch next file from incoming queue.
         """
         while True:
-            if not len(self.queue):
+            if not self.queue:
                 self._rescan_queue()
             try:
                 itemid = self.queue.pop()
diff --git a/lib/mentat/module/backup.py b/lib/mentat/module/backup.py
index 222ad4068f08d734ea0386259fc9157aba7f6e5a..b20faf42669fb0e277600f4eaf36ce1b07d8b485 100644
--- a/lib/mentat/module/backup.py
+++ b/lib/mentat/module/backup.py
@@ -132,9 +132,10 @@ import pprint
 #
 import pyzenkit.zenscript
 import mentat.const
+import mentat.script.base
 
 
-class MentatBackupScript(pyzenkit.zenscript.ZenScript):
+class MentatBackupScript(mentat.script.base.MentatBaseScript):
     """
     Implementation of Mentat module (script) providing database backup functions
     and features.
@@ -161,22 +162,7 @@ class MentatBackupScript(pyzenkit.zenscript.ZenScript):
         configuration values for parent contructor.
         """
         super().__init__(
-
-            description = 'mentat-backup.py - PostgreSQL database backup script for Mentat system',
-
-            #
-            # Configure required script paths.
-            #
-            path_bin = '/usr/local/bin',
-            path_cfg = '/etc/mentat',
-            path_log = '/var/mentat/log',
-            path_run = '/var/mentat/run',
-            path_tmp = '/tmp',
-
-            #
-            # Override default configurations.
-            #
-            default_config_dir = '/etc/mentat/core'
+            description = 'mentat-backup.py - PostgreSQL database backup script for Mentat system'
         )
 
     def _init_argparser(self, **kwargs):
@@ -200,12 +186,42 @@ class MentatBackupScript(pyzenkit.zenscript.ZenScript):
         #
         arggroup_script = argparser.add_argument_group('custom script arguments')
 
-        arggroup_script.add_argument('--no-upload',   help = 'do not upload the backup file to remote storage (flag)', action='store_true', default = None)
-        arggroup_script.add_argument('--mount-point', help = 'name of the mount point directory', type = str, default = None)
-        arggroup_script.add_argument('--temp-dir',    help = 'name of the temporary file directory', type = str, default = None)
-        arggroup_script.add_argument('--backup-dir',  help = 'name of the database backup directory', type = str, default = None)
-        arggroup_script.add_argument('--remote-host', help = 'SSH connection string for the remote host to which to sychronize backups', type = str, default = None)
-        arggroup_script.add_argument('--remote-dir',  help = 'directory path on the remote host to which to sychronize backups', type = str, default = None)
+        arggroup_script.add_argument(
+            '--no-upload',
+            help = 'do not upload the backup file to remote storage (flag)',
+            action = 'store_true',
+            default = None
+        )
+        arggroup_script.add_argument(
+            '--mount-point',
+            help = 'name of the local mount point directory for remote storage',
+            type = str,
+            default = None
+        )
+        arggroup_script.add_argument(
+            '--temp-dir',
+            help = 'name of the local temporary file directory',
+            type = str,
+            default = None
+        )
+        arggroup_script.add_argument(
+            '--backup-dir',
+            help = 'name of the local database backup directory',
+            type = str,
+            default = None
+        )
+        arggroup_script.add_argument(
+            '--remote-host',
+            help = 'SSH connection string for the remote host to which to sychronize backups',
+            type = str,
+            default = None
+        )
+        arggroup_script.add_argument(
+            '--remote-dir',
+            help = 'directory path on the remote host to which to sychronize backups',
+            type = str,
+            default = None
+        )
 
         return argparser
 
@@ -225,9 +241,9 @@ class MentatBackupScript(pyzenkit.zenscript.ZenScript):
         """
         cfgs = (
             (self.CONFIG_NO_UPLOAD,   False),
-            (self.CONFIG_MOUNT_POINT, '/media/du-store'),
-            (self.CONFIG_TEMP_DIR,    '/var/tmp'),
-            (self.CONFIG_BACKUP_DIR,  '/var/mentat/backups'),
+            (self.CONFIG_MOUNT_POINT, self.get_resource_path('media/ds-store')),
+            (self.CONFIG_TEMP_DIR,    self.paths[self.PATH_TMP]),
+            (self.CONFIG_BACKUP_DIR,  os.path.join(self.paths[self.PATH_VAR], 'backups')),
             (self.CONFIG_REMOTE_HOST, None),
             (self.CONFIG_REMOTE_DIR,  None),
         ) + cfgs
diff --git a/lib/mentat/module/cleanup.py b/lib/mentat/module/cleanup.py
index fe70cf7ce8fefb29aefddd54545c2c4efa4b413b..cfe196e860c4f6ff2403e5548be2771c310741cc 100644
--- a/lib/mentat/module/cleanup.py
+++ b/lib/mentat/module/cleanup.py
@@ -104,7 +104,7 @@ import json
 #
 import pydgets.widgets
 import mentat.script.fetcher
-
+import mentat.const
 
 #
 # Global variables.
@@ -150,6 +150,7 @@ def json_dump_cbk(obj):
         return obj.isoformat()
     return repr(obj)
 
+
 class MentatCleanupScript(mentat.script.fetcher.FetcherScript):
     """
     Implementation of Mentat module (script) providing database and cache cleanup
@@ -180,22 +181,7 @@ class MentatCleanupScript(mentat.script.fetcher.FetcherScript):
         self.sqlservice   = None
 
         super().__init__(
-
-            description = 'mentat-cleanup.py - Mentat system database and cache cleanup script',
-
-            #
-            # Configure required script paths.
-            #
-            path_bin = '/usr/local/bin',
-            path_cfg = '/etc/mentat',
-            path_log = '/var/mentat/log',
-            path_run = '/var/mentat/run',
-            path_tmp = '/tmp',
-
-            #
-            # Override default configurations.
-            #
-            default_config_dir = '/etc/mentat/core'
+            description = 'mentat-cleanup.py - Mentat system database and cache cleanup script'
         )
 
     def _init_argparser(self, **kwargs):
@@ -219,8 +205,18 @@ class MentatCleanupScript(mentat.script.fetcher.FetcherScript):
         #
         arggroup_script = argparser.add_argument_group('custom script arguments')
 
-        arggroup_script.add_argument('--db-path', help = 'filesystem path to database files', type = str, default = None)
-        arggroup_script.add_argument('--simulate', help = 'perform simulation, do not remove anything (flag)', action='store_true', default = None)
+        arggroup_script.add_argument(
+            '--db-path',
+            help = 'filesystem path to database files',
+            type = str,
+            default = None
+        )
+        arggroup_script.add_argument(
+            '--simulate',
+            help = 'perform simulation, do not remove anything (flag)',
+            action = 'store_true',
+            default = None
+        )
 
         return argparser
 
@@ -239,7 +235,7 @@ class MentatCleanupScript(mentat.script.fetcher.FetcherScript):
         :rtype: dict
         """
         cfgs = (
-            (self.CONFIG_DB_PATH,  '/var/lib/postgresql/10/main'),
+            (self.CONFIG_DB_PATH,  '/var/lib/postgresql/11/main'),
             (self.CONFIG_SIMULATE, False),
             (self.CONFIG_EVENTS,   []),
             (self.CONFIG_TABLES,   []),
diff --git a/lib/mentat/module/controller.py b/lib/mentat/module/controller.py
index f60159b2f2c3423bbd2cd7c74e0c5e3766071140..55a79d06616cb8dab6618753288976fc254f3ad0 100644
--- a/lib/mentat/module/controller.py
+++ b/lib/mentat/module/controller.py
@@ -170,10 +170,9 @@ import pprint
 #
 # Custom libraries
 #
-import pyzenkit.baseapp
-import pyzenkit.zenscript
 import mentat.const
 import mentat.system
+import mentat.script.base
 
 
 # Translation table to translate signal numbers to their names.
@@ -183,7 +182,7 @@ SIGNALS_TO_NAMES_DICT = dict((getattr(signal, n), n) \
 CRON_SCRIPT_DIR = '/etc/cron.d'
 
 
-class MentatControllerScript(pyzenkit.zenscript.ZenScript):
+class MentatControllerScript(mentat.script.base.MentatBaseScript):
 
     """
     Implementation of Mentat module (script) providing Mentat system control
@@ -208,23 +207,11 @@ class MentatControllerScript(pyzenkit.zenscript.ZenScript):
         it aims to even more simplify the script object creation by providing
         configuration values for parent contructor.
         """
-        super().__init__(
+        self.modules  = None
+        self.cronjobs = None
 
-            description = 'mentat-controller.py - Mentat system control script',
-
-            #
-            # Configure required script paths.
-            #
-            path_bin = '/usr/local/bin',
-            path_cfg = '/etc/mentat',
-            path_log = '/var/mentat/log',
-            path_run = '/var/mentat/run',
-            path_tmp = '/tmp',
-
-            #
-            # Override default configurations.
-            #
-            default_config_dir = '/etc/mentat/core'
+        super().__init__(
+            description = 'mentat-controller.py - Mentat system control script'
         )
 
     def _init_argparser(self, **kwargs):
@@ -251,8 +238,19 @@ class MentatControllerScript(pyzenkit.zenscript.ZenScript):
         arggroup_script = argparser.add_argument_group('custom script arguments')
 
         # Specify the target module(s) for the command
-        arggroup_script.add_argument('--target', help='target module(s) for the current command (*repeatable*)', action='append', type = str, default = None)
-        arggroup_script.add_argument('--nagios-plugin',  help = 'execute as Nagios plugin (flag)', action='store_true', default = None)
+        arggroup_script.add_argument(
+            '--target',
+            help = 'target module(s) for the current command (*repeatable*)',
+            action = 'append',
+            type = str,
+            default = None
+        )
+        arggroup_script.add_argument(
+            '--nagios-plugin',
+            help = 'execute in Nagios plugin compatible mode (flag)',
+            action = 'store_true',
+            default = None
+        )
 
         return argparser
 
@@ -272,7 +270,7 @@ class MentatControllerScript(pyzenkit.zenscript.ZenScript):
         """
 
         cfgs = (
-            (self.CONFIG_TARGET, None),
+            (self.CONFIG_TARGET,        None),
             (self.CONFIG_NAGIOS_PLUGIN, False)
         ) + cfgs
         return super()._init_config(cfgs, **kwargs)
@@ -284,8 +282,12 @@ class MentatControllerScript(pyzenkit.zenscript.ZenScript):
         This method is called from the main setup method :py:func:`pyzenkit.baseapp.BaseApp._stage_setup`
         as a part of the **setup** stage of application`s life cycle.
         """
-        self.modules  = mentat.system.make_module_list(self.c(self.CONFIG_MODULES))  # pylint: disable=locally-disabled,attribute-defined-outside-init
-        self.cronjobs = mentat.system.make_cronjob_list(self.c(self.CONFIG_CRONJOBS))  # pylint: disable=locally-disabled,attribute-defined-outside-init
+        self.modules = mentat.system.make_module_list(
+            self.c(self.CONFIG_MODULES)
+        )
+        self.cronjobs = mentat.system.make_cronjob_list(
+            self.c(self.CONFIG_CRONJOBS)
+        )
 
 
     #---------------------------------------------------------------------------
@@ -635,7 +637,7 @@ class MentatControllerScript(pyzenkit.zenscript.ZenScript):
             if stat[0] == mentat.system.STATUS_RT_RUNNING_OK:
                 self._module_signal(self.modules[mname], proc, signal.SIGUSR1)
             else:
-                self.logger.error("Module '%s': Unable to send signal", mname)
+                self.logger.error("Module '%s': Unable to send SIGUSR1 signal", mname)
 
         return self.RESULT_SUCCESS
 
@@ -659,7 +661,7 @@ class MentatControllerScript(pyzenkit.zenscript.ZenScript):
             if stat[0] == mentat.system.STATUS_RT_RUNNING_OK:
                 self._module_signal(self.modules[mname], proc, signal.SIGUSR2)
             else:
-                self.logger.error("Module '%s': Unable to send signal", mname)
+                self.logger.error("Module '%s': Unable to send SIGUSR2 signal", mname)
 
         return self.RESULT_SUCCESS
 
@@ -714,13 +716,17 @@ class MentatControllerScript(pyzenkit.zenscript.ZenScript):
     #---------------------------------------------------------------------------
 
 
-    def _prepare_command(self, mod_data):
+    @staticmethod
+    def _prepare_command(mod_data):
         """
         Prepare system command for execution of given module.
         """
-        path = os.path.join(self.paths.get(self.PATH_BIN), mod_data.executable)
+        path = mod_data.executable
+        # From documentation https://docs.python.org/3/library/os.html#os.execv:
+        # "...the arguments to the child process should start with the name of
+        # the command being run, but this is not enforced..."
         args = [path,]
-        if mod_data.name != mod_data.executable:
+        if mod_data.name != os.path.basename(mod_data.executable):
             args = args + ['--name', mod_data.name]
         if mod_data.paralel:
             args = args + ['--paralel',]
@@ -736,14 +742,30 @@ class MentatControllerScript(pyzenkit.zenscript.ZenScript):
 
         newpid = os.fork()
         if newpid == 0:
-            self.logger.info("Module '%s': Worker process '%d' ready, executing command '%s' with arguments '%s'", mod_data.name, os.getpid(), executable, pprint.pformat(arguments))
+            self.logger.info(
+                "Module '%s': Worker process '%d' ready, executing command '%s' with arguments '%s'",
+                mod_data.name,
+                os.getpid(),
+                executable,
+                pprint.pformat(arguments)
+            )
             os.sync()
-
-            os.execv(executable, arguments)
-            self.logger.critical("Module '%s': Worker process '%d' was unable to execute module", mod_data.name, os.getpid())
-            os._exit(0) # pylint: disable=locally-disabled,protected-access
+            os.execvp(executable, arguments)
+
+            # In case the os.execv() call was successfull we should never reach
+            # this point in code. If we are here, there was a critical error.
+            self.logger.critical(
+                "Module '%s': Worker process '%d' was unable to execute module",
+                mod_data.name,
+                os.getpid()
+            )
+            os._exit(1) # pylint: disable=locally-disabled,protected-access
         else:
-            self.logger.info("Module '%s': Waiting for worker process '%d'", mod_data.name, newpid)
+            self.logger.info(
+                "Module '%s': Waiting for worker process '%d'",
+                mod_data.name,
+                newpid
+            )
             time.sleep(1)
 
     def _module_start(self, mod_data, processes):
@@ -757,7 +779,11 @@ class MentatControllerScript(pyzenkit.zenscript.ZenScript):
             instances = instances - len(processes.keys())
 
         for i in range(0, instances):
-            self.logger.info("Module '%s': Launching instance '%d'", mod_data.name, i)
+            self.logger.info(
+                "Module '%s': Launching instance '%d'",
+                mod_data.name,
+                i
+            )
             self._execute(mod_data)
 
     def _module_enable(self, mod_data, meta):
@@ -790,14 +816,19 @@ class MentatControllerScript(pyzenkit.zenscript.ZenScript):
 
     def _signal(self, mod_data, pid, sig):
         """
-        Send given signal to given process.
+        Send given signal to given system process.
         """
-        self.logger.info("Module '%s': Sending signal '%s' to process '%d'", mod_data.name, SIGNALS_TO_NAMES_DICT.get(sig, sig), pid)
+        self.logger.info(
+            "Module '%s': Sending signal '%s' to process '%d'",
+            mod_data.name,
+            SIGNALS_TO_NAMES_DICT.get(sig, sig),
+            pid
+        )
         os.kill(pid, sig)
 
     def _module_signal(self, mod_data, processes, sig):
         """
-        Stop given module.
+        Send given signal to given module.
         """
         for pid in sorted(processes.keys()):
             self._signal(mod_data, pid, sig)
diff --git a/lib/mentat/module/dbmngr.py b/lib/mentat/module/dbmngr.py
index 2b1994b87b14a9d99456f35d07426b7c235b46fa..51066318732828ab2f2899bae3cc7ba2d80ff45e 100644
--- a/lib/mentat/module/dbmngr.py
+++ b/lib/mentat/module/dbmngr.py
@@ -175,22 +175,7 @@ class MentatDbmngrScript(mentat.script.fetcher.FetcherScript):
         self.sqlservice   = None
 
         super().__init__(
-
-            description = 'mentat-dbmngr.py - Mentat database management script',
-
-            #
-            # Configure required script paths.
-            #
-            path_bin = '/usr/local/bin',
-            path_cfg = '/etc/mentat',
-            path_log = '/var/mentat/log',
-            path_run = '/var/mentat/run',
-            path_tmp = '/tmp',
-
-            #
-            # Override default configurations.
-            #
-            default_config_dir = '/etc/mentat/core'
+            description = 'mentat-dbmngr.py - Mentat database management script'
         )
 
     def _init_argparser(self, **kwargs):
@@ -214,12 +199,41 @@ class MentatDbmngrScript(mentat.script.fetcher.FetcherScript):
         #
         arggroup_script = argparser.add_argument_group('custom script arguments')
 
-        arggroup_script.add_argument('--watchdog-delta', type = int, default = None, help = 'time interval delta in seconds for watchdog checks')
-        arggroup_script.add_argument('--mail-subject',   type = str, default = None, help = 'subject for the database watchdog emails')
-        arggroup_script.add_argument('--mail-from',      type = str, default = None, help = 'source email address for the database watchdog emails')
-        arggroup_script.add_argument('--mail-to',        type = str, default = None, help = 'target email address for the database watchdog emails')
-        arggroup_script.add_argument('--nagios-plugin',  help = 'execute as Nagios plugin (flag)', action='store_true', default = None)
-        arggroup_script.add_argument('additional_args',  help = 'optional additional arguments', nargs='*')
+        arggroup_script.add_argument(
+            '--watchdog-delta',
+            type = int,
+            default = None,
+            help = 'time interval delta in seconds for watchdog checks'
+        )
+        arggroup_script.add_argument(
+            '--mail-subject',
+            type = str,
+            default = None,
+            help = 'subject for the database watchdog emails'
+        )
+        arggroup_script.add_argument(
+            '--mail-from',
+            type = str,
+            default = None,
+            help = 'source email address for the database watchdog emails'
+        )
+        arggroup_script.add_argument(
+            '--mail-to',
+            type = str,
+            default = None,
+            help = 'target email address for the database watchdog emails'
+        )
+        arggroup_script.add_argument(
+            '--nagios-plugin',
+            action='store_true',
+            default = None,
+            help = 'execute as Nagios plugin (flag)'
+        )
+        arggroup_script.add_argument(
+            'additional_args',
+            nargs='*',
+            help = 'optional additional arguments'
+        )
 
         return argparser
 
diff --git a/lib/mentat/module/enricher.py b/lib/mentat/module/enricher.py
index 35cc2a24fe1e5b50b27bd1ed7615f61c654b0506..4646739e5556cadb3b975fa59648f83222aa1aca 100644
--- a/lib/mentat/module/enricher.py
+++ b/lib/mentat/module/enricher.py
@@ -46,6 +46,7 @@ __credits__ = "Pavel Kácha <pavel.kacha@cesnet.cz>, Andrea Kropáčová <andrea
 # Custom libraries.
 #
 import mentat.const
+import mentat.daemon.base
 import mentat.daemon.piper
 import mentat.plugin.app.sqlstorage
 import mentat.daemon.component.parser
@@ -70,35 +71,16 @@ class MentatEnricherDaemon(mentat.daemon.piper.PiperDaemon):
 
             description = 'mentat-enricher.py - IDEA message enrichment daemon',
 
-            #
-            # Configure required deamon paths.
-            #
-            path_bin = '/usr/local/bin',
-            path_cfg = '/etc/mentat',
-            path_log = '/var/mentat/log',
-            path_run = '/var/mentat/run',
-            path_tmp = '/var/tmp',
-
             #
             # Override default configurations.
             #
-            default_config_dir      = '/etc/mentat/core',
-            default_queue_in_dir    = '/var/mentat/spool/mentat-enricher.py',
-            default_queue_out_dir   = None,
             default_reload_interval = mentat.const.DFLT_INTERVAL_RELOAD,
-            default_stats_interval  = mentat.const.DFLT_INTERVAL_STATISTICS,
-            default_runlog_interval = mentat.const.DFLT_INTERVAL_RUNLOG,
 
             #
             # Schedule initial events.
             #
-            schedule = [
-                (mentat.const.DFLT_EVENT_START,)
-            ],
-            schedule_after = [
-                (mentat.const.DFLT_INTERVAL_RELOAD,     mentat.const.DFLT_EVENT_RELOAD),
-                (mentat.const.DFLT_INTERVAL_STATISTICS, mentat.const.DFLT_EVENT_LOG_STATISTICS),
-                (mentat.const.DFLT_INTERVAL_RUNLOG,     mentat.const.DFLT_EVENT_SAVE_RUNLOG)
+            schedule_after = mentat.daemon.base.DEFAULT_EVENTS_SCHEDULED_AFTER + [
+                (mentat.const.DFLT_INTERVAL_RELOAD,     mentat.const.DFLT_EVENT_RELOAD)
             ],
 
             #
@@ -139,7 +121,12 @@ class MentatEnricherDaemon(mentat.daemon.piper.PiperDaemon):
         #
         arggroup_daemon = argparser.add_argument_group('custom daemon arguments')
 
-        arggroup_daemon.add_argument('--reload-interval',  type = int, default = None, help = 'time interval for reloading enrichment plugins in seconds')
+        arggroup_daemon.add_argument(
+            '--reload-interval',
+            type = int,
+            default = None,
+            help = 'time interval for reloading enrichment plugins in seconds'
+        )
 
         return argparser
 
diff --git a/lib/mentat/module/ideagen.py b/lib/mentat/module/ideagen.py
index 66da7d5ed9010a27d182a5d209a916140bc7e603..a89b02a4dcd178620b040eee914b1cc0e85b8fef 100644
--- a/lib/mentat/module/ideagen.py
+++ b/lib/mentat/module/ideagen.py
@@ -127,13 +127,14 @@ from jinja2 import Environment, FileSystemLoader
 #
 # Custom libraries
 #
-import pyzenkit.zenscript
+import mentat.const
+import mentat.script.base
 
 
 #-------------------------------------------------------------------------------
 
 
-class MentatIdeagenScript(pyzenkit.zenscript.ZenScript):
+class MentatIdeagenScript(mentat.script.base.MentatBaseScript):
     """
     Implementation of Mentat module (script) providing functions for generating
     `IDEA <https://idea.cesnet.cz/en/index>`__ messages, mainly for testing or
@@ -174,23 +175,10 @@ class MentatIdeagenScript(pyzenkit.zenscript.ZenScript):
         it aims to even more simplify the script object creation by providing
         configuration values for parent contructor.
         """
-        super().__init__(
+        self.templ_env = None
 
+        super().__init__(
             description = 'mentat-ideagen.py - IDEA message generation script for Mentat system',
-
-            #
-            # Configure required script paths.
-            #
-            path_bin = '/usr/local/bin',
-            path_cfg = '/etc/mentat',
-            path_log = '/var/mentat/log',
-            path_run = '/var/mentat/run',
-            path_tmp = '/tmp',
-
-            #
-            # Override default configurations.
-            #
-            default_config_dir = '/etc/mentat/core'
         )
 
     def _init_argparser(self, **kwargs):
@@ -216,15 +204,55 @@ class MentatIdeagenScript(pyzenkit.zenscript.ZenScript):
 
         # Setup mutually exclusive group for regular counter vs. random counter.
         group_a = arggroup_script.add_mutually_exclusive_group()
-        group_a.add_argument('--count',        help = 'number of messages to be generated in one batch', type = int, default = None)
-        group_a.add_argument('--random-count', help = 'generate random number of messages', type = int, default = None)
+        group_a.add_argument(
+            '--count',
+            help = 'number of messages to be generated in one batch',
+            type = int,
+            default = None
+        )
+        group_a.add_argument(
+            '--random-count',
+            help = 'generate random number of messages',
+            type = int,
+            default = None
+        )
 
-        arggroup_script.add_argument('--steady',       help = 'generate messages continuously with given time backoff (flag)', action='store_true', default = None)
-        arggroup_script.add_argument('--back-off',     help = 'back-off time between message batches in seconds', type = int, default = None)
-        arggroup_script.add_argument('--queue-dir',    help = 'name of the target queue directory', type = str, default = None)
-        arggroup_script.add_argument('--temp-dir',     help = 'name of the temporary file directory', type = str, default = None)
-        arggroup_script.add_argument('--template',     help = 'name of template file for generating messages', type = str, default = None)
-        arggroup_script.add_argument('--template-dir', help = 'name of the directory containing message templates', type = str, default = None)
+        arggroup_script.add_argument(
+            '--steady',
+            help = 'generate messages continuously with given time backoff (flag)',
+            action = 'store_true',
+            default = None
+        )
+        arggroup_script.add_argument(
+            '--back-off',
+            help = 'back-off time between message batches in seconds',
+            type = int,
+            default = None
+        )
+        arggroup_script.add_argument(
+            '--queue-dir',
+            help = 'name of the target queue directory',
+            type = str,
+            default = None
+        )
+        arggroup_script.add_argument(
+            '--temp-dir',
+            help = 'name of the temporary file directory',
+            type = str,
+            default = None
+        )
+        arggroup_script.add_argument(
+            '--template',
+            help = 'name of template file for generating messages',
+            type = str,
+            default = None
+        )
+        arggroup_script.add_argument(
+            '--template-dir',
+            help = 'name of the directory containing message templates',
+            type = str,
+            default = None
+        )
 
         return argparser
 
@@ -247,10 +275,10 @@ class MentatIdeagenScript(pyzenkit.zenscript.ZenScript):
             (self.CONFIG_RANDOM_COUNT, None),
             (self.CONFIG_STEADY,       False),
             (self.CONFIG_BACK_OFF,     60),
-            (self.CONFIG_QUEUE_DIR,    '/var/tmp'),
-            (self.CONFIG_TEMP_DIR,     '/var/tmp'),
+            (self.CONFIG_QUEUE_DIR,    os.path.join(self.paths[self.PATH_VAR], 'spool', 'mentat-inspector.py', 'incoming')),
+            (self.CONFIG_TEMP_DIR,     os.path.join(self.paths[self.PATH_VAR], 'spool', 'mentat-inspector.py', 'tmp')),
             (self.CONFIG_TEMPLATE,     'msg.01.idea.j2'),
-            (self.CONFIG_TEMPLATE_DIR, os.path.join(self.paths.get(self.PATH_CFG), 'templates', 'idea')),
+            (self.CONFIG_TEMPLATE_DIR, os.path.join(self.paths[self.PATH_CFG], 'templates', 'idea')),
 
             (self.CONFIG_LIST_SOURCE_IP4S, []),
             (self.CONFIG_LIST_TARGET_IP4S, []),
@@ -274,7 +302,9 @@ class MentatIdeagenScript(pyzenkit.zenscript.ZenScript):
         This method is called from the main setup method :py:func:`pyzenkit.baseapp.BaseApp._stage_setup`
         as a part of the **setup** stage of application`s life cycle.
         """
-        self.templ_env = Environment(loader = FileSystemLoader(self.c(self.CONFIG_TEMPLATE_DIR)))
+        self.templ_env = Environment(
+            loader = FileSystemLoader(self.c(self.CONFIG_TEMPLATE_DIR))
+        )
 
 
     #---------------------------------------------------------------------------
@@ -300,14 +330,18 @@ class MentatIdeagenScript(pyzenkit.zenscript.ZenScript):
         """
         result = {'cnt_messages': 0, 'cnt_batches': 0}
 
-        self.dbgout("Using template '{}' to generate message(s)".format(self.c(self.CONFIG_TEMPLATE)))
         template = self.templ_env.get_template(self.c(self.CONFIG_TEMPLATE))
-
         counter = self.c(self.CONFIG_RANDOM_COUNT)
         if counter:
             counter = random.randint(1, counter)
         else:
             counter = self.c(self.CONFIG_COUNT)
+        self.dbgout(
+            "Using template '{}' to generate {:d} message(s)".format(
+                self.c(self.CONFIG_TEMPLATE),
+                counter
+            )
+        )
 
         try:
             while True:
@@ -332,6 +366,12 @@ class MentatIdeagenScript(pyzenkit.zenscript.ZenScript):
                     )
                     time.sleep(backoff)
 
+        except FileNotFoundError as err:
+            self.logger.critical("%s", str(err))
+
+        except PermissionError as err:
+            self.logger.critical("%s", str(err))
+
         except KeyboardInterrupt:
             pass
 
diff --git a/lib/mentat/module/informant.py b/lib/mentat/module/informant.py
index 558540ee221fff5f0ee0b77e663b4f70f051f3cf..f1747fcfe9e89104887ba2d85519a5c13e43794e 100644
--- a/lib/mentat/module/informant.py
+++ b/lib/mentat/module/informant.py
@@ -91,20 +91,6 @@ class MentatInformantScript(mentat.script.fetcher.FetcherScript):
 
             description = 'mentat-informant.py - Mentat system overall performance statistics',
 
-            #
-            # Configure required script paths.
-            #
-            path_bin = '/usr/local/bin',
-            path_cfg = '/etc/mentat',
-            path_log = '/var/mentat/log',
-            path_run = '/var/mentat/run',
-            path_tmp = '/tmp',
-
-            #
-            # Override default configurations.
-            #
-            default_config_dir = '/etc/mentat/core',
-
             #
             # Load additional application-level plugins.
             #
@@ -149,9 +135,24 @@ class MentatInformantScript(mentat.script.fetcher.FetcherScript):
         #
         arggroup_script = argparser.add_argument_group('custom script arguments')
 
-        arggroup_script.add_argument('--force-template',    type = str, default = None, help = 'force a template for generating reports')
-        arggroup_script.add_argument('--force-locale',      type = str, default = None, help = 'force a locale for generating reports')
-        arggroup_script.add_argument('--force-timezone',    type = str, default = None, help = 'force a timezone for generating reports')
+        arggroup_script.add_argument(
+            '--force-template',
+            type = str,
+            default = None,
+            help = 'force a template for generating reports'
+        )
+        arggroup_script.add_argument(
+            '--force-locale',
+            type = str,
+            default = None,
+            help = 'force a locale for generating reports'
+        )
+        arggroup_script.add_argument(
+            '--force-timezone',
+            type = str,
+            default = None,
+            help = 'force a timezone for generating reports'
+        )
 
         return argparser
 
diff --git a/lib/mentat/module/inspector.py b/lib/mentat/module/inspector.py
index 04cfda0f5e7060200a2f690ed51c5cf0ba6ce0db..4ab94cd14ab4cf60ecf55068dab462b7d8c54968 100644
--- a/lib/mentat/module/inspector.py
+++ b/lib/mentat/module/inspector.py
@@ -72,35 +72,6 @@ class MentatInspectorDaemon(mentat.daemon.piper.PiperDaemon):
 
             description = 'mentat-inspector.py - IDEA message inspection daemon',
 
-            #
-            # Configure required deamon paths.
-            #
-            path_bin = '/usr/local/bin',
-            path_cfg = '/etc/mentat',
-            path_log = '/var/mentat/log',
-            path_run = '/var/mentat/run',
-            path_tmp = '/var/tmp',
-
-            #
-            # Override default configurations.
-            #
-            default_config_dir      = '/etc/mentat/core',
-            default_queue_in_dir    = '/var/mentat/spool/mentat-inspector.py',
-            default_queue_out_dir   = None,
-            default_stats_interval  = mentat.const.DFLT_INTERVAL_STATISTICS,
-            default_runlog_interval = mentat.const.DFLT_INTERVAL_RUNLOG,
-
-            #
-            # Schedule initial events.
-            #
-            schedule = [
-                (mentat.const.DFLT_EVENT_START,)
-            ],
-            schedule_after = [
-                (mentat.const.DFLT_INTERVAL_STATISTICS, mentat.const.DFLT_EVENT_LOG_STATISTICS),
-                (mentat.const.DFLT_INTERVAL_RUNLOG,     mentat.const.DFLT_EVENT_SAVE_RUNLOG)
-            ],
-
             #
             # Define required daemon components.
             #
diff --git a/lib/mentat/module/netmngr.py b/lib/mentat/module/netmngr.py
index 8844a377c3bf66acbdb2c42180f783b19dd29f59..f4eda667837aa74ff2e6e60286cd6c5e84f846b2 100644
--- a/lib/mentat/module/netmngr.py
+++ b/lib/mentat/module/netmngr.py
@@ -236,22 +236,7 @@ class MentatNetmngrScript(mentat.script.fetcher.FetcherScript):
         self.sqlservice   = None
 
         super().__init__(
-
             description = 'mentat-netmngr.py - Abuse group network management script for Mentat database',
-
-            #
-            # Configure required script paths.
-            #
-            path_bin = '/usr/local/bin',
-            path_cfg = '/etc/mentat',
-            path_log = '/var/mentat/log',
-            path_run = '/var/mentat/run',
-            path_tmp = '/tmp',
-
-            #
-            # Override default configurations.
-            #
-            default_config_dir = '/etc/mentat/core'
         )
 
     def _init_argparser(self, **kwargs):
@@ -275,7 +260,12 @@ class MentatNetmngrScript(mentat.script.fetcher.FetcherScript):
         #
         arggroup_script = argparser.add_argument_group('custom script arguments')
 
-        arggroup_script.add_argument('--whois-file', type = str, default = None, help = 'path to reference whois file containing network data')
+        arggroup_script.add_argument(
+            '--whois-file',
+            type = str,
+            default = None,
+            help = 'path to reference whois file containing network data'
+        )
 
         return argparser
 
diff --git a/lib/mentat/module/precache.py b/lib/mentat/module/precache.py
index ba36d10988ff6724b96c6fe062debac8c932021d..f055414921046220a29be70f16a85a99787db834 100644
--- a/lib/mentat/module/precache.py
+++ b/lib/mentat/module/precache.py
@@ -101,8 +101,8 @@ import datetime
 # Custom libraries
 #
 import pyzenkit.jsonconf
-import mentat.script.fetcher
 import mentat.const
+import mentat.script.fetcher
 import mentat.system
 
 #
@@ -138,22 +138,7 @@ class MentatPrecacheScript(mentat.script.fetcher.FetcherScript):
         self.sqlservice   = None
 
         super().__init__(
-
             description = 'mentat-precache.py - Mentat database pre-caching script',
-
-            #
-            # Configure required script paths.
-            #
-            path_bin = '/usr/local/bin',
-            path_cfg = '/etc/mentat',
-            path_log = '/var/mentat/log',
-            path_run = '/var/mentat/run',
-            path_tmp = '/tmp',
-
-            #
-            # Override default configurations.
-            #
-            default_config_dir = '/etc/mentat/core'
         )
 
     def _init_argparser(self, **kwargs):
@@ -177,8 +162,18 @@ class MentatPrecacheScript(mentat.script.fetcher.FetcherScript):
         #
         arggroup_script = argparser.add_argument_group('custom script arguments')
 
-        arggroup_script.add_argument('--allow-empty', help = 'allow storing empty item sets as valid result (flag)', action='store_true', default = None)
-        arggroup_script.add_argument('--cache-dir', type = str, default = None, help = 'name of the cache directory')
+        arggroup_script.add_argument(
+            '--allow-empty',
+            action = 'store_true',
+            default = None,
+            help = 'allow storing empty item sets as valid result (flag)'
+        )
+        arggroup_script.add_argument(
+            '--cache-dir',
+            type = str,
+            default = None,
+            help = 'name of the cache directory'
+        )
 
         return argparser
 
@@ -199,7 +194,7 @@ class MentatPrecacheScript(mentat.script.fetcher.FetcherScript):
         cfgs = (
             (self.CONFIG_ITEMSETS,    None),
             (self.CONFIG_ALLOW_EMPTY, False),
-            (self.CONFIG_CACHE_DIR,   '/var/mentat/cache')
+            (self.CONFIG_CACHE_DIR,   os.path.join(self.paths[self.PATH_VAR], 'cache')),
         ) + cfgs
         return super()._init_config(cfgs, **kwargs)
 
diff --git a/lib/mentat/module/reporter.py b/lib/mentat/module/reporter.py
index 209036fe2d460d6d8be496b5e7d0b6313d496c87..cb42c110d17159dac0ada5b6796060519cefad7a 100644
--- a/lib/mentat/module/reporter.py
+++ b/lib/mentat/module/reporter.py
@@ -183,20 +183,6 @@ class MentatReporterScript(mentat.script.fetcher.FetcherScript):
 
             description = 'mentat-reporter.py - Mentat system event reporting',
 
-            #
-            # Configure required script paths.
-            #
-            path_bin = '/usr/local/bin',
-            path_cfg = '/etc/mentat',
-            path_log = '/var/mentat/log',
-            path_run = '/var/mentat/run',
-            path_tmp = '/tmp',
-
-            #
-            # Override default configurations.
-            #
-            default_config_dir = '/etc/mentat/core',
-
             #
             # Load additional application-level plugins.
             #
@@ -241,14 +227,48 @@ class MentatReporterScript(mentat.script.fetcher.FetcherScript):
         #
         arggroup_script = argparser.add_argument_group('custom script arguments')
 
-        arggroup_script.add_argument('--force-mode',        type = str, default = None, help = 'force a reporting mode setting')
-        arggroup_script.add_argument('--force-attachments', type = str, default = None, help = 'force a report attachment setting')
-        arggroup_script.add_argument('--force-template',    type = str, default = None, help = 'force a template for generating reports')
-        arggroup_script.add_argument('--force-locale',      type = str, default = None, help = 'force a locale for generating reports')
-        arggroup_script.add_argument('--force-timezone',    type = str, default = None, help = 'force a timezone for generating reports')
-        arggroup_script.add_argument('--force-max-attachment-size', type = int, default = None, help = 'force maximal size of email attachments in bytes')
-
-        arggroup_script.add_argument('--test-data', help = 'use test data for reporting (flag)', action = 'store_true', default = None)
+        arggroup_script.add_argument(
+            '--force-mode',
+            type = str,
+            default = None,
+            help = 'force a reporting mode setting'
+        )
+        arggroup_script.add_argument(
+            '--force-attachments',
+            type = str,
+            default = None,
+            help = 'force a report attachment setting'
+        )
+        arggroup_script.add_argument(
+            '--force-template',
+            type = str,
+            default = None,
+            help = 'force a template for generating reports'
+        )
+        arggroup_script.add_argument(
+            '--force-locale',
+            type = str,
+            default = None,
+            help = 'force a locale for generating reports'
+        )
+        arggroup_script.add_argument(
+            '--force-timezone',
+            type = str,
+            default = None,
+            help = 'force a timezone for generating reports'
+        )
+        arggroup_script.add_argument(
+            '--force-max-attachment-size',
+            type = int,
+            default = None,
+            help = 'force maximal size of email attachments in bytes'
+        )
+        arggroup_script.add_argument(
+            '--test-data',
+            action = 'store_true',
+            default = None,
+            help = 'use test data for reporting (flag)'
+        )
 
         return argparser
 
diff --git a/lib/mentat/module/sampler.py b/lib/mentat/module/sampler.py
index 6634ed040f43689762d3771c92ec03529d1039dd..b97e8ab62bc277e4b3cc15b6aa1ad7c83b800ebf 100644
--- a/lib/mentat/module/sampler.py
+++ b/lib/mentat/module/sampler.py
@@ -73,35 +73,6 @@ class MentatSamplerDaemon(mentat.daemon.piper.PiperDaemon):
 
             description = 'mentat-sampler.py - IDEA message sampling daemon',
 
-            #
-            # Configure required deamon paths.
-            #
-            path_bin = '/usr/local/bin',
-            path_cfg = '/etc/mentat',
-            path_log = '/var/mentat/log',
-            path_run = '/var/mentat/run',
-            path_tmp = '/tmp',
-
-            #
-            # Override default configurations.
-            #
-            default_config_dir      = '/etc/mentat/core',
-            default_queue_in_dir    = '/var/mentat/spool/mentat-sampler.py',
-            default_queue_out_dir   = None,
-            default_stats_interval  = mentat.const.DFLT_INTERVAL_STATISTICS,
-            default_runlog_interval = mentat.const.DFLT_INTERVAL_RUNLOG,
-
-            #
-            # Schedule initial events.
-            #
-            schedule = [
-                (mentat.const.DFLT_EVENT_START,)
-            ],
-            schedule_after = [
-                (mentat.const.DFLT_INTERVAL_STATISTICS, mentat.const.DFLT_EVENT_LOG_STATISTICS),
-                (mentat.const.DFLT_INTERVAL_RUNLOG,     mentat.const.DFLT_EVENT_SAVE_RUNLOG)
-            ],
-
             #
             # Define required daemon components.
             #
@@ -133,8 +104,18 @@ class MentatSamplerDaemon(mentat.daemon.piper.PiperDaemon):
         #
         arggroup_daemon = argparser.add_argument_group('custom daemon arguments')
 
-        arggroup_daemon.add_argument('--sampling-limit',  help='sampling limit',  type = int, default = None)
-        arggroup_daemon.add_argument('--sampling-policy', help='sampling policy', type = str, default = None)
+        arggroup_daemon.add_argument(
+            '--sampling-limit',
+            type = int,
+            default = None,
+            help = 'sampling limit'
+        )
+        arggroup_daemon.add_argument(
+            '--sampling-policy',
+            type = str,
+            default = None,
+            help = 'sampling policy'
+        )
 
         return argparser
 
diff --git a/lib/mentat/module/statistician.py b/lib/mentat/module/statistician.py
index 07c580ae2d293370ada8f6ff87883f5047d12a36..f33d4ee10ef45804778425edbba02675eac9c7a2 100644
--- a/lib/mentat/module/statistician.py
+++ b/lib/mentat/module/statistician.py
@@ -89,25 +89,11 @@ class MentatStatisticianScript(mentat.script.fetcher.FetcherScript):
         configuration values for parent contructor.
         """
         # Declare private attributes.
+        self.stats_rrd  = None
         self.sqlservice = None
 
         super().__init__(
-
             description = 'mentat-statistician.py - Mentat system statistical script',
-
-            #
-            # Configure required script paths.
-            #
-            path_bin = '/usr/local/bin',
-            path_cfg = '/etc/mentat',
-            path_log = '/var/mentat/log',
-            path_run = '/var/mentat/run',
-            path_tmp = '/tmp',
-
-            #
-            # Override default configurations.
-            #
-            default_config_dir = '/etc/mentat/core'
         )
 
     def _sub_stage_init(self, **kwargs):
diff --git a/lib/mentat/module/storage.py b/lib/mentat/module/storage.py
index 822af08c1c31a8c9f4ff7ab8201cd04cfd64b768..c412a9e22f2b4ccb25d75442bb894405d1ff4ec9 100644
--- a/lib/mentat/module/storage.py
+++ b/lib/mentat/module/storage.py
@@ -71,35 +71,6 @@ class MentatStorageDaemon(mentat.daemon.piper.PiperDaemon):
 
             description = 'mentat-storage.py - IDEA message storing daemon',
 
-            #
-            # Configure required deamon paths.
-            #
-            path_bin = '/usr/local/bin',
-            path_cfg = '/etc/mentat',
-            path_log = '/var/mentat/log',
-            path_run = '/var/mentat/run',
-            path_tmp = '/var/tmp',
-
-            #
-            # Override default configurations.
-            #
-            default_config_dir      = '/etc/mentat/core',
-            default_queue_in_dir    = '/var/mentat/spool/mentat-storage.py',
-            default_queue_out_dir   = None,
-            default_stats_interval  = mentat.const.DFLT_INTERVAL_STATISTICS,
-            default_runlog_interval = mentat.const.DFLT_INTERVAL_RUNLOG,
-
-            #
-            # Schedule initial events.
-            #
-            schedule = [
-                (mentat.const.DFLT_EVENT_START,)
-            ],
-            schedule_after = [
-                (mentat.const.DFLT_INTERVAL_STATISTICS, mentat.const.DFLT_EVENT_LOG_STATISTICS),
-                (mentat.const.DFLT_INTERVAL_RUNLOG,     mentat.const.DFLT_EVENT_SAVE_RUNLOG)
-            ],
-
             #
             # Define required daemon components.
             #
diff --git a/lib/mentat/script/base.py b/lib/mentat/script/base.py
new file mode 100644
index 0000000000000000000000000000000000000000..3b3ec01b9c64f7eb0d56006d2bbaf20e0cd3cf35
--- /dev/null
+++ b/lib/mentat/script/base.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#-------------------------------------------------------------------------------
+# This file is part of Mentat system (https://mentat.cesnet.cz/).
+#
+# Copyright (C) since 2011 CESNET, z.s.p.o (http://www.ces.net/)
+# Use of this source is governed by the MIT license, see LICENSE file.
+#-------------------------------------------------------------------------------
+
+
+"""
+This module provides base implementation of all Mentat scripts.
+"""
+
+
+__author__ = "Jan Mach <jan.mach@cesnet.cz>"
+__credits__ = "Pavel Kácha <pavel.kacha@cesnet.cz>, Andrea Kropáčová <andrea.kropacova@cesnet.cz>"
+
+
+#
+# Custom libraries.
+#
+import pyzenkit.baseapp
+import pyzenkit.zenscript
+import mentat.const
+
+
+class MentatBaseScript(pyzenkit.zenscript.ZenScript):  # pylint: disable=locally-disabled,abstract-method
+    """
+    Base implementation of all Mentat scripts.
+    """
+
+    def __init__(self, **kwargs):
+        #
+        # Configure required script paths.
+        #
+        kwargs.setdefault('path_cfg', mentat.const.PATH_CFG)
+        kwargs.setdefault('path_var', mentat.const.PATH_VAR)
+        kwargs.setdefault('path_log', mentat.const.PATH_LOG)
+        kwargs.setdefault('path_run', mentat.const.PATH_RUN)
+        kwargs.setdefault('path_tmp', mentat.const.PATH_TMP)
+
+        #
+        # Override default configurations.
+        #
+        kwargs.setdefault(
+            'default_config_dir',
+            self.get_resource_path(mentat.const.PATH_CFG_CORE)
+        )
+
+        super().__init__(**kwargs)
diff --git a/lib/mentat/script/fetcher.py b/lib/mentat/script/fetcher.py
index ebb644b2db226b6aa89d9d1660c671566be0c9c6..5cdc50289d566923f61ca07f69a86cf8af384eb1 100644
--- a/lib/mentat/script/fetcher.py
+++ b/lib/mentat/script/fetcher.py
@@ -28,11 +28,12 @@ import time
 import pyzenkit.baseapp
 import pyzenkit.zenscript
 import mentat.const
+import mentat.script.base
 import mentat.plugin.app.eventstorage
 import mentat.plugin.app.sqlstorage
 
 
-class FetcherScript(pyzenkit.zenscript.ZenScript):  # pylint: disable=locally-disabled,abstract-method
+class FetcherScript(mentat.script.base.MentatBaseScript):  # pylint: disable=locally-disabled,abstract-method
     """
     Base implementation of generic message fetching and processing script.
     """
@@ -150,11 +151,12 @@ class DemoFetcherScript(FetcherScript):
             #
             # Configure required script paths.
             #
-            path_bin = '/tmp',
-            path_cfg = '/tmp',
-            path_log = '/tmp',
-            path_run = '/tmp',
-            path_tmp = '/tmp',
+            path_bin = 'tmp',
+            path_cfg = 'tmp',
+            path_var = 'tmp',
+            path_log = 'tmp',
+            path_run = 'tmp',
+            path_tmp = 'tmp',
 
             #
             # Override default configurations.
diff --git a/lib/mentat/system.py b/lib/mentat/system.py
index a34a8a6ae308ad4795db57600537ea7bbcb97697..d0fd42f797676af9c447d5e9a0be5e3622be8232 100644
--- a/lib/mentat/system.py
+++ b/lib/mentat/system.py
@@ -729,7 +729,7 @@ def module_status(mod_data, pidf_data, proc_data, overall_status):
                     STATUS_RT_RUNNING_FEWER,
                     "There are fewer instances running than required ({}:{})".format(mod_data.count, len(proc_data.keys()))
                 )
-            elif mod_data.count < len(proc_data.keys()):
+            if mod_data.count < len(proc_data.keys()):
                 return (
                     STATUS_RT_RUNNING_MORE,
                     "There are more instances running than required ({}:{})".format(mod_data.count, len(proc_data.keys()))
diff --git a/setup.py b/setup.py
index 4e2cf2c4559639926da24efc5fdf502576fac36f..2a790b998a2750606e248fa47f30813333a54517 100644
--- a/setup.py
+++ b/setup.py
@@ -104,7 +104,6 @@ setup(
         'bin/mentat-controller.py',
         'bin/mentat-dbmngr.py',
         'bin/mentat-enricher.py',
-        'bin/mentat-hawat.py',
         'bin/mentat-hawat.wsgi',
         'bin/mentat-ideagen.py',
         'bin/mentat-informant.py',