anchor.diff:  
   -export_type([token/0]).
   
  --record(state, {credentials::betfair:credentials(), connection, token}).
  +-record(state, {credentials::betfair:credentials(),
  +                connection, token, keep_alive}).
  +
   
   %%%===================================================================
   %%% API
  
positive.code:     {ok, _} = gun:open("identitysso.betfair.com", 443,
                         #{transport => ssl, transport_opts => SslOpts}),
  
      {ok, #state{credentials=Credentials}}.
  
  handle_call(token, _From, #state{token=Token} = State) ->
      {reply, Token, State};
  
negative.code: %%% Internal functions
  %%%===================================================================
  
  %% TODO these look generic - maybe use elsewhere?
  
  receive_response(Self, Stream, Connection, Handler) ->
      receive
          {gun_response, Connection, Stream, fin, _Status, _Headers} ->
              no_data;
          {gun_response, Connection, Stream, nofin, _Status, _Headers} ->
              %% TODO only receive if 200 status?
              receive_data(Self, Connection, Stream, Handler);
          {'DOWN', _, process, Connection, Reason} ->
              error_logger:error_msg("Oops!"),
              exit(Reason)
      after 1000 ->
              exit(timeout)
      end.
  
  receive_data(Self, Connection, Stream, Handler) ->
      receive
          {gun_data, _Connection, _Stream, nofin, _Data} ->
              receive_data(Self, Connection, Stream, Handler);
          {gun_data, _Connection, Stream, fin, Data} ->
              lager:info("Received Data ~p", [Data]),
              Response = jsx:decode(Data, [return_maps, {labels, atom}]),
              Self ! Handler(Response);
          {'DOWN', _, process, _Connection, Reason} ->
              _ = lager:error("Oops!"),
              exit(Reason)
      after 1000 ->
              exit(timeout)
      end.
  
  
  login_handler(#{sessionToken := Token, loginStatus := _Reason}) ->
      {token, Token};
  login_handler(#{loginStatus := Reason}) ->
      exit(Reason).
  
  keep_alive_handler(#{token := Token, status := <<"SUCCESS">>}) ->
      {token, Token};
  keep_alive_handler(#{status := <<"SUCCESS">>, error := Reason}) ->
      exit(Reason).
  
  
  keep_alive(KeepAliveInterval) ->
      erlang:send_after(KeepAliveInterval, self(), keep_alive).
  