示例#1
0
 public static string GetPresenceDisplay(Presence presence)
 {
     if (presence.Type == PresenceType.available) {
         if (!String.IsNullOrEmpty(presence.Show)) {
             switch (presence.Show) {
                 case "away":
                     return "away";
                 case "chat":
                     return "free to chat";
                 case "dnd":
                     return "do not disturb";
                 case "xa":
                     return "extended away";
                 case "subscribed":
                     return "subscribed";
                 default:
                     return presence.Show;
             }
         } else {
             return "available";
         }
     } else if (presence.Type == PresenceType.unavailable) {
         return "offline";
     } else {
         throw new ArgumentException("presence type not supported: " + presence.Type);
     }
 }
示例#2
0
 public void Test_Create()
 {
     Presence p = new Presence(doc);
     p.Type   = PresenceType.available;
     p.Status = "foo";
     Assert.AreEqual("<presence><status>foo</status></presence>", p.ToString());
 }
		static void Main(string[] args)
		{
			var presence = new Presence("clusters/commerce", new Dictionary<string, string>
			{
				{"RavenDB-Url", new UriBuilder("http", Environment.MachineName, 8080).Uri.ToString()}
			}, TimeSpan.FromSeconds(3));
			presence.TopologyChanged += (sender, nodeMetadata) =>
			{
				switch (nodeMetadata.ChangeType)
				{
					case TopologyChangeType.MasterSelected:
						Console.WriteLine("Master selected {0}", nodeMetadata.Uri);
						break;
					case TopologyChangeType.Discovered:
						Console.WriteLine("Found {0}", nodeMetadata.Uri);
						break;
					case TopologyChangeType.Gone:
						Console.WriteLine("Oh no, {0} is gone!", nodeMetadata.Uri);
						break;
					default:
						throw new ArgumentOutOfRangeException();
				}
			};
			presence.Start();
			Console.WriteLine(presence.Address);
			Console.WriteLine("Waiting...");
			Console.ReadLine();
		}
		public Acceptor(Presence presence, Uri originatorUri, Uri[] learners) : base(presence)
		{
			this.originatorUri = originatorUri;
			this.learners = learners;
			Register<Propose>(OnPropose);
			Register<Accept>(OnAccept);
		}
 static ContactsNotificationService()
 {
     ContactsNotificationService.OfflinePresence = new Presence()
     {
         PresenceType = PresenceType.Offline
     };
     ContactsNotificationService.Contacts = new ConcurrentDictionary<string, ContactsNotificationService.JsFederatedDude>();
 }
 public void TestUserHost()
 {
     PresenceManager pp = new PresenceManager();
     Presence pres = new Presence(doc);
     JID f = new JID("foo", "bar", null);
     pres.From = f;
     pp.AddPresence(pres);
     Assert.AreEqual("foo@bar", pp[f.Bare].From.ToString());
 }
示例#7
0
        public Pet(StatsDK dkstats, DeathKnightTalents t, BossOptions bo, Presence p)
        {
            m_BO = bo;
            m_DKStats = dkstats;
            m_Talents = t;
            m_Presence = p;

            AccumulateStats();
        }
示例#8
0
 public static string GetResourceDisplay(Presence presence)
 {
     if (presence["ResourceDisplay"] != null && !String.IsNullOrEmpty(presence["ResourceDisplay"].InnerText))
         return presence["ResourceDisplay"].InnerText;
     else if (!String.IsNullOrEmpty(presence.From.Resource))
         return presence.From.Resource;
     else
         return "Unknown";
 }
示例#9
0
 internal InputArg(InputArgType type, string name, object defaultValue, Presence presence, string helpString)
 {
     HasBeenSeen = false;
     Type = type;
     Name = name;
     Value = defaultValue;
     Presence = presence;
     HelpString = helpString;
     HasBeenSeen = false;                
 }
