/**
   * Load the user quota details
   *
   * @param userName - name of the user.
   * @return UserQuotaDetails
   * @throws QuotaManagerException
   */
  private UserQuotaDetails loadUsageDetails(String userName) throws QuotaManagerException {

    // Check if the user name is available

    UserQuotaDetails quotaDetails = null;

    try {
      if (userName == null || userName.length() == 0) {
        logger.debug("user name is null or empty - throw QuotaManagerException");
        throw new QuotaManagerException("No user name for client");
      }

      // Get the usage quota and current usage values for the user

      long userQuota = m_usageService.getUserQuota(userName);
      long userUsage = m_usageService.getUserUsage(userName);

      // Create the user quota details for live tracking

      quotaDetails = new UserQuotaDetails(userName, userQuota);
      if (userUsage > 0L) {
        quotaDetails.setCurrentUsage(userUsage);
      }

      // Add the details to the live tracking table

      // Check if another thread has added the details

      UserQuotaDetails details = m_liveUsage.get(userName);
      if (details != null) {
        quotaDetails = details;
      } else {
        m_liveUsage.put(userName, quotaDetails);
      }

      // DEBUG

      if (logger.isDebugEnabled()) {
        logger.debug("Added live usage tracking " + quotaDetails);
      }
    } catch (Exception ex) {

      // Log the error

      if (logger.isDebugEnabled()) {
        logger.debug("Failed to load usage for" + userName, ex);
      }
      // Failed to load usage details

      throw new QuotaManagerException("Failed to load usage for " + userName + ", " + ex);
    }

    // Return the user usage details

    return quotaDetails;
  }
  /**
   * Release space to the free space for the filesystem.
   *
   * @param sess SrvSession
   * @param tree TreeConnection
   * @param fid int
   * @param path String
   * @param alloc long
   * @exception IOException
   */
  public void releaseSpace(SrvSession sess, TreeConnection tree, int fid, String path, long alloc)
      throws IOException {

    // Check if content usage is enabled

    if (m_usageService.getEnabled() == false) return;

    // Check if there is a live usage record for the user

    UserQuotaDetails userQuota = getQuotaDetails(sess, true);

    if (userQuota != null) {

      synchronized (userQuota) {

        // Release the space from the live usage value

        userQuota.subtractFromCurrentUsage(alloc);
      }

      // DEBUG

      if (logger.isDebugEnabled())
        logger.debug("Released " + alloc + " bytes, userQuota=" + userQuota);
    } else if (logger.isDebugEnabled())
      logger.debug("Failed to release " + alloc + " bytes for sess " + sess.getUniqueId());
  }
  /**
   * Allocate space on the filesystem.
   *
   * @param sess SrvSession
   * @param tree TreeConnection
   * @param file NetworkFile
   * @param alloc long requested allocation size
   * @return long granted allocation size
   * @exception IOException
   */
  public long allocateSpace(SrvSession sess, TreeConnection tree, NetworkFile file, long alloc)
      throws IOException {

    // Check if content usage is enabled

    if (m_usageService.getEnabled() == false) return alloc;

    // Check if there is a live usage record for the user

    UserQuotaDetails userQuota = getQuotaDetails(sess, true);
    long allowedAlloc = 0L;

    if (userQuota != null) {

      // Check if the user has a usage quota

      synchronized (userQuota) {
        if (userQuota.hasUserQuota()) {

          // Check if the user has enough free space allocation

          if (alloc > 0 && userQuota.getAvailableSpace() >= alloc) {
            userQuota.addToCurrentUsage(alloc);
            allowedAlloc = alloc;
          }
        } else {

          // Update the live usage
          userQuota.addToCurrentUsage(alloc);
          allowedAlloc = alloc;
        }
      }
    } else if (logger.isDebugEnabled())
      logger.debug("Failed to allocate " + alloc + " bytes for sess " + sess.getUniqueId());

    // Check if the allocation was allowed

    if (allowedAlloc < alloc) {

      // DEBUG

      if (logger.isDebugEnabled()) logger.debug("Allocation failed userQuota=" + userQuota);

      throw new DiskFullException();
    } else if (logger.isDebugEnabled())
      logger.debug("Allocated " + alloc + " bytes, userQuota=" + userQuota);

    // Return the allocation size

    return allowedAlloc;
  }
  /**
   * Return the quota space available to the specified user/session
   *
   * @param sess SrvSession
   * @param tree TreeConnection
   * @return long
   */
  public long getUserTotalSpace(SrvSession sess, TreeConnection tree) {

    // Check if content usage is enabled

    if (m_usageService.getEnabled() == false) return -1L;

    UserQuotaDetails userQuota = getQuotaDetails(sess, true);
    if (userQuota != null) {
      synchronized (userQuota) {
        return userQuota.getUserQuota();
      }
    }

    // No quota details available

    return -1L;
  }