-------------------------------------------------------------------------------
-- (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.
--
--=============================================================================

separate (Dictionary)
function LookupSelectedItem
  (Prefix   : Symbol;
   Selector : LexTokenManager.Lex_String;
   Scope    : Scopes;
   Context  : Contexts)
  return     Symbol
is
   Item : Symbol;

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

   function Lookup_Selected_Item_In_Package
     (The_Package : RawDict.Package_Info_Ref;
      Name        : LexTokenManager.Lex_String;
      Scope       : Scopes;
      Context     : Contexts)
     return        Symbol
   --# global in CommandLineData.Content;
   --#        in Dict;
   --#        in LexTokenManager.State;
   is
      Region          : Symbol;
      The_Variable    : RawDict.Variable_Info_Ref;
      Item            : Symbol;
      Library_Package : RawDict.Package_Info_Ref;
      Is_Visible      : Boolean;

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

      procedure Lookup_Global_Variables
        (Abstraction  : in     Abstractions;
         The_Package  : in     RawDict.Package_Info_Ref;
         Name         : in     LexTokenManager.Lex_String;
         Subprogram   : in     Symbol;
         Context      : in     Contexts;
         The_Variable :    out RawDict.Variable_Info_Ref;
         Is_Visible   :    out Boolean)
      --# global in Dict;
      --#        in LexTokenManager.State;
      --#        in Scope;
      --# derives Is_Visible   from Abstraction,
      --#                           Context,
      --#                           Dict,
      --#                           LexTokenManager.State,
      --#                           Name,
      --#                           Scope,
      --#                           Subprogram,
      --#                           The_Package &
      --#         The_Variable from Abstraction,
      --#                           Dict,
      --#                           LexTokenManager.State,
      --#                           Name,
      --#                           Subprogram,
      --#                           The_Package;
      is
         The_Global_Variable : RawDict.Global_Variable_Info_Ref;

         function First_Global (Subprogram  : Symbol;
                                Abstraction : Abstractions) return RawDict.Global_Variable_Info_Ref
         --# global in Dict;
         is
            The_Global_Variable : RawDict.Global_Variable_Info_Ref;
         begin
            case RawDict.GetSymbolDiscriminant (Subprogram) is
               when Subprogram_Symbol =>
                  The_Global_Variable :=
                    RawDict.Get_Subprogram_First_Global_Variable
                    (The_Subprogram => RawDict.Get_Subprogram_Info_Ref (Item => Subprogram),
                     Abstraction    => Abstraction);
               when Type_Symbol => -- must be a task type
                  SystemErrors.RT_Assert
                    (C       => Is_Task_Type (Type_Mark => RawDict.Get_Type_Info_Ref (Item => Subprogram)),
                     Sys_Err => SystemErrors.Invalid_Symbol_Table,
                     Msg     => "in Dictionary.First_Global");
                  The_Global_Variable :=
                    RawDict.Get_Task_Type_First_Global_Variable
                    (The_Task_Type => RawDict.Get_Type_Info_Ref (Item => Subprogram),
                     Abstraction   => Abstraction);
               when others => -- non-exec code
                  The_Global_Variable := RawDict.Null_Global_Variable_Info_Ref;
                  SystemErrors.Fatal_Error (Sys_Err => SystemErrors.Invalid_Symbol_Table,
                                            Msg     => "in Dictionary.First_Global");
            end case;
            return The_Global_Variable;
         end First_Global;

         -- Two function lifted out to simplify Boolean expression in main procedure
         function Is_Directly_Visible
           (The_Variable : RawDict.Variable_Info_Ref;
            The_Package  : RawDict.Package_Info_Ref)
           return         Boolean
         --# global in Dict;
         is
         begin
            return Get_Variable_Scope (The_Variable => The_Variable) =
              Set_Visibility (The_Visibility => Visible,
                              The_Unit       => RawDict.Get_Package_Symbol (The_Package));
         end Is_Directly_Visible;

         function Is_Visible_To_A_Child
           (The_Variable                 : RawDict.Variable_Info_Ref;
            The_Package, Library_Package : RawDict.Package_Info_Ref)
           return                         Boolean
         --# global in Dict;
         is
         begin
            return Get_Variable_Scope (The_Variable => The_Variable) =
              Set_Visibility (The_Visibility => Privat,
                              The_Unit       => RawDict.Get_Package_Symbol (The_Package))
              and then Is_Proper_Descendent (Inner_Package => Library_Package,
                                             Outer_Package => The_Package);
         end Is_Visible_To_A_Child;

      begin -- Lookup_Global_Variables
         The_Global_Variable := First_Global (Subprogram  => Subprogram,
                                              Abstraction => Abstraction);
         loop
            if The_Global_Variable = RawDict.Null_Global_Variable_Info_Ref then
               The_Variable := RawDict.Null_Variable_Info_Ref;
               Is_Visible   := False;
               exit;
            end if;
            if RawDict.Get_Kind_Of_Global_Variable (The_Global_Variable => The_Global_Variable) =
              RawDict.Subprogram_Variable_Item
              or else RawDict.Get_Kind_Of_Global_Variable (The_Global_Variable => The_Global_Variable) =
              RawDict.Task_Type_Variable_Item then
               The_Variable := RawDict.Get_Global_Variable_Variable (The_Global_Variable => The_Global_Variable);
            else
               The_Variable := RawDict.Null_Variable_Info_Ref;
            end if;
            if The_Variable /= RawDict.Null_Variable_Info_Ref
              and then LexTokenManager.Lex_String_Case_Insensitive_Compare
              (Lex_Str1 => RawDict.Get_Variable_Name (The_Variable => The_Variable),
               Lex_Str2 => Name) =
              LexTokenManager.Str_Eq
              and then RawDict.Get_Global_Variable_Prefix_Needed (The_Global_Variable => The_Global_Variable)
              and then RawDict.GetSymbolDiscriminant (Get_Owner (The_Variable => The_Variable)) = Package_Symbol
              and then RawDict.Get_Package_Info_Ref (Item => Get_Owner (The_Variable => The_Variable)) = The_Package then
               if Context = ProofContext then
                  Is_Visible := True;
               elsif Variable_Is_Declared (The_Variable => The_Variable) then
                  Is_Visible :=
                    Is_Directly_Visible (The_Variable => The_Variable,
                                         The_Package  => The_Package)
                    or else Is_Visible_To_A_Child
                    (The_Variable    => The_Variable,
                     The_Package     => The_Package,
                     Library_Package => Get_Library_Package (Scope => Scope))
                    or else IsLocal
                    (Scope,
                     Set_Visibility (The_Visibility => Local,
                                     The_Unit       => RawDict.Get_Package_Symbol (The_Package)));
               else
                  Is_Visible := False;
               end if;
               exit;
            end if;
            The_Global_Variable := RawDict.Get_Next_Global_Variable (The_Global_Variable => The_Global_Variable);
         end loop;
      end Lookup_Global_Variables;

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

      function Lookup_Children
        (Sort        : PackageSort;
         The_Package : RawDict.Package_Info_Ref;
         Name        : LexTokenManager.Lex_String;
         Scope       : Scopes;
         Context     : Contexts)
        return        RawDict.Package_Info_Ref
      --# global in Dict;
      --#        in LexTokenManager.State;
      is
         Current_Package : RawDict.Package_Info_Ref;
         Result          : RawDict.Package_Info_Ref := RawDict.Null_Package_Info_Ref;

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

         function Check_Is_Inherited (The_Package : RawDict.Package_Info_Ref;
                                      Scope       : Scopes) return RawDict.Package_Info_Ref
         --# global in Dict;
         is
            Current_Scope : Scopes;
            Region        : Symbol;
            Result        : RawDict.Package_Info_Ref;
         begin
            Current_Scope := Scope;
            loop
               Region := GetRegion (Current_Scope);
               if RawDict.GetSymbolDiscriminant (Region) = Package_Symbol then
                  if Is_Package_Inherited
                    (The_Inherited_Symbol => RawDict.Get_Package_Symbol (The_Package),
                     The_Package          => RawDict.Get_Package_Info_Ref (Item => Region)) then
                     Result := The_Package;
                  else
                     Result := RawDict.Null_Package_Info_Ref;
                  end if;
                  exit;
               end if;
               if RawDict.GetSymbolDiscriminant (Region) = Subprogram_Symbol
                 and then Is_Main_Program (The_Subprogram => RawDict.Get_Subprogram_Info_Ref (Item => Region)) then
                  if Is_Subprogram_Inherited
                    (The_Inherited_Symbol => RawDict.Get_Package_Symbol (The_Package),
                     The_Subprogram       => RawDict.Get_Subprogram_Info_Ref (Item => Region)) then
                     Result := The_Package;
                  else
                     Result := RawDict.Null_Package_Info_Ref;
                  end if;
                  exit;
               end if;
               Current_Scope := GetEnclosingScope (Current_Scope);
            end loop;
            return Result;
            -- *NB* the inheritance check also must succeed in the case where
            --      a private child package is with'd by its parent; since
            --      the context required for this check is not available here,
            --      this case is handled during wf checking of the with clause
            --      by insertion of a 'fake' inherit reference.
         end Check_Is_Inherited;

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

         function Check_Is_Withed
           (The_Package : RawDict.Package_Info_Ref;
            Scope       : Scopes;
            Context     : Contexts)
           return        RawDict.Package_Info_Ref
         --# global in Dict;
         is
            Current, Last1   : Scopes;
            Ancestor, Result : RawDict.Package_Info_Ref;
         begin
            if Context = ProofContext then
               Result := The_Package;
            else
               Current := Scope;
               Last1   := Current;
               loop
                  exit when (RawDict.GetSymbolDiscriminant (GetRegion (Current)) = Package_Symbol
                               and then RawDict.Get_Package_Info_Ref (Item => GetRegion (Current)) =
                               Get_Predefined_Package_Standard)
                    or else Is_Withed (The_Withed_Symbol => RawDict.Get_Package_Symbol (The_Package),
                                       Scope             => Current);
                  Last1   := Current;
                  Current := GetEnclosingScope (Current);
               end loop;

               if RawDict.GetSymbolDiscriminant (GetRegion (Current)) = Package_Symbol
                 and then RawDict.Get_Package_Info_Ref (Item => GetRegion (Current)) = Get_Predefined_Package_Standard then
                  Result := RawDict.Null_Package_Info_Ref;
                  if Last1 /= Current and then RawDict.GetSymbolDiscriminant (GetRegion (Last1)) = Package_Symbol then
                     -- search through ancestors
                     Ancestor :=
                       RawDict.Get_Package_Parent (The_Package => RawDict.Get_Package_Info_Ref (Item => GetRegion (Last1)));
                     loop
                        exit when Ancestor = RawDict.Null_Package_Info_Ref
                          or else Is_Withed
                          (The_Withed_Symbol => RawDict.Get_Package_Symbol (The_Package),
                           Scope             => Set_Visibility
                             (The_Visibility => Visible,
                              The_Unit       => RawDict.Get_Package_Symbol (Ancestor)));
                        Ancestor := RawDict.Get_Package_Parent (The_Package => Ancestor);
                     end loop;
                     if Ancestor /= RawDict.Null_Package_Info_Ref then
                        Result := The_Package;
                     end if;
                  end if;
               else
                  Result := The_Package;
               end if;
            end if;
            return Result;
         end Check_Is_Withed;

      begin -- Lookup_Children
         case Sort is
            when Public =>
               Current_Package := RawDict.Get_Package_First_Public_Child (The_Package => The_Package);
            when PrivateChild =>
               Current_Package := RawDict.Get_Package_First_Private_Child (The_Package => The_Package);
         end case;
         loop
            exit when Current_Package = RawDict.Null_Package_Info_Ref;

            if LexTokenManager.Lex_String_Case_Insensitive_Compare
              (Lex_Str1 => RawDict.Get_Package_Name (The_Package => Current_Package),
               Lex_Str2 => Name) =
              LexTokenManager.Str_Eq then
               Result := Current_Package;
               exit;
            end if;

            Current_Package := RawDict.Get_Package_Next_Sibling (The_Package => Current_Package);
         end loop;

         if Result /= RawDict.Null_Package_Info_Ref then
            if not IsGlobalScope (Scope) then
               Result := Check_Is_Inherited (The_Package => Result,
                                             Scope       => Scope);
            end if;

            if Result /= RawDict.Null_Package_Info_Ref then
               Result := Check_Is_Withed (The_Package => Result,
                                          Scope       => Scope,
                                          Context     => Context);
            end if;
         end if;
         return Result;
      end Lookup_Children;

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

      -- CFR 806 Adds this function.  Needed so scan for enclosing region
      -- ignores enclosing loop statements.  SEPRS 889 and 1083
      function GetEnclosingNonLoopRegion (Scope : Scopes) return Symbol
      --# global in Dict;
      is
         Current_Scope : Scopes;
         Region        : Symbol;
      begin
         Current_Scope := Scope;
         loop
            Region := GetRegion (Current_Scope);
            exit when RawDict.GetSymbolDiscriminant (Region) /= LoopSymbol;
            Current_Scope := GetEnclosingScope (Current_Scope);
         end loop;
         return Region;
      end GetEnclosingNonLoopRegion;

   begin -- Lookup_Selected_Item_In_Package
      Trace_Lex_Str (Msg => "In LookUpSelectedItemInPackage seeking ",
                     L   => Name);

      Region := GetEnclosingNonLoopRegion (Scope);
      if Is_Subprogram (Region) then
         Lookup_Global_Variables
           (Abstraction  => Get_Subprogram_Abstraction (The_Subprogram => RawDict.Get_Subprogram_Info_Ref (Region),
                                                        Scope          => Scope),
            The_Package  => The_Package,
            Name         => Name,
            Subprogram   => Region,
            Context      => Context,
            The_Variable => The_Variable,
            Is_Visible   => Is_Visible);
      elsif RawDict.GetSymbolDiscriminant (Region) = Type_Symbol
        and then Is_Task_Type (Type_Mark => RawDict.Get_Type_Info_Ref (Item => Region)) then
         Lookup_Global_Variables
           (Abstraction  => Get_Task_Type_Abstraction (The_Task_Type => RawDict.Get_Type_Info_Ref (Region),
                                                       Scope         => Scope),
            The_Package  => The_Package,
            Name         => Name,
            Subprogram   => Region,
            Context      => Context,
            The_Variable => The_Variable,
            Is_Visible   => Is_Visible);
      else
         The_Variable := RawDict.Null_Variable_Info_Ref;
         Is_Visible   := False;
      end if;
      Item := RawDict.Get_Variable_Symbol (The_Variable);
      --# assert True;
      if Item = NullSymbol then
         LookupScope
           (Name          => Name,
            Stop_At       => LexTokenManager.Null_String,
            Scope         => Set_Visibility (The_Visibility => Visible,
                                             The_Unit       => RawDict.Get_Package_Symbol (The_Package)),
            Calling_Scope => Scope,
            Context       => Context,
            Item          => Item,
            Is_Visible    => Is_Visible);

         if Item = NullSymbol then
            Library_Package := Get_Library_Package (Scope => Scope);
            if Is_Proper_Descendent (Inner_Package => Library_Package,
                                     Outer_Package => The_Package) then
               if Scope /= Set_Visibility (The_Visibility => Visible,
                                           The_Unit       => RawDict.Get_Package_Symbol (Library_Package))
                 or else Descendent_Is_Private (Inner_Package => Library_Package,
                                                Outer_Package => The_Package) then
                  LookupScope
                    (Name          => Name,
                     Stop_At       => LexTokenManager.Null_String,
                     Scope         => Set_Visibility (The_Visibility => Privat,
                                                      The_Unit       => RawDict.Get_Package_Symbol (The_Package)),
                     Calling_Scope => Scope,
                     Context       => Context,
                     Item          => Item,
                     Is_Visible    => Is_Visible);
               end if;
            elsif IsLocal
              (Scope,
               Set_Visibility (The_Visibility => Local,
                               The_Unit       => RawDict.Get_Package_Symbol (The_Package))) then
               Item       :=
                 LookupImmediateScope
                 (Name,
                  Set_Visibility (The_Visibility => Local,
                                  The_Unit       => RawDict.Get_Package_Symbol (The_Package)),
                  Context);
               Is_Visible := Item /= NullSymbol;
            end if;
         elsif Context = ProofContext
           and then RawDict.GetSymbolDiscriminant (Item) = Variable_Symbol
           and then Is_Own_Variable (The_Variable => RawDict.Get_Variable_Info_Ref (Item => Item)) then
            Library_Package := Get_Library_Package (Scope => Scope);
            if Is_Descendent_Of_Private_Child (Candidate   => Library_Package,
                                               The_Package => The_Package) then
               Item       :=
                 LookupImmediateScope
                 (Name,
                  Set_Visibility (The_Visibility => Privat,
                                  The_Unit       => RawDict.Get_Package_Symbol (The_Package)),
                  ProgramContext);
               Is_Visible := Item /= NullSymbol;
            end if;
         end if;

         --# assert True;
         if Is_Variable (Item)
           and then (Is_Subprogram (Region)
                       or else (RawDict.GetSymbolDiscriminant (Region) = Type_Symbol
                                  and then Is_Task_Type (Type_Mark => RawDict.Get_Type_Info_Ref (Item => Region)))) then
            -- Region is equal to Scope.Region if not within a loop (see start of subprog)
            --   and second arg is equivalent to Scope
            -- otherwise it is nearest enclosing non-loop region (subprogram)
            Is_Visible :=
              IsLocal
              (Set_Visibility (The_Visibility => Visible,
                               The_Unit       => RawDict.Get_Package_Symbol (The_Package)),
               Set_Visibility (The_Visibility => Get_Visibility (Scope => Scope),
                               The_Unit       => Region));
         elsif RawDict.GetSymbolDiscriminant (Item) = Subprogram_Symbol then
            Is_Visible := not Is_Renamed_Local (The_Subprogram => RawDict.Get_Subprogram_Info_Ref (Item => Item),
                                                Scope          => Scope);
         elsif RawDict.GetSymbolDiscriminant (Item) = ImplicitProofFunctionSymbol then
            Is_Visible :=
              not Is_Renamed_Local (The_Subprogram => RawDict.GetImplicitProofFunctionAdaFunction (Item),
                                    Scope          => Scope);
         end if;

      end if;

      --# assert True;
      if not Is_Visible then
         Item := NullSymbol;
      end if;

      --# assert True;
      if Item = NullSymbol then
         case CommandLineData.Content.Language_Profile is
            when CommandLineData.SPARK83 =>
               null;
            when CommandLineData.SPARK95_Onwards =>
               -- look up children, if relevant
               Library_Package := Get_Library_Package (Scope => Scope);
               if not Is_Proper_Descendent (Inner_Package => Library_Package,
                                            Outer_Package => The_Package) then
                  Item :=
                    RawDict.Get_Package_Symbol
                    (Lookup_Children
                       (Sort        => Public,
                        The_Package => The_Package,
                        Name        => Name,
                        Scope       => Scope,
                        Context     => Context));
                  if Item = NullSymbol and then IsGlobalScope (Scope) then
                     Item :=
                       RawDict.Get_Package_Symbol
                       (Lookup_Children
                          (Sort        => PrivateChild,
                           The_Package => The_Package,
                           Name        => Name,
                           Scope       => Scope,
                           Context     => Context));
                  end if;
               end if;
         end case;
      end if;
      return Item;
   end Lookup_Selected_Item_In_Package;

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

   function Lookup_Selected_Item_In_Type_Mark
     (Type_Mark : RawDict.Type_Info_Ref;
      Name      : LexTokenManager.Lex_String;
      Context   : Contexts)
     return      Symbol
   --# global in Dict;
   --#        in LexTokenManager.State;
   is
   begin
      Trace_Lex_Str (Msg => "In LookUpSelectedItemInTypeMark seeking ",
                     L   => Name);

      -- The Get_Root_Type in the following statement is needed to handle
      -- lookup of items of protected subtypes and record subtypes.
      return LookupImmediateScope
        (Name,
         Set_Visibility
           (The_Visibility => Local,
            The_Unit       => RawDict.Get_Type_Symbol (Get_Root_Type (Type_Mark => Type_Mark))),
         Context);
   end Lookup_Selected_Item_In_Type_Mark;

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

   function LookupSelectedItemInObject
     (Object  : Symbol;
      Name    : LexTokenManager.Lex_String;
      Context : Contexts)
     return    Symbol
   --# global in Dict;
   --#        in LexTokenManager.State;
   is
      Result : Symbol;

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

      function Lookup_Protected_Operation
        (Op_Name            : LexTokenManager.Lex_String;
         The_Protected_Type : RawDict.Type_Info_Ref)
        return               Symbol
      --# global in Dict;
      --#        in LexTokenManager.State;
      is
         It     : Iterator;
         Result : Symbol := NullSymbol; -- default answer for failure case
      begin
         It := First_Protected_Type_Visible_Subprogram (The_Protected_Type => The_Protected_Type);
         while not IsNullIterator (It) loop
            if LexTokenManager.Lex_String_Case_Insensitive_Compare
              (Lex_Str1 => GetSimpleName (CurrentSymbol (It)),
               Lex_Str2 => Op_Name) =
              LexTokenManager.Str_Eq then
               -- success
               Result := CurrentSymbol (It);
               exit;
            end if;
            It := NextSymbol (It);
         end loop;
         return Result;
      end Lookup_Protected_Operation;

   begin -- LookupSelectedItemInObject
      Trace_Lex_Str (Msg => "In LookUpSelectedItemInObject seeking ",
                     L   => Name);
      if RawDict.GetSymbolDiscriminant (Object) = Constant_Symbol then
         Result :=
           Lookup_Selected_Item_In_Type_Mark
           (Type_Mark => RawDict.Get_Constant_Type (The_Constant => RawDict.Get_Constant_Info_Ref (Item => Object)),
            Name      => Name,
            Context   => Context);
      else
         -- We need to distinguish between a record object where we will seek a field
         -- in local scope of the object and a protected object where we will need to
         -- seek an operation in the visible part of the type of the protected object
         if RawDict.Get_Type_Discriminant (Type_Mark => Get_Type (Object)) = Record_Type_Item then
            Result := LookupImmediateScope (Name, Set_Visibility (The_Visibility => Local,
                                                                  The_Unit       => Object), Context);
         elsif RawDict.Get_Type_Discriminant (Type_Mark => Get_Type (Object)) = Protected_Type_Item then
            Result :=
              Lookup_Protected_Operation (Op_Name            => Name,
                                          The_Protected_Type => Get_Root_Type (Type_Mark => Get_Type (Object)));
         else
            Result := NullSymbol; -- to avoid DF error
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Invalid_Symbol_Table,
               Msg     => "LookupSelectedItemInObject called with prefix which is not record or protected");
         end if;
      end if;
      return Result;
   end LookupSelectedItemInObject;

