/// <summary>
 /// called when receive from the other peer offline message
 /// </summary>
 /// <param name="compactPresenceInfo">contain the presence information of the peer that send the message</param>
 void IAnnouncementBusinessLogic.OnOfflineAnnouncementReceived(CompactPresenceInfo compactPresenceInfo)
 {
     if (compactPresenceInfo is MyCompactPresenceInfo)
     {
         var info    = compactPresenceInfo as MyCompactPresenceInfo;
         var removed = false;
         MyUserUpdateState state;
         lock (syncLock)
         {
             if (MyStateDictionary.TryGetValue(info.CorrelateKey, out state))
             {
                 removed = MyStateDictionary.Remove(info.CorrelateKey);
             }
         }
         if (removed)
         {
             LogManager.GetCurrentClassLogger().Debug("peer with key: {0} and name: {1} go offline",
                                                      info.CorrelateKey, state.Name);
         }
         else
         {
             LogManager.GetCurrentClassLogger().Debug("peer with key: {0} was not found !",
                                                      info.CorrelateKey);
         }
     }
 }
 /// <summary>
 /// cleaning the MyStateDictionary
 /// </summary>
 private void ClearStateDictionary()
 {
     lock (syncLock)
     {
         MyStateDictionary.Clear();
     }
 }
        /// <summary>
        /// called when receive from the other peer online message
        /// </summary>
        /// <param name="fullPresenceInfo">contain the presence information of the peer that send the online message</param>
        void IAnnouncementBusinessLogic.OnOnlineAnnouncementReceived(FullPresenceInfo fullPresenceInfo)
        {
            if (!(fullPresenceInfo is MyFullPresenceInfo))
            {
                return;
            }

            var info = fullPresenceInfo as MyFullPresenceInfo;

            lock (syncLock)
            {
                MyUserUpdateState myUserUpdateState;
                if (!MyStateDictionary.TryGetValue(info.CorrelateKey, out myUserUpdateState))
                {
                    myUserUpdateState = new MyUserUpdateState
                    {
                        FullPresenceInfo = info
                    };
                    MyStateDictionary.Add(info.CorrelateKey, myUserUpdateState);
                }
                else
                {
                    MyStateDictionary[info.CorrelateKey].FullPresenceInfo = info;
                }
            }
        }
        /// <summary>
        /// Generate SynchronizationDetailsRequest message that will be send back to the mesh by the peer that want to synchronized itself based on given SynchronizationResponse message
        /// should override to produce application specific request
        /// </summary>
        /// <remarks>this method will invoked On sender peer based on prior SynchronizationResponse operation</remarks>
        /// <param name="synchronizationResponse">the response from the mesh</param>
        BusinessLogicMessageBase ISynchronizationBusinessLogic.ProvideSynchronizationDetailRequest(BusinessLogicMessageBase synchronizationResponse)
        {
#if DEBUG
            LogManager.GetCurrentClassLogger().Debug("ProvideSynchronizationDetailRequest: {0}", synchronizationResponse);
#endif
            var myStateResponse = synchronizationResponse as MyStateContainer;

            //full response
            if (myStateResponse != null)
            {
                UpdateState(myStateResponse.StateDictionary);
            }
            //partial keys only response
            else if (synchronizationResponse is MyKeysStateIdsContainer)
            {
                var myKeysStateResponse = synchronizationResponse as MyKeysStateIdsContainer;
                myKeysStateResponse.StateIds.SkipWhile(key => MyStateDictionary.ContainsKey(key));
                if (myKeysStateResponse.StateIds.Count > 0)
                {
                    return(myKeysStateResponse);
                }
            }

            /*
             * returning null would stop the synchronization process
             * in this case there is no need to continue the synchronization because already got the full details
             */
            return(null);
        }
        /// <summary>
        /// Generate response message that will be returned back to the mesh based on given synchronizationRequest with FullDetailedResponse set to true
        /// should override to produce application specific response
        /// </summary>
        /// <returns>BusinessLogicMessageBase instance or null if don't want to response</returns>
        BusinessLogicMessageBase ISynchronizationBusinessLogic.ProvideFullSynchronizationDetailResponse()
        {
#if DEBUG
            LogManager.GetCurrentClassLogger().Debug("ProvideFullSynchronizationDetailResponse");
#endif
            lock (syncLock)
            {
                return(new MyStateContainer
                {
                    StateDictionary = MyStateDictionary.ToDictionary(kvp => kvp.Key, kvp => kvp.Value)
                });
            }
        }
        /// <summary>
        /// Generate SynchronizationResponse message that will be returned back to the mesh based on given synchronizationRequest message
        /// should override to produce application specific response
        /// </summary>
        /// <remarks>this method will invoked On receiver peer side based on prior SynchronizationRequest operation</remarks>
        /// <param name="synchronizationRequest">the request received from the mesh</param>
        /// <returns>SynchronizationResponse instance or null if don't want to response</returns>
        BusinessLogicMessageBase ISynchronizationBusinessLogic.ProvideSynchronizationResponse(SynchronizationRequest synchronizationRequest)
        {
#if DEBUG
            LogManager.GetCurrentClassLogger().Debug("ProvideSynchronizationResponse: {0}", synchronizationRequest);
#endif
            lock (syncLock)
            {
                //return all keys
                return(new MyKeysStateIdsContainer
                {
                    StateIds = MyStateDictionary.Select(kvp => kvp.Key).ToList()
                });
            }
        }
 private void UpdateState(Dictionary <Guid, MyUserUpdateState> myUserUpdateStates)
 {
     lock (syncLock)
     {
         foreach (var kvp in myUserUpdateStates)
         {
             MyUserUpdateState value;
             if (MyStateDictionary.TryGetValue(kvp.Key, out value))
             {
                 if (value.IsOwnPeerData)
                 {
                     continue;
                 }
             }
             MyStateDictionary[kvp.Key] = kvp.Value;
         }
     }
 }