diff --git a/src/integrationTest/java/PrintableDataExporterIntegTest.java b/src/integrationTest/java/PrintableDataExporterIntegTest.java
index 5d887597aed7972e852c97e3c6d3e2acfeac750e..39ddef7d56907c7a2f3246c2cfa7bdc0bf8d4d60 100644
--- a/src/integrationTest/java/PrintableDataExporterIntegTest.java
+++ b/src/integrationTest/java/PrintableDataExporterIntegTest.java
@@ -14,10 +14,10 @@ import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
 import javax.print.DocFlavor;
-import java.io.File;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.net.URL;
 
 /**
  * Integrationtests for the components PrintableData and Exporter.
@@ -45,8 +45,8 @@ public class PrintableDataExporterIntegTest {
     @BeforeAll
     public static void setUp() {
         Assertions.assertDoesNotThrow(() -> {
-            String correct = getResource("config/correct.properties").getAbsolutePath();
-            String standard = getResource("config/default.properties").getAbsolutePath();
+            URL correct = ClassLoader.getSystemClassLoader().getResource("config/correct.properties");
+            URL standard = ClassLoader.getSystemClassLoader().getResource("config/default.properties");
             JavaPropertiesConfigurationParser configParser = new JavaPropertiesConfigurationParser(correct, standard);
             printer = configParser.getPrinter();
             printer.getProperty("brailletable").toString();
@@ -55,11 +55,6 @@ public class PrintableDataExporterIntegTest {
         });
     }
 
-    public static File getResource(String fileName) {
-        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
-        File resourceFile = new File(classLoader.getResource(fileName).getFile());
-        return resourceFile;
-    }
     /**
      * Unittest/Integrationtest for the private Print method with a Null Servive.
      * Expected: Nullpointerexception.
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 fea3496dbc2042a5b1b14800bbb79adf3183b68e..ada2210886f06dae999db4d43f658ab5e2bd17dd 100644
--- a/src/main/java/de/tudresden/inf/mci/brailleplot/App.java
+++ b/src/main/java/de/tudresden/inf/mci/brailleplot/App.java
@@ -45,6 +45,7 @@ import java.io.BufferedReader;
 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,18 +167,15 @@ 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");
                 mLogger.warn("ATTENTION! Using default specific config from resources. Please remove default config behavior before packaging the jar.");
-                configPath = getClass().getResource("/config/index_everest_d_v4.properties").getFile();
             } 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/brailleparser/PropertiesParser.java b/src/main/java/de/tudresden/inf/mci/brailleplot/brailleparser/PropertiesParser.java
index ed095f3b562f3e8e5b35598dc78aa3a19e40303e..41869b198f888bfceaeb41b406399c9b09614fe9 100644
--- a/src/main/java/de/tudresden/inf/mci/brailleplot/brailleparser/PropertiesParser.java
+++ b/src/main/java/de/tudresden/inf/mci/brailleplot/brailleparser/PropertiesParser.java
@@ -1,6 +1,6 @@
 package de.tudresden.inf.mci.brailleplot.brailleparser;
 
-import de.tudresden.inf.mci.brailleplot.GeneralResource;
+import de.tudresden.inf.mci.brailleplot.util.GeneralResource;
 
 import java.io.InputStream;
 import java.util.Objects;
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..4ee9bc3995deda6577681d1e6220b4ac050ff3fb 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
@@ -3,10 +3,13 @@ package de.tudresden.inf.mci.brailleplot.configparser;
 import org.slf4j.Logger;
 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.URL;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -18,8 +21,8 @@ import java.util.Set;
 /**
  * Abstract parser for configuration files. Interface for {@link Printer} and multiple {@link Format} configurations.
  * Must be extended to implement a concrete parsing algorithm for a specific file format.
- * @author Leonard Kupper
- * @version 2019.07.18
+ * @author Leonard Kupper, Georg Graßnick
+ * @version 2019.09.23
  */
 
 public abstract class ConfigurationParser {
@@ -27,41 +30,32 @@ 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.
+     * @param path The URL identifying the location of the source of the {@link InputStream}. Required the inclusion of configurations from relative paths.
+     * @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 +64,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 +73,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 +89,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 +98,7 @@ public abstract class ConfigurationParser {
 
     /**
      * Get the {@link ConfigurationValidator} for this parser.
+     *
      * @return A {@link ConfigurationValidator} object.
      */
     protected ConfigurationValidator getValidator() {
@@ -109,6 +107,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 +116,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 +130,70 @@ 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.
+     * @param resource The URL identifying the configuration file.
+     * @param assertCompleteness Signals whether to check for existence of all required properties or not
+     * @throws ConfigurationParsingException if an error occurred reading from the resource identified by the URL resource parameter
+     * @throws ConfigurationValidationException if an exception occurred while calling the {@link JavaPropertiesConfigurationValidator}
+     */
+    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 e) {
+            throw new ConfigurationParsingException("Could not open resource at \"" + resource.toString() + "\"", e);
+        }
+    }
+
+    /**
+     * Parse a configuration file from the file system.
+     * @param filePath The location of the file to parse.
+     * @param assertCompleteness Signals whether to check for existence of all required properties or not
+     * @throws ConfigurationParsingException if the file could not be read correctly
+     * @throws ConfigurationValidationException if an exception occurred while calling the {@link JavaPropertiesConfigurationValidator}
+     */
+    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 InputStream} to be parsed
      * @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) {
@@ -180,41 +216,29 @@ 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)
+     * Returns the URL to the parent directory of a File / Resource.
+     * @param resourcePath The URL to analyze.
+     * @return The URL to the parent directory of the specified URL.
+     * @throws ConfigurationParsingException if the generated URL is not a valid URL.
      */
