docs: function() {
                  var asyncGetReadyTime = new Date().getTime();
  
                  asyncClient = new Async({
                      protocol: protocol,
                      queueHost: queueHost,
                      queuePort: queuePort,
                      queueUsername: queueUsername,
                      queuePassword: queuePassword,
                      queueReceive: queueReceive,
                      queueSend: queueSend,
                      queueConnectionTimeout: queueConnectionTimeout,
                      socketAddress: socketAddress,
                      serverName: serverName,
                      deviceId: deviceId,
                      wsConnectionWaitTime: wsConnectionWaitTime,
                      connectionRetryInterval: connectionRetryInterval,
                      connectionCheckTimeout: connectionCheckTimeout,
                      connectionCheckTimeoutThreshold: connectionCheckTimeoutThreshold,
                      messageTtl: messageTtl,
                      reconnectOnClose: reconnectOnClose,
                      asyncLogging: asyncLogging
                  });
  
                  asyncClient.on('asyncReady', function() {
                      if (actualTimingLog) {
                          Utility.chatStepLogger('Async Connection ', new Date().getTime() - asyncGetReadyTime);
                      }
  
                      peerId = asyncClient.getPeerId();
  
                      if (!userInfo) {
                          var getUserInfoTime = new Date().getTime();
  
                          getUserInfo(function(userInfoResult) {
                              if (actualTimingLog) {
                                  Utility.chatStepLogger('Get User Info ', new Date().getTime() - getUserInfoTime);
                              }
                              if (!userInfoResult.hasError) {
                                  userInfo = userInfoResult.result.user;
  
                                  /**
                                   * Check if user has KeyId stored in their cache or not?
                                   */
                                  if (canUseCache) {
                                      if (db) {
                                          db.users
                                              .where('id')
                                              .equals(userInfo.id)
                                              .toArray()
                                              .then(function(users) {
                                                  if (users.length > 0 && typeof users[0].keyId != 'undefined') {
                                                      var user = users[0];
  
                                                      getEncryptionKey({
                                                          keyId: user.keyId
                                                      }, function(result) {
                                                          if (!result.hasError) {
                                                              cacheSecret = result.secretKey;
                                                          }
                                                          else {
                                                              if (result.message != '') {
                                                                  try {
                                                                      var response = JSON.parse(result.message);
                                                                      if (response.error == 'invalid_param') {
                                                                          generateEncryptionKey({
                                                                              keyAlgorithm: 'AES',
                                                                              keySize: 256
                                                                          });
                                                                      }
                                                                  }
                                                                  catch (e) {
                                                                      console.log(e);
                                                                  }
                                                              }
                                                          }
                                                      });
                                                  }
                                                  else {
                                                      generateEncryptionKey({
                                                          keyAlgorithm: 'AES',
                                                          keySize: 256
                                                      });
                                                  }
                                              })
                                              .catch(function(error) {
                                                  fireEvent('error', {
                                                      code: error.errorCode,
                                                      message: error.errorMessage,
                                                      error: error
                                                  });
                                              });
                                      }
                                      else {
                                          fireEvent('error', {
                                              code: 6601,
                                              message: CHAT_ERRORS[6601],
                                              error: null
                                          });
                                      }
                                  }
  
                                  chatState = true;
                                  fireEvent('chatReady');
                                  chatSendQueueHandler();
                              }
                          });
                      }
                      else if (userInfo.id > 0) {
                          chatState = true;
                          fireEvent('chatReady');
                          chatSendQueueHandler();
                      }
                  });
  
                  asyncClient.on('stateChange', function(state) {
                      fireEvent('chatState', state);
                      chatFullStateObject = state;
  
                      switch (state.socketState) {
                          case 1: // CONNECTED
                              if (state.deviceRegister && state.serverRegister) {
                                  chatState = true;
                                  ping();
                              }
                              break;
                          case 0: // CONNECTING
                          case 2: // CLOSING
                          case 3: // CLOSED
                              chatState = false;
                              break;
                      }
                  });
  
                  asyncClient.on('connect', function(newPeerId) {
                      asyncGetReadyTime = new Date().getTime();
                      peerId = newPeerId;
                      fireEvent('connect');
                      ping();
                  });
  
                  asyncClient.on('disconnect', function(event) {
                      oldPeerId = peerId;
                      peerId = undefined;
                      fireEvent('disconnect', event);
                  });
  
                  asyncClient.on('reconnect', function(newPeerId) {
                      peerId = newPeerId;
                      fireEvent('reconnect');
                  });
  
                  asyncClient.on('message', function(params, ack) {
                      receivedAsyncMessageHandler(params);
                      ack && ack();
                  });
  
                  asyncClient.on('error', function(error) {
                      fireEvent('error', {
                          code: error.errorCode,
                          message: error.errorMessage,
                          error: error.errorEvent
                      });
                  });
              }