anchor.diff:  code_change(_OldVsn, State, _Extra) ->
       {ok, State}.
   
  +handle_reconnect(Error, Phase, #state{ping_timer=Timer} = State) ->
  +    maybe_cancel_timer(Timer),
  +    handle_reconnect0(Error, Phase, State#state{mqttc=undefined, ping_timer=undefined}).
  +
  +handle_reconnect0(Error, Phase, #state{phase=OldPhase, last_connect=Last, connect_count=Count} = State) ->
  +    lager:debug("Connector ~w ~w reconnect ~B", [OldPhase, Error, Count]),
  +    case calendar:datetime_to_gregorian_seconds(calendar:universal_time())
  +            - calendar:datetime_to_gregorian_seconds(Last) of
  +        Diff when Diff < 30, Count > 120 ->
  +            % give up after 2 hours
  +            {stop, Error, State};
  +        Diff when Diff < 30, Count > 0 ->
  +            % wait, then wait even longer, but no longer than 30 sec
  +            timer:send_after(erlang:min(Count*5000, 30000), {connect, Phase}),
  +            {noreply, State#state{connect_count=Count+1}};
  +        Diff when Diff < 30, Count == 0 ->
  +            % initially try to reconnect immediately
  +            {noreply, connect(Phase, State#state{connect_count=1})};
  +        true ->
  +            {noreply, connect(Phase, State#state{connect_count=0})}
  +    end.
  +
  +connect(Phase, #state{cargs=CArgs} = State) ->
  +    {ok, C} = connect0(Phase, CArgs),
  +    State#state{phase=Phase, mqttc=C, last_connect=calendar:universal_time()}.
  +
  +connect0(attempt31, CArgs) ->
  +    emqttc:start_link([{proto_ver, 3} | CArgs]);
  +connect0(attempt311, CArgs) ->
  +    emqttc:start_link([{proto_ver, 4} | CArgs]).
   
   handle_connect(#state{subscribe=undefined}=State) ->
       {noreply, State#state{phase=connected}};
  
positive.code:         [{host, HostName},
          {port, Port},
          {logger, warning},
          {reconnect, {4, 60, 3}},
          {keepalive, 0}],
          auth_args(ConnUri, Conn),
          ssl_args(ConnUri, Conn)
      ]),
      % initially use MQTT 3.1.1
      {ok, C} = emqttc:start_link([{proto_ver, 4} | CArgs]),
      {ok, #state{cargs=CArgs, phase=connect311, mqttc=C, subscribe=Sub,
          published=prepare_filling(Pub), consumed=prepare_matching(Cons)}}.
  
  % Microsoft Shared Access Signature
  auth_args({_Scheme, _UserInfo, HostName, _Port, _Path, _Query},
  
negative.code:     Timer = schedule_refresh(),
      {noreply, State#state{phase=connected, ping_timer=Timer}}.
  
  handle_ping(State=#state{mqttc=undefined}) ->
      % ping timer expired, but meanwhile the client crashed
      % wait for reconnection
      {noreply, State};
  handle_ping(State=#state{mqttc=C}) ->
      pong = emqttc:ping(C),
      Timer = schedule_refresh(),
      {noreply, State#state{ping_timer=Timer}}.
  
  schedule_refresh() ->
      erlang:send_after(60*1000, self(), ping).
  