示例#10
0
 public void Test_Available()
 {
     Presence p = new Presence(doc);
     Assert.AreEqual(PresenceType.available, p.Type);
     Assert.AreEqual("", p.GetAttribute("type"));
     p.Type = PresenceType.unavailable;
     Assert.AreEqual(PresenceType.unavailable, p.Type);
     Assert.AreEqual("unavailable", p.GetAttribute("type"));
     p.Type = PresenceType.available;
     Assert.AreEqual(PresenceType.available, p.Type);
     Assert.AreEqual("", p.GetAttribute("type"));
 }
		public Proposer(Presence presence, Acceptor myAcceptor, Uri orignatorUri, Uri[] allAcceptors) : base(presence)
		{
			this.myAcceptor = myAcceptor;
			this.orignatorUri = orignatorUri;
			this.allAcceptors = allAcceptors;

			ballotBase = base.GetHashCode()%25; // effectively a random choice

			Register<Promise>(OnPromise);
			Register<ProposalSubsumed>(OnProposalSubsumed);
			Register<Accepted>(OnAccepted);
		}
 public Encoding()
 {
     _primitiveType = null;
     _presence = Presence.Required;
     _byteOrder = ByteOrder.LittleEndian;
     _minValue = null;
     _maxValue = null;
     _nullValue = null;
     _constValue = null;
     _characterEncoding = null;
     _epoch = null;
     _timeUnit = null;
     _semanticType = null;
 }
        public Encoding(PrimitiveType primitiveType, Presence presence, ByteOrder byteOrder, PrimitiveValue minValue, PrimitiveValue maxValue, PrimitiveValue nullValue, PrimitiveValue constValue, string characterEncoding, string epoch, string timeUnit, string semanticType)
        {
            Verify.NotNull(presence, "presence");
            Verify.NotNull(byteOrder, "byteOrder");

            _primitiveType = primitiveType;
            _presence = presence;
            _byteOrder = byteOrder;
            _minValue = minValue;
            _maxValue = maxValue;
            _nullValue = nullValue;
            _constValue = constValue;
            _characterEncoding = characterEncoding;
            _epoch = epoch;
            _timeUnit = timeUnit;
            _semanticType = semanticType;
        }
示例#14
0
        public void TestAdd()
        {
            PresenceManager pp = new PresenceManager();
            Presence pres = new Presence(doc);
            JID f = new JID("foo", "bar", "baz");
            pres.From = f;
            pp.AddPresence(pres);
            Assert.AreEqual("foo@bar/baz", pp[f].From.ToString());
            f.Resource = null;
            Assert.AreEqual("foo@bar/baz", pp[f].From.ToString());

            pres = new Presence(doc);
            pres.Status = "wandering";
            pres.From = new JID("foo", "bar", "baz");
            pp.AddPresence(pres);
            Assert.AreEqual("wandering", pp[f].Status);
        }
示例#15
0
        /// <summary>
        /// Определение статуса юзера.
        /// </summary>
        /// <param name="pres"></param>
        public void SetOnlineStateFromPresence(Presence pres)
        {
            if (pres.Type == Matrix.Xmpp.PresenceType.unavailable)
                StatusOnline = Model.StatusOnline.Offline;

            if (pres.Type == Matrix.Xmpp.PresenceType.available)
            {
                if (pres.Show == Matrix.Xmpp.Show.chat)
                    StatusOnline = Model.StatusOnline.Chat;
                else if (pres.Show == Matrix.Xmpp.Show.away)
                    StatusOnline = Model.StatusOnline.Away;
                else if (pres.Show == Matrix.Xmpp.Show.xa)
                    StatusOnline = Model.StatusOnline.ExtendedAway;
                else if (pres.Show == Matrix.Xmpp.Show.dnd)
                    StatusOnline = Model.StatusOnline.DoNotDisturb;
                else if (pres.Show == Matrix.Xmpp.Show.NONE)
                    StatusOnline = Model.StatusOnline.Online;
                else
                    StatusOnline = Model.StatusOnline.Online;
            }

            //определяем в зависимости от статуса, какую иконку статуса отображать
            switch (StatusOnline)
            {
                case StatusOnline.Online:
                    ImageStatus = @"ContactListSettings/StatusImage/online.png";
                    break;
                case StatusOnline.Offline:
                    ImageStatus = @"ContactListSettings/StatusImage/offline.png";
                    break;
                case StatusOnline.Away:
                    ImageStatus = @"ContactListSettings/StatusImage/away.png";
                    break;
                case StatusOnline.ExtendedAway:
                    ImageStatus = @"ContactListSettings/StatusImage/extendedAway.png";
                    break;
                case StatusOnline.DoNotDisturb:
                    ImageStatus = @"ContactListSettings/StatusImage/doNotDisturb.png";
                    break;
                case StatusOnline.Chat:
                    ImageStatus = @"ContactListSettings/StatusImage/chat.png";
                    break;
            }
        }
