generic
    type Item is private;
    The_Size : in Positive;
    Maximum_Children : in Positive;
package Tree_Arbitrary_Double_Bounded_Managed is

    type Tree is private;

    Null_Tree : constant Tree;

    procedure Copy (From_The_Tree : in Tree; To_The_Tree : in out Tree);
    procedure Clear (The_Tree : in out Tree);
    procedure Construct (The_Item : in Item;
                         And_The_Tree : in out Tree;
                         Number_Of_Children : in Natural;
                         On_The_Child : in Natural);
    procedure Set_Item (Of_The_Tree : in out Tree; To_The_Item : in Item);
    procedure Swap_Child (The_Child : in Positive;
                          Of_The_Tree : in out Tree;
                          And_The_Tree : in out Tree);

    function Is_Equal (Left : in Tree; Right : in Tree) return Boolean;
    function Is_Null (The_Tree : in Tree) return Boolean;
    function Item_Of (The_Tree : in Tree) return Item;
    function Number_Of_Children_In (The_Tree : in Tree) return Natural;
    function Child_Of (The_Tree : in Tree; The_Child : in Positive) return Tree;
    function Parent_Of (The_Tree : in Tree) return Tree;

    Overflow : exception;
    Tree_Is_Null : exception;
    Tree_Is_Not_Null : exception;
    Not_At_Root : exception;
    Child_Error : exception;

private
    type Tree is
        record
            The_Head : Natural := 0;
        end record;
    Null_Tree : constant Tree := Tree'(The_Head => 0);
end Tree_Arbitrary_Double_Bounded_Managed;