-    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 static 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.
+     * Return a String representation of the path of a {@link URL}.
+     * Strips the {@literal "}file:{@literal "} prefix from an URL, if it exist.
+     * @param url The URL that needs to be stripped
+     * @return The String representation of the path of a URL where the leading {@literal "}file:{@literal "} prefix is stripped.
      */
-    final void closeInputStream(final InputStream input) throws ConfigurationParsingException {
-        try {
-            input.close();
-        } catch (IOException e) {
-            throw new ConfigurationParsingException("Unable to close input stream.", e);
-        }
+    private static String getPath(final URL url) {
+        String urlString = url.getPath();
+        return urlString.replaceAll("^file:", "");
     }
 }
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..0cb2a42fd35a4a380ed3ac950a99d9c8b8e32ab2 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,24 @@
 package de.tudresden.inf.mci.brailleplot.configparser;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
 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.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.23
  */
 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 +29,67 @@ 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"));
+        parseConfigFileFromResource(filePath, true);
+    }
+
+    public JavaPropertiesConfigurationParser(final URL filePath, final URL defaultPath) throws ConfigurationParsingException, ConfigurationValidationException {
+        setup();
+        parseConfigFileFromResource(defaultPath, false);
         setDefaults(getPrinter(), getFormat("default"));
-        parseConfigFile(filePath, true);
+        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)} where it was called to include other configurations.
+     * @param inStream The fileToParse stream to read the configuration properties from.
+     * @param path The URL identifying the location of the source of the {@link InputStream}. Required the inclusion of configurations from relative paths.
      * @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 +97,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 +107,59 @@ 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 The string representations of the paths to include.
+     * @param parentUrl The URL identifying the context from where the method was called. Required to construct relative paths.
+     * @throws ConfigurationParsingException If something went wrong while reading from the included files.
+     * @throws ConfigurationValidationException On any error while checking the parsed properties validity.
+     */
+    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());
+        }
+    }
+
+    /**
+     * Recursively parse configuration from a java resource.
+     * @param fileList The string representations of the paths to include.
+     * @param parentUrl The URL identifying the context from where the method was called. Required to construct relative paths.
+     * @throws ConfigurationParsingException If errors occurred while reading from a resource.
+     * @throws ConfigurationValidationException On any error while checking the parsed properties validity.
+     */
+    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);
             }
         }
     }
diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/configparser/JavaPropertiesConfigurationValidator.java b/src/main/java/de/tudresden/inf/mci/brailleplot/configparser/JavaPropertiesConfigurationValidator.java
index d8f5ecf10e7545674f1403b41e6fb4d1c1f3979d..124a55667f1848191aae837a3f879d6abb96054b 100644
--- a/src/main/java/de/tudresden/inf/mci/brailleplot/configparser/JavaPropertiesConfigurationValidator.java
+++ b/src/main/java/de/tudresden/inf/mci/brailleplot/configparser/JavaPropertiesConfigurationValidator.java
@@ -1,7 +1,7 @@
 package de.tudresden.inf.mci.brailleplot.configparser;
 
 
-import de.tudresden.inf.mci.brailleplot.GeneralResource;
+import de.tudresden.inf.mci.brailleplot.util.GeneralResource;
 import de.tudresden.inf.mci.brailleplot.printerbackend.PrinterCapability;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/rendering/Image.java b/src/main/java/de/tudresden/inf/mci/brailleplot/rendering/Image.java
index 1bbc3ca7a66d4931b8259bba2ee85a2cfb1f2745..e489060642715ed344c0ef205301f1a74c85a252 100644
--- a/src/main/java/de/tudresden/inf/mci/brailleplot/rendering/Image.java
+++ b/src/main/java/de/tudresden/inf/mci/brailleplot/rendering/Image.java
@@ -3,13 +3,15 @@ package de.tudresden.inf.mci.brailleplot.rendering;
 import javax.imageio.ImageIO;
 import java.awt.image.BufferedImage;
 import java.io.File;
