void SubscriptionService::createSubscriptionImplEnd(
        ExceptionPtr                    ePtr,
        ClientStubPtr                   clientStubPtr,
        boost::int32_t                  ret,
        const std::string &             publisherName,
        RcfClientPtr                    rcfClientPtr,
        OnSubscriptionDisconnect        onDisconnect,
        OnAsyncSubscribeCompleted       onCompletion,
        boost::uint32_t                 incomingPingIntervalMs,
        bool                            pingsEnabled)
    {
        SubscriptionPtr subscriptionPtr;

        if (!ePtr && ret != RcfError_Ok)
        {
            ePtr.reset( new Exception( Error(ret) ) );
        }

        if (!ePtr)
        {
            subscriptionPtr = onRequestSubscriptionCompleted(
                ret,
                publisherName,
                *clientStubPtr,
                rcfClientPtr,
                onDisconnect,
                incomingPingIntervalMs,
                pingsEnabled);
        }

        onCompletion(subscriptionPtr, ePtr);
    }
    SubscriptionPtr SubscriptionService::createSubscriptionImpl(
        RcfClientPtr rcfClientPtr, 
        const SubscriptionParms & parms,
        const std::string & defaultPublisherName)
    {
        if (parms.mOnAsyncSubscribeCompleted)
        {
            // Async code path.
            createSubscriptionImplBegin(rcfClientPtr, parms, defaultPublisherName);
            return SubscriptionPtr();
        }

        ClientStub & clientStub = const_cast<ClientStub &>(parms.mClientStub);
        OnSubscriptionDisconnect onDisconnect = parms.mOnDisconnect;
        std::string publisherName = parms.mPublisherName;
        if (publisherName.empty())
        {
            publisherName = defaultPublisherName;
        }

        boost::uint32_t     subToPubPingIntervalMs = mPingIntervalMs;
        boost::uint32_t     pubToSubPingIntervalMs = 0;
        bool                pingsEnabled = true;

        boost::int32_t ret = 0;

        // First round trip, to do version negotiation with the server.
        clientStub.ping();

        if (clientStub.getRuntimeVersion() <= 11)
        {
            ret = doRequestSubscription_Legacy(
                clientStub,
                publisherName,
                subToPubPingIntervalMs,
                pubToSubPingIntervalMs,
                pingsEnabled);
        }
        else
        {
            ret = doRequestSubscription(
                clientStub,
                publisherName,
                subToPubPingIntervalMs,
                pubToSubPingIntervalMs,
                pingsEnabled);
        }

        SubscriptionPtr subscriptionPtr = onRequestSubscriptionCompleted(
            ret,
            publisherName,
            clientStub,
            rcfClientPtr,
            onDisconnect,
            pubToSubPingIntervalMs,
            pingsEnabled);

        return subscriptionPtr;
    }
    SubscriptionPtr SubscriptionService::createSubscriptionImpl(
        RcfClientPtr rcfClientPtr, 
        const SubscriptionParms & parms,
        const std::string & defaultPublisherName)
    {
        if (parms.mOnAsyncSubscribeCompleted)
        {
            // Async code path.
            createSubscriptionImplBegin(rcfClientPtr, parms, defaultPublisherName);
            return SubscriptionPtr();
        }

        ClientStub & clientStub = const_cast<ClientStub &>(parms.mClientStub);
        OnSubscriptionDisconnect onDisconnect = parms.mOnDisconnect;
        std::string publisherName = parms.mPublisherName;
        if (publisherName.empty())
        {
            publisherName = defaultPublisherName;
        }

        RcfClient<I_RequestSubscription> client(clientStub);
        client.getClientStub().setTransport(clientStub.releaseTransport());
        boost::uint32_t subToPubPingIntervalMs = mPingIntervalMs;
        boost::uint32_t pubToSubPingIntervalMs = 0;

        bool pingsEnabled = true;

        boost::int32_t ret = 0;
        if (clientStub.getRuntimeVersion() < 8)
        {
            pingsEnabled = false;

            ret = client.RequestSubscription(
                Twoway, 
                publisherName);
        }
        else
        {
            ret = client.RequestSubscription(
                Twoway, 
                publisherName, 
                subToPubPingIntervalMs, 
                pubToSubPingIntervalMs);
        }

        SubscriptionPtr subscriptionPtr = onRequestSubscriptionCompleted(
            ret,
            publisherName,
            client,
            rcfClientPtr,
            onDisconnect,
            pubToSubPingIntervalMs,
            pingsEnabled);

        return subscriptionPtr;
    }
    void SubscriptionService::createSubscriptionImplEnd(
        Subscription::AsyncClientPtr    clientPtr,
        Future<boost::int32_t>          fRet,
        const std::string &             publisherName,
        RcfClientPtr                    rcfClientPtr,
        OnSubscriptionDisconnect        onDisconnect,
        OnAsyncSubscribeCompleted       onCompletion,
        Future<boost::uint32_t>         incomingPingIntervalMs,
        bool                            pingsEnabled)
    {
        SubscriptionPtr subscriptionPtr;

        ExceptionPtr exceptionPtr(
            clientPtr->getClientStub().getAsyncException().release());

        boost::int32_t ret = fRet;

        if (!exceptionPtr && ret != RcfError_Ok)
        {
            exceptionPtr.reset( new Exception( Error(ret) ) );
        }

        if (!exceptionPtr)
        {
            subscriptionPtr = onRequestSubscriptionCompleted(
                ret,
                publisherName,
                *clientPtr,
                rcfClientPtr,
                onDisconnect,
                incomingPingIntervalMs,
                pingsEnabled);
        }

        onCompletion(subscriptionPtr, exceptionPtr);
    }