separate (Compilation_Unit.Produce_Metrics)
task body Loc_State_Machine is
    --==============================================================
    -- This task will either modify a part of the present state    =
    -- or return part of the present state. A modification only    =
    -- entails invoking an operation in one of the LOC packages.   =
    -- The object to modify is choosen by the accept statement.    =
    -- Each line of code object is reported on through a separate  =
    -- accept statement.                                           =
    --                                                             =
    -- written by GER with help from Brad and JM                   =
    --==============================================================

    Delta_Blank_Lines : Positive;
    -- Change the number of Blank lines by this amount

    Delta_Comments : Positive;
    -- Change the number of comments by this amount

    Delta_Physical_Lines : Positive;
    -- Change the number of physical lines by this amount

    Delta_Data_Declarations : Positive;
    -- Change the number of data declarations by this amount

    Delta_Executable_Statements : Positive;
    -- Change the number of executable statements by this amount

    Current_Blank_Line_Count : Loc_Blank_Lines.Count := 0;
    -- The current number of blank lines in the compilation unit

    Current_Comment_Count : Loc_Comments.Count := 0;
    -- The current number of comments in the compilation unit

    Current_Physical_Line_Count : Loc_Physical_Lines.Count := 0;
    -- The current number of physical lines

    Current_Data_Declaration_Count : Loc_Data_Declarations.Count := 0;
    -- The current number of data declarations

    Current_Executable_Statement_Count : Loc_Executable_Statements.Count := 0;
    -- The current number of executable statements

begin
    -- LOC_State_Machine

    Calculate_And_Get:
        loop

            select
                -- Change the blank line count for this compilation
                -- unit

                accept Change_Blank_Lines_Count
                          (The_Amount_To_Change : in Positive := 1) do
                    Delta_Blank_Lines := The_Amount_To_Change;
                end Change_Blank_Lines_Count;

                Loc_Blank_Lines.Change (Number_Of_Blank_Lines =>
                                           Current_Blank_Line_Count,
                                        With_Delta => Delta_Blank_Lines);

            or
                -- Change the number of comments for this compilation unit

                accept Change_Comments_Count
                          (The_Amount_To_Change : in Positive := 1) do
                    Delta_Comments := The_Amount_To_Change;
                end Change_Comments_Count;

                Loc_Comments.Change (Number_Of_Comments =>
                                        Current_Comment_Count,
                                     With_Delta => Delta_Comments);

            or
                -- Change the Physical line count
                -- for this compilation unit

                accept Change_Physical_Lines_Count
                          (The_Amount_To_Change : in Positive := 1) do
                    Delta_Physical_Lines := The_Amount_To_Change;
                end Change_Physical_Lines_Count;

                Loc_Physical_Lines.Change (Number_Of_Physical_Lines =>
                                              Current_Physical_Line_Count,
                                           With_Delta => Delta_Physical_Lines);

            or
                -- Change the data declaration count
                -- for this compilation unit

                accept Change_Data_Declarations_Count
                          (The_Amount_To_Change : in Positive := 1) do
                    Delta_Data_Declarations := The_Amount_To_Change;
                end Change_Data_Declarations_Count;

                Loc_Data_Declarations.Change
                   (Number_Of_Data_Declarations =>
                       Current_Data_Declaration_Count,
                    With_Delta => Delta_Data_Declarations);

            or
                -- Change the executable statement count for this
                -- compilation unit

                accept Change_Executable_Statements_Count
                          (The_Amount_To_Change : in Positive := 1) do
                    Delta_Executable_Statements := The_Amount_To_Change;
                end Change_Executable_Statements_Count;

                Loc_Executable_Statements.Change
                   (Number_Of_Executable_Statements =>
                       Current_Executable_Statement_Count,
                    With_Delta => Delta_Executable_Statements);

            or
                -- Return the current number of blank lines

                accept Get_Blank_Lines_Count
                          (Blank_Line_Count : out Loc_Blank_Lines.Count) do
                    Blank_Line_Count := Current_Blank_Line_Count;
                end Get_Blank_Lines_Count;

            or
                -- Return the number of comments

                accept Get_Comments_Count (Comments : out Loc_Comments.Count) do
                    Comments := Current_Comment_Count;
                end Get_Comments_Count;

            or
                -- Return the number of physical lines

                accept Get_Physical_Lines_Count
                          (Physical_Lines : out Loc_Physical_Lines.Count) do
                    Physical_Lines := Current_Physical_Line_Count;
                end Get_Physical_Lines_Count;

            or
                -- return the current number of data declarations

                accept Get_Data_Declarations_Count
                          (Data_Declarations : out
                              Loc_Data_Declarations.Count) do
                    Data_Declarations := Current_Data_Declaration_Count;
                end Get_Data_Declarations_Count;

            or
                -- Return the current number of executable statements

                accept Get_Executable_Statements_Count
                          (Executable_Statements : out
                              Loc_Executable_Statements.Count) do
                    Executable_Statements := Current_Executable_Statement_Count;
                end Get_Executable_Statements_Count;

            or
                -- terminate this task

                terminate;

            end select;

        end loop Calculate_And_Get;

end Loc_State_Machine;