As a sort of follow-up to my post last week about remote participants and where they hide in the UCMA classes, I wanted to call out one case where the difference between the ConversationParticipant and ParticipantEndpoint classes is very important. There are a number of IP phones that have been optimized for Lync, and some of them can be tethered with a PC via a USB cable for added capabilities. Even when tethered to a PC with the Lync client running, though, these phones function as separate Lync endpoints. In other words, the user who has the phone is actually signed in to Lync from two network locations: the Lync client on the PC, and Lync Phone Edition on the phone. If you pick up a call on one of these phones, the SIP response comes from the phone itself, not from the PC, and the audio media is sent to and from the phone. The PC, sadly, is completely left out.
This is all well and good if you are working with audio calls only. But what happens if you pick up a call on your IP phone,and then the person on the other end (on a PC) adds instant messaging? The phone does not handle IMs,so the instant messaging portion of the conversation goes to the Lync client on your PC. Now you have a sort of "split" conversation, with an audio portion on the phone and an IM portion on the PC.
Now you may be wondering why this would make any difference to anybody. In most cases, it matters very little. Calls from your UCMA applications will function more or less identically whether they are handled by a PC on the other end or by a PC and an IP phone working together. But in a few cases, you might need to target something to the PC but not the phone, or to the phone but not the PC. You might be trying to target a call to the PC only, or send a context message that is meant for an application built with the Lync client API. In this case, being able to separate those two endpoints can be invaluable.
To do this on a two-party conversation, you can either look at the RemoteEndpoint property on the different Call objects that belong to the conversation, or you can get a ConversationParticipant object from Conversation.RemoteParticipants, and call the ConversationParticipant.GetEndpoints method to get all of the endpoints that represent the remote participant.
In conferences, you will see multiple endpoints in the focus or MCU that have the same base SIP URI (the user@host portion), but different GRUUs. In other words, the first part of the SIP URI will be the same, but all the other stuff after will be different. This can be quite confusing when you first see it, because normally Lync does not allow you to participate in a conference from multiple endpoints. The effect is that when you get the collection of remote participant endpoints from ConferenceSession or McuSession, you need to handle the situation where there are multiple endpoints for a single user. You can check for matching SIP URIs by looking at ParticipantEndpoint.Participant.Uri.
So, to sum up, if you expect to be handling calls from your UCMA application with users on IP phones, be on the lookout for multiple endpoints in a single conversation.
Let me know if you have questions about how this works in a specific situation.