diff --git a/config_override.php b/config_override.php
index b0c374e6fe369bbe1168b1699dd2b5efcc1d09ca..342360724cc4b99ca1121edc0eac44fa141be26f 100644
--- a/config_override.php
+++ b/config_override.php
@@ -10,3 +10,14 @@
 
 //Maximum number of Mailboxes in mail converter
 $max_mailboxes = 3;
+
+/**
+ * Configure runtime connectors to customization in core files.
+ * Ex: Sessions are currently handled by PHP default session handler. 
+ *     This can be customized using runtime connector hook and avoid core file modifications.
+ *     array('session' => 'Vtiger_CustomSession_Handler')
+ */
+$runtime_connectors = array();
+
+//Password Regex for validation
+$validation_regex = array('password_regex' => '^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*])(?=.{8,})');
\ No newline at end of file
diff --git a/cron/class.phpmailer.php b/cron/class.phpmailer.php
deleted file mode 100755
index fba70242a465b0feb5fd5238f1fdb3143d41f766..0000000000000000000000000000000000000000
--- a/cron/class.phpmailer.php
+++ /dev/null
@@ -1,4061 +0,0 @@
-<?php
-/**
- * PHPMailer - PHP email creation and transport class.
- * PHP Version 5
- * @package PHPMailer
- * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
- * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
- * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
- * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
- * @author Brent R. Matzelle (original founder)
- * @copyright 2012 - 2014 Marcus Bointon
- * @copyright 2010 - 2012 Jim Jagielski
- * @copyright 2004 - 2009 Andy Prevost
- * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
- * @note This program is distributed in the hope that it will be useful - WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/**
- * PHPMailer - PHP email creation and transport class.
- * @package PHPMailer
- * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
- * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
- * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
- * @author Brent R. Matzelle (original founder)
- */
-class PHPMailer
-{
-    /**
-     * The PHPMailer Version number.
-     * @var string
-     */
-    public $Version = '5.2.27';
-
-    /**
-     * Email priority.
-     * Options: null (default), 1 = High, 3 = Normal, 5 = low.
-     * When null, the header is not set at all.
-     * @var integer
-     */
-    public $Priority = null;
-
-    /**
-     * The character set of the message.
-     * @var string
-     */
-    public $CharSet = 'UTF-8';
-
-    /**
-     * The MIME Content-type of the message.
-     * @var string
-     */
-    public $ContentType = 'text/plain';
-
-    /**
-     * The message encoding.
-     * Options: "8bit", "7bit", "binary", "base64", and "quoted-printable".
-     * @var string
-     */
-    public $Encoding = '8bit';
-
-    /**
-     * Holds the most recent mailer error message.
-     * @var string
-     */
-    public $ErrorInfo = '';
-
-    /**
-     * The From email address for the message.
-     * @var string
-     */
-    public $From = 'root@localhost';
-
-    /**
-     * The From name of the message.
-     * @var string
-     */
-    public $FromName = 'Root User';
-
-    /**
-     * The Sender email (Return-Path) of the message.
-     * If not empty, will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.
-     * @var string
-     */
-    public $Sender = '';
-
-    /**
-     * The Return-Path of the message.
-     * If empty, it will be set to either From or Sender.
-     * @var string
-     * @deprecated Email senders should never set a return-path header;
-     * it's the receiver's job (RFC5321 section 4.4), so this no longer does anything.
-     * @link https://tools.ietf.org/html/rfc5321#section-4.4 RFC5321 reference
-     */
-    public $ReturnPath = '';
-
-    /**
-     * The Subject of the message.
-     * @var string
-     */
-    public $Subject = '';
-
-    /**
-     * An HTML or plain text message body.
-     * If HTML then call isHTML(true).
-     * @var string
-     */
-    public $Body = '';
-
-    /**
-     * The plain-text message body.
-     * This body can be read by mail clients that do not have HTML email
-     * capability such as mutt & Eudora.
-     * Clients that can read HTML will view the normal Body.
-     * @var string
-     */
-    public $AltBody = '';
-
-    /**
-     * An iCal message part body.
-     * Only supported in simple alt or alt_inline message types
-     * To generate iCal events, use the bundled extras/EasyPeasyICS.php class or iCalcreator
-     * @link http://sprain.ch/blog/downloads/php-class-easypeasyics-create-ical-files-with-php/
-     * @link http://kigkonsult.se/iCalcreator/
-     * @var string
-     */
-    public $Ical = '';
-
-    /**
-     * The complete compiled MIME message body.
-     * @access protected
-     * @var string
-     */
-    protected $MIMEBody = '';
-
-    /**
-     * The complete compiled MIME message headers.
-     * @var string
-     * @access protected
-     */
-    protected $MIMEHeader = '';
-
-    /**
-     * Extra headers that createHeader() doesn't fold in.
-     * @var string
-     * @access protected
-     */
-    protected $mailHeader = '';
-
-    /**
-     * Word-wrap the message body to this number of chars.
-     * Set to 0 to not wrap. A useful value here is 78, for RFC2822 section 2.1.1 compliance.
-     * @var integer
-     */
-    public $WordWrap = 0;
-
-    /**
-     * Which method to use to send mail.
-     * Options: "mail", "sendmail", or "smtp".
-     * @var string
-     */
-    public $Mailer = 'mail';
-
-    /**
-     * The path to the sendmail program.
-     * @var string
-     */
-    public $Sendmail = '/usr/sbin/sendmail';
-
-    /**
-     * Whether mail() uses a fully sendmail-compatible MTA.
-     * One which supports sendmail's "-oi -f" options.
-     * @var boolean
-     */
-    public $UseSendmailOptions = true;
-
-    /**
-     * Path to PHPMailer plugins.
-     * Useful if the SMTP class is not in the PHP include path.
-     * @var string
-     * @deprecated Should not be needed now there is an autoloader.
-     */
-    public $PluginDir = '';
-
-    /**
-     * The email address that a reading confirmation should be sent to, also known as read receipt.
-     * @var string
-     */
-    public $ConfirmReadingTo = '';
-
-    /**
-     * The hostname to use in the Message-ID header and as default HELO string.
-     * If empty, PHPMailer attempts to find one with, in order,
-     * $_SERVER['SERVER_NAME'], gethostname(), php_uname('n'), or the value
-     * 'localhost.localdomain'.
-     * @var string
-     */
-    public $Hostname = '';
-
-    /**
-     * An ID to be used in the Message-ID header.
-     * If empty, a unique id will be generated.
-     * You can set your own, but it must be in the format "<id@domain>",
-     * as defined in RFC5322 section 3.6.4 or it will be ignored.
-     * @see https://tools.ietf.org/html/rfc5322#section-3.6.4
-     * @var string
-     */
-    public $MessageID = '';
-
-    /**
-     * The message Date to be used in the Date header.
-     * If empty, the current date will be added.
-     * @var string
-     */
-    public $MessageDate = '';
-
-    /**
-     * SMTP hosts.
-     * Either a single hostname or multiple semicolon-delimited hostnames.
-     * You can also specify a different port
-     * for each host by using this format: [hostname:port]
-     * (e.g. "smtp1.example.com:25;smtp2.example.com").
-     * You can also specify encryption type, for example:
-     * (e.g. "tls://smtp1.example.com:587;ssl://smtp2.example.com:465").
-     * Hosts will be tried in order.
-     * @var string
-     */
-    public $Host = 'localhost';
-
-    /**
-     * The default SMTP server port.
-     * @var integer
-     * @TODO Why is this needed when the SMTP class takes care of it?
-     */
-    public $Port = 25;
-
-    /**
-     * The SMTP HELO of the message.
-     * Default is $Hostname. If $Hostname is empty, PHPMailer attempts to find
-     * one with the same method described above for $Hostname.
-     * @var string
-     * @see PHPMailer::$Hostname
-     */
-    public $Helo = '';
-
-    /**
-     * What kind of encryption to use on the SMTP connection.
-     * Options: '', 'ssl' or 'tls'
-     * @var string
-     */
-    public $SMTPSecure = '';
-
-    /**
-     * Whether to enable TLS encryption automatically if a server supports it,
-     * even if `SMTPSecure` is not set to 'tls'.
-     * Be aware that in PHP >= 5.6 this requires that the server's certificates are valid.
-     * @var boolean
-     */
-    public $SMTPAutoTLS = true;
-
-    /**
-     * Whether to use SMTP authentication.
-     * Uses the Username and Password properties.
-     * @var boolean
-     * @see PHPMailer::$Username
-     * @see PHPMailer::$Password
-     */
-    public $SMTPAuth = false;
-
-    /**
-     * Options array passed to stream_context_create when connecting via SMTP.
-     * @var array
-     */
-    public $SMTPOptions = array();
-
-    /**
-     * SMTP username.
-     * @var string
-     */
-    public $Username = '';
-
-    /**
-     * SMTP password.
-     * @var string
-     */
-    public $Password = '';
-
-    /**
-     * SMTP auth type.
-     * Options are CRAM-MD5, LOGIN, PLAIN, NTLM, XOAUTH2, attempted in that order if not specified
-     * @var string
-     */
-    public $AuthType = '';
-
-    /**
-     * SMTP realm.
-     * Used for NTLM auth
-     * @var string
-     */
-    public $Realm = '';
-
-    /**
-     * SMTP workstation.
-     * Used for NTLM auth
-     * @var string
-     */
-    public $Workstation = '';
-
-    /**
-     * The SMTP server timeout in seconds.
-     * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2
-     * @var integer
-     */
-    public $Timeout = 300;
-
-    /**
-     * SMTP class debug output mode.
-     * Debug output level.
-     * Options:
-     * * `0` No output
-     * * `1` Commands
-     * * `2` Data and commands
-     * * `3` As 2 plus connection status
-     * * `4` Low-level data output
-     * @var integer
-     * @see SMTP::$do_debug
-     */
-    public $SMTPDebug = 0;
-
-    /**
-     * How to handle debug output.
-     * Options:
-     * * `echo` Output plain-text as-is, appropriate for CLI
-     * * `html` Output escaped, line breaks converted to `<br>`, appropriate for browser output
-     * * `error_log` Output to error log as configured in php.ini
-     *
-     * Alternatively, you can provide a callable expecting two params: a message string and the debug level:
-     * <code>
-     * $mail->Debugoutput = function($str, $level) {echo "debug level $level; message: $str";};
-     * </code>
-     * @var string|callable
-     * @see SMTP::$Debugoutput
-     */
-    public $Debugoutput = 'echo';
-
-    /**
-     * Whether to keep SMTP connection open after each message.
-     * If this is set to true then to close the connection
-     * requires an explicit call to smtpClose().
-     * @var boolean
-     */
-    public $SMTPKeepAlive = false;
-
-    /**
-     * Whether to split multiple to addresses into multiple messages
-     * or send them all in one message.
-     * Only supported in `mail` and `sendmail` transports, not in SMTP.
-     * @var boolean
-     */
-    public $SingleTo = false;
-
-    /**
-     * Storage for addresses when SingleTo is enabled.
-     * @var array
-     * @TODO This should really not be public
-     */
-    public $SingleToArray = array();
-
-    /**
-     * Whether to generate VERP addresses on send.
-     * Only applicable when sending via SMTP.
-     * @link https://en.wikipedia.org/wiki/Variable_envelope_return_path
-     * @link http://www.postfix.org/VERP_README.html Postfix VERP info
-     * @var boolean
-     */
-    public $do_verp = false;
-
-    /**
-     * Whether to allow sending messages with an empty body.
-     * @var boolean
-     */
-    public $AllowEmpty = false;
-
-    /**
-     * The default line ending.
-     * @note The default remains "\n". We force CRLF where we know
-     *        it must be used via self::CRLF.
-     * @var string
-     */
-    public $LE = "\n";
-
-    /**
-     * DKIM selector.
-     * @var string
-     */
-    public $DKIM_selector = '';
-
-    /**
-     * DKIM Identity.
-     * Usually the email address used as the source of the email.
-     * @var string
-     */
-    public $DKIM_identity = '';
-
-    /**
-     * DKIM passphrase.
-     * Used if your key is encrypted.
-     * @var string
-     */
-    public $DKIM_passphrase = '';
-
-    /**
-     * DKIM signing domain name.
-     * @example 'example.com'
-     * @var string
-     */
-    public $DKIM_domain = '';
-
-    /**
-     * DKIM private key file path.
-     * @var string
-     */
-    public $DKIM_private = '';
-
-    /**
-     * DKIM private key string.
-     * If set, takes precedence over `$DKIM_private`.
-     * @var string
-     */
-    public $DKIM_private_string = '';
-
-    /**
-     * Callback Action function name.
-     *
-     * The function that handles the result of the send email action.
-     * It is called out by send() for each email sent.
-     *
-     * Value can be any php callable: http://www.php.net/is_callable
-     *
-     * Parameters:
-     *   boolean $result        result of the send action
-     *   array   $to            email addresses of the recipients
-     *   array   $cc            cc email addresses
-     *   array   $bcc           bcc email addresses
-     *   string  $subject       the subject
-     *   string  $body          the email body
-     *   string  $from          email address of sender
-     * @var string
-     */
-    public $action_function = '';
-
-    /**
-     * What to put in the X-Mailer header.
-     * Options: An empty string for PHPMailer default, whitespace for none, or a string to use
-     * @var string
-     */
-    public $XMailer = '';
-
-    /**
-     * Which validator to use by default when validating email addresses.
-     * May be a callable to inject your own validator, but there are several built-in validators.
-     * @see PHPMailer::validateAddress()
-     * @var string|callable
-     * @static
-     */
-    public static $validator = 'auto';
-
-    /**
-     * An instance of the SMTP sender class.
-     * @var SMTP
-     * @access protected
-     */
-    protected $smtp = null;
-
-    /**
-     * The array of 'to' names and addresses.
-     * @var array
-     * @access protected
-     */
-    protected $to = array();
-
-    /**
-     * The array of 'cc' names and addresses.
-     * @var array
-     * @access protected
-     */
-    protected $cc = array();
-
-    /**
-     * The array of 'bcc' names and addresses.
-     * @var array
-     * @access protected
-     */
-    protected $bcc = array();
-
-    /**
-     * The array of reply-to names and addresses.
-     * @var array
-     * @access protected
-     */
-    protected $ReplyTo = array();
-
-    /**
-     * An array of all kinds of addresses.
-     * Includes all of $to, $cc, $bcc
-     * @var array
-     * @access protected
-     * @see PHPMailer::$to @see PHPMailer::$cc @see PHPMailer::$bcc
-     */
-    protected $all_recipients = array();
-
-    /**
-     * An array of names and addresses queued for validation.
-     * In send(), valid and non duplicate entries are moved to $all_recipients
-     * and one of $to, $cc, or $bcc.
-     * This array is used only for addresses with IDN.
-     * @var array
-     * @access protected
-     * @see PHPMailer::$to @see PHPMailer::$cc @see PHPMailer::$bcc
-     * @see PHPMailer::$all_recipients
-     */
-    protected $RecipientsQueue = array();
-
-    /**
-     * An array of reply-to names and addresses queued for validation.
-     * In send(), valid and non duplicate entries are moved to $ReplyTo.
-     * This array is used only for addresses with IDN.
-     * @var array
-     * @access protected
-     * @see PHPMailer::$ReplyTo
-     */
-    protected $ReplyToQueue = array();
-
-    /**
-     * The array of attachments.
-     * @var array
-     * @access protected
-     */
-    protected $attachment = array();
-
-    /**
-     * The array of custom headers.
-     * @var array
-     * @access protected
-     */
-    protected $CustomHeader = array();
-
-    /**
-     * The most recent Message-ID (including angular brackets).
-     * @var string
-     * @access protected
-     */
-    protected $lastMessageID = '';
-
-    /**
-     * The message's MIME type.
-     * @var string
-     * @access protected
-     */
-    protected $message_type = '';
-
-    /**
-     * The array of MIME boundary strings.
-     * @var array
-     * @access protected
-     */
-    protected $boundary = array();
-
-    /**
-     * The array of available languages.
-     * @var array
-     * @access protected
-     */
-    protected $language = array();
-
-    /**
-     * The number of errors encountered.
-     * @var integer
-     * @access protected
-     */
-    protected $error_count = 0;
-
-    /**
-     * The S/MIME certificate file path.
-     * @var string
-     * @access protected
-     */
-    protected $sign_cert_file = '';
-
-    /**
-     * The S/MIME key file path.
-     * @var string
-     * @access protected
-     */
-    protected $sign_key_file = '';
-
-    /**
-     * The optional S/MIME extra certificates ("CA Chain") file path.
-     * @var string
-     * @access protected
-     */
-    protected $sign_extracerts_file = '';
-
-    /**
-     * The S/MIME password for the key.
-     * Used only if the key is encrypted.
-     * @var string
-     * @access protected
-     */
-    protected $sign_key_pass = '';
-
-    /**
-     * Whether to throw exceptions for errors.
-     * @var boolean
-     * @access protected
-     */
-    protected $exceptions = false;
-
-    /**
-     * Unique ID used for message ID and boundaries.
-     * @var string
-     * @access protected
-     */
-    protected $uniqueid = '';
-
-    /**
-     * Error severity: message only, continue processing.
-     */
-    const STOP_MESSAGE = 0;
-
-    /**
-     * Error severity: message, likely ok to continue processing.
-     */
-    const STOP_CONTINUE = 1;
-
-    /**
-     * Error severity: message, plus full stop, critical error reached.
-     */
-    const STOP_CRITICAL = 2;
-
-    /**
-     * SMTP RFC standard line ending.
-     */
-    const CRLF = "\r\n";
-
-    /**
-     * The maximum line length allowed by RFC 2822 section 2.1.1
-     * @var integer
-     */
-    const MAX_LINE_LENGTH = 998;
-
-    /**
-     * Constructor.
-     * @param boolean $exceptions Should we throw external exceptions?
-     */
-    public function __construct($exceptions = null)
-    {
-        if ($exceptions !== null) {
-            $this->exceptions = (boolean)$exceptions;
-        }
-        //Pick an appropriate debug output format automatically
-        $this->Debugoutput = (strpos(PHP_SAPI, 'cli') !== false ? 'echo' : 'html');
-    }
-
-    /**
-     * Destructor.
-     */
-    public function __destruct()
-    {
-        //Close any open SMTP connection nicely
-        $this->smtpClose();
-    }
-
-    /**
-     * Call mail() in a safe_mode-aware fashion.
-     * Also, unless sendmail_path points to sendmail (or something that
-     * claims to be sendmail), don't pass params (not a perfect fix,
-     * but it will do)
-     * @param string $to To
-     * @param string $subject Subject
-     * @param string $body Message Body
-     * @param string $header Additional Header(s)
-     * @param string $params Params
-     * @access private
-     * @return boolean
-     */
-    private function mailPassthru($to, $subject, $body, $header, $params)
-    {
-        //Check overloading of mail function to avoid double-encoding
-        if (ini_get('mbstring.func_overload') & 1) {
-            $subject = $this->secureHeader($subject);
-        } else {
-            $subject = $this->encodeHeader($this->secureHeader($subject));
-        }
-
-        //Can't use additional_parameters in safe_mode, calling mail() with null params breaks
-        //@link http://php.net/manual/en/function.mail.php
-        if (ini_get('safe_mode') or !$this->UseSendmailOptions or is_null($params)) {
-            $result = @mail($to, $subject, $body, $header);
-        } else {
-            $result = @mail($to, $subject, $body, $header, $params);
-        }
-        return $result;
-    }
-    /**
-     * Output debugging info via user-defined method.
-     * Only generates output if SMTP debug output is enabled (@see SMTP::$do_debug).
-     * @see PHPMailer::$Debugoutput
-     * @see PHPMailer::$SMTPDebug
-     * @param string $str
-     */
-    protected function edebug($str)
-    {
-        if ($this->SMTPDebug <= 0) {
-            return;
-        }
-        //Avoid clash with built-in function names
-        if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) {
-            call_user_func($this->Debugoutput, $str, $this->SMTPDebug);
-            return;
-        }
-        switch ($this->Debugoutput) {
-            case 'error_log':
-                //Don't output, just log
-                error_log($str);
-                break;
-            case 'html':
-                //Cleans up output a bit for a better looking, HTML-safe output
-                echo htmlentities(
-                    preg_replace('/[\r\n]+/', '', $str),
-                    ENT_QUOTES,
-                    'UTF-8'
-                )
-                . "<br>\n";
-                break;
-            case 'echo':
-            default:
-                //Normalize line breaks
-                $str = preg_replace('/\r\n?/ms', "\n", $str);
-                echo gmdate('Y-m-d H:i:s') . "\t" . str_replace(
-                    "\n",
-                    "\n                   \t                  ",
-                    trim($str)
-                ) . "\n";
-        }
-    }
-
-    /**
-     * Sets message type to HTML or plain.
-     * @param boolean $isHtml True for HTML mode.
-     * @return void
-     */
-    public function isHTML($isHtml = true)
-    {
-        if ($isHtml) {
-            $this->ContentType = 'text/html';
-        } else {
-            $this->ContentType = 'text/plain';
-        }
-    }
-
-    /**
-     * Send messages using SMTP.
-     * @return void
-     */
-    public function isSMTP()
-    {
-        $this->Mailer = 'smtp';
-    }
-
-    /**
-     * Send messages using PHP's mail() function.
-     * @return void
-     */
-    public function isMail()
-    {
-        $this->Mailer = 'mail';
-    }
-
-    /**
-     * Send messages using $Sendmail.
-     * @return void
-     */
-    public function isSendmail()
-    {
-        $ini_sendmail_path = ini_get('sendmail_path');
-
-        if (!stristr($ini_sendmail_path, 'sendmail')) {
-            $this->Sendmail = '/usr/sbin/sendmail';
-        } else {
-            $this->Sendmail = $ini_sendmail_path;
-        }
-        $this->Mailer = 'sendmail';
-    }
-
-    /**
-     * Send messages using qmail.
-     * @return void
-     */
-    public function isQmail()
-    {
-        $ini_sendmail_path = ini_get('sendmail_path');
-
-        if (!stristr($ini_sendmail_path, 'qmail')) {
-            $this->Sendmail = '/var/qmail/bin/qmail-inject';
-        } else {
-            $this->Sendmail = $ini_sendmail_path;
-        }
-        $this->Mailer = 'qmail';
-    }
-
-    /**
-     * Add a "To" address.
-     * @param string $address The email address to send to
-     * @param string $name
-     * @return boolean true on success, false if address already used or invalid in some way
-     */
-    public function addAddress($address, $name = '')
-    {
-        return $this->addOrEnqueueAnAddress('to', $address, $name);
-    }
-
-    /**
-     * Add a "CC" address.
-     * @note: This function works with the SMTP mailer on win32, not with the "mail" mailer.
-     * @param string $address The email address to send to
-     * @param string $name
-     * @return boolean true on success, false if address already used or invalid in some way
-     */
-    public function addCC($address, $name = '')
-    {
-        return $this->addOrEnqueueAnAddress('cc', $address, $name);
-    }
-
-    /**
-     * Add a "BCC" address.
-     * @note: This function works with the SMTP mailer on win32, not with the "mail" mailer.
-     * @param string $address The email address to send to
-     * @param string $name
-     * @return boolean true on success, false if address already used or invalid in some way
-     */
-    public function addBCC($address, $name = '')
-    {
-        return $this->addOrEnqueueAnAddress('bcc', $address, $name);
-    }
-
-    /**
-     * Add a "Reply-To" address.
-     * @param string $address The email address to reply to
-     * @param string $name
-     * @return boolean true on success, false if address already used or invalid in some way
-     */
-    public function addReplyTo($address, $name = '')
-    {
-        return $this->addOrEnqueueAnAddress('Reply-To', $address, $name);
-    }
-
-    /**
-     * Add an address to one of the recipient arrays or to the ReplyTo array. Because PHPMailer
-     * can't validate addresses with an IDN without knowing the PHPMailer::$CharSet (that can still
-     * be modified after calling this function), addition of such addresses is delayed until send().
-     * Addresses that have been added already return false, but do not throw exceptions.
-     * @param string $kind One of 'to', 'cc', 'bcc', or 'ReplyTo'
-     * @param string $address The email address to send, resp. to reply to
-     * @param string $name
-     * @throws phpmailerException
-     * @return boolean true on success, false if address already used or invalid in some way
-     * @access protected
-     */
-    protected function addOrEnqueueAnAddress($kind, $address, $name)
-    {
-        $address = trim($address);
-        $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
-        if (($pos = strrpos($address, '@')) === false) {
-            // At-sign is misssing.
-            $error_message = $this->lang('invalid_address') . " (addAnAddress $kind): $address";
-            $this->setError($error_message);
-            $this->edebug($error_message);
-            if ($this->exceptions) {
-                throw new phpmailerException($error_message);
-            }
-            return false;
-        }
-        $params = array($kind, $address, $name);
-        // Enqueue addresses with IDN until we know the PHPMailer::$CharSet.
-        if ($this->has8bitChars(substr($address, ++$pos)) and $this->idnSupported()) {
-            if ($kind != 'Reply-To') {
-                if (!array_key_exists($address, $this->RecipientsQueue)) {
-                    $this->RecipientsQueue[$address] = $params;
-                    return true;
-                }
-            } else {
-                if (!array_key_exists($address, $this->ReplyToQueue)) {
-                    $this->ReplyToQueue[$address] = $params;
-                    return true;
-                }
-            }
-            return false;
-        }
-        // Immediately add standard addresses without IDN.
-        return call_user_func_array(array($this, 'addAnAddress'), $params);
-    }
-
-    /**
-     * Add an address to one of the recipient arrays or to the ReplyTo array.
-     * Addresses that have been added already return false, but do not throw exceptions.
-     * @param string $kind One of 'to', 'cc', 'bcc', or 'ReplyTo'
-     * @param string $address The email address to send, resp. to reply to
-     * @param string $name
-     * @throws phpmailerException
-     * @return boolean true on success, false if address already used or invalid in some way
-     * @access protected
-     */
-    protected function addAnAddress($kind, $address, $name = '')
-    {
-        if (!in_array($kind, array('to', 'cc', 'bcc', 'Reply-To'))) {
-            $error_message = $this->lang('Invalid recipient kind: ') . $kind;
-            $this->setError($error_message);
-            $this->edebug($error_message);
-            if ($this->exceptions) {
-                throw new phpmailerException($error_message);
-            }
-            return false;
-        }
-        if (!$this->validateAddress($address)) {
-            $error_message = $this->lang('invalid_address') . " (addAnAddress $kind): $address";
-            $this->setError($error_message);
-            $this->edebug($error_message);
-            if ($this->exceptions) {
-                throw new phpmailerException($error_message);
-            }
-            return false;
-        }
-        if ($kind != 'Reply-To') {
-            if (!array_key_exists(strtolower($address), $this->all_recipients)) {
-                array_push($this->$kind, array($address, $name));
-                $this->all_recipients[strtolower($address)] = true;
-                return true;
-            }
-        } else {
-            if (!array_key_exists(strtolower($address), $this->ReplyTo)) {
-                $this->ReplyTo[strtolower($address)] = array($address, $name);
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Parse and validate a string containing one or more RFC822-style comma-separated email addresses
-     * of the form "display name <address>" into an array of name/address pairs.
-     * Uses the imap_rfc822_parse_adrlist function if the IMAP extension is available.
-     * Note that quotes in the name part are removed.
-     * @param string $addrstr The address list string
-     * @param bool $useimap Whether to use the IMAP extension to parse the list
-     * @return array
-     * @link http://www.andrew.cmu.edu/user/agreen1/testing/mrbs/web/Mail/RFC822.php A more careful implementation
-     */
-    public function parseAddresses($addrstr, $useimap = true)
-    {
-        $addresses = array();
-        if ($useimap and function_exists('imap_rfc822_parse_adrlist')) {
-            //Use this built-in parser if it's available
-            $list = imap_rfc822_parse_adrlist($addrstr, '');
-            foreach ($list as $address) {
-                if ($address->host != '.SYNTAX-ERROR.') {
-                    if ($this->validateAddress($address->mailbox . '@' . $address->host)) {
-                        $addresses[] = array(
-                            'name' => (property_exists($address, 'personal') ? $address->personal : ''),
-                            'address' => $address->mailbox . '@' . $address->host
-                        );
-                    }
-                }
-            }
-        } else {
-            //Use this simpler parser
-            $list = explode(',', $addrstr);
-            foreach ($list as $address) {
-                $address = trim($address);
-                //Is there a separate name part?
-                if (strpos($address, '<') === false) {
-                    //No separate name, just use the whole thing
-                    if ($this->validateAddress($address)) {
-                        $addresses[] = array(
-                            'name' => '',
-                            'address' => $address
-                        );
-                    }
-                } else {
-                    list($name, $email) = explode('<', $address);
-                    $email = trim(str_replace('>', '', $email));
-                    if ($this->validateAddress($email)) {
-                        $addresses[] = array(
-                            'name' => trim(str_replace(array('"', "'"), '', $name)),
-                            'address' => $email
-                        );
-                    }
-                }
-            }
-        }
-        return $addresses;
-    }
-
-    /**
-     * Set the From and FromName properties.
-     * @param string $address
-     * @param string $name
-     * @param boolean $auto Whether to also set the Sender address, defaults to true
-     * @throws phpmailerException
-     * @return boolean
-     */
-    public function setFrom($address, $name = '', $auto = true)
-    {
-        $address = trim($address);
-        $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
-        // Don't validate now addresses with IDN. Will be done in send().
-        if (($pos = strrpos($address, '@')) === false or
-            (!$this->has8bitChars(substr($address, ++$pos)) or !$this->idnSupported()) and
-            !$this->validateAddress($address)) {
-            $error_message = $this->lang('invalid_address') . " (setFrom) $address";
-            $this->setError($error_message);
-            $this->edebug($error_message);
-            if ($this->exceptions) {
-                throw new phpmailerException($error_message);
-            }
-            return false;
-        }
-        $this->From = $address;
-        $this->FromName = $name;
-        if ($auto) {
-            if (empty($this->Sender)) {
-                $this->Sender = $address;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Return the Message-ID header of the last email.
-     * Technically this is the value from the last time the headers were created,
-     * but it's also the message ID of the last sent message except in
-     * pathological cases.
-     * @return string
-     */
-    public function getLastMessageID()
-    {
-        return $this->lastMessageID;
-    }
-
-    /**
-     * Check that a string looks like an email address.
-     * @param string $address The email address to check
-     * @param string|callable $patternselect A selector for the validation pattern to use :
-     * * `auto` Pick best pattern automatically;
-     * * `pcre8` Use the squiloople.com pattern, requires PCRE > 8.0, PHP >= 5.3.2, 5.2.14;
-     * * `pcre` Use old PCRE implementation;
-     * * `php` Use PHP built-in FILTER_VALIDATE_EMAIL;
-     * * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements.
-     * * `noregex` Don't use a regex: super fast, really dumb.
-     * Alternatively you may pass in a callable to inject your own validator, for example:
-     * PHPMailer::validateAddress('user@example.com', function($address) {
-     *     return (strpos($address, '@') !== false);
-     * });
-     * You can also set the PHPMailer::$validator static to a callable, allowing built-in methods to use your validator.
-     * @return boolean
-     * @static
-     * @access public
-     */
-    public static function validateAddress($address, $patternselect = null)
-    {
-        if (is_null($patternselect)) {
-            $patternselect = self::$validator;
-        }
-        if (is_callable($patternselect)) {
-            return call_user_func($patternselect, $address);
-        }
-        //Reject line breaks in addresses; it's valid RFC5322, but not RFC5321
-        if (strpos($address, "\n") !== false or strpos($address, "\r") !== false) {
-            return false;
-        }
-        if (!$patternselect or $patternselect == 'auto') {
-            //Check this constant first so it works when extension_loaded() is disabled by safe mode
-            //Constant was added in PHP 5.2.4
-            if (defined('PCRE_VERSION')) {
-                //This pattern can get stuck in a recursive loop in PCRE <= 8.0.2
-                if (version_compare(PCRE_VERSION, '8.0.3') >= 0) {
-                    $patternselect = 'pcre8';
-                } else {
-                    $patternselect = 'pcre';
-                }
-            } elseif (function_exists('extension_loaded') and extension_loaded('pcre')) {
-                //Fall back to older PCRE
-                $patternselect = 'pcre';
-            } else {
-                //Filter_var appeared in PHP 5.2.0 and does not require the PCRE extension
-                if (version_compare(PHP_VERSION, '5.2.0') >= 0) {
-                    $patternselect = 'php';
-                } else {
-                    $patternselect = 'noregex';
-                }
-            }
-        }
-        switch ($patternselect) {
-            case 'pcre8':
-                /**
-                 * Uses the same RFC5322 regex on which FILTER_VALIDATE_EMAIL is based, but allows dotless domains.
-                 * @link http://squiloople.com/2009/12/20/email-address-validation/
-                 * @copyright 2009-2010 Michael Rushton
-                 * Feel free to use and redistribute this code. But please keep this copyright notice.
-                 */
-                return (boolean)preg_match(
-                    '/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)' .
-                    '((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)' .
-                    '(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)' .
-                    '([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*' .
-                    '(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)' .
-                    '(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}' .
-                    '|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:' .
-                    '|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}' .
-                    '|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD',
-                    $address
-                );
-            case 'pcre':
-                //An older regex that doesn't need a recent PCRE
-                return (boolean)preg_match(
-                    '/^(?!(?>"?(?>\\\[ -~]|[^"])"?){255,})(?!(?>"?(?>\\\[ -~]|[^"])"?){65,}@)(?>' .
-                    '[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*")' .
-                    '(?>\.(?>[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*"))*' .
-                    '@(?>(?![a-z0-9-]{64,})(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>\.(?![a-z0-9-]{64,})' .
-                    '(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)){0,126}|\[(?:(?>IPv6:(?>(?>[a-f0-9]{1,4})(?>:' .
-                    '[a-f0-9]{1,4}){7}|(?!(?:.*[a-f0-9][:\]]){8,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?' .
-                    '::(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?))|(?>(?>IPv6:(?>[a-f0-9]{1,4}(?>:' .
-                    '[a-f0-9]{1,4}){5}:|(?!(?:.*[a-f0-9]:){6,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4})?' .
-                    '::(?>(?:[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4}):)?))?(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}' .
-                    '|[1-9]?[0-9])(?>\.(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}))\])$/isD',
-                    $address
-                );
-            case 'html5':
-                /**
-                 * This is the pattern used in the HTML5 spec for validation of 'email' type form input elements.
-                 * @link http://www.whatwg.org/specs/web-apps/current-work/#e-mail-state-(type=email)
-                 */
-                return (boolean)preg_match(
-                    '/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}' .
-                    '[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD',
-                    $address
-                );
-            case 'noregex':
-                //No PCRE! Do something _very_ approximate!
-                //Check the address is 3 chars or longer and contains an @ that's not the first or last char
-                return (strlen($address) >= 3
-                    and strpos($address, '@') >= 1
-                    and strpos($address, '@') != strlen($address) - 1);
-            case 'php':
-            default:
-                return (boolean)filter_var($address, FILTER_VALIDATE_EMAIL);
-        }
-    }
-
-    /**
-     * Tells whether IDNs (Internationalized Domain Names) are supported or not. This requires the
-     * "intl" and "mbstring" PHP extensions.
-     * @return bool "true" if required functions for IDN support are present
-     */
-    public function idnSupported()
-    {
-        // @TODO: Write our own "idn_to_ascii" function for PHP <= 5.2.
-        return function_exists('idn_to_ascii') and function_exists('mb_convert_encoding');
-    }
-
-    /**
-     * Converts IDN in given email address to its ASCII form, also known as punycode, if possible.
-     * Important: Address must be passed in same encoding as currently set in PHPMailer::$CharSet.
-     * This function silently returns unmodified address if:
-     * - No conversion is necessary (i.e. domain name is not an IDN, or is already in ASCII form)
-     * - Conversion to punycode is impossible (e.g. required PHP functions are not available)
-     *   or fails for any reason (e.g. domain has characters not allowed in an IDN)
-     * @see PHPMailer::$CharSet
-     * @param string $address The email address to convert
-     * @return string The encoded address in ASCII form
-     */
-    public function punyencodeAddress($address)
-    {
-        // Verify we have required functions, CharSet, and at-sign.
-        if ($this->idnSupported() and
-            !empty($this->CharSet) and
-            ($pos = strrpos($address, '@')) !== false) {
-            $domain = substr($address, ++$pos);
-            // Verify CharSet string is a valid one, and domain properly encoded in this CharSet.
-            if ($this->has8bitChars($domain) and @mb_check_encoding($domain, $this->CharSet)) {
-                $domain = mb_convert_encoding($domain, 'UTF-8', $this->CharSet);
-                if (($punycode = defined('INTL_IDNA_VARIANT_UTS46') ?
-                    idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46) :
-                    idn_to_ascii($domain)) !== false) {
-                    return substr($address, 0, $pos) . $punycode;
-                }
-            }
-        }
-        return $address;
-    }
-
-    /**
-     * Create a message and send it.
-     * Uses the sending method specified by $Mailer.
-     * @throws phpmailerException
-     * @return boolean false on error - See the ErrorInfo property for details of the error.
-     */
-    public function send()
-    {
-        try {
-            if (!$this->preSend()) {
-                return false;
-            }
-            return $this->postSend();
-        } catch (phpmailerException $exc) {
-            $this->mailHeader = '';
-            $this->setError($exc->getMessage());
-            if ($this->exceptions) {
-                throw $exc;
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Prepare a message for sending.
-     * @throws phpmailerException
-     * @return boolean
-     */
-    public function preSend()
-    {
-        try {
-            $this->error_count = 0; // Reset errors
-            $this->mailHeader = '';
-
-            // Dequeue recipient and Reply-To addresses with IDN
-            foreach (array_merge($this->RecipientsQueue, $this->ReplyToQueue) as $params) {
-                $params[1] = $this->punyencodeAddress($params[1]);
-                call_user_func_array(array($this, 'addAnAddress'), $params);
-            }
-            if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
-                throw new phpmailerException($this->lang('provide_address'), self::STOP_CRITICAL);
-            }
-
-            // Validate From, Sender, and ConfirmReadingTo addresses
-            foreach (array('From', 'Sender', 'ConfirmReadingTo') as $address_kind) {
-                $this->$address_kind = trim($this->$address_kind);
-                if (empty($this->$address_kind)) {
-                    continue;
-                }
-                $this->$address_kind = $this->punyencodeAddress($this->$address_kind);
-                if (!$this->validateAddress($this->$address_kind)) {
-                    $error_message = $this->lang('invalid_address') . ' (punyEncode) ' . $this->$address_kind;
-                    $this->setError($error_message);
-                    $this->edebug($error_message);
-                    if ($this->exceptions) {
-                        throw new phpmailerException($error_message);
-                    }
-                    return false;
-                }
-            }
-
-            // Set whether the message is multipart/alternative
-            if ($this->alternativeExists()) {
-                $this->ContentType = 'multipart/alternative';
-            }
-
-            $this->setMessageType();
-            // Refuse to send an empty message unless we are specifically allowing it
-            if (!$this->AllowEmpty and empty($this->Body)) {
-                throw new phpmailerException($this->lang('empty_message'), self::STOP_CRITICAL);
-            }
-
-            // Create body before headers in case body makes changes to headers (e.g. altering transfer encoding)
-            $this->MIMEHeader = '';
-            $this->MIMEBody = $this->createBody();
-            // createBody may have added some headers, so retain them
-            $tempheaders = $this->MIMEHeader;
-            $this->MIMEHeader = $this->createHeader();
-            $this->MIMEHeader .= $tempheaders;
-
-            // To capture the complete message when using mail(), create
-            // an extra header list which createHeader() doesn't fold in
-            if ($this->Mailer == 'mail') {
-                if (count($this->to) > 0) {
-                    $this->mailHeader .= $this->addrAppend('To', $this->to);
-                } else {
-                    $this->mailHeader .= $this->headerLine('To', 'undisclosed-recipients:;');
-                }
-                $this->mailHeader .= $this->headerLine(
-                    'Subject',
-                    $this->encodeHeader($this->secureHeader(trim($this->Subject)))
-                );
-            }
-
-            // Sign with DKIM if enabled
-            if (!empty($this->DKIM_domain)
-                and !empty($this->DKIM_selector)
-                and (!empty($this->DKIM_private_string)
-                    or (!empty($this->DKIM_private)
-                        and self::isPermittedPath($this->DKIM_private)
-                        and file_exists($this->DKIM_private)
-                    )
-                )
-            ) {
-                $header_dkim = $this->DKIM_Add(
-                    $this->MIMEHeader . $this->mailHeader,
-                    $this->encodeHeader($this->secureHeader($this->Subject)),
-                    $this->MIMEBody
-                );
-                $this->MIMEHeader = rtrim($this->MIMEHeader, "\r\n ") . self::CRLF .
-                    str_replace("\r\n", "\n", $header_dkim) . self::CRLF;
-            }
-            return true;
-        } catch (phpmailerException $exc) {
-            $this->setError($exc->getMessage());
-            if ($this->exceptions) {
-                throw $exc;
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Actually send a message.
-     * Send the email via the selected mechanism
-     * @throws phpmailerException
-     * @return boolean
-     */
-    public function postSend()
-    {
-        try {
-            // Choose the mailer and send through it
-            switch ($this->Mailer) {
-                case 'sendmail':
-                case 'qmail':
-                    return $this->sendmailSend($this->MIMEHeader, $this->MIMEBody);
-                case 'smtp':
-                    return $this->smtpSend($this->MIMEHeader, $this->MIMEBody);
-                case 'mail':
-                    return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
-                default:
-                    $sendMethod = $this->Mailer.'Send';
-                    if (method_exists($this, $sendMethod)) {
-                        return $this->$sendMethod($this->MIMEHeader, $this->MIMEBody);
-                    }
-
-                    return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
-            }
-        } catch (phpmailerException $exc) {
-            $this->setError($exc->getMessage());
-            $this->edebug($exc->getMessage());
-            if ($this->exceptions) {
-                throw $exc;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Send mail using the $Sendmail program.
-     * @param string $header The message headers
-     * @param string $body The message body
-     * @see PHPMailer::$Sendmail
-     * @throws phpmailerException
-     * @access protected
-     * @return boolean
-     */
-    protected function sendmailSend($header, $body)
-    {
-        // CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.
-        if (!empty($this->Sender) and self::isShellSafe($this->Sender)) {
-            if ($this->Mailer == 'qmail') {
-                $sendmailFmt = '%s -f%s';
-            } else {
-                $sendmailFmt = '%s -oi -f%s -t';
-            }
-        } else {
-            if ($this->Mailer == 'qmail') {
-                $sendmailFmt = '%s';
-            } else {
-                $sendmailFmt = '%s -oi -t';
-            }
-        }
-
-        // TODO: If possible, this should be changed to escapeshellarg.  Needs thorough testing.
-        $sendmail = sprintf($sendmailFmt, escapeshellcmd($this->Sendmail), $this->Sender);
-
-        if ($this->SingleTo) {
-            foreach ($this->SingleToArray as $toAddr) {
-                if (!@$mail = popen($sendmail, 'w')) {
-                    throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
-                }
-                fputs($mail, 'To: ' . $toAddr . "\n");
-                fputs($mail, $header);
-                fputs($mail, $body);
-                $result = pclose($mail);
-                $this->doCallback(
-                    ($result == 0),
-                    array($toAddr),
-                    $this->cc,
-                    $this->bcc,
-                    $this->Subject,
-                    $body,
-                    $this->From
-                );
-                if ($result != 0) {
-                    throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
-                }
-            }
-        } else {
-            if (!@$mail = popen($sendmail, 'w')) {
-                throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
-            }
-            fputs($mail, $header);
-            fputs($mail, $body);
-            $result = pclose($mail);
-            $this->doCallback(
-                ($result == 0),
-                $this->to,
-                $this->cc,
-                $this->bcc,
-                $this->Subject,
-                $body,
-                $this->From
-            );
-            if ($result != 0) {
-                throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Fix CVE-2016-10033 and CVE-2016-10045 by disallowing potentially unsafe shell characters.
-     *
-     * Note that escapeshellarg and escapeshellcmd are inadequate for our purposes, especially on Windows.
-     * @param string $string The string to be validated
-     * @see https://github.com/PHPMailer/PHPMailer/issues/924 CVE-2016-10045 bug report
-     * @access protected
-     * @return boolean
-     */
-    protected static function isShellSafe($string)
-    {
-        // Future-proof
-        if (escapeshellcmd($string) !== $string
-            or !in_array(escapeshellarg($string), array("'$string'", "\"$string\""))
-        ) {
-            return false;
-        }
-
-        $length = strlen($string);
-
-        for ($i = 0; $i < $length; $i++) {
-            $c = $string[$i];
-
-            // All other characters have a special meaning in at least one common shell, including = and +.
-            // Full stop (.) has a special meaning in cmd.exe, but its impact should be negligible here.
-            // Note that this does permit non-Latin alphanumeric characters based on the current locale.
-            if (!ctype_alnum($c) && strpos('@_-.', $c) === false) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Check whether a file path is of a permitted type.
-     * Used to reject URLs and phar files from functions that access local file paths,
-     * such as addAttachment.
-     * @param string $path A relative or absolute path to a file.
-     * @return bool
-     */
-    protected static function isPermittedPath($path)
-    {
-        return !preg_match('#^[a-z]+://#i', $path);
-    }
-
-    /**
-     * Send mail using the PHP mail() function.
-     * @param string $header The message headers
-     * @param string $body The message body
-     * @link http://www.php.net/manual/en/book.mail.php
-     * @throws phpmailerException
-     * @access protected
-     * @return boolean
-     */
-    protected function mailSend($header, $body)
-    {
-        $toArr = array();
-        foreach ($this->to as $toaddr) {
-            $toArr[] = $this->addrFormat($toaddr);
-        }
-        $to = implode(', ', $toArr);
-
-        $params = null;
-        //This sets the SMTP envelope sender which gets turned into a return-path header by the receiver
-        if (!empty($this->Sender) and $this->validateAddress($this->Sender)) {
-            // CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.
-            if (self::isShellSafe($this->Sender)) {
-                $params = sprintf('-f%s', $this->Sender);
-            }
-        }
-        if (!empty($this->Sender) and !ini_get('safe_mode') and $this->validateAddress($this->Sender)) {
-            $old_from = ini_get('sendmail_from');
-            ini_set('sendmail_from', $this->Sender);
-        }
-        $result = false;
-        if ($this->SingleTo and count($toArr) > 1) {
-            foreach ($toArr as $toAddr) {
-                $result = $this->mailPassthru($toAddr, $this->Subject, $body, $header, $params);
-                $this->doCallback($result, array($toAddr), $this->cc, $this->bcc, $this->Subject, $body, $this->From);
-            }
-        } else {
-            $result = $this->mailPassthru($to, $this->Subject, $body, $header, $params);
-            $this->doCallback($result, $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
-        }
-        if (isset($old_from)) {
-            ini_set('sendmail_from', $old_from);
-        }
-        if (!$result) {
-            throw new phpmailerException($this->lang('instantiate'), self::STOP_CRITICAL);
-        }
-        return true;
-    }
-
-    /**
-     * Get an instance to use for SMTP operations.
-     * Override this function to load your own SMTP implementation
-     * @return SMTP
-     */
-    public function getSMTPInstance()
-    {
-        if (!is_object($this->smtp)) {
-            $this->smtp = new SMTP;
-        }
-        return $this->smtp;
-    }
-
-    /**
-     * Send mail via SMTP.
-     * Returns false if there is a bad MAIL FROM, RCPT, or DATA input.
-     * Uses the PHPMailerSMTP class by default.
-     * @see PHPMailer::getSMTPInstance() to use a different class.
-     * @param string $header The message headers
-     * @param string $body The message body
-     * @throws phpmailerException
-     * @uses SMTP
-     * @access protected
-     * @return boolean
-     */
-    protected function smtpSend($header, $body)
-    {
-        $bad_rcpt = array();
-        if (!$this->smtpConnect($this->SMTPOptions)) {
-            throw new phpmailerException($this->lang('smtp_connect_failed'), self::STOP_CRITICAL);
-        }
-        if (!empty($this->Sender) and $this->validateAddress($this->Sender)) {
-            $smtp_from = $this->Sender;
-        } else {
-            $smtp_from = $this->From;
-        }
-        if (!$this->smtp->mail($smtp_from)) {
-            $this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError()));
-            throw new phpmailerException($this->ErrorInfo, self::STOP_CRITICAL);
-        }
-
-        // Attempt to send to all recipients
-        foreach (array($this->to, $this->cc, $this->bcc) as $togroup) {
-            foreach ($togroup as $to) {
-                if (!$this->smtp->recipient($to[0])) {
-                    $error = $this->smtp->getError();
-                    $bad_rcpt[] = array('to' => $to[0], 'error' => $error['detail']);
-                    $isSent = false;
-                } else {
-                    $isSent = true;
-                }
-                $this->doCallback($isSent, array($to[0]), array(), array(), $this->Subject, $body, $this->From);
-            }
-        }
-
-        // Only send the DATA command if we have viable recipients
-        if ((count($this->all_recipients) > count($bad_rcpt)) and !$this->smtp->data($header . $body)) {
-            throw new phpmailerException($this->lang('data_not_accepted'), self::STOP_CRITICAL);
-        }
-        if ($this->SMTPKeepAlive) {
-            $this->smtp->reset();
-        } else {
-            $this->smtp->quit();
-            $this->smtp->close();
-        }
-        //Create error message for any bad addresses
-        if (count($bad_rcpt) > 0) {
-            $errstr = '';
-            foreach ($bad_rcpt as $bad) {
-                $errstr .= $bad['to'] . ': ' . $bad['error'];
-            }
-            throw new phpmailerException(
-                $this->lang('recipients_failed') . $errstr,
-                self::STOP_CONTINUE
-            );
-        }
-        return true;
-    }
-
-    /**
-     * Initiate a connection to an SMTP server.
-     * Returns false if the operation failed.
-     * @param array $options An array of options compatible with stream_context_create()
-     * @uses SMTP
-     * @access public
-     * @throws phpmailerException
-     * @return boolean
-     */
-    public function smtpConnect($options = null)
-    {
-        if (is_null($this->smtp)) {
-            $this->smtp = $this->getSMTPInstance();
-        }
-
-        //If no options are provided, use whatever is set in the instance
-        if (is_null($options)) {
-            $options = $this->SMTPOptions;
-        }
-
-        // Already connected?
-        if ($this->smtp->connected()) {
-            return true;
-        }
-
-        $this->smtp->setTimeout($this->Timeout);
-        $this->smtp->setDebugLevel($this->SMTPDebug);
-        $this->smtp->setDebugOutput($this->Debugoutput);
-        $this->smtp->setVerp($this->do_verp);
-        $hosts = explode(';', $this->Host);
-        $lastexception = null;
-
-        foreach ($hosts as $hostentry) {
-            $hostinfo = array();
-            if (!preg_match(
-                '/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*|\[[a-fA-F0-9:]+\]):?([0-9]*)$/',
-                trim($hostentry),
-                $hostinfo
-            )) {
-                // Not a valid host entry
-                $this->edebug('Ignoring invalid host: ' . $hostentry);
-                continue;
-            }
-            // $hostinfo[2]: optional ssl or tls prefix
-            // $hostinfo[3]: the hostname
-            // $hostinfo[4]: optional port number
-            // The host string prefix can temporarily override the current setting for SMTPSecure
-            // If it's not specified, the default value is used
-            $prefix = '';
-            $secure = $this->SMTPSecure;
-            $tls = ($this->SMTPSecure == 'tls');
-            if ('ssl' == $hostinfo[2] or ('' == $hostinfo[2] and 'ssl' == $this->SMTPSecure)) {
-                $prefix = 'ssl://';
-                $tls = false; // Can't have SSL and TLS at the same time
-                $secure = 'ssl';
-            } elseif ($hostinfo[2] == 'tls') {
-                $tls = true;
-                // tls doesn't use a prefix
-                $secure = 'tls';
-            }
-            //Do we need the OpenSSL extension?
-            $sslext = defined('OPENSSL_ALGO_SHA1');
-            if ('tls' === $secure or 'ssl' === $secure) {
-                //Check for an OpenSSL constant rather than using extension_loaded, which is sometimes disabled
-                if (!$sslext) {
-                    throw new phpmailerException($this->lang('extension_missing').'openssl', self::STOP_CRITICAL);
-                }
-            }
-            $host = $hostinfo[3];
-            $port = $this->Port;
-            $tport = (integer)$hostinfo[4];
-            if ($tport > 0 and $tport < 65536) {
-                $port = $tport;
-            }
-            if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) {
-                try {
-                    if ($this->Helo) {
-                        $hello = $this->Helo;
-                    } else {
-                        $hello = $this->serverHostname();
-                    }
-                    $this->smtp->hello($hello);
-                    //Automatically enable TLS encryption if:
-                    // * it's not disabled
-                    // * we have openssl extension
-                    // * we are not already using SSL
-                    // * the server offers STARTTLS
-                    if ($this->SMTPAutoTLS and $sslext and $secure != 'ssl' and $this->smtp->getServerExt('STARTTLS')) {
-                        $tls = true;
-                    }
-                    if ($tls) {
-                        if (!$this->smtp->startTLS()) {
-                            throw new phpmailerException($this->lang('connect_host'));
-                        }
-                        // We must resend EHLO after TLS negotiation
-                        $this->smtp->hello($hello);
-                    }
-                    if ($this->SMTPAuth) {
-                        if (!$this->smtp->authenticate(
-                            $this->Username,
-                            $this->Password,
-                            $this->AuthType,
-                            $this->Realm,
-                            $this->Workstation
-                        )
-                        ) {
-                            throw new phpmailerException($this->lang('authenticate'));
-                        }
-                    }
-                    return true;
-                } catch (phpmailerException $exc) {
-                    $lastexception = $exc;
-                    $this->edebug($exc->getMessage());
-                    // We must have connected, but then failed TLS or Auth, so close connection nicely
-                    $this->smtp->quit();
-                }
-            }
-        }
-        // If we get here, all connection attempts have failed, so close connection hard
-        $this->smtp->close();
-        // As we've caught all exceptions, just report whatever the last one was
-        if ($this->exceptions and !is_null($lastexception)) {
-            throw $lastexception;
-        }
-        return false;
-    }
-
-    /**
-     * Close the active SMTP session if one exists.
-     * @return void
-     */
-    public function smtpClose()
-    {
-        if (is_a($this->smtp, 'SMTP')) {
-            if ($this->smtp->connected()) {
-                $this->smtp->quit();
-                $this->smtp->close();
-            }
-        }
-    }
-
-    /**
-     * Set the language for error messages.
-     * Returns false if it cannot load the language file.
-     * The default language is English.
-     * @param string $langcode ISO 639-1 2-character language code (e.g. French is "fr")
-     * @param string $lang_path Path to the language file directory, with trailing separator (slash)
-     * @return boolean
-     * @access public
-     */
-    public function setLanguage($langcode = 'en', $lang_path = '')
-    {
-        // Backwards compatibility for renamed language codes
-        $renamed_langcodes = array(
-            'br' => 'pt_br',
-            'cz' => 'cs',
-            'dk' => 'da',
-            'no' => 'nb',
-            'se' => 'sv',
-            'sr' => 'rs'
-        );
-
-        if (isset($renamed_langcodes[$langcode])) {
-            $langcode = $renamed_langcodes[$langcode];
-        }
-
-        // Define full set of translatable strings in English
-        $PHPMAILER_LANG = array(
-            'authenticate' => 'SMTP Error: Could not authenticate.',
-            'connect_host' => 'SMTP Error: Could not connect to SMTP host.',
-            'data_not_accepted' => 'SMTP Error: data not accepted.',
-            'empty_message' => 'Message body empty',
-            'encoding' => 'Unknown encoding: ',
-            'execute' => 'Could not execute: ',
-            'file_access' => 'Could not access file: ',
-            'file_open' => 'File Error: Could not open file: ',
-            'from_failed' => 'The following From address failed: ',
-            'instantiate' => 'Could not instantiate mail function.',
-            'invalid_address' => 'Invalid address: ',
-            'mailer_not_supported' => ' mailer is not supported.',
-            'provide_address' => 'You must provide at least one recipient email address.',
-            'recipients_failed' => 'SMTP Error: The following recipients failed: ',
-            'signing' => 'Signing Error: ',
-            'smtp_connect_failed' => 'SMTP connect() failed.',
-            'smtp_error' => 'SMTP server error: ',
-            'variable_set' => 'Cannot set or reset variable: ',
-            'extension_missing' => 'Extension missing: '
-        );
-        if (empty($lang_path)) {
-            // Calculate an absolute path so it can work if CWD is not here
-            $lang_path = dirname(__FILE__). DIRECTORY_SEPARATOR . 'language'. DIRECTORY_SEPARATOR;
-        }
-        //Validate $langcode
-        if (!preg_match('/^[a-z]{2}(?:_[a-zA-Z]{2})?$/', $langcode)) {
-            $langcode = 'en';
-        }
-        $foundlang = true;
-        $lang_file = $lang_path . 'phpmailer.lang-' . $langcode . '.php';
-        // There is no English translation file
-        if ($langcode != 'en') {
-            // Make sure language file path is readable
-            if (!self::isPermittedPath($lang_file) or !is_readable($lang_file)) {
-                $foundlang = false;
-            } else {
-                // Overwrite language-specific strings.
-                // This way we'll never have missing translation keys.
-                $foundlang = include $lang_file;
-            }
-        }
-        $this->language = $PHPMAILER_LANG;
-        return (boolean)$foundlang; // Returns false if language not found
-    }
-
-    /**
-     * Get the array of strings for the current language.
-     * @return array
-     */
-    public function getTranslations()
-    {
-        return $this->language;
-    }
-
-    /**
-     * Create recipient headers.
-     * @access public
-     * @param string $type
-     * @param array $addr An array of recipient,
-     * where each recipient is a 2-element indexed array with element 0 containing an address
-     * and element 1 containing a name, like:
-     * array(array('joe@example.com', 'Joe User'), array('zoe@example.com', 'Zoe User'))
-     * @return string
-     */
-    public function addrAppend($type, $addr)
-    {
-        $addresses = array();
-        foreach ($addr as $address) {
-            $addresses[] = $this->addrFormat($address);
-        }
-        return $type . ': ' . implode(', ', $addresses) . $this->LE;
-    }
-
-    /**
-     * Format an address for use in a message header.
-     * @access public
-     * @param array $addr A 2-element indexed array, element 0 containing an address, element 1 containing a name
-     *      like array('joe@example.com', 'Joe User')
-     * @return string
-     */
-    public function addrFormat($addr)
-    {
-        if (empty($addr[1])) { // No name provided
-            return $this->secureHeader($addr[0]);
-        } else {
-            return $this->encodeHeader($this->secureHeader($addr[1]), 'phrase') . ' <' . $this->secureHeader(
-                $addr[0]
-            ) . '>';
-        }
-    }
-
-    /**
-     * Word-wrap message.
-     * For use with mailers that do not automatically perform wrapping
-     * and for quoted-printable encoded messages.
-     * Original written by philippe.
-     * @param string $message The message to wrap
-     * @param integer $length The line length to wrap to
-     * @param boolean $qp_mode Whether to run in Quoted-Printable mode
-     * @access public
-     * @return string
-     */
-    public function wrapText($message, $length, $qp_mode = false)
-    {
-        if ($qp_mode) {
-            $soft_break = sprintf(' =%s', $this->LE);
-        } else {
-            $soft_break = $this->LE;
-        }
-        // If utf-8 encoding is used, we will need to make sure we don't
-        // split multibyte characters when we wrap
-        $is_utf8 = (strtolower($this->CharSet) == 'utf-8');
-        $lelen = strlen($this->LE);
-        $crlflen = strlen(self::CRLF);
-
-        $message = $this->fixEOL($message);
-        //Remove a trailing line break
-        if (substr($message, -$lelen) == $this->LE) {
-            $message = substr($message, 0, -$lelen);
-        }
-
-        //Split message into lines
-        $lines = explode($this->LE, $message);
-        //Message will be rebuilt in here
-        $message = '';
-        foreach ($lines as $line) {
-            $words = explode(' ', $line);
-            $buf = '';
-            $firstword = true;
-            foreach ($words as $word) {
-                if ($qp_mode and (strlen($word) > $length)) {
-                    $space_left = $length - strlen($buf) - $crlflen;
-                    if (!$firstword) {
-                        if ($space_left > 20) {
-                            $len = $space_left;
-                            if ($is_utf8) {
-                                $len = $this->utf8CharBoundary($word, $len);
-                            } elseif (substr($word, $len - 1, 1) == '=') {
-                                $len--;
-                            } elseif (substr($word, $len - 2, 1) == '=') {
-                                $len -= 2;
-                            }
-                            $part = substr($word, 0, $len);
-                            $word = substr($word, $len);
-                            $buf .= ' ' . $part;
-                            $message .= $buf . sprintf('=%s', self::CRLF);
-                        } else {
-                            $message .= $buf . $soft_break;
-                        }
-                        $buf = '';
-                    }
-                    while (strlen($word) > 0) {
-                        if ($length <= 0) {
-                            break;
-                        }
-                        $len = $length;
-                        if ($is_utf8) {
-                            $len = $this->utf8CharBoundary($word, $len);
-                        } elseif (substr($word, $len - 1, 1) == '=') {
-                            $len--;
-                        } elseif (substr($word, $len - 2, 1) == '=') {
-                            $len -= 2;
-                        }
-                        $part = substr($word, 0, $len);
-                        $word = substr($word, $len);
-
-                        if (strlen($word) > 0) {
-                            $message .= $part . sprintf('=%s', self::CRLF);
-                        } else {
-                            $buf = $part;
-                        }
-                    }
-                } else {
-                    $buf_o = $buf;
-                    if (!$firstword) {
-                        $buf .= ' ';
-                    }
-                    $buf .= $word;
-
-                    if (strlen($buf) > $length and $buf_o != '') {
-                        $message .= $buf_o . $soft_break;
-                        $buf = $word;
-                    }
-                }
-                $firstword = false;
-            }
-            $message .= $buf . self::CRLF;
-        }
-
-        return $message;
-    }
-
-    /**
-     * Find the last character boundary prior to $maxLength in a utf-8
-     * quoted-printable encoded string.
-     * Original written by Colin Brown.
-     * @access public
-     * @param string $encodedText utf-8 QP text
-     * @param integer $maxLength Find the last character boundary prior to this length
-     * @return integer
-     */
-    public function utf8CharBoundary($encodedText, $maxLength)
-    {
-        $foundSplitPos = false;
-        $lookBack = 3;
-        while (!$foundSplitPos) {
-            $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
-            $encodedCharPos = strpos($lastChunk, '=');
-            if (false !== $encodedCharPos) {
-                // Found start of encoded character byte within $lookBack block.
-                // Check the encoded byte value (the 2 chars after the '=')
-                $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
-                $dec = hexdec($hex);
-                if ($dec < 128) {
-                    // Single byte character.
-                    // If the encoded char was found at pos 0, it will fit
-                    // otherwise reduce maxLength to start of the encoded char
-                    if ($encodedCharPos > 0) {
-                        $maxLength = $maxLength - ($lookBack - $encodedCharPos);
-                    }
-                    $foundSplitPos = true;
-                } elseif ($dec >= 192) {
-                    // First byte of a multi byte character
-                    // Reduce maxLength to split at start of character
-                    $maxLength = $maxLength - ($lookBack - $encodedCharPos);
-                    $foundSplitPos = true;
-                } elseif ($dec < 192) {
-                    // Middle byte of a multi byte character, look further back
-                    $lookBack += 3;
-                }
-            } else {
-                // No encoded character found
-                $foundSplitPos = true;
-            }
-        }
-        return $maxLength;
-    }
-
-    /**
-     * Apply word wrapping to the message body.
-     * Wraps the message body to the number of chars set in the WordWrap property.
-     * You should only do this to plain-text bodies as wrapping HTML tags may break them.
-     * This is called automatically by createBody(), so you don't need to call it yourself.
-     * @access public
-     * @return void
-     */
-    public function setWordWrap()
-    {
-        if ($this->WordWrap < 1) {
-            return;
-        }
-
-        switch ($this->message_type) {
-            case 'alt':
-            case 'alt_inline':
-            case 'alt_attach':
-            case 'alt_inline_attach':
-                $this->AltBody = $this->wrapText($this->AltBody, $this->WordWrap);
-                break;
-            default:
-                $this->Body = $this->wrapText($this->Body, $this->WordWrap);
-                break;
-        }
-    }
-
-    /**
-     * Assemble message headers.
-     * @access public
-     * @return string The assembled headers
-     */
-    public function createHeader()
-    {
-        $result = '';
-
-        $result .= $this->headerLine('Date', $this->MessageDate == '' ? self::rfcDate() : $this->MessageDate);
-
-        // To be created automatically by mail()
-        if ($this->SingleTo) {
-            if ($this->Mailer != 'mail') {
-                foreach ($this->to as $toaddr) {
-                    $this->SingleToArray[] = $this->addrFormat($toaddr);
-                }
-            }
-        } else {
-            if (count($this->to) > 0) {
-                if ($this->Mailer != 'mail') {
-                    $result .= $this->addrAppend('To', $this->to);
-                }
-            } elseif (count($this->cc) == 0) {
-                $result .= $this->headerLine('To', 'undisclosed-recipients:;');
-            }
-        }
-
-        $result .= $this->addrAppend('From', array(array(trim($this->From), $this->FromName)));
-
-        // sendmail and mail() extract Cc from the header before sending
-        if (count($this->cc) > 0) {
-            $result .= $this->addrAppend('Cc', $this->cc);
-        }
-
-        // sendmail and mail() extract Bcc from the header before sending
-        if ((
-                $this->Mailer == 'sendmail' or $this->Mailer == 'qmail' or $this->Mailer == 'mail'
-            )
-            and count($this->bcc) > 0
-        ) {
-            $result .= $this->addrAppend('Bcc', $this->bcc);
-        }
-
-        if (count($this->ReplyTo) > 0) {
-            $result .= $this->addrAppend('Reply-To', $this->ReplyTo);
-        }
-
-        // mail() sets the subject itself
-        if ($this->Mailer != 'mail') {
-            $result .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader($this->Subject)));
-        }
-
-        // Only allow a custom message ID if it conforms to RFC 5322 section 3.6.4
-        // https://tools.ietf.org/html/rfc5322#section-3.6.4
-        if ('' != $this->MessageID and preg_match('/^<.*@.*>$/', $this->MessageID)) {
-            $this->lastMessageID = $this->MessageID;
-        } else {
-            $this->lastMessageID = sprintf('<%s@%s>', $this->uniqueid, $this->serverHostname());
-        }
-        $result .= $this->headerLine('Message-ID', $this->lastMessageID);
-        if (!is_null($this->Priority)) {
-            $result .= $this->headerLine('X-Priority', $this->Priority);
-        }
-        if ($this->XMailer == '') {
-            $result .= $this->headerLine(
-                'X-Mailer',
-                'PHPMailer ' . $this->Version . ' (https://github.com/PHPMailer/PHPMailer)'
-            );
-        } else {
-            $myXmailer = trim($this->XMailer);
-            if ($myXmailer) {
-                $result .= $this->headerLine('X-Mailer', $myXmailer);
-            }
-        }
-
-        if ($this->ConfirmReadingTo != '') {
-            $result .= $this->headerLine('Disposition-Notification-To', '<' . $this->ConfirmReadingTo . '>');
-        }
-
-        // Add custom headers
-        foreach ($this->CustomHeader as $header) {
-            $result .= $this->headerLine(
-                trim($header[0]),
-                $this->encodeHeader(trim($header[1]))
-            );
-        }
-        if (!$this->sign_key_file) {
-            $result .= $this->headerLine('MIME-Version', '1.0');
-            $result .= $this->getMailMIME();
-        }
-
-        return $result;
-    }
-
-    /**
-     * Get the message MIME type headers.
-     * @access public
-     * @return string
-     */
-    public function getMailMIME()
-    {
-        $result = '';
-        $ismultipart = true;
-        switch ($this->message_type) {
-            case 'inline':
-                $result .= $this->headerLine('Content-Type', 'multipart/related;');
-                $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"');
-                break;
-            case 'attach':
-            case 'inline_attach':
-            case 'alt_attach':
-            case 'alt_inline_attach':
-                $result .= $this->headerLine('Content-Type', 'multipart/mixed;');
-                $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"');
-                break;
-            case 'alt':
-            case 'alt_inline':
-                $result .= $this->headerLine('Content-Type', 'multipart/alternative;');
-                $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"');
-                break;
-            default:
-                // Catches case 'plain': and case '':
-                $result .= $this->textLine('Content-Type: ' . $this->ContentType . '; charset=' . $this->CharSet);
-                $ismultipart = false;
-                break;
-        }
-        // RFC1341 part 5 says 7bit is assumed if not specified
-        if ($this->Encoding != '7bit') {
-            // RFC 2045 section 6.4 says multipart MIME parts may only use 7bit, 8bit or binary CTE
-            if ($ismultipart) {
-                if ($this->Encoding == '8bit') {
-                    $result .= $this->headerLine('Content-Transfer-Encoding', '8bit');
-                }
-                // The only remaining alternatives are quoted-printable and base64, which are both 7bit compatible
-            } else {
-                $result .= $this->headerLine('Content-Transfer-Encoding', $this->Encoding);
-            }
-        }
-
-        if ($this->Mailer != 'mail') {
-            $result .= $this->LE;
-        }
-
-        return $result;
-    }
-
-    /**
-     * Returns the whole MIME message.
-     * Includes complete headers and body.
-     * Only valid post preSend().
-     * @see PHPMailer::preSend()
-     * @access public
-     * @return string
-     */
-    public function getSentMIMEMessage()
-    {
-        return rtrim($this->MIMEHeader . $this->mailHeader, "\n\r") . self::CRLF . self::CRLF . $this->MIMEBody;
-    }
-
-    /**
-     * Create unique ID
-     * @return string
-     */
-    protected function generateId() {
-        return md5(uniqid(time()));
-    }
-
-    /**
-     * Assemble the message body.
-     * Returns an empty string on failure.
-     * @access public
-     * @throws phpmailerException
-     * @return string The assembled message body
-     */
-    public function createBody()
-    {
-        $body = '';
-        //Create unique IDs and preset boundaries
-        $this->uniqueid = $this->generateId();
-        $this->boundary[1] = 'b1_' . $this->uniqueid;
-        $this->boundary[2] = 'b2_' . $this->uniqueid;
-        $this->boundary[3] = 'b3_' . $this->uniqueid;
-
-        if ($this->sign_key_file) {
-            $body .= $this->getMailMIME() . $this->LE;
-        }
-
-        $this->setWordWrap();
-
-        $bodyEncoding = $this->Encoding;
-        $bodyCharSet = $this->CharSet;
-        //Can we do a 7-bit downgrade?
-        if ($bodyEncoding == '8bit' and !$this->has8bitChars($this->Body)) {
-            $bodyEncoding = '7bit';
-            //All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit
-            $bodyCharSet = 'us-ascii';
-        }
-        //If lines are too long, and we're not already using an encoding that will shorten them,
-        //change to quoted-printable transfer encoding for the body part only
-        if ('base64' != $this->Encoding and self::hasLineLongerThanMax($this->Body)) {
-            $bodyEncoding = 'quoted-printable';
-        }
-
-        $altBodyEncoding = $this->Encoding;
-        $altBodyCharSet = $this->CharSet;
-        //Can we do a 7-bit downgrade?
-        if ($altBodyEncoding == '8bit' and !$this->has8bitChars($this->AltBody)) {
-            $altBodyEncoding = '7bit';
-            //All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit
-            $altBodyCharSet = 'us-ascii';
-        }
-        //If lines are too long, and we're not already using an encoding that will shorten them,
-        //change to quoted-printable transfer encoding for the alt body part only
-        if ('base64' != $altBodyEncoding and self::hasLineLongerThanMax($this->AltBody)) {
-            $altBodyEncoding = 'quoted-printable';
-        }
-        //Use this as a preamble in all multipart message types
-        $mimepre = "This is a multi-part message in MIME format." . $this->LE . $this->LE;
-        switch ($this->message_type) {
-            case 'inline':
-                $body .= $mimepre;
-                $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding);
-                $body .= $this->encodeString($this->Body, $bodyEncoding);
-                $body .= $this->LE . $this->LE;
-                $body .= $this->attachAll('inline', $this->boundary[1]);
-                break;
-            case 'attach':
-                $body .= $mimepre;
-                $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding);
-                $body .= $this->encodeString($this->Body, $bodyEncoding);
-                $body .= $this->LE . $this->LE;
-                $body .= $this->attachAll('attachment', $this->boundary[1]);
-                break;
-            case 'inline_attach':
-                $body .= $mimepre;
-                $body .= $this->textLine('--' . $this->boundary[1]);
-                $body .= $this->headerLine('Content-Type', 'multipart/related;');
-                $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
-                $body .= $this->LE;
-                $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, '', $bodyEncoding);
-                $body .= $this->encodeString($this->Body, $bodyEncoding);
-                $body .= $this->LE . $this->LE;
-                $body .= $this->attachAll('inline', $this->boundary[2]);
-                $body .= $this->LE;
-                $body .= $this->attachAll('attachment', $this->boundary[1]);
-                break;
-            case 'alt':
-                $body .= $mimepre;
-                $body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding);
-                $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
-                $body .= $this->LE . $this->LE;
-                $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, 'text/html', $bodyEncoding);
-                $body .= $this->encodeString($this->Body, $bodyEncoding);
-                $body .= $this->LE . $this->LE;
-                if (!empty($this->Ical)) {
-                    $body .= $this->getBoundary($this->boundary[1], '', 'text/calendar; method=REQUEST', '');
-                    $body .= $this->encodeString($this->Ical, $this->Encoding);
-                    $body .= $this->LE . $this->LE;
-                }
-                $body .= $this->endBoundary($this->boundary[1]);
-                break;
-            case 'alt_inline':
-                $body .= $mimepre;
-                $body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding);
-                $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
-                $body .= $this->LE . $this->LE;
-                $body .= $this->textLine('--' . $this->boundary[1]);
-                $body .= $this->headerLine('Content-Type', 'multipart/related;');
-                $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
-                $body .= $this->LE;
-                $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, 'text/html', $bodyEncoding);
-                $body .= $this->encodeString($this->Body, $bodyEncoding);
-                $body .= $this->LE . $this->LE;
-                $body .= $this->attachAll('inline', $this->boundary[2]);
-                $body .= $this->LE;
-                $body .= $this->endBoundary($this->boundary[1]);
-                break;
-            case 'alt_attach':
-                $body .= $mimepre;
-                $body .= $this->textLine('--' . $this->boundary[1]);
-                $body .= $this->headerLine('Content-Type', 'multipart/alternative;');
-                $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
-                $body .= $this->LE;
-                $body .= $this->getBoundary($this->boundary[2], $altBodyCharSet, 'text/plain', $altBodyEncoding);
-                $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
-                $body .= $this->LE . $this->LE;
-                $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, 'text/html', $bodyEncoding);
-                $body .= $this->encodeString($this->Body, $bodyEncoding);
-                $body .= $this->LE . $this->LE;
-                $body .= $this->endBoundary($this->boundary[2]);
-                $body .= $this->LE;
-                $body .= $this->attachAll('attachment', $this->boundary[1]);
-                break;
-            case 'alt_inline_attach':
-                $body .= $mimepre;
-                $body .= $this->textLine('--' . $this->boundary[1]);
-                $body .= $this->headerLine('Content-Type', 'multipart/alternative;');
-                $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
-                $body .= $this->LE;
-                $body .= $this->getBoundary($this->boundary[2], $altBodyCharSet, 'text/plain', $altBodyEncoding);
-                $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
-                $body .= $this->LE . $this->LE;
-                $body .= $this->textLine('--' . $this->boundary[2]);
-                $body .= $this->headerLine('Content-Type', 'multipart/related;');
-                $body .= $this->textLine("\tboundary=\"" . $this->boundary[3] . '"');
-                $body .= $this->LE;
-                $body .= $this->getBoundary($this->boundary[3], $bodyCharSet, 'text/html', $bodyEncoding);
-                $body .= $this->encodeString($this->Body, $bodyEncoding);
-                $body .= $this->LE . $this->LE;
-                $body .= $this->attachAll('inline', $this->boundary[3]);
-                $body .= $this->LE;
-                $body .= $this->endBoundary($this->boundary[2]);
-                $body .= $this->LE;
-                $body .= $this->attachAll('attachment', $this->boundary[1]);
-                break;
-            default:
-                // Catch case 'plain' and case '', applies to simple `text/plain` and `text/html` body content types
-                //Reset the `Encoding` property in case we changed it for line length reasons
-                $this->Encoding = $bodyEncoding;
-                $body .= $this->encodeString($this->Body, $this->Encoding);
-                break;
-        }
-
-        if ($this->isError()) {
-            $body = '';
-        } elseif ($this->sign_key_file) {
-            try {
-                if (!defined('PKCS7_TEXT')) {
-                    throw new phpmailerException($this->lang('extension_missing') . 'openssl');
-                }
-                // @TODO would be nice to use php://temp streams here, but need to wrap for PHP < 5.1
-                $file = tempnam(sys_get_temp_dir(), 'mail');
-                if (false === file_put_contents($file, $body)) {
-                    throw new phpmailerException($this->lang('signing') . ' Could not write temp file');
-                }
-                $signed = tempnam(sys_get_temp_dir(), 'signed');
-                //Workaround for PHP bug https://bugs.php.net/bug.php?id=69197
-                if (empty($this->sign_extracerts_file)) {
-                    $sign = @openssl_pkcs7_sign(
-                        $file,
-                        $signed,
-                        'file://' . realpath($this->sign_cert_file),
-                        array('file://' . realpath($this->sign_key_file), $this->sign_key_pass),
-                        null
-                    );
-                } else {
-                    $sign = @openssl_pkcs7_sign(
-                        $file,
-                        $signed,
-                        'file://' . realpath($this->sign_cert_file),
-                        array('file://' . realpath($this->sign_key_file), $this->sign_key_pass),
-                        null,
-                        PKCS7_DETACHED,
-                        $this->sign_extracerts_file
-                    );
-                }
-                if ($sign) {
-                    @unlink($file);
-                    $body = file_get_contents($signed);
-                    @unlink($signed);
-                    //The message returned by openssl contains both headers and body, so need to split them up
-                    $parts = explode("\n\n", $body, 2);
-                    $this->MIMEHeader .= $parts[0] . $this->LE . $this->LE;
-                    $body = $parts[1];
-                } else {
-                    @unlink($file);
-                    @unlink($signed);
-                    throw new phpmailerException($this->lang('signing') . openssl_error_string());
-                }
-            } catch (phpmailerException $exc) {
-                $body = '';
-                if ($this->exceptions) {
-                    throw $exc;
-                }
-            }
-        }
-        return $body;
-    }
-
-    /**
-     * Return the start of a message boundary.
-     * @access protected
-     * @param string $boundary
-     * @param string $charSet
-     * @param string $contentType
-     * @param string $encoding
-     * @return string
-     */
-    protected function getBoundary($boundary, $charSet, $contentType, $encoding)
-    {
-        $result = '';
-        if ($charSet == '') {
-            $charSet = $this->CharSet;
-        }
-        if ($contentType == '') {
-            $contentType = $this->ContentType;
-        }
-        if ($encoding == '') {
-            $encoding = $this->Encoding;
-        }
-        $result .= $this->textLine('--' . $boundary);
-        $result .= sprintf('Content-Type: %s; charset=%s', $contentType, $charSet);
-        $result .= $this->LE;
-        // RFC1341 part 5 says 7bit is assumed if not specified
-        if ($encoding != '7bit') {
-            $result .= $this->headerLine('Content-Transfer-Encoding', $encoding);
-        }
-        $result .= $this->LE;
-
-        return $result;
-    }
-
-    /**
-     * Return the end of a message boundary.
-     * @access protected
-     * @param string $boundary
-     * @return string
-     */
-    protected function endBoundary($boundary)
-    {
-        return $this->LE . '--' . $boundary . '--' . $this->LE;
-    }
-
-    /**
-     * Set the message type.
-     * PHPMailer only supports some preset message types, not arbitrary MIME structures.
-     * @access protected
-     * @return void
-     */
-    protected function setMessageType()
-    {
-        $type = array();
-        if ($this->alternativeExists()) {
-            $type[] = 'alt';
-        }
-        if ($this->inlineImageExists()) {
-            $type[] = 'inline';
-        }
-        if ($this->attachmentExists()) {
-            $type[] = 'attach';
-        }
-        $this->message_type = implode('_', $type);
-        if ($this->message_type == '') {
-            //The 'plain' message_type refers to the message having a single body element, not that it is plain-text
-            $this->message_type = 'plain';
-        }
-    }
-
-    /**
-     * Format a header line.
-     * @access public
-     * @param string $name
-     * @param string $value
-     * @return string
-     */
-    public function headerLine($name, $value)
-    {
-        return $name . ': ' . $value . $this->LE;
-    }
-
-    /**
-     * Return a formatted mail line.
-     * @access public
-     * @param string $value
-     * @return string
-     */
-    public function textLine($value)
-    {
-        return $value . $this->LE;
-    }
-
-    /**
-     * Add an attachment from a path on the filesystem.
-     * Never use a user-supplied path to a file!
-     * Returns false if the file could not be found or read.
-     * Explicitly *does not* support passing URLs; PHPMailer is not an HTTP client.
-     * If you need to do that, fetch the resource yourself and pass it in via a local file or string.
-     * @param string $path Path to the attachment.
-     * @param string $name Overrides the attachment name.
-     * @param string $encoding File encoding (see $Encoding).
-     * @param string $type File extension (MIME) type.
-     * @param string $disposition Disposition to use
-     * @throws phpmailerException
-     * @return boolean
-     */
-    public function addAttachment($path, $name = '', $encoding = 'base64', $type = '', $disposition = 'attachment')
-    {
-        try {
-            if (!self::isPermittedPath($path) or !@is_file($path)) {
-                throw new phpmailerException($this->lang('file_access') . $path, self::STOP_CONTINUE);
-            }
-
-            // If a MIME type is not specified, try to work it out from the file name
-            if ($type == '') {
-                $type = self::filenameToType($path);
-            }
-
-            $filename = basename($path);
-            if ($name == '') {
-                $name = $filename;
-            }
-
-            $this->attachment[] = array(
-                0 => $path,
-                1 => $filename,
-                2 => $name,
-                3 => $encoding,
-                4 => $type,
-                5 => false, // isStringAttachment
-                6 => $disposition,
-                7 => 0
-            );
-
-        } catch (phpmailerException $exc) {
-            $this->setError($exc->getMessage());
-            $this->edebug($exc->getMessage());
-            if ($this->exceptions) {
-                throw $exc;
-            }
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Return the array of attachments.
-     * @return array
-     */
-    public function getAttachments()
-    {
-        return $this->attachment;
-    }
-
-    /**
-     * Attach all file, string, and binary attachments to the message.
-     * Returns an empty string on failure.
-     * @access protected
-     * @param string $disposition_type
-     * @param string $boundary
-     * @return string
-     */
-    protected function attachAll($disposition_type, $boundary)
-    {
-        // Return text of body
-        $mime = array();
-        $cidUniq = array();
-        $incl = array();
-
-        // Add all attachments
-        foreach ($this->attachment as $attachment) {
-            // Check if it is a valid disposition_filter
-            if ($attachment[6] == $disposition_type) {
-                // Check for string attachment
-                $string = '';
-                $path = '';
-                $bString = $attachment[5];
-                if ($bString) {
-                    $string = $attachment[0];
-                } else {
-                    $path = $attachment[0];
-                }
-
-                $inclhash = md5(serialize($attachment));
-                if (in_array($inclhash, $incl)) {
-                    continue;
-                }
-                $incl[] = $inclhash;
-                $name = $attachment[2];
-                $encoding = $attachment[3];
-                $type = $attachment[4];
-                $disposition = $attachment[6];
-                $cid = $attachment[7];
-                if ($disposition == 'inline' && array_key_exists($cid, $cidUniq)) {
-                    continue;
-                }
-                $cidUniq[$cid] = true;
-
-                $mime[] = sprintf('--%s%s', $boundary, $this->LE);
-                //Only include a filename property if we have one
-                if (!empty($name)) {
-                    $mime[] = sprintf(
-                        'Content-Type: %s; name="%s"%s',
-                        $type,
-                        $this->encodeHeader($this->secureHeader($name)),
-                        $this->LE
-                    );
-                } else {
-                    $mime[] = sprintf(
-                        'Content-Type: %s%s',
-                        $type,
-                        $this->LE
-                    );
-                }
-                // RFC1341 part 5 says 7bit is assumed if not specified
-                if ($encoding != '7bit') {
-                    $mime[] = sprintf('Content-Transfer-Encoding: %s%s', $encoding, $this->LE);
-                }
-
-                if ($disposition == 'inline') {
-                    $mime[] = sprintf('Content-ID: <%s>%s', $cid, $this->LE);
-                }
-
-                // If a filename contains any of these chars, it should be quoted,
-                // but not otherwise: RFC2183 & RFC2045 5.1
-                // Fixes a warning in IETF's msglint MIME checker
-                // Allow for bypassing the Content-Disposition header totally
-                if (!(empty($disposition))) {
-                    $encoded_name = $this->encodeHeader($this->secureHeader($name));
-                    if (preg_match('/[ \(\)<>@,;:\\"\/\[\]\?=]/', $encoded_name)) {
-                        $mime[] = sprintf(
-                            'Content-Disposition: %s; filename="%s"%s',
-                            $disposition,
-                            $encoded_name,
-                            $this->LE . $this->LE
-                        );
-                    } else {
-                        if (!empty($encoded_name)) {
-                            $mime[] = sprintf(
-                                'Content-Disposition: %s; filename=%s%s',
-                                $disposition,
-                                $encoded_name,
-                                $this->LE . $this->LE
-                            );
-                        } else {
-                            $mime[] = sprintf(
-                                'Content-Disposition: %s%s',
-                                $disposition,
-                                $this->LE . $this->LE
-                            );
-                        }
-                    }
-                } else {
-                    $mime[] = $this->LE;
-                }
-
-                // Encode as string attachment
-                if ($bString) {
-                    $mime[] = $this->encodeString($string, $encoding);
-                    if ($this->isError()) {
-                        return '';
-                    }
-                    $mime[] = $this->LE . $this->LE;
-                } else {
-                    $mime[] = $this->encodeFile($path, $encoding);
-                    if ($this->isError()) {
-                        return '';
-                    }
-                    $mime[] = $this->LE . $this->LE;
-                }
-            }
-        }
-
-        $mime[] = sprintf('--%s--%s', $boundary, $this->LE);
-
-        return implode('', $mime);
-    }
-
-    /**
-     * Encode a file attachment in requested format.
-     * Returns an empty string on failure.
-     * @param string $path The full path to the file
-     * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
-     * @throws phpmailerException
-     * @access protected
-     * @return string
-     */
-    protected function encodeFile($path, $encoding = 'base64')
-    {
-        try {
-            if (!self::isPermittedPath($path) or !file_exists($path)) {
-                throw new phpmailerException($this->lang('file_open') . $path, self::STOP_CONTINUE);
-            }
-            $magic_quotes = get_magic_quotes_runtime();
-            if ($magic_quotes) {
-                if (version_compare(PHP_VERSION, '5.3.0', '<')) {
-                    set_magic_quotes_runtime(false);
-                } else {
-                    //Doesn't exist in PHP 5.4, but we don't need to check because
-                    //get_magic_quotes_runtime always returns false in 5.4+
-                    //so it will never get here
-                    ini_set('magic_quotes_runtime', false);
-                }
-            }
-            $file_buffer = file_get_contents($path);
-            $file_buffer = $this->encodeString($file_buffer, $encoding);
-            if ($magic_quotes) {
-                if (version_compare(PHP_VERSION, '5.3.0', '<')) {
-                    set_magic_quotes_runtime($magic_quotes);
-                } else {
-                    ini_set('magic_quotes_runtime', $magic_quotes);
-                }
-            }
-            return $file_buffer;
-        } catch (Exception $exc) {
-            $this->setError($exc->getMessage());
-            return '';
-        }
-    }
-
-    /**
-     * Encode a string in requested format.
-     * Returns an empty string on failure.
-     * @param string $str The text to encode
-     * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
-     * @access public
-     * @return string
-     */
-    public function encodeString($str, $encoding = 'base64')
-    {
-        $encoded = '';
-        switch (strtolower($encoding)) {
-            case 'base64':
-                $encoded = chunk_split(base64_encode($str), 76, $this->LE);
-                break;
-            case '7bit':
-            case '8bit':
-                $encoded = $this->fixEOL($str);
-                // Make sure it ends with a line break
-                if (substr($encoded, -(strlen($this->LE))) != $this->LE) {
-                    $encoded .= $this->LE;
-                }
-                break;
-            case 'binary':
-                $encoded = $str;
-                break;
-            case 'quoted-printable':
-                $encoded = $this->encodeQP($str);
-                break;
-            default:
-                $this->setError($this->lang('encoding') . $encoding);
-                break;
-        }
-        return $encoded;
-    }
-
-    /**
-     * Encode a header string optimally.
-     * Picks shortest of Q, B, quoted-printable or none.
-     * @access public
-     * @param string $str
-     * @param string $position
-     * @return string
-     */
-    public function encodeHeader($str, $position = 'text')
-    {
-        $matchcount = 0;
-        switch (strtolower($position)) {
-            case 'phrase':
-                if (!preg_match('/[\200-\377]/', $str)) {
-                    // Can't use addslashes as we don't know the value of magic_quotes_sybase
-                    $encoded = addcslashes($str, "\0..\37\177\\\"");
-                    if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
-                        return ($encoded);
-                    } else {
-                        return ("\"$encoded\"");
-                    }
-                }
-                $matchcount = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
-                break;
-            /** @noinspection PhpMissingBreakStatementInspection */
-            case 'comment':
-                $matchcount = preg_match_all('/[()"]/', $str, $matches);
-                // Intentional fall-through
-            case 'text':
-            default:
-                $matchcount += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
-                break;
-        }
-
-        //There are no chars that need encoding
-        if ($matchcount == 0) {
-            return ($str);
-        }
-
-        $maxlen = 75 - 7 - strlen($this->CharSet);
-        // Try to select the encoding which should produce the shortest output
-        if ($matchcount > strlen($str) / 3) {
-            // More than a third of the content will need encoding, so B encoding will be most efficient
-            $encoding = 'B';
-            if (function_exists('mb_strlen') && $this->hasMultiBytes($str)) {
-                // Use a custom function which correctly encodes and wraps long
-                // multibyte strings without breaking lines within a character
-                $encoded = $this->base64EncodeWrapMB($str, "\n");
-            } else {
-                $encoded = base64_encode($str);
-                $maxlen -= $maxlen % 4;
-                $encoded = trim(chunk_split($encoded, $maxlen, "\n"));
-            }
-        } else {
-            $encoding = 'Q';
-            $encoded = $this->encodeQ($str, $position);
-            $encoded = $this->wrapText($encoded, $maxlen, true);
-            $encoded = str_replace('=' . self::CRLF, "\n", trim($encoded));
-        }
-
-        $encoded = preg_replace('/^(.*)$/m', ' =?' . $this->CharSet . "?$encoding?\\1?=", $encoded);
-        $encoded = trim(str_replace("\n", $this->LE, $encoded));
-
-        return $encoded;
-    }
-
-    /**
-     * Check if a string contains multi-byte characters.
-     * @access public
-     * @param string $str multi-byte text to wrap encode
-     * @return boolean
-     */
-    public function hasMultiBytes($str)
-    {
-        if (function_exists('mb_strlen')) {
-            return (strlen($str) > mb_strlen($str, $this->CharSet));
-        } else { // Assume no multibytes (we can't handle without mbstring functions anyway)
-            return false;
-        }
-    }
-
-    /**
-     * Does a string contain any 8-bit chars (in any charset)?
-     * @param string $text
-     * @return boolean
-     */
-    public function has8bitChars($text)
-    {
-        return (boolean)preg_match('/[\x80-\xFF]/', $text);
-    }
-
-    /**
-     * Encode and wrap long multibyte strings for mail headers
-     * without breaking lines within a character.
-     * Adapted from a function by paravoid
-     * @link http://www.php.net/manual/en/function.mb-encode-mimeheader.php#60283
-     * @access public
-     * @param string $str multi-byte text to wrap encode
-     * @param string $linebreak string to use as linefeed/end-of-line
-     * @return string
-     */
-    public function base64EncodeWrapMB($str, $linebreak = null)
-    {
-        $start = '=?' . $this->CharSet . '?B?';
-        $end = '?=';
-        $encoded = '';
-        if ($linebreak === null) {
-            $linebreak = $this->LE;
-        }
-
-        $mb_length = mb_strlen($str, $this->CharSet);
-        // Each line must have length <= 75, including $start and $end
-        $length = 75 - strlen($start) - strlen($end);
-        // Average multi-byte ratio
-        $ratio = $mb_length / strlen($str);
-        // Base64 has a 4:3 ratio
-        $avgLength = floor($length * $ratio * .75);
-
-        for ($i = 0; $i < $mb_length; $i += $offset) {
-            $lookBack = 0;
-            do {
-                $offset = $avgLength - $lookBack;
-                $chunk = mb_substr($str, $i, $offset, $this->CharSet);
-                $chunk = base64_encode($chunk);
-                $lookBack++;
-            } while (strlen($chunk) > $length);
-            $encoded .= $chunk . $linebreak;
-        }
-
-        // Chomp the last linefeed
-        $encoded = substr($encoded, 0, -strlen($linebreak));
-        return $encoded;
-    }
-
-    /**
-     * Encode a string in quoted-printable format.
-     * According to RFC2045 section 6.7.
-     * @access public
-     * @param string $string The text to encode
-     * @param integer $line_max Number of chars allowed on a line before wrapping
-     * @return string
-     * @link http://www.php.net/manual/en/function.quoted-printable-decode.php#89417 Adapted from this comment
-     */
-    public function encodeQP($string, $line_max = 76)
-    {
-        // Use native function if it's available (>= PHP5.3)
-        if (function_exists('quoted_printable_encode')) {
-            return quoted_printable_encode($string);
-        }
-        // Fall back to a pure PHP implementation
-        $string = str_replace(
-            array('%20', '%0D%0A.', '%0D%0A', '%'),
-            array(' ', "\r\n=2E", "\r\n", '='),
-            rawurlencode($string)
-        );
-        return preg_replace('/[^\r\n]{' . ($line_max - 3) . '}[^=\r\n]{2}/', "$0=\r\n", $string);
-    }
-
-    /**
-     * Backward compatibility wrapper for an old QP encoding function that was removed.
-     * @see PHPMailer::encodeQP()
-     * @access public
-     * @param string $string
-     * @param integer $line_max
-     * @param boolean $space_conv
-     * @return string
-     * @deprecated Use encodeQP instead.
-     */
-    public function encodeQPphp(
-        $string,
-        $line_max = 76,
-        /** @noinspection PhpUnusedParameterInspection */ $space_conv = false
-    ) {
-        return $this->encodeQP($string, $line_max);
-    }
-
-    /**
-     * Encode a string using Q encoding.
-     * @link http://tools.ietf.org/html/rfc2047
-     * @param string $str the text to encode
-     * @param string $position Where the text is going to be used, see the RFC for what that means
-     * @access public
-     * @return string
-     */
-    public function encodeQ($str, $position = 'text')
-    {
-        // There should not be any EOL in the string
-        $pattern = '';
-        $encoded = str_replace(array("\r", "\n"), '', $str);
-        switch (strtolower($position)) {
-            case 'phrase':
-                // RFC 2047 section 5.3
-                $pattern = '^A-Za-z0-9!*+\/ -';
-                break;
-            /** @noinspection PhpMissingBreakStatementInspection */
-            case 'comment':
-                // RFC 2047 section 5.2
-                $pattern = '\(\)"';
-                // intentional fall-through
-                // for this reason we build the $pattern without including delimiters and []
-            case 'text':
-            default:
-                // RFC 2047 section 5.1
-                // Replace every high ascii, control, =, ? and _ characters
-                $pattern = '\000-\011\013\014\016-\037\075\077\137\177-\377' . $pattern;
-                break;
-        }
-        $matches = array();
-        if (preg_match_all("/[{$pattern}]/", $encoded, $matches)) {
-            // If the string contains an '=', make sure it's the first thing we replace
-            // so as to avoid double-encoding
-            $eqkey = array_search('=', $matches[0]);
-            if (false !== $eqkey) {
-                unset($matches[0][$eqkey]);
-                array_unshift($matches[0], '=');
-            }
-            foreach (array_unique($matches[0]) as $char) {
-                $encoded = str_replace($char, '=' . sprintf('%02X', ord($char)), $encoded);
-            }
-        }
-        // Replace every spaces to _ (more readable than =20)
-        return str_replace(' ', '_', $encoded);
-    }
-
-    /**
-     * Add a string or binary attachment (non-filesystem).
-     * This method can be used to attach ascii or binary data,
-     * such as a BLOB record from a database.
-     * @param string $string String attachment data.
-     * @param string $filename Name of the attachment.
-     * @param string $encoding File encoding (see $Encoding).
-     * @param string $type File extension (MIME) type.
-     * @param string $disposition Disposition to use
-     * @return void
-     */
-    public function addStringAttachment(
-        $string,
-        $filename,
-        $encoding = 'base64',
-        $type = '',
-        $disposition = 'attachment'
-    ) {
-        // If a MIME type is not specified, try to work it out from the file name
-        if ($type == '') {
-            $type = self::filenameToType($filename);
-        }
-        // Append to $attachment array
-        $this->attachment[] = array(
-            0 => $string,
-            1 => $filename,
-            2 => basename($filename),
-            3 => $encoding,
-            4 => $type,
-            5 => true, // isStringAttachment
-            6 => $disposition,
-            7 => 0
-        );
-    }
-
-    /**
-     * Add an embedded (inline) attachment from a file.
-     * This can include images, sounds, and just about any other document type.
-     * These differ from 'regular' attachments in that they are intended to be
-     * displayed inline with the message, not just attached for download.
-     * This is used in HTML messages that embed the images
-     * the HTML refers to using the $cid value.
-     * Never use a user-supplied path to a file!
-     * @param string $path Path to the attachment.
-     * @param string $cid Content ID of the attachment; Use this to reference
-     *        the content when using an embedded image in HTML.
-     * @param string $name Overrides the attachment name.
-     * @param string $encoding File encoding (see $Encoding).
-     * @param string $type File MIME type.
-     * @param string $disposition Disposition to use
-     * @return boolean True on successfully adding an attachment
-     */
-    public function addEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = '', $disposition = 'inline')
-    {
-        if (!self::isPermittedPath($path) or !@is_file($path)) {
-            $this->setError($this->lang('file_access') . $path);
-            return false;
-        }
-
-        // If a MIME type is not specified, try to work it out from the file name
-        if ($type == '') {
-            $type = self::filenameToType($path);
-        }
-
-        $filename = basename($path);
-        if ($name == '') {
-            $name = $filename;
-        }
-
-        // Append to $attachment array
-        $this->attachment[] = array(
-            0 => $path,
-            1 => $filename,
-            2 => $name,
-            3 => $encoding,
-            4 => $type,
-            5 => false, // isStringAttachment
-            6 => $disposition,
-            7 => $cid
-        );
-        return true;
-    }
-
-    /**
-     * Add an embedded stringified attachment.
-     * This can include images, sounds, and just about any other document type.
-     * Be sure to set the $type to an image type for images:
-     * JPEG images use 'image/jpeg', GIF uses 'image/gif', PNG uses 'image/png'.
-     * @param string $string The attachment binary data.
-     * @param string $cid Content ID of the attachment; Use this to reference
-     *        the content when using an embedded image in HTML.
-     * @param string $name
-     * @param string $encoding File encoding (see $Encoding).
-     * @param string $type MIME type.
-     * @param string $disposition Disposition to use
-     * @return boolean True on successfully adding an attachment
-     */
-    public function addStringEmbeddedImage(
-        $string,
-        $cid,
-        $name = '',
-        $encoding = 'base64',
-        $type = '',
-        $disposition = 'inline'
-    ) {
-        // If a MIME type is not specified, try to work it out from the name
-        if ($type == '' and !empty($name)) {
-            $type = self::filenameToType($name);
-        }
-
-        // Append to $attachment array
-        $this->attachment[] = array(
-            0 => $string,
-            1 => $name,
-            2 => $name,
-            3 => $encoding,
-            4 => $type,
-            5 => true, // isStringAttachment
-            6 => $disposition,
-            7 => $cid
-        );
-        return true;
-    }
-
-    /**
-     * Check if an inline attachment is present.
-     * @access public
-     * @return boolean
-     */
-    public function inlineImageExists()
-    {
-        foreach ($this->attachment as $attachment) {
-            if ($attachment[6] == 'inline') {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Check if an attachment (non-inline) is present.
-     * @return boolean
-     */
-    public function attachmentExists()
-    {
-        foreach ($this->attachment as $attachment) {
-            if ($attachment[6] == 'attachment') {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Check if this message has an alternative body set.
-     * @return boolean
-     */
-    public function alternativeExists()
-    {
-        return !empty($this->AltBody);
-    }
-
-    /**
-     * Clear queued addresses of given kind.
-     * @access protected
-     * @param string $kind 'to', 'cc', or 'bcc'
-     * @return void
-     */
-    public function clearQueuedAddresses($kind)
-    {
-        $RecipientsQueue = $this->RecipientsQueue;
-        foreach ($RecipientsQueue as $address => $params) {
-            if ($params[0] == $kind) {
-                unset($this->RecipientsQueue[$address]);
-            }
-        }
-    }
-
-    /**
-     * Clear all To recipients.
-     * @return void
-     */
-    public function clearAddresses()
-    {
-        foreach ($this->to as $to) {
-            unset($this->all_recipients[strtolower($to[0])]);
-        }
-        $this->to = array();
-        $this->clearQueuedAddresses('to');
-    }
-
-    /**
-     * Clear all CC recipients.
-     * @return void
-     */
-    public function clearCCs()
-    {
-        foreach ($this->cc as $cc) {
-            unset($this->all_recipients[strtolower($cc[0])]);
-        }
-        $this->cc = array();
-        $this->clearQueuedAddresses('cc');
-    }
-
-    /**
-     * Clear all BCC recipients.
-     * @return void
-     */
-    public function clearBCCs()
-    {
-        foreach ($this->bcc as $bcc) {
-            unset($this->all_recipients[strtolower($bcc[0])]);
-        }
-        $this->bcc = array();
-        $this->clearQueuedAddresses('bcc');
-    }
-
-    /**
-     * Clear all ReplyTo recipients.
-     * @return void
-     */
-    public function clearReplyTos()
-    {
-        $this->ReplyTo = array();
-        $this->ReplyToQueue = array();
-    }
-
-    /**
-     * Clear all recipient types.
-     * @return void
-     */
-    public function clearAllRecipients()
-    {
-        $this->to = array();
-        $this->cc = array();
-        $this->bcc = array();
-        $this->all_recipients = array();
-        $this->RecipientsQueue = array();
-    }
-
-    /**
-     * Clear all filesystem, string, and binary attachments.
-     * @return void
-     */
-    public function clearAttachments()
-    {
-        $this->attachment = array();
-    }
-
-    /**
-     * Clear all custom headers.
-     * @return void
-     */
-    public function clearCustomHeaders()
-    {
-        $this->CustomHeader = array();
-    }
-
-    /**
-     * Add an error message to the error container.
-     * @access protected
-     * @param string $msg
-     * @return void
-     */
-    protected function setError($msg)
-    {
-        $this->error_count++;
-        if ($this->Mailer == 'smtp' and !is_null($this->smtp)) {
-            $lasterror = $this->smtp->getError();
-            if (!empty($lasterror['error'])) {
-                $msg .= $this->lang('smtp_error') . $lasterror['error'];
-                if (!empty($lasterror['detail'])) {
-                    $msg .= ' Detail: '. $lasterror['detail'];
-                }
-                if (!empty($lasterror['smtp_code'])) {
-                    $msg .= ' SMTP code: ' . $lasterror['smtp_code'];
-                }
-                if (!empty($lasterror['smtp_code_ex'])) {
-                    $msg .= ' Additional SMTP info: ' . $lasterror['smtp_code_ex'];
-                }
-            }
-        }
-        $this->ErrorInfo = $msg;
-    }
-
-    /**
-     * Return an RFC 822 formatted date.
-     * @access public
-     * @return string
-     * @static
-     */
-    public static function rfcDate()
-    {
-        // Set the time zone to whatever the default is to avoid 500 errors
-        // Will default to UTC if it's not set properly in php.ini
-        date_default_timezone_set(@date_default_timezone_get());
-        return date('D, j M Y H:i:s O');
-    }
-
-    /**
-     * Get the server hostname.
-     * Returns 'localhost.localdomain' if unknown.
-     * @access protected
-     * @return string
-     */
-    protected function serverHostname()
-    {
-        $result = 'localhost.localdomain';
-        if (!empty($this->Hostname)) {
-            $result = $this->Hostname;
-        } elseif (isset($_SERVER) and array_key_exists('SERVER_NAME', $_SERVER) and !empty($_SERVER['SERVER_NAME'])) {
-            $result = $_SERVER['SERVER_NAME'];
-        } elseif (function_exists('gethostname') && gethostname() !== false) {
-            $result = gethostname();
-        } elseif (php_uname('n') !== false) {
-            $result = php_uname('n');
-        }
-        return $result;
-    }
-
-    /**
-     * Get an error message in the current language.
-     * @access protected
-     * @param string $key
-     * @return string
-     */
-    protected function lang($key)
-    {
-        if (count($this->language) < 1) {
-            $this->setLanguage('en'); // set the default language
-        }
-
-        if (array_key_exists($key, $this->language)) {
-            if ($key == 'smtp_connect_failed') {
-                //Include a link to troubleshooting docs on SMTP connection failure
-                //this is by far the biggest cause of support questions
-                //but it's usually not PHPMailer's fault.
-                return $this->language[$key] . ' https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting';
-            }
-            return $this->language[$key];
-        } else {
-            //Return the key as a fallback
-            return $key;
-        }
-    }
-
-    /**
-     * Check if an error occurred.
-     * @access public
-     * @return boolean True if an error did occur.
-     */
-    public function isError()
-    {
-        return ($this->error_count > 0);
-    }
-
-    /**
-     * Ensure consistent line endings in a string.
-     * Changes every end of line from CRLF, CR or LF to $this->LE.
-     * @access public
-     * @param string $str String to fixEOL
-     * @return string
-     */
-    public function fixEOL($str)
-    {
-        // Normalise to \n
-        $nstr = str_replace(array("\r\n", "\r"), "\n", $str);
-        // Now convert LE as needed
-        if ($this->LE !== "\n") {
-            $nstr = str_replace("\n", $this->LE, $nstr);
-        }
-        return $nstr;
-    }
-
-    /**
-     * Add a custom header.
-     * $name value can be overloaded to contain
-     * both header name and value (name:value)
-     * @access public
-     * @param string $name Custom header name
-     * @param string $value Header value
-     * @return void
-     */
-    public function addCustomHeader($name, $value = null)
-    {
-        if ($value === null) {
-            // Value passed in as name:value
-            $this->CustomHeader[] = explode(':', $name, 2);
-        } else {
-            $this->CustomHeader[] = array($name, $value);
-        }
-    }
-
-    /**
-     * Returns all custom headers.
-     * @return array
-     */
-    public function getCustomHeaders()
-    {
-        return $this->CustomHeader;
-    }
-
-    /**
-     * Create a message body from an HTML string.
-     * Automatically inlines images and creates a plain-text version by converting the HTML,
-     * overwriting any existing values in Body and AltBody.
-     * Do not source $message content from user input!
-     * $basedir is prepended when handling relative URLs, e.g. <img src="/images/a.png"> and must not be empty
-     * will look for an image file in $basedir/images/a.png and convert it to inline.
-     * If you don't provide a $basedir, relative paths will be left untouched (and thus probably break in email)
-     * If you don't want to apply these transformations to your HTML, just set Body and AltBody directly.
-     * @access public
-     * @param string $message HTML message string
-     * @param string $basedir Absolute path to a base directory to prepend to relative paths to images
-     * @param boolean|callable $advanced Whether to use the internal HTML to text converter
-     *    or your own custom converter @see PHPMailer::html2text()
-     * @return string $message The transformed message Body
-     */
-    public function msgHTML($message, $basedir = '', $advanced = false)
-    {
-        preg_match_all('/(src|background)=["\'](.*)["\']/Ui', $message, $images);
-        if (array_key_exists(2, $images)) {
-            if (strlen($basedir) > 1 && substr($basedir, -1) != '/') {
-                // Ensure $basedir has a trailing /
-                $basedir .= '/';
-            }
-            foreach ($images[2] as $imgindex => $url) {
-                // Convert data URIs into embedded images
-                if (preg_match('#^data:(image[^;,]*)(;base64)?,#', $url, $match)) {
-                    $data = substr($url, strpos($url, ','));
-                    if ($match[2]) {
-                        $data = base64_decode($data);
-                    } else {
-                        $data = rawurldecode($data);
-                    }
-                    $cid = md5($url) . '@phpmailer.0'; // RFC2392 S 2
-                    if ($this->addStringEmbeddedImage($data, $cid, 'embed' . $imgindex, 'base64', $match[1])) {
-                        $message = str_replace(
-                            $images[0][$imgindex],
-                            $images[1][$imgindex] . '="cid:' . $cid . '"',
-                            $message
-                        );
-                    }
-                    continue;
-                }
-                if (
-                    // Only process relative URLs if a basedir is provided (i.e. no absolute local paths)
-                    !empty($basedir)
-                    // Ignore URLs containing parent dir traversal (..)
-                    && (strpos($url, '..') === false)
-                    // Do not change urls that are already inline images
-                    && substr($url, 0, 4) !== 'cid:'
-                    // Do not change absolute URLs, including anonymous protocol
-                    && !preg_match('#^[a-z][a-z0-9+.-]*:?//#i', $url)
-                ) {
-                    $filename = basename($url);
-                    $directory = dirname($url);
-                    if ($directory == '.') {
-                        $directory = '';
-                    }
-                    $cid = md5($url) . '@phpmailer.0'; // RFC2392 S 2
-                    if (strlen($directory) > 1 && substr($directory, -1) != '/') {
-                        $directory .= '/';
-                    }
-                    if ($this->addEmbeddedImage(
-                        $basedir . $directory . $filename,
-                        $cid,
-                        $filename,
-                        'base64',
-                        self::_mime_types((string)self::mb_pathinfo($filename, PATHINFO_EXTENSION))
-                    )
-                    ) {
-                        $message = preg_replace(
-                            '/' . $images[1][$imgindex] . '=["\']' . preg_quote($url, '/') . '["\']/Ui',
-                            $images[1][$imgindex] . '="cid:' . $cid . '"',
-                            $message
-                        );
-                    }
-                }
-            }
-        }
-        $this->isHTML(true);
-        // Convert all message body line breaks to CRLF, makes quoted-printable encoding work much better
-        $this->Body = $this->normalizeBreaks($message);
-        $this->AltBody = $this->normalizeBreaks($this->html2text($message, $advanced));
-        if (!$this->alternativeExists()) {
-            $this->AltBody = 'To view this email message, open it in a program that understands HTML!' .
-                self::CRLF . self::CRLF;
-        }
-        return $this->Body;
-    }
-
-    /**
-     * Convert an HTML string into plain text.
-     * This is used by msgHTML().
-     * Note - older versions of this function used a bundled advanced converter
-     * which was been removed for license reasons in #232.
-     * Example usage:
-     * <code>
-     * // Use default conversion
-     * $plain = $mail->html2text($html);
-     * // Use your own custom converter
-     * $plain = $mail->html2text($html, function($html) {
-     *     $converter = new MyHtml2text($html);
-     *     return $converter->get_text();
-     * });
-     * </code>
-     * @param string $html The HTML text to convert
-     * @param boolean|callable $advanced Any boolean value to use the internal converter,
-     *   or provide your own callable for custom conversion.
-     * @return string
-     */
-    public function html2text($html, $advanced = false)
-    {
-        if (is_callable($advanced)) {
-            return call_user_func($advanced, $html);
-        }
-        return html_entity_decode(
-            trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/si', '', $html))),
-            ENT_QUOTES,
-            $this->CharSet
-        );
-    }
-
-    /**
-     * Get the MIME type for a file extension.
-     * @param string $ext File extension
-     * @access public
-     * @return string MIME type of file.
-     * @static
-     */
-    public static function _mime_types($ext = '')
-    {
-        $mimes = array(
-            'xl'    => 'application/excel',
-            'js'    => 'application/javascript',
-            'hqx'   => 'application/mac-binhex40',
-            'cpt'   => 'application/mac-compactpro',
-            'bin'   => 'application/macbinary',
-            'doc'   => 'application/msword',
-            'word'  => 'application/msword',
-            'xlsx'  => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
-            'xltx'  => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
-            'potx'  => 'application/vnd.openxmlformats-officedocument.presentationml.template',
-            'ppsx'  => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
-            'pptx'  => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
-            'sldx'  => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
-            'docx'  => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
-            'dotx'  => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
-            'xlam'  => 'application/vnd.ms-excel.addin.macroEnabled.12',
-            'xlsb'  => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
-            'class' => 'application/octet-stream',
-            'dll'   => 'application/octet-stream',
-            'dms'   => 'application/octet-stream',
-            'exe'   => 'application/octet-stream',
-            'lha'   => 'application/octet-stream',
-            'lzh'   => 'application/octet-stream',
-            'psd'   => 'application/octet-stream',
-            'sea'   => 'application/octet-stream',
-            'so'    => 'application/octet-stream',
-            'oda'   => 'application/oda',
-            'pdf'   => 'application/pdf',
-            'ai'    => 'application/postscript',
-            'eps'   => 'application/postscript',
-            'ps'    => 'application/postscript',
-            'smi'   => 'application/smil',
-            'smil'  => 'application/smil',
-            'mif'   => 'application/vnd.mif',
-            'xls'   => 'application/vnd.ms-excel',
-            'ppt'   => 'application/vnd.ms-powerpoint',
-            'wbxml' => 'application/vnd.wap.wbxml',
-            'wmlc'  => 'application/vnd.wap.wmlc',
-            'dcr'   => 'application/x-director',
-            'dir'   => 'application/x-director',
-            'dxr'   => 'application/x-director',
-            'dvi'   => 'application/x-dvi',
-            'gtar'  => 'application/x-gtar',
-            'php3'  => 'application/x-httpd-php',
-            'php4'  => 'application/x-httpd-php',
-            'php'   => 'application/x-httpd-php',
-            'phtml' => 'application/x-httpd-php',
-            'phps'  => 'application/x-httpd-php-source',
-            'swf'   => 'application/x-shockwave-flash',
-            'sit'   => 'application/x-stuffit',
-            'tar'   => 'application/x-tar',
-            'tgz'   => 'application/x-tar',
-            'xht'   => 'application/xhtml+xml',
-            'xhtml' => 'application/xhtml+xml',
-            'zip'   => 'application/zip',
-            'mid'   => 'audio/midi',
-            'midi'  => 'audio/midi',
-            'mp2'   => 'audio/mpeg',
-            'mp3'   => 'audio/mpeg',
-            'mpga'  => 'audio/mpeg',
-            'aif'   => 'audio/x-aiff',
-            'aifc'  => 'audio/x-aiff',
-            'aiff'  => 'audio/x-aiff',
-            'ram'   => 'audio/x-pn-realaudio',
-            'rm'    => 'audio/x-pn-realaudio',
-            'rpm'   => 'audio/x-pn-realaudio-plugin',
-            'ra'    => 'audio/x-realaudio',
-            'wav'   => 'audio/x-wav',
-            'bmp'   => 'image/bmp',
-            'gif'   => 'image/gif',
-            'jpeg'  => 'image/jpeg',
-            'jpe'   => 'image/jpeg',
-            'jpg'   => 'image/jpeg',
-            'png'   => 'image/png',
-            'tiff'  => 'image/tiff',
-            'tif'   => 'image/tiff',
-            'eml'   => 'message/rfc822',
-            'css'   => 'text/css',
-            'html'  => 'text/html',
-            'htm'   => 'text/html',
-            'shtml' => 'text/html',
-            'log'   => 'text/plain',
-            'text'  => 'text/plain',
-            'txt'   => 'text/plain',
-            'rtx'   => 'text/richtext',
-            'rtf'   => 'text/rtf',
-            'vcf'   => 'text/vcard',
-            'vcard' => 'text/vcard',
-            'xml'   => 'text/xml',
-            'xsl'   => 'text/xml',
-            'mpeg'  => 'video/mpeg',
-            'mpe'   => 'video/mpeg',
-            'mpg'   => 'video/mpeg',
-            'mov'   => 'video/quicktime',
-            'qt'    => 'video/quicktime',
-            'rv'    => 'video/vnd.rn-realvideo',
-            'avi'   => 'video/x-msvideo',
-            'movie' => 'video/x-sgi-movie'
-        );
-        if (array_key_exists(strtolower($ext), $mimes)) {
-            return $mimes[strtolower($ext)];
-        }
-        return 'application/octet-stream';
-    }
-
-    /**
-     * Map a file name to a MIME type.
-     * Defaults to 'application/octet-stream', i.e.. arbitrary binary data.
-     * @param string $filename A file name or full path, does not need to exist as a file
-     * @return string
-     * @static
-     */
-    public static function filenameToType($filename)
-    {
-        // In case the path is a URL, strip any query string before getting extension
-        $qpos = strpos($filename, '?');
-        if (false !== $qpos) {
-            $filename = substr($filename, 0, $qpos);
-        }
-        $pathinfo = self::mb_pathinfo($filename);
-        return self::_mime_types($pathinfo['extension']);
-    }
-
-    /**
-     * Multi-byte-safe pathinfo replacement.
-     * Drop-in replacement for pathinfo(), but multibyte-safe, cross-platform-safe, old-version-safe.
-     * Works similarly to the one in PHP >= 5.2.0
-     * @link http://www.php.net/manual/en/function.pathinfo.php#107461
-     * @param string $path A filename or path, does not need to exist as a file
-     * @param integer|string $options Either a PATHINFO_* constant,
-     *      or a string name to return only the specified piece, allows 'filename' to work on PHP < 5.2
-     * @return string|array
-     * @static
-     */
-    public static function mb_pathinfo($path, $options = null)
-    {
-        $ret = array('dirname' => '', 'basename' => '', 'extension' => '', 'filename' => '');
-        $pathinfo = array();
-        if (preg_match('%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im', $path, $pathinfo)) {
-            if (array_key_exists(1, $pathinfo)) {
-                $ret['dirname'] = $pathinfo[1];
-            }
-            if (array_key_exists(2, $pathinfo)) {
-                $ret['basename'] = $pathinfo[2];
-            }
-            if (array_key_exists(5, $pathinfo)) {
-                $ret['extension'] = $pathinfo[5];
-            }
-            if (array_key_exists(3, $pathinfo)) {
-                $ret['filename'] = $pathinfo[3];
-            }
-        }
-        switch ($options) {
-            case PATHINFO_DIRNAME:
-            case 'dirname':
-                return $ret['dirname'];
-            case PATHINFO_BASENAME:
-            case 'basename':
-                return $ret['basename'];
-            case PATHINFO_EXTENSION:
-            case 'extension':
-                return $ret['extension'];
-            case PATHINFO_FILENAME:
-            case 'filename':
-                return $ret['filename'];
-            default:
-                return $ret;
-        }
-    }
-
-    /**
-     * Set or reset instance properties.
-     * You should avoid this function - it's more verbose, less efficient, more error-prone and
-     * harder to debug than setting properties directly.
-     * Usage Example:
-     * `$mail->set('SMTPSecure', 'tls');`
-     *   is the same as:
-     * `$mail->SMTPSecure = 'tls';`
-     * @access public
-     * @param string $name The property name to set
-     * @param mixed $value The value to set the property to
-     * @return boolean
-     * @TODO Should this not be using the __set() magic function?
-     */
-    public function set($name, $value = '')
-    {
-        if (property_exists($this, $name)) {
-            $this->$name = $value;
-            return true;
-        } else {
-            $this->setError($this->lang('variable_set') . $name);
-            return false;
-        }
-    }
-
-    /**
-     * Strip newlines to prevent header injection.
-     * @access public
-     * @param string $str
-     * @return string
-     */
-    public function secureHeader($str)
-    {
-        return trim(str_replace(array("\r", "\n"), '', $str));
-    }
-
-    /**
-     * Normalize line breaks in a string.
-     * Converts UNIX LF, Mac CR and Windows CRLF line breaks into a single line break format.
-     * Defaults to CRLF (for message bodies) and preserves consecutive breaks.
-     * @param string $text
-     * @param string $breaktype What kind of line break to use, defaults to CRLF
-     * @return string
-     * @access public
-     * @static
-     */
-    public static function normalizeBreaks($text, $breaktype = "\r\n")
-    {
-        return preg_replace('/(\r\n|\r|\n)/ms', $breaktype, $text);
-    }
-
-    /**
-     * Set the public and private key files and password for S/MIME signing.
-     * @access public
-     * @param string $cert_filename
-     * @param string $key_filename
-     * @param string $key_pass Password for private key
-     * @param string $extracerts_filename Optional path to chain certificate
-     */
-    public function sign($cert_filename, $key_filename, $key_pass, $extracerts_filename = '')
-    {
-        $this->sign_cert_file = $cert_filename;
-        $this->sign_key_file = $key_filename;
-        $this->sign_key_pass = $key_pass;
-        $this->sign_extracerts_file = $extracerts_filename;
-    }
-
-    /**
-     * Quoted-Printable-encode a DKIM header.
-     * @access public
-     * @param string $txt
-     * @return string
-     */
-    public function DKIM_QP($txt)
-    {
-        $line = '';
-        for ($i = 0; $i < strlen($txt); $i++) {
-            $ord = ord($txt[$i]);
-            if (((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E))) {
-                $line .= $txt[$i];
-            } else {
-                $line .= '=' . sprintf('%02X', $ord);
-            }
-        }
-        return $line;
-    }
-
-    /**
-     * Generate a DKIM signature.
-     * @access public
-     * @param string $signHeader
-     * @throws phpmailerException
-     * @return string The DKIM signature value
-     */
-    public function DKIM_Sign($signHeader)
-    {
-        if (!defined('PKCS7_TEXT')) {
-            if ($this->exceptions) {
-                throw new phpmailerException($this->lang('extension_missing') . 'openssl');
-            }
-            return '';
-        }
-        $privKeyStr = !empty($this->DKIM_private_string) ? $this->DKIM_private_string : file_get_contents($this->DKIM_private);
-        if ('' != $this->DKIM_passphrase) {
-            $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase);
-        } else {
-            $privKey = openssl_pkey_get_private($privKeyStr);
-        }
-        //Workaround for missing digest algorithms in old PHP & OpenSSL versions
-        //@link http://stackoverflow.com/a/11117338/333340
-        if (version_compare(PHP_VERSION, '5.3.0') >= 0 and
-            in_array('sha256WithRSAEncryption', openssl_get_md_methods(true))) {
-            if (openssl_sign($signHeader, $signature, $privKey, 'sha256WithRSAEncryption')) {
-                openssl_pkey_free($privKey);
-                return base64_encode($signature);
-            }
-        } else {
-            $pinfo = openssl_pkey_get_details($privKey);
-            $hash = hash('sha256', $signHeader);
-            //'Magic' constant for SHA256 from RFC3447
-            //@link https://tools.ietf.org/html/rfc3447#page-43
-            $t = '3031300d060960864801650304020105000420' . $hash;
-            $pslen = $pinfo['bits'] / 8 - (strlen($t) / 2 + 3);
-            $eb = pack('H*', '0001' . str_repeat('FF', $pslen) . '00' . $t);
-
-            if (openssl_private_encrypt($eb, $signature, $privKey, OPENSSL_NO_PADDING)) {
-                openssl_pkey_free($privKey);
-                return base64_encode($signature);
-            }
-        }
-        openssl_pkey_free($privKey);
-        return '';
-    }
-
-    /**
-     * Generate a DKIM canonicalization header.
-     * @access public
-     * @param string $signHeader Header
-     * @return string
-     */
-    public function DKIM_HeaderC($signHeader)
-    {
-        $signHeader = preg_replace('/\r\n\s+/', ' ', $signHeader);
-        $lines = explode("\r\n", $signHeader);
-        foreach ($lines as $key => $line) {
-            list($heading, $value) = explode(':', $line, 2);
-            $heading = strtolower($heading);
-            $value = preg_replace('/\s{2,}/', ' ', $value); // Compress useless spaces
-            $lines[$key] = $heading . ':' . trim($value); // Don't forget to remove WSP around the value
-        }
-        $signHeader = implode("\r\n", $lines);
-        return $signHeader;
-    }
-
-    /**
-     * Generate a DKIM canonicalization body.
-     * @access public
-     * @param string $body Message Body
-     * @return string
-     */
-    public function DKIM_BodyC($body)
-    {
-        if ($body == '') {
-            return "\r\n";
-        }
-        // stabilize line endings
-        $body = str_replace("\r\n", "\n", $body);
-        $body = str_replace("\n", "\r\n", $body);
-        // END stabilize line endings
-        while (substr($body, strlen($body) - 4, 4) == "\r\n\r\n") {
-            $body = substr($body, 0, strlen($body) - 2);
-        }
-        return $body;
-    }
-
-    /**
-     * Create the DKIM header and body in a new message header.
-     * @access public
-     * @param string $headers_line Header lines
-     * @param string $subject Subject
-     * @param string $body Body
-     * @return string
-     */
-    public function DKIM_Add($headers_line, $subject, $body)
-    {
-        $DKIMsignatureType = 'rsa-sha256'; // Signature & hash algorithms
-        $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body
-        $DKIMquery = 'dns/txt'; // Query method
-        $DKIMtime = time(); // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone)
-        $subject_header = "Subject: $subject";
-        $headers = explode($this->LE, $headers_line);
-        $from_header = '';
-        $to_header = '';
-        $date_header = '';
-        $current = '';
-        foreach ($headers as $header) {
-            if (strpos($header, 'From:') === 0) {
-                $from_header = $header;
-                $current = 'from_header';
-            } elseif (strpos($header, 'To:') === 0) {
-                $to_header = $header;
-                $current = 'to_header';
-            } elseif (strpos($header, 'Date:') === 0) {
-                $date_header = $header;
-                $current = 'date_header';
-            } else {
-                if (!empty($$current) && strpos($header, ' =?') === 0) {
-                    $$current .= $header;
-                } else {
-                    $current = '';
-                }
-            }
-        }
-        $from = str_replace('|', '=7C', $this->DKIM_QP($from_header));
-        $to = str_replace('|', '=7C', $this->DKIM_QP($to_header));
-        $date = str_replace('|', '=7C', $this->DKIM_QP($date_header));
-        $subject = str_replace(
-            '|',
-            '=7C',
-            $this->DKIM_QP($subject_header)
-        ); // Copied header fields (dkim-quoted-printable)
-        $body = $this->DKIM_BodyC($body);
-        $DKIMlen = strlen($body); // Length of body
-        $DKIMb64 = base64_encode(pack('H*', hash('sha256', $body))); // Base64 of packed binary SHA-256 hash of body
-        if ('' == $this->DKIM_identity) {
-            $ident = '';
-        } else {
-            $ident = ' i=' . $this->DKIM_identity . ';';
-        }
-        $dkimhdrs = 'DKIM-Signature: v=1; a=' .
-            $DKIMsignatureType . '; q=' .
-            $DKIMquery . '; l=' .
-            $DKIMlen . '; s=' .
-            $this->DKIM_selector .
-            ";\r\n" .
-            "\tt=" . $DKIMtime . '; c=' . $DKIMcanonicalization . ";\r\n" .
-            "\th=From:To:Date:Subject;\r\n" .
-            "\td=" . $this->DKIM_domain . ';' . $ident . "\r\n" .
-            "\tz=$from\r\n" .
-            "\t|$to\r\n" .
-            "\t|$date\r\n" .
-            "\t|$subject;\r\n" .
-            "\tbh=" . $DKIMb64 . ";\r\n" .
-            "\tb=";
-        $toSign = $this->DKIM_HeaderC(
-            $from_header . "\r\n" .
-            $to_header . "\r\n" .
-            $date_header . "\r\n" .
-            $subject_header . "\r\n" .
-            $dkimhdrs
-        );
-        $signed = $this->DKIM_Sign($toSign);
-        return $dkimhdrs . $signed . "\r\n";
-    }
-
-    /**
-     * Detect if a string contains a line longer than the maximum line length allowed.
-     * @param string $str
-     * @return boolean
-     * @static
-     */
-    public static function hasLineLongerThanMax($str)
-    {
-        //+2 to include CRLF line break for a 1000 total
-        return (boolean)preg_match('/^(.{'.(self::MAX_LINE_LENGTH + 2).',})/m', $str);
-    }
-
-    /**
-     * Allows for public read access to 'to' property.
-     * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included.
-     * @access public
-     * @return array
-     */
-    public function getToAddresses()
-    {
-        return $this->to;
-    }
-
-    /**
-     * Allows for public read access to 'cc' property.
-     * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included.
-     * @access public
-     * @return array
-     */
-    public function getCcAddresses()
-    {
-        return $this->cc;
-    }
-
-    /**
-     * Allows for public read access to 'bcc' property.
-     * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included.
-     * @access public
-     * @return array
-     */
-    public function getBccAddresses()
-    {
-        return $this->bcc;
-    }
-
-    /**
-     * Allows for public read access to 'ReplyTo' property.
-     * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included.
-     * @access public
-     * @return array
-     */
-    public function getReplyToAddresses()
-    {
-        return $this->ReplyTo;
-    }
-
-    /**
-     * Allows for public read access to 'all_recipients' property.
-     * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included.
-     * @access public
-     * @return array
-     */
-    public function getAllRecipientAddresses()
-    {
-        return $this->all_recipients;
-    }
-
-    /**
-     * Perform a callback.
-     * @param boolean $isSent
-     * @param array $to
-     * @param array $cc
-     * @param array $bcc
-     * @param string $subject
-     * @param string $body
-     * @param string $from
-     */
-    protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body, $from)
-    {
-        if (!empty($this->action_function) && is_callable($this->action_function)) {
-            $params = array($isSent, $to, $cc, $bcc, $subject, $body, $from);
-            call_user_func_array($this->action_function, $params);
-        }
-    }
-}
-
-/**
- * PHPMailer exception handler
- * @package PHPMailer
- */
-class phpmailerException extends Exception
-{
-    /**
-     * Prettify error message output
-     * @return string
-     */
-    public function errorMessage()
-    {
-        $errorMsg = '<strong>' . htmlspecialchars($this->getMessage()) . "</strong><br />\n";
-        return $errorMsg;
-    }
-}
diff --git a/cron/class.smtp.php b/cron/class.smtp.php
deleted file mode 100755
index 118cb20f6b9d952159fe88aff6b9dc4e9f2ad52c..0000000000000000000000000000000000000000
--- a/cron/class.smtp.php
+++ /dev/null
@@ -1,1276 +0,0 @@
-<?php
-/**
- * PHPMailer RFC821 SMTP email transport class.
- * PHP Version 5
- * @package PHPMailer
- * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
- * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
- * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
- * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
- * @author Brent R. Matzelle (original founder)
- * @copyright 2014 Marcus Bointon
- * @copyright 2010 - 2012 Jim Jagielski
- * @copyright 2004 - 2009 Andy Prevost
- * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
- * @note This program is distributed in the hope that it will be useful - WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/**
- * PHPMailer RFC821 SMTP email transport class.
- * Implements RFC 821 SMTP commands and provides some utility methods for sending mail to an SMTP server.
- * @package PHPMailer
- * @author Chris Ryan
- * @author Marcus Bointon <phpmailer@synchromedia.co.uk>
- */
-class SMTP
-{
-    /**
-     * The PHPMailer SMTP version number.
-     * @var string
-     */
-    const VERSION = '5.2.27';
-
-    /**
-     * SMTP line break constant.
-     * @var string
-     */
-    const CRLF = "\r\n";
-
-    /**
-     * The SMTP port to use if one is not specified.
-     * @var integer
-     */
-    const DEFAULT_SMTP_PORT = 25;
-
-    /**
-     * The maximum line length allowed by RFC 2822 section 2.1.1
-     * @var integer
-     */
-    const MAX_LINE_LENGTH = 998;
-
-    /**
-     * Debug level for no output
-     */
-    const DEBUG_OFF = 0;
-
-    /**
-     * Debug level to show client -> server messages
-     */
-    const DEBUG_CLIENT = 1;
-
-    /**
-     * Debug level to show client -> server and server -> client messages
-     */
-    const DEBUG_SERVER = 2;
-
-    /**
-     * Debug level to show connection status, client -> server and server -> client messages
-     */
-    const DEBUG_CONNECTION = 3;
-
-    /**
-     * Debug level to show all messages
-     */
-    const DEBUG_LOWLEVEL = 4;
-
-    /**
-     * The PHPMailer SMTP Version number.
-     * @var string
-     * @deprecated Use the `VERSION` constant instead
-     * @see SMTP::VERSION
-     */
-    public $Version = '5.2.27';
-
-    /**
-     * SMTP server port number.
-     * @var integer
-     * @deprecated This is only ever used as a default value, so use the `DEFAULT_SMTP_PORT` constant instead
-     * @see SMTP::DEFAULT_SMTP_PORT
-     */
-    public $SMTP_PORT = 25;
-
-    /**
-     * SMTP reply line ending.
-     * @var string
-     * @deprecated Use the `CRLF` constant instead
-     * @see SMTP::CRLF
-     */
-    public $CRLF = "\r\n";
-
-    /**
-     * Debug output level.
-     * Options:
-     * * self::DEBUG_OFF (`0`) No debug output, default
-     * * self::DEBUG_CLIENT (`1`) Client commands
-     * * self::DEBUG_SERVER (`2`) Client commands and server responses
-     * * self::DEBUG_CONNECTION (`3`) As DEBUG_SERVER plus connection status
-     * * self::DEBUG_LOWLEVEL (`4`) Low-level data output, all messages
-     * @var integer
-     */
-    public $do_debug = self::DEBUG_OFF;
-
-    /**
-     * How to handle debug output.
-     * Options:
-     * * `echo` Output plain-text as-is, appropriate for CLI
-     * * `html` Output escaped, line breaks converted to `<br>`, appropriate for browser output
-     * * `error_log` Output to error log as configured in php.ini
-     *
-     * Alternatively, you can provide a callable expecting two params: a message string and the debug level:
-     * <code>
-     * $smtp->Debugoutput = function($str, $level) {echo "debug level $level; message: $str";};
-     * </code>
-     * @var string|callable
-     */
-    public $Debugoutput = 'echo';
-
-    /**
-     * Whether to use VERP.
-     * @link http://en.wikipedia.org/wiki/Variable_envelope_return_path
-     * @link http://www.postfix.org/VERP_README.html Info on VERP
-     * @var boolean
-     */
-    public $do_verp = false;
-
-    /**
-     * The timeout value for connection, in seconds.
-     * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2
-     * This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure.
-     * @link http://tools.ietf.org/html/rfc2821#section-4.5.3.2
-     * @var integer
-     */
-    public $Timeout = 300;
-
-    /**
-     * How long to wait for commands to complete, in seconds.
-     * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2
-     * @var integer
-     */
-    public $Timelimit = 300;
-
-    /**
-     * @var array Patterns to extract an SMTP transaction id from reply to a DATA command.
-     * The first capture group in each regex will be used as the ID.
-     */
-    protected $smtp_transaction_id_patterns = array(
-        'exim' => '/[0-9]{3} OK id=(.*)/',
-        'sendmail' => '/[0-9]{3} 2.0.0 (.*) Message/',
-        'postfix' => '/[0-9]{3} 2.0.0 Ok: queued as (.*)/'
-    );
-
-    /**
-     * @var string The last transaction ID issued in response to a DATA command,
-     * if one was detected
-     */
-    protected $last_smtp_transaction_id;
-
-    /**
-     * The socket for the server connection.
-     * @var resource
-     */
-    protected $smtp_conn;
-
-    /**
-     * Error information, if any, for the last SMTP command.
-     * @var array
-     */
-    protected $error = array(
-        'error' => '',
-        'detail' => '',
-        'smtp_code' => '',
-        'smtp_code_ex' => ''
-    );
-
-    /**
-     * The reply the server sent to us for HELO.
-     * If null, no HELO string has yet been received.
-     * @var string|null
-     */
-    protected $helo_rply = null;
-
-    /**
-     * The set of SMTP extensions sent in reply to EHLO command.
-     * Indexes of the array are extension names.
-     * Value at index 'HELO' or 'EHLO' (according to command that was sent)
-     * represents the server name. In case of HELO it is the only element of the array.
-     * Other values can be boolean TRUE or an array containing extension options.
-     * If null, no HELO/EHLO string has yet been received.
-     * @var array|null
-     */
-    protected $server_caps = null;
-
-    /**
-     * The most recent reply received from the server.
-     * @var string
-     */
-    protected $last_reply = '';
-
-    /**
-     * Output debugging info via a user-selected method.
-     * @see SMTP::$Debugoutput
-     * @see SMTP::$do_debug
-     * @param string $str Debug string to output
-     * @param integer $level The debug level of this message; see DEBUG_* constants
-     * @return void
-     */
-    protected function edebug($str, $level = 0)
-    {
-        if ($level > $this->do_debug) {
-            return;
-        }
-        //Avoid clash with built-in function names
-        if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) {
-            call_user_func($this->Debugoutput, $str, $level);
-            return;
-        }
-        switch ($this->Debugoutput) {
-            case 'error_log':
-                //Don't output, just log
-                error_log($str);
-                break;
-            case 'html':
-                //Cleans up output a bit for a better looking, HTML-safe output
-                echo gmdate('Y-m-d H:i:s') . ' ' . htmlentities(
-                    preg_replace('/[\r\n]+/', '', $str),
-                    ENT_QUOTES,
-                    'UTF-8'
-                ) . "<br>\n";
-                break;
-            case 'echo':
-            default:
-                //Normalize line breaks
-                $str = preg_replace('/(\r\n|\r|\n)/ms', "\n", $str);
-                echo gmdate('Y-m-d H:i:s') . "\t" . str_replace(
-                    "\n",
-                    "\n                   \t                  ",
-                    trim($str)
-                ) . "\n";
-        }
-    }
-
-    /**
-     * Connect to an SMTP server.
-     * @param string $host SMTP server IP or host name
-     * @param integer $port The port number to connect to
-     * @param integer $timeout How long to wait for the connection to open
-     * @param array $options An array of options for stream_context_create()
-     * @access public
-     * @return boolean
-     */
-    public function connect($host, $port = null, $timeout = 30, $options = array())
-    {
-        static $streamok;
-        //This is enabled by default since 5.0.0 but some providers disable it
-        //Check this once and cache the result
-        if (is_null($streamok)) {
-            $streamok = function_exists('stream_socket_client');
-        }
-        // Clear errors to avoid confusion
-        $this->setError('');
-        // Make sure we are __not__ connected
-        if ($this->connected()) {
-            // Already connected, generate error
-            $this->setError('Already connected to a server');
-            return false;
-        }
-        if (empty($port)) {
-            $port = self::DEFAULT_SMTP_PORT;
-        }
-        // Connect to the SMTP server
-        $this->edebug(
-            "Connection: opening to $host:$port, timeout=$timeout, options=" .
-            var_export($options, true),
-            self::DEBUG_CONNECTION
-        );
-        $errno = 0;
-        $errstr = '';
-        if ($streamok) {
-            $socket_context = stream_context_create($options);
-            set_error_handler(array($this, 'errorHandler'));
-            $this->smtp_conn = stream_socket_client(
-                $host . ":" . $port,
-                $errno,
-                $errstr,
-                $timeout,
-                STREAM_CLIENT_CONNECT,
-                $socket_context
-            );
-            restore_error_handler();
-        } else {
-            //Fall back to fsockopen which should work in more places, but is missing some features
-            $this->edebug(
-                "Connection: stream_socket_client not available, falling back to fsockopen",
-                self::DEBUG_CONNECTION
-            );
-            set_error_handler(array($this, 'errorHandler'));
-            $this->smtp_conn = fsockopen(
-                $host,
-                $port,
-                $errno,
-                $errstr,
-                $timeout
-            );
-            restore_error_handler();
-        }
-        // Verify we connected properly
-        if (!is_resource($this->smtp_conn)) {
-            $this->setError(
-                'Failed to connect to server',
-                $errno,
-                $errstr
-            );
-            $this->edebug(
-                'SMTP ERROR: ' . $this->error['error']
-                . ": $errstr ($errno)",
-                self::DEBUG_CLIENT
-            );
-            return false;
-        }
-        $this->edebug('Connection: opened', self::DEBUG_CONNECTION);
-        // SMTP server can take longer to respond, give longer timeout for first read
-        // Windows does not have support for this timeout function
-        if (substr(PHP_OS, 0, 3) != 'WIN') {
-            $max = ini_get('max_execution_time');
-            // Don't bother if unlimited
-            if ($max != 0 && $timeout > $max) {
-                @set_time_limit($timeout);
-            }
-            stream_set_timeout($this->smtp_conn, $timeout, 0);
-        }
-        // Get any announcement
-        $announce = $this->get_lines();
-        $this->edebug('SERVER -> CLIENT: ' . $announce, self::DEBUG_SERVER);
-        return true;
-    }
-
-    /**
-     * Initiate a TLS (encrypted) session.
-     * @access public
-     * @return boolean
-     */
-    public function startTLS()
-    {
-        if (!$this->sendCommand('STARTTLS', 'STARTTLS', 220)) {
-            return false;
-        }
-
-        //Allow the best TLS version(s) we can
-        $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
-
-        //PHP 5.6.7 dropped inclusion of TLS 1.1 and 1.2 in STREAM_CRYPTO_METHOD_TLS_CLIENT
-        //so add them back in manually if we can
-        if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
-            $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
-            $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
-        }
-
-        // Begin encrypted connection
-        set_error_handler(array($this, 'errorHandler'));
-        $crypto_ok = stream_socket_enable_crypto(
-            $this->smtp_conn,
-            true,
-            $crypto_method
-        );
-        restore_error_handler();
-        return $crypto_ok;
-    }
-
-    /**
-     * Perform SMTP authentication.
-     * Must be run after hello().
-     * @see hello()
-     * @param string $username The user name
-     * @param string $password The password
-     * @param string $authtype The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5, XOAUTH2)
-     * @param string $realm The auth realm for NTLM
-     * @param string $workstation The auth workstation for NTLM
-     * @param null|OAuth $OAuth An optional OAuth instance (@see PHPMailerOAuth)
-     * @return bool True if successfully authenticated.* @access public
-     */
-    public function authenticate(
-        $username,
-        $password,
-        $authtype = null,
-        $realm = '',
-        $workstation = '',
-        $OAuth = null
-    ) {
-        if (!$this->server_caps) {
-            $this->setError('Authentication is not allowed before HELO/EHLO');
-            return false;
-        }
-
-        if (array_key_exists('EHLO', $this->server_caps)) {
-            // SMTP extensions are available; try to find a proper authentication method
-            if (!array_key_exists('AUTH', $this->server_caps)) {
-                $this->setError('Authentication is not allowed at this stage');
-                // 'at this stage' means that auth may be allowed after the stage changes
-                // e.g. after STARTTLS
-                return false;
-            }
-
-            self::edebug('Auth method requested: ' . ($authtype ? $authtype : 'UNKNOWN'), self::DEBUG_LOWLEVEL);
-            self::edebug(
-                'Auth methods available on the server: ' . implode(',', $this->server_caps['AUTH']),
-                self::DEBUG_LOWLEVEL
-            );
-
-            if (empty($authtype)) {
-                foreach (array('CRAM-MD5', 'LOGIN', 'PLAIN', 'NTLM', 'XOAUTH2') as $method) {
-                    if (in_array($method, $this->server_caps['AUTH'])) {
-                        $authtype = $method;
-                        break;
-                    }
-                }
-                if (empty($authtype)) {
-                    $this->setError('No supported authentication methods found');
-                    return false;
-                }
-                self::edebug('Auth method selected: ' . $authtype, self::DEBUG_LOWLEVEL);
-            }
-
-            if (!in_array($authtype, $this->server_caps['AUTH'])) {
-                $this->setError("The requested authentication method \"$authtype\" is not supported by the server");
-                return false;
-            }
-        } elseif (empty($authtype)) {
-            $authtype = 'LOGIN';
-        }
-        switch ($authtype) {
-            case 'PLAIN':
-                // Start authentication
-                if (!$this->sendCommand('AUTH', 'AUTH PLAIN', 334)) {
-                    return false;
-                }
-                // Send encoded username and password
-                if (!$this->sendCommand(
-                    'User & Password',
-                    base64_encode("\0" . $username . "\0" . $password),
-                    235
-                )
-                ) {
-                    return false;
-                }
-                break;
-            case 'LOGIN':
-                // Start authentication
-                if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) {
-                    return false;
-                }
-                if (!$this->sendCommand("Username", base64_encode($username), 334)) {
-                    return false;
-                }
-                if (!$this->sendCommand("Password", base64_encode($password), 235)) {
-                    return false;
-                }
-                break;
-            case 'XOAUTH2':
-                //If the OAuth Instance is not set. Can be a case when PHPMailer is used
-                //instead of PHPMailerOAuth
-                if (is_null($OAuth)) {
-                    return false;
-                }
-                $oauth = $OAuth->getOauth64();
-
-                // Start authentication
-                if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) {
-                    return false;
-                }
-                break;
-            case 'NTLM':
-                /*
-                 * ntlm_sasl_client.php
-                 * Bundled with Permission
-                 *
-                 * How to telnet in windows:
-                 * http://technet.microsoft.com/en-us/library/aa995718%28EXCHG.65%29.aspx
-                 * PROTOCOL Docs http://curl.haxx.se/rfc/ntlm.html#ntlmSmtpAuthentication
-                 */
-                require_once 'extras/ntlm_sasl_client.php';
-                $temp = new stdClass;
-                $ntlm_client = new ntlm_sasl_client_class;
-                //Check that functions are available
-                if (!$ntlm_client->initialize($temp)) {
-                    $this->setError($temp->error);
-                    $this->edebug(
-                        'You need to enable some modules in your php.ini file: '
-                        . $this->error['error'],
-                        self::DEBUG_CLIENT
-                    );
-                    return false;
-                }
-                //msg1
-                $msg1 = $ntlm_client->typeMsg1($realm, $workstation); //msg1
-
-                if (!$this->sendCommand(
-                    'AUTH NTLM',
-                    'AUTH NTLM ' . base64_encode($msg1),
-                    334
-                )
-                ) {
-                    return false;
-                }
-                //Though 0 based, there is a white space after the 3 digit number
-                //msg2
-                $challenge = substr($this->last_reply, 3);
-                $challenge = base64_decode($challenge);
-                $ntlm_res = $ntlm_client->NTLMResponse(
-                    substr($challenge, 24, 8),
-                    $password
-                );
-                //msg3
-                $msg3 = $ntlm_client->typeMsg3(
-                    $ntlm_res,
-                    $username,
-                    $realm,
-                    $workstation
-                );
-                // send encoded username
-                return $this->sendCommand('Username', base64_encode($msg3), 235);
-            case 'CRAM-MD5':
-                // Start authentication
-                if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) {
-                    return false;
-                }
-                // Get the challenge
-                $challenge = base64_decode(substr($this->last_reply, 4));
-
-                // Build the response
-                $response = $username . ' ' . $this->hmac($challenge, $password);
-
-                // send encoded credentials
-                return $this->sendCommand('Username', base64_encode($response), 235);
-            default:
-                $this->setError("Authentication method \"$authtype\" is not supported");
-                return false;
-        }
-        return true;
-    }
-
-    /**
-     * Calculate an MD5 HMAC hash.
-     * Works like hash_hmac('md5', $data, $key)
-     * in case that function is not available
-     * @param string $data The data to hash
-     * @param string $key The key to hash with
-     * @access protected
-     * @return string
-     */
-    protected function hmac($data, $key)
-    {
-        if (function_exists('hash_hmac')) {
-            return hash_hmac('md5', $data, $key);
-        }
-
-        // The following borrowed from
-        // http://php.net/manual/en/function.mhash.php#27225
-
-        // RFC 2104 HMAC implementation for php.
-        // Creates an md5 HMAC.
-        // Eliminates the need to install mhash to compute a HMAC
-        // by Lance Rushing
-
-        $bytelen = 64; // byte length for md5
-        if (strlen($key) > $bytelen) {
-            $key = pack('H*', md5($key));
-        }
-        $key = str_pad($key, $bytelen, chr(0x00));
-        $ipad = str_pad('', $bytelen, chr(0x36));
-        $opad = str_pad('', $bytelen, chr(0x5c));
-        $k_ipad = $key ^ $ipad;
-        $k_opad = $key ^ $opad;
-
-        return md5($k_opad . pack('H*', md5($k_ipad . $data)));
-    }
-
-    /**
-     * Check connection state.
-     * @access public
-     * @return boolean True if connected.
-     */
-    public function connected()
-    {
-        if (is_resource($this->smtp_conn)) {
-            $sock_status = stream_get_meta_data($this->smtp_conn);
-            if ($sock_status['eof']) {
-                // The socket is valid but we are not connected
-                $this->edebug(
-                    'SMTP NOTICE: EOF caught while checking if connected',
-                    self::DEBUG_CLIENT
-                );
-                $this->close();
-                return false;
-            }
-            return true; // everything looks good
-        }
-        return false;
-    }
-
-    /**
-     * Close the socket and clean up the state of the class.
-     * Don't use this function without first trying to use QUIT.
-     * @see quit()
-     * @access public
-     * @return void
-     */
-    public function close()
-    {
-        $this->setError('');
-        $this->server_caps = null;
-        $this->helo_rply = null;
-        if (is_resource($this->smtp_conn)) {
-            // close the connection and cleanup
-            fclose($this->smtp_conn);
-            $this->smtp_conn = null; //Makes for cleaner serialization
-            $this->edebug('Connection: closed', self::DEBUG_CONNECTION);
-        }
-    }
-
-    /**
-     * Send an SMTP DATA command.
-     * Issues a data command and sends the msg_data to the server,
-     * finializing the mail transaction. $msg_data is the message
-     * that is to be send with the headers. Each header needs to be
-     * on a single line followed by a <CRLF> with the message headers
-     * and the message body being separated by and additional <CRLF>.
-     * Implements rfc 821: DATA <CRLF>
-     * @param string $msg_data Message data to send
-     * @access public
-     * @return boolean
-     */
-    public function data($msg_data)
-    {
-        //This will use the standard timelimit
-        if (!$this->sendCommand('DATA', 'DATA', 354)) {
-            return false;
-        }
-
-        /* The server is ready to accept data!
-         * According to rfc821 we should not send more than 1000 characters on a single line (including the CRLF)
-         * so we will break the data up into lines by \r and/or \n then if needed we will break each of those into
-         * smaller lines to fit within the limit.
-         * We will also look for lines that start with a '.' and prepend an additional '.'.
-         * NOTE: this does not count towards line-length limit.
-         */
-
-        // Normalize line breaks before exploding
-        $lines = explode("\n", str_replace(array("\r\n", "\r"), "\n", $msg_data));
-
-        /* To distinguish between a complete RFC822 message and a plain message body, we check if the first field
-         * of the first line (':' separated) does not contain a space then it _should_ be a header and we will
-         * process all lines before a blank line as headers.
-         */
-
-        $field = substr($lines[0], 0, strpos($lines[0], ':'));
-        $in_headers = false;
-        if (!empty($field) && strpos($field, ' ') === false) {
-            $in_headers = true;
-        }
-
-        foreach ($lines as $line) {
-            $lines_out = array();
-            if ($in_headers and $line == '') {
-                $in_headers = false;
-            }
-            //Break this line up into several smaller lines if it's too long
-            //Micro-optimisation: isset($str[$len]) is faster than (strlen($str) > $len),
-            while (isset($line[self::MAX_LINE_LENGTH])) {
-                //Working backwards, try to find a space within the last MAX_LINE_LENGTH chars of the line to break on
-                //so as to avoid breaking in the middle of a word
-                $pos = strrpos(substr($line, 0, self::MAX_LINE_LENGTH), ' ');
-                //Deliberately matches both false and 0
-                if (!$pos) {
-                    //No nice break found, add a hard break
-                    $pos = self::MAX_LINE_LENGTH - 1;
-                    $lines_out[] = substr($line, 0, $pos);
-                    $line = substr($line, $pos);
-                } else {
-                    //Break at the found point
-                    $lines_out[] = substr($line, 0, $pos);
-                    //Move along by the amount we dealt with
-                    $line = substr($line, $pos + 1);
-                }
-                //If processing headers add a LWSP-char to the front of new line RFC822 section 3.1.1
-                if ($in_headers) {
-                    $line = "\t" . $line;
-                }
-            }
-            $lines_out[] = $line;
-
-            //Send the lines to the server
-            foreach ($lines_out as $line_out) {
-                //RFC2821 section 4.5.2
-                if (!empty($line_out) and $line_out[0] == '.') {
-                    $line_out = '.' . $line_out;
-                }
-                $this->client_send($line_out . self::CRLF);
-            }
-        }
-
-        //Message data has been sent, complete the command
-        //Increase timelimit for end of DATA command
-        $savetimelimit = $this->Timelimit;
-        $this->Timelimit = $this->Timelimit * 2;
-        $result = $this->sendCommand('DATA END', '.', 250);
-        $this->recordLastTransactionID();
-        //Restore timelimit
-        $this->Timelimit = $savetimelimit;
-        return $result;
-    }
-
-    /**
-     * Send an SMTP HELO or EHLO command.
-     * Used to identify the sending server to the receiving server.
-     * This makes sure that client and server are in a known state.
-     * Implements RFC 821: HELO <SP> <domain> <CRLF>
-     * and RFC 2821 EHLO.
-     * @param string $host The host name or IP to connect to
-     * @access public
-     * @return boolean
-     */
-    public function hello($host = '')
-    {
-        //Try extended hello first (RFC 2821)
-        return (boolean)($this->sendHello('EHLO', $host) or $this->sendHello('HELO', $host));
-    }
-
-    /**
-     * Send an SMTP HELO or EHLO command.
-     * Low-level implementation used by hello()
-     * @see hello()
-     * @param string $hello The HELO string
-     * @param string $host The hostname to say we are
-     * @access protected
-     * @return boolean
-     */
-    protected function sendHello($hello, $host)
-    {
-        $noerror = $this->sendCommand($hello, $hello . ' ' . $host, 250);
-        $this->helo_rply = $this->last_reply;
-        if ($noerror) {
-            $this->parseHelloFields($hello);
-        } else {
-            $this->server_caps = null;
-        }
-        return $noerror;
-    }
-
-    /**
-     * Parse a reply to HELO/EHLO command to discover server extensions.
-     * In case of HELO, the only parameter that can be discovered is a server name.
-     * @access protected
-     * @param string $type - 'HELO' or 'EHLO'
-     */
-    protected function parseHelloFields($type)
-    {
-        $this->server_caps = array();
-        $lines = explode("\n", $this->helo_rply);
-
-        foreach ($lines as $n => $s) {
-            //First 4 chars contain response code followed by - or space
-            $s = trim(substr($s, 4));
-            if (empty($s)) {
-                continue;
-            }
-            $fields = explode(' ', $s);
-            if (!empty($fields)) {
-                if (!$n) {
-                    $name = $type;
-                    $fields = $fields[0];
-                } else {
-                    $name = array_shift($fields);
-                    switch ($name) {
-                        case 'SIZE':
-                            $fields = ($fields ? $fields[0] : 0);
-                            break;
-                        case 'AUTH':
-                            if (!is_array($fields)) {
-                                $fields = array();
-                            }
-                            break;
-                        default:
-                            $fields = true;
-                    }
-                }
-                $this->server_caps[$name] = $fields;
-            }
-        }
-    }
-
-    /**
-     * Send an SMTP MAIL command.
-     * Starts a mail transaction from the email address specified in
-     * $from. Returns true if successful or false otherwise. If True
-     * the mail transaction is started and then one or more recipient
-     * commands may be called followed by a data command.
-     * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>
-     * @param string $from Source address of this message
-     * @access public
-     * @return boolean
-     */
-    public function mail($from)
-    {
-        $useVerp = ($this->do_verp ? ' XVERP' : '');
-        return $this->sendCommand(
-            'MAIL FROM',
-            'MAIL FROM:<' . $from . '>' . $useVerp,
-            250
-        );
-    }
-
-    /**
-     * Send an SMTP QUIT command.
-     * Closes the socket if there is no error or the $close_on_error argument is true.
-     * Implements from rfc 821: QUIT <CRLF>
-     * @param boolean $close_on_error Should the connection close if an error occurs?
-     * @access public
-     * @return boolean
-     */
-    public function quit($close_on_error = true)
-    {
-        $noerror = $this->sendCommand('QUIT', 'QUIT', 221);
-        $err = $this->error; //Save any error
-        if ($noerror or $close_on_error) {
-            $this->close();
-            $this->error = $err; //Restore any error from the quit command
-        }
-        return $noerror;
-    }
-
-    /**
-     * Send an SMTP RCPT command.
-     * Sets the TO argument to $toaddr.
-     * Returns true if the recipient was accepted false if it was rejected.
-     * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
-     * @param string $address The address the message is being sent to
-     * @access public
-     * @return boolean
-     */
-    public function recipient($address)
-    {
-        return $this->sendCommand(
-            'RCPT TO',
-            'RCPT TO:<' . $address . '>',
-            array(250, 251)
-        );
-    }
-
-    /**
-     * Send an SMTP RSET command.
-     * Abort any transaction that is currently in progress.
-     * Implements rfc 821: RSET <CRLF>
-     * @access public
-     * @return boolean True on success.
-     */
-    public function reset()
-    {
-        return $this->sendCommand('RSET', 'RSET', 250);
-    }
-
-    /**
-     * Send a command to an SMTP server and check its return code.
-     * @param string $command The command name - not sent to the server
-     * @param string $commandstring The actual command to send
-     * @param integer|array $expect One or more expected integer success codes
-     * @access protected
-     * @return boolean True on success.
-     */
-    protected function sendCommand($command, $commandstring, $expect)
-    {
-        if (!$this->connected()) {
-            $this->setError("Called $command without being connected");
-            return false;
-        }
-        //Reject line breaks in all commands
-        if (strpos($commandstring, "\n") !== false or strpos($commandstring, "\r") !== false) {
-            $this->setError("Command '$command' contained line breaks");
-            return false;
-        }
-        $this->client_send($commandstring . self::CRLF);
-
-        $this->last_reply = $this->get_lines();
-        // Fetch SMTP code and possible error code explanation
-        $matches = array();
-        if (preg_match("/^([0-9]{3})[ -](?:([0-9]\\.[0-9]\\.[0-9]) )?/", $this->last_reply, $matches)) {
-            $code = $matches[1];
-            $code_ex = (count($matches) > 2 ? $matches[2] : null);
-            // Cut off error code from each response line
-            $detail = preg_replace(
-                "/{$code}[ -]" .
-                ($code_ex ? str_replace('.', '\\.', $code_ex) . ' ' : '') . "/m",
-                '',
-                $this->last_reply
-            );
-        } else {
-            // Fall back to simple parsing if regex fails
-            $code = substr($this->last_reply, 0, 3);
-            $code_ex = null;
-            $detail = substr($this->last_reply, 4);
-        }
-
-        $this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER);
-
-        if (!in_array($code, (array)$expect)) {
-            $this->setError(
-                "$command command failed",
-                $detail,
-                $code,
-                $code_ex
-            );
-            $this->edebug(
-                'SMTP ERROR: ' . $this->error['error'] . ': ' . $this->last_reply,
-                self::DEBUG_CLIENT
-            );
-            return false;
-        }
-
-        $this->setError('');
-        return true;
-    }
-
-    /**
-     * Send an SMTP SAML command.
-     * Starts a mail transaction from the email address specified in $from.
-     * Returns true if successful or false otherwise. If True
-     * the mail transaction is started and then one or more recipient
-     * commands may be called followed by a data command. This command
-     * will send the message to the users terminal if they are logged
-     * in and send them an email.
-     * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>
-     * @param string $from The address the message is from
-     * @access public
-     * @return boolean
-     */
-    public function sendAndMail($from)
-    {
-        return $this->sendCommand('SAML', "SAML FROM:$from", 250);
-    }
-
-    /**
-     * Send an SMTP VRFY command.
-     * @param string $name The name to verify
-     * @access public
-     * @return boolean
-     */
-    public function verify($name)
-    {
-        return $this->sendCommand('VRFY', "VRFY $name", array(250, 251));
-    }
-
-    /**
-     * Send an SMTP NOOP command.
-     * Used to keep keep-alives alive, doesn't actually do anything
-     * @access public
-     * @return boolean
-     */
-    public function noop()
-    {
-        return $this->sendCommand('NOOP', 'NOOP', 250);
-    }
-
-    /**
-     * Send an SMTP TURN command.
-     * This is an optional command for SMTP that this class does not support.
-     * This method is here to make the RFC821 Definition complete for this class
-     * and _may_ be implemented in future
-     * Implements from rfc 821: TURN <CRLF>
-     * @access public
-     * @return boolean
-     */
-    public function turn()
-    {
-        $this->setError('The SMTP TURN command is not implemented');
-        $this->edebug('SMTP NOTICE: ' . $this->error['error'], self::DEBUG_CLIENT);
-        return false;
-    }
-
-    /**
-     * Send raw data to the server.
-     * @param string $data The data to send
-     * @access public
-     * @return integer|boolean The number of bytes sent to the server or false on error
-     */
-    public function client_send($data)
-    {
-        $this->edebug("CLIENT -> SERVER: $data", self::DEBUG_CLIENT);
-        set_error_handler(array($this, 'errorHandler'));
-        $result = fwrite($this->smtp_conn, $data);
-        restore_error_handler();
-        return $result;
-    }
-
-    /**
-     * Get the latest error.
-     * @access public
-     * @return array
-     */
-    public function getError()
-    {
-        return $this->error;
-    }
-
-    /**
-     * Get SMTP extensions available on the server
-     * @access public
-     * @return array|null
-     */
-    public function getServerExtList()
-    {
-        return $this->server_caps;
-    }
-
-    /**
-     * A multipurpose method
-     * The method works in three ways, dependent on argument value and current state
-     *   1. HELO/EHLO was not sent - returns null and set up $this->error
-     *   2. HELO was sent
-     *     $name = 'HELO': returns server name
-     *     $name = 'EHLO': returns boolean false
-     *     $name = any string: returns null and set up $this->error
-     *   3. EHLO was sent
-     *     $name = 'HELO'|'EHLO': returns server name
-     *     $name = any string: if extension $name exists, returns boolean True
-     *       or its options. Otherwise returns boolean False
-     * In other words, one can use this method to detect 3 conditions:
-     *  - null returned: handshake was not or we don't know about ext (refer to $this->error)
-     *  - false returned: the requested feature exactly not exists
-     *  - positive value returned: the requested feature exists
-     * @param string $name Name of SMTP extension or 'HELO'|'EHLO'
-     * @return mixed
-     */
-    public function getServerExt($name)
-    {
-        if (!$this->server_caps) {
-            $this->setError('No HELO/EHLO was sent');
-            return null;
-        }
-
-        // the tight logic knot ;)
-        if (!array_key_exists($name, $this->server_caps)) {
-            if ($name == 'HELO') {
-                return $this->server_caps['EHLO'];
-            }
-            if ($name == 'EHLO' || array_key_exists('EHLO', $this->server_caps)) {
-                return false;
-            }
-            $this->setError('HELO handshake was used. Client knows nothing about server extensions');
-            return null;
-        }
-
-        return $this->server_caps[$name];
-    }
-
-    /**
-     * Get the last reply from the server.
-     * @access public
-     * @return string
-     */
-    public function getLastReply()
-    {
-        return $this->last_reply;
-    }
-
-    /**
-     * Read the SMTP server's response.
-     * Either before eof or socket timeout occurs on the operation.
-     * With SMTP we can tell if we have more lines to read if the
-     * 4th character is '-' symbol. If it is a space then we don't
-     * need to read anything else.
-     * @access protected
-     * @return string
-     */
-    protected function get_lines()
-    {
-        // If the connection is bad, give up straight away
-        if (!is_resource($this->smtp_conn)) {
-            return '';
-        }
-        $data = '';
-        $endtime = 0;
-        stream_set_timeout($this->smtp_conn, $this->Timeout);
-        if ($this->Timelimit > 0) {
-            $endtime = time() + $this->Timelimit;
-        }
-        while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) {
-            $str = @fgets($this->smtp_conn, 515);
-            $this->edebug("SMTP -> get_lines(): \$data is \"$data\"", self::DEBUG_LOWLEVEL);
-            $this->edebug("SMTP -> get_lines(): \$str is  \"$str\"", self::DEBUG_LOWLEVEL);
-            $data .= $str;
-            // If response is only 3 chars (not valid, but RFC5321 S4.2 says it must be handled),
-            // or 4th character is a space, we are done reading, break the loop,
-            // string array access is a micro-optimisation over strlen
-            if (!isset($str[3]) or (isset($str[3]) and $str[3] == ' ')) {
-                break;
-            }
-            // Timed-out? Log and break
-            $info = stream_get_meta_data($this->smtp_conn);
-            if ($info['timed_out']) {
-                $this->edebug(
-                    'SMTP -> get_lines(): timed-out (' . $this->Timeout . ' sec)',
-                    self::DEBUG_LOWLEVEL
-                );
-                break;
-            }
-            // Now check if reads took too long
-            if ($endtime and time() > $endtime) {
-                $this->edebug(
-                    'SMTP -> get_lines(): timelimit reached (' .
-                    $this->Timelimit . ' sec)',
-                    self::DEBUG_LOWLEVEL
-                );
-                break;
-            }
-        }
-        return $data;
-    }
-
-    /**
-     * Enable or disable VERP address generation.
-     * @param boolean $enabled
-     */
-    public function setVerp($enabled = false)
-    {
-        $this->do_verp = $enabled;
-    }
-
-    /**
-     * Get VERP address generation mode.
-     * @return boolean
-     */
-    public function getVerp()
-    {
-        return $this->do_verp;
-    }
-
-    /**
-     * Set error messages and codes.
-     * @param string $message The error message
-     * @param string $detail Further detail on the error
-     * @param string $smtp_code An associated SMTP error code
-     * @param string $smtp_code_ex Extended SMTP code
-     */
-    protected function setError($message, $detail = '', $smtp_code = '', $smtp_code_ex = '')
-    {
-        $this->error = array(
-            'error' => $message,
-            'detail' => $detail,
-            'smtp_code' => $smtp_code,
-            'smtp_code_ex' => $smtp_code_ex
-        );
-    }
-
-    /**
-     * Set debug output method.
-     * @param string|callable $method The name of the mechanism to use for debugging output, or a callable to handle it.
-     */
-    public function setDebugOutput($method = 'echo')
-    {
-        $this->Debugoutput = $method;
-    }
-
-    /**
-     * Get debug output method.
-     * @return string
-     */
-    public function getDebugOutput()
-    {
-        return $this->Debugoutput;
-    }
-
-    /**
-     * Set debug output level.
-     * @param integer $level
-     */
-    public function setDebugLevel($level = 0)
-    {
-        $this->do_debug = $level;
-    }
-
-    /**
-     * Get debug output level.
-     * @return integer
-     */
-    public function getDebugLevel()
-    {
-        return $this->do_debug;
-    }
-
-    /**
-     * Set SMTP timeout.
-     * @param integer $timeout
-     */
-    public function setTimeout($timeout = 0)
-    {
-        $this->Timeout = $timeout;
-    }
-
-    /**
-     * Get SMTP timeout.
-     * @return integer
-     */
-    public function getTimeout()
-    {
-        return $this->Timeout;
-    }
-
-    /**
-     * Reports an error number and string.
-     * @param integer $errno The error number returned by PHP.
-     * @param string $errmsg The error message returned by PHP.
-     * @param string $errfile The file the error occurred in
-     * @param integer $errline The line number the error occurred on
-     */
-    protected function errorHandler($errno, $errmsg, $errfile = '', $errline = 0)
-    {
-        $notice = 'Connection failed.';
-        $this->setError(
-            $notice,
-            $errno,
-            $errmsg
-        );
-        $this->edebug(
-            $notice . ' Error #' . $errno . ': ' . $errmsg . " [$errfile line $errline]",
-            self::DEBUG_CONNECTION
-        );
-    }
-
-    /**
-     * Extract and return the ID of the last SMTP transaction based on
-     * a list of patterns provided in SMTP::$smtp_transaction_id_patterns.
-     * Relies on the host providing the ID in response to a DATA command.
-     * If no reply has been received yet, it will return null.
-     * If no pattern was matched, it will return false.
-     * @return bool|null|string
-     */
-    protected function recordLastTransactionID()
-    {
-        $reply = $this->getLastReply();
-
-        if (empty($reply)) {
-            $this->last_smtp_transaction_id = null;
-        } else {
-            $this->last_smtp_transaction_id = false;
-            foreach ($this->smtp_transaction_id_patterns as $smtp_transaction_id_pattern) {
-                if (preg_match($smtp_transaction_id_pattern, $reply, $matches)) {
-                    $this->last_smtp_transaction_id = $matches[1];
-                }
-            }
-        }
-
-        return $this->last_smtp_transaction_id;
-    }
-
-    /**
-     * Get the queue/transaction ID of the last SMTP transaction
-     * If no reply has been received yet, it will return null.
-     * If no pattern was matched, it will return false.
-     * @return bool|null|string
-     * @see recordLastTransactionID()
-     */
-    public function getLastTransactionID()
-    {
-        return $this->last_smtp_transaction_id;
-    }
-}
diff --git a/cron/modules/SalesOrder/RecurringInvoice.service b/cron/modules/SalesOrder/RecurringInvoice.service
index ccb87f5b54d1a6d44e24f5c1e8250f5fdeb35cb9..3028fb802cc2b88f51f890f3b656a33b0238f5a4 100644
--- a/cron/modules/SalesOrder/RecurringInvoice.service
+++ b/cron/modules/SalesOrder/RecurringInvoice.service
@@ -159,6 +159,7 @@ function getRecurringDate($recurringDate, $recurringFrequency) {
 
 		case 'monthly'		:	$m = $m + 1;			break;
 		case 'quarterly'	:	$m = $m + 3;			break;
+		case 'every 4 months':	$m = $m + 4;			break;
 		case 'half-yearly'	:	$m = $m + 6;			break;
 		case 'yearly'		:	$y = $y + 1;			break;
 
@@ -185,4 +186,3 @@ function getRecurringDate($recurringDate, $recurringFrequency) {
 
 	return array('validDate' => $validNextRecurringDate, 'nextRecurringDate' => $nextRecurringDate);
 }
-?>
diff --git a/cron/send_mail.php b/cron/send_mail.php
index 384ea3598c1923450233cc2b0996e12fd90d0066..88efc165d31e3abae87c18e6562780f0882431e2 100755
--- a/cron/send_mail.php
+++ b/cron/send_mail.php
@@ -22,8 +22,8 @@
 //file modified by richie
 
 
-require("class.smtp.php");
-require("class.phpmailer.php");
+require_once("modules/Emails/class.smtp.php");
+require_once("modules/Emails/class.phpmailer.php");
 require_once 'include/utils/CommonUtils.php';
 
 function sendmail($to,$from,$subject,$contents,$mail_server,$mail_server_username,$mail_server_password,$filename,$smtp_auth='')
diff --git a/data/CRMEntity.php b/data/CRMEntity.php
index ec61d6fed0bf98fd55446e7cc9d3fc6838baaac9..2ff6a3c47640c7ccbd86a2867470917f8027d793 100644
--- a/data/CRMEntity.php
+++ b/data/CRMEntity.php
@@ -278,6 +278,23 @@ class CRMEntity {
 		if ($module == 'Events') {
 			$module = 'Calendar';
 		}
+
+		$entityFields = Vtiger_Functions::getEntityModuleInfo($module);
+        $entityFieldNames  = explode(',', $entityFields['fieldname']);
+        switch ($module) {
+            case 'HelpDesk': $entityFieldNames = array('ticket_title');
+                break;
+            case 'Documents': $entityFieldNames = array('notes_title');
+                break;
+		}
+		
+		$record_label = '';
+		foreach($entityFieldNames as $entityFieldName) {
+			$record_label .= $this->column_fields[$entityFieldName]." ";
+		}
+        $label = decode_html($record_label);
+        $this->column_fields['label'] = $label;
+
 		if ($this->mode == 'edit') {
 			$description_val = from_html($this->column_fields['description'], ($insertion_mode == 'edit') ? true : false);
 
@@ -291,8 +308,8 @@ class CRMEntity {
 
 			$acl = Vtiger_AccessControl::loadUserPrivileges($current_user->id);
 			if ($acl->is_admin == true || $acl->profileGlobalPermission[1] == 0 || $acl->profileGlobalPermission[2] == 0 || $this->isWorkFlowFieldUpdate) {
-				$sql = "update vtiger_crmentity set smownerid=?, smgroupid=?,modifiedby=?,description=?, modifiedtime=? where crmid=?";
-				$params = array($ownerid, $groupid, $current_user->id, $description_val, $adb->formatDate($date_var, true), $this->id);
+				$sql = "update vtiger_crmentity set smownerid=?, smgroupid=?,modifiedby=?,description=?, modifiedtime=?";
+				$params = array($ownerid, $groupid, $current_user->id, $description_val, $adb->formatDate($date_var, true));
 			} else {
 				$profileList = getCurrentUserProfileList();
 				$perm_qry = "SELECT columnname FROM vtiger_field INNER JOIN vtiger_profile2field ON vtiger_profile2field.fieldid = vtiger_field.fieldid INNER JOIN vtiger_def_org_field ON vtiger_def_org_field.fieldid = vtiger_field.fieldid WHERE vtiger_field.tabid = ? AND vtiger_profile2field.visible = 0 AND vtiger_profile2field.readonly = 0 AND vtiger_profile2field.profileid IN (" . generateQuestionMarks($profileList) . ") AND vtiger_def_org_field.visible = 0 and vtiger_field.tablename='vtiger_crmentity' and vtiger_field.displaytype in (1,3) and vtiger_field.presence in (0,2);";
@@ -302,13 +319,22 @@ class CRMEntity {
 					$columname[] = $adb->query_result($perm_result, $i, "columnname");
 				}
 				if (is_array($columname) && in_array("description", $columname)) {
-					$sql = "update vtiger_crmentity set smownerid=?, smgroupid=?, modifiedby=?,description=?, modifiedtime=? where crmid=?";
-					$params = array($ownerid, $groupid, $current_user->id, $description_val, $adb->formatDate($date_var, true), $this->id);
+					$sql = "update vtiger_crmentity set smownerid=?, smgroupid=?, modifiedby=?,description=?, modifiedtime=?";
+					$params = array($ownerid, $groupid, $current_user->id, $description_val, $adb->formatDate($date_var, true));
 				} else {
-					$sql = "update vtiger_crmentity set smownerid=?, smgroupid=?,modifiedby=?, modifiedtime=? where crmid=?";
-					$params = array($ownerid, $groupid, $current_user->id, $adb->formatDate($date_var, true), $this->id);
+					$sql = "update vtiger_crmentity set smownerid=?, smgroupid=?,modifiedby=?, modifiedtime=?";
+					$params = array($ownerid, $groupid, $current_user->id, $adb->formatDate($date_var, true));
 				}
 			}
+
+			if($label) {
+				$sql .= ", label = ? ";
+				array_push($params, trim($label));
+			}
+
+			$sql .= " where crmid=?";
+			array_push($params,$this->id);
+
 			$adb->pquery($sql, $params);
 			$this->column_fields['modifiedtime'] =  $modified_date_var;
 			$this->column_fields['modifiedby'] = $current_user->id;
@@ -339,8 +365,19 @@ class CRMEntity {
 			}
 
 			$description_val = from_html($this->column_fields['description'], ($insertion_mode == 'edit') ? true : false);
-			$sql = "insert into vtiger_crmentity (crmid,smcreatorid,smownerid,smgroupid,setype,description,modifiedby,createdtime,modifiedtime,source) values(?,?,?,?,?,?,?,?,?,?)";
-			$params = array($current_id, $current_user->id, $ownerid, $groupid, $module, $description_val, $current_user->id, $created_date_var, $modified_date_var,$source);
+			$params = array("crmid" => $current_id, "smcreatorid" => $current_user->id, "smownerid" => $ownerid, 
+							"smgroupid" => $groupid, "setype" => $module, "description" => $description_val,
+							"modifiedby" => $current_user->id, "createdtime" => $created_date_var, 
+							"modifiedtime" => $modified_date_var, "source" => $source);
+
+			if($label) {
+				$params['label'] = trim($label);
+			}
+
+			$insert_columns = array_keys($params);
+			$insert_data = array_values($params);
+			$sql = "insert into vtiger_crmentity (".implode(",",$insert_columns).") values(".generateQuestionMarks($insert_data).")";
+
 			$adb->pquery($sql, $params);
 
 			$this->column_fields['createdtime'] = $created_date_var;
diff --git a/include/QueryGenerator/EnhancedQueryGenerator.php b/include/QueryGenerator/EnhancedQueryGenerator.php
index 5b139793b72e6c4b06693080d5ab59ae76e45921..67c7275c49317c374a76cca4f1e1b4bf54087be8 100644
--- a/include/QueryGenerator/EnhancedQueryGenerator.php
+++ b/include/QueryGenerator/EnhancedQueryGenerator.php
@@ -726,7 +726,7 @@ class EnhancedQueryGenerator extends QueryGenerator {
 						$startDateValue = explode(' ', $values[0]);
 						$endDateValue = explode(' ', $values[1]);
 						if (count($startDateValue) == 2 && count($endDateValue) == 2) {
-							$fieldSql .= " CAST(CONCAT($dateFieldColumnName,' ',$timeFieldColumnName) AS DATETIME) $valueSql";
+							$fieldSql .= " CONCAT($dateFieldColumnName,' ',$timeFieldColumnName) $valueSql";
 						} else {
 							$fieldSql .= "$dateFieldColumnName $valueSql";
 						}
@@ -736,7 +736,7 @@ class EnhancedQueryGenerator extends QueryGenerator {
 						}
 						$values = explode(' ', $value);
 						if (count($values) == 2) {
-							$fieldSql .= "$fieldGlue CAST(CONCAT($dateFieldColumnName,' ',$timeFieldColumnName) AS DATETIME) $valueSql ";
+							$fieldSql .= "$fieldGlue CONCAT($dateFieldColumnName,' ',$timeFieldColumnName) $valueSql ";
 						} else {
 							$fieldSql .= "$fieldGlue $dateFieldColumnName $valueSql";
 						}
diff --git a/include/QueryGenerator/QueryGenerator.php b/include/QueryGenerator/QueryGenerator.php
index bafbd821a7433f68c9553be0eb0f551593b9ae1c..3f452468efa6ad9880c977c59487aa631d10a2ff 100644
--- a/include/QueryGenerator/QueryGenerator.php
+++ b/include/QueryGenerator/QueryGenerator.php
@@ -799,7 +799,7 @@ class QueryGenerator {
 						$startDateValue = explode(' ', $values[0]);
 						$endDateValue = explode(' ', $values[1]);
 						if(count($startDateValue) == 2 && count($endDateValue) == 2) {
-							$fieldSql .= " CAST(CONCAT($dateFieldColumnName,' ',$timeFieldColumnName) AS DATETIME) $valueSql";
+							$fieldSql .= " CONCAT($dateFieldColumnName,' ',$timeFieldColumnName) $valueSql";
 						} else {
 							$fieldSql .= "$dateFieldColumnName $valueSql";
 						}
@@ -809,7 +809,7 @@ class QueryGenerator {
 						}
 						$values = explode(' ', $value);
 						if(count($values) == 2) {
-								$fieldSql .= "$fieldGlue CAST(CONCAT($dateFieldColumnName,' ',$timeFieldColumnName) AS DATETIME) $valueSql ";
+								$fieldSql .= "$fieldGlue CONCAT($dateFieldColumnName,' ',$timeFieldColumnName) $valueSql ";
 						} else {
 								$fieldSql .= "$fieldGlue $dateFieldColumnName $valueSql";
 						}
diff --git a/include/Webservices/Custom/ChangePassword.php b/include/Webservices/Custom/ChangePassword.php
index eafc3211e696d2902da2b17315ff68110e4bc956..716244b18c8645c1f8404b9b1f5de5b202357fdc 100644
--- a/include/Webservices/Custom/ChangePassword.php
+++ b/include/Webservices/Custom/ChangePassword.php
@@ -41,30 +41,45 @@ function vtws_changePassword($id, $oldPassword, $newPassword, $confirmPassword,
 							WebServiceErrorCode::$INVALIDOLDPASSWORD));
 			}
 		}
-		if(strcmp($newPassword, $confirmPassword) === 0) {
-			$db = PearDatabase::getInstance();
-			$db->dieOnError = true;
-			$db->startTransaction();
-			$success = $newUser->change_password($oldPassword, $newPassword, false);
-			$error = $db->hasFailedTransaction();
-			$db->completeTransaction();
-			if($error) {
-				throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR, 
-					vtws_getWebserviceTranslatedString('LBL_'.
-							WebServiceErrorCode::$DATABASEQUERYERROR));
-			}
-			if(!$success) {
-				throw new WebServiceException(WebServiceErrorCode::$CHANGEPASSWORDFAILURE, 
-					vtws_getWebserviceTranslatedString('LBL_'.
-							WebServiceErrorCode::$CHANGEPASSWORDFAILURE));
-			}
-		} else {
-			throw new WebServiceException(WebServiceErrorCode::$CHANGEPASSWORDFAILURE, 
-					vtws_getWebserviceTranslatedString('LBL_'.
-							WebServiceErrorCode::$CHANGEPASSWORDFAILURE));
-		}
+                if(isPasswordStrong($newPassword)) {
+                    if(strcmp($newPassword, $confirmPassword) === 0) {
+                            $db = PearDatabase::getInstance();
+                            $db->dieOnError = true;
+                            $db->startTransaction();
+                            $success = $newUser->change_password($oldPassword, $newPassword, false);
+                            $error = $db->hasFailedTransaction();
+                            $db->completeTransaction();
+                            if($error) {
+                                    throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR, 
+                                            vtws_getWebserviceTranslatedString('LBL_'.
+                                                            WebServiceErrorCode::$DATABASEQUERYERROR));
+                            }
+                            if(!$success) {
+                                    throw new WebServiceException(WebServiceErrorCode::$CHANGEPASSWORDFAILURE, 
+                                            vtws_getWebserviceTranslatedString('LBL_'.
+                                                            WebServiceErrorCode::$CHANGEPASSWORDFAILURE));
+                            }
+                    } else {
+                            throw new WebServiceException(WebServiceErrorCode::$CHANGEPASSWORDFAILURE, 
+                                            vtws_getWebserviceTranslatedString('LBL_'.
+                                                            WebServiceErrorCode::$CHANGEPASSWORDFAILURE));
+                    }
+                } else {
+                    throw new WebServiceException(WebServiceErrorCode::$CHANGEPASSWORDFAILURE, 
+                                            vtws_getWebserviceTranslatedString('LBL_'.
+                                                            WebServiceErrorCode::$PASSWORDNOTSTRONG));
+                }
 		VTWS_PreserveGlobal::flush();
 		return array('message' => 'Changed password successfully');
 	}
 }
+
+function isPasswordStrong($new_password){
+    $runtime_configs = Vtiger_Runtime_Configs::getInstance();
+    $password_regex = $runtime_configs->getValidationRegex('password_regex');
+    if (preg_match('/'.$password_regex.'/i', $new_password) == 1) {
+            return true;
+    }
+    return false;
+}
 ?>
\ No newline at end of file
diff --git a/include/Webservices/Utils.php b/include/Webservices/Utils.php
index cd0d3cc580fb82ddfbdda0142725bf43e4b57692..2ac8e592f797da550eff5774c0ff4a960c6f78c6 100644
--- a/include/Webservices/Utils.php
+++ b/include/Webservices/Utils.php
@@ -1291,7 +1291,7 @@ function vtws_filedetails($fileData){
         $fileName = $fileData['name'];
         $fileType = $fileData['type'];
         $fileName = html_entity_decode($fileName, ENT_QUOTES, vglobal('default_charset'));
-        $filenamewithpath = $fileData['path'].'_'.$fileData['encName'];
+        $filenamewithpath = $fileData['path'].$fileData['attachmentsid'].'_'.$fileData['storedname'];
         $filesize = filesize($filenamewithpath);
         $fileDetails['fileid'] = $fileData['attachmentsid'];
         $fileDetails['filename'] = $fileName;
diff --git a/include/Webservices/WebServiceErrorCode.php b/include/Webservices/WebServiceErrorCode.php
index 63e991f08c6cd98ab2286e8271827d415fd259e4..7b7a06d2327c04a08465a6019360ddeb60581a56 100644
--- a/include/Webservices/WebServiceErrorCode.php
+++ b/include/Webservices/WebServiceErrorCode.php
@@ -42,6 +42,7 @@
         public static $POTENTIAL_RELATED_UPDATE_FAILED = "POTENTIAL_RELATEDLIST_UPDATE_FAILED";
         public static $FAILED_TO_CREATE = "FAILED_TO_CREATE";
 		public static $INACTIVECURRENCY = "CURRENCY_INACTIVE";
+                public static $PASSWORDNOTSTRONG = "PASSWORD_NOT_STRONG";
 	}
 	
 ?>
diff --git a/include/fields/DateTimeField.php b/include/fields/DateTimeField.php
index 0fdce417a3fbdd98e306a56bae51fa0ca11eb49c..eb9dde1d86e59a12571ebae7ff8aed7452c1e592 100644
--- a/include/fields/DateTimeField.php
+++ b/include/fields/DateTimeField.php
@@ -372,7 +372,7 @@ class DateTimeField {
 					case 'mm.dd.yyyy': list($m, $d, $y) = explode('.', $date); break;
 					case 'dd.mm.yyyy': list($d, $m, $y) = explode('.', $date); break;
 					case 'dd/mm/yyyy': list($d, $m, $y) = explode('/', $date); break;
-					case 'mm/dd/yyyy': list($d, $m, $y) = explode('/', $date); break;
+					case 'mm/dd/yyyy': list($m, $d, $y) = explode('/', $date); break;
 					case 'mm-dd-yyyy': list($m, $d, $y) = explode('-', $date); break;
 					case 'dd-mm-yyyy': list($d, $m, $y) = explode('-', $date); break;
 				}
diff --git a/include/utils/UserInfoUtil.php b/include/utils/UserInfoUtil.php
index 2ce1811cc2c4d200d78e3cce48ab8814ec112da8..632e79778e048cfd512b512315b424c78a6657a0 100755
--- a/include/utils/UserInfoUtil.php
+++ b/include/utils/UserInfoUtil.php
@@ -1082,7 +1082,7 @@ function getRoleUsers($roleId)
 	$roleRelatedUsers=Array();
 	for($i=0; $i<$num_rows; $i++)
 	{
-		$roleRelatedUsers[$adb->query_result($result,$i,'userid')]=getFullNameFromQResult($result, $i, 'Users');
+		$roleRelatedUsers[$adb->query_result($result,$i,'userid')]=$adb->query_result($result,$i,'userlabel');
 	}
 	$log->debug("Exiting getRoleUsers method ...");
 	return $roleRelatedUsers;
@@ -1302,14 +1302,14 @@ function getAllUserName()
 	global $log;
 	$log->debug("Entering getAllUserName() method ...");
 	global $adb;
-	$query="select * from vtiger_users where deleted=0";
+	$query="select id, userlabel from vtiger_users where deleted=0";
 	$result = $adb->pquery($query, array());
 	$num_rows=$adb->num_rows($result);
 	$user_details=Array();
 	for($i=0;$i<$num_rows;$i++)
 	{
 		$userid=$adb->query_result($result,$i,'id');
-		$username=getFullNameFromQResult($result, $i, 'Users');
+		$username=$adb->query_result($result,$i,'userlabel');
 		$user_details[$userid]=$username;
 
 	}
diff --git a/include/utils/VtlibUtils.php b/include/utils/VtlibUtils.php
index 94e9b94c233c1b0f57c79050482c7d23fbee3a28..12b068873b3de9774376438c83da1e4ee2093b96 100644
--- a/include/utils/VtlibUtils.php
+++ b/include/utils/VtlibUtils.php
@@ -695,7 +695,7 @@ function vtlib_purify($input, $ignore = false) {
                 'data' => true
             );
 
-            include_once ('libraries/htmlpurifier410/library/HTMLPurifier.auto.php');
+            include_once __DIR__ . '/../../libraries/htmlpurifier410/library/HTMLPurifier.auto.php';
 
             $config = HTMLPurifier_Config::createDefault();
             $config->set('Core.Encoding', $use_charset);
diff --git a/include/utils/utils.php b/include/utils/utils.php
index a5a4e1b4afc5a9cae97a69f0c1d846f638b11bab..8f567566d834c4b281a0484dad6b294b8e5cb328 100755
--- a/include/utils/utils.php
+++ b/include/utils/utils.php
@@ -40,6 +40,7 @@ require_once 'vtlib/Vtiger/Deprecated.php';
 require_once 'includes/runtime/Cache.php';
 require_once 'modules/Vtiger/helpers/Util.php';
 require_once 'vtlib/Vtiger/AccessControl.php';
+require_once 'includes/runtime/Configs.php';
 // Constants to be defined here
 
 // For Migration status.
@@ -136,24 +137,24 @@ function get_user_array($add_blank=true, $status="Active", $assigned_user="",$pr
 		$temp_result = Array();
 		// Including deleted vtiger_users for now.
 		if (empty($status)) {
-				$query = "SELECT id, user_name from vtiger_users";
+				$query = "SELECT id, user_name, userlabel from vtiger_users";
 				$params = array();
 		}
 		else {
 				if($private == 'private')
 				{
 					$log->debug("Sharing is Private. Only the current user should be listed");
-					$query = "select id as id,user_name as user_name,first_name,last_name from vtiger_users where id=? and status='Active' union select vtiger_user2role.userid as id,vtiger_users.user_name as user_name ,
-							  vtiger_users.first_name as first_name ,vtiger_users.last_name as last_name
+					$query = "select id as id,user_name as user_name,first_name,last_name,userlabel from vtiger_users where id=? and status='Active' union select vtiger_user2role.userid as id,vtiger_users.user_name as user_name ,
+							  vtiger_users.first_name as first_name ,vtiger_users.last_name as last_name, vtiger_users.userlabel AS userlabel 
 							  from vtiger_user2role inner join vtiger_users on vtiger_users.id=vtiger_user2role.userid inner join vtiger_role on vtiger_role.roleid=vtiger_user2role.roleid where vtiger_role.parentrole like ? and status='Active' union
 							  select shareduserid as id,vtiger_users.user_name as user_name ,
-							  vtiger_users.first_name as first_name ,vtiger_users.last_name as last_name  from vtiger_tmp_write_user_sharing_per inner join vtiger_users on vtiger_users.id=vtiger_tmp_write_user_sharing_per.shareduserid where status='Active' and vtiger_tmp_write_user_sharing_per.userid=? and vtiger_tmp_write_user_sharing_per.tabid=? and (user_name != 'admin' OR is_owner=1)";
+							  vtiger_users.first_name as first_name ,vtiger_users.last_name as last_name,vtiger_users.userlabel AS userlabel from vtiger_tmp_write_user_sharing_per inner join vtiger_users on vtiger_users.id=vtiger_tmp_write_user_sharing_per.shareduserid where status='Active' and vtiger_tmp_write_user_sharing_per.userid=? and vtiger_tmp_write_user_sharing_per.tabid=? and (user_name != 'admin' OR is_owner=1)";
 					$params = array($current_user->id, $current_user_parent_role_seq."::%", $current_user->id, getTabid($module));
 				}
 				else
 				{
 					$log->debug("Sharing is Public. All vtiger_users should be listed");
-					$query = "SELECT id, user_name,first_name,last_name from vtiger_users WHERE status=? and (user_name != 'admin' OR is_owner=1)";
+					$query = "SELECT id, user_name,first_name,last_name,userlabel from vtiger_users WHERE status=? and (user_name != 'admin' OR is_owner=1)";
 					$params = array($status);
 				}
 		}
@@ -174,7 +175,7 @@ function get_user_array($add_blank=true, $status="Active", $assigned_user="",$pr
 		// Get the id and the name.
 		while($row = $db->fetchByAssoc($result))
 		{
-			$temp_result[$row['id']] = getFullNameFromArray('Users', $row);
+			$temp_result[$row['id']] = $row['userlabel'];
 		}
 
 		$user_array = &$temp_result;
diff --git a/includes/http/Session.php b/includes/http/Session.php
index 789812e98096ac066cbe34c4ea8f386558a7a2b9..2c8257059f4bdf92062e61b7b0976f2bbd5309db 100644
--- a/includes/http/Session.php
+++ b/includes/http/Session.php
@@ -8,6 +8,16 @@
  * All Rights Reserved.
  ************************************************************************************/
 
+/**
+ * Override default user-session storage functions if custom session connector exist.
+ */
+$runtime_configs = Vtiger_Runtime_Configs::getInstance();
+$custom_session_handlerclass = $runtime_configs->getConnector('session');
+if($custom_session_handlerclass) {
+	$handler = $custom_session_handlerclass::getInstance();
+	session_set_save_handler($handler, true);
+}
+
 // Import dependencies
 include_once 'libraries/HTTP_Session2/HTTP/Session2.php';
 
diff --git a/includes/runtime/Cache.php b/includes/runtime/Cache.php
index e89b800e96f62963a6a9e6dfdb1e8d5f4ddf4765..8f0f544b4618bd4dbb40175a396d60b551117239 100644
--- a/includes/runtime/Cache.php
+++ b/includes/runtime/Cache.php
@@ -17,7 +17,9 @@ class Vtiger_Cache {
 	protected $connector;
 
 	private function __construct() {
-		$this->connector = Vtiger_Cache_Connector::getInstance();
+		$runtime_configs = Vtiger_Runtime_Configs::getInstance();
+		$connector_class = $runtime_configs->getConnector('cache', 'Vtiger_Cache_Connector');
+		$this->connector = $connector_class::getInstance();
 	}
 
 	public static function getInstance(){
diff --git a/includes/runtime/Configs.php b/includes/runtime/Configs.php
new file mode 100644
index 0000000000000000000000000000000000000000..1ced96a96301f2210cf034c2cafc7597c95f3b60
--- /dev/null
+++ b/includes/runtime/Configs.php
@@ -0,0 +1,61 @@
+<?php
+/*+***********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.0
+ * ("License"); You may not use this file except in compliance with the License
+ * The Original Code is:  vtiger CRM Open Source
+ * The Initial Developer of the Original Code is vtiger.
+ * Portions created by vtiger are Copyright (C) vtiger.
+ * All Rights Reserved.
+ *************************************************************************************/
+
+ require_once 'includes/runtime/BaseModel.php';
+
+ class Vtiger_Runtime_Configs extends Vtiger_Base_Model {
+
+    private static $instance = false;
+
+    public static function getInstance() {
+        if(self::$instance === false) {
+            self::$instance = new self();
+        }
+
+        return self::$instance;
+    }
+
+    /**
+     * Function to fetch runtime connectors configured in config_override.php
+     * @params $identifier - Connector identifier Ex: session
+     * @params $default - Default connector class name.
+     */
+    public function getConnector($identifier, $default = '') {
+        global $runtime_connectors;
+
+        $connector = '';
+        if(isset($runtime_connectors[$identifier])) {
+            $connector = $runtime_connectors[$identifier];
+        }
+
+        if(empty($connector) && !empty($default)) {
+            $connector = $default;
+        }
+
+        return $connector;
+    }
+    
+    /**
+     * Function to fetch the value for given key
+     */
+    public function getValidationRegex($key, $default = '') {
+        global $validation_regex;
+        
+        $value = '';
+        if(isset($validation_regex[$key])) {
+            $value = $validation_regex[$key];
+        }
+
+        if(empty($value) && !empty($default)) {
+            $value = $default;
+        }
+        return $value;
+    }
+ }
\ No newline at end of file
diff --git a/kcfinder/core/uploader.php b/kcfinder/core/uploader.php
index 42059a6e293457f0d943fe7facc755c6381e54a6..5bc1b968c2511737004d96d3001de65e8b508b06 100644
--- a/kcfinder/core/uploader.php
+++ b/kcfinder/core/uploader.php
@@ -12,6 +12,9 @@
   *      @link http://kcfinder.sunhater.com
   */
 
+require_once __DIR__ . '/../../include/utils/VtlibUtils.php';
+require_once __DIR__ . '/../../vtlib/Vtiger/Functions.php';
+
 class uploader {
     protected $config = array();
     protected $opener = array();
diff --git a/languages/en_us/Vtiger.php b/languages/en_us/Vtiger.php
index fec33408cb3c3829e387560eb50fc1ff12cb95e7..b93df6ce8be8a4de9ee36c93ca9c84760a280e53 100644
--- a/languages/en_us/Vtiger.php
+++ b/languages/en_us/Vtiger.php
@@ -1942,4 +1942,5 @@ $jsLanguageStrings = array(
         'JS_RELATED_ACCOUNT_IS_NOT_AVAILABLE' => 'Related Organization record is not available',
         'JS_RELATED_CONTACT_IS_NOT_AVAILABLE' => 'Related Contact record is not available',
         'JS_REPEAT_DATE_SHOULD_BE_GREATER_THAN_START_DATE' => 'Repeat date should be greater than or equal to Start Date',
+        'JS_PASSWORD_NOT_STRONG' => 'To keep your data safe, we suggest that you use a strong password &lt;br&gt; &lt;ul&gt; &lt;li&gt;Password should be at least 8 characters long &lt;/li&gt; &lt;li&gt;Include at least one number &lt;/li&gt; &lt;li&gt;Include at least one lowercase alphabet &lt;/li&gt; &lt;li&gt;Include at least one uppercase alphabet &lt;/li&gt; &lt;li&gt;Include at least one special character in the password &lt;/li&gt; &lt;/ul&gt;',
 );
diff --git a/languages/en_us/Webservices.php b/languages/en_us/Webservices.php
index 5cac9203a02497b35b6229c8858016034861419a..8d0dfd545c22723a5343dca33afd9e44163aca8c 100644
--- a/languages/en_us/Webservices.php
+++ b/languages/en_us/Webservices.php
@@ -14,4 +14,5 @@ $languageStrings = array(
 	'LBL_DATABASE_QUERY_ERROR' => 'Database error while performing requested operation',
 	'LBL_INVALID_OLD_PASSWORD' => 'Invalid value given for old password.',
 	'LBL_NEW_PASSWORD_MISMATCH' => "New Password and confirm password don't match",
+        'LBL_PASSWORD_NOT_STRONG' => 'To keep your data safe, we suggest that you use a strong password &lt;br&gt; &lt;ul&gt; &lt;li&gt;Password should be at least 8 characters long &lt;/li&gt; &lt;li&gt;Include at least one number &lt;/li&gt; &lt;li&gt;Include at least one lowercase alphabet &lt;/li&gt; &lt;li&gt;Include at least one uppercase alphabet &lt;/li&gt; &lt;li&gt;Include at least one special character in the password &lt;/li&gt; &lt;/ul&gt;',
 );
\ No newline at end of file
diff --git a/layouts/v7/modules/Install/Step4.tpl b/layouts/v7/modules/Install/Step4.tpl
index f358877d786088e4ab182ef530e6bc1e71a7c5e0..63a659f15fad0bf95bf832efeddb4cf85f47f0f7 100644
--- a/layouts/v7/modules/Install/Step4.tpl
+++ b/layouts/v7/modules/Install/Step4.tpl
@@ -28,6 +28,7 @@
 			<div class="row hide" id="errorMessage"></div>
 			<div class="row">
 				<div class="col-sm-6">
+                                    <input type='hidden' name='pwd_regex' value= {ZEND_json::encode($PWD_REGEX)} />
 					<table class="config-table input-table">
 						<thead>
 							<tr><th colspan="2">{vtranslate('LBL_DATABASE_INFORMATION', 'Install')}</th></tr>
diff --git a/layouts/v7/modules/Install/resources/Index.js b/layouts/v7/modules/Install/resources/Index.js
index af13ce3359902a69cdb56c0b81b87b575d80266c..46a63970354432612a9039dbbf40fabbd743bdfc 100644
--- a/layouts/v7/modules/Install/resources/Index.js
+++ b/layouts/v7/modules/Install/resources/Index.js
@@ -73,7 +73,7 @@ jQuery.Class('Install_Index_Js', {}, {
 		});
 
 		jQuery('input[name="password"]').on('blur', function (e) {
-			var retypePassword = jQuery('input[name="retype_password"]');
+                        var retypePassword = jQuery('input[name="retype_password"]');
 			if (retypePassword.val() != '' && retypePassword.val() !== jQuery(e.currentTarget).val()) {
 				jQuery('#passwordError').html('Please re-enter passwords.  The \"Password\" and \"Re-type password\" values do not match.');
 			} else {
@@ -114,6 +114,13 @@ jQuery.Class('Install_Index_Js', {}, {
 				error = true;
 			}
 
+                        var passwordField = jQuery('input[name="password"]');
+                        if(passwordField.val() != ''){
+                            if(!vtUtils.isPasswordStrong(passwordField.val())) {
+                                    error = true;
+                                    var passwordNotStrong = true;
+                            }
+                        }
 			var emailField = jQuery('input[name="admin_email"]');
 			var regex = /^[_/a-zA-Z0-9*]+([!"#$%&'()*+,./:;<=>?\^_`{|}~-]?[a-zA-Z0-9/_/-])*@[a-zA-Z0-9]+([\_\-\.]?[a-zA-Z0-9]+)*\.([\-\_]?[a-zA-Z0-9])+(\.?[a-zA-Z0-9]+)?$/;
 			if (!regex.test(emailField.val()) && emailField.val() != '') {
@@ -133,7 +140,16 @@ jQuery.Class('Install_Index_Js', {}, {
 							'Warning! Invalid email address.' +
 							'</div>' +
 							'</div>';
-				} else {
+				} else if(passwordNotStrong){
+                                        content = '<div class="col-sm-12">' +
+							'<div class="alert errorMessageContent">' +
+							'<button class="close" data-dismiss="alert" type="button">x</button>' +
+							'To keep your data safe, we suggest that you use a strong password <br>'+
+                                                        '<ul> <li>Password should be at least 8 characters long </li> <li>Include at least one number </li><li>Include at least one lowercase alphabet </li> <li>Include at least one uppercase alphabet </li>'+
+                                                        '<li>Include at least one special character in the password </li> </ul>' +
+							'</div>' +
+							'</div>';
+                                }else {
 					content = '<div class="col-sm-12">' +
 							'<div class="alert errorMessageContent">' +
 							'<button class="close" data-dismiss="alert" type="button">x</button>' +
diff --git a/layouts/v7/modules/Users/DetailViewBlockView.tpl b/layouts/v7/modules/Users/DetailViewBlockView.tpl
index 33ba6ff0023b9b68204654283e635585ab0e7bab..18f2528e965f31245df4260364218a0e7b773286 100644
--- a/layouts/v7/modules/Users/DetailViewBlockView.tpl
+++ b/layouts/v7/modules/Users/DetailViewBlockView.tpl
@@ -9,6 +9,7 @@
 
 {strip}
 	<input type=hidden name="timeFormatOptions" data-value='{$DAY_STARTS}' />
+        <input type='hidden' name='pwd_regex' value= {ZEND_json::encode($PWD_REGEX)} />
 	{foreach key=BLOCK_LABEL_KEY item=FIELD_MODEL_LIST from=$RECORD_STRUCTURE}
 		{if $BLOCK_LABEL_KEY neq 'LBL_CALENDAR_SETTINGS'}
 			{assign var=BLOCK value=$BLOCK_LIST[$BLOCK_LABEL_KEY]}
diff --git a/layouts/v7/modules/Users/EditView.tpl b/layouts/v7/modules/Users/EditView.tpl
index 244ea2a65d2f6c76151c48200dead5d30f46fad9..a8126d8eaf03ad3b2c63efc9a2688ecffa518419 100644
--- a/layouts/v7/modules/Users/EditView.tpl
+++ b/layouts/v7/modules/Users/EditView.tpl
@@ -40,6 +40,7 @@
                     <input type="hidden" name="defaultCallDuration" value="{$USER_MODEL->get('callduration')}" />
                     <input type="hidden" name="defaultOtherEventDuration" value="{$USER_MODEL->get('othereventduration')}" />
                     <input type="hidden" name="isPreference" value="{$IS_PREFERENCE}" />
+                    <input type='hidden' name='pwd_regex' value= {ZEND_json::encode($PWD_REGEX)} />
                     {if $IS_RELATION_OPERATION }
                         <input type="hidden" name="sourceModule" value="{$SOURCE_MODULE}" />
                         <input type="hidden" name="sourceRecord" value="{$SOURCE_RECORD}" />
diff --git a/layouts/v7/modules/Users/FPLogin.tpl b/layouts/v7/modules/Users/FPLogin.tpl
index e383b6c3cfb1a2b0c9b445a993d1dd4202d2f789..8d4412a6d10ea1c692f4dab9ba2d2e890bb1f955 100644
--- a/layouts/v7/modules/Users/FPLogin.tpl
+++ b/layouts/v7/modules/Users/FPLogin.tpl
@@ -12,7 +12,7 @@
 {*<DIV>TEMPLATE: layout/modules/Users/FPLogin.tpl</DIV>*}
 
 {if $ERROR}
-	Error, please retry setting the password!!
+	{$MESSAGE}
 {else}
 	<h4>Loading .... </h4>
 	<form class="form-horizontal" name="login" id="login" method="post" action="../../../index.php?module=Users&action=Login">
diff --git a/layouts/v7/modules/Users/ListViewHeader.tpl b/layouts/v7/modules/Users/ListViewHeader.tpl
index 0bf4e1c24174521b7deeb62ff31147bd99098b9f..719ec63c4e30667e77b01de068838abc75c7beb4 100644
--- a/layouts/v7/modules/Users/ListViewHeader.tpl
+++ b/layouts/v7/modules/Users/ListViewHeader.tpl
@@ -10,6 +10,7 @@
 {strip}
 	<div class="listViewPageDiv" id="listViewContent">
 		<div class="col-sm-12 col-xs-12 full-height">
+                    <input type='hidden' name='pwd_regex' value= {ZEND_json::encode($PWD_REGEX)} />
 			<div id="listview-actions" class="listview-actions-container">
 				<div class = "row">
 					<div class="btn-group col-md-2"></div>
diff --git a/layouts/v7/modules/Users/resources/Detail.js b/layouts/v7/modules/Users/resources/Detail.js
index 9de7ede0a17a7999699eae23b45fedf48b20268c..9970c095b3ef4db78fa77a68f42fe471dca87cfd 100644
--- a/layouts/v7/modules/Users/resources/Detail.js
+++ b/layouts/v7/modules/Users/resources/Detail.js
@@ -28,35 +28,41 @@ Vtiger_Detail_Js("Users_Detail_Js",{
 							var old_password  = form.find('[name="old_password"]');
 							var userid = form.find('[name="userid"]').val();
 
-							if(new_password.val() === confirm_password.val()){
-								var params = {
-									'data' : {
-										'module': app.getModuleName(),
-										'action' : "SaveAjax",
-										'mode' : 'savePassword',
-										'old_password' : old_password.val(),
-										'new_password' : new_password.val(),
-										'userid' : userid
-									}
-								};
+                                                        if(vtUtils.isPasswordStrong(new_password.val())) {
+                                                            if(new_password.val() === confirm_password.val()){
+                                                                    var params = {
+                                                                            'data' : {
+                                                                                    'module': app.getModuleName(),
+                                                                                    'action' : "SaveAjax",
+                                                                                    'mode' : 'savePassword',
+                                                                                    'old_password' : old_password.val(),
+                                                                                    'new_password' : new_password.val(),
+                                                                                    'userid' : userid
+                                                                            }
+                                                                    };
 
-								app.request.post(params).then(
-									function(err, data) {
-										if(err == null){
-											app.helper.hideModal();
-											var successMessage = app.vtranslate(data.message);
-											app.helper.showSuccessNotification({"message":successMessage});
-										}else{
-											app.helper.showErrorNotification({"message":err});	
-											return false;
-										}
-									}
-								);
-							} else {
-								var errorMessage = app.vtranslate('JS_PASSWORD_MISMATCH_ERROR');
-								app.helper.showErrorNotification({"message":errorMessage});
-								return false;
-							}
+                                                                    app.request.post(params).then(
+                                                                            function(err, data) {
+                                                                                    if(err == null){
+                                                                                            app.helper.hideModal();
+                                                                                            var successMessage = app.vtranslate(data.message);
+                                                                                            app.helper.showSuccessNotification({"message":successMessage});
+                                                                                    }else{
+                                                                                            app.helper.showErrorNotification({"message":err});	
+                                                                                            return false;
+                                                                                    }
+                                                                            }
+                                                                    );
+                                                            } else {
+                                                                    var errorMessage = app.vtranslate('JS_PASSWORD_MISMATCH_ERROR');
+                                                                    app.helper.showErrorNotification({"message":errorMessage});
+                                                                    return false;
+                                                            }
+                                                        }else{
+                                                            var errorMessage = app.vtranslate('JS_PASSWORD_NOT_STRONG');
+                                                            app.helper.showErrorNotification({"message":errorMessage});
+                                                            return false;
+                                                        }
 						}
 					};
 					form.vtValidate(params);
@@ -156,6 +162,11 @@ Vtiger_Detail_Js("Users_Detail_Js",{
 							var form = jQuery(form);
 							var new_password = form.find('[name="new_password"]');
 							var confirm_password = form.find('[name="confirm_password"]');
+                                                        if(!vtUtils.isPasswordStrong(new_password.val())) {
+								var errorMessage = app.vtranslate('JS_PASSWORD_NOT_STRONG');
+								app.helper.showErrorNotification({"message":errorMessage});
+								return false;
+							}
 							if (new_password.val() !== confirm_password.val()) {
 								
 								var params = {
diff --git a/layouts/v7/modules/Users/resources/Edit.js b/layouts/v7/modules/Users/resources/Edit.js
index 09d594d14e5e515a59b6c2a32235a3fc5580bd2c..551617fe67fe4fc0348f9e0207d99277f66284b1 100644
--- a/layouts/v7/modules/Users/resources/Edit.js
+++ b/layouts/v7/modules/Users/resources/Edit.js
@@ -17,19 +17,24 @@ Vtiger_Edit_Js("Users_Edit_Js",{},{
 	 */
 	registerRecordPreSaveEvent : function(form){
 		var thisInstance = this;
+		if(typeof form == 'undefined') {
+			var form = this.getForm();
+		}
 		app.event.on(Vtiger_Edit_Js.recordPresaveEvent, function(e, data) {
+                        var editForm = thisInstance.getForm();
+                        editForm.find('.saveButton').attr('disabled',true);
 			var userName = jQuery('input[name="user_name"]').val();
 			var newPassword = jQuery('input[name="user_password"]').val();
 			var confirmPassword = jQuery('input[name="confirm_password"]').val();
 			var record = jQuery('input[name="record"]').val();
-            var firstName = jQuery('input[name="first_name"]').val();
-            var lastName = jQuery('input[name="last_name"]').val();
-            var specialChars = /[<\>\"\,]/;
-            if((specialChars.test(firstName)) || (specialChars.test(lastName))) {
-                app.helper.showErrorNotification({message :app.vtranslate('JS_COMMA_NOT_ALLOWED_USERS')});
-                e.preventDefault();
-                return false;
-            }
+                        var firstName = jQuery('input[name="first_name"]').val();
+                        var lastName = jQuery('input[name="last_name"]').val();
+                        var specialChars = /[<\>\"\,]/;
+                        if((specialChars.test(firstName)) || (specialChars.test(lastName))) {
+                            app.helper.showErrorNotification({message :app.vtranslate('JS_COMMA_NOT_ALLOWED_USERS')});
+                            e.preventDefault();
+                            return false;
+                        }
 			var firstName = jQuery('input[name="first_name"]').val();
 			var lastName = jQuery('input[name="last_name"]').val();
 			if((firstName.indexOf(',') !== -1) || (lastName.indexOf(',') !== -1)) {
@@ -38,10 +43,16 @@ Vtiger_Edit_Js("Users_Edit_Js",{},{
 				return false;
 			}
 			if(record == ''){
-				if(newPassword != confirmPassword){
-                    app.helper.showErrorNotification({message :app.vtranslate('JS_REENTER_PASSWORDS')});
-					e.preventDefault();
-				}
+                            if(!vtUtils.isPasswordStrong(newPassword)) {
+                                app.helper.showErrorNotification({message :app.vtranslate('JS_PASSWORD_NOT_STRONG')});
+                                editForm.find('.saveButton').removeAttr('disabled');
+                                e.preventDefault();
+                                return false;
+                            }
+                            if(newPassword != confirmPassword){
+                                app.helper.showErrorNotification({message :app.vtranslate('JS_REENTER_PASSWORDS')});
+                                e.preventDefault();
+                            }
 
                 if(!(userName in thisInstance.duplicateCheckCache)) {
                     e.preventDefault();
diff --git a/layouts/v7/modules/Users/resources/List.js b/layouts/v7/modules/Users/resources/List.js
index a618adcd093e17183aca54a2f79c3e443566c997..cc041dc2cce3bb8bafc9c092083cdb816e910e5a 100644
--- a/layouts/v7/modules/Users/resources/List.js
+++ b/layouts/v7/modules/Users/resources/List.js
@@ -192,32 +192,38 @@ Settings_Vtiger_List_Js("Settings_Users_List_Js",{
 							var old_password  = form.find('[name="old_password"]');
 							var userid = form.find('[name="userid"]').val();
 
-							if(new_password.val() === confirm_password.val()){
-								var params = {
-									'data' : {
-										'module': app.getModuleName(),
-										'action' : "SaveAjax",
-										'mode' : 'savePassword',
-										'old_password' : old_password.val(),
-										'new_password' : new_password.val(),
-										'userid' : userid
-									}
-								};
-
-								app.request.post(params).then(
-									function(err, data) {
-										if(err == null){
-											app.helper.hideModal();
-											var successMessage = app.vtranslate(data.message);
-											app.helper.showSuccessNotification({"message":successMessage});
-										}else{
-											app.helper.showErrorNotification({"message":err});	
-											return false;
-										}
-									}
-								);
-							} else {
-								var errorMessage = app.vtranslate('JS_PASSWORD_MISMATCH_ERROR');
+                                                        if(vtUtils.isPasswordStrong(new_password.val())) {
+                                                            if(new_password.val() === confirm_password.val()){
+                                                                    var params = {
+                                                                            'data' : {
+                                                                                    'module': app.getModuleName(),
+                                                                                    'action' : "SaveAjax",
+                                                                                    'mode' : 'savePassword',
+                                                                                    'old_password' : old_password.val(),
+                                                                                    'new_password' : new_password.val(),
+                                                                                    'userid' : userid
+                                                                            }
+                                                                    };
+
+                                                                    app.request.post(params).then(
+                                                                            function(err, data) {
+                                                                                    if(err == null){
+                                                                                            app.helper.hideModal();
+                                                                                            var successMessage = app.vtranslate(data.message);
+                                                                                            app.helper.showSuccessNotification({"message":successMessage});
+                                                                                    }else{
+                                                                                            app.helper.showErrorNotification({"message":err});	
+                                                                                            return false;
+                                                                                    }
+                                                                            }
+                                                                    );
+                                                            } else {
+                                                                    var errorMessage = app.vtranslate('JS_PASSWORD_MISMATCH_ERROR');
+                                                                    app.helper.showErrorNotification({"message":errorMessage});
+                                                                    return false;
+                                                            }
+                                                        } else {
+								var errorMessage = app.vtranslate('JS_PASSWORD_NOT_STRONG');
 								app.helper.showErrorNotification({"message":errorMessage});
 								return false;
 							}
@@ -245,6 +251,11 @@ Settings_Vtiger_List_Js("Settings_Users_List_Js",{
 							var form = jQuery(form);
 							var new_password = form.find('[name="new_password"]');
 							var confirm_password = form.find('[name="confirm_password"]');
+                                                        if(!vtUtils.isPasswordStrong(new_password.val())) {
+								var errorMessage = app.vtranslate('JS_PASSWORD_NOT_STRONG');
+								app.helper.showErrorNotification({"message":errorMessage});
+								return false;
+							}
 							if (new_password.val() !== confirm_password.val()) {
 
 								var params = {
diff --git a/layouts/v7/modules/Vtiger/Comment.tpl b/layouts/v7/modules/Vtiger/Comment.tpl
index 5980b51dab69187181379bbd213795532c49085b..0764a0dd502d6f7ff84e21944f46c521a76dc62e 100644
--- a/layouts/v7/modules/Vtiger/Comment.tpl
+++ b/layouts/v7/modules/Vtiger/Comment.tpl
@@ -19,7 +19,7 @@
 					<div class="col-lg-12">
 						<div class="media">
 							<div class="media-left title" id="{$COMMENT->getId()}">
-								{assign var=CREATOR_NAME value=$COMMENT->getCommentedByName()}
+								{assign var=CREATOR_NAME value={decode_html($COMMENT->getCommentedByName())}}
 								<div class="col-lg-2 recordImage commentInfoHeader" style ="width:50px; height:50px; font-size: 30px;" data-commentid="{$COMMENT->getId()}" data-parentcommentid="{$COMMENT->get('parent_comments')}" data-relatedto = "{$COMMENT->get('related_to')}">
 									{assign var=IMAGE_PATH value=$COMMENT->getImagePath()}
 									{if !empty($IMAGE_PATH)}
diff --git a/layouts/v7/modules/Vtiger/DetailViewHeaderTitle.tpl b/layouts/v7/modules/Vtiger/DetailViewHeaderTitle.tpl
index a2777bdfaa470ae182aafdca2767daa5685e32b9..4032e90a20a862270d51a26cfe57298b502bfc76 100644
--- a/layouts/v7/modules/Vtiger/DetailViewHeaderTitle.tpl
+++ b/layouts/v7/modules/Vtiger/DetailViewHeaderTitle.tpl
@@ -24,7 +24,7 @@
 							{foreach item=NAME_FIELD from=$MODULE_MODEL->getNameFields()}
 								{assign var=FIELD_MODEL value=$MODULE_MODEL->getField($NAME_FIELD)}
 								{if $FIELD_MODEL->getPermissions()}
-									<span class="{$NAME_FIELD}">{$RECORD->get($NAME_FIELD)}</span>&nbsp;
+									<span class="{$NAME_FIELD}">{decode_html($RECORD->get($NAME_FIELD))}</span>&nbsp;
 								{/if}
 							{/foreach}
 						</span>
diff --git a/layouts/v7/modules/Vtiger/EmailPreview.tpl b/layouts/v7/modules/Vtiger/EmailPreview.tpl
index db4bce28727bba8d681caed7b1e4c1f4ac5d9234..d97ef089889a2938e6b9732b606a974bc8ef2ddc 100644
--- a/layouts/v7/modules/Vtiger/EmailPreview.tpl
+++ b/layouts/v7/modules/Vtiger/EmailPreview.tpl
@@ -146,7 +146,7 @@
 							</div>
 						</div>
 					</div>
-					<textarea style="display:none;" id="iframeDescription">{$RECORD->get('description')}</textarea>
+					<textarea style="display:none;" id="iframeDescription">{decode_html($RECORD->get('description'))}</textarea>
 					<div class="row email-info-row">
 						<div class="col-lg-2" style="padding-right:10px;">
 							<div class="pull-right">{vtranslate('LBL_DESCRIPTION',$MODULE)}</div>
diff --git a/layouts/v7/modules/Vtiger/Header.tpl b/layouts/v7/modules/Vtiger/Header.tpl
index b6bb5e99e4131c99a394a19e63a0ff232e74dbc5..1a11b569f5d809a6ca226f3e400a4d6d21b67fcc 100644
--- a/layouts/v7/modules/Vtiger/Header.tpl
+++ b/layouts/v7/modules/Vtiger/Header.tpl
@@ -15,19 +15,19 @@
 		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
 		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 
-		<link type='text/css' rel='stylesheet' href='layouts/v7/lib/todc/css/bootstrap.min.css'>
-		<link type='text/css' rel='stylesheet' href='layouts/v7/lib/todc/css/docs.min.css'>
-		<link type='text/css' rel='stylesheet' href='layouts/v7/lib/todc/css/todc-bootstrap.min.css'>
-		<link type='text/css' rel='stylesheet' href='layouts/v7/lib/font-awesome/css/font-awesome.min.css'>
-        <link type='text/css' rel='stylesheet' href='layouts/v7/lib/jquery/select2/select2.css'>
-        <link type='text/css' rel='stylesheet' href='layouts/v7/lib/select2-bootstrap/select2-bootstrap.css'>
-        <link type='text/css' rel='stylesheet' href='libraries/bootstrap/js/eternicode-bootstrap-datepicker/css/datepicker3.css'>
-        <link type='text/css' rel='stylesheet' href='layouts/v7/lib/jquery/jquery-ui-1.11.3.custom/jquery-ui.css'>
-        <link type='text/css' rel='stylesheet' href='layouts/v7/lib/vt-icons/style.css'>
-        <link type='text/css' rel='stylesheet' href='layouts/v7/lib/animate/animate.min.css'>
-        <link type='text/css' rel='stylesheet' href='layouts/v7/lib/jquery/malihu-custom-scrollbar/jquery.mCustomScrollbar.css'>
-        <link type='text/css' rel='stylesheet' href='layouts/v7/lib/jquery/jquery.qtip.custom/jquery.qtip.css'>
-        <link type='text/css' rel='stylesheet' href='layouts/v7/lib/jquery/daterangepicker/daterangepicker.css'>
+		<link type='text/css' rel='stylesheet' href='{vresource_url("layouts/v7/lib/todc/css/bootstrap.min.css")}'>
+		<link type='text/css' rel='stylesheet' href='{vresource_url("layouts/v7/lib/todc/css/docs.min.css")}'>
+		<link type='text/css' rel='stylesheet' href='{vresource_url("layouts/v7/lib/todc/css/todc-bootstrap.min.css")}'>
+		<link type='text/css' rel='stylesheet' href='{vresource_url("layouts/v7/lib/font-awesome/css/font-awesome.min.css")}'>
+        <link type='text/css' rel='stylesheet' href='{vresource_url("layouts/v7/lib/jquery/select2/select2.css")}'>
+        <link type='text/css' rel='stylesheet' href='{vresource_url("layouts/v7/lib/select2-bootstrap/select2-bootstrap.css")}'>
+        <link type='text/css' rel='stylesheet' href='{vresource_url("libraries/bootstrap/js/eternicode-bootstrap-datepicker/css/datepicker3.css")}'>
+        <link type='text/css' rel='stylesheet' href='{vresource_url("layouts/v7/lib/jquery/jquery-ui-1.11.3.custom/jquery-ui.css")}'>
+        <link type='text/css' rel='stylesheet' href='{vresource_url("layouts/v7/lib/vt-icons/style.css")}'>
+        <link type='text/css' rel='stylesheet' href='{vresource_url("layouts/v7/lib/animate/animate.min.css")}'>
+        <link type='text/css' rel='stylesheet' href='{vresource_url("layouts/v7/lib/jquery/malihu-custom-scrollbar/jquery.mCustomScrollbar.css")}'>
+        <link type='text/css' rel='stylesheet' href='{vresource_url("layouts/v7/lib/jquery/jquery.qtip.custom/jquery.qtip.css")}'>
+        <link type='text/css' rel='stylesheet' href='{vresource_url("layouts/v7/lib/jquery/daterangepicker/daterangepicker.css")}'>
         
         <input type="hidden" id="inventoryModules" value={ZEND_JSON::encode($INVENTORY_MODULES)}>
         
@@ -59,8 +59,8 @@
             var _USERMETA;
             {if $CURRENT_USER_MODEL}
                _USERMETA =  { 'id' : "{$CURRENT_USER_MODEL->get('id')}", 'menustatus' : "{$CURRENT_USER_MODEL->get('leftpanelhide')}", 
-                              'currency' : "{$USER_CURRENCY_SYMBOL}", 'currencySymbolPlacement' : "{$CURRENT_USER_MODEL->get('currency_symbol_placement')}",
-                          'currencyGroupingPattern' : "{$CURRENT_USER_MODEL->get('currency_grouping_pattern')}", 'truncateTrailingZeros' : "{$CURRENT_USER_MODEL->get('truncate_trailing_zeros')}"};
+                              'currency' : "{decode_html($USER_CURRENCY_SYMBOL)}", 'currencySymbolPlacement' : "{$CURRENT_USER_MODEL->get('currency_symbol_placement')}",
+                          'currencyGroupingPattern' : "{$CURRENT_USER_MODEL->get('currency_grouping_pattern')}", 'truncateTrailingZeros' : "{$CURRENT_USER_MODEL->get('truncate_trailing_zeros')}",'userlabel':"{decode_html($CURRENT_USER_MODEL->get('userlabel'))}",};
             {/if}
 		</script>
 	</head>
diff --git a/layouts/v7/modules/Vtiger/JSResources.tpl b/layouts/v7/modules/Vtiger/JSResources.tpl
index fc4fa9b219ed0e7a4958a1874a2254fcf46c8897..ff7ac3d1cd5ca34c71e7629bed3f96b98cfe5ddb 100644
--- a/layouts/v7/modules/Vtiger/JSResources.tpl
+++ b/layouts/v7/modules/Vtiger/JSResources.tpl
@@ -10,34 +10,34 @@
 ********************************************************************************/
 -->*}
 {strip}
-    <script type="text/javascript" src="layouts/v7/lib/jquery/purl.js"></script>
-    <script type="text/javascript" src="layouts/v7/lib/jquery/select2/select2.min.js"></script>
-    <script type="text/javascript" src="layouts/v7/lib/jquery/jquery.class.min.js"></script>
-    <script type="text/javascript" src="layouts/v7/lib/jquery/jquery-ui-1.11.3.custom/jquery-ui.js"></script>
-    <script type="text/javascript" src="layouts/v7/lib/todc/js/popper.min.js"></script>
-    <script type="text/javascript" src="layouts/v7/lib/todc/js/bootstrap.min.js"></script>
-    <script type="text/javascript" src="libraries/jquery/jstorage.min.js"></script>
-    <script type="text/javascript" src="layouts/v7/lib/jquery/jquery-validation/jquery.validate.min.js"></script>
-    <script type="text/javascript" src="layouts/v7/lib/jquery/jquery.slimscroll.min.js"></script>
-    <script type="text/javascript" src="libraries/jquery/jquery.ba-outside-events.min.js"></script>
-	<script type="text/javascript" src="libraries/jquery/defunkt-jquery-pjax/jquery.pjax.js"></script>
-    <script type="text/javascript" src="libraries/jquery/multiplefileupload/jquery_MultiFile.js"></script>
-    <script type="text/javascript" src="resources/jquery.additions.js"></script>
-    <script type="text/javascript" src="layouts/v7/lib/bootstrap-notify/bootstrap-notify.min.js"></script>
-    <script type="text/javascript" src="layouts/v7/lib/jquery/websockets/reconnecting-websocket.js"></script>
-    <script type="text/javascript" src="layouts/v7/lib/jquery/jquery-play-sound/jquery.playSound.js"></script>
-    <script type="text/javascript" src="layouts/v7/lib/jquery/malihu-custom-scrollbar/jquery.mousewheel.min.js"></script>
-    <script type="text/javascript" src="layouts/v7/lib/jquery/malihu-custom-scrollbar/jquery.mCustomScrollbar.js"></script>
-    <script type="text/javascript" src="layouts/v7/lib/jquery/autoComplete/jquery.textcomplete.js"></script>
-    <script type="text/javascript" src="layouts/v7/lib/jquery/jquery.qtip.custom/jquery.qtip.js"></script>
-    <script type="text/javascript" src="libraries/jquery/jquery-visibility.min.js"></script>
-    <script type="text/javascript" src="layouts/v7/lib/momentjs/moment.js"></script>
-    <script type="text/javascript" src="layouts/v7/lib/jquery/daterangepicker/moment.min.js"></script>
-    <script type="text/javascript" src="layouts/v7/lib/jquery/daterangepicker/jquery.daterangepicker.js"></script>
-    <script type="text/javascript" src="layouts/v7/lib/jquery/jquery.timeago.js"></script>
-    <script type="text/javascript" src="libraries/jquery/ckeditor/ckeditor.js"></script>
-    <script type="text/javascript" src="libraries/jquery/ckeditor/adapters/jquery.js"></script>
-	<script type='text/javascript' src='layouts/v7/lib/anchorme_js/anchorme.min.js'></script>
+    <script type="text/javascript" src="{vresource_url('layouts/v7/lib/jquery/purl.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('layouts/v7/lib/jquery/select2/select2.min.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('layouts/v7/lib/jquery/jquery.class.min.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('layouts/v7/lib/jquery/jquery-ui-1.11.3.custom/jquery-ui.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('layouts/v7/lib/todc/js/popper.min.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('layouts/v7/lib/todc/js/bootstrap.min.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('libraries/jquery/jstorage.min.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('layouts/v7/lib/jquery/jquery-validation/jquery.validate.min.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('layouts/v7/lib/jquery/jquery.slimscroll.min.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('libraries/jquery/jquery.ba-outside-events.min.js')}"></script>
+	<script type="text/javascript" src="{vresource_url('libraries/jquery/defunkt-jquery-pjax/jquery.pjax.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('libraries/jquery/multiplefileupload/jquery_MultiFile.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('resources/jquery.additions.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('layouts/v7/lib/bootstrap-notify/bootstrap-notify.min.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('layouts/v7/lib/jquery/websockets/reconnecting-websocket.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('layouts/v7/lib/jquery/jquery-play-sound/jquery.playSound.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('layouts/v7/lib/jquery/malihu-custom-scrollbar/jquery.mousewheel.min.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('layouts/v7/lib/jquery/malihu-custom-scrollbar/jquery.mCustomScrollbar.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('layouts/v7/lib/jquery/autoComplete/jquery.textcomplete.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('layouts/v7/lib/jquery/jquery.qtip.custom/jquery.qtip.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('libraries/jquery/jquery-visibility.min.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('layouts/v7/lib/momentjs/moment.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('layouts/v7/lib/jquery/daterangepicker/moment.min.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('layouts/v7/lib/jquery/daterangepicker/jquery.daterangepicker.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('layouts/v7/lib/jquery/jquery.timeago.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('libraries/jquery/ckeditor/ckeditor.js')}"></script>
+    <script type="text/javascript" src="{vresource_url('libraries/jquery/ckeditor/adapters/jquery.js')}"></script>
+	<script type='text/javascript' src="{vresource_url('layouts/v7/lib/anchorme_js/anchorme.min.js')}"></script>
     <script type="text/javascript" src="{vresource_url('layouts/v7/modules/Vtiger/resources/Class.js')}"></script>
     <script type='text/javascript' src="{vresource_url('layouts/v7/resources/helper.js')}"></script>
     <script type="text/javascript" src="{vresource_url('layouts/v7/resources/application.js')}"></script>
@@ -60,7 +60,7 @@
 
     <script type="text/javascript" src="{vresource_url('layouts/v7/resources/v7_client_compat.js')}"></script>
     <!-- Added in the end since it should be after less file loaded -->
-    <script type="text/javascript" src="libraries/bootstrap/js/less.min.js"></script>
+    <script type="text/javascript" src="{vresource_url('libraries/bootstrap/js/less.min.js')}"></script>
 
     <!-- Enable tracking pageload time -->
 	<script type="text/javascript">
diff --git a/layouts/v7/modules/Vtiger/ListColumnsEdit.tpl b/layouts/v7/modules/Vtiger/ListColumnsEdit.tpl
index 710745bbdafd21d4de900be73e60b5575bd3c9d1..ead442bda2a451feeff55fef348ab6f85e50ce2f 100644
--- a/layouts/v7/modules/Vtiger/ListColumnsEdit.tpl
+++ b/layouts/v7/modules/Vtiger/ListColumnsEdit.tpl
@@ -67,7 +67,7 @@
 																{if $FIELD_MODEL->getDisplayType() eq '6'}
 																	{continue}
 																{/if}
-																<div class="instafilta-target item {if array_key_exists($FIELD_MODEL->getCustomViewColumnName(), $SELECTED_FIELDS)}hide{/if}" data-cv-columnname="{$FIELD_MODEL->getCustomViewColumnName()}" data-columnname='{$FIELD_MODEL->get('column')}' data-field-id='{$FIELD_MODEL->getId()}'>
+																<div class="instafilta-target item {if array_key_exists(decode_html($FIELD_MODEL->getCustomViewColumnName()), $SELECTED_FIELDS)}hide{/if}" data-cv-columnname="{$FIELD_MODEL->getCustomViewColumnName()}" data-columnname='{$FIELD_MODEL->get('column')}' data-field-id='{$FIELD_MODEL->getId()}'>
 																	<span class="fieldLabel">{vtranslate($FIELD_MODEL->get('label'),$FIELD_MODULE_NAME)}</span>
 																</div>
 															{/foreach} 
diff --git a/layouts/v7/modules/Vtiger/PicklistColorMap.tpl b/layouts/v7/modules/Vtiger/PicklistColorMap.tpl
index 94f8538cc31b87fa68e9d29de7f36ac2e6110200..4701f13598d8da05b4d4cfe7430df48b260b67b4 100644
--- a/layouts/v7/modules/Vtiger/PicklistColorMap.tpl
+++ b/layouts/v7/modules/Vtiger/PicklistColorMap.tpl
@@ -16,7 +16,7 @@
             {/if}
             {assign var=PICKLIST_COLOR_MAP value=Settings_Picklist_Module_Model::getPicklistColorMap($FIELD_NAME, true)}
             {foreach item=PICKLIST_COLOR key=PICKLIST_VALUE from=$PICKLIST_COLOR_MAP}
-                {assign var=PICKLIST_TEXT_COLOR value=decode_html(Settings_Picklist_Module_Model::getTextColor($PICKLIST_COLOR))}
+                {assign var=PICKLIST_TEXT_COLOR value= decode_html(Settings_Picklist_Module_Model::getTextColor($PICKLIST_COLOR))}
                 {assign var=CONVERTED_PICKLIST_VALUE value=Vtiger_Util_Helper::convertSpaceToHyphen($PICKLIST_VALUE)}
                     .picklist-{$FIELD_MODEL->getId()}-{Vtiger_Util_Helper::escapeCssSpecialCharacters($CONVERTED_PICKLIST_VALUE)} {
                         background-color: {$PICKLIST_COLOR};
diff --git a/layouts/v7/modules/Vtiger/QuickViewCommentsList.tpl b/layouts/v7/modules/Vtiger/QuickViewCommentsList.tpl
index e0f5b95cfc8e94664fe69ba477a8445c69c8ed79..f7424325937b26fa951580b594a5b06e21177ea4 100644
--- a/layouts/v7/modules/Vtiger/QuickViewCommentsList.tpl
+++ b/layouts/v7/modules/Vtiger/QuickViewCommentsList.tpl
@@ -17,7 +17,7 @@
                 <div class="recentCommentsBody row">
                     <br>
                     {foreach key=index item=COMMENT from=$COMMENTS}
-                        {assign var=CREATOR_NAME value=$COMMENT->getCommentedByName()}
+                        {assign var=CREATOR_NAME value={decode_html($COMMENT->getCommentedByName())}}
                         <div class="commentDetails">
                             <div class="singleComment">
                                 {assign var=PARENT_COMMENT_MODEL value=$COMMENT->getParentCommentModel()}
diff --git a/layouts/v7/modules/Vtiger/RelatedActivities.tpl b/layouts/v7/modules/Vtiger/RelatedActivities.tpl
index b9c0bdb3b54745c30bea56963535bd045fe3fe19..4858094ca04ff7726c166c4b4bb4508f90a1520d 100644
--- a/layouts/v7/modules/Vtiger/RelatedActivities.tpl
+++ b/layouts/v7/modules/Vtiger/RelatedActivities.tpl
@@ -113,8 +113,8 @@
 														<input type="hidden" class="fieldname" value='{$FIELD_MODEL->get('name')}' data-prev-value='{$FIELD_MODEL->getDisplayValue($FIELD_MODEL->get('fieldvalue'))}' />
 													{/if}
 												</span>
-											</div>
-										{/if}
+                                                                                        {/if}
+                                                                                    </div>
 									{/if}
 								</div>
 							</div>
diff --git a/layouts/v7/modules/Vtiger/partials/SidebarEssentials.tpl b/layouts/v7/modules/Vtiger/partials/SidebarEssentials.tpl
index cc6f933ef402db95dc6cf3fd81bb25afa985b384..f822cd53032df0172d520ae3934b1e862d1abb8c 100644
--- a/layouts/v7/modules/Vtiger/partials/SidebarEssentials.tpl
+++ b/layouts/v7/modules/Vtiger/partials/SidebarEssentials.tpl
@@ -23,6 +23,7 @@
 				<div class="list-menu-content">
 						{assign var="CUSTOM_VIEW_NAMES" value=array()}
                         {if $CUSTOM_VIEWS && count($CUSTOM_VIEWS) > 0}
+                            {assign var="IS_ADMIN" value=$CURRENT_USER_MODEL->isAdminUser()} <!-- Libertus Mod -->
                             {foreach key=GROUP_LABEL item=GROUP_CUSTOM_VIEWS from=$CUSTOM_VIEWS}
                             {if $GROUP_LABEL neq 'Mine' && $GROUP_LABEL neq 'Shared'}
                                 {continue}
@@ -40,7 +41,7 @@
 								{assign var=count value=0}
 								{assign var=LISTVIEW_URL value=$MODULE_MODEL->getListViewUrl()}
                                 {foreach item="CUSTOM_VIEW" from=$GROUP_CUSTOM_VIEWS name="customView"}
-                                    {assign var=IS_DEFAULT value=$CUSTOM_VIEW->isDefault()}
+                                    {assign var="IS_DEFAULT" value=$CUSTOM_VIEW->isDefault()}
 									{assign var="CUSTOME_VIEW_RECORD_MODEL" value=CustomView_Record_Model::getInstanceById($CUSTOM_VIEW->getId())}
 									{assign var="MEMBERS" value=$CUSTOME_VIEW_RECORD_MODEL->getMembers()}
 									{assign var="LIST_STATUS" value=$CUSTOME_VIEW_RECORD_MODEL->get('status')}
@@ -56,12 +57,22 @@
                                             <div class="pull-right">
                                                 <span class="js-popover-container" style="cursor:pointer;">
                                                     <span  class="fa fa-angle-down" rel="popover" data-toggle="popover" aria-expanded="true" 
-                                                {if $CUSTOM_VIEW->isMine() and $CUSTOM_VIEW->get('viewname') neq 'All'}
-                                                            data-deletable="{if $CUSTOM_VIEW->isDeletable()}true{else}false{/if}" data-editable="{if $CUSTOM_VIEW->isEditable()}true{else}false{/if}" 
-                                                            {if $CUSTOM_VIEW->isEditable()} data-editurl="{$CUSTOM_VIEW->getEditUrl()}{/if}" {if $CUSTOM_VIEW->isDeletable()} {if $SHARED_MEMBER_COUNT eq 1 or $LIST_STATUS eq 3} data-shared="1"{/if} data-deleteurl="{$CUSTOM_VIEW->getDeleteUrl()}"{/if}
-                                                           {/if}
-                                                          toggleClass="fa {if $IS_DEFAULT}fa-check-square-o{else}fa-square-o{/if}" data-filter-id="{$CUSTOM_VIEW->getId()}" 
-                                                          data-is-default="{$IS_DEFAULT}" data-defaulttoggle="{$CUSTOM_VIEW->getToggleDefaultUrl()}" data-default="{$CUSTOM_VIEW->getDuplicateUrl()}" data-isMine="{if $CUSTOM_VIEW->isMine()}true{else}false{/if}">
+                                                        {if ($CUSTOM_VIEW->isMine() || $IS_ADMIN) && $CUSTOM_VIEW->get('viewname') neq 'All'}
+                                                            data-deletable="{if $CUSTOM_VIEW->isDeletable()}true{else}false{/if}" 
+                                                            data-editable="{if $CUSTOM_VIEW->isEditable()}true{else}false{/if}" 
+                                                            {if $CUSTOM_VIEW->isEditable()} data-editurl="{$CUSTOM_VIEW->getEditUrl()}{/if}" 
+                                                            {if $CUSTOM_VIEW->isDeletable()} 
+                                                                {if $SHARED_MEMBER_COUNT eq 1 or $LIST_STATUS eq 3} data-shared="1"{/if} 
+                                                                data-deleteurl="{$CUSTOM_VIEW->getDeleteUrl()}"
+                                                            {/if}
+                                                        {/if}
+                                                        toggleClass="fa {if $IS_DEFAULT}fa-check-square-o{else}fa-square-o{/if}" 
+                                                        data-filter-id="{$CUSTOM_VIEW->getId()}" 
+                                                        data-is-default="{$IS_DEFAULT}" 
+                                                        data-defaulttoggle="{$CUSTOM_VIEW->getToggleDefaultUrl()}" 
+                                                        data-default="{$CUSTOM_VIEW->getDuplicateUrl()}" 
+                                                        data-isMine="{if $CUSTOM_VIEW->isMine()}true{else}false{/if}" 
+                                                        data-isadmin="{if $IS_ADMIN}true{else}false{/if}">
                                                     </span>
                                                      </span>
                                                 </div>
diff --git a/layouts/v7/modules/Vtiger/partials/Topbar.tpl b/layouts/v7/modules/Vtiger/partials/Topbar.tpl
index febd704847fcaed929f67a796629e7018ad2c70f..8ea4a0f2be380a8d11068e6c9369c3a2e1c20c1e 100644
--- a/layouts/v7/modules/Vtiger/partials/Topbar.tpl
+++ b/layouts/v7/modules/Vtiger/partials/Topbar.tpl
@@ -152,7 +152,7 @@
 						<li class="dropdown">
 							<div>
 								<a href="#" class="userName dropdown-toggle pull-right" data-toggle="dropdown" role="button">
-									<span class="fa fa-user" aria-hidden="true" title="{$USER_MODEL->get('first_name')} {$USER_MODEL->get('last_name')}
+									<span class="fa fa-user" aria-hidden="true" title="{$USER_MODEL->get('userlabel')}
 										  ({$USER_MODEL->get('user_name')})"></span>
 									<span class="link-text-xs-only hidden-lg hidden-md hidden-sm">{$USER_MODEL->getName()}</span>
 								</a>
diff --git a/layouts/v7/modules/Vtiger/resources/Field.js b/layouts/v7/modules/Vtiger/resources/Field.js
index 5bbed20b1ddbf429bb41cfa295fe2f08c5620dee..43587a9a0f694f04e985a8c75be82cf13c80ff15 100644
--- a/layouts/v7/modules/Vtiger/resources/Field.js
+++ b/layouts/v7/modules/Vtiger/resources/Field.js
@@ -475,7 +475,7 @@ Vtiger_Field_Js('Vtiger_Date_Field_Js',{},{
 	 */
 	getUi : function() {
 		//wrappig with another div for consistency
-		var html = '<div class="referencefield-wrapper"><div class="input-group date">'+
+		var html = '<div class=""><div class="input-group date">'+
 						'<input class="inputElement dateField form-control" type="text" data-rule-date="true" data-format="'+ this.getDateFormat() +'" name="'+ this.getName() +'" value="'+ this.getValue() + '" />'+
 						'<span class="input-group-addon"><i class="fa fa-calendar"></i></span>'+
 					'</div></div>';
@@ -495,9 +495,9 @@ Vtiger_Field_Js('Vtiger_Currency_Field_Js',{},{
 
 	getUi : function() {
 		//wrappig with another div for consistency
-		var html = '<div class="referencefield-wrapper"><div class="input-group">'+
+		var html = '<div class=""><div class="input-group">'+
 						'<span class="input-group-addon" id="basic-addon1">'+this.getCurrencySymbol()+'</span>'+
-						'<input class="inputElement" type="text" name="'+ this.getName() +'" data-rule-currency="true" value="'+ this.getValue() + '" />'+
+						'<input class="inputElement width100per" type="text" name="'+ this.getName() +'" data-rule-currency="true" value="'+ this.getValue() + '" />'+
 					'</div></div>';
 		var element = jQuery(html);
 		return this.addValidationToElement(element);
@@ -560,7 +560,7 @@ Vtiger_Field_Js('Vtiger_Time_Field_Js',{},{
 	 * @return - input text field
 	 */
 	getUi : function() {
-		var html = '<div class="referencefield-wrapper">'+'<div class="input-group time">'+
+		var html = '<div class="">'+'<div class="input-group time">'+
 						'<input class="timepicker-default form-control inputElement" type="text" data-format="'+ this.getTimeFormat() +'" name="'+ this.getName() +'" value="'+ this.getValue() + '" />'+
 						'<span class="input-group-addon"><i class="fa fa-clock-o"></i></span>'+
 					'</div>'+'</div>';
diff --git a/layouts/v7/modules/Vtiger/resources/ListSidebar.js b/layouts/v7/modules/Vtiger/resources/ListSidebar.js
index a8ecae4d28011dbb83ca4e5b77ff7b09bbdef55d..735d43e282d675162366efc980a6947ceecbc827 100644
--- a/layouts/v7/modules/Vtiger/resources/ListSidebar.js
+++ b/layouts/v7/modules/Vtiger/resources/ListSidebar.js
@@ -168,23 +168,33 @@ Vtiger.Class('Vtiger_ListSidebar_Js',{},{
             toggleEle.attr('data-is-default', jQuery(ele).data('is-default'));
             toggleEle.attr('data-filter-id', jQuery(ele).data('filter-id'));
             contentEle.find('.toggleDefault i').attr('class', jQuery(ele).attr('toggleClass'));
-             editEle.attr('data-id', jQuery(ele).data('id'));
+            editEle.attr('data-id', jQuery(ele).data('id'));
             deleteEle.attr('data-id', jQuery(ele).data('id'));
             
-            if(jQuery(ele).data('ismine') === false){
+            // Libertus Mod - data-isadmin also added to SideBarEssentials.tpl
+            if((jQuery(ele).data('ismine') === false) && (jQuery(ele).data('isadmin') === false)) {
                 contentEle.find('.editFilter').css("display", "none");
                 contentEle.find('.deleteFilter').css("display","none");
             }
+
+            if (!jQuery(ele).data('deletable')) {
+                contentEle.find('.deleteFilter').remove(); // This propogates to the next iteration of the each() method; removing the entire li
+            } else {
+                if(contentEle.find('li').hasClass('deleteFilter') === false) {
+                    contentEle.find('ul').prepend(deleteEle); // Add back if missing
+                }
+                contentEle.find('.deleteFilter').removeClass('disabled');
+            }
+
             if (!jQuery(ele).data('editable')) {
-                contentEle.find('.editFilter').remove();
+                contentEle.find('.editFilter').remove(); // This propogates to the next iteration of the each() method; removing the entire li
             } else {
+                if(contentEle.find('li').hasClass('editFilter') === false) {
+                    contentEle.find('ul').prepend(editEle); // Add back if missing
+                }
                 contentEle.find('.editFilter').removeClass('disabled');
             }
-            if (!jQuery(ele).data('deletable')) {
-                contentEle.find('.deleteFilter').remove();
-            } else {
-                contentEle.find('.deleteFilter').removeClass('disabled');
-            } 
+
             var options = {
                 html: true,
                 placement: 'left',
diff --git a/layouts/v7/modules/Vtiger/resources/Utils.js b/layouts/v7/modules/Vtiger/resources/Utils.js
index c51009b48d412c9d050e8d58079915bbaa794d2e..26cae5e2d7a57232cbb14991d3e3cdb59c9af20f 100644
--- a/layouts/v7/modules/Vtiger/resources/Utils.js
+++ b/layouts/v7/modules/Vtiger/resources/Utils.js
@@ -135,7 +135,9 @@ var vtUtils = {
                         showShortcuts: true,
                         autoClose : false,
                         duration : 500
-                    });
+                    }).on('datepicker-opened', function(e){
+						vtUtils.addMask(jQuery('.date-picker-wrapper:visible'));
+					}).on('datepicker-closed',vtUtils.removeMask);
                 }else{
                     var elementDateFormat = element.data('dateFormat');
                     if(typeof elementDateFormat !== 'undefined') {
@@ -375,5 +377,36 @@ var vtUtils = {
         return string.replace(tags, function ($0, $1) {
             return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
         });
-    }
+    },
+	
+    addMask: function (container) {
+            if (container.length && jQuery('#vt-mask').length == 0) {
+                    var mask = '<div id="vt-mask" class="vt-page-mask" ></div>'
+                    container.before(mask);
+            }
+    },
+
+    removeMask: function () {
+            if (jQuery('#vt-mask').length) {
+                    jQuery('#vt-mask').remove();
+            }
+    },
+        
+    isPasswordStrong : function(password) {
+            /*
+            * ^					The password string will start this way
+            * (?=.*[a-z])			The string must contain at least 1 lowercase alphabetical character
+            * (?=.*[A-Z])			The string must contain at least 1 uppercase alphabetical character
+            * (?=.*[0-9])			The string must contain at least 1 numeric character
+            * (?=.*[!@#\$%\^&\*])	The string must contain at least one special character, but we are escaping reserved RegEx characters to avoid conflict
+            * (?=.{8,})			The string must be eight characters or longer
+            */
+           var password_regex = jQuery('[name="pwd_regex"]').val();
+           if((typeof password_regex != 'undefined') && (password_regex != '')){
+                var strongPasswordRegex = new RegExp(password_regex);
+                var isStrong = strongPasswordRegex.test(password)? true : false; 
+                return isStrong;
+           }
+           return false;
+    },
 }
diff --git a/layouts/v7/modules/Vtiger/uitypes/Currency.tpl b/layouts/v7/modules/Vtiger/uitypes/Currency.tpl
index 2b7ca02d7f9381b786ee7ebd92a3154c407bceca..fb79b42457c8abdb1984c19b56ed3ed1bb1914d5 100644
--- a/layouts/v7/modules/Vtiger/uitypes/Currency.tpl
+++ b/layouts/v7/modules/Vtiger/uitypes/Currency.tpl
@@ -16,8 +16,8 @@
     {assign var="FIELD_NAME" value=$FIELD_MODEL->getFieldName()}
 {/if}
 {if $FIELD_MODEL->get('uitype') eq '71'}
-<div class="input-group">
-	<span class="input-group-addon">{$USER_MODEL->get('currency_symbol')}</span>
+<div class="input-group inputElement">
+	<span class="input-group-addon input-group-addon-right">{$USER_MODEL->get('currency_symbol')}</span>
 	<input id="{$MODULE}_editView_fieldName_{$FIELD_NAME}" type="text" class="inputElement currencyField" name="{$FIELD_NAME}"
 	value="{$FIELD_MODEL->getEditViewDisplayValue($FIELD_MODEL->get('fieldvalue'))}" {if !empty($SPECIAL_VALIDATOR)}data-validator='{Zend_Json::encode($SPECIAL_VALIDATOR)}'{/if}
     {if $FIELD_INFO["mandatory"] eq true} data-rule-required = "true" {/if} data-rule-currency='true'
diff --git a/layouts/v7/modules/Vtiger/uitypes/OwnerFieldSearchView.tpl b/layouts/v7/modules/Vtiger/uitypes/OwnerFieldSearchView.tpl
index 4fdd538d585da954607ce22c4d4277fcec339812..a48cef1382b4424748f27f2dc41c4ab37fff98cb 100644
--- a/layouts/v7/modules/Vtiger/uitypes/OwnerFieldSearchView.tpl
+++ b/layouts/v7/modules/Vtiger/uitypes/OwnerFieldSearchView.tpl
@@ -40,7 +40,7 @@
         {if count($ALL_ACTIVEGROUP_LIST) gt 0}
 		<optgroup label="{vtranslate('LBL_GROUPS')}">
 			{foreach key=OWNER_ID item=OWNER_NAME from=$ALL_ACTIVEGROUP_LIST}
-				<option value="{$OWNER_NAME}" data-picklistvalue= '{$OWNER_NAME}' {if in_array(trim($OWNER_NAME),$SEARCH_VALUES)} selected {/if}
+				<option value="{$OWNER_NAME}" data-picklistvalue= '{$OWNER_NAME}' {if in_array(trim(decode_html($OWNER_NAME)),$SEARCH_VALUES)} selected {/if}
 					{if array_key_exists($OWNER_ID, $ACCESSIBLE_GROUP_LIST)} data-recordaccess=true {else} data-recordaccess=false {/if} >
 				{$OWNER_NAME}
 				</option>
diff --git a/layouts/v7/modules/Vtiger/uitypes/OwnerGroupFieldSearchView.tpl b/layouts/v7/modules/Vtiger/uitypes/OwnerGroupFieldSearchView.tpl
index 51edb7f9ee6784a66ddf3d9b1a1a8726dc84bf45..847603524c2464f94bc4ba12cc6566c65e9e2e3c 100644
--- a/layouts/v7/modules/Vtiger/uitypes/OwnerGroupFieldSearchView.tpl
+++ b/layouts/v7/modules/Vtiger/uitypes/OwnerGroupFieldSearchView.tpl
@@ -26,7 +26,7 @@
 		<select class="select2 listSearchContributor {$ASSIGNED_USER_ID}"name="{$ASSIGNED_USER_ID}" multiple id="group_id" style="display:none">
 			{if count($ALL_ACTIVEGROUP_LIST) gt 0}
 				{foreach key=OWNER_ID item=OWNER_NAME from=$ALL_ACTIVEGROUP_LIST}
-					<option value="{$OWNER_NAME}" data-picklistvalue= '{$OWNER_NAME}' {if in_array(trim($OWNER_NAME),$SEARCH_VALUES)} selected {/if}
+					<option value="{$OWNER_NAME}" data-picklistvalue= '{$OWNER_NAME}' {if in_array(trim(decode_html($OWNER_NAME)),$SEARCH_VALUES)} selected {/if}
 							{if array_key_exists($OWNER_ID, $ACCESSIBLE_GROUP_LIST)} data-recordaccess=true {else} data-recordaccess=false {/if} >
 						{$OWNER_NAME}
 					</option>
diff --git a/layouts/v7/modules/Vtiger/uitypes/String.tpl b/layouts/v7/modules/Vtiger/uitypes/String.tpl
index 00ec549f4208b9fc32266f91d059df3358108c72..8d4f57446a9ed77ee9514bf164408d20a67c0150 100644
--- a/layouts/v7/modules/Vtiger/uitypes/String.tpl
+++ b/layouts/v7/modules/Vtiger/uitypes/String.tpl
@@ -16,7 +16,7 @@
 	{if (!$FIELD_NAME)}
 		{assign var="FIELD_NAME" value=$FIELD_MODEL->getFieldName()}
 	{/if}
-	<input id="{$MODULE}_editView_fieldName_{$FIELD_NAME}" type="text" data-fieldname="{$FIELD_NAME}" data-fieldtype="string" class="inputElement {if $FIELD_MODEL->isNameField()}nameField{/if}" name="{$FIELD_NAME}" value="{$FIELD_MODEL->get('fieldvalue')}"
+	<input id="{$MODULE}_editView_fieldName_{$FIELD_NAME}" type="text" data-fieldname="{$FIELD_NAME}" data-fieldtype="string" class="inputElement {if $FIELD_MODEL->isNameField()}nameField{/if}" name="{$FIELD_NAME}" value="{decode_html($FIELD_MODEL->get('fieldvalue'))|htmlentities}"
 		{if $FIELD_MODEL->get('uitype') eq '3' || $FIELD_MODEL->get('uitype') eq '4'|| $FIELD_MODEL->isReadOnly()}
 			{if $FIELD_MODEL->get('uitype') neq '106'}
 				readonly
diff --git a/layouts/v7/skins/vtiger/style.less b/layouts/v7/skins/vtiger/style.less
index bb8ce42475d8eba3a3c6cd0d553c90c206a74500..9a09e0f159da72e718685883415d9aa57db27377 100644
--- a/layouts/v7/skins/vtiger/style.less
+++ b/layouts/v7/skins/vtiger/style.less
@@ -1656,7 +1656,8 @@ ul.unstyled{
 .listViewEntries .relatedListEntryValues .value{
     vertical-align: middle;
 	width: 80%;
-	display: inline-block;
+    display: inline-block;
+    max-width: 300px;
 }
 
 .floatThead-table{
@@ -2679,6 +2680,12 @@ strong, b, th{
     border-left:1px solid #ddd;  
 }
 
+.input-group.inputElement .input-group-addon-right{
+    border:none;
+    border-left:0px;
+    border-right:1px solid #ddd;
+}
+
 .fieldBlockContainer textarea.inputElement{
     height : auto;
 }
@@ -6292,6 +6299,9 @@ hr{
 .width75per{
     width: 75%;
 }
+.width100per{
+    width: 100% !important;
+}
 #_mbox_pwd{
     padding: 3px 8px;
 }
@@ -6896,7 +6906,7 @@ div.tooltip-inner{
     width:80% !important;
 }
 .input-group-addon{
-    line-height: 1.5;
+    line-height: inherit;
     border-width: thin;
 }
 .input-group{
@@ -8665,4 +8675,20 @@ body .fc {
         border-width: thin;
         padding: 30px;
     }
+}
+
+#vt-mask{
+    border: 0;
+    margin: 0;
+    padding: 0;
+    position: fixed;
+    left: 0;
+    top: 0;
+    min-height: 100%;
+    min-width: 100%;
+    height: auto;
+    width: auto;
+    opacity: 0;
+    z-index: 10001;
+    background-color: #fff;
 }
\ No newline at end of file
diff --git a/layouts/vlayout/modules/Emails/EmailPreviewPrint.tpl b/layouts/vlayout/modules/Emails/EmailPreviewPrint.tpl
index f1c1d829031aeaba3c41a923c35c77dd26757594..dc75e49041880f00f0acce8fc69310461f85ebb1 100644
--- a/layouts/vlayout/modules/Emails/EmailPreviewPrint.tpl
+++ b/layouts/vlayout/modules/Emails/EmailPreviewPrint.tpl
@@ -20,7 +20,7 @@
 		{assign var="TO_EMAIL" value=$TO_EMAILS|replace:'[':''}
 		{assign var="TO_EMAIL_VALUE" value=$TO_EMAIL|replace:'&quot;':''}
 		<span style="position:absolute;right:6%;top:3%;font-family:'Lucida Grande';font-size:15px">
-			{$USER_MODEL->get('last_name')} {$USER_MODEL->get('first_name')} &lt;{$USER_MODEL->get('email1')}&gt;
+			{$USER_MODEL->get('userlabel')} &lt;{$USER_MODEL->get('email1')}&gt;
 		</span><hr/>
 		<span style="font-family:'Lucida Grande';font-size:15px">
 			{$RECORD->get('subject')}
diff --git a/modules/Calendar/CalendarCommon.php b/modules/Calendar/CalendarCommon.php
index cfecd4161fba2e0a6e0740ab8c8a25b28a9e83c1..93ea23f7eea69c46923fcf1ab544662976470903 100644
--- a/modules/Calendar/CalendarCommon.php
+++ b/modules/Calendar/CalendarCommon.php
@@ -225,12 +225,11 @@ function generateIcsAttachment($record) {
     $fileName = str_replace(' ', '_', decode_html($record['subject']));
     $assignedUserId = $record['user_id'];
     $userModel = Users_Record_Model::getInstanceById($assignedUserId, 'Users');
-    $firstName = $userModel->entity->column_fields['first_name'];
-    $lastName = $userModel->entity->column_fields['last_name'];
+    $userLabel = $userModel->entity->column_fields['userlabel'];
     $email = $userModel->entity->column_fields['email1'];
     $fp = fopen('test/upload/'.$fileName.'.ics', "w");
     fwrite($fp, "BEGIN:VCALENDAR\nVERSION:2.0\nBEGIN:VEVENT\n");
-    fwrite($fp, "ORGANIZER;CN=".$firstName." ".$lastName.":MAILTO:".$email."\n");
+    fwrite($fp, "ORGANIZER;CN=".$userLabel.":MAILTO:".$email."\n");
     fwrite($fp, "DTSTART:".date('Ymd\THis\Z', strtotime($record['st_date_time']))."\n");
     fwrite($fp, "DTEND:".date('Ymd\THis\Z', strtotime($record['end_date_time']))."\n");
     fwrite($fp, "DTSTAMP:".date('Ymd\THis\Z')."\n");
diff --git a/modules/Calendar/models/Module.php b/modules/Calendar/models/Module.php
index adfd7ed18202e1c4030f2ce14c66174e2ac92f8f..8cccc7648df9028f2234a84b0892c9f6aa4efe10 100644
--- a/modules/Calendar/models/Module.php
+++ b/modules/Calendar/models/Module.php
@@ -305,11 +305,11 @@ class Calendar_Module_Model extends Vtiger_Module_Model {
 		$db = PearDatabase::getInstance();
 		$currentUser = Users_Record_Model::getCurrentUserModel();
 		if($currentUser->isAdminUser()) {
-			$query = "SELECT first_name,last_name, id AS userid
+			$query = "SELECT userlabel, id AS userid
 					FROM vtiger_users WHERE status='Active' AND (user_name != 'admin' OR is_owner = 1) AND id <> ?";
 			$result = $db->pquery($query, array($id));
 		} else {
-			$query = "SELECT vtiger_users.first_name,vtiger_users.last_name, vtiger_users.id AS userid
+			$query = "SELECT vtiger_users.userlabel, vtiger_users.id AS userid
 				FROM vtiger_sharedcalendar RIGHT JOIN vtiger_users ON vtiger_sharedcalendar.userid=vtiger_users.id AND vtiger_users.status= 'Active'
 				WHERE vtiger_sharedcalendar.sharedid=? OR (vtiger_users.status='Active' AND vtiger_users.calendarsharedtype='public' AND vtiger_users.id <> ?)";
 			$result = $db->pquery($query, array($id, $id));
@@ -319,7 +319,7 @@ class Calendar_Module_Model extends Vtiger_Module_Model {
 		$userIds = Array();
 		for($i=0; $i<$rows; $i++){
 			$id = $db->query_result($result,$i,'userid');
-			$userName = $db->query_result($result,$i,'first_name').' '.$db->query_result($result,$i,'last_name');
+			$userName = $db->query_result($result,$i,'userlabel');
 			$userIds[$id] =$userName;
 		}
 
diff --git a/modules/CustomView/CustomView.php b/modules/CustomView/CustomView.php
index af3ea9c50a6ec8a4ea64fbca1272d75940fc1add..9860ad30079b6287a557bc5dd302dc1c2914dec6 100644
--- a/modules/CustomView/CustomView.php
+++ b/modules/CustomView/CustomView.php
@@ -209,7 +209,7 @@ class CustomView extends CRMEntity {
 		if ($markselected == false)
 			$selected = '';
 
-		$ssql = "select vtiger_customview.*, vtiger_users.first_name,vtiger_users.last_name from vtiger_customview inner join vtiger_tab on vtiger_tab.name = vtiger_customview.entitytype
+		$ssql = "select vtiger_customview.*, vtiger_users.first_name,vtiger_users.last_name,vtiger_users.userlabel from vtiger_customview inner join vtiger_tab on vtiger_tab.name = vtiger_customview.entitytype
 					left join vtiger_users on vtiger_customview.userid = vtiger_users.id ";
 		$ssql .= " where vtiger_tab.tabid=?";
 		$sparams = array($tabid);
@@ -230,7 +230,7 @@ class CustomView extends CRMEntity {
 			if ($cvrow['status'] == CV_STATUS_DEFAULT || $cvrow['userid'] == $current_user->id) {
 				$disp_viewname = $viewname;
 			} else {
-				$userName = getFullNameFromArray('Users', $cvrow);
+				$userName = $cvrow['userlabel'];
 				$disp_viewname = $viewname . " [" . $userName . "] ";
 			}
 
@@ -1182,9 +1182,9 @@ class CustomView extends CRMEntity {
 						if ($this->customviewmodule == 'Calendar' && ($columns[1] == 'date_start' || $columns[1] == 'due_date')) {
 							$tableColumnSql = '';
 							if ($columns[1] == 'date_start') {
-								$tableColumnSql = "CAST((CONCAT(date_start,' ',time_start)) AS DATETIME)";
+								$tableColumnSql = "(CONCAT(date_start,' ',time_start))";
 							} else {
-								$tableColumnSql = "CAST((CONCAT(due_date,' ',time_end)) AS DATETIME)";
+								$tableColumnSql = "(CONCAT(due_date,' ',time_end))";
 							}
 						} else {
 							$tableColumnSql = $columns[0] . "." . $columns[1];
diff --git a/modules/Emails/Emails.php b/modules/Emails/Emails.php
index e05b9fa3d06f81b73e48ef4091a0dd45542e4ec9..1a552f8bd4f992229ba0c9a8c22052adaf5555af 100644
--- a/modules/Emails/Emails.php
+++ b/modules/Emails/Emails.php
@@ -380,7 +380,7 @@ class Emails extends CRMEntity {
 				onclick=\"return window.open("index.php?module=Users&return_module=Emails&action=Popup&popuptype=detailview&select=enable&form=EditView&form_submit=true&return_id=' . $id . '&recordid=' . $id . '","test","width=640,height=520,resizable=0,scrollbars=0");\"
 				type="button">';
 
-		$query = 'SELECT vtiger_users.id, vtiger_users.first_name,vtiger_users.last_name, vtiger_users.user_name, vtiger_users.email1, vtiger_users.email2, vtiger_users.secondaryemail , vtiger_users.phone_home, vtiger_users.phone_work, vtiger_users.phone_mobile, vtiger_users.phone_other, vtiger_users.phone_fax from vtiger_users inner join vtiger_salesmanactivityrel on vtiger_salesmanactivityrel.smid=vtiger_users.id and vtiger_salesmanactivityrel.activityid=?';
+		$query = 'SELECT vtiger_users.id, vtiger_users.first_name,vtiger_users.last_name, vtiger_users.user_name, vtiger_users.email1, vtiger_users.email2, vtiger_users.secondaryemail , vtiger_users.phone_home, vtiger_users.phone_work, vtiger_users.phone_mobile, vtiger_users.phone_other, vtiger_users.phone_fax,vtiger_users.userlabel from vtiger_users inner join vtiger_salesmanactivityrel on vtiger_salesmanactivityrel.smid=vtiger_users.id and vtiger_salesmanactivityrel.activityid=?';
 		$result = $adb->pquery($query, array($id));
 
 		$noofrows = $adb->num_rows($result);
@@ -397,12 +397,7 @@ class Emails extends CRMEntity {
 
 			$entries = Array();
 
-			if (is_admin($current_user)) {
-				$entries[] = getFullNameFromArray('Users', $row);
-			} else {
-				$entries[] = getFullNameFromArray('Users', $row);
-			}
-
+			$entries[] = $row['userlabel'];
 			$entries[] = $row['user_name'];
 			$entries[] = $row['email1'];
 			if ($email == '')
diff --git a/modules/Emails/mail.php b/modules/Emails/mail.php
index 5824fbdb73ad5d59e5b18475d9e3e8e41065c909..58d9f5f6caa9fb1fa612f15e22a12987e3971d9f 100755
--- a/modules/Emails/mail.php
+++ b/modules/Emails/mail.php
@@ -153,11 +153,11 @@ function addSignature($contents, $fromname, $fromEmail = '') {
 	$sign = VTCacheUtils::getUserSignature($fromname);
 	if ($sign == null) {
 		$sign = VTCacheUtils::getUserSignature($fromEmail);
-		$result = $adb->pquery("select signature, first_name, last_name from vtiger_users where user_name=? or user_name=? or email1=? or email2=? or secondaryemail=?", array($fromname, $fromEmail, $fromEmail, $fromEmail, $fromEmail));
+		$result = $adb->pquery("select signature, userlabel from vtiger_users where user_name=? or user_name=? or email1=? or email2=? or secondaryemail=?", array($fromname, $fromEmail, $fromEmail, $fromEmail, $fromEmail));
 		$sign = $adb->query_result($result,0,"signature");
 		VTCacheUtils::setUserSignature($fromname, $sign);
 		VTCacheUtils::setUserSignature($fromEmail, $sign);
-		VTCacheUtils::setUserFullName($fromname, $adb->query_result($result,0,"first_name").' '.$adb->query_result($result,0,"last_name"));
+		VTCacheUtils::setUserFullName($fromname, $adb->query_result($result,0,"userlabel"));
 	}
 
 	$sign = nl2br($sign);
@@ -215,10 +215,10 @@ function setMailerProperties($mail,$subject,$contents,$from_email,$from_name,$to
 		$userFullName = $HELPDESK_SUPPORT_NAME;
 	}
 	if(empty($userFullName)) {
-		$rs = $adb->pquery("select first_name,last_name from vtiger_users where user_name=?", array($from_name));
+		$rs = $adb->pquery("select first_name,last_name,userlabel from vtiger_users where user_name=?", array($from_name));
 		$num_rows = $adb->num_rows($rs);
 		if($num_rows > 0) {
-			$fullName = getFullNameFromQResult($rs, 0, 'Users');
+			$fullName = $adb->query_result($rs, 0, 'userlabel');
 			VTCacheUtils::setUserFullName($from_name, $fullName);
 		}
 	} else {
diff --git a/modules/Emails/models/Record.php b/modules/Emails/models/Record.php
index 11fe808dd6baa4a3c89b53681bc5a6a1d45212f9..d92abdf56dad8b1ac73f9d4bb183ef3ee6d1da14 100644
--- a/modules/Emails/models/Record.php
+++ b/modules/Emails/models/Record.php
@@ -182,7 +182,7 @@ class Emails_Record_Model extends Vtiger_Record_Model {
             //Adding attachments to mail
             if(is_array($attachments)) {
                 foreach($attachments as $attachment) {
-                    $fileNameWithPath = $rootDirectory.$attachment['path'].$attachment['fileid']."_".$attachment['storedname'];
+                    $fileNameWithPath = $rootDirectory.$attachment['filenamewithpath'];
                     if(is_file($fileNameWithPath)) {
                         $mailer->AddAttachment($fileNameWithPath, $attachment['attachment']);
                     }
@@ -277,12 +277,24 @@ class Emails_Record_Model extends Vtiger_Record_Model {
 		$attachmentsList = array();
 		if($numOfRows) {
 			for($i=0; $i<$numOfRows; $i++) {
-				$attachmentsList[$i]['fileid'] = $db->query_result($attachmentRes, $i, 'attachmentsid');
-				$attachmentsList[$i]['attachment'] = decode_html($db->query_result($attachmentRes, $i, 'name'));
-                $attachmentsList[$i]['storedname'] = decode_html($db->query_result($attachmentRes, $i, 'storedname'));
-				$path = $db->query_result($attachmentRes, $i, 'path');
+                                $attachmentId = $db->query_result($attachmentRes, $i, 'attachmentsid');
+                                $rawFileName = $db->query_result($attachmentRes, $i, 'name');
+                                $storedName = $db->query_result($attachmentRes, $i, 'storedname');
+                                $path = $db->query_result($attachmentRes, $i, 'path');
+                                if($storedName) { 
+                                    $filename = $storedName;
+                                } else {
+                                    $filename = $rawFileName;
+                                }
+                                $attachmentsList[$i]['attachment'] = decode_html($rawFileName);
+                                $attachmentsList[$i]['fileid'] = $attachmentId;
+                                $attachmentsList[$i]['storedname'] = decode_html($storedName);
 				$attachmentsList[$i]['path'] = $path;
-				$attachmentsList[$i]['size'] = filesize($path.$attachmentsList[$i]['fileid'].'_'.$attachmentsList[$i]['storedname']);
+                                $saved_filename = $attachmentId."_".$filename;
+                                $filenamewithpath = $path.$saved_filename;
+                                $filesize = filesize($filenamewithpath);
+                                $attachmentsList[$i]['filenamewithpath'] = $filenamewithpath;
+				$attachmentsList[$i]['size'] = $filesize;
 				$attachmentsList[$i]['type'] = $db->query_result($attachmentRes, $i, 'type');
 				$attachmentsList[$i]['cid'] = $db->query_result($attachmentRes, $i, 'cid');
 			}
diff --git a/modules/HelpDesk/models/Module.php b/modules/HelpDesk/models/Module.php
index e0b2c4acfad56cf225365c626216287bdc157833..1ba6037196d9b5a81ad68c5043a48a6e8e6ffd23 100644
--- a/modules/HelpDesk/models/Module.php
+++ b/modules/HelpDesk/models/Module.php
@@ -69,7 +69,7 @@ class HelpDesk_Module_Model extends Vtiger_Module_Model {
         if(in_array('Open', $picklistvaluesmap)) $params[] = 'Open';
         
 		if(count($params) > 0) {
-		$result = $db->pquery('SELECT count(*) AS count, COALESCE(vtiger_groups.groupname,concat(vtiger_users.first_name, " " ,vtiger_users.last_name)) as name, COALESCE(vtiger_groups.groupid,vtiger_users.id) as id  FROM vtiger_troubletickets
+		$result = $db->pquery('SELECT count(*) AS count, COALESCE(vtiger_groups.groupname,vtiger_users.userlabel) as name, COALESCE(vtiger_groups.groupid,vtiger_users.id) as id  FROM vtiger_troubletickets
 						INNER JOIN vtiger_crmentity ON vtiger_troubletickets.ticketid = vtiger_crmentity.crmid
 						LEFT JOIN vtiger_users ON vtiger_users.id=vtiger_crmentity.smownerid AND vtiger_users.status="ACTIVE"
 						LEFT JOIN vtiger_groups ON vtiger_groups.groupid=vtiger_crmentity.smownerid
diff --git a/modules/Install/views/Index.php b/modules/Install/views/Index.php
index 54a29e5f49bfd76b83e7b3f86111cdbd0e6a9003..61097a2adf417a509ec35443e1cc2d7da0b7f8d2 100644
--- a/modules/Install/views/Index.php
+++ b/modules/Install/views/Index.php
@@ -111,6 +111,10 @@ class Install_Index_view extends Vtiger_View_Controller {
 		$viewer->assign('ADMIN_LASTNAME', $defaultParameters['admin_lastname']);
 		$viewer->assign('ADMIN_PASSWORD', $defaultParameters['admin_password']);
 		$viewer->assign('ADMIN_EMAIL', $defaultParameters['admin_email']);
+                
+                $runtime_configs = Vtiger_Runtime_Configs::getInstance();
+                $password_regex = $runtime_configs->getValidationRegex('password_regex');
+                $viewer->assign('PWD_REGEX', $password_regex);
 
 		$viewer->view('Step4.tpl', $moduleName);
 	}
diff --git a/modules/Migration/models/Module.php b/modules/Migration/models/Module.php
index 4e1bdc24ddac0e8fc0d1b60d0b56e75e4e738c3b..3c85143ea3415a45be261e734ffb6988a07fd78d 100644
--- a/modules/Migration/models/Module.php
+++ b/modules/Migration/models/Module.php
@@ -46,6 +46,7 @@ class Migration_Module_Model extends Vtiger_Module_Model {
                         array('711' => '7.1.1'),
                         array('720' => '7.2.0'),
                         array('730' => '7.3.0'),
+                        array('740' => '7.4.0'),
 		);
 		return $versions;
 	}
diff --git a/modules/Migration/schema/660_to_700.php b/modules/Migration/schema/660_to_700.php
index bbe645d9c5deddf3598961f5df9dc02813a860d5..3ee263c843c80bcf2ec9cbe93de06d022a4551ee 100644
--- a/modules/Migration/schema/660_to_700.php
+++ b/modules/Migration/schema/660_to_700.php
@@ -2225,9 +2225,6 @@ if(defined('VTIGER_UPGRADE')) {
 		rename('modules/Vtiger/resources', 'modules/Vtiger/resources_650');
 	}
 
-	//Update existing package modules
-	Install_Utils_Model::installModules();
-
 	//recalculate user files to finish
 	RecalculateSharingRules();
 
diff --git a/modules/Migration/schema/701_to_710.php b/modules/Migration/schema/701_to_710.php
index 7562d9775ccd0776a4a41f1f55a6605a8fea3d1c..5610f0c5058a97c893c11b13483ad2f9f9e54cdb 100644
--- a/modules/Migration/schema/701_to_710.php
+++ b/modules/Migration/schema/701_to_710.php
@@ -426,8 +426,5 @@ if (defined('VTIGER_UPGRADE')) {
 	}
 	//END::Updating custom view and report columns, filters for createdtime and modifiedtime fields as typeofdata (T~...) is being transformed to (DT~...)
 
-	//Update existing package modules
-	Install_Utils_Model::installModules();
-
 	echo '<br>Succecssfully vtiger version updated to <b>7.1.0</b><br>';
 }
diff --git a/modules/Migration/schema/711_to_720.php b/modules/Migration/schema/711_to_720.php
index 8a75abe106a4f715588103df37b73a7701564a17..8ef2b7b493c6fd41c4a4f953ec57ee22a16943ee 100644
--- a/modules/Migration/schema/711_to_720.php
+++ b/modules/Migration/schema/711_to_720.php
@@ -18,7 +18,4 @@ if (defined('VTIGER_UPGRADE')) {
     if(!in_array($columnName,$columns)) {
         $db->pquery('ALTER TABLE vtiger_attachments ADD COLUMN storedname varchar(255) NULL AFTER path', array());
     }
-    
-    //Update existing package modules
-    Install_Utils_Model::installModules();
 }
diff --git a/modules/Migration/schema/720_to_730.php b/modules/Migration/schema/720_to_730.php
index 78f27fb6235761b5d5c933d1df365e58487ec34d..d048909f4299812fc2e5a43129018382b39c96cf 100644
--- a/modules/Migration/schema/720_to_730.php
+++ b/modules/Migration/schema/720_to_730.php
@@ -297,7 +297,4 @@ if (defined('VTIGER_UPGRADE')) {
     $db->pquery('ALTER TABLE vtiger_calendar_default_activitytypes ADD COLUMN conditions VARCHAR(255) DEFAULT ""', array());
     
     echo 'Conditions column in vtiger_calendar_default_activitytypes updated';
-    
-    //Update existing package modules
-    Install_Utils_Model::installModules();
 }
\ No newline at end of file
diff --git a/modules/Migration/schema/730_to_740.php b/modules/Migration/schema/730_to_740.php
new file mode 100644
index 0000000000000000000000000000000000000000..563270f25458b9dc5dc5404179556b6a343608e6
--- /dev/null
+++ b/modules/Migration/schema/730_to_740.php
@@ -0,0 +1,51 @@
+<?php
+/*+********************************************************************************
+ * The contents of this file are subject to the vtiger CRM Public License Version 1.0
+ * ("License"); You may not use this file except in compliance with the License
+ * The Original Code is: vtiger CRM Open Source
+ * The Initial Developer of the Original Code is vtiger.
+ * Portions created by vtiger are Copyright (C) vtiger.
+ * All Rights Reserved.
+ *********************************************************************************/
+
+if (defined('VTIGER_UPGRADE')) {
+	global $current_user, $adb;
+    $db = PearDatabase::getInstance();
+ 
+    $eventManager = new VTEventsManager($db);
+    $className = 'Vtiger_RecordLabelUpdater_Handler';
+    $eventManager->unregisterHandler($className);
+    echo "Unregistered record label update handler.<br>";
+
+    $moduleName = 'Users';
+    $moduleModel = Vtiger_Module_Model::getInstance($moduleName);
+    $fieldName = 'userlabel';
+    $blockModel = Vtiger_Block_Model::getInstance('LBL_MORE_INFORMATION', $moduleModel);
+    if ($blockModel) {
+        $fieldModel = Vtiger_Field_Model::getInstance($fieldName, $moduleModel);
+        if (!$fieldModel) {
+            $fieldModel				= new Vtiger_Field();
+            $fieldModel->name		= $fieldName;
+            $fieldModel->label		= 'User Label';
+            $fieldModel->table		= 'vtiger_users';
+            $fieldModel->columntype = 'VARCHAR(255)';
+            $fieldModel->typeofdata = 'V~O';
+            $fieldModel->displaytype= 3;
+            $blockModel->addField($fieldModel);
+            echo "<br>Successfully added <b>$fieldName</b> field to <b>$moduleName</b><br>";
+        }
+    }
+    $db->pquery("UPDATE vtiger_users SET $fieldName=TRIM(CONCAT(first_name, ' ' , last_name))", array());
+    echo "<br>Successfully updated <b>$fieldName</b> value as concatenate of firstname and lastname for <b>$moduleName</b> module<br>";
+
+    vimport('~modules/Users/CreateUserPrivilegeFile.php');
+    $result = $db->pquery('SELECT id FROM vtiger_users', array());
+    $count = $db->num_rows($result);
+    while ($row = $db->fetch_array($result)) {
+        $userId = $row['id'];
+        createUserPrivilegesfile($userId);
+        echo "<br>Successfully recreated <b>User's privileges</b> file for id:<b>$userId</b><br>";
+    }
+    echo "<br>Successfully completed concatenate of firstname and lastname as label in <b>$moduleName</b> module<br>";
+
+}
\ No newline at end of file
diff --git a/modules/Migration/views/Index.php b/modules/Migration/views/Index.php
index caecf7dba720fbd2bc1f23719ababfe80ae7d160..f83ca730551b919501fc55df85bdfa729a09ca4d 100644
--- a/modules/Migration/views/Index.php
+++ b/modules/Migration/views/Index.php
@@ -129,6 +129,19 @@ class Migration_Index_View extends Vtiger_View_Controller {
 				echo "<table class='config-table'><tr><th><span><b><font color='red'> There is no Database Changes from ".$migrateVersions[$i]." ==> ".$migrateVersions[$i+1]."</font></b></span></th></tr></table>";
 			}
 		}
+                
+                //During migration process we need to upgrade the package changes
+                if(defined('VTIGER_UPGRADE')) {
+		
+			echo "<table class='config-table'><tr><th><span><b><font color='red'> Upgrading Modules -- Starts. </font></b></span></th></tr></table>";
+			echo "<table class='config-table'>";
+	
+			//Update existing package modules
+			Install_Utils_Model::installModules();
+
+			echo "<table class='config-table'><tr><th><span><b><font color='red'>Upgrading Modules -- Ends.</font></b></span></th></tr></table>";
+			
+		}
 
 		//update vtiger version in db
 		$migrationModuleModel->updateVtigerVersion();
diff --git a/modules/Potentials/models/Module.php b/modules/Potentials/models/Module.php
index bb6a9a7a342bc4e0214120d1085187c3424dc2b7..cc90a4899688ce31c7bac35925c3c5cfd84a7231 100644
--- a/modules/Potentials/models/Module.php
+++ b/modules/Potentials/models/Module.php
@@ -99,7 +99,7 @@ class Potentials_Module_Model extends Vtiger_Module_Model {
             $params[] = $picklistValue;
         }
         
-		$result = $db->pquery('SELECT COUNT(*) AS count, concat(first_name," ",last_name) as last_name, vtiger_potential.sales_stage, vtiger_groups.groupname FROM vtiger_potential
+		$result = $db->pquery('SELECT COUNT(*) AS count, vtiger_users.userlabel as last_name, vtiger_potential.sales_stage, vtiger_groups.groupname FROM vtiger_potential
 						INNER JOIN vtiger_crmentity ON vtiger_potential.potentialid = vtiger_crmentity.crmid AND vtiger_crmentity.deleted = 0
 						LEFT JOIN vtiger_users ON vtiger_users.id=vtiger_crmentity.smownerid AND vtiger_users.status="ACTIVE"
 						LEFT JOIN vtiger_groups ON vtiger_groups.groupid=vtiger_crmentity.smownerid'.Users_Privileges_Model::getNonAdminAccessControlQuery($this->getName()).'
@@ -134,7 +134,7 @@ class Potentials_Module_Model extends Vtiger_Module_Model {
         unset($picklistvaluesmap['Closed Won']);unset($picklistvaluesmap['Closed Lost']);
         foreach($picklistvaluesmap as $picklistValue) $params[] = $picklistValue;
         
-		$result = $db->pquery('SELECT sum(amount) AS amount, concat(first_name," ",last_name) as last_name, vtiger_potential.sales_stage FROM vtiger_potential
+		$result = $db->pquery('SELECT sum(amount) AS amount, vtiger_users.userlabel as last_name, vtiger_potential.sales_stage FROM vtiger_potential
 						INNER JOIN vtiger_crmentity ON vtiger_potential.potentialid = vtiger_crmentity.crmid
 						INNER JOIN vtiger_users ON vtiger_users.id=vtiger_crmentity.smownerid AND vtiger_users.status="ACTIVE"
 						AND vtiger_crmentity.deleted = 0 '.Users_Privileges_Model::getNonAdminAccessControlQuery($this->getName()).
@@ -168,7 +168,7 @@ class Potentials_Module_Model extends Vtiger_Module_Model {
 			$params[] = $dateFilter['end'];
 		}
 		
-		$result = $db->pquery('SELECT sum(amount) amount, concat(first_name," ",last_name) as last_name,vtiger_users.id as id,DATE_FORMAT(closingdate, "%d-%m-%Y") AS closingdate  FROM vtiger_potential
+		$result = $db->pquery('SELECT sum(amount) amount, vtiger_users.userlabel as last_name,vtiger_users.id as id,DATE_FORMAT(closingdate, "%d-%m-%Y") AS closingdate  FROM vtiger_potential
 						INNER JOIN vtiger_crmentity ON vtiger_potential.potentialid = vtiger_crmentity.crmid
 						INNER JOIN vtiger_users ON vtiger_users.id=vtiger_crmentity.smownerid AND vtiger_users.status="ACTIVE"
 						AND vtiger_crmentity.deleted = 0 '.Users_Privileges_Model::getNonAdminAccessControlQuery($this->getName()).'WHERE sales_stage = ? '.' '.$dateFilterSql.' GROUP BY smownerid', $params);
diff --git a/modules/Reports/ReportRun.php b/modules/Reports/ReportRun.php
index 0dc0f675c63ebd64d67b21b32e31dd25e2356035..b4515a308f0dcd7dffe2fee63de31b967cb78cd0 100644
--- a/modules/Reports/ReportRun.php
+++ b/modules/Reports/ReportRun.php
@@ -541,7 +541,7 @@ class ReportRun extends CRMEntity {
 					if ($module == 'Emails') {
 						$columnSQL = "YEAR(cast(concat($emailTableName.date_start,'  ',$emailTableName.time_start) as DATE)) AS Emails_Date_Sent_Year";
 					} else {
-						$columnSQL = "YEAR(cast(concat(vtiger_activity.date_start,'  ',vtiger_activity.time_start) as DATETIME)) AS Calendar_Start_Date_and_Time_Year";
+						$columnSQL = "YEAR(concat(vtiger_activity.date_start,' ',vtiger_activity.time_start)) AS Calendar_Start_Date_and_Time_Year";
 					}
 				} else if ($selectedfields[0] == "vtiger_crmentity" . $this->primarymodule) {
 					$columnSQL = "YEAR(vtiger_crmentity." . $selectedfields[1] . ") AS '" . decode_html($header_label) . "_Year'";
@@ -554,7 +554,7 @@ class ReportRun extends CRMEntity {
 					if ($module == 'Emails') {
 						$columnSQL = "MONTHNAME(cast(concat($emailTableName.date_start,'  ',$emailTableName.time_start) as DATE)) AS Emails_Date_Sent_Month";
 					} else {
-						$columnSQL = "MONTHNAME(cast(concat(vtiger_activity.date_start,'  ',vtiger_activity.time_start) as DATETIME)) AS Calendar_Start_Date_and_Time_Month";
+						$columnSQL = "MONTHNAME(concat(vtiger_activity.date_start,'  ',vtiger_activity.time_start)) AS Calendar_Start_Date_and_Time_Month";
 					}
 				} else if ($selectedfields[0] == "vtiger_crmentity" . $this->primarymodule) {
 					$columnSQL = "MONTHNAME(vtiger_crmentity." . $selectedfields[1] . ") AS '" . decode_html($header_label) . "_Month'";
@@ -567,7 +567,7 @@ class ReportRun extends CRMEntity {
 					if ($module == 'Emails') {
 						$columnSQL = "CONCAT('Week ',WEEK(cast(concat($emailTableName.date_start,'  ',$emailTableName.time_start) as DATE), 1)) AS Emails_Date_Sent_Week";
 					} else {
-						$columnSQL = "CONCAT('Week ',WEEK(cast(concat(vtiger_activity.date_start,'  ',vtiger_activity.time_start) as DATETIME), 1)) AS Calendar_Start_Date_and_Time_Week";
+						$columnSQL = "CONCAT('Week ',WEEK(concat(vtiger_activity.date_start,'  ',vtiger_activity.time_start), 1)) AS Calendar_Start_Date_and_Time_Week";
 					}
 				} else if ($selectedfields[0] == "vtiger_crmentity" . $this->primarymodule) {
 					$columnSQL = "CONCAT('Week ',WEEK(vtiger_crmentity." . $selectedfields[1] . ", 1)) AS '" . decode_html($header_label) . "_Week'";
@@ -580,7 +580,7 @@ class ReportRun extends CRMEntity {
 					if ($module == 'Emails') {
 						$columnSQL = "date_format(cast(concat($emailTableName.date_start,'  ',$emailTableName.time_start) as DATE), '%M %Y') AS Emails_Date_Sent_Month";
 					} else {
-						$columnSQL = "date_format(cast(concat(vtiger_activity.date_start,'  ',vtiger_activity.time_start) as DATETIME), '%M %Y') AS Calendar_Start_Date_and_Time_Month";
+						$columnSQL = "date_format(concat(vtiger_activity.date_start,'  ',vtiger_activity.time_start), '%M %Y') AS Calendar_Start_Date_and_Time_Month";
 					}
 				} else if ($selectedfields[0] == "vtiger_crmentity" . $this->primarymodule) {
 					$columnSQL = "date_format(vtiger_crmentity." . $selectedfields[1] . ", '%M %Y') AS '" . decode_html($header_label) . "_Month'";
@@ -593,7 +593,7 @@ class ReportRun extends CRMEntity {
 					if ($module == 'Emails') {
 						$columnSQL = "cast(concat($emailTableName.date_start,'  ',$emailTableName.time_start) as DATE) AS Emails_Date_Sent";
 					} else {
-						$columnSQL = "cast(concat(vtiger_activity.date_start,'  ',vtiger_activity.time_start) as DATETIME) AS Calendar_Start_Date_and_Time";
+						$columnSQL = "concat(vtiger_activity.date_start,'  ',vtiger_activity.time_start) AS Calendar_Start_Date_and_Time";
 					}
 				} else if ($selectedfields[0] == "vtiger_crmentity" . $this->primarymodule) {
 					$columnSQL = "vtiger_crmentity." . $selectedfields[1] . " AS '" . decode_html($header_label) . "'";
@@ -608,7 +608,7 @@ class ReportRun extends CRMEntity {
 			if ($module == 'Emails') {
 				$columnSQL = "cast(concat($emailTableName.date_start,'  ',$emailTableName.time_start) as DATE) AS Emails_Date_Sent";
 			} else {
-				$columnSQL = "cast(concat(vtiger_activity.date_start,'  ',vtiger_activity.time_start) as DATETIME) AS Calendar_Start_Date_and_Time";
+				$columnSQL = "concat(vtiger_activity.date_start,'  ',vtiger_activity.time_start) AS Calendar_Start_Date_and_Time";
 			}
 		} elseif (stristr($selectedfields[0], "vtiger_users") && ($selectedfields[1] == 'user_name')) {
 			$temp_module_from_tablename = str_replace("vtiger_users", "", $selectedfields[0]);
@@ -1079,7 +1079,7 @@ class ReportRun extends CRMEntity {
 										$endDateTime = "DATE_FORMAT('$endDateTime', '%m%d')";
 									} else {
 										if ($selectedFields[0] == 'vtiger_activity' && ($selectedFields[1] == 'date_start')) {
-											$tableColumnSql = 'CAST((CONCAT(date_start, " ", time_start)) AS DATETIME)';
+											$tableColumnSql = '(CONCAT(date_start, " ", time_start))';
 										} else {
 											if (empty($emailTableName)) {
 												$tableColumnSql = $selectedFields[0] . '.' . $selectedFields[1];
@@ -1110,7 +1110,7 @@ class ReportRun extends CRMEntity {
 							}
 
 							if ($selectedFields[0] == 'vtiger_activity' && ($selectedFields[1] == 'date_start')) {
-								$tableColumnSql = 'CAST((CONCAT(date_start, " ", time_start)) AS DATETIME)';
+								$tableColumnSql = '(CONCAT(date_start, " ", time_start))';
 							} else {
 								if (empty($emailTableName)) {
 									$tableColumnSql = $selectedFields[0] . '.' . $selectedFields[1];
@@ -1532,7 +1532,7 @@ class ReportRun extends CRMEntity {
 					} else {
 						if ($selectedfields[0] == 'vtiger_activity' && ($selectedfields[1] == 'date_start')) {
 							$tableColumnSql = '';
-							$tableColumnSql = "CAST((CONCAT(date_start,' ',time_start)) AS DATETIME)";
+							$tableColumnSql = "(CONCAT(date_start,' ',time_start))";
 						} else {
 							$tableColumnSql = $selectedfields[0] . "." . $selectedfields[1];
 						}
diff --git a/modules/Reports/models/ListView.php b/modules/Reports/models/ListView.php
index 6bcfb4aef0abeabc226c08002aec6f21fb3480e4..f1557fa0032d361a25aafc5ea5edd4ae8e58b2b6 100644
--- a/modules/Reports/models/ListView.php
+++ b/modules/Reports/models/ListView.php
@@ -100,7 +100,7 @@ class Reports_ListView_Model extends Vtiger_ListView_Model {
 		if (!empty($orderBy) && $orderBy === 'smownerid') {
 			$fieldModel = Vtiger_Field_Model::getInstance('assigned_user_id', $moduleModel);
 			if ($fieldModel->getFieldDataType() == 'owner') {
-				$orderBy = 'COALESCE(CONCAT(vtiger_users.first_name,vtiger_users.last_name),vtiger_groups.groupname)';
+				$orderBy = 'COALESCE(vtiger_users.userlabel,vtiger_groups.groupname)';
 			}
 		}
 		if(!empty($orderBy)) {
diff --git a/modules/Settings/Groups/models/Member.php b/modules/Settings/Groups/models/Member.php
index bcc72c1e075e9e9b42f71449a280fe804155af6a..9a3dc90fe1a25c4b917d2d87bfbc6c0c2e83a8ce 100644
--- a/modules/Settings/Groups/models/Member.php
+++ b/modules/Settings/Groups/models/Member.php
@@ -102,7 +102,7 @@ class Settings_Groups_Member_Model extends Vtiger_Base_Model {
             $tableName = $tables[self::MEMBER_TYPE_USERS]['table'];
             $tableIndex = $tables[self::MEMBER_TYPE_USERS]['index'];
             $refIndex = $tables[self::MEMBER_TYPE_USERS]['refIndex'];
-			$sql = "SELECT vtiger_users.id, vtiger_users.last_name, vtiger_users.first_name FROM vtiger_users
+			$sql = "SELECT vtiger_users.id, vtiger_users.last_name, vtiger_users.first_name, vtiger_users.userlabel FROM vtiger_users
 							INNER JOIN $tableName ON $tableName.$refIndex = vtiger_users.id
 							WHERE $tableName.$tableIndex = ?";
 			$params = array($groupModel->getId());
@@ -113,7 +113,7 @@ class Settings_Groups_Member_Model extends Vtiger_Base_Model {
 				$row = $db->query_result_rowdata($result, $i);
 				$userId = $row['id'];
 				$qualifiedId = self::getQualifiedId(self::MEMBER_TYPE_USERS, $userId);
-				$name = getFullNameFromArray('Users', $row);
+				$name = $row['userlabel'];
 				$member = new self();
 				$members[$qualifiedId] = $member->set('id', $qualifiedId)->set('name', $name)->set('userId', $userId);
 			}
diff --git a/modules/Settings/Vtiger/models/ListView.php b/modules/Settings/Vtiger/models/ListView.php
index 1e944f10c12bcfb9408ad44043befb162c0daa67..0ffe2428a446c98ec83432c24afc95a06a60557b 100644
--- a/modules/Settings/Vtiger/models/ListView.php
+++ b/modules/Settings/Vtiger/models/ListView.php
@@ -72,7 +72,7 @@ class Settings_Vtiger_ListView_Model extends Vtiger_Base_Model {
 		if (!empty($orderBy) && $orderBy === 'smownerid') { 
 			$fieldModel = Vtiger_Field_Model::getInstance('assigned_user_id', $moduleModel); 
 			if ($fieldModel->getFieldDataType() == 'owner') { 
-				$orderBy = 'COALESCE(CONCAT(vtiger_users.first_name,vtiger_users.last_name),vtiger_groups.groupname)'; 
+				$orderBy = 'COALESCE(vtiger_users.userlabel,vtiger_groups.groupname)'; 
 			} 
 		}
 		if (!empty($orderBy)) {
diff --git a/modules/Users/Users.php b/modules/Users/Users.php
index 6c024b967b63c8567bdb775120487fdcf970f5f1..232ad18e8d0ad3a9826d1db9896dd17ccc87d7cd 100755
--- a/modules/Users/Users.php
+++ b/modules/Users/Users.php
@@ -112,7 +112,7 @@ class Users extends CRMEntity {
 	);
 
 	//Default Fields for Email Templates -- Pavani
-	var $emailTemplate_defaultFields = array('first_name','last_name','title','department','phone_home','phone_mobile','signature','email1','email2','address_street','address_city','address_state','address_country','address_postalcode');
+	var $emailTemplate_defaultFields = array('first_name','last_name','userlabel','title','department','phone_home','phone_mobile','signature','email1','email2','address_street','address_city','address_state','address_country','address_postalcode');
 
 	var $popup_fields = array('last_name');
 
@@ -621,14 +621,14 @@ class Users extends CRMEntity {
 	}
 
 	function fill_in_additional_detail_fields() {
-		$query = "SELECT u1.first_name, u1.last_name from vtiger_users u1, vtiger_users u2 where u1.id = u2.reports_to_id AND u2.id = ? and u1.deleted=0";
+		$query = "SELECT u1.first_name, u1.last_name, u1.userlabel from vtiger_users u1, vtiger_users u2 where u1.id = u2.reports_to_id AND u2.id = ? and u1.deleted=0";
 		$result =$this->db->pquery($query, array($this->id), true, "Error filling in additional detail vtiger_fields") ;
 
 		$row = $this->db->fetchByAssoc($result);
 		$this->log->debug("additional detail query results: $row");
 
 		if($row != null) {
-			$this->reports_to_name = stripslashes(getFullNameFromArray('Users', $row));
+			$this->reports_to_name = stripslashes($row['userlabel']);
 		}
 		else {
 			$this->reports_to_name = '';
@@ -768,6 +768,20 @@ class Users extends CRMEntity {
 		// We will set the crypt_type based on the insertion_mode
 		$crypt_type = '';
 
+		// userlabel is a field. So, setting to column_fields will take care for update and insert as well
+        if($table_name == 'vtiger_users') {
+			$entityFields = Vtiger_Functions::getEntityModuleInfo($module);
+			$entityFieldNames  = explode(',', $entityFields['fieldname']);
+
+			$userlabel = '';
+			foreach($entityFieldNames as $entityFieldName) {
+				$userlabel .= $this->column_fields[$entityFieldName]." ";
+			}
+			$userlabel = trim(decode_html($userlabel));
+			
+			$this->column_fields['userlabel'] = strip_tags($userlabel);
+		}
+
 		if($insertion_mode == 'edit') {
 			$update = '';
 			$update_params = array();
@@ -1795,7 +1809,7 @@ class Users extends CRMEntity {
 						$reportsTo = null;
 						foreach($allUsers as $user) {
 							$userName = strtolower($user->get('user_name'));
-							$firstLastName = strtolower($user->get('first_name')." ".$user->get('last_name'));
+							$firstLastName = strtolower($user->get('userlabel'));
 							if(strtolower($fieldValue) == $userName || strtolower($fieldValue) == $firstLastName) {
 								$reportsTo = $user->getId();
 								break;
diff --git a/modules/Users/actions/ForgotPassword.php b/modules/Users/actions/ForgotPassword.php
index 38556c0214a8909a9b58dddcfb06c89906b76cae..721e3262e7b3489aec7c1de4d3cb972c58c1fccf 100644
--- a/modules/Users/actions/ForgotPassword.php
+++ b/modules/Users/actions/ForgotPassword.php
@@ -43,13 +43,19 @@ class Users_ForgotPassword_Action {
 			$userId = getUserId_Ol($userName);
 			$user = Users::getActiveAdminUser();
 			$wsUserId = vtws_getWebserviceEntityId('Users', $userId);
-			vtws_changePassword($wsUserId, '', $newPassword, $confirmPassword, $user);
+                        try{
+                            vtws_changePassword($wsUserId, '', $newPassword, $confirmPassword, $user);
+                        } catch (Exception $e){
+                            $viewer->assign('ERROR', true);
+                            $viewer->assign('MESSAGE', html_entity_decode($e->getMessage()));
+                        }
 		} else {
 			$viewer->assign('ERROR', true);
+                        $viewer->assign('MESSAGE', 'Error, please retry setting the password!!');
 		}
-		$shortURLModel->delete();
-		$viewer->assign('USERNAME', $userName);
-		$viewer->assign('PASSWORD', $newPassword);
+                    $shortURLModel->delete();
+                    $viewer->assign('USERNAME', $userName);
+                    $viewer->assign('PASSWORD', $newPassword);
 		$viewer->view('FPLogin.tpl', 'Users');
 	}
 
diff --git a/modules/Users/models/Module.php b/modules/Users/models/Module.php
index f875d3c5024d4feae09f2bc8367c9c485e341ed7..e08a3042e0f7c6b38fc5beffcd10d3c820143eca 100644
--- a/modules/Users/models/Module.php
+++ b/modules/Users/models/Module.php
@@ -46,10 +46,10 @@ class Users_Module_Model extends Vtiger_Module_Model {
 		if(!empty($searchValue)) {
 			$db = PearDatabase::getInstance();
 
-			$query = 'SELECT * FROM vtiger_users WHERE (first_name LIKE ? OR last_name LIKE ?) AND status = ?';
+			$query = 'SELECT * FROM vtiger_users WHERE userlabel LIKE ? AND status = ?';
 			$currentUser = Users_Record_Model::getCurrentUserModel();
 			$allSubordinates = $currentUser->getAllSubordinatesByReportsToField($currentUser->getId());
-			$params = array("%$searchValue%", "%$searchValue%", 'Active');
+			$params = array("%$searchValue%", 'Active');
 
 			// do not allow the subordinates
 			if(count($allSubordinates) > 0) {
diff --git a/modules/Users/models/Record.php b/modules/Users/models/Record.php
index 206b8aac48a07bbea5c097cb9049585292f4e989..b6a0c43c692bcef3638059411d8c76c9ad1e9a3b 100644
--- a/modules/Users/models/Record.php
+++ b/modules/Users/models/Record.php
@@ -275,7 +275,7 @@ class Users_Record_Model extends Vtiger_Record_Model {
 		if($subordinateRoleUsers) {
 			foreach($subordinateRoleUsers as $role=>$users) {
 				foreach($users as $user) {
-					$subordinateUsers[$user] = $privilegesModel->get('first_name').' '.$privilegesModel->get('last_name');
+					$subordinateUsers[$user] = $privilegesModel->get('userlabel');
 				}
 			}
 		}
@@ -458,7 +458,7 @@ class Users_Record_Model extends Vtiger_Record_Model {
 		$currentUserRoleModel = Settings_Roles_Record_Model::getInstanceById($this->getRole());
 		$childernRoles = $currentUserRoleModel->getAllChildren();
 		$users = $this->getAllUsersOnRoles($childernRoles);
-        $currentUserDetail = array($this->getId() => $this->get('first_name').' '.$this->get('last_name'));
+        $currentUserDetail = array($this->getId() => $this->get('userlabel'));
         $users = $currentUserDetail + $users;
         return $users;
 	}
@@ -488,14 +488,12 @@ class Users_Record_Model extends Vtiger_Record_Model {
 			for($i=0; $i<$noOfUsers; ++$i) {
 				$userIds[] = $db->query_result($result, $i, 'userid');
 			}
-			$query = 'SELECT id, first_name, last_name FROM vtiger_users WHERE status = ? AND id IN ('.  generateQuestionMarks($userIds).')';
+			$query = 'SELECT id, userlabel FROM vtiger_users WHERE status = ? AND id IN ('.  generateQuestionMarks($userIds).')';
 			$result = $db->pquery($query, array('ACTIVE', $userIds));
 			$noOfUsers = $db->num_rows($result);
 			for($j=0; $j<$noOfUsers; ++$j) {
 				$userId = $db->query_result($result, $j,'id');
-				$firstName = $db->query_result($result, $j, 'first_name');
-				$lastName = $db->query_result($result, $j, 'last_name');
-				$subUsers[$userId] = $firstName .' '.$lastName;
+				$subUsers[$userId] = $db->query_result($result, $j, 'userlabel');
 			}
 		}
 		return $subUsers;
@@ -807,7 +805,12 @@ class Users_Record_Model extends Vtiger_Record_Model {
 	 * @return <String> - Entity Display Name for the record
 	 */
 	public function getDisplayName() {
-		return getFullNameFromArray($this->getModuleName(),$this->getData());
+		$userLabel = $this->get('userlabel');
+
+		if (!$userLabel) {
+			$userLabel = getFullNameFromArray($this->getModuleName(),$this->getData());
+		}
+		return $userLabel;
 	}
 
 	/**
diff --git a/modules/Users/views/List.php b/modules/Users/views/List.php
index 40bff8e2273cee67f5e593119a6e496017bf78ff..6daceada7b59aa2eaececf5cd26d395138ff5526 100644
--- a/modules/Users/views/List.php
+++ b/modules/Users/views/List.php
@@ -167,6 +167,10 @@ class Users_List_View extends Settings_Vtiger_List_View {
 		$viewer->assign('USER_MODEL', Users_Record_Model::getCurrentUserModel());
 		$viewer->assign('SEARCH_VALUE', $searchValue);
 		$viewer->assign('SEARCH_DETAILS', $searchParams);
+                
+                $runtime_configs = Vtiger_Runtime_Configs::getInstance();
+                $password_regex = $runtime_configs->getValidationRegex('password_regex');
+                $viewer->assign('PWD_REGEX', $password_regex);
 	}
 
 	/**
diff --git a/modules/Users/views/PreferenceDetail.php b/modules/Users/views/PreferenceDetail.php
index 154544d3f55115a62d547cbab687e136a8e53bb2..8df592a4bade5dcef8a54ee074cf44f1e435ae2c 100644
--- a/modules/Users/views/PreferenceDetail.php
+++ b/modules/Users/views/PreferenceDetail.php
@@ -172,6 +172,9 @@ class Users_PreferenceDetail_View extends Vtiger_Detail_View {
 		$viewer->assign("DAY_STARTS", Zend_Json::encode($dayStartPicklistValues));
 		$viewer->assign('IMAGE_DETAILS', $recordModel->getImageDetails());
 
+                $runtime_configs = Vtiger_Runtime_Configs::getInstance();
+                $password_regex = $runtime_configs->getValidationRegex('password_regex');
+                $viewer->assign('PWD_REGEX', $password_regex);
 		return parent::process($request);
 	}
 
diff --git a/modules/Users/views/PreferenceEdit.php b/modules/Users/views/PreferenceEdit.php
index cc1e4032604a127e3d2082fc649dbc9cd3460027..108680c552c91ddd9a44efd64fcd978c689fbbf4 100644
--- a/modules/Users/views/PreferenceEdit.php
+++ b/modules/Users/views/PreferenceEdit.php
@@ -121,7 +121,7 @@ Class Users_PreferenceEdit_View extends Vtiger_Edit_View {
 				$fieldsInfo[$fieldName] = $fieldModel->getFieldInfo();
 			}
 			$viewer->assign('FIELDS_INFO', json_encode($fieldsInfo));
-
+                        
 			if($display) {
 				$this->preProcessDisplay($request);
 			}
@@ -150,6 +150,10 @@ Class Users_PreferenceEdit_View extends Vtiger_Edit_View {
 		$viewer->assign("DAY_STARTS", Zend_Json::encode($dayStartPicklistValues));
 		$viewer->assign('TAG_CLOUD', $recordModel->getTagCloudStatus());
 		$viewer->assign('USER_MODEL', Users_Record_Model::getCurrentUserModel());
+                
+                $runtime_configs = Vtiger_Runtime_Configs::getInstance();
+                $password_regex = $runtime_configs->getValidationRegex('password_regex');
+                $viewer->assign('PWD_REGEX', $password_regex);
 
 		parent::process($request);
 	}
diff --git a/modules/Vtiger/RecordLabelUpdater.php b/modules/Vtiger/RecordLabelUpdater.php
deleted file mode 100644
index 2c4447f88fa2c8fdb7f32dffdbc1f8eeb343f6a9..0000000000000000000000000000000000000000
--- a/modules/Vtiger/RecordLabelUpdater.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-/* +***********************************************************************************
- * The contents of this file are subject to the vtiger CRM Public License Version 1.0
- * ("License"); You may not use this file except in compliance with the License
- * The Original Code is:  vtiger CRM Open Source
- * The Initial Developer of the Original Code is vtiger.
- * Portions created by vtiger are Copyright (C) vtiger.
- * All Rights Reserved.
- * *********************************************************************************** */
-require_once 'include/events/VTEventHandler.inc';
-
-class Vtiger_RecordLabelUpdater_Handler extends VTEventHandler {
-
-	function handleEvent($eventName, $data) {
-		global $adb;
-
-		if ($eventName == 'vtiger.entity.aftersave') {
-			$labelInfo = getEntityName($data->getModuleName(), $data->getId(), true);
-
-			if ($labelInfo) {
-				$label = decode_html($labelInfo[$data->getId()]);
-				$adb->pquery('UPDATE vtiger_crmentity SET label=? WHERE crmid=?', array($label, $data->getId()));
-			}
-		}
-	}
-}
\ No newline at end of file
diff --git a/modules/Vtiger/handlers/RecordLabelUpdater.php b/modules/Vtiger/handlers/RecordLabelUpdater.php
deleted file mode 100644
index b4472d3d2bf564b4cff1c974ef9628800c3eeb44..0000000000000000000000000000000000000000
--- a/modules/Vtiger/handlers/RecordLabelUpdater.php
+++ /dev/null
@@ -1,33 +0,0 @@
-<?php
-/* +***********************************************************************************
- * The contents of this file are subject to the vtiger CRM Public License Version 1.0
- * ("License"); You may not use this file except in compliance with the License
- * The Original Code is:  vtiger CRM Open Source
- * The Initial Developer of the Original Code is vtiger.
- * Portions created by vtiger are Copyright (C) vtiger.
- * All Rights Reserved.
- * *********************************************************************************** */
-require_once 'include/events/VTEventHandler.inc';
-
-class Vtiger_RecordLabelUpdater_Handler extends VTEventHandler {
-
-	function handleEvent($eventName, $data) {
-		global $adb;
-
-		if ($eventName == 'vtiger.entity.aftersave') {
-			$record = $data->getId();
-			$module = $data->getModuleName();
-
-			if($module === 'Users') {
-				return;
-			}
-
-			$labelInfo = getEntityName($module, $record, true);
-
-			if ($labelInfo) {
-				$label = decode_html($labelInfo[$data->getId()]);
-				$adb->pquery('UPDATE vtiger_crmentity SET label=? WHERE crmid=?', array($label, $record));
-			}
-		}
-	}
-}
\ No newline at end of file
diff --git a/modules/Vtiger/models/RelationListView.php b/modules/Vtiger/models/RelationListView.php
index 74e829bec76437437709147fcc5797b477078712..d09fc9d2853a600a919452a2aba974deb8cad382 100644
--- a/modules/Vtiger/models/RelationListView.php
+++ b/modules/Vtiger/models/RelationListView.php
@@ -318,7 +318,7 @@ class Vtiger_RelationListView_Model extends Vtiger_Base_Model {
 				$query = $selectAndFromClause.' WHERE '.$whereCondition;
 				$query .= ' ORDER BY '.$qualifiedOrderBy.'.label '.$sortOrder;
 			} elseif($orderByFieldModuleModel && $orderByFieldModuleModel->isOwnerField()) {
-				 $query .= ' ORDER BY COALESCE(CONCAT(vtiger_users.first_name,vtiger_users.last_name),vtiger_groups.groupname) '.$sortOrder;
+				 $query .= ' ORDER BY COALESCE(vtiger_users.userlabel,vtiger_groups.groupname) '.$sortOrder;
 			} else{
 				// Qualify the the column name with table to remove ambugity
 				$qualifiedOrderBy = $orderBy;
diff --git a/modules/Vtiger/uitypes/Reference.php b/modules/Vtiger/uitypes/Reference.php
index 3ac8f7e77494f1eaa18a0ebd3a7cb288fbdc94a7..2769a45538a146f81e2e7e45f613f42c03e5a84f 100644
--- a/modules/Vtiger/uitypes/Reference.php
+++ b/modules/Vtiger/uitypes/Reference.php
@@ -46,9 +46,9 @@ class Vtiger_Reference_UIType extends Vtiger_Base_UIType {
 			$referenceModuleName = $referenceModule->get('name');
 			if($referenceModuleName == 'Users') {
 				$db = PearDatabase::getInstance();
-				$nameResult = $db->pquery('SELECT first_name, last_name FROM vtiger_users WHERE id = ?', array($value));
+				$nameResult = $db->pquery('SELECT userlabel FROM vtiger_users WHERE id = ?', array($value));
 				if($db->num_rows($nameResult)) {
-					return $db->query_result($nameResult, 0, 'first_name').' '.$db->query_result($nameResult, 0, 'last_name');
+					return $db->query_result($nameResult, 0, 'userlabel');
 				}
 			} else {
 				$fieldModel = $this->get('field');
diff --git a/modules/com_vtiger_workflow/VTWorkflowManager.inc b/modules/com_vtiger_workflow/VTWorkflowManager.inc
index 0ea8f1235af3b2a4337ded33ab62b9e1dc936f2f..bfd394c5dc3b3ce68bd9279379c3013ea0ee85a7 100644
--- a/modules/com_vtiger_workflow/VTWorkflowManager.inc
+++ b/modules/com_vtiger_workflow/VTWorkflowManager.inc
@@ -24,6 +24,7 @@ class VTWorkflowManager{
 
 	function __construct($adb){
 		$this->adb = $adb;
+                $this->setMaxAllowedScheduledWorkflows();
 	}
 
 	function save($workflow){
@@ -105,13 +106,24 @@ class VTWorkflowManager{
 		$result = $adb->pquery($query, $params);
 		return $adb->query_result($result, 0, 'count');
 	}
+        
+        /**
+         * Function to set max allowed scheduled workflow count as per global defaults
+         */
+        function setMaxAllowedScheduledWorkflows(){
+            global $max_scheduled_workflows;
+            if(!empty($max_scheduled_workflows)){
+                vglobal('max_scheduled_workflows', $max_scheduled_workflows);
+            }else{
+                vglobal('max_scheduled_workflows', 10);
+            }
+        }
 
 	/**
 	 * Function returns the maximum allowed scheduled workflows
 	 * @return int
 	 */
 	function getMaxAllowedScheduledWorkflows() {
-            vglobal('max_scheduled_workflows', 10);
             return vglobal('max_scheduled_workflows');
 	}
 
diff --git a/modules/com_vtiger_workflow/tasks/VTEmailTask.inc b/modules/com_vtiger_workflow/tasks/VTEmailTask.inc
index cc8b6eb5c4b5d4ed82535567b95ce06a9f7798c1..ff514b2d511ccbd9d30b73cb7963246241db00a1 100644
--- a/modules/com_vtiger_workflow/tasks/VTEmailTask.inc
+++ b/modules/com_vtiger_workflow/tasks/VTEmailTask.inc
@@ -256,11 +256,11 @@ class VTEmailTask extends VTTask{
 			} else {
 				if ($userObj) {
 					$fromEmail = $userObj->email1;
-					$fromName =	trim($userObj->first_name.' '.$userObj->last_name);
+					$fromName =	$userObj->userlabel;
 				} else {
 					$fromEmail = $this->getDefaultFromEmail();
 					$userObj = Users::getActiveAdminUser();
-					$fromName =	trim($userObj->first_name.' '.$userObj->last_name);
+					$fromName =	$userObj->userlabel;
 				}
 			}
 
diff --git a/packages/vtiger/mandatory/ModTracker.zip b/packages/vtiger/mandatory/ModTracker.zip
index 2890f3939517b195682c8d74f11309d6718630b2..192cbcecdc0a1aa78968179c36dd3b02239e6bb3 100644
Binary files a/packages/vtiger/mandatory/ModTracker.zip and b/packages/vtiger/mandatory/ModTracker.zip differ
diff --git a/packages/vtiger/mandatory/PBXManager.zip b/packages/vtiger/mandatory/PBXManager.zip
index 07720357484e4878f38e42a5fd296ffb599f1bbe..3227486951dbe1aad0abcc85eba0acceaeeef9b3 100644
Binary files a/packages/vtiger/mandatory/PBXManager.zip and b/packages/vtiger/mandatory/PBXManager.zip differ
diff --git a/packages/vtiger/optional/CustomerPortal.zip b/packages/vtiger/optional/CustomerPortal.zip
index d81610c26a208ca3563d9e7fb607064b57d7700a..ac46c5b1c6d6793ca69c6ae251469ddaa1b45765 100644
Binary files a/packages/vtiger/optional/CustomerPortal.zip and b/packages/vtiger/optional/CustomerPortal.zip differ
diff --git a/packages/vtiger/optional/MexicanSpanishLanguagePack_es_mx.zip b/packages/vtiger/optional/MexicanSpanishLanguagePack_es_mx.zip
index 1437cd38b9760740291814e39ef8eb4af990ad7d..8883bf590ed374f9faef469de48c8ccfa495ac84 100644
Binary files a/packages/vtiger/optional/MexicanSpanishLanguagePack_es_mx.zip and b/packages/vtiger/optional/MexicanSpanishLanguagePack_es_mx.zip differ
diff --git a/packages/vtiger/optional/ModComments.zip b/packages/vtiger/optional/ModComments.zip
index a1e37d05c84937d116fe22278de9d221f6e0ab05..bba05805eec71b34c2cd9dbd062a9fda1ef45be7 100644
Binary files a/packages/vtiger/optional/ModComments.zip and b/packages/vtiger/optional/ModComments.zip differ
diff --git a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/DownloadFile.php b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/DownloadFile.php
index c8260dda8db6e8922a0d84fe144430c510e00b4b..110b6141249dabbffb95e0aa41b2fc0231c6e01a 100644
--- a/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/DownloadFile.php
+++ b/pkg/vtiger/modules/CustomerPortal/modules/CustomerPortal/apis/DownloadFile.php
@@ -63,18 +63,22 @@ class CustomerPortal_DownloadFile extends CustomerPortal_API_Abstract {
 				$fileres = $adb->pquery($fileidQuery, array($id));
 				$fileid = $adb->query_result($fileres, 0, 'attachmentsid');
 
-				$filepathQuery = 'SELECT path,name FROM vtiger_attachments WHERE attachmentsid = ?';
-				$fileres = $adb->pquery($filepathQuery, array($fileid));
-				$filepath = $adb->query_result($fileres, 0, 'path');
-				$filename = $adb->query_result($fileres, 0, 'name');
-				$filename = decode_html($filename);
+				$filepathQuery = 'SELECT path,name,storedname FROM vtiger_attachments WHERE attachmentsid = ?';
+                                $fileres = $adb->pquery($filepathQuery, array($fileid));
+                                $filepath = $adb->query_result($fileres, 0, 'path');
+                                if($adb->query_result($fileres, 0, 'storedname')) { 
+                                    $filename = $adb->query_result($fileres, 0, 'storedname');
+                                } else {
+                                    $filename = $adb->query_result($fileres, 0, 'name');
+                                }
+                                $realfilename = decode_html($adb->query_result($fileres, 0, 'name'));
 
-				$saved_filename = $fileid."_".$filename;
-				$filenamewithpath = $filepath.$saved_filename;
-				$filesize = filesize($filenamewithpath);
-				$fileDetails = array();
-				$fileDetails['fileid'] = $fileid;
-				$fileDetails['filename'] = $filename;
+                                $saved_filename = $fileid."_".$filename;
+                                $filenamewithpath = $filepath.$saved_filename;
+                                $filesize = filesize($filenamewithpath);
+                                $fileDetails = array();
+                                $fileDetails['fileid'] = $fileid;
+                                $fileDetails['filename'] = $realfilename;
 				$fileDetails['filetype'] = $filetype;
 				$fileDetails['filesize'] = $filesize;
 				$fileDetails['filecontents'] = base64_encode(file_get_contents($filenamewithpath));
@@ -86,8 +90,13 @@ class CustomerPortal_DownloadFile extends CustomerPortal_API_Abstract {
 				//construct path for attachment and get file size and type details
 				$attachmentDetails = $rawAttachmentDetails[0];
 				$fileid = $attachmentDetails['attachmentsid'];
-				$filename = $attachmentDetails['name'];
+                                $filename = $attachmentDetails['storedname'];
+                                if(empty($filename)){
+                                    $filename = $attachmentDetails['name'];
+                                }
 				$filepath = $attachmentDetails['path'];
+                                $realfilename = decode_html($attachmentDetails['name']);
+                                
 				$saved_filename = $fileid."_".$filename;
 				$filenamewithpath = $filepath.$saved_filename;
 				$filesize = filesize($filenamewithpath);
@@ -96,7 +105,7 @@ class CustomerPortal_DownloadFile extends CustomerPortal_API_Abstract {
 				//Construct array with all attachment details
 				$fileDetails = array();
 				$fileDetails['fileid'] = $fileid;
-				$fileDetails['filename'] = $filename;
+				$fileDetails['filename'] = $realfilename;
 				$fileDetails['filetype'] = $filetype;
 				$fileDetails['filesize'] = $filesize;
 				$fileDetails['filecontents'] = base64_encode(file_get_contents($filenamewithpath));
diff --git a/pkg/vtiger/modules/Import/modules/Import/actions/Data.php b/pkg/vtiger/modules/Import/modules/Import/actions/Data.php
index 5e0e36a0965a1fb656cef858d5b7f9335295c0cc..718a828e58dbebadeb1cd1ca03c32269412baf74 100644
--- a/pkg/vtiger/modules/Import/modules/Import/actions/Data.php
+++ b/pkg/vtiger/modules/Import/modules/Import/actions/Data.php
@@ -896,7 +896,7 @@ class Import_Data_Action extends Vtiger_Action_Controller {
 
                         $emailData = getTranslatedString('LBL_IMPORT_COMPLETED', 'Import').' '.$importResult.getTranslatedString('LBL_CHECK_IMPORT_STATUS', 'Import');
 
-			$userName = getFullNameFromArray('Users', $importDataController->user->column_fields);
+			$userName = $importDataController->user->column_fields['userlabel'];
 			$userEmail = $importDataController->user->email1;
 			$vtigerMailer->AddAddress($userEmail, $userName);
 			$vtigerMailer->Subject = $emailSubject;
diff --git a/pkg/vtiger/modules/MailManager/modules/MailManager/views/Mail.php b/pkg/vtiger/modules/MailManager/modules/MailManager/views/Mail.php
index 7d03ebff4cc62ac61393f14a575f7c473c66ece4..996f53ff1c8b3498fd3e8c385922d2c325ea877c 100755
--- a/pkg/vtiger/modules/MailManager/modules/MailManager/views/Mail.php
+++ b/pkg/vtiger/modules/MailManager/modules/MailManager/views/Mail.php
@@ -164,7 +164,7 @@ class MailManager_Mail_View extends MailManager_Abstract_View {
 					}
 
 					$fromEmail = $connector->getFromEmailAddress();
-					$userFullName = getFullNameFromArray('Users', $currentUserModel->getData());
+					$userFullName = $currentUserModel->get('userlabel');
 					$userId = $currentUserModel->getId();
 
 					$mailer = new Vtiger_Mailer();
diff --git a/pkg/vtiger/modules/Mobile/modules/Mobile/api/ws/FetchModuleOwners.php b/pkg/vtiger/modules/Mobile/modules/Mobile/api/ws/FetchModuleOwners.php
index 381a9b41863e5942271a87d1784f181db25cc993..2d0a8800087eff2124af6fb19f5be2d19c3cc9a0 100644
--- a/pkg/vtiger/modules/Mobile/modules/Mobile/api/ws/FetchModuleOwners.php
+++ b/pkg/vtiger/modules/Mobile/modules/Mobile/api/ws/FetchModuleOwners.php
@@ -38,7 +38,7 @@ class Mobile_WS_FetchModuleOwners extends Mobile_WS_Controller {
             $userRecord = Users_Record_Model::getInstanceById($userId, 'Users');
             $usersList[] = array(
                 'value' => $usersWSId . 'x' . $userId,
-                'label' => decode_html($userRecord->get("first_name") . ' ' . $userRecord->get('last_name'))
+                'label' => decode_html($userRecord->get("userlabel"))
             );
         }
         return $usersList;
diff --git a/pkg/vtiger/modules/ModComments/modules/ModComments/models/Record.php b/pkg/vtiger/modules/ModComments/modules/ModComments/models/Record.php
index 6d8807df47e7beeca77944c5be875adc1c410da6..6616d6a6e80c69fd01b85d7757c38aadebd4f667 100644
--- a/pkg/vtiger/modules/ModComments/modules/ModComments/models/Record.php
+++ b/pkg/vtiger/modules/ModComments/modules/ModComments/models/Record.php
@@ -412,14 +412,27 @@ class ModComments_Record_Model extends Vtiger_Record_Model {
 		$attachmentsList = array();
 		if($numOfRows) {
 			for($i=0; $i<$numOfRows; $i++) {
-				$attachmentsList[$i]['fileid'] = $db->query_result($attachmentRes, $i, 'attachmentsid');
-				$attachmentsList[$i]['attachment'] = decode_html($db->query_result($attachmentRes, $i, 'name'));
-				$path = $db->query_result($attachmentRes, $i, 'path');
+                                $attachmentId = $db->query_result($attachmentRes, $i, 'attachmentsid');
+                                $rawFileName = $db->query_result($attachmentRes, $i, 'name');
+                                $storedName = $db->query_result($attachmentRes, $i, 'storedname');
+                                $path = $db->query_result($attachmentRes, $i, 'path');
+                                if($storedName) { 
+                                    $filename = $storedName;
+                                } else {
+                                    $filename = $rawFileName;
+                                }
+                                $attachmentsList[$i]['attachment'] = decode_html($rawFileName);
+                                $attachmentsList[$i]['fileid'] = $attachmentId;
+                                $attachmentsList[$i]['storedname'] = decode_html($storedName);
 				$attachmentsList[$i]['path'] = $path;
-				$attachmentsList[$i]['size'] = filesize($path.$attachmentsList[$i]['fileid'].'_'.$attachmentsList[$i]['attachment']);
+                                $saved_filename = $attachmentId."_".$filename;
+                                $filenamewithpath = $path.$saved_filename;
+                                $filesize = filesize($filenamewithpath);
+                                $attachmentsList[$i]['filenamewithpath'] = $filenamewithpath;
+				$attachmentsList[$i]['size'] = $filesize;
 				$attachmentsList[$i]['type'] = $db->query_result($attachmentRes, $i, 'type');
 				$attachmentsList[$i]['cid'] = $db->query_result($attachmentRes, $i, 'cid');
-			}
+                        }
 		}
 		return $attachmentsList;
 	}
diff --git a/pkg/vtiger/modules/ModTracker/modules/ModTracker/ModTrackerHandler.php b/pkg/vtiger/modules/ModTracker/modules/ModTracker/ModTrackerHandler.php
index dc9849a147b34cbff74ce2a68028bcf4d17aec55..abe1bc3cb282746c492ef10001216065d7432100 100644
--- a/pkg/vtiger/modules/ModTracker/modules/ModTracker/ModTrackerHandler.php
+++ b/pkg/vtiger/modules/ModTracker/modules/ModTracker/ModTrackerHandler.php
@@ -14,16 +14,21 @@ class ModTrackerHandler extends VTEventHandler {
 
 	function handleEvent($eventName, $data) {
 		global $adb;
-		$current_user_id=$_SESSION["authenticated_user_id"];
-		$current_user = Users_Record_Model::getInstanceById($current_user_id, 'Users');
-		$curid=$current_user->get('id'); 
-		global $current_user;
+		if (isset($_SESSION["authenticated_user_id"])) {
+			$current_user_id = $_SESSION["authenticated_user_id"];
+			$current_user = Users_Record_Model::getInstanceById($current_user_id, 'Users');
+			$curid = $current_user->get('id');
+		} else {
+			//$_SESSION["authenticated_user_id"] is not set when creating/updating via Webservice
+			global $current_user;
+			$curid = $current_user->id;
+		}
 		$moduleName = $data->getModuleName();
 		$isTrackingEnabled = ModTracker::isTrackingEnabledForModule($moduleName);
-		if(!$isTrackingEnabled) {
+		if (!$isTrackingEnabled) {
 			return;
 		}
-		if($eventName == 'vtiger.entity.aftersave.final') {
+		if ($eventName == 'vtiger.entity.aftersave.final') {
 			$recordId = $data->getId();
 			$columnFields = $data->getData();
 			$vtEntityDelta = new VTEntityDelta();
diff --git a/pkg/vtiger/modules/PBXManager/settings/models/Record.php b/pkg/vtiger/modules/PBXManager/settings/models/Record.php
index f17988f3559bd58d0c779b7c837a97f9f3217ba6..2520ff18b6ea6bd61a7e927fa4457bdbf37e3ffa 100644
--- a/pkg/vtiger/modules/PBXManager/settings/models/Record.php
+++ b/pkg/vtiger/modules/PBXManager/settings/models/Record.php
@@ -11,29 +11,29 @@
 class Settings_PBXManager_Record_Model extends Settings_Vtiger_Record_Model {
 
     const tableName = 'vtiger_pbxmanager_gateway';
-    
+
     public function getId() {
         return $this->get('id');
     }
 
     public function getName() {
     }
-    
+
     public function getModule(){
         return new Settings_PBXManager_Module_Model;
     }
-    
+
     static function getCleanInstance(){
         return new self;
     }
-    
+
      public static function getInstance(){
         $serverModel = new self();
         $db = PearDatabase::getInstance();
         $query = 'SELECT * FROM '.self::tableName;
         $gatewatResult = $db->pquery($query, array());
         $gatewatResultCount = $db->num_rows($gatewatResult);
-        
+
         if($gatewatResultCount > 0) {
             $rowData = $db->query_result_rowdata($gatewatResult, 0);
             $serverModel->set('gateway',$rowData['gateway']);
@@ -46,7 +46,7 @@ class Settings_PBXManager_Record_Model extends Settings_Vtiger_Record_Model {
         }
         return $serverModel;
     }
-    
+
     public static function getInstanceById($recordId, $qualifiedModuleName) {
 		$db = PearDatabase::getInstance();
 		$result = $db->pquery('SELECT * FROM '.self::tableName.' WHERE id = ?', array($recordId));
@@ -66,20 +66,20 @@ class Settings_PBXManager_Record_Model extends Settings_Vtiger_Record_Model {
 		}
 		return false;
 	}
-    
+
     public function save() {
 		$db = PearDatabase::getInstance();
-		$parameters = '';
+		$parameters = array();
 		$selectedGateway = $this->get('gateway');
                 $connector = new PBXManager_PBXManager_Connector;
-                
+
                 foreach ($connector->getSettingsParameters() as $field => $type) {
                         $parameters[$field] = $this->get($field);
                 }
                 $this->set('parameters', Zend_Json::encode($parameters));
 		$params = array($selectedGateway,$this->get('parameters'));
 		$id = $this->getId();
-                
+
 		if ($id) {
 			$query = 'UPDATE '.self::tableName.' SET gateway=?, parameters = ? WHERE id = ?';
 			array_push($params, $id);
diff --git a/pkg/vtiger/translations/MexicanSpanishLanguagePack_es_mx/manifest.xml b/pkg/vtiger/translations/MexicanSpanishLanguagePack_es_mx/manifest.xml
index a477fd2e9ae58d3cff55b03c25591939927f8f09..28e8c17ae1013ff52406bad1b281f8ffaacd36e7 100644
--- a/pkg/vtiger/translations/MexicanSpanishLanguagePack_es_mx/manifest.xml
+++ b/pkg/vtiger/translations/MexicanSpanishLanguagePack_es_mx/manifest.xml
@@ -4,7 +4,7 @@
 	<name>Mexican Spanish</name>
 	<label>ES Mexico</label>
 	<prefix>es_mx</prefix>
-	<version>7.2.1</version>
+	<version>1.0</version>
 	<dependencies>
 		<vtiger_version>7.2</vtiger_version>
 		<vtiger_max_version>7.*</vtiger_max_version>
@@ -19,7 +19,7 @@
  * the specific language governing rights and limitations under the License.
  ********************************************************************************
  *  Language     : Español es_mx
- *  Version      : 7.2.1
+ *  Version      : 1.0
  *  Author       : Aimée Valckx - simplesistemas.com (Simple - Sistemas e Implementos Empresariales SA de CV)
  *  Author       : Rubén Estrada - simplesistemas.com (Simple - Sistemas e Implementos Empresariales SA de CV)
  *  Author       : Francisco Hernandez Odin Consultores S de RL de CV
diff --git a/pkg/vtiger/translations/MexicanSpanishLanguagePack_es_mx/modules/Leads.php b/pkg/vtiger/translations/MexicanSpanishLanguagePack_es_mx/modules/Leads.php
index ca8227f0eb91e557024df14d8e847e2d1438578f..831d7f61cd41496f4d439a4eb5902682a73d021b 100644
--- a/pkg/vtiger/translations/MexicanSpanishLanguagePack_es_mx/modules/Leads.php
+++ b/pkg/vtiger/translations/MexicanSpanishLanguagePack_es_mx/modules/Leads.php
@@ -37,7 +37,7 @@ $languageStrings = array(
 	'Pre Qualified'                => 'Pre calificado'              , 
 	'Qualified'                    => 'Calificado'                  , 
 	'Warm'                         => 'Tibio'                       , 
-	'LBL_CONVERT_LEAD'             => 'Convertir Prospecto:'        , 
+	'LBL_CONVERT_LEAD'             => 'Convertir Prospecto'        , 
 	'LBL_TRANSFER_RELATED_RECORD'  => 'Transferir registro relacionado a', 
 	'LBL_CONVERT_LEAD_ERROR'       => 'Necesita tener habilitado el módulo de Cuentas o Contactos para convertir el Prospecto', 
 	'LBL_LEADS_FIELD_MAPPING_INCOMPLETE' => 'No se han vinculado todos los campos obligatorios', 
diff --git a/pkg/vtiger/translations/MexicanSpanishLanguagePack_es_mx/modules/Reports.php b/pkg/vtiger/translations/MexicanSpanishLanguagePack_es_mx/modules/Reports.php
index 33b047ffadf765e5039945961c30a39ee7673297..2823c74f6edfebf7c4b8670dcbd5bb86a7382ace 100644
--- a/pkg/vtiger/translations/MexicanSpanishLanguagePack_es_mx/modules/Reports.php
+++ b/pkg/vtiger/translations/MexicanSpanishLanguagePack_es_mx/modules/Reports.php
@@ -8,17 +8,17 @@
  * All Rights Reserved.
  ************************************************************************************/
 $languageStrings = array(
-	'Reports'                      => 'Informes'                     , // TODO: Review
-	'SINGLE_Reports'               => 'Informe'                      , // TODO: Review
+	'Reports'                      => 'Reportes'                     ,
+	'SINGLE_Reports'               => 'Reporte'                      ,
 	'LBL_FOLDER_NOT_EMPTY'         => 'La carpeta no está vacía'  ,
-	'LBL_MOVE_REPORT'              => 'Mover Informe'              ,
+	'LBL_MOVE_REPORT'              => 'Mover Reporte'              ,
 	'LBL_CUSTOMIZE'                => 'Personalizar'                ,
 	'LBL_REPORT_EXPORT_EXCEL'      => 'Exportar a Excel'            ,
 	'LBL_REPORT_PRINT'             => 'Imprimir'                    ,
 	'LBL_STEP_1'                   => 'Paso 1'                      ,
 	'LBL_STEP_2'                   => 'Paso 2'                      ,
 	'LBL_STEP_3'                   => 'Paso 3'                      ,
-	'LBL_REPORT_DETAILS'           => 'Detalles del Informe'         ,
+	'LBL_REPORT_DETAILS'           => 'Detalles del Reporte'         ,
 	'LBL_SELECT_COLUMNS'           => 'Seleccionar columnas'        ,
 	'LBL_FILTERS'                  => 'Filtros'                     ,
 	'LBL_FOLDERS'                  => 'Carpetas'                    ,
@@ -28,22 +28,22 @@ $languageStrings = array(
 	'LBL_WRITE_YOUR_DESCRIPTION_HERE' => 'Agregue la descripción aquí',
 	'LBL_DUPLICATES_EXIST'         => 'Existe un duplicado'         ,
 	'LBL_FOLDERS_LIST'             => 'Lista de carpetas'           ,
-	'LBL_DENIED_REPORTS'           => 'Informes denegados'          ,
+	'LBL_DENIED_REPORTS'           => 'Reportes denegados'          ,
 	'LBL_NO_OF_RECORDS'            => 'Registros en total : '           , 
 	'LBL_MORE_RECORDS_TXT'		   => 'Sólo se muestran 500 registros. Por favor, exporte para ver todos los registros',
-	'LBL_ADD_RECORD'               => 'Agregar Informe'             ,
+	'LBL_ADD_RECORD'               => 'Agregar Reporte'             ,
 	'LBL_ADD_FOLDER'               => 'Agregar carpeta'             ,
-	'LBL_REPORT_DELETE_DENIED'     => 'No cuenta con los permisos para eliminar este informe',
+	'LBL_REPORT_DELETE_DENIED'     => 'No cuenta con los permisos para eliminar este Reporte',
 	'LBL_FOLDER_CAN_NOT_BE_DELETED' => 'Esta carpeta no puede ser eliminada',
-	'LBL_REPORTS_LIST'             => 'Lista de Informes'           ,
-	'LBL_REPORT_NAME'              => 'Nombre del Informe'          ,
-	'LBL_REPORT_FOLDER'            => 'Carpeta del Informe'         ,
+	'LBL_REPORTS_LIST'             => 'Lista de Reportes'           ,
+	'LBL_REPORT_NAME'              => 'Nombre del Reporte'          ,
+	'LBL_REPORT_FOLDER'            => 'Carpeta del Reporte'         ,
 	'LBL_DESCRIPTION'              => 'Descripción'                ,
 	'PRIMARY_MODULE'               => 'Módulo principal'           ,
 	'LBL_SELECT_RELATED_MODULES'   => 'Seleccionar módulos relacionados',
 	'LBL_MAX'                      => 'MAX'                         ,
 	'LBL_NEXT'                     => 'Siguiente'                   ,
-	'LBL_REPORTS'                  => 'Lista de Informes'           ,
+	'LBL_REPORTS'                  => 'Lista de Reportes'           ,
 	'LBL_GROUP_BY'                 => 'Agrupar por'                 ,
 	'LBL_SORT_ORDER'               => 'Ordenar'                     ,
 	'LBL_ASCENDING'                => 'Ascendente'                  ,
@@ -54,7 +54,7 @@ $languageStrings = array(
 	'LBL_AVERAGE'                  => 'Promedio'                    ,
 	'LBL_LOWEST_VALUE'             => 'El valor más bajo'          ,
 	'LBL_HIGHEST_VALUE'            => 'El valor más alto'          ,
-	'LBL_GENERATE_REPORT'          => 'Guardar y generar Informe'   ,
+	'LBL_GENERATE_REPORT'          => 'Guardar y generar Reporte'   ,
 	'LBL_SUM'                      => 'SUM'                         ,
 	'LBL_AVG'                      => 'PROM'                        ,
 	'LBL_MIN'                      => 'MIN'                         ,
@@ -62,18 +62,23 @@ $languageStrings = array(
 	'LBL_REPORT_CSV'               => 'Exportar a CSV'              ,
 	'LBL_VIEW_DETAILS'             => 'Ver Detalles'                ,
 	'LBL_GENERATE_NOW'             => 'Generar ahora'                ,
-	'Report Name'                  => 'Nombre del Informe'          ,
-	'Account and Contact Reports'  => 'Informes de Cuenta y Contactos',
-	'Lead Reports'                 => 'Informes de Prospectos'      ,
-	'Potential Reports'            => 'Informes de Oportunidades'   ,
-	'Activity Reports'             => 'Informes de Tareas'          ,
-	'HelpDesk Reports'             => 'Informes de Casos'           ,
-	'Product Reports'              => 'Informes de Productos'       ,
-	'Quote Reports'                => 'Informes de Cotizaciones'    ,
-	'PurchaseOrder Reports'        => 'Informes de Órdenes de Compra',
-	'SalesOrder Reports'           => 'Informes de Pedidos de Venta',
-	'Invoice Reports'              => 'Informes de Facturas'        ,
-	'Campaign Reports'             => 'Informes de Campañas'       ,
+	'Report Name'                  => 'Nombre del Reporte'          ,
+	'Account and Contact Reports'  => 'Reportes de Cuenta y Contactos',
+    'Organization and Contact Reports' => 'Reportes de Cuentas y Contactos',
+	'Lead Reports'                 => 'Reportes de Prospectos'      ,
+	'Potential Reports'            => 'Reportes de Oportunidades'   ,
+    'Opportunity Reports' => 'Reportes de Oportunidades',
+	'Activity Reports'             => 'Reportes de Tareas'          ,
+    'Sales Order Reports' => 'Reportes de Pedidos',
+	'HelpDesk Reports'             => 'Reportes de Casos'           ,
+    'Tickets Reports'              => 'Reportes de Casos'           ,
+	'Product Reports'              => 'Reportes de Productos'       ,
+	'Quote Reports'                => 'Reportes de Cotizaciones'    ,
+	'PurchaseOrder Reports'        => 'Reportes de Órdenes de Compra',
+    'Purchase Order Reports'        => 'Reportes de Órdenes de Compra',
+	'SalesOrder Reports'           => 'Reportes de Pedidos de Venta',
+	'Invoice Reports'              => 'Reportes de Facturas'        ,
+	'Campaign Reports'             => 'Reportes de Campañas'       ,
 	'Contacts by Accounts'         => 'Contactos por Cuenta'        ,
 	'Contacts without Accounts'    => 'Contactos sin Cuenta'        ,
 	'Contacts by Potentials'       => 'Contactos por Oportunidades' ,
@@ -81,7 +86,7 @@ $languageStrings = array(
 	'Contacts not related to Accounts' => 'Contactos sin Cuenta'        ,
 	'Contacts related to Potentials' => 'Contactos relacionados con Oportunidades',
 	'Lead by Source'               => 'Prospectos por Origen'       ,
-	'Lead Status Report'           => 'Informe de estado de los Prospectos',
+	'Lead Status Report'           => 'Reporte de estado de los Prospectos',
 	'Potential Pipeline'           => 'Gráfica de Oportunidades'   ,
 	'Closed Potentials'            => 'Oportunidades Cerradas'      ,
 	'Potential that have Won'      => 'Oportunidades Exitosas'      ,
@@ -92,38 +97,38 @@ $languageStrings = array(
 	'Tickets that are Open'        => 'Casos que están abiertos'   ,
 	'Product Details'              => 'Detalles de Productos'       ,
 	'Products by Contacts'         => 'Productos por Contacto'      ,
-	'Product Detailed Report'      => 'Informe detallado de Productos',
+	'Product Detailed Report'      => 'Reporte detallado de Productos',
 	'Products related to Contacts' => 'Productos relacionados con Contactos',
 	'Open Quotes'                  => 'Cotizaciones pendientes'     ,
-	'Quotes Detailed Report'       => 'Informe detallado de Cotizaciones',
+	'Quotes Detailed Report'       => 'Reporte detallado de Cotizaciones',
 	'Quotes that are Open'         => 'Cotizaciones pendientes'     ,
 	'PurchaseOrder by Contacts'    => 'Órdenes de Compra por Contactos',
-	'PurchaseOrder Detailed Report' => 'Informe detallado de Órdenes de Compra',
+	'PurchaseOrder Detailed Report' => 'Reporte detallado de Órdenes de Compra',
 	'PurchaseOrder related to Contacts' => 'Órdenes de Compra relacionadas con Contactos',
-	'Invoice Detailed Report'      => 'Informe detallado de Facturas ',
+	'Invoice Detailed Report'      => 'Reporte detallado de Facturas ',
 	'Last Month Activities'        => 'Tareas del mes pasado'       ,
 	'This Month Activities'        => 'Tareas de este mes'          ,
 	'Campaign Expectations and Actuals' => 'Expectativa y realidad de campaña',
-	'SalesOrder Detailed Report'   => 'Informe detallado de Pedidos',
-	'Email Reports'                => 'Informe de Correos'          ,
-	'Contacts Email Report'        => 'Informe de correos de Contactos',
-	'Accounts Email Report'        => 'Informe de correos de Cuentas',
-	'Leads Email Report'           => 'Informe de correos de Prospectos',
-	'Vendors Email Report'         => 'Informe de correos de Proveedores',
+	'SalesOrder Detailed Report'   => 'Reporte detallado de Pedidos',
+	'Email Reports'                => 'Reporte de Correos'          ,
+	'Contacts Email Report'        => 'Reporte de correos de Contactos',
+	'Accounts Email Report'        => 'Reporte de correos de Cuentas',
+	'Leads Email Report'           => 'Reporte de correos de Prospectos',
+	'Vendors Email Report'         => 'Reporte de correos de Proveedores',
 	'Emails sent to Contacts'      => 'Correos enviados a Contactos',
 	'Emails sent to Organizations' => 'Correos enviados a Cuentas'  ,
 	'Emails sent to Leads'         => 'Correos enviados a Prospectos',
 	'Emails sent to Vendors'       => 'Correos enviados a Proveedores',
-	'LBL_PRINT_REPORT'             => 'Imprimir Informe'                ,
+	'LBL_PRINT_REPORT'             => 'Imprimir Reporte'                ,
 	'LBL_RECORDS'                  => 'Registros'                     ,
 	'LBL_LIMIT_EXCEEDED'           => 'Solo se muestran 1000 + registros. Utilice CSV o Excel Export para ver todos los registros',
 	'LBL_TOP'                      => 'Top'                         , 
-	'LBL_ALL_REPORTS'              => 'Todos los Informes'                 , 
+	'LBL_ALL_REPORTS'              => 'Todos los Reportes'                 , 
 	'LBL_CALCULATION_CONVERSION_MESSAGE' => 'El cálculo se basa en la moneda establecida en Mis Preferencias de su CRM',
     //Scedule Reports
-    'LBL_CREATING_REPORT'	=>	'Creando Informe',
-	'LBL_EDITING_REPORT'	=>	'Editando Informe',
-	'LBL_SCHEDULE_REPORTS'	=>	'Programar Informe',
+    'LBL_CREATING_REPORT'	=>	'Creando Reporte',
+	'LBL_EDITING_REPORT'	=>	'Editando Reporte',
+	'LBL_SCHEDULE_REPORTS'	=>	'Programar Reporte',
 	'LBL_AT_TIME'	=>	'A la hora',
 	'LBL_DAILY'	=>	'Diario',
 	'LBL_WEEKLY'	=>	'Semanal',
@@ -136,13 +141,13 @@ $languageStrings = array(
 	'LBL_SELECTED_DATES'	=>	'Fechas seleccionadas',
 	'LBL_EXCEEDING_MAXIMUM_LIMIT'	=>	'Superando el límite máximo',
 	'LBL_NEXT_TRIGGER_TIME'	=>	'Tiempo de activación siguiente',
-	'LBL_RUN_REPORT'	=>	'Ejecutar informe',
+	'LBL_RUN_REPORT'	=>	'Ejecutar Reporte',
 	'LBL_SELECT_RECIEPIENTS'	=>	'Seleccionar destinatarios',
 	'LBL_SPECIFIC_EMAIL_ADDRESS'	=>	'Enviar al correo electrónico específico',
 
     //Summary/Pivot Reports
-    'LBL_CREATING_PIVOT_REPORT' => 'Creando informe dinámico',
-    'LBL_EDITING_PIVOT_REPORT' => 'Editando informe dinámico',
+    'LBL_CREATING_PIVOT_REPORT' => 'Creando Reporte dinámico',
+    'LBL_EDITING_PIVOT_REPORT' => 'Editando Reporte dinámico',
     'LBL_SELECT_PIVOT_FIELDS' => 'Seleccione los campos dinámicos',
     'LBL_SELECT_ROWS' => 'Seleccione las filas',
     'LBL_SELECT_DATA_FIELDS' => 'Seleccione los campos de datos',
@@ -154,7 +159,7 @@ $languageStrings = array(
     'LBL_SELECT_PIVOT_FIELDS_WARNING' => 'Advertencia: Por favor, seleccione al menos un campo de fila, un campo columna y un campo de datos',
     'LBL_PIVOT_DATA_FIELDS_WARNING' => 'Advertencia: En la columna de datos las funciones de agregación (suma, promedio, mínimo y máximo) no se deben repetir.',
     'LBL_MODIFY_CONDITIONS' => 'Modificar condiciones',
-    'LBL_PIVOT_PREVIEW_EX' => 'Vista previa del informe dinámico (Ejemplo)',
+    'LBL_PIVOT_PREVIEW_EX' => 'Vista previa del Reporte dinámico (Ejemplo)',
 
 	//charts labels
 	'LBL_SELECT_CHART_TYPE' => 'Seleccionar tipo de gráfico',
@@ -177,20 +182,20 @@ $languageStrings = array(
 	'LBL_MODIFY_CONDITION' => 'Modificar condiciones',
 	'LBL_PLEASE_SELECT_ATLEAST_ONE_GROUP_FIELD_AND_DATA_FIELD' => 'Por favor, seleccione al menos un grupo de campos y un campo de datos',
 	'LBL_FOR_BAR_GRAPH_AND_LINE_GRAPH_SELECT_3_MAX_DATA_FIELDS' => 'Para la gráfica de barras y de líneas, puede seleccionar un máximo de 3 campos de datos',
-	'LBL_DETAIL_REPORT' =>	'Informe detallado',
+	'LBL_DETAIL_REPORT' =>	'Reporte detallado',
 	'LBL_PIVOT_REPORT' =>	'Reporte dinámico',
 	'LBL_CHARTS' => 'Gráficas',
     //Schedule Reports - Mail Content
-    'LBL_AUTO_GENERATED_REPORT_EMAIL' => 'Este es un mensaje generado automáticamente enviado en nombre de un informe programado',
+    'LBL_AUTO_GENERATED_REPORT_EMAIL' => 'Este es un mensaje generado automáticamente enviado en nombre de un Reporte programado',
     'LBL_PIN_CHART_TO_DASHBOARD' => 'Anclar la gráfica en el tablero',
     'LBL_FILE_FORMAT' => 'Formato de archivo',
     
-    'Report Type' => 'Tipo de informe',
+    'Report Type' => 'Tipo de Reporte',
     'tabular' => 'Detalle',
     'summary' => 'Detalle',
     'pivot' => 'Dinámico',
     'chart' => 'Gráfica',
-    'LBL_REPORTS_MOVED_SUCCESSFULLY'=>'Informes movidos exitosamente.',
+    'LBL_REPORTS_MOVED_SUCCESSFULLY'=>'Reportes movidos exitosamente.',
     'LBL_SAME_SOURCE_AND_TARGET_FOLDER'=>'La carpeta de destino es igual que la carpeta de origen',
 	'LBL_SEARCH_FOR_FOLDERS' => 'Buscar carpetas',
 	'LBL_CHART_REPORT' => 'Reporte de gráficas',
@@ -198,26 +203,26 @@ $languageStrings = array(
 
   'LBL_SAME_LEVEL_ROLES' => 'Mismo nivel de funciones',
   'LBL_SUBORDINATE_ROLES' => 'Funciones subordinadas',
-  'LBL_SHARE_REPORT' => 'Informe de acciones',
-  'LBL_SHARED_REPORTS' => 'Informes compartidos',
+  'LBL_SHARE_REPORT' => 'Compartir Reporte con',
+  'LBL_SHARED_REPORTS' => 'Reportes compartidos',
   'LBL_PINNED' => 'Anclada',
   'LBL_UNPINNED' => 'Desanclada',
 
 
-  'LBL_REPORTS_DELETED_SUCCESSFULLY' => 'Informes eliminados sorrectamente',
+  'LBL_REPORTS_DELETED_SUCCESSFULLY' => 'Reportes eliminados sorrectamente',
 
 );
 $jsLanguageStrings = array(
-	'JS_DUPLICATE_RECORD'          => 'Duplicar reporte'            , 
-	'JS_CALCULATION_LINE_ITEM_FIELDS_SELECTION_LIMITATION' => 'Limitación: Los campos de artículos de línea (precio de lista, descuento & cantidad) solo pueden usarse cuando otros campos de cálculo no están seleccionados',
-    'JS_CHART_PINNED_TO_DASHBOARD' => 'Gráfica anclada en el tablero',
-    'JS_CHART_ALREADY_PINNED_TO_DASHBOARD' => 'La gráfica ya está anclada en el tablero',
-	'JS_MOVE_REPORTS'=>'Mover Informes',
+	'JS_DUPLICATE_RECORD'          => 'Duplicar Reporte'            , 
+	'JS_CALCULATION_LINE_ITEM_FIELDS_SELECTION_LIMITATION' => 'Limitación: Los campos de partidas (precio de lista, descuento & cantidad) solo pueden usarse cuando otros campos de cálculo no están seleccionados',
+    'JS_CHART_PINNED_TO_DASHBOARD' => 'Gráfica agregada al tablero',
+    'JS_CHART_ALREADY_PINNED_TO_DASHBOARD' => 'La gráfica ya está agregada en el tablero',
+	'JS_MOVE_REPORTS' => 'Mover Reportes',
     'JS_SCHEDULED_DATE_TIME_ERROR' => 'La fecha y hora programada deben ser mayores que la fecha y hora actuales',
-	'JSLBL_PIN_CHART_TO_DASHBOARD' => 'Anclar la gráfica en el tablero',
-	'JSLBL_UNPIN_CHART_FROM_DASHBOARD' => 'Desanclar la gráfica del tablero',
+	'JSLBL_PIN_CHART_TO_DASHBOARD' => 'Agregar la gráfica al tablero',
+	'JSLBL_UNPIN_CHART_FROM_DASHBOARD' => 'Retirar la gráfica del tablero',
 	'JS_CHART_REMOVED_FROM_DASHBOARD' => 'Gráfica retirada del tablero',
 
-  'JS_NO_CHART_DATA_AVAILABLE' => 'No se dispone de datos, por favor revise los campos seleccionados',
+    'JS_NO_CHART_DATA_AVAILABLE' => 'No se dispone de datos, por favor revise los campos seleccionados',
 
 );
\ No newline at end of file
diff --git a/pkg/vtiger/translations/MexicanSpanishLanguagePack_es_mx/modules/Vtiger.php b/pkg/vtiger/translations/MexicanSpanishLanguagePack_es_mx/modules/Vtiger.php
index 9081820013f05f29ff5d6f5352640aa49b8d9832..d1b33bdf609e6d7b470771b01cbd279bfb20763d 100644
--- a/pkg/vtiger/translations/MexicanSpanishLanguagePack_es_mx/modules/Vtiger.php
+++ b/pkg/vtiger/translations/MexicanSpanishLanguagePack_es_mx/modules/Vtiger.php
@@ -211,7 +211,7 @@ $languageStrings = array(
 	'LBL_SEARCH_RESULTS'           => 'Buscar resultados'           ,
 	'LBL_SAVE_AS_FILTER'           => 'Guardar como lista'          ,
 	'LBL_NOT_ACCESSIBLE'           => 'No accesible'                ,
-	'LBL_ITEM_DETAILS'             => 'Detalles del elemento'       ,
+	'LBL_ITEM_DETAILS'             => 'Partidas'       ,
 	'LBL_CURRENCY'                 => 'Moneda'                      ,
 	'LBL_TAX_MODE'                 => 'Tipo de impuestos'           ,
 	'LBL_INDIVIDUAL'               => 'Individual'                  ,
@@ -491,13 +491,13 @@ $languageStrings = array(
 	'In Progress'                  => 'En progreso'                 ,
 	'Subject'                      => 'Asunto'                      ,
 	'Terms & Conditions'           => 'Términos y condiciones'     ,
-	'Item Name'                    => 'Nombre del elemento'             ,
+	'Item Name'                    => 'Nombre del artículo'             ,
 	'Quantity'                     => 'Cantidad'                    ,
 	'List Price'                   => 'Precio de venta'				,
 	'Image'						   => 'Imagen'						,
 	'Purchase Cost'				   => 'Costo de compra'				,
 	'Margin'					   => 'Margen'						,
-	'Item Comment'                 => 'Comentario al elemento'      ,
+	'Item Comment'                 => 'Comentario del artículo'      ,
 	'Tax1'                         => 'Impuesto1'                   ,
 	'Tax2'                         => 'Impuesto2'                   ,
 	'Tax3'                         => 'Impuesto3'                   ,
@@ -788,8 +788,9 @@ $languageStrings = array(
     'Workflows' => 'Flujos de trabajo',
     'Primary Twitter' => 'Twitter principal',
 
-	'Engagement Score'             => 'Tasa de interacción'      ,
-	'Click Count'                  => 'Contador de clics'             ,
+	'Engagement Score'             => 'Tasa de interacción',
+	'Click Count'                  => 'Contador de clics',
+    'Access Count' => 'Contador de accesos',
 	// Extensions
     'LBL_SYNC_LOG' => 'Registro de sincronización',
 	'LBL_SYNC_SETTINGS' => 'Configuración de sincronización',
@@ -865,7 +866,7 @@ $languageStrings = array(
   'LBL_IS_REMOVED' => 'se elimina',
   'LBL_REASON_FOR_CHANGING_COMMENT' => 'Razón para cambiar el comentario',
   'LBL_APPLBL_NONEROVE' => 'Aprobar',
-  'LBL_ITEM' => 'Elemento',
+  'LBL_ITEM' => 'Artículo',
   'Add Note' => 'Agregar documento',
   'LBL_form' => 'de',
   'LBL_to' => 'a',
@@ -1076,8 +1077,7 @@ fuera de Vtiger.',
   'LBL_HOUR(S)' => 'hora(s)',
   'LBL_SLA_INFORMATION' => 'Información SLA',
   'LBL_TO_USE_SWITCH_TO_NEW_LOOK' => 'Para utilizar <b>%s</b>, le recomendamos cambiar al nuevo aspecto visual.',
-	'LBL_DELETE_USER_CONFIRMATION' => 'Cuando se elimina un usuario, el usuario será marcado como "inactivo" y no se le podrán asignar nuevos registros ni tampoco podrá iniciar sesión. ¿Estás seguro que quieres borrarlo?',
-
+    
 	'LBL_DUPLICATES' => 'duplicados',
 	'LBL_DUPLICATES_DETECTED' => 'Duplicado(s) detectado(s)',
 	'LBL_DUPLICATES_FOUND_MESSAGE' => 'Esto%s no se pueden guardar ya que existe o existen duplicado%s en VTiger con los mismos valores para %s.',
@@ -1110,9 +1110,11 @@ $jsLanguageStrings = array(
 	'OVERWRITE_EXISTING_MSG2'      => 'Detalles de la dirección'   , 
 	'SINGLE_Accounts'              => 'Cuenta'                      ,
 	'SINGLE_Contacts'              => 'Contacto'                    , 
-	'LBL_DELETE_CONFIRMATION'      => '¿Seguro que lo quiere borrar?', 
-	'LBL_MASS_DELETE_CONFIRMATION' => '¿Seguro que quiere borrar los siguientes registros?', 
-	'JS_LBL_SAVE'                  => 'Guardar'                     , 
+	'LBL_DELETE_CONFIRMATION'      => '¿Estás seguro que lo quieres borrar?', 
+	'LBL_MASS_DELETE_CONFIRMATION' => '¿Estás seguro que quieres borrar los registros seleccionados?', 
+    'LBL_DELETE_USER_CONFIRMATION' => 'Cuando se elimina un usuario, el usuario será marcado como "inactivo" y no se le podrán asignar nuevos registros ni tampoco podrá iniciar sesión. ¿Estás seguro que quieres borrarlo?',
+    'LBL_UNLINK_CONFIRMATION' => '¿Estás seguro que quieres desvincluar?',
+    'JS_LBL_SAVE'                  => 'Guardar'                     , 
 	'JS_LBL_CANCEL'                => 'Cancelar'                    , 
 	'SHOULD_BE_LESS_THAN_TODAY'    => 'Debe suceder antes de hoy'   , 
 	'JS_PLEASE_SELECT_ATLEAST_ONE_OPTION' => 'Seleccione al menos una opción', 
@@ -1298,7 +1300,7 @@ $jsLanguageStrings = array(
     'JS_INVALID_EMAILS' => 'Los correos electrónicos no válidos',
     'JS_INTERNAL_COMMENT' => 'Comentario interno',
     'JS_INTERNAL_COMMENT_INFO' => 'El comentario sólo será visto por los usuarios de CRM si la casilla de verificación comentario interno está activada. Para notificar a los clientes (a través de flujos de trabajo configurables o del portal de clientes) deje esta casilla deshabilitada',
-    'JS_NO_LINE_ITEM' =>'Los artículos de línea no pueden estar vacíos.',
+    'JS_NO_LINE_ITEM' =>'Los artículos no pueden estar vacíos.',
 
 	//More currencies message
 	'JS_BASE_CURRENCY_CHANGED_TO_DISABLE_CURRENCY' => 'La moneda base tiene que cambiarse para desactivar ',
diff --git a/schema/DatabaseSchema.xml b/schema/DatabaseSchema.xml
index bc7399e40bbc004148d11b1b665473ff63de33c0..7d0b001407ed5e9efc2e52aefca5d167e148b14b 100644
--- a/schema/DatabaseSchema.xml
+++ b/schema/DatabaseSchema.xml
@@ -101,7 +101,7 @@
 		<field name="currency_decimal_separator" type="C" size="2" />
 		<field name="currency_grouping_separator" type="C" size="2" />
 		<field name="currency_symbol_placement" type="C" size="20" />
-
+                <field name="userlabel" type="C" size="255" />
 		<index name="user_user_name_idx">
 			<col>user_name</col>
 		</index>
diff --git a/vtigerversion.php b/vtigerversion.php
index 7a7ade6383272ef11256d683a03c6f8f0c031b03..83a0f13b2d1a2031527763983cd6e0b2be9d2de6 100644
--- a/vtigerversion.php
+++ b/vtigerversion.php
@@ -8,9 +8,9 @@
  * All Rights Reserved.
  ************************************************************************************/
 
-$patch_version = '20201013'; // -ve timestamp before release, +ve timestamp after release.
+$patch_version = '-20201019'; // -ve timestamp before release, +ve timestamp after release.
 $modified_database = '';
-$vtiger_current_version = '7.3.0';
+$vtiger_current_version = '7.4.0';
 $_SESSION['vtiger_version'] = $vtiger_current_version;
 
 ?>
diff --git a/vtlib/Vtiger/Deprecated.php b/vtlib/Vtiger/Deprecated.php
index 7a5288679a7f44f0d6ea6841a1b72423e20746a9..a23a02a49264d560d6463a3ed1bdcad09cc63cb6 100644
--- a/vtlib/Vtiger/Deprecated.php
+++ b/vtlib/Vtiger/Deprecated.php
@@ -544,6 +544,23 @@ class Vtiger_Deprecated {
 	}
 
 	static function getSqlForNameInDisplayFormat($input, $module, $glue = ' ') {
+		if ($module == 'Users') {
+			if (is_string($input)) {
+				$input = array($input);
+			}
+
+			$tableName = '';
+			foreach ($input as $fieldTableColumn) {
+				if ($fieldTableColumn) {
+					list($tableName, $columnName) = explode('.', $fieldTableColumn);
+					break;
+				}
+			}
+			if ($tableName) {
+				return "$tableName.userlabel";
+			}
+		}
+
 		$entity_field_info = Vtiger_Functions::getEntityModuleInfoFieldsFormatted($module);
 		$fieldsName = $entity_field_info['fieldname'];
 		if(is_array($fieldsName)) {