OSDN Git Service

2010-10-05 Ed Schonberg <schonberg@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / prj-tree.adb
index e8603c6..55f2195 100644 (file)
@@ -6,26 +6,29 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---             Copyright (C) 2001-2004 Free Software Foundation, Inc.       --
+--          Copyright (C) 2001-2010, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
--- ware  Foundation;  either version 2,  or (at your option) any later ver- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
 -- OUT 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 GNAT;  see file COPYING.  If not, write --
--- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
--- MA 02111-1307, USA.                                                      --
+-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
+-- http://www.gnu.org/licenses for a complete copy of the license.          --
 --                                                                          --
 -- GNAT was originally developed  by the GNAT team at  New York University. --
 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
 --                                                                          --
 ------------------------------------------------------------------------------
 
+with Osint;   use Osint;
+with Prj.Env; use Prj.Env;
 with Prj.Err;
 
+with Ada.Unchecked_Deallocation;
+
 package body Prj.Tree is
 
    Node_With_Comments : constant array (Project_Node_Kind) of Boolean :=
@@ -76,7 +79,8 @@ package body Prj.Tree is
    --  Set to True when some comments may not be associated with any node
 
    function Comment_Zones_Of
-     (Node : Project_Node_Id) return Project_Node_Id;
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
    --  Returns the ID of the N_Comment_Zones node associated with node Node.
    --  If there is not already an N_Comment_Zones node, create one and
    --  associate it with node Node.
@@ -85,47 +89,53 @@ package body Prj.Tree is
    -- Add_Comments --
    ------------------
 
-   procedure Add_Comments (To : Project_Node_Id; Where : Comment_Location) is
+   procedure Add_Comments
+     (To       : Project_Node_Id;
+      In_Tree  : Project_Node_Tree_Ref;
+      Where    : Comment_Location) is
       Zone     : Project_Node_Id := Empty_Node;
       Previous : Project_Node_Id := Empty_Node;
 
    begin
       pragma Assert
-        (To /= Empty_Node
-          and then
-         Project_Nodes.Table (To).Kind /= N_Comment);
+        (Present (To)
+          and then In_Tree.Project_Nodes.Table (To).Kind /= N_Comment);
 
-      Zone := Project_Nodes.Table (To).Comments;
+      Zone := In_Tree.Project_Nodes.Table (To).Comments;
 
-      if Zone = Empty_Node then
+      if No (Zone) then
 
          --  Create new N_Comment_Zones node
 
-         Project_Nodes.Increment_Last;
-         Project_Nodes.Table (Project_Nodes.Last) :=
-           (Kind             => N_Comment_Zones,
-            Expr_Kind        => Undefined,
-            Location         => No_Location,
-            Directory        => No_Name,
-            Variables        => Empty_Node,
-            Packages         => Empty_Node,
-            Pkg_Id           => Empty_Package,
-            Name             => No_Name,
-            Path_Name        => No_Name,
-            Value            => No_Name,
-            Field1           => Empty_Node,
-            Field2           => Empty_Node,
-            Field3           => Empty_Node,
-            Flag1            => False,
-            Flag2            => False,
-            Comments         => Empty_Node);
-
-         Zone := Project_Nodes.Last;
-         Project_Nodes.Table (To).Comments := Zone;
+         Project_Node_Table.Increment_Last (In_Tree.Project_Nodes);
+         In_Tree.Project_Nodes.Table
+           (Project_Node_Table.Last (In_Tree.Project_Nodes)) :=
+           (Kind      => N_Comment_Zones,
+            Qualifier => Unspecified,
+            Expr_Kind => Undefined,
+            Location  => No_Location,
+            Directory => No_Path,
+            Variables => Empty_Node,
+            Packages  => Empty_Node,
+            Pkg_Id    => Empty_Package,
+            Name      => No_Name,
+            Src_Index => 0,
+            Path_Name => No_Path,
+            Value     => No_Name,
+            Field1    => Empty_Node,
+            Field2    => Empty_Node,
+            Field3    => Empty_Node,
+            Field4    => Empty_Node,
+            Flag1     => False,
+            Flag2     => False,
+            Comments  => Empty_Node);
+
+         Zone := Project_Node_Table.Last (In_Tree.Project_Nodes);
+         In_Tree.Project_Nodes.Table (To).Comments := Zone;
       end if;
 
       if Where = End_Of_Line then
-         Project_Nodes.Table (Zone).Value := Comments.Table (1).Value;
+         In_Tree.Project_Nodes.Table (Zone).Value := Comments.Table (1).Value;
 
       else
          --  Get each comments in the Comments table and link them to node To
@@ -144,42 +154,50 @@ package body Prj.Tree is
                return;
             end if;
 
-            Project_Nodes.Increment_Last;
-            Project_Nodes.Table (Project_Nodes.Last) :=
+            Project_Node_Table.Increment_Last (In_Tree.Project_Nodes);
+            In_Tree.Project_Nodes.Table
+              (Project_Node_Table.Last (In_Tree.Project_Nodes)) :=
               (Kind             => N_Comment,
+               Qualifier        => Unspecified,
                Expr_Kind        => Undefined,
                Flag1            => Comments.Table (J).Follows_Empty_Line,
                Flag2            =>
                  Comments.Table (J).Is_Followed_By_Empty_Line,
                Location         => No_Location,
-               Directory        => No_Name,
+               Directory        => No_Path,
                Variables        => Empty_Node,
                Packages         => Empty_Node,
                Pkg_Id           => Empty_Package,
                Name             => No_Name,
-               Path_Name        => No_Name,
+               Src_Index        => 0,
+               Path_Name        => No_Path,
                Value            => Comments.Table (J).Value,
                Field1           => Empty_Node,
                Field2           => Empty_Node,
                Field3           => Empty_Node,
+               Field4           => Empty_Node,
                Comments         => Empty_Node);
 
             --  If this is the first comment, put it in the right field of
             --  the node Zone.
 
-            if Previous = Empty_Node then
+            if No (Previous) then
                case Where is
                   when Before =>
-                     Project_Nodes.Table (Zone).Field1 := Project_Nodes.Last;
+                     In_Tree.Project_Nodes.Table (Zone).Field1 :=
+                       Project_Node_Table.Last (In_Tree.Project_Nodes);
 
                   when After =>
-                     Project_Nodes.Table (Zone).Field2 := Project_Nodes.Last;
+                     In_Tree.Project_Nodes.Table (Zone).Field2 :=
+                       Project_Node_Table.Last (In_Tree.Project_Nodes);
 
                   when Before_End =>
-                     Project_Nodes.Table (Zone).Field3 := Project_Nodes.Last;
+                     In_Tree.Project_Nodes.Table (Zone).Field3 :=
+                       Project_Node_Table.Last (In_Tree.Project_Nodes);
 
                   when After_End =>
-                     Project_Nodes.Table (Zone).Comments := Project_Nodes.Last;
+                     In_Tree.Project_Nodes.Table (Zone).Comments :=
+                       Project_Node_Table.Last (In_Tree.Project_Nodes);
 
                   when End_Of_Line =>
                      null;
@@ -188,13 +206,14 @@ package body Prj.Tree is
             else
                --  When it is not the first, link it to the previous one
 
-               Project_Nodes.Table (Previous).Comments := Project_Nodes.Last;
+               In_Tree.Project_Nodes.Table (Previous).Comments :=
+                 Project_Node_Table.Last (In_Tree.Project_Nodes);
             end if;
 
             --  This node becomes the previous one for the next comment, if
             --  there is one.
 
-            Previous := Project_Nodes.Last;
+            Previous := Project_Node_Table.Last (In_Tree.Project_Nodes);
          end loop;
       end if;
 
@@ -204,22 +223,22 @@ package body Prj.Tree is
       Comments.Set_Last (0);
    end Add_Comments;
 
-
    --------------------------------
    -- Associative_Array_Index_Of --
    --------------------------------
 
    function Associative_Array_Index_Of
-     (Node : Project_Node_Id) return Name_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Name_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
+            (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
                or else
-             Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
-      return Project_Nodes.Table (Node).Value;
+             In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
+      return In_Tree.Project_Nodes.Table (Node).Value;
    end Associative_Array_Index_Of;
 
    ----------------------------
@@ -227,14 +246,15 @@ package body Prj.Tree is
    ----------------------------
 
    function Associative_Package_Of
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_Attribute_Declaration));
-      return Project_Nodes.Table (Node).Field3;
+          (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration));
+      return In_Tree.Project_Nodes.Table (Node).Field3;
    end Associative_Package_Of;
 
    ----------------------------
@@ -242,29 +262,32 @@ package body Prj.Tree is
    ----------------------------
 
    function Associative_Project_Of
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_Attribute_Declaration));
-      return Project_Nodes.Table (Node).Field2;
+          (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration));
+      return In_Tree.Project_Nodes.Table (Node).Field2;
    end Associative_Project_Of;
 
    ----------------------
    -- Case_Insensitive --
    ----------------------
 
-   function Case_Insensitive (Node : Project_Node_Id) return Boolean is
+   function Case_Insensitive
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Boolean is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
+            (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
                or else
-             Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
-      return Project_Nodes.Table (Node).Flag1;
+             In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
+      return In_Tree.Project_Nodes.Table (Node).Flag1;
    end Case_Insensitive;
 
    --------------------------------
@@ -272,14 +295,15 @@ package body Prj.Tree is
    --------------------------------
 
    function Case_Variable_Reference_Of
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Case_Construction);
-      return Project_Nodes.Table (Node).Field1;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Construction);
+      return In_Tree.Project_Nodes.Table (Node).Field1;
    end Case_Variable_Reference_Of;
 
    ----------------------
@@ -287,38 +311,42 @@ package body Prj.Tree is
    ----------------------
 
    function Comment_Zones_Of
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
       Zone : Project_Node_Id;
 
    begin
-      pragma Assert (Node /= Empty_Node);
-      Zone := Project_Nodes.Table (Node).Comments;
+      pragma Assert (Present (Node));
+      Zone := In_Tree.Project_Nodes.Table (Node).Comments;
 
       --  If there is not already an N_Comment_Zones associated, create a new
       --  one and associate it with node Node.
 
-      if Zone = Empty_Node then
-         Project_Nodes.Increment_Last;
-         Zone := Project_Nodes.Last;
-         Project_Nodes.Table (Zone) :=
+      if No (Zone) then
+         Project_Node_Table.Increment_Last (In_Tree.Project_Nodes);
+         Zone := Project_Node_Table.Last (In_Tree.Project_Nodes);
+         In_Tree.Project_Nodes.Table (Zone) :=
         (Kind             => N_Comment_Zones,
+         Qualifier        => Unspecified,
          Location         => No_Location,
-         Directory        => No_Name,
+         Directory        => No_Path,
          Expr_Kind        => Undefined,
          Variables        => Empty_Node,
          Packages         => Empty_Node,
          Pkg_Id           => Empty_Package,
          Name             => No_Name,
-         Path_Name        => No_Name,
+         Src_Index        => 0,
+         Path_Name        => No_Path,
          Value            => No_Name,
          Field1           => Empty_Node,
          Field2           => Empty_Node,
          Field3           => Empty_Node,
+         Field4           => Empty_Node,
          Flag1            => False,
          Flag2            => False,
          Comments         => Empty_Node);