示例#16
0
文件: Util.cs 项目: aile54/chatclient
        public static int GetRosterImageIndex(Presence pres)
        {
            if (pres.Type == PresenceType.Unavailable)
                return 0;

            switch (pres.Show)
            {
                case Show.Chat:
                    return 1;
                case Show.Away:
                    return 2;
                case Show.ExtendedAway:
                    return 2;
                case Show.DoNotDisturb:
                    return 3;
                default:
                    return 1;
            }
        }
示例#17
0
文件: Util.cs 项目: uri247/lib
        public static int GetRosterImageIndex(Presence pres)
        {
            if (pres.Type == PresenceType.unavailable)
                return 0;

            switch (pres.Show)
            {
                case Show.chat:
                    return 1;
                case Show.away:
                    return 2;
                case Show.xa:
                    return 2;
                case Show.dnd:
                    return 3;
                default:
                    return 1;
            }
        }
示例#18
0
        public void TestRetrieve()
        {
            PresenceManager pp = new PresenceManager();
            Presence pres = new Presence(doc);
            JID f = new JID("foo", "bar", "baz");
            pres.From = f;
            pres.Priority = "0";
            pp.AddPresence(pres);
            Assert.AreEqual("foo@bar/baz", pp[f.Bare].From.ToString());

            pres = new Presence(doc);
            f = new JID("foo", "bar", "bay");
            pres.From = f;
            pres.Priority = "1";
            pp.AddPresence(pres);
            Assert.AreEqual("foo@bar/bay", pp[f.Bare].From.ToString());

            pres = new Presence(doc);
            pres.From = f;
            pres.Type = PresenceType.unavailable;
            pp.AddPresence(pres);
            Assert.AreEqual("foo@bar/baz", pp[f.Bare].From.ToString());
        }
示例#19
0
        public void Test_Order()
        {
            Presence small = new Presence(doc);
            DateTime d = DateTime.Now;
            small.IntPriority = 0;
            small.Stamp = d;

            Presence big = new Presence(doc);
            big.IntPriority = 10;
            big.Stamp = d.AddSeconds(1);

            Assert.IsTrue(small < big);
            Assert.IsTrue(big > small);

            small.IntPriority = 10;
            small.Show = "dnd";
            Assert.IsTrue(small < big);

            big.Show = "chat";
            Assert.IsTrue(small < big);

            small.Show = "chat";
            Assert.IsTrue(small < big);
        }
示例#20
0
        public static int GetRosterImageIndex(Presence pres)
        {
            if ((pres.get_Type() != 4) && (pres.get_Type() != 6))
            {
                switch (pres.get_Show())
                {
                    case -1:
                        return 1;

                    case 0:
                        return 2;

                    case 1:
                        return 4;

                    case 2:
                        return 5;

                    case 3:
                        return 3;
                }
            }
            return 0;
        }
示例#21
0
 private void rm_OnUnsubscription(jabber.client.RosterManager manager, Presence pres, ref bool remove)
 {
     MessageBox.Show(pres.From + " has removed you from their roster.", "Unsubscription notification", MessageBoxButtons.OK);
 }
