/// <summary>
        /// Registers a <see cref="NetworkCredential"/> for a given <see cref="ResourcePath"/>
        /// </summary>
        /// <param name="path">
        /// For this <see cref="ResourcePath"/> and all subpaths the <see cref="credential"/> is impersonated,
        /// assuming that no better matching path is registered.
        /// </param>
        /// <param name="credential"><see cref="NetworkCredential"/> to impersonate for accessing <paramref name="path"/></param>
        /// <returns><c>true</c> if registration was successful; otherwise <c>false</c></returns>
        public bool TryRegisterCredential(ResourcePath path, NetworkCredential credential)
        {
            _debugLogger.Info("ImpersonationService: Trying to register credential (User: '******' Domain: '{1}') for ResourcePath '{2}'", credential.UserName, credential.Domain, path);

            // If there is already a credential registered for exactly the same ResourcePath,
            // we unregister the old credential and log a warning. It should have been
            // unregistered with TryUnregisterCredential before.
            WindowsIdentityWrapper oldIdWrapper;

            if (_ids.TryRemove(path, out oldIdWrapper))
            {
                _debugLogger.Warn("ImpersonationService: There was already a credential registered For ResourcePath '{0}'. The old credential was unregistered.", path);
                oldIdWrapper.Dispose();
            }

            var             logonHelper = new LogonHelper(_debugLogger);
            WindowsIdentity id;

            // We use LogonType.NewCredentials because this logon type allows the caller to clone its current token
            // and specify new credentials only for outbound connections. The new logon session has the same local
            // identifier but uses different credentials for other network connections.
            // This logon type is only supported by LogonProvider.WinNt50.
            if (logonHelper.TryLogon(credential, LogonHelper.LogonType.NewCredentials, LogonHelper.LogonProvider.WinNt50, out id))
            {
                var idWrapper = new WindowsIdentityWrapper(id, credential);
                if (!_ids.TryAdd(path, idWrapper))
                {
                    // In a multithreaded environment, a new credential could have been added
                    // despite the TryUnregisterCredential call above in the meantime.
                    _debugLogger.Error("ImpersonationService: For ResourcePath '{0}' there was already a credential registered. Cannot register new credential.", path);
                    idWrapper.Dispose();
                    return(false);
                }
                _debugLogger.Info("ImpersonationService: Successfully registered credential for ResourcePath '{0}': User: '******' (Domain: '{2}')", path, idWrapper.UserName, idWrapper.Domain);
                return(true);
            }
            _debugLogger.Error("ImpersonationService: Could not register credential for ResourcePath '{0}': User: '******' (Domain: '{2}')", path, credential.UserName, credential.Domain);
            return(false);
        }
    /// <summary>
    /// Registers a <see cref="NetworkCredential"/> for a given <see cref="ResourcePath"/>
    /// </summary>
    /// <param name="path">
    /// For this <see cref="ResourcePath"/> and all subpaths the <see cref="credential"/> is impersonated,
    /// assuming that no better matching path is registered.
    /// </param>
    /// <param name="credential"><see cref="NetworkCredential"/> to impersonate for accessing <paramref name="path"/></param>
    /// <returns><c>true</c> if registration was successful; otherwise <c>false</c></returns>
    public bool TryRegisterCredential(ResourcePath path, NetworkCredential credential)
    {
      _debugLogger.Info("ImpersonationService: Trying to register credential (User: '******' Domain: '{1}') for ResourcePath '{2}'", credential.UserName, credential.Domain, path);

      // If there is already a credential registered for exactly the same ResourcePath,
      // we unregister the old credential and log a warning. It should have been
      // unregistered with TryUnregisterCredential before.
      WindowsIdentityWrapper oldIdWrapper;
      if (_ids.TryRemove(path, out oldIdWrapper))
      {
        _debugLogger.Warn("ImpersonationService: There was already a credential registered For ResourcePath '{0}'. The old credential was unregistered.", path);
        oldIdWrapper.Dispose();
      }

      var logonHelper = new LogonHelper(_debugLogger);
      WindowsIdentity id;

      // We use LogonType.NewCredentials because this logon type allows the caller to clone its current token
      // and specify new credentials only for outbound connections. The new logon session has the same local
      // identifier but uses different credentials for other network connections.
      // This logon type is only supported by LogonProvider.WinNt50.
      if (logonHelper.TryLogon(credential, LogonHelper.LogonType.NewCredentials, LogonHelper.LogonProvider.WinNt50, out id))
      {
        var idWrapper = new WindowsIdentityWrapper(id, credential);
        if(!_ids.TryAdd(path, idWrapper))
        {
          // In a multithreaded environment, a new credential could have been added
          // despite the TryUnregisterCredential call above in the meantime.
          _debugLogger.Error("ImpersonationService: For ResourcePath '{0}' there was already a credential registered. Cannot register new credential.", path);
          idWrapper.Dispose();
          return false;
        }
        _debugLogger.Info("ImpersonationService: Successfully registered credential for ResourcePath '{0}': User: '******' (Domain: '{2}')", path, idWrapper.UserName, idWrapper.Domain);
        return true;
      }
      _debugLogger.Error("ImpersonationService: Could not register credential for ResourcePath '{0}': User: '******' (Domain: '{2}')", path, credential.UserName, credential.Domain);
      return false;
    }