protected virtual void OnNSMessageReceived(object sender, NSMessageEventArgs e)
 {
     if (NSMessageReceived != null)
     {
         NSMessageReceived(sender, e);
     }
 }
        /// <summary>
        /// Handles message from the name server processor.
        /// </summary>
        /// <remarks>
        /// This is one of the most important functions of the class.
        /// It handles incoming messages and performs actions based on the commands in the messages.
        /// Many commands will affect the data objects in MSNPSharp, like <see cref="Contact"/> and <see cref="ContactGroup"/>.
        /// For example contacts are renamed, contactgroups are added and status is set.
        /// Exceptions which occur in this method are redirected via the <see cref="ExceptionOccurred"/> event.
        /// </remarks>
        /// <param name="sender">The message processor that dispatched the message.</param>
        /// <param name="e">The ns message received from the notification server</param>
        protected virtual void OnProcessorNSMessageReceivedCallback(object sender, NSMessageEventArgs e)
        {
            try
            {
                NSMessage nsMessage = e.NSMessage;

                Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "Incoming NS command: " + nsMessage.ToDebugString() + "\r\n", GetType().Name);

                if (ProcessNetworkMessage(nsMessage))
                    return;

                // Check whether it is a numeric error command
                if (nsMessage.Command[0] >= '0' && nsMessage.Command[0] <= '9')
                {
                    MSNError msnError = 0;
                    string description = string.Empty;
                    try
                    {
                        int errorCode = int.Parse(nsMessage.Command, System.Globalization.CultureInfo.InvariantCulture);
                        msnError = (MSNError)errorCode;

                        if (nsMessage.InnerBody != null && nsMessage.InnerBody.Length > 0)
                        {
                            description = Encoding.UTF8.GetString(nsMessage.InnerBody);
                        }
                        else
                        {
                            description = msnError.ToString();
                        }
                    }
                    catch (Exception fe)
                    {
                        throw new MSNPSharpException("Exception Occurred when parsing an error code received from the server", fe);
                    }

                    Trace.WriteLineIf(Settings.TraceSwitch.TraceError,
                        "A server error occurred\r\nError Code: " + nsMessage.Command
                        + "\r\nError Description: " + msnError.ToString());

                    OnServerErrorReceived(new MSNErrorEventArgs(msnError, description));
                }
                else
                {
                    // It is a unknown command
                    Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning, "UNKNOWN COMMAND: " + nsMessage.Command + "\r\n" + nsMessage.ToDebugString(), GetType().ToString());
                }
            }
            catch (Exception exc)
            {
                OnExceptionOccurred(new ExceptionEventArgs(exc));
                throw; //RethrowToPreserveStackDetails (without exc)
            }
        }
 protected virtual void OnNSMessageReceived(object sender, NSMessageEventArgs e)
 {
     if (NSMessageReceived != null)
         NSMessageReceived(sender, e);
 }