-         Project_Nodes.Table (Node).Comments := Zone;
+         In_Tree.Project_Nodes.Table (Node).Comments := Zone;
       end if;
 
       return Zone;
@@ -329,14 +357,15 @@ package body Prj.Tree is
    -----------------------
 
    function Current_Item_Node
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Declarative_Item);
-      return Project_Nodes.Table (Node).Field1;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Declarative_Item);
+      return In_Tree.Project_Nodes.Table (Node).Field1;
    end Current_Item_Node;
 
    ------------------
@@ -344,14 +373,15 @@ package body Prj.Tree is
    ------------------
 
    function Current_Term
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Term);
-      return Project_Nodes.Table (Node).Field1;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Term);
+      return In_Tree.Project_Nodes.Table (Node).Field1;
    end Current_Term;
 
    --------------------------
@@ -359,7 +389,8 @@ package body Prj.Tree is
    --------------------------
 
    function Default_Project_Node
-     (Of_Kind       : Project_Node_Kind;
+     (In_Tree       : Project_Node_Tree_Ref;
+      Of_Kind       : Project_Node_Kind;
       And_Expr_Kind : Variable_Kind := Undefined) return Project_Node_Id
    is
       Result   : Project_Node_Id;
@@ -369,28 +400,32 @@ package body Prj.Tree is
    begin
       --  Create new node with specified kind and expression kind
 
-      Project_Nodes.Increment_Last;
-      Project_Nodes.Table (Project_Nodes.Last) :=
+      Project_Node_Table.Increment_Last (In_Tree.Project_Nodes);
+      In_Tree.Project_Nodes.Table
+        (Project_Node_Table.Last (In_Tree.Project_Nodes)) :=
         (Kind             => Of_Kind,
+         Qualifier        => Unspecified,
          Location         => No_Location,
-         Directory        => No_Name,
+         Directory        => No_Path,
          Expr_Kind        => And_Expr_Kind,
          Variables        => Empty_Node,
          Packages         => Empty_Node,
          Pkg_Id           => Empty_Package,
          Name             => No_Name,
-         Path_Name        => No_Name,
+         Src_Index        => 0,
+         Path_Name        => No_Path,
          Value            => No_Name,
          Field1           => Empty_Node,
          Field2           => Empty_Node,
          Field3           => Empty_Node,
+         Field4           => Empty_Node,
          Flag1            => False,
          Flag2            => False,
          Comments         => Empty_Node);
 
       --  Save the new node for the returned value
 
-      Result := Project_Nodes.Last;
+      Result := Project_Node_Table.Last (In_Tree.Project_Nodes);
 
       if Comments.Last > 0 then
 
@@ -401,68 +436,77 @@ package body Prj.Tree is
 
          elsif Of_Kind /= N_Comment and then Of_Kind /= N_Comment_Zones then
 
-            Project_Nodes.Increment_Last;
-            Project_Nodes.Table (Project_Nodes.Last) :=
+            Project_Node_Table.Increment_Last (In_Tree.Project_Nodes);
+            In_Tree.Project_Nodes.Table
+              (Project_Node_Table.Last (In_Tree.Project_Nodes)) :=
               (Kind             => N_Comment_Zones,
+               Qualifier        => Unspecified,
                Expr_Kind        => Undefined,
                Location         => No_Location,
-               Directory        => No_Name,
+               Directory        => No_Path,
                Variables        => Empty_Node,
                Packages         => Empty_Node,
                Pkg_Id           => Empty_Package,
                Name             => No_Name,
-               Path_Name        => No_Name,
+               Src_Index        => 0,
+               Path_Name        => No_Path,
                Value            => No_Name,
                Field1           => Empty_Node,
                Field2           => Empty_Node,
                Field3           => Empty_Node,
+               Field4           => Empty_Node,
                Flag1            => False,
                Flag2            => False,
                Comments         => Empty_Node);
 
-            Zone := Project_Nodes.Last;
-            Project_Nodes.Table (Result).Comments := Zone;
+            Zone := Project_Node_Table.Last (In_Tree.Project_Nodes);
+            In_Tree.Project_Nodes.Table (Result).Comments := Zone;
             Previous := Empty_Node;
 
             for J in 1 .. Comments.Last loop
 
                --  Create a new N_Comment node
 
-               Project_Nodes.Increment_Last;
-               Project_Nodes.Table (Project_Nodes.Last) :=
+               Project_Node_Table.Increment_Last (In_Tree.Project_Nodes);
+               In_Tree.Project_Nodes.Table
+                 (Project_Node_Table.Last (In_Tree.Project_Nodes)) :=
                  (Kind             => N_Comment,
+                  Qualifier        => Unspecified,
                   Expr_Kind        => Undefined,
                   Flag1            => Comments.Table (J).Follows_Empty_Line,
                   Flag2            =>
                     Comments.Table (J).Is_Followed_By_Empty_Line,
                   Location         => No_Location,
-                  Directory        => No_Name,
+                  Directory        => No_Path,
                   Variables        => Empty_Node,
                   Packages         => Empty_Node,
                   Pkg_Id           => Empty_Package,
                   Name             => No_Name,
-                  Path_Name        => No_Name,
+                  Src_Index        => 0,
+                  Path_Name        => No_Path,
                   Value            => Comments.Table (J).Value,
                   Field1           => Empty_Node,
                   Field2           => Empty_Node,
                   Field3           => Empty_Node,
+                  Field4           => Empty_Node,
                   Comments         => Empty_Node);
 
                --  Link it to the N_Comment_Zones node, if it is the first,
                --  otherwise to the previous one.
 
-               if Previous = Empty_Node then
-                  Project_Nodes.Table (Zone).Field1 := Project_Nodes.Last;
+               if No (Previous) then
+                  In_Tree.Project_Nodes.Table (Zone).Field1 :=
+                    Project_Node_Table.Last (In_Tree.Project_Nodes);
 
                else
-                  Project_Nodes.Table (Previous).Comments :=
-                    Project_Nodes.Last;
+                  In_Tree.Project_Nodes.Table (Previous).Comments :=
+                    Project_Node_Table.Last (In_Tree.Project_Nodes);
                end if;
 
                --  This new node will be the previous one for the next
                --  N_Comment node, if there is one.
 
-               Previous := Project_Nodes.Last;
+               Previous := Project_Node_Table.Last (In_Tree.Project_Nodes);
             end loop;
 
             --  Empty the Comments table after all comments have been processed
@@ -478,30 +522,34 @@ package body Prj.Tree is
    -- Directory_Of --
    ------------------
 
-   function Directory_Of (Node : Project_Node_Id) return Name_Id is
+   function Directory_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Path_Name_Type is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Project);
-      return Project_Nodes.Table (Node).Directory;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
+      return In_Tree.Project_Nodes.Table (Node).Directory;
    end Directory_Of;
 
    -------------------------
    -- End_Of_Line_Comment --
    -------------------------
 
-   function End_Of_Line_Comment (Node : Project_Node_Id) return Name_Id is
+   function End_Of_Line_Comment
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Name_Id is
       Zone : Project_Node_Id := Empty_Node;
 
    begin
-      pragma Assert (Node /= Empty_Node);
-      Zone := Project_Nodes.Table (Node).Comments;
+      pragma Assert (Present (Node));
+      Zone := In_Tree.Project_Nodes.Table (Node).Comments;
 
-      if Zone = Empty_Node then
+      if No (Zone) then
          return No_Name;
       else
-         return Project_Nodes.Table (Zone).Value;
+         return In_Tree.Project_Nodes.Table (Zone).Value;
       end if;
    end End_Of_Line_Comment;
 
@@ -509,30 +557,34 @@ package body Prj.Tree is
    -- Expression_Kind_Of --
    ------------------------
 
-   function Expression_Kind_Of (Node : Project_Node_Id) return Variable_Kind is
+   function Expression_Kind_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Variable_Kind is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
            and then
-             (Project_Nodes.Table (Node).Kind = N_Literal_String
+             (In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String
                 or else
-              Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
+              In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
                 or else
-              Project_Nodes.Table (Node).Kind = N_Variable_Declaration
+              In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Declaration
                 or else
-              Project_Nodes.Table (Node).Kind = N_Typed_Variable_Declaration
+              In_Tree.Project_Nodes.Table (Node).Kind =
+                       N_Typed_Variable_Declaration
                 or else
-              Project_Nodes.Table (Node).Kind = N_Package_Declaration
+              In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration
                 or else
-              Project_Nodes.Table (Node).Kind = N_Expression
+              In_Tree.Project_Nodes.Table (Node).Kind = N_Expression
                 or else
-              Project_Nodes.Table (Node).Kind = N_Term
+              In_Tree.Project_Nodes.Table (Node).Kind = N_Term
                 or else
-              Project_Nodes.Table (Node).Kind = N_Variable_Reference
+              In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference
                 or else
-              Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
+              In_Tree.Project_Nodes.Table (Node).Kind =
+                        N_Attribute_Reference));
 
-      return Project_Nodes.Table (Node).Expr_Kind;
+      return In_Tree.Project_Nodes.Table (Node).Expr_Kind;
    end Expression_Kind_Of;
 
    -------------------
@@ -540,19 +592,23 @@ package body Prj.Tree is
    -------------------
 
    function Expression_Of
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
+           (In_Tree.Project_Nodes.Table (Node).Kind =
+              N_Attribute_Declaration
                or else
-             Project_Nodes.Table (Node).Kind = N_Typed_Variable_Declaration
+            In_Tree.Project_Nodes.Table (Node).Kind =
+              N_Typed_Variable_Declaration
                or else
-             Project_Nodes.Table (Node).Kind = N_Variable_Declaration));
+            In_Tree.Project_Nodes.Table (Node).Kind =
+              N_Variable_Declaration));
 
-      return Project_Nodes.Table (Node).Field1;
+      return In_Tree.Project_Nodes.Table (Node).Field1;
    end Expression_Of;
 
    -------------------------
@@ -560,14 +616,15 @@ package body Prj.Tree is
    -------------------------
 
    function Extended_Project_Of
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Project_Declaration);
-      return Project_Nodes.Table (Node).Field2;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration);
+      return In_Tree.Project_Nodes.Table (Node).Field2;
    end Extended_Project_Of;
 
    ------------------------------
@@ -575,28 +632,30 @@ package body Prj.Tree is
    ------------------------------
 
    function Extended_Project_Path_Of
-     (Node : Project_Node_Id) return Name_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Path_Name_Type
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Project);
-      return Project_Nodes.Table (Node).Value;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
+      return Path_Name_Type (In_Tree.Project_Nodes.Table (Node).Value);
    end Extended_Project_Path_Of;
 
    --------------------------
    -- Extending_Project_Of --
    --------------------------
    function Extending_Project_Of
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Project_Declaration);
-      return Project_Nodes.Table (Node).Field3;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration);
+      return In_Tree.Project_Nodes.Table (Node).Field3;
    end Extending_Project_Of;
 
    ---------------------------
