diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/App.java b/src/main/java/de/tudresden/inf/mci/brailleplot/App.java
index 9074a22d9cf8b30bb99ea335862ca556cd1b938b..7dc49223a3ed0186247595eefab2baa51d3d36a4 100644
--- a/src/main/java/de/tudresden/inf/mci/brailleplot/App.java
+++ b/src/main/java/de/tudresden/inf/mci/brailleplot/App.java
@@ -42,9 +42,11 @@ import tec.units.ri.unit.MetricPrefix;
 import javax.measure.Quantity;
 import javax.measure.quantity.Length;
 import java.io.BufferedReader;
+import java.io.File;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
+import java.net.URL;
 import java.util.Optional;
 import java.util.concurrent.ConcurrentLinkedDeque;
 
@@ -166,17 +168,14 @@ public final class App {
             }
 
             // Config Parsing
-            String configPath;
+            URL configPath;
             if (!settingsReader.isPresent(SettingType.PRINTER_CONFIG_PATH)) { // TODO: exception if missing this argument, until then use default location for test runs
-                configPath = getClass().getResource("/config/index_everest_d_v4.properties").getFile();
+                configPath = getClass().getResource("/config/index_everest_d_v4.properties");
             } else {
-                configPath = settingsReader.getSetting(SettingType.PRINTER_CONFIG_PATH).get();
+                configPath = new URL(settingsReader.getSetting(SettingType.PRINTER_CONFIG_PATH).get());
             }
 
-            JavaPropertiesConfigurationParser configParser = new JavaPropertiesConfigurationParser(
-                    configPath,
-                    "/config/default.properties"
-            );
+            JavaPropertiesConfigurationParser configParser = new JavaPropertiesConfigurationParser(configPath, getClass().getClassLoader().getResource("config/default.properties"));
             Printer indexV4Printer = configParser.getPrinter();
             Format a4Format = configParser.getFormat("A4");
 
diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/GeneralResource.java b/src/main/java/de/tudresden/inf/mci/brailleplot/GeneralResource.java
index 92ba1c802aecb8ce2b300db2ce69ed4e821d5e73..c647880df7baf46b1d6022bc464584c31d2b76a3 100644
--- a/src/main/java/de/tudresden/inf/mci/brailleplot/GeneralResource.java
+++ b/src/main/java/de/tudresden/inf/mci/brailleplot/GeneralResource.java
@@ -70,8 +70,8 @@ public final class GeneralResource {
                 validExternalFile = true;
             }
         }
