-------------------------------------------------------------------------------
-- (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 Casing;
with CommandLineData;
with ConfigFile;
with ContextManager;
with ContextManager.Ops;
with Dictionary;
with Error_Types;
with ErrorHandler;
with E_Strings;
with File_Utils;
with FileSystem;
with IndexManager;
with LexTokenLists;
with LexTokenManager;
with MetaFile;
with RequiredUnits;
with ScreenEcho;
with Sem;
with SLI;
with SPARK_IO;
with SparkHTML;
with SparkLex;
with SPParser;
with Statistics;
with STree;
with VCG;
with XMLReport;

use type CommandLineData.Flow_Analysis_Options;
use type CommandLineData.Rule_Generation_Policies;
use type ContextManager.FileDescriptors;
use type ContextManager.FileStatus;
use type ContextManager.UnitDescriptors;
use type ContextManager.UnitStatus;
use type ContextManager.UnitTypes;
use type ErrorHandler.Error_Level;
use type LexTokenManager.Str_Comp_Result;
use type SPARK_IO.File_Status;
use type SPARK_IO.File_Type;

package body MainLoop is

   procedure Print_Filename (File  : in SPARK_IO.File_Type;
                             Name  : in E_Strings.T;
                             Plain : in Boolean)
   --  all-from-all derives for data flow analysis only
   --# global in out SPARK_IO.File_Sys;
   --# derives SPARK_IO.File_Sys from *,
   --#                                File,
   --#                                Name,
   --#                                Plain;
   is
      Stat      : FileSystem.Typ_File_Spec_Status;
      Full_Name : E_Strings.T;
   begin
      if Plain then
         Full_Name := FileSystem.Just_File (Fn  => Name,
                                            Ext => True);
      else
         --# accept F, 10, Stat, "Stat not used";
         FileSystem.Find_Full_File_Name (File_Spec      => Name,
                                         File_Status    => Stat,
                                         Full_File_Name => Full_Name);
         --# end accept;
      end if;

      if File = SPARK_IO.Standard_Output then
         ScreenEcho.Put_ExaminerString (Full_Name);
      else
         E_Strings.Put_String (File  => File,
                               E_Str => Full_Name);
      end if;
      --# accept F, 33, Stat, "Stat not used";
   end Print_Filename;

   procedure Initialise_Processing
   --# global in     CommandLineData.Content;
   --#        in out LexTokenManager.State;
   --#        in out SparkHTML.Generate_HTML;
   --#        in out SPARK_IO.File_Sys;
   --#           out Dictionary.Dict;
   --#           out SparkHTML.HTML_Work_Dir;
   --#           out SparkHTML.SPARK_Work_Dir;
   --#           out SparkLex.Curr_Line;
   --#           out XMLReport.State;
   --# derives Dictionary.Dict,
   --#         SparkHTML.HTML_Work_Dir,
   --#         SparkHTML.SPARK_Work_Dir,
   --#         SPARK_IO.File_Sys        from CommandLineData.Content,
   --#                                       LexTokenManager.State,
   --#                                       SPARK_IO.File_Sys &
   --#         LexTokenManager.State    from *,
   --#                                       CommandLineData.Content &
   --#         SparkHTML.Generate_HTML  from *,
   --#                                       CommandLineData.Content,
   --#                                       LexTokenManager.State,
   --#                                       SPARK_IO.File_Sys &
   --#         SparkLex.Curr_Line,
   --#         XMLReport.State          from ;
   is
   begin
      SparkLex.Clear_Line_Context;
      LexTokenManager.Initialise_String_Table;
      Dictionary.Initialize (CommandLineData.Content.Write_Dict);
      --# accept F, 602, SparkHTML.HTML_Work_Dir, SparkHTML.HTML_Work_Dir, "Only used in HTML selected" &
      --#        F, 602, SparkHTML.SPARK_Work_Dir, SparkHTML.SPARK_Work_Dir, "Only used in HTML selected";
      if CommandLineData.Content.HTML then
         SparkHTML.Init_SPARK_HTML;
      end if;
      XMLReport.Init;
   end Initialise_Processing;

   procedure Create_File_Context (Source_Filename : in     E_Strings.T;
                                  File_Descriptor :    out ContextManager.FileDescriptors)
   --# global in out ContextManager.Ops.File_Heap;
   --#        in out LexTokenManager.State;
   --# derives ContextManager.Ops.File_Heap,
   --#         LexTokenManager.State        from *,
   --#                                           LexTokenManager.State,
   --#                                           Source_Filename &
   --#         File_Descriptor              from ContextManager.Ops.File_Heap;
   is
      FD2                        : ContextManager.FileDescriptors;
      Lex_String_Source_Filename : LexTokenManager.Lex_String;
   begin
      ContextManager.Ops.CreateFileDescriptor (FD2);
      LexTokenManager.Insert_Examiner_String (Str     => Source_Filename,
                                              Lex_Str => Lex_String_Source_Filename);
      ContextManager.Ops.SetSourceFileName (FD2, Lex_String_Source_Filename);
      ContextManager.Ops.SetFileStatus (FD2, ContextManager.FileCreated);
      File_Descriptor := FD2;
   end Create_File_Context;

   procedure Prepare_Next_Argument_File
     (The_Filename     : in     E_Strings.T;
      Do_Listing       : in     Boolean;
      The_Listing_Name : in     E_Strings.T;
      Do_VCG           : in out Boolean;
      File_Descriptor  :    out ContextManager.FileDescriptors)
   --# global in out CommandLineData.Content;
   --#        in out ContextManager.Ops.File_Heap;
   --#        in out LexTokenManager.State;
   --# derives CommandLineData.Content      from *,
   --#                                           Do_VCG &
   --#         ContextManager.Ops.File_Heap from *,
   --#                                           Do_Listing,
   --#                                           LexTokenManager.State,
   --#                                           The_Filename,
   --#                                           The_Listing_Name &
   --#         Do_VCG                       from CommandLineData.Content &
   --#         File_Descriptor              from ContextManager.Ops.File_Heap &
   --#         LexTokenManager.State        from *,
   --#                                           The_Filename;
   is
      FD2           : ContextManager.FileDescriptors;
      Global_Do_VCG : Boolean;
   begin
      Create_File_Context (Source_Filename => The_Filename,
                           File_Descriptor => FD2);
      if Do_Listing then
         ContextManager.Ops.SetListingReq (FD2, True);
         ContextManager.Ops.SetListingFileName (FD2, The_Listing_Name);
      end if;
      File_Descriptor := FD2;
      Global_Do_VCG   := CommandLineData.Content.VCG;
      if Do_VCG then
         --# accept W, 169, CommandLineData.Content.VCG, "Direct updates OK here";
         CommandLineData.Content.VCG := True;
         --# end accept;
      end if;
      Do_VCG := Global_Do_VCG;
   end Prepare_Next_Argument_File;

   procedure Show_End_Of_File (To_File : in SPARK_IO.File_Type)
   --# global in out SPARK_IO.File_Sys;
   --# derives SPARK_IO.File_Sys from *,
   --#                                To_File;
   is
   begin

      SPARK_IO.New_Line (To_File, 2);
      SPARK_IO.Put_Line (To_File, "--End of file--------------------------------------------------", 0);
   end Show_End_Of_File;

   --  Important warnings or notes appear in makefile mode.
   procedure Echo_Warning_Or_Note (About_File : in E_Strings.T;
                                   Msg        : in String;
                                   Important  : in Boolean)
   --# global in     CommandLineData.Content;
   --#        in out SPARK_IO.File_Sys;
   --# derives SPARK_IO.File_Sys from *,
   --#                                About_File,
   --#                                CommandLineData.Content,
   --#                                Important,
   --#                                Msg;
   is
   begin
      if CommandLineData.Content.Echo and (Important or not CommandLineData.Content.Makefile_Mode) then
         if CommandLineData.Content.Brief then
            -- Echo the first filename from the command-line.  If it starts with an '@'
            -- then chop it off, so the file is recognized by the IDE.
            if E_Strings.Get_Length (E_Str => About_File) >= 2
              and then E_Strings.Get_Element (E_Str => About_File,
                                              Pos   => 1) = '@' then

               ScreenEcho.Put_ExaminerString (E_Strings.Section (About_File, 2, E_Strings.Get_Length (E_Str => About_File) - 1));
            else
               ScreenEcho.Put_ExaminerString (About_File);
            end if;

            ScreenEcho.Put_String (":1:1: ");
            ScreenEcho.Put_Line (Msg);
         else
            ScreenEcho.New_Line (1);
            ScreenEcho.Put_Line (Msg);
         end if;
      end if;
   end Echo_Warning_Or_Note;

   procedure Output_Dictionary_File
   --# global in     CommandLineData.Content;
   --#        in     LexTokenManager.State;
   --#        in out Dictionary.Dict;
   --#        in out SPARK_IO.File_Sys;
   --# derives Dictionary.Dict   from *,
   --#                                CommandLineData.Content,
   --#                                SPARK_IO.File_Sys &
   --#         SPARK_IO.File_Sys from *,
   --#                                CommandLineData.Content,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State;
   is
      Dict_Message   : constant String := "Generating dictionary file";
      Status         : SPARK_IO.File_Status;
      Dict_File_Name : E_Strings.T;
   begin
      if CommandLineData.Content.Write_Dict then
         if CommandLineData.Content.Echo and not CommandLineData.Content.Brief then
            ScreenEcho.Echo (E_Strings.Copy_String (Str => Dict_Message));
         end if;
         if CommandLineData.Content.Output_Directory then
            Dict_File_Name := CommandLineData.Content.Output_Directory_Name;
            E_Strings.Append_Examiner_String (E_Str1 => Dict_File_Name,
                                              E_Str2 => FileSystem.Directory_Separator);
            E_Strings.Append_Examiner_String (E_Str1 => Dict_File_Name,
                                              E_Str2 => CommandLineData.Content.Dict_File_Name);
         else
            Dict_File_Name := CommandLineData.Content.Dict_File_Name;
         end if;
         Dictionary.Write (Dict_File_Name, Status);
         if Status /= SPARK_IO.Ok then
            ScreenEcho.Put_Line ("Error writing dictionary file: ");
            Print_Filename (File  => SPARK_IO.Standard_Output,
                            Name  => Dict_File_Name,
                            Plain => False);
            ScreenEcho.New_Line (1);
         end if;
      end if;
   end Output_Dictionary_File;

   procedure Print_Lex_Token_List (File : in SPARK_IO.File_Type;
                                   List : in LexTokenLists.Lists)
   --# global in     LexTokenManager.State;
   --#        in out SPARK_IO.File_Sys;
   --# derives SPARK_IO.File_Sys from *,
   --#                                File,
   --#                                LexTokenManager.State,
   --#                                List;
   is
   begin
      if LexTokenLists.Get_Length (List => List) = 0 then
         SPARK_IO.Put_String (File, "Unexpected Empty Lextoken List", 0);
      else
         LexTokenLists.Print_List (File => File,
                                   List => List);
      end if;
   end Print_Lex_Token_List;

   -- Following hidden trace routines enabled by -debug=u -----------------------------------
   procedure Trace (Msg : String)
   --# derives null from Msg;
   is
      --# hide Trace;
   begin
      if CommandLineData.Content.Debug.Units then
         SPARK_IO.Put_Line (SPARK_IO.Standard_Output, Msg, 0);
      end if;
   end Trace;

   procedure Trace_Unit (List  : in LexTokenLists.Lists;
                         Types : in ContextManager.UnitTypeSets)
   --# derives null from List,
   --#                   Types;
   is
      --# hide Trace_Unit;
      FirstType : Boolean := True;
   begin
      if CommandLineData.Content.Debug.Units then
         SPARK_IO.Put_String (SPARK_IO.Standard_Output, "   unit name: ", 0);
         Print_Lex_Token_List (File => SPARK_IO.Standard_Output,
                               List => List);
         SPARK_IO.Put_String (SPARK_IO.Standard_Output, " which is {", 0);
         for I in ContextManager.UnitTypes loop
            if Types (I) then
               if not FirstType then
                  SPARK_IO.Put_String (SPARK_IO.Standard_Output, ", ", 0);
               end if;
               SPARK_IO.Put_String (SPARK_IO.Standard_Output, ContextManager.UnitTypes'Image (I), 0);
               FirstType := False;
            end if;
         end loop;
         SPARK_IO.Put_Line (SPARK_IO.Standard_Output, "}", 0);
      end if;
   end Trace_Unit;
   -----------------------------------------------------------------------------------

   function Get_Unit_Name (List : in LexTokenLists.Lists) return E_Strings.T
   --# global in LexTokenManager.State;
   is
      Return_String : E_Strings.T;
   begin
      if LexTokenLists.Get_Length (List => List) = 0 then
         Return_String := E_Strings.Copy_String (Str => "Unexpected Empty LexToken List");
      else
         Return_String := LexTokenLists.Token_List_To_String (Token_List => List);
      end if;
      return Return_String;
   end Get_Unit_Name;

   procedure Print_Unit_Type (File      : in SPARK_IO.File_Type;
                              Unit_Type : in ContextManager.UnitTypes)
   --# global in out SPARK_IO.File_Sys;
   --# derives SPARK_IO.File_Sys from *,
   --#                                File,
   --#                                Unit_Type;
   is
   begin
      case Unit_Type is
         when ContextManager.MainProgram =>
            SPARK_IO.Put_String (File, "main program", 0);
         when ContextManager.PackageSpecification =>
            SPARK_IO.Put_String (File, "package specification", 0);
         when ContextManager.PackageBody =>
            SPARK_IO.Put_String (File, "package body", 0);
         when ContextManager.SubUnit =>
            SPARK_IO.Put_String (File, "subunit", 0);
         when ContextManager.GenericSubprogramDeclaration =>
            SPARK_IO.Put_String (File, "generic subprogram declaration", 0);
         when ContextManager.GenericSubprogramBody =>
            SPARK_IO.Put_String (File, "generic subprogram body", 0);
         when ContextManager.InterUnitPragma =>
            null;
         when ContextManager.InvalidUnit =>
            null;
      end case;
   end Print_Unit_Type;

   function Get_Unit_Type (Unit_Type : in ContextManager.UnitTypes) return E_Strings.T is
      Return_Str : E_Strings.T;
   begin
      case Unit_Type is
         when ContextManager.MainProgram =>
            Return_Str := E_Strings.Copy_String (Str => "main program");
         when ContextManager.PackageSpecification =>
            Return_Str := E_Strings.Copy_String (Str => "package specification");
         when ContextManager.PackageBody =>
            Return_Str := E_Strings.Copy_String (Str => "package body");
         when ContextManager.SubUnit =>
            Return_Str := E_Strings.Copy_String (Str => "subunit");
         when ContextManager.GenericSubprogramDeclaration =>
            Return_Str := E_Strings.Copy_String (Str => "generic subprogram declaration");
         when ContextManager.GenericSubprogramBody =>
            Return_Str := E_Strings.Copy_String (Str => "generic subprogram body");
         when ContextManager.InterUnitPragma =>
            Return_Str := E_Strings.Copy_String (Str => "InterUnitPragma");
         when ContextManager.InvalidUnit =>
            Return_Str := E_Strings.Copy_String (Str => "InvalidUnit");
      end case;
      return Return_Str;
   end Get_Unit_Type;

   procedure Print_Reason (File        : in SPARK_IO.File_Type;
                           Unit_Status : in ContextManager.UnitStatus)
   --# global in out SPARK_IO.File_Sys;
   --# derives SPARK_IO.File_Sys from *,
   --#                                File,
   --#                                Unit_Status;
   is
   begin
      case Unit_Status is
         when ContextManager.NoIndexFile =>
            SPARK_IO.Put_String (File, "No index file specified.", 0);
         when ContextManager.NotInIndexFile =>
            SPARK_IO.Put_String (File, "Omitted from index file.", 0);
         when ContextManager.CannotOpenFile =>
            SPARK_IO.Put_String (File, "Cannot open source file specified in index file.", 0);
         when ContextManager.UnableToLocate =>
            SPARK_IO.Put_String (File, "Declaration not found in source code.", 0);
         when others =>
            null;  -- should not happen because only called when unit is not found
      end case;
   end Print_Reason;

   -- This function is not currently used but will be required when
   -- XMLReport is updated to contain the reason
   function Get_Reason (Unit_Status : in ContextManager.UnitStatus) return E_Strings.T is
      Return_Str : E_Strings.T;
   begin
      case Unit_Status is
         when ContextManager.NoIndexFile =>
            Return_Str := E_Strings.Copy_String (Str => "No index file specified.");
         when ContextManager.NotInIndexFile =>
            Return_Str := E_Strings.Copy_String (Str => "Omitted from index file.");
         when ContextManager.CannotOpenFile =>
            Return_Str := E_Strings.Copy_String (Str => "Cannot open source file specified in index file.");
         when ContextManager.UnableToLocate =>
            Return_Str := E_Strings.Copy_String (Str => "Declaration not found in source code.");
         when others =>
            Return_Str := E_Strings.Empty_String;  -- only called when unit is not found
      end case;
      return Return_Str;
   end Get_Reason;

   procedure Append_To_Report_File
     (Report_File     : in SPARK_IO.File_Type;
      Purpose         : in Error_Types.ConversionRequestSource;
      File_Descriptor : in ContextManager.FileDescriptors)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in out ContextManager.Ops.File_Heap;
   --#        in out ErrorHandler.Error_Context;
   --#        in out SPARK_IO.File_Sys;
   --#        in out XMLReport.State;
   --# derives ContextManager.Ops.File_Heap,
   --#         ErrorHandler.Error_Context,
   --#         SPARK_IO.File_Sys,
   --#         XMLReport.State              from CommandLineData.Content,
   --#                                           ContextManager.Ops.File_Heap,
   --#                                           ContextManager.Ops.Unit_Heap,
   --#                                           Dictionary.Dict,
   --#                                           ErrorHandler.Error_Context,
   --#                                           File_Descriptor,
   --#                                           LexTokenManager.State,
   --#                                           Purpose,
   --#                                           Report_File,
   --#                                           SPARK_IO.File_Sys,
   --#                                           XMLReport.State;
   is

      Error_Context : ErrorHandler.Error_Contexts;

      function Get_Source_Filename (File_Descriptor : in ContextManager.FileDescriptors) return E_Strings.T
      --# global in ContextManager.Ops.File_Heap;
      --#        in LexTokenManager.State;
      is
      begin
         return LexTokenManager.Lex_String_To_String (Lex_Str => ContextManager.Ops.GetSourceFileName (File_Descriptor));
      end Get_Source_Filename;

      procedure Print_Source_Filename (Report_File     : in SPARK_IO.File_Type;
                                       File_Descriptor : in ContextManager.FileDescriptors)
      --# global in     CommandLineData.Content;
      --#        in     ContextManager.Ops.File_Heap;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                CommandLineData.Content,
      --#                                ContextManager.Ops.File_Heap,
      --#                                File_Descriptor,
      --#                                LexTokenManager.State,
      --#                                Report_File;
      is
      begin
         SPARK_IO.Put_String (Report_File, "Source Filename:   ", 0);
         Print_Filename
           (File  => Report_File,
            Name  => LexTokenManager.Lex_String_To_String (Lex_Str => ContextManager.Ops.GetSourceFileName (File_Descriptor)),
            Plain => CommandLineData.Content.Plain_Output);
         SPARK_IO.New_Line (Report_File, 1);
      end Print_Source_Filename;

      procedure Print_Listing_Filename
        (Report_File     : in SPARK_IO.File_Type;
         File_Descriptor : in ContextManager.FileDescriptors)
      --# global in     CommandLineData.Content;
      --#        in     ContextManager.Ops.File_Heap;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                CommandLineData.Content,
      --#                                ContextManager.Ops.File_Heap,
      --#                                File_Descriptor,
      --#                                Report_File;
      is
         Filename : E_Strings.T;
      begin
         if ContextManager.Ops.ListingReqt (File_Descriptor) then
            SPARK_IO.Put_String (Report_File, "Listing Filename:  ", 0);
            ContextManager.Ops.GetListingFileName (File_Descriptor, Filename);
            CommandLineData.Normalize_File_Name_To_Output_Directory (F => Filename);
            Print_Filename (File  => Report_File,
                            Name  => Filename,
                            Plain => CommandLineData.Content.Plain_Output);
            SPARK_IO.New_Line (Report_File, 1);
         else
            SPARK_IO.Put_Line (Report_File, "No Listing File", 0);
         end if;
      end Print_Listing_Filename;

      procedure Print_Unit_Status (File            : in SPARK_IO.File_Type;
                                   Unit_Descriptor : in ContextManager.UnitDescriptors)
      --# global in     ContextManager.Ops.Unit_Heap;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                ContextManager.Ops.Unit_Heap,
      --#                                File,
      --#                                Unit_Descriptor;
      is
      begin
         case ContextManager.Ops.Get_Unit_Status (Unit_Descriptor => Unit_Descriptor) is
            when ContextManager.NoUnitEntry =>
               null;
            when ContextManager.UnitCreated =>
               null;
            when ContextManager.UnitParsed | ContextManager.UnitDeferred =>
               SPARK_IO.Put_String (File, "Unit has been parsed only, any errors are listed below.", 0);
            when ContextManager.UnitAnalysed =>
               SPARK_IO.Put_String (File, "Unit has been analysed, any errors are listed below.", 0);
            when ContextManager.NoIndexFile =>
               SPARK_IO.Put_String (File, "Unit required but not found in source file and no index file has been specified.", 0);
            when ContextManager.NotInIndexFile =>
               SPARK_IO.Put_String (File, "Unit required but not found in source file or in index file.", 0);
            when ContextManager.CannotOpenFile =>
               SPARK_IO.Put_String (File, "Source file for required Unit given in index file cannot be opened.", 0);
            when ContextManager.UnableToLocate =>
               SPARK_IO.Put_String (File, "Unit required but not found.", 0);
         end case;
      end Print_Unit_Status;

      function Get_Unit_Status (Unit_Descriptor : in ContextManager.UnitDescriptors) return E_Strings.T
      --# global in ContextManager.Ops.Unit_Heap;
      is
         Return_String : E_Strings.T;
      begin
         Return_String := E_Strings.Empty_String;
         case ContextManager.Ops.Get_Unit_Status (Unit_Descriptor => Unit_Descriptor) is
            when ContextManager.NoUnitEntry =>
               null;
            when ContextManager.UnitCreated =>
               null;
            when ContextManager.UnitParsed | ContextManager.UnitDeferred =>
               Return_String := E_Strings.Copy_String (Str => "parsed");
            when ContextManager.UnitAnalysed =>
               Return_String := E_Strings.Copy_String (Str => "analysed");
            when ContextManager.NoIndexFile =>
               Return_String := E_Strings.Copy_String (Str => "not found and no index file specified");
            when ContextManager.NotInIndexFile =>
               Return_String := E_Strings.Copy_String (Str => "not found in source file or in index file.");
            when ContextManager.CannotOpenFile =>
               Return_String := E_Strings.Copy_String (Str => "unit source file name given in index file cannot be opened.");
            when ContextManager.UnableToLocate =>
               Return_String := E_Strings.Copy_String (Str => "not found");
         end case;
         return Return_String;
      end Get_Unit_Status;

      procedure Output_Unit_List (Report_File     : in SPARK_IO.File_Type;
                                  File_Descriptor : in ContextManager.FileDescriptors)
      --# global in     CommandLineData.Content;
      --#        in     ContextManager.Ops.Unit_Heap;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --#        in out XMLReport.State;
      --# derives SPARK_IO.File_Sys from *,
      --#                                CommandLineData.Content,
      --#                                ContextManager.Ops.Unit_Heap,
      --#                                File_Descriptor,
      --#                                LexTokenManager.State,
      --#                                Report_File,
      --#                                XMLReport.State &
      --#         XMLReport.State   from *,
      --#                                CommandLineData.Content,
      --#                                ContextManager.Ops.Unit_Heap,
      --#                                File_Descriptor,
      --#                                LexTokenManager.State;
      is
         Unit_Descriptor : ContextManager.UnitDescriptors;
         Unit_Name       : LexTokenLists.Lists;
         Unit_Type       : ContextManager.UnitTypes;
         Unit_Output     : Boolean;
      begin
         Unit_Output     := False;
         Unit_Descriptor := ContextManager.Ops.FirstUnitDescriptor;
         if CommandLineData.Content.XML then
            XMLReport.Start_Section (Section => XMLReport.S_Units_In_File,
                                     Report  => Report_File);
         end if;
         loop
            exit when Unit_Descriptor = ContextManager.NullUnit;
            if (ContextManager.Ops.Get_Unit_Status (Unit_Descriptor => Unit_Descriptor) /= ContextManager.NoUnitEntry)
              and then File_Descriptor = ContextManager.Ops.Get_File_Descriptor (Unit_Descriptor => Unit_Descriptor) then
               ContextManager.Ops.GetUnitName (Unit_Descriptor, Unit_Name, Unit_Type);
               if LexTokenLists.Get_Length (List => Unit_Name) /= 0 then
                  --# accept F, 41, "Stable expression expected";
                  if CommandLineData.Content.XML then
                     XMLReport.Ada_Unit
                       (Name        => Get_Unit_Name (List => Unit_Name),
                        Typ         => Get_Unit_Type (Unit_Type => Unit_Type),
                        Unit_Status => Get_Unit_Status (Unit_Descriptor => Unit_Descriptor),
                        Report      => Report_File);
                     Unit_Output := True;
                  else
                     Unit_Output := True;
                     SPARK_IO.Put_String (Report_File, "   Unit name:  ", 0);
                     Print_Lex_Token_List (File => Report_File,
                                           List => Unit_Name);
                     SPARK_IO.New_Line (Report_File, 1);
                     SPARK_IO.Put_String (Report_File, "   Unit type:  ", 0);
                     Print_Unit_Type (File      => Report_File,
                                      Unit_Type => Unit_Type);
                     SPARK_IO.New_Line (Report_File, 1);
                     SPARK_IO.Put_String (Report_File, "   ", 0);
                     Print_Unit_Status (File            => Report_File,
                                        Unit_Descriptor => Unit_Descriptor);
                     SPARK_IO.New_Line (Report_File, 2);
                  end if;
                  --# end accept;
               end if;
            end if;
            Unit_Descriptor := ContextManager.Ops.NextUnitDescriptor (Unit_Descriptor);
         end loop;
         if CommandLineData.Content.XML then
            XMLReport.End_Section (Section => XMLReport.S_Units_In_File,
                                   Report  => Report_File);
         end if;
         if not Unit_Output then
            SPARK_IO.Put_Line (Report_File, "***     No units in file", 0);
            SPARK_IO.New_Line (Report_File, 2);
         end if;
      end Output_Unit_List;

   begin -- Append_To_Report_File
      SPARK_IO.New_Line (Report_File, 1);
      if not CommandLineData.Content.XML then
         Print_Source_Filename (Report_File     => Report_File,
                                File_Descriptor => File_Descriptor);
      end if;
      if ContextManager.Ops.GetFileStatus (File_Descriptor) = ContextManager.UnableToOpen then
         if CommandLineData.Content.XML then
            XMLReport.Start_File
              (Plain_Output => CommandLineData.Content.Plain_Output,
               F_Name       => Get_Source_Filename (File_Descriptor => File_Descriptor),
               Report       => Report_File);
            Output_Unit_List (Report_File     => Report_File,
                              File_Descriptor => File_Descriptor);
            XMLReport.End_File (Report => Report_File);
         else
            SPARK_IO.New_Line (Report_File, 1);
            Output_Unit_List (Report_File     => Report_File,
                              File_Descriptor => File_Descriptor);
            SPARK_IO.Put_Line (Report_File, "***     Unable to open source file", 0);
         end if;
      else
         if CommandLineData.Content.XML then
            XMLReport.Start_File
              (Plain_Output => CommandLineData.Content.Plain_Output,
               F_Name       => Get_Source_Filename (File_Descriptor => File_Descriptor),
               Report       => Report_File);
            Output_Unit_List (Report_File     => Report_File,
                              File_Descriptor => File_Descriptor);
            ContextManager.Ops.GetErrorContext (File_Descriptor, Error_Context);
            ErrorHandler.Set_Error_Context (Context => Error_Context);
            ErrorHandler.AppendErrors (Report_File, Purpose);
            ErrorHandler.Get_Error_Context (Context => Error_Context);
            ContextManager.Ops.SetErrorContext (File_Descriptor, Error_Context);
            XMLReport.End_File (Report => Report_File);
         else
            Print_Listing_Filename (Report_File     => Report_File,
                                    File_Descriptor => File_Descriptor);
            SPARK_IO.New_Line (Report_File, 1);
            Output_Unit_List (Report_File     => Report_File,
                              File_Descriptor => File_Descriptor);
            ContextManager.Ops.GetErrorContext (File_Descriptor, Error_Context);
            ErrorHandler.Set_Error_Context (Context => Error_Context);
            ErrorHandler.AppendErrors (Report_File, Purpose);
            ErrorHandler.Get_Error_Context (Context => Error_Context);
            ContextManager.Ops.SetErrorContext (File_Descriptor, Error_Context);
         end if;
      end if;
   end Append_To_Report_File;

   procedure Output_Report_File (Report_File_Error_List : in out SPARK_IO.File_Type)
   --# global in     CommandLineData.Content;
   --#        in     ConfigFile.State;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     Dictionary.Dict;
   --#        in     IndexManager.State;
   --#        in     SparkHTML.HTML_Work_Dir;
   --#        in     SparkHTML.SPARK_Work_Dir;
   --#        in     Statistics.TableUsage;
   --#        in out ContextManager.Ops.File_Heap;
   --#        in out ErrorHandler.Error_Context;
   --#        in out LexTokenManager.State;
   --#        in out SparkHTML.Generate_HTML;
   --#        in out SPARK_IO.File_Sys;
   --#        in out XMLReport.State;
   --# derives ContextManager.Ops.File_Heap,
   --#         ErrorHandler.Error_Context,
   --#         XMLReport.State              from CommandLineData.Content,
   --#                                           ConfigFile.State,
   --#                                           ContextManager.Ops.File_Heap,
   --#                                           ContextManager.Ops.Unit_Heap,
   --#                                           Dictionary.Dict,
   --#                                           ErrorHandler.Error_Context,
   --#                                           IndexManager.State,
   --#                                           LexTokenManager.State,
   --#                                           SPARK_IO.File_Sys,
   --#                                           XMLReport.State &
   --#         LexTokenManager.State        from *,
   --#                                           CommandLineData.Content,
   --#                                           ErrorHandler.Error_Context,
   --#                                           IndexManager.State,
   --#                                           SPARK_IO.File_Sys,
   --#                                           XMLReport.State &
   --#         Report_File_Error_List       from *,
   --#                                           CommandLineData.Content,
   --#                                           SPARK_IO.File_Sys &
   --#         SparkHTML.Generate_HTML      from *,
   --#                                           CommandLineData.Content,
   --#                                           ConfigFile.State,
   --#                                           ContextManager.Ops.File_Heap,
   --#                                           ContextManager.Ops.Unit_Heap,
   --#                                           Dictionary.Dict,
   --#                                           ErrorHandler.Error_Context,
   --#                                           IndexManager.State,
   --#                                           LexTokenManager.State,
   --#                                           Report_File_Error_List,
   --#                                           SPARK_IO.File_Sys,
   --#                                           Statistics.TableUsage,
   --#                                           XMLReport.State &
   --#         SPARK_IO.File_Sys            from *,
   --#                                           CommandLineData.Content,
   --#                                           ConfigFile.State,
   --#                                           ContextManager.Ops.File_Heap,
   --#                                           ContextManager.Ops.Unit_Heap,
   --#                                           Dictionary.Dict,
   --#                                           ErrorHandler.Error_Context,
   --#                                           IndexManager.State,
   --#                                           LexTokenManager.State,
   --#                                           Report_File_Error_List,
   --#                                           SparkHTML.Generate_HTML,
   --#                                           SparkHTML.HTML_Work_Dir,
   --#                                           SparkHTML.SPARK_Work_Dir,
   --#                                           Statistics.TableUsage,
   --#                                           XMLReport.State;
   is
      Report_File : SPARK_IO.File_Type;
      OK          : Boolean;

      Report_Message : constant String := "Generating report file";

      procedure Create_Report_File (Report_File : out SPARK_IO.File_Type;
                                    OK          : out Boolean)
      --# global in     CommandLineData.Content;
      --#        in out SPARK_IO.File_Sys;
      --#        in out XMLReport.State;
      --# derives OK,
      --#         Report_File       from CommandLineData.Content,
      --#                                SPARK_IO.File_Sys &
      --#         SPARK_IO.File_Sys,
      --#         XMLReport.State   from CommandLineData.Content,
      --#                                SPARK_IO.File_Sys,
      --#                                XMLReport.State;
      is
         Local_File : SPARK_IO.File_Type;
         Status     : SPARK_IO.File_Status;
         Filename   : E_Strings.T;
      begin
         OK         := True;
         Local_File := SPARK_IO.Null_File;

         Filename := CommandLineData.Content.Report_File_Name;
         CommandLineData.Normalize_File_Name_To_Output_Directory (F => Filename);
         Filename := FileSystem.Case_Of_Files_For_Create (E_Str => Filename);

         E_Strings.Create (File         => Local_File,
                           Name_Of_File => Filename,
                           Form_Of_File => "",
                           Status       => Status);
         if Status = SPARK_IO.Ok then
            if CommandLineData.Content.XML then
               XMLReport.Start_Section (Section => XMLReport.S_Report,
                                        Report  => Local_File);
               XMLReport.Start_Section (Section => XMLReport.S_Prologue,
                                        Report  => Local_File);
            else
               File_Utils.Print_A_Header
                 (File        => Local_File,
                  Header_Line => "Report of SPARK Examination",
                  File_Type   => File_Utils.Other_File);
            end if;
         else
            OK := False;
            ScreenEcho.Put_Line ("Unable to open report file: ");
            Print_Filename (File  => SPARK_IO.Standard_Output,
                            Name  => Filename,
                            Plain => CommandLineData.Content.Plain_Output);
            ScreenEcho.New_Line (1);
         end if;
         Report_File := Local_File;
      end Create_Report_File;

      procedure Close_Report_File (Report_File : in out SPARK_IO.File_Type)
      --# global in out SPARK_IO.File_Sys;
      --# derives Report_File,
      --#         SPARK_IO.File_Sys from *,
      --#                                Report_File;
      is
         Status : SPARK_IO.File_Status;
      begin
         --# accept F, 10, Status, "Status not used here" &
         --#        F, 33, Status, "Status not used here";
         SPARK_IO.Close (Report_File, Status);
      end Close_Report_File;

      procedure Output_File_List (Report_File : in SPARK_IO.File_Type)
      --# global in     CommandLineData.Content;
      --#        in     ContextManager.Ops.File_Heap;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                CommandLineData.Content,
      --#                                ContextManager.Ops.File_Heap,
      --#                                LexTokenManager.State,
      --#                                Report_File;
      is
         File_Descriptor : ContextManager.FileDescriptors;
      begin
         if not CommandLineData.Content.XML then
            File_Descriptor := ContextManager.Ops.FirstFileDescriptor;
            SPARK_IO.New_Line (Report_File, 2);
            if File_Descriptor = ContextManager.NullFile then
               SPARK_IO.Put_Line (Report_File, "No source files used", 0);
            else
               if not CommandLineData.Content.XML then
                  SPARK_IO.Put_Line (Report_File, "Source Filename(s) used were:", 0);
               end if;
               loop
                  exit when File_Descriptor = ContextManager.NullFile;
                  SPARK_IO.Put_String (Report_File, "   ", 0);
                  Print_Filename
                    (File  => Report_File,
                     Name  => LexTokenManager.Lex_String_To_String (Lex_Str => ContextManager.Ops.GetSourceFileName (File_Descriptor)),
                     Plain => CommandLineData.Content.Plain_Output);
                  SPARK_IO.New_Line (Report_File, 1);
                  File_Descriptor := ContextManager.Ops.NextFileDescriptor (File_Descriptor);
               end loop;
            end if;
         end if;
      end Output_File_List;

      procedure Output_Error_List (Report_File            : in     SPARK_IO.File_Type;
                                   Report_File_Error_List : in out SPARK_IO.File_Type)
      --# global in     CommandLineData.Content;
      --#        in     ContextManager.Ops.Unit_Heap;
      --#        in     Dictionary.Dict;
      --#        in     LexTokenManager.State;
      --#        in out ContextManager.Ops.File_Heap;
      --#        in out ErrorHandler.Error_Context;
      --#        in out SPARK_IO.File_Sys;
      --#        in out XMLReport.State;
      --# derives ContextManager.Ops.File_Heap,
      --#         ErrorHandler.Error_Context,
      --#         XMLReport.State              from CommandLineData.Content,
      --#                                           ContextManager.Ops.File_Heap,
      --#                                           ContextManager.Ops.Unit_Heap,
      --#                                           Dictionary.Dict,
      --#                                           ErrorHandler.Error_Context,
      --#                                           LexTokenManager.State,
      --#                                           Report_File,
      --#                                           SPARK_IO.File_Sys,
      --#                                           XMLReport.State &
      --#         Report_File_Error_List       from * &
      --#         SPARK_IO.File_Sys            from *,
      --#                                           CommandLineData.Content,
      --#                                           ContextManager.Ops.File_Heap,
      --#                                           ContextManager.Ops.Unit_Heap,
      --#                                           Dictionary.Dict,
      --#                                           ErrorHandler.Error_Context,
      --#                                           LexTokenManager.State,
      --#                                           Report_File,
      --#                                           Report_File_Error_List,
      --#                                           XMLReport.State;
      is
         subtype Line_Index is Positive range 1 .. 512;
         subtype Lines is String (Line_Index);
         Current_Line     : Lines;
         Stop             : Natural;
         Unused1, Unused2 : SPARK_IO.File_Status;
         File_Descriptor  : ContextManager.FileDescriptors;
      begin
         --# accept F, 10, Unused1, "Not required" &
         --#        F, 33, Unused1, "Not required" &
         --#        F, 10, Unused2, "Not required" &
         --#        F, 33, Unused2, "Not required";
         if CommandLineData.Content.XML then
            XMLReport.Start_Section (Section => XMLReport.S_Results,
                                     Report  => Report_File);
         end if;

         --first output errors associated with files picked up from index mechanism
         File_Descriptor := ContextManager.Ops.FirstFileDescriptor;
         loop
            exit when File_Descriptor = ContextManager.NullFile;
            if not ContextManager.Ops.ErrorsReported (File_Descriptor) then
               Append_To_Report_File
                 (Report_File     => Report_File,
                  Purpose         => Error_Types.ForReportIndexedFiles,
                  File_Descriptor => File_Descriptor);
            end if;
            File_Descriptor := ContextManager.Ops.NextFileDescriptor (File_Descriptor);
         end loop;

         --then append errors from files on command line/meta files
         SPARK_IO.Reset (Report_File_Error_List, SPARK_IO.In_File, Unused1);
         while not SPARK_IO.End_Of_File (Report_File_Error_List) loop
            SPARK_IO.Get_Line (Report_File_Error_List,
                               --to get
                               Current_Line, Stop);
            if Stop = 0 then
               SPARK_IO.New_Line (Report_File, 1);
            else
               SPARK_IO.Put_Line (Report_File, Current_Line, Stop);
            end if;
         end loop;
         SPARK_IO.Close (Report_File_Error_List, Unused2);
      end Output_Error_List;

      procedure Output_Units_Required_But_Not_Found (Report_File : in SPARK_IO.File_Type)
      --# global in     CommandLineData.Content;
      --#        in     ContextManager.Ops.Unit_Heap;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --#        in out XMLReport.State;
      --# derives SPARK_IO.File_Sys from *,
      --#                                CommandLineData.Content,
      --#                                ContextManager.Ops.Unit_Heap,
      --#                                LexTokenManager.State,
      --#                                Report_File,
      --#                                XMLReport.State &
      --#         XMLReport.State   from *,
      --#                                CommandLineData.Content,
      --#                                ContextManager.Ops.Unit_Heap,
      --#                                LexTokenManager.State;
      is
         Status_Col : constant Positive := 50;
         Reason_Col : constant Positive := 72;

         Unit_Descriptor : ContextManager.UnitDescriptors;
         Unit_Name       : LexTokenLists.Lists;
         Unit_Type       : ContextManager.UnitTypes;

         First_Time : Boolean;
      begin
         if CommandLineData.Content.XML then
            XMLReport.Start_Section (Section => XMLReport.S_Units_Not_Found,
                                     Report  => Report_File);

            Unit_Descriptor := ContextManager.Ops.FirstUnitDescriptor;

            loop
               exit when Unit_Descriptor = ContextManager.NullUnit;
               if ContextManager.Ops.Get_Unit_Status (Unit_Descriptor => Unit_Descriptor) in ContextManager.UnitNotFound then
                  ContextManager.Ops.GetUnitName (Unit_Descriptor, Unit_Name, Unit_Type);

                  -- XMLReport needs to be updated to include the reason
                  XMLReport.Ada_Unit
                    (Name        => LexTokenLists.Token_List_To_String (Token_List => Unit_Name),
                     Typ         => Get_Unit_Type (Unit_Type => Unit_Type),
                     Unit_Status => Get_Reason (Unit_Status => ContextManager.Ops.Get_Unit_Status (Unit_Descriptor => Unit_Descriptor)),
                     Report      => Report_File);

               end if;
               Unit_Descriptor := ContextManager.Ops.NextUnitDescriptor (Unit_Descriptor);
            end loop;

            XMLReport.End_Section (Section => XMLReport.S_Units_Not_Found,
                                   Report  => Report_File);

         else
            First_Time      := True;
            Unit_Descriptor := ContextManager.Ops.FirstUnitDescriptor;
            loop
               exit when Unit_Descriptor = ContextManager.NullUnit;
               if ContextManager.Ops.Get_Unit_Status (Unit_Descriptor => Unit_Descriptor) in ContextManager.UnitNotFound then
                  SPARK_IO.New_Line (Report_File, 1);
                  if First_Time then
                     SPARK_IO.New_Line (Report_File, 1);
                     SPARK_IO.Put_Line (Report_File, "The following were required during analysis but could not be located:", 0);
                     SPARK_IO.New_Line (Report_File, 1);
                     SPARK_IO.Put_String (Report_File, "   Unit name", 0);
                     SPARK_IO.Set_Col (Report_File, Status_Col);
                     SPARK_IO.Put_String (Report_File, "Unit type", 0);
                     SPARK_IO.Set_Col (Report_File, Reason_Col);
                     SPARK_IO.Put_Line (Report_File, "Reason", 0);
                     SPARK_IO.Put_String (Report_File, "   ---------", 0);
                     SPARK_IO.Set_Col (Report_File, Status_Col);
                     SPARK_IO.Put_String (Report_File, "---------", 0);
                     SPARK_IO.Set_Col (Report_File, Reason_Col);
                     SPARK_IO.Put_Line (Report_File, "------", 0);
                     First_Time := False;
                  end if;
                  ContextManager.Ops.GetUnitName (Unit_Descriptor, Unit_Name, Unit_Type);
                  SPARK_IO.Put_String (Report_File, "   ", 0);
                  Print_Lex_Token_List (File => Report_File,
                                        List => Unit_Name);
                  SPARK_IO.Set_Col (Report_File, Status_Col);
                  Print_Unit_Type (File      => Report_File,
                                   Unit_Type => Unit_Type);
                  SPARK_IO.Set_Col (Report_File, Reason_Col);
                  Print_Reason
                    (File        => Report_File,
                     Unit_Status => ContextManager.Ops.Get_Unit_Status (Unit_Descriptor => Unit_Descriptor));
               end if;
               Unit_Descriptor := ContextManager.Ops.NextUnitDescriptor (Unit_Descriptor);
            end loop;
            SPARK_IO.New_Line (Report_File, 2);
         end if;
      end Output_Units_Required_But_Not_Found;

      procedure Output_Units_With_Cyclic_Requirements (Report_File : in SPARK_IO.File_Type)
      --# global in     CommandLineData.Content;
      --#        in     ContextManager.Ops.Unit_Heap;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --#        in out XMLReport.State;
      --# derives SPARK_IO.File_Sys from *,
      --#                                CommandLineData.Content,
      --#                                ContextManager.Ops.Unit_Heap,
      --#                                LexTokenManager.State,
      --#                                Report_File,
      --#                                XMLReport.State &
      --#         XMLReport.State   from *,
      --#                                CommandLineData.Content,
      --#                                ContextManager.Ops.Unit_Heap,
      --#                                LexTokenManager.State;
      is
         Status_Col : constant Positive := 50;

         Unit_Descriptor : ContextManager.UnitDescriptors;
         Unit_Name       : LexTokenLists.Lists;
         Unit_Type       : ContextManager.UnitTypes;

         First_Time : Boolean;
      begin
         if CommandLineData.Content.XML then
            XMLReport.Start_Section (Section => XMLReport.S_Cyclic_Requirements,
                                     Report  => Report_File);
            Unit_Descriptor := ContextManager.Ops.FirstUnitDescriptor;
            loop
               exit when Unit_Descriptor = ContextManager.NullUnit;
               if ContextManager.Ops.UnitInCycle (Unit_Descriptor) then
                  ContextManager.Ops.GetUnitName (Unit_Descriptor, Unit_Name, Unit_Type);
                  XMLReport.Unit
                    (LexTokenLists.Token_List_To_String (Token_List => Unit_Name),
                     Get_Unit_Type (Unit_Type => Unit_Type),
                     Report_File);
               end if;
               Unit_Descriptor := ContextManager.Ops.NextUnitDescriptor (Unit_Descriptor);
            end loop;
            XMLReport.End_Section (Section => XMLReport.S_Cyclic_Requirements,
                                   Report  => Report_File);
         else
            First_Time      := True;
            Unit_Descriptor := ContextManager.Ops.FirstUnitDescriptor;
            loop
               exit when Unit_Descriptor = ContextManager.NullUnit;
               if ContextManager.Ops.UnitInCycle (Unit_Descriptor) then
                  SPARK_IO.New_Line (Report_File, 1);
                  if First_Time then
                     SPARK_IO.New_Line (Report_File, 1);
                     SPARK_IO.Put_Line
                       (Report_File,
                        "A cycle was detected when determining the required units of the following:",
                        0);
                     SPARK_IO.New_Line (Report_File, 1);
                     SPARK_IO.Put_String (Report_File, "   Unit name", 0);
                     SPARK_IO.Set_Col (Report_File, Status_Col);
                     SPARK_IO.Put_Line (Report_File, "Unit type", 0);
                     SPARK_IO.Put_String (Report_File, "   ---------", 0);
                     SPARK_IO.Set_Col (Report_File, Status_Col);
                     SPARK_IO.Put_Line (Report_File, "---------", 0);
                     First_Time := False;
                  end if;
                  ContextManager.Ops.GetUnitName (Unit_Descriptor, Unit_Name, Unit_Type);
                  SPARK_IO.Put_String (Report_File, "   ", 0);
                  Print_Lex_Token_List (File => Report_File,
                                        List => Unit_Name);
                  SPARK_IO.Set_Col (Report_File, Status_Col);
                  Print_Unit_Type (File      => Report_File,
                                   Unit_Type => Unit_Type);
               end if;
               Unit_Descriptor := ContextManager.Ops.NextUnitDescriptor (Unit_Descriptor);
            end loop;
            if not First_Time then
               SPARK_IO.New_Line (Report_File, 2);
            end if;

         end if;
      end Output_Units_With_Cyclic_Requirements;

      procedure Output_Command_Line (Report_File : in SPARK_IO.File_Type)
      --# global in     CommandLineData.Content;
      --#        in out SPARK_IO.File_Sys;
      --#        in out XMLReport.State;
      --# derives SPARK_IO.File_Sys from *,
      --#                                CommandLineData.Content,
      --#                                Report_File,
      --#                                XMLReport.State &
      --#         XMLReport.State   from *,
      --#                                CommandLineData.Content;
      is
         Tmp_String : E_Strings.T;
         Option_Str : E_Strings.T;

         function Plain_Output (E_Str : E_Strings.T) return E_Strings.T
         --# global in CommandLineData.Content;
         is
            Result : E_Strings.T;
         begin
            if CommandLineData.Content.Plain_Output and then not CommandLineData.Content.XML then
               Result := FileSystem.Just_File (Fn  => E_Str,
                                               Ext => True);
            else
               Result := E_Str;
            end if;
            return Result;
         end Plain_Output;

      begin

         if CommandLineData.Content.XML then
            XMLReport.Start_Section (Section => XMLReport.S_Commandline,
                                     Report  => Report_File);
         else
            SPARK_IO.Put_Line (Report_File, "Options:", 0);
         end if;

         CommandLineData.Output_Command_Line (Prefix     => "    ",
                                              XML        => CommandLineData.Content.XML,
                                              Option_Str => Option_Str);
         E_Strings.Put_String (File  => Report_File,
                               E_Str => Option_Str);

         --# assert True;

         if not CommandLineData.Content.XML then
            SPARK_IO.New_Line (Report_File, 1);
            SPARK_IO.Put_Line (Report_File, "Selected files:", 0);
         end if;

         --# assert True;

         for I in CommandLineData.Source_File_Counts range 1 .. CommandLineData.Content.Number_Source loop
            Tmp_String := Plain_Output (E_Str => CommandLineData.Content.Source_File_List (I).Source_File_Name);

            --# accept F, 41, "Stable expression OK here";
            if CommandLineData.Content.XML then
               XMLReport.Filename (Plain_Output => CommandLineData.Content.Plain_Output,
                                   File         => Tmp_String);
               E_Strings.Put_String (File  => Report_File,
                                     E_Str => Tmp_String);
            else
               SPARK_IO.Put_String (Report_File, "   ", 0);
               E_Strings.Put_Line (File  => Report_File,
                                   E_Str => Tmp_String);
            end if;
            --# end accept;
         end loop;

         --# assert True;

         if CommandLineData.Content.XML then
            XMLReport.End_Section (Section => XMLReport.S_Commandline,
                                   Report  => Report_File);
         else
            SPARK_IO.New_Line (Report_File, 2);
         end if;
      end Output_Command_Line;

      procedure Output_Index_List (Report_File : in SPARK_IO.File_Type)
      --# global in     CommandLineData.Content;
      --#        in     IndexManager.State;
      --#        in     LexTokenManager.State;
      --#        in out SPARK_IO.File_Sys;
      --#        in out XMLReport.State;
      --# derives SPARK_IO.File_Sys from *,
      --#                                CommandLineData.Content,
      --#                                IndexManager.State,
      --#                                LexTokenManager.State,
      --#                                Report_File,
      --#                                XMLReport.State &
      --#         XMLReport.State   from *,
      --#                                CommandLineData.Content,
      --#                                IndexManager.State;
      is
      begin
         IndexManager.List_Index_File (Report_File => Report_File);
      end Output_Index_List;

      procedure Output_Meta_File_List (Report_File : in SPARK_IO.File_Type)
      --# global in     CommandLineData.Content;
      --#        in out SPARK_IO.File_Sys;
      --#        in out XMLReport.State;
      --# derives SPARK_IO.File_Sys,
      --#         XMLReport.State   from CommandLineData.Content,
      --#                                Report_File,
      --#                                SPARK_IO.File_Sys,
      --#                                XMLReport.State;
      is
         Meta_File_Used : Boolean := False;
         Filename       : E_Strings.T;
      begin
         if CommandLineData.Content.XML then
            XMLReport.Start_Section (Section => XMLReport.S_Meta_Files,
                                     Report  => Report_File);
         else
            SPARK_IO.New_Line (Report_File, 1);
         end if;

         for CurrentSource in CommandLineData.Source_File_Positions range 1 .. CommandLineData.Content.Number_Source loop
            Filename := CommandLineData.Content.Source_File_List (CurrentSource).Source_File_Name;
            if E_Strings.Get_Element (E_Str => Filename,
                                      Pos   => 1) = '@' then
               MetaFile.Report_File_Content (To_File        => Report_File,
                                             Filename       => Filename,
                                             Meta_File_Used => Meta_File_Used);
            end if;
         end loop;
         if not Meta_File_Used and not CommandLineData.Content.XML then
            SPARK_IO.New_Line (Report_File, 1);
            SPARK_IO.Put_Line (Report_File, "No Meta Files used", 0);
         end if;

         if CommandLineData.Content.XML then
            XMLReport.End_Section (Section => XMLReport.S_Meta_Files,
                                   Report  => Report_File);
         end if;

      end Output_Meta_File_List;

   begin  --Output_Report_File

      if CommandLineData.Content.Report then
         Create_Report_File (Report_File => Report_File,
                             OK          => OK);
         if OK then
            if CommandLineData.Content.Echo and not CommandLineData.Content.Brief then
               ScreenEcho.Echo (E_Strings.Copy_String (Str => Report_Message));
            end if;
            Output_Command_Line (Report_File => Report_File);
            Output_Index_List (Report_File => Report_File);
            Output_Meta_File_List (Report_File => Report_File);
            ErrorHandler.Output_Warning_List (To_File => Report_File);
            Dictionary.Output_Target_Data_File (To_File => Report_File);
            ConfigFile.Output_Config_File (To_File => Report_File);
            Output_File_List (Report_File => Report_File);
            Output_Units_Required_But_Not_Found (Report_File => Report_File);
            Output_Units_With_Cyclic_Requirements (Report_File => Report_File);
            if CommandLineData.Content.XML then
               XMLReport.End_Section (Section => XMLReport.S_Prologue,
                                      Report  => Report_File);
            end if;
            Output_Error_List (Report_File            => Report_File,
                               Report_File_Error_List => Report_File_Error_List);
            if CommandLineData.Content.Syntax_Only then
               SPARK_IO.New_Line (Report_File, 1);
               SPARK_IO.Put_Line (Report_File, "Warning: No semantic checks carried out, text may not be legal SPARK", 0);
            end if;
            if CommandLineData.Content.Flow_Option = CommandLineData.Data_Flow then
               SPARK_IO.New_Line (Report_File, 1);
               SPARK_IO.Put_Line (Report_File, "Note: Data flow analysis mode selected", 0);
            elsif CommandLineData.Content.Flow_Option = CommandLineData.Auto_Flow then
               SPARK_IO.New_Line (Report_File, 1);
               SPARK_IO.Put_Line (Report_File, "Note: Automatic flow analysis mode selected", 0);
            end if;
            if CommandLineData.Content.Write_Statistics then
               Statistics.WriteOutput (Report_File);
            end if;
            if not CommandLineData.Content.Plain_Output then
               ErrorHandler.Output_Reference_List (To_File => Report_File);
            end if;
            if CommandLineData.Content.XML then
               XMLReport.End_Section (Section => XMLReport.S_Report,
                                      Report  => Report_File);
            else
               Show_End_Of_File (To_File => Report_File);
            end if;
            --# accept F, 10, Report_File, "Final assignment after close";
            Close_Report_File (Report_File => Report_File);
            --# end accept;
            if CommandLineData.Content.HTML then
               SparkHTML.Gen_Report_HTML;
            end if;
         end if;
      end if;
   end Output_Report_File;

   procedure Echo_Listing_File (Filename : in E_Strings.T)
   --# global in     CommandLineData.Content;
   --#        in out SPARK_IO.File_Sys;
   --# derives SPARK_IO.File_Sys from *,
   --#                                CommandLineData.Content,
   --#                                Filename;
   is
      Message : E_Strings.T;
   begin
      if CommandLineData.Content.Echo and not CommandLineData.Content.Brief then
         Message := E_Strings.Copy_String (Str => "Generating listing file ");
         if CommandLineData.Content.Plain_Output then
            E_Strings.Append_Examiner_String (E_Str1 => Message,
                                              E_Str2 => FileSystem.Just_File (Fn  => Filename,
                                                                              Ext => True));
         else
            E_Strings.Append_Examiner_String (E_Str1 => Message,
                                              E_Str2 => Filename);
         end if;
         ScreenEcho.Echo (Message);
      end if;
   end Echo_Listing_File;

   procedure Output_Listing_File (File_Descriptor : in ContextManager.FileDescriptors)
   --# global in     CommandLineData.Content;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in out ContextManager.Ops.File_Heap;
   --#        in out ErrorHandler.Error_Context;
   --#        in out SPARK_IO.File_Sys;
   --# derives ContextManager.Ops.File_Heap,
   --#         ErrorHandler.Error_Context,
   --#         SPARK_IO.File_Sys            from CommandLineData.Content,
   --#                                           ContextManager.Ops.File_Heap,
   --#                                           Dictionary.Dict,
   --#                                           ErrorHandler.Error_Context,
   --#                                           File_Descriptor,
   --#                                           LexTokenManager.State,
   --#                                           SPARK_IO.File_Sys;
   is
      Listing_File           : SPARK_IO.File_Type := SPARK_IO.Null_File;
      Plain_Listing_Filename : E_Strings.T;
      Listing_Filename       : E_Strings.T;
      Status                 : SPARK_IO.File_Status;
      Error_Context          : ErrorHandler.Error_Contexts;
   begin
      ContextManager.Ops.GetListingFileName (File_Descriptor, Listing_Filename);

      Plain_Listing_Filename := Listing_Filename;
      CommandLineData.Normalize_File_Name_To_Output_Directory (F => Listing_Filename);

      Listing_Filename := FileSystem.Case_Of_Files_For_Create (E_Str => Listing_Filename);
      E_Strings.Create (File         => Listing_File,
                        Name_Of_File => Listing_Filename,
                        Form_Of_File => "",
                        Status       => Status);
      if Status /= SPARK_IO.Ok then
         ScreenEcho.Put_String ("Listing file, ");
         Print_Filename (File  => SPARK_IO.Standard_Output,
                         Name  => Listing_Filename,
                         Plain => False);
         ScreenEcho.Put_Line (", could not be created");
      else
         Echo_Listing_File (Filename => Plain_Listing_Filename);
         File_Utils.Print_A_Header
           (File        => Listing_File,
            Header_Line => "Listing of SPARK Text",
            File_Type   => File_Utils.Other_File);
         ContextManager.Ops.GetErrorContext (File_Descriptor, Error_Context);
         ErrorHandler.Set_Error_Context (Context => Error_Context);
         ErrorHandler.PrintErrors (Listing_File, Error_Types.ForListing);
         if CommandLineData.Content.Syntax_Only then

            -- HTML directives:
            --! <NameFormat> <Name>
            --! <ErrorFormat> <Error>

            -- HTML output
            --! <Name> warning-no-semantic-checks
            --! <Error> Warning : No semantic checks carried out, text may not be legal SPARK.
            --! Issued when the Examiner is used solely to check the syntax of a
            --! SPARK text: this does not check the semantics of a program
            --! (e.g. the correctness of the annotations) and
            --! therefore does not guarantee that a program is legal SPARK.
            SPARK_IO.New_Line (Listing_File, 1);
            SPARK_IO.Put_Line (Listing_File, "Warning: No semantic checks carried out, text may not be legal SPARK", 0);
         end if;
         if CommandLineData.Content.Flow_Option = CommandLineData.Data_Flow then
            --! <Name> note-information-flow
            --! <Error> Note: Information flow analysis not carried out
            --! This is issued as a reminder that information flow analysis has
            --! not been carried out in this run of the Examiner: information
            --! flow errors may be present undetected in the text analysed
            SPARK_IO.New_Line (Listing_File, 1);
            SPARK_IO.Put_Line (Listing_File, "Note: Information flow analysis not carried out", 0);
         elsif CommandLineData.Content.Flow_Option = CommandLineData.Auto_Flow then
            --! <Name> note-automatic-flow
            --! <Error> Note: Flow analysis mode is automatic
            --! This is issued as a reminder that the Examiner will perform
            --! information flow analysis if it encounters full derives annotations
            --! and will perform data flow analysis if only moded global annotations
            --! are present. Information flow errors may be present undetected in the
            --! text analysed
            SPARK_IO.New_Line (Listing_File, 1);
            SPARK_IO.Put_Line (Listing_File, "Note: Flow analysis mode is automatic", 0);
         end if;

         case CommandLineData.Content.Language_Profile is
            when CommandLineData.SPARK83 =>
               --! <Name> note-ada-83
               --! <Error> Note: Ada 83 language rules selected
               --! Issued when the Examiner is used in SPARK 83 mode
               SPARK_IO.New_Line (Listing_File, 1);
               SPARK_IO.Put_Line (Listing_File, "Note: Ada83 language rules selected", 0);

            when CommandLineData.SPARK95_Onwards =>
               null;
         end case;

         ErrorHandler.Get_Error_Context (Context => Error_Context);
         ContextManager.Ops.SetErrorContext (File_Descriptor, Error_Context);
         Show_End_Of_File (To_File => Listing_File);
         --# accept F, 10, Listing_File, "Final assignment after close" &
         --#        F, 10, Status, "Final assignment after close";
         SPARK_IO.Close (Listing_File, Status);
         --# end accept;
      end if;
   end Output_Listing_File;

   procedure Parse_Current_Unit
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.Unit_Stack;
   --#        in     Dictionary.Dict;
   --#        in out ContextManager.Ops.File_Heap;
   --#        in out ContextManager.Ops.Unit_Heap;
   --#        in out ErrorHandler.Error_Context;
   --#        in out LexTokenManager.State;
   --#        in out SPARK_IO.File_Sys;
   --#        in out STree.Table;
   --#           out SparkLex.Curr_Line;
   --# derives ContextManager.Ops.File_Heap,
   --#         ContextManager.Ops.Unit_Heap,
   --#         ErrorHandler.Error_Context,
   --#         LexTokenManager.State,
   --#         SparkLex.Curr_Line,
   --#         SPARK_IO.File_Sys,
   --#         STree.Table                  from CommandLineData.Content,
   --#                                           ContextManager.Ops.File_Heap,
   --#                                           ContextManager.Ops.Unit_Heap,
   --#                                           ContextManager.Ops.Unit_Stack,
   --#                                           Dictionary.Dict,
   --#                                           ErrorHandler.Error_Context,
   --#                                           LexTokenManager.State,
   --#                                           SPARK_IO.File_Sys,
   --#                                           STree.Table;
   is
      File_Descriptor : ContextManager.FileDescriptors;
      Source_File     : SPARK_IO.File_Type;
      Max_Stack_Size  : Natural;
      File_End        : Boolean;
      Severity        : ErrorHandler.Error_Level;
      Parse_Tree      : STree.SyntaxNode;
      File_Context    : SparkLex.Line_Context;
      Error_Context   : ErrorHandler.Error_Contexts;
   begin
      File_Descriptor := ContextManager.Ops.Get_File_Descriptor (Unit_Descriptor => ContextManager.Ops.Current_Unit);
      ContextManager.Ops.GetSourceFile (File_Descriptor, Source_File);
      ContextManager.Ops.GetLineContext (File_Descriptor, File_Context);
      SparkLex.Restore_Line_Context (File_Line => File_Context);
      ContextManager.Ops.GetErrorContext (File_Descriptor, Error_Context);
      ErrorHandler.Set_Error_Context (Context => Error_Context);
      --# accept F, 10, Max_Stack_Size, "Not required here";
      SPParser.SPParse (Source_File, Max_Stack_Size, File_End);
      --# end accept;
      STree.RetrieveCurrentRoot (Parse_Tree);
      ContextManager.Ops.SetParseTree (ContextManager.Ops.Current_Unit, Parse_Tree);
      ContextManager.Ops.SetUnitStatus (ContextManager.Ops.Current_Unit, ContextManager.UnitParsed);
      if File_End then
         ContextManager.Ops.Close_File (File_Descriptor => File_Descriptor);
      end if;
      ErrorHandler.Get_Error_Severity (Severity => Severity);
      if Severity = ErrorHandler.Fatal then
         ContextManager.Ops.SetUnitStatus (ContextManager.Ops.Current_Unit, ContextManager.UnitAnalysed);
         ContextManager.Ops.Close_File (File_Descriptor => File_Descriptor);
      end if;
      SparkLex.Store_Line_Context (File_Line => File_Context);
      ContextManager.Ops.SetLineContext (File_Descriptor, File_Context);
      ErrorHandler.Get_Error_Context (Context => Error_Context);
      ContextManager.Ops.SetErrorContext (File_Descriptor, Error_Context);
      --# accept F, 33, Max_Stack_Size, "Not required here";
   end Parse_Current_Unit;

   procedure Echo_Compilation_Unit (Unit_Name : in LexTokenLists.Lists;
                                    Unit_Type : in ContextManager.UnitTypes)
   --# global in     CommandLineData.Content;
   --#        in     LexTokenManager.State;
   --#        in out SPARK_IO.File_Sys;
   --# derives SPARK_IO.File_Sys from *,
   --#                                CommandLineData.Content,
   --#                                LexTokenManager.State,
   --#                                Unit_Name,
   --#                                Unit_Type;
   is
      Message : E_Strings.T;
   begin

      if CommandLineData.Content.Echo
        and then not CommandLineData.Content.Brief
        and then Unit_Type /= ContextManager.InterUnitPragma then

         Message := E_Strings.Copy_String (Str => "Examining ");
         case Unit_Type is
            when ContextManager.MainProgram =>
               E_Strings.Append_String (E_Str => Message,
                                        Str   => "main program ");
            when ContextManager.PackageSpecification =>
               E_Strings.Append_String (E_Str => Message,
                                        Str   => "the specification of package ");
            when ContextManager.PackageBody =>
               E_Strings.Append_String (E_Str => Message,
                                        Str   => "the body of package ");
            when ContextManager.SubUnit =>
               E_Strings.Append_String (E_Str => Message,
                                        Str   => "subunit ");
            when ContextManager.GenericSubprogramDeclaration =>
               E_Strings.Append_String (E_Str => Message,
                                        Str   => "generic subprogram declaration ");
            when ContextManager.GenericSubprogramBody =>
               E_Strings.Append_String (E_Str => Message,
                                        Str   => "generic subprogram body ");

               -- following don't get examined so don't need suitable message
            when ContextManager.InterUnitPragma | ContextManager.InvalidUnit =>
               null;
         end case;

         E_Strings.Append_Examiner_String
           (E_Str1 => Message,
            E_Str2 => LexTokenManager.Lex_String_To_String
              (Lex_Str => LexTokenLists.Get_Element (List => Unit_Name,
                                                     Pos  => LexTokenLists.Get_Length (List => Unit_Name))));
         ScreenEcho.Echo (Message);
      end if;
   end Echo_Compilation_Unit;

   function Get_Likely_Unit_Type (Possible_Unit_Types : ContextManager.UnitTypeSets) return ContextManager.UnitTypes is
      Actual_Unit_Type : ContextManager.UnitTypes;
   begin
      -- since we didn't find the unit we need to guess what kind of thing we were
      -- looking for so that we can make a sensible report about missing units in the
      -- report file.  We use the "sets" of possible units to decide.
      if Possible_Unit_Types (ContextManager.PackageSpecification) then
         Actual_Unit_Type := ContextManager.PackageSpecification;
      elsif Possible_Unit_Types (ContextManager.GenericSubprogramDeclaration) then
         Actual_Unit_Type := ContextManager.GenericSubprogramDeclaration;
      elsif Possible_Unit_Types (ContextManager.SubUnit) then
         Actual_Unit_Type := ContextManager.SubUnit;
      else
         Actual_Unit_Type := ContextManager.PackageBody;
      end if;
      return Actual_Unit_Type;
   end Get_Likely_Unit_Type;

   procedure Print_Lookup_Fail_Message
     (Curr_File     : in E_Strings.T;
      Required_Unit : in E_Strings.T;
      Expected_Sort : in E_Strings.T;
      Message       : in String)
   --# global in     CommandLineData.Content;
   --#        in out SPARK_IO.File_Sys;
   --# derives SPARK_IO.File_Sys from *,
   --#                                CommandLineData.Content,
   --#                                Curr_File,
   --#                                Expected_Sort,
   --#                                Message,
   --#                                Required_Unit;
   is
      Curr_Str : E_Strings.T;
   begin
      if E_Strings.Get_Length (E_Str => Curr_File) > 0 then
         if CommandLineData.Content.Plain_Output or else CommandLineData.Content.Brief then
            Curr_Str := FileSystem.Just_File (Fn  => Curr_File,
                                              Ext => True);
         else
            Curr_Str := Curr_File;
         end if;
      else
         Curr_Str := E_Strings.Empty_String;
      end if;

      if CommandLineData.Content.Brief then
         ScreenEcho.Put_ExaminerString (Curr_Str);
         ScreenEcho.Put_Char (':');
         ScreenEcho.Put_Integer (1, 0, 10);
         ScreenEcho.Put_Char (':');
         ScreenEcho.Put_Integer (1, 0, 10);
         ScreenEcho.Put_String (": ");
      else
         ScreenEcho.New_Line (1);
         ScreenEcho.Put_String ("In ");
         ScreenEcho.Put_ExaminerString (Curr_Str);
         ScreenEcho.Put_String (": ");
      end if;

      ScreenEcho.Put_ExaminerString (Expected_Sort);
      ScreenEcho.Put_Char (' ');
      ScreenEcho.Put_ExaminerString (Required_Unit);
      ScreenEcho.Put_String (" is not declared in this file ");
      ScreenEcho.Put_String ("and ");
      ScreenEcho.Put_ExaminerString (Expected_Sort);
      ScreenEcho.Put_Char (' ');
      ScreenEcho.Put_ExaminerString (Required_Unit);
      ScreenEcho.Put_Char (' ');
      ScreenEcho.Put_Line (Message);
   end Print_Lookup_Fail_Message;

   procedure Add_Required_Unit (Required_Unit       : in LexTokenLists.Lists;
                                Possible_Unit_Types : in ContextManager.UnitTypeSets)
   --# global in     CommandLineData.Content;
   --#        in     Dictionary.Dict;
   --#        in out ContextManager.Ops.File_Heap;
   --#        in out ContextManager.Ops.Unit_Heap;
   --#        in out ContextManager.Ops.Unit_Stack;
   --#        in out ErrorHandler.Error_Context;
   --#        in out IndexManager.State;
   --#        in out LexTokenManager.State;
   --#        in out SparkLex.Curr_Line;
   --#        in out SPARK_IO.File_Sys;
   --# derives ContextManager.Ops.File_Heap,
   --#         ContextManager.Ops.Unit_Heap,
   --#         ContextManager.Ops.Unit_Stack,
   --#         ErrorHandler.Error_Context    from *,
   --#                                            CommandLineData.Content,
   --#                                            ContextManager.Ops.File_Heap,
   --#                                            ContextManager.Ops.Unit_Heap,
   --#                                            Dictionary.Dict,
   --#                                            ErrorHandler.Error_Context,
   --#                                            IndexManager.State,
   --#                                            LexTokenManager.State,
   --#                                            Possible_Unit_Types,
   --#                                            Required_Unit,
   --#                                            SPARK_IO.File_Sys &
   --#         IndexManager.State            from *,
   --#                                            CommandLineData.Content,
   --#                                            ContextManager.Ops.Unit_Heap,
   --#                                            ErrorHandler.Error_Context,
   --#                                            LexTokenManager.State,
   --#                                            Possible_Unit_Types,
   --#                                            Required_Unit,
   --#                                            SPARK_IO.File_Sys &
   --#         LexTokenManager.State,
   --#         SparkLex.Curr_Line            from *,
   --#                                            CommandLineData.Content,
   --#                                            ContextManager.Ops.File_Heap,
   --#                                            ContextManager.Ops.Unit_Heap,
   --#                                            ErrorHandler.Error_Context,
   --#                                            IndexManager.State,
   --#                                            LexTokenManager.State,
   --#                                            Possible_Unit_Types,
   --#                                            Required_Unit,
   --#                                            SPARK_IO.File_Sys &
   --#         SPARK_IO.File_Sys             from *,
   --#                                            CommandLineData.Content,
   --#                                            ContextManager.Ops.File_Heap,
   --#                                            ContextManager.Ops.Unit_Heap,
   --#                                            ContextManager.Ops.Unit_Stack,
   --#                                            Dictionary.Dict,
   --#                                            ErrorHandler.Error_Context,
   --#                                            IndexManager.State,
   --#                                            LexTokenManager.State,
   --#                                            Possible_Unit_Types,
   --#                                            Required_Unit;
   is
      Unit_Descriptor  : ContextManager.UnitDescriptors;
      Source_Filename  : LexTokenManager.Lex_String;
      Actual_Unit_Type : ContextManager.UnitTypes;
      File_Descriptor  : ContextManager.FileDescriptors;
      File_Str         : E_Strings.T;
      Found            : Boolean;
   begin
      Trace (Msg => "In MainLoop.Add_Required_Unit");
      Trace_Unit (List  => Required_Unit,
                  Types => Possible_Unit_Types);
      ContextManager.Ops.GetUnitByName (Required_Unit, Possible_Unit_Types, Unit_Descriptor);
      if Unit_Descriptor = ContextManager.NullUnit then
         File_Descriptor := ContextManager.Ops.Get_File_Descriptor (Unit_Descriptor => ContextManager.Ops.Current_Unit);

         -- A unit which was previously referenced, but could not be located
         -- can have a NullFile entry, and therefore won't have an entry
         -- in the Source_Filename table either.  We need to report something, so...
         if File_Descriptor = ContextManager.NullFile then
            File_Str := E_Strings.Copy_String (Str => "UNKNOWN");
         else
            File_Str := LexTokenManager.Lex_String_To_String (Lex_Str => ContextManager.Ops.GetSourceFileName (File_Descriptor));
         end if;

         if CommandLineData.Content.Index or else CommandLineData.Content.SPARK_Lib then
            Trace (Msg => "   unit not known, calling IndexManager.LookUp");
            IndexManager.Look_Up
              (Required_Unit       => Required_Unit,
               Possible_Unit_Types => Possible_Unit_Types,
               Source_Filename     => Source_Filename,
               Actual_Unit_Type    => Actual_Unit_Type,
               Found               => Found);
            if Found then
               Trace (Msg => "      Found");
               File_Descriptor := ContextManager.Ops.GetFileByName (Source_Filename);
               if File_Descriptor = ContextManager.NullFile then
                  Create_File_Context
                    (Source_Filename => LexTokenManager.Lex_String_To_String (Lex_Str => Source_Filename),
                     File_Descriptor => File_Descriptor);
                  ContextManager.Ops.Open_File (File_Descriptor => File_Descriptor);
               end if;
               ContextManager.Ops.Create_Unit_Descriptor (File_Descriptor => File_Descriptor,
                                                          Unit_Descriptor => Unit_Descriptor);
               ContextManager.Ops.SetUnitName (Unit_Descriptor, Required_Unit, Actual_Unit_Type);
               if ContextManager.Ops.GetFileStatus (File_Descriptor) = ContextManager.UnableToOpen then
                  Trace (Msg => "      unit name found in index file but cannot open specified file");
                  Actual_Unit_Type := Get_Likely_Unit_Type (Possible_Unit_Types => Possible_Unit_Types);
                  Print_Lookup_Fail_Message
                    (Curr_File     => File_Str,
                     Required_Unit => Get_Unit_Name (List => Required_Unit),
                     Expected_Sort => Get_Unit_Type (Unit_Type => Actual_Unit_Type),
                     Message       => "source file entry in index file cannot be opened.");
                  ContextManager.Ops.SetUnitStatus (Unit_Descriptor, ContextManager.CannotOpenFile);
               else
                  ContextManager.Ops.PushUnit (Unit_Descriptor);
               end if;
            else
               Trace (Msg => "      not found in Index File");
               Actual_Unit_Type := Get_Likely_Unit_Type (Possible_Unit_Types => Possible_Unit_Types);
               Print_Lookup_Fail_Message
                 (Curr_File     => File_Str,
                  Required_Unit => Get_Unit_Name (List => Required_Unit),
                  Expected_Sort => Get_Unit_Type (Unit_Type => Actual_Unit_Type),
                  Message       => "is not referenced in an index file.");
               ContextManager.Ops.Create_Unit_Descriptor
                 (File_Descriptor => ContextManager.NullFile,
                  Unit_Descriptor => Unit_Descriptor);
               ContextManager.Ops.SetUnitName (Unit_Descriptor, Required_Unit, Actual_Unit_Type);
               ContextManager.Ops.SetUnitStatus (Unit_Descriptor, ContextManager.NotInIndexFile);
            end if;
         else
            Trace (Msg => "   unit not known, and no index file specified");
            Actual_Unit_Type := Get_Likely_Unit_Type (Possible_Unit_Types => Possible_Unit_Types);
            Print_Lookup_Fail_Message
              (Curr_File     => File_Str,
               Required_Unit => Get_Unit_Name (List => Required_Unit),
               Expected_Sort => Get_Unit_Type (Unit_Type => Actual_Unit_Type),
               Message       => "cannot be located as no index file has been specified.");
            ContextManager.Ops.Create_Unit_Descriptor
              (File_Descriptor => ContextManager.NullFile,
               Unit_Descriptor => Unit_Descriptor);
            ContextManager.Ops.SetUnitName (Unit_Descriptor, Required_Unit, Actual_Unit_Type);
            ContextManager.Ops.SetUnitStatus (Unit_Descriptor, ContextManager.NoIndexFile);
         end if;
      else
         Trace (Msg => "   unit already seen");
         if ContextManager.Ops.Get_Unit_Status (Unit_Descriptor => Unit_Descriptor) = ContextManager.UnitParsed then
            ContextManager.Ops.MarkUnitInCycle (Unit_Descriptor);
         end if;
         ContextManager.Ops.PushUnit (Unit_Descriptor);
      end if;
   end Add_Required_Unit;

   procedure Set_Up_Required_Units
   --# global in     CommandLineData.Content;
   --#        in     Dictionary.Dict;
   --#        in     STree.Table;
   --#        in out ContextManager.Ops.File_Heap;
   --#        in out ContextManager.Ops.Unit_Heap;
   --#        in out ContextManager.Ops.Unit_Stack;
   --#        in out ErrorHandler.Error_Context;
   --#        in out IndexManager.State;
   --#        in out LexTokenManager.State;
   --#        in out SparkLex.Curr_Line;
   --#        in out SPARK_IO.File_Sys;
   --# derives ContextManager.Ops.File_Heap,
   --#         ContextManager.Ops.Unit_Heap,
   --#         ContextManager.Ops.Unit_Stack,
   --#         ErrorHandler.Error_Context,
   --#         IndexManager.State,
   --#         LexTokenManager.State,
   --#         SparkLex.Curr_Line,
   --#         SPARK_IO.File_Sys             from *,
   --#                                            CommandLineData.Content,
   --#                                            ContextManager.Ops.File_Heap,
   --#                                            ContextManager.Ops.Unit_Heap,
   --#                                            ContextManager.Ops.Unit_Stack,
   --#                                            Dictionary.Dict,
   --#                                            ErrorHandler.Error_Context,
   --#                                            IndexManager.State,
   --#                                            LexTokenManager.State,
   --#                                            SPARK_IO.File_Sys,
   --#                                            STree.Table;
   is
      Inherit_Ptr       : STree.SyntaxNode;
      Unit_Type         : ContextManager.UnitTypes;
      Unit_Name         : LexTokenLists.Lists;
      Current_Unit_Name : LexTokenLists.Lists;
      Current_Unit_Type : ContextManager.UnitTypes;

      function Found_Top_Unit
        (Wanted_Name : LexTokenLists.Lists;
         Wanted_Type : ContextManager.UnitTypes;
         Found_Name  : LexTokenLists.Lists;
         Found_Type  : ContextManager.UnitTypes)
        return        Boolean
      --# global in LexTokenManager.State;
      is
      begin
         Trace (Msg => "In MainLoop.Found_Top_Unit");
         return LexTokenLists.Get_Length (List => Wanted_Name) = 0
           or else (LexTokenLists.Eq_Unit (First_Item => Wanted_Name,
                                           Second     => Found_Name) and Wanted_Type = Found_Type);
      end Found_Top_Unit;

      procedure Replace_Top_Unit (Current_Unit_Name : in LexTokenLists.Lists;
                                  Current_Unit_Type : in ContextManager.UnitTypes)
      --# global in     LexTokenManager.State;
      --#        in     STree.Table;
      --#        in out ContextManager.Ops.File_Heap;
      --#        in out ContextManager.Ops.Unit_Heap;
      --#        in out ContextManager.Ops.Unit_Stack;
      --# derives ContextManager.Ops.File_Heap,
      --#         ContextManager.Ops.Unit_Stack from ContextManager.Ops.File_Heap,
      --#                                            ContextManager.Ops.Unit_Heap,
      --#                                            ContextManager.Ops.Unit_Stack,
      --#                                            Current_Unit_Name,
      --#                                            LexTokenManager.State &
      --#         ContextManager.Ops.Unit_Heap  from *,
      --#                                            ContextManager.Ops.File_Heap,
      --#                                            ContextManager.Ops.Unit_Stack,
      --#                                            Current_Unit_Name,
      --#                                            Current_Unit_Type,
      --#                                            LexTokenManager.State,
      --#                                            STree.Table;
      is
         New_Unit_Descriptor, Old_Unit_Descriptor : ContextManager.UnitDescriptors;
         File_Descriptor                          : ContextManager.FileDescriptors;
         Found_Unit                               : LexTokenLists.Lists;
         Found_Unit_Type                          : ContextManager.UnitTypes;
         Found_Unit_Type_Set                      : ContextManager.UnitTypeSets;
         Found_Unit_Descriptor                    : ContextManager.UnitDescriptors;
         Found_File_Descriptor                    : ContextManager.FileDescriptors;
         Parse_Tree                               : STree.SyntaxNode;
      begin
         --# accept F, 10, Old_Unit_Descriptor, "Not required here" &
         --#        F, 33, Old_Unit_Descriptor, "Not required here";
         Trace (Msg => "In MainLoop.Replace_Top_Unit");
         if LexTokenLists.Get_Length (List => Current_Unit_Name) = 0 then
            ContextManager.Ops.PopUnit (Old_Unit_Descriptor);
         else
            File_Descriptor       := ContextManager.Ops.Get_File_Descriptor (Unit_Descriptor => ContextManager.Ops.Current_Unit);
            Found_File_Descriptor := File_Descriptor;
            ContextManager.Ops.GetUnitName (ContextManager.Ops.Current_Unit, Found_Unit, Found_Unit_Type);
            Found_Unit_Type_Set                   := ContextManager.UnitTypeSets'(others => False);
            Found_Unit_Type_Set (Found_Unit_Type) := True;
            ContextManager.Ops.GetUnitByName (Found_Unit, Found_Unit_Type_Set, Found_Unit_Descriptor);
            if ContextManager.Ops.Get_Unit_Status (Unit_Descriptor => Found_Unit_Descriptor) = ContextManager.UnitCreated then
               Found_File_Descriptor := ContextManager.Ops.Get_File_Descriptor (Unit_Descriptor => Found_Unit_Descriptor);
            end if;
            if Found_Unit_Descriptor /= ContextManager.Ops.Current_Unit and then Found_File_Descriptor = File_Descriptor then
               -- special case of earlier pending unit found
               ContextManager.Ops.SetUnitStatus (Found_Unit_Descriptor, ContextManager.UnitParsed);
               ContextManager.Ops.GetParseTree (ContextManager.Ops.Current_Unit, Parse_Tree);
               ContextManager.Ops.SetParseTree (Found_Unit_Descriptor, Parse_Tree);
               ContextManager.Ops.SetParseTree (ContextManager.Ops.Current_Unit, STree.NullNode);
               ContextManager.Ops.SetUnitName (ContextManager.Ops.Current_Unit, Current_Unit_Name, Current_Unit_Type);
               case ContextManager.Ops.GetFileStatus (File_Descriptor) is
                  when ContextManager.FileEnd =>
                     ContextManager.Ops.SetUnitStatus (ContextManager.Ops.Current_Unit, ContextManager.UnableToLocate);
                     ContextManager.Ops.PopUnit (Old_Unit_Descriptor);
                  when ContextManager.UnableToOpen =>
                     ContextManager.Ops.SetUnitStatus (ContextManager.Ops.Current_Unit, ContextManager.CannotOpenFile);
                     ContextManager.Ops.PopUnit (Old_Unit_Descriptor);
                  when others =>
                     ContextManager.Ops.SetUnitStatus (ContextManager.Ops.Current_Unit, ContextManager.UnitCreated);
               end case;
            else -- 'normal' case
               ContextManager.Ops.Create_Unit_Descriptor
                 (File_Descriptor => File_Descriptor,
                  Unit_Descriptor => New_Unit_Descriptor);
               ContextManager.Ops.SetUnitStatus (ContextManager.Ops.Current_Unit, ContextManager.UnitDeferred);
               ContextManager.Ops.PopUnit (Old_Unit_Descriptor);
               ContextManager.Ops.SetUnitName (New_Unit_Descriptor, Current_Unit_Name, Current_Unit_Type);
               case ContextManager.Ops.GetFileStatus (File_Descriptor) is
                  when ContextManager.FileEnd =>
                     ContextManager.Ops.SetUnitStatus (New_Unit_Descriptor, ContextManager.UnableToLocate);
                  when ContextManager.UnableToOpen =>
                     ContextManager.Ops.SetUnitStatus (New_Unit_Descriptor, ContextManager.CannotOpenFile);
                  when others =>
                     ContextManager.Ops.PushUnit (New_Unit_Descriptor);
               end case;
            end if;
         end if;
      end Replace_Top_Unit;

      procedure Add_Inherited_Packages
      --# global in     CommandLineData.Content;
      --#        in     Dictionary.Dict;
      --#        in     STree.Table;
      --#        in out ContextManager.Ops.File_Heap;
      --#        in out ContextManager.Ops.Unit_Heap;
      --#        in out ContextManager.Ops.Unit_Stack;
      --#        in out ErrorHandler.Error_Context;
      --#        in out IndexManager.State;
      --#        in out Inherit_Ptr;
      --#        in out LexTokenManager.State;
      --#        in out SparkLex.Curr_Line;
      --#        in out SPARK_IO.File_Sys;
      --# derives ContextManager.Ops.File_Heap,
      --#         ContextManager.Ops.Unit_Heap,
      --#         ContextManager.Ops.Unit_Stack,
      --#         ErrorHandler.Error_Context,
      --#         IndexManager.State,
      --#         LexTokenManager.State,
      --#         SparkLex.Curr_Line,
      --#         SPARK_IO.File_Sys             from *,
      --#                                            CommandLineData.Content,
      --#                                            ContextManager.Ops.File_Heap,
      --#                                            ContextManager.Ops.Unit_Heap,
      --#                                            ContextManager.Ops.Unit_Stack,
      --#                                            Dictionary.Dict,
      --#                                            ErrorHandler.Error_Context,
      --#                                            IndexManager.State,
      --#                                            Inherit_Ptr,
      --#                                            LexTokenManager.State,
      --#                                            SPARK_IO.File_Sys,
      --#                                            STree.Table &
      --#         Inherit_Ptr                   from *,
      --#                                            STree.Table;
      is
         Required_Unit : LexTokenLists.Lists;
         Found         : Boolean;

         -- If a package is inherited and therefore required we do not want to add it
         -- to the required unit list if it is predefined.  Currently only
         -- Ada.Characters.Latin_1 is predefined. If Ravenscar is selected, package
         -- Ada.Real_Time is also predefined.
         function Is_Predefined_Package return Boolean
         --# global in CommandLineData.Content;
         --#        in LexTokenManager.State;
         --#        in Required_Unit;
         is
            Result : Boolean;
         begin
            case LexTokenLists.Get_Length (List => Required_Unit) is
               when 1 =>
                  -- Ada
                  Result :=
                    LexTokenManager.Lex_String_Case_Insensitive_Compare
                    (Lex_Str1 => LexTokenLists.Get_Element (List => Required_Unit,
                                                            Pos  => 1),
                     Lex_Str2 => LexTokenManager.Ada_Token) =
                    LexTokenManager.Str_Eq;
               when 2 =>
                  -- Ada.Real_Time, Ada.Characters or Ada.Interrupts
                  Result :=
                    LexTokenManager.Lex_String_Case_Insensitive_Compare
                    (Lex_Str1 => LexTokenLists.Get_Element (List => Required_Unit,
                                                            Pos  => 1),
                     Lex_Str2 => LexTokenManager.Ada_Token) =
                    LexTokenManager.Str_Eq
                    and then (LexTokenManager.Lex_String_Case_Insensitive_Compare
                                (Lex_Str1 => LexTokenLists.Get_Element (List => Required_Unit, Pos => 2),
                                 Lex_Str2 => LexTokenManager.Characters_Token) =
                                LexTokenManager.Str_Eq
                                or else (CommandLineData.Ravenscar_Selected
                                           and then (LexTokenManager.Lex_String_Case_Insensitive_Compare
                                                       (Lex_Str1 => LexTokenLists.Get_Element (List => Required_Unit,
                                                                                               Pos  => 2),
                                                        Lex_Str2 => LexTokenManager.Real_Time_Token) =
                                                       LexTokenManager.Str_Eq
                                                       or else LexTokenManager.Lex_String_Case_Insensitive_Compare
                                                       (Lex_Str1 => LexTokenLists.Get_Element (List => Required_Unit,
                                                                                               Pos  => 2),
                                                        Lex_Str2 => LexTokenManager.Interrupts_Token) =
                                                       LexTokenManager.Str_Eq
                                                       or else LexTokenManager.Lex_String_Case_Insensitive_Compare
                                                       (Lex_Str1 => LexTokenLists.Get_Element (List => Required_Unit,
                                                                                               Pos  => 2),
                                                        Lex_Str2 => LexTokenManager.Synchronous_Task_Control_Token) =
                                                       LexTokenManager.Str_Eq)));
               when 3 =>
                  -- Ada.Characters.Latin_1
                  Result :=
                    LexTokenManager.Lex_String_Case_Insensitive_Compare
                    (Lex_Str1 => LexTokenLists.Get_Element (List => Required_Unit,
                                                            Pos  => 1),
                     Lex_Str2 => LexTokenManager.Ada_Token) =
                    LexTokenManager.Str_Eq
                    and then LexTokenManager.Lex_String_Case_Insensitive_Compare
                    (Lex_Str1 => LexTokenLists.Get_Element (List => Required_Unit,
                                                            Pos  => 2),
                     Lex_Str2 => LexTokenManager.Characters_Token) =
                    LexTokenManager.Str_Eq
                    and then LexTokenManager.Lex_String_Case_Insensitive_Compare
                    (Lex_Str1 => LexTokenLists.Get_Element (List => Required_Unit,
                                                            Pos  => 3),
                     Lex_Str2 => LexTokenManager.Latin_1_Token) =
                    LexTokenManager.Str_Eq;
               when others =>
                  Result := False;
            end case;
            return Result;
         end Is_Predefined_Package;

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

         function System_Needed_And_Provided_By_Config_File return Boolean
         --# global in CommandLineData.Content;
         --#        in Dictionary.Dict;
         --#        in LexTokenManager.State;
         --#        in Required_Unit;
         is
         begin
            return LexTokenLists.Get_Length (List => Required_Unit) = 1
              and then LexTokenManager.Lex_String_Case_Insensitive_Compare
              (Lex_Str1 => LexTokenLists.Get_Element (List => Required_Unit,
                                                      Pos  => 1),
               Lex_Str2 => LexTokenManager.System_Token) =
              LexTokenManager.Str_Eq
              and then Dictionary.IsDefined
              (Name              => LexTokenManager.System_Token,
               Scope             => Dictionary.GlobalScope,
               Context           => Dictionary.ProgramContext,
               Full_Package_Name => False);
         end System_Needed_And_Provided_By_Config_File;

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

         function Is_Predefined_Generic return Boolean
         --# global in LexTokenManager.State;
         --#        in Required_Unit;
         is
            Result : Boolean;
         begin
            case LexTokenLists.Get_Length (List => Required_Unit) is
               when 1 =>
                  -- Unchecked_Conversion
                  Result :=
                    LexTokenManager.Lex_String_Case_Insensitive_Compare
                    (Lex_Str1 => LexTokenLists.Get_Element (List => Required_Unit,
                                                            Pos  => 1),
                     Lex_Str2 => LexTokenManager.Unchecked_Conversion_Token) =
                    LexTokenManager.Str_Eq;
               when 2 =>
                  -- Ada.Unchecked_Conversion
                  Result :=
                    LexTokenManager.Lex_String_Case_Insensitive_Compare
                    (Lex_Str1 => LexTokenLists.Get_Element (List => Required_Unit,
                                                            Pos  => 1),
                     Lex_Str2 => LexTokenManager.Ada_Token) =
                    LexTokenManager.Str_Eq
                    and then LexTokenManager.Lex_String_Case_Insensitive_Compare
                    (Lex_Str1 => LexTokenLists.Get_Element (List => Required_Unit,
                                                            Pos  => 2),
                     Lex_Str2 => LexTokenManager.Unchecked_Conversion_Token) =
                    LexTokenManager.Str_Eq;
               when others =>
                  Result := False;
            end case;
            return Result;
         end Is_Predefined_Generic;

      begin -- Add_Inherited_Packages
         Trace (Msg => "In MainLoop.Add_Inherited_Packages");
         loop
            RequiredUnits.Next (Inherit_Ptr   => Inherit_Ptr,
                                Required_Unit => Required_Unit,
                                Found         => Found);
            exit when not Found;

            -- Ignore dotted package names in 83 mode and ignore predefined packages
            -- in 95 mode.  Ignore System if provided by config file. Ignore
            -- predefined generic units.
            --# accept F, 41, "Expect stable expression here";
            case CommandLineData.Content.Language_Profile is
               when CommandLineData.SPARK83 =>

                  if LexTokenLists.Get_Length (List => Required_Unit) <= 1
                    and then not System_Needed_And_Provided_By_Config_File
                    and then not Is_Predefined_Generic then
                     Add_Required_Unit (Required_Unit       => Required_Unit,
                                        Possible_Unit_Types => ContextManager.InheritableItem);
                  end if;

               when CommandLineData.SPARK95_Onwards =>

                  if not Is_Predefined_Package
                    and then not System_Needed_And_Provided_By_Config_File
                    and then not Is_Predefined_Generic then
                     Add_Required_Unit (Required_Unit       => Required_Unit,
                                        Possible_Unit_Types => ContextManager.InheritableItem);
                  end if;
            end case;
            --# end accept;
         end loop;
      end Add_Inherited_Packages;

      procedure Handle_Main_Program
      --# global in     CommandLineData.Content;
      --#        in     Current_Unit_Name;
      --#        in     Current_Unit_Type;
      --#        in     Dictionary.Dict;
      --#        in     STree.Table;
      --#        in     Unit_Name;
      --#        in     Unit_Type;
      --#        in out ContextManager.Ops.File_Heap;
      --#        in out ContextManager.Ops.Unit_Heap;
      --#        in out ContextManager.Ops.Unit_Stack;
      --#        in out ErrorHandler.Error_Context;
      --#        in out IndexManager.State;
      --#        in out Inherit_Ptr;
      --#        in out LexTokenManager.State;
      --#        in out SparkLex.Curr_Line;
      --#        in out SPARK_IO.File_Sys;
      --# derives ContextManager.Ops.File_Heap,
      --#         ContextManager.Ops.Unit_Heap,
      --#         ContextManager.Ops.Unit_Stack,
      --#         ErrorHandler.Error_Context,
      --#         IndexManager.State,
      --#         LexTokenManager.State,
      --#         SparkLex.Curr_Line,
      --#         SPARK_IO.File_Sys             from *,
      --#                                            CommandLineData.Content,
      --#                                            ContextManager.Ops.File_Heap,
      --#                                            ContextManager.Ops.Unit_Heap,
      --#                                            ContextManager.Ops.Unit_Stack,
      --#                                            Current_Unit_Name,
      --#                                            Current_Unit_Type,
      --#                                            Dictionary.Dict,
      --#                                            ErrorHandler.Error_Context,
      --#                                            IndexManager.State,
      --#                                            Inherit_Ptr,
      --#                                            LexTokenManager.State,
      --#                                            SPARK_IO.File_Sys,
      --#                                            STree.Table,
      --#                                            Unit_Name,
      --#                                            Unit_Type &
      --#         Inherit_Ptr                   from *,
      --#                                            Current_Unit_Name,
      --#                                            Current_Unit_Type,
      --#                                            LexTokenManager.State,
      --#                                            STree.Table,
      --#                                            Unit_Name,
      --#                                            Unit_Type;
      is
      begin
         Trace (Msg => "In MainLoop.Handle_Main_Program");
         ContextManager.Ops.SetUnitName (ContextManager.Ops.Current_Unit, Unit_Name, Unit_Type);
         if Found_Top_Unit
           (Wanted_Name => Current_Unit_Name,
            Wanted_Type => Current_Unit_Type,
            Found_Name  => Unit_Name,
            Found_Type  => Unit_Type) then
            Add_Inherited_Packages;
         else
            Replace_Top_Unit (Current_Unit_Name => Current_Unit_Name,
                              Current_Unit_Type => Current_Unit_Type);
         end if;
      end Handle_Main_Program;

      procedure Handle_Inter_Unit_Pragma
      --# global in     Current_Unit_Name;
      --#        in     Current_Unit_Type;
      --#        in     LexTokenManager.State;
      --#        in     STree.Table;
      --#        in     Unit_Name;
      --#        in     Unit_Type;
      --#        in out ContextManager.Ops.File_Heap;
      --#        in out ContextManager.Ops.Unit_Heap;
      --#        in out ContextManager.Ops.Unit_Stack;
      --# derives ContextManager.Ops.File_Heap,
      --#         ContextManager.Ops.Unit_Stack from ContextManager.Ops.File_Heap,
      --#                                            ContextManager.Ops.Unit_Heap,
      --#                                            ContextManager.Ops.Unit_Stack,
      --#                                            Current_Unit_Name,
      --#                                            Current_Unit_Type,
      --#                                            LexTokenManager.State,
      --#                                            Unit_Name,
      --#                                            Unit_Type &
      --#         ContextManager.Ops.Unit_Heap  from *,
      --#                                            ContextManager.Ops.File_Heap,
      --#                                            ContextManager.Ops.Unit_Stack,
      --#                                            Current_Unit_Name,
      --#                                            Current_Unit_Type,
      --#                                            LexTokenManager.State,
      --#                                            STree.Table,
      --#                                            Unit_Name,
      --#                                            Unit_Type;
      is
         New_Unit_Name : LexTokenLists.Lists;
      begin
         Trace (Msg => "In MainLoop.Handle_Inter_Unit_Pragma");
         New_Unit_Name := LexTokenLists.Null_List;
         ContextManager.Ops.SetUnitName (ContextManager.Ops.Current_Unit, New_Unit_Name, Unit_Type);
         if not Found_Top_Unit
           (Wanted_Name => Current_Unit_Name,
            Wanted_Type => Current_Unit_Type,
            Found_Name  => Unit_Name,
            Found_Type  => Unit_Type) then
            Replace_Top_Unit (Current_Unit_Name => Current_Unit_Name,
                              Current_Unit_Type => Current_Unit_Type);
         end if;
      end Handle_Inter_Unit_Pragma;

      procedure Handle_Package_Specification
      --# global in     CommandLineData.Content;
      --#        in     Current_Unit_Name;
      --#        in     Current_Unit_Type;
      --#        in     Dictionary.Dict;
      --#        in     STree.Table;
      --#        in     Unit_Name;
      --#        in     Unit_Type;
      --#        in out ContextManager.Ops.File_Heap;
      --#        in out ContextManager.Ops.Unit_Heap;
      --#        in out ContextManager.Ops.Unit_Stack;
      --#        in out ErrorHandler.Error_Context;
      --#        in out IndexManager.State;
      --#        in out Inherit_Ptr;
      --#        in out LexTokenManager.State;
      --#        in out SparkLex.Curr_Line;
      --#        in out SPARK_IO.File_Sys;
      --# derives ContextManager.Ops.File_Heap,
      --#         ContextManager.Ops.Unit_Heap,
      --#         ContextManager.Ops.Unit_Stack,
      --#         ErrorHandler.Error_Context,
      --#         IndexManager.State,
      --#         LexTokenManager.State,
      --#         SparkLex.Curr_Line,
      --#         SPARK_IO.File_Sys             from *,
      --#                                            CommandLineData.Content,
      --#                                            ContextManager.Ops.File_Heap,
      --#                                            ContextManager.Ops.Unit_Heap,
      --#                                            ContextManager.Ops.Unit_Stack,
      --#                                            Current_Unit_Name,
      --#                                            Current_Unit_Type,
      --#                                            Dictionary.Dict,
      --#                                            ErrorHandler.Error_Context,
      --#                                            IndexManager.State,
      --#                                            Inherit_Ptr,
      --#                                            LexTokenManager.State,
      --#                                            SPARK_IO.File_Sys,
      --#                                            STree.Table,
      --#                                            Unit_Name,
      --#                                            Unit_Type &
      --#         Inherit_Ptr                   from *,
      --#                                            Current_Unit_Name,
      --#                                            Current_Unit_Type,
      --#                                            LexTokenManager.State,
      --#                                            STree.Table,
      --#                                            Unit_Name,
      --#                                            Unit_Type;
      is
         procedure Add_Parent (Unit_Name : in LexTokenLists.Lists)
         --# global in     CommandLineData.Content;
         --#        in     Dictionary.Dict;
         --#        in out ContextManager.Ops.File_Heap;
         --#        in out ContextManager.Ops.Unit_Heap;
         --#        in out ContextManager.Ops.Unit_Stack;
         --#        in out ErrorHandler.Error_Context;
         --#        in out IndexManager.State;
         --#        in out LexTokenManager.State;
         --#        in out SparkLex.Curr_Line;
         --#        in out SPARK_IO.File_Sys;
         --# derives ContextManager.Ops.File_Heap,
         --#         ContextManager.Ops.Unit_Heap,
         --#         ContextManager.Ops.Unit_Stack,
         --#         ErrorHandler.Error_Context    from *,
         --#                                            CommandLineData.Content,
         --#                                            ContextManager.Ops.File_Heap,
         --#                                            ContextManager.Ops.Unit_Heap,
         --#                                            Dictionary.Dict,
         --#                                            ErrorHandler.Error_Context,
         --#                                            IndexManager.State,
         --#                                            LexTokenManager.State,
         --#                                            SPARK_IO.File_Sys,
         --#                                            Unit_Name &
         --#         IndexManager.State            from *,
         --#                                            CommandLineData.Content,
         --#                                            ContextManager.Ops.Unit_Heap,
         --#                                            ErrorHandler.Error_Context,
         --#                                            LexTokenManager.State,
         --#                                            SPARK_IO.File_Sys,
         --#                                            Unit_Name &
         --#         LexTokenManager.State,
         --#         SparkLex.Curr_Line            from *,
         --#                                            CommandLineData.Content,
         --#                                            ContextManager.Ops.File_Heap,
         --#                                            ContextManager.Ops.Unit_Heap,
         --#                                            ErrorHandler.Error_Context,
         --#                                            IndexManager.State,
         --#                                            LexTokenManager.State,
         --#                                            SPARK_IO.File_Sys,
         --#                                            Unit_Name &
         --#         SPARK_IO.File_Sys             from *,
         --#                                            CommandLineData.Content,
         --#                                            ContextManager.Ops.File_Heap,
         --#                                            ContextManager.Ops.Unit_Heap,
         --#                                            ContextManager.Ops.Unit_Stack,
         --#                                            Dictionary.Dict,
         --#                                            ErrorHandler.Error_Context,
         --#                                            IndexManager.State,
         --#                                            LexTokenManager.State,
         --#                                            Unit_Name;
         is
            Required_Unit : LexTokenLists.Lists;
            Dummy_Item    : LexTokenManager.Lex_String;
         begin
            Trace (Msg => "In MainLoop.Handle_Package_Specification.Add_Parent");
            Required_Unit := Unit_Name;
            --# accept F, 10, Dummy_Item, "Ineffective assignment here OK";
            LexTokenLists.Pop (List => Required_Unit,
                               Item => Dummy_Item);
            --# end accept;
            Add_Required_Unit (Required_Unit       => Required_Unit,
                               Possible_Unit_Types => ContextManager.PackageSpecificationSet);
            --# accept F, 33, Dummy_Item, "Expect Dummy_Item unused";
         end Add_Parent;

      begin -- Handle_Package_Specification
         Trace (Msg => "In MainLoop.Handle_Package_Specification");
         ContextManager.Ops.SetUnitName (ContextManager.Ops.Current_Unit, Unit_Name, Unit_Type);
         if Found_Top_Unit
           (Wanted_Name => Current_Unit_Name,
            Wanted_Type => Current_Unit_Type,
            Found_Name  => Unit_Name,
            Found_Type  => Unit_Type) then
            Add_Inherited_Packages;
            case CommandLineData.Content.Language_Profile is
               when CommandLineData.SPARK83 =>
                  null;
               when CommandLineData.SPARK95_Onwards =>
                  if LexTokenLists.Get_Length (List => Unit_Name) > 1
                    and then LexTokenManager.Lex_String_Case_Insensitive_Compare
                    (Lex_Str1 => LexTokenLists.Get_Element (List => Unit_Name,
                                                            Pos  => 1),
                     Lex_Str2 => LexTokenManager.Ada_Token) /=
                    LexTokenManager.Str_Eq
                    and then LexTokenManager.Lex_String_Case_Insensitive_Compare
                    (Lex_Str1 => LexTokenLists.Get_Element (List => Unit_Name,
                                                            Pos  => 1),
                     Lex_Str2 => LexTokenManager.System_Token) /=
                    LexTokenManager.Str_Eq then
                     Add_Parent (Unit_Name => Unit_Name);
                  end if;
            end case;
         else
            Replace_Top_Unit (Current_Unit_Name => Current_Unit_Name,
                              Current_Unit_Type => Current_Unit_Type);
         end if;
      end Handle_Package_Specification;

      procedure Handle_Package_Body
      --# global in     CommandLineData.Content;
      --#        in     Current_Unit_Name;
      --#        in     Current_Unit_Type;
      --#        in     Dictionary.Dict;
      --#        in     STree.Table;
      --#        in     Unit_Name;
      --#        in out ContextManager.Ops.File_Heap;
      --#        in out ContextManager.Ops.Unit_Heap;
      --#        in out ContextManager.Ops.Unit_Stack;
      --#        in out ErrorHandler.Error_Context;
      --#        in out IndexManager.State;
      --#        in out LexTokenManager.State;
      --#        in out SparkLex.Curr_Line;
      --#        in out SPARK_IO.File_Sys;
      --# derives ContextManager.Ops.File_Heap,
      --#         ContextManager.Ops.Unit_Stack,
      --#         ErrorHandler.Error_Context,
      --#         IndexManager.State,
      --#         LexTokenManager.State,
      --#         SparkLex.Curr_Line,
      --#         SPARK_IO.File_Sys             from *,
      --#                                            CommandLineData.Content,
      --#                                            ContextManager.Ops.File_Heap,
      --#                                            ContextManager.Ops.Unit_Heap,
      --#                                            ContextManager.Ops.Unit_Stack,
      --#                                            Current_Unit_Name,
      --#                                            Current_Unit_Type,
      --#                                            Dictionary.Dict,
      --#                                            ErrorHandler.Error_Context,
      --#                                            IndexManager.State,
      --#                                            LexTokenManager.State,
      --#                                            SPARK_IO.File_Sys,
      --#                                            Unit_Name &
      --#         ContextManager.Ops.Unit_Heap  from *,
      --#                                            CommandLineData.Content,
      --#                                            ContextManager.Ops.File_Heap,
      --#                                            ContextManager.Ops.Unit_Stack,
      --#                                            Current_Unit_Name,
      --#                                            Current_Unit_Type,
      --#                                            Dictionary.Dict,
      --#                                            ErrorHandler.Error_Context,
      --#                                            IndexManager.State,
      --#                                            LexTokenManager.State,
      --#                                            SPARK_IO.File_Sys,
      --#                                            STree.Table,
      --#                                            Unit_Name;
      is
         Components : IndexManager.Component_Lists;
         Index      : IndexManager.Component_Index;
      begin
         Trace (Msg => "In MainLoop.Handle_Package_Body");
         ContextManager.Ops.SetUnitName (ContextManager.Ops.Current_Unit, Unit_Name, ContextManager.PackageBody);
         if Found_Top_Unit
           (Wanted_Name => Current_Unit_Name,
            Wanted_Type => Current_Unit_Type,
            Found_Name  => Unit_Name,
            Found_Type  => ContextManager.PackageBody) then
            case CommandLineData.Content.Language_Profile is
               when CommandLineData.SPARK83 =>
                  if LexTokenLists.Get_Length (List => Unit_Name) <= 1 then
                     Add_Required_Unit (Required_Unit       => Unit_Name,
                                        Possible_Unit_Types => ContextManager.PackageSpecificationSet);
                  end if;

               when CommandLineData.SPARK95_Onwards =>
                  -- look for components in index file
                  IndexManager.Look_Up_Components (Required_Unit => Unit_Name,
                                                   Components    => Components);
                  Index := IndexManager.Component_Index'First;
                  loop
                     exit when LexTokenLists.Eq_Unit (First_Item => Components (Index),
                                                      Second     => LexTokenLists.Null_List);
                     Add_Required_Unit
                       (Required_Unit       => Components (Index),
                        Possible_Unit_Types => ContextManager.PackageSpecificationSet);
                     Index := IndexManager.Component_Index'Succ (Index);
                  end loop;

                  if LexTokenManager.Lex_String_Case_Insensitive_Compare
                    (Lex_Str1 => LexTokenLists.Get_Element (List => Unit_Name,
                                                            Pos  => 1),
                     Lex_Str2 => LexTokenManager.Ada_Token) /=
                    LexTokenManager.Str_Eq then
                     Add_Required_Unit (Required_Unit       => Unit_Name,
                                        Possible_Unit_Types => ContextManager.PackageSpecificationSet);
                  end if;

            end case;

         else
            Replace_Top_Unit (Current_Unit_Name => Current_Unit_Name,
                              Current_Unit_Type => Current_Unit_Type);
         end if;
      end Handle_Package_Body;

      procedure Handle_Generic_Subprogram_Declaration
      --# global in     CommandLineData.Content;
      --#        in     Dictionary.Dict;
      --#        in     STree.Table;
      --#        in     Unit_Name;
      --#        in out ContextManager.Ops.File_Heap;
      --#        in out ContextManager.Ops.Unit_Heap;
      --#        in out ContextManager.Ops.Unit_Stack;
      --#        in out ErrorHandler.Error_Context;
      --#        in out IndexManager.State;
      --#        in out Inherit_Ptr;
      --#        in out LexTokenManager.State;
      --#        in out SparkLex.Curr_Line;
      --#        in out SPARK_IO.File_Sys;
      --# derives ContextManager.Ops.File_Heap,
      --#         ContextManager.Ops.Unit_Heap,
      --#         ContextManager.Ops.Unit_Stack,
      --#         ErrorHandler.Error_Context,
      --#         IndexManager.State,
      --#         LexTokenManager.State,
      --#         SparkLex.Curr_Line,
      --#         SPARK_IO.File_Sys             from *,
      --#                                            CommandLineData.Content,
      --#                                            ContextManager.Ops.File_Heap,
      --#                                            ContextManager.Ops.Unit_Heap,
      --#                                            ContextManager.Ops.Unit_Stack,
      --#                                            Dictionary.Dict,
      --#                                            ErrorHandler.Error_Context,
      --#                                            IndexManager.State,
      --#                                            Inherit_Ptr,
      --#                                            LexTokenManager.State,
      --#                                            SPARK_IO.File_Sys,
      --#                                            STree.Table,
      --#                                            Unit_Name &
      --#         Inherit_Ptr                   from *,
      --#                                            STree.Table;
      is
      begin
         Trace (Msg => "In MainLoop.Handle_Generic_Subprogram_Declaration");
         ContextManager.Ops.SetUnitName (ContextManager.Ops.Current_Unit, Unit_Name, ContextManager.GenericSubprogramDeclaration);
         Add_Inherited_Packages;
      end Handle_Generic_Subprogram_Declaration;

      procedure Handle_Generic_Subprogram_Body
      --# global in     CommandLineData.Content;
      --#        in     Dictionary.Dict;
      --#        in     Unit_Name;
      --#        in out ContextManager.Ops.File_Heap;
      --#        in out ContextManager.Ops.Unit_Heap;
      --#        in out ContextManager.Ops.Unit_Stack;
      --#        in out ErrorHandler.Error_Context;
      --#        in out IndexManager.State;
      --#        in out LexTokenManager.State;
      --#        in out SparkLex.Curr_Line;
      --#        in out SPARK_IO.File_Sys;
      --# derives ContextManager.Ops.File_Heap,
      --#         ContextManager.Ops.Unit_Heap,
      --#         ContextManager.Ops.Unit_Stack,
      --#         ErrorHandler.Error_Context,
      --#         SPARK_IO.File_Sys             from CommandLineData.Content,
      --#                                            ContextManager.Ops.File_Heap,
      --#                                            ContextManager.Ops.Unit_Heap,
      --#                                            ContextManager.Ops.Unit_Stack,
      --#                                            Dictionary.Dict,
      --#                                            ErrorHandler.Error_Context,
      --#                                            IndexManager.State,
      --#                                            LexTokenManager.State,
      --#                                            SPARK_IO.File_Sys,
      --#                                            Unit_Name &
      --#         IndexManager.State            from *,
      --#                                            CommandLineData.Content,
      --#                                            ContextManager.Ops.Unit_Heap,
      --#                                            ContextManager.Ops.Unit_Stack,
      --#                                            ErrorHandler.Error_Context,
      --#                                            LexTokenManager.State,
      --#                                            SPARK_IO.File_Sys,
      --#                                            Unit_Name &
      --#         LexTokenManager.State,
      --#         SparkLex.Curr_Line            from *,
      --#                                            CommandLineData.Content,
      --#                                            ContextManager.Ops.File_Heap,
      --#                                            ContextManager.Ops.Unit_Heap,
      --#                                            ContextManager.Ops.Unit_Stack,
      --#                                            ErrorHandler.Error_Context,
      --#                                            IndexManager.State,
      --#                                            LexTokenManager.State,
      --#                                            SPARK_IO.File_Sys,
      --#                                            Unit_Name;
      is
      begin
         Trace (Msg => "In MainLoop.Handle_Generic_Subprogram_Body");
         ContextManager.Ops.SetUnitName (ContextManager.Ops.Current_Unit, Unit_Name, ContextManager.GenericSubprogramBody);
         -- generic body found so we need to see its spec
         Add_Required_Unit (Required_Unit       => Unit_Name,
                            Possible_Unit_Types => ContextManager.GenericDeclarationSet);
      end Handle_Generic_Subprogram_Body;

      procedure Handle_Sub_Unit
      --# global in     CommandLineData.Content;
      --#        in     Current_Unit_Name;
      --#        in     Current_Unit_Type;
      --#        in     Dictionary.Dict;
      --#        in     STree.Table;
      --#        in     Unit_Name;
      --#        in out ContextManager.Ops.File_Heap;
      --#        in out ContextManager.Ops.Unit_Heap;
      --#        in out ContextManager.Ops.Unit_Stack;
      --#        in out ErrorHandler.Error_Context;
      --#        in out IndexManager.State;
      --#        in out Inherit_Ptr;
      --#        in out LexTokenManager.State;
      --#        in out SparkLex.Curr_Line;
      --#        in out SPARK_IO.File_Sys;
      --# derives ContextManager.Ops.File_Heap,
      --#         ContextManager.Ops.Unit_Heap,
      --#         ContextManager.Ops.Unit_Stack,
      --#         ErrorHandler.Error_Context,
      --#         SPARK_IO.File_Sys             from CommandLineData.Content,
      --#                                            ContextManager.Ops.File_Heap,
      --#                                            ContextManager.Ops.Unit_Heap,
      --#                                            ContextManager.Ops.Unit_Stack,
      --#                                            Current_Unit_Name,
      --#                                            Current_Unit_Type,
      --#                                            Dictionary.Dict,
      --#                                            ErrorHandler.Error_Context,
      --#                                            IndexManager.State,
      --#                                            Inherit_Ptr,
      --#                                            LexTokenManager.State,
      --#                                            SPARK_IO.File_Sys,
      --#                                            STree.Table,
      --#                                            Unit_Name &
      --#         IndexManager.State            from *,
      --#                                            CommandLineData.Content,
      --#                                            ContextManager.Ops.Unit_Heap,
      --#                                            ContextManager.Ops.Unit_Stack,
      --#                                            Current_Unit_Name,
      --#                                            Current_Unit_Type,
      --#                                            ErrorHandler.Error_Context,
      --#                                            Inherit_Ptr,
      --#                                            LexTokenManager.State,
      --#                                            SPARK_IO.File_Sys,
      --#                                            STree.Table,
      --#                                            Unit_Name &
      --#         Inherit_Ptr                   from *,
      --#                                            STree.Table &
      --#         LexTokenManager.State,
      --#         SparkLex.Curr_Line            from *,
      --#                                            CommandLineData.Content,
      --#                                            ContextManager.Ops.File_Heap,
      --#                                            ContextManager.Ops.Unit_Heap,
      --#                                            ContextManager.Ops.Unit_Stack,
      --#                                            Current_Unit_Name,
      --#                                            Current_Unit_Type,
      --#                                            ErrorHandler.Error_Context,
      --#                                            IndexManager.State,
      --#                                            Inherit_Ptr,
      --#                                            LexTokenManager.State,
      --#                                            SPARK_IO.File_Sys,
      --#                                            STree.Table,
      --#                                            Unit_Name;
      is
         Required_Unit : LexTokenLists.Lists;
         New_Unit_Name : LexTokenLists.Lists;
         Found         : Boolean;
      begin
         Trace (Msg => "In MainLoop.Handle_Sub_Unit");
         RequiredUnits.Next (Inherit_Ptr   => Inherit_Ptr,
                             Required_Unit => Required_Unit,
                             Found         => Found);
         if Found then
            New_Unit_Name := Required_Unit;
            LexTokenLists.Append (List => New_Unit_Name,
                                  Item => LexTokenLists.Get_Element (List => Unit_Name,
                                                                     Pos  => 1));
            ContextManager.Ops.SetUnitName (ContextManager.Ops.Current_Unit, New_Unit_Name, ContextManager.SubUnit);
            if Found_Top_Unit
              (Wanted_Name => Current_Unit_Name,
               Wanted_Type => Current_Unit_Type,
               Found_Name  => New_Unit_Name,
               Found_Type  => ContextManager.SubUnit) then
               if LexTokenLists.Get_Length (List => Required_Unit) = 1 then
                  Add_Required_Unit (Required_Unit       => Required_Unit,
                                     Possible_Unit_Types => ContextManager.BodySet);
               else
                  Add_Required_Unit (Required_Unit       => Required_Unit,
                                     Possible_Unit_Types => ContextManager.SubUnitSet);
               end if;
            else
               Replace_Top_Unit (Current_Unit_Name => Current_Unit_Name,
                                 Current_Unit_Type => Current_Unit_Type);
            end if;
         end if;
      end Handle_Sub_Unit;

      procedure Look_At_Parse_Tree
      --# global in     ContextManager.Ops.Unit_Heap;
      --#        in     ContextManager.Ops.Unit_Stack;
      --#        in     STree.Table;
      --#           out Inherit_Ptr;
      --#           out Unit_Name;
      --#           out Unit_Type;
      --# derives Inherit_Ptr,
      --#         Unit_Name,
      --#         Unit_Type   from ContextManager.Ops.Unit_Heap,
      --#                          ContextManager.Ops.Unit_Stack,
      --#                          STree.Table;
      is
         Parse_Tree : STree.SyntaxNode;
      begin
         ContextManager.Ops.GetParseTree (ContextManager.Ops.Current_Unit, Parse_Tree);
         RequiredUnits.Init (Top_Node    => Parse_Tree,
                             Inherit_Ptr => Inherit_Ptr,
                             Unit_Type   => Unit_Type,
                             Unit_Name   => Unit_Name);
      end Look_At_Parse_Tree;

   begin -- Set_Up_Required_Units
      Trace (Msg => "In MainLoop.Set_Up_Required_Units");
      Look_At_Parse_Tree;
      ContextManager.Ops.GetUnitName (ContextManager.Ops.Current_Unit, Current_Unit_Name, Current_Unit_Type);

      if LexTokenLists.Eq_Unit (First_Item => Unit_Name,
                                Second     => LexTokenLists.Null_List)
        and then Unit_Type /= ContextManager.InterUnitPragma then
         ContextManager.Ops.SetUnitStatus (ContextManager.Ops.Current_Unit, ContextManager.NoUnitEntry);
         Replace_Top_Unit (Current_Unit_Name => Current_Unit_Name,
                           Current_Unit_Type => Current_Unit_Type);
      else
         --# accept F, 10, Inherit_Ptr, "Not required here";
         case Unit_Type is
            when ContextManager.MainProgram =>
               Handle_Main_Program;
            when ContextManager.PackageSpecification =>
               Handle_Package_Specification;
            when ContextManager.PackageBody =>
               Handle_Package_Body;
            when ContextManager.SubUnit =>
               Handle_Sub_Unit;
            when ContextManager.GenericSubprogramDeclaration =>
               Handle_Generic_Subprogram_Declaration;
            when ContextManager.GenericSubprogramBody =>
               Handle_Generic_Subprogram_Body;
            when ContextManager.InterUnitPragma =>
               Handle_Inter_Unit_Pragma;
            when ContextManager.InvalidUnit =>
               null;
         end case;
         --# end accept;
      end if;
   end Set_Up_Required_Units;

   procedure Process_Units (File_Descriptor : in ContextManager.FileDescriptors)
   --# global in     CommandLineData.Content;
   --#        in out ContextManager.Ops.File_Heap;
   --#        in out ContextManager.Ops.Unit_Heap;
   --#        in out ContextManager.Ops.Unit_Stack;
   --#        in out Declarations.State;
   --#        in out Dictionary.Dict;
   --#        in out ErrorHandler.Error_Context;
   --#        in out Graph.Table;
   --#        in out IndexManager.State;
   --#        in out LexTokenManager.State;
   --#        in out SLI.State;
   --#        in out SparkLex.Curr_Line;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Statistics.TableUsage;
   --#        in out StmtStack.S;
   --#        in out STree.Table;
   --#        in out VCG.Invoked;
   --#        in out XMLReport.State;
   --#           out Sem.State;
   --# derives ContextManager.Ops.File_Heap,
   --#         ContextManager.Ops.Unit_Heap,
   --#         ContextManager.Ops.Unit_Stack,
   --#         Declarations.State,
   --#         Dictionary.Dict,
   --#         ErrorHandler.Error_Context,
   --#         Graph.Table,
   --#         IndexManager.State,
   --#         LexTokenManager.State,
   --#         SparkLex.Curr_Line,
   --#         Statistics.TableUsage,
   --#         StmtStack.S,
   --#         STree.Table,
   --#         VCG.Invoked,
   --#         XMLReport.State               from *,
   --#                                            CommandLineData.Content,
   --#                                            ContextManager.Ops.File_Heap,
   --#                                            ContextManager.Ops.Unit_Heap,
   --#                                            ContextManager.Ops.Unit_Stack,
   --#                                            Dictionary.Dict,
   --#                                            ErrorHandler.Error_Context,
   --#                                            File_Descriptor,
   --#                                            IndexManager.State,
   --#                                            LexTokenManager.State,
   --#                                            SLI.State,
   --#                                            SPARK_IO.File_Sys,
   --#                                            STree.Table &
   --#         Sem.State                     from CommandLineData.Content,
   --#                                            ContextManager.Ops.File_Heap,
   --#                                            ContextManager.Ops.Unit_Heap,
   --#                                            ContextManager.Ops.Unit_Stack,
   --#                                            Dictionary.Dict,
   --#                                            ErrorHandler.Error_Context,
   --#                                            File_Descriptor,
   --#                                            IndexManager.State,
   --#                                            LexTokenManager.State,
   --#                                            SLI.State,
   --#                                            SPARK_IO.File_Sys,
   --#                                            STree.Table &
   --#         SLI.State,
   --#         SPARK_IO.File_Sys             from CommandLineData.Content,
   --#                                            ContextManager.Ops.File_Heap,
   --#                                            ContextManager.Ops.Unit_Heap,
   --#                                            ContextManager.Ops.Unit_Stack,
   --#                                            Dictionary.Dict,
   --#                                            ErrorHandler.Error_Context,
   --#                                            File_Descriptor,
   --#                                            IndexManager.State,
   --#                                            LexTokenManager.State,
   --#                                            SLI.State,
   --#                                            SPARK_IO.File_Sys,
   --#                                            STree.Table,
   --#                                            XMLReport.State;
   is
      Unit_Descriptor     : ContextManager.UnitDescriptors;
      SLI_Unit_Descriptor : ContextManager.UnitDescriptors := ContextManager.NullUnit;
      Severity            : ErrorHandler.Error_Level;
      Unit_Name           : LexTokenLists.Lists;
      Unit_Type           : ContextManager.UnitTypes;
      Scope               : Dictionary.Scopes;
      Prefix_Sym          : Dictionary.Symbol;
      Source_Filename     : E_Strings.T;
      L_Source_Filename   : E_Strings.T;
      File_Status         : FileSystem.Typ_File_Spec_Status;

      procedure Analyse_Current_Unit
      --# global in     CommandLineData.Content;
      --#        in     ContextManager.Ops.Unit_Stack;
      --#        in out ContextManager.Ops.File_Heap;
      --#        in out ContextManager.Ops.Unit_Heap;
      --#        in out Declarations.State;
      --#        in out Dictionary.Dict;
      --#        in out ErrorHandler.Error_Context;
      --#        in out Graph.Table;
      --#        in out LexTokenManager.State;
      --#        in out SLI.State;
      --#        in out SLI_Unit_Descriptor;
      --#        in out SPARK_IO.File_Sys;
      --#        in out Statistics.TableUsage;
      --#        in out StmtStack.S;
      --#        in out STree.Table;
      --#        in out VCG.Invoked;
      --#           out Sem.State;
      --#           out SparkLex.Curr_Line;
      --# derives ContextManager.Ops.File_Heap,
      --#         Declarations.State,
      --#         Dictionary.Dict,
      --#         ErrorHandler.Error_Context,
      --#         Graph.Table,
      --#         LexTokenManager.State,
      --#         SLI.State,
      --#         SPARK_IO.File_Sys,
      --#         Statistics.TableUsage,
      --#         StmtStack.S,
      --#         STree.Table,
      --#         VCG.Invoked                  from *,
      --#                                           CommandLineData.Content,
      --#                                           ContextManager.Ops.File_Heap,
      --#                                           ContextManager.Ops.Unit_Heap,
      --#                                           ContextManager.Ops.Unit_Stack,
      --#                                           Dictionary.Dict,
      --#                                           ErrorHandler.Error_Context,
      --#                                           LexTokenManager.State,
      --#                                           SLI.State,
      --#                                           SPARK_IO.File_Sys,
      --#                                           STree.Table &
      --#         ContextManager.Ops.Unit_Heap from *,
      --#                                           ContextManager.Ops.Unit_Stack &
      --#         Sem.State                    from CommandLineData.Content,
      --#                                           ContextManager.Ops.File_Heap,
      --#                                           ContextManager.Ops.Unit_Heap,
      --#                                           ContextManager.Ops.Unit_Stack,
      --#                                           Dictionary.Dict,
      --#                                           ErrorHandler.Error_Context,
      --#                                           LexTokenManager.State,
      --#                                           SLI.State,
      --#                                           SPARK_IO.File_Sys,
      --#                                           STree.Table &
      --#         SLI_Unit_Descriptor          from *,
      --#                                           CommandLineData.Content,
      --#                                           ContextManager.Ops.File_Heap,
      --#                                           ContextManager.Ops.Unit_Heap,
      --#                                           ContextManager.Ops.Unit_Stack,
      --#                                           Dictionary.Dict,
      --#                                           ErrorHandler.Error_Context,
      --#                                           SPARK_IO.File_Sys &
      --#         SparkLex.Curr_Line           from ContextManager.Ops.File_Heap,
      --#                                           ContextManager.Ops.Unit_Heap,
      --#                                           ContextManager.Ops.Unit_Stack;
      is
         File_Descriptor : ContextManager.FileDescriptors;
         Unit_Name       : LexTokenLists.Lists;
         Unit_Type       : ContextManager.UnitTypes;
         Severity        : ErrorHandler.Error_Level;
         File_Context    : SparkLex.Line_Context;
         Parse_Tree      : STree.SyntaxNode;
         Error_Context   : ErrorHandler.Error_Contexts;
         Do_VCG          : Boolean;
      begin
         ContextManager.Ops.GetParseTree (ContextManager.Ops.Current_Unit, Parse_Tree);
         File_Descriptor := ContextManager.Ops.Get_File_Descriptor (Unit_Descriptor => ContextManager.Ops.Current_Unit);
         ContextManager.Ops.GetLineContext (File_Descriptor, File_Context);
         ContextManager.Ops.GetVCG (ContextManager.Ops.Current_Unit, Do_VCG);
         ContextManager.Ops.GetUnitName (ContextManager.Ops.Current_Unit, Unit_Name, Unit_Type);
         SparkLex.Restore_Line_Context (File_Line => File_Context);
         ContextManager.Ops.GetErrorContext (File_Descriptor, Error_Context);
         ErrorHandler.Set_Error_Context (Context => Error_Context);
         Echo_Compilation_Unit (Unit_Name => Unit_Name,
                                Unit_Type => Unit_Type);
         Dictionary.Set_Current_File_Name
           (File_Name => LexTokenManager.Lex_String_To_String (Lex_Str => ContextManager.Ops.GetSourceFileName (File_Descriptor)));
         if ErrorHandler.Generate_SLI then
            ContextManager.Ops.Get_Unit (Descriptor      => File_Descriptor,
                                         Unit_Descriptor => SLI_Unit_Descriptor);
         end if;
         Sem.CompUnit (Top_Node => Parse_Tree,
                       Do_VCG   => Do_VCG);
         Casing.Check_Node_Casing (Top_Node => Parse_Tree);
         ErrorHandler.Get_Error_Severity (Severity => Severity);

         if Severity = ErrorHandler.Fatal then
            ContextManager.Ops.Close_File (File_Descriptor => File_Descriptor);
         end if;
         SparkLex.Store_Line_Context (File_Line => File_Context);
         ContextManager.Ops.SetLineContext (File_Descriptor, File_Context);
         ErrorHandler.Get_Error_Context (Context => Error_Context);
         ContextManager.Ops.SetErrorContext (File_Descriptor, Error_Context);

         -- return the Parse_Tree to the syntax tree free list, except sub-trees
         -- that are later needed by the VCG.  If the user has selected /rules=none,
         -- then we _can_ return constant declarations as well.
         STree.DeleteSyntaxTree
           (Root          => Parse_Tree,
            KeepConstants => CommandLineData.Content.Constant_Rules /= CommandLineData.No_Rules);

         ContextManager.Ops.SetUnitStatus (ContextManager.Ops.Current_Unit, ContextManager.UnitAnalysed);
      end Analyse_Current_Unit;

   begin -- Process_Units
      loop
         exit when ContextManager.Ops.GetFileStatus (File_Descriptor) = ContextManager.FileEnd;
         ContextManager.Ops.Create_Unit_Descriptor (File_Descriptor => File_Descriptor,
                                                    Unit_Descriptor => Unit_Descriptor);
         ContextManager.Ops.SetVCG (Unit_Descriptor, CommandLineData.Content.VCG or CommandLineData.Content.DPC);
         ContextManager.Ops.PushUnit (Unit_Descriptor);
         loop
            exit when ContextManager.Ops.Current_Unit = ContextManager.NullUnit;
            case ContextManager.Ops.Get_Unit_Status (Unit_Descriptor => ContextManager.Ops.Current_Unit) is
               when ContextManager.NoUnitEntry =>
                  null;
               when ContextManager.UnitCreated =>
                  Parse_Current_Unit;
                  ErrorHandler.Get_Error_Severity (Severity => Severity);
                  if Severity /= ErrorHandler.Fatal then
                     Set_Up_Required_Units;
                  end if;
               when ContextManager.UnitDeferred =>
                  ContextManager.Ops.SetUnitStatus (ContextManager.Ops.Current_Unit, ContextManager.UnitParsed);
                  Set_Up_Required_Units;
               when ContextManager.UnitParsed =>
                  --# accept F, 41, "Stable expression OK here";
                  if CommandLineData.Content.Syntax_Only then
                     ContextManager.Ops.PopUnit (Unit_Descriptor);
                  else
                     Analyse_Current_Unit;
                  end if;
                  --# end accept;
               when ContextManager.UnitAnalysed | ContextManager.NoIndexFile .. ContextManager.UnableToLocate =>
                  ContextManager.Ops.PopUnit (Unit_Descriptor);
            end case;
         end loop;
         if not ErrorHandler.Syntax_Or_Semantic_Error then
            L_Source_Filename :=
              LexTokenManager.Lex_String_To_String
              (Lex_Str => ContextManager.Ops.GetSourceFileName (Descriptor => File_Descriptor));
            ContextManager.Ops.GetUnitName (Descriptor => Unit_Descriptor,
                                            UnitName   => Unit_Name,
                                            UnitType   => Unit_Type);
            --# accept F, 41, "Stable expression expected here";
            if CommandLineData.Content.Debug.File_Names then
               SPARK_IO.Put_String (File => SPARK_IO.Standard_Output,
                                    Item => "MAINLOOP ",
                                    Stop => 0);
            end if;
            --# end accept;
            --# accept F, 10, File_Status, "Expect File_Status Unused";
            FileSystem.Find_Full_File_Name
              (File_Spec      => L_Source_Filename,
               File_Status    => File_Status,
               Full_File_Name => Source_Filename);
            --# end accept;
            if Unit_Type /= ContextManager.InterUnitPragma then
               IndexManager.Add_Unit (Unit            => Unit_Name,
                                      Unit_Types      => Unit_Type,
                                      Source_Filename => Source_Filename);
            end if;
         end if;
      end loop;
      if ErrorHandler.Generate_SLI and then SLI_Unit_Descriptor /= ContextManager.NullUnit then
         ContextManager.Ops.GetUnitName (Descriptor => SLI_Unit_Descriptor,
                                         UnitName   => Unit_Name,
                                         UnitType   => Unit_Type);
         Scope      := Dictionary.GlobalScope;
         Prefix_Sym := Dictionary.NullSymbol;
         for I in LexTokenLists.Positions range LexTokenLists.Positions'First .. LexTokenLists.Get_Length (List => Unit_Name) loop
            SLI.Look_Up
              (Prefix            => Prefix_Sym,
               Scope             => Scope,
               Subprog_Sym       => Dictionary.NullSymbol,
               Lex_Str           => LexTokenLists.Get_Element (List => Unit_Name,
                                                               Pos  => I),
               Pos               => LexTokenManager.Null_Token_Position,
               Full_Package_Name => False);
            exit when Dictionary.Is_Null_Symbol (Prefix_Sym);
         end loop;
         if Unit_Type = ContextManager.MainProgram
           or else Unit_Type = ContextManager.GenericSubprogramBody
           or else Unit_Type = ContextManager.PackageBody
           or else Unit_Type = ContextManager.SubUnit
           or else (Unit_Type = ContextManager.PackageSpecification
                      and then not Dictionary.Is_Null_Symbol (Prefix_Sym)
                      and then not Dictionary.PackageRequiresBody (ThePackage => Prefix_Sym)) then
            ContextManager.Ops.Dependency_Closure (Descriptor => File_Descriptor);
            SLI.Create_File (File_Descriptor => File_Descriptor);
            SLI.Header (File_Descriptor => File_Descriptor);
            SLI.Dump_Xref (File_Descriptor => File_Descriptor);
            SLI.Close_File;
         end if;
      end if;
      --# accept Flow, 33, File_Status, "Expect File_Status unused" &
      --#        Flow, 602, Sem.State, Sem.State, "Expect undefined initial value";
   end Process_Units;

   procedure Close_File
     (File_Descriptor        : in ContextManager.FileDescriptors;
      Report_File_Error_List : in SPARK_IO.File_Type;
      Report_Needed          : in Boolean)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     SparkHTML.Generate_HTML;
   --#        in out ContextManager.Ops.File_Heap;
   --#        in out ErrorHandler.Error_Context;
   --#        in out SPARK_IO.File_Sys;
   --#        in out XMLReport.State;
   --# derives ContextManager.Ops.File_Heap,
   --#         ErrorHandler.Error_Context,
   --#         SPARK_IO.File_Sys,
   --#         XMLReport.State              from CommandLineData.Content,
   --#                                           ContextManager.Ops.File_Heap,
   --#                                           ContextManager.Ops.Unit_Heap,
   --#                                           Dictionary.Dict,
   --#                                           ErrorHandler.Error_Context,
   --#                                           File_Descriptor,
   --#                                           LexTokenManager.State,
   --#                                           Report_File_Error_List,
   --#                                           Report_Needed,
   --#                                           SparkHTML.Generate_HTML,
   --#                                           SPARK_IO.File_Sys,
   --#                                           XMLReport.State;
   is
   begin
      if ContextManager.Ops.ListingReqt (File_Descriptor) and not CommandLineData.Content.No_Listings then
         Output_Listing_File (File_Descriptor => File_Descriptor);
         if CommandLineData.Content.HTML then
            SparkHTML.Gen_Listing_HTML (File_Descriptor => File_Descriptor);
         end if;
      end if;
      if Report_Needed then
         Append_To_Report_File
           (Report_File     => Report_File_Error_List,
            Purpose         => Error_Types.ForReportSelectedFiles,
            File_Descriptor => File_Descriptor);
         ContextManager.Ops.SetErrorsReported (File_Descriptor);
      end if;
   end Close_File;

   procedure Process_Files is
      File_Descriptor                                             : ContextManager.FileDescriptors;
      File_Found, Config_Success, Config_Read, Do_Listing, Do_VCG : Boolean;
      Filename, The_Filename, The_Listing_Name                    : E_Strings.T;
      The_Meta_File                                               : MetaFile.Meta_Files;
      Report_File_Error_List                                      : SPARK_IO.File_Type := SPARK_IO.Null_File;
      Error_File_Status                                           : SPARK_IO.File_Status;
      File_Status                                                 : FileSystem.Typ_File_Spec_Status;

      procedure Open_Error_List
      --# global in out Report_File_Error_List;
      --#        in out SPARK_IO.File_Sys;
      --#           out Error_File_Status;
      --# derives Error_File_Status,
      --#         Report_File_Error_List,
      --#         SPARK_IO.File_Sys      from Report_File_Error_List,
      --#                                     SPARK_IO.File_Sys;
      --#
      is
      begin
         SPARK_IO.Create (Report_File_Error_List, 0, "", "", -- Temporary file
                          --to get
                          Error_File_Status);
      end Open_Error_List;

      procedure Trace_Meta_Filenames
        (The_Filename     : in E_Strings.T;
         Do_Listing       : in Boolean;
         The_Listing_Name : in E_Strings.T;
         Do_VCG           : in Boolean;
         File_Found       : in Boolean)
      --# global in CommandLineData.Content;
      --# derives null from CommandLineData.Content,
      --#                   Do_Listing,
      --#                   Do_VCG,
      --#                   File_Found,
      --#                   The_Filename,
      --#                   The_Listing_Name;
      is
         --# hide Trace_Meta_Filenames;
      begin
         if File_Found and CommandLineData.Content.Debug.File_Names then
            SPARK_IO.Put_String (SPARK_IO.Standard_Output, "MetaFile.NextName returns:", 0);

            Print_Filename (File  => SPARK_IO.Standard_Output,
                            Name  => The_Filename,
                            Plain => CommandLineData.Content.Plain_Output);
            if Do_Listing then
               SPARK_IO.Put_String (SPARK_IO.Standard_Output, ", ", 0);

               Print_Filename
                 (File  => SPARK_IO.Standard_Output,
                  Name  => The_Listing_Name,
                  Plain => CommandLineData.Content.Plain_Output);
            else
               SPARK_IO.Put_Line (SPARK_IO.Standard_Output, ", No listing file", 0);
            end if;
            if Do_VCG then
               SPARK_IO.Put_Line (SPARK_IO.Standard_Output, ", VCG", 0);
            end if;
            ScreenEcho.New_Line (1);
         end if;
      end Trace_Meta_Filenames;

   begin -- Process_Files
      Initialise_Processing;
      Open_Error_List;
      if Error_File_Status = SPARK_IO.Ok then
         ErrorHandler.Read_Warning_File;
         Dictionary.Read_Target_Data_File;
         --# accept F, 10, Config_Read, "Not required here" &
         --#        F, 33, Config_Read, "Not required here";
         ConfigFile.Read_Config_File (Opened_OK => Config_Read,
                                      No_Errors => Config_Success);
         if Config_Success then
            for CurrentSource in CommandLineData.Source_File_Positions range 1 .. CommandLineData.Content.Number_Source loop
               Filename := CommandLineData.Content.Source_File_List (CurrentSource).Source_File_Name;
               if E_Strings.Get_Element (E_Str => Filename,
                                         Pos   => 1) = '@' then -- process a meta file
                  MetaFile.Create (Filename, The_Meta_File);
                  loop
                     MetaFile.Next_Name
                       (The_Meta_File    => The_Meta_File,
                        The_Filename     => The_Filename,
                        Do_Listing       => Do_Listing,
                        The_Listing_Name => The_Listing_Name,
                        Do_VCG           => Do_VCG,
                        File_Found       => File_Found);
                     exit when not File_Found;

                     Trace_Meta_Filenames
                       (The_Filename     => The_Filename,
                        Do_Listing       => Do_Listing,
                        The_Listing_Name => The_Listing_Name,
                        Do_VCG           => Do_VCG,
                        File_Found       => File_Found);

                     Prepare_Next_Argument_File
                       (The_Filename     => The_Filename,
                        Do_Listing       => Do_Listing,
                        The_Listing_Name => The_Listing_Name,
                        Do_VCG           => Do_VCG,
                        File_Descriptor  => File_Descriptor);
                     ContextManager.Ops.Open_File (File_Descriptor => File_Descriptor);
                     if ContextManager.Ops.GetFileStatus (File_Descriptor) /= ContextManager.UnableToOpen then
                        Process_Units (File_Descriptor => File_Descriptor);
                        Close_File
                          (File_Descriptor        => File_Descriptor,
                           Report_File_Error_List => Report_File_Error_List,
                           Report_Needed          => CommandLineData.Content.Report);
                     end if;
                     --# accept W, 169, CommandLineData.Content.VCG, "Direct updates OK here";
                     CommandLineData.Content.VCG := Do_VCG;
                     --# end accept;
                  end loop;

               else -- its a single source file

                  --# accept F, 10, File_Status, "Expect File_Status Unused";
                  FileSystem.Find_Full_File_Name
                    (File_Spec      => Filename,
                     File_Status    => File_Status,
                     Full_File_Name => The_Filename);
                  --# end accept;
                  The_Listing_Name := CommandLineData.Content.Source_File_List (CurrentSource).Listing_File_Name;
                  Do_Listing       := CommandLineData.Content.Source_File_List (CurrentSource).Listing;
                  Do_VCG           := CommandLineData.Content.VCG;
                  Prepare_Next_Argument_File
                    (The_Filename     => The_Filename,
                     Do_Listing       => Do_Listing,
                     The_Listing_Name => The_Listing_Name,
                     Do_VCG           => Do_VCG,
                     File_Descriptor  => File_Descriptor);
                  ContextManager.Ops.Open_File (File_Descriptor => File_Descriptor);
                  if ContextManager.Ops.GetFileStatus (File_Descriptor) /= ContextManager.UnableToOpen then
                     Process_Units (File_Descriptor => File_Descriptor);
                     Close_File
                       (File_Descriptor        => File_Descriptor,
                        Report_File_Error_List => Report_File_Error_List,
                        Report_Needed          => CommandLineData.Content.Report);
                  end if;
                  --# accept W, 169, CommandLineData.Content.VCG, "Direct updates OK here";
                  CommandLineData.Content.VCG := Do_VCG;
                  --# end accept;
               end if;
            end loop;  --each file on command line
         else
            Echo_Warning_Or_Note
              (About_File => CommandLineData.Content.Target_Config_File,
               Msg        => "Warning - analysis aborted due to errors in target configuration file",
               Important  => True);
         end if;
         LexTokenManager.Report_Usage;
         Dictionary.ReportUsage;
         STree.ReportUsage;
         SLI.Cleanup;
         --# accept F, 10, Report_File_Error_List, "Final assignment on Close";
         Output_Report_File (Report_File_Error_List => Report_File_Error_List);
         --# end accept;
         Output_Dictionary_File;
         if CommandLineData.Content.Syntax_Only then
            Echo_Warning_Or_Note
              (About_File => CommandLineData.Content.Source_File_List (1).Source_File_Name,
               Msg        => "Warning - No semantic checks carried out, text may not be legal SPARK",
               Important  => True);
         end if;
         if CommandLineData.Content.VCG
           and then -- Any sort of VC generation requested
           not VCG.Invoked
           and then              -- and VCG not actually invoked on any body
           ErrorHandler.Get_Errors_Type < 3 then   -- and no syntax or semantic errors

            Echo_Warning_Or_Note
              (About_File => CommandLineData.Content.Source_File_List (1).Source_File_Name,
               Msg        => "Warning - VC generation requested but no bodies presented. No VCs generated.",
               Important  => False);
         end if;

         case CommandLineData.Content.Language_Profile is
            when CommandLineData.SPARK83 =>
               Echo_Warning_Or_Note
                 (About_File => CommandLineData.Content.Source_File_List (1).Source_File_Name,
                  Msg        => "Note - Ada83 language rules selected",
                  Important  => False);

            when CommandLineData.SPARK95_Onwards =>
               null;
         end case;

         ErrorHandler.Echo_Total_Error_Count;

         if CommandLineData.Content.Echo and not CommandLineData.Content.Brief then
            ScreenEcho.New_Line (2);
            ScreenEcho.Put_Line ("-----------End of SPARK Examination--------------------------------");
         end if;
      else -- Error_File_Status test
         Echo_Warning_Or_Note
           (About_File => CommandLineData.Content.Source_File_List (1).Source_File_Name,
            Msg        => "Creating temp error file failed. Check existence and ACL of temp directory",
            Important  => True);
      end if;
      --# accept Flow, 33, File_Status, "Expect File_Status unused" &
      --#        Flow, 602, Sem.State, Sem.State, "Expect undefined initial value";
   end Process_Files;

end MainLoop;
