   listen: =>
     @isListening = true
     selfWindow.addEventListener 'message', @onMessage
-    @validation = @client.call 'ping', null, {timeout: @handshakeTimeout}
+
+    @clientValidation = @client.call 'ping', null, {timeout: @handshakeTimeout}
+    .then (registeredMethods) =>
+      if registeredMethods is 'pong'
+        @isLegacy = true
+      else
+        @parentsRegisteredMethods = @parentsRegisteredMethods.concat(
+          registeredMethods
+        )
+
+    @swValidation = @ready.then =>
+      @sw.call 'ping', null, {timeout: @handshakeTimeout}
+    .then (registeredMethods) =>
+      @parentsRegisteredMethods = @parentsRegisteredMethods.concat(
+        registeredMethods
+      )
 
   close: =>
     @isListening = true

        throw new Error 'Method not found'
      return fn.apply null, params

    @ready.then =>
      if @hasParent
        parentError = null
        @validation
        .then =>
          @client.call method, params
        .catch (err) =>
          parentError = err
          if @sw
            @sw.call method, params
            .catch ->
              return localMethod method, params
          else
            return localMethod method, params
        .catch (err) ->
          if err.message is 'Method not found' and parentError isnt null
            throw parentError
          else
            throw err
      else
        new Promise (resolve) =>
          if @sw
            resolve(
              @sw.call(method, params)
              .catch (err) ->
                return localMethod method, params
            )
          else
            resolve localMethod(method, params)

    timeout ?= null
    @handshakeTimeout ?= DEFAULT_HANDSHAKE_TIMEOUT_MS
    @isListening = false
    @isLegacy = false # TODO: remove when native apps are updated
    @hasParent = window? and window.self isnt window.top
    @parent = window?.parent