@@ -604,14 +663,15 @@ package body Prj.Tree is
    ---------------------------
 
    function External_Reference_Of
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_External_Value);
-      return Project_Nodes.Table (Node).Field1;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_External_Value);
+      return In_Tree.Project_Nodes.Table (Node).Field1;
    end External_Reference_Of;
 
    -------------------------
@@ -619,15 +679,16 @@ package body Prj.Tree is
    -------------------------
 
    function External_Default_Of
-     (Node : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref)
       return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_External_Value);
-      return Project_Nodes.Table (Node).Field2;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_External_Value);
+      return In_Tree.Project_Nodes.Table (Node).Field2;
    end External_Default_Of;
 
    ------------------------
@@ -635,14 +696,15 @@ package body Prj.Tree is
    ------------------------
 
    function First_Case_Item_Of
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Case_Construction);
-      return Project_Nodes.Table (Node).Field2;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Construction);
+      return In_Tree.Project_Nodes.Table (Node).Field2;
    end First_Case_Item_Of;
 
    ---------------------
@@ -650,15 +712,16 @@ package body Prj.Tree is
    ---------------------
 
    function First_Choice_Of
-     (Node : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref)
       return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Case_Item);
-      return Project_Nodes.Table (Node).Field1;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Item);
+      return In_Tree.Project_Nodes.Table (Node).Field1;
    end First_Choice_Of;
 
    -------------------------
@@ -666,18 +729,19 @@ package body Prj.Tree is
    -------------------------
 
    function First_Comment_After
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
       Zone : Project_Node_Id := Empty_Node;
    begin
-      pragma Assert (Node /= Empty_Node);
-      Zone := Project_Nodes.Table (Node).Comments;
+      pragma Assert (Present (Node));
+      Zone := In_Tree.Project_Nodes.Table (Node).Comments;
 
-      if Zone = Empty_Node then
+      if No (Zone) then
          return Empty_Node;
 
       else
-         return Project_Nodes.Table (Zone).Field2;
+         return In_Tree.Project_Nodes.Table (Zone).Field2;
       end if;
    end First_Comment_After;
 
@@ -686,20 +750,21 @@ package body Prj.Tree is
    -----------------------------
 
    function First_Comment_After_End
-     (Node : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref)
       return Project_Node_Id
    is
       Zone : Project_Node_Id := Empty_Node;
 
    begin
-      pragma Assert (Node /= Empty_Node);
-      Zone := Project_Nodes.Table (Node).Comments;
+      pragma Assert (Present (Node));
+      Zone := In_Tree.Project_Nodes.Table (Node).Comments;
 
-      if Zone = Empty_Node then
+      if No (Zone) then
          return Empty_Node;
 
       else
-         return Project_Nodes.Table (Zone).Comments;
+         return In_Tree.Project_Nodes.Table (Zone).Comments;
       end if;
    end First_Comment_After_End;
 
@@ -708,19 +773,20 @@ package body Prj.Tree is
    --------------------------
 
    function First_Comment_Before
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
       Zone : Project_Node_Id := Empty_Node;
 
    begin
-      pragma Assert (Node /= Empty_Node);
-      Zone := Project_Nodes.Table (Node).Comments;
+      pragma Assert (Present (Node));
+      Zone := In_Tree.Project_Nodes.Table (Node).Comments;
 
-      if Zone = Empty_Node then
+      if No (Zone) then
          return Empty_Node;
 
       else
-         return Project_Nodes.Table (Zone).Field1;
+         return In_Tree.Project_Nodes.Table (Zone).Field1;
       end if;
    end First_Comment_Before;
 
@@ -729,19 +795,20 @@ package body Prj.Tree is
    ------------------------------
 
    function First_Comment_Before_End
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
       Zone : Project_Node_Id := Empty_Node;
 
    begin
-      pragma Assert (Node /= Empty_Node);
-      Zone := Project_Nodes.Table (Node).Comments;
+      pragma Assert (Present (Node));
+      Zone := In_Tree.Project_Nodes.Table (Node).Comments;
 
-      if Zone = Empty_Node then
+      if No (Zone) then
          return Empty_Node;
 
       else
-         return Project_Nodes.Table (Zone).Field3;
+         return In_Tree.Project_Nodes.Table (Zone).Field3;
       end if;
    end First_Comment_Before_End;
 
@@ -750,22 +817,23 @@ package body Prj.Tree is
    -------------------------------
 
    function First_Declarative_Item_Of
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_Project_Declaration
+            (In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration
                or else
-             Project_Nodes.Table (Node).Kind = N_Case_Item
+             In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Item
                or else
-             Project_Nodes.Table (Node).Kind = N_Package_Declaration));
+             In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration));
 
-      if Project_Nodes.Table (Node).Kind = N_Project_Declaration then
-         return Project_Nodes.Table (Node).Field1;
+      if In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration then
+         return In_Tree.Project_Nodes.Table (Node).Field1;
       else
-         return Project_Nodes.Table (Node).Field2;
+         return In_Tree.Project_Nodes.Table (Node).Field2;
       end if;
    end First_Declarative_Item_Of;
 
@@ -774,14 +842,15 @@ package body Prj.Tree is
    ------------------------------
 
    function First_Expression_In_List
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Literal_String_List);
-      return Project_Nodes.Table (Node).Field1;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String_List);
+      return In_Tree.Project_Nodes.Table (Node).Field1;
    end First_Expression_In_List;
 
    --------------------------
@@ -789,14 +858,16 @@ package body Prj.Tree is
    --------------------------
 
    function First_Literal_String
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_String_Type_Declaration);
-      return Project_Nodes.Table (Node).Field1;
+         In_Tree.Project_Nodes.Table (Node).Kind =
+           N_String_Type_Declaration);
+      return In_Tree.Project_Nodes.Table (Node).Field1;
    end First_Literal_String;
 
    ----------------------
@@ -804,14 +875,15 @@ package body Prj.Tree is
    ----------------------
 
    function First_Package_Of
-     (Node : Project_Node_Id) return Package_Declaration_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Package_Declaration_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Project);
-      return Project_Nodes.Table (Node).Packages;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
+      return In_Tree.Project_Nodes.Table (Node).Packages;
    end First_Package_Of;
 
    --------------------------
@@ -819,14 +891,15 @@ package body Prj.Tree is
    --------------------------
 
    function First_String_Type_Of
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Project);
-      return Project_Nodes.Table (Node).Field3;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
+      return In_Tree.Project_Nodes.Table (Node).Field3;
    end First_String_Type_Of;
 
    ----------------
@@ -834,14 +907,15 @@ package body Prj.Tree is
    ----------------
 
    function First_Term
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Expression);
-      return Project_Nodes.Table (Node).Field1;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Expression);
+      return In_Tree.Project_Nodes.Table (Node).Field1;
    end First_Term;
 
    -----------------------
@@ -849,17 +923,18 @@ package body Prj.Tree is
    -----------------------
 
    function First_Variable_Of
-     (Node : Project_Node_Id) return Variable_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Variable_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_Project
+            (In_Tree.Project_Nodes.Table (Node).Kind = N_Project
                or else
-             Project_Nodes.Table (Node).Kind = N_Package_Declaration));
+             In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration));
 
-      return Project_Nodes.Table (Node).Variables;
+      return In_Tree.Project_Nodes.Table (Node).Variables;
    end First_Variable_Of;
 
    --------------------------
@@ -867,27 +942,30 @@ package body Prj.Tree is
    --------------------------
 
    function First_With_Clause_Of
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Project);
-      return Project_Nodes.Table (Node).Field1;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
+      return In_Tree.Project_Nodes.Table (Node).Field1;
    end First_With_Clause_Of;
 
    ------------------------
    -- Follows_Empty_Line --
    ------------------------
 
-   function Follows_Empty_Line (Node : Project_Node_Id) return Boolean is
+   function Follows_Empty_Line
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Boolean is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
          and then
-         Project_Nodes.Table (Node).Kind = N_Comment);
-      return Project_Nodes.Table (Node).Flag1;
+         In_Tree.Project_Nodes.Table (Node).Kind = N_Comment);
+      return In_Tree.Project_Nodes.Table (Node).Flag1;
    end Follows_Empty_Line;
 
    ----------
@@ -903,76 +981,120 @@ package body Prj.Tree is
    -- Initialize --
    ----------------
 
-   procedure Initialize is
+   procedure Initialize (Tree : Project_Node_Tree_Ref) is
    begin
-      Project_Nodes.Set_Last (Empty_Node);
-      Projects_Htable.Reset;
+      Project_Node_Table.Init (Tree.Project_Nodes);
+      Projects_Htable.Reset (Tree.Projects_HT);
+
+      --  Do not reset the external references, in case we are reloading a
+      --  project, since we want to preserve the current environment
+      --  Name_To_Name_HTable.Reset (Tree.External_References);
    end Initialize;
 
+   ----------
+   -- Free --
+   ----------
+
+   procedure Free (Proj : in out Project_Node_Tree_Ref) is
+      procedure Unchecked_Free is new Ada.Unchecked_Deallocation
+        (Project_Node_Tree_Data, Project_Node_Tree_Ref);
+   begin
+      if Proj /= null then
+         Project_Node_Table.Free (Proj.Project_Nodes);
+         Projects_Htable.Reset (Proj.Projects_HT);
+         Name_To_Name_HTable.Reset (Proj.External_References);
+         Free (Proj.Project_Path);
+         Unchecked_Free (Proj);
+      end if;
+   end Free;
+
    -------------------------------
    -- Is_Followed_By_Empty_Line --
    -------------------------------
 
    function Is_Followed_By_Empty_Line
-     (Node : Project_Node_Id) return Boolean
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Boolean
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Comment);
-      return Project_Nodes.Table (Node).Flag2;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Comment);
+      return In_Tree.Project_Nodes.Table (Node).Flag2;
    end Is_Followed_By_Empty_Line;
 
    ----------------------
    -- Is_Extending_All --
    ----------------------
 
-   function Is_Extending_All (Node  : Project_Node_Id) return Boolean is
+   function Is_Extending_All
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Boolean is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-           (Project_Nodes.Table (Node).Kind = N_Project
+           (In_Tree.Project_Nodes.Table (Node).Kind = N_Project
               or else
-            Project_Nodes.Table (Node).Kind = N_With_Clause));
-      return Project_Nodes.Table (Node).Flag2;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause));
+      return In_Tree.Project_Nodes.Table (Node).Flag2;
    end Is_Extending_All;
 
+   -------------------------
+   -- Is_Not_Last_In_List --
+   -------------------------
+
+   function Is_Not_Last_In_List
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Boolean is
+   begin
+      pragma Assert
+        (Present (Node)
+          and then
+            In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause);
+      return In_Tree.Project_Nodes.Table (Node).Flag1;
+   end Is_Not_Last_In_List;
+
    -------------------------------------
    -- Imported_Or_Extended_Project_Of --
    -------------------------------------
 
    function Imported_Or_Extended_Project_Of
      (Project   : Project_Node_Id;
+      In_Tree   : Project_Node_Tree_Ref;
       With_Name : Name_Id) return Project_Node_Id
    is
