with Set_Simple_Sequential_Unbounded_Unmanaged_Iterator;
generic
    type Item is private;
    type Attribute is private;
package Graph_Undirected_Unbounded_Unmanaged is

    type Graph is limited private;
    type Vertex is private;
    type Arc is private;

    Null_Vertex : constant Vertex;
    Null_Arc : constant Arc;

    procedure Copy (From_The_Graph : in Graph; To_The_Graph : in out Graph);
    procedure Clear (The_Graph : in out Graph);
    procedure Add (The_Vertex : in out Vertex;
                   With_The_Item : in Item;
                   To_The_Graph : in out Graph);
    procedure Remove (The_Vertex : in out Vertex;
                      From_The_Graph : in out Graph);
    procedure Set_Item (Of_The_Vertex : in out Vertex; To_The_Item : in Item);
    procedure Create (The_Arc : in out Arc;
                      With_The_Attribute : in Attribute;
                      With_The_Vertex : in out Vertex;
                      And_The_Vertex : in Vertex;
                      In_The_Graph : in out Graph);
    procedure Destroy (The_Arc : in out Arc; In_The_Graph : in out Graph);
    procedure Set_Attribute (Of_The_Arc : in out Arc;
                             To_The_Attribute : in Attribute);

    function Is_Empty (The_Graph : in Graph) return Boolean;
    function Is_Null (The_Vertex : in Vertex) return Boolean;
    function Is_Null (The_Arc : in Arc) return Boolean;
    function Number_Of_Vertices_In (The_Graph : in Graph) return Natural;
    function Number_Of_Arcs_In (The_Graph : in Graph) return Natural;
    function Number_Of_Arcs_With (The_Vertex : in Vertex) return Natural;
    function Item_Of (The_Vertex : in Vertex) return Item;
    function Attribute_Of (The_Arc : in Arc) return Attribute;
    function First_Vertex_Of (The_Arc : in Arc) return Vertex;  
    function Second_Vertex_Of (The_Arc : in Arc) return Vertex;
    function Is_A_Member (The_Vertex : in Vertex; Of_The_Graph : in Graph)
                         return Boolean;
    function Is_A_Member
                (The_Arc : in Arc; Of_The_Graph : in Graph) return Boolean;

    generic
        with procedure Process (The_Vertex : in Vertex; Continue : out Boolean);
    procedure Iterate_Vertices (Over_The_Graph : in Graph);

    generic
        with procedure Process (The_Arc : in Arc; Continue : out Boolean);
    procedure Iterate_Arcs (Over_The_Graph : in Graph);

    generic
        with procedure Process (The_Arc : in Arc; Continue : out Boolean);
    procedure Reiterate (Over_The_Vertex : in Vertex);

    Overflow : exception;
    Vertex_Is_Null : exception;
    Vertex_Is_Not_In_Graph : exception;
    Arc_Is_Null : exception;
    Arc_Is_Not_In_Graph : exception;

private
    type Vertex_Node;
    type Vertex is access Vertex_Node;
    package Vertex_Set is
       new Set_Simple_Sequential_Unbounded_Unmanaged_Iterator (Item => Vertex);
    type Arc_Node;
    type Arc is access Arc_Node;
    package Arc_Set is
       new Set_Simple_Sequential_Unbounded_Unmanaged_Iterator (Item => Arc);
    type Graph is
        record
            The_Vertices : Vertex_Set.Set;
            The_Arcs : Arc_Set.Set;
        end record;
    Null_Vertex : constant Vertex := null;
    Null_Arc : constant Arc := null;
end Graph_Undirected_Unbounded_Unmanaged;