anchor.diff:  %%========================================
   %% Types
   %%========================================
  --type encoding() :: text | binary.
  --type client_name() :: {local, atom()} | {global, atom()} | anon.
  +-type encoding()            :: text | binary.
  +-type client_name()         :: {local, atom()} | {global, atom()} | anon.
  +-type on_open_callback()    :: fun(() -> any()).
  +-type on_error_callback()   :: fun((Error :: string()) -> any()).
  +-type data_callback() :: fun((text, Payload :: string()) -> any() )| fun((binary, Payload :: binary()) -> any()).
  +-type on_message_callback() :: data_callback().
  +-type on_close_callback()   :: data_callback().
   
   %%========================================
   %% Constants
  
positive.code: %% @doc Send data to a remote endpoint
  %%
  %% This is the same as calling {@link send/3} whit the third parameter being the type of the Data sent.
  %%
  -spec send(
    Socket :: pid() | atom(),
    Data :: binary()|string()
    ) -> ok.
  send(Socket, Data) when is_binary(Data) ->
    send(Socket, Data, binary);
  send(Socket, Data) when is_list(Data) ->
    send(Socket, Data, text).
  
  %% @doc Send data to a remote endpoint
  %%
  %% Sends data using the specified wsecli client, encoding the data as the give type.
  %%
  -spec send(
    Socket :: pid() | atom(),
    Data :: binary() | string(),
    Type :: encoding()
    ) -> ok.
  send(Socket, Data, Type) ->
    gen_fsm:send_event(Socket, {send, Data, Type}).
  
  %% @doc Add a callback to be called when a connection is opened
  %%
  %% This callback is called when the connection is opened (after a successful websocket handshake)
  %%or inmediatelly if called while in the open state. Adding it not it connecting or open state will
  %%raise an error.
  %%
  %% The callback function must be a function which takes no parameters
  -spec on_open(Callback::fun()) -> any().
  on_open(Callback) ->
    on_open(?DEFAULT_REG_NAME, Callback).
  
  %% @doc Add a callback to be called when a connection is opened
  %%
  %% This callback is called when the connection is opened (after a successful websocket handshake)
  %%or inmediatelly if called while in the open state. Adding it not it connecting or open state will
  %%raise an error.
  %%
  %% The callback function must be a function which takes no parameters
  -spec on_open(Socket::pid()|atom(), Callback::fun()) -> any().
  on_open(Socket, Callback) ->
    gen_fsm:send_event(Socket, {on_open, Callback}).
  
  %% @doc Add a callback to be called when an error occurs
  %%
  %% The callback function must be a function which takes one parameter, the reason for
  %%the error
  -spec on_error(Callback::fun()) -> any().
  on_error(Callback) ->
    on_error(?DEFAULT_REG_NAME, Callback).
  
  %% @doc Add a callback to be called when an error occurs
  %%
  %% The callback function must be a function which takes one parameter, the reason for
  %%the error
  -spec on_error(Socket::pid()|atom(), Callback::fun()) -> any().
  on_error(Socket, Callback) ->
    gen_fsm:send_all_state_event(Socket, {on_error, Callback}).
  
  %% @doc Add a callback to be called when a message arrives
  %%
  %% The callback function must be a function which takes two parameters:
  %% <ul>
  %% <li> The first is an atom with values binary or text depending on the type of the websocket message</li>
  %% <li> The second parameter is the message payload</li>
  %% </ul>
  -spec on_message(Callback::fun()) -> any().
  on_message(Callback) ->
    on_message(?DEFAULT_REG_NAME, Callback).
  
  %% @doc Add a callback to be called when a message arrives
  %%
  %% The callback function must be a function which takes two parameters:
  %% <ul>
  %% <li> The first is an atom with values binary or text depending on the type of the websocket message</li>
  %% <li> The second parameter is the message payload</li>
  %% </ul>
  -spec on_message(Socket::atom()|pid(), Callback::fun()) -> any().
  on_message(Socket, Callback) ->
    gen_fsm:send_all_state_event(Socket, {on_message, Callback}).
  
  %% @doc Add a callback to be called when then connection was closed
  %%
  %% This callback will be called when the connection is successfully closed, i.e. after performing the
  %%websocket closing handshake.
  %%
  %% The callback function must be a function which takes one parameter, the payload
  %%of the close message received from the remote endpoint (if any)
  -spec on_close(Callback::fun()) -> any().
  on_close(Callback) ->
    on_close(?DEFAULT_REG_NAME, Callback).
  
  %% @doc Add a callback to be called when then connection was closed
  %%
  %% This callback will be called when the connection is successfully closed, i.e. after performing the
  %%websocket closing handshake.
  %%
  %% The callback function must be a function which takes one parameter, the payload
  %%of the close message received from the remote endpoint (if any)
  -spec on_close(Socket::pid()|atom(), Callback::fun()) -> any().
  on_close(Socket, Callback) ->
    gen_fsm:send_all_state_event(Socket, {on_close, Callback}).
  
  %%%%%%%%%%%%%%%%%%%%%
  %
  % GEN FSM STATENAME FUNCTIONS
  %
  %%%%%%%%%%%%%%%%%%%%%
  %% @hidden
  -spec init({Host::string(), Port::integer(), Resource::string()}) -> {ok, connecting, #data{}}.
  init({Host, Port, Resource}) ->
    {ok, Socket} = gen_tcp:connect(Host, Port, [binary, {reuseaddr, true}, {packet, raw}] ),
  
  
negative.code: %% @doc Start the websocket client
  %%
  %% This function will open a connection with the specified remote endpoint building an URL like `ws://Host:PortResource'.
  %% If the atom `anon' is given as the ClientName, the client will not be registered.
  -spec start(
    Host     :: string(),
    Port     :: inet:port_number(),
    Resource :: string(),
    ClientName  :: client_name()
    ) -> pid().
  start(Host, Port, Path, anon) ->
    gen_fsm:start_link(?MODULE, {Host, Port, Path}, [{timeout, 5000}]);
  start(Host, Port, Path, ClientName) ->
    gen_fsm:start_link(ClientName, ?MODULE, {Host, Port, Path}, [{timeout, 5000}]).
  
  %% @doc Stop the websocket client
  %%
  %% This is the same as calling {@link stop/1} with the atom `wsecli' as a parameter.
  -spec stop() -> ok.
  stop() ->
    stop(?DEFAULT_REG_NAME).
  
  %% @doc Stop the websocket client
  %%
  %% Calling this function doesn't mean that the connection will be inmediatelly closed. A
  %% closing handshake is tryed and only after that the connection is closed and the client stopped.
  -spec stop(
    Client :: client_name()
    ) -> ok.
  stop(Client) ->
    gen_fsm:sync_send_all_state_event(Client, stop).
  
  %% @doc Send data to a remote endpoint
  %%
  %% This is the same as calling {@link send/2} with the atom `wsecli' (see {@link start/3}) as first parameter
  -spec send(
      Data::string()
    ) -> ok;
  