diff --git a/include/ajax.forms.php b/include/ajax.forms.php
index bb5c32957dd4b9d9b71dd1260cd127abcc9659a3..d9e61dbd5312a9d5df4d5ca70e92fd25bc2b6025 100644
--- a/include/ajax.forms.php
+++ b/include/ajax.forms.php
@@ -25,6 +25,8 @@ class DynamicFormsAjaxAPI extends AjaxController {
         }
 
         foreach ($topic->getForms() as $form) {
+            if (!$form->hasAnyVisibleFields())
+                continue;
             ob_start();
             $form->getForm($_SESSION[':form-data'])->render(!$client);
             $html .= ob_get_clean();
diff --git a/include/class.dynamic_forms.php b/include/class.dynamic_forms.php
index 110f28377666a11ed1acf476fec8f4f095fdd0bc..d51ddc7af107193a6a76ef24e3e9c836bed5e600 100644
--- a/include/class.dynamic_forms.php
+++ b/include/class.dynamic_forms.php
@@ -125,6 +125,23 @@ class DynamicForm extends VerySimpleModel {
         }
     }
 
+    function hasAnyVisibleFields($user=false) {
+        global $thisstaff, $thisclient;
+        $user = $user ?: $thisstaff ?: $thisclient;
+        $visible = 0;
+        $isstaff = $user instanceof Staff;
+        foreach ($this->getFields() as $F) {
+            if ($isstaff) {
+                if ($F->isVisibleToStaff())
+                    $visible++;
+            }
+            elseif ($F->isVisibleToUsers()) {
+                $visible++;
+            }
+        }
+        return $visible > 0;
+    }
+
     function instanciate($sort=1) {
         return DynamicFormEntry::create(array(
             'form_id'=>$this->get('id'), 'sort'=>$sort));
@@ -1154,9 +1171,13 @@ class DynamicFormEntryAnswer extends VerySimpleModel {
     }
 
     function getValue() {
-        if (!$this->_value && isset($this->value))
+        if (!isset($this->_value) && isset($this->value)) {
+            //XXX: We're settting the value here to avoid infinite loop
+            $this->_value = false;
             $this->_value = $this->getField()->to_php(
                 $this->get('value'), $this->get('value_id'));
+        }
+
         return $this->_value;
     }
 
diff --git a/include/class.group.php b/include/class.group.php
index 24e955f7ce28bffb5e9b804544a65436f96d753a..c8b8e6ef76c36ab51faf0fc1d4e88f75d37f48f3 100644
--- a/include/class.group.php
+++ b/include/class.group.php
@@ -249,6 +249,10 @@ class Group extends VerySimpleModel {
     }
 
     static function create($vars=false) {
+
+        if (!isset($vars['flags']))
+            $vars['flags'] = 0;
+
         $group = parent::create($vars);
         $group->created = SqlFunction::NOW();
         return $group;
diff --git a/include/class.setup.php b/include/class.setup.php
index fe70fc10b10f8688e9eabbeab0944aa27e3379f5..2bddbd65da51d950bda0b428f63eb4a470784e10 100644
--- a/include/class.setup.php
+++ b/include/class.setup.php
@@ -47,6 +47,8 @@ Class SetupWizard {
         load SQL schema - assumes MySQL && existing connection
         */
     function load_sql($schema, $prefix, $abort=true, $debug=false) {
+        global $ost;
+
         # Strip comments and remarks
         $schema=preg_replace('%^\s*(#|--).*$%m', '', $schema);
         # Replace table prefix
@@ -62,8 +64,10 @@ Class SetupWizard {
         foreach($statements as $k=>$sql) {
             if(db_query($sql, false)) continue;
             $error = "[$sql] ".db_error();
-            if($abort)
-                    return $this->abort($error, $debug);
+            if ($abort)
+                return $this->abort($error, $debug);
+            elseif ($debug && $ost)
+                $ost->logDBError('DB Error #'.db_errno(), $error, false);
         }
 
         return true;
diff --git a/include/class.staff.php b/include/class.staff.php
index 955785bd885ec8c72b47540400968b87d56f4a0c..44f7d6302e70558bbfe604b74050d825218836a7 100644
--- a/include/class.staff.php
+++ b/include/class.staff.php
@@ -58,8 +58,15 @@ implements AuthenticatedUser, EmailContact {
     var $_perms = null;
 
     function __onload() {
+
         // WE have to patch info here to support upgrading from old versions.
-        if ($time=strtotime($this->passwdreset ?: (isset($this->added) ? $this->added : '')))
+        $time = null;
+        if (isset($this->passwdreset) && $this->passwdreset)
+            $time=strtotime($this->passwdreset);
+        elseif (isset($this->added) && $this->added)
+            $time=strtotime($this->added);
+
+        if ($time)
             $this->passwd_change = time()-$time; //XXX: check timezone issues.
     }
 
diff --git a/include/client/open.inc.php b/include/client/open.inc.php
index e29f2b651be929de68e8d50f759e7bef41c28c33..e04c9f6eefcb4e165aa9918e602503281f5c3fcd 100644
--- a/include/client/open.inc.php
+++ b/include/client/open.inc.php
@@ -82,14 +82,7 @@ if ($info['topicId'] && ($topic=Topic::lookup($info['topicId']))) {
     </tbody>
     <tbody id="dynamic-form">
         <?php foreach ($forms as $form) {
-            $hasFields = false;
-            foreach ($form->getFields() as $f) {
-                if ($f->isVisibleToUsers()) {
-                    $hasFields = true;
-                    break;
-                }
-            }
-            if (!$hasFields)
+            if (!$form->hasAnyVisibleFields())
                 continue;
             include(CLIENTINC_DIR . 'templates/dynamic-form.tmpl.php');
         } ?>
diff --git a/include/pear/Mail.php b/include/pear/Mail.php
index 5d4d3b09dd61c14a501cc52cb8d2f9f1499bb98a..751616debf634aa180b502c5f16a0b0fd5d63418 100644
--- a/include/pear/Mail.php
+++ b/include/pear/Mail.php
@@ -76,14 +76,13 @@ class Mail
         $driver = strtolower($driver);
         $class = 'Mail_' . $driver;
         if (!class_exists($class))
-            include_once PEAR_DIR.'Mail/' . $driver . '.php';
+            include_once 'Mail/' . $driver . '.php';
 
-        if (class_exists($class)) {
-            $mailer = new $class($params);
-            return $mailer;
-        }
+        if (!class_exists($class))
+            return PEAR::raiseError('Unable to find class for driver ' .  $driver);
 
-        return PEAR::raiseError('Unable to find class for driver ' . $driver);
+        $mailer = new $class($params);
+        return $mailer;
     }
 
     /**
diff --git a/include/staff/helptopic.inc.php b/include/staff/helptopic.inc.php
index cf43338fa5abf33fc15477418cc5d485d6a48653..7df72585c1efdc152630af9438bf53a09419106d 100644
--- a/include/staff/helptopic.inc.php
+++ b/include/staff/helptopic.inc.php
@@ -1,6 +1,6 @@
 <?php
 if(!defined('OSTADMININC') || !$thisstaff || !$thisstaff->isAdmin()) die('Access Denied');
-$info = $qs = array();
+$info = $qs = $forms = array();
 if($topic && $_REQUEST['a']!='add') {
     $title=__('Update Help Topic');
     $action='update';
@@ -17,8 +17,8 @@ if($topic && $_REQUEST['a']!='add') {
     $submit_text=__('Add Topic');
     $info['isactive']=isset($info['isactive'])?$info['isactive']:1;
     $info['ispublic']=isset($info['ispublic'])?$info['ispublic']:1;
-    $info['form_id'] = Topic::FORM_USE_PARENT;
     $qs += array('a' => $_REQUEST['a']);
+    $forms = TicketForm::objects();
 }
 $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
 ?>
@@ -387,21 +387,7 @@ foreach ($forms as $F) {
 
    <br/>
    <strong><?php echo __('Add Custom Form'); ?></strong>:
-   <select name="form_id" onchange="javascript:
-    event.preventDefault();
-    var $this = $(this),
-        val = $this.val();
-    if (!val) return;
-    $.ajax({
-        url: 'ajax.php/form/' + val + '/fields/view',
-        dataType: 'json',
-        success: function(json) {
-            if (json.success) {
-                $(json.html).appendTo('#topic-forms').effect('highlight');
-                $this.find(':selected').prop('disabled', true);
-            }
-        }
-    });">
+   <select name="form_id" id="newform">
     <option value=""><?php echo '— '.__('Add a custom form') . ' —'; ?></option>
     <?php foreach (DynamicForm::objects()->filter(array('type'=>'G')) as $F) { ?>
         <option value="<?php echo $F->get('id'); ?>"
@@ -438,6 +424,23 @@ $(function() {
     };
     $('[name=sequence_id]').on('change', update_example);
     $('[name=number_format]').on('keyup', update_example);
+
+    $('form select#newform').change(function() {
+        var $this = $(this),
+            val = $this.val();
+        if (!val) return;
+        $.ajax({
+            url: 'ajax.php/form/' + val + '/fields/view',
+            dataType: 'json',
+            success: function(json) {
+                if (json.success) {
+                    $(json.html).appendTo('#topic-forms').effect('highlight');
+                    $this.find(':selected').prop('disabled', true);
+                }
+            }
+        });
+    });
+
 });
 $('table#topic-forms').sortable({
   items: 'tbody',
diff --git a/include/staff/settings-tickets.inc.php b/include/staff/settings-tickets.inc.php
index 021d24c4397e1ac632e4c974e8f9fe0cd718b607..dc94ca4d272424e19562a40ecbb907ed19de11cc 100644
--- a/include/staff/settings-tickets.inc.php
+++ b/include/staff/settings-tickets.inc.php
@@ -23,7 +23,7 @@ if(!($maxfileuploads=ini_get('max_file_uploads')))
             </td>
             <td>
                 <input type="text" name="ticket_number_format" value="<?php
-                echo $config['ticke_number_format']; ?>"/>
+                echo $config['ticket_number_format']; ?>"/>
                 <span class="faded"><?php echo __('e.g.'); ?> <span id="format-example"><?php
                     if ($config['ticket_sequence_id'])
                         $seq = Sequence::lookup($config['ticket_sequence_id']);
diff --git a/include/staff/templates/dynamic-form-fields-view.tmpl.php b/include/staff/templates/dynamic-form-fields-view.tmpl.php
new file mode 100644
index 0000000000000000000000000000000000000000..9ec9651f55c39af31e6692ddad10e3eac3e64abb
--- /dev/null
+++ b/include/staff/templates/dynamic-form-fields-view.tmpl.php
@@ -0,0 +1,40 @@
+<tbody data-form-id="<?php echo $form->get('id'); ?>">
+    <tr>
+        <td class="handle" colspan="7">
+            <input type="hidden" name="forms[]" value="<?php echo $form->get('id'); ?>" />
+            <div class="pull-right">
+            <i class="icon-large icon-move icon-muted"></i>
+            <a href="#" title="<?php echo __('Delete'); ?>" onclick="javascript:
+            if (confirm(__('You sure?'))) {
+                var tbody = $(this).closest('tbody');
+                $(this).closest('form')
+                    .find('[name=form_id] [value=' + tbody.data('formId') + ']')
+                    .prop('disabled', false);
+                tbody.fadeOut(function(){this.remove()});
+            }
+            return false;"><i class="icon-large icon-trash"></i></a>
+            </div>
+            <div><strong><?php echo Format::htmlchars($form->getLocal('title')); ?></strong></div>
+            <div><?php echo Format::display($form->getLocal('instructions')); ?></div>
+        </td>
+    </tr>
+    <tr class="header">
+        <th><?php echo __('Enable'); ?></th>
+        <th><?php echo __('Label'); ?></th>
+        <th><?php echo __('Type'); ?></th>
+        <th><?php echo __('Visibility'); ?></th>
+        <th><?php echo __('Variable'); ?></th>
+    </tr>
+<?php
+    foreach ($form->getFields() as $f) { ?>
+    <tr>
+        <td><input type="checkbox" name="fields[]" value="<?php
+            echo $f->get('id'); ?>" <?php
+            if ($f->isEnabled()) echo 'checked="checked"'; ?>/></td>
+        <td><?php echo $f->get('label'); ?></td>
+        <td><?php $t=FormField::getFieldType($f->get('type')); echo __($t[0]); ?></td>
+        <td><?php echo $f->getVisibilityDescription(); ?></td>
+        <td><?php echo $f->get('name'); ?></td>
+    </tr>
+    <?php } ?>
+</tbody>
diff --git a/include/staff/ticket-open.inc.php b/include/staff/ticket-open.inc.php
index e9edb4643ade0c9aa8dbf48f3b3c498c641a4ddc..9591f1794afe9ba08f62db40f9fafb073fb88954 100644
--- a/include/staff/ticket-open.inc.php
+++ b/include/staff/ticket-open.inc.php
@@ -263,14 +263,7 @@ if ($_POST)
         <tbody id="dynamic-form">
         <?php
             foreach ($forms as $form) {
-                $hasFields = false;
-                foreach ($form->getFields() as $f) {
-                    if ($f->isVisibleToStaff()) {
-                        $hasFields = true;
-                        break;
-                    }
-                }
-                if (!$hasFields)
+                if (!$form->hasAnyVisibleFields())
                     continue;
                 print $form->getForm()->getMedia();
                 include(STAFFINC_DIR .  'templates/dynamic-form.tmpl.php');
diff --git a/include/staff/tickets.inc.php b/include/staff/tickets.inc.php
index 0e1b346415c42707295a14928c995e5da4a5e8c3..f8013df254662376ad4546e6d10d3c0cf115813e 100644
--- a/include/staff/tickets.inc.php
+++ b/include/staff/tickets.inc.php
@@ -77,10 +77,13 @@ case 'search':
 case 'open':
     $status='open';
     $results_type=__('Open Tickets');
+    $showassigned = ($cfg && $cfg->showAssignedTickets()) || $thisstaff->showAssignedTickets();
     if (!$cfg->showAnsweredTickets())
         $tickets->filter(array('isanswered'=>0));
-    if (!$cfg || !($cfg->showAssignedTickets() || $thisstaff->showAssignedTickets()))
+    if (!$showassigned)
         $tickets->filter(Q::any(array('staff_id'=>0, 'team_id'=>0)));
+    else
+        $tickets->values('staff__firstname', 'staff__lastname', 'team__name');
     break;
 }
 
@@ -287,7 +290,7 @@ $_SESSION[':Q:tickets'] = $tickets;
                 $dept = Dept::getLocalById($T['dept_id'], 'name', $T['dept__name']);
                 if($showassigned) {
                     if($T['staff_id'])
-                        $lc=sprintf('<span class="Icon staffAssigned truncate">%s</span>',(string) new PersonsName($T['staff__firstname'], $T['staff__lastname']));
+                        $lc=sprintf('<span class="Icon staffAssigned truncate">%s</span>',(string) new PersonsName($T['staff__firstname'].' '.$T['staff__lastname']));
                     elseif($T['team_id'])
                         $lc=sprintf('<span class="Icon teamAssigned">%s</span>',
                             Team::getLocalById($T['team_id'], 'name', $T['team__name']));
diff --git a/include/upgrader/streams/core/03ff59bf-b26f29a6.patch.sql b/include/upgrader/streams/core/03ff59bf-b26f29a6.patch.sql
index ca097c81066c4ca07bc3706868fa4c3d2378f9ec..277b10950b97645e82920fb39aaaed4fced83ed1 100644
--- a/include/upgrader/streams/core/03ff59bf-b26f29a6.patch.sql
+++ b/include/upgrader/streams/core/03ff59bf-b26f29a6.patch.sql
@@ -1,7 +1,7 @@
 /**
  * @version v1.9.4
  * @signature b26f29a6bb5dbb3510b057632182d138
- * @title Add properties filed and drop 'resolved' state
+ * @title Add properties field and drop 'resolved' state
  *
  * This patch drops resolved state and any associated statuses
  *
diff --git a/include/upgrader/streams/core/15b30765-dd0022fb.task.php b/include/upgrader/streams/core/15b30765-dd0022fb.task.php
index 0bf1576190be9a1eb3cd3de3a60f87115fa99e00..faf8c99670670a6e96c8fc95302759e791d26428 100644
--- a/include/upgrader/streams/core/15b30765-dd0022fb.task.php
+++ b/include/upgrader/streams/core/15b30765-dd0022fb.task.php
@@ -18,6 +18,9 @@
 require_once INCLUDE_DIR.'class.migrater.php';
 require_once(INCLUDE_DIR.'class.file.php');
 
+// Later version of osTicket dropped/undefined the table
+@define('TICKET_ATTACHMENT_TABLE', TABLE_PREFIX.'ticket_attachment');
+
 class AttachmentMigrater extends MigrationTask {
     var $description = "Attachment migration from disk to database";
 
diff --git a/include/upgrader/streams/core/36f6b328-5cd0a25a.patch.sql b/include/upgrader/streams/core/36f6b328-5cd0a25a.patch.sql
index e30f48a0b89854d8f79cd8f6b03fdccc2ae00899..56d07587fb37b298d9a5cdc4a31158a7ec346dc3 100644
--- a/include/upgrader/streams/core/36f6b328-5cd0a25a.patch.sql
+++ b/include/upgrader/streams/core/36f6b328-5cd0a25a.patch.sql
@@ -67,7 +67,8 @@ ALTER TABLE  `%TABLE_PREFIX%attachment`
 INSERT INTO `%TABLE_PREFIX%attachment`
     (`object_id`, `type`, `file_id`, `inline`)
     SELECT `ref_id`, 'H', `file_id`, `inline`
-    FROM `%TABLE_PREFIX%ticket_attachment`;
+    FROM `%TABLE_PREFIX%ticket_attachment` A
+    WHERE A.file_id > 0;
 
 -- convert ticket_email_info to thread_entry_email
 ALTER TABLE  `%TABLE_PREFIX%ticket_email_info`
diff --git a/scp/helptopics.php b/scp/helptopics.php
index 01c01337b5f82a083dfd69089c01fc6d5d94fcae..adb1eb7c4fcc8c2830fd2b2e3e72b734a0a25d2b 100644
--- a/scp/helptopics.php
+++ b/scp/helptopics.php
@@ -36,8 +36,9 @@ if($_POST){
             }
             break;
         case 'create':
-            $topic = Topic::create();
-            if ($topic->update($_POST, $errors)) {
+            $_topic = Topic::create();
+            if ($_topic->update($_POST, $errors)) {
+                $topic = $_topic;
                 $msg=sprintf(__('Successfully added %s'), Format::htmlchars($_POST['topic']));
                 $_REQUEST['a']=null;
             }elseif(!$errors['err']){