//
        // Converts Guid class to GUID structure that we can pass into native
        //
        internal static GUID ConvertGuidToGUID(Guid guid)
        {
            GUID newGuid = new GUID();

            if (guid != null){
                byte[] guidBytes = guid.ToByteArray();
                string guidString = guid.ToString();

                int startVal = 0;
                int endVal = guidString.IndexOf('-');
                newGuid.data1 = (uint)(Convert.ToUInt32(guidString.Substring(startVal, endVal - startVal), 16));
                startVal = endVal + 1;
                endVal = guidString.IndexOf('-', endVal + 1);
                newGuid.data2 = (ushort)(Convert.ToUInt16(guidString.Substring(startVal, endVal - startVal), 16));
                startVal = endVal + 1;
                endVal = guidString.IndexOf('-', endVal + 1);
                newGuid.data3 = (ushort)(Convert.ToUInt16(guidString.Substring(startVal, endVal - startVal), 16));
                newGuid.data4 = guidBytes[8];
                newGuid.data5 = guidBytes[9];
                newGuid.data6 = guidBytes[10];
                newGuid.data7 = guidBytes[11];
                newGuid.data8 = guidBytes[12];
                newGuid.data9 = guidBytes[13];
                newGuid.data10 = guidBytes[14];
                newGuid.data11 = guidBytes[15];
            }
            return newGuid;
        }
        //
        // Converts native GUID structure to managed Guid class
        //
        internal static Guid ConvertGUIDToGuid(GUID guid)
        {
            byte[] bytes = new byte[8];
            bytes[0] = guid.data4;
            bytes[1] = guid.data5;
            bytes[2] = guid.data6;
            bytes[3] = guid.data7;
            bytes[4] = guid.data8;
            bytes[5] = guid.data9;
            bytes[6] = guid.data10;
            bytes[7] = guid.data11;

            return new Guid((int)guid.data1, (short)guid.data2, (short)guid.data3, bytes);
        }
 internal extern static int PeerCollabGetApplicationRegistrationInfo(ref GUID pApplicationId,
                                         PeerApplicationRegistrationType registrationType,
                                         out SafeCollabData ppApplication);
 internal extern static int PeerCollabDeleteObject(ref GUID pObjectId);
 internal extern static int PeerCollabUnregisterApplication(ref GUID pApplicationId,
                                                             PeerApplicationRegistrationType appRegType);
        private void AddObjectChangedEvent(EventHandler <ObjectChangedEventArgs> callback)
        {
            //
            // Register a wait handle if one has not been registered already
            //

            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddObjectChanged() called.");

            lock (LockObjChangedEvent){
                if (m_objectChanged == null)
                {
                    if (m_id.Equals(Guid.Empty))
                    {
                        throw (new PeerToPeerException(SR.GetString(SR.Collab_EmptyGuidError)));
                    }

                    m_objChangedEvent = new AutoResetEvent(false);

                    //
                    // Register callback with a wait handle
                    //

                    m_regObjChangedWaitHandle = ThreadPool.RegisterWaitForSingleObject(m_objChangedEvent,                              //Event that triggers the callback
                                                                                       new WaitOrTimerCallback(ObjectChangedCallback), //callback to be called
                                                                                       null,                                           //state to be passed
                                                                                       -1,                                             //Timeout - aplicable only for timers
                                                                                       false                                           //call us everytime the event is set
                                                                                       );
                    PEER_COLLAB_EVENT_REGISTRATION pcer = new PEER_COLLAB_EVENT_REGISTRATION();
                    pcer.eventType = PeerCollabEventType.EndPointObjectChanged;

                    GUID     guid       = CollaborationHelperFunctions.ConvertGuidToGUID(m_id);
                    GCHandle guidHandle = GCHandle.Alloc(guid, GCHandleType.Pinned);

                    //
                    // Register event with collab
                    //

                    pcer.pInstance = guidHandle.AddrOfPinnedObject();
                    try{
                        int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent(
                            m_objChangedEvent.SafeWaitHandle,
                            1,
                            ref pcer,
                            out m_safeObjChangedEvent);
                        if (errorCode != 0)
                        {
                            Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode);
                            throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_ObjectChangedRegFailed), errorCode);
                        }
                    }
                    finally{
                        if (guidHandle.IsAllocated)
                        {
                            guidHandle.Free();
                        }
                    }
                }
                m_objectChanged += callback;
            }

            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddObjectChanged() successful.");
        }