Goes through all the configuration fields and predefines empty ones with default values

        Top level:
            `dir` field is predefined with current working directory value, in case of empty string or `None`
            `io_silent_fail` field if predefined with :attr:`Configuration.DEFAULT_IOSF` in case of None or empty string

        Logger section:
            `name` field is predefined with :attr:`Configuration.DEFAULT_LOGGER_NAME`. Field is set to str() of itself
            `level` field is predefined with :attr:`Configuration.DEFAULT_LOGGER_LEVEL`. Field is set to str() of itself
            `format` field is predefined with :attr:`Configuration.DEFAULT_LOGGER_LEVEL`. Field is set to str() of itself
            `destination` field if predefined with

        Input section:
            `dir` field is predefined with a relative path constructed with top level `dir` field and :attr:`Configuration.DEFAULT_INPUT_DIR`
            `source` field is predefined with an empty list
            `io_silent_fail` if predefined with a top level `io_silent_fail`
            `logger` subsection if predefined by a top level `logger` section it substitutes all the missing values in `input` `logger` subsection

        Algorithm section:
            `io_silent_fail` is predefined with a top level `io_silent_fail` value
            `logger` is predefined with top level `logger` configuration
            `tasks` section:
                `paths` is predefined by [:attr:`Configuration.DEFAULT_ALGORITHM_TASKS_PATH`]. If value is supplied,
                        :attr:`Configuration.DEFAULT_ALGORITHM_TASKS_PATH` is prepended  to the supplied list
            `stages` section: (is predefined with [])
                if any values are predefined, such fields as `io_silent_fail`, `logger` are propagated to stages entries
                `self_loop` value is predefined by :attr:`Configuration.DEFAULT_ALGORITHM_STAGES_SELF_LOOP`
            `rounds` section: (is predefined with [])
                if any values are predefined, such fields as `io_silent_fail`, `logger` are propagated to stages entries
                `self_loop` value is predefined by :attr:`Configuration.DEFAULT_ALGORITHM_ROUNDS_SELF_LOOP`
            `pipeline` section:
                `self_loop` if predefined by :attr:`Configuration.DEFAULT_ALGORITHM_PIPELINE_SELF_LOOP`
                `logger` if predefined with an algorithm->logger configuration. All non specified value are propagated respectively
                `rounds` is predefined with []

        Output section:
            `dir` field is predefined with :attr:`Configuration.DEFAULT_OUTPUT_DIR`
            `io_silent_fail` field is predefined with top level `io_silent_fail`
            `logger` subsection is predefined with a top level logger section, which substitutes all of missing values from top level `logger` section
            `stats` section
                `io_silent_fail` field is predefined with `output->io_silent_fail` value
                `dir` is predefined with :attr:`Configuration.DEFAULT_OUTPUT_STATS_DIR`
                `file` is predefined with :attr:`Configuration.DEFAULT_OUTPUT_STATS_FILE`
                `logger` is defaulted (all, or just missing parts) bu `output->logger` section

            `assembly_points` section
                `io_silent_fail` field is predefined with `output->io_silent_fail` value
                `dir` is predefined with :attr:`Configuration.DEFAULT_OUTPUT_AP_DIR`
                `file` is predefined with :attr:`Configuration.DEFAULT_OUTPUT_AP_FILE`
                `logger` is defaulted (all, or just missing parts) bu `output->logger` section
                `genome_specific` is predefined with :attr:`Configuration.DEFAULT_OUTPUT_AP_GENOME_SPECIFIC`
                `genome_specific_file_name_pattern` is predefined with :attr:`Configuration.DEFAULT_OUTPUT_AP_GSFNP`

            `genomes` section
                `io_silent_fail` field is predefined with `output->io_silent_fail` value
                `dir` is predefined with :attr:`Configuration.DEFAULT_OUTPUT_GENOMES_DIR`
                `logger` is defaulted (all, or just missing parts) bu `output->logger` section
                `output_non_glued_fragments` is predefined with :attr:`Configuration.DEFAULT_OUTPUT_GENOMES_ONGF`

        :return: Nothing, performs inplace changes
        :rtype: `None`