begin -- LookupSelectedItem
   Trace_Lex_Str (Msg => "In LookUpSelectedItem seeking ",
                  L   => Selector);
   Trace_Sym (Msg   => "   in ",
              Sym   => Prefix,
              Scope => Scope);

   case RawDict.GetSymbolDiscriminant (Prefix) is
      when Package_Symbol =>
         Item :=
           Lookup_Selected_Item_In_Package
           (The_Package => RawDict.Get_Package_Info_Ref (Item => Prefix),
            Name        => Selector,
            Scope       => Scope,
            Context     => Context);
      when Type_Symbol =>
         Item :=
           Lookup_Selected_Item_In_Type_Mark
           (Type_Mark => RawDict.Get_Type_Info_Ref (Item => Prefix),
            Name      => Selector,
            Context   => Context);
      when Variable_Symbol | Constant_Symbol | Subcomponent_Symbol | -- record object field may also have fields
        Subprogram_Parameter_Symbol =>
         Item := LookupSelectedItemInObject (Prefix, Selector, Context);
      when Subprogram_Symbol =>
         Item := LookupImmediateScope (Selector, Set_Visibility (The_Visibility => Local,
                                                                 The_Unit       => Prefix), Context);
      when others => -- non-exec code
         Item := NullSymbol;
         SystemErrors.Fatal_Error (Sys_Err => SystemErrors.Invalid_Symbol_Table,
                                   Msg     => "in Dictionary.LookUpSelectedItem");
   end case;
   return Item;
end LookupSelectedItem;
