separate (Structure)
procedure Traverse (This_Catalog : in Catalog; This_State : in out State) is
    --
    Control_Result : Traversal_Control := Continue;
    --
    The_Catalog : Catalog := This_Catalog;
    --
    The_Current_Item : Item;
    The_Current_Section : Section;
    --
    Assert_Abandon_Children : exception;
    Assert_Abandon_Level : exception;
    Assert_Abandon_Traversal : exception;
    --
    procedure Assert_Control is
    begin  
        case (Control_Result) is
            when Continue =>
                null;
            when Abandon_Children =>
                raise Assert_Abandon_Children;
            when Abandon_Level =>
                raise Assert_Abandon_Level;
            when Abandon_Traversal =>
                raise Assert_Abandon_Traversal;
        end case;
    end Assert_Control;
    --
begin
    begin
        Assert_Is_Good (The_Catalog);
        Operate_On (The_Catalog, This_State, Control_Result);
        Assert_Control;
        Reset (The_Catalog);
        while (not Done (The_Catalog)) loop  
            begin
                The_Current_Section := Current_Section (The_Catalog);
                Operate_On (The_Current_Section, This_State, Control_Result);
                Assert_Control;
                Reset (The_Current_Section);  
                begin
                    while (not Done (The_Current_Section)) loop
                        begin
                            The_Current_Item := Current_Item
                                                   (The_Current_Section);
                            Operate_On (The_Current_Item,
                                        This_State, Control_Result);
                            Assert_Control;
                            --
                        exception
                            when Assert_Abandon_Children =>
                                null;
                            when others =>
                                raise;
                        end;
                        Next (The_Current_Section);
                    end loop;
                    --
                exception
                    when Assert_Abandon_Children | Assert_Abandon_Level =>
                        null;
                    when others =>
                        raise;
                        --
                end;
            exception
                when Assert_Abandon_Children =>
                    null;
                when others =>
                    raise;
                    --
            end;
            Next (The_Catalog);
        end loop;
        --
    exception
        when Assert_Abandon_Children | Assert_Abandon_Level |
             Assert_Abandon_Traversal =>
            Finalize_Traversal (The_Catalog, This_State);
        when Bad_Element =>
            Finalize_Traversal (The_Catalog, This_State);
            raise;
        when others =>
            Finalize_Traversal (The_Catalog, This_State);
            raise;
            --
    end;
    Finalize_Traversal (The_Catalog, This_State);
    --
end Traverse;