def update_with_default_values(self):
        """ Goes through all the configuration fields and predefines empty ones with default values

        Top level:
            `dir` field is predefined with current working directory value, in case of empty string or `None`
            `io_silent_fail` field if predefined with :attr:`Configuration.DEFAULT_IOSF` in case of None or empty string

        Logger section:
            `name` field is predefined with :attr:`Configuration.DEFAULT_LOGGER_NAME`. Field is set to str() of itself
            `level` field is predefined with :attr:`Configuration.DEFAULT_LOGGER_LEVEL`. Field is set to str() of itself
            `format` field is predefined with :attr:`Configuration.DEFAULT_LOGGER_LEVEL`. Field is set to str() of itself
            `destination` field if predefined with

        Input section:
            `dir` field is predefined with a relative path constructed with top level `dir` field and :attr:`Configuration.DEFAULT_INPUT_DIR`
            `source` field is predefined with an empty list
            `io_silent_fail` if predefined with a top level `io_silent_fail`
            `logger` subsection if predefined by a top level `logger` section it substitutes all the missing values in `input` `logger` subsection

        Algorithm section:
            `io_silent_fail` is predefined with a top level `io_silent_fail` value
            `logger` is predefined with top level `logger` configuration
            `tasks` section:
                `paths` is predefined by [:attr:`Configuration.DEFAULT_ALGORITHM_TASKS_PATH`]. If value is supplied,
                        :attr:`Configuration.DEFAULT_ALGORITHM_TASKS_PATH` is prepended  to the supplied list
            `stages` section: (is predefined with [])
                if any values are predefined, such fields as `io_silent_fail`, `logger` are propagated to stages entries
                `self_loop` value is predefined by :attr:`Configuration.DEFAULT_ALGORITHM_STAGES_SELF_LOOP`
            `rounds` section: (is predefined with [])
                if any values are predefined, such fields as `io_silent_fail`, `logger` are propagated to stages entries
                `self_loop` value is predefined by :attr:`Configuration.DEFAULT_ALGORITHM_ROUNDS_SELF_LOOP`
            `pipeline` section:
                `self_loop` if predefined by :attr:`Configuration.DEFAULT_ALGORITHM_PIPELINE_SELF_LOOP`
                `logger` if predefined with an algorithm->logger configuration. All non specified value are propagated respectively
                `rounds` is predefined with []

        Output section:
            `dir` field is predefined with :attr:`Configuration.DEFAULT_OUTPUT_DIR`
            `io_silent_fail` field is predefined with top level `io_silent_fail`
            `logger` subsection is predefined with a top level logger section, which substitutes all of missing values from top level `logger` section
            `stats` section
                `io_silent_fail` field is predefined with `output->io_silent_fail` value
                `dir` is predefined with :attr:`Configuration.DEFAULT_OUTPUT_STATS_DIR`
                `file` is predefined with :attr:`Configuration.DEFAULT_OUTPUT_STATS_FILE`
                `logger` is defaulted (all, or just missing parts) bu `output->logger` section

            `assembly_points` section
                `io_silent_fail` field is predefined with `output->io_silent_fail` value
                `dir` is predefined with :attr:`Configuration.DEFAULT_OUTPUT_AP_DIR`
                `file` is predefined with :attr:`Configuration.DEFAULT_OUTPUT_AP_FILE`
                `logger` is defaulted (all, or just missing parts) bu `output->logger` section
                `genome_specific` is predefined with :attr:`Configuration.DEFAULT_OUTPUT_AP_GENOME_SPECIFIC`
                `genome_specific_file_name_pattern` is predefined with :attr:`Configuration.DEFAULT_OUTPUT_AP_GSFNP`

            `genomes` section
                `io_silent_fail` field is predefined with `output->io_silent_fail` value
                `dir` is predefined with :attr:`Configuration.DEFAULT_OUTPUT_GENOMES_DIR`
                `logger` is defaulted (all, or just missing parts) bu `output->logger` section
                `output_non_glued_fragments` is predefined with :attr:`Configuration.DEFAULT_OUTPUT_GENOMES_ONGF`

        :return: Nothing, performs inplace changes
        :rtype: `None`
        """
        if self[self.DIR] in ("", None):
            self[self.DIR] = os.getcwd()
        if self[self.IOSF] in ("", None):
            self[self.IOSF] = self.DEFAULT_IOSF

        # logger section
        if self[self.LOGGER][self.NAME] in ("", None):
            self[self.LOGGER][self.NAME] = self.DEFAULT_LOGGER_NAME
        self[self.LOGGER][self.NAME] = str(self[self.LOGGER][self.NAME])
        if self[self.LOGGER][self.LEVEL] in ("", None):
            self[self.LOGGER][self.LEVEL] = self.DEFAULT_LOGGER_LEVEL
        self[self.LOGGER][self.LEVEL] = str(self[self.LOGGER][self.LEVEL])
        if self[self.LOGGER][self.FORMAT] in ("", None):
            self[self.LOGGER][self.FORMAT] = self.DEFAULT_LOGGER_FORMAT
        self[self.LOGGER][self.FORMAT] = str(self[self.LOGGER][self.FORMAT])
        if self[self.LOGGER][self.DESTINATION] in ([], "", None):
            self[self.LOGGER][self.DESTINATION] = self.DEFAULT_LOGGER_DESTINATION

        # input section
        if self[self.INPUT][self.SOURCE] in ("", None):
            self[self.INPUT][self.SOURCE] = []
        if self[self.INPUT][self.DIR] in ("", None):
            self[self.INPUT][self.DIR] = self.DEFAULT_INPUT_DIR
        if self[self.INPUT][self.IOSF] in ("", None):
            self[self.INPUT][self.IOSF] = self[self.IOSF]
        self._update_logger_config(logger_to_update=self[self.INPUT][self.LOGGER],
                                   source_logger=self[self.LOGGER])

        # algorithm section
        if self.LOGGER not in self[self.ALGORITHM] or self[self.ALGORITHM][self.LOGGER] in ("", None):
            self[self.ALGORITHM][self.LOGGER] = {}
        self._update_logger_config(logger_to_update=self[self.ALGORITHM][self.LOGGER],
                                   source_logger=self[self.LOGGER])
        if self.IOSF not in self[self.ALGORITHM] or self[self.ALGORITHM][self.IOSF] in ("", None):
            self[self.ALGORITHM][self.IOSF] = self[self.IOSF]
        if self.TASKS not in self[self.ALGORITHM]:
            self[self.ALGORITHM][self.TASKS] = {}
        if self.EXECUTABLE_CONTAINERS not in self[self.ALGORITHM]:
            self[self.ALGORITHM][self.EXECUTABLE_CONTAINERS] = []

        if self.PATHS not in self[self.ALGORITHM][self.TASKS] or self[self.ALGORITHM][self.TASKS][self.PATHS] in ("", None):
            self[self.ALGORITHM][self.TASKS][self.PATHS] = []
        self[self.ALGORITHM][self.TASKS][self.PATHS] = [self.DEFAULT_ALGORITHM_TASKS_PATH] + self[self.ALGORITHM][self.TASKS][self.PATHS]

        for ecs in self[self.ALGORITHM][self.EXECUTABLE_CONTAINERS]:
            if self.REFERENCE not in ecs:
                ecs[self.REFERENCE] = ecs[self.NAME] + "s"
            if ecs[self.REFERENCE] not in self[self.ALGORITHM]:
                self[self.ALGORITHM][ecs[self.REFERENCE]] = []
            for executable_container in self[self.ALGORITHM][ecs[self.REFERENCE]]:
                if self.SELF_LOOP not in executable_container:
                    executable_container[self.SELF_LOOP] = self.DEFAULT_ALGORITHM_EC_SELF_LOOP
                if self.ENTRIES not in executable_container:
                    executable_container[self.ENTRIES] = []

        if self.PIPELINE not in self[self.ALGORITHM]:
            self[self.ALGORITHM][self.PIPELINE] = {}
        if self.LOGGER not in self[self.ALGORITHM][self.PIPELINE] or self[self.ALGORITHM][self.PIPELINE][self.LOGGER] in ("", None):
            self[self.ALGORITHM][self.PIPELINE][self.LOGGER] = {}
        self._update_logger_config(logger_to_update=self[self.ALGORITHM][self.PIPELINE][self.LOGGER],
                                   source_logger=self[self.ALGORITHM][self.LOGGER])
        if self.IOSF not in self[self.ALGORITHM][self.PIPELINE] or self[self.ALGORITHM][self.PIPELINE][self.IOSF] in ("", None):
            self[self.ALGORITHM][self.PIPELINE][self.IOSF] = self[self.ALGORITHM][self.IOSF]
        if self.ENTRIES not in self[self.ALGORITHM][self.PIPELINE] or self[self.ALGORITHM][self.PIPELINE][self.ENTRIES] in ("", None):
            self[self.ALGORITHM][self.PIPELINE][self.ENTRIES] = []
        if self.SELF_LOOP not in self[self.ALGORITHM][self.PIPELINE] or self[self.ALGORITHM][self.PIPELINE][self.SELF_LOOP] in ("", None):
            self[self.ALGORITHM][self.PIPELINE][self.SELF_LOOP] = self.DEFAULT_ALGORITHM_PIPELINE_SELF_LOOP

        # output section
        if self[self.OUTPUT][self.DIR] in ("", None):
            self[self.OUTPUT][self.DIR] = os.path.join(self[self.DIR], self.DEFAULT_OUTPUT_DIR)
        if self[self.OUTPUT][self.IOSF] in ("", None):
            self[self.OUTPUT][self.IOSF] = self[self.IOSF]
        self._update_logger_config(logger_to_update=self[self.OUTPUT][self.LOGGER],
                                   source_logger=self[self.LOGGER])

        # output -> stats section
        if self.DIR not in self[self.OUTPUT][self.STATS] or self[self.OUTPUT][self.STATS][self.DIR] in ("", None):
            self[self.OUTPUT][self.STATS][self.DIR] = self.DEFAULT_OUTPUT_STATS_DIR
        if self.IOSF not in self[self.OUTPUT][self.STATS] or self[self.OUTPUT][self.STATS][self.IOSF] in ("", None):
            self[self.OUTPUT][self.STATS][self.IOSF] = self[self.OUTPUT][self.IOSF]
        if self.FILE not in self[self.OUTPUT][self.STATS] or self[self.OUTPUT][self.STATS][self.FILE] in ("", None):
            self[self.OUTPUT][self.STATS][self.FILE] = self.DEFAULT_OUTPUT_STATS_FILE
        if self.LOGGER not in self[self.OUTPUT][self.STATS]:
            self[self.OUTPUT][self.STATS][self.LOGGER] = {}
        self._update_logger_config(logger_to_update=self[self.OUTPUT][self.STATS][self.LOGGER],
                                   source_logger=self[self.OUTPUT][self.LOGGER])

        # output -> assembly_points section
        if self.DIR not in self[self.OUTPUT][self.ASSEMBLY_POINTS] or self[self.OUTPUT][self.ASSEMBLY_POINTS][self.DIR] in ("", None):
            self[self.OUTPUT][self.ASSEMBLY_POINTS][self.DIR] = self.DEFAULT_OUTPUT_AP_DIR
        if self.IOSF not in self[self.OUTPUT][self.ASSEMBLY_POINTS] or self[self.OUTPUT][self.ASSEMBLY_POINTS][self.IOSF] in ("", None):
            self[self.OUTPUT][self.ASSEMBLY_POINTS][self.IOSF] = self[self.OUTPUT][self.IOSF]
        if self.FILE not in self[self.OUTPUT][self.ASSEMBLY_POINTS] or self[self.OUTPUT][self.ASSEMBLY_POINTS][self.FILE] in ("", None):
            self[self.OUTPUT][self.ASSEMBLY_POINTS][self.FILE] = self.DEFAULT_OUTPUT_AP_FILE
        if self.GENOME_SPECIFIC not in self[self.OUTPUT][self.ASSEMBLY_POINTS] or self[self.OUTPUT][self.ASSEMBLY_POINTS][
            self.GENOME_SPECIFIC]:
            self[self.OUTPUT][self.ASSEMBLY_POINTS][self.GENOME_SPECIFIC] = self.DEFAULT_OUTPUT_AP_GENOME_SPECIFIC
        if self.GENOME_SPECIFIC_FNP not in self[self.OUTPUT][self.ASSEMBLY_POINTS] or self[self.OUTPUT][self.ASSEMBLY_POINTS][
            self.GENOME_SPECIFIC_FNP]:
            self[self.OUTPUT][self.ASSEMBLY_POINTS][self.GENOME_SPECIFIC_FNP] = self.DEFAULT_OUTPUT_AP_GSFNP
        if self.LOGGER not in self[self.OUTPUT][self.ASSEMBLY_POINTS]:
            self[self.OUTPUT][self.ASSEMBLY_POINTS][self.LOGGER] = {}
        self._update_logger_config(logger_to_update=self[self.OUTPUT][self.ASSEMBLY_POINTS][self.LOGGER],
                                   source_logger=self[self.OUTPUT][self.LOGGER])

        # output -> genomes section
        if self.DIR not in self[self.OUTPUT][self.GENOMES] or self[self.OUTPUT][self.GENOMES][self.DIR] in ("", None):
            self[self.OUTPUT][self.GENOMES][self.DIR] = self.DEFAULT_OUTPUT_GENOMES_DIR
        if self.IOSF not in self[self.OUTPUT][self.GENOMES] or self[self.OUTPUT][self.GENOMES][self.IOSF] in ("", None):
            self[self.OUTPUT][self.GENOMES][self.IOSF] = self[self.OUTPUT][self.IOSF]
        if self.OUTPUT_NG_FRAGMENTS not in self[self.OUTPUT][self.GENOMES] or self[self.OUTPUT][self.GENOMES][self.OUTPUT_NG_FRAGMENTS] in (
        "", None):
            self[self.OUTPUT][self.GENOMES][self.OUTPUT_NG_FRAGMENTS] = self.DEFAULT_OUTPUT_GENOMES_ONGF
        if self.LOGGER not in self[self.OUTPUT][self.GENOMES]:
            self[self.OUTPUT][self.GENOMES][self.LOGGER] = {}
        self._update_logger_config(logger_to_update=self[self.OUTPUT][self.GENOMES][self.LOGGER],
                                   source_logger=self[self.OUTPUT][self.LOGGER])