+import java.io.IOException;
+import java.net.URL;
 import java.util.Objects;
 
 /**
  * A representation of an (raster graphic) image. Basically just a wrapper for {@link javax.imageio.ImageIO} and
  * {@link java.awt.image.BufferedImage}.
- * @author Leonard Kupper
- * @version 2019.07.22
+ * @author Leonard Kupper, Georg Graßnick
+ * @version 2019.09.24
  */
 public class Image implements Renderable {
 
@@ -24,6 +26,15 @@ public class Image implements Renderable {
         imageData = ImageIO.read(Objects.requireNonNull(imageFile));
     }
 
+    /**
+     * Constructor. Creates a new renderable representation from an image identified by an URL.
+     * @param url The URL to a resource containing an raster graphic image. (Different types supported. BMP, PNG, JPEG, ...)
+     * @throws java.io.IOException If an I/O exception of some sort has occurred while reading the image file.
+     */
+    public Image(final URL url) throws IOException {
+        imageData = ImageIO.read(url);
+    }
+
     /**
      * Get the loaded image as {@link BufferedImage}.
      * @return An instance of {@link BufferedImage}.
diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/rendering/LiblouisBrailleTextRasterizer.java b/src/main/java/de/tudresden/inf/mci/brailleplot/rendering/LiblouisBrailleTextRasterizer.java
index 0eadd35bd34b23fc5bc408fd0ec4377d4d0380cf..d47dec2bdf145074670ad4b3bdb0394ef4b39947 100644
--- a/src/main/java/de/tudresden/inf/mci/brailleplot/rendering/LiblouisBrailleTextRasterizer.java
+++ b/src/main/java/de/tudresden/inf/mci/brailleplot/rendering/LiblouisBrailleTextRasterizer.java
@@ -1,6 +1,6 @@
 package de.tudresden.inf.mci.brailleplot.rendering;
 
-import de.tudresden.inf.mci.brailleplot.GeneralResource;
+import de.tudresden.inf.mci.brailleplot.util.GeneralResource;
 import de.tudresden.inf.mci.brailleplot.brailleparser.AbstractBrailleTableParser;
 import de.tudresden.inf.mci.brailleplot.configparser.Printer;
 import de.tudresden.inf.mci.brailleplot.layout.InsufficientRenderingAreaException;
diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/GeneralResource.java b/src/main/java/de/tudresden/inf/mci/brailleplot/util/GeneralResource.java
similarity index 78%
rename from src/main/java/de/tudresden/inf/mci/brailleplot/GeneralResource.java
rename to src/main/java/de/tudresden/inf/mci/brailleplot/util/GeneralResource.java
index 3f6c3e6e2f825e85440ce2a46cdf3e9ba2c87298..9ff63c0cdf4bbd20520ab2e02aee0ac5c062fb63 100644
--- a/src/main/java/de/tudresden/inf/mci/brailleplot/GeneralResource.java
+++ b/src/main/java/de/tudresden/inf/mci/brailleplot/util/GeneralResource.java
@@ -1,4 +1,4 @@
-package de.tudresden.inf.mci.brailleplot;
+package de.tudresden.inf.mci.brailleplot.util;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -18,9 +18,9 @@ import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 
 /**
- * This class is used to make files & resources available across the app independent from the application running as packed jar or not.
- * @author Leonard Kupper
- * @version 2019-09-11
+ * This class is used to make files and resources available across the app independent from the application running as packed jar or not.
+ * @author Leonard Kupper, Georg Graßnick
+ * @version 2019-09-24
  */
 public final class GeneralResource {
 
@@ -48,14 +48,14 @@ public final class GeneralResource {
      */
     public GeneralResource(final String resourcePath, final String searchPath) throws IOException {
         File checkFile = new File(resourcePath);
-        mLogger.trace("Checking referenced path: " + checkFile);
+        mLogger.debug("Checking referenced path: " + checkFile);
         if (checkFile.isFile()) {
             mLogger.trace("Interpreting path as file: " + checkFile.getCanonicalPath());
             mResourcePath = checkFile.getCanonicalPath();
             mValidExternalFile = true;
         }
         checkFile = checkFile.getAbsoluteFile();
-        mLogger.trace("Checking referenced path as absolute path: " + checkFile);
+        mLogger.debug("Checking referenced path as absolute path: " + checkFile);
         if (checkFile.isFile()) {
             mLogger.trace("Interpreting path as absolute file: " + checkFile.getCanonicalPath());
             mResourcePath = checkFile.getCanonicalPath();
@@ -63,26 +63,31 @@ public final class GeneralResource {
         }
         if (Objects.nonNull(searchPath)) {
             checkFile = new File(searchPath + File.separator + resourcePath);
-            mLogger.trace("Looking for referenced path in search path: " + checkFile);
+            mLogger.debug("Looking for referenced path in search path: " + checkFile);
             if (checkFile.isFile()) {
                 mLogger.trace("Interpreting path as search path relative file: " + checkFile.getCanonicalPath());
                 mResourcePath = checkFile.getCanonicalPath();
                 mValidExternalFile = true;
             }
         }
-        String resourceClassPath = resourcePath.replace("\\", "/"); // classpaths are always separated by forward slash
-        InputStream checkStream = getClass().getResourceAsStream(resourceClassPath);
-        mLogger.trace("Checking referenced path as resource: " + resourceClassPath);
+        String resourceSearchPath = searchPath;
+        if (resourceSearchPath != null) {
+            resourceSearchPath = stripJarPath(resourceSearchPath);
+        }
+        String resourceClassPath = stripJarPath(resourcePath);
+        resourceClassPath = resourceClassPath.replace(File.separator, "/"); // class paths are always separated by forward slash
+        InputStream checkStream = getClass().getClassLoader().getResourceAsStream(resourceClassPath);
+        mLogger.debug("Checking referenced path as resource: " + resourceClassPath);
         if (Objects.nonNull(checkStream)) {
             mLogger.trace("Interpreting path as resource stream: " + resourceClassPath);
             mResourcePath = resourceClassPath;
             mValidPackedResource = true;
         }
-        if (Objects.nonNull(searchPath)) {
-            String relativeResourcePath = new File(searchPath + File.separator + resourceClassPath).toPath().normalize().toString();
+        if (Objects.nonNull(resourceSearchPath)) {
+            String relativeResourcePath = new File(resourceSearchPath + File.separator + resourceClassPath).toPath().normalize().toString();
             relativeResourcePath = relativeResourcePath.replace("\\", "/");
-            checkStream = getClass().getResourceAsStream(relativeResourcePath);
-            mLogger.trace("Checking referenced path as search path relative resource: " + relativeResourcePath);
+            checkStream = getClass().getClassLoader().getResourceAsStream(relativeResourcePath);
+            mLogger.debug("Checking referenced path as search path relative resource: " + relativeResourcePath);
             if (Objects.nonNull(checkStream)) {
                 mLogger.trace("Interpreting path as resource stream: " + relativeResourcePath);
                 mResourcePath = relativeResourcePath;
@@ -111,7 +116,7 @@ public final class GeneralResource {
             if (isValidExternalFile()) {
                 return new FileInputStream(getResourcePath());
             }
-            return getClass().getResourceAsStream(mResourcePath);
+            return getClass().getClassLoader().getResourceAsStream(mResourcePath);
         } catch (Exception e) {
             throw new RuntimeException("Error while opening resource as stream: ", e);
         }
@@ -197,4 +202,20 @@ public final class GeneralResource {
     private static Class getClassRef() {
         return GeneralResource.class;
     }
+
+    /**
+     * Removes the the jar file path from the given path.
+     * Example: file:/home/user/BraillePlot.jar!/config/example.properties -> config/example.properties.
+     * Note that this method identifies the distinction between jar path and inner path by the '!' (exclamation mark) character. Please
+     * make sure your packaged resource does not contain this character in it's name or path. If you don't, things will break.
+     * @param path The string representation of the path to use.
+     * @return The input path where any leading path outside of the jar file is truncated.
+     */
+    private static String stripJarPath(final String path) {
+        String ret = path.substring(path.lastIndexOf('!') + 1);
+        if (ret.startsWith("/")) {
+            ret = ret.substring(1);
+        }
+        return ret;
+    }
 }
diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/util/package-info.java b/src/main/java/de/tudresden/inf/mci/brailleplot/util/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..0a568e49d338b9e5031c5514da161a5ef5e28b31
--- /dev/null
+++ b/src/main/java/de/tudresden/inf/mci/brailleplot/util/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * This package contains utility classes which can be invoked from all other packages.
+ */
+package de.tudresden.inf.mci.brailleplot.util;
diff --git a/src/test/java/de/tudresden/inf/mci/brailleplot/configparser/JavaPropertiesConfigurationParserTest.java b/src/test/java/de/tudresden/inf/mci/brailleplot/configparser/JavaPropertiesConfigurationParserTest.java
index fe01525acc5b33c9cadd6f917f3c7c82cb5fa8b9..ce71eb080ebfbf12987943715e93386c8c4a6c30 100644
--- a/src/test/java/de/tudresden/inf/mci/brailleplot/configparser/JavaPropertiesConfigurationParserTest.java
+++ b/src/test/java/de/tudresden/inf/mci/brailleplot/configparser/JavaPropertiesConfigurationParserTest.java
@@ -4,7 +4,7 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
-import java.io.File;
+import java.net.URL;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.NoSuchElementException;
@@ -13,15 +13,13 @@ import java.util.Set;
 
 public class JavaPropertiesConfigurationParserTest {
 
-    public static final String mDefaultConfigPath = getResource("config/default.properties").getAbsolutePath();
-    public static final String mConcreteConfigPath = getResource("config/concrete.properties").getAbsolutePath();
+    public static final URL mDefaultConfigPath = getResource("config/default.properties");
+    public static final URL mConcreteConfigPath = getResource("config/concrete.properties");
     public static Printer mPrinterConfig;
     public static Format mFormatConfig;
 
-    public static File getResource(String fileName) {
-        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
-        File resourceFile = new File(classLoader.getResource(fileName).getFile());
-        return resourceFile;
+    public static URL getResource(final String location) {
+        return ClassLoader.getSystemClassLoader().getResource(location);
     }
 
     // Correct use testcases
@@ -79,13 +77,13 @@ public class JavaPropertiesConfigurationParserTest {
     @Test
     public void testIllegalFile() {
         Assertions.assertThrows(
-                ConfigurationParsingException.class,
-                () -> new JavaPropertiesConfigurationParser("config/nonexistent.properties", mDefaultConfigPath)
+                NullPointerException.class,
+                () -> new JavaPropertiesConfigurationParser(getResource("config/nonexistent.properties"), mDefaultConfigPath)
         );
     }
     @Test
     public void testMissingRequired() {
-        String configPath = getResource("config/missingRequiredPropertyExample.properties").getAbsolutePath();
+        URL configPath = getResource("config/missingRequiredPropertyExample.properties");
         Assertions.assertThrows(
                 IllegalStateException.class,
                 () -> new JavaPropertiesConfigurationParser(configPath, mDefaultConfigPath)
@@ -93,7 +91,7 @@ public class JavaPropertiesConfigurationParserTest {
     }
     @Test
     public void testIllegalProperty() {
-        String configPath = getResource("config/illegalPropertyNameExample.properties").getAbsolutePath();
+        URL configPath = getResource("config/illegalPropertyNameExample.properties");
         Assertions.assertThrows(
                 ConfigurationValidationException.class,
                 () -> new JavaPropertiesConfigurationParser(configPath, mDefaultConfigPath)
@@ -101,7 +99,7 @@ public class JavaPropertiesConfigurationParserTest {
     }
     @Test
     public void testIllegalValue() {
-        String configPath = getResource("config/illegalPropertyValueExample.properties").getAbsolutePath();
+        URL configPath = getResource("config/illegalPropertyValueExample.properties");
         Assertions.assertThrows(
                 ConfigurationValidationException.class,
                 () -> new JavaPropertiesConfigurationParser(configPath, mDefaultConfigPath)
diff --git a/src/test/java/de/tudresden/inf/mci/brailleplot/layout/RasterCanvasTest.java b/src/test/java/de/tudresden/inf/mci/brailleplot/layout/RasterCanvasTest.java
index f0cbc05ce550ce78ee1261c77801fb15da0c952c..5401330467bd48923bdea75abf543f27688340c3 100644
--- a/src/test/java/de/tudresden/inf/mci/brailleplot/layout/RasterCanvasTest.java
+++ b/src/test/java/de/tudresden/inf/mci/brailleplot/layout/RasterCanvasTest.java
@@ -2,9 +2,6 @@ package de.tudresden.inf.mci.brailleplot.layout;
 
 import de.tudresden.inf.mci.brailleplot.configparser.ConfigurationParser;
 import de.tudresden.inf.mci.brailleplot.configparser.JavaPropertiesConfigurationParser;
-import de.tudresden.inf.mci.brailleplot.layout.RasterCanvas;
-import de.tudresden.inf.mci.brailleplot.layout.Rectangle;
-import de.tudresden.inf.mci.brailleplot.layout.SixDotBrailleRasterCanvas;
 import de.tudresden.inf.mci.brailleplot.printabledata.MatrixData;
 import de.tudresden.inf.mci.brailleplot.rendering.Image;
 import de.tudresden.inf.mci.brailleplot.rendering.MasterRenderer;
@@ -12,21 +9,20 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
 import java.io.File;
+import java.net.URL;
 import java.util.ListIterator;
 
 
 public class RasterCanvasTest {
 
-    public static final String mDefaultConfig = getResource("config/rasterizer_test_default.properties").getAbsolutePath();
-    public static final String mBaseConfig = getResource("config/base_format.properties").getAbsolutePath();
-    public static final String mMarginsOnlyConfig = getResource("config/margins_only.properties").getAbsolutePath();
-    public static final String mConstraintOnlyConfig = getResource("config/constraint_only.properties").getAbsolutePath();
-    public static final String mBothConfig = getResource("config/margins_and_constraint.properties").getAbsolutePath();
+    public static final URL mDefaultConfig = getResource("config/rasterizer_test_default.properties");
+    public static final URL mBaseConfig = getResource("config/base_format.properties");
+    public static final URL mMarginsOnlyConfig = getResource("config/margins_only.properties");
+    public static final URL mConstraintOnlyConfig = getResource("config/constraint_only.properties");
+    public static final URL mBothConfig = getResource("config/margins_and_constraint.properties");
 
-    public static File getResource(String fileName) {
-        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
-        File resourceFile = new File(classLoader.getResource(fileName).getFile());
-        return resourceFile;
+    public static URL getResource(final String location) {
+        return ClassLoader.getSystemClassLoader().getResource(location);
     }
 
     @Test
diff --git a/src/test/java/de/tudresden/inf/mci/brailleplot/rendering/FunctionalRasterizerTest.java b/src/test/java/de/tudresden/inf/mci/brailleplot/rendering/FunctionalRasterizerTest.java
index 630419f330bc118d71d6add1be0aca3d023d82e3..0a410a48602d8a1272023ed4f01898a9c490a4ff 100644
--- a/src/test/java/de/tudresden/inf/mci/brailleplot/rendering/FunctionalRasterizerTest.java
+++ b/src/test/java/de/tudresden/inf/mci/brailleplot/rendering/FunctionalRasterizerTest.java
@@ -11,19 +11,18 @@ import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
 import java.io.File;
+import java.net.URL;
 
 
 public class FunctionalRasterizerTest {
 
-    public static final String mDefaultConfig = getResource("config/rasterizer_test_default.properties").getAbsolutePath();
-    public static final String mBaseConfig = getResource("config/base_format.properties").getAbsolutePath();
+    public static final URL mDefaultConfig = getResource("config/rasterizer_test_default.properties");
+    public static final URL mBaseConfig = getResource("config/base_format.properties");
     public static Printer mPrinter;
     public static Format mFormat;
 
-    public static File getResource(String fileName) {
-        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
-        File resourceFile = new File(classLoader.getResource(fileName).getFile());
-        return resourceFile;
+    public static URL getResource(final String location) {
+        return ClassLoader.getSystemClassLoader().getResource(location);
     }
 
     @BeforeAll
diff --git a/src/test/java/de/tudresden/inf/mci/brailleplot/rendering/MasterRendererTest.java b/src/test/java/de/tudresden/inf/mci/brailleplot/rendering/MasterRendererTest.java
index 27a0db664751722ae32a3d1bdee76a04a745e46c..cbd630e1ac20fde76502301d57f9207a8a440a6f 100644
--- a/src/test/java/de/tudresden/inf/mci/brailleplot/rendering/MasterRendererTest.java
+++ b/src/test/java/de/tudresden/inf/mci/brailleplot/rendering/MasterRendererTest.java
@@ -10,20 +10,18 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
-import java.io.File;
+import java.net.URL;
 
 
 public class MasterRendererTest {
 
-    public static final String mDefaultConfig = getResource("config/rasterizer_test_default.properties").getAbsolutePath();
-    public static final String mBaseConfig = getResource("config/base_format.properties").getAbsolutePath();
+    public static final URL mDefaultConfig = getResource("config/rasterizer_test_default.properties");
+    public static final URL mBaseConfig = getResource("config/base_format.properties");
     public static Printer mPrinter;
     public static Format mFormat;
 
-    public static File getResource(String fileName) {
-        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
-        File resourceFile = new File(classLoader.getResource(fileName).getFile());
-        return resourceFile;
+    public static URL getResource(final String location) {
+        return ClassLoader.getSystemClassLoader().getResource(location);
     }
 
     @BeforeAll