'Add edge to graph
key: optional key
attr_dict: optional attribute dict
attrs: more attributes
warning: udpates attr_dict with attrs'

def add_edge(self, src, dst, key=None, attr_dict=None, **attrs):

    attr_dict = ({} if (attr_dict is None) else attr_dict)
    attr_dict.update(attrs)
    self.node.setdefault(src, {})
    self.node.setdefault(dst, {})
    self.edge.setdefault(src, {})
    self.edge.setdefault(dst, {})
    self.edge[src].setdefault(dst, {})
    entry = self.edge[dst][src] = self.edge[src][dst]
    if (key is None):
        keys = [k for k in entry.keys() if isinstance(k, int)]
        key = (max(([0] + keys)) + 1)
    entry[key] = attr_dict
    return key
