separate (Compilation_Unit.Produce_Metrics)
procedure Statement (Current_Compilation_Unit : in out Ada_Compilation_Unit;
                     Program_Unit : in Program_Unit_State_Machine;
                     Halstead : in Halstead_State_Machine;
                     Loc : in Loc_State_Machine;
                     Mccabe : in Mccabe_State_Machine) is

    --======================================================
    -- Block statement is not included since it is defined
    -- as a program unit.
    --======================================================

    -- Statement ::=
    -- simple statement
    --      ABORT_Statement
    --    | DELAY_Statement
    --    | EXIT_Statement
    --    | GOTO_Statement
    --    | Name_Statement -- can be assignment statement, procedure or
    -- entry call statement, code statement, or
    -- loop statement
    --    | NULL_Statement
    --    | RAISE_Statement
    --    | RETURN_Statement
    --
    -- compound statement
    --    | ACCEPT_Statement
    --    | CASE_Statement
    --    | IF_Statement
    --    | LOOP_Statement
    --    | SELECT_Statement

    -- Increment LOC data declaration count by one.
    -- Recurse.
    --   | <BEGIN_COMPILATION_UNIT>
    --======================================================

    --**
    Current_Token : Token_Package.Token;
    Peek_Ahead_Token : Token_Package.Token;

begin
    -- Statement

    Peek_Ahead_Token := Peek (From => Current_Compilation_Unit);

    case Token_Package.Class_Of (Peek_Ahead_Token) is

        when Token_Package.Keyword =>

            case Token_Package.Value_Of (Peek_Ahead_Token) is

                when Token_Package.Abort_Token =>
                    Abort_Statement
                       (Current_Compilation_Unit => Current_Compilation_Unit,
                        Program_Unit => Program_Unit,
                        Halstead => Halstead,
                        Loc => Loc,
                        Mccabe => Mccabe);

                when Token_Package.Delay_Token =>
                    Delay_Statement
                       (Current_Compilation_Unit => Current_Compilation_Unit,
                        Program_Unit => Program_Unit,
                        Halstead => Halstead,
                        Loc => Loc,
                        Mccabe => Mccabe);

                when Token_Package.Exit_Token =>
                    Exit_Statement
                       (Current_Compilation_Unit => Current_Compilation_Unit,
                        Program_Unit => Program_Unit,
                        Halstead => Halstead,
                        Loc => Loc,
                        Mccabe => Mccabe);

                when Token_Package.Goto_Token =>
                    Goto_Statement
                       (Current_Compilation_Unit => Current_Compilation_Unit,
                        Program_Unit => Program_Unit,
                        Halstead => Halstead,
                        Loc => Loc,
                        Mccabe => Mccabe);

                when Token_Package.Null_Token =>
                    Null_Statement
                       (Current_Compilation_Unit => Current_Compilation_Unit,
                        Program_Unit => Program_Unit,
                        Halstead => Halstead,
                        Loc => Loc,
                        Mccabe => Mccabe);

                when Token_Package.Raise_Token =>
                    Raise_Statement
                       (Current_Compilation_Unit => Current_Compilation_Unit,
                        Program_Unit => Program_Unit,
                        Halstead => Halstead,
                        Loc => Loc,
                        Mccabe => Mccabe);

                when Token_Package.Return_Token =>
                    Return_Statement
                       (Current_Compilation_Unit => Current_Compilation_Unit,
                        Program_Unit => Program_Unit,
                        Halstead => Halstead,
                        Loc => Loc,
                        Mccabe => Mccabe);

                when Token_Package.Accept_Token =>
                    Accept_Statement
                       (Current_Compilation_Unit => Current_Compilation_Unit,
                        Program_Unit => Program_Unit,
                        Halstead => Halstead,
                        Loc => Loc,
                        Mccabe => Mccabe);

                when Token_Package.Case_Token =>
                    Case_Statement
                       (Current_Compilation_Unit => Current_Compilation_Unit,
                        Program_Unit => Program_Unit,
                        Halstead => Halstead,
                        Loc => Loc,
                        Mccabe => Mccabe);

                when Token_Package.If_Token =>
                    If_Statement
                       (Current_Compilation_Unit => Current_Compilation_Unit,
                        Program_Unit => Program_Unit,
                        Halstead => Halstead,
                        Loc => Loc,
                        Mccabe => Mccabe);

                when Token_Package.For_Token | Token_Package.While_Token |
                     Token_Package.Loop_Token =>

                    Loop_Statement
                       (Current_Compilation_Unit => Current_Compilation_Unit,
                        Program_Unit => Program_Unit,
                        Halstead => Halstead,
                        Loc => Loc,
                        Mccabe => Mccabe);

                when Token_Package.Select_Token =>
                    Select_Statement
                       (Current_Compilation_Unit => Current_Compilation_Unit,
                        Program_Unit => Program_Unit,
                        Halstead => Halstead,
                        Loc => Loc,
                        Mccabe => Mccabe);

                when others =>
                    raise Syntax_Error;

            end case;

        when Token_Package.Identifier | Token_Package.Character_Literal |
             Token_Package.Standard_String_Literal |
             Token_Package.Alternate_String_Literal =>

            Name_Statement
               (Current_Compilation_Unit => Current_Compilation_Unit,
                Program_Unit => Program_Unit,
                Halstead => Halstead,
                Loc => Loc,
                Mccabe => Mccabe);

        when Token_Package.Begin_Compilation_Unit =>
            --**
            -- flush new lines, blank lines, and comments
            Get_Next_Token (Out_Token => Current_Token,
                            From => Current_Compilation_Unit,
                            Current_Loc => Loc);
            -- set current compilation unit back
            Current_Compilation_Unit :=
               Seek (Origin => Current_Compilation_Unit, Offset => -1);
            Produce_Metrics (This_Compilation_Unit => Current_Compilation_Unit);

        when others =>
            raise Syntax_Error;

    end case;

end Statement;