private void ShutdownPresenceView(AsyncTask task, object state)
        {
            RemotePresenceView presenceView = m_remotePresenceView;

            if (presenceView == null)
            {
                task.Complete(null);
                return;
            }
            m_remotePresenceView.PresenceNotificationReceived -= this.PresenceView_NotificationReceived;
            task.DoOneStep(
                delegate()
            {
                presenceView.BeginTerminate(
                    delegate(IAsyncResult ar)
                {
                    task.DoFinalStep(
                        delegate()
                    {
                        presenceView.EndTerminate(ar);
                    });
                },
                    null);
            });
        }
        private void Run()
        {
            // A helper class to take care of platform and endpoint setup and cleanup.
            _helper = new UCMASampleHelper();

            // Create and establish a user endpoint using the user’s network credentials.
            _userEndpoint = _helper.CreateEstablishedUserEndpoint(
                "FindContact Sample User" /* endpointFriendlyName */);

            // Register a delegate to be called when an incoming InstantMessagingCall arrives.
            _userEndpoint.RegisterForIncomingCall <InstantMessagingCall>(InstantMessagingCall_Received);

            Console.WriteLine("Waiting for an incoming instant messaging call...");
            int ThreadID = Thread.CurrentThread.ManagedThreadId;

            Console.WriteLine("Main thread: ID " + ThreadID);
            // Pause main thread until an incoming call arrives and is accepted.
            _waitUntilIncomingCallIsAccepted.WaitOne();

            InstantMessagingFlow imFlow = _instantMessagingCall.Flow;

            imFlow.BeginSendInstantMessage("Press 1 for Service Department.\n" +
                                           "Press 2 for Sales Department.", CallSendInstantMessageCB, _instantMessagingCall);
            imFlow.MessageReceived += new EventHandler <InstantMessageReceivedEventArgs>(IMFlow_MessageReceived);
            _waitForAvailableTarget.WaitOne();

            if (_remoteContactUri != null)
            {
                imFlow.BeginSendInstantMessage("Contact found: " + _remoteContactUri.ToString(), CallSendInstantMessageCB, _instantMessagingCall);
                // Join the conversation to the IM MCU.
                _conferenceSession = _incomingConversation.ConferenceSession;
                ConferenceJoinOptions confJoinOptions = new ConferenceJoinOptions();
                confJoinOptions.JoinMode = JoinMode.Default;
                _conferenceSession.BeginJoin(confJoinOptions, ConferenceJoinCB, _conferenceSession);

                ThreadID = Thread.CurrentThread.ManagedThreadId;
                Console.WriteLine("Main thread: ID " + ThreadID);
                _waitUntilConferenceInvitationIsDelivered.WaitOne();
            }
            else
            {
                Console.WriteLine("Could not find an available contact.");
                imFlow.BeginSendInstantMessage("Could not find an available contact.\nPlease call again later.", CallSendInstantMessageCB, _instantMessagingCall);
            }
            // Unregister for notification of the MessageReceived event.
            imFlow.MessageReceived -= new EventHandler <InstantMessageReceivedEventArgs>(IMFlow_MessageReceived);
            // Cancel the subscription to the presence session by unsubscribing.
            _userEndpoint.ContactGroupServices.BeginUnsubscribe(ContactGroupUnsubscribeCB, _userEndpoint.ContactGroupServices);
            _remotePresenceView.BeginTerminate(ViewTerminateCB, _remotePresenceView);
            UCMASampleHelper.PauseBeforeContinuing("Press ENTER to shut down and exit.");

            // Terminate the call, the conversation, and then unregister the
            // endpoint from receiving an incoming call. Terminating these
            // additional objects individually is made redundant by shutting down
            // the platform right after, but in the multiple call case, this is
            // needed for object hygiene. Terminating a Conversation terminates
            // all its associated calls, and terminating an endpoint
            // terminates all conversations on that endpoint.
            _instantMessagingCall.BeginTerminate(CallTerminateCB, _instantMessagingCall);
            _waitUntilConversationIsTerminated.WaitOne();
            _userEndpoint.UnregisterForIncomingCall <InstantMessagingCall>(InstantMessagingCall_Received);

            // Clean up by shutting down the platform.
            _helper.ShutdownPlatform();
        }