def mutate_genome(self, genome) -> StorageGenome:

        analysis_genome = AnalysisGenome(self.gene_repository, genome)

        if len(analysis_genome.edges) == 0:
            return self.mutate_add_edge(analysis_genome, genome)

        edge_or_vertex = ProbabilisticTools.weighted_choice(
            [
                (0, self.mutation_parameters["add_edge_probability"]),
                (1, 1 - self.mutation_parameters["add_edge_probability"])
            ]
        )

        if edge_or_vertex == 0:
            new_genome = self.mutate_add_edge(analysis_genome, genome)
        else:
            new_genome = self.mutate_add_node(analysis_genome, genome)

        return self.mutate_perturb_weights(new_genome)
    def mutate_add_edge(
            self,
            analysis_genome: AnalysisGenome,
            storage_genome: StorageGenome
    ) -> StorageGenome:

        random.seed()

        starting_vertex = random.choice(list(analysis_genome.nodes))

        if starting_vertex not in analysis_genome.edges.keys():
            # if the chosen vertex has no outgoing edges (i.e. is a sink), every
            # other vertex may be a possible endpoint
            possible_endpoints = list(analysis_genome.nodes)
        else:
            possible_endpoints = []
            for node in analysis_genome.nodes:
                for target_node, _ in analysis_genome.edges[starting_vertex]:
                    if node != target_node:
                        # if there is no edge from the selected node to the cur-
                        # rent node, it is a possible endpoint
                        possible_endpoints.append(node)

        endpoint = random.choice(possible_endpoints)

        gene_id = self.gene_repository.get_gene_id_for_endpoints(
            starting_vertex,
            endpoint
        )
        gene_weight = random.random()
        gene_enabled = ProbabilisticTools.weighted_choice(
            [
                (True, self.mutation_parameters["new_gene_enabled_probability"]),
                (False, 1 - self.mutation_parameters["new_gene_enabled_probability"])
            ]
        )

        new_genome = StorageGenome(storage_genome)
        new_genome.genes[gene_id] = (gene_enabled, gene_weight)

        return new_genome