separate (Compilation_Unit.Produce_Metrics)
procedure Expanded_Name (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

    --=========================================================
    -- Expanded_Name ::= <IDENTIFIER> { "." <IDENTIFIER> }
    --=========================================================

    Current_Token : Token_Package.Token;
    Is_Done : Boolean := False;

    Operator : Halstead_Operator.Definition;

    -- save the location of the first operator token.
    First_Operator : Ada_Compilation_Unit;

    -- save the location of the last operator token.
    Last_Operator : Ada_Compilation_Unit;

    -- save the location of the first operand token.
    First_Operand : Ada_Compilation_Unit;

    -- save the location of the last operand token.
    Last_Operand : Ada_Compilation_Unit;

begin
    -- Expanded_Name

    --** changed 9/26/85 by J. Margono
    --** reason: due to change in the doubly-linked list spec,
    --**         now List is of type PRIVATE, thus assignment
    --**         is allowed
    -- save the location of the first operator token
    First_Operator := Seek (Origin => Current_Compilation_Unit, Offset => +1);

    --** changed 9/26/85 by J. Margono
    --** reason: due to change in the doubly-linked list spec,
    --**         now List is of type PRIVATE, thus assignment
    --**         is allowed
    -- save the location of the first operand token.
    First_Operand := Seek (Origin => Current_Compilation_Unit, Offset => +1);

    Process_Expanded_Name:
        loop

            Get_Next_Token (Out_Token => Current_Token,
                            From => Current_Compilation_Unit,
                            Current_Loc => Loc);

            if "/=" (Token_Package.Class_Of (Current_Token),
                     Token_Package.Identifier) then
                raise Syntax_Error;
            end if;

            --** removed 11/20/85 by J. Margono
            --** reason: same operand was counted TWICE

            if Token_Package.Value_Of (Peek
                                          (From => Current_Compilation_Unit)) =
               Token_Package.Dot_Token then

                --** changed 9/26/85 by J. Margono
                --** reason: due to change in the doubly-linked list spec,
                --**         now List is of type PRIVATE, thus assignment
                --**         is allowed
                -- modify position of Last_Operator to previous
                -- significant token
                Last_Operator :=
                   Seek (Origin => Current_Compilation_Unit, Offset => +1);

                --** changed 9/26/85 by J. Margono
                --** reason: due to change in the doubly-linked list spec,
                --**         now List is of type PRIVATE, thus assignment
                --**         is allowed
                -- modify position of First_Operand to first
                -- significant token after the DOT
                First_Operand :=
                   Seek (Origin => Current_Compilation_Unit, Offset => +2);

                Get_Next_Token (Out_Token => Current_Token,
                                From => Current_Compilation_Unit,
                                Current_Loc => Loc);

                -- increment Halstead DOT operator count
                Halstead.Store_Operator ((Kind =>
                                             Halstead_Operator.Dot_Halstead));

            else
                -- no more dots or identifiers

                Is_Done := True;

            end if;

            exit Process_Expanded_Name when Is_Done;

        end loop Process_Expanded_Name;

    -- everything up to the last dot counts as one Halstead operator,
    -- dot counts as one Halstead operator, and the last IDENTIFIER
    -- counts as one Halstead operand

    if not New_List.Is_Equal (New_List.List (First_Operator),
                              New_List.List (First_Operand)) then

        -- concatenate all significant tokens beginning at First_Location
        -- First_Operator up to the Last_Operator
        Operator := Halstead_Operator.Convert
                       (Concatenate (First_Operator, Last_Operator));

        -- increment Halstead operator count
        Halstead.Store_Operator (Operator);

    end if;

    --** changed 9/26/85 by J. Margono
    --** reason: due to change in the doubly-linked list spec,
    --**         now List is of type PRIVATE, thus assignment
    --**         is allowed
    -- modify position of Last_Operand
    Last_Operand := Seek (Origin => Current_Compilation_Unit, Offset => -1);

    -- concatenate all significant tokens beginning at
    -- First_Operand up to Last_Operand
    -- increment Halstead operand count
    Halstead.Store_Operand (Halstead_Operand.Definition
                               (Concatenate (First_Operand, Last_Operand)));

end Expanded_Name;