public void addEdge(T start, T end)
    {
        // copy the out and in list
        HashMap<T, List<T> > newOut, newIn;
        
        newOut = new HashMap<>();
        newIn = new HashMap<>();
        
        for (Entry<T, List<T> > e : out.entrySet())
        {
            newOut.put(e.getKey(), new ArrayList<>(e.getValue()));
        }
        
        for (Entry<T, List<T> > e : in.entrySet())
        {
            newIn.put(e.getKey(), new ArrayList<>(e.getValue()));
        }
        
        // add the start and end node to the new structures
        insertEnd(end, start, newIn);
        insertStart(start, end, newOut);
        
        List<T> noIn = noIncoming(newIn, newOut);
        // so loop over nodes that do not have
        // any incoming edges (this means that
        // the 
        while(!noIn.isEmpty())
        {
            // this node is not a key in newIn
            // curOut ----> {n,m,l}
            T curOut = noIn.remove(noIn.size() - 1);
            if (newOut.get(curOut) != null)
            {
                Iterator<T> it = newOut.get(curOut).iterator();
                // loop over all of the nodes that curOut connect to
                while(it.hasNext())
                {
                    // curOut ---> curIn
                    // must remove the connection
                    // so first remove from curOut list of in nodes
                    T curIn = it.next();
                    it.remove();
                    // then remove curIn's in connection
                    // from curOut
                    newIn.get(curIn).remove(curOut);
                    // if curIn has no incoming edges
                    // then it is empty 

                    if (newIn.get(curIn).isEmpty())
                    {
                        // I will remove
                        // curIn from newIn since no longer
                        // any connections into it
                        newIn.remove(curIn);

                        // and then add curIn to the noIn list
                        // since it has no incoming edges
                        noIn.add(curIn);
                    }

                }
            }
            
        }
        
        if (newIn.isEmpty())
        {
            // we have a dag with the new nodes still so add them
            insertEnd(end, start, in);
            insertStart(start, end, out);
        }
        
        // do nothing.
        
    }