private void CheckRoster() { SortedDictionary <string, TreeNode> Contacts = this.children; Dictionary <string, TreeNode> Existing = new Dictionary <string, TreeNode>(); LinkedList <TreeNode> Added = null; LinkedList <KeyValuePair <string, TreeNode> > Removed = null; LinkedList <RosterItem> Resubscribe = null; LinkedList <RosterItem> Reunsubscribe = null; if (Contacts == null) { Contacts = new SortedDictionary <string, TreeNode>(); } lock (Contacts) { foreach (RosterItem Item in this.client.Roster) { if (Contacts.TryGetValue(Item.BareJid, out TreeNode Contact)) { Existing[Item.BareJid] = Contact; } else { if (Item.IsInGroup(ConcentratorGroupName)) { Contact = new XmppConcentrator(this, this.client, Item.BareJid, Item.IsInGroup(EventsGroupName)); } else if (Item.IsInGroup(ActuatorGroupName)) { Contact = new XmppActuator(this, this.client, Item.BareJid, Item.IsInGroup(SensorGroupName), Item.IsInGroup(EventsGroupName)); } else if (Item.IsInGroup(SensorGroupName)) { Contact = new XmppSensor(this, this.client, Item.BareJid, Item.IsInGroup(EventsGroupName)); } else if (Item.IsInGroup(OtherGroupName)) { Contact = new XmppOther(this, this.client, Item.BareJid); } else { Contact = new XmppContact(this, this.client, Item.BareJid); } Contacts[Item.BareJid] = Contact; if (Added == null) { Added = new LinkedList <TreeNode>(); } Added.AddLast(Contact); } switch (Item.PendingSubscription) { case PendingSubscription.Subscribe: if (Resubscribe == null) { Resubscribe = new LinkedList <RosterItem>(); } Resubscribe.AddLast(Item); break; case PendingSubscription.Unsubscribe: if (Reunsubscribe == null) { Reunsubscribe = new LinkedList <RosterItem>(); } Reunsubscribe.AddLast(Item); break; } } if (this.children == null) { this.children = Contacts; } else { foreach (KeyValuePair <string, TreeNode> P in this.children) { if (P.Value is XmppContact Contact && !Existing.ContainsKey(Contact.BareJID)) { if (Removed == null) { Removed = new LinkedList <KeyValuePair <string, TreeNode> >(); } Removed.AddLast(P); } } if (Removed != null) { foreach (KeyValuePair <string, TreeNode> P in Removed) { this.children.Remove(P.Key); } } } } if (Added != null) { foreach (TreeNode Node in Added) { this.connections.Owner.MainView.NodeAdded(this, Node); } } if (Removed != null) { foreach (KeyValuePair <string, TreeNode> P in Removed) { this.connections.Owner.MainView.NodeRemoved(this, P.Value); } } if (Resubscribe != null) { foreach (RosterItem Item in Resubscribe) { this.client.RequestPresenceSubscription(Item.BareJid); } } if (Reunsubscribe != null) { foreach (RosterItem Item in Reunsubscribe) { this.client.RequestPresenceUnsubscription(Item.BareJid); } } this.OnUpdated(); }