with Data_Maps;      use Data_Maps;
with Relation_Maps;  use Relation_Maps;
with Ada.Text_IO;    use Ada.Text_IO;

procedure Find_Roots is

   Roots : Set renames Element (Students, Key => "---");
   --
   --This is the set of all students whose advisor is unknown.
   --We now have to find these students' advisors, and among
   --those advisors find those that don't have a database
   --record of their own.  Those advisors are then added to
   --the set of students with unknown advisors.
   --
   --Note also that the declaration above assumes that the Roots
   --set (the map entry with key = "---") already exists in the
   --map.  If you want to automatically create that set if it
   --doesn't exist, then in the declaration above use the Insert
   --function instead.  (Or you could use the item-less
   --procedure form of Insert, that creates the map entry with
   --an empty set.

--     procedure Print_Roots is
--        procedure Process (Name : String) is
--        begin
--           Put_Line (Name);
--        end;
--     begin
--        Iterate (Roots, Process'Access);
--        New_Line (2);
--     end;

   function Contains (Advisor : in String) return Boolean is

      C : Set_Cursor := First (Roots);

   begin

      while Has_Element (C) loop

         if Element (C) = Advisor then
            return True;
         end if;

         Next (C);

      end loop;

      return False;

   end Contains;

   procedure Process_Advisors
     (Student  : in String;
      Advisors : in Set) is

      Any_Advisor : Boolean := False;
      C : Set_Cursor := First (Advisors);

   begin

      while Has_Element (C) loop

         declare
            Advisor : constant String := Element (C);
         begin
            if Advisor = "---"
              or else Contains (Relation_Maps.Advisors, Advisor)
            then
               Any_Advisor := True;
            end if;
         end;

         Next (C);

      end loop;

      if not Any_Advisor then

         declare
            First_Advisor : constant String := First_Element (Advisors);
         begin
            if not Contains (First_Advisor) then
               Insert (Roots, First_Advisor);
            end if;
         end;

      end if;

   end Process_Advisors;

begin

   Iterate (Advisors, Process_Advisors'Access);

end Find_Roots;
