anchor.diff:  	{_, NewPort} = lists:keyfind("port", 1, Object1),
   	{_, NewProtocol} = lists:keyfind("protocol", 1, Object1),
   	{_, Secret} = lists:keyfind("secret", 1, Object1),
  -	ok = ssl:close(SslSock).
  -
  -update_subscriber_password_json_patch() ->
  -	[{userdata, [{doc,"Use HTTP PATCH to update subscriber's password using
  -			json-patch media type"}]}].
  -
  -update_subscriber_password_json_patch(Config) ->
  -	ContentType = "application/json",
  -	ID = ocs:generate_identity(),
  -	Password = ocs:generate_password(),
  -	ProdID = ?config(product_id, Config),
  -	AsendDataRate = {struct, [{"name", "ascendDataRate"}, {"value", 1000000}]},
  -	AsendXmitRate = {struct, [{"name", "ascendXmitRate"}, {"value", 64000}]},
  -	SessionTimeout = {struct, [{"name", "sessionTimeout"}, {"value", 3600}]},
  -	Interval = {struct, [{"name", "acctInterimInterval"}, {"value", 300}]},
  -	Class = {struct, [{"name", "class"}, {"value", "skiorgs"}]},
  -	SortedAttributes = lists:sort([AsendDataRate, AsendXmitRate, SessionTimeout, Interval, Class]),
  -	AttributeArray = {array, SortedAttributes},
  -	Amount = {"remainAmount", "3000"},
  -	Units = {"units", "cents"},
  -	Buckets = {array, [{struct, [Amount, Units]}]},
  -	Enabled = true,
  -	Multi = false,
  -	JSON = {struct, [{"id", ID}, {"password", Password},
  -	{"attributes", AttributeArray}, {"buckets", Buckets}, {"enabled", Enabled},
  -	{"multisession", Multi}, {"product", ProdID}]},
  -	RequestBody = lists:flatten(mochijson:encode(JSON)),
  -	HostUrl = ?config(host_url, Config),
  -	Accept = {"accept", "application/json"},
  -	Request = {HostUrl ++ "/ocs/v1/subscriber", [Accept, auth_header()], ContentType, RequestBody},
  -	{ok, Result} = httpc:request(post, Request, [], []),
  -	{{"HTTP/1.1", 201, _Created}, Headers, ResponseBody} = Result,
  -	{_, "application/json"} = lists:keyfind("content-type", 1, Headers),
  -	{_, Etag} = lists:keyfind("etag", 1, Headers),
  -	true = is_etag_valid(Etag),
  -	ContentLength = integer_to_list(length(ResponseBody)),
  -	{_, ContentLength} = lists:keyfind("content-length", 1, Headers),
  -	{_, URI} = lists:keyfind("location", 1, Headers),
  -	{"/ocs/v1/subscriber/" ++ ID, _} = httpd_util:split_path(URI),
  -	{struct, Object} = mochijson:decode(ResponseBody),
  -	{"id", ID} = lists:keyfind("id", 1, Object),
  -	{_, URI} = lists:keyfind("href", 1, Object),
  -	{"password", Password} = lists:keyfind("password", 1, Object),
  -	{_, {array, Attributes}} = lists:keyfind("attributes", 1, Object),
  -	ExtraAttributes = Attributes -- SortedAttributes,
  -	SortedAttributes = lists:sort(Attributes -- ExtraAttributes),
  -	{"totalBalance", Buckets1} = lists:keyfind("totalBalance", 1, Object),
  -	{"enabled", Enabled} = lists:keyfind("enabled", 1, Object),
  -	{"multisession", Multi} = lists:keyfind("multisession", 1, Object),
  -	RestPort = ?config(port, Config),
  -	{ok, SslSock} = ssl:connect({127,0,0,1}, RestPort,  [binary, {active, false}], infinity),
  -	NewContentType = "application/json-patch+json",
  -	NewPassword = ocs:generate_password(),
  -	JSON1 = {array, [{struct, [{op, "replace"}, {path, "/password"}, {value, NewPassword}]}]},
  -	PatchBody = lists:flatten(mochijson:encode(JSON1)),
  -	PatchBodyLen = size(list_to_binary(PatchBody)),
  -	PatchUri = "/ocs/v1/subscriber/" ++ ID,
  -	PatchReq = ["PATCH ", PatchUri, " HTTP/1.1",$\r,$\n,
  -			"Content-Type:" ++ NewContentType, $\r,$\n, "Accept:application/json",$\r,$\n,
  -			"If-match:" ++ Etag,$\r,$\n,"Authorization:"++ basic_auth(),$\r,$\n,
  -			"Host:localhost:" ++ integer_to_list(RestPort),$\r,$\n,
  -			"Content-Length:" ++ integer_to_list(PatchBodyLen),$\r,$\n,
  -			$\r, $\n,
  -			PatchBody],
  -	ok = ssl:send(SslSock, list_to_binary(PatchReq)),
  -	Timeout = 1500,
  -	F = fun(_F, _Sock, {error, timeout}, Acc) ->
  -					lists:reverse(Acc);
  -			(F, Sock, {ok, Bin}, Acc) ->
  -					F(F, Sock, ssl:recv(Sock, 0, Timeout), [Bin | Acc])
  -	end,
  -	RecvBuf = F(F, SslSock, ssl:recv(SslSock, 0, Timeout), []),
  -	PatchResponse = list_to_binary(RecvBuf),
  -	[Headers1, ResponseBody1] = binary:split(PatchResponse, <<$\r,$\n,$\r,$\n>>),
  -	<<"HTTP/1.1 200", _/binary>> = Headers1,
  -	{struct, Object1} = mochijson:decode(ResponseBody1),
  -	{"id", ID} = lists:keyfind("id", 1, Object1),
  -	{_, URI} = lists:keyfind("href", 1, Object1),
  -	{"password", NewPassword} = lists:keyfind("password", 1, Object1),
  -	{_, {array, Attributes}} = lists:keyfind("attributes", 1, Object1),
  -	ExtraAttributes = Attributes -- SortedAttributes,
  -	SortedAttributes = lists:sort(Attributes -- ExtraAttributes),
  -	{"totalBalance", Buckets1} = lists:keyfind("totalBalance", 1, Object1),
  -	{"enabled", Enabled} = lists:keyfind("enabled", 1, Object1),
  -	{"multisession", Multi} = lists:keyfind("multisession", 1, Object1),
  -	ok = ssl:close(SslSock).
  -
  -update_subscriber_attributes_json_patch() ->
  -	[{userdata, [{doc,"Use HTTP PATCH to update subscriber's attributes using
  -			json-patch media type"}]}].
  -
  -update_subscriber_attributes_json_patch(Config) ->
  -	ContentType = "application/json",
  -	ProdID = ?config(product_id, Config),
  -	ID = ocs:generate_identity(),
  -	Password = ocs:generate_password(),
  -	AsendDataRate = {struct, [{"name", "ascendDataRate"}, {"value", 1000000}]},
  -	AsendXmitRate = {struct, [{"name", "ascendXmitRate"}, {"value", 64000}]},
  -	SessionTimeout = {struct, [{"name", "sessionTimeout"}, {"value", 3600}]},
  -	Interval = {struct, [{"name", "acctInterimInterval"}, {"value", 300}]},
  -	Class = {struct, [{"name", "class"}, {"value", "skiorgs"}]},
  -	SortedAttributes = lists:sort([AsendDataRate, AsendXmitRate, SessionTimeout, Interval, Class]),
  -	AttributeArray = {array, SortedAttributes},
  -	Amount = {"remainAmount", "3000"},
  -	Units = {"units", "cents"},
  -	Buckets = {array, [{struct, [Amount, Units]}]},
  -	Enabled = true,
  -	Multi = true,
  -	JSON = {struct, [{"id", ID}, {"password", Password}, {"product", ProdID},
  -	{"attributes", AttributeArray}, {"buckets", Buckets}, {"enabled", Enabled},
  -	{"multisession", Multi}]},
  -	RequestBody = lists:flatten(mochijson:encode(JSON)),
  -	HostUrl = ?config(host_url, Config),
  -	Accept = {"accept", "application/json"},
  -	Request = {HostUrl ++ "/ocs/v1/subscriber", [Accept, auth_header()], ContentType, RequestBody},
  -	{ok, Result} = httpc:request(post, Request, [], []),
  -	{{"HTTP/1.1", 201, _Created}, Headers, ResponseBody} = Result,
  -	{_, "application/json"} = lists:keyfind("content-type", 1, Headers),
  -	{_, Etag} = lists:keyfind("etag", 1, Headers),
  -	true = is_etag_valid(Etag),
  -	ContentLength = integer_to_list(length(ResponseBody)),
  -	{_, ContentLength} = lists:keyfind("content-length", 1, Headers),
  -	{_, URI} = lists:keyfind("location", 1, Headers),
  -	{"/ocs/v1/subscriber/" ++ ID, _} = httpd_util:split_path(URI),
  -	{struct, Object} = mochijson:decode(ResponseBody),
  -	{"id", ID} = lists:keyfind("id", 1, Object),
  -	{_, URI} = lists:keyfind("href", 1, Object),
  -	{"password", Password} = lists:keyfind("password", 1, Object),
  -	{_, {array, Attributes}} = lists:keyfind("attributes", 1, Object),
  -	ExtraAttributes = Attributes -- SortedAttributes,
  -	SortedAttributes = lists:sort(Attributes -- ExtraAttributes),
  -	{"totalBalance", Buckets1} = lists:keyfind("totalBalance", 1, Object),
  -	{"enabled", Enabled} = lists:keyfind("enabled", 1, Object),
  -	{"multisession", Multi} = lists:keyfind("multisession", 1, Object),
  -	RestPort = ?config(port, Config),
  -	{ok, SslSock} = ssl:connect({127,0,0,1}, RestPort,  [binary, {active, false}], infinity),
  -	NewContentType = "application/json-patch+json",
  -	NewEnabled = false,
  -	NewMulti = false,
  -	NewAttributes = {array,[
  -			{struct, [{"name", "ascendDataRate"}, {"value", 100000}]},
  -			{struct, [{"name", "ascendXmitRate"}, {"value", 512000}]}]},
  -	JSON1 = {array, [
  -			{struct, [{op, "replace"}, {path, "/attributes"}, {value, NewAttributes}]},
  -			{struct, [{op, "replace"}, {path, "/enabled"}, {value, NewEnabled}]},
  -			{struct, [{op, "replace"}, {path, "/multisession"}, {value, NewMulti}]}]},
  -	PatchBody = lists:flatten(mochijson:encode(JSON1)),
  -	PatchBodyLen = size(list_to_binary(PatchBody)),
  -	PatchUri = "/ocs/v1/subscriber/" ++ ID,
  -	PatchReq = ["PATCH ", PatchUri, " HTTP/1.1",$\r,$\n,
  -			"Content-Type:" ++ NewContentType, $\r,$\n, "Accept:application/json",$\r,$\n,
  -			"If-match:" ++ Etag,$\r,$\n,"Authorization:"++ basic_auth(),$\r,$\n,
  -			"Host:localhost:" ++ integer_to_list(RestPort),$\r,$\n,
  -			"Content-Length:" ++ integer_to_list(PatchBodyLen),$\r,$\n,
  -			$\r, $\n,
  -			PatchBody],
  -	ok = ssl:send(SslSock, list_to_binary(PatchReq)),
  -	Timeout = 1500,
  -	F = fun(_F, _Sock, {error, timeout}, Acc) ->
  -					lists:reverse(Acc);
  -			(F, Sock, {ok, Bin}, Acc) ->
  -					F(F, Sock, ssl:recv(Sock, 0, Timeout), [Bin | Acc])
  -	end,
  -	RecvBuf = F(F, SslSock, ssl:recv(SslSock, 0, Timeout), []),
  -	PatchResponse = list_to_binary(RecvBuf),
  -	[Headers1, ResponseBody1] = binary:split(PatchResponse, <<$\r,$\n,$\r,$\n>>),
  -	<<"HTTP/1.1 200", _/binary>> = Headers1,
  -	{struct, Object1} = mochijson:decode(ResponseBody1),
  -	{"id", ID} = lists:keyfind("id", 1, Object1),
  -	{_, URI} = lists:keyfind("href", 1, Object1),
  -	{"password", Password} = lists:keyfind("password", 1, Object1),
  -	{_, NewAttributes} = lists:keyfind("attributes", 1, Object1),
  -	{"totalBalance", Buckets1} = lists:keyfind("totalBalance", 1, Object1),
  -	{"enabled", NewEnabled} = lists:keyfind("enabled", 1, Object1),
  -	{"multisession", NewMulti} = lists:keyfind("multisession", 1, Object1),
   	ok = ssl:close(SslSock).
   
   %%---------------------------------------------------------------------
  
positive.code: 	{_, Balance1} = lists:keyfind("amount", 1, TotalAmount),
  	Balance1 = ocs_rest:millionths_out(Balance).
  
  simultaneous_updates_on_subscriber_failure() ->
  	[{userdata, [{doc,"Simulataneous HTTP PATCH updates on subscriber resource must fail
  			if the resource is already being updated by someone else"}]}].
  
  simultaneous_updates_on_subscriber_failure(Config) ->
  	ContentType = "application/json",
  	ID = "eacfd73ae10a",
  	Password = "ksc8c244npqc",
  	ProdID = ?config(product_id, Config),
  	AsendDataRate = {struct, [{"name", "ascendDataRate"}, {"value", 1000000}]},
  	AsendXmitRate = {struct, [{"name", "ascendXmitRate"}, {"value", 64000}]},
  	SessionTimeout = {struct, [{"name", "sessionTimeout"}, {"value", 3600}]},
  	Interval = {struct, [{"name", "acctInterimInterval"}, {"value", 300}]},
  	Class = {struct, [{"name", "class"}, {"value", "skiorgs"}]},
  	SortedAttributes = lists:sort([AsendDataRate, AsendXmitRate, SessionTimeout, Interval, Class]),
  	AttributeArray = {array, SortedAttributes},
  	Amount = {"remainAmount", "3000"},
  	Units = {"units", "cents"},
  	Buckets = {array, [{struct, [Amount, Units]}]},
  	Enable = true,
  	Multi = false,
  	JSON1 = {struct, [{"id", ID}, {"password", Password},
  	{"attributes", AttributeArray}, {"buckets", Buckets}, {"enabled", Enable},
  	{"multisession", Multi}, {"product", ProdID}]},
  	RequestBody = lists:flatten(mochijson:encode(JSON1)),
  	HostUrl = ?config(host_url, Config),
  	Accept = {"accept", "application/json"},
  	Request = {HostUrl ++ "/ocs/v1/subscriber", [Accept, auth_header()], ContentType, RequestBody},
  	{ok, Result} = httpc:request(post, Request, [], []),
  	{{"HTTP/1.1", 201, _Created}, Headers, ResponseBody} = Result,
  	{_, "application/json"} = lists:keyfind("content-type", 1, Headers),
  	{_, _Etag} = lists:keyfind("etag", 1, Headers),
  	ContentLength = integer_to_list(length(ResponseBody)),
  	{_, ContentLength} = lists:keyfind("content-length", 1, Headers),
  	{_, URI} = lists:keyfind("location", 1, Headers),
  	{"/ocs/v1/subscriber/" ++ ID, _} = httpd_util:split_path(URI),
  	{struct, Object} = mochijson:decode(ResponseBody),
  	{"id", ID} = lists:keyfind("id", 1, Object),
  	{_, URI} = lists:keyfind("href", 1, Object),
  	{"password", Password} = lists:keyfind("password", 1, Object),
  	{_, {array, Attributes}} = lists:keyfind("attributes", 1, Object),
  	ExtraAttributes = Attributes -- SortedAttributes,
  	SortedAttributes = lists:sort(Attributes -- ExtraAttributes),
  	{"totalBalance", _Buckets1} = lists:keyfind("totalBalance", 1, Object),
  	{"enabled", Enable} = lists:keyfind("enabled", 1, Object),
  	{"multisession", Multi} = lists:keyfind("multisession", 1, Object),
  	Port = ?config(port, Config),
  	{ok, SslSock} = ssl:connect({127,0,0,1}, Port,  [binary, {active, false}], infinity),
  	Json = {array, [{struct, [{op, "replace"}, {path, "/password"}, {value, "7fy8qhs7hh7n"}]}]},
  	PatchBody = mochijson:encode(Json),
  	PatchBodyLen = size(list_to_binary(PatchBody)),
  	PatchUri = "/ocs/v1/subscriber/" ++ ID,
  	TS = integer_to_list(erlang:system_time(milli_seconds)),
  	N = integer_to_list(erlang:unique_integer([positive])),
  	NewEtag = TS ++ "-" ++ N,
  	PatchReq = ["PATCH ", PatchUri, " HTTP/1.1",$\r,$\n,
  			"Content-Type:application/json-patch+json", $\r,$\n, "Accept:application/json",$\r,$\n,
  			"If-match:" ++ NewEtag,$\r,$\n,"Authorization:"++ basic_auth() ,$\r,$\n,
  			"Host:localhost:" ++ integer_to_list(Port),$\r,$\n,
  			"Content-Length:" ++ integer_to_list(PatchBodyLen),$\r,$\n,
  			$\r, $\n,
  			PatchBody],
  	ok = ssl:send(SslSock, list_to_binary(PatchReq)),
  	Timeout = 1500,
  	F = fun(_F, _Sock, {error, timeout}, Acc) ->
  					lists:reverse(Acc);
  			(F, Sock, {ok, Bin}, Acc) ->
  					F(F, Sock, ssl:recv(Sock, 0, Timeout), [Bin | Acc])
  	end,
  	RecvBuf = F(F, SslSock, ssl:recv(SslSock, 0, Timeout), []),
  	PatchResponse = list_to_binary(RecvBuf),
  	[H, _ErroMsg] = binary:split(PatchResponse, <<$\r,$\n,$\r,$\n>>),
  	<<"HTTP/1.1 412", _/binary>> = H,
  	ok = ssl:close(SslSock).
  
  simultaneous_updates_on_client_failure() ->
  	[{userdata, [{doc,"Simulataneous HTTP PATCH requests on client resource must fail
  			if the resource is already being updated by someone else"}]}].
  
negative.code: 	get_auth_usage, get_auth_usage_id, get_auth_usage_filter,
  	get_auth_usage_range, get_acct_usage, get_acct_usage_id,
  	get_acct_usage_filter, get_acct_usage_range, get_ipdr_usage,
  	top_up, get_balance, simultaneous_updates_on_client_failure,
  	get_product, add_product, add_product_sms,
  	update_product_realizing_service, delete_product,
  	ignore_delete_product, query_product, filter_product].
  
  %%%%%---------------------------------------------------------------------
  