A wrapper around Molecule.insert(), which also incorporates the new
        site into the MoleculeGraph.

        :param i: Index at which to insert the new site
        :param species: Species for the new site
        :param coords: 3x1 array representing coordinates of the new site
        :param validate_proximity: For Molecule.insert(); if True (default
            False), distance will be checked to ensure that site can be safely
            added.
        :param site_properties: Site properties for Molecule
        :param edges: List of dicts representing edges to be added to the
            MoleculeGraph. These edges must include the index of the new site i,
            and all indices used for these edges should reflect the
            MoleculeGraph AFTER the insertion, NOT before. Each dict should at
            least have a "to_index" and "from_index" key, and can also have a
            "weight" and a "properties" key.
        :return:

def insert_node(self, i, species, coords, validate_proximity=False,
                    site_properties=None, edges=None):
        """
        A wrapper around Molecule.insert(), which also incorporates the new
        site into the MoleculeGraph.

        :param i: Index at which to insert the new site
        :param species: Species for the new site
        :param coords: 3x1 array representing coordinates of the new site
        :param validate_proximity: For Molecule.insert(); if True (default
            False), distance will be checked to ensure that site can be safely
            added.
        :param site_properties: Site properties for Molecule
        :param edges: List of dicts representing edges to be added to the
            MoleculeGraph. These edges must include the index of the new site i,
            and all indices used for these edges should reflect the
            MoleculeGraph AFTER the insertion, NOT before. Each dict should at
            least have a "to_index" and "from_index" key, and can also have a
            "weight" and a "properties" key.
        :return:
        """

        self.molecule.insert(i, species, coords,
                             validate_proximity=validate_proximity,
                             properties=site_properties)

        mapping = {}
        for j in range(len(self.molecule) - 1):
            if j < i:
                mapping[j] = j
            else:
                mapping[j] = j + 1
        nx.relabel_nodes(self.graph, mapping, copy=False)

        self.graph.add_node(i)
        self.set_node_attributes()

        if edges is not None:
            for edge in edges:
                try:
                    self.add_edge(edge["from_index"], edge["to_index"],
                                  weight=edge.get("weight", None),
                                  edge_properties=edge.get("properties", None))
                except KeyError:
                    raise RuntimeError("Some edges are invalid.")