-------------------------------------------------------------------------------
-- (C) Altran Praxis Limited
-------------------------------------------------------------------------------
--
-- The SPARK toolset is free software; you can redistribute it and/or modify it
-- under terms of the GNU General Public License as published by the Free
-- Software Foundation; either version 3, or (at your option) any later
-- version. The SPARK toolset is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-- Public License for more details. You should have received a copy of the GNU
-- General Public License distributed with the SPARK toolset; see file
-- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy of
-- the license.
--
--=============================================================================

with Maths;
with FileSystem;
with E_Strings;

separate (Dictionary)
procedure Write (File_Name : in     E_Strings.T;
                 Status    :    out SPARK_IO.File_Status) is

   File            : SPARK_IO.File_Type := SPARK_IO.Null_File;
   Local_File_Name : E_Strings.T;

   --------------------------------------------------------------------------------

   procedure Write_Library_Units (File : in SPARK_IO.File_Type)
   --# global in     Dict;
   --#        in     LexTokenManager.State;
   --#        in out SPARK_IO.File_Sys;
   --# derives SPARK_IO.File_Sys from *,
   --#                                Dict,
   --#                                File,
   --#                                LexTokenManager.State;
   is
      Library_Units : Iterator;

      --------------------------------------------------------------------------------

      procedure Write_Generic_Formal_Parameters (File        : in SPARK_IO.File_Type;
                                                 The_Generic : in RawDict.Subprogram_Info_Ref)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State,
      --#                                The_Generic;
      is
         Parameter_It : Iterator;
         Number       : Positive;

         --------------------------------------------------------------------------------

         procedure Write_Generic_Formal_Parameter
           (File                  : in SPARK_IO.File_Type;
            The_Generic           : in RawDict.Subprogram_Info_Ref;
            Number                : in Positive;
            The_Generic_Parameter : in RawDict.Generic_Parameter_Info_Ref)
         --# global in     Dict;
         --#        in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                Dict,
         --#                                File,
         --#                                LexTokenManager.State,
         --#                                Number,
         --#                                The_Generic,
         --#                                The_Generic_Parameter;
         is

            procedure Write_Generic_Type
              (File                  : in SPARK_IO.File_Type;
               The_Generic_Parameter : in RawDict.Generic_Parameter_Info_Ref)
            --# global in     Dict;
            --#        in out SPARK_IO.File_Sys;
            --# derives SPARK_IO.File_Sys from *,
            --#                                Dict,
            --#                                File,
            --#                                The_Generic_Parameter;
            is
               Type_Mark : RawDict.Type_Info_Ref;
            begin
               Type_Mark := RawDict.Get_Generic_Parameter_Type (The_Generic_Parameter => The_Generic_Parameter);
               case RawDict.Get_Type_Discriminant (Type_Mark) is
                  when Generic_Type_Item =>
                     Write_String (File, "generic ");
                     case RawDict.Get_Type_Kind_Of_Generic (Type_Mark => Type_Mark) is
                        when Invalid_Generic_Type =>
                           Write_String (File, "invalid generic type ");
                           SystemErrors.Fatal_Error
                             (Sys_Err => SystemErrors.Invalid_Symbol_Table,
                              Msg     => "in Dictionary.Write_Generic_Type");
                        when Generic_Private_Type =>
                           Write_String (File, "private ");
                        when Generic_Discrete_Type =>
                           Write_String (File, "discrete ");
                        when Generic_Integer_Type =>
                           Write_String (File, "integer ");
                        when Generic_Modular_Type =>
                           Write_String (File, "modular ");
                        when Generic_Floating_Point_Type =>
                           Write_String (File, "floating point ");
                        when Generic_Fixed_Point_Type =>
                           Write_String (File, "fixed point ");
                        when Generic_Array_Type =>
                           Write_String (File, "array ");
                     end case;
                  when others => -- non-exec code
                     Write_String (File, "invalid generic type ");
                     SystemErrors.Fatal_Error
                       (Sys_Err => SystemErrors.Invalid_Symbol_Table,
                        Msg     => "in Dictionary.Write_Generic_Type");
               end case;
            end Write_Generic_Type;

         begin -- Write_Generic_Formal_Parameter
            Write_String (File, "generic formal parameter # ");
            Write_Integer (File, Number);
            Write_String (File, " of ");
            Write_Name (File => File,
                        Item => RawDict.Get_Subprogram_Symbol (The_Generic));
            Write_String (File, " is ");
            Write_Simple_Name (File => File,
                               Item => RawDict.Get_Generic_Parameter_Symbol (The_Generic_Parameter));
            Write_String (File, " which is ");
            case RawDict.Get_Generic_Parameter_Kind (The_Generic_Parameter => The_Generic_Parameter) is
               when Generic_Type_Parameter =>
                  Write_String (File, "a ");
                  Write_Generic_Type (File                  => File,
                                      The_Generic_Parameter => The_Generic_Parameter);
                  Write_String (File, "type parameter");
               when Generic_Object_Parameter =>
                  Write_String (File, "a generic object parameter of type ");
                  Write_Name
                    (File => File,
                     Item => RawDict.Get_Type_Symbol
                       (RawDict.Get_Constant_Type
                          (The_Constant => RawDict.Get_Generic_Parameter_Object (The_Generic_Parameter => The_Generic_Parameter))));
            end case;
            Write_Line (File, " ;");
         end Write_Generic_Formal_Parameter;

      begin -- Write_Generic_Formal_Parameters
         Parameter_It := First_Generic_Formal_Subprogram_Parameter (The_Subprogram => The_Generic);
         Number       := 1;
         while not IsNullIterator (Parameter_It) and then Number < Positive'Last loop
            Write_Generic_Formal_Parameter
              (File                  => File,
               The_Generic           => The_Generic,
               Number                => Number,
               The_Generic_Parameter => RawDict.Get_Generic_Parameter_Info_Ref (CurrentSymbol (Parameter_It)));
            Parameter_It := NextSymbol (Parameter_It);
            Number       := Number + 1;
         end loop;
      end Write_Generic_Formal_Parameters;

      --------------------------------------------------------------------------------

      function First_Library_Unit return Iterator
      --# global in Dict;
      is
         The_Declaration : RawDict.Declaration_Info_Ref;
         Item            : Symbol   := NullSymbol;
         Found           : Boolean  := False;
         Library_Units   : Iterator := NullIterator;
      begin
         The_Declaration := RawDict.Get_Package_First_Local_Declaration (The_Package => Get_Predefined_Package_Standard);
         while (The_Declaration /= RawDict.Null_Declaration_Info_Ref and then not Found) loop
            Item := RawDict.Get_Declaration_Item (The_Declaration => The_Declaration);
            case RawDict.GetSymbolDiscriminant (Item) is
               when Package_Symbol =>
                  Found := The_Declaration /=
                    RawDict.Get_Package_Body (The_Package => RawDict.Get_Package_Info_Ref (Item => Item));
               when Subprogram_Symbol =>
                  Found := The_Declaration /=
                    RawDict.Get_Subprogram_Body (The_Subprogram => RawDict.Get_Subprogram_Info_Ref (Item => Item));
               when others =>
                  Found := False;
            end case;
            if not Found then
               The_Declaration := RawDict.Get_Next_Declaration (The_Declaration => The_Declaration);
            end if;
         end loop;

         if The_Declaration /= RawDict.Null_Declaration_Info_Ref then
            Library_Units :=
              Iterator'
              (LibraryUnitIterator,
               IsAbstract,
               Item,
               RawDict.Get_Declaration_Symbol (The_Declaration => The_Declaration));
         end if;
         return Library_Units;
      end First_Library_Unit;

      --------------------------------------------------------------------------------
      -- Subprograms that should be in Write_Library_Unit
      --------------------------------------------------------------------------------

      procedure Write_With_References (File  : in SPARK_IO.File_Type;
                                       Scope : in Scopes)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State,
      --#                                Scope;
      is
         With_Reference : Iterator;

         --------------------------------------------------------------------------------

         function First_Withed_Package (Scope : Scopes) return Iterator
         --# global in Dict;
         is
            Region             : Symbol;
            The_Generic_Unit   : RawDict.Generic_Unit_Info_Ref;
            The_Context_Clause : RawDict.Context_Clause_Info_Ref;
            Withed_Packages    : Iterator := NullIterator;
         begin
            Region := GetRegion (Scope);
            case Get_Visibility (Scope => Scope) is
               when Visible | Privat =>
                  case RawDict.GetSymbolDiscriminant (Region) is
                     when Package_Symbol =>
                        The_Context_Clause :=
                          RawDict.Get_Package_Visible_With_Clauses (The_Package => RawDict.Get_Package_Info_Ref (Item => Region));
                     when Generic_Unit_Symbol =>
                        The_Generic_Unit := RawDict.Get_Generic_Unit_Info_Ref (Item => Region);
                        case RawDict.Get_Generic_Unit_Kind (The_Generic_Unit => The_Generic_Unit) is
                           when Generic_Of_Package =>
                              The_Context_Clause :=
                                RawDict.Get_Package_Visible_With_Clauses
                                (The_Package => RawDict.Get_Generic_Unit_Owning_Package (The_Generic_Unit => The_Generic_Unit));
                           when Generic_Of_Subprogram =>
                              The_Context_Clause :=
                                RawDict.Get_Subprogram_With_Clauses
                                (The_Subprogram => RawDict.Get_Generic_Unit_Owning_Subprogram (The_Generic_Unit => The_Generic_Unit));
                        end case;
                     when others => -- non-exec code
                        The_Context_Clause := RawDict.Null_Context_Clause_Info_Ref;
                        SystemErrors.Fatal_Error
                          (Sys_Err => SystemErrors.Invalid_Symbol_Table,
                           Msg     => "in Dictionary.First_Withed_Package");
                  end case;
               when Local =>
                  case RawDict.GetSymbolDiscriminant (Region) is
                     when Package_Symbol =>
                        The_Context_Clause :=
                          RawDict.Get_Package_Local_With_Clauses (The_Package => RawDict.Get_Package_Info_Ref (Item => Region));
                     when Subprogram_Symbol =>
                        The_Context_Clause :=
                          RawDict.Get_Subprogram_With_Clauses
                          (The_Subprogram => RawDict.Get_Subprogram_Info_Ref (Item => Region));
                     when others => -- non-exec code
                        The_Context_Clause := RawDict.Null_Context_Clause_Info_Ref;
                        SystemErrors.Fatal_Error
                          (Sys_Err => SystemErrors.Invalid_Symbol_Table,
                           Msg     => "in Dictionary.First_Withed_Package");
                  end case;
            end case;

            if The_Context_Clause /= RawDict.Null_Context_Clause_Info_Ref then
               case RawDict.Get_Context_Clause_Is_Subprogram (The_Context_Clause => The_Context_Clause) is
                  when False =>
                     Withed_Packages :=
                       Iterator'
                       (WithedPackageIterator,
                        IsAbstract,
                        RawDict.Get_Package_Symbol (RawDict.Get_Context_Clause_Package (The_Context_Clause => The_Context_Clause)),
                        RawDict.Get_Context_Clause_Symbol (The_Context_Clause));
                  when True =>
                     Withed_Packages :=
                       Iterator'
                       (WithedPackageIterator,
                        IsAbstract,
                        RawDict.Get_Subprogram_Symbol
                          (RawDict.Get_Context_Clause_Subprogram (The_Context_Clause => The_Context_Clause)),
                        RawDict.Get_Context_Clause_Symbol (The_Context_Clause));
               end case;
            end if;
            return Withed_Packages;
         end First_Withed_Package;

         --------------------------------------------------------------------------------

         procedure Write_With_Reference
           (File        : in SPARK_IO.File_Type;
            The_Package : in RawDict.Package_Info_Ref;
            Scope       : in Scopes)
         --# global in     Dict;
         --#        in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                Dict,
         --#                                File,
         --#                                LexTokenManager.State,
         --#                                Scope,
         --#                                The_Package;
         is
         begin
            Write_String (File, "with reference to ");
            Write_Simple_Name (File => File,
                               Item => RawDict.Get_Package_Symbol (The_Package));
            Write_String (File, " in ");
            Write_Scope (File, Scope);
            Write_Line (File, " ;");
         end Write_With_Reference;

      begin -- Write_With_References
         With_Reference := First_Withed_Package (Scope => Scope);
         loop
            exit when IsNullIterator (With_Reference);
            Write_With_Reference
              (File        => File,
               The_Package => RawDict.Get_Package_Info_Ref (CurrentSymbol (With_Reference)),
               Scope       => Scope);
            With_Reference := NextSymbol (With_Reference);
         end loop;
      end Write_With_References;

      --------------------------------------------------------------------------------

      procedure Write_Inherits_References (File             : in SPARK_IO.File_Type;
                                           Compilation_Unit : in Symbol)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Compilation_Unit,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State;
      is

         Inherits_Reference : Iterator;

         --------------------------------------------------------------------------------

         function First_Inherited_Package (Compilation_Unit : Symbol) return Iterator
         --# global in Dict;
         is
            The_Context_Clause : RawDict.Context_Clause_Info_Ref;
            Inherited_Packages : Iterator := NullIterator;
         begin
            case RawDict.GetSymbolDiscriminant (Compilation_Unit) is
               when Package_Symbol =>
                  The_Context_Clause :=
                    RawDict.Get_Package_Inherit_Clauses (The_Package => RawDict.Get_Package_Info_Ref (Item => Compilation_Unit));
               when Subprogram_Symbol =>
                  if Is_Main_Program (The_Subprogram => RawDict.Get_Subprogram_Info_Ref (Item => Compilation_Unit)) then
                     The_Context_Clause :=
                       RawDict.Get_Subprogram_Inherit_Clauses
                       (The_Subprogram => RawDict.Get_Subprogram_Info_Ref (Item => Compilation_Unit));
                  else
                     The_Context_Clause := RawDict.Null_Context_Clause_Info_Ref;
                  end if;
               when others => -- non-exec code
                  The_Context_Clause := RawDict.Null_Context_Clause_Info_Ref;
                  SystemErrors.Fatal_Error
                    (Sys_Err => SystemErrors.Invalid_Symbol_Table,
                     Msg     => "in Dictionary.First_Inherited_Package");
            end case;

            if The_Context_Clause /= RawDict.Null_Context_Clause_Info_Ref then
               case RawDict.Get_Context_Clause_Is_Subprogram (The_Context_Clause => The_Context_Clause) is
                  when False =>
                     Inherited_Packages :=
                       Iterator'
                       (InheritedPackageIterator,
                        IsAbstract,
                        RawDict.Get_Package_Symbol (RawDict.Get_Context_Clause_Package (The_Context_Clause => The_Context_Clause)),
                        RawDict.Get_Context_Clause_Symbol (The_Context_Clause));
                  when True =>
                     Inherited_Packages :=
                       Iterator'
                       (InheritedPackageIterator,
                        IsAbstract,
                        RawDict.Get_Subprogram_Symbol
                          (RawDict.Get_Context_Clause_Subprogram (The_Context_Clause => The_Context_Clause)),
                        RawDict.Get_Context_Clause_Symbol (The_Context_Clause));
               end case;
            end if;
            return Inherited_Packages;
         end First_Inherited_Package;

         --------------------------------------------------------------------------------

         procedure Write_Inherits_Reference
           (File             : in SPARK_IO.File_Type;
            The_Package      : in RawDict.Package_Info_Ref;
            Compilation_Unit : in Symbol)
         --# global in     Dict;
         --#        in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                Compilation_Unit,
         --#                                Dict,
         --#                                File,
         --#                                LexTokenManager.State,
         --#                                The_Package;
         is
         begin
            Write_String (File, "inherits reference to ");
            Write_Simple_Name (File => File,
                               Item => RawDict.Get_Package_Symbol (The_Package));
            Write_String (File, " in ");
            Write_Name (File => File,
                        Item => Compilation_Unit);
            Write_Line (File, " ;");
         end Write_Inherits_Reference;

      begin -- Write_Inherits_References
         Inherits_Reference := First_Inherited_Package (Compilation_Unit => Compilation_Unit);
         loop
            exit when IsNullIterator (Inherits_Reference);
            Write_Inherits_Reference
              (File             => File,
               The_Package      => RawDict.Get_Package_Info_Ref (CurrentSymbol (Inherits_Reference)),
               Compilation_Unit => Compilation_Unit);
            Inherits_Reference := NextSymbol (Inherits_Reference);
         end loop;
      end Write_Inherits_References;

      --------------------------------------------------------------------------------

      procedure Write_Package_Info (File        : in SPARK_IO.File_Type;
                                    The_Package : in RawDict.Package_Info_Ref)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State,
      --#                                The_Package;
      is
         Scope : Scopes;
      begin
         if RawDict.Get_Package_Parent (The_Package => The_Package) /= RawDict.Null_Package_Info_Ref then
            Write_String (File, "child ");
         end if;

         Write_String (File, "package named ");
         Write_Simple_Name (File => File,
                            Item => RawDict.Get_Package_Symbol (The_Package));
         Scope := Get_Package_Scope (The_Package => The_Package);
         if RawDict.GetSymbolDiscriminant (GetRegion (Scope)) /= Package_Symbol
           or else RawDict.Get_Package_Info_Ref (Item => GetRegion (Scope)) /= Get_Predefined_Package_Standard then
            Write_String (File, " declared in ");
            Write_Scope (File, Scope);
         end if;
         Write_Line (File, " ;");
      end Write_Package_Info;

      --------------------------------------------------------------------------------

      function First_Declarative_Item (Scope : Scopes) return Iterator
      --# global in Dict;
      is
         The_Declaration   : RawDict.Declaration_Info_Ref;
         Region            : Symbol;
         Item              : Symbol   := NullSymbol;
         Found             : Boolean  := False;
         Declarative_Items : Iterator := NullIterator;
      begin
         case Get_Visibility (Scope => Scope) is
            when Visible =>
               The_Declaration :=
                 RawDict.Get_Package_First_Visible_Declaration (The_Package => RawDict.Get_Package_Info_Ref (GetRegion (Scope)));
            when Local =>
               Region := GetRegion (Scope);
               case RawDict.GetSymbolDiscriminant (Region) is
                  when Package_Symbol =>
                     The_Declaration :=
                       RawDict.Get_Package_First_Local_Declaration (The_Package => RawDict.Get_Package_Info_Ref (Item => Region));
                  when Subprogram_Symbol =>
                     The_Declaration :=
                       RawDict.Get_Subprogram_First_Declaration
                       (The_Subprogram => RawDict.Get_Subprogram_Info_Ref (Item => Region));
                  when others =>
                     The_Declaration := RawDict.Null_Declaration_Info_Ref;
               end case;
            when Privat =>
               The_Declaration :=
                 RawDict.Get_Package_First_Private_Declaration (The_Package => RawDict.Get_Package_Info_Ref (GetRegion (Scope)));
         end case;

         while (The_Declaration /= RawDict.Null_Declaration_Info_Ref and then not Found) loop
            Item := RawDict.Get_Declaration_Item (The_Declaration => The_Declaration);
            case RawDict.GetSymbolDiscriminant (Item) is
               when Package_Symbol =>
                  Found := The_Declaration /=
                    RawDict.Get_Package_Body (The_Package => RawDict.Get_Package_Info_Ref (Item => Item));
               when Subprogram_Symbol =>
                  Found := The_Declaration /=
                    RawDict.Get_Subprogram_Body (The_Subprogram => RawDict.Get_Subprogram_Info_Ref (Item => Item));
               when others =>
                  Found := True;
            end case;
            if not Found then
               The_Declaration := RawDict.Get_Next_Declaration (The_Declaration => The_Declaration);
            end if;
         end loop;

         if The_Declaration /= RawDict.Null_Declaration_Info_Ref then
            Declarative_Items :=
              Iterator'
              (DeclarativeItemIterator,
               IsAbstract,
               Item,
               RawDict.Get_Declaration_Symbol (The_Declaration => The_Declaration));
         end if;
         return Declarative_Items;
      end First_Declarative_Item;

      --------------------------------------------------------------------------------

      procedure Write_Static_Value
        (File      : in SPARK_IO.File_Type;
         Value     : in LexTokenManager.Lex_String;
         Type_Mark : in RawDict.Type_Info_Ref)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State,
      --#                                Type_Mark,
      --#                                Value;
      is
         Root_Type : RawDict.Type_Info_Ref;

         --------------------------------------------------------------------------------

         procedure Write_Lex_String (File    : in SPARK_IO.File_Type;
                                     Lex_Str : in LexTokenManager.Lex_String)
         --# global in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                File,
         --#                                LexTokenManager.State,
         --#                                Lex_Str;
         is
         begin
            E_Strings.Put_String (File  => File,
                                  E_Str => LexTokenManager.Lex_String_To_String (Lex_Str => Lex_Str));
         end Write_Lex_String;

      begin -- Write_Static_Value
         Root_Type := Get_Root_Type (Type_Mark => Type_Mark);
         if Type_Mark = Get_Unknown_Type_Mark then
            Write_String (File, " unknown ");
         elsif Type_Is_Numeric (Type_Mark => Type_Mark) or else Root_Type = Get_Predefined_Character_Type then
            E_Strings.Put_String (File  => File,
                                  E_Str => Maths.ValueToString (Maths.ValueRep (Value)));
         elsif Root_Type = Get_Predefined_Boolean_Type or else Root_Type = Get_Predefined_String_Type then
            Write_Lex_String (File    => File,
                              Lex_Str => Value);
         elsif RawDict.Get_Type_Discriminant (Type_Mark => Type_Mark) = Enumeration_Type_Item then
            Write_Name (File => File,
                        Item => Get_Enumeration_Literal (Type_Mark => Type_Mark,
                                                         Position  => Value));
         else
            Write_String (File, " unknown ");
         end if;
      end Write_Static_Value;

      --------------------------------------------------------------------------------

      procedure Write_Subprogram_Global_Variables
        (Abstraction    : in Abstractions;
         File           : in SPARK_IO.File_Type;
         The_Subprogram : in RawDict.Subprogram_Info_Ref)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Abstraction,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State,
      --#                                The_Subprogram;
      is
         Global_Variable : Iterator;

         --------------------------------------------------------------------------------

         procedure Write_Global_Variable
           (Abstraction     : in Abstractions;
            File            : in SPARK_IO.File_Type;
            The_Subprogram  : in RawDict.Subprogram_Info_Ref;
            Global_Variable : in Symbol)
         --# global in     Dict;
         --#        in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                Abstraction,
         --#                                Dict,
         --#                                File,
         --#                                Global_Variable,
         --#                                LexTokenManager.State,
         --#                                The_Subprogram;
         is
            The_Mode : Modes;
         begin
            if Abstraction = IsRefined then
               Write_String (File, "refined ");
            end if;
            Write_String (File, "global variable named ");
            Write_Name (File => File,
                        Item => Global_Variable);

            Write_String (File, " of mode ");

            case RawDict.GetSymbolDiscriminant (Global_Variable) is
               when Variable_Symbol =>
                  The_Mode :=
                    Get_Subprogram_Variable_Global_Mode
                    (The_Subprogram => The_Subprogram,
                     Abstraction    => Abstraction,
                     The_Variable   => RawDict.Get_Variable_Info_Ref (Item => Global_Variable));
               when Subprogram_Parameter_Symbol =>
                  The_Mode :=
                    Get_Subprogram_Parameter_Global_Mode
                    (The_Subprogram           => The_Subprogram,
                     Abstraction              => Abstraction,
                     The_Subprogram_Parameter => RawDict.Get_Subprogram_Parameter_Info_Ref (Item => Global_Variable));
               when others => -- non-exec code
                  The_Mode := InvalidMode;
                  SystemErrors.Fatal_Error
                    (Sys_Err => SystemErrors.Invalid_Symbol_Table,
                     Msg     => "in Dictionary.Write_Global_Variable");
            end case;

            case The_Mode is
               when DefaultMode =>
                  Write_String (File, "default");
               when InMode =>
                  Write_String (File, "in");
               when OutMode =>
                  Write_String (File, "out");
               when InOutMode =>
                  Write_String (File, "in out");
               when InvalidMode =>
                  Write_String (File, "invalid");
            end case;
            Write_String (File, " is referenced by ");
            Write_Name (File => File,
                        Item => RawDict.Get_Subprogram_Symbol (The_Subprogram));
            Write_Line (File, " ;");
         end Write_Global_Variable;

      begin -- Write_Subprogram_Global_Variables
         Global_Variable := First_Subprogram_Global_Variable (The_Subprogram => The_Subprogram,
                                                              Abstraction    => Abstraction);
         loop
            exit when IsNullIterator (Global_Variable);
            Write_Global_Variable
              (Abstraction     => Abstraction,
               File            => File,
               The_Subprogram  => The_Subprogram,
               Global_Variable => CurrentSymbol (Global_Variable));
            Global_Variable := NextSymbol (Global_Variable);
         end loop;
      end Write_Subprogram_Global_Variables;

      --------------------------------------------------------------------------------

      procedure Write_Task_Type_Global_Variables
        (Abstraction   : in Abstractions;
         File          : in SPARK_IO.File_Type;
         The_Task_Type : in RawDict.Type_Info_Ref)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Abstraction,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State,
      --#                                The_Task_Type;
      is
         Global_Variable : Iterator;

         --------------------------------------------------------------------------------

         procedure Write_Global_Variable
           (Abstraction     : in Abstractions;
            File            : in SPARK_IO.File_Type;
            The_Task_Type   : in RawDict.Type_Info_Ref;
            Global_Variable : in RawDict.Variable_Info_Ref)
         --# global in     Dict;
         --#        in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                Abstraction,
         --#                                Dict,
         --#                                File,
         --#                                Global_Variable,
         --#                                LexTokenManager.State,
         --#                                The_Task_Type;
         is
            The_Mode : Modes;
         begin
            if Abstraction = IsRefined then
               Write_String (File, "refined ");
            end if;
            Write_String (File, "global variable named ");
            Write_Name (File => File,
                        Item => RawDict.Get_Variable_Symbol (Global_Variable));

            Write_String (File, " of mode ");

            The_Mode :=
              Get_Task_Type_Variable_Global_Mode
              (The_Task_Type => The_Task_Type,
               Abstraction   => Abstraction,
               The_Variable  => Global_Variable);

            case The_Mode is
               when DefaultMode =>
                  Write_String (File, "default");
               when InMode =>
                  Write_String (File, "in");
               when OutMode =>
                  Write_String (File, "out");
               when InOutMode =>
                  Write_String (File, "in out");
               when InvalidMode =>
                  Write_String (File, "invalid");
            end case;
            Write_String (File, " is referenced by ");
            Write_Name (File => File,
                        Item => RawDict.Get_Type_Symbol (The_Task_Type));
            Write_Line (File, " ;");
         end Write_Global_Variable;

      begin
         Global_Variable := First_Task_Type_Global_Variable (The_Task_Type => The_Task_Type,
                                                             Abstraction   => Abstraction);
         loop
            exit when IsNullIterator (Global_Variable);
            Write_Global_Variable
              (Abstraction     => Abstraction,
               File            => File,
               The_Task_Type   => The_Task_Type,
               Global_Variable => RawDict.Get_Variable_Info_Ref (CurrentSymbol (Global_Variable)));
            Global_Variable := NextSymbol (Global_Variable);
         end loop;
      end Write_Task_Type_Global_Variables;

      --------------------------------------------------------------------------------

      procedure Write_Subprogram_Dependency_Clauses
        (Abstraction    : in Abstractions;
         File           : in SPARK_IO.File_Type;
         The_Subprogram : in RawDict.Subprogram_Info_Ref)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Abstraction,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State,
      --#                                The_Subprogram;
      is
         Export : Iterator;

         --------------------------------------------------------------------------------

         procedure Write_Dependencies
           (Abstraction    : in Abstractions;
            File           : in SPARK_IO.File_Type;
            The_Subprogram : in RawDict.Subprogram_Info_Ref;
            Export         : in Symbol)
         --# global in     Dict;
         --#        in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                Abstraction,
         --#                                Dict,
         --#                                Export,
         --#                                File,
         --#                                LexTokenManager.State,
         --#                                The_Subprogram;
         is
            Dependency : Iterator;

            --------------------------------------------------------------------------------

            procedure Write_Dependency
              (Abstraction    : in Abstractions;
               File           : in SPARK_IO.File_Type;
               The_Subprogram : in RawDict.Subprogram_Info_Ref;
               Export         : in Symbol;
               Import         : in Symbol)
            --# global in     Dict;
            --#        in     LexTokenManager.State;
            --#        in out SPARK_IO.File_Sys;
            --# derives SPARK_IO.File_Sys from *,
            --#                                Abstraction,
            --#                                Dict,
            --#                                Export,
            --#                                File,
            --#                                Import,
            --#                                LexTokenManager.State,
            --#                                The_Subprogram;
            is
            begin
               if Abstraction = IsRefined then
                  Write_String (File, "refined ");
               end if;
               if RawDict.GetSymbolDiscriminant (Export) = Variable_Symbol
                 and then Get_Own_Variable_Or_Constituent_Mode (The_Variable => RawDict.Get_Variable_Info_Ref (Item => Export)) =
                 InMode then
                  Write_String (File, "implicit ");
               end if;
               Write_String (File, "export named ");
               Write_Name (File => File,
                           Item => Export);
               Write_String (File, " is ");
               if RawDict.GetSymbolDiscriminant (Import) = Variable_Symbol
                 and then Get_Own_Variable_Or_Constituent_Mode (The_Variable => RawDict.Get_Variable_Info_Ref (Item => Import)) =
                 OutMode then
                  Write_String (File, "implicitly ");
               end if;
               Write_String (File, "derived from ");
               if Import = NullSymbol then
                  Write_String (File, "nothing");
               else
                  Write_Name (File => File,
                              Item => Import);
               end if;
               Write_String (File, " in ");
               Write_Name (File => File,
                           Item => RawDict.Get_Subprogram_Symbol (The_Subprogram));
               Write_Line (File, " ;");
            end Write_Dependency;

         begin -- Write_Dependencies
            Dependency :=
              First_Subprogram_Dependency (The_Subprogram => The_Subprogram,
                                           Abstraction    => Abstraction,
                                           The_Export     => Export);
            if IsNullIterator (Dependency) then
               Write_Dependency
                 (Abstraction    => Abstraction,
                  File           => File,
                  The_Subprogram => The_Subprogram,
                  Export         => Export,
                  Import         => NullSymbol);
            else
               loop
                  exit when IsNullIterator (Dependency);
                  Write_Dependency
                    (Abstraction    => Abstraction,
                     File           => File,
                     The_Subprogram => The_Subprogram,
                     Export         => Export,
                     Import         => CurrentSymbol (Dependency));
                  Dependency := NextSymbol (Dependency);
               end loop;
            end if;
         end Write_Dependencies;

      begin -- Write_Subprogram_Dependency_Clauses
         Export := First_Subprogram_Export (The_Subprogram => The_Subprogram,
                                            Abstraction    => Abstraction);
         loop
            exit when IsNullIterator (Export);
            Write_Dependencies
              (Abstraction    => Abstraction,
               File           => File,
               The_Subprogram => The_Subprogram,
               Export         => CurrentSymbol (Export));
            Export := NextSymbol (Export);
         end loop;
      end Write_Subprogram_Dependency_Clauses;

      --------------------------------------------------------------------------------

      procedure Write_Task_Type_Dependency_Clauses
        (Abstraction   : in Abstractions;
         File          : in SPARK_IO.File_Type;
         The_Task_Type : in RawDict.Type_Info_Ref)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Abstraction,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State,
      --#                                The_Task_Type;
      is
         Export : Iterator;

         --------------------------------------------------------------------------------

         procedure Write_Dependencies
           (Abstraction   : in Abstractions;
            File          : in SPARK_IO.File_Type;
            The_Task_Type : in RawDict.Type_Info_Ref;
            The_Export    : in RawDict.Variable_Info_Ref)
         --# global in     Dict;
         --#        in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                Abstraction,
         --#                                Dict,
         --#                                File,
         --#                                LexTokenManager.State,
         --#                                The_Export,
         --#                                The_Task_Type;
         is
            Dependency : Iterator;

            --------------------------------------------------------------------------------

            procedure Write_Dependency
              (Abstraction   : in Abstractions;
               File          : in SPARK_IO.File_Type;
               The_Task_Type : in RawDict.Type_Info_Ref;
               The_Export    : in RawDict.Variable_Info_Ref;
               The_Import    : in RawDict.Variable_Info_Ref)
            --# global in     Dict;
            --#        in     LexTokenManager.State;
            --#        in out SPARK_IO.File_Sys;
            --# derives SPARK_IO.File_Sys from *,
            --#                                Abstraction,
            --#                                Dict,
            --#                                File,
            --#                                LexTokenManager.State,
            --#                                The_Export,
            --#                                The_Import,
            --#                                The_Task_Type;
            is
            begin
               if Abstraction = IsRefined then
                  Write_String (File, "refined ");
               end if;
               if Get_Own_Variable_Or_Constituent_Mode (The_Variable => The_Export) = InMode then
                  Write_String (File, "implicit ");
               end if;
               Write_String (File, "export named ");
               Write_Name (File => File,
                           Item => RawDict.Get_Variable_Symbol (The_Export));
               Write_String (File, " is ");
               if Get_Own_Variable_Or_Constituent_Mode (The_Variable => The_Import) = OutMode then
                  Write_String (File, "implicitly ");
               end if;
               Write_String (File, "derived from ");
               if The_Import = RawDict.Null_Variable_Info_Ref then
                  Write_String (File, "nothing");
               else
                  Write_Name (File => File,
                              Item => RawDict.Get_Variable_Symbol (The_Import));
               end if;
               Write_String (File, " in ");
               Write_Name (File => File,
                           Item => RawDict.Get_Type_Symbol (The_Task_Type));
               Write_Line (File, " ;");
            end Write_Dependency;

         begin -- Write_Dependencies
            Dependency :=
              First_Task_Type_Dependency (The_Task_Type => The_Task_Type,
                                          Abstraction   => Abstraction,
                                          The_Export    => The_Export);
            if IsNullIterator (Dependency) then
               Write_Dependency
                 (Abstraction   => Abstraction,
                  File          => File,
                  The_Task_Type => The_Task_Type,
                  The_Export    => The_Export,
                  The_Import    => RawDict.Null_Variable_Info_Ref);
            else
               loop
                  exit when IsNullIterator (Dependency);
                  Write_Dependency
                    (Abstraction   => Abstraction,
                     File          => File,
                     The_Task_Type => The_Task_Type,
                     The_Export    => The_Export,
                     The_Import    => RawDict.Get_Variable_Info_Ref (CurrentSymbol (Dependency)));
                  Dependency := NextSymbol (Dependency);
               end loop;
            end if;
         end Write_Dependencies;

      begin -- Write_Task_Type_Dependency_Clauses
         Export := First_Task_Type_Export (The_Task_Type => The_Task_Type,
                                           Abstraction   => Abstraction);
         loop
            exit when IsNullIterator (Export);
            Write_Dependencies
              (Abstraction   => Abstraction,
               File          => File,
               The_Task_Type => The_Task_Type,
               The_Export    => RawDict.Get_Variable_Info_Ref (CurrentSymbol (Export)));
            Export := NextSymbol (Export);
         end loop;
      end Write_Task_Type_Dependency_Clauses;

      --------------------------------------------------------------------------------

      procedure Write_Type_Info (File      : in SPARK_IO.File_Type;
                                 Type_Mark : in RawDict.Type_Info_Ref)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State,
      --#                                Type_Mark;
      is

         procedure Write_Discriminant (File      : in SPARK_IO.File_Type;
                                       Type_Mark : in RawDict.Type_Info_Ref)
         --# global in     Dict;
         --#        in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                Dict,
         --#                                File,
         --#                                LexTokenManager.State,
         --#                                Type_Mark;
         is
         begin
            case RawDict.Get_Type_Discriminant (Type_Mark => Type_Mark) is
               when Unknown_Type_Item =>
                  Write_String (File, "unknown");
               when Enumeration_Type_Item =>
                  Write_String (File, "enumeration");
               when Integer_Type_Item =>
                  Write_String (File, "integer");
               when Modular_Type_Item =>
                  Write_String (File, "modular");
               when Floating_Point_Type_Item =>
                  Write_String (File, "floating point");
               when Fixed_Point_Type_Item =>
                  Write_String (File, "fixed point");
               when Array_Type_Item =>
                  Write_String (File, "array");
               when Record_Type_Item =>
                  Write_String (File, "record");
               when Abstract_Proof_Type_Item =>
                  Write_String (File, "abstract ");
               when Protected_Type_Item =>
                  Write_String (File, "protected");
               when Task_Type_Item =>
                  Write_String (File, "task");
               when Access_Type_Item =>
                  Write_String (File, "access ");
                  Write_Name (File => File,
                              Item => RawDict.Get_Type_Symbol (RawDict.Get_Type_Accesses (Type_Mark => Type_Mark)));
               when Generic_Type_Item =>
                  Write_String (File, "generic ");
                  case RawDict.Get_Type_Kind_Of_Generic (Type_Mark => Type_Mark) is
                     when Invalid_Generic_Type =>
                        Write_String (File, "invalid generic type ");
                        SystemErrors.Fatal_Error
                          (Sys_Err => SystemErrors.Invalid_Symbol_Table,
                           Msg     => "in Dictionary.Write_Discriminant");
                     when Generic_Private_Type =>
                        Write_String (File, "private ");
                     when Generic_Discrete_Type =>
                        Write_String (File, "discrete ");
                     when Generic_Integer_Type =>
                        Write_String (File, "integer ");
                     when Generic_Modular_Type =>
                        Write_String (File, "modular ");
                     when Generic_Floating_Point_Type =>
                        Write_String (File, "floating point ");
                     when Generic_Fixed_Point_Type =>
                        Write_String (File, "fixed point ");
                     when Generic_Array_Type =>
                        Write_String (File, "array ");
                  end case;
            end case;
         end Write_Discriminant;

         -------------------------------------------------------------------------

         procedure Write_Bound
           (File      : in SPARK_IO.File_Type;
            Bound     : in LexTokenManager.Lex_String;
            Type_Mark : in RawDict.Type_Info_Ref)
         --# global in     Dict;
         --#        in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                Bound,
         --#                                Dict,
         --#                                File,
         --#                                LexTokenManager.State,
         --#                                Type_Mark;
         is
         begin
            if LexTokenManager.Lex_String_Case_Insensitive_Compare (Lex_Str1 => Bound,
                                                                    Lex_Str2 => LexTokenManager.Null_String) =
              LexTokenManager.Str_Eq then
               SPARK_IO.Put_String (File, "unknown", 7);
            else
               Write_Static_Value (File      => File,
                                   Value     => Bound,
                                   Type_Mark => Type_Mark);
            end if;
         end Write_Bound;

         --------------------------------------------------------------------------------

         function Type_Is_Limited_Private (Type_Mark : RawDict.Type_Info_Ref) return Boolean
         --# global in Dict;
         is
         begin
            return RawDict.Get_Type_Limited (Type_Mark => Type_Mark) /= Never;
         end Type_Is_Limited_Private;

         --------------------------------------------------------------------------------

         procedure Write_Protected_Refinement (File      : in SPARK_IO.File_Type;
                                               Type_Mark : in RawDict.Type_Info_Ref)
         --# global in     Dict;
         --#        in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                Dict,
         --#                                File,
         --#                                LexTokenManager.State,
         --#                                Type_Mark;
         is
            It : Iterator;
         begin
            Write_String (File, "The implicit state variable of type ");
            Write_Simple_Name (File => File,
                               Item => RawDict.Get_Type_Symbol (Type_Mark));
            Write_Line (File, " has the following refinement constituents:");
            It := First_Constituent (The_Variable => Get_Protected_Type_Own_Variable (The_Protected_Type => Type_Mark));
            while not IsNullIterator (It) loop
               Write_String (File, "      ");
               Write_Simple_Name (File => File,
                                  Item => CurrentSymbol (It));
               Write_Line (File, ",");
               It := NextSymbol (It);
            end loop;
            Write_Line (File, ";");
         end Write_Protected_Refinement;

         --------------------------------------------------------------------------------

         procedure Write_Type_Discriminants (File      : in SPARK_IO.File_Type;
                                             Type_Mark : in RawDict.Type_Info_Ref)
         --# global in     Dict;
         --#        in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                Dict,
         --#                                File,
         --#                                LexTokenManager.State,
         --#                                Type_Mark;
         is
            It : Iterator;
         begin
            Write_String (File, "Type ");
            Write_Simple_Name (File => File,
                               Item => RawDict.Get_Type_Symbol (Type_Mark));
            Write_Line (File, " has the following known discriminants:");
            It := First_Known_Discriminant (Protected_Or_Task_Type => Type_Mark);
            if IsNullIterator (It) then
               Write_Line (File, "None;");
            else
               while not IsNullIterator (It) loop
                  Write_String (File, "      ");
                  Write_Simple_Name (File => File,
                                     Item => CurrentSymbol (It));
                  Write_String (File, " which is of type ");
                  Write_Name (File => File,
                              Item => RawDict.Get_Type_Symbol (Get_Type (The_Symbol => CurrentSymbol (It))));
                  if RawDict.GetDiscriminantSetsPriority (CurrentSymbol (It)) then
                     Write_String (File, " and is used to set the priority");
                  end if;
                  Write_Line (File, ";");
                  It := NextSymbol (It);
               end loop;
            end if;
         end Write_Type_Discriminants;

         --------------------------------------------------------------------------------

         procedure Write_Discriminant_Constraint (File      : in SPARK_IO.File_Type;
                                                  Type_Mark : in RawDict.Type_Info_Ref)
         --# global in     Dict;
         --#        in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                Dict,
         --#                                File,
         --#                                LexTokenManager.State,
         --#                                Type_Mark;
         is
            Constraint_It : Iterator;
            Known_It      : Iterator;

            procedure Write_Constraint_Value (File           : in SPARK_IO.File_Type;
                                              The_Constraint : in Symbol)
            --# global in     Dict;
            --#        in     LexTokenManager.State;
            --#        in out SPARK_IO.File_Sys;
            --# derives SPARK_IO.File_Sys from *,
            --#                                Dict,
            --#                                File,
            --#                                LexTokenManager.State,
            --#                                The_Constraint;
            is
               Val : LexTokenManager.Lex_String;
            begin
               Val := RawDict.GetDiscriminantConstraintStaticValue (The_Constraint);
               if LexTokenManager.Lex_String_Case_Insensitive_Compare (Lex_Str1 => Val,
                                                                       Lex_Str2 => LexTokenManager.Null_String) /=
                 LexTokenManager.Str_Eq then
                  Write_Static_Value (File      => File,
                                      Value     => Val,
                                      Type_Mark => Get_Predefined_Integer_Type);
               elsif RawDict.GetDiscriminantConstraintAccessedObject (The_Constraint) /= NullSymbol then
                  -- if no static value then must be access to PO
                  Write_Name (File => File,
                              Item => RawDict.GetDiscriminantConstraintAccessedObject (The_Constraint));
               end if;
            end Write_Constraint_Value;

         begin -- Write_Discriminant_Constraint
            Write_String (File, "Type ");
            Write_Simple_Name (File => File,
                               Item => RawDict.Get_Type_Symbol (Type_Mark));
            Write_Line (File, " has the following discriminant constraints:");
            Constraint_It := First_Discriminant_Constraint (Protected_Or_Task_Subtype => Type_Mark);
            if IsNullIterator (Constraint_It) then
               Write_Line (File, "None;");
            else
               Known_It := First_Known_Discriminant (Protected_Or_Task_Type => RawDict.Get_Type_Parent (Type_Mark => Type_Mark));
               while not IsNullIterator (Constraint_It) and then not IsNullIterator (Known_It) loop
                  Write_String (File, "      ");
                  Write_Simple_Name (File => File,
                                     Item => CurrentSymbol (Known_It));
                  Write_String (File, " => ");
                  Write_Constraint_Value (File           => File,
                                          The_Constraint => CurrentSymbol (Constraint_It));
                  if RawDict.GetDiscriminantSetsPriority (CurrentSymbol (Known_It)) then
                     Write_String (File, " which is used to set the priority");
                  end if;
                  Write_Line (File, ";");
                  Known_It      := NextSymbol (Known_It);
                  Constraint_It := NextSymbol (Constraint_It);
               end loop;
            end if;
         end Write_Discriminant_Constraint;

         --------------------------------------------------------------------------------

         procedure Write_Type_Priority (File      : in SPARK_IO.File_Type;
                                        Type_Mark : in RawDict.Type_Info_Ref)
         --# global in     Dict;
         --#        in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                Dict,
         --#                                File,
         --#                                LexTokenManager.State,
         --#                                Type_Mark;
         is
            Val : LexTokenManager.Lex_String;
         begin
            if Get_Type_Has_Pragma (Protected_Or_Task_Type => Type_Mark,
                                    The_Pragma             => Priority) then
               Write_String (File, "Type ");
               Write_Simple_Name (File => File,
                                  Item => RawDict.Get_Type_Symbol (Type_Mark));
               Write_String (File, " has pragma Priority");
               Val := Get_Type_Pragma_Value (Protected_Or_Task_Type => Type_Mark,
                                             The_Pragma             => Priority);
               if LexTokenManager.Lex_String_Case_Insensitive_Compare (Lex_Str1 => Val,
                                                                       Lex_Str2 => LexTokenManager.Null_String) =
                 LexTokenManager.Str_Eq then
                  Write_Line (File, " of unknown value;");
               else
                  Write_String (File, " of value ");
                  Write_Static_Value (File      => File,
                                      Value     => Val,
                                      Type_Mark => Get_Predefined_Integer_Type);
                  Write_Line (File, ";");
               end if;

            elsif Get_Type_Has_Pragma (Protected_Or_Task_Type => Type_Mark,
                                       The_Pragma             => InterruptPriority) then
               Write_String (File, "Type ");
               Write_Simple_Name (File => File,
                                  Item => RawDict.Get_Type_Symbol (Type_Mark));
               Write_String (File, " has pragma Interrupt_Priority");
               Val := Get_Type_Pragma_Value (Protected_Or_Task_Type => Type_Mark,
                                             The_Pragma             => InterruptPriority);
               if LexTokenManager.Lex_String_Case_Insensitive_Compare (Lex_Str1 => Val,
                                                                       Lex_Str2 => LexTokenManager.Null_String) =
                 LexTokenManager.Str_Eq then
                  Write_Line (File, " of unknown value;");
               else
                  Write_String (File, " of value ");
                  Write_Static_Value (File      => File,
                                      Value     => Val,
                                      Type_Mark => Get_Predefined_Integer_Type);
                  Write_Line (File, ";");
               end if;
            end if;
         end Write_Type_Priority;

         --------------------------------------------------------------------------------

         procedure Write_Priority (File      : in SPARK_IO.File_Type;
                                   Type_Mark : in RawDict.Type_Info_Ref)
         --# global in     Dict;
         --#        in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                Dict,
         --#                                File,
         --#                                LexTokenManager.State,
         --#                                Type_Mark;
         is
         begin
            Write_String (File, "Type ");
            Write_Name (File => File,
                        Item => RawDict.Get_Type_Symbol (Type_Mark));
            Write_String (File, " has a priority of ");
            Write_Static_Value
              (File      => File,
               Value     => Get_Type_Priority (Protected_Or_Task_Type => Type_Mark),
               Type_Mark => Get_Predefined_Integer_Type);
            Write_Line (File, ";");
         end Write_Priority;

         --------------------------------------------------------------------------------

         procedure Write_Suspends_List (File          : in SPARK_IO.File_Type;
                                        The_Task_Type : in RawDict.Type_Info_Ref)
         --# global in     Dict;
         --#        in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                Dict,
         --#                                File,
         --#                                LexTokenManager.State,
         --#                                The_Task_Type;
         is
            It : Iterator;
         begin
            Write_String (File, "Type ");
            Write_Simple_Name (File => File,
                               Item => RawDict.Get_Type_Symbol (The_Task_Type));
            Write_Line (File, " has the following PO or SO names in its Suspend list");
            It := First_Task_Type_Suspends_List_Item (The_Task_Type => The_Task_Type);
            if IsNullIterator (It) then
               Write_Line (File, "None;");
            else
               while not IsNullIterator (It) loop
                  Write_String (File, "      ");
                  Write_Name (File => File,
                              Item => CurrentSymbol (It));
                  Write_Line (File, ";");
                  It := NextSymbol (It);
               end loop;
            end if;
         end Write_Suspends_List;

      begin -- Write_Type_Info
         Write_String (File, "type named ");
         Write_Simple_Name (File => File,
                            Item => RawDict.Get_Type_Symbol (Type_Mark));
         Write_String (File, " is ");

         if RawDict.Get_Type_Extends (Type_Mark => Type_Mark) /= RawDict.Null_Type_Info_Ref then
            Write_String (File, "an extension of type ");
            Write_Name (File => File,
                        Item => RawDict.Get_Type_Symbol (RawDict.Get_Type_Extends (Type_Mark => Type_Mark)));
            Write_String (File, " and is ");
         end if;

         --# assert True;

         if Type_Is_Tagged (Type_Mark => Type_Mark) then
            Write_String (File, "tagged ");
         end if;

         --# assert True;

         if Type_Is_Private (Type_Mark => Type_Mark) then
            if Type_Is_Limited_Private (Type_Mark => Type_Mark) then
               Write_String (File, "limited ");
            end if;
            Write_String (File, "private ");
         end if;

         --# assert True;

         if Is_Unconstrained_Array_Type (Type_Mark => Type_Mark) then
            Write_String (File, "unconstrained ");
         end if;

         --# assert True;

         if Is_Static_Type (Type_Mark => Type_Mark,
                            Scope     => Get_Type_Scope (Type_Mark => Type_Mark)) then
            Write_String (File, "static ");
         end if;
         Write_Discriminant (File      => File,
                             Type_Mark => Type_Mark);

         --# assert True;

         if Is_Proof_Type (Type_Mark => Type_Mark) then
            Write_String (File, "proof ");
         end if;
         Write_Space (File => File);

         --# assert True;

         if Is_Type (Type_Mark => Type_Mark) then
            Write_String (File, "type");
         else
            Write_String (File, "subtype of ");
            Write_Name (File => File,
                        Item => RawDict.Get_Type_Symbol (RawDict.Get_Type_Parent (Type_Mark => Type_Mark)));
         end if;

         --# assert True;

         if Type_Is_Scalar (Type_Mark => Type_Mark) then
            Write_String (File, " range ");
            Write_Bound (File      => File,
                         Bound     => RawDict.Get_Type_Lower (Type_Mark => Type_Mark),
                         Type_Mark => Type_Mark);
            Write_String (File, " .. ");
            Write_Bound (File      => File,
                         Bound     => RawDict.Get_Type_Upper (Type_Mark => Type_Mark),
                         Type_Mark => Type_Mark);
            if LexTokenManager.Lex_String_Case_Insensitive_Compare
              (Lex_Str1 => RawDict.Get_Type_Error_Bound (Type_Mark => Type_Mark),
               Lex_Str2 => LexTokenManager.Null_String) /=
              LexTokenManager.Str_Eq then
               if RawDict.Get_Type_Discriminant (Type_Mark => Type_Mark) = Floating_Point_Type_Item then
                  Write_String (File, " digits ");
               else
                  Write_String (File, " delta ");
               end if;
               Write_Static_Value
                 (File      => File,
                  Value     => RawDict.Get_Type_Error_Bound (Type_Mark => Type_Mark),
                  Type_Mark => Type_Mark);
            end if;
         elsif Type_Is_Array (Type_Mark => Type_Mark) then
            Write_String (File, " of ");
            Write_Name (File => File,
                        Item => RawDict.Get_Type_Symbol (Get_Array_Component (Type_Mark => Type_Mark)));
         elsif Is_Type (Type_Mark => Type_Mark)
           and then RawDict.Get_Type_Discriminant (Type_Mark => Type_Mark) = Protected_Type_Item
           and then RawDict.Get_Protected_Type_Elements_Hidden (The_Protected_Type => Type_Mark) then
            Write_String (File, " with hidden elements ");
         end if;

         --# assert True;

         if RawDict.Get_Type_Discriminant (Type_Mark => Type_Mark) = Access_Type_Item then
            Write_String (File, " implicitly");
         end if;
         Write_String (File, " declared in ");
         Write_Scope (File, Get_Type_Scope (Type_Mark => Type_Mark));
         Write_Line (File, " ;");

         --# assert True;

         if RawDict.Get_Type_Discriminant (Type_Mark => Type_Mark) = Protected_Type_Item then
            if Is_Type (Type_Mark => Type_Mark) then
               Write_Type_Discriminants (File      => File,
                                         Type_Mark => Type_Mark);
               Write_Protected_Refinement (File      => File,
                                           Type_Mark => Type_Mark);
               Write_Type_Priority (File      => File,
                                    Type_Mark => Type_Mark);
            else -- subtype
               Write_Discriminant_Constraint (File      => File,
                                              Type_Mark => Type_Mark);
            end if;
            Write_Priority (File      => File,
                            Type_Mark => Type_Mark);
         end if;

         --# assert True;

         if RawDict.Get_Type_Discriminant (Type_Mark => Type_Mark) = Task_Type_Item then
            if Is_Type (Type_Mark => Type_Mark) then
               Write_Type_Discriminants (File      => File,
                                         Type_Mark => Type_Mark);
               Write_Task_Type_Global_Variables (Abstraction   => IsAbstract,
                                                 File          => File,
                                                 The_Task_Type => Type_Mark);
               Write_Task_Type_Dependency_Clauses (Abstraction   => IsAbstract,
                                                   File          => File,
                                                   The_Task_Type => Type_Mark);
               Write_Suspends_List (File          => File,
                                    The_Task_Type => Type_Mark);
               Write_Type_Priority (File      => File,
                                    Type_Mark => Type_Mark);
               if not RawDict.Get_Task_Type_Signature_Is_Wellformed (The_Task_Type => Type_Mark,
                                                                     Abstraction   => IsAbstract) then
                  Write_Line (File, "Task type signature contains errors");
               end if;
            else -- subtype
               Write_Discriminant_Constraint (File      => File,
                                              Type_Mark => Type_Mark);
            end if;
            Write_Priority (File      => File,
                            Type_Mark => Type_Mark);
         end if;
      end Write_Type_Info;

      --------------------------------------------------------------------------------

      procedure Write_Enumeration_Literals (File      : in SPARK_IO.File_Type;
                                            Type_Mark : in RawDict.Type_Info_Ref)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State,
      --#                                Type_Mark;
      is
         Literal : Iterator;
         Value   : Natural;

         --------------------------------------------------------------------------------

         procedure Write_Enumeration_Literal
           (File                    : in SPARK_IO.File_Type;
            Type_Mark               : in RawDict.Type_Info_Ref;
            The_Enumeration_Value   : in Natural;
            The_Enumeration_Literal : in Symbol)
         --# global in     Dict;
         --#        in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                Dict,
         --#                                File,
         --#                                LexTokenManager.State,
         --#                                The_Enumeration_Literal,
         --#                                The_Enumeration_Value,
         --#                                Type_Mark;
         is
         begin
            Write_String (File, "enumeration literal # ");
            Write_Integer (File, The_Enumeration_Value);
            Write_String (File, " of ");
            Write_Name (File => File,
                        Item => RawDict.Get_Type_Symbol (Type_Mark));
            Write_String (File, " is ");
            Write_Simple_Name (File => File,
                               Item => The_Enumeration_Literal);
            Write_Line (File, " ;");
         end Write_Enumeration_Literal;

      begin -- Write_Enumeration_Literals
         Literal := First_Enumeration_Literal (Type_Mark => Type_Mark);
         Value   := 0;
         while not IsNullIterator (Literal) and then Value < Natural'Last loop
            Write_Enumeration_Literal
              (File                    => File,
               Type_Mark               => Type_Mark,
               The_Enumeration_Value   => Value,
               The_Enumeration_Literal => CurrentSymbol (Literal));
            Literal := NextSymbol (Literal);
            Value   := Value + 1;
         end loop;
      end Write_Enumeration_Literals;

      --------------------------------------------------------------------------------

      procedure Write_Record_Components (File      : in SPARK_IO.File_Type;
                                         Type_Mark : in RawDict.Type_Info_Ref)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State,
      --#                                Type_Mark;
      is
         Component : Iterator;
         Number    : Positive;

         --------------------------------------------------------------------------------

         procedure Write_Record_Component
           (File             : in SPARK_IO.File_Type;
            Type_Mark        : in RawDict.Type_Info_Ref;
            Number           : in Positive;
            Record_Component : in Symbol)
         --# global in     Dict;
         --#        in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                Dict,
         --#                                File,
         --#                                LexTokenManager.State,
         --#                                Number,
         --#                                Record_Component,
         --#                                Type_Mark;
         is
         begin
            Write_String (File, "record component # ");
            Write_Integer (File, Number);
            Write_String (File, " of ");
            Write_Name (File => File,
                        Item => RawDict.Get_Type_Symbol (Type_Mark));
            Write_String (File, " is ");
            Write_Simple_Name (File => File,
                               Item => Record_Component);
            Write_String (File, " of type ");
            Write_Name (File => File,
                        Item => RawDict.Get_Type_Symbol (Get_Type (The_Symbol => Record_Component)));
            Write_Line (File, " ;");
         end Write_Record_Component;

      begin -- Write_Record_Components
         Component := First_Record_Component (Type_Mark => Type_Mark);
         Number    := 1;
         while not IsNullIterator (Component) and then Number < Positive'Last loop
            Write_Record_Component
              (File             => File,
               Type_Mark        => Type_Mark,
               Number           => Number,
               Record_Component => CurrentSymbol (Component));
            Component := NextSymbol (Component);
            Number    := Number + 1;
         end loop;
      end Write_Record_Components;

      --------------------------------------------------------------------------------

      procedure Write_Array_Indices (File      : in SPARK_IO.File_Type;
                                     Type_Mark : in RawDict.Type_Info_Ref)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State,
      --#                                Type_Mark;
      is
         Array_Index : Iterator;
         Dimension   : Positive;

         --------------------------------------------------------------------------------

         procedure Write_Array_Index
           (File       : in SPARK_IO.File_Type;
            Type_Mark  : in RawDict.Type_Info_Ref;
            Dimension  : in Positive;
            Index_Type : in Symbol)
         --# global in     Dict;
         --#        in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                Dict,
         --#                                Dimension,
         --#                                File,
         --#                                Index_Type,
         --#                                LexTokenManager.State,
         --#                                Type_Mark;
         is
         begin
            Write_String (File, "index # ");
            Write_Integer (File, Dimension);
            Write_String (File, " of ");
            Write_Name (File => File,
                        Item => RawDict.Get_Type_Symbol (Type_Mark));
            Write_String (File, " is ");
            Write_Name (File => File,
                        Item => Index_Type);
            Write_Line (File, " ;");
         end Write_Array_Index;

      begin -- Write_Array_Indices
         Array_Index := First_Array_Index (Type_Mark => Type_Mark);
         Dimension   := 1;
         while not IsNullIterator (Array_Index) and then Dimension < Positive'Last loop
            Write_Array_Index
              (File       => File,
               Type_Mark  => Type_Mark,
               Dimension  => Dimension,
               Index_Type => CurrentSymbol (Array_Index));
            Array_Index := NextSymbol (Array_Index);
            Dimension   := Dimension + 1;
         end loop;
      end Write_Array_Indices;

      --------------------------------------------------------------------------------

      procedure Write_Variable (File         : in SPARK_IO.File_Type;
                                The_Variable : in RawDict.Variable_Info_Ref)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State,
      --#                                The_Variable;
      is
      begin
         Write_String (File, "variable named ");
         Write_Simple_Name (File => File,
                            Item => RawDict.Get_Variable_Symbol (The_Variable));
         Write_String (File, " is");
         if RawDict.Get_Variable_Initialized (The_Variable => The_Variable) then
            Write_String (File, " initialized");
         end if;
         if RawDict.Get_Variable_Is_Aliased (The_Variable => The_Variable) then
            Write_String (File, " aliased");
         end if;
         Write_String (File, " variable of ");
         Write_Name (File => File,
                     Item => RawDict.Get_Type_Symbol (RawDict.Get_Variable_Type (The_Variable => The_Variable)));
         Write_String (File, " declared in ");
         Write_Scope (File, Get_Variable_Scope (The_Variable => The_Variable));
         if RawDict.Get_Variable_Has_Pragma_Import (The_Variable => The_Variable) then
            Write_String (File, " and completed by a pragma Import");
         end if;
         Write_Line (File, " ;");
      end Write_Variable;

      --------------------------------------------------------------------------------

      procedure Write_Constant (File         : in SPARK_IO.File_Type;
                                The_Constant : in RawDict.Constant_Info_Ref)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State,
      --#                                The_Constant;
      is
      begin
         Write_String (File, "constant named ");
         Write_Simple_Name (File => File,
                            Item => RawDict.Get_Constant_Symbol (The_Constant));
         Write_String (File, " is ");
         if Constant_Is_Deferred (The_Constant => The_Constant) then
            Write_String (File, "deferred ");
         end if;
         if Is_Static_Constant (The_Constant => The_Constant,
                                Scope        => Get_Constant_Scope (The_Constant => The_Constant)) then
            Write_String (File, "static ");
         end if;
         if Get_Constant_Context (The_Constant => The_Constant) = ProofContext then
            Write_String (File, "proof ");
         end if;
         Write_String (File, "constant of ");
         Write_Name (File => File,
                     Item => RawDict.Get_Type_Symbol (RawDict.Get_Constant_Type (The_Constant => The_Constant)));
         if LexTokenManager.Lex_String_Case_Insensitive_Compare
           (Lex_Str1 => RawDict.Get_Constant_Value (The_Constant => The_Constant),
            Lex_Str2 => LexTokenManager.Null_String) /=
           LexTokenManager.Str_Eq then
            Write_String (File, " value ");
            Write_Static_Value
              (File      => File,
               Value     => RawDict.Get_Constant_Value (The_Constant => The_Constant),
               Type_Mark => RawDict.Get_Constant_Type (The_Constant => The_Constant));
         end if;
         Write_String (File, " declared in ");
         Write_Scope (File, Get_Constant_Scope (The_Constant => The_Constant));
         Write_Line (File, " ;");
      end Write_Constant;

      --------------------------------------------------------------------------------

      procedure Write_Loops (File             : in SPARK_IO.File_Type;
                             Compilation_Unit : in Symbol)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Compilation_Unit,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State;
      is
         The_Loop : Iterator;

         --------------------------------------------------------------------------------

         procedure Write_Loop (File     : in SPARK_IO.File_Type;
                               The_Loop : in Symbol)
         --# global in     Dict;
         --#        in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                Dict,
         --#                                File,
         --#                                LexTokenManager.State,
         --#                                The_Loop;
         is

            --------------------------------------------------------------------------------

            procedure Write_Loop_Info (File     : in SPARK_IO.File_Type;
                                       The_Loop : in Symbol)
            --# global in     Dict;
            --#        in     LexTokenManager.State;
            --#        in out SPARK_IO.File_Sys;
            --# derives SPARK_IO.File_Sys from *,
            --#                                Dict,
            --#                                File,
            --#                                LexTokenManager.State,
            --#                                The_Loop;
            is
            begin
               Write_String (File, "loop named ");
               Write_Simple_Name (File => File,
                                  Item => The_Loop);
               Write_String (File, " declared in ");
               Write_Scope (File, GetScope (The_Loop));
               Write_Line (File, " ;");
            end Write_Loop_Info;

            --------------------------------------------------------------------------------

            procedure Write_Loop_Parameter (File           : in SPARK_IO.File_Type;
                                            Loop_Parameter : in Symbol)
            --# global in     Dict;
            --#        in     LexTokenManager.State;
            --#        in out SPARK_IO.File_Sys;
            --# derives SPARK_IO.File_Sys from *,
            --#                                Dict,
            --#                                File,
            --#                                LexTokenManager.State,
            --#                                Loop_Parameter;
            is
            begin
               Write_String (File, "loop parameter of ");
               Write_Name (File => File,
                           Item => GetRegion (GetScope (Loop_Parameter)));
               Write_String (File, " named ");
               Write_Simple_Name (File => File,
                                  Item => Loop_Parameter);
               Write_String (File, " is of type ");
               Write_Name (File => File,
                           Item => RawDict.Get_Type_Symbol (Get_Type (The_Symbol => Loop_Parameter)));
               Write_Line (File, " ;");
            end Write_Loop_Parameter;

         begin -- Write_Loop
            Write_Loop_Info (File     => File,
                             The_Loop => The_Loop);
            if Is_For_Loop (TheSymbol => The_Loop) then
               Write_Loop_Parameter (File           => File,
                                     Loop_Parameter => RawDict.GetLoopParameter (The_Loop));
            end if;
         end Write_Loop;

      begin -- Write_Loops
         The_Loop := First_Loop (CompilationUnit => Compilation_Unit);
         loop
            exit when IsNullIterator (The_Loop);
            Write_Loop (File     => File,
                        The_Loop => CurrentSymbol (The_Loop));
            The_Loop := NextSymbol (The_Loop);
         end loop;
      end Write_Loops;

      --------------------------------------------------------------------------------

      procedure Write_Protected_Element
        (File               : in SPARK_IO.File_Type;
         The_Protected_Type : in RawDict.Type_Info_Ref;
         The_Element        : in Symbol)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State,
      --#                                The_Element,
      --#                                The_Protected_Type;
      is
      begin
         Write_String (File, "protected element named ");
         Write_Simple_Name (File => File,
                            Item => The_Element);
         Write_String (File, "  of ");
         Write_Name (File => File,
                     Item => RawDict.Get_Type_Symbol (Get_Type (The_Symbol => The_Element)));
         Write_String (File, " declared in ");
         Write_Name (File => File,
                     Item => RawDict.Get_Type_Symbol (The_Protected_Type));
         Write_Line (File, " ;");
      end Write_Protected_Element;

      --------------------------------------------------------------------------------

      procedure Write_Own_Variables (File        : in SPARK_IO.File_Type;
                                     The_Package : in RawDict.Package_Info_Ref)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State,
      --#                                The_Package;
      is

         Own_Variables : Iterator;

         --------------------------------------------------------------------------------

         procedure Write_Own_Variable
           (File         : in SPARK_IO.File_Type;
            The_Package  : in RawDict.Package_Info_Ref;
            The_Variable : in RawDict.Variable_Info_Ref)
         --# global in     Dict;
         --#        in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                Dict,
         --#                                File,
         --#                                LexTokenManager.State,
         --#                                The_Package,
         --#                                The_Variable;
         is
            The_Own_Variable : RawDict.Own_Variable_Info_Ref;
         begin
            The_Own_Variable := RawDict.Get_Variable_Own_Variable (The_Variable => The_Variable);
            case RawDict.Get_Own_Variable_Mode (The_Own_Variable => The_Own_Variable) is
               when DefaultMode =>
                  Write_String (File, "default");
               when InMode =>
                  Write_String (File, "in");
               when OutMode =>
                  Write_String (File, "out");
               when InOutMode =>
                  Write_String (File, "in out");
               when InvalidMode =>
                  Write_String (File, "invalid");
            end case;
            Write_String (File, " mode ");
            if RawDict.Get_Own_Variable_Protected (The_Own_Variable => The_Own_Variable) then
               Write_String (File, "protected ");
            end if;
            Write_String (File, "own variable ");
            Write_Simple_Name (File => File,
                               Item => RawDict.Get_Variable_Symbol (The_Variable));
            if RawDict.Get_Own_Variable_Typed (The_Own_Variable => The_Own_Variable) then
               Write_String (File, " of type ");
               Write_Name
                 (File => File,
                  Item => RawDict.Get_Type_Symbol (RawDict.Get_Variable_Type (The_Variable => The_Variable)));
            end if;
            Write_String (File, " is owned ");
            if RawDict.Get_Own_Variable_Initialized (The_Own_Variable => The_Own_Variable) then
               Write_String (File, "and initialized ");
            end if;
            Write_String (File, "by ");
            Write_Name (File => File,
                        Item => RawDict.Get_Package_Symbol (The_Package));
            Write_Line (File, " ;");
         end Write_Own_Variable;

      begin -- Write_Own_Variables
         Own_Variables := First_Own_Variable (The_Package => The_Package);
         loop
            exit when IsNullIterator (Own_Variables);
            Write_Own_Variable
              (File         => File,
               The_Package  => The_Package,
               The_Variable => RawDict.Get_Variable_Info_Ref (CurrentSymbol (Own_Variables)));
            Own_Variables := NextSymbol (Own_Variables);
         end loop;
      end Write_Own_Variables;

      --------------------------------------------------------------------------------

      procedure Write_Embedded_Packages (File        : in SPARK_IO.File_Type;
                                         The_Package : in RawDict.Package_Info_Ref)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State,
      --#                                The_Package;
      is
         Packages : Iterator;
      begin
         Packages := First_Embedded_Package_In_Package (The_Package => The_Package);
         loop
            exit when IsNullIterator (Packages);
            Write_Package_Info (File        => File,
                                The_Package => RawDict.Get_Package_Info_Ref (CurrentSymbol (Packages)));
            Packages := NextSymbol (Packages);
         end loop;
      end Write_Embedded_Packages;

      --------------------------------------------------------------------------------

      procedure Write_Abstract_Own_Variables (File        : in SPARK_IO.File_Type;
                                              The_Package : in RawDict.Package_Info_Ref)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State,
      --#                                The_Package;
      is

         Abstract_Own_Variables : Iterator;

         --------------------------------------------------------------------------------

         procedure Write_Abstract_Own_Variable (File         : in SPARK_IO.File_Type;
                                                The_Variable : in RawDict.Variable_Info_Ref)
         --# global in     Dict;
         --#        in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                Dict,
         --#                                File,
         --#                                LexTokenManager.State,
         --#                                The_Variable;
         is
            Constituents : Iterator;

            --------------------------------------------------------------------------------

            procedure Write_Constituent
              (File         : in SPARK_IO.File_Type;
               The_Variable : in RawDict.Variable_Info_Ref;
               Constituent  : in RawDict.Variable_Info_Ref)
            --# global in     Dict;
            --#        in     LexTokenManager.State;
            --#        in out SPARK_IO.File_Sys;
            --# derives SPARK_IO.File_Sys from *,
            --#                                Constituent,
            --#                                Dict,
            --#                                File,
            --#                                LexTokenManager.State,
            --#                                The_Variable;
            is
            begin
               case Get_Constituent_Mode (The_Variable => Constituent) is
                  when DefaultMode =>
                     Write_String (File, "default");
                  when InMode =>
                     Write_String (File, "in");
                  when OutMode =>
                     Write_String (File, "out");
                  when InOutMode =>
                     Write_String (File, "in out");
                  when InvalidMode =>
                     Write_String (File, "invalid");
               end case;
               Write_String (File, " mode ");
               Write_String (File, "constituent of ");
               Write_Name (File => File,
                           Item => RawDict.Get_Variable_Symbol (The_Variable));
               Write_String (File, " is ");
               Write_Simple_Name (File => File,
                                  Item => RawDict.Get_Variable_Symbol (Constituent));
               if Get_Owner (The_Variable => The_Variable) /= Get_Owner (The_Variable => Constituent) then
                  Write_String (File, " declared in ");
                  Write_Name (File => File,
                              Item => Get_Owner (The_Variable => Constituent));
               end if;
               Write_Line (File, " ;");
            end Write_Constituent;

         begin -- Write_Abstract_Own_Variable
            Constituents := First_Constituent (The_Variable => The_Variable);
            loop
               exit when IsNullIterator (Constituents);
               Write_Constituent
                 (File         => File,
                  The_Variable => The_Variable,
                  Constituent  => RawDict.Get_Variable_Info_Ref (CurrentSymbol (Constituents)));
               Constituents := NextSymbol (Constituents);
            end loop;
         end Write_Abstract_Own_Variable;

      begin -- Write_Abstract_Own_Variables
         Abstract_Own_Variables := First_Abstract_Own_Variable (The_Package => The_Package);
         loop
            exit when IsNullIterator (Abstract_Own_Variables);
            Write_Abstract_Own_Variable
              (File         => File,
               The_Variable => RawDict.Get_Variable_Info_Ref (CurrentSymbol (Abstract_Own_Variables)));
            Abstract_Own_Variables := NextSymbol (Abstract_Own_Variables);
         end loop;
      end Write_Abstract_Own_Variables;

      --------------------------------------------------------------------------------

      procedure Write_Subprogram_Bodies (File  : in SPARK_IO.File_Type;
                                         Scope : in Scopes)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State,
      --#                                Scope;
      is
         Declarative_Items : Iterator;
         Declarative_Item  : Symbol;
      begin
         Declarative_Items := First_Declarative_Item (Scope => Scope);
         loop
            exit when IsNullIterator (Declarative_Items);
            Declarative_Item := CurrentSymbol (Declarative_Items);
            if Is_Subprogram (Declarative_Item) then
               Write_Subprogram_Global_Variables
                 (Abstraction    => IsRefined,
                  File           => File,
                  The_Subprogram => RawDict.Get_Subprogram_Info_Ref (Declarative_Item));
               if RawDict.GetSymbolDiscriminant (Declarative_Item) = Subprogram_Symbol
                 and then Is_Procedure (The_Subprogram => RawDict.Get_Subprogram_Info_Ref (Item => Declarative_Item)) then
                  Write_Subprogram_Dependency_Clauses
                    (Abstraction    => IsRefined,
                     File           => File,
                     The_Subprogram => RawDict.Get_Subprogram_Info_Ref (Declarative_Item));
               end if;
            end if;
            Declarative_Items := NextSymbol (Declarative_Items);
         end loop;
      end Write_Subprogram_Bodies;

      --------------------------------------------------------------------------------

      procedure Write_Subprogram_Info (File           : in SPARK_IO.File_Type;
                                       The_Subprogram : in RawDict.Subprogram_Info_Ref)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State,
      --#                                The_Subprogram;
      is
      begin
         Write_String (File, "subprogram named ");
         Write_Simple_Name (File => File,
                            Item => RawDict.Get_Subprogram_Symbol (The_Subprogram));
         Write_String (File, " is ");
         if RawDict.Get_Subprogram_Generic_Unit (The_Subprogram => The_Subprogram) /= RawDict.Null_Generic_Unit_Info_Ref then
            Write_String (File, "generic ");
         end if;
         if RawDict.Get_Subprogram_Is_Entry (The_Subprogram => The_Subprogram) then
            Write_String (File, "entry");
         elsif Is_Procedure (The_Subprogram => The_Subprogram) then
            Write_String (File, "procedure");
         else
            if IsProofFunction (RawDict.Get_Subprogram_Symbol (The_Subprogram)) then
               Write_String (File, "proof ");
            end if;
            Write_String (File, "function of ");
            Write_Name
              (File => File,
               Item => RawDict.Get_Type_Symbol (RawDict.Get_Subprogram_Return_Type (The_Subprogram => The_Subprogram)));
         end if;
         -- don't try and print declaration region for library-level units
         if not (RawDict.GetSymbolDiscriminant (RawDict.Get_Subprogram_Symbol (The_Subprogram)) = Subprogram_Symbol
                   and then Is_Main_Program
                   (The_Subprogram => RawDict.Get_Subprogram_Info_Ref (Item => RawDict.Get_Subprogram_Symbol (The_Subprogram))))
           and then The_Subprogram /= Get_The_Partition
           and then RawDict.Get_Subprogram_Generic_Unit (The_Subprogram => The_Subprogram) = RawDict.Null_Generic_Unit_Info_Ref
         then
            Write_String (File, " declared in ");
            Write_Scope (File, Get_Subprogram_Scope (The_Subprogram => The_Subprogram));
         end if;
         if RawDict.Get_Subprogram_Instantiation_Of (The_Subprogram => The_Subprogram) /= RawDict.Null_Subprogram_Info_Ref then
            Write_String (File, " and which is an instantiation of ");
            Write_Name
              (File => File,
               Item => RawDict.Get_Subprogram_Symbol (RawDict.Get_Subprogram_Instantiation_Of (The_Subprogram => The_Subprogram)));
         end if;
         if RawDict.Get_Subprogram_Is_Interrupt_Handler (The_Subprogram => The_Subprogram) then
            Write_String (File, " and is an interrupt handler");
         end if;
         if The_Subprogram = Get_The_Partition then
            Write_String (File, " and is the partition table of the whole program");
         end if;
         Write_Line (File, " ;");
      end Write_Subprogram_Info;

      --------------------------------------------------------------------------------

      procedure Write_Subprogram_Parameters
        (File                        : in SPARK_IO.File_Type;
         The_Subprogram              : in RawDict.Subprogram_Info_Ref;
         The_Implicit_Proof_Function : in Symbol)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State,
      --#                                The_Implicit_Proof_Function,
      --#                                The_Subprogram;
      is
         Parameter : Iterator;
         Number    : Positive;

         --------------------------------------------------------------------------------

         procedure Write_Subprogram_Parameter
           (File                     : in SPARK_IO.File_Type;
            The_Subprogram           : in RawDict.Subprogram_Info_Ref;
            Number                   : in Positive;
            The_Subprogram_Parameter : in RawDict.Subprogram_Parameter_Info_Ref)
         --# global in     Dict;
         --#        in     LexTokenManager.State;
         --#        in out SPARK_IO.File_Sys;
         --# derives SPARK_IO.File_Sys from *,
         --#                                Dict,
         --#                                File,
         --#                                LexTokenManager.State,
         --#                                Number,
         --#                                The_Subprogram,
         --#                                The_Subprogram_Parameter;
         is
         begin
            Write_String (File, "subprogram parameter # ");
            Write_Integer (File, Number);
            Write_String (File, " of ");
            Write_Name (File => File,
                        Item => RawDict.Get_Subprogram_Symbol (The_Subprogram));
            Write_String (File, " is ");
            Write_Simple_Name (File => File,
                               Item => RawDict.Get_Subprogram_Parameter_Symbol (The_Subprogram_Parameter));
            Write_String (File, " which is ");
            case RawDict.Get_Subprogram_Parameter_Mode (The_Subprogram_Parameter => The_Subprogram_Parameter) is
               when DefaultMode =>
                  Write_String (File, "default");
               when InMode =>
                  Write_String (File, "in");
               when OutMode =>
                  Write_String (File, "out");
               when InOutMode =>
                  Write_String (File, "in out");
               when InvalidMode =>
                  Write_String (File, "invalid");
            end case;
            Write_String (File, " parameter of type ");
            Write_Name
              (File => File,
               Item => RawDict.Get_Type_Symbol
                 (RawDict.Get_Subprogram_Parameter_Type (The_Subprogram_Parameter => The_Subprogram_Parameter)));
            Write_Line (File, " ;");
         end Write_Subprogram_Parameter;

      begin -- Write_Subprogram_Parameters
         if The_Implicit_Proof_Function = NullSymbol then
            Parameter := First_Ada_Subprogram_Parameter (The_Subprogram => The_Subprogram);
         else
            Parameter := First_Implicit_Proof_Function_Parameter (ProofFunction => The_Implicit_Proof_Function);
         end if;
         Number := 1;
         while not IsNullIterator (Parameter) and then Number < Positive'Last loop
            Write_Subprogram_Parameter
              (File                     => File,
               The_Subprogram           => The_Subprogram,
               Number                   => Number,
               The_Subprogram_Parameter => RawDict.Get_Subprogram_Parameter_Info_Ref (CurrentSymbol (Parameter)));
            Parameter := NextSymbol (Parameter);
            Number    := Number + 1;
         end loop;
      end Write_Subprogram_Parameters;

      --------------------------------------------------------------------------------

      procedure Write_Library_Unit (File : in SPARK_IO.File_Type;
                                    Unit : in Symbol)
      --# global in     Dict;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Dict,
      --#                                File,
      --#                                LexTokenManager.State,
      --#                                Unit;
      is
         --# hide Write_Library_Unit;

         --------------------------------------------------------------------------------

         procedure Write_Subprogram
           (File                        : in SPARK_IO.File_Type;
            The_Subprogram              : in RawDict.Subprogram_Info_Ref;
            The_Implicit_Proof_Function : in Symbol);

         --------------------------------------------------------------------------------

         procedure Write_Package (File        : in SPARK_IO.File_Type;
                                  The_Package : in RawDict.Package_Info_Ref);

         --------------------------------------------------------------------------------

         procedure Write_Library_Package (File        : in SPARK_IO.File_Type;
                                          The_Package : in RawDict.Package_Info_Ref) is
         begin
            if Get_Root_Package (The_Package => The_Package) /= Get_Predefined_Package_Ada then
               Write_Package_Info (File        => File,
                                   The_Package => The_Package);
               Write_Package (File        => File,
                              The_Package => The_Package);
            end if;
         end Write_Library_Package;

         --------------------------------------------------------------------------------

         procedure Write_Declarative_Items (File  : in SPARK_IO.File_Type;
                                            Scope : in Scopes) is

            Declarative_Items : Iterator;
            Declarative_Item  : Symbol;

            --------------------------------------------------------------------------------

            procedure Write_Declarative_Item (File : in SPARK_IO.File_Type;
                                              Item : in Symbol) is

               procedure Write_Type (File      : in SPARK_IO.File_Type;
                                     Type_Mark : in RawDict.Type_Info_Ref) is

                  procedure Write_Protected_Declarations
                    (File               : in SPARK_IO.File_Type;
                     The_Protected_Type : in RawDict.Type_Info_Ref) is
                     It : Iterator;
                  begin
                     It := First_Protected_Type_Visible_Subprogram (The_Protected_Type => The_Protected_Type);
                     while not IsNullIterator (It) loop
                        Write_Subprogram
                          (File                        => File,
                           The_Subprogram              => RawDict.Get_Subprogram_Info_Ref (CurrentSymbol (It)),
                           The_Implicit_Proof_Function => NullSymbol);
                        It := NextSymbol (It);
                     end loop;
                     It := First_Protected_Element (The_Protected_Type => The_Protected_Type);
                     while not IsNullIterator (It) loop
                        Write_Protected_Element
                          (File               => File,
                           The_Protected_Type => The_Protected_Type,
                           The_Element        => CurrentSymbol (It));
                        It := NextSymbol (It);
                     end loop;
                  end Write_Protected_Declarations;

               begin -- Write_Type
                  Write_Type_Info (File      => File,
                                   Type_Mark => Type_Mark);
                  case RawDict.Get_Type_Discriminant (Type_Mark => Type_Mark) is
                     when Enumeration_Type_Item =>
                        if Is_Type (Type_Mark => Type_Mark) then
                           Write_Enumeration_Literals (File      => File,
                                                       Type_Mark => Type_Mark);
                        end if;
                     when Record_Type_Item =>
                        Write_Record_Components (File      => File,
                                                 Type_Mark => Type_Mark);
                     when Array_Type_Item =>
                        Write_Array_Indices (File      => File,
                                             Type_Mark => Type_Mark);
                     when Protected_Type_Item =>
                        if Is_Type (Type_Mark => Type_Mark) then
                           Write_Protected_Declarations (File               => File,
                                                         The_Protected_Type => Type_Mark);
                        end if;
                     when others =>
                        null;
                  end case;
               end Write_Type;

            begin -- Write_Declarative_Item
               case RawDict.GetSymbolDiscriminant (Item) is
                  when Type_Symbol =>
                     Write_Type (File      => File,
                                 Type_Mark => RawDict.Get_Type_Info_Ref (Item => Item));
                  when Variable_Symbol =>
                     Write_Variable (File         => File,
                                     The_Variable => RawDict.Get_Variable_Info_Ref (Item => Item));
                  when Constant_Symbol =>
                     Write_Constant (File         => File,
                                     The_Constant => RawDict.Get_Constant_Info_Ref (Item => Item));
                  when Subprogram_Symbol =>
                     Write_Subprogram
                       (File                        => File,
                        The_Subprogram              => RawDict.Get_Subprogram_Info_Ref (Item => Item),
                        The_Implicit_Proof_Function => NullSymbol);
                  when Package_Symbol =>
                     Write_Package (File        => File,
                                    The_Package => RawDict.Get_Package_Info_Ref (Item => Item));
                  when others => -- non-exec code
                     SystemErrors.Fatal_Error
                       (Sys_Err => SystemErrors.Invalid_Symbol_Table,
                        Msg     => "in Dictionary.Write_Declarative_Item");
               end case;
            end Write_Declarative_Item;

         begin -- Write_Declarative_Items
            Declarative_Items := First_Declarative_Item (Scope => Scope);
            loop
               exit when IsNullIterator (Declarative_Items);
               Declarative_Item := CurrentSymbol (Declarative_Items);
               if RawDict.GetSymbolDiscriminant (Declarative_Item) = Type_Symbol
                 and then Is_Type (Type_Mark => RawDict.Get_Type_Info_Ref (Item => Declarative_Item))
                 and then Type_Is_Private (Type_Mark => RawDict.Get_Type_Info_Ref (Item => Declarative_Item))
                 and then (Get_Visibility (Scope => Scope) = Local or else Get_Visibility (Scope => Scope) = Privat) then
                  null;
               elsif (Get_Visibility (Scope => Scope) = Local or else Get_Visibility (Scope => Scope) = Privat)
                 and then RawDict.GetSymbolDiscriminant (Declarative_Item) = Constant_Symbol
                 and then Constant_Is_Deferred (The_Constant => RawDict.Get_Constant_Info_Ref (Item => Declarative_Item)) then
                  null;
               else
                  Write_Declarative_Item (File => File,
                                          Item => Declarative_Item);
               end if;
               Declarative_Items := NextSymbol (Declarative_Items);
            end loop;
         end Write_Declarative_Items;

         --------------------------------------------------------------------------------

         procedure Write_Package (File        : in SPARK_IO.File_Type;
                                  The_Package : in RawDict.Package_Info_Ref) is

            procedure Write_Owned_Packages (File        : in SPARK_IO.File_Type;
                                            The_Package : in RawDict.Package_Info_Ref) is
               Packages : Iterator;
            begin
               Packages := First_Owned_Package (The_Package => The_Package);
               loop
                  exit when IsNullIterator (Packages);
                  Write_Package_Info (File        => File,
                                      The_Package => RawDict.Get_Package_Info_Ref (CurrentSymbol (Packages)));
                  Write_Package (File        => File,
                                 The_Package => RawDict.Get_Package_Info_Ref (CurrentSymbol (Packages)));
                  Packages := NextSymbol (Packages);
               end loop;
            end Write_Owned_Packages;

         begin -- Write_Package
            Write_With_References
              (File  => File,
               Scope => Set_Visibility (The_Visibility => Visible,
                                        The_Unit       => RawDict.Get_Package_Symbol (The_Package)));
            Write_With_References
              (File  => File,
               Scope => Set_Visibility (The_Visibility => Local,
                                        The_Unit       => RawDict.Get_Package_Symbol (The_Package)));
            Write_Inherits_References (File             => File,
                                       Compilation_Unit => RawDict.Get_Package_Symbol (The_Package));
            Write_Own_Variables (File        => File,
                                 The_Package => The_Package);
            Write_Embedded_Packages (File        => File,
                                     The_Package => The_Package);
            Write_Abstract_Own_Variables (File        => File,
                                          The_Package => The_Package);
            Write_Declarative_Items
              (File  => File,
               Scope => Set_Visibility (The_Visibility => Visible,
                                        The_Unit       => RawDict.Get_Package_Symbol (The_Package)));
            Write_Declarative_Items
              (File  => File,
               Scope => Set_Visibility (The_Visibility => Privat,
                                        The_Unit       => RawDict.Get_Package_Symbol (The_Package)));
            Write_Declarative_Items
              (File  => File,
               Scope => Set_Visibility (The_Visibility => Local,
                                        The_Unit       => RawDict.Get_Package_Symbol (The_Package)));
            Write_Subprogram_Bodies
              (File  => File,
               Scope => Set_Visibility (The_Visibility => Visible,
                                        The_Unit       => RawDict.Get_Package_Symbol (The_Package)));
            Write_Subprogram_Bodies
              (File  => File,
               Scope => Set_Visibility (The_Visibility => Local,
                                        The_Unit       => RawDict.Get_Package_Symbol (The_Package)));
            Write_Loops (File             => File,
                         Compilation_Unit => RawDict.Get_Package_Symbol (The_Package));
            Write_Owned_Packages (File        => File,
                                  The_Package => The_Package);
         end Write_Package;

         --------------------------------------------------------------------------------

         procedure Write_Subprogram
           (File                        : in SPARK_IO.File_Type;
            The_Subprogram              : in RawDict.Subprogram_Info_Ref;
            The_Implicit_Proof_Function : in Symbol) is
         begin
            Write_Subprogram_Info (File           => File,
                                   The_Subprogram => The_Subprogram);
            Write_With_References
              (File  => File,
               Scope => Set_Visibility (The_Visibility => Local,
                                        The_Unit       => RawDict.Get_Subprogram_Symbol (The_Subprogram)));
            Write_Inherits_References (File             => File,
                                       Compilation_Unit => RawDict.Get_Subprogram_Symbol (The_Subprogram));
            Write_Subprogram_Parameters
              (File                        => File,
               The_Subprogram              => The_Subprogram,
               The_Implicit_Proof_Function => The_Implicit_Proof_Function);
            Write_Subprogram_Global_Variables (Abstraction    => IsAbstract,
                                               File           => File,
                                               The_Subprogram => The_Subprogram);
            if Is_Procedure (The_Subprogram => The_Subprogram) then
               Write_Subprogram_Dependency_Clauses (Abstraction    => IsAbstract,
                                                    File           => File,
                                                    The_Subprogram => The_Subprogram);
            end if;
            if RawDict.Get_Subprogram_Generic_Unit (The_Subprogram => The_Subprogram) /= RawDict.Null_Generic_Unit_Info_Ref then
               Write_Generic_Formal_Parameters (File        => File,
                                                The_Generic => The_Subprogram);
            end if;
            Write_Declarative_Items
              (File  => File,
               Scope => Set_Visibility (The_Visibility => Local,
                                        The_Unit       => RawDict.Get_Subprogram_Symbol (The_Subprogram)));
            Write_Loops (File             => File,
                         Compilation_Unit => RawDict.Get_Subprogram_Symbol (The_Subprogram));
         end Write_Subprogram;

      begin -- Write_Library_Unit
         case RawDict.GetSymbolDiscriminant (Unit) is
            when Package_Symbol =>
               Write_Library_Package (File        => File,
                                      The_Package => RawDict.Get_Package_Info_Ref (Item => Unit));
            when Subprogram_Symbol =>
               Write_Subprogram
                 (File                        => File,
                  The_Subprogram              => RawDict.Get_Subprogram_Info_Ref (Item => Unit),
                  The_Implicit_Proof_Function => NullSymbol);
            when ImplicitProofFunctionSymbol =>
               Write_Subprogram
                 (File                        => File,
                  The_Subprogram              => RawDict.GetImplicitProofFunctionAdaFunction (Unit),
                  The_Implicit_Proof_Function => Unit);
            when others =>
               null;
         end case;
      end Write_Library_Unit;

   begin -- Write_Library_Units
      Library_Units := First_Library_Unit;
      loop
         exit when IsNullIterator (Library_Units);
         Write_Library_Unit (File => File,
                             Unit => CurrentSymbol (Library_Units));
         Library_Units := NextSymbol (Library_Units);
      end loop;
      -- If we are in Ravencar mode, then a pseudo procedure called main_program will have been
      -- created as a place to store partition-wide flow anno data.  We print these details out now.
      if Get_The_Partition /= RawDict.Null_Subprogram_Info_Ref then
         Write_Library_Unit (File => File,
                             Unit => RawDict.Get_Subprogram_Symbol (Get_The_Partition));
      end if;
   end Write_Library_Units;

   --------------------------------------------------------------------------------

   procedure Append_Viewer_Specific_Info (File : in SPARK_IO.File_Type)
   --# global in out Dict;
   --#        in out SPARK_IO.File_Sys;
   --# derives Dict              from * &
   --#         SPARK_IO.File_Sys from *,
   --#                                Dict,
   --#                                File;
   is
      MaxLineLength : constant Positive := 512;
      subtype LineIndex is Positive range 1 .. MaxLineLength;
      subtype Lines is String (LineIndex);
      Line          : Lines;
      Length        : Natural;
      File_Status   : SPARK_IO.File_Status;
      TemporaryFile : SPARK_IO.File_Type;
   begin
      TemporaryFile := Dict.TemporaryFile;
      SPARK_IO.Reset (TemporaryFile, SPARK_IO.In_File, File_Status);
      if File_Status = SPARK_IO.Ok then
         loop
            exit when SPARK_IO.End_Of_File (TemporaryFile);
            SPARK_IO.Get_Line (TemporaryFile, Line, Length);
            SPARK_IO.Put_Line (File, Line, Length);
         end loop;
      end if;
      Dict.TemporaryFile := TemporaryFile;
   end Append_Viewer_Specific_Info;

begin -- Write
   Local_File_Name := FileSystem.Case_Of_Files_For_Create (E_Str => File_Name);
   E_Strings.Create (File         => File,
                     Name_Of_File => Local_File_Name,
                     Form_Of_File => "",
                     Status       => Status);

   if Status = SPARK_IO.Ok then
      -- File := SPARK_IO.Standard_Output; -- useful debug statement
      Write_Library_Units (File => File);
      Append_Viewer_Specific_Info (File => File);
      --# accept Flow, 10, File, "Expected ineffective assignment";
      SPARK_IO.Close (File, Status);
      --# end accept;
   end if;
end Write;
