anchor.diff:  			remove_session(SessionAttributes, T, [H | T])
   	end;
   remove_session(SessionAttributes, [], Acc) ->
  +erlang:display({?MODULE, ?LINE, SessionAttributes, lists:reverse(Acc)}),
   	lists:reverse(Acc).
   
  --spec update_session(SessionAttributes, SessionList) ->NewSessionList
  +-spec add_session(SessionAttributes, SessionList) -> SessionList
   	when
   		SessionAttributes :: [tuple()],
  -		SessionList :: [tuple()],
  -		NewSessionList :: [tuple()].
  +		SessionList :: [{pos_integer(), [tuple()]}].
   %% @doc Add new session identification attributes set to active sessions list.
   %% @private
  -update_session(SessionAttributes, SessionList) ->
  -	update_session(SessionAttributes, SessionList, []).
  -%% @hidden
  -update_session(SessionAttributes, [], Acc) ->
  -	Now = erlang:system_time(?MILLISECOND),
  -	[{Now, SessionAttributes} | Acc];
  -update_session(SessionAttributes, [{_, Attributes} = H | T] = S, Acc) ->
  -	case update_session1(SessionAttributes, Attributes) of
  -		true ->
  -			S ++ Acc;
  -		false ->
  -			update_session(SessionAttributes, T, [H | Acc])
  +add_session(SessionAttributes, SessionList) ->
  +	[{erlang:system_time(?MILLISECOND), SessionAttributes} | SessionList].
  +
  +-spec get_session_id(SessionAttributes) -> SessionId
  +	when
  +		SessionAttributes :: [tuple()],
  +		SessionId :: [tuple()].
  +%% @doc Get the session identifier value.
  +%% 	Returns a list of DIAMETER/RADIUS attributes.
  +%% @private
  +get_session_id(SessionAttributes) ->
  +	case lists:keyfind('Session-Id', 1, SessionAttributes) of
  +		false ->
  +			get_session_id1(SessionAttributes, []);
  +		SessionId ->
  +			[SessionId]
   	end.
   %% @hidden
  -update_session1([], _Attributes) ->
  -	false;
  -update_session1([Identifier | T], Attributes) ->
  -	case lists:member(Identifier, Attributes) of
  -		true ->
  +get_session_id1([], Acc) ->
  +	lists:keysort(1, Acc);
  +get_session_id1(_, Acc) when length(Acc) =:= 3 ->
  +	lists:keysort(1, Acc);
  +get_session_id1([{?AcctSessionId, _} = AcctSessionId | T], Acc) ->
  +	get_session_id1(T, [AcctSessionId | Acc]);
  +get_session_id1([{?NasIdentifier, _} = NasIdentifier | T], Acc) ->
  +	get_session_id1(T, [NasIdentifier | Acc]);
  +get_session_id1([{?NasIpAddress, _} = NasIpAddress | T], Acc) ->
  +	get_session_id1(T, [NasIpAddress | Acc]);
  +get_session_id1([_ | T], Acc) ->
  +	get_session_id1(T, Acc).
  +
  +-spec sort(Buckets) -> Buckets
  +	when
  +		Buckets :: [#bucket{}].
  +%% @doc Sort `Buckets' oldest first.
  +%% @private
  +sort(Buckets) ->
  +	F = fun(#bucket{termination_date = T1},
  +				#bucket{termination_date = T2}) when T1 =< T2 ->
   			true;
  -		false ->
  -			update_session1(T, Attributes)
  +		(_, _)->
  +			false
  +	end,
  +	lists:sort(F, Buckets).
  +
  +-spec price_units(Amount, UnitSize, UnitPrice) -> {TotalUnits, TotalPrice}
  +	when
  +		Amount :: non_neg_integer(),
  +		UnitSize :: pos_integer(),
  +		UnitPrice :: pos_integer(),
  +		TotalUnits :: pos_integer(),
  +		TotalPrice :: pos_integer().
  +%% @doc Calculate total size and price.
  +price_units(0, _UnitSize, _UnitPrice) ->
  +	{0, 0};
  +price_units(Amount, UnitSize, UnitPrice) when (Amount rem UnitSize) == 0 ->
  +	{Amount, UnitPrice * (Amount div UnitSize)};
  +price_units(Amount, UnitSize, UnitPrice) ->
  +	Units = (Amount div UnitSize + 1),
  +	{Units * UnitSize, UnitPrice * Units}.
  +
  +-spec get_reserve(Price) -> ReserveAmount
  +	when
  +		Price :: #price{},
  +		ReserveAmount :: pos_integer().
  +%% @doc Get the reserve amount.
  +get_reserve(#price{units = seconds,
  +		char_value_use = CharValueUse} = _Price) ->
  +	case lists:keyfind("radiusReserveTime",
  +			#char_value_use.name, CharValueUse) of
  +		#char_value_use{values = [#char_value{value = Value}]} ->
  +			Value;
  +		false ->
  +			0
  +	end;
  +get_reserve(#price{units = octets,
  +		char_value_use = CharValueUse} = _Price) ->
  +	case lists:keyfind("radiusReserveBytes",
  +			#char_value_use.name, CharValueUse) of
  +		#char_value_use{values = [#char_value{value = Value}]} ->
  +			Value;
  +		false ->
  +			0
   	end.
   
  
positive.code: 				| {disabled, SessionList} | {error, Reason},
  		Subscriber :: #subscriber{},
  		GrantedAmount :: integer(),
  		SessionList :: [tuple()],
  		Reason :: term().
  %% @doc Handle rating and balance management for used and reserved unit amounts.
  %%
  %% 	Subscriber balance buckets are permanently reduced by the
  %% 	amount(s) in `DebitAmount' and `Type' buckets are allocated
  %% 	by the amount(s) in `ReserveAmount'. The subscribed product
  %% 	determines the price used to calculate the amount to be
  %% 	permanently debited from available `cents' buckets.
  %%
  %% 	Returns `{ok, Subscriber, GrantedAmount}' if successful.
  %%
  %% 	Returns `{out_of_credit, SessionList}' if the subscriber's
  %% 	balance is insufficient to cover the `DebitAmount' and
  %% 	`ReserveAmount' or `{disabled, SessionList}' if the subscriber
  %% 	is not enabled. In both cases subscriber's balance is debited.
  %% 	`SessionList' describes the known active sessions which
  %% 	should be disconnected.
  %%
  rate(Protocol, SubscriberID, Destination,
  		Flag, DebitAmount, ReserveAmount, SessionAttributes) when is_list(SubscriberID)->
  	rate(Protocol, list_to_binary(SubscriberID), Destination,
  		Flag, DebitAmount, ReserveAmount, SessionAttributes);
  rate(Protocol, SubscriberID, Destination, Flag, DebitAmount, ReserveAmount, SessionAttributes)
  		when ((Protocol == radius) or (Protocol == diameter)), is_binary(SubscriberID),
  		((Flag == initial) or (Flag == interim) or (Flag == final)),
  		is_list(DebitAmount), is_list(ReserveAmount), is_list(SessionAttributes) ->
  	F = fun() ->
  			case mnesia:read(subscriber, SubscriberID, write) of
  				[#subscriber{product = #product_instance{product = ProdID,
  
negative.code: -export([rate/6, rate/7]).
  
  -include("ocs.hrl").
  -include_lib("radius/include/radius.hrl").
  
  %% support deprecated_time_unit()
  -define(MILLISECOND, milli_seconds).
  %-define(MILLISECOND, millisecond).
  
  -spec rate(Protocol, SubscriberID, Destination, Flag, DebitAmounts, ReserveAmounts) -> Result
  	when
  		Protocol :: radius | diameter,
  		SubscriberID :: string() | binary(),
  		Destination :: string(),
  		Flag :: initial | interim | final,
  		DebitAmounts :: [{Type, Amount}],
  		ReserveAmounts :: [{Type, Amount}],
  		Type :: octets | seconds,
  		Amount :: integer(),
  		Result :: {ok, Subscriber, GrantedAmount} | {disabled, SessionList}
  				| {out_of_credit, SessionList} | {error, Reason},
  		Subscriber :: #subscriber{},
  		GrantedAmount :: integer(),
  		SessionList :: [{pos_integer(), [tuple()]}],
  		Reason :: term().
  %% @equiv rate(Protocol, SubscriberID, Destination, Flag, DebitAmounts, ReserveAmounts, [])
  rate(Protocol, SubscriberID, Destination, Flag, DebitAmounts, ReserveAmounts) ->
  	rate(Protocol, SubscriberID, Destination, Flag, DebitAmounts, ReserveAmounts, []).
  
  -spec rate(Protocol, SubscriberID, Destination,
  		Flag, DebitAmounts, ReserveAmounts, SessionAttributes) -> Result
  	when
  		Protocol :: radius | diameter,
  		SubscriberID :: string() | binary(),
  		Destination :: string(),
  		Flag :: initial | interim | final,
  		DebitAmounts :: [{Type, Amount}],
  		ReserveAmounts :: [{Type, Amount}],
  		SessionAttributes :: [tuple()],
  		Type :: octets | seconds,
  		Amount :: integer(),
  