internal extern static int PeerGetNextItem(SafeCollabEnum hPeerEnum,
                                            ref UInt32 pCount,
                                            out SafeCollabData pppvItems);
        public static PeerApplicationCollection GetLocalRegisteredApplications(PeerApplicationRegistrationType type)
        {
            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Entering GetLocalRegisteredApplications.");
            
            PeerCollaborationPermission.UnrestrictedPeerCollaborationPermission.Demand();

            if ((type < PeerApplicationRegistrationType.CurrentUser) || (type > PeerApplicationRegistrationType.AllUsers)){
                throw new ArgumentOutOfRangeException("type");
            }

            CollaborationHelperFunctions.Initialize();

            PeerApplicationCollection peerAppColl = new PeerApplicationCollection();
            SafeCollabEnum handlePeerEnum = new SafeCollabEnum();
            UInt32 appCount = 0;
            int errorCode = 0;

            //
            // Enumerate and get all the registered applications from native
            //

            try{
                errorCode = UnsafeCollabNativeMethods.PeerCollabEnumApplications(IntPtr.Zero, IntPtr.Zero, out handlePeerEnum);
                if (errorCode != 0){
                    Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabEnumApplications returned with errorcode {0}", errorCode);
                    throw (PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetLocalAppsFailed), errorCode));
                }

                errorCode = UnsafeCollabNativeMethods.PeerGetItemCount(handlePeerEnum, ref appCount);
                if (errorCode != 0){
                    Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerGetItemCount returned with errorcode {0}", errorCode);
                    throw (PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetLocalAppsFailed), errorCode));
                }

                if (appCount == 0){
                    Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "No local registered PeerApplications found.");
                    return peerAppColl;
                }

                unsafe{
                    SafeCollabData appArray = null;
                    try{
                        errorCode = UnsafeCollabNativeMethods.PeerGetNextItem(handlePeerEnum, ref appCount, out appArray);
                        if (errorCode != 0){
                            Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerGetNextItem returned with errorcode {0}", errorCode);
                            throw (PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_GetLocalAppsFailed), errorCode));
                        }

                        //
                        // Marshal each application from the array
                        //

                        IntPtr pPEER_APLICATION = appArray.DangerousGetHandle();
                        IntPtr* pApps = (IntPtr*)pPEER_APLICATION;
                        for (ulong i = 0; i < appCount; i++){
                            PEER_APPLICATION* pPeerApp = (PEER_APPLICATION*)pApps[i];
                            string description = Marshal.PtrToStringUni(pPeerApp->pwzDescription);
                            byte[] data = null;

                            if (pPeerApp->data.cbData != 0){
                                data = new byte[pPeerApp->data.cbData];
                                Marshal.Copy(pPeerApp->data.pbData, data, 0, (int)pPeerApp->data.cbData);
                            }

                            PeerApplication peerApp = new PeerApplication(  CollaborationHelperFunctions.ConvertGUIDToGuid(pPeerApp->guid), 
                                                                            description, data, null, null, PeerScope.None);
                            peerAppColl.Add(peerApp);
                        }
                    }
                    finally{
                        appArray.Dispose();
                    }
                }
            }
            finally{
                handlePeerEnum.Dispose();
            }

            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Got all local registered Applications. Start filtering");

            PeerApplicationCollection peerAppCollFiltered = new PeerApplicationCollection();

            //
            // Filter the apps according to the Registration type the user wants
            //

            foreach (PeerApplication peerApplication in peerAppColl)
            {
                GUID guid = CollaborationHelperFunctions.ConvertGuidToGUID(peerApplication.Id);
                SafeCollabData safeAppRegInfo = new SafeCollabData();

                try{
                    errorCode = UnsafeCollabNativeMethods.PeerCollabGetApplicationRegistrationInfo(ref guid,
                                                                                                    type,
                                                                                                    out safeAppRegInfo);
                    if (errorCode != 0)
                        Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabGetApplicationRegistrationInfo returned with errorcode {0}", errorCode);

                    if (!safeAppRegInfo.IsInvalid){
                        PEER_APPLICATION_REGISTRATION_INFO pari = (PEER_APPLICATION_REGISTRATION_INFO)
                                                                Marshal.PtrToStructure(safeAppRegInfo.DangerousGetHandle(),
                                                                                        typeof(PEER_APPLICATION_REGISTRATION_INFO));
                        peerApplication.Path = pari.pwzApplicationToLaunch;
                        peerApplication.CommandLineArgs = pari.pwzApplicationArguments;
                        peerApplication.PeerScope = (PeerScope)pari.dwPublicationScope;
                        
                        peerAppCollFiltered.Add(peerApplication);
                    }
                }
                finally{
                    safeAppRegInfo.Dispose();
                }

            }
            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Filtering successful. Returning collection with {0} applications", peerAppCollFiltered.Count);

            return peerAppCollFiltered;
        }
 internal extern static int PeerCollabEnumContacts(out SafeCollabEnum phPeerEnum);
 internal extern static int PeerGetItemCount(SafeCollabEnum hPeerEnum, ref UInt32 pCount);
 internal extern static int PeerCollabEnumPeopleNearMe(out SafeCollabEnum phPeerEnum);
 internal extern static int PeerCollabEnumEndpoints(ref PEER_CONTACT pcContact,
                                                    out SafeCollabEnum phPeerEnum);
 internal extern static int PeerGetNextItem(SafeCollabEnum hPeerEnum,
                                             ref UInt32 pCount,
                                             out SafeCollabData pppvItems);
 internal extern static int PeerCollabEnumApplications(IntPtr pcEndpoint,
                                                       IntPtr pObjectId,
                                                       out SafeCollabEnum phPeerEnum);
 internal extern static int PeerGetItemCount(SafeCollabEnum hPeerEnum, ref UInt32 pCount);
 internal extern static int PeerCollabEnumContacts(out SafeCollabEnum phPeerEnum);
 internal extern static int PeerCollabEnumEndpoints(ref PEER_CONTACT pcContact,
                                         out SafeCollabEnum phPeerEnum);
 internal extern static int PeerCollabEnumPeopleNearMe(out SafeCollabEnum phPeerEnum);
 internal extern static int PeerCollabEnumApplications( IntPtr pcEndpoint,
                                                         IntPtr pObjectId,
                                                         out SafeCollabEnum phPeerEnum);