-      With_Clause : Project_Node_Id := First_With_Clause_Of (Project);
+      With_Clause : Project_Node_Id :=
+        First_With_Clause_Of (Project, In_Tree);
       Result      : Project_Node_Id := Empty_Node;
 
    begin
       --  First check all the imported projects
 
-      while With_Clause /= Empty_Node loop
+      while Present (With_Clause) loop
 
          --  Only non limited imported project may be used as prefix
          --  of variable or attributes.
 
-         Result := Non_Limited_Project_Node_Of (With_Clause);
-         exit when Result /= Empty_Node and then Name_Of (Result) = With_Name;
-         With_Clause := Next_With_Clause_Of (With_Clause);
+         Result := Non_Limited_Project_Node_Of (With_Clause, In_Tree);
+         exit when Present (Result)
+           and then Name_Of (Result, In_Tree) = With_Name;
+         With_Clause := Next_With_Clause_Of (With_Clause, In_Tree);
       end loop;
 
-      --  If it is not an imported project, it might be the imported project
+      --  If it is not an imported project, it might be an extended project
 
-      if With_Clause = Empty_Node then
-         Result := Extended_Project_Of (Project_Declaration_Of (Project));
+      if No (With_Clause) then
+         Result := Project;
+         loop
+            Result :=
+              Extended_Project_Of
+                (Project_Declaration_Of (Result, In_Tree), In_Tree);
 
-         if Result /= Empty_Node
-           and then Name_Of (Result) /= With_Name
-         then
-            Result := Empty_Node;
-         end if;
+            exit when No (Result)
+              or else Name_Of (Result, In_Tree) = With_Name;
+         end loop;
       end if;
 
       return Result;
@@ -982,30 +1104,36 @@ package body Prj.Tree is
    -- Kind_Of --
    -------------
 
-   function Kind_Of (Node : Project_Node_Id) return Project_Node_Kind is
+   function Kind_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Kind is
    begin
-      pragma Assert (Node /= Empty_Node);
-      return Project_Nodes.Table (Node).Kind;
+      pragma Assert (Present (Node));
+      return In_Tree.Project_Nodes.Table (Node).Kind;
    end Kind_Of;
 
    -----------------
    -- Location_Of --
    -----------------
 
-   function Location_Of (Node : Project_Node_Id) return Source_Ptr is
+   function Location_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Source_Ptr is
    begin
-      pragma Assert (Node /= Empty_Node);
-      return Project_Nodes.Table (Node).Location;
+      pragma Assert (Present (Node));
+      return In_Tree.Project_Nodes.Table (Node).Location;
    end Location_Of;
 
    -------------
    -- Name_Of --
    -------------
 
-   function Name_Of (Node : Project_Node_Id) return Name_Id is
+   function Name_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Name_Id is
    begin
-      pragma Assert (Node /= Empty_Node);
-      return Project_Nodes.Table (Node).Name;
+      pragma Assert (Present (Node));
+      return In_Tree.Project_Nodes.Table (Node).Name;
    end Name_Of;
 
    --------------------
@@ -1013,27 +1141,30 @@ package body Prj.Tree is
    --------------------
 
    function Next_Case_Item
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Case_Item);
-      return Project_Nodes.Table (Node).Field3;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Item);
+      return In_Tree.Project_Nodes.Table (Node).Field3;
    end Next_Case_Item;
 
    ------------------
    -- Next_Comment --
    ------------------
 
-   function Next_Comment (Node : Project_Node_Id) return Project_Node_Id is
+   function Next_Comment
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Comment);
-      return Project_Nodes.Table (Node).Comments;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Comment);
+      return In_Tree.Project_Nodes.Table (Node).Comments;
    end Next_Comment;
 
    ---------------------------
@@ -1041,14 +1172,15 @@ package body Prj.Tree is
    ---------------------------
 
    function Next_Declarative_Item
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Declarative_Item);
-      return Project_Nodes.Table (Node).Field2;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Declarative_Item);
+      return In_Tree.Project_Nodes.Table (Node).Field2;
    end Next_Declarative_Item;
 
    -----------------------------
@@ -1056,14 +1188,15 @@ package body Prj.Tree is
    -----------------------------
 
    function Next_Expression_In_List
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Expression);
-      return Project_Nodes.Table (Node).Field2;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Expression);
+      return In_Tree.Project_Nodes.Table (Node).Field2;
    end Next_Expression_In_List;
 
    -------------------------
@@ -1071,15 +1204,16 @@ package body Prj.Tree is
    -------------------------
 
    function Next_Literal_String
-     (Node : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref)
       return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Literal_String);
-      return Project_Nodes.Table (Node).Field1;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String);
+      return In_Tree.Project_Nodes.Table (Node).Field1;
    end Next_Literal_String;
 
    -----------------------------
@@ -1087,14 +1221,15 @@ package body Prj.Tree is
    -----------------------------
 
    function Next_Package_In_Project
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Package_Declaration);
-      return Project_Nodes.Table (Node).Field3;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration);
+      return In_Tree.Project_Nodes.Table (Node).Field3;
    end Next_Package_In_Project;
 
    ----------------------
@@ -1102,15 +1237,17 @@ package body Prj.Tree is
    ----------------------
 
    function Next_String_Type
-     (Node : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref)
       return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_String_Type_Declaration);
-      return Project_Nodes.Table (Node).Field2;
+         In_Tree.Project_Nodes.Table (Node).Kind =
+           N_String_Type_Declaration);
+      return In_Tree.Project_Nodes.Table (Node).Field2;
    end Next_String_Type;
 
    ---------------
@@ -1118,14 +1255,15 @@ package body Prj.Tree is
    ---------------
 
    function Next_Term
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Term);
-      return Project_Nodes.Table (Node).Field2;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Term);
+      return In_Tree.Project_Nodes.Table (Node).Field2;
    end Next_Term;
 
    -------------------
@@ -1133,18 +1271,21 @@ package body Prj.Tree is
    -------------------
 
    function Next_Variable
-     (Node : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref)
       return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_Typed_Variable_Declaration
+           (In_Tree.Project_Nodes.Table (Node).Kind =
+              N_Typed_Variable_Declaration
                or else
-             Project_Nodes.Table (Node).Kind = N_Variable_Declaration));
+            In_Tree.Project_Nodes.Table (Node).Kind =
+              N_Variable_Declaration));
 
-      return Project_Nodes.Table (Node).Field3;
+      return In_Tree.Project_Nodes.Table (Node).Field3;
    end Next_Variable;
 
    -------------------------
@@ -1152,42 +1293,56 @@ package body Prj.Tree is
    -------------------------
 
    function Next_With_Clause_Of
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_With_Clause);
-      return Project_Nodes.Table (Node).Field2;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause);
+      return In_Tree.Project_Nodes.Table (Node).Field2;
    end Next_With_Clause_Of;
 
+   --------
+   -- No --
+   --------
+
+   function No (Node : Project_Node_Id) return Boolean is
+   begin
+      return Node = Empty_Node;
+   end No;
+
    ---------------------------------
    -- Non_Limited_Project_Node_Of --
    ---------------------------------
 
    function Non_Limited_Project_Node_Of
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-           (Project_Nodes.Table (Node).Kind = N_With_Clause));
-      return Project_Nodes.Table (Node).Field3;
+           (In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause));
+      return In_Tree.Project_Nodes.Table (Node).Field3;
    end Non_Limited_Project_Node_Of;
 
    -------------------
    -- Package_Id_Of --
    -------------------
 
-   function Package_Id_Of (Node : Project_Node_Id) return Package_Node_Id is
+   function Package_Id_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Package_Node_Id
+   is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Package_Declaration);
-      return Project_Nodes.Table (Node).Pkg_Id;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration);
+      return In_Tree.Project_Nodes.Table (Node).Pkg_Id;
    end Package_Id_Of;
 
    ---------------------
@@ -1195,58 +1350,106 @@ package body Prj.Tree is
    ---------------------
 
    function Package_Node_Of
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_Variable_Reference
+            (In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference
                or else
-             Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
-      return Project_Nodes.Table (Node).Field2;
+             In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
+      return In_Tree.Project_Nodes.Table (Node).Field2;
    end Package_Node_Of;
 
    ------------------
    -- Path_Name_Of --
    ------------------
 
-   function Path_Name_Of (Node : Project_Node_Id) return Name_Id is
+   function Path_Name_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Path_Name_Type
+   is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_Project
+            (In_Tree.Project_Nodes.Table (Node).Kind = N_Project
                or else
-             Project_Nodes.Table (Node).Kind = N_With_Clause));
-      return Project_Nodes.Table (Node).Path_Name;
+             In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause));
+      return In_Tree.Project_Nodes.Table (Node).Path_Name;
    end Path_Name_Of;
 
+   -------------
+   -- Present --
+   -------------
+
+   function Present (Node : Project_Node_Id) return Boolean is
+   begin
+      return Node /= Empty_Node;
+   end Present;
+
    ----------------------------
    -- Project_Declaration_Of --
    ----------------------------
 
    function Project_Declaration_Of
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Project);
-      return Project_Nodes.Table (Node).Field2;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
+      return In_Tree.Project_Nodes.Table (Node).Field2;
    end Project_Declaration_Of;
 