示例#22
0
 private void rm_OnSubscription(jabber.client.RosterManager manager, Item ri, Presence pres)
 {
     DialogResult res = MessageBox.Show("Allow incoming presence subscription request from: " + pres.From,
         "Subscription Request",
         MessageBoxButtons.YesNoCancel);
     switch (res)
     {
     case DialogResult.Yes:
         manager.ReplyAllow(pres);
         break;
     case DialogResult.No:
         manager.ReplyDeny(pres);
         break;
     case DialogResult.Cancel:
         // do nothing;
         break;
     }
 }
示例#23
0
 private void muc_OnPresenceError(Room room, Presence pres)
 {
     m_err = true;
     pnlCon.Text = "Groupchat error: " + pres.Error.OuterXml;
 }
示例#24
0
 /// <summary>
 /// Denies the subscription request.
 /// </summary>
 /// <param name="pres">
 /// The presence packet containing the subscription request.
 /// </param>
 public void ReplyDeny(Presence pres)
 {
     Debug.Assert(pres.Type == PresenceType.subscribe);
     Presence reply = new Presence(m_stream.Document);
     reply.To = pres.From;
     reply.Type = PresenceType.unsubscribed;
     m_stream.Write(reply);
 }
示例#25
0
        /// <summary>
        /// Allows the subscription request and sends a subscribed to the user.
        /// </summary>
        /// <param name="pres">
        /// The presence packet containing the subscription request.
        /// </param>
        public void ReplyAllow(Presence pres)
        {
            Debug.Assert(pres.Type == PresenceType.subscribe);
            Presence reply = new Presence(m_stream.Document);
            reply.To = pres.From;
            reply.Type = PresenceType.subscribed;
            m_stream.Write(reply);

            if (m_autoSubscribe)
            {
                Presence sub = new Presence(m_stream.Document);
                sub.To = pres.From;
                sub.Type = PresenceType.subscribe;
                m_stream.Write(sub);
            }
        }
示例#26
0
        // Retrieve the friend's connected S2 node address. Returns null if not found
        public string searchForRelay()
        {
            string ip = null;

            byte[]   wallet   = null;
            Presence presence = PresenceList.containsWalletAddress(walletAddress);

            if (presence == null)
            {
                return(ip);
            }

            lock (PresenceList.presences)
            {
                // Go through each presence address searching for C nodes
                foreach (PresenceAddress addr in presence.addresses)
                {
                    // Only check Client nodes
                    if (addr.type == 'C')
                    {
                        // We have a potential candidate here, store it
                        string candidate_ip = addr.address;

                        // Go through each presence again. This should be more optimized.
                        foreach (Presence s2presence in PresenceList.presences)
                        {
                            // Go through each single address
                            foreach (PresenceAddress s2addr in s2presence.addresses)
                            {
                                // Only check Relay nodes that have the candidate ip
                                if (s2addr.type == 'R' && s2addr.address.Equals(candidate_ip, StringComparison.Ordinal))
                                {
                                    // We found the friend's connected s2 node
                                    ip     = s2addr.address;
                                    wallet = s2presence.wallet;
                                    break;
                                }
                            }
                        }
                    }
                    else
                    // Check for R nodes for testing purposes
                    if (addr.type == 'R')
                    {
                        ip     = addr.address;
                        wallet = presence.wallet;
                    }

                    // If we find a valid node ip, don't continue searching
                    if (ip != null)
                    {
                        break;
                    }
                }
            }

            // Store the last relay ip and wallet for this friend
            relayIP     = ip;
            relayWallet = wallet;

            // Finally, return the ip address of the node
            return(relayIP);
        }
