-------------------------------------------------------------------------------
-- (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 SLI;
with SystemErrors;

separate (Sem)
procedure Wf_Property_List
  (Node          : in     STree.SyntaxNode;
   Type_Node_Pos : in     LexTokenManager.Token_Position;
   Scope         : in     Dictionary.Scopes;
   The_Owner     : in     Dictionary.Symbol;
   The_Heap      : in out Heap.HeapRecord)
is

   Property_Node : STree.SyntaxNode;
   It            : STree.Iterator;

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

   procedure Wf_Interrupt_Property
     (Name_Node        : in STree.SyntaxNode;
      Value_Node       : in STree.SyntaxNode;
      Scope            : in Dictionary.Scopes;
      The_Own_Variable : in Dictionary.Symbol)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     ContextManager.Ops.Unit_Stack;
   --#        in     STree.Table;
   --#        in out Dictionary.Dict;
   --#        in out ErrorHandler.Error_Context;
   --#        in out LexTokenManager.State;
   --#        in out SLI.State;
   --#        in out SPARK_IO.File_Sys;
   --# derives Dictionary.Dict            from *,
   --#                                         CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         LexTokenManager.State,
   --#                                         Scope,
   --#                                         STree.Table,
   --#                                         The_Own_Variable,
   --#                                         Value_Node &
   --#         ErrorHandler.Error_Context from *,
   --#                                         CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Name_Node,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table,
   --#                                         The_Own_Variable,
   --#                                         Value_Node &
   --#         LexTokenManager.State      from *,
   --#                                         CommandLineData.Content,
   --#                                         Dictionary.Dict,
   --#                                         Scope,
   --#                                         The_Own_Variable &
   --#         SLI.State                  from *,
   --#                                         CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Heap,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Name_Node,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table,
   --#                                         The_Own_Variable,
   --#                                         Value_Node &
   --#         SPARK_IO.File_Sys          from *,
   --#                                         CommandLineData.Content,
   --#                                         ContextManager.Ops.File_Heap,
   --#                                         ContextManager.Ops.Unit_Heap,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Name_Node,
   --#                                         Scope,
   --#                                         SLI.State,
   --#                                         STree.Table,
   --#                                         The_Own_Variable,
   --#                                         Value_Node;
   --# pre Syntax_Node_Type (Name_Node, STree.Table) = SP_Symbols.identifier and
   --#   (Syntax_Node_Type (Value_Node, STree.Table) = SP_Symbols.annotation_aggregate_or_expression or
   --#      Value_Node = STree.NullNode);
   is
      Consistent       : Boolean;
      Unused_Value_Rep : LexTokenManager.Lex_String;
      It               : STree.Iterator;
      Next_Node        : STree.SyntaxNode;

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

      procedure Process_One_Element (Node      : in STree.SyntaxNode;
                                     The_Owner : in Dictionary.Symbol)
      --# global in     CommandLineData.Content;
      --#        in     ContextManager.Ops.Unit_Stack;
      --#        in     LexTokenManager.State;
      --#        in     STree.Table;
      --#        in out Dictionary.Dict;
      --#        in out ErrorHandler.Error_Context;
      --#        in out SPARK_IO.File_Sys;
      --# derives Dictionary.Dict            from *,
      --#                                         CommandLineData.Content,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         LexTokenManager.State,
      --#                                         Node,
      --#                                         STree.Table,
      --#                                         The_Owner &
      --#         ErrorHandler.Error_Context,
      --#         SPARK_IO.File_Sys          from CommandLineData.Content,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         LexTokenManager.State,
      --#                                         Node,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table,
      --#                                         The_Owner;
      --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.annotation_aggregate_choice_rep;
      is
         It                       : Dictionary.Iterator;
         Handler_Lex_Str          : LexTokenManager.Lex_String;
         Interrupt_Stream_Lex_Str : LexTokenManager.Lex_String;
         OK_To_Add                : Boolean;
      begin
         -- Extract the handler name
         Handler_Lex_Str :=
           Node_Lex_String
           (Node => Get_Node
              (It => Find_First_Node (Node_Kind    => SP_Symbols.identifier,
                                      From_Root    => Node,
                                      In_Direction => STree.Down)));

         -- Extract the stream name
         Interrupt_Stream_Lex_Str :=
           Node_Lex_String
           (Node => Get_Node
              (It => Find_First_Node
                 (Node_Kind    => SP_Symbols.identifier,
                  From_Root    => Next_Sibling (Node),
                  In_Direction => STree.Down)));

         -- Check the handler is not already in the list
         OK_To_Add := True;
         It        := Dictionary.FirstInterruptStreamMapping (The_Owner);
         while OK_To_Add and not Dictionary.IsNullIterator (It) loop
            OK_To_Add :=
              LexTokenManager.Lex_String_Case_Insensitive_Compare
              (Lex_Str1 => Dictionary.GetInterruptStreamMappingHandler (Dictionary.CurrentSymbol (It)),
               Lex_Str2 => Handler_Lex_Str) /=
              LexTokenManager.Str_Eq;
            It        := Dictionary.NextSymbol (It);
         end loop;

         if OK_To_Add then
            -- This is not a duplicate
            -- Record the mapping of handler onto stream
            Dictionary.AddInterruptStreamMapping
              (Subject             => The_Owner,
               Comp_Unit           => ContextManager.Ops.Current_Unit,
               Declaration         => Dictionary.Location'(Start_Position => Node_Position (Node => Node),
                                                           End_Position   => Node_Position (Node => Node)),
               TheInterruptHandler => Handler_Lex_Str,
               TheInterruptStream  => Interrupt_Stream_Lex_Str);

            -- If the protected type is declared in another package we can create the
            -- implicit interrupt stream variable now.
            if Dictionary.Is_Declared (Item => Dictionary.GetType (The_Owner)) then
               Create_Interrupt_Stream_Variable
                 (For_PO              => The_Owner,
                  The_Handler         => Handler_Lex_Str,
                  The_Stream_Variable => Interrupt_Stream_Lex_Str,
                  Error_Node_Pos      => Node_Position (Node => Node));
            end if;
         else
            -- This is a duplicate
            ErrorHandler.Semantic_Error
              (Err_Num   => 956,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Position (Node => Node),
               Id_Str    => Handler_Lex_Str);
         end if;
      end Process_One_Element;

   begin -- Wf_Interrupt_Property
      if not (Dictionary.IsOwnVariable (The_Own_Variable)
                and then Dictionary.GetOwnVariableProtected (The_Own_Variable)
                and then Dictionary.OwnVariableHasType (The_Own_Variable, Scope)) then
         -- The interrupt property can only apply to protected own variables that
         -- are type announced.
         ErrorHandler.Semantic_Error
           (Err_Num   => 936,
            Reference => ErrorHandler.No_Reference,
            Position  => Node_Position (Node => Parent_Node (Current_Node => Name_Node)),
            Id_Str    => Dictionary.GetSimpleName (The_Own_Variable));
      else
         Check_Interrupt_Property_Consistency
           (Has_Interrupt_Property => True,
            Sym                    => The_Own_Variable,
            Type_Sym               => Dictionary.GetType (The_Own_Variable),
            Error_Node_Pos         => Node_Position (Node => Name_Node),
            Consistent             => Consistent);
         if Consistent then
            if LexTokenManager.Lex_String_Case_Insensitive_Compare
              (Lex_Str1 => Dictionary.GetPriorityProperty (The_Own_Variable),
               Lex_Str2 => LexTokenManager.Null_String) /=
              LexTokenManager.Str_Eq then
               --# accept Flow, 10, Unused_Value_Rep, "Expected ineffective assignment";
               Check_Priority_Range
                 (Error_Sym   => The_Own_Variable,
                  Scope       => Scope,
                  Pragma_Kind => Dictionary.AttachHandler,
                  Err_Pos     => Node_Position (Node => Parent_Node (Current_Node => Name_Node)),
                  Value       => Maths.ValueRep (Dictionary.GetPriorityProperty (The_Own_Variable)),
                  Value_Rep   => Unused_Value_Rep);
               --# end accept;
            end if;
            Dictionary.SetHasInterruptProperty (The_Own_Variable);
            -- Parse the interrupt stream list if there is one
            if Syntax_Node_Type (Node => Value_Node) = SP_Symbols.annotation_aggregate_or_expression then
               It :=
                 Find_First_Node
                 (Node_Kind    => SP_Symbols.annotation_aggregate_choice_rep,
                  From_Root    => Value_Node,
                  In_Direction => STree.Down);
               while not STree.IsNull (It) loop
                  Next_Node := Get_Node (It => It);
                  --# assert Syntax_Node_Type (Next_Node, STree.Table) = SP_Symbols.annotation_aggregate_choice_rep and
                  --#   Next_Node = Get_Node (It);
                  Process_One_Element (Node      => Next_Node,
                                       The_Owner => The_Own_Variable);
                  It := STree.NextNode (It);
               end loop;
            end if;
         end if;
      end if;
      if ErrorHandler.Generate_SLI then
         SLI.Generate_Xref_Interrupt (Comp_Unit  => ContextManager.Ops.Current_Unit,
                                      Parse_Tree => Value_Node,
                                      Scope      => Scope);
      end if;
      --# accept Flow, 33, Unused_Value_Rep, "Expected to be neither referenced nor exported";
   end Wf_Interrupt_Property;

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

   procedure Wf_Name_Property (Node      : in STree.SyntaxNode;
                               Scope     : in Dictionary.Scopes;
                               The_Owner : in Dictionary.Symbol)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     ContextManager.Ops.Unit_Stack;
   --#        in     STree.Table;
   --#        in out Dictionary.Dict;
   --#        in out ErrorHandler.Error_Context;
   --#        in out LexTokenManager.State;
   --#        in out SLI.State;
   --#        in out SPARK_IO.File_Sys;
   --# derives Dictionary.Dict            from *,
   --#                                         CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         STree.Table,
   --#                                         The_Owner &
   --#         ErrorHandler.Error_Context from *,
   --#                                         CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table,
   --#                                         The_Owner &
   --#         LexTokenManager.State      from *,
   --#                                         CommandLineData.Content,
   --#                                         Dictionary.Dict,
   --#                                         Node,
   --#                                         Scope,
   --#                                         STree.Table,
   --#                                         The_Owner &
   --#         SLI.State                  from *,
   --#                                         CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Heap,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table,
   --#                                         The_Owner &
   --#         SPARK_IO.File_Sys          from *,
   --#                                         CommandLineData.Content,
   --#                                         ContextManager.Ops.File_Heap,
   --#                                         ContextManager.Ops.Unit_Heap,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         SLI.State,
   --#                                         STree.Table,
   --#                                         The_Owner;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.name_property;
   is
      Name_Node : STree.SyntaxNode;
      Name_Str  : E_Strings.T;

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

      procedure Wf_Suspendable_Property
        (Node_Pos         : in LexTokenManager.Token_Position;
         Scope            : in Dictionary.Scopes;
         The_Own_Variable : in Dictionary.Symbol)
      --# global in     CommandLineData.Content;
      --#        in     LexTokenManager.State;
      --#        in out Dictionary.Dict;
      --#        in out ErrorHandler.Error_Context;
      --#        in out SPARK_IO.File_Sys;
      --# derives Dictionary.Dict            from *,
      --#                                         CommandLineData.Content,
      --#                                         Scope,
      --#                                         The_Own_Variable &
      --#         ErrorHandler.Error_Context,
      --#         SPARK_IO.File_Sys          from CommandLineData.Content,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         LexTokenManager.State,
      --#                                         Node_Pos,
      --#                                         Scope,
      --#                                         SPARK_IO.File_Sys,
      --#                                         The_Own_Variable;
      is
         Type_Sym   : Dictionary.Symbol;
         Consistent : Boolean;
      begin
         if Dictionary.IsOwnVariable (The_Own_Variable) and then Dictionary.OwnVariableHasType (The_Own_Variable, Scope) then
            Type_Sym := Dictionary.GetType (The_Own_Variable);
         else
            Type_Sym := Dictionary.GetUnknownTypeMark;
         end if;
         Check_Suspendable_Property_Consistency
           (Sym                 => The_Own_Variable,
            Type_Sym            => Type_Sym,
            Is_In_Suspends_List => True,
            Error_Node_Pos      => Node_Pos,
            Consistent          => Consistent);
         if Consistent then
            Dictionary.SetIsSuspendable (The_Own_Variable);
         end if;
      end Wf_Suspendable_Property;

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

      procedure Wf_Delay_Property
        (Node          : in STree.SyntaxNode;
         Scope         : in Dictionary.Scopes;
         The_Procedure : in Dictionary.Symbol)
      --# global in     CommandLineData.Content;
      --#        in     LexTokenManager.State;
      --#        in     STree.Table;
      --#        in out Dictionary.Dict;
      --#        in out ErrorHandler.Error_Context;
      --#        in out SPARK_IO.File_Sys;
      --# derives Dictionary.Dict            from *,
      --#                                         Scope,
      --#                                         The_Procedure &
      --#         ErrorHandler.Error_Context,
      --#         SPARK_IO.File_Sys          from CommandLineData.Content,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         LexTokenManager.State,
      --#                                         Node,
      --#                                         Scope,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table,
      --#                                         The_Procedure;
      --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.RWdelay;
      is
      begin
         if not Dictionary.IsProcedure (The_Procedure) then
            -- Only procedures can have the delay property.
            ErrorHandler.Semantic_Error
              (Err_Num   => 918,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Position (Node => Parent_Node (Current_Node => Node)),
               Id_Str    => Dictionary.GetSimpleName (The_Procedure));
         elsif Dictionary.IsOrIsInProtectedScope (Scope) then
            -- Blocking annotation not allowed in protected scope.
            ErrorHandler.Semantic_Error
              (Err_Num   => 908,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Position (Node => Node),
               Id_Str    => LexTokenManager.Null_String);
         elsif Dictionary.HasDelayProperty (The_Procedure) then
            -- The applicable compilation unit already has a delay statement.
            ErrorHandler.Semantic_Error
              (Err_Num   => 888,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Position (Node => Parent_Node (Current_Node => Node)),
               Id_Str    => Dictionary.GetSimpleName (The_Procedure));
         else
            Dictionary.SetHasDelayProperty (The_Procedure);
         end if;
      end Wf_Delay_Property;

   begin -- Wf_Name_Property
      Name_Node := Child_Node (Current_Node => Node);
      -- ASSUME Name_Node = RWdelay OR identifier
      if Syntax_Node_Type (Node => Name_Node) = SP_Symbols.RWdelay then
         -- ASSUME Name_Node = RWdelay
         Wf_Delay_Property (Node          => Name_Node,
                            Scope         => Scope,
                            The_Procedure => The_Owner);
      elsif Syntax_Node_Type (Node => Name_Node) = SP_Symbols.identifier then
         -- ASSUME Name_Node = identifier
         Name_Str := LexTokenManager.Lex_String_To_String (Lex_Str => Node_Lex_String (Node => Name_Node));
         if E_Strings.Eq1_String (E_Str => Name_Str,
                                  Str   => "suspendable") then
            Wf_Suspendable_Property (Node_Pos         => Node_Position (Node => Name_Node),
                                     Scope            => Scope,
                                     The_Own_Variable => The_Owner);
         elsif E_Strings.Eq1_String (E_Str => Name_Str,
                                     Str   => "interrupt") then
            Wf_Interrupt_Property
              (Name_Node        => Name_Node,
               Value_Node       => STree.NullNode,
               Scope            => Scope,
               The_Own_Variable => The_Owner);
         else
            ErrorHandler.Semantic_Error
              (Err_Num   => 921,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Position (Node => Node),
               Id_Str    => Node_Lex_String (Node => Name_Node));
         end if;
      else
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Name_Node = RWdelay OR identifier in Wf_Name_Property");
      end if;
   end Wf_Name_Property;

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

   procedure Wf_Name_Value_Property
     (Node          : in     STree.SyntaxNode;
      Type_Node_Pos : in     LexTokenManager.Token_Position;
      Scope         : in     Dictionary.Scopes;
      The_Owner     : in     Dictionary.Symbol;
      The_Heap      : in out Heap.HeapRecord)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     ContextManager.Ops.Unit_Stack;
   --#        in out Aggregate_Stack.State;
   --#        in out Dictionary.Dict;
   --#        in out ErrorHandler.Error_Context;
   --#        in out LexTokenManager.State;
   --#        in out SLI.State;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Statistics.TableUsage;
   --#        in out STree.Table;
   --# derives Aggregate_Stack.State,
   --#         Statistics.TableUsage,
   --#         The_Heap                   from *,
   --#                                         CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         STree.Table,
   --#                                         The_Heap &
   --#         Dictionary.Dict,
   --#         LexTokenManager.State,
   --#         STree.Table                from CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         STree.Table,
   --#                                         The_Heap,
   --#                                         The_Owner &
   --#         ErrorHandler.Error_Context,
   --#         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,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         SLI.State,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table,
   --#                                         The_Heap,
   --#                                         The_Owner,
   --#                                         Type_Node_Pos;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.name_value_property;
   --# post STree.Table = STree.Table~;
   is
      Name_Node  : STree.SyntaxNode;
      Value_Node : STree.SyntaxNode;
      Name_Str   : E_Strings.T;

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

      procedure Wf_Priority_Property
        (Name_Node  : in     STree.SyntaxNode;
         Value_Node : in     STree.SyntaxNode;
         The_Owner  : in     Dictionary.Symbol;
         Scope      : in     Dictionary.Scopes;
         The_Heap   : in out Heap.HeapRecord)
      --# global in     CommandLineData.Content;
      --#        in     ContextManager.Ops.File_Heap;
      --#        in     ContextManager.Ops.Unit_Heap;
      --#        in     ContextManager.Ops.Unit_Stack;
      --#        in out Aggregate_Stack.State;
      --#        in out Dictionary.Dict;
      --#        in out ErrorHandler.Error_Context;
      --#        in out LexTokenManager.State;
      --#        in out SLI.State;
      --#        in out SPARK_IO.File_Sys;
      --#        in out Statistics.TableUsage;
      --#        in out STree.Table;
      --# derives Aggregate_Stack.State,
      --#         Statistics.TableUsage,
      --#         STree.Table,
      --#         The_Heap                   from *,
      --#                                         CommandLineData.Content,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Dictionary.Dict,
      --#                                         LexTokenManager.State,
      --#                                         Scope,
      --#                                         STree.Table,
      --#                                         The_Heap,
      --#                                         Value_Node &
      --#         Dictionary.Dict,
      --#         LexTokenManager.State      from CommandLineData.Content,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Dictionary.Dict,
      --#                                         LexTokenManager.State,
      --#                                         Scope,
      --#                                         STree.Table,
      --#                                         The_Heap,
      --#                                         The_Owner,
      --#                                         Value_Node &
      --#         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,
      --#                                         LexTokenManager.State,
      --#                                         Name_Node,
      --#                                         Scope,
      --#                                         SLI.State,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table,
      --#                                         The_Heap,
      --#                                         The_Owner,
      --#                                         Value_Node &
      --#         SLI.State                  from *,
      --#                                         CommandLineData.Content,
      --#                                         ContextManager.Ops.File_Heap,
      --#                                         ContextManager.Ops.Unit_Heap,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         LexTokenManager.State,
      --#                                         Scope,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table,
      --#                                         The_Heap,
      --#                                         Value_Node;
      --# pre Syntax_Node_Type (Name_Node, STree.Table) = SP_Symbols.identifier and
      --#   Syntax_Node_Type (Value_Node, STree.Table) = SP_Symbols.annotation_aggregate_or_expression;
      --# post STree.Table = STree.Table~;
      is
         Var_Type        : Dictionary.Symbol;
         Value_Rep       : LexTokenManager.Lex_String;
         Expression_Node : STree.SyntaxNode;
         Valid           : Boolean;

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

         function Determine_Pragma_Kind (The_Owner : Dictionary.Symbol) return Dictionary.RavenscarPragmas
         --# global in Dictionary.Dict;
         is
            Result : Dictionary.RavenscarPragmas;
         begin
            if Dictionary.IsOwnVariable (The_Owner) and then Dictionary.GetHasInterruptProperty (The_Owner) then
               Result := Dictionary.AttachHandler;
            else
               Result := Dictionary.InterruptPriority;
            end if;
            return Result;
         end Determine_Pragma_Kind;

      begin -- Wf_Priority_Property
         Expression_Node := Child_Node (Current_Node => Value_Node);
         -- ASSUME Expression_Node = annotation_aggregate OR annotation_expression
         if Syntax_Node_Type (Node => Expression_Node) = SP_Symbols.annotation_aggregate then
            -- ASSUME Expression_Node = annotation_aggregate
            -- The grammar allows an aggregate here but for the priority property
            -- value we must have a static expression.
            ErrorHandler.Semantic_Error
              (Err_Num   => 945,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Position (Node => Value_Node),
               Id_Str    => Node_Lex_String (Node => Name_Node));
         elsif Syntax_Node_Type (Node => Expression_Node) = SP_Symbols.annotation_expression then
            -- ASSUME Expression_Node = annotation_expression
            Wf_Priority_Value
              (Node        => Expression_Node,
               Pragma_Kind => Determine_Pragma_Kind (The_Owner => The_Owner),
               Error_Sym   => The_Owner,
               Scope       => Scope,
               The_Heap    => The_Heap,
               Value_Rep   => Value_Rep,
               Compatible  => Valid);
            if Valid then
               if Dictionary.IsOwnVariable (The_Owner) and then Dictionary.OwnVariableHasType (The_Owner, Scope) then
                  Var_Type := Dictionary.GetType (The_Owner);
               else
                  Var_Type := Dictionary.GetUnknownTypeMark;
               end if;
               Check_Priority_Property_Consistency
                 (Sym                     => The_Owner,
                  Type_Sym                => Var_Type,
                  Priority_Property_Value => Value_Rep,
                  Error_Node_Pos          => Node_Position (Node => Name_Node),
                  Consistent              => Valid);
               if Valid then
                  Dictionary.SetPriorityProperty (OwnVariable => The_Owner,
                                                  TheValue    => Value_Rep);
               end if;
            end if;
         else
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect Expression_Node = annotation_aggregate OR annotation_expression in Wf_Priority_Property");
         end if;
      end Wf_Priority_Property;

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

      procedure Wf_Suspends_Property
        (Name_Node_Pos : in LexTokenManager.Token_Position;
         Value_Node    : in STree.SyntaxNode;
         Scope         : in Dictionary.Scopes;
         The_Owner     : in Dictionary.Symbol)
      --# global in     CommandLineData.Content;
      --#        in     ContextManager.Ops.File_Heap;
      --#        in     ContextManager.Ops.Unit_Heap;
      --#        in     ContextManager.Ops.Unit_Stack;
      --#        in     LexTokenManager.State;
      --#        in out Dictionary.Dict;
      --#        in out ErrorHandler.Error_Context;
      --#        in out SLI.State;
      --#        in out SPARK_IO.File_Sys;
      --#        in out STree.Table;
      --# derives Dictionary.Dict,
      --#         STree.Table                from CommandLineData.Content,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Dictionary.Dict,
      --#                                         LexTokenManager.State,
      --#                                         Scope,
      --#                                         STree.Table,
      --#                                         The_Owner,
      --#                                         Value_Node &
      --#         ErrorHandler.Error_Context from *,
      --#                                         CommandLineData.Content,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Dictionary.Dict,
      --#                                         LexTokenManager.State,
      --#                                         Name_Node_Pos,
      --#                                         Scope,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table,
      --#                                         The_Owner,
      --#                                         Value_Node &
      --#         SLI.State                  from *,
      --#                                         CommandLineData.Content,
      --#                                         ContextManager.Ops.Unit_Heap,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         LexTokenManager.State,
      --#                                         Name_Node_Pos,
      --#                                         Scope,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table,
      --#                                         The_Owner,
      --#                                         Value_Node &
      --#         SPARK_IO.File_Sys          from *,
      --#                                         CommandLineData.Content,
      --#                                         ContextManager.Ops.File_Heap,
      --#                                         ContextManager.Ops.Unit_Heap,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         LexTokenManager.State,
      --#                                         Name_Node_Pos,
      --#                                         Scope,
      --#                                         SLI.State,
      --#                                         STree.Table,
      --#                                         The_Owner,
      --#                                         Value_Node;
      --# pre Syntax_Node_Type (Value_Node, STree.Table) = SP_Symbols.annotation_aggregate_or_expression;
      --# post STree.Table = STree.Table~;
      is
         It             : STree.Iterator;
         Scope_To_Check : Dictionary.Scopes;
         Next_Node      : STree.SyntaxNode;

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

         procedure Process_One_PO_Or_SO
           (Value_Node : in STree.SyntaxNode;
            Scope      : in Dictionary.Scopes;
            The_Owner  : in Dictionary.Symbol)
         --# global in     CommandLineData.Content;
         --#        in     ContextManager.Ops.Unit_Stack;
         --#        in     LexTokenManager.State;
         --#        in out Dictionary.Dict;
         --#        in out ErrorHandler.Error_Context;
         --#        in out SPARK_IO.File_Sys;
         --#        in out STree.Table;
         --# derives Dictionary.Dict            from *,
         --#                                         CommandLineData.Content,
         --#                                         ContextManager.Ops.Unit_Stack,
         --#                                         LexTokenManager.State,
         --#                                         Scope,
         --#                                         STree.Table,
         --#                                         The_Owner,
         --#                                         Value_Node &
         --#         ErrorHandler.Error_Context,
         --#         SPARK_IO.File_Sys          from CommandLineData.Content,
         --#                                         Dictionary.Dict,
         --#                                         ErrorHandler.Error_Context,
         --#                                         LexTokenManager.State,
         --#                                         Scope,
         --#                                         SPARK_IO.File_Sys,
         --#                                         STree.Table,
         --#                                         The_Owner,
         --#                                         Value_Node &
         --#         STree.Table                from *,
         --#                                         CommandLineData.Content,
         --#                                         Dictionary.Dict,
         --#                                         LexTokenManager.State,
         --#                                         Scope,
         --#                                         Value_Node;
         --# pre Syntax_Node_Type (Value_Node, STree.Table) = SP_Symbols.annotation_primary;
         --# post STree.Table = STree.Table~;
         is
            Var_Sym : Dictionary.Symbol;
            Unused  : Boolean;
         begin
            --# accept Flow, 10, Unused, "Expected ineffective assignment";
            Wf_Entire_Variable
              (Node       => Value_Node,
               Scope      => Scope,
               Error_Hint => In_Suspends_List,
               Var_Sym    => Var_Sym,
               Dotted     => Unused);
            --# end accept;
            if not Dictionary.Is_Null_Symbol (Var_Sym) then
               if Dictionary.SuspendsOn (TheTaskOrProc => The_Owner,
                                         ThePOorSO     => Var_Sym) then
                  ErrorHandler.Semantic_Error_Sym
                    (Err_Num   => 890,
                     Reference => ErrorHandler.No_Reference,
                     Position  => Node_Position (Node => Value_Node),
                     Sym       => Var_Sym,
                     Scope     => Scope);
               elsif Dictionary.GetIsSuspendable (Var_Sym) then
                  Dictionary.AddPOorSOToSuspendsList
                    (TheTaskOrProc => The_Owner,
                     Comp_Unit     => ContextManager.Ops.Current_Unit,
                     Declaration   => Dictionary.Location'(Start_Position => Node_Position (Node => Value_Node),
                                                           End_Position   => Node_Position (Node => Value_Node)),
                     ThePOorSO     => Var_Sym);
               else
                  -- This symbol cannot suspend.
                  ErrorHandler.Semantic_Error_Sym
                    (Err_Num   => 909,
                     Reference => ErrorHandler.No_Reference,
                     Position  => Node_Position (Node => Value_Node),
                     Sym       => Var_Sym,
                     Scope     => Scope);
               end if;
            end if;
            --# accept Flow, 33, Unused, "Expected to be neither referenced nor exported";
         end Process_One_PO_Or_SO;

      begin -- Wf_Suspends_Property
         if Dictionary.IsOwnTask (The_Owner) then
            Scope_To_Check := Scope;
         else
            Scope_To_Check := Dictionary.Set_Visibility (The_Visibility => Dictionary.Local,
                                                         The_Unit       => The_Owner);
         end if;

         if not ((Dictionary.IsTypeMark (The_Owner) and then Dictionary.TypeIsTask (The_Owner))
                 or else (Dictionary.IsProcedure (The_Owner))) then
            -- The suspends list is not being applied to a valid construct.
            ErrorHandler.Semantic_Error
              (Err_Num   => 920,
               Reference => ErrorHandler.No_Reference,
               Position  => Name_Node_Pos,
               Id_Str    => Dictionary.GetSimpleName (The_Owner));
         elsif Dictionary.IsProcedure (The_Owner) and then Dictionary.IsOrIsInProtectedScope (Scope) then
            -- Blocking annotation not allowed in protected scope.
            ErrorHandler.Semantic_Error
              (Err_Num   => 908,
               Reference => ErrorHandler.No_Reference,
               Position  => Name_Node_Pos,
               Id_Str    => LexTokenManager.Null_String);
         else
            It :=
              Find_First_Node (Node_Kind    => SP_Symbols.annotation_primary,
                               From_Root    => Value_Node,
                               In_Direction => STree.Down);
            while not STree.IsNull (It) loop
               Next_Node := Get_Node (It => It);
               --# assert Syntax_Node_Type (Next_Node, STree.Table) = SP_Symbols.annotation_primary and
               --#   Next_Node = Get_Node (It) and
               --#   STree.Table = STree.Table~;
               Process_One_PO_Or_SO (Value_Node => Next_Node,
                                     Scope      => Scope_To_Check,
                                     The_Owner  => The_Owner);
               It := STree.NextNode (It);
            end loop;
         end if;
         if ErrorHandler.Generate_SLI then
            SLI.Generate_Xref_Suspends_Protects
              (Comp_Unit  => ContextManager.Ops.Current_Unit,
               Parse_Tree => Value_Node,
               Scope      => Scope_To_Check);
         end if;
      end Wf_Suspends_Property;

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

      procedure Wf_Protects_Property
        (Name_Node_Pos : in LexTokenManager.Token_Position;
         Value_Node    : in STree.SyntaxNode;
         Type_Node_Pos : in LexTokenManager.Token_Position;
         Scope         : in Dictionary.Scopes;
         The_Own_Var   : in Dictionary.Symbol)
      --# global in     CommandLineData.Content;
      --#        in     ContextManager.Ops.File_Heap;
      --#        in     ContextManager.Ops.Unit_Heap;
      --#        in     ContextManager.Ops.Unit_Stack;
      --#        in     LexTokenManager.State;
      --#        in out Dictionary.Dict;
      --#        in out ErrorHandler.Error_Context;
      --#        in out SLI.State;
      --#        in out SPARK_IO.File_Sys;
      --#        in out STree.Table;
      --# derives Dictionary.Dict,
      --#         STree.Table                from CommandLineData.Content,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Dictionary.Dict,
      --#                                         LexTokenManager.State,
      --#                                         Scope,
      --#                                         STree.Table,
      --#                                         The_Own_Var,
      --#                                         Value_Node &
      --#         ErrorHandler.Error_Context from *,
      --#                                         CommandLineData.Content,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Dictionary.Dict,
      --#                                         LexTokenManager.State,
      --#                                         Name_Node_Pos,
      --#                                         Scope,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table,
      --#                                         The_Own_Var,
      --#                                         Type_Node_Pos,
      --#                                         Value_Node &
      --#         SLI.State                  from *,
      --#                                         CommandLineData.Content,
      --#                                         ContextManager.Ops.Unit_Heap,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         LexTokenManager.State,
      --#                                         Name_Node_Pos,
      --#                                         Scope,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table,
      --#                                         The_Own_Var,
      --#                                         Type_Node_Pos,
      --#                                         Value_Node &
      --#         SPARK_IO.File_Sys          from *,
      --#                                         CommandLineData.Content,
      --#                                         ContextManager.Ops.File_Heap,
      --#                                         ContextManager.Ops.Unit_Heap,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         LexTokenManager.State,
      --#                                         Name_Node_Pos,
      --#                                         Scope,
      --#                                         SLI.State,
      --#                                         STree.Table,
      --#                                         The_Own_Var,
      --#                                         Type_Node_Pos,
      --#                                         Value_Node;
      --# pre Syntax_Node_Type (Value_Node, STree.Table) = SP_Symbols.annotation_aggregate_or_expression;
      --# post STree.Table = STree.Table~;
      is
         The_Own_Var_Type : Dictionary.Symbol;
         It               : STree.Iterator;
         Next_Node        : STree.SyntaxNode;

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

         procedure Process_One_Element
           (Value_Node       : in STree.SyntaxNode;
            Scope            : in Dictionary.Scopes;
            The_Own_Var      : in Dictionary.Symbol;
            The_Own_Var_Type : in Dictionary.Symbol)
         --# global in     CommandLineData.Content;
         --#        in     ContextManager.Ops.Unit_Stack;
         --#        in     LexTokenManager.State;
         --#        in out Dictionary.Dict;
         --#        in out ErrorHandler.Error_Context;
         --#        in out SPARK_IO.File_Sys;
         --#        in out STree.Table;
         --# derives Dictionary.Dict            from *,
         --#                                         CommandLineData.Content,
         --#                                         ContextManager.Ops.Unit_Stack,
         --#                                         LexTokenManager.State,
         --#                                         Scope,
         --#                                         STree.Table,
         --#                                         The_Own_Var,
         --#                                         The_Own_Var_Type,
         --#                                         Value_Node &
         --#         ErrorHandler.Error_Context,
         --#         SPARK_IO.File_Sys          from CommandLineData.Content,
         --#                                         Dictionary.Dict,
         --#                                         ErrorHandler.Error_Context,
         --#                                         LexTokenManager.State,
         --#                                         Scope,
         --#                                         SPARK_IO.File_Sys,
         --#                                         STree.Table,
         --#                                         The_Own_Var,
         --#                                         Value_Node &
         --#         STree.Table                from *,
         --#                                         CommandLineData.Content,
         --#                                         Dictionary.Dict,
         --#                                         LexTokenManager.State,
         --#                                         Scope,
         --#                                         Value_Node;
         --# pre Syntax_Node_Type (Value_Node, STree.Table) = SP_Symbols.annotation_primary;
         --# post STree.Table = STree.Table~;
         is
            Protects_Item_Sym : Dictionary.Symbol;
            Is_Dotted         : Boolean;
         begin
            Wf_Entire_Variable
              (Node       => Value_Node,
               Scope      => Scope,
               Error_Hint => In_Suspends_List,
               Var_Sym    => Protects_Item_Sym,
               Dotted     => Is_Dotted);
            if not Dictionary.Is_Null_Symbol (Protects_Item_Sym) then
               if not Dictionary.IsOwnVariable (Protects_Item_Sym)
                 or else Is_Dotted
                 or else Dictionary.GetOwnVariableProtected (Protects_Item_Sym) then
                  -- Items in protects properties must be local, unprotected own variables.
                  ErrorHandler.Semantic_Error_Sym
                    (Err_Num   => 943,
                     Reference => ErrorHandler.No_Reference,
                     Position  => Node_Position (Node => Value_Node),
                     Sym       => Protects_Item_Sym,
                     Scope     => Scope);
               elsif Dictionary.GetOwnVariableMode (The_Own_Var) /= Dictionary.DefaultMode
                 and then Dictionary.GetOwnVariableMode (The_Own_Var) /= Dictionary.GetOwnVariableMode (Protects_Item_Sym) then
                  -- Refinement constituent mode mismatch
                  ErrorHandler.Semantic_Error_Sym
                    (Err_Num   => 701,
                     Reference => ErrorHandler.No_Reference,
                     Position  => Node_Position (Node => Value_Node),
                     Sym       => Protects_Item_Sym,
                     Scope     => Scope);
               elsif Dictionary.IsVirtualElement (Protects_Item_Sym) then
                  -- This item has already appeared in another protects list.
                  ErrorHandler.Semantic_Error_Sym2
                    (Err_Num   => 944,
                     Reference => ErrorHandler.No_Reference,
                     Position  => Node_Position (Node => Value_Node),
                     Sym       => Protects_Item_Sym,
                     Sym2      => Dictionary.GetVirtualElementOwner (Protects_Item_Sym),
                     Scope     => Scope);
               else
                  -- Add this variable to the protects list for the type.
                  Dictionary.AddVirtualElement
                    (ToProtectedType   => The_Own_Var_Type,
                     Comp_Unit         => ContextManager.Ops.Current_Unit,
                     Declaration       => Dictionary.Location'(Start_Position => Node_Position (Node => Value_Node),
                                                               End_Position   => Node_Position (Node => Value_Node)),
                     TheVirtualElement => Protects_Item_Sym,
                     TheOwner          => The_Own_Var);
               end if;
            end if;
         end Process_One_Element;

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

         function Value_Is_Correct_Format (Value_Node : STree.SyntaxNode) return Boolean
         --# global in STree.Table;
         --# pre Syntax_Node_Type (Value_Node, STree.Table) = SP_Symbols.annotation_aggregate_or_expression;
         -- The allowable values are:
         -- (1) protects => X
         -- (2) protects => (X)
         -- (3) protects => (X, Y, Z)
         -- Hence the only branch allowed in the syntax tree for the above is at nodes
         -- of type annotation_positional_association_rep vis (3).
         -- However, we also allow
         -- (4) protects => X.Y
         -- i.e. a branch at nodes of type annotation_selected_component.
         -- This ensures we get the more meaningful error message (943).
         is
            It     : STree.Iterator;
            Result : Boolean := True;
         begin
            It := Find_First_Branch_Node (From_Root    => Value_Node,
                                          In_Direction => STree.Down);
            while not STree.IsNull (It) loop
               if Syntax_Node_Type (Node => Get_Node (It => It)) /= SP_Symbols.annotation_positional_association_rep
                 and then Syntax_Node_Type (Node => Get_Node (It => It)) /= SP_Symbols.annotation_selected_component then
                  Result := False;
                  exit;
               end if;
               It := STree.NextNode (It);
            end loop;
            return Result;
         end Value_Is_Correct_Format;

      begin -- Wf_Protects_Property
         if Dictionary.IsOwnVariable (The_Own_Var)
           and then Dictionary.GetOwnVariableProtected (The_Own_Var)
           and then Dictionary.OwnVariableHasType (OwnVariable => The_Own_Var,
                                                   Scope       => Scope) then
            The_Own_Var_Type := Dictionary.GetRootType (Dictionary.GetType (The_Own_Var));
            if Dictionary.Is_Declared (Item => The_Own_Var_Type) then
               -- The type of the own variable must be local to this package.
               ErrorHandler.Semantic_Error
                 (Err_Num   => 941,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Type_Node_Pos,
                  Id_Str    => Dictionary.GetSimpleName (The_Own_Var));
            elsif not Value_Is_Correct_Format (Value_Node => Value_Node) then
               -- The format must be a simple expression or a position associated
               -- aggregate.
               ErrorHandler.Semantic_Error
                 (Err_Num   => 961,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Value_Node),
                  Id_Str    => Dictionary.GetSimpleName (The_Own_Var));
            else
               It :=
                 Find_First_Node
                 (Node_Kind    => SP_Symbols.annotation_primary,
                  From_Root    => Value_Node,
                  In_Direction => STree.Down);
               while not STree.IsNull (It) loop
                  Next_Node := Get_Node (It => It);
                  --# assert Syntax_Node_Type (Next_Node, STree.Table) = SP_Symbols.annotation_primary and
                  --#   Next_Node = Get_Node (It) and
                  --#   STree.Table = STree.Table~;
                  Process_One_Element
                    (Value_Node       => Next_Node,
                     Scope            => Scope,
                     The_Own_Var      => The_Own_Var,
                     The_Own_Var_Type => The_Own_Var_Type);
                  It := STree.NextNode (It);
               end loop;
            end if;
         else
            -- The protects property must be applied to protected own variables
            ErrorHandler.Semantic_Error
              (Err_Num   => 937,
               Reference => ErrorHandler.No_Reference,
               Position  => Name_Node_Pos,
               Id_Str    => Dictionary.GetSimpleName (The_Own_Var));
         end if;
         if ErrorHandler.Generate_SLI then
            SLI.Generate_Xref_Suspends_Protects
              (Comp_Unit  => ContextManager.Ops.Current_Unit,
               Parse_Tree => Value_Node,
               Scope      => Scope);
         end if;
      end Wf_Protects_Property;

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

      procedure Wf_Integrity_Property
        (Name_Str         : in     LexTokenManager.Lex_String;
         Value_Node       : in     STree.SyntaxNode;
         Scope            : in     Dictionary.Scopes;
         The_Own_Variable : in     Dictionary.Symbol;
         The_Heap         : in out Heap.HeapRecord)
      --# global in     CommandLineData.Content;
      --#        in     ContextManager.Ops.File_Heap;
      --#        in     ContextManager.Ops.Unit_Heap;
      --#        in     ContextManager.Ops.Unit_Stack;
      --#        in out Aggregate_Stack.State;
      --#        in out Dictionary.Dict;
      --#        in out ErrorHandler.Error_Context;
      --#        in out LexTokenManager.State;
      --#        in out SLI.State;
      --#        in out SPARK_IO.File_Sys;
      --#        in out Statistics.TableUsage;
      --#        in out STree.Table;
      --# derives Aggregate_Stack.State,
      --#         LexTokenManager.State,
      --#         Statistics.TableUsage,
      --#         STree.Table,
      --#         The_Heap                   from *,
      --#                                         CommandLineData.Content,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Dictionary.Dict,
      --#                                         LexTokenManager.State,
      --#                                         Scope,
      --#                                         STree.Table,
      --#                                         The_Heap,
      --#                                         Value_Node &
      --#         Dictionary.Dict            from *,
      --#                                         CommandLineData.Content,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         LexTokenManager.State,
      --#                                         Scope,
      --#                                         STree.Table,
      --#                                         The_Heap,
      --#                                         The_Own_Variable,
      --#                                         Value_Node &
      --#         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,
      --#                                         LexTokenManager.State,
      --#                                         Name_Str,
      --#                                         Scope,
      --#                                         SLI.State,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table,
      --#                                         The_Heap,
      --#                                         Value_Node &
      --#         SLI.State                  from *,
      --#                                         CommandLineData.Content,
      --#                                         ContextManager.Ops.File_Heap,
      --#                                         ContextManager.Ops.Unit_Heap,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         LexTokenManager.State,
      --#                                         Scope,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table,
      --#                                         The_Heap,
      --#                                         Value_Node;
      --# pre Syntax_Node_Type (Value_Node, STree.Table) = SP_Symbols.annotation_aggregate_or_expression;
      --# post STree.Table = STree.Table~;
      is
         Expression_Node       : STree.SyntaxNode;
         Type_Sym              : Dictionary.Symbol;
         Result                : Exp_Record;
         Result_Rep            : LexTokenManager.Lex_String;
         Unused_Seq            : SeqAlgebra.Seq;
         Unused_Component_Data : ComponentManager.ComponentData;

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

         function Is_Natural_Integer (V : in Maths.Value) return Boolean is
            Comp   : Maths.Value;
            Result : Boolean;
            Unused : Maths.ErrorCode;
         begin
            if Maths.IsIntegerValue (V) then
               --# accept Flow, 10, Unused, "Expected ineffective assignment";
               Maths.GreaterOrEqual (V, Maths.ZeroInteger, Comp, Unused);
               Maths.ValueToBool (Comp, Result, Unused);
               --# end accept;
            else
               Result := False;
            end if;
            --# accept Flow, 33, Unused, "Expected to be neither referenced nor exported";
            return Result;
         end Is_Natural_Integer;

      begin -- Wf_Integrity_Property

         -- Value should be static expression, type Integer, and  >= 0

         Expression_Node := Child_Node (Current_Node => Value_Node);
         -- ASSUME Expression_Node = annotation_aggregate OR annotation_expression
         if Syntax_Node_Type (Node => Expression_Node) = SP_Symbols.annotation_aggregate then
            -- ASSUME Expression_Node = annotation_aggregate
            -- The grammar allows an aggregate here but for the integrity property
            -- value we must have a static expression.
            ErrorHandler.Semantic_Error
              (Err_Num   => 945,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Position (Node => Value_Node),
               Id_Str    => Name_Str);
         elsif Syntax_Node_Type (Node => Expression_Node) = SP_Symbols.annotation_expression then
            -- ASSUME Expression_Node = annotation_expression
            -- 1 walk the expression
            SeqAlgebra.CreateSeq (The_Heap, Unused_Seq);
            ComponentManager.Initialise (Unused_Component_Data);
            --# accept Flow, 10, Unused_Component_Data, "Expected ineffective assignment";
            Walk_Expression_P.Walk_Annotation_Expression
              (Exp_Node       => Expression_Node,
               Scope          => Scope,
               Type_Context   => Dictionary.GetPredefinedIntegerType,
               Context        => Precondition,
               Result         => Result,
               Component_Data => Unused_Component_Data,
               The_Heap       => The_Heap);
            --# end accept;
            SeqAlgebra.DisposeOfSeq (The_Heap, Unused_Seq);
            -- 2 check it's constant
            if Result.Is_Constant then
               -- 3 check type
               Type_Sym := Dictionary.GetRootType (Result.Type_Symbol);
               if Dictionary.CompatibleTypes (Scope, Type_Sym, Dictionary.GetPredefinedIntegerType)
                 and then
                 -- 4 check >= 0
                 Is_Natural_Integer (V => Result.Value) then
                  Maths.StorageRep (Result.Value, Result_Rep);
                  Dictionary.SetIntegrityProperty (The_Own_Variable, Result_Rep);
               else
                  ErrorHandler.Semantic_Error
                    (Err_Num   => 882,
                     Reference => ErrorHandler.No_Reference,
                     Position  => Node_Position (Node => Expression_Node),
                     Id_Str    => LexTokenManager.Null_String);
               end if;
            else
               ErrorHandler.Semantic_Error
                 (Err_Num   => 37,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Expression_Node),
                  Id_Str    => LexTokenManager.Null_String);
            end if;
         else
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect Expression_Node = annotation_aggregate OR annotation_expression in Wf_Integrity_Property");
         end if;
      end Wf_Integrity_Property;

   begin -- Wf_Name_Value_Property
      Name_Node := Child_Node (Current_Node => Node);
      -- ASSUME Name_Node = identifier
      SystemErrors.RT_Assert
        (C       => Syntax_Node_Type (Node => Name_Node) = SP_Symbols.identifier,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Name_Node = identifier in Wf_Name_Value_Property");
      Name_Str := LexTokenManager.Lex_String_To_String (Lex_Str => Node_Lex_String (Node => Name_Node));

      Value_Node := Next_Sibling (Current_Node => Name_Node);
      -- ASSUME Value_Node = annotation_aggregate_or_expression
      SystemErrors.RT_Assert
        (C       => Syntax_Node_Type (Node => Value_Node) = SP_Symbols.annotation_aggregate_or_expression,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Value_Node = annotation_aggregate_or_expression in Wf_Name_Value_Property");

      if E_Strings.Eq1_String (E_Str => Name_Str,
                               Str   => "priority") then
         Wf_Priority_Property
           (Name_Node  => Name_Node,
            Value_Node => Value_Node,
            The_Owner  => The_Owner,
            Scope      => Scope,
            The_Heap   => The_Heap);
      elsif E_Strings.Eq1_String (E_Str => Name_Str,
                                  Str   => "suspends") then
         Wf_Suspends_Property
           (Name_Node_Pos => Node_Position (Node => Name_Node),
            Value_Node    => Value_Node,
            Scope         => Scope,
            The_Owner     => The_Owner);
      elsif E_Strings.Eq1_String (E_Str => Name_Str,
                                  Str   => "protects") then
         Wf_Protects_Property
           (Name_Node_Pos => Node_Position (Node => Name_Node),
            Value_Node    => Value_Node,
            Type_Node_Pos => Type_Node_Pos,
            Scope         => Scope,
            The_Own_Var   => The_Owner);
      elsif E_Strings.Eq1_String (E_Str => Name_Str,
                                  Str   => "interrupt") then
         Wf_Interrupt_Property (Name_Node        => Name_Node,
                                Value_Node       => Value_Node,
                                Scope            => Scope,
                                The_Own_Variable => The_Owner);
      elsif E_Strings.Eq1_String (E_Str => Name_Str,
                                  Str   => "integrity") then
         Wf_Integrity_Property
           (Name_Str         => Node_Lex_String (Node => Name_Node),
            Value_Node       => Value_Node,
            Scope            => Scope,
            The_Own_Variable => The_Owner,
            The_Heap         => The_Heap);
      else
         ErrorHandler.Semantic_Error
           (Err_Num   => 921,
            Reference => ErrorHandler.No_Reference,
            Position  => Node_Position (Node => Node),
            Id_Str    => Node_Lex_String (Node => Name_Node));
      end if;
   end Wf_Name_Value_Property;

begin -- Wf_Property_List
   It := Find_First_Node (Node_Kind    => SP_Symbols.property,
                          From_Root    => Node,
                          In_Direction => STree.Down);
   while not STree.IsNull (It) loop
      --# assert STree.Table = STree.Table~;
      -- ASSUME It = property
      Property_Node := Child_Node (Current_Node => Get_Node (It => It));
      -- ASSUME Property_Node = name_property OR name_value_property
      if Syntax_Node_Type (Node => Property_Node) = SP_Symbols.name_property then
         -- ASSUME Property_Node = name_property
         Wf_Name_Property (Node      => Property_Node,
                           Scope     => Scope,
                           The_Owner => The_Owner);
      elsif Syntax_Node_Type (Node => Property_Node) = SP_Symbols.name_value_property then
         -- ASSUME Property_Node = name_value_property
         Wf_Name_Value_Property
           (Node          => Property_Node,
            Type_Node_Pos => Type_Node_Pos,
            Scope         => Scope,
            The_Owner     => The_Owner,
            The_Heap      => The_Heap);
      else
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Property_Node = name_property OR name_value_property in Wf_Property_List");
      end if;
      It := STree.NextNode (It);
   end loop;
end Wf_Property_List;