+   --------------------------
+   -- Project_Qualifier_Of --
+   --------------------------
+
+   function Project_Qualifier_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Qualifier
+   is
+   begin
+      pragma Assert
+        (Present (Node)
+          and then
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
+      return In_Tree.Project_Nodes.Table (Node).Qualifier;
+   end Project_Qualifier_Of;
+
+   -----------------------
+   -- Parent_Project_Of --
+   -----------------------
+
+   function Parent_Project_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
+   is
+   begin
+      pragma Assert
+        (Present (Node)
+          and then
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
+      return In_Tree.Project_Nodes.Table (Node).Field4;
+   end Parent_Project_Of;
+
    -------------------------------------------
    -- Project_File_Includes_Unkept_Comments --
    -------------------------------------------
 
    function Project_File_Includes_Unkept_Comments
-     (Node : Project_Node_Id) return Boolean
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Boolean
    is
-      Declaration : constant Project_Node_Id := Project_Declaration_Of (Node);
+      Declaration : constant Project_Node_Id :=
+                      Project_Declaration_Of (Node, In_Tree);
    begin
-      return Project_Nodes.Table (Declaration).Flag1;
+      return In_Tree.Project_Nodes.Table (Declaration).Flag1;
    end Project_File_Includes_Unkept_Comments;
 
    ---------------------
@@ -1254,18 +1457,19 @@ package body Prj.Tree is
    ---------------------
 
    function Project_Node_Of
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-           (Project_Nodes.Table (Node).Kind = N_With_Clause
+           (In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause
               or else
-            Project_Nodes.Table (Node).Kind = N_Variable_Reference
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference
               or else
-            Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
-      return Project_Nodes.Table (Node).Field1;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
+      return In_Tree.Project_Nodes.Table (Node).Field1;
    end Project_Node_Of;
 
    -----------------------------------
@@ -1273,14 +1477,15 @@ package body Prj.Tree is
    -----------------------------------
 
    function Project_Of_Renamed_Package_Of
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Package_Declaration);
-      return Project_Nodes.Table (Node).Field1;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration);
+      return In_Tree.Project_Nodes.Table (Node).Field1;
    end Project_Of_Renamed_Package_Of;
 
    --------------------------
@@ -1305,11 +1510,14 @@ package body Prj.Tree is
       Comments.Set_Last (0);
    end Reset_State;
 
-   -------------
-   -- Restore --
-   -------------
+   ----------------------
+   -- Restore_And_Free --
+   ----------------------
+
+   procedure Restore_And_Free (S : in out Comment_State) is
+      procedure Unchecked_Free is new
+        Ada.Unchecked_Deallocation (Comment_Array, Comments_Ptr);
 
-   procedure Restore (S : in Comment_State) is
    begin
       End_Of_Line_Node   := S.End_Of_Line_Node;
       Previous_Line_Node := S.Previous_Line_Node;
@@ -1323,7 +1531,9 @@ package body Prj.Tree is
          Comments.Increment_Last;
          Comments.Table (Comments.Last) := S.Comments (J);
       end loop;
-   end Restore;
+
+      Unchecked_Free (S.Comments);
+   end Restore_And_Free;
 
    ----------
    -- Save --
@@ -1349,8 +1559,9 @@ package body Prj.Tree is
    -- Scan --
    ----------
 
-   procedure Scan is
+   procedure Scan (In_Tree : Project_Node_Tree_Ref) is
       Empty_Line : Boolean := False;
+
    begin
       --  If there are comments, then they will not be kept. Set the flag and
       --  clear the comments.
@@ -1392,12 +1603,12 @@ package body Prj.Tree is
                --  an end of line node specified, associate the comment with
                --  this node.
 
-               elsif End_Of_Line_Node /= Empty_Node then
+               elsif Present (End_Of_Line_Node) then
                   declare
                      Zones : constant Project_Node_Id :=
-                               Comment_Zones_Of (End_Of_Line_Node);
+                               Comment_Zones_Of (End_Of_Line_Node, In_Tree);
                   begin
-                     Project_Nodes.Table (Zones).Value := Comment_Id;
+                     In_Tree.Project_Nodes.Table (Zones).Value := Comment_Id;
                   end;
 
                --  Otherwise, this end of line node cannot be kept
@@ -1417,13 +1628,17 @@ package body Prj.Tree is
 
                if Comments.Last > 0 and then
                  not Comments.Table (1).Follows_Empty_Line then
-                  if Previous_Line_Node /= Empty_Node then
+                  if Present (Previous_Line_Node) then
                      Add_Comments
-                       (To => Previous_Line_Node, Where => After);
+                       (To      => Previous_Line_Node,
+                        Where   => After,
+                        In_Tree => In_Tree);
 
-                  elsif Previous_End_Node /= Empty_Node then
+                  elsif Present (Previous_End_Node) then
                      Add_Comments
-                       (To => Previous_End_Node, Where => After_End);
+                       (To      => Previous_End_Node,
+                        Where   => After_End,
+                        In_Tree => In_Tree);
                   end if;
                end if;
 
@@ -1435,8 +1650,9 @@ package body Prj.Tree is
                if Comments.Last > 0 and then Token = Tok_End then
                   if Next_End_Nodes.Last > 0 then
                      Add_Comments
-                       (To => Next_End_Nodes.Table (Next_End_Nodes.Last),
-                        Where => Before_End);
+                       (To      => Next_End_Nodes.Table (Next_End_Nodes.Last),
+                        Where   => Before_End,
+                        In_Tree => In_Tree);
 
                   else
                      Unkept_Comments := True;
@@ -1464,17 +1680,18 @@ package body Prj.Tree is
    ------------------------------------
 
    procedure Set_Associative_Array_Index_Of
-     (Node : Project_Node_Id;
-      To   : Name_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Name_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
+            (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
                or else
-             Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
-      Project_Nodes.Table (Node).Value := To;
+             In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
+      In_Tree.Project_Nodes.Table (Node).Value := To;
    end Set_Associative_Array_Index_Of;
 
    --------------------------------
@@ -1482,15 +1699,16 @@ package body Prj.Tree is
    --------------------------------
 
    procedure Set_Associative_Package_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-         (Node /= Empty_Node
+         (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Attribute_Declaration);
-      Project_Nodes.Table (Node).Field3 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration);
+      In_Tree.Project_Nodes.Table (Node).Field3 := To;
    end Set_Associative_Package_Of;
 
    --------------------------------
@@ -1498,15 +1716,17 @@ package body Prj.Tree is
    --------------------------------
 
    procedure Set_Associative_Project_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_Attribute_Declaration));
-      Project_Nodes.Table (Node).Field2 := To;
+           (In_Tree.Project_Nodes.Table (Node).Kind =
+              N_Attribute_Declaration));
+      In_Tree.Project_Nodes.Table (Node).Field2 := To;
    end Set_Associative_Project_Of;
 
    --------------------------
@@ -1514,17 +1734,18 @@ package body Prj.Tree is
    --------------------------
 
    procedure Set_Case_Insensitive
-     (Node : Project_Node_Id;
-      To   : Boolean)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Boolean)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-           (Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
+           (In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
                or else
-            Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
-      Project_Nodes.Table (Node).Flag1 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
+      In_Tree.Project_Nodes.Table (Node).Flag1 := To;
    end Set_Case_Insensitive;
 
    ------------------------------------
@@ -1532,15 +1753,16 @@ package body Prj.Tree is
    ------------------------------------
 
    procedure Set_Case_Variable_Reference_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Case_Construction);
-      Project_Nodes.Table (Node).Field1 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Construction);
+      In_Tree.Project_Nodes.Table (Node).Field1 := To;
    end Set_Case_Variable_Reference_Of;
 
    ---------------------------
@@ -1548,15 +1770,16 @@ package body Prj.Tree is
    ---------------------------
 
    procedure Set_Current_Item_Node
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Declarative_Item);
-      Project_Nodes.Table (Node).Field1 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Declarative_Item);
+      In_Tree.Project_Nodes.Table (Node).Field1 := To;
    end Set_Current_Item_Node;
 
    ----------------------
@@ -1564,15 +1787,16 @@ package body Prj.Tree is
    ----------------------
 
    procedure Set_Current_Term
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Term);
-      Project_Nodes.Table (Node).Field1 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Term);
+      In_Tree.Project_Nodes.Table (Node).Field1 := To;
    end Set_Current_Term;
 
    ----------------------
@@ -1580,15 +1804,16 @@ package body Prj.Tree is
    ----------------------
 
    procedure Set_Directory_Of
-     (Node : Project_Node_Id;
-      To   : Name_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Path_Name_Type)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Project);
-      Project_Nodes.Table (Node).Directory := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
+      In_Tree.Project_Nodes.Table (Node).Directory := To;
    end Set_Directory_Of;
 
    ---------------------
@@ -1605,31 +1830,34 @@ package body Prj.Tree is
    ----------------------------
 
    procedure Set_Expression_Kind_Of
-     (Node : Project_Node_Id;
-      To   : Variable_Kind)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Variable_Kind)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
            and then
-             (Project_Nodes.Table (Node).Kind = N_Literal_String
+             (In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String
                 or else
-              Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
+              In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
                 or else
-              Project_Nodes.Table (Node).Kind = N_Variable_Declaration
+              In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Declaration
                 or else
-              Project_Nodes.Table (Node).Kind = N_Typed_Variable_Declaration
+              In_Tree.Project_Nodes.Table (Node).Kind =
+                N_Typed_Variable_Declaration
                 or else
-              Project_Nodes.Table (Node).Kind = N_Package_Declaration
+              In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration
                 or else
-              Project_Nodes.Table (Node).Kind = N_Expression
+              In_Tree.Project_Nodes.Table (Node).Kind = N_Expression
                 or else
-              Project_Nodes.Table (Node).Kind = N_Term
+              In_Tree.Project_Nodes.Table (Node).Kind = N_Term
                 or else
-              Project_Nodes.Table (Node).Kind = N_Variable_Reference
+              In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference
                 or else
-              Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
-      Project_Nodes.Table (Node).Expr_Kind := To;
+              In_Tree.Project_Nodes.Table (Node).Kind =
+                N_Attribute_Reference));
+      In_Tree.Project_Nodes.Table (Node).Expr_Kind := To;
    end Set_Expression_Kind_Of;
 
    -----------------------
@@ -1637,19 +1865,23 @@ package body Prj.Tree is
    -----------------------
 
    procedure Set_Expression_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_Attribute_Declaration
+           (In_Tree.Project_Nodes.Table (Node).Kind =
+              N_Attribute_Declaration
                or else
-             Project_Nodes.Table (Node).Kind = N_Typed_Variable_Declaration
+            In_Tree.Project_Nodes.Table (Node).Kind =
+              N_Typed_Variable_Declaration
                or else
-             Project_Nodes.Table (Node).Kind = N_Variable_Declaration));
-      Project_Nodes.Table (Node).Field1 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind =
+              N_Variable_Declaration));
+      In_Tree.Project_Nodes.Table (Node).Field1 := To;
    end Set_Expression_Of;
 
    -------------------------------
@@ -1657,15 +1889,16 @@ package body Prj.Tree is
    -------------------------------
 
    procedure Set_External_Reference_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_External_Value);
-      Project_Nodes.Table (Node).Field1 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_External_Value);
+      In_Tree.Project_Nodes.Table (Node).Field1 := To;
    end Set_External_Reference_Of;
 
    -----------------------------
@@ -1673,15 +1906,16 @@ package body Prj.Tree is
    -----------------------------
 
    procedure Set_External_Default_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_External_Value);
-      Project_Nodes.Table (Node).Field2 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_External_Value);
+      In_Tree.Project_Nodes.Table (Node).Field2 := To;
    end Set_External_Default_Of;
 
    ----------------------------
@@ -1689,15 +1923,16 @@ package body Prj.Tree is
    ----------------------------
 
    procedure Set_First_Case_Item_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Case_Construction);
-      Project_Nodes.Table (Node).Field2 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Construction);
+      In_Tree.Project_Nodes.Table (Node).Field2 := To;
    end Set_First_Case_Item_Of;
 
    -------------------------
@@ -1705,15 +1940,16 @@ package body Prj.Tree is
    -------------------------
 
    procedure Set_First_Choice_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Case_Item);
-      Project_Nodes.Table (Node).Field1 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Item);
+      In_Tree.Project_Nodes.Table (Node).Field1 := To;
    end Set_First_Choice_Of;
 
    -----------------------------
@@ -1721,12 +1957,13 @@ package body Prj.Tree is
    -----------------------------
 
    procedure Set_First_Comment_After
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
-      Zone : constant Project_Node_Id := Comment_Zones_Of (Node);
+      Zone : constant Project_Node_Id := Comment_Zones_Of (Node, In_Tree);
    begin
-      Project_Nodes.Table (Zone).Field2 := To;
+      In_Tree.Project_Nodes.Table (Zone).Field2 := To;
    end Set_First_Comment_After;
 
    ---------------------------------
