/// <summary>
        /// Gets message header + number of specified lines.
        /// </summary>
        /// <param name="accessingUser">User who accesses this method. 
        /// User needs r permission to call this method or Exception is thrown. 
        /// There is special user 'system' for which permission check is skipped.</param>
        /// <param name="folderOwnerUser">User who's folder it is.</param>
        /// <param name="folder">Folder what message top lines to get. For example: Inbox,Public Folders/Documnets .</param>
        /// <param name="msgID">MessageID.</param>
        /// <param name="nrLines">Number of lines to retrieve. NOTE: line counting starts at the end of header.</param>
        /// <returns>Returns message header + number of specified lines.</returns>
        public byte[] GetMessageTopLines(string accessingUser,string folderOwnerUser,string folder,string msgID,int nrLines)
        {
            /* Implementation notes:
                *) Validate values. Throw ArgumnetExcetion if invalid values.
                *) Ensure that user exists.
                *) Normalize folder. Remove '/' from folder start and end, ... .
                *) Do Shared Folders mapping.
                *) Ensure that folder exists. Throw Exception if don't.
                *) See if user has sufficient permissions. User requires 'r' permission.
                    There is builtin user system, skip ACL for it.
                *) Get message top lines.
            */

            //--- Validate values -------------------//
            ArgsValidator.ValidateUserName(folderOwnerUser);
            ArgsValidator.ValidateFolder(folder);
            ArgsValidator.ValidateNotNull(msgID);
            //---------------------------------------//

            // Ensure that user exists.
            if(!UserExists(folderOwnerUser)){
                throw new Exception("User '" + folderOwnerUser + "' doesn't exist !");
            }

            // Normalize folder. Remove '/' from folder start and end.
            folder = API_Utlis.NormalizeFolder(folder);

            // Do Shared Folders mapping.
            string originalFolder = folder;
            SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder);
            if(mappedFolder.IsSharedFolder){
                folderOwnerUser = mappedFolder.FolderOnwer;
                folder = mappedFolder.Folder;

                if(folderOwnerUser == "" || folder == ""){
                    throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !");
                }
            }

            // Ensure that folder exists. Throw Exception if don't.
            if(!FolderExists(folderOwnerUser + "/" + folder)){
                throw new Exception("Folder '" + folder + "' doesn't exist !");
            }

            // See if user has sufficient permissions. User requires 'r' permission.
            //  There is builtin user system, skip ACL for it.
            if(accessingUser.ToLower() != "system"){
                IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser);
                if((acl & IMAP_ACL_Flags.r) == 0){
                    throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !");
                }
            }

            //--- Get message top lines
            if(nrLines < 50){
                using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_GetMessageTopLines")){
                    sqlCmd.AddParameter("_userName"  ,NpgsqlDbType.Varchar,folderOwnerUser);
                    sqlCmd.AddParameter("_folder"    ,NpgsqlDbType.Varchar,folder);
                    sqlCmd.AddParameter("_messageID" ,NpgsqlDbType.Varchar,msgID);

                    return GetTopLines(new MemoryStream((byte[])sqlCmd.ExecuteScalar()),nrLines);
                }
            }
            else{
                EmailMessageItems msgItems = new EmailMessageItems(msgID,IMAP_MessageItems_enum.Message);
                GetMessageItems(accessingUser,folderOwnerUser,folder,msgItems);
                byte[] topLines = GetTopLines(msgItems.MessageStream,nrLines);
                msgItems.MessageStream.Dispose();
                return topLines;
            }
        }
        /// <summary>
        /// Checks if specified mailbox size is exceeded.
        /// </summary>
        /// <param name="userName">User name. Use <see cref="IMailServerApi.GetUsers">GetUsers()</see> to get valid values.</param>
        /// <returns>Returns true if exceeded.</returns>
        public bool ValidateMailboxSize(string userName)
        {
            using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_ValidateMailboxSize")){
                sqlCmd.AddParameter("_userName",NpgsqlDbType.Varchar,userName);

                DataSet ds = sqlCmd.Execute();
                return (bool)sqlCmd.ExecuteScalar();
            }
        }
        /// <summary>
        /// Gets specified user mailbox size.
        /// </summary>
        /// <param name="userName">User name.</param>
        /// <returns>Returns mailbox size.</returns>
        public long GetMailboxSize(string userName)
        {
            using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_GetMailboxSize")){
                sqlCmd.AddParameter("_userName",NpgsqlDbType.Varchar,userName);

                object result = sqlCmd.ExecuteScalar();
                if(result == DBNull.Value){
                    return 0;
                }
                else{
                    return (long)result;
                }
            }
        }