void SubscriptionService::doRequestSubscriptionAsync(
        ClientStub &            clientStubOrig, 
        const std::string &     publisherName,
        RcfClientPtr            rcfClientPtr,
        const SubscriptionParms & parms)
    {
        RcfClientPtr requestClientPtr( new I_RcfClient("", clientStubOrig) );
        requestClientPtr->getClientStub().setTransport( clientStubOrig.releaseTransport() );
        requestClientPtr->getClientStub().setAsyncDispatcher(*mpServer);

        // Set OOB request.
        boost::uint32_t subToPubPingIntervalMs = mPingIntervalMs;
        OobRequestSubscription msg(
            clientStubOrig.getRuntimeVersion(), 
            publisherName, 
            subToPubPingIntervalMs);

        ByteBuffer controlRequest;
        msg.encodeRequest(controlRequest);
        requestClientPtr->getClientStub().setOutofBandRequest(controlRequest);

        Future<Void> fv;
        fv = requestClientPtr->getClientStub().ping( RCF::AsyncTwoway( boost::bind(
            &SubscriptionService::doRequestSubscriptionAsync_Complete,
            this,
            fv,
            requestClientPtr,
            publisherName,
            rcfClientPtr,
            parms.mOnDisconnect,
            parms.mOnAsyncSubscribeCompleted )));
    }
    boost::int32_t SubscriptionService::doRequestSubscription(
        ClientStub &            clientStubOrig, 
        const std::string &     publisherName,
        boost::uint32_t subToPubPingIntervalMs, 
        boost::uint32_t &       pubToSubPingIntervalMs,
        bool &                  pingsEnabled)
    {
        I_RcfClient client("", clientStubOrig);
        ClientStub & clientStub = client.getClientStub();
        clientStub.setTransport(clientStubOrig.releaseTransport());

        pingsEnabled = true;

        // Set OOB request.
        OobRequestSubscription msg(
            clientStubOrig.getRuntimeVersion(), 
            publisherName, 
            subToPubPingIntervalMs);

        ByteBuffer controlRequest;
        msg.encodeRequest(controlRequest);
        clientStub.setOutofBandRequest(controlRequest);

        clientStub.ping(RCF::Twoway);

        // Get OOB response.
        ByteBuffer controlResponse = clientStub.getOutOfBandResponse();
        clientStub.setOutofBandRequest(ByteBuffer());
        clientStub.setOutofBandResponse(ByteBuffer());
        msg.decodeResponse(controlResponse);

        boost::int32_t ret = msg.mResponseError;
        pubToSubPingIntervalMs = msg.mPubToSubPingIntervalMs;

        clientStubOrig.setTransport( client.getClientStub().releaseTransport() );

        return ret;
    }
    SubscriptionPtr SubscriptionService::onRequestSubscriptionCompleted(
        boost::int32_t                      ret,
        const std::string &                 publisherName,
        ClientStub &                        clientStub,
        RcfClientPtr                        rcfClientPtr,
        OnSubscriptionDisconnect            onDisconnect,
        boost::uint32_t                     pubToSubPingIntervalMs,
        bool                                pingsEnabled)
    {
        if (ret != RcfError_Ok)
        {
            RCF_THROW( Exception( Error(ret) ) );
        }

        ClientTransportAutoPtr clientTransportAutoPtr( 
                clientStub.releaseTransport() );

        ServerTransport * pTransport = NULL;
        ServerTransportEx * pTransportEx = NULL;

        pTransport = & mpServer->findTransportCompatibleWith(
            *clientTransportAutoPtr);

        pTransportEx = dynamic_cast<ServerTransportEx *>(pTransport);

        ServerTransportEx & serverTransportEx = * pTransportEx; 

        SessionPtr sessionPtr = serverTransportEx.createServerSession(
            clientTransportAutoPtr,
            StubEntryPtr(new StubEntry(rcfClientPtr)),
            true);

        RCF_ASSERT( sessionPtr );

        RcfSessionPtr rcfSessionPtr = sessionPtr;

        rcfSessionPtr->setUserData(clientStub.getUserData());
        rcfSessionPtr->setPingTimestamp();

        std::string publisherUrl;
        EndpointPtr epPtr = clientStub.getEndpoint();
        if (epPtr)
        {
            publisherUrl = epPtr->asString();
        }

        //if (!clientTransportAutoPtr->isAssociatedWithIoService())
        //{
        //    AsioServerTransport & asioTransport = dynamic_cast<AsioServerTransport &>(
        //        mpServer->getServerTransport());

        //    clientTransportAutoPtr->associateWithIoService(asioTransport.getIoService());
        //}

        SubscriptionPtr subscriptionPtr( new Subscription(
            *this,
            clientTransportAutoPtr, 
            rcfSessionPtr, 
            pubToSubPingIntervalMs, 
            publisherUrl,
            publisherName,
            onDisconnect));

        rcfSessionPtr->setOnDestroyCallback( boost::bind(
            &Subscription::onDisconnect,
            SubscriptionWeakPtr(subscriptionPtr),
            _1));

        subscriptionPtr->setWeakThisPtr(subscriptionPtr);

        subscriptionPtr->mPingsEnabled = pingsEnabled;

        Lock lock(mSubscriptionsMutex);
        mSubscriptions.insert(subscriptionPtr);

        return subscriptionPtr;                
    }