示例#27
0
        /// <summary>
        /// Sends a presence subscription request and updates the roster
        /// for a new roster contact.
        /// </summary>
        /// <param name="to">The JID of the contact (required)</param>
        /// <param name="nickname">The nickname to show for the contact.</param>
        /// <param name="groups">A list of groups to put the contact in.  May be null.  Hint: new string[] {"foo", "bar"}</param>
        public void Subscribe(JID to, string nickname, string[] groups)
        {
            Debug.Assert(to != null);

            RosterIQ riq = new RosterIQ(Document) {Type = IQType.Set};
            Roster r = riq.Instruction;
            Item i = r.AddItem();
            i.JID = to;
            if (nickname != null)
                i.Nickname = nickname;
            if (groups != null)
            {
                foreach (string g in groups)
                    i.AddGroup(g);
            }
            Write(riq); // don't care about result.  we should get a iq/response and a roster push.

            Presence pres = new Presence(Document) {To = to, Type = PresenceType.subscribe};
            Write(pres);
        }
示例#28
0
 public HandleUpdate(Presence presence) => Presence = presence;
示例#29
0
 public void EmitPresence(Action <PresenceResponse> callback, Presence status)
 {
     APIRequestWithToken(callback, new Tuple <string, string>("presence", status.ToString()));
 }
示例#30
0
 private void rm_OnSubscription(RosterManager manager, Item ri, Presence pres)
 {
     manager.ReplyAllow(pres);
     OnMessage("WMSMLC", string.Format("Пользовтель {0} добавился в список контактов", pres.From));
 }
示例#31
0
 private void rm_OnUnsubscription(RosterManager manager, Presence pres, ref bool remove)
 {
     OnMessage("WMSMLC", string.Format("Пользовтель {0} удалился из списока контактов", pres.From));
 }
示例#32
0
 /// <summary>
 /// Closes down the connection.
 /// </summary>
 public override void Close()
 {
     if (IsAuthenticated)
     {
         Presence p = new Presence(Document) {Type = PresenceType.unavailable, Status = "offline"};
         Write(p);
     }
     base.Close();
 }
示例#33
0
        /// <summary>
        /// Sends a presence packet to the XMPP server.
        /// </summary>
        /// <param name="t">The type of presence.</param>
        /// <param name="status">Determines the status of the presence.</param>
        /// <param name="show">Shows the available, away, dnd and so on status.</param>
        /// <param name="priority">Prioritizes this connection.
        /// Higher number mean higher priority. 0 minumum, 127 max.
        /// -1 means this is a presence-only connection.</param>
        public void Presence(PresenceType t, string status, string show, int priority)
        {
            if (IsAuthenticated)
            {
                if ((priority < -128) || (priority > 127))
                {
                    throw new ArgumentException("Priority must be -128 to 127", "priority");
                }

                Presence p = new Presence(Document);
                if (status != null)
                    p.Status = status;
                if (t != PresenceType.available)
                {
                    p.Type = t;
                }
                if (show != null)
                    p.Show = show;
                p.Priority = priority.ToString();

                if (OnBeforePresenceOut != null)
                    OnBeforePresenceOut(this, p);
                Write(p);
                if (OnAfterPresenceOut != null)
                    OnAfterPresenceOut(this, p);
            }
            else
            {
                throw new InvalidOperationException("Client must be authenticated before sending presence.");
            }
        }
示例#34
0
        /// <summary>
        /// Exits the room.  This cleans up the entry in the ConferenceManager, as well.
        /// </summary>
        /// <param name="reason">Reason for leaving the room.  May be null for no reason.</param>
        public void Leave(string reason)
        {
            m_state = STATE.leaving;

            /*
            <presence
                to='[email protected]/oldhag'
                type='unavailable'>
              <status>gone where the goblins go</status>
            </presence>
             */
            Presence p = new Presence(m_manager.Stream.Document);
            p.To = m_jid;
            p.Type = PresenceType.unavailable;
            if (reason != null)
                p.Status = reason;
            m_manager.Write(p);


            // cleanup done when unavailable/110 received.
        }
