/// <summary>
        /// Register a state for the given <paramref name="sateTag"/>. The new state doesn't contain any
        /// edges.
        /// </summary>
        /// <param name="fromStateTag">The tag of the state from which the edge originates.</param>
        /// <param name="edgeTag">The tag of the edge that is registered.</param>
        /// <param name="toStateTag">The tag of the state to which the edge maps.</param>
        /// <returns>A <see cref="T:IEdge`2"/> instance that is either an already registered
        /// state with the given <paramref name="stateTag"/> or a new state created.</returns>
        /// <remarks>
        /// <para>If there is no state associated with the <paramref name="fromStateTag"/> or <paramref name="toStateTag"/>,
        /// states are registered (using the <see cref="M:RegisterState"/> method) for these tags.</para>
        /// <para>If there already exists an edge between the two given states with the given tag, no additional
        /// edge is registered.</para>
        /// <para>This operation is not completely specific to the given automaton: if the state is shared with another
        /// automaton, the edge will be added to all the automata.</para>
        /// </remarks>
        public IEdge <TStateTag, TEdgeTag> RegisterEdge(TStateTag fromStateTag, TEdgeTag edgeTag, TStateTag toStateTag)
        {
            IState <TStateTag, TEdgeTag> frm = this.RegisterState(fromStateTag);
            IState <TStateTag, TEdgeTag> tos = this.RegisterState(toStateTag);

            foreach (IEdge <TStateTag, TEdgeTag> edge in frm.TaggedEdges(edgeTag))
            {
                if (edge.Contains(tos))
                {
                    return(edge);
                }
            }
            Edge <TStateTag, TEdgeTag> cedge = new Edge <TStateTag, TEdgeTag> (edgeTag, tos);

            frm.AddEdge(cedge);
            return(cedge);
        }