-        String resourceClassPath = resourcePath.replace("\\", "/"); // classpaths are always separated by forward slash
-        InputStream checkStream = getClass().getResourceAsStream(resourceClassPath);
+        String resourceClassPath = resourcePath.replace(File.separator, "/"); // classpaths are always separated by forward slash
+        InputStream checkStream = getClass().getClassLoader().getResourceAsStream(resourceClassPath);
         mLogger.trace("checking referenced path as resource: " + resourceClassPath);
         if (Objects.nonNull(checkStream)) {
             mLogger.trace("interpreting path as resource stream: " + resourceClassPath);
@@ -81,7 +81,7 @@ public final class GeneralResource {
         if (Objects.nonNull(searchPath)) {
             String relativeResourcePath = new File(searchPath + File.separator + resourceClassPath).toPath().normalize().toString();
             relativeResourcePath = relativeResourcePath.replace("\\", "/");
-            checkStream = getClass().getResourceAsStream(relativeResourcePath);
+            checkStream = getClass().getClassLoader().getResourceAsStream(relativeResourcePath);
             mLogger.trace("checking referenced path as search path relative resource: " + relativeResourcePath);
             if (Objects.nonNull(checkStream)) {
                 mLogger.trace("interpreting path as resource stream: " + relativeResourcePath);
diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/configparser/ConfigurationParser.java b/src/main/java/de/tudresden/inf/mci/brailleplot/configparser/ConfigurationParser.java
index bdd14b694134e933355410cd845d1c23ee7b9b7f..9fbcdbb8f4b1580adfe5ae1e37b084c21c530b6d 100644
--- a/src/main/java/de/tudresden/inf/mci/brailleplot/configparser/ConfigurationParser.java
+++ b/src/main/java/de/tudresden/inf/mci/brailleplot/configparser/ConfigurationParser.java
@@ -5,8 +5,13 @@ import org.slf4j.LoggerFactory;
 
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -27,41 +32,34 @@ public abstract class ConfigurationParser {
     private ConfigurationValidator mValidator;
     private Printer mPrinter;
     private Map<String, Format> mFormats = new HashMap<>();
-    private File mCurrentConfigFile;
     private List<PrinterProperty> mPrinterProperties = new ArrayList<>();
     private Map<String, List<FormatProperty>> mFormatProperties = new HashMap<>();
     private Printer mDefaultPrinter;
     private Format mDefaultFormat;
 
-    private final Logger mLogger;
+    protected final Logger mLogger = LoggerFactory.getLogger(getClass());
 
     ConfigurationParser() {
-        mLogger = LoggerFactory.getLogger(this.getClass());
-    };
+    }
+
+    ;
 
     /**
      * Internal algorithm used for parsing of the configuration file.
      * Implement this method by parsing information from the given input stream, optionally validating it (see {@link ConfigurationValidator}),
      * constructing {@link PrinterProperty} and {@link FormatProperty} objects from this information and adding them with the methods
      * {@link #addProperty(PrinterProperty)} and {@link #addProperty(FormatProperty)}.
-     * This method is called by ({@link #parseConfigFile(String, boolean)}).
-     * @param input The input stream to read the configuration from.
-     * @throws ConfigurationParsingException On any error while accessing the configuration file or syntax.
+     * This method is called by ({@link #parseConfigFile(InputStream, URL, boolean)}).
+     *
+     * @param inStream The input stream to read the configuration from.
+     * @throws ConfigurationParsingException    On any error while accessing the configuration file or syntax.
      * @throws ConfigurationValidationException On any error while checking the parsed properties validity.
      */
-    protected abstract void parse(InputStream input) throws ConfigurationParsingException, ConfigurationValidationException;
-
-
-    /**
-     * Get the current configuration file.
-     * @return A {@link File} object representing the configuration file.
-     */
-    public final File getConfigFile() {
-        return mCurrentConfigFile;
-    }
+    protected abstract void parse(InputStream inStream, URL path) throws ConfigurationParsingException, ConfigurationValidationException;
 
     /**
      * Get the printer configuration.
+     *
      * @return A {@link Printer} object, representing the printers properties.
      */
     public final Printer getPrinter() {
@@ -70,6 +68,7 @@ public abstract class ConfigurationParser {
 
     /**
      * Get the names of all available format configurations.
+     *
      * @return A {@link Set}&lt;{@link String}&gt; containing the name of each format.
      */
     public final Set<String> getFormatNames() {
@@ -78,6 +77,7 @@ public abstract class ConfigurationParser {
 
     /**
      * Get a specific format configuration.
+     *
      * @param formatName The name of the format.
      * @return A {@link Format} object, representing the formats properties.
      * @throws NoSuchElementException If no format has the specified name.
@@ -93,6 +93,7 @@ public abstract class ConfigurationParser {
     /**
      * Set a {@link ConfigurationValidator} for this parser.
      * This method should be called inside the concrete parsers constructor
+     *
      * @param validator The {@link ConfigurationValidator} object.
      */
     protected void setValidator(final ConfigurationValidator validator) {
@@ -101,6 +102,7 @@ public abstract class ConfigurationParser {
 
     /**
      * Get the {@link ConfigurationValidator} for this parser.
+     *
      * @return A {@link ConfigurationValidator} object.
      */
     protected ConfigurationValidator getValidator() {
@@ -109,6 +111,7 @@ public abstract class ConfigurationParser {
 
     /**
      * Add a general printer property to the internal printer configuration representation.
+     *
      * @param property The represented property of the printer.
      */
     protected void addProperty(final PrinterProperty property) {
@@ -117,6 +120,7 @@ public abstract class ConfigurationParser {
 
     /**
      * Add a specific format property to the internal list of format configuration representation.
+     *
      * @param property The represented property of a specific format.
      */
     protected void addProperty(final FormatProperty property) {
@@ -130,34 +134,61 @@ public abstract class ConfigurationParser {
     /**
      * Set the optional default configurations for {@link Printer} and {@link Format} objects created by this parser.
      * This method should be called inside the concrete parsers constructor.
+     *
      * @param defaultPrinter A {@link Printer} object containing the default properties or null for no default to be set.
-     * @param defaultFormat A {@link Format} object containing the default properties or null for no default to be set.
+     * @param defaultFormat  A {@link Format} object containing the default properties or null for no default to be set.
      */
     protected final void setDefaults(final Printer defaultPrinter, final Format defaultFormat) {
         mDefaultPrinter = defaultPrinter;
         mDefaultFormat = defaultFormat;
     }
 
+    /**
+     * Parse a configuration file from the resource folder
+     * As we know the root path of the configuration files, there is no need to specify any further.
+     */
+    protected final void parseConfigFileFromResource(final URL resource, final boolean assertCompleteness) throws ConfigurationParsingException, ConfigurationValidationException {
+        Objects.requireNonNull(resource);
+
+        mLogger.debug("Starting parsing properties file from java resources: \"{}\"", resource);
+
+        try {
+            parseConfigFile(resource.openStream(), getParentUrl(resource), assertCompleteness);
+        } catch (IOException|ConfigurationParsingException e) {
+            throw new ConfigurationParsingException("Could not open resource at \"" + resource.toString() + "\"", e);
+        }
+    }
+
+    protected final void parseConfigFileFromFileSystem(final Path filePath, final boolean assertCompleteness) throws ConfigurationParsingException, ConfigurationValidationException {
+        Objects.requireNonNull(filePath);
+
+        mLogger.debug("Starting parsing properties file from file system: \"{}\"", filePath);
+
+        try {
+            parseConfigFile(new FileInputStream(filePath.toFile()), filePath.toFile().toURI().toURL(), assertCompleteness);
+        } catch (FileNotFoundException | MalformedURLException e) {
+            throw new ConfigurationParsingException("Configuration file could not be read at \"" + filePath.toString() + "\"");
+        }
+    }
+
     /**
      * Parse the specified configuration file.
      * This method should be called inside the concrete parsers constructor after the optional default configurations
      * ({@link #setDefaults(Printer, Format)}) and the validator ({@link #setValidator(ConfigurationValidator)}) have been set.
-     * @param filePath The configuration file to be parsed. The type depends on the concrete implementation of the parser.
+     *
+     * @param config             The {@link File} to be parsed. The type depends on the concrete implementation of the parser.
      * @param assertCompleteness Signals whether to check for existence of all required properties or not.
-     * @throws ConfigurationParsingException On any error while accessing the configuration file or syntax
+     * @throws ConfigurationParsingException    On any error while accessing the configuration file or syntax
      * @throws ConfigurationValidationException On any error while checking the parsed properties validity.
      */
-    protected final void parseConfigFile(final String filePath, final boolean assertCompleteness)
+    private void parseConfigFile(final InputStream config, final URL path, final boolean assertCompleteness)
             throws ConfigurationParsingException, ConfigurationValidationException {
         // reset internal property buffer
         mPrinterProperties.clear();
         mFormatProperties.clear();
+        mValidator.setSearchPath(getPath(path));
         // load and parse file
-        mCurrentConfigFile = new File(filePath);
-        InputStream input = openInputStream(filePath);
-        getValidator().setSearchPath(Objects.requireNonNullElse(getConfigFile().getParent(), ""));
-        parse(input);
-        closeInputStream(input);
+        parse(config, path);
         // build printer object from added properties
         mPrinter = new Printer(mPrinterProperties);
         if (mDefaultPrinter != null) {
@@ -179,42 +210,19 @@ public abstract class ConfigurationParser {
         }
     }
 
-    /**
-     * Opens the input stream for the given file path.
-     * @param filePath The file to read from.
-     * @return A {@link FileInputStream} for the given file path.
-     * @throws ConfigurationParsingException On any error while opening the stream. (e.g. missing file)
-     */
-    final InputStream openInputStream(final String filePath) throws ConfigurationParsingException {
-        // This has to take the fact into consideration, that a resource from a packaged jar is not a real file in
-        // the file system and must be read via classloader resource stream.  We want to be able to process files as
-        // well as packed resources.
+    private URL getParentUrl(final URL resourcePath) throws ConfigurationParsingException {
+        String fileString = resourcePath.getPath();
+        String parentString = fileString.substring(0, fileString.lastIndexOf("/"));
         try {
-            // first try to read as file
-            mLogger.info("trying to open as file: " + filePath);
-            return new FileInputStream(filePath);
-        } catch (IOException e) {
-            // if that fails, try to read as resource
-            mLogger.info("trying to open as resource: " + filePath);
-            InputStream resourceStream = this.getClass().getResourceAsStream(filePath);
-            if (Objects.isNull(resourceStream)) {
-                // if that also fails:
-                throw new ConfigurationParsingException("Unable to read configuration file / resource.", e);
-            }
-            return resourceStream;
+            return new URL(resourcePath.getProtocol(), resourcePath.getHost(), parentString);
+        } catch (MalformedURLException e) {
+            throw new ConfigurationParsingException("Could not create URL to parent path", e);
         }
     }
 
-    /**
-     * Closes the given input stream.
-     * @param input The {@link FileInputStream} to be closed.
-     * @throws ConfigurationParsingException On any error while closing the stream.
-     */
-    final void closeInputStream(final InputStream input) throws ConfigurationParsingException {
-        try {
-            input.close();
-        } catch (IOException e) {
-            throw new ConfigurationParsingException("Unable to close input stream.", e);
-        }
+    protected String getPath(final URL url) {
+        String urlString = url.getPath();
+        String ret = urlString.replace("file:", "");
+        return ret;
     }
 }
diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/configparser/JavaPropertiesConfigurationParser.java b/src/main/java/de/tudresden/inf/mci/brailleplot/configparser/JavaPropertiesConfigurationParser.java
index 39611e2397549052991b5f6823219e8e2453788b..9a571bad77bf0006709e7e0e33b563967855fa00 100644
--- a/src/main/java/de/tudresden/inf/mci/brailleplot/configparser/JavaPropertiesConfigurationParser.java
+++ b/src/main/java/de/tudresden/inf/mci/brailleplot/configparser/JavaPropertiesConfigurationParser.java
@@ -1,24 +1,27 @@
 package de.tudresden.inf.mci.brailleplot.configparser;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
+import java.io.BufferedInputStream;
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.Objects;
 import java.util.Properties;
-import java.util.Stack;
 
 /**
  * Concrete parser for configuration files in Java Property File format.
- * @author Leonard Kupper
- * @version 2019.07.18
+ * @author Leonard Kupper, Georg Graßnick
+ * @version 2019.09.16
  */
 public final class JavaPropertiesConfigurationParser extends ConfigurationParser {
 
-    Stack<File> mInclusionStack = new Stack<>();
-    private final Logger mLogger;
+    private static final String INCLUDE_FILE_EXTENSION = ".properties";
 
     /**
      * Constructor.
@@ -29,39 +32,66 @@ public final class JavaPropertiesConfigurationParser extends ConfigurationParser
      * @throws ConfigurationParsingException On any error while accessing the configuration file or syntax.
      * @throws ConfigurationValidationException On any error while checking the parsed properties validity.
      */
-    public JavaPropertiesConfigurationParser(
-            final String filePath,
-            final String defaultPath
-    ) throws ConfigurationParsingException, ConfigurationValidationException {
-        mLogger = LoggerFactory.getLogger(this.getClass());
-        setValidator(new JavaPropertiesConfigurationValidator());
-        parseConfigFile(defaultPath, false);
+    public JavaPropertiesConfigurationParser(final Path filePath, final URL defaultPath) throws ConfigurationParsingException, ConfigurationValidationException {
+        setup();
+        parseConfigFileFromResource(defaultPath, false);
+        setDefaults(getPrinter(), getFormat("default"));
+        parseConfigFileFromFileSystem(filePath, true);
+    }
+
+    public JavaPropertiesConfigurationParser(final Path filePath, final Path defaultPath) throws ConfigurationParsingException, ConfigurationValidationException {
+        setup();
+        parseConfigFileFromFileSystem(defaultPath, false);
+        setDefaults(getPrinter(), getFormat("default"));
+        parseConfigFileFromFileSystem(filePath, true);
+    }
+
+    public JavaPropertiesConfigurationParser(final URL filePath, final Path defaultPath) throws ConfigurationParsingException, ConfigurationValidationException {
+        setup();
+        parseConfigFileFromFileSystem(defaultPath, false);
         setDefaults(getPrinter(), getFormat("default"));
-        parseConfigFile(filePath, true);
+        parseConfigFileFromResource(filePath, true);
+    }
+
+    public JavaPropertiesConfigurationParser(final URL filePath, final URL defaultPath) throws ConfigurationParsingException, ConfigurationValidationException {
+        setup();
+        parseConfigFileFromResource(defaultPath, false);
+        setDefaults(getPrinter(), getFormat("default"));
+        parseConfigFileFromResource(filePath, true);
+    }
+
+    private void setup() {
+        setValidator(new JavaPropertiesConfigurationValidator());
     }
 
     /**
      * Concrete internal algorithm used for parsing the Java Property File.
-     * This method is called by ({@link #parseConfigFile(String, boolean)}) and will call itself recursively for every included file.
-     * @param input The input stream to read the configuration properties from.
+     * This method is called by ({@link ConfigurationParser#parseConfigFileFromFileSystem(Path, boolean)} (InputStream, boolean)})
+     * or {@link ConfigurationParser#parseConfigFileFromResource(URL, boolean)} and will call itself recursively for every included file.
+     * @param inStream The fileToParse stream to read the configuration properties from.
      * @throws ConfigurationParsingException On any error while accessing the configuration file or syntax.
      * @throws ConfigurationValidationException On any error while checking the parsed properties validity.
      */
-    protected void parse(final InputStream input) throws ConfigurationParsingException, ConfigurationValidationException {
+    protected void parse(final InputStream inStream, final URL path) throws ConfigurationParsingException, ConfigurationValidationException {
+        Objects.requireNonNull(inStream);
+        Objects.requireNonNull(path);
         // Create property instance for current recursion level
         Properties properties = new Properties();
+
         try {
             // Load properties from the .properties file
-            properties.load(input);
+            properties.load(inStream);
         } catch (IOException e) {
-            throw new ConfigurationParsingException("Unable to load properties from file.", e);
+            throw new ConfigurationParsingException("Unable to load properties from file \"" + inStream + "\"", e);
         }
         // Iterate over all properties as key -> value pairs
         for (String key : properties.stringPropertyNames()) {
             String value = properties.getProperty(key);
             // check for special property key: 'include'
-            if (("include").equals(key.toLowerCase())) {
-                includeFiles(value);
+            if (key.equalsIgnoreCase("include")) {
+                includeResource(value, path);
+            } else if (key.equalsIgnoreCase("include-file")) {
+                includeFiles(value, path);
             } else {
                 parseProperty(key, value);
             }
@@ -69,6 +99,7 @@ public final class JavaPropertiesConfigurationParser extends ConfigurationParser
     }
 
     private void parseProperty(final String key, final String value) throws ConfigurationValidationException {
+        mLogger.trace("Parsed property \"{}\" with value \"{}\"", key, value);
         ValidProperty property = getValidator().validate(key, value);
         if (property instanceof FormatProperty) {
             addProperty((FormatProperty) property);
@@ -78,38 +109,51 @@ public final class JavaPropertiesConfigurationParser extends ConfigurationParser
         }
     }
 
-    private void includeFiles(final String fileList) throws ConfigurationParsingException, ConfigurationValidationException {
-        for (String includeName : fileList.split(",")) {
-            if (mInclusionStack.empty()) {
-                mInclusionStack.push(getConfigFile());
-            }
-            File includeFile, parentFile = Objects.requireNonNullElse(mInclusionStack.peek().getParentFile(), new File(""));
+    /**
+     * Recursively parses the configuration file.
+     * This method handles files on the local file system.
+     * @param fileList
+     * @throws ConfigurationParsingException
+     * @throws ConfigurationValidationException
+     */
+    private void includeFiles(final String fileList, final URL parentUrl) throws ConfigurationParsingException, ConfigurationValidationException {
+        for (String s : fileList.split(",")) {
+
+            Path parentPath = null;
             try {
-                String findIncludePath = parentFile.getAbsolutePath() + File.separator + includeName.trim();
-                File abstractPath = new File(findIncludePath);
-                if (!abstractPath.exists()) {
-                    abstractPath = new File(findIncludePath + ".properties");
-                }
-                includeFile = abstractPath.getCanonicalFile();
-                if (!includeFile.isFile()) {
-                    throw new ConfigurationParsingException("Given include path is not a file: " + includeFile);
-                }
-            } catch (IOException e) {
-                throw new ConfigurationParsingException("Can not find include file.", e);
+                parentPath = Path.of(parentUrl.toURI());
+            } catch (URISyntaxException e) {
+                throw new ConfigurationParsingException("Could not generate URI", e);
             }
-            if (mInclusionStack.contains(includeFile)) {
-                continue;
+            Path newPath = parentPath.getParent().resolve(s.trim() + INCLUDE_FILE_EXTENSION);
+            String newPathString = newPath.toAbsolutePath().toString();
+
+            mLogger.debug("Prepare recursive parsing of properties file in the file system for file \"{}\"", newPathString);
+
+            try (InputStream is = new BufferedInputStream(new FileInputStream(newPathString))) {
+                parse(is, newPath.toUri().toURL());
+            } catch (IOException e) {
+                throw new ConfigurationParsingException("Could not open include file", e);
             }
-            InputStream includeInput = openInputStream(includeFile.getAbsolutePath());
+        }
+    }
+
+    private void includeResource(final String fileList, final URL parentUrl) throws ConfigurationParsingException, ConfigurationValidationException {
+        for (String s : fileList.split(",")) {
+
+            URL newUrl = null;
             try {
-                mInclusionStack.push(includeFile);
-                mLogger.info("Including config file: " + includeFile);
-                getValidator().setSearchPath(Objects.requireNonNullElse(mInclusionStack.peek().getParent(), ""));
-                parse(includeInput);
-                mInclusionStack.pop();
-                getValidator().setSearchPath(Objects.requireNonNullElse(mInclusionStack.peek().getParent(), ""));
-            } finally {
-                closeInputStream(includeInput);
+                newUrl = new URL(parentUrl + "/" + s.trim() + INCLUDE_FILE_EXTENSION);
+            } catch (MalformedURLException e) {
+                throw new ConfigurationParsingException("Could not generate URI", e);
+            }
+
+            mLogger.debug("Prepare recursive parsing of properties file in the java resources at \"{}\"", newUrl);
+
+            try (InputStream is = newUrl.openStream()) {
+                parse(is, newUrl);
+            } catch (IOException e) {
+                throw new ConfigurationParsingException("Could not open include resource", e);
             }
         }
     }