示例#35
0
        public XmppWebSocketConnection(JID jid, string password, string websocketUri)
            : base(jid, password)
        {
            Capabilities = new CapabilitiesManager
            {
                Identity = new Identity
                {
                    Category     = "client",
                    IdentityType = "mobile",
                    IdentityName = "SharpXMPP"
                },

                Node     = "http://bggg.net.ru/caps",
                Features = new List <string>
                {
                    Namespaces.DiscoInfo,
                    Namespaces.DiscoItems
                }
            };
            IqTracker = new XMPP.Client.IqHandler(this)
            {
                ResponseHandlers = new Dictionary <string, ResponseHandler>(),
                PayloadHandlers  = new List <PayloadHandler>
                {
                    new InfoHandler(Capabilities),
                    new ItemsHandler()
                }
            };
            Iq += (sender, iq) => IqTracker.Handle(iq);
// ReSharper disable RedundantArgumentDefaultValue
            _connection = new WebSocket(websocketUri, "xmpp", cookies: (List <KeyValuePair <string, string> >)null);
// ReSharper restore RedundantArgumentDefaultValue
            _connection.Opened += (sender, args) =>

            {
                _currentState = XmppConnectionState.Connected;
                RestartStream();
            };
            _connection.MessageReceived += (sender, args) =>
            {
                if (_currentState == XmppConnectionState.Connected)
                {
                    ReadStreamStart(args.Message);
                    _currentState = XmppConnectionState.StreamInitiated;
                }
                else if (_currentState == XmppConnectionState.StreamAuthenticated)
                {
                    ReadStreamStart(args.Message);
                    _currentState =
                        XmppConnectionState.StreamResourceBindingRequest;
                }
                else
                {
                    var currentStanza = Stanza.Parse(args.Message);
                    OnElement(new ElementArgs
                    {
                        IsInput = false,
                        Stanza  = currentStanza
                    });
                    var error = Stanza.Parse <StreamError>(currentStanza);
                    if (error != null)
                    {
                        OnConnectionFailed(new ConnFailedArgs {
                            Message = error.Value
                        });
                        return;
                    }
                    switch (_currentState)
                    {
                    case XmppConnectionState.StreamInitiated:

                        var features = Stanza.Parse <Features>(currentStanza);

                        authenticator = SASLHandler.Create(features.SaslMechanisms,
                                                           Jid, Password);
                        if (authenticator == null)
                        {
                            OnConnectionFailed(new ConnFailedArgs
                            {
                                Message =
                                    "supported sasl mechanism not available"
                            });
                            return;
                        }
                        var auth = new SASLAuth();
                        auth.SetAttributeValue("mechanism", authenticator.SASLMethod);
                        var authInit = authenticator.Initiate();
                        if (!string.IsNullOrEmpty(authInit))
                        {
                            auth.SetValue(authInit);
                        }
                        Send(auth);
                        _currentState = XmppConnectionState.StreamAuthenticating;
                        break;

                    case XmppConnectionState.StreamAuthenticating:
                        switch (currentStanza.Name.LocalName)
                        {
                        case "success":
                            _currentState =
                                XmppConnectionState.StreamAuthenticated;
                            RestartStream();
                            break;

                        case "failure":
                            OnConnectionFailed(new ConnFailedArgs
                            {
                                Message =
                                    currentStanza.Value
                            });
                            _currentState = XmppConnectionState.Disconnected;
                            return;

                        case "challenge":
                            var response = new SASLResponse();
                            response.SetValue(
                                authenticator.NextChallenge(currentStanza.Value));
                            Send(response);
                            break;
                        }
                        break;

                    case XmppConnectionState.StreamResourceBindingRequest:
                        // todo: parse features of negotiated stream
                        //Stanza.Parse<Features>(currentStanza);
                        var bind = new Bind(Jid.Resource);
                        var iq   = new Iq(XMPP.Client.Elements.Iq.IqTypes.set);
                        iq.Add(bind);
                        Send(iq);
                        _currentState =
                            XmppConnectionState.StreamResourceBindingResponse;
                        break;

                    case XmppConnectionState.StreamResourceBindingResponse:
                        var bindedJid =
                            currentStanza.Element(
                                XNamespace.Get(Namespaces.XmppBind) +
                                "bind");
                        if (bindedJid == null)
                        {
                            OnConnectionFailed(new ConnFailedArgs
                            {
                                Message =
                                    "bind failed"
                            });
                            _currentState = XmppConnectionState.Disconnected;
                        }
                        else
                        {
                            var sess =
                                new XElement(
                                    XNamespace.Get(Namespaces.XmppSession) +
                                    "session");
                            var sessIq = new Iq(XMPP.Client.Elements.Iq.IqTypes.set);
                            sessIq.Add(sess);
                            Send(sessIq);
                            _currentState = XmppConnectionState.StreamSessionNoOp;
                            Jid           =
                                new JID(
                                    bindedJid.Element(
                                        XNamespace.Get(Namespaces.XmppBind) + "jid")
                                    .Value);
                        }
                        break;

                    case XmppConnectionState.StreamSessionNoOp:
                        OnSignedIn(new SignedInArgs {
                            Jid = Jid
                        });
                        Roster.Query(this);
                        var initPresence = new Presence(Capabilities);
                        Send(initPresence);
                        _currentState = XmppConnectionState.StreamNegotiated;
                        break;

                    case XmppConnectionState.StreamNegotiated:
                        if (currentStanza.Name.LocalName.Equals("iq"))
                        {
                            OnIq(Stanza.Parse <Iq>(currentStanza));
                        }
                        if (currentStanza.Name.LocalName.Equals("message"))
                        {
                            OnMessage(Stanza.Parse <Message>(currentStanza));
                        }
                        break;

                    default:
                        throw new IOException("Invalid state");
                    }
                }
            };
        }
