/// <summary>
        /// The static member returns the list of clouds
        /// </summary>
        /// <returns></returns>
        // <SecurityKernel Critical="True" Ring="1">
        // <ReferencesCritical Name="Method: GetCloudOrClouds(String, Boolean, CloudCollection&, Cloud&):Void" Ring="1" />
        // </SecurityKernel>
        //[System.Security.SecurityCritical]
        public static CloudCollection GetAvailableClouds()
        {
            CloudCollection clouds = null;
            Cloud           dummy  = null;

            GetCloudOrClouds(null, false, out clouds, out dummy);
            return(clouds);
        }
        // <SecurityKernel Critical="True" Ring="1">
        // <ReferencesCritical Name="Method: GetCloudOrClouds(String, Boolean, CloudCollection&, Cloud&):Void" Ring="1" />
        // </SecurityKernel>
        //[System.Security.SecurityCritical]
        public static Cloud GetCloudByName(string cloudName)
        {
            if (cloudName == null || cloudName.Length == 0)
            {
                throw new ArgumentException(SR.GetString(SR.Pnrp_CloudNameCantBeNull), "cloudName");
            }
            CloudCollection dummy = null;
            Cloud           cloud = null;

            GetCloudOrClouds(cloudName, false, out dummy, out cloud);
            return(cloud);
        }
        private static void GetCloudOrClouds(string cloudName, bool bGlobalCloudOnly, out CloudCollection clouds, out Cloud cloud)
        {
            cloud  = null;
            clouds = null;

            Logging.Enter(Logging.P2PTraceSource, "Cloud::GetCloudOrClouds()");

            //-------------------------------------------------
            //Demand for the Unrestricted Pnrp Permission
            //-------------------------------------------------
            PnrpPermission.UnrestrictedPnrpPermission.Demand();

            Int32        result    = 0;
            UInt32       numClouds = 0;
            SafePeerData ArrayOfCloudInfoStructures = null;

            if (cloudName == null)
            {
                //-----------------------------------------
                //We need the collection only when we are not
                //getting a specific cloud
                //-----------------------------------------
                clouds = new CloudCollection();
            }
            try
            {
                //---------------------------------------------------------------
                //No perf hit here, real native call happens only one time if it
                //did not already happen
                //---------------------------------------------------------------
                UnsafeP2PNativeMethods.PnrpStartup();

                result = UnsafeP2PNativeMethods.PeerPnrpGetCloudInfo(out numClouds, out ArrayOfCloudInfoStructures);
                if (result != 0)
                {
                    throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Pnrp_CouldNotEnumerateClouds), result);
                }
                if (numClouds != 0)
                {
                    Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Number of clouds returned {0}", numClouds);
                    IntPtr pPEER_PNRP_CLOUD_INFO = ArrayOfCloudInfoStructures.DangerousGetHandle();
                    for (ulong i = 0; i < numClouds; i++)
                    {
                        PEER_PNRP_CLOUD_INFO cloudinfo = (PEER_PNRP_CLOUD_INFO)Marshal.PtrToStructure(pPEER_PNRP_CLOUD_INFO, typeof(PEER_PNRP_CLOUD_INFO));
                        string nativeCloudName         = Marshal.PtrToStringUni(cloudinfo.pwzCloudName);
                        pPEER_PNRP_CLOUD_INFO = (IntPtr)((long)pPEER_PNRP_CLOUD_INFO + Marshal.SizeOf(typeof(PEER_PNRP_CLOUD_INFO)));
                        Cloud c = new Cloud(nativeCloudName, (PnrpScope)((int)cloudinfo.dwScope), (int)cloudinfo.dwScopeId);
                        if (cloudName == null && !bGlobalCloudOnly)
                        {
                            clouds.Add(c);
                            continue;
                        }
                        //If a specific cloud by name is required, then test for name
                        //note that scope is PnrpScope.All but we don't test that now
                        if (cloudName != null && cloudName == nativeCloudName)
                        {
                            cloud = c;
                            break;
                        }

                        if (bGlobalCloudOnly && c.Scope == PnrpScope.Global)
                        {
                            cloud = c;
                            break;
                        }
                    }
                }
                else
                {
                    Logging.P2PTraceSource.TraceEvent(TraceEventType.Warning, 0, "No Clouds returned from the native call");
                }
            }
            finally
            {
                if (ArrayOfCloudInfoStructures != null)
                {
                    ArrayOfCloudInfoStructures.Dispose();
                }
            }
            if (cloudName != null && cloud == null)
            {
                Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "The specific cloud name {0} asked for is not found", cloudName);
            }
            Logging.Leave(Logging.P2PTraceSource, "Cloud::GetCloudOrClouds()");
        }