diff --git a/~dev_rating/application/bootstrap.php b/~dev_rating/application/bootstrap.php
index 0a418c9803b39e7e77290aa5046d623d98f1d2c5..1f913902e38389f2c2d1c91a47f98dd51ee79aca 100644
--- a/~dev_rating/application/bootstrap.php
+++ b/~dev_rating/application/bootstrap.php
@@ -135,6 +135,7 @@ Kohana::modules(array(
          'kotwig'     => MODPATH.'kotwig', // Twig template engine
          'mpdf'     => MODPATH.'mpdf', // HTML->PDF converter
          'phpexcel' => MODPATH.'phpexcel', // HTML->MS Excel 2007 converter
+         'mailer' => MODPATH.'mail',
 		// 'codebench'  => MODPATH.'codebench',  // Benchmarking tool
 	 	'database'   => MODPATH.'database',   // Database access
 	));
diff --git a/~dev_rating/application/views/email/recovery.twig b/~dev_rating/application/views/email/recovery.twig
index 7985f29f9c5b3c69f2b52ed5503e8fd34993b9e9..1e07a4485c2136da6559d60c00b3c10e8504d5dd 100644
--- a/~dev_rating/application/views/email/recovery.twig
+++ b/~dev_rating/application/views/email/recovery.twig
@@ -1,19 +1,9 @@
-<html>
-<head>
-  <title>{{ Subject }}</title>
-</head>
-<body>
-  <h1>Здравствуйте!</h1>
-  <p>
-      Вы получили это письмо, потому что кто-то попытался запустить процедуру смены пароля от Вашего аккаунта. 
-      Если это были Вы, то для завершения процедуры смены пароля пройдите по ссылке, указаной ниже:
-  </p>
-  <br>
-  <a href="{{ curl }}remind/{{ Token }}">{{ curl }}remind/{{ Token }}</a>
-  <br>
-  <p>
-      Данная ссылка работоспособна в течение одного часа. 
-      Если Вы не пытались восстановить доступ к аккаунту, то просто проигнорируйте это письмо. Спасибо!
-  </p>
-</body>
-</html>
\ No newline at end of file
+Здравствуйте!
+
+Вы получили это письмо, потому что кто-то попытался запустить процедуру смены пароля от Вашего аккаунта.
+Если это были Вы, то для завершения процедуры смены пароля перейдите по этой ссылке:
+
+{{ curl }}remind/{{ Token }}
+
+Ваша ссылка для восстановления будет работоспособна в течение одного часа.
+Если Вы не пытались восстановить доступ к аккаунту, то просто проигнорируйте это письмо. Спасибо!
\ No newline at end of file
diff --git a/~dev_rating/modules/account/classes/Kohana/Account.php b/~dev_rating/modules/account/classes/Kohana/Account.php
index 5667090c7f4a4141a6dc99df04ea7dbbca9dd19f..5635b0a3043cf0119bafb8a075b1ef3741e5e3ff 100644
--- a/~dev_rating/modules/account/classes/Kohana/Account.php
+++ b/~dev_rating/modules/account/classes/Kohana/Account.php
@@ -153,13 +153,14 @@ class Kohana_Account {
             $twig->Token = $requestToken;
             $twig->EMail = $email;
             $twig->Subject = $subject;
-            
-            $message = $twig->render();
-            $headers = 'MIME-Version: 1.0' . "\r\n";
-            $headers .= 'Content-type: text/html; charset=utf-8' . "\r\n";
-            $headers .=  "From: RatingSystem@no-reply.mmcs.sfedu.ru\r\n";
-            $headers .= "Reply-To: ".$email;
-            mail($email, $subject, $message, $headers);
+
+            Mailer::factory()
+                ->subject($subject)
+                ->in_reply_to(Mailer::message_id())
+                ->from('no-reply@rating.mmcs.sfedu.ru')
+                ->headers('Content-Type', 'text/plain')
+                ->body($twig->render())
+                ->send($email);
         }
     }
     