示例#36
0
        private void cli_OnPresence(object sender, Presence pres)
        {
            PresenceType typ = pres.Type;
            switch (typ)
            {
            case PresenceType.available:
            case PresenceType.unavailable:
            case PresenceType.error:
            case PresenceType.probe:
                return;
            case PresenceType.subscribe:
                switch (m_autoAllow)
                {
                case AutoSubscriptionHanding.AllowAll:
                    ReplyAllow(pres);
                    return;
                case AutoSubscriptionHanding.DenyAll:
                    ReplyDeny(pres);
                    return;
                case AutoSubscriptionHanding.NONE:
                    if (OnSubscription != null)
                        OnSubscription(this, this[pres.From], pres);
                    return;
                case AutoSubscriptionHanding.AllowIfSubscribed:
                    Item ri = this[pres.From];
                    if (ri != null)
                    {
                        switch (ri.Subscription)
                        {
                        case Subscription.to:
                            ReplyAllow(pres);
                            return;
                        case Subscription.from:
                        case Subscription.both:
                            // Almost an assert
                            throw new InvalidOperationException("Server sent a presence subscribe for an already-subscribed contact");
                        case Subscription.none:
                            if (ri.Ask == Ask.subscribe)
                            {
                                ReplyAllow(pres);
                                return;
                            }
                            break;
                        }
                    }
                    if (OnSubscription != null)
                        OnSubscription(this, ri, pres);
                    break;
                }
                break;
            case PresenceType.subscribed:
                // This is the new ack case.
                Presence sub_ack = new Presence(m_stream.Document);
                sub_ack.To = pres.From;
                sub_ack.Type = PresenceType.subscribe;
                m_stream.Write(sub_ack);                
                break;
            case PresenceType.unsubscribe:
                // ack.  we'll likely get an unsubscribed soon, anyway.
                Presence un_ack = new Presence(m_stream.Document);
                un_ack.To = pres.From;
                un_ack.Type = PresenceType.unsubscribed;
                m_stream.Write(un_ack);
                break;
            case PresenceType.unsubscribed:
                bool remove = true;
                if (OnUnsubscription != null)
                    OnUnsubscription(this, pres, ref remove);

                if (remove)
                    Remove(pres.From);
                break;
            }
        }