with Directory;
package Objects is

    type Kind is private;
    type Class is (Ada_Unit, A_Structure, A_File, An_Other);

    Null_Object : constant Kind;

    procedure Set_Object (The_Object : in out Kind; The_Name : in String);
    procedure Set_Object (The_Object : in out Kind;
                          The_Declaration : in Directory.Object);
    procedure Visit (The_Object : in Kind);

    function Kind_Of (The_Declaration : in Directory.Object) return Kind;
    function Declaration_Of (The_Object : in Kind) return Directory.Object;
    function Id_Of (The_Object : in Kind) return Directory.Object;
    function Class_Of (The_Object : in Kind) return Class;
    function Enclosing_Object_Of (The_Object : in Kind) return Kind;
    function Unique_Name_Of (The_Object : in Kind) return String;
    function Qualified_Name_Of (The_Object : in Kind) return String;
    function Simple_Name_Of (The_Object : in Kind) return String;
    function Version_Of (The_Object : in Kind) return String;
    function Creator_Of (The_Object : in Kind) return String;
    function Updater_Of (The_Object : in Kind) return String;
    function Reader_Of (The_Object : in Kind) return String;
    function Creation_Time_Of (The_Object : in Kind) return String;
    function Update_Time_Of (The_Object : in Kind) return String;
    function Read_Time_Of (The_Object : in Kind) return String;
    function Size_Of (The_Object : in Kind) return String;
    function Is_Frozen (The_Object : in Kind) return String;

    package Ada is

        type Ada_Class is (A_Subprogram, A_Package, A_Task, Undecided);
        type Ada_Unit_Kind is (Function_Spec, Function_Body, Procedure_Spec,
                               Procedure_Body, Package_Spec,
                               Package_Body, Generic_Function_Spec,
                               Generic_Function_Body, Generic_Procedure_Spec,
                               Generic_Procedure_Body, Generic_Package_Spec,
                               Generic_Package_Body, Function_Instantiation,
                               Procedure_Instantiation, Package_Instantiation,
                               Task_Spec, Task_Body, Undecided);
        type Status is (Source, Installed, Coded, Unknown);

        function Ada_Class_Of (The_Object : in Kind) return Ada_Class;
        function Ada_Unit_Kind_Of (The_Object : in Kind) return Ada_Unit_Kind;
        function Is_Generic (The_Object : in Kind) return Boolean;
        function Is_Spec (The_Object : in Kind) return Boolean;
        function Is_Subunit (The_Object : in Kind) return Boolean;
        function Has_Subunits (The_Object : in Kind) return Boolean;
        function Status_Of (The_Object : in Kind) return Status;

        generic
            with procedure Process (The_Object : in Kind);
        procedure Traverse_Withs_Of (The_Object : in Kind);

        generic
            with procedure Process (The_Object : in Kind);
        procedure Traverse_Uses_Of (The_Object : in Kind);

        generic
            with procedure Process (The_Object : in Kind);
        procedure Traverse_Subunits_Of (The_Object : in Kind);

        Is_Not_Ada_Unit : exception;

    end Ada;

    package Structure is

        type Structure_Class is (Subsystem, View, World, Directory);

        function Structure_Class_Of
                    (The_Object : in Kind) return Structure_Class;

        generic
            with procedure Process (The_Object : in Kind);
        procedure Traverse_Objects_Of (The_Object : in Kind);

        Is_Not_A_Structure : exception;

    end Structure;

    package File is

        type File_Class is (Text, Activity, Switches, Object_Collection);

        function File_Class_Of (The_Object : in Kind) return File_Class;

        generic
            with procedure Process (The_Object : in Kind);
        procedure Traverse_Subsystems_Of (The_Object : in Kind);

        generic
            with procedure Process (The_Object : in Kind);
        procedure Traverse_Spec_View_Of (The_Object : in Kind);

        generic
            with procedure Process (The_Objects : in Kind);
        procedure Traverse_Load_View_Of (The_Object : in Kind);

        generic
            with procedure Process (The_Objects : in Kind);
        procedure Traverse_Objects_Of (The_Object : in Kind);

        Is_Not_A_File : exception;
        Is_Not_An_Activity : exception;
        Is_Not_An_Object_Set : exception;

    end File;

    package Other is

        type Other_Class is (Session, User, Tape, Terminal, Pipe, Unknown);

        function Other_Class_Of (The_Object : in Kind) return Other_Class;

        Is_Not_An_Other : exception;

    end Other;

    Name_Error : exception;
    Object_Is_Null : exception;
    Directory_Error : exception;
    At_Root_Of_Universe : exception;

private
    type Node;
    type Kind is access Node;
    Null_Object : constant Kind := null;
end Objects;