diff --git a/~dev_rating/modules/mail/.gitignore b/~dev_rating/modules/mail/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..2c4290fe7630c29e3d88b781c05c0768d5c2894a
--- /dev/null
+++ b/~dev_rating/modules/mail/.gitignore
@@ -0,0 +1,2 @@
+*~
+*.orig
diff --git a/~dev_rating/modules/mail/classes/Kohana/Mail/Sender.php b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender.php
new file mode 100644
index 0000000000000000000000000000000000000000..a4dfc0b7d491bd1cb14e699b74ba18b98c1ccad9
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender.php
@@ -0,0 +1,394 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+/**
+ * Abstract mail sender.
+ *
+ * @package   Mail
+ * @category  Senders
+ * @author    Guillaume Poirier-Morency <guillaumepoiriermorency@gmail.com>
+ * @copyright (c) 2013, HГЁte.ca Inc.
+ * @license   BSD-3-Clauses
+ */
+abstract class Kohana_Mail_Sender {
+
+	/**
+	 * Return an instance of the specified sender.
+	 *
+	 * @param  string $name    name of the Mail_Sender object to instanciate.
+	 * @param  array  $headers initial headers
+	 * @param  array  $options options for the Mail_Sender object.
+	 * @return Mail_Sender
+	 */
+	public static function factory($name, array $headers, array $options)
+	{
+		$class = "Mail_Sender_$name";
+
+		return new $class($headers, $options);
+	}
+
+	/**
+	 *
+	 * @var array
+	 */
+	protected $to;
+
+	/**
+	 *
+	 * @var array
+	 */
+	protected $headers = array();
+
+	/**
+	 *
+	 * @var string
+	 */
+	protected $body;
+
+	/**
+	 *
+	 * @var array
+	 */
+	protected $attachments = array();
+
+	/**
+	 *
+	 * @var array
+	 */
+	protected $params = array();
+
+	/**
+	 *
+	 * @var array
+	 */
+	protected $options = array();
+
+	/**
+	 * Initialize a Sender with options.
+	 *
+	 * @param array $options options for the Mail_Sender object.
+	 */
+	public function __construct(array $headers, array $options)
+	{
+		$this->headers = $headers;
+		$this->options = $options;
+	}
+
+	/**
+	 * Getter-setter for mail headers.
+	 *
+	 * If you assign $value with an array, it will be parsed as a recipient
+	 * list.
+	 *
+	 * @param  string  $key
+	 * @param  variant $value
+	 * @return variant
+	 */
+	public function headers($key = NULL, $value = NULL)
+	{
+		if (is_array($key))
+		{
+			$this->headers = $key;
+
+			return $this;
+		}
+
+		if ($key === NULL)
+		{
+			return $this->headers;
+		}
+
+		if ($value === NULL)
+		{
+			return Arr::get($this->headers, $key);
+		}
+
+		$this->headers[$key] = (string) $value;
+
+		return $this;
+	}
+
+	/**
+	 * Set the Content-Type header of this mail.
+	 *
+	 * Use text/html for HTML email.
+	 * Use text/plain for plain email.
+	 *
+	 * You may also specify a custom charset using the charset parameter like
+	 *
+	 * text/html; charset=utf-8
+	 *
+	 * @param string $content_type
+	 * @return \Mail_Sender
+	 */
+	public function content_type($content_type = NULL)
+	{
+		return $this->headers('Content-Type', $content_type);
+	}
+
+	/**
+	 *
+	 * @param string $sender
+	 * @return \Mail_Sender
+	 */
+	public function sender($sender = NULL)
+	{
+		return $this->headers('Sender', $sender);
+	}
+
+	/**
+	 *
+	 * @param  string $cc
+	 * @return \Mail_Sender
+	 */
+	public function cc($cc = NULL)
+	{
+		return $this->headers('Cc', $cc);
+	}
+
+	/**
+	 *
+	 * @param  string $bcc
+	 * @return \Mail_Sender
+	 */
+	public function bcc($bcc = NULL)
+	{
+		return $this->headers('Bcc', $bcc);
+	}
+
+	/**
+	 *
+	 * @param  string $from
+	 * @return \Mail_Sender
+	 */
+	public function from($from = NULL)
+	{
+		return $this->headers('From', $from);
+	}
+
+	/**
+	 *
+	 * @param  string $resent_from
+	 * @return \Mail_Sender
+	 */
+	public function resent_from($resent_from = NULL)
+	{
+		return $this->headers('Resent-From', $resent_from);
+	}
+
+	/**
+	 *
+	 * @param  string $resent_to
+	 * @return \Mail_Sender
+	 */
+	public function resent_to($resent_to = NULL)
+	{
+		return $this->headers('Resent-To', $resent_to);
+	}
+
+	/**
+	 *
+	 * @param  string $subject
+	 * @return \Mail_Sender
+	 */
+	public function subject($subject = NULL)
+	{
+		return $this->headers('Subject', $subject);
+	}
+
+	/**
+	 *
+	 * @param  string $resent_subject
+	 * @return \Mail_Sender
+	 */
+	public function resent_subject($resent_subject = NULL)
+	{
+		return $this->headers('Resent-Subject', $resent_subject);
+	}
+
+	/**
+	 *
+	 * @param  string $return_path
+	 * @return \Mail_Sender
+	 */
+	public function return_path($return_path = NULL)
+	{
+		return $this->headers('Return-Path', $return_path);
+	}
+
+	/**
+	 *
+	 * @param  string $reply_to
+	 * @return \Mail_Sender
+	 */
+	public function reply_to($reply_to = NULL)
+	{
+		return $this->headers('Reply-To', $reply_to);
+	}
+
+	/**
+	 *
+	 * @param  string $mail_reply_to
+	 * @return \Mail_Sender
+	 */
+	public function mail_reply_to($mail_reply_to = NULL)
+	{
+		return $this->headers('Mail-Reply-To', $mail_reply_to);
+	}
+
+	/**
+	 *
+	 * @param  string $mail_followup_to
+	 * @return \Mail_Sender
+	 */
+	public function mail_followup_to($mail_followup_to = NULL)
+	{
+		return $this->headers('Mail-Followup-To', $mail_followup_to);
+	}
+
+	/**
+	 *
+	 * @param  string $message_id
+	 * @return \Mail_Sender
+	 */
+	public function message_id($message_id = NULL)
+	{
+		return $this->headers('Message-ID', $message_id);
+	}
+
+	/**
+	 *
+	 * @param  string $in_reply_to
+	 * @return \Mail_Sender
+	 */
+	public function in_reply_to($in_reply_to = NULL)
+	{
+		return $this->headers('In-Reply-To', $in_reply_to);
+	}
+
+	/**
+	 *
+	 * @param  string $references
+	 * @return \Mail_Sender
+	 */
+	public function references($references = NULL)
+	{
+		return $this->headers('References', $references);
+	}
+
+	/**
+	 * Get or set the body of the mail.
+	 *
+	 * The body is immediatly evaluated.
+	 *
+	 * If you are assigning an HTML body, specify Content-Type to text/html in
+	 * headers.
+	 *
+	 * @param variant $body
+	 * @return string the body of the mail
+	 */
+	public function body($body = NULL)
+	{
+		if ($body === NULL)
+		{
+			return $this->body;
+		}
+
+		$this->body = (string) $body;
+
+		return $this;
+	}
+
+	/**
+	 * Append an attachment to this mail.
+	 *
+	 * You should set at least the Content-Type header.
+	 *
+	 * @param string $attachment the raw content of the attachment
+	 * @param array  $headers    headers for this attachment.
+	 */
+	public function attachment($attachment, array $headers = array())
+	{
+		$this->attachments[] = array(
+			'attachment' => $attachment,
+			'headers' => $headers
+		);
+
+		return $this;
+	}
+
+	/**
+	 * Bind a substitution parameter to this mail sender.
+	 *
+	 * Mail headers values (including subject) and body will be substituted.
+	 *
+	 * @param  string  $name
+	 * @param  variant $value
+	 * @return \Mail_Sender
+	 */
+	public function param($name, $value)
+	{
+		$this->params[$name] = (string) $value;
+
+		return $this;
+	}
+
+	/**
+	 * Last error message.
+	 */
+	public abstract function error();
+
+	/**
+	 * Send an email to its receivers.
+	 *
+	 * When fetching an ORM, it is somewhat useful to do
+	 *
+	 *     $users = $model->as_array('email', 'username');
+	 *
+	 * To send heavy mail, you may use register_shutdown_function so that your
+	 * mail gets sent after the user has received his mail.
+	 *
+	 * Don't do that for critical mail! You will not be able to access the
+	 * result of the function.
+	 *
+	 *     register_shutdown_function(array($mailer, 'send'), $users);
+	 *
+	 * @param  variant $to an email, list of email or associative array of email to name.
+	 * @return boolean TRUE on success FALSE otherwise.
+	 */
+	public function send($to)
+	{
+		if (Kohana::$profiling)
+		{
+			$benchmark = Profiler::start('Mailer', $this->subject());
+		}
+
+		// Check if the receiver is a traversable structure
+		$this->to = Arr::is_array($to) ? $to : array($to);
+
+		// substitute headers
+		foreach ($this->headers as $name => $header)
+		{
+			$this->headers[$name] = strtr($header, $this->params);
+		}
+
+		// substitute body values
+		$this->body = strtr($this->body, $this->params);
+
+		$status = (bool) $this->_send($to);
+
+		if (isset($benchmark))
+		{
+			Profiler::stop($benchmark);
+		}
+
+		return $status;
+	}
+
+	/**
+	 * Implemented by the sender.
+	 *
+	 * @param  string $to list of valid RFC emails.
+	 * @return boolean return code of the sender.
+	 */
+	protected abstract function _send();
+}
diff --git a/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/Mail.php b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/Mail.php
new file mode 100644
index 0000000000000000000000000000000000000000..8fa7a79c87f1506926f569cb7a3a7eb690c85352
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/Mail.php
@@ -0,0 +1,148 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+/**
+ * Driver for built-in mail() PHP function.
+ *
+ * @uses mail
+ *
+ * @package   Mail
+ * @category  Senders
+ * @author    HГЁte.ca Team
+ * @copyright (c) 2013, HГЁte.ca Inc.
+ * @license   BSD-3-Clauses
+ */
+class Kohana_Mail_Sender_Mail extends Mail_Sender {
+
+	/**
+	 * Encode a mime header.
+	 *
+	 * @param  string $header   header value
+	 * @reutrn string
+	 */
+	public static function header_encode($name, $header)
+	{
+		// restrict encoding to specific headers
+		if ( ! in_array($name, array('Subject', 'To', 'Reply-To', 'From', 'Cc', 'Bcc')))
+		{
+			return $header;
+		}
+
+		if (Arr::is_array($header))
+		{
+			$recipients = array();
+
+			foreach ($header as $key => $value)
+			{
+				if (is_string($key) AND Valid::email($key))
+				{
+					// $key is an email, so $value is a name
+					$recipients[] = static::header_encode($name, $value).' <'.$key.'>';
+				}
+				else
+				{
+					// $key is a numeric index, $value is an email
+					$recipients[] = static::header_encode($name, $value);
+				}
+			}
+
+			return join(', ', $recipients);
+		}
+
+		if (function_exists('mb_encode_mimeheader'))
+		{
+			return mb_encode_mimeheader($header, Kohana::$charset);
+		}
+
+		// strip non-ascii
+		return UTF8::strip_non_ascii($header);
+	}
+
+	/**
+	 * Mail sender does not provide any relevant error information.
+     *
+	 * We can at least tell if the $body is empty.
+	 */
+	public function error()
+	{
+		if (empty($this->body))
+		{
+			return 'Message body is empty';
+		}
+
+		return NULL;
+	}
+
+	protected function _send()
+	{
+		$headers = $this->headers;
+
+        $body = $this->body;
+
+		$attachments = $this->attachments;
+
+		$boundary = sha1(uniqid(NULL, TRUE));
+
+		if ($this->attachments)
+		{
+			// the body is the first part of the message
+			array_unshift($attachments, array(
+				'attachment' => $body,
+				'headers' => array(
+					'Content-Type' => Arr::get($headers, 'Content-Type', 'text/plain')
+				)
+			));
+
+			$body = 'This is a message with multiple parts in MIME format.'."\r\n";
+			$body .= '--'.$boundary."\r\n";
+
+			// override Content-Type of the message as it is a multipart
+			$headers['Content-Type'] = "multipart/mixed; boundary=$boundary";
+		}
+
+		foreach ($attachments as $index => $attachment)
+		{
+			$attachment['headers']['Content-Transfer-Encoding'] = 'base64';
+
+			foreach ($attachment['headers'] as $name => $header)
+			{
+				$body .= $name.': '.static::header_encode($name, $header)."\r\n";
+			}
+
+			$body .= "\r\n";
+
+			$body .= wordwrap(base64_encode($attachment['attachment']), 78, "\r\n", TRUE)."\r\n";
+
+			$body .= "\r\n";
+
+			$body .= '--'.$boundary.(($index + 1 === count($attachments)) ? '--' : '')."\r\n";
+		}
+
+		$subject = NULL;
+
+		// avoid duplicated Subject header
+		if (array_key_exists('Subject', $headers))
+		{
+			$subject = $headers['Subject'];
+
+			unset($headers['Subject']);
+		}
+
+		$encoded_headers = array();
+
+		foreach ($headers as $name => $header)
+		{
+			$encoded_headers[] = $name.': '.static::header_encode($name, $header);
+		}
+
+		$to = static::header_encode('To', $this->to);
+
+        $body = wordwrap($body, 78, "\r\n");
+
+		$headers = implode("\r\n", $encoded_headers);
+
+		$options = implode(' ', $this->options);
+
+		return mail($to, $subject, $body, $headers, $options) AND ! empty($body);
+	}
+
+}
diff --git a/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/Mock.php b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/Mock.php
new file mode 100644
index 0000000000000000000000000000000000000000..6e44a9be1789c74b744ff3cad88536b6324e6aa9
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/Mock.php
@@ -0,0 +1,64 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+/**
+ * Fake sender for testing application without sending real mails.
+ *
+ * @package  Mail
+ * @category Senders
+ * @author   Guillaume Poirier-Morency <guillaumepoiriermorency@gmail.com>
+ * @license  BSD-3-Clauses
+ */
+class Kohana_Mail_Sender_Mock extends Mail_Sender {
+
+	/**
+	 * Stack of sent mail.
+	 *
+	 * Use array_pop in your tests to ensure specific mail have been sent.
+	 *
+	 * @var array
+	 */
+	public static $history;
+
+	/**
+	 * Expose $to for testing purposes.
+	 */
+	public $to;
+
+	/**
+	 * Expose attachments for testing purposes.
+	 *
+	 * @var array
+	 */
+	public $attachments = array();
+
+	public function error()
+	{
+		if (empty($this->to))
+		{
+			return 'Recipient cannot be empty.';
+		}
+
+		if (empty($this->body))
+		{
+			return 'Body cannot be empty.';
+		}
+
+		return NULL;
+	}
+
+	protected function _send()
+	{
+		// push the mail on the stack
+		static::$history[] = $this;
+
+		// log the mocked mail for debugging
+		Kohana::$log->add(Log::DEBUG, "Mocked mail for :to\n\n:headers\n\n:body", array(
+			':to'      => print_r($this->to, TRUE),
+			':headers' => print_r($this->headers, TRUE),
+			':body'    => $this->body
+		));
+
+		return ! empty($this->to) AND ! empty($this->body);
+	}
+
+}
diff --git a/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PEAR.php b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PEAR.php
new file mode 100644
index 0000000000000000000000000000000000000000..328c95af48bdbef9f551d2cebcdd0483fbce4791
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PEAR.php
@@ -0,0 +1,92 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+require_once 'Mail.php';
+require_once 'Mail/mime.php';
+
+/**
+ * PEAR wrapper for the Mail module.
+ *
+ * PEAR must be included in your PHP path.
+ *
+ * @uses Mail
+ * @uses Mail_mime
+ *
+ * @package  Mail
+ * @category Senders
+ * @author   Guillaume Poirier-Morency <guillaumepoiriermorency@gmail.com>
+ * @license  BSD-3-Clauses
+ */
+abstract class Kohana_Mail_Sender_PEAR extends Mail_Sender {
+
+	/**
+	 *
+	 * @var Mail
+	 */
+	protected $mail;
+
+	/**
+     *
+	 * @var PEAR_Error
+	 */
+	private $error;
+
+	public function __construct(array $headers, array $options)
+	{
+		parent::__construct($headers, $options);
+
+		$this->mail = new Mail;
+	}
+
+	public function error()
+	{
+		return ($this->error instanceof PEAR_Error) ? $this->error->getMessage() : NULL;
+	}
+
+	protected function _send()
+	{
+		$mime = new Mail_mime(array('head_charset' => Kohana::$charset, 'text_charset' => Kohana::$charset, 'html_charset' => Kohana::$charset));
+
+		if ($this->content_type() === 'text/html')
+		{
+			$mime->setHTMLBody($this->body);
+		}
+		else
+		{
+			$mime->setTxtBody($this->body);
+		}
+
+		foreach ($this->attachments as $attachment)
+		{
+			$headers = $attachment['headers'];
+
+			$content_type = Arr::get($headers, 'Content-Type', 'application/octet-stream');
+			$disposition = Arr::get($headers, 'Content-Disposition', 'attachment');
+			$filename = NULL;
+			$description = Arr::get($headers, 'Content-Description');
+			$charset = Kohana::$charset;
+			$language = Arr::get($headers, 'Content-Language');
+			$location = Arr::get($headers, 'Content-Location');
+
+			if (strpos($content_type, '; charset=') !== FALSE)
+			{
+				list ($content_type, $charset) = preg_split('/; charset=/', $content_type);
+			}
+
+			if (strpos($disposition, '; filename=') !== FALSE)
+			{
+				list ($disposition, $filename) = preg_split('/; filename=/', $disposition);
+			}
+
+			$mime->addAttachment($attachment['attachment'], $content_type, $filename, FALSE, 'base64', $disposition, $charset, $language, $location, NULL, NULL, $description, Kohana::$charset);
+		}
+
+		// get must be called before headers
+		$body = $mime->get();
+		$headers = $mime->headers($this->headers);
+
+		$this->error = $this->mail->send($this->to, $headers, $body);
+
+		return $this->error === TRUE AND ! empty($body);
+	}
+
+}
diff --git a/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PEAR/Mail.php b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PEAR/Mail.php
new file mode 100644
index 0000000000000000000000000000000000000000..f863632c16391b003e896bbb266f0ebe75d51795
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PEAR/Mail.php
@@ -0,0 +1,22 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+/**
+ * Sender based on PEAR mail built-in function.
+ *
+ * @uses Mail_mail
+ *
+ * @package  Mail
+ * @category Senders
+ * @author   Guillaume Poirier-Morency <guillaumepoiriermorency@gmail.com>
+ * @license  BSD-3-Clauses
+ */
+class Kohana_Mail_Sender_PEAR_Mail extends Mail_Sender_PEAR {
+
+	public function __construct(array $headers, array $options)
+	{
+		parent::__construct($headers, $options);
+
+		$this->mail->factory('mail', $this->options);
+	}
+
+}
diff --git a/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PEAR/SMTP.php b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PEAR/SMTP.php
new file mode 100644
index 0000000000000000000000000000000000000000..10ee6162f046fea6415dbf961e3051c328165236
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PEAR/SMTP.php
@@ -0,0 +1,27 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+/**
+ * Disable E_STRICT error reporting.
+ */
+error_reporting(error_reporting() & ~ E_STRICT);
+
+/**
+ * Sender based on PEAR SMTP.
+ *
+ * @uses Mail_smtp
+ *
+ * @package  Mail
+ * @category Senders
+ * @author   Guillaume Poirier-Morency <guillaumepoiriermorency@gmail.com>
+ * @license  BSD-3-Clauses
+ */
+class Kohana_Mail_Sender_PEAR_SMTP extends Mail_Sender_PEAR {
+
+	public function __construct(array $headers, array $options)
+	{
+		parent::__construct($headers, $options);
+
+		$this->mail->factory('smtp', $this->options);
+	}
+
+}
diff --git a/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PEAR/Sendmail.php b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PEAR/Sendmail.php
new file mode 100644
index 0000000000000000000000000000000000000000..4608abe22995f9ef026fb14adc0f7f929ba39211
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PEAR/Sendmail.php
@@ -0,0 +1,22 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+/**
+ * Sender based on PEAR Sendmail.
+ *
+ * @uses Mail_sendmail
+ *
+ * @package  Mail
+ * @category Senders
+ * @author   Guillaume Poirier-Morency <guillaumepoiriermorency@gmail.com>
+ * @license  BSD-3-Clauses
+ */
+class Kohana_Mail_Sender_PEAR_Sendmail extends Mail_Sender_PEAR {
+
+	public function __construct(array $headers, array $options)
+	{
+		parent::__construct($headers, $options);
+
+		$this->mail->factory('sendmail', $this->options);
+	}
+
+}
diff --git a/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PHPMailer.php b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PHPMailer.php
new file mode 100644
index 0000000000000000000000000000000000000000..48a67e3a638f3d355cc02ca8e2137de5eb4ce823
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PHPMailer.php
@@ -0,0 +1,84 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+require Kohana::find_file('vendor', 'PHPMailer/PHPMailerAutoload');
+
+/**
+ * PHPMailer-based mail sender.
+ *
+ * @package   Mail
+ * @category  Senders
+ * @author    Guillaume Poirier-Morency <guillaumepoiriermorency@gmail.com>
+ * @copyright (c) 2014, Guillaume Poirier-Morency
+ * @license   BSD-3-Clauses
+ */
+abstract class Kohana_Mail_Sender_PHPMailer extends Mail_Sender {
+
+	/**
+	 *
+	 * @var PHPMailer
+	 */
+	public $mailer;
+
+	public function __construct(array $headers, array $options)
+	{
+		parent::__construct($headers, $options);
+
+		$this->mailer = new PHPMailer;
+
+		foreach ($this->options as $key => $value)
+		{
+			$this->mailer->{$key} = $value;
+		}
+	}
+
+	public function error()
+	{
+		return $this->mailer->ErrorInfo;
+	}
+
+	protected function _send()
+	{
+		foreach ($this->to as $email => $name)
+		{
+			$this->mailer->addAddress(Valid::email($name) ? $name : $email, $name);
+		}
+
+        $this->mailer->From = $this->from();
+		$this->mailer->Subject = $this->subject();
+		$this->mailer->Body = $this->body;
+		$this->mailer->isHTML(strpos('text/html', $this->headers('Content-Type')) === 0);
+
+		foreach ($this->headers as $name => $header)
+		{
+            if ( ! in_array($name, array('From', 'To')))
+            {
+                if (Arr::is_array($header))
+                {
+                    $header = $this->mailer->addrFormat($header);
+                }
+
+                $this->mailer->addCustomHeader($name, $header);
+            }
+		}
+
+		foreach ($this->attachments as $attachment)
+		{
+			$headers = $attachment['headers'];
+
+			$content_type = Arr::get($headers, 'Content-Type', '');
+			$disposition = Arr::get($headers, 'Content-Disposition', 'attachment');
+			$filename = NULL;
+			$description = Arr::get($headers, 'Content-Description');
+
+			if (strpos($disposition, '; filename=') !== FALSE)
+			{
+				list ($disposition, $filename) = preg_split('/;\s*filename=/', $disposition);
+			}
+
+			$this->mailer->addStringAttachment($attachment['attachment'], $filename, 'base64', $content_type, $disposition);
+		}
+
+		return $this->mailer->send();
+	}
+
+}
diff --git a/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PHPMailer/Mail.php b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PHPMailer/Mail.php
new file mode 100644
index 0000000000000000000000000000000000000000..ce7d07fd6d96f26efb6dd2cc90dfb542af99be54
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PHPMailer/Mail.php
@@ -0,0 +1,21 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+/**
+ * PHPMailer mail built-in function mailer.
+ *
+ * @package   Mail
+ * @category  Senders
+ * @author    Guillaume Poirier-Morency <guillaumepoiriermorency@gmail.com>
+ * @copyright (c) 2014, Guillaume Poirier-Morency
+ * @license   BSD-3-Clauses
+ */
+class Kohana_Mail_Sender_PHPMailer_Mail extends Mail_Sender_PHPMailer {
+
+	public function __construct(array $headers, array $options)
+	{
+        parent::__construct($headers, $options);
+
+		$this->mailer->isMail();
+	}
+
+}
diff --git a/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PHPMailer/Qmail.php b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PHPMailer/Qmail.php
new file mode 100644
index 0000000000000000000000000000000000000000..d0fe1199214e0528a42271b3145c23a9c52e35cb
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PHPMailer/Qmail.php
@@ -0,0 +1,21 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+/**
+ * PHPMailer Qmail sender.
+ *
+ * @package   Mail
+ * @category  Senders
+ * @author    Guillaume Poirier-Morency <guillaumepoiriermorency@gmail.com>
+ * @copyright (c) 2013, HГЁte.ca Inc.
+ * @license   BSD-3-Clauses
+ */
+class Kohana_Mail_Sender_PHPMailer_Qmail extends Mail_Sender_PHPMailer {
+
+	public function __construct(array $headers, array $options)
+	{
+		parent::__construct($headers, $options);
+
+		$this->mailer->isQmail();
+	}
+
+}
diff --git a/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PHPMailer/SMTP.php b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PHPMailer/SMTP.php
new file mode 100644
index 0000000000000000000000000000000000000000..b67b006e9a13d3b551ecb86505138fe7cd26e573
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PHPMailer/SMTP.php
@@ -0,0 +1,20 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+/**
+ * PHPMailer SMTP sender.
+ *
+ * @package  Mail
+ * @category Senders
+ * @author   Guillaume Poirier-Morency <guillaumepoiriermorency@gmail.com>
+ * @license  BSD-3-Clauses
+ */
+class Kohana_Mail_Sender_PHPMailer_SMTP extends Mail_Sender_PHPMailer {
+
+	public function __construct(array $headers, array $options)
+	{
+		parent::__construct($headers, $options);
+
+		$this->mailer->isSMTP();
+	}
+
+}
diff --git a/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PHPMailer/Sendmail.php b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PHPMailer/Sendmail.php
new file mode 100644
index 0000000000000000000000000000000000000000..5f2200e7ba5dd25660cc4e05d596efdbeb7a026f
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Kohana/Mail/Sender/PHPMailer/Sendmail.php
@@ -0,0 +1,21 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+/**
+ * PHPMailer sendmail sender.
+ *
+ * @package   Mail
+ * @category  Senders
+ * @author    Guillaume Poirier-Morency <guillaumepoiriermorency@gmail.com>
+ * @copyright (c) 2013, HГЁte.ca Inc.
+ * @license   BSD-3-Clauses
+ */
+class Kohana_Mail_Sender_PHPMailer_Sendmail extends Mail_Sender_PHPMailer {
+
+	public function __construct(array $headers, array $options)
+	{
+		parent::__construct($headers, $options);
+
+		$this->mailer->isSendmail();
+	}
+
+}
diff --git a/~dev_rating/modules/mail/classes/Kohana/Mailer.php b/~dev_rating/modules/mail/classes/Kohana/Mailer.php
new file mode 100644
index 0000000000000000000000000000000000000000..f3fe7a8df18052c163d50aa501b7d57e937ecc08
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Kohana/Mailer.php
@@ -0,0 +1,64 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+/**
+ * Mailer.
+ *
+ * @package   Mail
+ * @author    Guillaume Poirier-Morency <guillaumepoiriermorency@gmail.com>
+ * @copyright (c) 2014, Guillaume Poirier-Morency
+ * @license   BSD-3-Clauses
+ */
+class Kohana_Mailer {
+
+	public static $default = 'default';
+
+	/**
+	 * Prepare a Mail_Sender.
+	 *
+	 * @param string $name
+	 * @return Mail_Sender
+	 */
+	public static function factory($name = NULL)
+	{
+		if ($name === NULL)
+		{
+			$name = Mailer::$default;
+		}
+
+		$sender = Kohana::$config->load("mail.$name.sender");
+		$headers = (array) Kohana::$config->load("mail.$name.headers");
+		$options = (array) Kohana::$config->load("mail.$name.options");
+
+		return Mail_Sender::factory($sender, $headers, $options);
+	}
+
+	/**
+	 * A Message-ID generator following Matt Curtin and Jamie Zawinski
+	 * recommendations.
+	 *
+	 * It is using base64 encoding instead of base36 for the random byte.
+	 *
+	 * domain is defaulted to localhost.
+	 *
+	 * @link http://www.jwz.org/doc/mid.html
+	 */
+	public static function message_id()
+	{
+		$microtime = base_convert(microtime(), 10, 36);
+
+		// Generate a new unique token
+		if (function_exists('openssl_random_pseudo_bytes'))
+		{
+			$random = base64_encode(openssl_random_pseudo_bytes(8));
+		}
+		else
+		{
+			$random = base64_encode(substr(sha1(uniqid(NULL, TRUE)), 0, 8));
+		}
+
+		$domain = Arr::get($_SERVER, 'SERVER_NAME', 'localhost');
+
+		return '<'.$microtime.'.'.$random.'@'.$domain.'>';
+	}
+
+}
diff --git a/~dev_rating/modules/mail/classes/Mail/Sender.php b/~dev_rating/modules/mail/classes/Mail/Sender.php
new file mode 100644
index 0000000000000000000000000000000000000000..f9796f1000d53885d6cb3d0cc9fdaa6574f3b45b
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Mail/Sender.php
@@ -0,0 +1,3 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+abstract class Mail_Sender extends Kohana_Mail_Sender {}
diff --git a/~dev_rating/modules/mail/classes/Mail/Sender/Mail.php b/~dev_rating/modules/mail/classes/Mail/Sender/Mail.php
new file mode 100644
index 0000000000000000000000000000000000000000..fbb74c09d0434378ee0b726a4a63ede159679613
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Mail/Sender/Mail.php
@@ -0,0 +1,3 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+class Mail_Sender_Mail extends Kohana_Mail_Sender_Mail {}
diff --git a/~dev_rating/modules/mail/classes/Mail/Sender/Mock.php b/~dev_rating/modules/mail/classes/Mail/Sender/Mock.php
new file mode 100644
index 0000000000000000000000000000000000000000..2328f10305520dd5d8b26db77ac6a9ef0a173438
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Mail/Sender/Mock.php
@@ -0,0 +1,3 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+class Mail_Sender_Mock extends Kohana_Mail_Sender_Mock {}
diff --git a/~dev_rating/modules/mail/classes/Mail/Sender/PEAR.php b/~dev_rating/modules/mail/classes/Mail/Sender/PEAR.php
new file mode 100644
index 0000000000000000000000000000000000000000..ea1450876153139d0663f98db71111bf42d09afe
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Mail/Sender/PEAR.php
@@ -0,0 +1,3 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+abstract class Mail_Sender_PEAR extends Kohana_Mail_Sender_PEAR {}
diff --git a/~dev_rating/modules/mail/classes/Mail/Sender/PEAR/Mail.php b/~dev_rating/modules/mail/classes/Mail/Sender/PEAR/Mail.php
new file mode 100644
index 0000000000000000000000000000000000000000..d096877e0b4a0c55cc1ed97ebbd491addaad60ac
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Mail/Sender/PEAR/Mail.php
@@ -0,0 +1,3 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+class Mail_Sender_PEAR_Mail extends Kohana_Mail_Sender_PEAR_Mail {}
diff --git a/~dev_rating/modules/mail/classes/Mail/Sender/PEAR/SMTP.php b/~dev_rating/modules/mail/classes/Mail/Sender/PEAR/SMTP.php
new file mode 100644
index 0000000000000000000000000000000000000000..dad7cb87136399dca2864c37afc3e1ef6a023694
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Mail/Sender/PEAR/SMTP.php
@@ -0,0 +1,3 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+class Mail_Sender_PEAR_SMTP extends Kohana_Mail_Sender_PEAR_SMTP {}
diff --git a/~dev_rating/modules/mail/classes/Mail/Sender/PEAR/Sendmail.php b/~dev_rating/modules/mail/classes/Mail/Sender/PEAR/Sendmail.php
new file mode 100644
index 0000000000000000000000000000000000000000..6e86728b8fb7cd4d2afceffd9c39e2005d69dbba
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Mail/Sender/PEAR/Sendmail.php
@@ -0,0 +1,3 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+class Mail_Sender_PEAR_Sendmail extends Kohana_Mail_Sender_PEAR_Sendmail {}
diff --git a/~dev_rating/modules/mail/classes/Mail/Sender/PHPMailer.php b/~dev_rating/modules/mail/classes/Mail/Sender/PHPMailer.php
new file mode 100644
index 0000000000000000000000000000000000000000..8959fd8e613485faa1ed21b053fd00bcd8942734
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Mail/Sender/PHPMailer.php
@@ -0,0 +1,3 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+class Mail_Sender_PHPMailer extends Kohana_Mail_Sender_PHPMailer {}
diff --git a/~dev_rating/modules/mail/classes/Mail/Sender/PHPMailer/Mail.php b/~dev_rating/modules/mail/classes/Mail/Sender/PHPMailer/Mail.php
new file mode 100644
index 0000000000000000000000000000000000000000..e011b801abb2d933f7808603486903336af5c41c
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Mail/Sender/PHPMailer/Mail.php
@@ -0,0 +1,3 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+class Mail_Sender_PHPMailer_Mail extends Kohana_Mail_Sender_PHPMailer_Mail {}
diff --git a/~dev_rating/modules/mail/classes/Mail/Sender/PHPMailer/Qmail.php b/~dev_rating/modules/mail/classes/Mail/Sender/PHPMailer/Qmail.php
new file mode 100644
index 0000000000000000000000000000000000000000..0168cb6858fb09660c71bac16c32895bc27060ba
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Mail/Sender/PHPMailer/Qmail.php
@@ -0,0 +1,3 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+class Mail_Sender_PHPMailer_Qmail extends Kohana_Mail_Sender_PHPMailer_Qmail {}
diff --git a/~dev_rating/modules/mail/classes/Mail/Sender/PHPMailer/SMTP.php b/~dev_rating/modules/mail/classes/Mail/Sender/PHPMailer/SMTP.php
new file mode 100644
index 0000000000000000000000000000000000000000..6cd3e43409e874009193f76b69d2715e8a89944b
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Mail/Sender/PHPMailer/SMTP.php
@@ -0,0 +1,3 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+class Mail_Sender_PHPMailer_SMTP extends Kohana_Mail_Sender_PHPMailer_SMTP {}
diff --git a/~dev_rating/modules/mail/classes/Mail/Sender/PHPMailer/Sendmail.php b/~dev_rating/modules/mail/classes/Mail/Sender/PHPMailer/Sendmail.php
new file mode 100644
index 0000000000000000000000000000000000000000..973af6c362c18ab80f13858a4df618bbe1b80f41
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Mail/Sender/PHPMailer/Sendmail.php
@@ -0,0 +1,3 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+class Mail_Sender_PHPMailer_Sendmail extends Kohana_Mail_Sender_PHPMailer_Sendmail {}
diff --git a/~dev_rating/modules/mail/classes/Mailer.php b/~dev_rating/modules/mail/classes/Mailer.php
new file mode 100644
index 0000000000000000000000000000000000000000..3e3f53324e1902571365be63cbc3e40a232d0b84
--- /dev/null
+++ b/~dev_rating/modules/mail/classes/Mailer.php
@@ -0,0 +1,3 @@
+<?php defined('SYSPATH') OR die('No direct script access.');
+
+class Mailer extends Kohana_Mailer {}
diff --git a/~dev_rating/modules/mail/config/mail.php b/~dev_rating/modules/mail/config/mail.php
new file mode 100644
index 0000000000000000000000000000000000000000..db5b4d2857f6d998b289c298e02c866150c82ba8
--- /dev/null
+++ b/~dev_rating/modules/mail/config/mail.php
@@ -0,0 +1,80 @@
+<?php defined('SYSPATH') or die('No direct script access.');
+
+/**
+ * Configuration for the mail module.
+ *
+ * @package   Mail
+ * @author    Guillaume Poirier-Morency <guillaumepoiriermorency@gmail.com>
+ * @copyright (c) 2013, HГЁte.ca Inc.
+ * @license   BSD-3-Clauses
+ */
+return array(
+    'default' => array(
+        /**
+         * Mail: simple mail() function wrapper.
+         *
+         * You will need the PEAR Mail package installed on your computer if
+         * you want to use any of the following mailer.
+         *
+         * PEAR_Sendmail: send mail through a sendmail server using PEAR.
+         *
+         * PEAR_SMTP: send mail through smtp protocol using PEAR.
+         *
+         * PEAR_Mail: PEAR wrapper for the mail() function.
+         *
+         * PHPMailer: send mail using PHPMailer.
+         */
+        'sender' => 'PHPMailer',
+        /**
+         * Initialize headers.
+         */
+        'headers' => array(),
+        /**
+         * Options for the sender.
+         *
+         * For PEAR senders options, refer to their official documentation at http://pear.php.net/manual/en/package.mail.mail.factory.php
+         */
+        'options' => array(
+            /**
+             * Mail
+             *
+             * Specify an array of commands. They will be automatically joined
+             * by a space character.
+             *
+             * 'option_1', 'option_2',
+             */
+            /**
+             * PEAR_Sendmail
+             *
+             * 'sendmail_path' => '/usr/bin/sendmail',
+             * 'sendmail_args' => '-i',
+             */
+            /**
+             * PEAR_SMTP
+             *
+             * 'host' => 'localhost',
+             * 'port' => 25,
+             * 'auth' => FALSE,
+             * 'username' => NULL,
+             * 'password' => NULL,
+             * 'localhost' => 'localhost',
+             * 'timeout' => NULL,
+             * 'verp' => FALSE,
+             * 'debug' => FALSE,
+             * 'persist' => NULL,
+             * 'pipelining' => NULL
+             */
+            /**
+             * PHPMailer_SMTP
+             *
+             * @link https://github.com/PHPMailer/PHPMailer
+             *
+             * 'SMTPAuth' => TRUE
+             * 'Host'     => 'localhost',
+             * 'Port'     => 26,
+             * 'Username' => NULL,
+             * 'Password' => NULL
+             */
+        )
+    )
+);
diff --git a/~dev_rating/modules/mail/tests/MailTest.php b/~dev_rating/modules/mail/tests/MailTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..7402d1df2fa509c31e97f9d51a6ed7d2a938edec
--- /dev/null
+++ b/~dev_rating/modules/mail/tests/MailTest.php
@@ -0,0 +1,236 @@
+<?php
+
+defined('SYSPATH') or die('No direct script access.');
+
+/**
+ * Tests for the Mail package.
+ *
+ * @package   Mail
+ * @category  Tests
+ * @author    HГЁte.ca Team
+ * @copyright (c) 2013, HГЁte.ca Inc.
+ * @license   BSD-3-Clauses
+ */
+class MailTest extends Unittest_TestCase {
+
+	/**
+	 * Set a custom email to receive the test results.
+	 */
+	const RECEIVER = 'foo@example.com';
+
+	public function providerHeaders() 
+	{
+		return array(
+			array('Subject', 'test', 'test'),
+			array('Subject', 'test В¤', 'test =?UTF-8?B?wqQ=?='),
+			array('To', 'test@test.com', 'test@test.com'),
+			array('To', array('test@test.com'), 'test@test.com'),
+			array('To', array('test@test.com' => 'test'), 'test <test@test.com>'),
+			array('To', array('test@test.com' => 'test', 'test2@test.com' => 'test'), 'test <test@test.com>, test <test2@test.com>'),
+		);	
+	}
+	
+	/**
+	 * @dataProvider providerHeaders
+	 */
+	public function testEncodeHeaderWithMbstring($name, $header, $encoded) 
+	{
+		$this->assertEquals($encoded, Mail_Sender_Mail::header_encode($name, $header));
+	}
+
+	public function testMessageIDGenerator()
+	{
+		$this->assertRegExp('/<[\d\w\+=]+\.[\d\w\+=]+@\w+(\.\w+)*>/', Mailer::message_id());
+	}
+
+	public function providerSender()
+	{
+		return array(
+			array(Mail_Sender::factory('Mail',               array(), array())),
+			array(Mail_Sender::factory('PEAR_Mail',          array(), array())),
+			array(Mail_Sender::factory('PEAR_Sendmail',      array(), array())),
+			array(Mail_Sender::factory('PEAR_SMTP',          array(), array())),
+			array(Mail_Sender::factory('PHPMailer_Mail',     array(), array())),
+			array(Mail_Sender::factory('PHPMailer_Qmail',    array(), array())), // could not test this one :(
+			array(Mail_Sender::factory('PHPMailer_Sendmail', array(), array())),
+			array(Mail_Sender::factory('PHPMailer_SMTP',     array(), array())),
+			array(Mail_Sender::factory('Mock',               array(), array()))
+		);
+	}
+
+	public function testSendWithDefaultSender()
+	{
+		$sender = Mailer::factory();
+
+		$this->assertTrue($sender->subject('test')
+						->from(get_class(Mailer::factory()))
+						->body('test')
+						->send(MailTest::RECEIVER), $sender->error());
+	}
+
+	/**
+	 * @dataProvider providerSender
+	 */
+	public function testSend(Mail_Sender $sender)
+	{
+		$this->assertTrue($sender->subject('test')
+						->from((get_class($sender)))
+						->body('test')
+						->send(MailTest::RECEIVER), $sender->error());
+	}
+
+	/**
+	 * @dataProvider providerSender
+	 */
+	public function testSubject(Mail_Sender $sender)
+	{
+		// ascii subect
+		$this->assertTrue($sender->subject('Hello Foo')
+						->from(get_class($sender))
+						->body('test')
+						->send(MailTest::RECEIVER), $sender->error());
+	}
+
+	/**
+	 * @dataProvider providerSender
+	 */
+	public function testSubjectNonAscii(Mail_Sender $sender)
+	{
+		// non-ascii subject
+		$this->assertTrue($sender->subject('В¤ Hello Foo В¤')
+						->from(get_class($sender))
+						->body('test')
+						->send(MailTest::RECEIVER), $sender->error());
+	}
+
+	/**
+	 * @dataProvider providerSender
+	 */
+	public function testSubjectEmpty(Mail_Sender $sender)
+	{
+		$this->assertTrue($sender
+						->subject('')
+						->from(get_class($sender))
+						->body('test')
+						->send(MailTest::RECEIVER), $sender->error());
+	}
+
+	/**
+	 * @dataProvider providerSender
+	 */
+	public function testSubjectOmmited(Mail_Sender $sender)
+	{
+		$this->assertTrue($sender
+						->from(get_class($sender))
+						->body('test')
+						->send(MailTest::RECEIVER), $sender->error());
+	}
+
+	/**
+	 * @dataProvider providerSender
+	 */
+	public function testHeaders(Mail_Sender $sender)
+	{
+		$this->assertTrue($sender->subject('test')
+						->from(get_class($sender))
+						->body('test')
+						->headers('Content-Type', 'text/html')
+						->send(MailTest::RECEIVER), $sender->error());
+	}
+
+	/**
+	 * @dataProvider providerSender
+	 */
+	public function testParam(Mail_Sender $sender)
+	{
+		$this->assertTrue($sender->subject('Mail sent by :name')
+						->from(get_class($sender))
+						->body('Hi, it\'s :name, how are you?')
+						->param(':name', 'Foo')
+						->send(MailTest::RECEIVER), $sender->error());
+
+		$this->assertEquals('Mail sent by Foo', $sender->subject());
+		$this->assertEquals('Hi, it\'s Foo, how are you?', $sender->body());
+	}
+
+	/**
+	 * @dataProvider providerSender
+	 */
+	public function testBodyHTML(Mail_Sender $sender)
+	{
+		$this->assertTrue($sender->subject('Hey foo!')
+						->from(get_class($sender))
+						->content_type('text/html')
+						->body('<html><body>Hey foo!</body></html>')
+						->send(MailTest::RECEIVER), $sender->error());
+	}
+
+	/**
+	 * @dataProvider providerSender
+	 */
+	public function testBodyPlainText(Mail_Sender $sender)
+	{
+		$this->assertTrue($sender->subject('Hey foo!')
+						->from(get_class($sender))
+						->body('Hey!')
+						->send(MailTest::RECEIVER), $sender->error());
+	}
+
+	/**
+	 * @dataProvider providerSender
+	 */
+	public function testBodyOmmited(Mail_Sender $sender)
+	{
+		$this->assertFalse($sender->subject('Hey foo!')
+						->from(get_class($sender))
+						->send(MailTest::RECEIVER), $sender->error());
+	}
+
+	/**
+	 * @dataProvider providerSender
+	 */
+	public function testAttachment(Mail_Sender $sender)
+	{
+		$this->assertTrue($sender->subject('Sent you some files!')
+						->from(get_class($sender))
+						->body('Hey!')
+						->attachment('{}', array('Content-Type' => 'application/json'))
+						->attachment(file_get_contents(MODPATH.'mail/tests/test.png'), array(
+							'Content-Type' => 'image/png'))
+						->send(MailTest::RECEIVER), $sender->error());
+	}
+
+	/**
+	 * @dataProvider providerSender
+	 */
+	public function testAttachmentWithFilename(Mail_Sender $sender)
+	{
+		// with filename
+		$this->assertTrue($sender->subject('Sent you some files!')
+						->from(get_class($sender))
+						->body('Hey!')
+						->attachment('{}', array('Content-Type' => 'application/json'))
+						->attachment(file_get_contents(MODPATH.'mail/tests/test.png'), array(
+							'Content-Type' => 'image/png',
+							'Content-Disposition' => 'attachment;filename=test'))
+						->send(MailTest::RECEIVER), $sender->error());
+	}
+
+	/**
+	 * @dataProvider providerSender
+	 */
+	public function testAttachmentWithManyHeaders(Mail_Sender $sender)
+	{
+		// with filename
+		$this->assertTrue($sender->subject('Sent you some files!')
+						->from(get_class($sender))
+						->body('Hey!')
+						->attachment('test', array(
+							'Content-Type' => 'text/plain; charset=utf-8',
+							'Content-Disposition' => 'attachment; filename=test',
+							'Content-Description' => 'lol',
+							'Content-Language' => 'en'))
+						->send(MailTest::RECEIVER), $sender->error());
+	}
+
+}
diff --git a/~dev_rating/modules/mail/tests/test.png b/~dev_rating/modules/mail/tests/test.png
new file mode 100644
index 0000000000000000000000000000000000000000..5de7e6fa545228b6ce34d191d73e95def57cdf96
Binary files /dev/null and b/~dev_rating/modules/mail/tests/test.png differ
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/.gitignore b/~dev_rating/modules/mail/vendor/PHPMailer/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..989164d65a5f869e2e6e3a68bfb9f97e3a9c2912
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/.gitignore
@@ -0,0 +1,5 @@
+docs/phpdoc/
+test/message.txt
+test/testbootstrap.php
+.idea
+build/
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/PHPMailerAutoload.php b/~dev_rating/modules/mail/vendor/PHPMailer/PHPMailerAutoload.php
new file mode 100644
index 0000000000000000000000000000000000000000..eaa2e30349bb1d221ae88846e05361e83e610731
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/PHPMailerAutoload.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * PHPMailer SPL autoloader.
+ * 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 SPL autoloader.
+ * @param string $classname The name of the class to load
+ */
+function PHPMailerAutoload($classname)
+{
+    //Can't use __DIR__ as it's only in PHP 5.3+
+    $filename = dirname(__FILE__).DIRECTORY_SEPARATOR.'class.'.strtolower($classname).'.php';
+    if (is_readable($filename)) {
+        require $filename;
+    }
+}
+
+if (version_compare(PHP_VERSION, '5.1.2', '>=')) {
+    //SPL autoloading was introduced in PHP 5.1.2
+    if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
+        spl_autoload_register('PHPMailerAutoload', true, true);
+    } else {
+        spl_autoload_register('PHPMailerAutoload');
+    }
+} else {
+    /**
+     * Fall back to traditional autoload for old PHP versions
+     * @param string $classname The name of the class to load
+     */
+    function __autoload($classname)
+    {
+        PHPMailerAutoload($classname);
+    }
+}
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/class.phpmailer.php b/~dev_rating/modules/mail/vendor/PHPMailer/class.phpmailer.php
new file mode 100644
index 0000000000000000000000000000000000000000..e8f25b4e535294b7138870fed82266e9392fe428
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/class.phpmailer.php
@@ -0,0 +1,3454 @@
+<?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.
+     * @type string
+     */
+    public $Version = '5.2.9';
+
+    /**
+     * Email priority.
+     * Options: 1 = High, 3 = Normal, 5 = low.
+     * @type integer
+     */
+    public $Priority = 3;
+
+    /**
+     * The character set of the message.
+     * @type string
+     */
+    public $CharSet = 'UTF-8';
+
+    /**
+     * The MIME Content-type of the message.
+     * @type string
+     */
+    public $ContentType = 'text/plain';
+
+    /**
+     * The message encoding.
+     * Options: "8bit", "7bit", "binary", "base64", and "quoted-printable".
+     * @type string
+     */
+    public $Encoding = '8bit';
+
+    /**
+     * Holds the most recent mailer error message.
+     * @type string
+     */
+    public $ErrorInfo = '';
+
+    /**
+     * The From email address for the message.
+     * @type string
+     */
+    public $From = 'no-reply@rating.mmcs.sfedu.ru';
+
+    /**
+     * The From name of the message.
+     * @type string
+     */
+    public $FromName = 'Сервис БРС';
+
+    /**
+     * 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.
+     * @type string
+     */
+    public $Sender = '';
+
+    /**
+     * The Return-Path of the message.
+     * If empty, it will be set to either From or Sender.
+     * @type 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.
+     * @type string
+     */
+    public $Subject = '';
+
+    /**
+     * An HTML or plain text message body.
+     * If HTML then call isHTML(true).
+     * @type 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.
+     * @type 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/
+     * @type string
+     */
+    public $Ical = '';
+
+    /**
+     * The complete compiled MIME message body.
+     * @access protected
+     * @type string
+     */
+    protected $MIMEBody = '';
+
+    /**
+     * The complete compiled MIME message headers.
+     * @type string
+     * @access protected
+     */
+    protected $MIMEHeader = '';
+
+    /**
+     * Extra headers that createHeader() doesn't fold in.
+     * @type string
+     * @access protected
+     */
+    protected $mailHeader = '';
+
+    /**
+     * Word-wrap the message body to this number of chars.
+     * @type integer
+     */
+    public $WordWrap = 0;
+
+    /**
+     * Which method to use to send mail.
+     * Options: "mail", "sendmail", or "smtp".
+     * @type string
+     */
+    public $Mailer = 'mail';
+
+    /**
+     * The path to the sendmail program.
+     * @type string
+     */
+    public $Sendmail = '/usr/sbin/sendmail';
+
+    /**
+     * Whether mail() uses a fully sendmail-compatible MTA.
+     * One which supports sendmail's "-oi -f" options.
+     * @type boolean
+     */
+    public $UseSendmailOptions = true;
+
+    /**
+     * Path to PHPMailer plugins.
+     * Useful if the SMTP class is not in the PHP include path.
+     * @type string
+     * @deprecated Should not be needed now there is an autoloader.
+     */
+    public $PluginDir = '';
+
+    /**
+     * The email address that a reading confirmation should be sent to.
+     * @type string
+     */
+    public $ConfirmReadingTo = '';
+
+    /**
+     * The hostname to use in Message-Id and Received headers
+     * and as default HELO string.
+     * If empty, the value returned
+     * by SERVER_NAME is used or 'localhost.localdomain'.
+     * @type string
+     */
+    public $Hostname = '';
+
+    /**
+     * An ID to be used in the Message-Id header.
+     * If empty, a unique id will be generated.
+     * @type string
+     */
+    public $MessageID = '';
+
+    /**
+     * The message Date to be used in the Date header.
+     * If empty, the current date will be added.
+     * @type 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.
+     * @type string
+     */
+    public $Host = 'localhost';
+
+    /**
+     * The default SMTP server port.
+     * @type 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.
+     * @type string
+     * @see PHPMailer::$Hostname
+     */
+    public $Helo = '';
+
+    /**
+     * The secure connection prefix.
+     * Options: "", "ssl" or "tls"
+     * @type string
+     */
+    public $SMTPSecure = '';
+
+    /**
+     * Whether to use SMTP authentication.
+     * Uses the Username and Password properties.
+     * @type boolean
+     * @see PHPMailer::$Username
+     * @see PHPMailer::$Password
+     */
+    public $SMTPAuth = false;
+
+    /**
+     * SMTP username.
+     * @type string
+     */
+    public $Username = '';
+
+    /**
+     * SMTP password.
+     * @type string
+     */
+    public $Password = '';
+
+    /**
+     * SMTP auth type.
+     * Options are LOGIN (default), PLAIN, NTLM, CRAM-MD5
+     * @type string
+     */
+    public $AuthType = '';
+
+    /**
+     * SMTP realm.
+     * Used for NTLM auth
+     * @type string
+     */
+    public $Realm = '';
+
+    /**
+     * SMTP workstation.
+     * Used for NTLM auth
+     * @type string
+     */
+    public $Workstation = '';
+
+    /**
+     * The SMTP server timeout in seconds.
+     * @type integer
+     */
+    public $Timeout = 10;
+
+    /**
+     * 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
+     * @type 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>
+     * @type 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().
+     * @type boolean
+     */
+    public $SMTPKeepAlive = false;
+
+    /**
+     * Whether to split multiple to addresses into multiple messages
+     * or send them all in one message.
+     * @type boolean
+     */
+    public $SingleTo = false;
+
+    /**
+     * Storage for addresses when SingleTo is enabled.
+     * @type 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 http://en.wikipedia.org/wiki/Variable_envelope_return_path
+     * @link http://www.postfix.org/VERP_README.html Postfix VERP info
+     * @type boolean
+     */
+    public $do_verp = false;
+
+    /**
+     * Whether to allow sending messages with an empty body.
+     * @type 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.
+     * @type string
+     */
+    public $LE = "\n";
+
+    /**
+     * DKIM selector.
+     * @type string
+     */
+    public $DKIM_selector = '';
+
+    /**
+     * DKIM Identity.
+     * Usually the email address used as the source of the email
+     * @type string
+     */
+    public $DKIM_identity = '';
+
+    /**
+     * DKIM passphrase.
+     * Used if your key is encrypted.
+     * @type string
+     */
+    public $DKIM_passphrase = '';
+
+    /**
+     * DKIM signing domain name.
+     * @example 'example.com'
+     * @type string
+     */
+    public $DKIM_domain = '';
+
+    /**
+     * DKIM private key file path.
+     * @type string
+     */
+    public $DKIM_private = '';
+
+    /**
+     * 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
+     *   string  $to            email address of the recipient
+     *   string  $cc            cc email addresses
+     *   string  $bcc           bcc email addresses
+     *   string  $subject       the subject
+     *   string  $body          the email body
+     *   string  $from          email address of sender
+     * @type string
+     */
+    public $action_function = '';
+
+    /**
+     * What to use in the X-Mailer header.
+     * Options: null for default, whitespace for none, or a string to use
+     * @type string
+     */
+    public $XMailer = '';
+
+    /**
+     * An instance of the SMTP sender class.
+     * @type SMTP
+     * @access protected
+     */
+    protected $smtp = null;
+
+    /**
+     * The array of 'to' addresses.
+     * @type array
+     * @access protected
+     */
+    protected $to = array();
+
+    /**
+     * The array of 'cc' addresses.
+     * @type array
+     * @access protected
+     */
+    protected $cc = array();
+
+    /**
+     * The array of 'bcc' addresses.
+     * @type array
+     * @access protected
+     */
+    protected $bcc = array();
+
+    /**
+     * The array of reply-to names and addresses.
+     * @type array
+     * @access protected
+     */
+    protected $ReplyTo = array();
+
+    /**
+     * An array of all kinds of addresses.
+     * Includes all of $to, $cc, $bcc, $replyto
+     * @type array
+     * @access protected
+     */
+    protected $all_recipients = array();
+
+    /**
+     * The array of attachments.
+     * @type array
+     * @access protected
+     */
+    protected $attachment = array();
+
+    /**
+     * The array of custom headers.
+     * @type array
+     * @access protected
+     */
+    protected $CustomHeader = array();
+
+    /**
+     * The most recent Message-ID (including angular brackets).
+     * @type string
+     * @access protected
+     */
+    protected $lastMessageID = '';
+
+    /**
+     * The message's MIME type.
+     * @type string
+     * @access protected
+     */
+    protected $message_type = '';
+
+    /**
+     * The array of MIME boundary strings.
+     * @type array
+     * @access protected
+     */
+    protected $boundary = array();
+
+    /**
+     * The array of available languages.
+     * @type array
+     * @access protected
+     */
+    protected $language = array();
+
+    /**
+     * The number of errors encountered.
+     * @type integer
+     * @access protected
+     */
+    protected $error_count = 0;
+
+    /**
+     * The S/MIME certificate file path.
+     * @type string
+     * @access protected
+     */
+    protected $sign_cert_file = '';
+
+    /**
+     * The S/MIME key file path.
+     * @type string
+     * @access protected
+     */
+    protected $sign_key_file = '';
+
+    /**
+     * The S/MIME password for the key.
+     * Used only if the key is encrypted.
+     * @type string
+     * @access protected
+     */
+    protected $sign_key_pass = '';
+
+    /**
+     * Whether to throw exceptions for errors.
+     * @type boolean
+     * @access protected
+     */
+    protected $exceptions = false;
+
+    /**
+     * 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";
+
+    /**
+     * Constructor.
+     * @param boolean $exceptions Should we throw external exceptions?
+     */
+    public function __construct($exceptions = false)
+    {
+        $this->exceptions = ($exceptions == true);
+    }
+
+    /**
+     * Destructor.
+     */
+    public function __destruct()
+    {
+        if ($this->Mailer == 'smtp') { //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));
+        }
+        if (ini_get('safe_mode') || !($this->UseSendmailOptions)) {
+            $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;
+        }
+        if (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|\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
+     * @param string $name
+     * @return boolean true on success, false if address already used
+     */
+    public function addAddress($address, $name = '')
+    {
+        return $this->addAnAddress('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
+     * @param string $name
+     * @return boolean true on success, false if address already used
+     */
+    public function addCC($address, $name = '')
+    {
+        return $this->addAnAddress('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
+     * @param string $name
+     * @return boolean true on success, false if address already used
+     */
+    public function addBCC($address, $name = '')
+    {
+        return $this->addAnAddress('bcc', $address, $name);
+    }
+
+    /**
+     * Add a "Reply-to" address.
+     * @param string $address
+     * @param string $name
+     * @return boolean
+     */
+    public function addReplyTo($address, $name = '')
+    {
+        return $this->addAnAddress('Reply-To', $address, $name);
+    }
+
+    /**
+     * Add an address to one of the recipient arrays.
+     * Addresses that have been added already return false, but do not throw exceptions
+     * @param string $kind One of 'to', 'cc', 'bcc', 'ReplyTo'
+     * @param string $address The email address to send 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 (!preg_match('/^(to|cc|bcc|Reply-To)$/', $kind)) {
+            $this->setError($this->lang('Invalid recipient array') . ': ' . $kind);
+            $this->edebug($this->lang('Invalid recipient array') . ': ' . $kind);
+            if ($this->exceptions) {
+                throw new phpmailerException('Invalid recipient array: ' . $kind);
+            }
+            return false;
+        }
+        $address = trim($address);
+        $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
+        if (!$this->validateAddress($address)) {
+            $this->setError($this->lang('invalid_address') . ': ' . $address);
+            $this->edebug($this->lang('invalid_address') . ': ' . $address);
+            if ($this->exceptions) {
+                throw new phpmailerException($this->lang('invalid_address') . ': ' . $address);
+            }
+            return false;
+        }
+        if ($kind != 'Reply-To') {
+            if (!isset($this->all_recipients[strtolower($address)])) {
+                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;
+    }
+
+    /**
+     * 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
+        if (!$this->validateAddress($address)) {
+            $this->setError($this->lang('invalid_address') . ': ' . $address);
+            $this->edebug($this->lang('invalid_address') . ': ' . $address);
+            if ($this->exceptions) {
+                throw new phpmailerException($this->lang('invalid_address') . ': ' . $address);
+            }
+            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 $patternselect A selector for the validation pattern to use :
+     * * `auto` Pick strictest one 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; same as pcre8 but does not allow 'dotless' domains;
+     * * `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.
+     * @return boolean
+     * @static
+     * @access public
+     */
+    public static function validateAddress($address, $patternselect = 'auto')
+    {
+        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);
+        }
+    }
+
+    /**
+     * 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->mailHeader = '';
+            if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
+                throw new phpmailerException($this->lang('provide_address'), self::STOP_CRITICAL);
+            }
+
+            // Set whether the message is multipart/alternative
+            if (!empty($this->AltBody)) {
+                $this->ContentType = 'multipart/alternative';
+            }
+
+            $this->error_count = 0; // reset errors
+            $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);
+            }
+
+            $this->MIMEHeader = $this->createHeader();
+            $this->MIMEBody = $this->createBody();
+
+            // 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)
+                && !empty($this->DKIM_private)
+                && !empty($this->DKIM_selector)
+                && !empty($this->DKIM_domain)
+                && 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)
+    {
+        if ($this->Sender != '') {
+            if ($this->Mailer == 'qmail') {
+                $sendmail = sprintf('%s -f%s', escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
+            } else {
+                $sendmail = sprintf('%s -oi -f%s -t', escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
+            }
+        } else {
+            if ($this->Mailer == 'qmail') {
+                $sendmail = sprintf('%s', escapeshellcmd($this->Sendmail));
+            } else {
+                $sendmail = sprintf('%s -oi -t', escapeshellcmd($this->Sendmail));
+            }
+        }
+        if ($this->SingleTo === true) {
+            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;
+    }
+
+    /**
+     * 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);
+
+        if (empty($this->Sender)) {
+            $params = ' ';
+        } else {
+            $params = sprintf('-f%s', $this->Sender);
+        }
+        if ($this->Sender != '' and !ini_get('safe_mode')) {
+            $old_from = ini_get('sendmail_from');
+            ini_set('sendmail_from', $this->Sender);
+        }
+        $result = false;
+        if ($this->SingleTo === true && 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()) {
+            throw new phpmailerException($this->lang('smtp_connect_failed'), self::STOP_CRITICAL);
+        }
+        $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender;
+        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 ($this->to as $to) {
+            if (!$this->smtp->recipient($to[0])) {
+                $bad_rcpt[] = $to[0];
+                $isSent = false;
+            } else {
+                $isSent = true;
+            }
+            $this->doCallback($isSent, array($to[0]), array(), array(), $this->Subject, $body, $this->From);
+        }
+        foreach ($this->cc as $cc) {
+            if (!$this->smtp->recipient($cc[0])) {
+                $bad_rcpt[] = $cc[0];
+                $isSent = false;
+            } else {
+                $isSent = true;
+            }
+            $this->doCallback($isSent, array(), array($cc[0]), array(), $this->Subject, $body, $this->From);
+        }
+        foreach ($this->bcc as $bcc) {
+            if (!$this->smtp->recipient($bcc[0])) {
+                $bad_rcpt[] = $bcc[0];
+                $isSent = false;
+            } else {
+                $isSent = true;
+            }
+            $this->doCallback($isSent, array(), array(), array($bcc[0]), $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 == true) {
+            $this->smtp->reset();
+        } else {
+            $this->smtp->quit();
+            $this->smtp->close();
+        }
+        if (count($bad_rcpt) > 0) { // Create error message for any bad addresses
+            throw new phpmailerException(
+                $this->lang('recipients_failed') . implode(', ', $bad_rcpt),
+                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 = array())
+    {
+        if (is_null($this->smtp)) {
+            $this->smtp = $this->getSMTPInstance();
+        }
+
+        // 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\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) {
+                // Not a valid host entry
+                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 = '';
+            $tls = ($this->SMTPSecure == 'tls');
+            if ($hostinfo[2] == 'ssl' or ($hostinfo[2] == '' and $this->SMTPSecure == 'ssl')) {
+                $prefix = 'ssl://';
+                $tls = false; // Can't have SSL and TLS at once
+            } elseif ($hostinfo[2] == 'tls') {
+                $tls = true;
+                // tls doesn't use a prefix
+            }
+            $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);
+
+                    if ($tls) {
+                        if (!$this->smtp->startTLS()) {
+                            throw new phpmailerException($this->lang('connect_host'));
+                        }
+                        // We must resend HELO 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;
+                    // 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 ($this->smtp !== null) {
+            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 = '')
+    {
+        // 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: '
+        );
+        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;
+        }
+        $foundlang = true;
+        $lang_file = $lang_path . 'phpmailer.lang-' . $langcode . '.php';
+        if ($langcode != 'en') { // There is no English translation file
+            // Make sure language file path is readable
+            if (!is_readable($lang_file)) {
+                $foundlang = false;
+            } else {
+                // Overwrite language-specific strings.
+                // This way we'll never have missing translations.
+                $foundlang = include $lang_file;
+            }
+        }
+        $this->language = $PHPMAILER_LANG;
+        return ($foundlang == true); // 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)
+    {
+        $soft_break = ($qp_mode) ? sprintf(' =%s', $this->LE) : $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);
+        if (substr($message, -$lelen) == $this->LE) {
+            $message = substr($message, 0, -$lelen);
+        }
+
+        $line = explode($this->LE, $message); // Magic. We know fixEOL uses $LE
+        $message = '';
+        for ($i = 0; $i < count($line); $i++) {
+            $line_part = explode(' ', $line[$i]);
+            $buf = '';
+            for ($e = 0; $e < count($line_part); $e++) {
+                $word = $line_part[$e];
+                if ($qp_mode and (strlen($word) > $length)) {
+                    $space_left = $length - strlen($buf) - $crlflen;
+                    if ($e != 0) {
+                        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;
+                    $buf .= ($e == 0) ? $word : (' ' . $word);
+
+                    if (strlen($buf) > $length and $buf_o != '') {
+                        $message .= $buf_o . $soft_break;
+                        $buf = $word;
+                    }
+                }
+            }
+            $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 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 ($encodedCharPos !== false) {
+                // 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
+                    $maxLength = ($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;
+    }
+
+    /**
+     * Set the body wrapping.
+     * @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 = '';
+
+        // Set the boundaries
+        $uniq_id = md5(uniqid(time()));
+        $this->boundary[1] = 'b1_' . $uniq_id;
+        $this->boundary[2] = 'b2_' . $uniq_id;
+        $this->boundary[3] = 'b3_' . $uniq_id;
+
+        if ($this->MessageDate == '') {
+            $this->MessageDate = self::rfcDate();
+        }
+        $result .= $this->headerLine('Date', $this->MessageDate);
+
+
+        // To be created automatically by mail()
+        if ($this->SingleTo === true) {
+            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)));
+        }
+
+        if ($this->MessageID != '') {
+            $this->lastMessageID = $this->MessageID;
+        } else {
+            $this->lastMessageID = sprintf('<%s@%s>', $uniq_id, $this->ServerHostname());
+        }
+        $result .= $this->HeaderLine('Message-ID', $this->lastMessageID);
+        $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', '<' . trim($this->ConfirmReadingTo) . '>');
+        }
+
+        // Add custom headers
+        for ($index = 0; $index < count($this->CustomHeader); $index++) {
+            $result .= $this->headerLine(
+                trim($this->CustomHeader[$index][0]),
+                $this->encodeHeader(trim($this->CustomHeader[$index][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 $this->MIMEHeader . $this->mailHeader . self::CRLF . $this->MIMEBody;
+    }
+
+
+    /**
+     * Assemble the message body.
+     * Returns an empty string on failure.
+     * @access public
+     * @throws phpmailerException
+     * @return string The assembled message body
+     */
+    public function createBody()
+    {
+        $body = '';
+
+        if ($this->sign_key_file) {
+            $body .= $this->getMailMIME() . $this->LE;
+        }
+
+        $this->setWordWrap();
+
+        $bodyEncoding = $this->Encoding;
+        $bodyCharSet = $this->CharSet;
+        if ($bodyEncoding == '8bit' and !$this->has8bitChars($this->Body)) {
+            $bodyEncoding = '7bit';
+            $bodyCharSet = 'us-ascii';
+        }
+        $altBodyEncoding = $this->Encoding;
+        $altBodyCharSet = $this->CharSet;
+        if ($altBodyEncoding == '8bit' and !$this->has8bitChars($this->AltBody)) {
+            $altBodyEncoding = '7bit';
+            $altBodyCharSet = 'us-ascii';
+        }
+        switch ($this->message_type) {
+            case 'inline':
+                $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 .= $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 .= $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 .= $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 .= $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 .= $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 .= $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 ''
+                $body .= $this->encodeString($this->Body, $bodyEncoding);
+                break;
+        }
+
+        if ($this->isError()) {
+            $body = '';
+        } elseif ($this->sign_key_file) {
+            try {
+                if (!defined('PKCS7_TEXT')) {
+                    throw new phpmailerException($this->lang('signing') . ' OpenSSL extension missing.');
+                }
+                // @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');
+                file_put_contents($file, $body); // @TODO check this worked
+                $signed = tempnam(sys_get_temp_dir(), 'signed');
+                if (@openssl_pkcs7_sign(
+                    $file,
+                    $signed,
+                    'file://' . realpath($this->sign_cert_file),
+                    array('file://' . realpath($this->sign_key_file), $this->sign_key_pass),
+                    null
+                )
+                ) {
+                    @unlink($file);
+                    $body = file_get_contents($signed);
+                    @unlink($signed);
+                } 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 == '') {
+            $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.
+     * Returns false if the file could not be found or read.
+     * @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 (!@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' && isset($cidUniq[$cid])) {
+                    continue;
+                }
+                $cidUniq[$cid] = true;
+
+                $mime[] = sprintf('--%s%s', $boundary, $this->LE);
+                $mime[] = sprintf(
+                    'Content-Type: %s; name="%s"%s',
+                    $type,
+                    $this->encodeHeader($this->secureHeader($name)),
+                    $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 {
+                        $mime[] = sprintf(
+                            'Content-Disposition: %s; filename=%s%s',
+                            $disposition,
+                            $encoded_name,
+                            $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
+     * @see EncodeFile(encodeFile
+     * @access protected
+     * @return string
+     */
+    protected function encodeFile($path, $encoding = 'base64')
+    {
+        try {
+            if (!is_readable($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', 0);
+                }
+            }
+            $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?'1':'0'));
+                }
+            }
+            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;
+        }
+
+        if ($matchcount == 0) { // There are no chars that need encoding
+            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)
+    {
+        if (function_exists('quoted_printable_encode')) { // Use native function if it's available (>= PHP5.3)
+            return $this->fixEOL(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)
+        );
+        $string = preg_replace('/[^\r\n]{' . ($line_max - 3) . '}[^=\r\n]{2}/', "$0=\r\n", $string);
+        return $this->fixEOL($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 ($eqkey !== false) {
+                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' attachmants 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.
+     * @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 (!@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 == '') {
+            $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 all To recipients.
+     * @return void
+     */
+    public function clearAddresses()
+    {
+        foreach ($this->to as $to) {
+            unset($this->all_recipients[strtolower($to[0])]);
+        }
+        $this->to = array();
+    }
+
+    /**
+     * Clear all CC recipients.
+     * @return void
+     */
+    public function clearCCs()
+    {
+        foreach ($this->cc as $cc) {
+            unset($this->all_recipients[strtolower($cc[0])]);
+        }
+        $this->cc = array();
+    }
+
+    /**
+     * Clear all BCC recipients.
+     * @return void
+     */
+    public function clearBCCs()
+    {
+        foreach ($this->bcc as $bcc) {
+            unset($this->all_recipients[strtolower($bcc[0])]);
+        }
+        $this->bcc = array();
+    }
+
+    /**
+     * Clear all ReplyTo recipients.
+     * @return void
+     */
+    public function clearReplyTos()
+    {
+        $this->ReplyTo = array();
+    }
+
+    /**
+     * Clear all recipient types.
+     * @return void
+     */
+    public function clearAllRecipients()
+    {
+        $this->to = array();
+        $this->cc = array();
+        $this->bcc = array();
+        $this->all_recipients = 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) and array_key_exists('smtp_msg', $lasterror)) {
+                $msg .= '<p>' . $this->lang('smtp_error') . $lasterror['smtp_msg'] . "</p>\n";
+            }
+        }
+        $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 (isset($this->language[$key])) {
+            return $this->language[$key];
+        } else {
+            return 'Language string failed to load: ' . $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);
+        }
+    }
+
+    /**
+     * Create a message from an HTML string.
+     * Automatically makes modifications for inline images and backgrounds
+     * and creates a plain-text version by converting the HTML.
+     * Overwrites any existing values in $this->Body and $this->AltBody
+     * @access public
+     * @param string $message HTML message string
+     * @param string $basedir baseline directory for path
+     * @param boolean $advanced Whether to use the advanced HTML to text converter
+     * @return string $message
+     */
+    public function msgHTML($message, $basedir = '', $advanced = false)
+    {
+        preg_match_all('/(src|background)=["\'](.*)["\']/Ui', $message, $images);
+        if (isset($images[2])) {
+            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, '', 'base64', $match[1])) {
+                        $message = preg_replace(
+                            '/' . $images[1][$imgindex] . '=["\']' . preg_quote($url, '/') . '["\']/Ui',
+                            $images[1][$imgindex] . '="cid:' . $cid . '"',
+                            $message
+                        );
+                    }
+                } elseif (!preg_match('#^[A-z]+://#', $url)) {
+                    // Do not change urls for absolute images (thanks to corvuscorax)
+                    $filename = basename($url);
+                    $directory = dirname($url);
+                    if ($directory == '.') {
+                        $directory = '';
+                    }
+                    $cid = md5($url) . '@phpmailer.0'; // RFC2392 S 2
+                    if (strlen($basedir) > 1 && substr($basedir, -1) != '/') {
+                        $basedir .= '/';
+                    }
+                    if (strlen($directory) > 1 && substr($directory, -1) != '/') {
+                        $directory .= '/';
+                    }
+                    if ($this->addEmbeddedImage(
+                        $basedir . $directory . $filename,
+                        $cid,
+                        $filename,
+                        'base64',
+                        self::_mime_types(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 (empty($this->AltBody)) {
+            $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.
+     * @param string $html The HTML text to convert
+     * @param boolean $advanced Should this use the more complex html2text converter or just a simple one?
+     * @return string
+     */
+    public function html2text($html, $advanced = false)
+    {
+        if ($advanced) {
+            require_once 'extras/class.html2text.php';
+            $htmlconverter = new html2text($html);
+            return $htmlconverter->get_text();
+        }
+        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',
+            'hqx' => 'application/mac-binhex40',
+            'cpt' => 'application/mac-compactpro',
+            'bin' => 'application/macbinary',
+            'doc' => 'application/msword',
+            'word' => 'application/msword',
+            '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',
+            'js' => 'application/x-javascript',
+            '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'
+        );
+        return (array_key_exists(strtolower($ext), $mimes) ? $mimes[strtolower($ext)]: '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 ($qpos !== false) {
+            $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.
+     *
+     * Usage Example:
+     * $page->set('X-Priority', '3');
+     *
+     * @access public
+     * @param string $name
+     * @param mixed $value
+     * NOTE: will not work with arrays, there are no arrays to set/reset
+     * @throws phpmailerException
+     * @return boolean
+     * @TODO Should this not be using __set() magic function?
+     */
+    public function set($name, $value = '')
+    {
+        try {
+            if (isset($this->$name)) {
+                $this->$name = $value;
+            } else {
+                throw new phpmailerException($this->lang('variable_set') . $name, self::STOP_CRITICAL);
+            }
+        } catch (Exception $exc) {
+            $this->setError($exc->getMessage());
+            if ($exc->getCode() == self::STOP_CRITICAL) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 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
+     */
+    public function sign($cert_filename, $key_filename, $key_pass)
+    {
+        $this->sign_cert_file = $cert_filename;
+        $this->sign_key_file = $key_filename;
+        $this->sign_key_pass = $key_pass;
+    }
+
+    /**
+     * 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
+     */
+    public function DKIM_Sign($signHeader)
+    {
+        if (!defined('PKCS7_TEXT')) {
+            if ($this->exceptions) {
+                throw new phpmailerException($this->lang('signing') . ' OpenSSL extension missing.');
+            }
+            return '';
+        }
+        $privKeyStr = file_get_contents($this->DKIM_private);
+        if ($this->DKIM_passphrase != '') {
+            $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase);
+        } else {
+            $privKey = $privKeyStr;
+        }
+        if (openssl_sign($signHeader, $signature, $privKey)) {
+            return base64_encode($signature);
+        }
+        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+/', ' ', $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-sha1'; // 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 = '';
+        $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';
+            } else {
+                if ($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));
+        $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*', sha1($body))); // Base64 of packed binary SHA-1 hash of body
+        $ident = ($this->DKIM_identity == '') ? '' : ' 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:Subject;\r\n" .
+            "\td=" . $this->DKIM_domain . ';' . $ident . "\r\n" .
+            "\tz=$from\r\n" .
+            "\t|$to\r\n" .
+            "\t|$subject;\r\n" .
+            "\tbh=" . $DKIMb64 . ";\r\n" .
+            "\tb=";
+        $toSign = $this->DKIM_HeaderC(
+            $from_header . "\r\n" . $to_header . "\r\n" . $subject_header . "\r\n" . $dkimhdrs
+        );
+        $signed = $this->DKIM_Sign($toSign);
+        return $dkimhdrs . $signed . "\r\n";
+    }
+
+    /**
+     * Allows for public read access to 'to' property.
+     * @access public
+     * @return array
+     */
+    public function getToAddresses()
+    {
+        return $this->to;
+    }
+
+    /**
+     * Allows for public read access to 'cc' property.
+     * @access public
+     * @return array
+     */
+    public function getCcAddresses()
+    {
+        return $this->cc;
+    }
+
+    /**
+     * Allows for public read access to 'bcc' property.
+     * @access public
+     * @return array
+     */
+    public function getBccAddresses()
+    {
+        return $this->bcc;
+    }
+
+    /**
+     * Allows for public read access to 'ReplyTo' property.
+     * @access public
+     * @return array
+     */
+    public function getReplyToAddresses()
+    {
+        return $this->ReplyTo;
+    }
+
+    /**
+     * Allows for public read access to 'all_recipients' property.
+     * @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>' . $this->getMessage() . "</strong><br />\n";
+        return $errorMsg;
+    }
+}
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/class.pop3.php b/~dev_rating/modules/mail/vendor/PHPMailer/class.pop3.php
new file mode 100644
index 0000000000000000000000000000000000000000..9d3e7bdccba5a17debd5a5eb4313685f3896da3f
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/class.pop3.php
@@ -0,0 +1,397 @@
+<?php
+/**
+ * PHPMailer POP-Before-SMTP Authentication Class.
+ * PHP Version 5
+ * @package PHPMailer
+ * @link https://github.com/PHPMailer/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)
+ * @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 POP-Before-SMTP Authentication Class.
+ * Specifically for PHPMailer to use for RFC1939 POP-before-SMTP authentication.
+ * Does not support APOP.
+ * @package PHPMailer
+ * @author Richard Davey (original author) <rich@corephp.co.uk>
+ * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
+ * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
+ * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
+ */
+class POP3
+{
+    /**
+     * The POP3 PHPMailer Version number.
+     * @type string
+     * @access public
+     */
+    public $Version = '5.2.9';
+
+    /**
+     * Default POP3 port number.
+     * @type integer
+     * @access public
+     */
+    public $POP3_PORT = 110;
+
+    /**
+     * Default timeout in seconds.
+     * @type integer
+     * @access public
+     */
+    public $POP3_TIMEOUT = 30;
+
+    /**
+     * POP3 Carriage Return + Line Feed.
+     * @type string
+     * @access public
+     * @deprecated Use the constant instead
+     */
+    public $CRLF = "\r\n";
+
+    /**
+     * Debug display level.
+     * Options: 0 = no, 1+ = yes
+     * @type integer
+     * @access public
+     */
+    public $do_debug = 0;
+
+    /**
+     * POP3 mail server hostname.
+     * @type string
+     * @access public
+     */
+    public $host;
+
+    /**
+     * POP3 port number.
+     * @type integer
+     * @access public
+     */
+    public $port;
+
+    /**
+     * POP3 Timeout Value in seconds.
+     * @type integer
+     * @access public
+     */
+    public $tval;
+
+    /**
+     * POP3 username
+     * @type string
+     * @access public
+     */
+    public $username;
+
+    /**
+     * POP3 password.
+     * @type string
+     * @access public
+     */
+    public $password;
+
+    /**
+     * Resource handle for the POP3 connection socket.
+     * @type resource
+     * @access private
+     */
+    private $pop_conn;
+
+    /**
+     * Are we connected?
+     * @type boolean
+     * @access private
+     */
+    private $connected = false;
+
+    /**
+     * Error container.
+     * @type array
+     * @access private
+     */
+    private $errors = array();
+
+    /**
+     * Line break constant
+     */
+    const CRLF = "\r\n";
+
+    /**
+     * Simple static wrapper for all-in-one POP before SMTP
+     * @param $host
+     * @param boolean $port
+     * @param boolean $tval
+     * @param string $username
+     * @param string $password
+     * @param integer $debug_level
+     * @return boolean
+     */
+    public static function popBeforeSmtp(
+        $host,
+        $port = false,
+        $tval = false,
+        $username = '',
+        $password = '',
+        $debug_level = 0
+    ) {
+        $pop = new POP3;
+        return $pop->authorise($host, $port, $tval, $username, $password, $debug_level);
+    }
+
+    /**
+     * Authenticate with a POP3 server.
+     * A connect, login, disconnect sequence
+     * appropriate for POP-before SMTP authorisation.
+     * @access public
+     * @param string $host The hostname to connect to
+     * @param integer|boolean $port The port number to connect to
+     * @param integer|boolean $timeout The timeout value
+     * @param string $username
+     * @param string $password
+     * @param integer $debug_level
+     * @return boolean
+     */
+    public function authorise($host, $port = false, $timeout = false, $username = '', $password = '', $debug_level = 0)
+    {
+        $this->host = $host;
+        // If no port value provided, use default
+        if ($port === false) {
+            $this->port = $this->POP3_PORT;
+        } else {
+            $this->port = (integer)$port;
+        }
+        // If no timeout value provided, use default
+        if ($timeout === false) {
+            $this->tval = $this->POP3_TIMEOUT;
+        } else {
+            $this->tval = (integer)$timeout;
+        }
+        $this->do_debug = $debug_level;
+        $this->username = $username;
+        $this->password = $password;
+        //  Reset the error log
+        $this->errors = array();
+        //  connect
+        $result = $this->connect($this->host, $this->port, $this->tval);
+        if ($result) {
+            $login_result = $this->login($this->username, $this->password);
+            if ($login_result) {
+                $this->disconnect();
+                return true;
+            }
+        }
+        // We need to disconnect regardless of whether the login succeeded
+        $this->disconnect();
+        return false;
+    }
+
+    /**
+     * Connect to a POP3 server.
+     * @access public
+     * @param string $host
+     * @param integer|boolean $port
+     * @param integer $tval
+     * @return boolean
+     */
+    public function connect($host, $port = false, $tval = 30)
+    {
+        //  Are we already connected?
+        if ($this->connected) {
+            return true;
+        }
+
+        //On Windows this will raise a PHP Warning error if the hostname doesn't exist.
+        //Rather than suppress it with @fsockopen, capture it cleanly instead
+        set_error_handler(array($this, 'catchWarning'));
+
+        if ($port === false) {
+            $port = $this->POP3_PORT;
+        }
+
+        //  connect to the POP3 server
+        $this->pop_conn = fsockopen(
+            $host, //  POP3 Host
+            $port, //  Port #
+            $errno, //  Error Number
+            $errstr, //  Error Message
+            $tval
+        ); //  Timeout (seconds)
+        //  Restore the error handler
+        restore_error_handler();
+
+        //  Did we connect?
+        if ($this->pop_conn === false) {
+            //  It would appear not...
+            $this->setError(array(
+                'error' => "Failed to connect to server $host on port $port",
+                'errno' => $errno,
+                'errstr' => $errstr
+            ));
+            return false;
+        }
+
+        //  Increase the stream time-out
+        stream_set_timeout($this->pop_conn, $tval, 0);
+
+        //  Get the POP3 server response
+        $pop3_response = $this->getResponse();
+        //  Check for the +OK
+        if ($this->checkResponse($pop3_response)) {
+            //  The connection is established and the POP3 server is talking
+            $this->connected = true;
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Log in to the POP3 server.
+     * Does not support APOP (RFC 2828, 4949).
+     * @access public
+     * @param string $username
+     * @param string $password
+     * @return boolean
+     */
+    public function login($username = '', $password = '')
+    {
+        if (!$this->connected) {
+            $this->setError('Not connected to POP3 server');
+        }
+        if (empty($username)) {
+            $username = $this->username;
+        }
+        if (empty($password)) {
+            $password = $this->password;
+        }
+
+        // Send the Username
+        $this->sendString("USER $username" . self::CRLF);
+        $pop3_response = $this->getResponse();
+        if ($this->checkResponse($pop3_response)) {
+            // Send the Password
+            $this->sendString("PASS $password" . self::CRLF);
+            $pop3_response = $this->getResponse();
+            if ($this->checkResponse($pop3_response)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Disconnect from the POP3 server.
+     * @access public
+     */
+    public function disconnect()
+    {
+        $this->sendString('QUIT');
+        //The QUIT command may cause the daemon to exit, which will kill our connection
+        //So ignore errors here
+        try {
+            @fclose($this->pop_conn);
+        } catch (Exception $e) {
+            //Do nothing
+        };
+    }
+
+    /**
+     * Get a response from the POP3 server.
+     * $size is the maximum number of bytes to retrieve
+     * @param integer $size
+     * @return string
+     * @access private
+     */
+    private function getResponse($size = 128)
+    {
+        $response = fgets($this->pop_conn, $size);
+        if ($this->do_debug >= 1) {
+            echo "Server -> Client: $response";
+        }
+        return $response;
+    }
+
+    /**
+     * Send raw data to the POP3 server.
+     * @param string $string
+     * @return integer
+     * @access private
+     */
+    private function sendString($string)
+    {
+        if ($this->pop_conn) {
+            if ($this->do_debug >= 2) { //Show client messages when debug >= 2
+                echo "Client -> Server: $string";
+            }
+            return fwrite($this->pop_conn, $string, strlen($string));
+        }
+        return 0;
+    }
+
+    /**
+     * Checks the POP3 server response.
+     * Looks for for +OK or -ERR.
+     * @param string $string
+     * @return boolean
+     * @access private
+     */
+    private function checkResponse($string)
+    {
+        if (substr($string, 0, 3) !== '+OK') {
+            $this->setError(array(
+                'error' => "Server reported an error: $string",
+                'errno' => 0,
+                'errstr' => ''
+            ));
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * Add an error to the internal error store.
+     * Also display debug output if it's enabled.
+     * @param $error
+     */
+    private function setError($error)
+    {
+        $this->errors[] = $error;
+        if ($this->do_debug >= 1) {
+            echo '<pre>';
+            foreach ($this->errors as $error) {
+                print_r($error);
+            }
+            echo '</pre>';
+        }
+    }
+
+    /**
+     * POP3 connection error handler.
+     * @param integer $errno
+     * @param string $errstr
+     * @param string $errfile
+     * @param integer $errline
+     * @access private
+     */
+    private function catchWarning($errno, $errstr, $errfile, $errline)
+    {
+        $this->setError(array(
+            'error' => "Connecting to the POP3 server raised a PHP warning: ",
+            'errno' => $errno,
+            'errstr' => $errstr,
+            'errfile' => $errfile,
+            'errline' => $errline
+        ));
+    }
+}
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/class.smtp.php b/~dev_rating/modules/mail/vendor/PHPMailer/class.smtp.php
new file mode 100644
index 0000000000000000000000000000000000000000..9d1f2283ddb3fe68394d666cac2fdf9772681ae2
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/class.smtp.php
@@ -0,0 +1,966 @@
+<?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 <unknown@example.com>
+ * @author Marcus Bointon <phpmailer@synchromedia.co.uk>
+ */
+class SMTP
+{
+    /**
+     * The PHPMailer SMTP version number.
+     * @type string
+     */
+    const VERSION = '5.2.9';
+
+    /**
+     * SMTP line break constant.
+     * @type string
+     */
+    const CRLF = "\r\n";
+
+    /**
+     * The SMTP port to use if one is not specified.
+     * @type integer
+     */
+    const DEFAULT_SMTP_PORT = 25;
+
+    /**
+     * The maximum line length allowed by RFC 2822 section 2.1.1
+     * @type 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.
+     * @type string
+     * @deprecated Use the `VERSION` constant instead
+     * @see SMTP::VERSION
+     */
+    public $Version = '5.2.9';
+
+    /**
+     * SMTP server port number.
+     * @type 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.
+     * @type 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
+     * @type 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>
+     * @type 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
+     * @type 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
+     * @type integer
+     */
+    public $Timeout = 300;
+
+    /**
+     * The SMTP timelimit value for reads, in seconds.
+     * @type integer
+     */
+    public $Timelimit = 30;
+
+    /**
+     * The socket for the server connection.
+     * @type resource
+     */
+    protected $smtp_conn;
+
+    /**
+     * Error message, if any, for the last call.
+     * @type array
+     */
+    protected $error = array();
+
+    /**
+     * The reply the server sent to us for HELO.
+     * If null, no HELO string has yet been received.
+     * @type string|null
+     */
+    protected $helo_rply = null;
+
+    /**
+     * The most recent reply received from the server.
+     * @type 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;
+        }
+        if (is_callable($this->Debugoutput)) {
+            call_user_func($this->Debugoutput, $str, $this->do_debug);
+            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|\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->error = array();
+        // Make sure we are __not__ connected
+        if ($this->connected()) {
+            // Already connected, generate error
+            $this->error = array('error' => '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, t=$timeout, opt=".var_export($options, true),
+            self::DEBUG_CONNECTION
+        );
+        $errno = 0;
+        $errstr = '';
+        if ($streamok) {
+            $socket_context = stream_context_create($options);
+            //Suppress errors; connection failures are handled at a higher level
+            $this->smtp_conn = @stream_socket_client(
+                $host . ":" . $port,
+                $errno,
+                $errstr,
+                $timeout,
+                STREAM_CLIENT_CONNECT,
+                $socket_context
+            );
+        } 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
+            );
+            $this->smtp_conn = fsockopen(
+                $host,
+                $port,
+                $errno,
+                $errstr,
+                $timeout
+            );
+        }
+        // Verify we connected properly
+        if (!is_resource($this->smtp_conn)) {
+            $this->error = array(
+                'error' => 'Failed to connect to server',
+                'errno' => $errno,
+                'errstr' => $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');
+            if ($max != 0 && $timeout > $max) { // Don't bother if unlimited
+                @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;
+        }
+        // Begin encrypted connection
+        if (!stream_socket_enable_crypto(
+            $this->smtp_conn,
+            true,
+            STREAM_CRYPTO_METHOD_TLS_CLIENT
+        )) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 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)
+     * @param string $realm       The auth realm for NTLM
+     * @param string $workstation The auth workstation for NTLM
+     * @access public
+     * @return boolean True if successfully authenticated.
+     */
+    public function authenticate(
+        $username,
+        $password,
+        $authtype = 'LOGIN',
+        $realm = '',
+        $workstation = ''
+    ) {
+        if (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 '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->error = array('error' => $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);
+        }
+        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->error = array();
+        $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)
+    {
+        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;
+            }
+            // ok we need to break this line up into several smaller lines
+            //This is a small micro-optimisation: isset($str[$len]) is equivalent to (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), ' ');
+                if (!$pos) { //Deliberately matches both false and 0
+                    //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
+        return $this->sendCommand('DATA END', '.', 250);
+    }
+
+    /**
+     * 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;
+        return $noerror;
+    }
+
+    /**
+     * 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 $toaddr The address the message is being sent to
+     * @access public
+     * @return boolean
+     */
+    public function recipient($toaddr)
+    {
+        return $this->sendCommand(
+            'RCPT TO',
+            'RCPT TO:<' . $toaddr . '>',
+            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->error = array(
+                'error' => "Called $command without being connected"
+            );
+            return false;
+        }
+        $this->client_send($commandstring . self::CRLF);
+
+        $this->last_reply = $this->get_lines();
+        $code = substr($this->last_reply, 0, 3);
+
+        $this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER);
+
+        if (!in_array($code, (array)$expect)) {
+            $this->error = array(
+                'error' => "$command command failed",
+                'smtp_code' => $code,
+                'detail' => substr($this->last_reply, 4)
+            );
+            $this->edebug(
+                'SMTP ERROR: ' . $this->error['error'] . ': ' . $this->last_reply,
+                self::DEBUG_CLIENT
+            );
+            return false;
+        }
+
+        $this->error = array();
+        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->error = array(
+            'error' => '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);
+        return fwrite($this->smtp_conn, $data);
+    }
+
+    /**
+     * Get the latest error.
+     * @access public
+     * @return array
+     */
+    public function getError()
+    {
+        return $this->error;
+    }
+
+    /**
+     * 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 was \"$data\"", self::DEBUG_LOWLEVEL);
+            $this->edebug("SMTP -> get_lines(): \$str is \"$str\"", self::DEBUG_LOWLEVEL);
+            $data .= $str;
+            $this->edebug("SMTP -> get_lines(): \$data is \"$data\"", self::DEBUG_LOWLEVEL);
+            // If 4th character is a space, we are done reading, break the loop, micro-optimisation over strlen
+            if ((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 debug output method.
+     * @param string $method The function/method to use for debugging output.
+     */
+    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;
+    }
+}
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/extras/EasyPeasyICS.php b/~dev_rating/modules/mail/vendor/PHPMailer/extras/EasyPeasyICS.php
new file mode 100644
index 0000000000000000000000000000000000000000..f076895588f8d15523bce67e4b6d48f97e1c1f59
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/extras/EasyPeasyICS.php
@@ -0,0 +1,90 @@
+<?php
+
+/* ------------------------------------------------------------------------ */
+/* EasyPeasyICS
+/* ------------------------------------------------------------------------ */
+/* Manuel Reinhard, manu@sprain.ch
+/* Twitter: @sprain
+/* Web: www.sprain.ch
+/*
+/* Built with inspiration by
+/" http://stackoverflow.com/questions/1463480/how-can-i-use-php-to-dynamically-publish-an-ical-file-to-be-read-by-google-calend/1464355#1464355
+/* ------------------------------------------------------------------------ */
+/* History:
+/* 2010/12/17 - Manuel Reinhard - when it all started
+/* ------------------------------------------------------------------------ */  
+
+class EasyPeasyICS {
+
+	protected $calendarName;
+	protected $events = array();
+	
+
+	/**
+	 * Constructor
+	 * @param string $calendarName
+	 */	
+	public function __construct($calendarName=""){
+		$this->calendarName = $calendarName;
+	}//function
+
+
+	/**
+	 * Add event to calendar
+	 * @param string $calendarName
+	 */	
+	public function addEvent($start, $end, $summary="", $description="", $url=""){
+		$this->events[] = array(
+			"start" => $start,
+			"end"   => $end,
+			"summary" => $summary,
+			"description" => $description,
+			"url" => $url
+		);
+	}//function
+	
+	
+	public function render($output = true){
+		
+		//start Variable
+		$ics = "";
+	
+		//Add header
+		$ics .= "BEGIN:VCALENDAR
+METHOD:PUBLISH
+VERSION:2.0
+X-WR-CALNAME:".$this->calendarName."
+PRODID:-//hacksw/handcal//NONSGML v1.0//EN";
+		
+		//Add events
+		foreach($this->events as $event){
+			$ics .= "
+BEGIN:VEVENT
+UID:". md5(uniqid(mt_rand(), true)) ."@EasyPeasyICS.php
+DTSTAMP:" . gmdate('Ymd').'T'. gmdate('His') . "Z
+DTSTART:".gmdate('Ymd', $event["start"])."T".gmdate('His', $event["start"])."Z
+DTEND:".gmdate('Ymd', $event["end"])."T".gmdate('His', $event["end"])."Z
+SUMMARY:".str_replace("\n", "\\n", $event['summary'])."
+DESCRIPTION:".str_replace("\n", "\\n", $event['description'])."
+URL;VALUE=URI:".$event['url']."
+END:VEVENT";
+		}//foreach
+		
+		
+		//Footer
+		$ics .= "
+END:VCALENDAR";
+
+
+		if ($output) {
+			//Output
+			header('Content-type: text/calendar; charset=utf-8');
+			header('Content-Disposition: inline; filename='.$this->calendarName.'.ics');
+			echo $ics;
+		} else {
+			return $ics;
+		}
+
+	}//function
+
+}//class
\ No newline at end of file
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/extras/README.md b/~dev_rating/modules/mail/vendor/PHPMailer/extras/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..b51e7aa3c32bb394814cb49dc04b54a7a190ae8a
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/extras/README.md
@@ -0,0 +1,21 @@
+#PHPMailer Extras
+
+These classes provide optional additional functions to PHPMailer.
+
+These are not loaded by the PHPMailer autoloader, so in some cases you may need to `require` them yourself before using them.
+
+##HTML2Text
+
+This class was written by Jon Abernathy and provides a simple conversion of HTML to plain-text, while attempting to preserve some aspects of the formatting. It is used in PHPMailer if you set the `advanced` parameter to `true` in either the `msgHTML()` or `html2text` methods of PHPMailer.
+
+##EasyPeasyICS
+
+This class was originally written by Manuel Reinhard and provides a simple means of generating ICS/vCal files that are used in sending calendar events. PHPMailer does not use it diorectly, but you can use it to generate content appropriate for placing in the `Ical` property of PHPMailer. The PHPMailer project is now its official home as Manuel has given permission for that and is no longer maintaining it himself.
+
+##htmlfilter
+
+This class by Konstantin Riabitsev and Jim Jagielski implements HTML filtering to remove potentially malicious tags, such as `<script>` or `onclick=` attributes that can result in XSS attacks. This is a simple filter and is not as comprehensive as [HTMLawed](http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/) or [HTMLPurifier](http://htmlpurifier.org), but it's easier to use and considerably better than nothing! PHPMailer does not use it directly, but you may want to apply it to user-supplied HTML before using it as a message body.
+
+##NTLM_SASL_client
+
+This class by Manuel Lemos (bundled with permission) adds the ability to authenticate with Microsoft Windows mail servers that use NTLM-based authentication. It is used by PHPMailer if you send via SMTP and set the `AuthType` property to `NTLM`; you will also need to use the `Realm` and `Workstation` properties. The original source is [here](http://www.phpclasses.org/browse/file/7495.html).
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/extras/class.html2text.php b/~dev_rating/modules/mail/vendor/PHPMailer/extras/class.html2text.php
new file mode 100644
index 0000000000000000000000000000000000000000..20609919b4a916142e1b92198beeefa6ad6d435c
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/extras/class.html2text.php
@@ -0,0 +1,677 @@
+<?php
+/*************************************************************************
+ *                                                                       *
+ * Converts HTML to formatted plain text                                 *
+ *                                                                       *
+ * Portions Copyright (c) 2005-2007 Jon Abernathy <jon@chuggnutt.com>    *
+ *                                                                       *
+ * This script is free software; you can redistribute it and/or modify   *
+ * it under the terms of the GNU General Public License as published by  *
+ * the Free Software Foundation; either version 2 of the License, or     *
+ * (at your option) any later version.                                   *
+ *                                                                       *
+ * The GNU General Public License can be found at                        *
+ * http://www.gnu.org/copyleft/gpl.html.                                 *
+ *                                                                       *
+ * This script is distributed in the hope that it will be useful,        *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the          *
+ * GNU General Public License for more details.                          *
+ *                                                                       *
+ *************************************************************************/
+
+/**
+ * Converts HTML to formatted plain text
+ */
+class Html2Text
+{
+    /**
+     * Contains the HTML content to convert.
+     *
+     * @type string
+     */
+    protected $html;
+
+    /**
+     * Contains the converted, formatted text.
+     *
+     * @type string
+     */
+    protected $text;
+
+    /**
+     * Maximum width of the formatted text, in columns.
+     *
+     * Set this value to 0 (or less) to ignore word wrapping
+     * and not constrain text to a fixed-width column.
+     *
+     * @type integer
+     */
+    protected $width = 70;
+
+    /**
+     * List of preg* regular expression patterns to search for,
+     * used in conjunction with $replace.
+     *
+     * @type array
+     * @see $replace
+     */
+    protected $search = array(
+        "/\r/",                                  // Non-legal carriage return
+        "/[\n\t]+/",                             // Newlines and tabs
+        '/<head[^>]*>.*?<\/head>/i',             // <head>
+        '/<script[^>]*>.*?<\/script>/i',         // <script>s -- which strip_tags supposedly has problems with
+        '/<style[^>]*>.*?<\/style>/i',           // <style>s -- which strip_tags supposedly has problems with
+        '/<p[^>]*>/i',                           // <P>
+        '/<br[^>]*>/i',                          // <br>
+        '/<i[^>]*>(.*?)<\/i>/i',                 // <i>
+        '/<em[^>]*>(.*?)<\/em>/i',               // <em>
+        '/(<ul[^>]*>|<\/ul>)/i',                 // <ul> and </ul>
+        '/(<ol[^>]*>|<\/ol>)/i',                 // <ol> and </ol>
+        '/(<dl[^>]*>|<\/dl>)/i',                 // <dl> and </dl>
+        '/<li[^>]*>(.*?)<\/li>/i',               // <li> and </li>
+        '/<dd[^>]*>(.*?)<\/dd>/i',               // <dd> and </dd>
+        '/<dt[^>]*>(.*?)<\/dt>/i',               // <dt> and </dt>
+        '/<li[^>]*>/i',                          // <li>
+        '/<hr[^>]*>/i',                          // <hr>
+        '/<div[^>]*>/i',                         // <div>
+        '/(<table[^>]*>|<\/table>)/i',           // <table> and </table>
+        '/(<tr[^>]*>|<\/tr>)/i',                 // <tr> and </tr>
+        '/<td[^>]*>(.*?)<\/td>/i',               // <td> and </td>
+        '/<span class="_html2text_ignore">.+?<\/span>/i'  // <span class="_html2text_ignore">...</span>
+    );
+
+    /**
+     * List of pattern replacements corresponding to patterns searched.
+     *
+     * @type array
+     * @see $search
+     */
+    protected $replace = array(
+        '',                                     // Non-legal carriage return
+        ' ',                                    // Newlines and tabs
+        '',                                     // <head>
+        '',                                     // <script>s -- which strip_tags supposedly has problems with
+        '',                                     // <style>s -- which strip_tags supposedly has problems with
+        "\n\n",                                 // <P>
+        "\n",                                   // <br>
+        '_\\1_',                                // <i>
+        '_\\1_',                                // <em>
+        "\n\n",                                 // <ul> and </ul>
+        "\n\n",                                 // <ol> and </ol>
+        "\n\n",                                 // <dl> and </dl>
+        "\t* \\1\n",                            // <li> and </li>
+        " \\1\n",                               // <dd> and </dd>
+        "\t* \\1",                              // <dt> and </dt>
+        "\n\t* ",                               // <li>
+        "\n-------------------------\n",        // <hr>
+        "<div>\n",                              // <div>
+        "\n\n",                                 // <table> and </table>
+        "\n",                                   // <tr> and </tr>
+        "\t\t\\1\n",                            // <td> and </td>
+        ""                                      // <span class="_html2text_ignore">...</span>
+    );
+
+    /**
+     * List of preg* regular expression patterns to search for,
+     * used in conjunction with $ent_replace.
+     *
+     * @type array
+     * @see $ent_replace
+     */
+    protected $ent_search = array(
+        '/&(nbsp|#160);/i',                      // Non-breaking space
+        '/&(quot|rdquo|ldquo|#8220|#8221|#147|#148);/i',
+        // Double quotes
+        '/&(apos|rsquo|lsquo|#8216|#8217);/i',   // Single quotes
+        '/&gt;/i',                               // Greater-than
+        '/&lt;/i',                               // Less-than
+        '/&(copy|#169);/i',                      // Copyright
+        '/&(trade|#8482|#153);/i',               // Trademark
+        '/&(reg|#174);/i',                       // Registered
+        '/&(mdash|#151|#8212);/i',               // mdash
+        '/&(ndash|minus|#8211|#8722);/i',        // ndash
+        '/&(bull|#149|#8226);/i',                // Bullet
+        '/&(pound|#163);/i',                     // Pound sign
+        '/&(euro|#8364);/i',                     // Euro sign
+        '/&(amp|#38);/i',                        // Ampersand: see _converter()
+        '/[ ]{2,}/',                             // Runs of spaces, post-handling
+    );
+
+    /**
+     * List of pattern replacements corresponding to patterns searched.
+     *
+     * @type array
+     * @see $ent_search
+     */
+    protected $ent_replace = array(
+        ' ',                                    // Non-breaking space
+        '"',                                    // Double quotes
+        "'",                                    // Single quotes
+        '>',
+        '<',
+        '(c)',
+        '(tm)',
+        '(R)',
+        '--',
+        '-',
+        '*',
+        'ВЈ',
+        'EUR',                                  // Euro sign. € ?
+        '|+|amp|+|',                            // Ampersand: see _converter()
+        ' ',                                    // Runs of spaces, post-handling
+    );
+
+    /**
+     * List of preg* regular expression patterns to search for
+     * and replace using callback function.
+     *
+     * @type array
+     */
+    protected $callback_search = array(
+        '/<(a) [^>]*href=("|\')([^"\']+)\2([^>]*)>(.*?)<\/a>/i', // <a href="">
+        '/<(h)[123456]( [^>]*)?>(.*?)<\/h[123456]>/i',           // h1 - h6
+        '/<(b)( [^>]*)?>(.*?)<\/b>/i',                           // <b>
+        '/<(strong)( [^>]*)?>(.*?)<\/strong>/i',                 // <strong>
+        '/<(th)( [^>]*)?>(.*?)<\/th>/i',                         // <th> and </th>
+    );
+
+    /**
+     * List of preg* regular expression patterns to search for in PRE body,
+     * used in conjunction with $pre_replace.
+     *
+     * @type array
+     * @see $pre_replace
+     */
+    protected $pre_search = array(
+        "/\n/",
+        "/\t/",
+        '/ /',
+        '/<pre[^>]*>/',
+        '/<\/pre>/'
+    );
+
+    /**
+     * List of pattern replacements corresponding to patterns searched for PRE body.
+     *
+     * @type array
+     * @see $pre_search
+     */
+    protected $pre_replace = array(
+        '<br>',
+        '&nbsp;&nbsp;&nbsp;&nbsp;',
+        '&nbsp;',
+        '',
+        ''
+    );
+
+    /**
+     * Temporary workspace used during PRE processing.
+     *
+     * @type string
+     */
+    protected $pre_content = '';
+
+    /**
+     * Contains a list of HTML tags to allow in the resulting text.
+     *
+     * @type string
+     * @see set_allowed_tags()
+     */
+    protected $allowed_tags = '';
+
+    /**
+     * Contains the base URL that relative links should resolve to.
+     *
+     * @type string
+     */
+    protected $url;
+
+    /**
+     * Indicates whether content in the $html variable has been converted yet.
+     *
+     * @type boolean
+     * @see $html, $text
+     */
+    protected $_converted = false;
+
+    /**
+     * Contains URL addresses from links to be rendered in plain text.
+     *
+     * @type array
+     * @see _build_link_list()
+     */
+    protected $_link_list = array();
+
+    /**
+     * Various configuration options (able to be set in the constructor)
+     *
+     * @type array
+     */
+    protected $_options = array(
+        // 'none'
+        // 'inline' (show links inline)
+        // 'nextline' (show links on the next line)
+        // 'table' (if a table of link URLs should be listed after the text.
+        'do_links' => 'inline',
+        //  Maximum width of the formatted text, in columns.
+        //  Set this value to 0 (or less) to ignore word wrapping
+        //  and not constrain text to a fixed-width column.
+        'width' => 70,
+    );
+
+    /**
+     * Constructor.
+     *
+     * If the HTML source string (or file) is supplied, the class
+     * will instantiate with that source propagated, all that has
+     * to be done it to call get_text().
+     *
+     * @param string $source HTML content
+     * @param boolean $from_file Indicates $source is a file to pull content from
+     * @param array $options Set configuration options
+     */
+    public function __construct($source = '', $from_file = false, $options = array())
+    {
+        $this->_options = array_merge($this->_options, $options);
+
+        if (!empty($source)) {
+            $this->set_html($source, $from_file);
+        }
+
+        $this->set_base_url();
+    }
+
+    /**
+     * Loads source HTML into memory, either from $source string or a file.
+     *
+     * @param string $source HTML content
+     * @param boolean $from_file Indicates $source is a file to pull content from
+     */
+    public function set_html($source, $from_file = false)
+    {
+        if ($from_file && file_exists($source)) {
+            $this->html = file_get_contents($source);
+        } else {
+            $this->html = $source;
+        }
+
+        $this->_converted = false;
+    }
+
+    /**
+     * Returns the text, converted from HTML.
+     *
+     * @return string
+     */
+    public function get_text()
+    {
+        if (!$this->_converted) {
+            $this->_convert();
+        }
+
+        return $this->text;
+    }
+
+    /**
+     * Prints the text, converted from HTML.
+     */
+    public function print_text()
+    {
+        print $this->get_text();
+    }
+
+    /**
+     * Alias to print_text(), operates identically.
+     *
+     * @see print_text()
+     */
+    public function p()
+    {
+        print $this->get_text();
+    }
+
+    /**
+     * Sets the allowed HTML tags to pass through to the resulting text.
+     *
+     * Tags should be in the form "<p>", with no corresponding closing tag.
+     * @param string $allowed_tags
+     */
+    public function set_allowed_tags($allowed_tags = '')
+    {
+        if (!empty($allowed_tags)) {
+            $this->allowed_tags = $allowed_tags;
+        }
+    }
+
+    /**
+     * Sets a base URL to handle relative links.
+     *
+     * @param string $url
+     */
+    public function set_base_url($url = '')
+    {
+        if (empty($url)) {
+            if (!empty($_SERVER['HTTP_HOST'])) {
+                $this->url = 'http://' . $_SERVER['HTTP_HOST'];
+            } else {
+                $this->url = '';
+            }
+        } else {
+            // Strip any trailing slashes for consistency (relative
+            // URLs may already start with a slash like "/file.html")
+            if (substr($url, -1) == '/') {
+                $url = substr($url, 0, -1);
+            }
+            $this->url = $url;
+        }
+    }
+
+    /**
+     * Workhorse function that does actual conversion (calls _converter() method).
+     */
+    protected function _convert()
+    {
+        // Variables used for building the link list
+        $this->_link_list = array();
+
+        $text = trim(stripslashes($this->html));
+
+        // Convert HTML to TXT
+        $this->_converter($text);
+
+        // Add link list
+        if (!empty($this->_link_list)) {
+            $text .= "\n\nLinks:\n------\n";
+            foreach ($this->_link_list as $idx => $url) {
+                $text .= '[' . ($idx + 1) . '] ' . $url . "\n";
+            }
+        }
+
+        $this->text = $text;
+
+        $this->_converted = true;
+    }
+
+    /**
+     * Workhorse function that does actual conversion.
+     *
+     * First performs custom tag replacement specified by $search and
+     * $replace arrays. Then strips any remaining HTML tags, reduces whitespace
+     * and newlines to a readable format, and word wraps the text to
+     * $this->_options['width'] characters.
+     *
+     * @param string $text Reference to HTML content string
+     */
+    protected function _converter(&$text)
+    {
+        // Convert <BLOCKQUOTE> (before PRE!)
+        $this->_convert_blockquotes($text);
+
+        // Convert <PRE>
+        $this->_convert_pre($text);
+
+        // Run our defined tags search-and-replace
+        $text = preg_replace($this->search, $this->replace, $text);
+
+        // Run our defined tags search-and-replace with callback
+        $text = preg_replace_callback($this->callback_search, array($this, '_preg_callback'), $text);
+
+        // Strip any other HTML tags
+        $text = strip_tags($text, $this->allowed_tags);
+
+        // Run our defined entities/characters search-and-replace
+        $text = preg_replace($this->ent_search, $this->ent_replace, $text);
+
+        // Replace known html entities
+        $text = html_entity_decode($text, ENT_QUOTES);
+
+        // Remove unknown/unhandled entities (this cannot be done in search-and-replace block)
+        $text = preg_replace('/&([a-zA-Z0-9]{2,6}|#[0-9]{2,4});/', '', $text);
+
+        // Convert "|+|amp|+|" into "&", need to be done after handling of unknown entities
+        // This properly handles situation of "&amp;quot;" in input string
+        $text = str_replace('|+|amp|+|', '&', $text);
+
+        // Bring down number of empty lines to 2 max
+        $text = preg_replace("/\n\s+\n/", "\n\n", $text);
+        $text = preg_replace("/[\n]{3,}/", "\n\n", $text);
+
+        // remove leading empty lines (can be produced by eg. P tag on the beginning)
+        $text = ltrim($text, "\n");
+
+        // Wrap the text to a readable format
+        // for PHP versions >= 4.0.2. Default width is 75
+        // If width is 0 or less, don't wrap the text.
+        if ($this->_options['width'] > 0) {
+            $text = wordwrap($text, $this->_options['width']);
+        }
+    }
+
+    /**
+     * Helper function called by preg_replace() on link replacement.
+     *
+     * Maintains an internal list of links to be displayed at the end of the
+     * text, with numeric indices to the original point in the text they
+     * appeared. Also makes an effort at identifying and handling absolute
+     * and relative links.
+     *
+     * @param string $link URL of the link
+     * @param string $display Part of the text to associate number with
+     * @param null $link_override
+     * @return string
+     */
+    protected function _build_link_list($link, $display, $link_override = null)
+    {
+        $link_method = ($link_override) ? $link_override : $this->_options['do_links'];
+        if ($link_method == 'none') {
+            return $display;
+        }
+
+
+        // Ignored link types
+        if (preg_match('!^(javascript:|mailto:|#)!i', $link)) {
+            return $display;
+        }
+
+        if (preg_match('!^([a-z][a-z0-9.+-]+:)!i', $link)) {
+            $url = $link;
+        } else {
+            $url = $this->url;
+            if (substr($link, 0, 1) != '/') {
+                $url .= '/';
+            }
+            $url .= "$link";
+        }
+
+        if ($link_method == 'table') {
+            if (($index = array_search($url, $this->_link_list)) === false) {
+                $index = count($this->_link_list);
+                $this->_link_list[] = $url;
+            }
+
+            return $display . ' [' . ($index + 1) . ']';
+        } elseif ($link_method == 'nextline') {
+            return $display . "\n[" . $url . ']';
+        } else { // link_method defaults to inline
+
+            return $display . ' [' . $url . ']';
+        }
+    }
+
+    /**
+     * Helper function for PRE body conversion.
+     *
+     * @param string $text HTML content
+     */
+    protected function _convert_pre(&$text)
+    {
+        // get the content of PRE element
+        while (preg_match('/<pre[^>]*>(.*)<\/pre>/ismU', $text, $matches)) {
+            $this->pre_content = $matches[1];
+
+            // Run our defined tags search-and-replace with callback
+            $this->pre_content = preg_replace_callback(
+                $this->callback_search,
+                array($this, '_preg_callback'),
+                $this->pre_content
+            );
+
+            // convert the content
+            $this->pre_content = sprintf(
+                '<div><br>%s<br></div>',
+                preg_replace($this->pre_search, $this->pre_replace, $this->pre_content)
+            );
+
+            // replace the content (use callback because content can contain $0 variable)
+            $text = preg_replace_callback(
+                '/<pre[^>]*>.*<\/pre>/ismU',
+                array($this, '_preg_pre_callback'),
+                $text,
+                1
+            );
+
+            // free memory
+            $this->pre_content = '';
+        }
+    }
+
+    /**
+     * Helper function for BLOCKQUOTE body conversion.
+     *
+     * @param string $text HTML content
+     */
+    protected function _convert_blockquotes(&$text)
+    {
+        if (preg_match_all('/<\/*blockquote[^>]*>/i', $text, $matches, PREG_OFFSET_CAPTURE)) {
+            $start = 0;
+            $taglen = 0;
+            $level = 0;
+            $diff = 0;
+            foreach ($matches[0] as $m) {
+                if ($m[0][0] == '<' && $m[0][1] == '/') {
+                    $level--;
+                    if ($level < 0) {
+                        $level = 0; // malformed HTML: go to next blockquote
+                    } elseif ($level > 0) {
+                        // skip inner blockquote
+                    } else {
+                        $end = $m[1];
+                        $len = $end - $taglen - $start;
+                        // Get blockquote content
+                        $body = substr($text, $start + $taglen - $diff, $len);
+
+                        // Set text width
+                        $p_width = $this->_options['width'];
+                        if ($this->_options['width'] > 0) $this->_options['width'] -= 2;
+                        // Convert blockquote content
+                        $body = trim($body);
+                        $this->_converter($body);
+                        // Add citation markers and create PRE block
+                        $body = preg_replace('/((^|\n)>*)/', '\\1> ', trim($body));
+                        $body = '<pre>' . htmlspecialchars($body) . '</pre>';
+                        // Re-set text width
+                        $this->_options['width'] = $p_width;
+                        // Replace content
+                        $text = substr($text, 0, $start - $diff)
+                            . $body . substr($text, $end + strlen($m[0]) - $diff);
+
+                        $diff = $len + $taglen + strlen($m[0]) - strlen($body);
+                        unset($body);
+                    }
+                } else {
+                    if ($level == 0) {
+                        $start = $m[1];
+                        $taglen = strlen($m[0]);
+                    }
+                    $level++;
+                }
+            }
+        }
+    }
+
+    /**
+     * Callback function for preg_replace_callback use.
+     *
+     * @param array $matches PREG matches
+     * @return string
+     */
+    protected function _preg_callback($matches)
+    {
+        switch (strtolower($matches[1])) {
+            case 'b':
+            case 'strong':
+                return $this->_toupper($matches[3]);
+            case 'th':
+                return $this->_toupper("\t\t" . $matches[3] . "\n");
+            case 'h':
+                return $this->_toupper("\n\n" . $matches[3] . "\n\n");
+            case 'a':
+                // override the link method
+                $link_override = null;
+                if (preg_match('/_html2text_link_(\w+)/', $matches[4], $link_override_match)) {
+                    $link_override = $link_override_match[1];
+                }
+                // Remove spaces in URL (#1487805)
+                $url = str_replace(' ', '', $matches[3]);
+
+                return $this->_build_link_list($url, $matches[5], $link_override);
+        }
+        return '';
+    }
+
+    /**
+     * Callback function for preg_replace_callback use in PRE content handler.
+     *
+     * @param array $matches PREG matches
+     * @return string
+     */
+    protected function _preg_pre_callback(
+        /** @noinspection PhpUnusedParameterInspection */
+        $matches)
+    {
+        return $this->pre_content;
+    }
+
+    /**
+     * Strtoupper function with HTML tags and entities handling.
+     *
+     * @param string $str Text to convert
+     * @return string Converted text
+     */
+    private function _toupper($str)
+    {
+        // string can contain HTML tags
+        $chunks = preg_split('/(<[^>]*>)/', $str, null, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
+
+        // convert toupper only the text between HTML tags
+        foreach ($chunks as $idx => $chunk) {
+            if ($chunk[0] != '<') {
+                $chunks[$idx] = $this->_strtoupper($chunk);
+            }
+        }
+
+        return implode($chunks);
+    }
+
+    /**
+     * Strtoupper multibyte wrapper function with HTML entities handling.
+     * Forces mb_strtoupper-call to UTF-8.
+     *
+     * @param string $str Text to convert
+     * @return string Converted text
+     */
+    private function _strtoupper($str)
+    {
+        $str = html_entity_decode($str, ENT_COMPAT);
+
+        if (function_exists('mb_strtoupper'))
+            $str = mb_strtoupper($str, 'UTF-8');
+        else
+            $str = strtoupper($str);
+
+        $str = htmlspecialchars($str, ENT_COMPAT);
+
+        return $str;
+    }
+}
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/extras/htmlfilter.php b/~dev_rating/modules/mail/vendor/PHPMailer/extras/htmlfilter.php
new file mode 100644
index 0000000000000000000000000000000000000000..e91b3147af1b4761f9ff4f50c23472420992e19d
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/extras/htmlfilter.php
@@ -0,0 +1,874 @@
+<?php
+/**
+ * htmlfilter.inc
+ * ---------------
+ * This set of functions allows you to filter html in order to remove
+ * any malicious tags from it. Useful in cases when you need to filter
+ * user input for any cross-site-scripting attempts.
+ *
+ * Copyright (C) 2002-2004 by Duke University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.     See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301  USA
+ *
+ * @Author    Konstantin Riabitsev <icon@linux.duke.edu>
+ * @Author  Jim Jagielski <jim@jaguNET.com / jimjag@gmail.com>
+ */
+
+/**
+ * This function returns the final tag out of the tag name, an array
+ * of attributes, and the type of the tag. This function is called by
+ * tln_sanitize internally.
+ *
+ * @param string $tagname the name of the tag.
+ * @param array $attary the array of attributes and their values
+ * @param integer $tagtype The type of the tag (see in comments).
+ * @return string A string with the final tag representation.
+ */
+function tln_tagprint($tagname, $attary, $tagtype)
+{
+    if ($tagtype == 2) {
+        $fulltag = '</' . $tagname . '>';
+    } else {
+        $fulltag = '<' . $tagname;
+        if (is_array($attary) && sizeof($attary)) {
+            $atts = array();
+            while (list($attname, $attvalue) = each($attary)) {
+                array_push($atts, "$attname=$attvalue");
+            }
+            $fulltag .= ' ' . join(' ', $atts);
+        }
+        if ($tagtype == 3) {
+            $fulltag .= ' /';
+        }
+        $fulltag .= '>';
+    }
+    return $fulltag;
+}
+
+/**
+ * A small helper function to use with array_walk. Modifies a by-ref
+ * value and makes it lowercase.
+ *
+ * @param string $val a value passed by-ref.
+ * @return        void since it modifies a by-ref value.
+ */
+function tln_casenormalize(&$val)
+{
+    $val = strtolower($val);
+}
+
+/**
+ * This function skips any whitespace from the current position within
+ * a string and to the next non-whitespace value.
+ *
+ * @param string $body the string
+ * @param integer $offset the offset within the string where we should start
+ *                   looking for the next non-whitespace character.
+ * @return integer          the location within the $body where the next
+ *                   non-whitespace char is located.
+ */
+function tln_skipspace($body, $offset)
+{
+    preg_match('/^(\s*)/s', substr($body, $offset), $matches);
+    if (sizeof($matches[1])) {
+        $count = strlen($matches[1]);
+        $offset += $count;
+    }
+    return $offset;
+}
+
+/**
+ * This function looks for the next character within a string.    It's
+ * really just a glorified "strpos", except it catches the failures
+ * nicely.
+ *
+ * @param string $body   The string to look for needle in.
+ * @param integer $offset Start looking from this position.
+ * @param string $needle The character/string to look for.
+ * @return integer           location of the next occurrence of the needle, or
+ *                   strlen($body) if needle wasn't found.
+ */
+function tln_findnxstr($body, $offset, $needle)
+{
+    $pos = strpos($body, $needle, $offset);
+    if ($pos === false) {
+        $pos = strlen($body);
+    }
+    return $pos;
+}
+
+/**
+ * This function takes a PCRE-style regexp and tries to match it
+ * within the string.
+ *
+ * @param string $body   The string to look for needle in.
+ * @param integer $offset Start looking from here.
+ * @param string $reg       A PCRE-style regex to match.
+ * @return array|boolean  Returns a false if no matches found, or an array
+ *                   with the following members:
+ *                   - integer with the location of the match within $body
+ *                   - string with whatever content between offset and the match
+ *                   - string with whatever it is we matched
+ */
+function tln_findnxreg($body, $offset, $reg)
+{
+    $matches = array();
+    $retarr = array();
+    $preg_rule = '%^(.*?)(' . $reg . ')%s';
+    preg_match($preg_rule, substr($body, $offset), $matches);
+    if (!isset($matches[0])) {
+        $retarr = false;
+    } else {
+        $retarr[0] = $offset + strlen($matches[1]);
+        $retarr[1] = $matches[1];
+        $retarr[2] = $matches[2];
+    }
+    return $retarr;
+}
+
+/**
+ * This function looks for the next tag.
+ *
+ * @param string $body   String where to look for the next tag.
+ * @param integer $offset Start looking from here.
+ * @return array|boolean false if no more tags exist in the body, or
+ *                   an array with the following members:
+ *                   - string with the name of the tag
+ *                   - array with attributes and their values
+ *                   - integer with tag type (1, 2, or 3)
+ *                   - integer where the tag starts (starting "<")
+ *                   - integer where the tag ends (ending ">")
+ *                   first three members will be false, if the tag is invalid.
+ */
+function tln_getnxtag($body, $offset)
+{
+    if ($offset > strlen($body)) {
+        return false;
+    }
+    $lt = tln_findnxstr($body, $offset, '<');
+    if ($lt == strlen($body)) {
+        return false;
+    }
+    /**
+     * We are here:
+     * blah blah <tag attribute="value">
+     * \---------^
+     */
+    $pos = tln_skipspace($body, $lt + 1);
+    if ($pos >= strlen($body)) {
+        return array(false, false, false, $lt, strlen($body));
+    }
+    /**
+     * There are 3 kinds of tags:
+     * 1. Opening tag, e.g.:
+     *      <a href="blah">
+     * 2. Closing tag, e.g.:
+     *      </a>
+     * 3. XHTML-style content-less tag, e.g.:
+     *      <img src="blah"/>
+     */
+    switch (substr($body, $pos, 1)) {
+        case '/':
+            $tagtype = 2;
+            $pos++;
+            break;
+        case '!':
+            /**
+             * A comment or an SGML declaration.
+             */
+            if (substr($body, $pos + 1, 2) == '--') {
+                $gt = strpos($body, '-->', $pos);
+                if ($gt === false) {
+                    $gt = strlen($body);
+                } else {
+                    $gt += 2;
+                }
+                return array(false, false, false, $lt, $gt);
+            } else {
+                $gt = tln_findnxstr($body, $pos, '>');
+                return array(false, false, false, $lt, $gt);
+            }
+            break;
+        default:
+            /**
+             * Assume tagtype 1 for now. If it's type 3, we'll switch values
+             * later.
+             */
+            $tagtype = 1;
+            break;
+    }
+
+    /**
+     * Look for next [\W-_], which will indicate the end of the tag name.
+     */
+    $regary = tln_findnxreg($body, $pos, '[^\w\-_]');
+    if ($regary == false) {
+        return array(false, false, false, $lt, strlen($body));
+    }
+    list($pos, $tagname, $match) = $regary;
+    $tagname = strtolower($tagname);
+
+    /**
+     * $match can be either of these:
+     * '>'    indicating the end of the tag entirely.
+     * '\s' indicating the end of the tag name.
+     * '/'    indicating that this is type-3 xhtml tag.
+     *
+     * Whatever else we find there indicates an invalid tag.
+     */
+    switch ($match) {
+        case '/':
+            /**
+             * This is an xhtml-style tag with a closing / at the
+             * end, like so: <img src="blah"/>. Check if it's followed
+             * by the closing bracket. If not, then this tag is invalid
+             */
+            if (substr($body, $pos, 2) == '/>') {
+                $pos++;
+                $tagtype = 3;
+            } else {
+                $gt = tln_findnxstr($body, $pos, '>');
+                $retary = array(false, false, false, $lt, $gt);
+                return $retary;
+            }
+            //intentional fall-through
+        case '>':
+            return array($tagname, false, $tagtype, $lt, $pos);
+            break;
+        default:
+            /**
+             * Check if it's whitespace
+             */
+            if (preg_match('/\s/', $match)) {
+            } else {
+                /**
+                 * This is an invalid tag! Look for the next closing ">".
+                 */
+                $gt = tln_findnxstr($body, $lt, '>');
+                return array(false, false, false, $lt, $gt);
+            }
+    }
+
+    /**
+     * At this point we're here:
+     * <tagname     attribute='blah'>
+     * \-------^
+     *
+     * At this point we loop in order to find all attributes.
+     */
+    $attary = array();
+
+    while ($pos <= strlen($body)) {
+        $pos = tln_skipspace($body, $pos);
+        if ($pos == strlen($body)) {
+            /**
+             * Non-closed tag.
+             */
+            return array(false, false, false, $lt, $pos);
+        }
+        /**
+         * See if we arrived at a ">" or "/>", which means that we reached
+         * the end of the tag.
+         */
+        $matches = array();
+        preg_match('%^(\s*)(>|/>)%s', substr($body, $pos), $matches);
+        if (isset($matches[0]) && $matches[0]) {
+            /**
+             * Yep. So we did.
+             */
+            $pos += strlen($matches[1]);
+            if ($matches[2] == '/>') {
+                $tagtype = 3;
+                $pos++;
+            }
+            return array($tagname, $attary, $tagtype, $lt, $pos);
+        }
+
+        /**
+         * There are several types of attributes, with optional
+         * [:space:] between members.
+         * Type 1:
+         *     attrname[:space:]=[:space:]'CDATA'
+         * Type 2:
+         *     attrname[:space:]=[:space:]"CDATA"
+         * Type 3:
+         *     attr[:space:]=[:space:]CDATA
+         * Type 4:
+         *     attrname
+         *
+         * We leave types 1 and 2 the same, type 3 we check for
+         * '"' and convert to "&quot" if needed, then wrap in
+         * double quotes. Type 4 we convert into:
+         * attrname="yes".
+         */
+        $regary = tln_findnxreg($body, $pos, '[^\w\-_]');
+        if ($regary == false) {
+            /**
+             * Looks like body ended before the end of tag.
+             */
+            return array(false, false, false, $lt, strlen($body));
+        }
+        list($pos, $attname, $match) = $regary;
+        $attname = strtolower($attname);
+        /**
+         * We arrived at the end of attribute name. Several things possible
+         * here:
+         * '>'    means the end of the tag and this is attribute type 4
+         * '/'    if followed by '>' means the same thing as above
+         * '\s' means a lot of things -- look what it's followed by.
+         *        anything else means the attribute is invalid.
+         */
+        switch ($match) {
+            case '/':
+                /**
+                 * This is an xhtml-style tag with a closing / at the
+                 * end, like so: <img src="blah"/>. Check if it's followed
+                 * by the closing bracket. If not, then this tag is invalid
+                 */
+                if (substr($body, $pos, 2) == '/>') {
+                    $pos++;
+                    $tagtype = 3;
+                } else {
+                    $gt = tln_findnxstr($body, $pos, '>');
+                    $retary = array(false, false, false, $lt, $gt);
+                    return $retary;
+                }
+                //intentional fall-through
+            case '>':
+                $attary{$attname} = '"yes"';
+                return array($tagname, $attary, $tagtype, $lt, $pos);
+                break;
+            default:
+                /**
+                 * Skip whitespace and see what we arrive at.
+                 */
+                $pos = tln_skipspace($body, $pos);
+                $char = substr($body, $pos, 1);
+                /**
+                 * Two things are valid here:
+                 * '=' means this is attribute type 1 2 or 3.
+                 * \w means this was attribute type 4.
+                 * anything else we ignore and re-loop. End of tag and
+                 * invalid stuff will be caught by our checks at the beginning
+                 * of the loop.
+                 */
+                if ($char == '=') {
+                    $pos++;
+                    $pos = tln_skipspace($body, $pos);
+                    /**
+                     * Here are 3 possibilities:
+                     * "'"    attribute type 1
+                     * '"'    attribute type 2
+                     * everything else is the content of tag type 3
+                     */
+                    $quot = substr($body, $pos, 1);
+                    if ($quot == '\'') {
+                        $regary = tln_findnxreg($body, $pos + 1, '\'');
+                        if ($regary == false) {
+                            return array(false, false, false, $lt, strlen($body));
+                        }
+                        list($pos, $attval, $match) = $regary;
+                        $pos++;
+                        $attary{$attname} = '\'' . $attval . '\'';
+                    } else {
+                        if ($quot == '"') {
+                            $regary = tln_findnxreg($body, $pos + 1, '\"');
+                            if ($regary == false) {
+                                return array(false, false, false, $lt, strlen($body));
+                            }
+                            list($pos, $attval, $match) = $regary;
+                            $pos++;
+                            $attary{$attname} = '"' . $attval . '"';
+                        } else {
+                            /**
+                             * These are hateful. Look for \s, or >.
+                             */
+                            $regary = tln_findnxreg($body, $pos, '[\s>]');
+                            if ($regary == false) {
+                                return array(false, false, false, $lt, strlen($body));
+                            }
+                            list($pos, $attval, $match) = $regary;
+                            /**
+                             * If it's ">" it will be caught at the top.
+                             */
+                            $attval = preg_replace('/\"/s', '&quot;', $attval);
+                            $attary{$attname} = '"' . $attval . '"';
+                        }
+                    }
+                } else {
+                    if (preg_match('|[\w/>]|', $char)) {
+                        /**
+                         * That was attribute type 4.
+                         */
+                        $attary{$attname} = '"yes"';
+                    } else {
+                        /**
+                         * An illegal character. Find next '>' and return.
+                         */
+                        $gt = tln_findnxstr($body, $pos, '>');
+                        return array(false, false, false, $lt, $gt);
+                    }
+                }
+        }
+    }
+    /**
+     * The fact that we got here indicates that the tag end was never
+     * found. Return invalid tag indication so it gets stripped.
+     */
+    return array(false, false, false, $lt, strlen($body));
+}
+
+/**
+ * Translates entities into literal values so they can be checked.
+ *
+ * @param string $attvalue the by-ref value to check.
+ * @param string $regex    the regular expression to check against.
+ * @param boolean $hex        whether the entites are hexadecimal.
+ * @return boolean            True or False depending on whether there were matches.
+ */
+function tln_deent(&$attvalue, $regex, $hex = false)
+{
+    preg_match_all($regex, $attvalue, $matches);
+    if (is_array($matches) && sizeof($matches[0]) > 0) {
+        $repl = array();
+        for ($i = 0; $i < sizeof($matches[0]); $i++) {
+            $numval = $matches[1][$i];
+            if ($hex) {
+                $numval = hexdec($numval);
+            }
+            $repl{$matches[0][$i]} = chr($numval);
+        }
+        $attvalue = strtr($attvalue, $repl);
+        return true;
+    } else {
+        return false;
+    }
+}
+
+/**
+ * This function checks attribute values for entity-encoded values
+ * and returns them translated into 8-bit strings so we can run
+ * checks on them.
+ *
+ * @param string $attvalue A string to run entity check against.
+ * @return             Void, modifies a reference value.
+ */
+function tln_defang(&$attvalue)
+{
+    /**
+     * Skip this if there aren't ampersands or backslashes.
+     */
+    if (strpos($attvalue, '&') === false
+        && strpos($attvalue, '\\') === false
+    ) {
+        return;
+    }
+    do {
+        $m = false;
+        $m = $m || tln_deent($attvalue, '/\&#0*(\d+);*/s');
+        $m = $m || tln_deent($attvalue, '/\&#x0*((\d|[a-f])+);*/si', true);
+        $m = $m || tln_deent($attvalue, '/\\\\(\d+)/s', true);
+    } while ($m == true);
+    $attvalue = stripslashes($attvalue);
+}
+
+/**
+ * Kill any tabs, newlines, or carriage returns. Our friends the
+ * makers of the browser with 95% market value decided that it'd
+ * be funny to make "java[tab]script" be just as good as "javascript".
+ *
+ * @param string $attvalue     The attribute value before extraneous spaces removed.
+ * @return     Void, modifies a reference value.
+ */
+function tln_unspace(&$attvalue)
+{
+    if (strcspn($attvalue, "\t\r\n\0 ") != strlen($attvalue)) {
+        $attvalue = str_replace(
+            array("\t", "\r", "\n", "\0", " "),
+            array('', '', '', '', ''),
+            $attvalue
+        );
+    }
+}
+
+/**
+ * This function runs various checks against the attributes.
+ *
+ * @param string $tagname            String with the name of the tag.
+ * @param array $attary            Array with all tag attributes.
+ * @param array $rm_attnames        See description for tln_sanitize
+ * @param array $bad_attvals        See description for tln_sanitize
+ * @param array $add_attr_to_tag See description for tln_sanitize
+ * @return                    Array with modified attributes.
+ */
+function tln_fixatts(
+    $tagname,
+    $attary,
+    $rm_attnames,
+    $bad_attvals,
+    $add_attr_to_tag
+) {
+    while (list($attname, $attvalue) = each($attary)) {
+        /**
+         * See if this attribute should be removed.
+         */
+        foreach ($rm_attnames as $matchtag => $matchattrs) {
+            if (preg_match($matchtag, $tagname)) {
+                foreach ($matchattrs as $matchattr) {
+                    if (preg_match($matchattr, $attname)) {
+                        unset($attary{$attname});
+                        continue;
+                    }
+                }
+            }
+        }
+        /**
+         * Remove any backslashes, entities, or extraneous whitespace.
+         */
+        tln_defang($attvalue);
+        tln_unspace($attvalue);
+
+        /**
+         * Now let's run checks on the attvalues.
+         * I don't expect anyone to comprehend this. If you do,
+         * get in touch with me so I can drive to where you live and
+         * shake your hand personally. :)
+         */
+        foreach ($bad_attvals as $matchtag => $matchattrs) {
+            if (preg_match($matchtag, $tagname)) {
+                foreach ($matchattrs as $matchattr => $valary) {
+                    if (preg_match($matchattr, $attname)) {
+                        /**
+                         * There are two arrays in valary.
+                         * First is matches.
+                         * Second one is replacements
+                         */
+                        list($valmatch, $valrepl) = $valary;
+                        $newvalue = preg_replace($valmatch, $valrepl, $attvalue);
+                        if ($newvalue != $attvalue) {
+                            $attary{$attname} = $newvalue;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    /**
+     * See if we need to append any attributes to this tag.
+     */
+    foreach ($add_attr_to_tag as $matchtag => $addattary) {
+        if (preg_match($matchtag, $tagname)) {
+            $attary = array_merge($attary, $addattary);
+        }
+    }
+    return $attary;
+}
+
+/**
+ *
+ * @param string $body                    The HTML you wish to filter
+ * @param array $tag_list                see description above
+ * @param array $rm_tags_with_content see description above
+ * @param array $self_closing_tags    see description above
+ * @param boolean $force_tag_closing    see description above
+ * @param array $rm_attnames            see description above
+ * @param array $bad_attvals            see description above
+ * @param array $add_attr_to_tag        see description above
+ * @return string                       Sanitized html safe to show on your pages.
+ */
+function tln_sanitize(
+    $body,
+    $tag_list,
+    $rm_tags_with_content,
+    $self_closing_tags,
+    $force_tag_closing,
+    $rm_attnames,
+    $bad_attvals,
+    $add_attr_to_tag
+) {
+    /**
+     * Normalize rm_tags and rm_tags_with_content.
+     */
+    $rm_tags = array_shift($tag_list);
+    @array_walk($tag_list, 'tln_casenormalize');
+    @array_walk($rm_tags_with_content, 'tln_casenormalize');
+    @array_walk($self_closing_tags, 'tln_casenormalize');
+    /**
+     * See if tag_list is of tags to remove or tags to allow.
+     * false  means remove these tags
+     * true      means allow these tags
+     */
+    $curpos = 0;
+    $open_tags = array();
+    $trusted = "<!-- begin tln_sanitized html -->\n";
+    $skip_content = false;
+    /**
+     * Take care of netscape's stupid javascript entities like
+     * &{alert('boo')};
+     */
+    $body = preg_replace('/&(\{.*?\};)/si', '&amp;\\1', $body);
+    while (($curtag = tln_getnxtag($body, $curpos)) != false) {
+        list($tagname, $attary, $tagtype, $lt, $gt) = $curtag;
+        $free_content = substr($body, $curpos, $lt - $curpos);
+        if ($skip_content == false) {
+            $trusted .= $free_content;
+        } else {
+        }
+        if ($tagname != false) {
+            if ($tagtype == 2) {
+                if ($skip_content == $tagname) {
+                    /**
+                     * Got to the end of tag we needed to remove.
+                     */
+                    $tagname = false;
+                    $skip_content = false;
+                } else {
+                    if ($skip_content == false) {
+                        if (isset($open_tags{$tagname}) &&
+                            $open_tags{$tagname} > 0
+                        ) {
+                            $open_tags{$tagname}--;
+                        } else {
+                            $tagname = false;
+                        }
+                    } else {
+                    }
+                }
+            } else {
+                /**
+                 * $rm_tags_with_content
+                 */
+                if ($skip_content == false) {
+                    /**
+                     * See if this is a self-closing type and change
+                     * tagtype appropriately.
+                     */
+                    if ($tagtype == 1
+                        && in_array($tagname, $self_closing_tags)
+                    ) {
+                        $tagtype = 3;
+                    }
+                    /**
+                     * See if we should skip this tag and any content
+                     * inside it.
+                     */
+                    if ($tagtype == 1
+                        && in_array($tagname, $rm_tags_with_content)
+                    ) {
+                        $skip_content = $tagname;
+                    } else {
+                        if (($rm_tags == false
+                                && in_array($tagname, $tag_list)) ||
+                            ($rm_tags == true
+                                && !in_array($tagname, $tag_list))
+                        ) {
+                            $tagname = false;
+                        } else {
+                            if ($tagtype == 1) {
+                                if (isset($open_tags{$tagname})) {
+                                    $open_tags{$tagname}++;
+                                } else {
+                                    $open_tags{$tagname} = 1;
+                                }
+                            }
+                            /**
+                             * This is where we run other checks.
+                             */
+                            if (is_array($attary) && sizeof($attary) > 0) {
+                                $attary = tln_fixatts(
+                                    $tagname,
+                                    $attary,
+                                    $rm_attnames,
+                                    $bad_attvals,
+                                    $add_attr_to_tag
+                                );
+                            }
+                        }
+                    }
+                } else {
+                }
+            }
+            if ($tagname != false && $skip_content == false) {
+                $trusted .= tln_tagprint($tagname, $attary, $tagtype);
+            }
+        } else {
+        }
+        $curpos = $gt + 1;
+    }
+    $trusted .= substr($body, $curpos, strlen($body) - $curpos);
+    if ($force_tag_closing == true) {
+        foreach ($open_tags as $tagname => $opentimes) {
+            while ($opentimes > 0) {
+                $trusted .= '</' . $tagname . '>';
+                $opentimes--;
+            }
+        }
+        $trusted .= "\n";
+    }
+    $trusted .= "<!-- end tln_sanitized html -->\n";
+    return $trusted;
+}
+
+// 
+// Use the nifty htmlfilter library
+//
+
+
+function HTMLFilter($body, $trans_image_path, $block_external_images = false)
+{
+
+    $tag_list = array(
+        false,
+        "object",
+        "meta",
+        "html",
+        "head",
+        "base",
+        "link",
+        "frame",
+        "iframe",
+        "plaintext",
+        "marquee"
+    );
+
+    $rm_tags_with_content = array(
+        "script",
+        "applet",
+        "embed",
+        "title",
+        "frameset",
+        "xmp",
+        "xml"
+    );
+
+    $self_closing_tags = array(
+        "img",
+        "br",
+        "hr",
+        "input",
+        "outbind"
+    );
+
+    $force_tag_closing = true;
+
+    $rm_attnames = array(
+        "/.*/" =>
+            array(
+                // "/target/i",
+                "/^on.*/i",
+                "/^dynsrc/i",
+                "/^data.*/i",
+                "/^lowsrc.*/i"
+            )
+    );
+
+    $bad_attvals = array(
+        "/.*/" =>
+            array(
+                "/^src|background/i" =>
+                    array(
+                        array(
+                            '/^([\'"])\s*\S+script\s*:.*([\'"])/si',
+                            '/^([\'"])\s*mocha\s*:*.*([\'"])/si',
+                            '/^([\'"])\s*about\s*:.*([\'"])/si'
+                        ),
+                        array(
+                            "\\1$trans_image_path\\2",
+                            "\\1$trans_image_path\\2",
+                            "\\1$trans_image_path\\2",
+                            "\\1$trans_image_path\\2"
+                        )
+                    ),
+                "/^href|action/i" =>
+                    array(
+                        array(
+                            '/^([\'"])\s*\S+script\s*:.*([\'"])/si',
+                            '/^([\'"])\s*mocha\s*:*.*([\'"])/si',
+                            '/^([\'"])\s*about\s*:.*([\'"])/si'
+                        ),
+                        array(
+                            "\\1#\\1",
+                            "\\1#\\1",
+                            "\\1#\\1",
+                            "\\1#\\1"
+                        )
+                    ),
+                "/^style/i" =>
+                    array(
+                        array(
+                            "/expression/i",
+                            "/binding/i",
+                            "/behaviou*r/i",
+                            "/include-source/i",
+                            '/position\s*:\s*absolute/i',
+                            '/url\s*\(\s*([\'"])\s*\S+script\s*:.*([\'"])\s*\)/si',
+                            '/url\s*\(\s*([\'"])\s*mocha\s*:.*([\'"])\s*\)/si',
+                            '/url\s*\(\s*([\'"])\s*about\s*:.*([\'"])\s*\)/si',
+                            '/(.*)\s*:\s*url\s*\(\s*([\'"]*)\s*\S+script\s*:.*([\'"]*)\s*\)/si'
+                        ),
+                        array(
+                            "idiocy",
+                            "idiocy",
+                            "idiocy",
+                            "idiocy",
+                            "",
+                            "url(\\1#\\1)",
+                            "url(\\1#\\1)",
+                            "url(\\1#\\1)",
+                            "url(\\1#\\1)",
+                            "url(\\1#\\1)",
+                            "\\1:url(\\2#\\3)"
+                        )
+                    )
+            )
+    );
+
+    if ($block_external_images) {
+        array_push(
+            $bad_attvals{'/.*/'}{'/^src|background/i'}[0],
+            '/^([\'\"])\s*https*:.*([\'\"])/si'
+        );
+        array_push(
+            $bad_attvals{'/.*/'}{'/^src|background/i'}[1],
+            "\\1$trans_image_path\\1"
+        );
+        array_push(
+            $bad_attvals{'/.*/'}{'/^style/i'}[0],
+            '/url\(([\'\"])\s*https*:.*([\'\"])\)/si'
+        );
+        array_push(
+            $bad_attvals{'/.*/'}{'/^style/i'}[1],
+            "url(\\1$trans_image_path\\1)"
+        );
+    }
+
+    $add_attr_to_tag = array(
+        "/^a$/i" =>
+            array('target' => '"_blank"')
+    );
+
+    $trusted = tln_sanitize(
+        $body,
+        $tag_list,
+        $rm_tags_with_content,
+        $self_closing_tags,
+        $force_tag_closing,
+        $rm_attnames,
+        $bad_attvals,
+        $add_attr_to_tag
+    );
+    return $trusted;
+}
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/extras/ntlm_sasl_client.php b/~dev_rating/modules/mail/vendor/PHPMailer/extras/ntlm_sasl_client.php
new file mode 100644
index 0000000000000000000000000000000000000000..b21ccce0e40a0531edb8ffc89c2c3ddc1ae5fa63
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/extras/ntlm_sasl_client.php
@@ -0,0 +1,185 @@
+<?php
+/*
+ * ntlm_sasl_client.php
+ *
+ * @(#) $Id: ntlm_sasl_client.php,v 1.3 2004/11/17 08:00:37 mlemos Exp $
+ *
+ **
+ ** Source: http://www.phpclasses.org/browse/file/7495.html
+ ** License: BSD (http://www.phpclasses.org/package/1888-PHP-Single-API-for-standard-authentication-mechanisms.html)
+ ** Bundled with Permission
+ **
+ */
+
+define("SASL_NTLM_STATE_START",             0);
+define("SASL_NTLM_STATE_IDENTIFY_DOMAIN",   1);
+define("SASL_NTLM_STATE_RESPOND_CHALLENGE", 2);
+define("SASL_NTLM_STATE_DONE",              3);
+
+class ntlm_sasl_client_class
+{
+	var $credentials=array();
+	var $state=SASL_NTLM_STATE_START;
+
+	Function Initialize(&$client)
+	{
+		if(!function_exists($function="mcrypt_encrypt")
+		|| !function_exists($function="mhash"))
+		{
+			$extensions=array(
+				"mcrypt_encrypt"=>"mcrypt",
+				"mhash"=>"mhash"
+			);
+			$client->error="the extension ".$extensions[$function]." required by the NTLM SASL client class is not available in this PHP configuration";
+			return(0);
+		}
+		return(1);
+	}
+
+	Function ASCIIToUnicode($ascii)
+	{
+		for($unicode="",$a=0;$a<strlen($ascii);$a++)
+			$unicode.=substr($ascii,$a,1).chr(0);
+		return($unicode);
+	}
+
+	Function TypeMsg1($domain,$workstation)
+	{
+		$domain_length=strlen($domain);
+		$workstation_length=strlen($workstation);
+		$workstation_offset=32;
+		$domain_offset=$workstation_offset+$workstation_length;
+		return(
+			"NTLMSSP\0".
+			"\x01\x00\x00\x00".
+			"\x07\x32\x00\x00".
+			pack("v",$domain_length).
+			pack("v",$domain_length).
+			pack("V",$domain_offset).
+			pack("v",$workstation_length).
+			pack("v",$workstation_length).
+			pack("V",$workstation_offset).
+			$workstation.
+			$domain
+		);
+	}
+
+	Function NTLMResponse($challenge,$password)
+	{
+		$unicode=$this->ASCIIToUnicode($password);
+		$md4=mhash(MHASH_MD4,$unicode);
+		$padded=$md4.str_repeat(chr(0),21-strlen($md4));
+		$iv_size=mcrypt_get_iv_size(MCRYPT_DES,MCRYPT_MODE_ECB);
+		$iv=mcrypt_create_iv($iv_size,MCRYPT_RAND);
+		for($response="",$third=0;$third<21;$third+=7)
+		{
+			for($packed="",$p=$third;$p<$third+7;$p++)
+				$packed.=str_pad(decbin(ord(substr($padded,$p,1))),8,"0",STR_PAD_LEFT);
+			for($key="",$p=0;$p<strlen($packed);$p+=7)
+			{
+				$s=substr($packed,$p,7);
+				$b=$s.((substr_count($s,"1") % 2) ? "0" : "1");
+				$key.=chr(bindec($b));
+			}
+			$ciphertext=mcrypt_encrypt(MCRYPT_DES,$key,$challenge,MCRYPT_MODE_ECB,$iv);
+			$response.=$ciphertext;
+		}
+		return $response;
+	}
+
+	Function TypeMsg3($ntlm_response,$user,$domain,$workstation)
+	{
+		$domain_unicode=$this->ASCIIToUnicode($domain);
+		$domain_length=strlen($domain_unicode);
+		$domain_offset=64;
+		$user_unicode=$this->ASCIIToUnicode($user);
+		$user_length=strlen($user_unicode);
+		$user_offset=$domain_offset+$domain_length;
+		$workstation_unicode=$this->ASCIIToUnicode($workstation);
+		$workstation_length=strlen($workstation_unicode);
+		$workstation_offset=$user_offset+$user_length;
+		$lm="";
+		$lm_length=strlen($lm);
+		$lm_offset=$workstation_offset+$workstation_length;
+		$ntlm=$ntlm_response;
+		$ntlm_length=strlen($ntlm);
+		$ntlm_offset=$lm_offset+$lm_length;
+		$session="";
+		$session_length=strlen($session);
+		$session_offset=$ntlm_offset+$ntlm_length;
+		return(
+			"NTLMSSP\0".
+			"\x03\x00\x00\x00".
+			pack("v",$lm_length).
+			pack("v",$lm_length).
+			pack("V",$lm_offset).
+			pack("v",$ntlm_length).
+			pack("v",$ntlm_length).
+			pack("V",$ntlm_offset).
+			pack("v",$domain_length).
+			pack("v",$domain_length).
+			pack("V",$domain_offset).
+			pack("v",$user_length).
+			pack("v",$user_length).
+			pack("V",$user_offset).
+			pack("v",$workstation_length).
+			pack("v",$workstation_length).
+			pack("V",$workstation_offset).
+			pack("v",$session_length).
+			pack("v",$session_length).
+			pack("V",$session_offset).
+			"\x01\x02\x00\x00".
+			$domain_unicode.
+			$user_unicode.
+			$workstation_unicode.
+			$lm.
+			$ntlm
+		);
+	}
+
+	Function Start(&$client, &$message, &$interactions)
+	{
+		if($this->state!=SASL_NTLM_STATE_START)
+		{
+			$client->error="NTLM authentication state is not at the start";
+			return(SASL_FAIL);
+		}
+		$this->credentials=array(
+			"user"=>"",
+			"password"=>"",
+			"realm"=>"",
+			"workstation"=>""
+		);
+		$defaults=array();
+		$status=$client->GetCredentials($this->credentials,$defaults,$interactions);
+		if($status==SASL_CONTINUE)
+			$this->state=SASL_NTLM_STATE_IDENTIFY_DOMAIN;
+		Unset($message);
+		return($status);
+	}
+
+	Function Step(&$client, $response, &$message, &$interactions)
+	{
+		switch($this->state)
+		{
+			case SASL_NTLM_STATE_IDENTIFY_DOMAIN:
+				$message=$this->TypeMsg1($this->credentials["realm"],$this->credentials["workstation"]);
+				$this->state=SASL_NTLM_STATE_RESPOND_CHALLENGE;
+				break;
+			case SASL_NTLM_STATE_RESPOND_CHALLENGE:
+				$ntlm_response=$this->NTLMResponse(substr($response,24,8),$this->credentials["password"]);
+				$message=$this->TypeMsg3($ntlm_response,$this->credentials["user"],$this->credentials["realm"],$this->credentials["workstation"]);
+				$this->state=SASL_NTLM_STATE_DONE;
+				break;
+			case SASL_NTLM_STATE_DONE:
+				$client->error="NTLM authentication was finished without success";
+				return(SASL_FAIL);
+			default:
+				$client->error="invalid NTLM authentication step state";
+				return(SASL_FAIL);
+		}
+		return(SASL_CONTINUE);
+	}
+};
+
+?>
\ No newline at end of file
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-ar.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-ar.php
new file mode 100644
index 0000000000000000000000000000000000000000..19e9e8f3161ac06d4455f0743a6457642d225d6d
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-ar.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Arabic PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author bahjat al mostafa <bahjat983@hotmail.com>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'Ш®Ш·ШЈ SMTP : Щ„Ш§ ЩЉЩ…ЩѓЩ† ШЄШЈЩѓЩЉШЇ Ш§Щ„Щ‡Щ€ЩЉШ©.';
+$PHPMAILER_LANG['connect_host']         = 'Ш®Ш·ШЈ SMTP: Щ„Ш§ ЩЉЩ…ЩѓЩ† Ш§Щ„Ш§ШЄШµШ§Щ„ ШЁШ§Щ„Ш®Ш§ШЇЩ… SMTP.';
+$PHPMAILER_LANG['data_not_accepted']    = 'Ш®Ш·ШЈ SMTP: Щ„Щ… ЩЉШЄЩ… Щ‚ШЁЩ€Щ„ Ш§Щ„Щ…Ш№Щ„Щ€Щ…Ш§ШЄ .';
+$PHPMAILER_LANG['empty_message']        = 'Щ†Шµ Ш§Щ„Ш±ШіШ§Щ„Ш© ЩЃШ§Ш±Шє';
+$PHPMAILER_LANG['encoding']             = 'ШЄШ±Щ…ЩЉШІ ШєЩЉШ± Щ…Ш№Ш±Щ€ЩЃ: ';
+$PHPMAILER_LANG['execute']              = 'Щ„Ш§ ЩЉЩ…ЩѓЩ† ШЄЩ†ЩЃЩЉШ° : ';
+$PHPMAILER_LANG['file_access']          = 'Щ„Ш§ ЩЉЩ…ЩѓЩ† Ш§Щ„Щ€ШµЩ€Щ„ Щ„Щ„Щ…Щ„ЩЃ: ';
+$PHPMAILER_LANG['file_open']            = 'Ш®Ш·ШЈ ЩЃЩЉ Ш§Щ„Щ…Щ„ЩЃ: Щ„Ш§ ЩЉЩ…ЩѓЩ† ЩЃШЄШ­Щ‡: ';
+$PHPMAILER_LANG['from_failed']          = 'Ш®Ш·ШЈ Ш№Щ„Щ‰ Щ…ШіШЄЩ€Щ‰ Ш№Щ†Щ€Ш§Щ† Ш§Щ„Щ…Ш±ШіЩ„ : ';
+$PHPMAILER_LANG['instantiate']          = 'Щ„Ш§ ЩЉЩ…ЩѓЩ† ШЄЩ€ЩЃЩЉШ± Ш®ШЇЩ…Ш© Ш§Щ„ШЁШ±ЩЉШЇ.';
+$PHPMAILER_LANG['invalid_address']      = 'Ш§Щ„ШҐШ±ШіШ§Щ„ ШєЩЉШ± Щ…Щ…ЩѓЩ† Щ„ШЈЩ† Ш№Щ†Щ€Ш§Щ† Ш§Щ„ШЁШ±ЩЉШЇ Ш§Щ„ШҐЩ„ЩѓШЄШ±Щ€Щ†ЩЉ ШєЩЉШ± ШµШ§Щ„Ш­.';
+$PHPMAILER_LANG['mailer_not_supported'] = ' ШЁШ±Щ†Ш§Щ…Ш¬ Ш§Щ„ШҐШ±ШіШ§Щ„ ШєЩЉШ± Щ…ШЇШ№Щ€Щ….';
+$PHPMAILER_LANG['provide_address']      = 'ЩЉШ¬ШЁ ШЄЩ€ЩЃЩЉШ± Ш№Щ†Щ€Ш§Щ† Ш§Щ„ШЁШ±ЩЉШЇ Ш§Щ„ШҐЩ„ЩѓШЄШ±Щ€Щ†ЩЉ Щ„Щ…ШіШЄЩ„Щ… Щ€Ш§Ш­ШЇ Ш№Щ„Щ‰ Ш§Щ„ШЈЩ‚Щ„.';
+$PHPMAILER_LANG['recipients_failed']    = 'Ш®Ш·ШЈ SMTP: Ш§Щ„ШЈШ®Ш·Ш§ШЎ Ш§Щ„ШЄШ§Щ„ЩЉШ© ' .
+                                          'ЩЃШґЩ„ ЩЃЩЉ Ш§Щ„Ш§Ш±ШіШ§Щ„ Щ„ЩѓЩ„ Щ…Щ† : ';
+$PHPMAILER_LANG['signing']              = 'Ш®Ш·ШЈ ЩЃЩЉ Ш§Щ„ШЄЩ€Щ‚ЩЉШ№: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() ШєЩЉШ± Щ…Щ…ЩѓЩ†.';
+$PHPMAILER_LANG['smtp_error']           = 'Ш®Ш·ШЈ Ш№Щ„Щ‰ Щ…ШіШЄЩ€Щ‰ Ш§Щ„Ш®Ш§ШЇЩ… SMTP: ';
+$PHPMAILER_LANG['variable_set']         = 'Щ„Ш§ ЩЉЩ…ЩѓЩ† ШЄШ№ЩЉЩЉЩ† ШЈЩ€ ШҐШ№Ш§ШЇШ© ШЄШ№ЩЉЩЉЩ† Щ…ШЄШєЩЉШ±: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-be.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-be.php
new file mode 100644
index 0000000000000000000000000000000000000000..9801368d63ae1dd3465e1869ddfb948ad7d688c0
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-be.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Belarusian PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Aleksander Maksymiuk <info@setpro.pl>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'Памылка SMTP: памылка ідэнтыфікацыі.';
+$PHPMAILER_LANG['connect_host']         = 'Памылка SMTP: нельга ўстанавіць сувязь з SMTP-серверам.';
+$PHPMAILER_LANG['data_not_accepted']    = 'Памылка SMTP: звесткі непрынятыя.';
+$PHPMAILER_LANG['empty_message']        = 'Пустое паведамленне.';
+$PHPMAILER_LANG['encoding']             = 'Невядомая кадыроўка тэксту: ';
+$PHPMAILER_LANG['execute']              = 'Нельга выканаць каманду: ';
+$PHPMAILER_LANG['file_access']          = 'Няма доступу да файла: ';
+$PHPMAILER_LANG['file_open']            = 'Нельга адкрыць файл: ';
+$PHPMAILER_LANG['from_failed']          = 'Няправільны адрас адпраўніка: ';
+$PHPMAILER_LANG['instantiate']          = 'Нельга прымяніць функцыю mail().';
+$PHPMAILER_LANG['invalid_address']      = 'Нельга даслаць паведамленне, няправільны email атрымальніка: ';
+$PHPMAILER_LANG['provide_address']      = 'Запоўніце, калі ласка, правільны email атрымальніка.';
+$PHPMAILER_LANG['mailer_not_supported'] = ' - паштовы сервер не падтрымліваецца.';
+$PHPMAILER_LANG['recipients_failed']    = 'Памылка SMTP: няправільныя атрымальнікі: ';
+$PHPMAILER_LANG['signing']              = 'Памылка подпісу паведамлення: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'Памылка сувязі з SMTP-серверам.';
+$PHPMAILER_LANG['smtp_error']           = 'Памылка SMTP: ';
+$PHPMAILER_LANG['variable_set']         = 'Нельга ўстанавіць або перамяніць значэнне пераменнай: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-br.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-br.php
new file mode 100644
index 0000000000000000000000000000000000000000..d157ccd63262149eb2708288d4a54200270e0728
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-br.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Brazilian Portuguese PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Paulo Henrique Garcia <paulo@controllerweb.com.br>
+ * @author Lucas GuimarГЈes <lucas@lucasguimaraes.com>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'Erro de SMTP: NГЈo foi possГ­vel autenticar.';
+$PHPMAILER_LANG['connect_host']         = 'Erro de SMTP: NГЈo foi possГ­vel conectar com o servidor SMTP.';
+$PHPMAILER_LANG['data_not_accepted']    = 'Erro de SMTP: Dados rejeitados.';
+$PHPMAILER_LANG['empty_message']        = 'Corpo da mensagem vazio';
+$PHPMAILER_LANG['encoding']             = 'Codificação desconhecida: ';
+$PHPMAILER_LANG['execute']              = 'NГЈo foi possГ­vel executar: ';
+$PHPMAILER_LANG['file_access']          = 'NГЈo foi possГ­vel acessar o arquivo: ';
+$PHPMAILER_LANG['file_open']            = 'Erro de Arquivo: NГЈo foi possГ­vel abrir o arquivo: ';
+$PHPMAILER_LANG['from_failed']          = 'Os endereços dos remententes a seguir falharam: ';
+$PHPMAILER_LANG['instantiate']          = 'Não foi possível iniciar uma instância da função mail.';
+$PHPMAILER_LANG['invalid_address']      = 'Não enviando, endereço de e-mail inválido: ';
+$PHPMAILER_LANG['mailer_not_supported'] = ' mailer nГЈo Г© suportado.';
+$PHPMAILER_LANG['provide_address']      = 'Você deve fornecer pelo menos um endereço de destinatário de e-mail.';
+$PHPMAILER_LANG['recipients_failed']    = 'Erro de SMTP: Os endereços de destinatário a seguir falharam: ';
+$PHPMAILER_LANG['signing']              = 'Erro ao assinar: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() falhou.';
+$PHPMAILER_LANG['smtp_error']           = 'Erro de servidor SMTP: ';
+$PHPMAILER_LANG['variable_set']         = 'NГЈo foi possГ­vel definir ou resetar a variГЎvel: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-ca.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-ca.php
new file mode 100644
index 0000000000000000000000000000000000000000..c5964ce54ad8bf095ec39f06bd75ff72b1f1a196
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-ca.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Catalan PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Ivan <web AT microstudi DOT com>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'Error SMTP: No s’ha pogut autenticar.';
+$PHPMAILER_LANG['connect_host']         = 'Error SMTP: No es pot connectar al servidor SMTP.';
+$PHPMAILER_LANG['data_not_accepted']    = 'Error SMTP: Dades no acceptades.';
+$PHPMAILER_LANG['empty_message']        = 'El cos del missatge estГ  buit.';
+$PHPMAILER_LANG['encoding']             = 'CodificaciГі desconeguda: ';
+$PHPMAILER_LANG['execute']              = 'No es pot executar: ';
+$PHPMAILER_LANG['file_access']          = 'No es pot accedir a l’arxiu: ';
+$PHPMAILER_LANG['file_open']            = 'Error d’Arxiu: No es pot obrir l’arxiu: ';
+$PHPMAILER_LANG['from_failed']          = 'La(s) segГјent(s) adreces de remitent han fallat: ';
+$PHPMAILER_LANG['instantiate']          = 'No s’ha pogut crear una instància de la funció Mail.';
+$PHPMAILER_LANG['invalid_address']      = 'Adreça d’email invalida';
+$PHPMAILER_LANG['mailer_not_supported'] = ' mailer no estГ  suportat';
+$PHPMAILER_LANG['provide_address']      = 'S’ha de proveir almenys una adreça d’email com a destinatari.';
+$PHPMAILER_LANG['recipients_failed']    = 'Error SMTP: Els segГјents destinataris han fallat: ';
+$PHPMAILER_LANG['signing']              = 'Error al signar: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'Ha fallat el SMTP Connect().';
+$PHPMAILER_LANG['smtp_error']           = 'Error del servidor SMTP: ';
+$PHPMAILER_LANG['variable_set']         = 'No s’ha pogut establir o restablir la variable: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-ch.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-ch.php
new file mode 100644
index 0000000000000000000000000000000000000000..70d7a63a1a0d103f3cad4a622c1f4c68f22d33a6
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-ch.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Chinese PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author LiuXin <http://www.80x86.cn/blog/>
+ */
+
+$PHPMAILER_LANG['authenticate'] = 'SMTP 错误:身份验证失败。';
+$PHPMAILER_LANG['connect_host'] = 'SMTP й”™иЇЇ: дёЌиѓЅиїћжЋҐSMTPдё»жњєгЂ‚';
+$PHPMAILER_LANG['data_not_accepted'] = 'SMTP й”™иЇЇ: ж•°жЌ®дёЌеЏЇжЋҐеЏ—гЂ‚';
+//$PHPMAILER_LANG['empty_message']        = 'Message body empty';
+$PHPMAILER_LANG['encoding'] = '未知编码:';
+$PHPMAILER_LANG['execute'] = '不能执行: ';
+$PHPMAILER_LANG['file_access'] = '不能访问文件:';
+$PHPMAILER_LANG['file_open'] = '文件错误:不能打开文件:';
+$PHPMAILER_LANG['from_failed'] = '下面的发送地址邮件发送失败了: ';
+$PHPMAILER_LANG['instantiate'] = 'дёЌиѓЅе®ћзЋ°mailж–№жі•гЂ‚';
+//$PHPMAILER_LANG['invalid_address']        = 'Not sending, email address is invalid: ';
+$PHPMAILER_LANG['mailer_not_supported'] = ' 您所选择的发送邮件的方法并不支持。';
+$PHPMAILER_LANG['provide_address'] = '您必须提供至少一个 收信人的email地址。';
+$PHPMAILER_LANG['recipients_failed'] = 'SMTP 错误: 下面的 收件人失败了: ';
+//$PHPMAILER_LANG['signing']              = 'Signing Error: ';
+//$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';
+//$PHPMAILER_LANG['smtp_error']           = 'SMTP server error: ';
+//$PHPMAILER_LANG['variable_set']         = 'Cannot set or reset variable: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-cz.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-cz.php
new file mode 100644
index 0000000000000000000000000000000000000000..89f40f8bff06d8888760eb88e0506b9b7da695d9
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-cz.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Czech PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'Chyba SMTP: Autentizace selhala.';
+$PHPMAILER_LANG['connect_host']         = 'Chyba SMTP: Nelze navГЎzat spojenГ­ se SMTP serverem.';
+$PHPMAILER_LANG['data_not_accepted']    = 'Chyba SMTP: Data nebyla pЕ™ijata.';
+$PHPMAILER_LANG['empty_message']        = 'PrГЎzdnГ© tД›lo zprГЎvy';
+$PHPMAILER_LANG['encoding']             = 'NeznГЎmГ© kГіdovГЎnГ­: ';
+$PHPMAILER_LANG['execute']              = 'Nelze provГ©st: ';
+$PHPMAILER_LANG['file_access']          = 'Nelze zГ­skat pЕ™Г­stup k souboru: ';
+$PHPMAILER_LANG['file_open']            = 'Chyba souboru: Nelze otevЕ™Г­t soubor pro ДЌtenГ­: ';
+$PHPMAILER_LANG['from_failed']          = 'NГЎsledujГ­cГ­ adresa odesГ­latele je nesprГЎvnГЎ: ';
+$PHPMAILER_LANG['instantiate']          = 'Nelze vytvoЕ™it instanci emailovГ© funkce.';
+$PHPMAILER_LANG['invalid_address']      = 'NeplatnГЎ adresa: ';
+$PHPMAILER_LANG['mailer_not_supported'] = ' mailer nenГ­ podporovГЎn.';
+$PHPMAILER_LANG['provide_address']      = 'MusГ­te zadat alespoЕ€ jednu emailovou adresu pЕ™Г­jemce.';
+$PHPMAILER_LANG['recipients_failed']    = 'Chyba SMTP: NГЎsledujГ­cГ­ adresy pЕ™Г­jemcЕЇ nejsou sprГЎvnД›: ';
+$PHPMAILER_LANG['signing']              = 'Chyba pЕ™ihlaЕЎovГЎnГ­: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() selhal.';
+$PHPMAILER_LANG['smtp_error']           = 'Chyba SMTP serveru: ';
+$PHPMAILER_LANG['variable_set']         = 'Nelze nastavit nebo zmД›nit promД›nnou: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-de.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-de.php
new file mode 100644
index 0000000000000000000000000000000000000000..1386208d34cf8596441a13ae3c3f1d3ca87a10eb
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-de.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * German PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'SMTP Fehler: Authentifizierung fehlgeschlagen.';
+$PHPMAILER_LANG['connect_host']         = 'SMTP Fehler: Konnte keine Verbindung zum SMTP-Host herstellen.';
+$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Fehler: Daten werden nicht akzeptiert.';
+$PHPMAILER_LANG['empty_message']        = 'E-Mail Inhalt ist leer.';
+$PHPMAILER_LANG['encoding']             = 'Unbekanntes Encoding-Format: ';
+$PHPMAILER_LANG['execute']              = 'Konnte folgenden Befehl nicht ausfГјhren: ';
+$PHPMAILER_LANG['file_access']          = 'Zugriff auf folgende Datei fehlgeschlagen: ';
+$PHPMAILER_LANG['file_open']            = 'Datei Fehler: konnte folgende Datei nicht Г¶ffnen: ';
+$PHPMAILER_LANG['from_failed']          = 'Die folgende Absenderadresse ist nicht korrekt: ';
+$PHPMAILER_LANG['instantiate']          = 'Mail Funktion konnte nicht initialisiert werden.';
+$PHPMAILER_LANG['invalid_address']        = 'E-Mail wird nicht gesendet, die Adresse ist ungГјltig.';
+$PHPMAILER_LANG['mailer_not_supported'] = ' mailer wird nicht unterstГјtzt.';
+$PHPMAILER_LANG['provide_address']      = 'Bitte geben Sie mindestens eine Empfänger E-Mailadresse an.';
+$PHPMAILER_LANG['recipients_failed']    = 'SMTP Fehler: Die folgenden Empfänger sind nicht korrekt: ';
+$PHPMAILER_LANG['signing']              = 'Fehler beim Signieren: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'Verbindung zu SMTP Server fehlgeschlagen.';
+$PHPMAILER_LANG['smtp_error']           = 'Fehler vom SMTP Server: ';
+$PHPMAILER_LANG['variable_set']         = 'Kann Variable nicht setzen oder zurГјcksetzen: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-dk.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-dk.php
new file mode 100644
index 0000000000000000000000000000000000000000..16d74afcde01eb9ef763f0eb4cb249e2bbb18482
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-dk.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Danish PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Mikael Stokkebro <info@stokkebro.dk>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'SMTP fejl: Kunne ikke logge pГҐ.';
+$PHPMAILER_LANG['connect_host']         = 'SMTP fejl: Kunne ikke tilslutte SMTP serveren.';
+$PHPMAILER_LANG['data_not_accepted']    = 'SMTP fejl: Data kunne ikke accepteres.';
+//$PHPMAILER_LANG['empty_message']        = 'Message body empty';
+$PHPMAILER_LANG['encoding']             = 'Ukendt encode-format: ';
+$PHPMAILER_LANG['execute']              = 'Kunne ikke kГёre: ';
+$PHPMAILER_LANG['file_access']          = 'Ingen adgang til fil: ';
+$PHPMAILER_LANG['file_open']            = 'Fil fejl: Kunne ikke ГҐbne filen: ';
+$PHPMAILER_LANG['from_failed']          = 'FГёlgende afsenderadresse er forkert: ';
+$PHPMAILER_LANG['instantiate']          = 'Kunne ikke initialisere email funktionen.';
+//$PHPMAILER_LANG['invalid_address']        = 'Not sending, email address is invalid: ';
+$PHPMAILER_LANG['mailer_not_supported'] = ' mailer understГёttes ikke.';
+$PHPMAILER_LANG['provide_address']      = 'Du skal indtaste mindst en modtagers emailadresse.';
+$PHPMAILER_LANG['recipients_failed']    = 'SMTP fejl: FГёlgende modtagere er forkerte: ';
+//$PHPMAILER_LANG['signing']              = 'Signing Error: ';
+//$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';
+//$PHPMAILER_LANG['smtp_error']           = 'SMTP server error: ';
+//$PHPMAILER_LANG['variable_set']         = 'Cannot set or reset variable: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-el.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-el.php
new file mode 100644
index 0000000000000000000000000000000000000000..abd2cb923f8d0f7ad340ad25017294a5b7208105
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-el.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Greek PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'SMTP ОЈП†О¬О»ОјО±: О‘ОґП…ОЅО±ОјОЇО± ПЂО№ПѓП„ОїПЂОїОЇО·ПѓО·П‚ (authentication).';
+$PHPMAILER_LANG['connect_host']         = 'SMTP ОЈП†О¬О»ОјО±: О‘ОґП…ОЅО±ОјОЇО± ПѓПЌОЅОґОµПѓО·П‚ ПѓП„ОїОЅ SMTP-Host.';
+$PHPMAILER_LANG['data_not_accepted']    = 'SMTP ОЈП†О¬О»ОјО±: О¤О± ОґОµОґОїОјО­ОЅО± ОґОµОЅ О­ОіО№ОЅО±ОЅ О±ПЂОїОґОµОєП„О¬.';
+$PHPMAILER_LANG['empty_message']        = 'О¤Ої E-Mail ОґОµОЅ О­П‡ОµО№ ПЂОµПЃО№ОµП‡ПЊОјОµОЅОї .';
+$PHPMAILER_LANG['encoding']             = 'О‘ОіОЅП‰ПѓП„Ої Encoding-Format: ';
+$PHPMAILER_LANG['execute']              = 'О‘ОґП…ОЅО±ОјОЇО± ОµОєП„О­О»ОµПѓО·П‚ О±ОєПЊО»ОїП…ОёО·П‚ ОµОЅП„ОїО»О®П‚: ';
+$PHPMAILER_LANG['file_access']          = 'О‘ОґП…ОЅО±ОјОЇО± ПЂПЃОїПѓПЂО­О»О±ПѓО·П‚ П„ОїП… О±ПЃП‡ОµОЇОїП…: ';
+$PHPMAILER_LANG['file_open']            = 'ОЈП†О¬О»ОјО± О‘ПЃП‡ОµОЇОїП…: О”ОµОЅ ОµОЇОЅО±ОЇ ОґП…ОЅО±П„ПЊ П„Ої О¬ОЅОїО№ОіОјО± П„ОїП… О±ОєПЊО»ОїП…ОёОїП… О±ПЃП‡ОµОЇОїП…: ';
+$PHPMAILER_LANG['from_failed']          = 'О— ПЂО±ПЃО±ОєО¬П„П‰ ОґО№ОµПЌОёП…ОЅПѓО· О±ПЂОїПѓП„ОїО»О­О± ОґОµОЅ ОµОЇОЅО±О№ ПѓП‰ПѓП„О®: ';
+$PHPMAILER_LANG['instantiate']          = 'О‘ОґП…ОЅО±ОјОЇО± ОµОєОєОЇОЅО·ПѓО·П‚ Mail function.';
+$PHPMAILER_LANG['invalid_address']        = 'О¤Ої ОјО®ОЅП…ОјО± ОґОµОЅ О±ПЂОїПѓП„О­О»ОёО·ОєОµ, О· ОґО№ОµПЌОёП…ОЅПѓО· ОґОµОЅ ОµОЇОЅО±О№ О­ОіОєП…ПЃО·.';
+$PHPMAILER_LANG['mailer_not_supported'] = ' mailer ОґОµОЅ П…ПЂОїПѓП„О·ПЃОЇО¶ОµП„О±О№.';
+$PHPMAILER_LANG['provide_address']      = 'О О±ПЃО±ОєО±О»ОїПЌОјОµ ОґПЋПѓП„Оµ П„ОїП…О»О¬П‡О№ПѓП„ОїОЅ ОјО№О± e-mail ОґО№ОµПЌОёП…ОЅПѓО· ПЂО±ПЃО±О»О®ПЂП„О·.';
+$PHPMAILER_LANG['recipients_failed']    = 'SMTP ОЈП†О¬О»ОјО±: ОџО№ ПЂО±ПЃО±ОєО¬П„П‰ОЅ ОґО№ОµП…ОёПЌОЅПѓОµО№П‚ ПЂО±ПЃО±О»О®ПЂП„О· ОґОµОЅ ОµОЇОЅО±О№ О­ОіОєП…ПЃОµП‚: ';
+$PHPMAILER_LANG['signing']              = 'ОЈП†О¬О»ОјО± П…ПЂОїОіПЃО±П†О®П‚: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'О‘ПЂОїП„П…П‡ОЇО± ПѓПЌОЅОґОµПѓО·П‚ ПѓП„ОїОЅ SMTP Server.';
+$PHPMAILER_LANG['smtp_error']           = 'ОЈП†О¬О»ОјО± О±ПЂПЊ П„ОїОЅ SMTP Server: ';
+$PHPMAILER_LANG['variable_set']         = 'О‘ОґП…ОЅО±ОјОЇО± ОїПЃО№ПѓОјОїПЌ О® О±ПЃП‡О№ОєОїПЂОїОЇО·ПѓО·П‚ ОјОµП„О±ОІО»О·П„О®П‚: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-eo.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-eo.php
new file mode 100644
index 0000000000000000000000000000000000000000..786e945d73b788a0b1ec723dc92e197b4c2b5110
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-eo.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Esperanto PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'Eraro de servilo SMTPВ : aЕ­tentigo malsukcesis.';
+$PHPMAILER_LANG['connect_host']         = 'Eraro de servilo SMTPВ : konektado al servilo malsukcesis.';
+$PHPMAILER_LANG['data_not_accepted']    = 'Eraro de servilo SMTPВ : neДќustaj datumoj.';
+$PHPMAILER_LANG['empty_message']        = 'Teksto de mesaДќo mankas.';
+$PHPMAILER_LANG['encoding']             = 'Nekonata kodoprezento: ';
+$PHPMAILER_LANG['execute']              = 'Lanĉi rulumadon ne eblis: ';
+$PHPMAILER_LANG['file_access']          = 'Aliro al dosiero ne sukcesis: ';
+$PHPMAILER_LANG['file_open']            = 'Eraro de dosiero: malfermo neeblas: ';
+$PHPMAILER_LANG['from_failed']          = 'Jena adreso de sendinto malsukcesis: ';
+$PHPMAILER_LANG['instantiate']          = 'Genero de retmesaДќa funkcio neeblis.';
+$PHPMAILER_LANG['invalid_address']      = 'Retadreso ne validas: ';
+$PHPMAILER_LANG['mailer_not_supported'] = ' mesaДќilo ne subtenata.';
+$PHPMAILER_LANG['provide_address']      = 'Vi devas tajpi almenaЕ­ unu recevontan retadreson.';
+$PHPMAILER_LANG['recipients_failed']    = 'Eraro de servilo SMTPВ : la jenaj poЕќtrecivuloj kaЕ­zis eraron: ';
+$PHPMAILER_LANG['signing']              = 'Eraro de subskribo: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP konektado malsukcesis.';
+$PHPMAILER_LANG['smtp_error']           = 'Eraro de servilo SMTPВ : ';
+$PHPMAILER_LANG['variable_set']         = 'Variablo ne pravalorizeblas aЕ­ ne repravalorizeblas: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-es.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-es.php
new file mode 100644
index 0000000000000000000000000000000000000000..9ceb93b26331095ddfc051523019c32ebc6bd863
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-es.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Spanish PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Matt Sturdy <matt.sturdy@gmail.com>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'Error SMTP: No se pudo autentificar.';
+$PHPMAILER_LANG['connect_host']         = 'Error SMTP: No se pudo conectar al servidor SMTP.';
+$PHPMAILER_LANG['data_not_accepted']    = 'Error SMTP: Datos no aceptados.';
+$PHPMAILER_LANG['empty_message']        = 'Cuerpo del mensaje vacГ­o';
+$PHPMAILER_LANG['encoding']             = 'CodificaciГіn desconocida: ';
+$PHPMAILER_LANG['execute']              = 'No se pudo ejecutar: ';
+$PHPMAILER_LANG['file_access']          = 'No se pudo acceder al archivo: ';
+$PHPMAILER_LANG['file_open']            = 'Error de Archivo: No se pudo abrir el archivo: ';
+$PHPMAILER_LANG['from_failed']          = 'La(s) siguiente(s) direcciones de remitente fallaron: ';
+$PHPMAILER_LANG['instantiate']          = 'No se pudo crear una instancia de la funciГіn Mail.';
+$PHPMAILER_LANG['invalid_address']      = 'No se pudo enviar: direcciГіn de email invГЎlido: ';
+$PHPMAILER_LANG['mailer_not_supported'] = ' mailer no estГЎ soportado.';
+$PHPMAILER_LANG['provide_address']      = 'Debe proveer al menos una direcciГіn de email como destino.';
+$PHPMAILER_LANG['recipients_failed']    = 'Error SMTP: Los siguientes destinos fallaron: ';
+$PHPMAILER_LANG['signing']              = 'Error al firmar: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() se fallГі.';
+$PHPMAILER_LANG['smtp_error']           = 'Error del servidor SMTP: ';
+$PHPMAILER_LANG['variable_set']         = 'No se pudo ajustar o reajustar la variable: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-et.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-et.php
new file mode 100644
index 0000000000000000000000000000000000000000..ceb1aab1ab0c5e1a08f9a1da712dcfbdcab21ac9
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-et.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Estonian PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Indrek Päri
+ * @author Elan Ruusamäe <glen@delfi.ee>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'SMTP Viga: Autoriseerimise viga.';
+$PHPMAILER_LANG['connect_host']         = 'SMTP Viga: Ei Гµnnestunud luua Гјhendust SMTP serveriga.';
+$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Viga: Vigased andmed.';
+$PHPMAILER_LANG['empty_message']        = 'TГјhi kirja sisu';
+$PHPMAILER_LANG["encoding"]             = 'Tundmatu kodeering: ';
+$PHPMAILER_LANG['execute']              = 'Tegevus ebaГµnnestus: ';
+$PHPMAILER_LANG['file_access']          = 'Pole piisavalt õiguseid järgneva faili avamiseks: ';
+$PHPMAILER_LANG['file_open']            = 'Faili Viga: Faili avamine ebaГµnnestus: ';
+$PHPMAILER_LANG['from_failed']          = 'Järgnev saatja e-posti aadress on vigane: ';
+$PHPMAILER_LANG['instantiate']          = 'mail funktiooni käivitamine ebaõnnestus.';
+$PHPMAILER_LANG['invalid_address']        = 'Saatmine peatatud, e-posti address vigane: ';
+$PHPMAILER_LANG['provide_address']      = 'Te peate määrama vähemalt ühe saaja e-posti aadressi.';
+$PHPMAILER_LANG['mailer_not_supported'] = ' maileri tugi puudub.';
+$PHPMAILER_LANG['recipients_failed']    = 'SMTP Viga: Järgnevate saajate e-posti aadressid on vigased: ';
+$PHPMAILER_LANG["signing"]              = 'Viga allkirjastamisel: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() ebaГµnnestus.';
+$PHPMAILER_LANG['smtp_error']           = 'SMTP serveri viga: ';
+$PHPMAILER_LANG['variable_set']         = 'Ei õnnestunud määrata või lähtestada muutujat: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-fa.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-fa.php
new file mode 100644
index 0000000000000000000000000000000000000000..af2b6961a184c0f0a95251b8f1626b7f52214c7a
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-fa.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Persian/Farsi PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Ali Jazayeri <jaza.ali@gmail.com>
+ * @author Mohammad Hossein Mojtahedi <mhm5000@gmail.com>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'Ш®Ш·Ш§ЫЊ SMTP: Ш§Ш­Ш±Ш§ШІ Щ‡Щ€ЫЊШЄ ШЁШ§ ШґЪ©ШіШЄ Щ…Щ€Ш§Ш¬Щ‡ ШґШЇ.';
+$PHPMAILER_LANG['connect_host']         = 'Ш®Ш·Ш§ЫЊ SMTP: Ш§ШЄШµШ§Щ„ ШЁЩ‡ ШіШ±Щ€Ш± SMTP ШЁШ±Щ‚Ш±Ш§Ш± Щ†ШґШЇ.';
+$PHPMAILER_LANG['data_not_accepted']    = 'خطای SMTP: داده‌ها نا‌درست هستند.';
+$PHPMAILER_LANG['empty_message']        = 'ШЁШ®Шґ Щ…ШЄЩ† ЩѕЫЊШ§Щ… Ш®Ш§Щ„ЫЊ Ш§ШіШЄ.';
+$PHPMAILER_LANG['encoding']             = 'کد‌گذاری نا‌شناخته: ';
+$PHPMAILER_LANG['execute']              = 'Ш§Щ…Ъ©Ш§Щ† Ш§Ш¬Ш±Ш§ Щ€Ш¬Щ€ШЇ Щ†ШЇШ§Ш±ШЇ: ';
+$PHPMAILER_LANG['file_access']          = 'Ш§Щ…Ъ©Ш§Щ† ШЇШіШЄШ±ШіЫЊ ШЁЩ‡ ЩЃШ§ЫЊЩ„ Щ€Ш¬Щ€ШЇ Щ†ШЇШ§Ш±ШЇ: ';
+$PHPMAILER_LANG['file_open']            = 'Ш®Ш·Ш§ЫЊ File: Ш§Щ…Ъ©Ш§Щ† ШЁШ§ШІЪ©Ш±ШЇЩ† ЩЃШ§ЫЊЩ„ Щ€Ш¬Щ€ШЇ Щ†ШЇШ§Ш±ШЇ: ';
+$PHPMAILER_LANG['from_failed']          = 'ШўШЇШ±Ші ЩЃШ±ШіШЄЩ†ШЇЩ‡ Ш§ШґШЄШЁШ§Щ‡ Ш§ШіШЄ: ';
+$PHPMAILER_LANG['instantiate']          = 'Ш§Щ…Ъ©Ш§Щ† Щ…Ш№Ш±ЩЃЫЊ ШЄШ§ШЁШ№ Ш§ЫЊЩ…ЫЊЩ„ Щ€Ш¬Щ€ШЇ Щ†ШЇШ§Ш±ШЇ.';
+$PHPMAILER_LANG['invalid_address']      = 'ШўШЇШ±Ші Ш§ЫЊЩ…ЫЊЩ„ Щ…Ш№ШЄШЁШ± Щ†ЫЊШіШЄ: ';
+$PHPMAILER_LANG['mailer_not_supported'] = ' mailer پشتیبانی نمی‌شود.';
+$PHPMAILER_LANG['provide_address']      = 'ШЁШ§ЫЊШЇ Ш­ШЇШ§Щ‚Щ„ ЫЊЪ© ШўШЇШ±Ші ЪЇЫЊШ±Щ†ШЇЩ‡ Щ€Ш§Ш±ШЇ Ъ©Щ†ЫЊШЇ.';
+$PHPMAILER_LANG['recipients_failed']    = 'Ш®Ш·Ш§ЫЊ SMTP: Ш§Ш±ШіШ§Щ„ ШЁЩ‡ ШўШЇШ±Ші ЪЇЫЊШ±Щ†ШЇЩ‡ ШЁШ§ Ш®Ш·Ш§ Щ…Щ€Ш§Ш¬Щ‡ ШґШЇ: ';
+$PHPMAILER_LANG['signing']              = 'Ш®Ш·Ш§ ШЇШ± Ш§Щ…Ш¶Ш§: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'Ш®Ш·Ш§ ШЇШ± Ш§ШЄШµШ§Щ„ ШЁЩ‡ SMTP.';
+$PHPMAILER_LANG['smtp_error']           = 'Ш®Ш·Ш§ ШЇШ± SMTP Server: ';
+$PHPMAILER_LANG['variable_set']         = 'امکان ارسال یا ارسال مجدد متغیر‌ها وجود ندارد: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-fi.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-fi.php
new file mode 100644
index 0000000000000000000000000000000000000000..6533110f76629735ca41ef8c115602de4d0db300
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-fi.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Finnish PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Jyry Kuukanen
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'SMTP-virhe: käyttäjätunnistus epäonnistui.';
+$PHPMAILER_LANG['connect_host']         = 'SMTP-virhe: yhteys palvelimeen ei onnistu.';
+$PHPMAILER_LANG['data_not_accepted']    = 'SMTP-virhe: data on virheellinen.';
+//$PHPMAILER_LANG['empty_message']        = 'Message body empty';
+$PHPMAILER_LANG['encoding']             = 'Tuntematon koodaustyyppi: ';
+$PHPMAILER_LANG['execute']              = 'Suoritus epäonnistui: ';
+$PHPMAILER_LANG['file_access']          = 'Seuraavaan tiedostoon ei ole oikeuksia: ';
+$PHPMAILER_LANG['file_open']            = 'Tiedostovirhe: Ei voida avata tiedostoa: ';
+$PHPMAILER_LANG['from_failed']          = 'Seuraava lähettäjän osoite on virheellinen: ';
+$PHPMAILER_LANG['instantiate']          = 'mail-funktion luonti epäonnistui.';
+//$PHPMAILER_LANG['invalid_address']        = 'Not sending, email address is invalid: ';
+$PHPMAILER_LANG['mailer_not_supported'] = 'postivälitintyyppiä ei tueta.';
+$PHPMAILER_LANG['provide_address']      = 'Aseta vähintään yksi vastaanottajan sähk&ouml;postiosoite.';
+$PHPMAILER_LANG['recipients_failed']    = 'SMTP-virhe: seuraava vastaanottaja osoite on virheellinen.';
+$PHPMAILER_LANG['encoding']             = 'Tuntematon koodaustyyppi: ';
+//$PHPMAILER_LANG['signing']              = 'Signing Error: ';
+//$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';
+//$PHPMAILER_LANG['smtp_error']           = 'SMTP server error: ';
+//$PHPMAILER_LANG['variable_set']         = 'Cannot set or reset variable: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-fo.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-fo.php
new file mode 100644
index 0000000000000000000000000000000000000000..97e2a00785083e1d60dd9075db41dda50dc1f558
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-fo.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Faroese PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author DГЎvur SГёrensen <http://www.profo-webdesign.dk>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'SMTP feilur: Kundi ikki gГіГ°kenna.';
+$PHPMAILER_LANG['connect_host']         = 'SMTP feilur: Kundi ikki knГЅta samband viГ° SMTP vert.';
+$PHPMAILER_LANG['data_not_accepted']    = 'SMTP feilur: Data ikki gГіГ°kent.';
+//$PHPMAILER_LANG['empty_message']        = 'Message body empty';
+$PHPMAILER_LANG['encoding']             = 'Г“kend encoding: ';
+$PHPMAILER_LANG['execute']              = 'Kundi ikki ГєtfГёra: ';
+$PHPMAILER_LANG['file_access']          = 'Kundi ikki tilganga fГ­lu: ';
+$PHPMAILER_LANG['file_open']            = 'FГ­lu feilur: Kundi ikki opna fГ­lu: ';
+$PHPMAILER_LANG['from_failed']          = 'fylgjandi FrГЎ/From adressa miseydnaГ°ist: ';
+$PHPMAILER_LANG['instantiate']          = 'Kuni ikki instantiera mail funktiГіn.';
+//$PHPMAILER_LANG['invalid_address']        = 'Not sending, email address is invalid: ';
+$PHPMAILER_LANG['mailer_not_supported'] = ' er ikki supporteraГ°.';
+$PHPMAILER_LANG['provide_address']      = 'TГє skal uppgeva minst mГіttakara-emailadressu(r).';
+$PHPMAILER_LANG['recipients_failed']    = 'SMTP Feilur: Fylgjandi mГіttakarar miseydnaГ°ust: ';
+//$PHPMAILER_LANG['signing']              = 'Signing Error: ';
+//$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';
+//$PHPMAILER_LANG['smtp_error']           = 'SMTP server error: ';
+//$PHPMAILER_LANG['variable_set']         = 'Cannot set or reset variable: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-fr.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-fr.php
new file mode 100644
index 0000000000000000000000000000000000000000..604b44c9634c15464b6482310766f80af64e5aa6
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-fr.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * French PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * Some French punctuation requires a thin non-breaking space (U+202F) character before it,
+ * for example before a colon or exclamation mark.
+ * There is one of these characters between these quotes: " "
+ * @link http://unicode.org/udhr/n/notes_fra.html
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'Erreur SMTP : échec de l\'authentification.';
+$PHPMAILER_LANG['connect_host']         = 'Erreur SMTP : impossible de se connecter au serveur SMTP.';
+$PHPMAILER_LANG['data_not_accepted']    = 'Erreur SMTP : données incorrectes.';
+$PHPMAILER_LANG['empty_message']        = 'Corps du message vide.';
+$PHPMAILER_LANG['encoding']             = 'Encodage inconnu : ';
+$PHPMAILER_LANG['execute']              = 'Impossible de lancer l\'exécution : ';
+$PHPMAILER_LANG['file_access']          = 'Impossible d\'accéder au fichier : ';
+$PHPMAILER_LANG['file_open']            = 'Ouverture du fichier impossible : ';
+$PHPMAILER_LANG['from_failed']          = 'L\'adresse d\'expéditeur suivante a échoué : ';
+$PHPMAILER_LANG['instantiate']          = 'Impossible d\'instancier la fonction mail.';
+$PHPMAILER_LANG['invalid_address']      = 'L\'adresse courriel n\'est pas valide : ';
+$PHPMAILER_LANG['mailer_not_supported'] = ' client de messagerie non supportГ©.';
+$PHPMAILER_LANG['provide_address']      = 'Vous devez fournir au moins une adresse de destinataire.';
+$PHPMAILER_LANG['recipients_failed']    = 'Erreur SMTP : les destinataires suivants sont en erreur : ';
+$PHPMAILER_LANG['signing']              = 'Erreur de signature : ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'Г‰chec de la connexion SMTP.';
+$PHPMAILER_LANG['smtp_error']           = 'Erreur du serveur SMTP : ';
+$PHPMAILER_LANG['variable_set']         = 'Impossible d\'initialiser ou de réinitialiser une variable : ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-gl.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-gl.php
new file mode 100644
index 0000000000000000000000000000000000000000..9675a707c2abcbd55666424c841e8bf433dcb11b
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-gl.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Galician PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author by Donato Rouco <donatorouco@gmail.com>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'Erro SMTP: Non puido ser autentificado.';
+$PHPMAILER_LANG['connect_host']         = 'Erro SMTP: Non puido conectar co servidor SMTP.';
+$PHPMAILER_LANG['data_not_accepted']    = 'Erro SMTP: Datos non aceptados.';
+$PHPMAILER_LANG['empty_message']        = 'Corpo da mensaxe vacГ­a';
+$PHPMAILER_LANG['encoding']             = 'CodificaciГіn descoГ±ecida: ';
+$PHPMAILER_LANG['execute']              = 'Non puido ser executado: ';
+$PHPMAILER_LANG['file_access']          = 'Nob puido acceder Гі arquivo: ';
+$PHPMAILER_LANG['file_open']            = 'Erro de Arquivo: No puido abrir o arquivo: ';
+$PHPMAILER_LANG['from_failed']          = 'A(s) seguinte(s) direcciГіn(s) de remitente(s) deron erro: ';
+$PHPMAILER_LANG['instantiate']          = 'Non puido crear unha instancia da funciГіn Mail.';
+$PHPMAILER_LANG['invalid_address']      = 'Non puido envia-lo correo: direcciГіn de email invГЎlida: ';
+$PHPMAILER_LANG['mailer_not_supported'] = ' mailer non estГЎ soportado.';
+$PHPMAILER_LANG['provide_address']      = 'Debe engadir polo menos unha direcciГіn de email coma destino.';
+$PHPMAILER_LANG['recipients_failed']    = 'Erro SMTP: Os seguintes destinos fallaron: ';
+$PHPMAILER_LANG['signing']              = 'Erro Гі firmar: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() fallou.';
+$PHPMAILER_LANG['smtp_error']           = 'Erro do servidor SMTP: ';
+$PHPMAILER_LANG['variable_set']         = 'Non puidemos axustar ou reaxustar a variГЎbel: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-he.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-he.php
new file mode 100644
index 0000000000000000000000000000000000000000..857f7239f57de1e479601337ecb565fd2b0fc501
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-he.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Hebrew PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Ronny Sherer <ronny@hoojima.com>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'Ч©Ч’Ч™ЧђЧЄ SMTP: Ч¤ЧўЧ•ЧњЧЄ Ч”ЧђЧ™ЧћЧ•ЧЄ Ч Ч›Ч©ЧњЧ”.';
+$PHPMAILER_LANG['connect_host']         = 'Ч©Ч’Ч™ЧђЧЄ SMTP: ЧњЧђ Ч”Ч¦ЧњЧ—ЧЄЧ™ ЧњЧ”ЧЄЧ—Ч‘ЧЁ ЧњЧ©ЧЁЧЄ SMTP.';
+$PHPMAILER_LANG['data_not_accepted']    = 'Ч©Ч’Ч™ЧђЧЄ SMTP: ЧћЧ™Ч“Чў ЧњЧђ Ч”ЧЄЧ§Ч‘Чњ.';
+$PHPMAILER_LANG['empty_message']        = 'Ч’Ч•ЧЈ Ч”Ч”Ч•Ч“ЧўЧ” ЧЁЧ™Ч§';
+$PHPMAILER_LANG['invalid_address']      = 'Ч›ЧЄЧ•Ч‘ЧЄ Ч©Ч’Ч•Ч™Ч”';
+$PHPMAILER_LANG['encoding']             = 'Ч§Ч™Ч“Ч•Ч“ ЧњЧђ ЧћЧ•Ч›ЧЁ: ';
+$PHPMAILER_LANG['execute']              = 'ЧњЧђ Ч”Ч¦ЧњЧ—ЧЄЧ™ ЧњЧ”Ч¤ЧўЧ™Чњ ЧђЧЄ: ';
+$PHPMAILER_LANG['file_access']          = 'ЧњЧђ Ч Ч™ЧЄЧџ ЧњЧ’Ч©ЧЄ ЧњЧ§Ч•Ч‘ЧҐ: ';
+$PHPMAILER_LANG['file_open']            = 'Ч©Ч’Ч™ЧђЧЄ Ч§Ч•Ч‘ЧҐ: ЧњЧђ Ч Ч™ЧЄЧџ ЧњЧ’Ч©ЧЄ ЧњЧ§Ч•Ч‘ЧҐ: ';
+$PHPMAILER_LANG['from_failed']          = 'Ч›ЧЄЧ•Ч‘Ч•ЧЄ Ч”Ч ЧћЧўЧ Ч™Чќ Ч”Ч‘ЧђЧ•ЧЄ Ч Ч›Ч©ЧњЧ•: ';
+$PHPMAILER_LANG['instantiate']          = 'ЧњЧђ Ч”Ч¦ЧњЧ—ЧЄЧ™ ЧњЧ”Ч¤ЧўЧ™Чњ ЧђЧЄ Ч¤Ч•Ч Ч§Ч¦Ч™Ч™ЧЄ Ч”ЧћЧ™Ч™Чњ.';
+$PHPMAILER_LANG['mailer_not_supported'] = ' ЧђЧ™Ч Ч” Ч ЧЄЧћЧ›ЧЄ.';
+$PHPMAILER_LANG['provide_address']      = 'Ч—Ч•Ч‘Ч” ЧњЧЎЧ¤Ч§ ЧњЧ¤Ч—Ч•ЧЄ Ч›ЧЄЧ•Ч‘ЧЄ ЧђЧ—ЧЄ Ч©Чњ ЧћЧ§Ч‘Чњ Ч”ЧћЧ™Ч™Чњ.';
+$PHPMAILER_LANG['recipients_failed']    = 'Ч©Ч’Ч™ЧђЧЄ SMTP: Ч”Ч ЧћЧўЧ Ч™Чќ Ч”Ч‘ЧђЧ™Чќ Ч Ч›Ч©ЧњЧ•: ';
+$PHPMAILER_LANG['signing']              = 'Ч©Ч’Ч™ЧђЧЄ Ч—ЧЄЧ™ЧћЧ”: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';
+$PHPMAILER_LANG['smtp_error']           = 'Ч©Ч’Ч™ЧђЧЄ Ч©ЧЁЧЄ SMTP: ';
+$PHPMAILER_LANG['variable_set']         = 'ЧњЧђ Ч Ч™ЧЄЧџ ЧњЧ§Ч‘Ч•Чў ЧђЧ• ЧњЧ©Ч Ч•ЧЄ ЧђЧЄ Ч”ЧћЧ©ЧЄЧ Ч”: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-hr.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-hr.php
new file mode 100644
index 0000000000000000000000000000000000000000..ad00ed9446c1e2c11d85da0faf272271545bf7fb
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-hr.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Croatian PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Hrvoj3e <hrvoj3e@gmail.com>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'SMTP GreЕЎka: Neuspjela autentikacija.';
+$PHPMAILER_LANG['connect_host']         = 'SMTP GreЕЎka: Ne mogu se spojiti na SMTP posluЕѕitelj.';
+$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Greška: Podatci nisu prihvaćeni.';
+$PHPMAILER_LANG['empty_message']        = 'SadrЕѕaj poruke je prazan.';
+$PHPMAILER_LANG['encoding']             = 'Nepoznati encoding: ';
+$PHPMAILER_LANG['execute']              = 'Nije moguće izvršiti naredbu: ';
+$PHPMAILER_LANG['file_access']          = 'Nije moguće pristupiti datoteci: ';
+$PHPMAILER_LANG['file_open']            = 'Nije moguće otvoriti datoteku: ';
+$PHPMAILER_LANG['from_failed']          = 'SMTP GreЕЎka: Slanje s navedenih e-mail adresa nije uspjelo: ';
+$PHPMAILER_LANG['recipients_failed']    = 'SMTP GreЕЎka: Slanje na navedenih e-mail adresa nije uspjelo: ';
+$PHPMAILER_LANG['instantiate']          = 'Ne mogu pokrenuti mail funkcionalnost.';
+$PHPMAILER_LANG['invalid_address']      = 'E-mail nije poslan. Neispravna e-mail adresa.';
+$PHPMAILER_LANG['mailer_not_supported'] = ' mailer nije podrЕѕan.';
+$PHPMAILER_LANG['provide_address']      = 'Definirajte barem jednu adresu primatelja.';
+$PHPMAILER_LANG['signing']              = 'GreЕЎka prilikom prijave: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'Spajanje na SMTP posluЕѕitelj nije uspjelo.';
+$PHPMAILER_LANG['smtp_error']           = 'GreЕЎka SMTP posluЕѕitelja: ';
+$PHPMAILER_LANG['variable_set']         = 'Ne mogu postaviti varijablu niti ju vratiti nazad: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-hu.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-hu.php
new file mode 100644
index 0000000000000000000000000000000000000000..8139c08c0e5eb3db27026309837600824491e3ad
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-hu.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Hungarian PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author @dominicus-75
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'SMTP hiba: az azonosГ­tГЎs sikertelen.';
+$PHPMAILER_LANG['connect_host']         = 'SMTP hiba: nem lehet kapcsolГіdni az SMTP-szerverhez.';
+$PHPMAILER_LANG['data_not_accepted']    = 'SMTP hiba: adatok visszautasГ­tva.';
+$PHPMAILER_LANG['empty_message']        = 'Üres az üzenettörzs.';
+$PHPMAILER_LANG['encoding']             = 'Ismeretlen kГіdolГЎs: ';
+$PHPMAILER_LANG['execute']              = 'Nem lehet vГ©grehajtani: ';
+$PHPMAILER_LANG['file_access']          = 'A következő fájl nem elérhető: ';
+$PHPMAILER_LANG['file_open']            = 'Fájl hiba: a következő fájlt nem lehet megnyitni: ';
+$PHPMAILER_LANG['from_failed']          = 'A feladóként megadott következő cím hibás: ';
+$PHPMAILER_LANG['instantiate']          = 'A PHP mail() fГјggvГ©nyt nem sikerГјlt vГ©grehajtani.';
+$PHPMAILER_LANG['invalid_address']      = 'Г‰rvГ©nytelen cГ­m: ';
+$PHPMAILER_LANG['mailer_not_supported'] = ' a mailer-osztГЎly nem tГЎmogatott.';
+$PHPMAILER_LANG['provide_address']      = 'LegalГЎbb egy cГ­mzettet fel kell tГјntetni.';
+$PHPMAILER_LANG['recipients_failed']    = 'SMTP hiba: a címzettként megadott következő címek hibásak: ';
+$PHPMAILER_LANG['signing']              = 'HibГЎs alГЎГ­rГЎs: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'Hiba az SMTP-kapcsolatban.';
+$PHPMAILER_LANG['smtp_error']           = 'SMTP-szerver hiba: ';
+$PHPMAILER_LANG['variable_set']         = 'A következő változók beállítása nem sikerült: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-it.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-it.php
new file mode 100644
index 0000000000000000000000000000000000000000..59649d53323db17e0f3944de3211a73a8223796f
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-it.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Italian PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Ilias Bartolini <brain79@inwind.it>
+ * @author Stefano Sabatini <sabas88@gmail.com>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'SMTP Error: Impossibile autenticarsi.';
+$PHPMAILER_LANG['connect_host']         = 'SMTP Error: Impossibile connettersi all\'host SMTP.';
+$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Error: Dati non accettati dal server.';
+$PHPMAILER_LANG['empty_message']        = 'Il corpo del messaggio ГЁ vuoto';
+$PHPMAILER_LANG['encoding']             = 'Codifica dei caratteri sconosciuta: ';
+$PHPMAILER_LANG['execute']              = 'Impossibile eseguire l\'operazione: ';
+$PHPMAILER_LANG['file_access']          = 'Impossibile accedere al file: ';
+$PHPMAILER_LANG['file_open']            = 'File Error: Impossibile aprire il file: ';
+$PHPMAILER_LANG['from_failed']          = 'I seguenti indirizzi mittenti hanno generato errore: ';
+$PHPMAILER_LANG['instantiate']          = 'Impossibile istanziare la funzione mail';
+$PHPMAILER_LANG['invalid_address']        = 'Impossibile inviare, l\'indirizzo email non ГЁ valido: ';
+$PHPMAILER_LANG['provide_address']      = 'Deve essere fornito almeno un indirizzo ricevente';
+$PHPMAILER_LANG['mailer_not_supported'] = 'Mailer non supportato';
+$PHPMAILER_LANG['recipients_failed']    = 'SMTP Error: I seguenti indirizzi destinatari hanno generato un errore: ';
+$PHPMAILER_LANG['signing']              = 'Errore nella firma: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() fallita.';
+$PHPMAILER_LANG['smtp_error']           = 'Errore del server SMTP: ';
+$PHPMAILER_LANG['variable_set']         = 'Impossibile impostare o resettare la variabile: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-ja.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-ja.php
new file mode 100644
index 0000000000000000000000000000000000000000..d5423da40a240fb7270a1f2ca8833dc590689e54
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-ja.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Japanese PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Mitsuhiro Yoshida <http://mitstek.com/>
+ * @author Yoshi Sakai <http://bluemooninc.jp/>
+ */
+
+$PHPMAILER_LANG['authenticate'] = 'SMTPг‚Ёгѓ©гѓј: иЄЌиЁјгЃ§гЃЌгЃѕгЃ›г‚“гЃ§гЃ—гЃџгЂ‚';
+$PHPMAILER_LANG['connect_host'] = 'SMTPг‚Ёгѓ©гѓј: SMTPгѓ›г‚№гѓ€гЃ«жЋҐз¶љгЃ§гЃЌгЃѕгЃ›г‚“гЃ§гЃ—гЃџгЂ‚';
+$PHPMAILER_LANG['data_not_accepted'] = 'SMTPエラー: データが受け付けられませんでした。';
+//$PHPMAILER_LANG['empty_message']        = 'Message body empty';
+$PHPMAILER_LANG['encoding'] = '不明なエンコーディング: ';
+$PHPMAILER_LANG['execute'] = 'е®џиЎЊгЃ§гЃЌгЃѕгЃ›г‚“гЃ§гЃ—гЃџ: ';
+$PHPMAILER_LANG['file_access'] = 'ファイルにアクセスできません: ';
+$PHPMAILER_LANG['file_open'] = 'ファイルエラー: ファイルを開けません: ';
+$PHPMAILER_LANG['from_failed'] = 'Fromг‚ўгѓ‰гѓ¬г‚№г‚’з™»йЊІгЃ™г‚‹йљ›гЃ«г‚Ёгѓ©гѓјгЃЊз™єз”џгЃ—гЃѕгЃ—гЃџ: ';
+$PHPMAILER_LANG['instantiate'] = 'гѓЎгѓјгѓ«й–ўж•°гЃЊж­ЈеёёгЃ«е‹•дЅњгЃ—гЃѕгЃ›г‚“гЃ§гЃ—гЃџгЂ‚';
+//$PHPMAILER_LANG['invalid_address']        = 'Not sending, email address is invalid: ';
+$PHPMAILER_LANG['provide_address'] = 'е°‘гЃЄгЃЏгЃЁг‚‚1гЃ¤гѓЎгѓјгѓ«г‚ўгѓ‰гѓ¬г‚№г‚’ жЊ‡е®љгЃ™г‚‹еї…и¦ЃгЃЊгЃ‚г‚ЉгЃѕгЃ™гЂ‚';
+$PHPMAILER_LANG['mailer_not_supported'] = ' гѓЎгѓјгѓ©гѓјгЃЊг‚µгѓќгѓјгѓ€гЃ•г‚ЊгЃ¦гЃ„гЃѕгЃ›г‚“гЂ‚';
+$PHPMAILER_LANG['recipients_failed'] = 'SMTPг‚Ёгѓ©гѓј: ж¬ЎгЃ®еЏ—дїЎиЂ…г‚ўгѓ‰гѓ¬г‚№гЃ« й–“йЃ•гЃ„гЃЊгЃ‚г‚ЉгЃѕгЃ™: ';
+//$PHPMAILER_LANG['signing']              = 'Signing Error: ';
+//$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';
+//$PHPMAILER_LANG['smtp_error']           = 'SMTP server error: ';
+//$PHPMAILER_LANG['variable_set']         = 'Cannot set or reset variable: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-ka.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-ka.php
new file mode 100644
index 0000000000000000000000000000000000000000..e5b6b57bf1f9d61cd305435025cac242cfbafa66
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-ka.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Georgian PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Avtandil Kikabidze aka LONGMAN <akalongman@gmail.com>
+ */
+
+$PHPMAILER_LANG['authenticate'] 			= 'SMTP შეცდომა: ავტორიზაცია შეუძლებელია.';
+$PHPMAILER_LANG['connect_host']  			= 'SMTP შეცდომა: SMTP სერვერთან დაკავშირება შეუძლებელია.';
+$PHPMAILER_LANG['data_not_accepted'] 		= 'SMTP შეცდომა: მონაცემები არ იქნა მიღებული.';
+$PHPMAILER_LANG['encoding'] 				= 'კოდირების უცნობი ტიპი: ';
+$PHPMAILER_LANG['execute'] 					= 'შეუძლებელია შემდეგი ბრძანების შესრულება: ';
+$PHPMAILER_LANG['file_access'] 				= 'შეუძლებელია წვდომა ფაილთან: ';
+$PHPMAILER_LANG['file_open'] 				= 'ფაილური სისტემის შეცდომა: არ იხსნება ფაილი: ';
+$PHPMAILER_LANG['from_failed'] 				= 'გამგზავნის არასწორი მისამართი: ';
+$PHPMAILER_LANG['instantiate'] 				= 'mail ფუნქციის გაშვება ვერ ხერხდება.';
+$PHPMAILER_LANG['provide_address'] 		= 'გთხოვთ მიუთითოთ ერთი ადრესატის e-mail მისამართი მაინც.';
+$PHPMAILER_LANG['mailer_not_supported'] 	= ' - საფოსტო სერვერის მხარდაჭერა არ არის.';
+$PHPMAILER_LANG['recipients_failed'] 		= 'SMTP შეცდომა: შემდეგ მისამართებზე გაგზავნა ვერ მოხერხდა: ';
+$PHPMAILER_LANG['empty_message'] 		= 'შეტყობინება ცარიელია';
+$PHPMAILER_LANG['invalid_address'] 			= 'არ გაიგზავნა, e-mail მისამართის არასწორი ფორმატი: ';
+$PHPMAILER_LANG['signing'] 					= 'ხელმოწერის შეცდომა: ';
+$PHPMAILER_LANG['smtp_connect_failed'] 	= 'შეცდომა SMTP სერვერთან დაკავშირებისას';
+$PHPMAILER_LANG['smtp_error'] 				= 'SMTP სერვერის შეცდომა: ';
+$PHPMAILER_LANG['variable_set'] 				= 'შეუძლებელია შემდეგი ცვლადის შექმნა ან შეცვლა: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-lt.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-lt.php
new file mode 100644
index 0000000000000000000000000000000000000000..4ff70cf4d1811cd4254043738e350cf1dcb277e8
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-lt.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Lithuanian PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Dainius Kaupaitis <dk@sum.lt>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'SMTP klaida: autentifikacija nepavyko.';
+$PHPMAILER_LANG['connect_host']         = 'SMTP klaida: nepavyksta prisijungti prie SMTP stoties.';
+$PHPMAILER_LANG['data_not_accepted']    = 'SMTP klaida: duomenys nepriimti.';
+$PHPMAILER_LANG['empty_message']        = 'LaiЕЎko turinys tuЕЎДЌias';
+$PHPMAILER_LANG['encoding']             = 'NeatpaЕѕinta koduotД—: ';
+$PHPMAILER_LANG['execute']              = 'Nepavyko ДЇvykdyti komandos: ';
+$PHPMAILER_LANG['file_access']          = 'Byla nepasiekiama: ';
+$PHPMAILER_LANG['file_open']            = 'Bylos klaida: Nepavyksta atidaryti: ';
+$PHPMAILER_LANG['from_failed']          = 'Neteisingas siuntД—jo adresas: ';
+$PHPMAILER_LANG['instantiate']          = 'Nepavyko paleisti mail funkcijos.';
+$PHPMAILER_LANG['invalid_address']      = 'Neteisingas adresas';
+$PHPMAILER_LANG['mailer_not_supported'] = ' paЕЎto stotis nepalaikoma.';
+$PHPMAILER_LANG['provide_address']      = 'Nurodykite bent vienД… gavД—jo adresД….';
+$PHPMAILER_LANG['recipients_failed']    = 'SMTP klaida: nepavyko iЕЎsiЕіsti ЕЎiems gavД—jams: ';
+$PHPMAILER_LANG['signing']              = 'Prisijungimo klaida: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP susijungimo klaida';
+$PHPMAILER_LANG['smtp_error']           = 'SMTP stoties klaida: ';
+$PHPMAILER_LANG['variable_set']         = 'Nepavyko priskirti reikЕЎmД—s kintamajam: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-lv.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-lv.php
new file mode 100644
index 0000000000000000000000000000000000000000..8eabb5030791b679953085508fc6f9a3de574737
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-lv.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Latvian PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Eduards M. <e@npd.lv>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'SMTP kДјЕ«da: AutorizДЃcija neizdevДЃs.';
+$PHPMAILER_LANG['connect_host']         = 'SMTP KДјЕ«da: Nevar izveidot savienojumu ar SMTP serveri.';
+$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Kļūda: Nepieņem informāciju.';
+$PHPMAILER_LANG['empty_message']        = 'Ziņojuma teksts ir tukšs';
+$PHPMAILER_LANG['encoding']             = 'NeatpazД«ts kodД“jums: ';
+$PHPMAILER_LANG['execute']              = 'NeizdevДЃs izpildД«t komandu: ';
+$PHPMAILER_LANG['file_access']          = 'Fails nav pieejams: ';
+$PHPMAILER_LANG['file_open']            = 'Faila kДјЕ«da: Nevar atvД“rt failu: ';
+$PHPMAILER_LANG['from_failed']          = 'Nepareiza sЕ«tД«tДЃja adrese: ';
+$PHPMAILER_LANG['instantiate']          = 'Nevar palaist sЕ«tД«ЕЎanas funkciju.';
+$PHPMAILER_LANG['invalid_address']      = 'Nepareiza adrese';
+$PHPMAILER_LANG['mailer_not_supported'] = ' sЕ«tД«tДЃjs netiek atbalstД«ts.';
+$PHPMAILER_LANG['provide_address']      = 'LЕ«dzu, norДЃdiet vismaz vienu adresДЃtu.';
+$PHPMAILER_LANG['recipients_failed']    = 'SMTP kļūda: neizdevās nosūtīt šādiem saņēmējiem: ';
+$PHPMAILER_LANG['signing']              = 'AutorizДЃcijas kДјЕ«da: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP savienojuma kДјЕ«da';
+$PHPMAILER_LANG['smtp_error']           = 'SMTP servera kДјЕ«da: ';
+$PHPMAILER_LANG['variable_set']         = 'Nevar pieЕЎД·irt mainД«gДЃ vД“rtД«bu: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-nl.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-nl.php
new file mode 100644
index 0000000000000000000000000000000000000000..87fa940edd7b2b4c9fe513b15dee058764b09f02
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-nl.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Dutch PHPMailer language file: refer to class.phpmailer.php for definitive list.
+ * @package PHPMailer
+ * @author Tuxion <team@tuxion.nl>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'SMTP-fout: authenticatie mislukt.';
+$PHPMAILER_LANG['connect_host']         = 'SMTP-fout: kon niet verbinden met SMTP-host.';
+$PHPMAILER_LANG['data_not_accepted']    = 'SMTP-fout: data niet geaccepteerd.';
+$PHPMAILER_LANG['empty_message']        = 'Berichttekst is leeg';
+$PHPMAILER_LANG['encoding']             = 'Onbekende codering: ';
+$PHPMAILER_LANG['execute']              = 'Kon niet uitvoeren: ';
+$PHPMAILER_LANG['file_access']          = 'Kreeg geen toegang tot bestand: ';
+$PHPMAILER_LANG['file_open']            = 'Bestandsfout: kon bestand niet openen: ';
+$PHPMAILER_LANG['from_failed']          = 'Het volgende afzendersadres is mislukt: ';
+$PHPMAILER_LANG['instantiate']          = 'Kon mailfunctie niet initialiseren.';
+$PHPMAILER_LANG['invalid_address']      = 'Ongeldig adres';
+$PHPMAILER_LANG['mailer_not_supported'] = ' mailer wordt niet ondersteund.';
+$PHPMAILER_LANG['provide_address']      = 'Er moet minstens één ontvanger worden opgegeven.';
+$PHPMAILER_LANG['recipients_failed']    = 'SMTP-fout: de volgende ontvangers zijn mislukt: ';
+$PHPMAILER_LANG['signing']              = 'Signeerfout: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Verbinding mislukt.';
+$PHPMAILER_LANG['smtp_error']           = 'SMTP-serverfout: ';
+$PHPMAILER_LANG['variable_set']         = 'Kan de volgende variablen niet instellen of resetten: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-no.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-no.php
new file mode 100644
index 0000000000000000000000000000000000000000..d02282177a5a846484de6508173054528318dc29
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-no.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Norwegian PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'SMTP Feil: Kunne ikke authentisere.';
+$PHPMAILER_LANG['connect_host']         = 'SMTP Feil: Kunne ikke koble til SMTP host.';
+$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Feil: Data ble ikke akseptert.';
+$PHPMAILER_LANG['empty_message']        = 'Meldingsinnholdet er tomt';
+$PHPMAILER_LANG['encoding']             = 'Ukjent tegnkoding: ';
+$PHPMAILER_LANG['execute']              = 'Kunne ikke utfГёre: ';
+$PHPMAILER_LANG['file_access']          = 'FГҐr ikke tilgang til filen: ';
+$PHPMAILER_LANG['file_open']            = 'Fil feil: Kunne ikke ГҐpne filen: ';
+$PHPMAILER_LANG['from_failed']          = 'FГёlgende avsenderadresse feilet: ';
+$PHPMAILER_LANG['instantiate']          = 'Kunne ikke initialisere mailfunksjonen.';
+$PHPMAILER_LANG['invalid_address']      = 'Meldingen ble ikke sendt, fГёlgende adresse er ugyldig: ';
+$PHPMAILER_LANG['provide_address']      = 'Du mГҐ angi minst en mottakeradresse.';
+$PHPMAILER_LANG['mailer_not_supported'] = ' mailer er ikke supportert.';
+$PHPMAILER_LANG['recipients_failed']    = 'SMTP Feil: FГёlgende mottagere feilet: ';
+$PHPMAILER_LANG['signing']              = 'Signeringsfeil: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() feilet.';
+$PHPMAILER_LANG['smtp_error']           = 'SMTP-serverfeil: ';
+$PHPMAILER_LANG['variable_set']         = 'Kan ikke sette eller resette variabelen: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-pl.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-pl.php
new file mode 100644
index 0000000000000000000000000000000000000000..704961a9eddbca965bcb88dda2ea42d90b78e940
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-pl.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Polish PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'Błąd SMTP: Nie można przeprowadzić uwierzytelnienia.';
+$PHPMAILER_LANG['connect_host']         = 'Błąd SMTP: Nie można połączyć się z wybranym hostem.';
+$PHPMAILER_LANG['data_not_accepted']    = 'BЕ‚Д…d SMTP: Dane nie zostaЕ‚y przyjД™te.';
+$PHPMAILER_LANG['empty_message']        = 'WiadomoЕ›Д‡ jest pusta.';
+$PHPMAILER_LANG['encoding']             = 'Nieznany sposГіb kodowania znakГіw: ';
+$PHPMAILER_LANG['execute']              = 'Nie można uruchomić: ';
+$PHPMAILER_LANG['file_access']          = 'Brak dostД™pu do pliku: ';
+$PHPMAILER_LANG['file_open']            = 'Nie można otworzyć pliku: ';
+$PHPMAILER_LANG['from_failed']          = 'NastД™pujД…cy adres Nadawcy jest nieprawidЕ‚owy: ';
+$PHPMAILER_LANG['instantiate']          = 'Nie można wywołać funkcji mail(). Sprawdź konfigurację serwera.';
+$PHPMAILER_LANG['invalid_address']      = 'Nie można wysłać wiadomości, '.
+    'nastД™pujД…cy adres Odbiorcy jest nieprawidЕ‚owy: ';
+$PHPMAILER_LANG['provide_address']      = 'Należy podać prawidłowy adres email Odbiorcy.';
+$PHPMAILER_LANG['mailer_not_supported'] = 'Wybrana metoda wysyЕ‚ki wiadomoЕ›ci nie jest obsЕ‚ugiwana.';
+$PHPMAILER_LANG['recipients_failed']    = 'BЕ‚Д…d SMTP: NastД™pujД…cy odbiorcy sД… nieprawidЕ‚owi: ';
+$PHPMAILER_LANG['signing']              = 'BЕ‚Д…d podpisywania wiadomoЕ›ci: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() zakoЕ„czone niepowodzeniem.';
+$PHPMAILER_LANG['smtp_error']           = 'BЕ‚Д…d SMTP: ';
+$PHPMAILER_LANG['variable_set']         = 'Nie można ustawić lub zmodyfikować zmiennej: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-pt.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-pt.php
new file mode 100644
index 0000000000000000000000000000000000000000..2c8c1e715fb6d1ed705e2cd96fec8f5d7b040567
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-pt.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Portuguese (European) PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Jonadabe <jonadabe@hotmail.com>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'Erro do SMTP: Não foi possível realizar a autenticação.';
+$PHPMAILER_LANG['connect_host']         = 'Erro do SMTP: Não foi possível realizar ligação com o servidor SMTP.';
+$PHPMAILER_LANG['data_not_accepted']    = 'Erro do SMTP: Os dados foram rejeitados.';
+$PHPMAILER_LANG['empty_message']        = 'A mensagem no e-mail estГЎ vazia.';
+$PHPMAILER_LANG['encoding']             = 'Codificação desconhecida: ';
+$PHPMAILER_LANG['execute']              = 'NГЈo foi possГ­vel executar: ';
+$PHPMAILER_LANG['file_access']          = 'NГЈo foi possГ­vel aceder o ficheiro: ';
+$PHPMAILER_LANG['file_open']            = 'Abertura do ficheiro: NГЈo foi possГ­vel abrir o ficheiro: ';
+$PHPMAILER_LANG['from_failed']          = 'Ocorreram falhas nos endereços dos seguintes remententes: ';
+$PHPMAILER_LANG['instantiate']          = 'Não foi possível iniciar uma instância da função mail.';
+$PHPMAILER_LANG['invalid_address']      = 'Não foi enviado nenhum e-mail para o endereço de e-mail inválido: ';
+$PHPMAILER_LANG['mailer_not_supported'] = ' mailer nГЈo Г© suportado.';
+$PHPMAILER_LANG['provide_address']      = 'Tem de fornecer pelo menos um endereço como destinatário do e-mail.';
+$PHPMAILER_LANG['recipients_failed']    = 'Erro do SMTP: O endereço do seguinte destinatário falhou: ';
+$PHPMAILER_LANG['signing']              = 'Erro ao assinar: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() falhou.';
+$PHPMAILER_LANG['smtp_error']           = 'Erro de servidor SMTP: ';
+$PHPMAILER_LANG['variable_set']         = 'NГЈo foi possГ­vel definir ou redefinir a variГЎvel: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-ro.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-ro.php
new file mode 100644
index 0000000000000000000000000000000000000000..82fbe1b39d83fba701cee0371cb63e820807dfbe
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-ro.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Romanian PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Catalin Constantin <catalin@dazoot.ro>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'Eroare SMTP: Nu a functionat autentificarea.';
+$PHPMAILER_LANG['connect_host']         = 'Eroare SMTP: Nu m-am putut conecta la adresa SMTP.';
+$PHPMAILER_LANG['data_not_accepted']    = 'Eroare SMTP: Continutul mailului nu a fost acceptat.';
+$PHPMAILER_LANG['empty_message']        = 'Mesajul este gol.';
+$PHPMAILER_LANG['encoding']             = 'Encodare necunoscuta: ';
+$PHPMAILER_LANG['execute']              = 'Nu pot executa:  ';
+$PHPMAILER_LANG['file_access']          = 'Nu pot accesa fisierul: ';
+$PHPMAILER_LANG['file_open']            = 'Eroare de fisier: Nu pot deschide fisierul: ';
+$PHPMAILER_LANG['from_failed']          = 'Urmatoarele adrese From au dat eroare: ';
+$PHPMAILER_LANG['instantiate']          = 'Nu am putut instantia functia mail.';
+$PHPMAILER_LANG['invalid_address']      = 'Adresa de email nu este valida. ';
+$PHPMAILER_LANG['mailer_not_supported'] = ' mailer nu este suportat.';
+$PHPMAILER_LANG['provide_address']      = 'Trebuie sa adaugati cel putin un recipient (adresa de mail).';
+$PHPMAILER_LANG['recipients_failed']    = 'Eroare SMTP: Urmatoarele adrese de mail au dat eroare: ';
+$PHPMAILER_LANG['signing']              = 'A aparut o problema la semnarea emailului. ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'Conectarea la serverul SMTP a esuat.';
+$PHPMAILER_LANG['smtp_error']           = 'A aparut o eroare la serverul SMTP. ';
+$PHPMAILER_LANG['variable_set']         = 'Nu se poate seta/reseta variabila. ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-ru.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-ru.php
new file mode 100644
index 0000000000000000000000000000000000000000..83abda4813a30dfa83562558fc9e34c4c4969761
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-ru.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Russian PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Alexey Chumakov <alex@chumakov.ru>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'Ошибка SMTP: ошибка авторизации.';
+$PHPMAILER_LANG['connect_host']         = 'Ошибка SMTP: не удается подключиться к серверу SMTP.';
+$PHPMAILER_LANG['data_not_accepted']    = 'Ошибка SMTP: данные не приняты.';
+$PHPMAILER_LANG['encoding']             = 'Неизвестный вид кодировки: ';
+$PHPMAILER_LANG['execute']              = 'Невозможно выполнить команду: ';
+$PHPMAILER_LANG['file_access']          = 'Нет доступа к файлу: ';
+$PHPMAILER_LANG['file_open']            = 'Файловая ошибка: не удается открыть файл: ';
+$PHPMAILER_LANG['from_failed']          = 'Неверный адрес отправителя: ';
+$PHPMAILER_LANG['instantiate']          = 'Невозможно запустить функцию mail.';
+$PHPMAILER_LANG['provide_address']      = 'Пожалуйста, введите хотя бы один адрес e-mail получателя.';
+$PHPMAILER_LANG['mailer_not_supported'] = ' - почтовый сервер не поддерживается.';
+$PHPMAILER_LANG['recipients_failed']    = 'Ошибка SMTP: отправка по следующим адресам получателей не удалась: ';
+$PHPMAILER_LANG['empty_message']        = 'Пустое тело сообщения';
+$PHPMAILER_LANG['invalid_address']        = 'Не отослано, неправильный формат email адреса: ';
+$PHPMAILER_LANG['signing']              = 'Ошибка подписывания: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'Ошибка соединения с SMTP-сервером';
+$PHPMAILER_LANG['smtp_error']           = 'Ошибка SMTP-сервера: ';
+$PHPMAILER_LANG['variable_set']         = 'Невозможно установить или переустановить переменную: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-se.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-se.php
new file mode 100644
index 0000000000000000000000000000000000000000..2f1c05ac072d3e9cb3c1d35c1db0ea415b70f847
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-se.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Swedish PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Johan LinnГ©r <johan@linner.biz>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'SMTP fel: Kunde inte autentisera.';
+$PHPMAILER_LANG['connect_host']         = 'SMTP fel: Kunde inte ansluta till SMTP-server.';
+$PHPMAILER_LANG['data_not_accepted']    = 'SMTP fel: Data accepterades inte.';
+//$PHPMAILER_LANG['empty_message']        = 'Message body empty';
+$PHPMAILER_LANG['encoding']             = 'Okänt encode-format: ';
+$PHPMAILER_LANG['execute']              = 'Kunde inte köra: ';
+$PHPMAILER_LANG['file_access']          = 'Ingen ГҐtkomst till fil: ';
+$PHPMAILER_LANG['file_open']            = 'Fil fel: Kunde inte Г¶ppna fil: ';
+$PHPMAILER_LANG['from_failed']          = 'Följande avsändaradress är felaktig: ';
+$PHPMAILER_LANG['instantiate']          = 'Kunde inte initiera e-postfunktion.';
+//$PHPMAILER_LANG['invalid_address']        = 'Not sending, email address is invalid: ';
+$PHPMAILER_LANG['provide_address']      = 'Du mГҐste ange minst en mottagares e-postadress.';
+$PHPMAILER_LANG['mailer_not_supported'] = ' mailer stöds inte.';
+$PHPMAILER_LANG['recipients_failed']    = 'SMTP fel: Följande mottagare är felaktig: ';
+//$PHPMAILER_LANG['signing']              = 'Signing Error: ';
+//$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';
+//$PHPMAILER_LANG['smtp_error']           = 'SMTP server error: ';
+//$PHPMAILER_LANG['variable_set']         = 'Cannot set or reset variable: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-sk.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-sk.php
new file mode 100644
index 0000000000000000000000000000000000000000..5c3c12e18a1521d41da96dcf1eaf32365bfcbba5
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-sk.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Slovak PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Michal Tinka <michaltinka@gmail.com>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'SMTP Error: Chyba autentifikГЎcie.';
+$PHPMAILER_LANG['connect_host']         = 'SMTP Error: Nebolo moЕѕnГ© nadviazaЕҐ spojenie so SMTP serverom.';
+$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Error: DГЎta neboli prijatГ©';
+$PHPMAILER_LANG['empty_message']        = 'PrГЎzdne telo sprГЎvy.';
+$PHPMAILER_LANG['encoding']             = 'NeznГЎme kГіdovanie: ';
+$PHPMAILER_LANG['execute']              = 'NedГЎ sa vykonaЕҐ: ';
+$PHPMAILER_LANG['file_access']          = 'SГєbor nebol nГЎjdenГЅ: ';
+$PHPMAILER_LANG['file_open']            = 'File Error: SГєbor sa otvoriЕҐ pre ДЌГ­tanie: ';
+$PHPMAILER_LANG['from_failed']          = 'NГЎsledujГєca adresa From je nesprГЎvna: ';
+$PHPMAILER_LANG['instantiate']          = 'NedГЎ sa vytvoriЕҐ inЕЎtancia emailovej funkcie.';
+$PHPMAILER_LANG['invalid_address']        = 'NeodoslanГ©, emailovГЎ adresa je nesprГЎvna: ';
+$PHPMAILER_LANG['mailer_not_supported'] = ' emailovГЅ klient nieje podporovanГЅ.';
+$PHPMAILER_LANG['provide_address']      = 'MusГ­te zadaЕҐ aspoЕ€ jednu emailovГє adresu prГ­jemcu.';
+$PHPMAILER_LANG['recipients_failed']    = 'SMTP Error: Adresy prГ­jemcov niesu sprГЎvne ';
+$PHPMAILER_LANG['signing']              = 'Chyba prihlasovania: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() zlyhalo.';
+$PHPMAILER_LANG['smtp_error']           = 'SMTP chyba serveru: ';
+$PHPMAILER_LANG['variable_set']         = 'NemoЕѕno nastaviЕҐ alebo resetovaЕҐ premennГє: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-sr.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-sr.php
new file mode 100644
index 0000000000000000000000000000000000000000..29258e36b56756589134530b88847d84cb19404f
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-sr.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Serbian PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Александар Јевремовић <ajevremovic@gmail.com>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'SMTP грешка: аутентификација није успела.';
+$PHPMAILER_LANG['connect_host']         = 'SMTP грешка: није могуће повезивање са SMTP сервером.';
+$PHPMAILER_LANG['data_not_accepted']    = 'SMTP грешка: подаци нису прихваћени.';
+$PHPMAILER_LANG['empty_message']        = 'Садржај поруке је празан.';
+$PHPMAILER_LANG['encoding']             = 'Непознато кодовање: ';
+$PHPMAILER_LANG['execute']              = 'Није могуће извршити наредбу: ';
+$PHPMAILER_LANG['file_access']          = 'Није могуће приступити датотеци: ';
+$PHPMAILER_LANG['file_open']            = 'Није могуће отворити датотеку: ';
+$PHPMAILER_LANG['from_failed']          = 'SMTP грешка: слање са следећих адреса није успело: ';
+$PHPMAILER_LANG['recipients_failed']    = 'SMTP грешка: слање на следеће адресе није успело: ';
+$PHPMAILER_LANG['instantiate']          = 'Није могуће покренути mail функцију.';
+$PHPMAILER_LANG['invalid_address']      = 'Порука није послата због неисправне адресе.';
+$PHPMAILER_LANG['mailer_not_supported'] = ' мејлер није подржан.';
+$PHPMAILER_LANG['provide_address']      = 'Потребно је задати најмање једну адресу.';
+$PHPMAILER_LANG['signing']              = 'Грешка приликом пријављивања: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'Повезивање са SMTP сервером није успело.';
+$PHPMAILER_LANG['smtp_error']           = 'Грешка SMTP сервера: ';
+$PHPMAILER_LANG['variable_set']         = 'Није могуће задати променљиву, нити је вратити уназад: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-tr.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-tr.php
new file mode 100644
index 0000000000000000000000000000000000000000..c291ea68c3c27d5e5d27c07fd551cc86db98c3e0
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-tr.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Turkish PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Elçin Özel
+ * @author Can YД±lmaz
+ * @author Mehmet BenlioДџlu
+ * @author @yasinaydin
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'SMTP Hatası: Oturum açılamadı.';
+$PHPMAILER_LANG['connect_host']         = 'SMTP HatasД±: SMTP sunucusuna baДџlanД±lamadД±.';
+$PHPMAILER_LANG['data_not_accepted']    = 'SMTP HatasД±: Veri kabul edilmedi.';
+$PHPMAILER_LANG['empty_message']        = 'Mesajın içeriği boş';
+$PHPMAILER_LANG['encoding']             = 'Bilinmeyen karakter kodlama: ';
+$PHPMAILER_LANG['execute']              = 'Г‡alД±ЕџtД±rД±lamadД±: ';
+$PHPMAILER_LANG['file_access']          = 'Dosyaya eriЕџilemedi: ';
+$PHPMAILER_LANG['file_open']            = 'Dosya Hatası: Dosya açılamadı: ';
+$PHPMAILER_LANG['from_failed']          = 'Belirtilen adreslere gönderme başarısız: ';
+$PHPMAILER_LANG['instantiate']          = 'Г–rnek e-posta fonksiyonu oluЕџturulamadД±.';
+$PHPMAILER_LANG['invalid_address']      = 'Geçersiz e-posta adresi: ';
+$PHPMAILER_LANG['mailer_not_supported'] = ' e-posta kГјtГјphanesi desteklenmiyor.';
+$PHPMAILER_LANG['provide_address']      = 'En az bir alД±cД± e-posta adresi belirtmelisiniz.';
+$PHPMAILER_LANG['recipients_failed']    = 'SMTP HatasД±: Belirtilen alД±cД±lara ulaЕџД±lamadД±: ';
+$PHPMAILER_LANG['signing']              = 'Д°mzalama hatasД±: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP connect() fonksiyonu baЕџarД±sД±z.';
+$PHPMAILER_LANG['smtp_error']           = 'SMTP sunucu hatasД±: ';
+$PHPMAILER_LANG['variable_set']         = 'DeДџiЕџken ayarlanamadД± ya da sД±fД±rlanamadД±: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-uk.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-uk.php
new file mode 100644
index 0000000000000000000000000000000000000000..c2bb86c2c8a5263bf9c998566beb7bee508d65d2
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-uk.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Ukrainian PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author Yuriy Rudyy <yrudyy@prs.net.ua>
+ */
+
+$PHPMAILER_LANG['authenticate']         = 'Помилка SMTP: помилка авторизації.';
+$PHPMAILER_LANG['connect_host']         = 'Помилка SMTP: не вдається підєднатися до серверу SMTP.';
+$PHPMAILER_LANG['data_not_accepted']    = 'Помилка SMTP: дані не прийняті.';
+$PHPMAILER_LANG['encoding']             = 'Невідомий тип кодування: ';
+$PHPMAILER_LANG['execute']              = 'Неможливо виконати команду: ';
+$PHPMAILER_LANG['file_access']          = 'Немає доступу до файлу: ';
+$PHPMAILER_LANG['file_open']            = 'Помилка файлової системи: не вдається відкрити файл: ';
+$PHPMAILER_LANG['from_failed']          = 'Невірна адреса відправника: ';
+$PHPMAILER_LANG['instantiate']          = 'Неможливо запустити функцію mail.';
+$PHPMAILER_LANG['provide_address']      = 'Будь-ласка, введіть хоча б одну адресу e-mail отримувача.';
+$PHPMAILER_LANG['mailer_not_supported'] = ' - поштовий сервер не підтримується.';
+$PHPMAILER_LANG['recipients_failed']    = 'Помилка SMTP: відправти наступним отрмувачам не вдалася: ';
+$PHPMAILER_LANG['empty_message']        = 'Пусте тіло повідомлення';
+$PHPMAILER_LANG['invalid_address']      = 'Не відправлено, невірний формат email адреси: ';
+$PHPMAILER_LANG['signing']              = 'Помилка підпису: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'Помилка зєднання із SMTP-сервером';
+$PHPMAILER_LANG['smtp_error']           = 'Помилка SMTP-сервера: ';
+$PHPMAILER_LANG['variable_set']         = 'Неможливо встановити або перевстановити змінну: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-vi.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-vi.php
new file mode 100644
index 0000000000000000000000000000000000000000..00f741f3bb59a580aac157983b8280bc4884cce0
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-vi.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Vietnamese (Tiếng Việt) PHPMailer language file: refer to English translation for definitive list.
+ * @package PHPMailer
+ * @author VINADES.,JSC <contact@vinades.vn>
+ */
+
+$PHPMAILER_LANG['authenticate'] = 'Lб»—i SMTP: KhГґng thб»ѓ xГЎc thб»±c.';
+$PHPMAILER_LANG['connect_host'] = 'Lỗi SMTP: Không thể kết nối máy chủ SMTP.';
+$PHPMAILER_LANG['data_not_accepted'] = 'Lỗi SMTP: Dữ liệu không được chấp nhận.';
+$PHPMAILER_LANG['empty_message'] = 'KhГґng cГі nб»™i dung';
+$PHPMAILER_LANG['encoding'] = 'MГЈ hГіa khГґng xГЎc Д‘б»‹nh: ';
+$PHPMAILER_LANG['execute'] = 'Không thực hiện được: ';
+$PHPMAILER_LANG['file_access'] = 'Không thể truy cập tệp tin ';
+$PHPMAILER_LANG['file_open'] = 'Lỗi Tập tin: Không thể mở tệp tin: ';
+$PHPMAILER_LANG['from_failed'] = 'Lỗi địa chỉ gửi đi: ';
+$PHPMAILER_LANG['instantiate'] = 'KhГґng dГ№ng Д‘Ж°б»Јc cГЎc hГ m gб»­i thЖ°.';
+$PHPMAILER_LANG['invalid_address'] = 'Đại chỉ emai không đúng';
+$PHPMAILER_LANG['mailer_not_supported'] = ' trình gửi thư không được hỗ trợ.';
+$PHPMAILER_LANG['provide_address'] = 'Bạn phải cung cấp ít nhất một địa chỉ người nhận.';
+$PHPMAILER_LANG['recipients_failed'] = 'Lỗi SMTP: lỗi địa chỉ người nhận: ';
+$PHPMAILER_LANG['signing'] = 'Lб»—i Д‘Дѓng nhбє­p: ';
+$PHPMAILER_LANG['smtp_connect_failed'] = 'Lб»—i kбєїt nб»‘i vб»›i SMTP';
+$PHPMAILER_LANG['smtp_error'] = 'Lỗi máy chủ smtp ';
+$PHPMAILER_LANG['variable_set'] = 'KhГґng thб»ѓ thiбєїt lбє­p hoбє·c thiбєїt lбє­p lбєЎi biбєїn: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-zh.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-zh.php
new file mode 100644
index 0000000000000000000000000000000000000000..3e3e88362c2e81360f3c5ababbfea42835e1cccf
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-zh.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Traditional Chinese PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author liqwei <liqwei@liqwei.com>
+ * @author Peter Dave Hello <@PeterDaveHello/>
+ */
+
+$PHPMAILER_LANG['authenticate'] = 'SMTP 錯誤:登入失敗。';
+$PHPMAILER_LANG['connect_host'] = 'SMTP йЊЇиЄ¤пјљз„Ўжі•йЂЈз·ље€° SMTP дё»ж©џгЂ‚';
+$PHPMAILER_LANG['data_not_accepted'] = 'SMTP йЊЇиЄ¤пјљз„Ўжі•жЋҐеЏ—зљ„иі‡ж–™гЂ‚';
+$PHPMAILER_LANG['empty_message'] = '郵件內容為空';
+$PHPMAILER_LANG['encoding'] = '未知編碼: ';
+$PHPMAILER_LANG['file_access'] = '無法存取檔案:';
+$PHPMAILER_LANG['file_open'] = 'жЄ”жЎ€йЊЇиЄ¤пјљз„Ўжі•й–‹е•џжЄ”жЎ€пјљ';
+$PHPMAILER_LANG['from_failed'] = 'з™јйЂЃењ°еќЂйЊЇиЄ¤пјљ';
+$PHPMAILER_LANG['execute'] = 'з„Ўжі•еџ·иЎЊпјљ';
+$PHPMAILER_LANG['instantiate'] = '未知函數呼叫。';
+$PHPMAILER_LANG['invalid_address'] = '因為電子郵件地址無效,無法傳送: ';
+$PHPMAILER_LANG['provide_address'] = '必須提供至少一個收件人地址。';
+$PHPMAILER_LANG['mailer_not_supported'] = '不支援的發信客戶端。';
+$PHPMAILER_LANG['recipients_failed'] = 'SMTP 錯誤:收件人地址錯誤:';
+$PHPMAILER_LANG['signing']              = '登入失敗: ';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP連線失敗';
+$PHPMAILER_LANG['smtp_error']           = 'SMTPдјєжњЌе™ЁйЊЇиЄ¤: ';
+$PHPMAILER_LANG['variable_set']         = 'з„Ўжі•иЁ­е®љж€–й‡ЌиЁ­и®Љж•ё: ';
diff --git a/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-zh_cn.php b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-zh_cn.php
new file mode 100644
index 0000000000000000000000000000000000000000..2250dc0c635efeb1ece0190abbb6c74fa97f51a9
--- /dev/null
+++ b/~dev_rating/modules/mail/vendor/PHPMailer/language/phpmailer.lang-zh_cn.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Simplified Chinese PHPMailer language file: refer to English translation for definitive list
+ * @package PHPMailer
+ * @author liqwei <liqwei@liqwei.com>
+ * @author young <masxy@foxmail.com>
+ */
+
+$PHPMAILER_LANG['authenticate'] = 'SMTP 错误:登录失败。';
+$PHPMAILER_LANG['connect_host'] = 'SMTP й”™иЇЇпјљж— жі•иїћжЋҐе€° SMTP дё»жњєгЂ‚';
+$PHPMAILER_LANG['data_not_accepted'] = 'SMTP й”™иЇЇпјљж•°жЌ®дёЌиў«жЋҐеЏ—гЂ‚';
+$PHPMAILER_LANG['empty_message']        = '邮件正文为空。';
+$PHPMAILER_LANG['encoding'] = '未知编码: ';
+$PHPMAILER_LANG['execute'] = '无法执行:';
+$PHPMAILER_LANG['file_access'] = '无法访问文件:';
+$PHPMAILER_LANG['file_open'] = '文件错误:无法打开文件:';
+$PHPMAILER_LANG['from_failed'] = 'еЏ‘йЂЃењ°еќЂй”™иЇЇпјљ';
+$PHPMAILER_LANG['instantiate'] = '未知函数调用。';
+$PHPMAILER_LANG['invalid_address']        = '发送失败,电子邮箱地址是无效的。';
+$PHPMAILER_LANG['mailer_not_supported'] = 'еЏ‘дїЎе®ўж€·з«ЇдёЌиў«ж”ЇжЊЃгЂ‚';
+$PHPMAILER_LANG['provide_address'] = '必须提供至少一个收件人地址。';
+$PHPMAILER_LANG['recipients_failed'] = 'SMTP 错误:收件人地址错误:';
+$PHPMAILER_LANG['signing']              = '登录失败:';
+$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP服务器连接失败。';
+$PHPMAILER_LANG['smtp_error']           = 'SMTPжњЌеЉЎе™Ёе‡єй”™: ';
+$PHPMAILER_LANG['variable_set']         = '无法设置或重置变量:';