anchor.diff:  		false ->
   			0
   	end,
  -	rate5(Subscriber, Price, Validity, Flag,
  -			DebitAmount, ReserveAmount, SessionAttributes, Rated).
  -%% @hidden
  -rate5(#service{buckets = Buckets1} = Subscriber,
  +	rate5(Service, Buckets, Price, Flag, DebitAmount, ReserveAmount, State).
  +%% @hidden
  +rate5(Service, Buckets1,
   		#price{units = Units, size = UnitSize, amount = UnitPrice},
  -		_Validity, initial, 0, ReserveAmount, SessionAttributes, Rated) ->
  -	SessionId = get_session_id(SessionAttributes),
  +		initial, 0, ReserveAmount, #{session_id := SessionId} = State) ->
   	case reserve_session(Units, ReserveAmount, SessionId, Buckets1) of
   		{ReserveAmount, Buckets2} ->
  -			rate6(Subscriber#service{buckets = Buckets2},
  -					initial, 0, 0, ReserveAmount, ReserveAmount,
  -					SessionId, Rated);
  +			rate6(Service, Buckets2, initial,
  +					0, 0, ReserveAmount, ReserveAmount, State);
   		{UnitsReserved, Buckets2} ->
   			PriceReserveUnits = (ReserveAmount - UnitsReserved),
   			{UnitReserve, PriceReserve} = price_units(PriceReserveUnits,
   					UnitSize, UnitPrice),
   			case reserve_session(cents, PriceReserve, SessionId, Buckets2) of
   				{PriceReserve, Buckets3} ->
  -					rate6(Subscriber#service{buckets = Buckets3},
  -							initial, 0, 0, ReserveAmount,
  -							UnitsReserved + UnitReserve, SessionId, Rated);
  +					rate6(Service, Buckets3, initial, 0, 0,
  +							ReserveAmount, UnitsReserved + UnitReserve, State);
   				{PriceReserved, Buckets3} ->
  -					rate6(Subscriber#service{buckets = Buckets3},
  -							initial, 0, 0, ReserveAmount,
  -							UnitsReserved + (PriceReserved div UnitPrice),
  -							SessionId, Rated)
  +					rate6(Service, Buckets3, initial, 0, 0, ReserveAmount,
  +							UnitsReserved + (PriceReserved div UnitPrice), State)
   			end
   	end;
  -rate5(#service{enabled = false, buckets = Buckets1} = Subscriber,
  +rate5(#service{enabled = false} = Service, Buckets1,
   		#price{units = Units, size = UnitSize, amount = UnitPrice},
  -		_Validity, interim, DebitAmount, _ReserveAmount,
  -		SessionAttributes, Rated) ->
  -	SessionId = get_session_id(SessionAttributes),
  +		interim, DebitAmount, _ReserveAmount,
  +		#{session_id := SessionId} = State) ->
   	case update_session(Units, DebitAmount, 0, SessionId, Buckets1) of
   		{DebitAmount, 0, Buckets2} ->
  -			rate6(Subscriber#service{buckets = Buckets2}, interim,
  -					DebitAmount, DebitAmount, 0, 0, SessionId, Rated);
  +			rate6(Service, Buckets2, interim,
  +					DebitAmount, DebitAmount, 0, 0, State);
   		{UnitsCharged, 0, Buckets2} ->
   			PriceChargeUnits = DebitAmount - UnitsCharged,
   			{UnitCharge, PriceCharge} = price_units(PriceChargeUnits,
   					UnitSize, UnitPrice),
   			case update_session(cents, PriceCharge, 0, SessionId, Buckets2) of
   				{PriceCharge, 0, Buckets3} ->
  -					rate6(Subscriber#service{buckets = Buckets3}, interim,
  -							DebitAmount, DebitAmount + UnitCharge, 0, 0,
  -							SessionId, Rated);
  +					rate6(Service, Buckets3, interim, DebitAmount,
  +							DebitAmount + UnitCharge, 0, 0, State);
   				{PriceCharged, 0, Buckets3} ->
  +					%% @todo generate unique bucket id
   					Buckets4 = [#bucket{remain_amount = PriceCharged - PriceCharge,
   							units = cents} | Buckets3],
  -					rate6(Subscriber#service{buckets = Buckets4}, interim, DebitAmount,
  -							UnitsCharged + (PriceCharged div UnitPrice), 0, 0,
  -							SessionId, Rated)
  +					rate6(Service, Buckets4, interim, DebitAmount,
  +							UnitsCharged + (PriceCharged div UnitPrice), 0, 0, State)
   			end
   	end;
  -rate5(#service{buckets = Buckets1} = Subscriber,
  +rate5(Service, Buckets1,
   		#price{units = Units, size = UnitSize, amount = UnitPrice},
  -		_Validity, interim, DebitAmount, ReserveAmount,
  -		SessionAttributes, Rated) ->
  -	SessionId = get_session_id(SessionAttributes),
  -	case update_session(Units, DebitAmount, ReserveAmount,
  -			SessionId, Buckets1) of
  +		interim, DebitAmount, ReserveAmount, #{session_id := SessionId} = State) ->
  +	case update_session(Units, DebitAmount, ReserveAmount, SessionId, Buckets1) of
   		{DebitAmount, ReserveAmount, Buckets2} ->
  -			rate6(Subscriber#service{buckets = Buckets2}, interim,
  -					DebitAmount, DebitAmount, ReserveAmount,
  -					ReserveAmount, SessionId, Rated);
  +			rate6(Service, Buckets2, interim, DebitAmount,
  +					DebitAmount, ReserveAmount, ReserveAmount, State);
   		{DebitAmount, UnitsReserved, Buckets2} ->
   			PriceReserveUnits = ReserveAmount - UnitsReserved,
   			{UnitReserve, PriceReserve} = price_units(PriceReserveUnits,
   					UnitSize, UnitPrice),
   			case update_session(cents, 0, PriceReserve, SessionId, Buckets2) of
   				{0, PriceReserve, Buckets3} ->
  -					rate6(Subscriber#service{buckets = Buckets3}, interim,
  -							DebitAmount, DebitAmount, ReserveAmount,
  -							UnitReserve, SessionId, Rated);
  +					rate6(Service, Buckets3, interim, DebitAmount,
  +							DebitAmount, ReserveAmount, UnitReserve, State);
   				{0, PriceReserved, Buckets3} ->
  -					rate6(Subscriber#service{buckets = Buckets3}, interim,
  -							DebitAmount, DebitAmount, ReserveAmount,
  -							UnitsReserved + PriceReserved div UnitPrice,
  -							SessionId, Rated)
  +					rate6(Service, Buckets3,
  +							interim, DebitAmount, DebitAmount, ReserveAmount,
  +							UnitsReserved + PriceReserved div UnitPrice, State)
   			end;
   		{UnitsCharged, 0, Buckets2} ->
   			PriceChargeUnits = DebitAmount - UnitsCharged,
  
positive.code: 						Acc
  				end
  		end,
  		[#offer{name = ProductName} = Product | _] = lists:foldl(F, [], Bundle),
  		rate2(Protocol, Subscriber, Timestamp, Address, Direction, Product,
  				Validity, Flag, DebitAmounts, ReserveAmounts, SessionAttributes,
  				#rated{product = ProductName})
  	catch
  		_:_ ->
  			throw(invalid_bundle_product)
  	end;
  rate1(Protocol, _ServiceType, Subscriber, Timestamp, Address, Direction,
  		#offer{name = ProductName} = Product, Validity, Flag, DebitAmounts,
  		ReserveAmounts, SessionAttributes) ->
  	rate2(Protocol, Subscriber, Timestamp, Address, Direction, Product,
  		Validity, Flag, DebitAmounts, ReserveAmounts, SessionAttributes,
  		#rated{product = ProductName}).
  %% @hidden
  rate2(Protocol, Subscriber, Timestamp, Address, Direction,
  		#offer{specification = ProdSpec, price = Prices},
  		Validity, Flag, DebitAmounts, ReserveAmounts,
  		SessionAttributes, Rated) when ProdSpec == "10"; ProdSpec == "11" ->
  	F = fun(#price{type = usage, units = messages}) ->
  				true;
  			(#price{type = usage, units = cents}) ->
  
negative.code: 				Expires /= undefined, Expires =< Now ->
  			NewDebitedAmount = DebitedAmount + Charge,
  			NewReservation = {Now, NewDebitedAmount, 0, SessionId},
  			NewAcc = [B#bucket{reservations =
  					[NewReservation | NewReservations]} | Acc],
  			charge_session(Type, 0, Now, SessionId, T, Charged + Charge, NewAcc);
  		{value, {_, DebitedAmount, ReservedAmount, _}, NewReservations}
  