@@ -1734,12 +1971,13 @@ package body Prj.Tree is
    ---------------------------------
 
    procedure Set_First_Comment_After_End
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
-      Zone : constant Project_Node_Id := Comment_Zones_Of (Node);
+      Zone : constant Project_Node_Id := Comment_Zones_Of (Node, In_Tree);
    begin
-      Project_Nodes.Table (Zone).Comments := To;
+      In_Tree.Project_Nodes.Table (Zone).Comments := To;
    end Set_First_Comment_After_End;
 
    ------------------------------
@@ -1747,13 +1985,14 @@ package body Prj.Tree is
    ------------------------------
 
    procedure Set_First_Comment_Before
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
 
    is
-      Zone : constant Project_Node_Id := Comment_Zones_Of (Node);
+      Zone : constant Project_Node_Id := Comment_Zones_Of (Node, In_Tree);
    begin
-      Project_Nodes.Table (Zone).Field1 := To;
+      In_Tree.Project_Nodes.Table (Zone).Field1 := To;
    end Set_First_Comment_Before;
 
    ----------------------------------
@@ -1761,12 +2000,13 @@ package body Prj.Tree is
    ----------------------------------
 
    procedure Set_First_Comment_Before_End
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
-      Zone : constant Project_Node_Id := Comment_Zones_Of (Node);
+      Zone : constant Project_Node_Id := Comment_Zones_Of (Node, In_Tree);
    begin
-      Project_Nodes.Table (Zone).Field2 := To;
+      In_Tree.Project_Nodes.Table (Zone).Field2 := To;
    end Set_First_Comment_Before_End;
 
    ------------------------
@@ -1774,15 +2014,16 @@ package body Prj.Tree is
    ------------------------
 
    procedure Set_Next_Case_Item
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Case_Item);
-      Project_Nodes.Table (Node).Field3 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Item);
+      In_Tree.Project_Nodes.Table (Node).Field3 := To;
    end Set_Next_Case_Item;
 
    ----------------------
@@ -1790,15 +2031,16 @@ package body Prj.Tree is
    ----------------------
 
    procedure Set_Next_Comment
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Comment);
-      Project_Nodes.Table (Node).Comments := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Comment);
+      In_Tree.Project_Nodes.Table (Node).Comments := To;
    end Set_Next_Comment;
 
    -----------------------------------
@@ -1806,23 +2048,24 @@ package body Prj.Tree is
    -----------------------------------
 
    procedure Set_First_Declarative_Item_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_Project_Declaration
+            (In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration
                or else
-             Project_Nodes.Table (Node).Kind = N_Case_Item
+             In_Tree.Project_Nodes.Table (Node).Kind = N_Case_Item
                or else
-             Project_Nodes.Table (Node).Kind = N_Package_Declaration));
+             In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration));
 
-      if Project_Nodes.Table (Node).Kind = N_Project_Declaration then
-         Project_Nodes.Table (Node).Field1 := To;
+      if In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration then
+         In_Tree.Project_Nodes.Table (Node).Field1 := To;
       else
-         Project_Nodes.Table (Node).Field2 := To;
+         In_Tree.Project_Nodes.Table (Node).Field2 := To;
       end if;
    end Set_First_Declarative_Item_Of;
 
@@ -1831,15 +2074,16 @@ package body Prj.Tree is
    ----------------------------------
 
    procedure Set_First_Expression_In_List
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Literal_String_List);
-      Project_Nodes.Table (Node).Field1 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String_List);
+      In_Tree.Project_Nodes.Table (Node).Field1 := To;
    end Set_First_Expression_In_List;
 
    ------------------------------
@@ -1847,15 +2091,17 @@ package body Prj.Tree is
    ------------------------------
 
    procedure Set_First_Literal_String
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_String_Type_Declaration);
-      Project_Nodes.Table (Node).Field1 := To;
+         In_Tree.Project_Nodes.Table (Node).Kind =
+           N_String_Type_Declaration);
+      In_Tree.Project_Nodes.Table (Node).Field1 := To;
    end Set_First_Literal_String;
 
    --------------------------
@@ -1863,15 +2109,16 @@ package body Prj.Tree is
    --------------------------
 
    procedure Set_First_Package_Of
-     (Node : Project_Node_Id;
-      To   : Package_Declaration_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Package_Declaration_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Project);
-      Project_Nodes.Table (Node).Packages := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
+      In_Tree.Project_Nodes.Table (Node).Packages := To;
    end Set_First_Package_Of;
 
    ------------------------------
@@ -1879,15 +2126,16 @@ package body Prj.Tree is
    ------------------------------
 
    procedure Set_First_String_Type_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Project);
-      Project_Nodes.Table (Node).Field3 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
+      In_Tree.Project_Nodes.Table (Node).Field3 := To;
    end Set_First_String_Type_Of;
 
    --------------------
@@ -1895,15 +2143,16 @@ package body Prj.Tree is
    --------------------
 
    procedure Set_First_Term
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Expression);
-      Project_Nodes.Table (Node).Field1 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Expression);
+      In_Tree.Project_Nodes.Table (Node).Field1 := To;
    end Set_First_Term;
 
    ---------------------------
@@ -1911,17 +2160,18 @@ package body Prj.Tree is
    ---------------------------
 
    procedure Set_First_Variable_Of
-     (Node : Project_Node_Id;
-      To   : Variable_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Variable_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_Project
+            (In_Tree.Project_Nodes.Table (Node).Kind = N_Project
                or else
-             Project_Nodes.Table (Node).Kind = N_Package_Declaration));
-      Project_Nodes.Table (Node).Variables := To;
+             In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration));
+      In_Tree.Project_Nodes.Table (Node).Variables := To;
    end Set_First_Variable_Of;
 
    ------------------------------
@@ -1929,43 +2179,64 @@ package body Prj.Tree is
    ------------------------------
 
    procedure Set_First_With_Clause_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Project);
-      Project_Nodes.Table (Node).Field1 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
+      In_Tree.Project_Nodes.Table (Node).Field1 := To;
    end Set_First_With_Clause_Of;
 
    --------------------------
    -- Set_Is_Extending_All --
    --------------------------
 
-   procedure Set_Is_Extending_All (Node  : Project_Node_Id) is
+   procedure Set_Is_Extending_All
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref)
+   is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_Project
+            (In_Tree.Project_Nodes.Table (Node).Kind = N_Project
                or else
-             Project_Nodes.Table (Node).Kind = N_With_Clause));
-      Project_Nodes.Table (Node).Flag2 := True;
+             In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause));
+      In_Tree.Project_Nodes.Table (Node).Flag2 := True;
    end Set_Is_Extending_All;
 
+   -----------------------------
+   -- Set_Is_Not_Last_In_List --
+   -----------------------------
+
+   procedure Set_Is_Not_Last_In_List
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref)
+   is
+   begin
+      pragma Assert
+        (Present (Node)
+          and then
+             In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause);
+      In_Tree.Project_Nodes.Table (Node).Flag1 := True;
+   end Set_Is_Not_Last_In_List;
+
    -----------------
    -- Set_Kind_Of --
    -----------------
 
    procedure Set_Kind_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Kind)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Kind)
    is
    begin
-      pragma Assert (Node /= Empty_Node);
-      Project_Nodes.Table (Node).Kind := To;
+      pragma Assert (Present (Node));
+      In_Tree.Project_Nodes.Table (Node).Kind := To;
    end Set_Kind_Of;
 
    ---------------------
@@ -1973,12 +2244,13 @@ package body Prj.Tree is
    ---------------------
 
    procedure Set_Location_Of
-     (Node : Project_Node_Id;
-      To   : Source_Ptr)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Source_Ptr)
    is
    begin
-      pragma Assert (Node /= Empty_Node);
-      Project_Nodes.Table (Node).Location := To;
+      pragma Assert (Present (Node));
+      In_Tree.Project_Nodes.Table (Node).Location := To;
    end Set_Location_Of;
 
    -----------------------------
@@ -1986,15 +2258,16 @@ package body Prj.Tree is
    -----------------------------
 
    procedure Set_Extended_Project_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Project_Declaration);
-      Project_Nodes.Table (Node).Field2 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration);
+      In_Tree.Project_Nodes.Table (Node).Field2 := To;
    end Set_Extended_Project_Of;
 
    ----------------------------------
@@ -2002,15 +2275,16 @@ package body Prj.Tree is
    ----------------------------------
 
    procedure Set_Extended_Project_Path_Of
-     (Node : Project_Node_Id;
-      To   : Name_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Path_Name_Type)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Project);
-      Project_Nodes.Table (Node).Value := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
+      In_Tree.Project_Nodes.Table (Node).Value := Name_Id (To);
    end Set_Extended_Project_Path_Of;
 
    ------------------------------
@@ -2018,15 +2292,16 @@ package body Prj.Tree is
    ------------------------------
 
    procedure Set_Extending_Project_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Project_Declaration);
-      Project_Nodes.Table (Node).Field3 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Project_Declaration);
+      In_Tree.Project_Nodes.Table (Node).Field3 := To;
    end Set_Extending_Project_Of;
 
    -----------------
@@ -2034,12 +2309,13 @@ package body Prj.Tree is
    -----------------
 
    procedure Set_Name_Of
-     (Node : Project_Node_Id;
-      To   : Name_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Name_Id)
    is
    begin
-      pragma Assert (Node /= Empty_Node);
-      Project_Nodes.Table (Node).Name := To;
+      pragma Assert (Present (Node));
+      In_Tree.Project_Nodes.Table (Node).Name := To;
    end Set_Name_Of;
 
    -------------------------------
@@ -2047,15 +2323,16 @@ package body Prj.Tree is
    -------------------------------
 
    procedure Set_Next_Declarative_Item
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Declarative_Item);
-      Project_Nodes.Table (Node).Field2 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Declarative_Item);
+      In_Tree.Project_Nodes.Table (Node).Field2 := To;
    end Set_Next_Declarative_Item;
 
    -----------------------
@@ -2073,15 +2350,16 @@ package body Prj.Tree is
    ---------------------------------
 
    procedure Set_Next_Expression_In_List
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Expression);
-      Project_Nodes.Table (Node).Field2 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Expression);
+      In_Tree.Project_Nodes.Table (Node).Field2 := To;
    end Set_Next_Expression_In_List;
 
    -----------------------------
@@ -2089,15 +2367,16 @@ package body Prj.Tree is
    -----------------------------
 
    procedure Set_Next_Literal_String
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Literal_String);
-      Project_Nodes.Table (Node).Field1 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String);
+      In_Tree.Project_Nodes.Table (Node).Field1 := To;
    end Set_Next_Literal_String;
 
    ---------------------------------
@@ -2105,15 +2384,16 @@ package body Prj.Tree is
    ---------------------------------
 
    procedure Set_Next_Package_In_Project
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Package_Declaration);
-      Project_Nodes.Table (Node).Field3 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration);
+      In_Tree.Project_Nodes.Table (Node).Field3 := To;
    end Set_Next_Package_In_Project;
 
    --------------------------
