anchor.diff:      OptAcc.
   
   
  -%% @doc Add an option with no argument.
  --spec add_option_no_arg(option_spec(), [option()]) -> [option()].
  -add_option_no_arg({Name, _Short, _Long, ArgSpec, _Help} = OptSpec, OptAcc) ->
  +%% @doc Add an option with argument converting it to the data type indicated by the
  +%%      argument specification.
  +-spec add_option_with_arg(option_spec(), string(), [option()]) -> [option()].
  +add_option_with_arg({Name, _Short, _Long, ArgSpec, _Help} = OptSpec, Arg, OptAcc) ->
  +    case is_valid_arg(ArgSpec, Arg) of
  +        true ->
  +            try
  +                [{Name, to_type(ArgSpec, Arg)} | OptAcc]
  +            catch
  +                error:_ ->
  +                    throw({error, {invalid_option_arg, {Name, Arg}}})
  +            end;
  +        false ->
  +            add_option_with_implicit_arg(OptSpec, OptAcc)
  +    end.
  +
  +
  +%% @doc Add an option with argument that was part of an assignment expression
  +%%      (e.g. "--verbose=3") converting it to the data type indicated by the
  +%%      argument specification.
  +-spec add_option_with_assigned_arg(option_spec(), string(), [option()]) -> [option()].
  +add_option_with_assigned_arg({Name, _Short, _Long, ArgSpec, _Help}, Arg, OptAcc) ->
  +    try
  +        [{Name, to_type(ArgSpec, Arg)} | OptAcc]
  +    catch
  +        error:_ ->
  +            throw({error, {invalid_option_arg, {Name, Arg}}})
  +    end.
  +
  +
  +%% @doc Add an option that required an argument but did not have one. Some data
  +%%      types (boolean, integer) allow implicit or assumed arguments.
  +-spec add_option_with_implicit_arg(option_spec(), [option()]) -> [option()].
  +add_option_with_implicit_arg({Name, _Short, _Long, ArgSpec, _Help}, OptAcc) ->
       case arg_spec_type(ArgSpec) of
           boolean ->
               %% Special case for boolean arguments: if there is no argument we
               %% set the value to 'true'.
  -            add_arg(OptSpec, true, OptAcc);
  +            [{Name, true} | OptAcc];
  +        integer ->
  +            %% Special case for integer arguments: if the option had not been set
  +            %% before we set the value to 1. This is needed to support options like
  +            %% "-v" to return something like {verbose, 1}.
  +            [{Name, 1} | OptAcc];
  +        _ ->
  +            throw({error, {missing_option_arg, Name}})
  +    end.
  +
  +
  +%% @doc Add an option with an implicit or assumed argument.
  +-spec add_option_with_implicit_incrementable_arg(option_spec() | arg_spec(), [option()]) -> [option()].
  +add_option_with_implicit_incrementable_arg({Name, _Short, _Long, ArgSpec, _Help}, OptAcc) ->
  +    case arg_spec_type(ArgSpec) of
  +        boolean ->
  +            %% Special case for boolean arguments: if there is no argument we
  +            %% set the value to 'true'.
  +            [{Name, true} | OptAcc];
           integer ->
               %% Special case for integer arguments: if the option had not been set
               %% before we set the value to 1; if not we increment the previous value
               %% the option had. This is needed to support options like "-vvv" to
               %% return something like {verbose, 3}.
  -            add_implicit_integer_arg(OptSpec, OptAcc);
  +            case OptAcc of
  +                [{Name, Count} | Tail] ->
  +                    [{Name, Count + 1} | Tail];
  +                _ ->
  +                    [{Name, 1} | OptAcc]
  +            end;
           _ ->
               throw({error, {missing_option_arg, Name}})
       end.
  -
  -
  -%% @doc Add an option with argument converting it to the data type indicated by the
  -%%      argument specification.
  --spec add_option_arg(option_spec(), string(), [option()]) -> [option()].
  -add_option_arg({Name, _Short, _Long, ArgSpec, _Help} = OptSpec, Arg, OptAcc) ->
  -    ArgSpecType = arg_spec_type(ArgSpec),
  -    case (ArgSpecType =:= boolean) andalso not is_boolean_arg(Arg) of
  -        true ->
  -            %% Special case for booleans: when the next string is not a boolean
  -            %% argument we assume the value is 'true'.
  -            add_arg(OptSpec, true, OptAcc);
  -        false ->
  -            case (ArgSpecType =:= integer) andalso not is_integer_arg(Arg) of
  -                true ->
  -                    %% Special case for integer arguments: if the option had not been set
  -                    %% before we set the value to 1; if not we increment the previous value
  -                    %% the option had. This is needed to support options like "-vvv" to
  -                    %% return something like {verbose, 3}.
  -                    add_implicit_integer_arg(OptSpec, OptAcc);
  -                false ->
  -                    try
  -                       add_arg(OptSpec, to_type(ArgSpecType, Arg), OptAcc)
  -                    catch
  -                        error:_ ->
  -                            throw({error, {invalid_option_arg, {Name, Arg}}})
  -                    end
  -            end
  -    end.
  -
  -
  -%% Add an option with an integer argument.
  --spec add_implicit_integer_arg(option_spec(), [option()]) -> [option()].
  -add_implicit_integer_arg({Name, _Short, _Long, _ArgSpec, _Help}, OptAcc) ->
  -    case lists:keyfind(Name, 1, OptAcc) of
  -        {Name, Count} ->
  -            lists:keyreplace(Name, 1, OptAcc, {Name, Count + 1});
  -        false ->
  -            [{Name, 1} | OptAcc]
  -    end.
  -
  -
  -%% @doc Add an option with an argument and convert it to the data type corresponding
  -%%      to the argument specification.
  --spec add_arg(option_spec(), arg_value(), [option()]) -> [option()].
  -add_arg({Name, _Short, _Long, _ArgSpec, _Help}, Arg, OptAcc) ->
  -    [{Name, Arg} | lists:keydelete(Name, 1, OptAcc)].
   
   
   %% @doc Retrieve the data type form an argument specification.
  
positive.code: is_valid_arg(boolean, Arg) ->
      is_boolean_arg(Arg);
  is_valid_arg(integer, Arg) ->
      is_integer_arg(Arg);
  is_valid_arg(float, Arg) ->
      is_float_arg(Arg);
  is_valid_arg(_Type, _Arg) ->
      true.
  
  
  -spec is_boolean_arg(string()) -> boolean().
  
negative.code: 
  
  -spec is_integer_arg(string()) -> boolean().
  is_integer_arg([$- | Tail]) ->
      is_non_neg_integer_arg(Tail);
  is_integer_arg(Arg) ->
      is_non_neg_integer_arg(Arg).
  
  
  -spec is_non_neg_integer_arg(string()) -> boolean().
  is_non_neg_integer_arg([Head | Tail]) when Head >= $0, Head =< $9 ->
      is_non_neg_integer_arg(Tail);
  is_non_neg_integer_arg([_Head | _Tail]) ->
      false;
  is_non_neg_integer_arg([]) ->
      true.
  
  
  -spec is_non_neg_float_arg(string()) -> boolean().
  is_non_neg_float_arg([Head | Tail]) when (Head >= $0 andalso Head =< $9) orelse Head =:= $. ->
      is_non_neg_float_arg(Tail);
  is_non_neg_float_arg([_Head | _Tail]) ->
      false;
  is_non_neg_float_arg([]) ->
      true.
  
  
  