/// <summary>
        /// This property verifies whether the current machine was prepared for consuming and producing RM protected content. 
        /// If property returns true it could be used as an indication that Init function call will not result in a network transaction.
        /// </summary>
        public static bool IsUserActivated(ContentUser user)
        {
            SecurityHelper.DemandRightsManagementPermission();
        
            if (user == null)
            {
                throw new ArgumentNullException("user");
            }

            // we only let specifically identified users to be used here  
            if ((user.AuthenticationType != AuthenticationType.Windows) && 
                 (user.AuthenticationType != AuthenticationType.Passport))
            {
                throw new ArgumentOutOfRangeException("user", SR.Get(SRID.OnlyPassportOrWindowsAuthenticatedUsersAreAllowed));
            }
            
            using (ClientSession userClientSession = new ClientSession(user))
            {
                // if machine activation is not present we can return false right away             
                return (userClientSession.IsMachineActivated() && userClientSession.IsUserActivated());
            }
        }
        /// <summary>
        /// Private Constructor for the SecureEnvironment. 
        /// </summary>
        private SecureEnvironment(string applicationManifest,
                                                         ContentUser user, 
                                                         ClientSession clientSession) 
        {
            Invariant.Assert(applicationManifest != null);
            Invariant.Assert(user != null);
            Invariant.Assert(clientSession != null);

            _user = user;
            _applicationManifest = applicationManifest;
            _clientSession = clientSession;
        }
        private static SecureEnvironment CriticalCreate(
            string applicationManifest, 
            AuthenticationType authentication,
            UserActivationMode userActivationMode)
        {
            if (applicationManifest == null)
            {
                throw new ArgumentNullException("applicationManifest");
            }

            if ((authentication != AuthenticationType.Windows) && 
                 (authentication != AuthenticationType.Passport))
            {
                throw new ArgumentOutOfRangeException("authentication");
            }

            if ((userActivationMode != UserActivationMode.Permanent) &&
                 (userActivationMode != UserActivationMode.Temporary))
            {
                throw new ArgumentOutOfRangeException("userActivationMode");            
            }

            //build user with the given authnetication type and a default name 
            // only authentication type is critical in this case 
            ContentUser user; 
            
            using (ClientSession tempClientSession =
                ClientSession.DefaultUserClientSession(authentication))
            {
                //Activate Machine if neccessary
                if (!tempClientSession.IsMachineActivated())
                {
                    // activate Machine
                    tempClientSession.ActivateMachine(authentication);
                }

                //Activate User (we will force start activation at this point)
                // at this point we should have a real user name 
                user = tempClientSession.ActivateUser(authentication, userActivationMode);
            }

            Debug.Assert(IsUserActivated(user));

            ClientSession clientSession = new ClientSession(user, userActivationMode);

            try
            {
                try
                {
                    // make sure we have a Client Licensor Certificate 
                    clientSession.AcquireClientLicensorCertificate();
                }
                catch (RightsManagementException)
                {
                    // In case of the RightsMnaagement exception we are willing to proceed
                    // as ClientLicensorCertificate only required for publishing not for consumption 
                    // and therefore it is optional to have one.
                }
            
                clientSession.BuildSecureEnvironment(applicationManifest);

                return new SecureEnvironment(applicationManifest, user, clientSession);
            }
            catch
            {
                clientSession.Dispose();
                throw;
            }
        }
        /// <summary>
        /// This static Method builds a new instance of a secure environment for a given user that is assumed to be already activated. 
        /// client Application can use GetActivatedUsers property to enumerate Activated users.
        /// </summary>
        private static SecureEnvironment CriticalCreate(string applicationManifest, ContentUser user)
        {
            if (applicationManifest == null)
            {
                throw new ArgumentNullException("applicationManifest");
            }

            if (user == null)
            {
                throw new  ArgumentNullException("user");
            }

            // we only let specifically identifyed users to be used here  
            if ((user.AuthenticationType != AuthenticationType.Windows) && 
                 (user.AuthenticationType != AuthenticationType.Passport))
            {
                throw new ArgumentOutOfRangeException("user");
            }

            if (!IsUserActivated(user))
            {
                throw new RightsManagementException(RightsManagementFailureCode.NeedsGroupIdentityActivation);
            }
            
            ClientSession clientSession = new ClientSession(user);

            try
            {
                clientSession.BuildSecureEnvironment(applicationManifest);

                return new SecureEnvironment(applicationManifest, user, clientSession);
            }
            catch
            {
                clientSession.Dispose();
                throw;
            }
        }
        /// <summary>
        /// This function returns a read only collection of the activated users.
        /// </summary>
        static public  ReadOnlyCollection<ContentUser>  GetActivatedUsers()
        {
            SecurityHelper.DemandRightsManagementPermission();
            
            //build user with the default authentication type and a default name 
            // neither name not authentication type is important in this case 
            //ContentUser tempUser = new ContentUser(_defaultUserName, AuthenticationType.Windows);
        
            // Generic client session to enumerate user certificates 
            using(ClientSession genericClientSession = 
                ClientSession.DefaultUserClientSession(AuthenticationType.Windows))
            {
                List<ContentUser> userList = new List<ContentUser>(); 

                // if machine activation is not present we can return empty list right away             
                if (genericClientSession.IsMachineActivated())
                {
                    int index =0; 
                    while(true)
                    {
                        // we get a string which can be parsed to get the ID and type 
                        string userCertificate = genericClientSession.EnumerateLicense(EnumerateLicenseFlags.GroupIdentity, index);

                        if (userCertificate == null)
                            break;

                        // we need to parse the information out of the string 
                        ContentUser user = ClientSession.ExtractUserFromCertificateChain(userCertificate);

                        // User specific client session to check it's status 
                        using(ClientSession userClientSession = new ClientSession(user))
                        {
                            if (userClientSession.IsUserActivated()) 
                            {
                                userList.Add(user);
                            }
                        }

                        index ++;
                    }
                }
                
                return new ReadOnlyCollection<ContentUser>(userList);
            }
        }
        /// <summary>
        /// Removes activation for a given user. User must have Windows or Passport authnetication 
        /// </summary>
        public static void RemoveActivatedUser(ContentUser user)
        {
            SecurityHelper.DemandRightsManagementPermission();
            
            if (user == null)
            {
                throw new ArgumentNullException("user");
            }

            // we only let specifically identifyed users to be used here  
            if ((user.AuthenticationType != AuthenticationType.Windows) && 
                 (user.AuthenticationType != AuthenticationType.Passport))
            {
                throw new ArgumentOutOfRangeException("user", SR.Get(SRID.OnlyPassportOrWindowsAuthenticatedUsersAreAllowed));
            }

            // Generic client session to enumerate user certificates 
            using (ClientSession userClientSession = new ClientSession(user))
            {          
                // Remove Licensor certificastes first 
                List<string> userClientLicensorCertificateIds = 
                                userClientSession.EnumerateUsersCertificateIds(user, EnumerateLicenseFlags.ClientLicensor);

                // and now we can remove certificates that have been enumerated 
                foreach(string licenseId in userClientLicensorCertificateIds)
                {
                    userClientSession.DeleteLicense(licenseId); 
                }                
                        
                // Remove User's identity certificastes second 
                List<string> userGroupIdentityCertificateIds = 
                                userClientSession.EnumerateUsersCertificateIds(user, EnumerateLicenseFlags.GroupIdentity);

                // and now we can remove certificates that have been enumerated 
                foreach(string licenseId in userGroupIdentityCertificateIds)
                {
                    userClientSession.DeleteLicense(licenseId); 
                }                
            }
        }