@@ -2121,15 +2401,17 @@ package body Prj.Tree is
    --------------------------
 
    procedure Set_Next_String_Type
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_String_Type_Declaration);
-      Project_Nodes.Table (Node).Field2 := To;
+         In_Tree.Project_Nodes.Table (Node).Kind =
+           N_String_Type_Declaration);
+      In_Tree.Project_Nodes.Table (Node).Field2 := To;
    end Set_Next_String_Type;
 
    -------------------
@@ -2137,15 +2419,16 @@ package body Prj.Tree is
    -------------------
 
    procedure Set_Next_Term
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Term);
-      Project_Nodes.Table (Node).Field2 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Term);
+      In_Tree.Project_Nodes.Table (Node).Field2 := To;
    end Set_Next_Term;
 
    -----------------------
@@ -2153,17 +2436,20 @@ package body Prj.Tree is
    -----------------------
 
    procedure Set_Next_Variable
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_Typed_Variable_Declaration
+           (In_Tree.Project_Nodes.Table (Node).Kind =
+              N_Typed_Variable_Declaration
                or else
-             Project_Nodes.Table (Node).Kind = N_Variable_Declaration));
-      Project_Nodes.Table (Node).Field3 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind =
+              N_Variable_Declaration));
+      In_Tree.Project_Nodes.Table (Node).Field3 := To;
    end Set_Next_Variable;
 
    -----------------------------
@@ -2171,15 +2457,16 @@ package body Prj.Tree is
    -----------------------------
 
    procedure Set_Next_With_Clause_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_With_Clause);
-      Project_Nodes.Table (Node).Field2 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause);
+      In_Tree.Project_Nodes.Table (Node).Field2 := To;
    end Set_Next_With_Clause_Of;
 
    -----------------------
@@ -2187,15 +2474,16 @@ package body Prj.Tree is
    -----------------------
 
    procedure Set_Package_Id_Of
-     (Node : Project_Node_Id;
-      To   : Package_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Package_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Package_Declaration);
-      Project_Nodes.Table (Node).Pkg_Id := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration);
+      In_Tree.Project_Nodes.Table (Node).Pkg_Id := To;
    end Set_Package_Id_Of;
 
    -------------------------
@@ -2203,17 +2491,18 @@ package body Prj.Tree is
    -------------------------
 
    procedure Set_Package_Node_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_Variable_Reference
+            (In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference
                or else
-             Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
-      Project_Nodes.Table (Node).Field2 := To;
+             In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
+      In_Tree.Project_Nodes.Table (Node).Field2 := To;
    end Set_Package_Node_Of;
 
    ----------------------
@@ -2221,17 +2510,18 @@ package body Prj.Tree is
    ----------------------
 
    procedure Set_Path_Name_Of
-     (Node : Project_Node_Id;
-      To   : Name_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Path_Name_Type)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_Project
+            (In_Tree.Project_Nodes.Table (Node).Kind = N_Project
                or else
-             Project_Nodes.Table (Node).Kind = N_With_Clause));
-      Project_Nodes.Table (Node).Path_Name := To;
+             In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause));
+      In_Tree.Project_Nodes.Table (Node).Path_Name := To;
    end Set_Path_Name_Of;
 
    ---------------------------
@@ -2256,28 +2546,63 @@ package body Prj.Tree is
    --------------------------------
 
    procedure Set_Project_Declaration_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
          and then
-           Project_Nodes.Table (Node).Kind = N_Project);
-      Project_Nodes.Table (Node).Field2 := To;
+           In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
+      In_Tree.Project_Nodes.Table (Node).Field2 := To;
    end Set_Project_Declaration_Of;
 
+   ------------------------------
+   -- Set_Project_Qualifier_Of --
+   ------------------------------
+
+   procedure Set_Project_Qualifier_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Qualifier)
+   is
+   begin
+      pragma Assert
+        (Present (Node)
+          and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
+      In_Tree.Project_Nodes.Table (Node).Qualifier := To;
+   end Set_Project_Qualifier_Of;
+
+   ---------------------------
+   -- Set_Parent_Project_Of --
+   ---------------------------
+
+   procedure Set_Parent_Project_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
+   is
+   begin
+      pragma Assert
+        (Present (Node)
+          and then In_Tree.Project_Nodes.Table (Node).Kind = N_Project);
+      In_Tree.Project_Nodes.Table (Node).Field4 := To;
+   end Set_Parent_Project_Of;
+
    -----------------------------------------------
    -- Set_Project_File_Includes_Unkept_Comments --
    -----------------------------------------------
 
    procedure Set_Project_File_Includes_Unkept_Comments
-     (Node : Project_Node_Id;
-      To   : Boolean)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Boolean)
    is
-      Declaration : constant Project_Node_Id := Project_Declaration_Of (Node);
+      Declaration : constant Project_Node_Id :=
+                      Project_Declaration_Of (Node, In_Tree);
    begin
-      Project_Nodes.Table (Declaration).Flag1 := To;
+      In_Tree.Project_Nodes.Table (Declaration).Flag1 := To;
    end Set_Project_File_Includes_Unkept_Comments;
 
    -------------------------
@@ -2286,24 +2611,25 @@ package body Prj.Tree is
 
    procedure Set_Project_Node_Of
      (Node         : Project_Node_Id;
+      In_Tree      : Project_Node_Tree_Ref;
       To           : Project_Node_Id;
       Limited_With : Boolean := False)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_With_Clause
+            (In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause
                or else
-             Project_Nodes.Table (Node).Kind = N_Variable_Reference
+             In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference
                or else
-             Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
-      Project_Nodes.Table (Node).Field1 := To;
+             In_Tree.Project_Nodes.Table (Node).Kind = N_Attribute_Reference));
+      In_Tree.Project_Nodes.Table (Node).Field1 := To;
 
-      if Project_Nodes.Table (Node).Kind = N_With_Clause
+      if In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause
         and then not Limited_With
       then
-         Project_Nodes.Table (Node).Field3 := To;
+         In_Tree.Project_Nodes.Table (Node).Field3 := To;
       end if;
    end Set_Project_Node_Of;
 
@@ -2312,39 +2638,63 @@ package body Prj.Tree is
    ---------------------------------------
 
    procedure Set_Project_Of_Renamed_Package_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            Project_Nodes.Table (Node).Kind = N_Package_Declaration);
-      Project_Nodes.Table (Node).Field1 := To;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Package_Declaration);
+      In_Tree.Project_Nodes.Table (Node).Field1 := To;
    end Set_Project_Of_Renamed_Package_Of;
 
+   -------------------------
+   -- Set_Source_Index_Of --
+   -------------------------
+
+   procedure Set_Source_Index_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Int)
+   is
+   begin
+      pragma Assert
+        (Present (Node)
+          and then
+           (In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String
+            or else
+            In_Tree.Project_Nodes.Table (Node).Kind =
+              N_Attribute_Declaration));
+      In_Tree.Project_Nodes.Table (Node).Src_Index := To;
+   end Set_Source_Index_Of;
+
    ------------------------
    -- Set_String_Type_Of --
    ------------------------
 
    procedure Set_String_Type_Of
-     (Node : Project_Node_Id;
-      To   : Project_Node_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Project_Node_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_Variable_Reference
+           (In_Tree.Project_Nodes.Table (Node).Kind =
+              N_Variable_Reference
                or else
-             Project_Nodes.Table (Node).Kind = N_Typed_Variable_Declaration)
-           and then
-            Project_Nodes.Table (To).Kind    = N_String_Type_Declaration);
+            In_Tree.Project_Nodes.Table (Node).Kind =
+              N_Typed_Variable_Declaration)
+          and then
+            In_Tree.Project_Nodes.Table (To).Kind = N_String_Type_Declaration);
 
-      if Project_Nodes.Table (Node).Kind = N_Variable_Reference then
-         Project_Nodes.Table (Node).Field3 := To;
+      if In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference then
+         In_Tree.Project_Nodes.Table (Node).Field3 := To;
       else
-         Project_Nodes.Table (Node).Field2 := To;
+         In_Tree.Project_Nodes.Table (Node).Field2 := To;
       end if;
    end Set_String_Type_Of;
 
@@ -2353,40 +2703,63 @@ package body Prj.Tree is
    -------------------------
 
    procedure Set_String_Value_Of
-     (Node : Project_Node_Id;
-      To   : Name_Id)
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref;
+      To      : Name_Id)
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_With_Clause
+            (In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause
                or else
-             Project_Nodes.Table (Node).Kind = N_Comment
+             In_Tree.Project_Nodes.Table (Node).Kind = N_Comment
                or else
-             Project_Nodes.Table (Node).Kind = N_Literal_String));
-      Project_Nodes.Table (Node).Value := To;
+             In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String));
+      In_Tree.Project_Nodes.Table (Node).Value := To;
    end Set_String_Value_Of;
 
+   ---------------------
+   -- Source_Index_Of --
+   ---------------------
+
+   function Source_Index_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Int
+   is
+   begin
+      pragma Assert
+        (Present (Node)
+          and then
+            (In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String
+              or else
+             In_Tree.Project_Nodes.Table (Node).Kind =
+               N_Attribute_Declaration));
+      return In_Tree.Project_Nodes.Table (Node).Src_Index;
+   end Source_Index_Of;
+
    --------------------
    -- String_Type_Of --
    --------------------
 
    function String_Type_Of
-     (Node : Project_Node_Id) return Project_Node_Id
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Project_Node_Id
    is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-            (Project_Nodes.Table (Node).Kind = N_Variable_Reference
+           (In_Tree.Project_Nodes.Table (Node).Kind =
+              N_Variable_Reference
                or else
-             Project_Nodes.Table (Node).Kind = N_Typed_Variable_Declaration));
+            In_Tree.Project_Nodes.Table (Node).Kind =
+              N_Typed_Variable_Declaration));
 
-      if Project_Nodes.Table (Node).Kind = N_Variable_Reference then
-         return Project_Nodes.Table (Node).Field3;
+      if In_Tree.Project_Nodes.Table (Node).Kind = N_Variable_Reference then
+         return In_Tree.Project_Nodes.Table (Node).Field3;
       else
-         return Project_Nodes.Table (Node).Field2;
+         return In_Tree.Project_Nodes.Table (Node).Field2;
       end if;
    end String_Type_Of;
 
@@ -2394,17 +2767,20 @@ package body Prj.Tree is
    -- String_Value_Of --
    ---------------------
 
-   function String_Value_Of (Node : Project_Node_Id) return Name_Id is
+   function String_Value_Of
+     (Node    : Project_Node_Id;
+      In_Tree : Project_Node_Tree_Ref) return Name_Id
+   is
    begin
       pragma Assert
-        (Node /= Empty_Node
+        (Present (Node)
           and then
-           (Project_Nodes.Table (Node).Kind = N_With_Clause
+           (In_Tree.Project_Nodes.Table (Node).Kind = N_With_Clause
               or else
-            Project_Nodes.Table (Node).Kind = N_Comment
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Comment
                or else
-            Project_Nodes.Table (Node).Kind = N_Literal_String));
-      return Project_Nodes.Table (Node).Value;
+            In_Tree.Project_Nodes.Table (Node).Kind = N_Literal_String));
+      return In_Tree.Project_Nodes.Table (Node).Value;
    end String_Value_Of;
 
    --------------------
