diff --git a/include/class.attachment.php b/include/class.attachment.php
index 15f3fd9b1dec6de619247e1158771a73434ba797..bcda6d08af5d757c01b691b78a29b28f03def623 100644
--- a/include/class.attachment.php
+++ b/include/class.attachment.php
@@ -108,15 +108,23 @@ extends InstrumentedList {
      */
     function keepOnlyFileIds($ids, $inline=false, $lang=false) {
         if (!$ids) $ids = array();
-        $new = array_fill_keys($ids, 1);
+        $new = array_flip($ids);
         foreach ($this as $A) {
             if (!isset($new[$A->file_id]) && $A->lang == $lang && $A->inline == $inline)
                 // Not in the $ids list, delete
                 $this->remove($A);
             unset($new[$A->file_id]);
         }
-        // Everything remaining in $new is truly new
-        $this->upload(array_keys($new), $inline, $lang);
+        $attachments = array();
+        // Format $new for upload() with new name
+        foreach ($new as $id=>$name) {
+            $attachments[] = array(
+                    'id' => $id,
+                    'name' => $name
+                );
+        }
+        // Everything remaining in $attachments is truly new
+        $this->upload($attachments, $inline, $lang);
     }
 
     function upload($files, $inline=false, $lang=false) {
diff --git a/include/class.auth.php b/include/class.auth.php
index 1dc5a9ccf8f05172bd081929dfcb4d50c4104fa8..cf1866a4ce32bb4d321299ad3e0a41149e082818 100644
--- a/include/class.auth.php
+++ b/include/class.auth.php
@@ -1313,7 +1313,35 @@ abstract class PasswordPolicy {
     static function register($policy) {
         static::$registry[] = $policy;
     }
+
+    static function cleanSessions($model, $user=null) {
+        $criteria = array();
+
+        switch (true) {
+            case ($model instanceof Staff):
+                $criteria['user_id'] = $model->getId();
+
+                if ($user && ($model->getId() == $user->getId()))
+                    array_push($criteria,
+                        Q::not(array('session_id' => $user->session->session_id)));
+                break;
+            case ($model instanceof User):
+                $regexp = '_auth\|.*"user";[a-z]+:[0-9]+:{[a-z]+:[0-9]+:"id";[a-z]+:'.$model->getId();
+                $criteria['user_id'] = 0;
+                $criteria['session_data__regex'] = $regexp;
+
+                if ($user)
+                    array_push($criteria,
+                        Q::not(array('session_id' => $user->session->session_id)));
+                break;
+            default:
+                return false;
+        }
+
+        return SessionData::objects()->filter($criteria)->delete();
+    }
 }
+Signal::connect('auth.clean', array('PasswordPolicy', 'cleanSessions'));
 
 class osTicketPasswordPolicy
 extends PasswordPolicy {
diff --git a/include/class.client.php b/include/class.client.php
index 53b6376c98ce603b76251ec6d4295fa88d91b2b8..bcf3c4257f8a2c0d2e4222b2ba4beb66b78e005c 100644
--- a/include/class.client.php
+++ b/include/class.client.php
@@ -396,7 +396,7 @@ class ClientAccount extends UserAccount {
         global $cfg;
 
         // FIXME: Updates by agents should go through UserAccount::update()
-        global $thisstaff;
+        global $thisstaff, $thisclient;
         if ($thisstaff)
             return parent::update($vars, $errors);
 
@@ -454,6 +454,8 @@ class ClientAccount extends UserAccount {
             Signal::send('auth.pwchange', $this->getUser(), $info);
             $this->cancelResetTokens();
             $this->clearStatus(UserAccountStatus::REQUIRE_PASSWD_RESET);
+            // Clean sessions
+            Signal::send('auth.clean', $this->getUser(), $thisclient);
         }
 
         return $this->save();
diff --git a/include/class.config.php b/include/class.config.php
index 6ce3716b931d710751b6ecc122f31798a7b459fb..32f5ca702feb2855e52d437ea8d4bbb625354ded 100644
--- a/include/class.config.php
+++ b/include/class.config.php
@@ -176,6 +176,20 @@ extends VerySimpleModel {
             $this->updated = SqlFunction::NOW();
         return parent::save($this->dirty || $refetch);
     }
+
+    // Clean password reset tokens that have expired
+    static function cleanPwResets() {
+        global $cfg;
+
+        if (!$cfg || !($period = $cfg->getPwResetWindow())) // In seconds
+            return false;
+
+        return ConfigItem::objects()
+             ->filter(array(
+                'namespace' => 'pwreset',
+                'updated__lt' => SqlFunction::NOW()->minus(SqlInterval::SECOND($period)),
+            ))->delete();
+    }
 }
 
 class OsticketConfig extends Config {
diff --git a/include/class.cron.php b/include/class.cron.php
index 232d6bf2bee90bad3824e238ee77812ee411a187..5db0a5b7b1aa6e898096e1cf964fc90d786d76fa 100644
--- a/include/class.cron.php
+++ b/include/class.cron.php
@@ -56,6 +56,11 @@ class Cron {
         DbSessionBackend::cleanup();
     }
 
+    function CleanPwResets() {
+        require_once(INCLUDE_DIR.'class.config.php');
+        ConfigItem::cleanPwResets();
+    }
+
     function MaybeOptimizeTables() {
         // Once a week on a 5-minute cron
         $chance = rand(1,2000);
@@ -106,6 +111,7 @@ class Cron {
         self::TicketMonitor();
         self::PurgeLogs();
         self::CleanExpiredSessions();
+        self::CleanPwResets();
         // Run file purging about every 10 cron runs
         if (mt_rand(1, 9) == 4)
             self::CleanOrphanedFiles();
diff --git a/include/class.filter.php b/include/class.filter.php
index 29f49d904949b2318dbd4da9d16c6ebed7f1f299..64ad3625db96aa98eb900b2d45ce68957361ea59 100644
--- a/include/class.filter.php
+++ b/include/class.filter.php
@@ -251,7 +251,7 @@ class Filter {
             'starts'    => array('stripos', 0),
             'ends'      => array('iendsWith', true),
             'match'     => array('pregMatchB', 1),
-            'not_match' => array('pregMatchB', null, 0),
+            'not_match' => array('pregMatchB', null, 1),
         );
 
         $match = false;
diff --git a/include/class.format.php b/include/class.format.php
index 9b5f0fe5a6efaf7c9e603465d2d55aabadf3df19..fead2044d9abe9c018d6eb66482c84dde14b6356 100644
--- a/include/class.format.php
+++ b/include/class.format.php
@@ -894,17 +894,10 @@ class Format {
           return sprintf($timeDiff >= 0 ? __('%d hours ago') : __('in %d hours'), $absTimeDiff / 3600);
         }
 
-        // within 2 days
-        $days2 = 2 * 86400;
-        if ($absTimeDiff < $days2) {
-            // XXX: yesterday / tomorrow?
-          return $absTimeDiff >= 0 ? __('yesterday') : __('tomorrow');
-        }
-
         // within 29 days
         $days29 = 29 * 86400;
         if ($absTimeDiff < $days29) {
-          return sprintf($timeDiff >= 0 ? __('%d days ago') : __('in %d days'), $absTimeDiff / 86400);
+          return sprintf($timeDiff >= 0 ? __('%d days ago') : __('in %d days'), round($absTimeDiff / 86400));
         }
 
         // within 60 days
diff --git a/include/class.forms.php b/include/class.forms.php
index 0fc575637fb65985892316196c8697f55e15211e..4a447cd14bcd0def2ed14a24892983b5023fc62c 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -2688,6 +2688,7 @@ class FileUploadField extends FormField {
     static $widget = 'FileUploadWidget';
 
     protected $attachments;
+    protected $files;
 
     static function getFileTypes() {
         static $filetypes;
@@ -2859,7 +2860,7 @@ class FileUploadField extends FormField {
         return ($ext && is_array($allowed) && in_array(".$ext", $allowed));
     }
 
-    function getFiles() {
+    function getAttachments() {
         if (!isset($this->attachments) && ($a = $this->getAnswer())
             && ($e = $a->getEntry()) && ($e->get('id'))
         ) {
@@ -2875,6 +2876,18 @@ class FileUploadField extends FormField {
         $this->attachments = $att;
     }
 
+    function getFiles() {
+        if (!isset($this->files)) {
+            $files = array();
+            foreach ($this->getAttachments() as $a) {
+                if ($a && ($f=$a->getFile()))
+                    $files[] = $f;
+            }
+            $this->files = $files;
+        }
+        return $this->files;
+    }
+
     function getConfiguration() {
         $config = parent::getConfiguration();
         $_types = self::getFileTypes();
@@ -2932,8 +2945,8 @@ class FileUploadField extends FormField {
     // array. Then, inspect the difference between the files actually
     // attached to this field
     function to_database($value) {
-        $this->getFiles();
-        if (isset($this->attachments)) {
+        $this->getAttachments();
+        if (isset($this->attachments) && $this->attachments) {
             $this->attachments->keepOnlyFileIds($value);
         }
         return JsonDataEncoder::encode($value);
@@ -2951,10 +2964,10 @@ class FileUploadField extends FormField {
 
     function display($value) {
         $links = array();
-        foreach ($this->getFiles() as $f) {
+        foreach ($this->getAttachments() as $a) {
             $links[] = sprintf('<a class="no-pjax" href="%s">%s</a>',
-                Format::htmlchars($f->file->getDownloadUrl()),
-                Format::htmlchars($f->file->name));
+                Format::htmlchars($a->file->getDownloadUrl()),
+                Format::htmlchars($a->getFilename()));
         }
         return implode('<br/>', $links);
     }
@@ -2962,21 +2975,22 @@ class FileUploadField extends FormField {
     function toString($value) {
         $files = array();
         foreach ($this->getFiles() as $f) {
-            $files[] = $f->file->name;
+            $files[] = $f->name;
         }
         return implode(', ', $files);
     }
 
     function db_cleanup($field=false) {
-        // Delete associated attachments from the database, if any
-        $this->getFiles();
-        if (isset($this->attachments)) {
+        if ($this->getAttachments()) {
             $this->attachments->deleteAll();
         }
     }
 
     function asVar($value, $id=false) {
-        return new FileFieldAttachments($this->getFiles());
+        if (($attachments = $this->getAttachments()))
+            $attachments = $attachments->all();
+
+        return new FileFieldAttachments($attachments ?: array());
     }
     function asVarType() {
         return 'FileFieldAttachments';
@@ -3015,26 +3029,30 @@ class FileUploadField extends FormField {
 }
 
 class FileFieldAttachments {
-    var $files;
+    var $attachments;
 
-    function __construct($files) {
-        $this->files = $files;
+    function __construct($attachments) {
+        $this->attachments = $attachments;
     }
 
     function __toString() {
         $files = array();
-        foreach ($this->files as $f) {
-            $files[] = $f->file->name;
+        foreach ($this->getAttachments() as $a) {
+            $files[] = $a->getFilename();
         }
         return implode(', ', $files);
     }
 
+    function getAttachments() {
+        return $this->attachments ?: array();
+    }
+
     function getVar($tag) {
         switch ($tag) {
         case 'names':
             return $this->__toString();
         case 'files':
-            throw new OOBContent(OOBContent::FILES, $this->files->all());
+            throw new OOBContent(OOBContent::FILES, $this->getAttachments());
         }
     }
 
@@ -3891,33 +3909,32 @@ class FileUploadWidget extends Widget {
         $config = $this->field->getConfiguration();
         $name = $this->field->getFormName();
         $id = substr(md5(spl_object_hash($this)), 10);
-        $attachments = $this->field->getFiles();
+        $attachments = $this->field->getAttachments();
         $mimetypes = array_filter($config['__mimetypes'],
             function($t) { return strpos($t, '/') !== false; }
         );
         $maxfilesize = ($config['size'] ?: 1048576) / 1048576;
-        $files = $F = array();
+        $files = array();
         $new = array_fill_keys($this->field->getClean(), 1);
         foreach ($attachments as $a) {
-            $F[] = $a->file;
             unset($new[$a->file_id]);
         }
         // Add in newly added files not yet saved (if redisplaying after an
         // error)
         if ($new) {
-            $F = array_merge($F, AttachmentFile::objects()
-                ->filter(array('id__in' => array_keys($new)))
+            $attachments = array_merge($attachments, GenericAttachment::objects()
+                ->filter(array('file_id__in' => array_keys($new)))
                 ->all()
             );
         }
 
-        foreach ($F as $file) {
+        foreach ($attachments as $att) {
             $files[] = array(
-                'id' => $file->getId(),
-                'name' => $file->getName(),
-                'type' => $file->getType(),
-                'size' => $file->getSize(),
-                'download_url' => $file->getDownloadUrl(),
+                'id' => $att->file->getId(),
+                'name' => $att->getFilename(),
+                'type' => $att->file->getType(),
+                'size' => $att->file->getSize(),
+                'download_url' => $att->file->getDownloadUrl(),
             );
         }
         ?><div id="<?php echo $id;
@@ -4049,21 +4066,22 @@ class FreeTextField extends FormField {
     }
 
     function getAttachments() {
-
         if (!isset($this->attachments))
             $this->attachments = GenericAttachments::forIdAndType($this->get('id'), 'I');
 
-        return $this->attachments;
+        return $this->attachments ?: array();
     }
 
     function getFiles() {
-
-        if (!($attachments = $this->getAttachments()))
-            return array();
-
-        return $attachments->all();
+        if (!isset($this->files)) {
+            $files = array();
+            if (($attachments=$this->getAttachments()))
+                foreach ($attachments->all() as $a)
+                    $files[] = $a->getFile();
+            $this->files = $files;
+        }
+        return $this->files;
     }
-
 }
 
 class FreeTextWidget extends Widget {
@@ -4085,10 +4103,10 @@ class FreeTextWidget extends Widget {
             echo Format::viewableImages($config['content']); ?></div>
         </div>
         <?php
-        if (($attachments=$this->field->getFiles())) { ?>
+        if (($attachments = $this->field->getAttachments()) && count($attachments)) { ?>
             <section class="freetext-files">
             <div class="title"><?php echo __('Related Resources'); ?></div>
-            <?php foreach ($attachments as $attach) { ?>
+            <?php foreach ($attachments->all() as $attach) { ?>
                 <div class="file">
                 <a href="<?php echo $attach->file->getDownloadUrl(); ?>"
                     target="_blank" download="<?php echo $attach->file->getDownloadUrl();
diff --git a/include/class.mailer.php b/include/class.mailer.php
index a97cf650f1addc3b6537b901b1c46f1c3c08a78a..08de4edc7378bcc9bb91c080652fac97680e28c1 100644
--- a/include/class.mailer.php
+++ b/include/class.mailer.php
@@ -422,10 +422,10 @@ class Mailer {
 
         // Add in extra attachments, if any from template variables
         if ($message instanceof TextWithExtras
-            && ($files = $message->getFiles())
+            && ($attachments = $message->getAttachments())
         ) {
-            foreach ($files as $F) {
-                $file = $F->getFile();
+            foreach ($attachments as $a) {
+                $file = $a->getFile();
                 $mime->addAttachment($file->getData(),
                     $file->getType(), $file->getName(), false);
             }
diff --git a/include/class.pdf.php b/include/class.pdf.php
index c12d071e82dd48058513fad2d1a89dcf5efb25a7..39f47a80b4281561882db3b69d6a9ec6dd482052 100644
--- a/include/class.pdf.php
+++ b/include/class.pdf.php
@@ -86,6 +86,7 @@ class Ticket2PDF extends mPDFWithLocalImages
             return;
         $html = ob_get_clean();
 
+        $this->SetAutoFont();
         $this->WriteHtml($html, 0, true, true);
     }
 }
@@ -115,6 +116,7 @@ class Task2PDF extends mPDFWithLocalImages {
         ob_start();
         include STAFFINC_DIR.'templates/task-print.tmpl.php';
         $html = ob_get_clean();
+        $this->SetAutoFont();
         $this->WriteHtml($html, 0, true, true);
 
     }
diff --git a/include/class.role.php b/include/class.role.php
index 0e0f89af2b493003fe2ef3437a0e554152325c36..7afb3f21b20437c72dc1855bf37e81f05aca7049 100644
--- a/include/class.role.php
+++ b/include/class.role.php
@@ -320,6 +320,16 @@ class RolePermission {
     }
 
     static function allPermissions() {
+        static $sorted = false;
+
+        if (!$sorted) {
+            // Sort permissions in alphabetical order
+            foreach (static::$_permissions as $k => $v) {
+                asort(static::$_permissions[$k]);
+            }
+            $sorted = true;
+        }
+
         return static::$_permissions;
     }
 
diff --git a/include/class.staff.php b/include/class.staff.php
index e5ed7e77555e5bb72f1376d10de92bc9b579569d..941f8baba2abd7849ed3c3d9036be434de26b3d7 100644
--- a/include/class.staff.php
+++ b/include/class.staff.php
@@ -217,6 +217,8 @@ implements AuthenticatedUser, EmailContact, TemplateVariable {
     }
 
     function setPassword($new, $current=false) {
+        global $thisstaff;
+
         // Allow the backend to update the password. This is the preferred
         // method as it allows for integration with password policies and
         // also allows for remotely updating the password where possible and
@@ -241,6 +243,9 @@ implements AuthenticatedUser, EmailContact, TemplateVariable {
         $this->cancelResetTokens();
         $this->passwdreset = SqlFunction::NOW();
 
+        // Clean sessions
+        Signal::send('auth.clean', $this, $thisstaff);
+
         return $rv;
     }
 
diff --git a/include/class.user.php b/include/class.user.php
index f0d5f235d85f14dd2d55efec6590c814f74d3b1d..e16259ce7e30f50ba15d619de90a24de4f6924f8 100644
--- a/include/class.user.php
+++ b/include/class.user.php
@@ -1033,6 +1033,8 @@ class UserAccount extends VerySimpleModel {
 
     function setPassword($new) {
         $this->set('passwd', Passwd::hash($new));
+        // Clean sessions
+        Signal::send('auth.clean', $this->getUser());
     }
 
     protected function sendUnlockEmail($template) {
diff --git a/include/class.variable.php b/include/class.variable.php
index 8b346e0cd387483494dc2f245211a16ac75a5784..6a1517b9426a551afe416cb8441f713f37aff421 100644
--- a/include/class.variable.php
+++ b/include/class.variable.php
@@ -383,8 +383,8 @@ class TextWithExtras {
         return $this->text;
     }
 
-    function getFiles() {
-        return $this->extras[OOBContent::FILES];
+    function getAttachments() {
+        return $this->extras[OOBContent::FILES] ?: array();
     }
 }
 
diff --git a/include/client/templates/sidebar.tmpl.php b/include/client/templates/sidebar.tmpl.php
index 09f9bd689c80c7be183b95bde2de14084c3ce031..b6f7958389d83b368519414faea567f9c5b6da23 100644
--- a/include/client/templates/sidebar.tmpl.php
+++ b/include/client/templates/sidebar.tmpl.php
@@ -19,8 +19,9 @@ $BUTTONS = isset($BUTTONS) ? $BUTTONS : true;
         </div>
 <?php } ?>
         <div class="content"><?php
-    $faqs = FAQ::getFeatured()->select_related('category')->limit(5);
-    if ($faqs->all()) { ?>
+    if ($cfg->isKnowledgebaseEnabled()
+        && ($faqs = FAQ::getFeatured()->select_related('category')->limit(5))
+        && $faqs->all()) { ?>
             <section><div class="header"><?php echo __('Featured Questions'); ?></div>
 <?php   foreach ($faqs as $F) { ?>
             <div><a href="<?php echo ROOT_PATH; ?>kb/faq.php?id=<?php
diff --git a/include/mpdf/ttfonts/XB Riyaz.ttf b/include/mpdf/ttfonts/XB Riyaz.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..80e15803dc0aa7b0d8758e0e26793d10fa484ef1
Binary files /dev/null and b/include/mpdf/ttfonts/XB Riyaz.ttf differ
diff --git a/include/mpdf/ttfonts/XB RiyazBd.ttf b/include/mpdf/ttfonts/XB RiyazBd.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..e6cf58f93bb2d2093a9b858ab74393416537c46b
Binary files /dev/null and b/include/mpdf/ttfonts/XB RiyazBd.ttf differ
diff --git a/include/mpdf/ttfonts/XB RiyazBdIt.ttf b/include/mpdf/ttfonts/XB RiyazBdIt.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..19fba7887e965c9f331479862c53ec97f4caf22e
Binary files /dev/null and b/include/mpdf/ttfonts/XB RiyazBdIt.ttf differ
diff --git a/include/mpdf/ttfonts/XB RiyazIt.ttf b/include/mpdf/ttfonts/XB RiyazIt.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..cc9cc3ab2a7da6ee26b3d78b18f2c18de42474a4
Binary files /dev/null and b/include/mpdf/ttfonts/XB RiyazIt.ttf differ
diff --git a/include/mpdf/ttfonts/XB Zar Bd.ttf b/include/mpdf/ttfonts/XB Zar Bd.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..52a2e38f977989124e657b0d197cf78b5af7a8d8
Binary files /dev/null and b/include/mpdf/ttfonts/XB Zar Bd.ttf differ
diff --git a/include/mpdf/ttfonts/XB Zar BdIt.ttf b/include/mpdf/ttfonts/XB Zar BdIt.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..a7f19d97b7e85f5fa95ad99c58a6a847da78bd8e
Binary files /dev/null and b/include/mpdf/ttfonts/XB Zar BdIt.ttf differ
diff --git a/include/mpdf/ttfonts/XB Zar It.ttf b/include/mpdf/ttfonts/XB Zar It.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..4365d1d78ec95f847d650c89f65c91105df71dd8
Binary files /dev/null and b/include/mpdf/ttfonts/XB Zar It.ttf differ
diff --git a/include/mpdf/ttfonts/XB Zar.ttf b/include/mpdf/ttfonts/XB Zar.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..7a168b6ee5eb76c3ef3731017c604e25ce30b995
Binary files /dev/null and b/include/mpdf/ttfonts/XB Zar.ttf differ
diff --git a/include/staff/tasks.inc.php b/include/staff/tasks.inc.php
index 6d52d61fa2952b5413bd9eb6a62aebd71891e3ad..712a795af5d7ea2da6093b89c5c79f17ecb9eddf 100644
--- a/include/staff/tasks.inc.php
+++ b/include/staff/tasks.inc.php
@@ -127,19 +127,19 @@ if ($filters)
 // Impose visibility constraints
 // ------------------------------------------------------------
 // -- Open and assigned to me
-$visibility = array(
+$visibility = Q::any(
     new Q(array('flags__hasbit' => TaskModel::ISOPEN, 'staff_id' => $thisstaff->getId()))
 );
 // -- Routed to a department of mine
 if (!$thisstaff->showAssignedOnly() && ($depts=$thisstaff->getDepts()))
-    $visibility[] = new Q(array('dept_id__in' => $depts));
+    $visibility->add(new Q(array('dept_id__in' => $depts)));
 // -- Open and assigned to a team of mine
 if (($teams = $thisstaff->getTeams()) && count(array_filter($teams)))
-    $visibility[] = new Q(array(
+    $visibility->add(new Q(array(
         'team_id__in' => array_filter($teams),
         'flags__hasbit' => TaskModel::ISOPEN
-    ));
-$tasks->filter(Q::any($visibility));
+    )));
+$tasks->filter(new Q($visibility));
 
 // Add in annotations
 $tasks->annotate(array(
diff --git a/include/staff/ticket-tasks.inc.php b/include/staff/ticket-tasks.inc.php
index a260f0f05b07e2427b973ccfd68f44ea9ce0e30c..01bc6e2847c9d6884a3aceb1e90f7537ecd60054 100644
--- a/include/staff/ticket-tasks.inc.php
+++ b/include/staff/ticket-tasks.inc.php
@@ -79,9 +79,13 @@ if ($count) { ?>
         $id = $task->getId();
         $access = $task->checkStaffPerm($thisstaff);
         $assigned='';
-        if ($task->staff)
-            $assigned=sprintf('<span class="Icon staffAssigned">%s</span>',
-                    Format::truncate($task->staff->getName(),40));
+        if ($task->staff || $task->team) {
+            $assigneeType = $task->staff ? 'staff' : 'team';
+            $icon = $assigneeType == 'staff' ? 'staffAssigned' : 'teamAssigned';
+            $assigned=sprintf('<span class="Icon %s">%s</span>',
+                    $icon,
+                    Format::truncate($task->getAssigned(),40));
+        }
 
         $status = $task->isOpen() ? '<strong>open</strong>': 'closed';
 
diff --git a/scp/canned.php b/scp/canned.php
index ae8ded5fe76017b4a65b3c75929088e4110127b6..88fdf4b81360e4b49b1b7208b14e56e723652449 100644
--- a/scp/canned.php
+++ b/scp/canned.php
@@ -37,6 +37,13 @@ $canned_form = new SimpleForm(array(
    )),
 ));
 
+// Set fields' attachments so exsting files stay put
+if ($canned
+    && $canned->attachments
+    && ($attachments = $canned_form->getField('attachments'))) {
+     $attachments->setAttachments($canned->attachments);
+}
+
 if ($_POST) {
     switch(strtolower($_POST['do'])) {
         case 'update':
diff --git a/scp/faq.php b/scp/faq.php
index 310809947f82b90d7b2f4238802aecda6a8b36a4..8b948c1421ff0b51e044410ce3f9d8ba0b296cb5 100644
--- a/scp/faq.php
+++ b/scp/faq.php
@@ -48,6 +48,21 @@ if ($langs = $cfg->getSecondaryLanguages()) {
 
 $faq_form = new SimpleForm($form_fields, $_POST);
 
+// Set fields' attachments so exsting files stay put
+if ($faq
+    && $faq->getAttachments()->window(array('inline' => false))
+    && ($common_attachments = $faq_form->getField('attachments'))) {
+     // Common attachments
+     $common_attachments->setAttachments($faq->getAttachments()->window(array('inline' => false)));
+}
+if ($langs && $faq) {
+    // Multi-lingual system
+    foreach ($langs as $lang) {
+        $attachments = $faq_form->getField('attachments.'.$lang);
+        $attachments->setAttachments($faq->getAttachments($lang)->window(array('inline' => false)));
+    }
+}
+
 if ($_POST) {
     $errors=array();
     // General attachments
@@ -126,21 +141,6 @@ if ($_POST) {
 
     }
 }
-else {
-    // Not a POST — load database-backed attachments to attachment fields
-    if ($langs && $faq) {
-        // Multi-lingual system
-        foreach ($langs as $lang) {
-            $attachments = $faq_form->getField('attachments.'.$lang);
-            $attachments->setAttachments($faq->getAttachments($lang)->window(array('inline' => false)));
-        }
-    }
-    if ($faq) {
-        // Common attachments
-        $attachments = $faq_form->getField('attachments');
-        $attachments->setAttachments($faq->getAttachments()->window(array('inline' => false)));
-    }
-}
 
 $inc='faq-categories.inc.php'; //FAQs landing page.
 if($faq) {
diff --git a/scp/js/scp.js b/scp/js/scp.js
index 085ae525a03cb6bc22d75ece712805756374dde4..27d8e6167f94b1fc666aa0bdc1e4d466a5be6cd4 100644
--- a/scp/js/scp.js
+++ b/scp/js/scp.js
@@ -193,7 +193,7 @@ var scp_prep = function() {
         }
      });
 
-    $('form select#cannedResp').select2({width: '300px'});
+    $('form select#cannedResp').select2({width: '350px'});
     $('form select#cannedResp').on('select2:opening', function (e) {
         var redactor = $('.richtext', $(this).closest('form')).data('redactor');
         if (redactor)
diff --git a/setup/test/tests/test.git-conflicts.php b/setup/test/tests/test.git-conflicts.php
new file mode 100644
index 0000000000000000000000000000000000000000..5aa27bfb951a0d43d5eb8df02fcdbb31b5e05697
--- /dev/null
+++ b/setup/test/tests/test.git-conflicts.php
@@ -0,0 +1,27 @@
+<?php
+require_once "class.test.php";
+
+class GitConflicts extends Test {
+    var $name = "Git Conflicts Checks";
+
+    function testFindGitConflicts() {
+        $regex = '/^[\t ]*?<{3,} ?HEAD[\t ]*?|^[\t ]*?>{3,}[\t ]*?/m';
+        foreach ($this->getAllScripts('*') as $s) {
+            $matches = array();
+            $content = file_get_contents($s);
+            if (preg_match_all($regex,
+                    $content, $matches,
+                    PREG_OFFSET_CAPTURE) > 0) {
+                foreach ($matches[0] as $match) {
+                    $this->fail(
+                        $s,
+                        $this->line_number_for_offset($content, $match[1]),
+                        trim($match[0]));
+                }
+            }
+            else $this->pass();
+        }
+    }
+}
+return 'GitConflicts';
+?>