 
       channelInstance = new PubnubChannel name: pubnubChannelName
 
-      err = @pubnub.subscribe
+      callbackCalled = no
+
+      pb = options.pbInstance or @pubnub
+
+      pb.subscribe
         channel : pubnubChannelName
-        message : (message, env, channel) =>
-
-          return  unless message
-
-          {eventName, body, eventId} = message
-
-          return  unless eventName and body
-
-          if eventId?
-            return  if @eventCache[eventId]
-
-            # TODO delete this periodically
-            @eventCache[eventId] = yes
-
-
-          # when a user is connected in two browsers, and leaves a channel, in second one
-          # they receive RemovedFromChannel event for their own. Therefore we must unsubscribe
-          # user from all connected devices.
-          if eventName is 'RemovedFromChannel' and body.accountId is whoami().socialApiId
-            return @unsubscribePubnub message.channel
-
-          # no need to emit any events when not subscribed
-          return  unless @channels[channel]
-
-          # instance events are received via public channel. For this reason
-          # if an event name includes "instance-", update the related message channel
-          # An instance event format is like "instance-5dc4ce55-b159-11e4-8329-c485b673ee34.ReplyAdded" - ctf
-          if eventName.indexOf("instance-") < 0
-            return @channels[channel].emit eventName, body
-
-          events = eventName.split "."
-          if events.length < 2
-            warn 'could not parse event name', eventName
-            return
-
-          [instanceChannel, eventName] = events
-
-          return  unless @channels[instanceChannel]
-
-          @channels[instanceChannel].emit eventName, body
-
-
+        message : (message, env, channel) => @handleMessage message, channel
         connect : =>
           @channels[pubnubChannelName] = channelInstance
           @removeFromForbiddenChannels pubnubChannelName
+          callbackCalled = yes
           callback null, channelInstance
-        error   : (err) => @handleError err
-        reconnect: => @getTimeDiffWithServer()
+        error   : (err) =>
+          @handleError err
+          callback err  unless callbackCalled
+        reconnect: (channel) => @reconnect channel, pb
         # with each channel subscription pubnub resubscribes to every channel
         # and some messages are dropped in this resubscription time interval
         # for this reason for every subscribe request, we are fetching all messages sent


      return callback err  if err

  getTimeDiffWithServer: ->
    @pubnub.time (serverTime) =>

      return  unless serverTime

      diff = new Date() * 10000 - serverTime
      # when time difference between pubnub server and client is less than 500ms
      # ignore the difference
      @timeDiff = if Math.abs(diff) < 5000000 then 0 else diff

  handleError: (err) ->
    {message, payload} = err

    return kd.warn err  unless payload?.channels



        @authenticated = yes
        @emit 'authenticated'


  fetchServerTime: ->
    @pubnub.time (timestamp) =>
      return  unless timestamp

      @serverTimestamp = timestamp
      @emit 'Ping', timestamp


  setAuthToken: (token) ->
    @pubnub.auth token
    @pbNotification.auth token


  # channel authentication is needed for notification channel and