@@ -2413,30 +2789,32 @@ package body Prj.Tree is
 
    function Value_Is_Valid
      (For_Typed_Variable : Project_Node_Id;
+      In_Tree            : Project_Node_Tree_Ref;
       Value              : Name_Id) return Boolean
    is
    begin
       pragma Assert
-        (For_Typed_Variable /= Empty_Node
+        (Present (For_Typed_Variable)
           and then
-           (Project_Nodes.Table (For_Typed_Variable).Kind =
+           (In_Tree.Project_Nodes.Table (For_Typed_Variable).Kind =
                                      N_Typed_Variable_Declaration));
 
       declare
          Current_String : Project_Node_Id :=
                             First_Literal_String
-                              (String_Type_Of (For_Typed_Variable));
+                              (String_Type_Of (For_Typed_Variable, In_Tree),
+                               In_Tree);
 
       begin
-         while Current_String /= Empty_Node
+         while Present (Current_String)
            and then
-             String_Value_Of (Current_String) /= Value
+             String_Value_Of (Current_String, In_Tree) /= Value
          loop
             Current_String :=
-              Next_Literal_String (Current_String);
+              Next_Literal_String (Current_String, In_Tree);
          end loop;
 
-         return Current_String /= Empty_Node;
+         return Present (Current_String);
       end;
 
    end Value_Is_Valid;
@@ -2450,5 +2828,283 @@ package body Prj.Tree is
       return Unkept_Comments;
    end There_Are_Unkept_Comments;
 
+   --------------------
+   -- Create_Project --
+   --------------------
+
+   function Create_Project
+     (In_Tree        : Project_Node_Tree_Ref;
+      Name           : Name_Id;
+      Full_Path      : Path_Name_Type;
+      Is_Config_File : Boolean := False) return Project_Node_Id
+   is
+      Project   : Project_Node_Id;
+      Qualifier : Project_Qualifier := Unspecified;
+   begin
+      Project := Default_Project_Node (In_Tree, N_Project);
+      Set_Name_Of (Project, In_Tree, Name);
+      Set_Directory_Of
+        (Project, In_Tree,
+         Path_Name_Type (Get_Directory (File_Name_Type (Full_Path))));
+      Set_Path_Name_Of (Project, In_Tree, Full_Path);
+
+      Set_Project_Declaration_Of
+        (Project, In_Tree,
+         Default_Project_Node (In_Tree, N_Project_Declaration));
+
+      if Is_Config_File then
+         Qualifier := Configuration;
+      end if;
+
+      if not Is_Config_File then
+         Prj.Tree.Tree_Private_Part.Projects_Htable.Set
+           (In_Tree.Projects_HT,
+            Name,
+            Prj.Tree.Tree_Private_Part.Project_Name_And_Node'
+              (Name           => Name,
+               Display_Name   => Name,
+               Canonical_Path => No_Path,
+               Node           => Project,
+               Extended       => False,
+               Proj_Qualifier => Qualifier));
+      end if;
+
+      return Project;
+   end Create_Project;
+
+   ----------------
+   -- Add_At_End --
+   ----------------
+
+   procedure Add_At_End
+     (Tree                  : Project_Node_Tree_Ref;
+      Parent                : Project_Node_Id;
+      Expr                  : Project_Node_Id;
+      Add_Before_First_Pkg  : Boolean := False;
+      Add_Before_First_Case : Boolean := False)
+   is
+      Real_Parent          : Project_Node_Id;
+      New_Decl, Decl, Next : Project_Node_Id;
+      Last, L              : Project_Node_Id;
+
+   begin
+      if Kind_Of (Expr, Tree) /= N_Declarative_Item then
+         New_Decl := Default_Project_Node (Tree, N_Declarative_Item);
+         Set_Current_Item_Node (New_Decl, Tree, Expr);
+      else
+         New_Decl := Expr;
+      end if;
+
+      if Kind_Of (Parent, Tree) = N_Project then
+         Real_Parent := Project_Declaration_Of (Parent, Tree);
+      else
+         Real_Parent := Parent;
+      end if;
+
+      Decl := First_Declarative_Item_Of (Real_Parent, Tree);
+
+      if Decl = Empty_Node then
+         Set_First_Declarative_Item_Of (Real_Parent, Tree, New_Decl);
+      else
+         loop
+            Next := Next_Declarative_Item (Decl, Tree);
+            exit when Next = Empty_Node
+              or else
+               (Add_Before_First_Pkg
+                 and then Kind_Of (Current_Item_Node (Next, Tree), Tree) =
+                                                        N_Package_Declaration)
+              or else
+               (Add_Before_First_Case
+                 and then Kind_Of (Current_Item_Node (Next, Tree), Tree) =
+                                                        N_Case_Construction);
+            Decl := Next;
+         end loop;
+
+         --  In case Expr is in fact a range of declarative items
+
+         Last := New_Decl;
+         loop
+            L := Next_Declarative_Item (Last, Tree);
+            exit when L = Empty_Node;
+            Last := L;
+         end loop;
+
+         --  In case Expr is in fact a range of declarative items
+
+         Last := New_Decl;
+         loop
+            L := Next_Declarative_Item (Last, Tree);
+            exit when L = Empty_Node;
+            Last := L;
+         end loop;
+
+         Set_Next_Declarative_Item (Last, Tree, Next);
+         Set_Next_Declarative_Item (Decl, Tree, New_Decl);
+      end if;
+   end Add_At_End;
+
+   ---------------------------
+   -- Create_Literal_String --
+   ---------------------------
+
+   function Create_Literal_String
+     (Str  : Namet.Name_Id;
+      Tree : Project_Node_Tree_Ref) return Project_Node_Id
+   is
+      Node : Project_Node_Id;
+   begin
+      Node := Default_Project_Node (Tree, N_Literal_String, Prj.Single);
+      Set_Next_Literal_String (Node, Tree, Empty_Node);
+      Set_String_Value_Of (Node, Tree, Str);
+      return Node;
+   end Create_Literal_String;
+
+   ---------------------------
+   -- Enclose_In_Expression --
+   ---------------------------
+
+   function Enclose_In_Expression
+     (Node : Project_Node_Id;
+      Tree : Project_Node_Tree_Ref) return Project_Node_Id
+   is
+      Expr : Project_Node_Id;
+   begin
+      if Kind_Of (Node, Tree) /= N_Expression then
+         Expr := Default_Project_Node (Tree, N_Expression, Single);
+         Set_First_Term
+           (Expr, Tree, Default_Project_Node (Tree, N_Term, Single));
+         Set_Current_Term (First_Term (Expr, Tree), Tree, Node);
+         return Expr;
+      else
+         return Node;
+      end if;
+   end Enclose_In_Expression;
+
+   --------------------
+   -- Create_Package --
+   --------------------
+
+   function Create_Package
+     (Tree    : Project_Node_Tree_Ref;
+      Project : Project_Node_Id;
+      Pkg     : String) return Project_Node_Id
+   is
+      Pack : Project_Node_Id;
+      N    : Name_Id;
+
+   begin
+      Name_Len := Pkg'Length;
+      Name_Buffer (1 .. Name_Len) := Pkg;
+      N := Name_Find;
+
+      --  Check if the package already exists
+
+      Pack := First_Package_Of (Project, Tree);
+      while Pack /= Empty_Node loop
+         if Prj.Tree.Name_Of (Pack, Tree) = N then
+            return Pack;
+         end if;
+
+         Pack := Next_Package_In_Project (Pack, Tree);
+      end loop;
+
+      --  Create the package and add it to the declarative item
+
+      Pack := Default_Project_Node (Tree, N_Package_Declaration);
+      Set_Name_Of (Pack, Tree, N);
+
+      --  Find the correct package id to use
+
+      Set_Package_Id_Of (Pack, Tree, Package_Node_Id_Of (N));
+
+      --  Add it to the list of packages
+
+      Set_Next_Package_In_Project
+        (Pack, Tree, First_Package_Of (Project, Tree));
+      Set_First_Package_Of (Project, Tree, Pack);
+
+      Add_At_End (Tree, Project_Declaration_Of (Project, Tree), Pack);
+
+      return Pack;
+   end Create_Package;
+
+   ----------------------
+   -- Create_Attribute --
+   ----------------------
+
+   function Create_Attribute
+     (Tree       : Project_Node_Tree_Ref;
+      Prj_Or_Pkg : Project_Node_Id;
+      Name       : Name_Id;
+      Index_Name : Name_Id       := No_Name;
+      Kind       : Variable_Kind := List;
+      At_Index   : Integer       := 0;
+      Value      : Project_Node_Id := Empty_Node) return Project_Node_Id
+   is
+      Node : constant Project_Node_Id :=
+               Default_Project_Node (Tree, N_Attribute_Declaration, Kind);
+
+      Case_Insensitive : Boolean;
+
+      Pkg      : Package_Node_Id;
+      Start_At : Attribute_Node_Id;
+      Expr     : Project_Node_Id;
+
+   begin
+      Set_Name_Of (Node, Tree, Name);
+
+      if Index_Name /= No_Name then
+         Set_Associative_Array_Index_Of (Node, Tree, Index_Name);
+      end if;
+
+      if Prj_Or_Pkg /= Empty_Node then
+         Add_At_End (Tree, Prj_Or_Pkg, Node);
+      end if;
+
+      --  Find out the case sensitivity of the attribute
+
+      if Prj_Or_Pkg /= Empty_Node
+        and then Kind_Of (Prj_Or_Pkg, Tree) = N_Package_Declaration
+      then
+         Pkg      := Prj.Attr.Package_Node_Id_Of (Name_Of (Prj_Or_Pkg, Tree));
+         Start_At := First_Attribute_Of (Pkg);
+      else
+         Start_At := Attribute_First;
+      end if;
+
+      Start_At := Attribute_Node_Id_Of (Name, Start_At);
+      Case_Insensitive :=
+        Attribute_Kind_Of (Start_At) = Case_Insensitive_Associative_Array;
+      Tree.Project_Nodes.Table (Node).Flag1 := Case_Insensitive;
+
+      if At_Index /= 0 then
+         if Attribute_Kind_Of (Start_At) =
+              Optional_Index_Associative_Array
+           or else Attribute_Kind_Of (Start_At) =
+              Optional_Index_Case_Insensitive_Associative_Array
+         then
+            --  Results in:   for Name ("index" at index) use "value";
+            --  This is currently only used for executables.
+
+            Set_Source_Index_Of (Node, Tree, To => Int (At_Index));
+
+         else
+            --  Results in:   for Name ("index") use "value" at index;
+
+            --  ??? This limitation makes no sense, we should be able to
+            --  set the source index on an expression.
+
+            pragma Assert (Kind_Of (Value, Tree) = N_Literal_String);
+            Set_Source_Index_Of (Value, Tree, To => Int (At_Index));
+         end if;
+      end if;
+
+      if Value /= Empty_Node then
+         Expr := Enclose_In_Expression (Value, Tree);
+         Set_Expression_Of (Node, Tree, Expr);
+      end if;
+
+      return Node;
+   end Create_Attribute;
 
 end Prj.Tree;