diff --git a/include/JSON.php b/include/JSON.php
index e75eba65b8ed62d0c8648fe4bd322177a7ffab46..efa9424976e76bcba3eb96b8ede3e0453c259376 100644
--- a/include/JSON.php
+++ b/include/JSON.php
@@ -129,7 +129,7 @@ class Services_JSON
     *                                   bubble up with an error, so all return values
     *                                   from encode() should be checked with isError()
     */
-    function Services_JSON($use = 0)
+    function __construct($use = 0)
     {
         $this->use = $use;
     }
@@ -779,10 +779,10 @@ if (class_exists('PEAR_Error')) {
 
     class Services_JSON_Error extends PEAR_Error
     {
-        function Services_JSON_Error($message = 'unknown error', $code = null,
+        function __construct($message = 'unknown error', $code = null,
                                      $mode = null, $options = null, $userinfo = null)
         {
-            parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
+            parent::__construct($message, $code, $mode, $options, $userinfo);
         }
     }
 
@@ -793,7 +793,7 @@ if (class_exists('PEAR_Error')) {
      */
     class Services_JSON_Error
     {
-        function Services_JSON_Error($message = 'unknown error', $code = null,
+        function __construct($message = 'unknown error', $code = null,
                                      $mode = null, $options = null, $userinfo = null)
         {
 
diff --git a/include/PasswordHash.php b/include/PasswordHash.php
index b5b8efcadbb70123ddedc61ae673c15342f94955..745c93ba2038adbcaf474d8679e59e852d2ed9cb 100644
--- a/include/PasswordHash.php
+++ b/include/PasswordHash.php
@@ -30,7 +30,7 @@ class PasswordHash {
 	var $portable_hashes;
 	var $random_state;
 
-	function PasswordHash($iteration_count_log2, $portable_hashes)
+	function __construct($iteration_count_log2, $portable_hashes)
 	{
 		$this->itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
 
diff --git a/include/ajax.note.php b/include/ajax.note.php
index 8e179ab163e14f15b40878d9254cffaa5debaa29..8980a561109256c83959a9173e9c4205da9f2b43 100644
--- a/include/ajax.note.php
+++ b/include/ajax.note.php
@@ -54,14 +54,14 @@ class NoteAjaxAPI extends AjaxController {
             Http::response(403, "Login required");
         elseif (!isset($_POST['note']) || !$_POST['note'])
             Http::response(422, "Send `note` parameter");
-        elseif (!($note = QuickNote::create(array(
-                'staff_id' => $thisstaff->getId(),
-                'body' => Format::sanitize($_POST['note']),
-                'created' => new SqlFunction('NOW'),
-                'ext_id' => $ext_id,
-                ))))
-            Http::response(500, "Unable to create new note");
-        elseif (!$note->save(true))
+
+        $note = new QuickNote(array(
+            'staff_id' => $thisstaff->getId(),
+            'body' => Format::sanitize($_POST['note']),
+            'created' => new SqlFunction('NOW'),
+            'ext_id' => $ext_id,
+        ));
+        if (!$note->save(true))
             Http::response(500, "Unable to create new note");
 
         $show_options = true;
diff --git a/include/class.ajax.php b/include/class.ajax.php
index 870d5ae88aaf3fd1cea9392a36c566704ceea67a..143dbac2a7d5f95cde71d620264660cfd75b2365 100644
--- a/include/class.ajax.php
+++ b/include/class.ajax.php
@@ -25,9 +25,6 @@ require_once (INCLUDE_DIR.'class.api.php');
  * consistency.
  */
 class AjaxController extends ApiController {
-    function AjaxController() {
-    
-    }
     function staffOnly() {
         global $thisstaff;
         if(!$thisstaff || !$thisstaff->isValid()) {
diff --git a/include/class.api.php b/include/class.api.php
index 86a8320cd3e71a0171860d054b685f2a32fdc7d0..818b8826e8cf8526643c44d0020559b1564e47a2 100644
--- a/include/class.api.php
+++ b/include/class.api.php
@@ -19,7 +19,7 @@ class API {
 
     var $ht;
 
-    function API($id) {
+    function __construct($id) {
         $this->id = 0;
         $this->load($id);
     }
diff --git a/include/class.attachment.php b/include/class.attachment.php
index 6dd48233833d622186dd5f9395b15bce80ed523f..15f3fd9b1dec6de619247e1158771a73434ba797 100644
--- a/include/class.attachment.php
+++ b/include/class.attachment.php
@@ -137,7 +137,7 @@ extends InstrumentedList {
 
             $_inline = isset($file['inline']) ? $file['inline'] : $inline;
 
-            $att = $this->add(Attachment::create(array(
+            $att = $this->add(new Attachment(array(
                 'file_id' => $fileId,
                 'inline' => $_inline ? 1 : 0,
             )));
diff --git a/include/class.canned.php b/include/class.canned.php
index 6bd2e99d0840490d462ca5c72641e19f3f7517b7..bb126d74088ab72b2677d3d0125c9bd0871a71bf 100644
--- a/include/class.canned.php
+++ b/include/class.canned.php
@@ -207,7 +207,7 @@ extends VerySimpleModel {
     /*** Static functions ***/
 
     static function create($vars=false) {
-        $faq = parent::create($vars);
+        $faq = new static($vars);
         $faq->created = SqlFunction::NOW();
         return $faq;
     }
diff --git a/include/class.captcha.php b/include/class.captcha.php
index 86f89d9792da363351dee17d151238f03872616e..c741172543b0c82297bd73e5653d75fba55b6086 100644
--- a/include/class.captcha.php
+++ b/include/class.captcha.php
@@ -18,7 +18,7 @@ class Captcha {
     var $bgimages=array('cottoncandy.png','grass.png','ripple.png','silk.png','whirlpool.png',
                         'bubbles.png','crackle.png','lines.png','sand.png','snakeskin.png');
     var $font = 10;
-    function Captcha($len=6,$font=7,$bg=''){
+    function __construct($len=6,$font=7,$bg=''){
 
         $this->hash = strtoupper(substr(md5(rand(0, 9999)),rand(0, 24),$len));
         $this->font = $font;
diff --git a/include/class.category.php b/include/class.category.php
index d786e5ee61b2234f998cf87ff4deeb5936c377e3..d8cbb72f27de63b4fe25e2256f49cb20f740ab59 100644
--- a/include/class.category.php
+++ b/include/class.category.php
@@ -244,7 +244,7 @@ class Category extends VerySimpleModel {
     }
 
     static function create($vars=false) {
-        $category = parent::create($vars);
+        $category = new static($vars);
         $category->created = SqlFunction::NOW();
         return $category;
     }
diff --git a/include/class.collaborator.php b/include/class.collaborator.php
index b51fbe48cddd695b76496db3c3fd34c3bf335dcb..2d73efbfd26aa211dd0e45adfe6b3510e0730e69 100644
--- a/include/class.collaborator.php
+++ b/include/class.collaborator.php
@@ -115,7 +115,7 @@ implements EmailContact, ITicketUser {
     }
 
     static function create($vars=false) {
-        $inst = parent::create($vars);
+        $inst = new static($vars);
         $inst->created = SqlFunction::NOW();
         return $inst;
     }
diff --git a/include/class.config.php b/include/class.config.php
index e1e7e7b06594aed1df81e6d89a580ff9cde32209..6835a2a457e98170ef7fec090c915bed0ee49ffe 100644
--- a/include/class.config.php
+++ b/include/class.config.php
@@ -30,7 +30,7 @@ class Config {
     # new settings and the corresponding default values.
     var $defaults = array();                # List of default values
 
-    function Config($section=null, $defaults=array()) {
+    function __construct($section=null, $defaults=array()) {
         if ($section)
             $this->section = $section;
 
@@ -98,7 +98,7 @@ class Config {
     }
 
     function create($key, $value) {
-        $item = ConfigItem::create([
+        $item = new ConfigItem([
             $this->section_column => $this->section,
             'key' => $key,
             'value' => $value,
@@ -209,15 +209,16 @@ class OsticketConfig extends Config {
         'max_open_tickets' => 0,
     );
 
-    function OsticketConfig($section=null) {
-        parent::Config($section);
+    function __construct($section=null) {
+        parent::__construct($section);
 
         if (count($this->config) == 0) {
             // Fallback for osticket < 1.7@852ca89e
             $sql='SELECT * FROM '.$this->table.' WHERE id = 1';
+            $meta = ConfigItem::getMeta();
             if (($res=db_query($sql)) && db_num_rows($res))
                 foreach (db_fetch_array($res) as $key=>$value)
-                    $this->config[$key] = new ConfigItem(array('value'=>$value));
+                    $this->config[$key] = $meta->newInstance(array('value'=>$value));
         }
 
         return true;
diff --git a/include/class.crypto.php b/include/class.crypto.php
index a9aebcd2f87b6e5e66b67a0c70ba0c6855ddd0cf..b169cbb29f4986fa40a989d73a8237e943ac0746 100644
--- a/include/class.crypto.php
+++ b/include/class.crypto.php
@@ -231,7 +231,7 @@ class CryptoAlgo {
 
     var $ciphers = null;
 
-    function  CryptoAlgo($tag) {
+    function __construct($tag) {
         $this->tag_number = $tag;
     }
 
@@ -332,8 +332,8 @@ Class CryptoMcrypt extends CryptoAlgo {
                 ),
             );
 
-    function getCipher($cid=null) {
-        return parent::getCipher($cid, array($this, '_checkCipher'));
+    function getCipher($cid=null, $callback=false) {
+        return parent::getCipher($cid, $callback ?: array($this, '_checkCipher'));
     }
 
    function _checkCipher($c) {
@@ -465,8 +465,8 @@ class CryptoOpenSSL extends CryptoAlgo {
             ? $cipher['method']: '';
     }
 
-    function getCipher($cid) {
-        return parent::getCipher($cid, array($this, '_checkCipher'));
+    function getCipher($cid=null, $callback=false) {
+        return parent::getCipher($cid, $callback ?: array($this, '_checkCipher'));
     }
 
     function _checkCipher($c) {
@@ -580,8 +580,8 @@ class CryptoPHPSecLib extends CryptoAlgo {
         return new $class($c['mode']);
     }
 
-    function getCipher($cid) {
-        return  parent::getCipher($cid, array($this, '_checkCipher'));
+    function getCipher($cid=null, $callback=false) {
+        return  parent::getCipher($cid, $callback ?: array($this, '_checkCipher'));
     }
 
     function _checkCipher($c) {
diff --git a/include/class.csrf.php b/include/class.csrf.php
index a1c3aed21392d5932b6b1edb31108cc6d3bedf8a..77a8bf833f3de3c0745e8c957cc1bda3a3fcc84b 100644
--- a/include/class.csrf.php
+++ b/include/class.csrf.php
@@ -34,7 +34,7 @@ Class CSRF {
 
     var $csrf;
 
-    function CSRF($name='__CSRFToken__', $timeout=0) {
+    function __construct($name='__CSRFToken__', $timeout=0) {
 
         $this->name = $name;
         $this->timeout = $timeout;
diff --git a/include/class.dept.php b/include/class.dept.php
index 5e916a8167cafdf8e8a7c8e8e4bbe273bd5d2bfc..397df89c480b7fafa20ba09a51cd6dfa41fca78c 100644
--- a/include/class.dept.php
+++ b/include/class.dept.php
@@ -558,9 +558,8 @@ implements TemplateVariable {
     }
 
     static function create($vars=false, &$errors=array()) {
-        $dept = parent::create($vars);
+        $dept = new static($vars);
         $dept->created = SqlFunction::NOW();
-
         return $dept;
     }
 
@@ -733,7 +732,7 @@ extends Form {
         return $clean;
     }
 
-    function render($staff=true) {
-        return parent::render($staff, false, array('template' => 'dynamic-form-simple.tmpl.php'));
+    function render($staff=true, $title=false, $options=array()) {
+        return parent::render($staff, $title, $options + array('template' => 'dynamic-form-simple.tmpl.php'));
     }
 }
diff --git a/include/class.dispatcher.php b/include/class.dispatcher.php
index 3490e78826d62287530f2fc23ba1a1bf4a15b462..00cec8700a644dcf33d1c352ac36304e2069c209 100644
--- a/include/class.dispatcher.php
+++ b/include/class.dispatcher.php
@@ -21,7 +21,7 @@
  * functions aren't separated
  */
 class Dispatcher {
-    function Dispatcher($file=false) {
+    function __construct($file=false) {
         $this->urls = array();
         $this->file = $file;
     }
@@ -81,7 +81,7 @@ class Dispatcher {
 }
 
 class UrlMatcher {
-    function UrlMatcher($regex, $func, $args=false, $method=false) {
+    function __construct($regex, $func, $args=false, $method=false) {
         # Add the slashes for the Perl syntax
         $this->regex = "@" . $regex . "@";
         $this->func = $func;
diff --git a/include/class.draft.php b/include/class.draft.php
index a12fbf292d06e3650c32dad6e7e510ddbda8e5a9..d123ff6935abd7d21c96890d23bb2084d656a57b 100644
--- a/include/class.draft.php
+++ b/include/class.draft.php
@@ -146,7 +146,7 @@ class Draft extends VerySimpleModel {
 
         $vars['created'] = SqlFunction::NOW();
         $vars['staff_id'] = self::getCurrentUserId();
-        $draft = parent::create($vars);
+        $draft = new static($vars);
 
         // Cloned attachments ...
         if (false && $attachments && is_array($attachments))
diff --git a/include/class.dynamic_forms.php b/include/class.dynamic_forms.php
index 172a1580901259b03aff20a0878e90212b8f69f5..86e1d51d6009e31914cc4ee0c63835b9c91a9aaf 100644
--- a/include/class.dynamic_forms.php
+++ b/include/class.dynamic_forms.php
@@ -216,7 +216,7 @@ class DynamicForm extends VerySimpleModel {
     }
 
     static function create($ht=false) {
-        $inst = parent::create($ht);
+        $inst = new static($ht);
         $inst->set('created', new SqlFunction('NOW'));
         if (isset($ht['fields'])) {
             $inst->save();
@@ -487,58 +487,6 @@ class TicketForm extends DynamicForm {
         return static::$instance;
     }
 
-    static function ensureDynamicDataView() {
-        $sql = 'SHOW TABLES LIKE \''.TABLE_PREFIX.'ticket__cdata\'';
-        if (!db_num_rows(db_query($sql)))
-            return static::buildDynamicDataView();
-    }
-
-    static function buildDynamicDataView() {
-        // create  table __cdata (primary key (ticket_id)) as select
-        // entry.object_id as ticket_id, MAX(IF(field.name = 'subject',
-        // ans.value, NULL)) as `subject`,MAX(IF(field.name = 'priority',
-        // ans.value, NULL)) as `priority_desc`,MAX(IF(field.name =
-        // 'priority', ans.value_id, NULL)) as `priority_id`
-        // FROM ost_form_entry entry LEFT JOIN ost_form_entry_values ans ON
-        // ans.entry_id = entry.id LEFT JOIN ost_form_field field ON
-        // field.id=ans.field_id
-        // where entry.object_type='T' group by entry.object_id;
-        $sql = 'CREATE TABLE IF NOT EXISTS `'.TABLE_PREFIX.'ticket__cdata` (PRIMARY KEY
-            (ticket_id)) DEFAULT CHARSET=utf8 AS '
-            . static::getCrossTabQuery('T', 'ticket_id');
-        db_query($sql);
-    }
-
-    static function dropDynamicDataView() {
-        db_query('DROP TABLE IF EXISTS `'.TABLE_PREFIX.'ticket__cdata`');
-    }
-
-    static function updateDynamicDataView($answer, $data) {
-        // TODO: Detect $data['dirty'] for value and value_id
-        // We're chiefly concerned with Ticket form answers
-        if (!($e = $answer->getEntry()) || $e->form->get('type') != 'T')
-            return;
-
-        // $record = array();
-        // $record[$f] = $answer->value'
-        // TicketFormData::objects()->filter(array('ticket_id'=>$a))
-        //      ->merge($record);
-        $sql = 'SHOW TABLES LIKE \''.TABLE_PREFIX.'ticket__cdata\'';
-        if (!db_num_rows(db_query($sql)))
-            return;
-
-        $f = $answer->getField();
-        if (!$f->getFormId())
-            return;
-
-        $name = $f->get('name') ?: ('field_'.$f->get('id'));
-        $fields = sprintf('`%s`=', $name) . db_input($answer->getSearchKeys());
-        $sql = 'INSERT INTO `'.TABLE_PREFIX.'ticket__cdata` SET '.$fields
-            .', `ticket_id`='.db_input($answer->getEntry()->get('object_id'))
-            .' ON DUPLICATE KEY UPDATE '.$fields;
-        if (!db_query($sql))
-            return self::dropDynamicDataView();
-    }
 }
 // Add fields from the standard ticket form to the ticket filterable fields
 Filter::addSupportedMatches(/* @trans */ 'Ticket Data', function() {
@@ -948,7 +896,7 @@ class DynamicFormField extends VerySimpleModel {
     }
 
     static function create($ht=false) {
-        $inst = parent::create($ht);
+        $inst = new static($ht);
         $inst->set('created', new SqlFunction('NOW'));
         if (isset($ht['configuration']))
             $inst->configuration = JsonDataEncoder::encode($ht['configuration']);
@@ -1340,7 +1288,7 @@ class DynamicFormEntry extends VerySimpleModel {
     }
 
     static function create($ht=false, $data=null) {
-        $inst = parent::create($ht);
+        $inst = new static($ht);
         $inst->set('created', new SqlFunction('NOW'));
         if ($data)
             $inst->setSource($data);
@@ -1349,7 +1297,7 @@ class DynamicFormEntry extends VerySimpleModel {
                 continue;
             if (!$impl->hasData() || !$impl->isStorable())
                 continue;
-            $a = DynamicFormEntryAnswer::create(
+            $a = new DynamicFormEntryAnswer(
                 array('field'=>$field, 'entry'=>$inst));
             $a->field->setAnswer($a);
             $inst->answers->add($a);
@@ -1485,9 +1433,8 @@ class SelectionField extends FormField {
         return $this->_list;
     }
 
-    function getWidget() {
+    function getWidget($widgetClass=false) {
         $config = $this->getConfiguration();
-        $widgetClass = false;
         if ($config['widget'] == 'typeahead' && $config['multiselect'] == false)
             $widgetClass = 'TypeaheadSelectionWidget';
         elseif ($config['widget'] == 'textbox')
diff --git a/include/class.email.php b/include/class.email.php
index 92348241cc543f0041e6fa4ca69ab4a5c55d645a..e0bdb64bd38fe3ffb82a15139d222cebffed18df 100644
--- a/include/class.email.php
+++ b/include/class.email.php
@@ -224,7 +224,7 @@ class Email extends VerySimpleModel {
     }
 
     static function create($vars=false) {
-        $inst = parent::create($vars);
+        $inst = new static($vars);
         $inst->created = SqlFunction::NOW();
         return $inst;
     }
diff --git a/include/class.error.php b/include/class.error.php
index 72909a615e2a61cde374ccdcba9213a80f4e2515..c083437d879e0719582d65d6ce5807e89a424219 100644
--- a/include/class.error.php
+++ b/include/class.error.php
@@ -17,7 +17,7 @@
     vim: expandtab sw=4 ts=4 sts=4:
 **********************************************************************/
 
-class Error extends Exception {
+class BaseError extends Exception {
     static $title = '';
     static $sendAlert = true;
 
@@ -42,7 +42,7 @@ class Error extends Exception {
     }
 }
 
-class InitialDataError extends Error {
+class InitialDataError extends BaseError {
     static $title = 'Problem with install initial data';
 }
 
@@ -52,7 +52,7 @@ function raise_error($message, $class=false) {
 }
 
 // File storage backend exceptions
-class IOException extends Error {
+class IOException extends BaseError {
     static $title = 'Unable to read resource content';
 }
 
diff --git a/include/class.export.php b/include/class.export.php
index ee2c6a8ec8e2b3029c08602136aa3ee452442dcc..9235a18bc93164c737c824ad59b01db4b0f9ee35 100644
--- a/include/class.export.php
+++ b/include/class.export.php
@@ -393,7 +393,7 @@ class DatabaseExporter {
         USER_ACCOUNT_TABLE, ORGANIZATION_TABLE, NOTE_TABLE
     );
 
-    function DatabaseExporter($stream, $options=array()) {
+    function __construct($stream, $options=array()) {
         $this->stream = $stream;
         $this->options = $options;
     }
diff --git a/include/class.faq.php b/include/class.faq.php
index 372ee0f0d581031b04a8a293e58cc45e074074ab..027b25ef09815a24ab775ba55ed9e639393f3eb1 100644
--- a/include/class.faq.php
+++ b/include/class.faq.php
@@ -338,7 +338,7 @@ class FAQ extends VerySimpleModel {
     }
 
     static function create($vars=false) {
-        $faq = parent::create($vars);
+        $faq = new static($vars);
         $faq->created = SqlFunction::NOW();
         return $faq;
     }
diff --git a/include/class.file.php b/include/class.file.php
index 8e95bc08f7bae821e6a897211f3954e0aca240d1..a7b8eb64807d010e1b6b0f1b3db11c5f76a986d5 100644
--- a/include/class.file.php
+++ b/include/class.file.php
@@ -380,7 +380,7 @@ class AttachmentFile extends VerySimpleModel {
             $file['type'] = 'application/octet-stream';
 
 
-        $f = parent::create(array(
+        $f = new static(array(
             'type' => strtolower($file['type']),
             'name' => $file['name'],
             'key' => $file['key'],
diff --git a/include/class.filter.php b/include/class.filter.php
index c15249ec319ef8e0d39e1f58a3789fc429863da5..20bac5ce53b856d13d439a0afedd8e8abe1ab97a 100644
--- a/include/class.filter.php
+++ b/include/class.filter.php
@@ -37,7 +37,7 @@ class Filter {
         ),
     );
 
-    function Filter($id) {
+    function __construct($id) {
         $this->id=0;
         $this->load($id);
     }
@@ -530,7 +530,7 @@ class Filter {
 
             switch ($action) {
             case 'N': # new filter action
-                $I = FilterAction::create(array(
+                $I = new FilterAction(array(
                     'type'=>$info,
                     'filter_id'=>$id,
                     'sort' => (int) $sort,
@@ -561,7 +561,7 @@ class FilterRule {
 
     var $filter;
 
-    function FilterRule($id,$filterId=0) {
+    function __construct($id,$filterId=0) {
         $this->id=0;
         $this->load($id,$filterId);
     }
@@ -697,7 +697,7 @@ class TicketFilter {
      *  ---------------
      *  @see Filter::matches() for a complete list of supported keys
      */
-    function TicketFilter($origin, $vars=array()) {
+    function __construct($origin, $vars=array()) {
 
         //Normalize the target based on ticket's origin.
         $this->target = self::origin2target($origin);
diff --git a/include/class.forms.php b/include/class.forms.php
index 59bd50d38d79c8cd286c180cb15fbbda565ac1cb..e7558c7d444d5b425909fc103356c53020db93c3 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -2166,8 +2166,8 @@ FormField::addFieldTypes(/*@trans*/ 'Dynamic Fields', function() {
 
 
 class DepartmentField extends ChoiceField {
-    function getWidget() {
-        $widget = parent::getWidget();
+    function getWidget($widgetClass=false) {
+        $widget = parent::getWidget($widgetClass);
         if ($widget->value instanceof Dept)
             $widget->value = $widget->value->getId();
         return $widget;
@@ -2177,7 +2177,7 @@ class DepartmentField extends ChoiceField {
         return true;
     }
 
-    function getChoices() {
+    function getChoices($verbose=false) {
         global $cfg;
 
         $choices = array();
@@ -2235,8 +2235,8 @@ class AssigneeField extends ChoiceField {
     var $_choices = null;
     var $_criteria = null;
 
-    function getWidget() {
-        $widget = parent::getWidget();
+    function getWidget($widgetClass=false) {
+        $widget = parent::getWidget($widgetClass);
         if (is_object($widget->value))
             $widget->value = $widget->value->getId();
         return $widget;
@@ -2261,7 +2261,7 @@ class AssigneeField extends ChoiceField {
         $this->_choices = $choices;
     }
 
-    function getChoices() {
+    function getChoices($verbose=false) {
         global $cfg;
 
         if (!isset($this->_choices)) {
@@ -2509,14 +2509,14 @@ class FileUploadField extends FormField {
         static $filetypes;
 
         if (!isset($filetypes)) {
-            if (function_exists('apc_fetch')) {
+            if (function_exists('apcu_fetch')) {
                 $key = md5(SECRET_SALT . GIT_VERSION . 'filetypes');
-                $filetypes = apc_fetch($key);
+                $filetypes = apcu_fetch($key);
             }
             if (!$filetypes)
                 $filetypes = YamlDataParser::load(INCLUDE_DIR . '/config/filetype.yaml');
             if ($key)
-                apc_store($key, $filetypes, 7200);
+                apcu_store($key, $filetypes, 7200);
         }
         return $filetypes;
     }
@@ -3071,7 +3071,7 @@ class TextboxWidget extends Widget {
 
 class TextboxSelectionWidget extends TextboxWidget {
     //TODO: Support multi-input e.g comma separated inputs
-    function render($options=array()) {
+    function render($options=array(), $extraConfig=array()) {
 
         if ($this->value && is_array($this->value))
             $this->value = current($this->value);
@@ -4072,9 +4072,9 @@ class AssignmentForm extends Form {
             return $fields[$name];
     }
 
-    function isValid() {
+    function isValid($include=false) {
 
-        if (!parent::isValid() || !($f=$this->getField('assignee')))
+        if (!parent::isValid($include) || !($f=$this->getField('assignee')))
             return false;
 
         // Do additional assignment validation
@@ -4212,9 +4212,9 @@ class TransferForm extends Form {
         return $this->fields;
     }
 
-    function isValid() {
+    function isValid($include=false) {
 
-        if (!parent::isValid())
+        if (!parent::isValid($include))
             return false;
 
         // Do additional validations
diff --git a/include/class.i18n.php b/include/class.i18n.php
index c290821194ddacee624ef6a4400da4f170db2857..3954ea0d0765a6777afc396c30e87f9fac251c05 100644
--- a/include/class.i18n.php
+++ b/include/class.i18n.php
@@ -23,7 +23,7 @@ class Internationalization {
     // fallback
     var $langs = array('en_US');
 
-    function Internationalization($language=false) {
+    function __construct($language=false) {
         global $cfg;
 
         if ($cfg && ($lang = $cfg->getPrimaryLanguage()))
@@ -540,7 +540,7 @@ class DataTemplate {
      * template itself does not have to keep track of the language for which
      * it is defined.
      */
-    function DataTemplate($path, $langs=array('en_US')) {
+    function __construct($path, $langs=array('en_US')) {
         foreach ($langs as $l) {
             if (file_exists("{$this->base}/$l/$path")) {
                 $this->lang = $l;
diff --git a/include/class.knowledgebase.php b/include/class.knowledgebase.php
index 33b214d6a1cbc21d293cfa0cfffd4ff20c735b9f..8c4b010250151d16bbd4a198e910072aab9b8876 100644
--- a/include/class.knowledgebase.php
+++ b/include/class.knowledgebase.php
@@ -17,7 +17,7 @@ require_once("class.file.php");
 
 class Knowledgebase {
 
-    function Knowledgebase($id) {
+    function __construct($id) {
         $res=db_query(
             'SELECT title, isenabled, dept_id, created, updated '
            .'FROM '.CANNED_TABLE.' WHERE canned_id='.db_input($id));
diff --git a/include/class.list.php b/include/class.list.php
index a60925874bb4dd272d8efbf9d7b79ccb51023d70..84322f7006435453f857ee5ca82dd984b4555eff 100644
--- a/include/class.list.php
+++ b/include/class.list.php
@@ -478,7 +478,7 @@ class DynamicList extends VerySimpleModel implements CustomList {
             $ht['configuration'] = JsonDataEncoder::encode($ht['configuration']);
         }
 
-        $inst = parent::create($ht);
+        $inst = new static($ht);
         $inst->set('created', new SqlFunction('NOW'));
 
         if (isset($ht['properties'])) {
@@ -798,7 +798,7 @@ class DynamicListItem extends VerySimpleModel implements CustomListItem {
         if (isset($ht['properties']) && is_array($ht['properties']))
             $ht['properties'] = JsonDataEncoder::encode($ht['properties']);
 
-        $inst = parent::create($ht);
+        $inst = new static($ht);
 
         // Auto-config properties if any
         if ($ht['configuration'] && is_array($ht['configuration'])) {
@@ -1398,7 +1398,7 @@ implements CustomListItem, TemplateVariable {
 
         $ht['created'] = new SqlFunction('NOW');
 
-        return  parent::create($ht);
+        return new static($ht);
     }
 
     static function lookup($var, $list=null) {
diff --git a/include/class.lock.php b/include/class.lock.php
index e5da2f048e894bd60733254a0604a5ae51c6fcf9..c0e8c2823e696ffd0bdef3fd8c98988bfc6dd815 100644
--- a/include/class.lock.php
+++ b/include/class.lock.php
@@ -115,7 +115,7 @@ class Lock extends VerySimpleModel {
             return null;
 
         // Create the new lock.
-        $lock = parent::create(array(
+        $lock = new static(array(
             'created' => SqlFunction::NOW(),
             'staff_id' => $staffId,
             'expire' => SqlExpression::plus(
@@ -128,11 +128,6 @@ class Lock extends VerySimpleModel {
             return $lock;
     }
 
-    static function create($staffId, $lockTime) {
-        if ($lock = self::acquire($staffId, $lockTime))
-            return $lock;
-    }
-
     // Simply remove ALL locks a user (staff) holds on a ticket(s).
     static function removeStaffLocks($staffId, $object=false) {
         $locks = static::objects()->filter(array(
diff --git a/include/class.log.php b/include/class.log.php
index 4fea7e4c1ffbf5662bbca89e9216f2ce7650470a..eec2192b128477513754aefc0d184e62c039a4a8 100644
--- a/include/class.log.php
+++ b/include/class.log.php
@@ -19,7 +19,7 @@ class Log {
     var $id;
     var $info;
 
-    function Log($id){
+    function __construct($id){
         $this->id=0;
         return $this->load($id);
     }
diff --git a/include/class.mailer.php b/include/class.mailer.php
index 1d3712211a43a69d040b976a4fa80d67899b99bc..cffaec5ed6f5c1b54923bb63c168e0c291f1980f 100644
--- a/include/class.mailer.php
+++ b/include/class.mailer.php
@@ -30,7 +30,7 @@ class Mailer {
     var $smtp = array();
     var $eol="\n";
 
-    function Mailer($email=null, array $options=array()) {
+    function __construct($email=null, array $options=array()) {
         global $cfg;
 
         if(is_object($email) && $email->isSMTPEnabled() && ($info=$email->getSMTPInfo())) { //is SMTP enabled for the current email?
diff --git a/include/class.mailfetch.php b/include/class.mailfetch.php
index 94b80c91aa9cd71a4089a9da2fe21550776d0631..325300f7b6e09e310324e6002d2f72844b75552e 100644
--- a/include/class.mailfetch.php
+++ b/include/class.mailfetch.php
@@ -33,7 +33,7 @@ class MailFetcher {
 
     var $tnef = false;
 
-    function MailFetcher($email, $charset='UTF-8') {
+    function __construct($email, $charset='UTF-8') {
 
 
         if($email && is_numeric($email)) //email_id
diff --git a/include/class.mailparse.php b/include/class.mailparse.php
index 1efd5a8b15fa48c88a9936172451840cffe72015..1564cc07735a2d7460d65eaff8d4935c15ecd668 100644
--- a/include/class.mailparse.php
+++ b/include/class.mailparse.php
@@ -32,7 +32,7 @@ class Mail_Parse {
 
     var $tnef = false;      // TNEF encoded mail
 
-    function Mail_parse(&$mimeMessage, $charset=null){
+    function __construct(&$mimeMessage, $charset=null){
 
         $this->mime_message = &$mimeMessage;
 
@@ -581,7 +581,7 @@ class EmailDataParser {
     var $stream;
     var $error;
 
-    function EmailDataParser($stream=null) {
+    function __construct($stream=null) {
         $this->stream = $stream;
     }
 
diff --git a/include/class.migrater.php b/include/class.migrater.php
index b9dbdca2e663c01b9e7f506319367b4a16548175..0348f1b310bebe466bef8d195f7a4de26dc53017 100644
--- a/include/class.migrater.php
+++ b/include/class.migrater.php
@@ -33,12 +33,10 @@ class DatabaseMigrater {
     var $end;
     var $sqldir;
 
-    function DatabaseMigrater($start, $end, $sqldir) {
-
+    function __construct($start, $end, $sqldir) {
         $this->start = $start;
         $this->end = $end;
         $this->sqldir = $sqldir;
-
     }
 
     function getPatches($stop=null) {
diff --git a/include/class.nav.php b/include/class.nav.php
index e69014817a1496e555f15de1f94fae2bd6e7dbb9..dfe308f796f6538be1177c10da4febc0c6e79af7 100644
--- a/include/class.nav.php
+++ b/include/class.nav.php
@@ -23,7 +23,7 @@ class StaffNav {
 
     var $staff;
 
-    function StaffNav($staff, $panel='staff'){
+    function __construct($staff, $panel='staff'){
         $this->staff=$staff;
         $this->panel=strtolower($panel);
     }
@@ -206,8 +206,8 @@ class StaffNav {
 
 class AdminNav extends StaffNav{
 
-    function AdminNav($staff){
-        parent::StaffNav($staff, 'admin');
+    function __construct($staff){
+        parent::__construct($staff, 'admin');
     }
 
     function getRegisteredApps() {
@@ -296,7 +296,7 @@ class UserNav {
 
     var $user;
 
-    function UserNav($user=null, $active=''){
+    function __construct($user=null, $active=''){
 
         $this->user=$user;
         $this->navs=$this->getNavs();
diff --git a/include/class.organization.php b/include/class.organization.php
index aa3690beea32fc41ef237d23e6e26ef1895d9dda..669854350d7f010ef80de07b24b6d138fb4204ae 100644
--- a/include/class.organization.php
+++ b/include/class.organization.php
@@ -448,8 +448,8 @@ implements TemplateVariable {
 
     static function fromVars($vars) {
 
-        if (!($org = Organization::lookup(array('name' => $vars['name'])))) {
-            $org = Organization::create(array(
+        if (!($org = static::lookup(array('name' => $vars['name'])))) {
+            $org = static::create(array(
                 'name' => $vars['name'],
                 'updated' => new SqlFunction('NOW'),
             ));
@@ -474,7 +474,7 @@ implements TemplateVariable {
         // Make sure the name is not in-use
         if (($field=$form->getField('name'))
                 && $field->getClean()
-                && Organization::lookup(array('name' => $field->getClean()))) {
+                && static::lookup(array('name' => $field->getClean()))) {
             $field->addError(__('Organization with the same name already exists'));
             $valid = false;
         }
@@ -483,7 +483,7 @@ implements TemplateVariable {
     }
 
     static function create($vars=false) {
-        $org = parent::create($vars);
+        $org = new static($vars);
 
         $org->created = new SqlFunction('NOW');
         $org->setStatus(self::SHARE_PRIMARY_CONTACT);
@@ -493,7 +493,7 @@ implements TemplateVariable {
     // Custom create called by installer/upgrader to load initial data
     static function __create($ht, &$error=false) {
 
-        $org = Organization::create($ht);
+        $org = static::create($ht);
         // Add dynamic data (if any)
         if ($ht['fields']) {
             $org->save(true);
diff --git a/include/class.orm.php b/include/class.orm.php
index f816265e326e1014eac1ec9407713784d7534577..e0120814d3a72170c4412c8fa59b7b067204778b 100644
--- a/include/class.orm.php
+++ b/include/class.orm.php
@@ -32,7 +32,7 @@ class InconsistentModelException extends OrmException {
  * name, default sorting information, database fields, etc.
  *
  * This class is constructed and built automatically from the model's
- * ::_inspect method using a class's ::$meta array.
+ * ::getMeta() method using a class's ::$meta array.
  */
 class ModelMeta implements ArrayAccess {
 
@@ -48,17 +48,39 @@ class ModelMeta implements ArrayAccess {
     static $model_cache;
 
     var $model;
+    var $meta = array();
+    var $new;
+    var $subclasses = array();
+    var $fields;
 
     function __construct($model) {
         $this->model = $model;
 
         // Merge ModelMeta from parent model (if inherited)
         $parent = get_parent_class($this->model);
+        $meta = $model::$meta;
+        if ($model::$meta instanceof self)
+            $meta = $meta->meta;
         if (is_subclass_of($parent, 'VerySimpleModel')) {
-            $meta = $parent::getMeta()->extend($model::$meta);
+            $this->parent = $parent::getMeta();
+            $meta = $this->parent->extend($this, $meta);
         }
         else {
-            $meta = $model::$meta + self::$base;
+            $meta = $meta + self::$base;
+        }
+
+        // Short circuit the meta-data processing if APCu is available.
+        // This is preferred as the meta-data is unlikely to change unless
+        // osTicket is upgraded, (then the upgrader calls the
+        // flushModelCache method to clear this cache). Also, GIT_VERSION is
+        // used in the APC key which should be changed if new code is
+        // deployed.
+        if (function_exists('apcu_store')) {
+            $loaded = false;
+            $apc_key = SECRET_SALT.GIT_VERSION."/orm/{$this->model}";
+            $this->meta = apcu_fetch($apc_key, $loaded);
+            if ($loaded)
+                return;
         }
 
         if (!$meta['view']) {
@@ -85,13 +107,34 @@ class ModelMeta implements ArrayAccess {
                 $meta['foreign_keys'][$j['local']] = $field;
         }
         unset($j);
-        $this->base = $meta;
+        $this->meta = $meta;
+
+        if (function_exists('apcu_store')) {
+            apcu_store($apc_key, $this->meta, 1800);
+        }
+    }
+
+    function extend(ModelMeta $child, $meta) {
+        $this->subclasses[$child->model] = $child;
+        return $meta + $this->meta + self::$base;
     }
 
-    function extend($meta) {
-        if ($meta instanceof self)
-            $meta = $meta->base;
-        return $meta + $this->base + self::$base;
+    function isSuperClassOf($model) {
+        if (isset($this->subclasses[$model]))
+            return true;
+        foreach ($this->subclasses as $M=>$meta)
+            if ($meta->isSuperClassOf($M))
+                return true;
+    }
+
+    function isSubclassOf($model) {
+        if (!isset($this->parent))
+            return false;
+
+        if ($this->parent->model === $model)
+            return true;
+
+        return $this->parent->isSubclassOf($model);
     }
 
     /**
@@ -159,63 +202,76 @@ class ModelMeta implements ArrayAccess {
     }
 
     function addJoin($name, array $join) {
-        $this->base['joins'][$name] = $join;
-        $this->processJoin($this->base['joins'][$name]);
+        $this->meta['joins'][$name] = $join;
+        $this->processJoin($this->meta['joins'][$name]);
     }
 
     function offsetGet($field) {
-        if (!isset($this->base[$field]))
-            $this->setupLazy($field);
-        return $this->base[$field];
+        return $this->meta[$field];
     }
     function offsetSet($field, $what) {
-        $this->base[$field] = $what;
+        $this->meta[$field] = $what;
     }
     function offsetExists($field) {
-        return isset($this->base[$field]);
+        return isset($this->meta[$field]);
     }
     function offsetUnset($field) {
         throw new Exception('Model MetaData is immutable');
     }
 
-    function setupLazy($what) {
-        switch ($what) {
-        case 'fields':
-            $this->base['fields'] = self::inspectFields();
-            break;
-        case 'newInstance':
-            $class_repr = sprintf(
-                'O:%d:"%s":0:{}',
-                strlen($this->model), $this->model
-            );
-            $this->base['newInstance'] = function() use ($class_repr) {
-                return unserialize($class_repr);
-            };
-            break;
-        default:
-            throw new Exception($what . ': No such meta-data');
+    /**
+     * Fetch the column names of the table used to persist instances of this
+     * model in the database.
+     */
+    function getFieldNames() {
+        if (!isset($this->fields))
+            $this->fields = self::inspectFields();
+        return $this->fields;
+    }
+
+    /**
+     * Create a new instance of the model, optionally hydrating it with the
+     * given hash table. The constructor is not called, which leaves the
+     * default constructor free to assume new object status.
+     *
+     * Three methods were considered, with runtime for 10000 iterations
+     *   * unserialze('O:9:"ModelBase":0:{}') - 0.0671s
+     *   * new ReflectionClass("ModelBase")->newInstanceWithoutConstructor()
+     *      - 0.0478s
+     *   * and a hybrid by cloning the reflection class instance - 0.0335s
+     */
+    function newInstance($props=false) {
+        if (!isset($this->new)) {
+            $rc = new ReflectionClass($this->model);
+            $this->new = $rc->newInstanceWithoutConstructor();
         }
+        $instance = clone $this->new;
+        // Hydrate if props were included
+        if (is_array($props)) {
+            $instance->ht = $props;
+        }
+        return $instance;
     }
 
     function inspectFields() {
         if (!isset(self::$model_cache))
-            self::$model_cache = function_exists('apc_fetch');
+            self::$model_cache = function_exists('apcu_fetch');
         if (self::$model_cache) {
-            $key = md5(SECRET_SALT . GIT_VERSION . $this['table']);
-            if ($fields = apc_fetch($key)) {
+            $key = SECRET_SALT.GIT_VERSION."/orm/{$this['table']}";
+            if ($fields = apcu_fetch($key)) {
                 return $fields;
             }
         }
         $fields = DbEngine::getCompiler()->inspectTable($this['table']);
         if (self::$model_cache) {
-            apc_store($key, $fields);
+            apcu_store($key, $fields, 1800);
         }
         return $fields;
     }
 
     static function flushModelCache() {
         if (self::$model_cache)
-            @apc_clear_cache('user');
+            @apcu_clear_cache('user');
     }
 }
 
@@ -232,8 +288,12 @@ class VerySimpleModel {
     var $__deleted__ = false;
     var $__deferred__ = array();
 
-    function __construct($row) {
-        $this->ht = $row;
+    function __construct($row=false) {
+        if (is_array($row))
+            foreach ($row as $field=>$value)
+                if (!is_array($value))
+                    $this->set($field, $value);
+        $this->__new__ = true;
     }
 
     function get($field, $default=false) {
@@ -305,7 +365,7 @@ class VerySimpleModel {
             return null;
 
         // Check to see if the column referenced is actually valid
-        if (in_array($field, static::getMeta('fields')))
+        if (in_array($field, static::getMeta()->getFieldNames()))
             return null;
 
         throw new OrmException(sprintf(__('%s: %s: Field not defined'),
@@ -354,7 +414,19 @@ class VerySimpleModel {
                 }
                 // Pass. Set local field to NULL in logic below
             }
-            elseif ($value instanceof $j['fkey'][0]) {
+            elseif ($value instanceof VerySimpleModel) {
+                // Ensure that the model being assigned as a relationship is
+                // an instance of the foreign model given in the
+                // relationship, or is a super class thereof. The super
+                // class case is used primary for the xxxThread classes
+                // which all extend from the base Thread class.
+                if (!$value instanceof $j['fkey'][0]
+                    && !$value::getMeta()->isSuperClassOf($j['fkey'][0])
+                ) {
+                    throw new InvalidArgumentException(
+                        sprintf(__('Expecting NULL or instance of %s. Got a %s instead'),
+                        $j['fkey'][0], is_object($value) ? get_class($value) : gettype($value)));
+                }
                 // Capture the object under the object's field name
                 $this->ht[$field] = $value;
                 if ($value->__new__)
@@ -364,11 +436,6 @@ class VerySimpleModel {
                     $value = $value->get($j['fkey'][1]);
                 // Fall through to the standard logic below
             }
-            else
-                throw new InvalidArgumentException(
-                    sprintf(__('Expecting NULL or instance of %s. Got a %s instead'),
-                    $j['fkey'][0], is_object($value) ? get_class($value) : gettype($value)));
-
             // Capture the foreign key id value
             $field = $j['local'];
         }
@@ -402,18 +469,13 @@ class VerySimpleModel {
     }
 
     function __onload() {}
-    static function __oninspect() {}
-
-    static function _inspect() {
-        static::$meta = new ModelMeta(get_called_class());
-
-        // Let the model participate
-        static::__oninspect();
-    }
 
     static function getMeta($key=false) {
-        if (!static::$meta instanceof ModelMeta)
-            static::_inspect();
+        if (!static::$meta instanceof ModelMeta
+            || get_called_class() != static::$meta->model
+        ) {
+            static::$meta = new ModelMeta(get_called_class());
+        }
         $M = static::$meta;
         return ($key) ? $M->offsetGet($key) : $M;
     }
@@ -458,10 +520,11 @@ class VerySimpleModel {
      */
     static function lookup($criteria) {
         // Model::lookup(1), where >1< is the pk value
+        $args = func_get_args();
         if (!is_array($criteria)) {
             $criteria = array();
             $pk = static::getMeta('pk');
-            foreach (func_get_args() as $i=>$f)
+            foreach ($args as $i=>$f)
                 $criteria[$pk[$i]] = $f;
 
             // Only consult cache for PK lookup, which is assumed if the
@@ -586,17 +649,6 @@ class VerySimpleModel {
         return true;
     }
 
-    static function create($ht=false) {
-        if (!$ht) $ht=array();
-        $class = get_called_class();
-        $i = new $class(array());
-        $i->__new__ = true;
-        foreach ($ht as $field=>$value)
-            if (!is_array($value))
-                $i->set($field, $value);
-        return $i;
-    }
-
     private function getPk() {
         $pk = array();
         foreach ($this::getMeta('pk') as $f)
@@ -653,7 +705,7 @@ class AnnotatedModel {
 class SqlFunction {
     var $alias;
 
-    function SqlFunction($name) {
+    function __construct($name) {
         $this->func = $name;
         $this->args = array_slice(func_get_args(), 1);
     }
@@ -1267,16 +1319,17 @@ class QuerySet implements IteratorAggregate, ArrayAccess, Serializable, Countabl
 
         // Load defaults from model
         $model = $this->model;
+        $meta = $model::getMeta();
         $query = clone $this;
         $options += $this->options;
         if ($options['nosort'])
             $query->ordering = array();
-        elseif (!$query->ordering && $model::getMeta('ordering'))
-            $query->ordering = $model::getMeta('ordering');
-        if (false !== $query->related && !$query->values && $model::getMeta('select_related'))
-            $query->related = $model::getMeta('select_related');
-        if (!$query->defer && $model::getMeta('defer'))
-            $query->defer = $model::getMeta('defer');
+        elseif (!$query->ordering && $meta['ordering'])
+            $query->ordering = $meta['ordering'];
+        if (false !== $query->related && !$query->values && $meta['select_related'])
+            $query->related = $meta['select_related'];
+        if (!$query->defer && $meta['defer'])
+            $query->defer = $meta['defer'];
 
         $class = $options['compiler'] ?: $this->compiler;
         $compiler = new $class($options);
@@ -1479,19 +1532,13 @@ class ModelInstanceManager extends ResultSet {
         // Check the cache for the model instance first
         if (!($m = self::checkCache($modelClass, $fields))) {
             // Construct and cache the object
-            $m = new $modelClass($fields);
+            $m = $modelClass::$meta->newInstance($fields);
             // XXX: defer may refer to fields not in this model
             $m->__deferred__ = $this->queryset->defer;
             $m->__onload();
             if ($cache)
                 $this->cache($m);
         }
-        elseif (get_class($m) != $modelClass) {
-            // Change the class of the object to be returned to match what
-            // was expected
-            // TODO: Emit a warning?
-            $m = new $modelClass($m->ht);
-        }
         // Wrap annotations in an AnnotatedModel
         if ($extras) {
             $m = new AnnotatedModel($m, $extras);
@@ -1671,7 +1718,7 @@ class InstrumentedList extends ModelInstanceManager {
      */
     function window($constraint) {
         $model = $this->model;
-        $fields = $model::getMeta('fields');
+        $fields = $model::getMeta()->getFieldNames();
         $key = $this->key;
         foreach ($constraint as $field=>$value) {
             if (!is_string($field) || false === in_array($field, $fields))
@@ -2343,10 +2390,11 @@ class MySqlCompiler extends SqlCompiler {
         if (!isset($rmodel))
             $rmodel = $model;
         // Support inline views
-        $table = ($rmodel::getMeta('view'))
+        $rmeta = $rmodel::getMeta();
+        $table = ($rmeta['view'])
             // XXX: Support parameters from the nested query
             ? $rmodel::getSqlAddParams($this)
-            : $this->quote($rmodel::getMeta('table'));
+            : $this->quote($rmeta['table']);
         $base = "{$join}{$table} {$alias}";
         return array($base, $constraints);
     }
@@ -2480,14 +2528,15 @@ class MySqlCompiler extends SqlCompiler {
 
         // Compile the field listing
         $fields = $group_by = array();
-        $table = $this->quote($model::getMeta('table')).' '.$rootAlias;
+        $meta = $model::getMeta();
+        $table = $this->quote($meta['table']).' '.$rootAlias;
         // Handle related tables
         if ($queryset->related) {
             $count = 0;
             $fieldMap = $theseFields = array();
             $defer = $queryset->defer ?: array();
             // Add local fields first
-            foreach ($model::getMeta('fields') as $f) {
+            foreach ($meta->getFieldNames() as $f) {
                 // Handle deferreds
                 if (isset($defer[$f]))
                     continue;
@@ -2509,7 +2558,7 @@ class MySqlCompiler extends SqlCompiler {
                     $theseFields = array();
                     list($alias, $fmodel) = $this->getField($full_path, $model,
                         array('table'=>true, 'model'=>true));
-                    foreach ($fmodel::getMeta('fields') as $f) {
+                    foreach ($fmodel::getMeta()->getFieldNames() as $f) {
                         // Handle deferreds
                         if (isset($defer[$sr . '__' . $f]))
                             continue;
@@ -2546,7 +2595,7 @@ class MySqlCompiler extends SqlCompiler {
         // Simple selection from one table
         elseif (!$queryset->aggregated) {
             if ($queryset->defer) {
-                foreach ($model::getMeta('fields') as $f) {
+                foreach ($meta->getFieldNames() as $f) {
                     if (isset($queryset->defer[$f]))
                         continue;
                     $fields[$rootAlias .'.'. $this->quote($f)] = true;
@@ -2574,7 +2623,7 @@ class MySqlCompiler extends SqlCompiler {
             }
             // If no group by has been set yet, use the root model pk
             if (!$group_by && !$queryset->aggregated && !$queryset->distinct) {
-                foreach ($model::getMeta('pk') as $pk)
+                foreach ($meta['pk'] as $pk)
                     $group_by[] = $rootAlias .'.'. $pk;
             }
         }
diff --git a/include/class.osticket.php b/include/class.osticket.php
index d6f1f5533361ce72f6abbe64bd39be47a94bc05b..40c939c0493a30d685ea7c51fac0d808eb5b39a5 100644
--- a/include/class.osticket.php
+++ b/include/class.osticket.php
@@ -51,7 +51,7 @@ class osTicket {
     var $company;
     var $plugins;
 
-    function osTicket() {
+    function __construct() {
 
         require_once(INCLUDE_DIR.'class.config.php'); //Config helper
         require_once(INCLUDE_DIR.'class.company.php');
diff --git a/include/class.ostsession.php b/include/class.ostsession.php
index e08ab604f061ffed25e157e8081c25c21f5878a8..8581965eb5f538e343875a0e0ea2df94a02748c2 100644
--- a/include/class.ostsession.php
+++ b/include/class.ostsession.php
@@ -27,7 +27,7 @@ class osTicketSession {
     var $id = '';
     var $backend;
 
-    function osTicketSession($ttl=0){
+    function __construct($ttl=0){
         $this->ttl = $ttl ?: ini_get('session.gc_maxlifetime') ?: SESSION_TTL;
 
         // Set osTicket specific session name.
@@ -164,60 +164,62 @@ abstract class SessionBackend {
     abstract function gc($maxlife);
 }
 
+class SessionData
+extends VerySimpleModel {
+    static $meta = array(
+        'table' => SESSION_TABLE,
+        'pk' => array('session_id'),
+    );
+}
+
 class DbSessionBackend
 extends SessionBackend {
-
-    function read($id){
-        $this->isnew = false;
-        if (!$this->data || $this->id != $id) {
-            $sql='SELECT session_data FROM '.SESSION_TABLE
-                .' WHERE session_id='.db_input($id)
-                .'  AND session_expire>NOW()';
-            if(!($res=db_query($sql)))
-                return false;
-            elseif (db_num_rows($res))
-                list($this->data)=db_fetch_row($res);
-            else
-                // No session data on record -- new session
-                $this->isnew = true;
+    function read($id) {
+        try {
+            $this->data = SessionData::objects()->filter([
+                'session_id' => $id,
+                'session_expire__gt' => SqlFunction::NOW(),
+            ])->one();
             $this->id = $id;
         }
-        $this->data_hash = md5($id.$this->data);
-        return $this->data;
+        catch (DoesNotExist $e) {
+            $this->data = new SessionData(['session_id' => $id]);
+        }
+        catch (OrmException $e) {
+            return false;
+        }
+        return $this->data->session_data;
     }
 
     function update($id, $data){
         global $thisstaff;
 
-        if (md5($id.$data) == $this->data_hash)
-            return;
-
-        elseif (defined('DISABLE_SESSION') && $this->isnew)
-            return;
+        if (defined('DISABLE_SESSION') && $this->data->__new__)
+            return true;
 
-        $ttl = ($this && get_class($this) == 'osTicketSession')
+        $ttl = $this && method_exists($this, 'getTTL')
             ? $this->getTTL() : SESSION_TTL;
 
-        $sql='REPLACE INTO '.SESSION_TABLE.' SET session_updated=NOW() '.
-             ',session_id='.db_input($id).
-             ',session_data=0x'.bin2hex($data).
-             ',session_expire=(NOW() + INTERVAL '.$ttl.' SECOND)'.
-             ',user_id='.db_input($thisstaff?$thisstaff->getId():0).
-             ',user_ip='.db_input($_SERVER['REMOTE_ADDR']).
-             ',user_agent='.db_input($_SERVER['HTTP_USER_AGENT']);
+        assert($this->data->session_id == $id);
+
+        $this->data->session_data = $data;
+        $this->data->session_expire =
+            SqlFunction::NOW()->plus(SqlInterval::SECOND($ttl));
+        $this->data->user_id = $thisstaff ? $thisstaff->getId() : 0;
+        $this->data->user_ip = $_SERVER['REMOTE_ADDR'];
+        $this->data->user_agent = $_SERVER['HTTP_USER_AGENT'];
 
-        $this->data = '';
-        return (db_query($sql) && db_affected_rows());
+        return $this->data->save();
     }
 
     function destroy($id){
-        $sql='DELETE FROM '.SESSION_TABLE.' WHERE session_id='.db_input($id);
-        return (db_query($sql) && db_affected_rows());
+        return SessionData::objects()->filter(['session_id' => $id])->delete();
     }
 
     function gc($maxlife){
-        $sql='DELETE FROM '.SESSION_TABLE.' WHERE session_expire<NOW()';
-        db_query($sql);
+        SessionData::objects()->filter([
+            'session_expire__lte' => SqlFunction::NOW()
+        ])->delete();
     }
 }
 
diff --git a/include/class.page.php b/include/class.page.php
index fa0eb8f77c592f0d489cb1170bbd33fadcd47ec0..920c2ee88ecfd3cd06c3eb8bf36756bad487c76f 100644
--- a/include/class.page.php
+++ b/include/class.page.php
@@ -168,7 +168,7 @@ class Page extends VerySimpleModel {
     /* ------------------> Static methods <--------------------- */
 
     static function create($vars=false) {
-        $page = parent::create($vars);
+        $page = new static($vars);
         $page->created = SqlFunction::NOW();
         return $page;
     }
diff --git a/include/class.pagenate.php b/include/class.pagenate.php
index 5873862c05617843c1c716665f43ada93b2d111c..69368393e431e4d9edb95da7940e90101d9c66b4 100644
--- a/include/class.pagenate.php
+++ b/include/class.pagenate.php
@@ -24,7 +24,7 @@ class PageNate {
     var $pages;
 
 
-    function PageNate($total,$page,$limit=20,$url='') {
+    function __construct($total,$page,$limit=20,$url='') {
         $this->total = intval($total);
         $this->limit = max($limit, 1 );
         $this->page  = max($page, 1 );
diff --git a/include/class.pdf.php b/include/class.pdf.php
index 7f149f342740716be8ef1d99951377f8d067073c..c12d071e82dd48058513fad2d1a89dcf5efb25a7 100644
--- a/include/class.pdf.php
+++ b/include/class.pdf.php
@@ -56,7 +56,7 @@ class Ticket2PDF extends mPDFWithLocalImages
 
     var $ticket = null;
 
-	function Ticket2PDF($ticket, $psize='Letter', $notes=false) {
+	function __construct($ticket, $psize='Letter', $notes=false) {
         global $thisstaff;
 
         $this->ticket = $ticket;
diff --git a/include/class.plugin.php b/include/class.plugin.php
index 39028f6ee3bd833fc4dc1896969dc356a9ed9564..9d15bd3595a97adac8c6f0c67d45152ea8cb159b 100644
--- a/include/class.plugin.php
+++ b/include/class.plugin.php
@@ -8,7 +8,7 @@ class PluginConfig extends Config {
     function __construct($name) {
         // Use parent constructor to place configurable information into the
         // central config table in a namespace of "plugin.<id>"
-        parent::Config("plugin.$name");
+        parent::__construct("plugin.$name");
         foreach ($this->getOptions() as $name => $field) {
             if ($this->exists($name))
                 $this->config[$name]->value = $field->to_php($this->get($name));
@@ -370,7 +370,7 @@ abstract class Plugin {
 
     static $verify_domain = 'updates.osticket.com';
 
-    function Plugin($id) {
+    function __construct($id) {
         $this->id = $id;
         $this->load();
     }
diff --git a/include/class.role.php b/include/class.role.php
index 64fdbe07d2c74aebb608e4fdb30e8bcaaeaf9d74..f584cfa430af8f7c25ba990cf302d601a3439dcf 100644
--- a/include/class.role.php
+++ b/include/class.role.php
@@ -193,7 +193,7 @@ class Role extends RoleModel {
     }
 
     static function create($vars=false) {
-        $role = parent::create($vars);
+        $role = new static($vars);
         $role->created = SqlFunction::NOW();
         return $role;
     }
@@ -383,7 +383,7 @@ extends AbstractForm {
         return $clean;
     }
 
-    function render($staff=true) {
-        return parent::render($staff, false, array('template' => 'dynamic-form-simple.tmpl.php'));
+    function render($staff=true, $title=false, $options=array()) {
+        return parent::render($staff, $title, $options + array('template' => 'dynamic-form-simple.tmpl.php'));
     }
 }
diff --git a/include/class.search.php b/include/class.search.php
index fb4c4e8007079313614698f618bd68fc109f3dfc..25617b27bf401995c9bd14c5afda2ba2d36e346f 100644
--- a/include/class.search.php
+++ b/include/class.search.php
@@ -230,7 +230,7 @@ class MySqlSearchConfig extends Config {
     var $table = CONFIG_TABLE;
 
     function __construct() {
-        parent::Config("mysqlsearch");
+        parent::__construct("mysqlsearch");
     }
 }
 
@@ -983,7 +983,7 @@ class SavedSearch extends VerySimpleModel {
     }
 
     static function create($vars=array()) {
-        $inst = parent::create($vars);
+        $inst = new static($vars);
         $inst->created = SqlFunction::NOW();
         return $inst;
     }
@@ -1011,14 +1011,14 @@ class HelpTopicChoiceField extends ChoiceField {
         return true;
     }
 
-    function getChoices() {
+    function getChoices($verbose=false) {
         return Topic::getHelpTopics(false, Topic::DISPLAY_DISABLED);
     }
 }
 
 require_once INCLUDE_DIR . 'class.dept.php';
 class DepartmentChoiceField extends ChoiceField {
-    function getChoices() {
+    function getChoices($verbose=false) {
         return Dept::getDepartments();
     }
 
@@ -1031,7 +1031,7 @@ class DepartmentChoiceField extends ChoiceField {
 }
 
 class AssigneeChoiceField extends ChoiceField {
-    function getChoices() {
+    function getChoices($verbose=false) {
         global $thisstaff;
 
         $items = array(
@@ -1128,7 +1128,7 @@ class AssigneeChoiceField extends ChoiceField {
 }
 
 class TicketStateChoiceField extends ChoiceField {
-    function getChoices() {
+    function getChoices($verbose=false) {
         return array(
             'open' => __('Open'),
             'closed' => __('Closed'),
@@ -1150,7 +1150,7 @@ class TicketStateChoiceField extends ChoiceField {
 }
 
 class TicketFlagChoiceField extends ChoiceField {
-    function getChoices() {
+    function getChoices($verbose=false) {
         return array(
             'isanswered' =>   __('Answered'),
             'isoverdue' =>    __('Overdue'),
@@ -1178,7 +1178,7 @@ class TicketFlagChoiceField extends ChoiceField {
 }
 
 class TicketSourceChoiceField extends ChoiceField {
-    function getChoices() {
+    function getChoices($verbose=false) {
         return array(
             'web' => __('Web'),
             'email' => __('Email'),
diff --git a/include/class.sequence.php b/include/class.sequence.php
index cf75701fb3849333159fe1e4fd1721b8dd240444..912e7cd28e910f2ba16c6b7345d56c70d2c94166 100644
--- a/include/class.sequence.php
+++ b/include/class.sequence.php
@@ -205,7 +205,7 @@ class Sequence extends VerySimpleModel {
     }
 
     function __create($data) {
-        $instance = parent::create($data);
+        $instance = new static($data);
         $instance->save();
         return $instance;
     }
@@ -214,9 +214,6 @@ class Sequence extends VerySimpleModel {
 class RandomSequence extends Sequence {
     var $padding = '0';
 
-    // Override the ORM constructor and do nothing
-    function __construct($ht=false) {}
-
     function __next($digits=6) {
         if ($digits < 6)
             $digits = 6;
diff --git a/include/class.setup.php b/include/class.setup.php
index 2bddbd65da51d950bda0b428f63eb4a470784e10..bcdd24687dde9b92131c87f54dcda5be552eb486 100644
--- a/include/class.setup.php
+++ b/include/class.setup.php
@@ -14,10 +14,10 @@
     vim: expandtab sw=4 ts=4 sts=4:
 **********************************************************************/
 
-Class SetupWizard {
+class SetupWizard {
 
     //Mimimum requirements
-    var $prereq = array('php'   => '5.3',
+    var $prereq = array('php'   => '5.4',
                         'mysql' => '5.0');
 
     //Version info - same as the latest version.
@@ -28,7 +28,7 @@ Class SetupWizard {
     //Errors
     var $errors=array();
 
-    function SetupWizard(){
+    function __construct(){
         $this->errors=array();
         $this->version_verbose = sprintf(__('osTicket %s' /* <%s> is for the version */),
             THIS_VERSION);
diff --git a/include/class.sla.php b/include/class.sla.php
index 936f300a40b32e6d2071fcfe59391bab43511590..d961ebcba2f9e7de02a6eb8051415e46c396111e 100644
--- a/include/class.sla.php
+++ b/include/class.sla.php
@@ -203,7 +203,7 @@ implements TemplateVariable {
     }
 
     static function create($vars=false, &$errors=array()) {
-        $sla = parent::create($vars);
+        $sla = new static($vars);
         $sla->created = SqlFunction::NOW();
         return $sla;
     }
diff --git a/include/class.staff.php b/include/class.staff.php
index 0c1b40712b5a0effa657c6a3f32891da3fb14b2a..a5e56c22addbf69c3ec83dfa4def3f0eaf6750b8 100644
--- a/include/class.staff.php
+++ b/include/class.staff.php
@@ -702,7 +702,7 @@ implements AuthenticatedUser, EmailContact, TemplateVariable {
         while(list(, list($team_id, $alerts)) = each($membership)) {
             $member = $this->teams->findFirst(array('team_id' => $team_id));
             if (!$member) {
-                $this->teams->add($member = TeamMember::create(array(
+                $this->teams->add($member = new TeamMember(array(
                     'team_id' => $team_id,
                 )));
             }
@@ -819,7 +819,7 @@ implements AuthenticatedUser, EmailContact, TemplateVariable {
 
 
     static function create($vars=false) {
-        $staff = parent::create($vars);
+        $staff = new static($vars);
         $staff->created = SqlFunction::NOW();
         return $staff;
     }
@@ -840,7 +840,7 @@ implements AuthenticatedUser, EmailContact, TemplateVariable {
         $token = Misc::randCode(48); // 290-bits
 
         if (!$content)
-            return new Error(/* @trans */ 'Unable to retrieve password reset email template');
+            return new BaseError(/* @trans */ 'Unable to retrieve password reset email template');
 
         $vars = array(
             'url' => $ost->getConfig()->getBaseUrl(),
@@ -1093,7 +1093,7 @@ implements AuthenticatedUser, EmailContact, TemplateVariable {
                 $errors['dept_access'][$dept_id] = __('Agent already has access to this department');
             $da = $this->dept_access->findFirst(array('dept_id' => $dept_id));
             if (!isset($da)) {
-                $da = StaffDeptAccess::create(array(
+                $da = new StaffDeptAccess(array(
                     'dept_id' => $dept_id, 'role_id' => $role_id
                 ));
                 $this->dept_access->add($da);
@@ -1315,8 +1315,8 @@ extends AbstractForm {
         return $clean;
     }
 
-    function render($staff=true) {
-        return parent::render($staff, false, array('template' => 'dynamic-form-simple.tmpl.php'));
+    function render($staff=true, $title=false, $options=array()) {
+        return parent::render($staff, $title, $options + array('template' => 'dynamic-form-simple.tmpl.php'));
     }
 }
 
@@ -1366,8 +1366,8 @@ extends AbstractForm {
         return $clean;
     }
 
-    function render($staff=true) {
-        return parent::render($staff, false, array('template' => 'dynamic-form-simple.tmpl.php'));
+    function render($staff=true, $title=false, $options=array()) {
+        return parent::render($staff, $title, $options + array('template' => 'dynamic-form-simple.tmpl.php'));
     }
 }
 
diff --git a/include/class.task.php b/include/class.task.php
index 3de800bce36b9322b197c567af6825f74970e6b0..5350d9b606d33f949213d78d3589a047f1169e40 100644
--- a/include/class.task.php
+++ b/include/class.task.php
@@ -1269,7 +1269,7 @@ class Task extends TaskModel implements RestrictedAccess, Threadable {
                 || !$thisstaff->hasPerm(Task::PERM_CREATE, false))
             return null;
 
-        $task = parent::create(array(
+        $task = new static(array(
             'flags' => self::ISOPEN,
             'object_id' => $vars['object_id'],
             'object_type' => $vars['object_type'],
@@ -1545,7 +1545,9 @@ class TaskThread extends ObjectThread {
         return MessageThreadEntry::create($vars, $errors);
     }
 
-    static function create($task) {
+    static function create($task=false) {
+        assert($task !== false);
+
         $id = is_object($task) ? $task->getId() : $task;
         $thread = parent::create(array(
                     'object_id' => $id,
diff --git a/include/class.team.php b/include/class.team.php
index d059eba518a7af990b6d65442a1c8ca98ff26119..d6963eb9213272959dc5fe0da0d319b59376a784 100644
--- a/include/class.team.php
+++ b/include/class.team.php
@@ -203,7 +203,7 @@ implements TemplateVariable {
               $errors['members'][$staff_id] = __('No such agent');
           $member = $this->members->findFirst(array('staff_id' => $staff_id));
           if (!isset($member)) {
-              $member = TeamMember::create(array('staff_id' => $staff_id));
+              $member = new TeamMember(array('staff_id' => $staff_id));
               $this->members->add($member);
           }
           $member->setAlerts($alerts);
@@ -305,7 +305,7 @@ implements TemplateVariable {
     }
 
     static function create($vars=false) {
-        $team = parent::create($vars);
+        $team = new static($vars);
         $team->created = SqlFunction::NOW();
         return $team;
     }
@@ -375,7 +375,7 @@ extends AbstractForm {
         );
     }
 
-    function render($staff=true) {
-        return parent::render($staff, false, array('template' => 'dynamic-form-simple.tmpl.php'));
+    function render($staff=true, $title=false, $options=array()) {
+        return parent::render($staff, $title, $options + array('template' => 'dynamic-form-simple.tmpl.php'));
     }
 }
diff --git a/include/class.template.php b/include/class.template.php
index bc998c8516240abb0f0b8dc24ee21433e96f675a..36cf856028f5f3b6527c81fc65204e8cb53dccaf 100644
--- a/include/class.template.php
+++ b/include/class.template.php
@@ -182,7 +182,7 @@ class EmailTemplateGroup {
         ),
     );
 
-    function EmailTemplateGroup($id){
+    function __construct($id){
         $this->id=0;
         $this->load($id);
     }
@@ -508,7 +508,7 @@ class EmailTemplate {
     var $ht;
     var $_group;
 
-    function EmailTemplate($id, $group=null){
+    function __construct($id, $group=null){
         $this->id=0;
         if ($id) $this->load($id);
         if ($group) $this->_group = $group;
diff --git a/include/class.thread.php b/include/class.thread.php
index 0a1162487feece9b9d247574657b2287a75afa24..f0a92c78b108fad7e70e9e71dd9a4c3e1ed102b9 100644
--- a/include/class.thread.php
+++ b/include/class.thread.php
@@ -533,8 +533,8 @@ class Thread extends VerySimpleModel {
         return true;
     }
 
-    static function create($vars) {
-        $inst = parent::create($vars);
+    static function create($vars=false) {
+        $inst = new static($vars);
         $inst->created = SqlFunction::NOW();
         return $inst;
     }
@@ -968,7 +968,7 @@ implements TemplateVariable {
         else
             return false;
 
-        $att = Attachment::create(array(
+        $att = new Attachment(array(
             'type' => 'H',
             'object_id' => $this->getId(),
             'file_id' => $fileId,
@@ -1064,7 +1064,7 @@ implements TemplateVariable {
         if (!$id || !$mid)
             return false;
 
-        $this->email_info = ThreadEntryEmailInfo::create(array(
+        $this->email_info = new ThreadEntryEmailInfo(array(
             'thread_entry_id' => $id,
             'mid' => $mid,
         ));
@@ -1309,9 +1309,11 @@ implements TemplateVariable {
     }
 
     //new entry ... we're trusting the caller to check validity of the data.
-    static function create($vars, &$errors=array()) {
+    static function create($vars=false) {
         global $cfg;
 
+        assert(is_array($vars));
+
         //Must have...
         if (!$vars['threadId'] || !$vars['type'])
             return false;
@@ -1354,7 +1356,7 @@ implements TemplateVariable {
         if ($poster && is_object($poster))
             $poster = (string) $poster;
 
-        $entry = parent::create(array(
+        $entry = new static(array(
             'created' => SqlFunction::NOW(),
             'type' => $vars['type'],
             'thread_id' => $vars['threadId'],
@@ -1698,7 +1700,7 @@ class ThreadEvent extends VerySimpleModel {
     }
 
     static function create($ht=false, $user=false) {
-        $inst = parent::create($ht);
+        $inst = new static($ht);
         $inst->timestamp = SqlFunction::NOW();
 
         global $thisstaff, $thisclient;
@@ -1716,7 +1718,7 @@ class ThreadEvent extends VerySimpleModel {
     }
 
     static function forTicket($ticket, $state, $user=false) {
-        $inst = static::create(array(
+        $inst = self::create(array(
             'staff_id' => $ticket->getStaffId(),
             'team_id' => $ticket->getTeamId(),
             'dept_id' => $ticket->getDeptId(),
@@ -2280,10 +2282,6 @@ class MessageThreadEntry extends ThreadEntry {
         return $this->getTitle();
     }
 
-    static function create($vars, &$errors=array()) {
-        return static::add($vars, $errors);
-    }
-
     static function add($vars, &$errors=array()) {
 
         if (!$vars || !is_array($vars) || !$vars['threadId'])
@@ -2330,10 +2328,6 @@ class ResponseThreadEntry extends ThreadEntry {
         return $this->getStaff();
     }
 
-    static function create($vars, &$errors=array()) {
-        return static::add($vars, $errors);
-    }
-
     static function add($vars, &$errors=array()) {
 
         if (!$vars || !is_array($vars) || !$vars['threadId'])
@@ -2377,10 +2371,6 @@ class NoteThreadEntry extends ThreadEntry {
                 _S('New internal note posted'));
     }
 
-    static function create($vars, &$errors) {
-        return self::add($vars, $errors);
-    }
-
     static function add($vars, &$errors=array()) {
 
         //Check required params.
@@ -2518,7 +2508,7 @@ implements TemplateVariable {
 
         //Add ticket Id.
         $vars['threadId'] = $this->getId();
-        return NoteThreadEntry::create($vars, $errors);
+        return NoteThreadEntry::add($vars, $errors);
     }
 
     function addMessage($vars, &$errors) {
@@ -2526,7 +2516,7 @@ implements TemplateVariable {
         $vars['threadId'] = $this->getId();
         $vars['staffId'] = 0;
 
-        if (!($message = MessageThreadEntry::create($vars, $errors)))
+        if (!($message = MessageThreadEntry::add($vars, $errors)))
             return $message;
 
         $this->lastmessage = SqlFunction::NOW();
@@ -2539,7 +2529,7 @@ implements TemplateVariable {
         $vars['threadId'] = $this->getId();
         $vars['userId'] = 0;
 
-        if (!($resp = ResponseThreadEntry::create($vars, $errors)))
+        if (!($resp = ResponseThreadEntry::add($vars, $errors)))
             return $resp;
 
         $this->lastresponse = SqlFunction::NOW();
@@ -2593,8 +2583,9 @@ implements TemplateVariable {
 
 // Ticket thread class
 class TicketThread extends ObjectThread {
+    static function create($ticket=false) {
+        assert($ticket !== false);
 
-    static function create($ticket) {
         $id = is_object($ticket) ? $ticket->getId() : $ticket;
         $thread = parent::create(array(
                     'object_id' => $id,
diff --git a/include/class.ticket.php b/include/class.ticket.php
index 6d68aae893ee823da44fbedf9638f4d75cf0d394..9d32abcdecaea4b559f069f53f92329fcf3dd741 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -3294,7 +3294,7 @@ implements RestrictedAccess, Threadable {
 
         //We are ready son...hold on to the rails.
         $number = $topic ? $topic->getNewTicketNumber() : $cfg->getNewTicketNumber();
-        $ticket = parent::create(array(
+        $ticket = new static(array(
             'created' => SqlFunction::NOW(),
             'lastupdate' => SqlFunction::NOW(),
             'number' => $number,
@@ -3504,7 +3504,7 @@ implements RestrictedAccess, Threadable {
         $create_vars['cannedattachments']
             = $tform->getField('message')->getWidget()->getAttachments()->getClean();
 
-        if (!($ticket=Ticket::create($create_vars, $errors, 'staff', false)))
+        if (!($ticket=self::create($create_vars, $errors, 'staff', false)))
             return false;
 
         $vars['msgId']=$ticket->getLastMsgId();
diff --git a/include/class.topic.php b/include/class.topic.php
index 0b808cc2f66e6ab7457f6bb9c2209da1f590e427..c25ab788a4288beaae3bd1163ecb72c6b2ea183f 100644
--- a/include/class.topic.php
+++ b/include/class.topic.php
@@ -277,7 +277,7 @@ implements TemplateVariable {
     /*** Static functions ***/
 
     static function create($vars=array()) {
-        $topic = parent::create($vars);
+        $topic = new static($vars);
         $topic->created = SqlFunction::NOW();
         return $topic;
     }
@@ -505,14 +505,15 @@ implements TemplateVariable {
                     // Don't add a form more than once
                     continue;
                 }
-                TopicFormModel::create(array(
+                $tf = new TopicFormModel(array(
                     'topic_id' => $this->getId(),
                     'form_id' => $id,
                     'sort' => $sort + 1,
                     'extra' => JsonDataEncoder::encode(
                         array('disable' => $find_disabled($form))
                     )
-                ))->save();
+                ));
+                $tf->save();
             }
         }
         return true;
diff --git a/include/class.translation.php b/include/class.translation.php
index 93c7cc4f330a7399040e9c9d753ecd487b148298..2e864b39383fd0dc26b4244eb4f68e304eb532d8 100644
--- a/include/class.translation.php
+++ b/include/class.translation.php
@@ -119,7 +119,7 @@ class gettext_reader {
    * @param object Reader the StreamReader object
    * @param boolean enable_cache Enable or disable caching of strings (default on)
    */
-  function gettext_reader($Reader, $enable_cache = true) {
+  function __construct($Reader, $enable_cache = true) {
     // If there isn't a StreamReader, turn on short circuit mode.
     if (! $Reader || isset($Reader->error) ) {
       $this->short_circuit = true;
@@ -462,7 +462,7 @@ class FileReader {
   var $_fd;
   var $_length;
 
-  function FileReader($filename) {
+  function __construct($filename) {
     if (is_resource($filename)) {
         $this->_length = strlen(stream_get_contents($filename));
         rewind($filename);
@@ -651,16 +651,16 @@ class Translation extends gettext_reader implements Serializable {
     }
 
     static function resurrect($key) {
-        if (!function_exists('apc_fetch'))
+        if (!function_exists('apcu_fetch'))
             return false;
 
         $success = true;
-        if (($translation = apc_fetch($key, $success)) && $success)
+        if (($translation = apcu_fetch($key, $success)) && $success)
             return $translation;
     }
     function cache($key) {
-        if (function_exists('apc_add'))
-            apc_add($key, $this);
+        if (function_exists('apcu_add'))
+            apcu_add($key, $this);
     }
 
 
@@ -1018,7 +1018,7 @@ class CustomDataTranslation extends VerySimpleModel {
             $ht['text'] = static::encodeComplex($ht['text']);
             $ht['flags'] = ($ht['flags'] ?: 0) | self::FLAG_COMPLEX;
         }
-        return parent::create($ht);
+        return new static($ht);
     }
 
     static function allTranslations($msgid, $type='phrase', $lang=false) {
diff --git a/include/class.upgrader.php b/include/class.upgrader.php
index cf75be7847adc7feb56b4218ad27c7a677208e01..87fb63c89be95b0cab01f8beb838a111e1b06841 100644
--- a/include/class.upgrader.php
+++ b/include/class.upgrader.php
@@ -18,7 +18,7 @@ require_once INCLUDE_DIR.'class.setup.php';
 require_once INCLUDE_DIR.'class.migrater.php';
 
 class Upgrader {
-    function Upgrader($prefix, $basedir) {
+    function __construct($prefix, $basedir) {
         global $ost;
 
         $this->streams = array();
@@ -114,44 +114,6 @@ class Upgrader {
             return call_user_func_array($callable, $args);
         }
     }
-
-    function getTask() {
-        if($this->getCurrentStream())
-            return $this->getCurrentStream()->getTask();
-    }
-
-    function doTask() {
-        return $this->getCurrentStream()->doTask();
-    }
-
-    function getErrors() {
-        if ($this->getCurrentStream())
-            return $this->getCurrentStream()->getErrors();
-    }
-
-    function getUpgradeSummary() {
-        if ($this->getCurrentStream())
-            return $this->getCurrentStream()->getUpgradeSummary();
-    }
-
-    function getNextAction() {
-        if ($this->getCurrentStream())
-            return $this->getCurrentStream()->getNextAction();
-    }
-
-    function getNextVersion() {
-        return $this->getCurrentStream()->getNextVersion();
-    }
-
-    function getSchemaSignature() {
-        if ($this->getCurrentStream())
-            return $this->getCurrentStream()->getSchemaSignature();
-    }
-
-    function getSHash() {
-        if ($this->getCurrentStream())
-            return $this->getCurrentStream()->getSHash();
-    }
 }
 
 /**
@@ -185,7 +147,7 @@ class StreamUpgrader extends SetupWizard {
      * sqldir - (string<path>) Path of sql patches
      * upgrader - (Upgrader) Parent coordinator of parallel stream updates
      */
-    function StreamUpgrader($schema_signature, $target, $stream, $prefix, $sqldir, $upgrader) {
+    function __construct($schema_signature, $target, $stream, $prefix, $sqldir, $upgrader) {
 
         $this->signature = $schema_signature;
         $this->target = $target;
diff --git a/include/class.user.php b/include/class.user.php
index b4feed8283c3a9bdf50d21861c209ee88714926d..82e1f9cfeea202b79ea971050a1076084bbc70ff 100644
--- a/include/class.user.php
+++ b/include/class.user.php
@@ -206,7 +206,7 @@ implements TemplateVariable {
             elseif (!$name)
                 list($name) = explode('@', $vars['email'], 2);
 
-            $user = User::create(array(
+            $user = new User(array(
                 'name' => Format::htmldecode(Format::sanitize($name, false)),
                 'created' => new SqlFunction('NOW'),
                 'updated' => new SqlFunction('NOW'),
@@ -871,7 +871,7 @@ class UserEmail extends UserEmailModel {
     static function ensure($address) {
         $email = static::lookup(array('address'=>$address));
         if (!$email) {
-            $email = static::create(array('address'=>$address));
+            $email = new static(array('address'=>$address));
             $email->save();
         }
         return $email;
@@ -1051,7 +1051,7 @@ class UserAccount extends VerySimpleModel {
         $content = Page::lookupByType($template);
 
         if (!$email ||  !$content)
-            return new Error(sprintf(_S('%s: Unable to retrieve template'),
+            return new BaseError(sprintf(_S('%s: Unable to retrieve template'),
                 $template));
 
         $vars = array(
@@ -1146,7 +1146,7 @@ class UserAccount extends VerySimpleModel {
     }
 
     static function createForUser($user, $defaults=false) {
-        $acct = static::create(array('user_id'=>$user->getId()));
+        $acct = new static(array('user_id'=>$user->getId()));
         if ($defaults && is_array($defaults)) {
             foreach ($defaults as $k => $v)
                 $acct->set($k, $v);
@@ -1181,12 +1181,11 @@ class UserAccount extends VerySimpleModel {
 
         if ($errors) return false;
 
-        $account = UserAccount::create(array('user_id' => $user->getId()));
-        if (!$account)
-            return false;
-
-        $account->set('timezone', $vars['timezone']);
-        $account->set('backend', $vars['backend']);
+        $account = new UserAccount(array(
+            'user_id' => $user->getId(),
+            'timezone' => $vars['timezone'],
+            'backend' => $vars['backend'],
+        ));
 
         if ($vars['username'] && strcasecmp($vars['username'], $user->getEmail()))
             $account->set('username', $vars['username']);
diff --git a/include/class.usersession.php b/include/class.usersession.php
index 004eda9ee5e55ac7910990829102720eeaa42ae6..bb113f5d3bf2f82fcff08c11c4fb933dcf48b011 100644
--- a/include/class.usersession.php
+++ b/include/class.usersession.php
@@ -25,7 +25,7 @@ class UserSession {
    var $ip = '';
    var $validated=FALSE;
 
-   function UserSession($userid){
+   function __construct($userid){
 
       $this->browser=(!empty($_SERVER['HTTP_USER_AGENT'])) ? $_SERVER['HTTP_USER_AGENT'] : $_ENV['HTTP_USER_AGENT'];
       $this->ip=(!empty($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : getenv('REMOTE_ADDR');
diff --git a/include/class.validator.php b/include/class.validator.php
index 88075ab45b41f52c553caa2b6dd18a4b68add2fe..2cce38f21432dc457efbae59bd4277bec9d213d3 100644
--- a/include/class.validator.php
+++ b/include/class.validator.php
@@ -20,7 +20,7 @@ class Validator {
     var $fields=array();
     var $errors=array();
 
-    function Validator($fields=null) {
+    function __construct($fields=null) {
         $this->setFields($fields);
     }
     function setFields(&$fields){
@@ -99,15 +99,15 @@ class Validator {
                 break;
             case 'phone':
             case 'fax':
-                if(!$this->is_phone($this->input[$k]))
+                if(!self::is_phone($this->input[$k]))
                     $this->errors[$k]=$field['error'];
                 break;
             case 'email':
-                if(!$this->is_email($this->input[$k]))
+                if(!self::is_email($this->input[$k]))
                     $this->errors[$k]=$field['error'];
                 break;
             case 'url':
-                if(!$this->is_url($this->input[$k]))
+                if(!self::is_url($this->input[$k]))
                     $this->errors[$k]=$field['error'];
                 break;
             case 'password':
@@ -116,7 +116,7 @@ class Validator {
                 break;
             case 'username':
                 $error = '';
-                if (!$this->is_username($this->input[$k], $error))
+                if (!self::is_username($this->input[$k], $error))
                     $this->errors[$k]=$field['error'].": $error";
                 break;
             case 'zipcode':
@@ -140,10 +140,11 @@ class Validator {
 
     /*** Functions below can be called directly without class instance.
          Validator::func(var..);  (nolint) ***/
-    function is_email($email, $list=false, $verify=false) {
+    static function is_email($email, $list=false, $verify=false) {
         require_once PEAR_DIR . 'Mail/RFC822.php';
         require_once PEAR_DIR . 'PEAR.php';
-        if (!($mails = Mail_RFC822::parseAddressList($email)) || PEAR::isError($mails))
+        $rfc822 = new Mail_RFC822();
+        if (!($mails = $rfc822->parseAddressList($email)) || PEAR::isError($mails))
             return false;
 
         if (!$list && count($mails) > 1)
@@ -166,24 +167,24 @@ class Validator {
         return true;
     }
 
-    function is_valid_email($email) {
+    static function is_valid_email($email) {
         global $cfg;
         // Default to FALSE for installation
         return self::is_email($email, false, $cfg && $cfg->verifyEmailAddrs());
     }
 
-    function is_phone($phone) {
+    static function is_phone($phone) {
         /* We're not really validating the phone number but just making sure it doesn't contain illegal chars and of acceptable len */
         $stripped=preg_replace("(\(|\)|\-|\.|\+|[  ]+)","",$phone);
         return (!is_numeric($stripped) || ((strlen($stripped)<7) || (strlen($stripped)>16)))?false:true;
     }
 
-    function is_url($url) {
+    static function is_url($url) {
         //XXX: parse_url is not ideal for validating urls but it's ideal for basic checks.
         return ($url && ($info=parse_url($url)) && $info['host']);
     }
 
-    function is_ip($ip) {
+    static function is_ip($ip) {
 
         if(!$ip or empty($ip))
             return false;
@@ -203,7 +204,7 @@ class Validator {
         return false;
     }
 
-    function is_username($username, &$error='') {
+    static function is_username($username, &$error='') {
         if (strlen($username)<2)
             $error = __('Username must have at least two (2) characters');
         elseif (!preg_match('/^[\p{L}\d._-]+$/u', $username))
diff --git a/include/class.variable.php b/include/class.variable.php
index 48c39095ebdbe022f324ce02847dbf36896b1e6f..fb968336a697c505654d485829ab8e79620ab87f 100644
--- a/include/class.variable.php
+++ b/include/class.variable.php
@@ -27,7 +27,7 @@ class VariableReplacer {
 
     var $errors;
 
-    function VariableReplacer($start_delim='(?:%{|%%7B)', $end_delim='(?:}|%7D)') {
+    function __construct($start_delim='(?:%{|%%7B)', $end_delim='(?:}|%7D)') {
 
         $this->start_delim = $start_delim;
         $this->end_delim = $end_delim;
diff --git a/include/class.xml.php b/include/class.xml.php
index 129e05877609686f298154bd554cad38d6c55b5a..c73a7cf7379a4461d3aebed1f615f9759b50e1b8 100644
--- a/include/class.xml.php
+++ b/include/class.xml.php
@@ -18,7 +18,7 @@
 
 class XmlDataParser {
 
-    function XmlDataParser() {
+    function __construct() {
         $this->parser = xml_parser_create('utf-8');
         xml_set_object($this->parser, $this);
         xml_set_element_handler($this->parser, "startElement", "endElement");
diff --git a/include/class.yaml.php b/include/class.yaml.php
index 63ceb37543d3fe4044172e1a7775c84e6734feb8..9fffc9a3f08ecad2515fda5b8681d2de020546b7 100644
--- a/include/class.yaml.php
+++ b/include/class.yaml.php
@@ -36,7 +36,7 @@ class YamlDataParser {
     }
 }
 
-class YamlParserError extends Error {
+class YamlParserError extends BaseError {
     static $title = 'Error parsing YAML document';
 }
 ?>
diff --git a/include/htmLawed.php b/include/htmLawed.php
index 9d0cc9e95e8210746f52933e0615eb2df29a7275..58f12039d376cc5dc3351810816765f6d8b8411b 100644
--- a/include/htmLawed.php
+++ b/include/htmLawed.php
@@ -379,7 +379,8 @@ return $r;
 function hl_spec($t){
 // final $spec
 $s = array();
-$t = str_replace(array("\t", "\r", "\n", ' '), '', preg_replace('/"(?>(`.|[^"])*)"/sme', 'substr(str_replace(array(";", "|", "~", " ", ",", "/", "(", ")", \'`"\'), array("\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", "\x08", "\""), "$0"), 1, -1)', trim($t)));
+$t = str_replace(array("\t", "\r", "\n", ' '), '',
+preg_replace_callback('/"(?>(`.|[^"])*)"/sm', function($m) {return substr(str_replace(array(";", "|", "~", " ", ",", "/", "(", ")", '`"'), array("\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", "\x08", "\""), $m[0]), 1, -1);}, trim($t)));
 for($i = count(($t = explode(';', $t))); --$i>=0;){
  $w = $t[$i];
  if(empty($w) or ($e = strpos($w, '=')) === false or !strlen(($a =  substr($w, $e+1)))){continue;}
diff --git a/include/html2text.php b/include/html2text.php
index d8ef77c5e77c51284a0fa9e304c6989754873f58..0fcaa5cab999744bac97d90e0c8092b476bfbe4c 100644
--- a/include/html2text.php
+++ b/include/html2text.php
@@ -561,7 +561,7 @@ class HtmlUnorderedListElement extends HtmlListElement {
 }
 
 class HtmlListItem extends HtmlBlockElement {
-    function HtmlListItem($node, $parent, $number) {
+    function __construct($node, $parent, $number) {
         parent::__construct($node, $parent);
         $this->number = $number;
     }
diff --git a/include/mpdf/classes/bmp.php b/include/mpdf/classes/bmp.php
index acf7f808549104a003bcf9b180aee41b5b6bcfd8..04b64326d4b9826b6270d8082903be49526b0016 100755
--- a/include/mpdf/classes/bmp.php
+++ b/include/mpdf/classes/bmp.php
@@ -4,7 +4,7 @@ class bmp {
 
 var $mpdf = null;
 
-function bmp(&$mpdf) {
+function __construct(&$mpdf) {
 	$this->mpdf = $mpdf;
 }
 
@@ -245,4 +245,4 @@ function rle4_decode ($str, $width){
 
 }
 
-?>
\ No newline at end of file
+?>
diff --git a/include/mpdf/classes/cssmgr.php b/include/mpdf/classes/cssmgr.php
index aef74542d44b0ab9019f40841162b59464151750..3b030f8c4c0866b54092811bb6091385d0a55b6b 100755
--- a/include/mpdf/classes/cssmgr.php
+++ b/include/mpdf/classes/cssmgr.php
@@ -12,7 +12,7 @@ var $tbCSSlvl;
 var $listCSSlvl;
 
 
-function cssmgr(&$mpdf) {
+function __construct(&$mpdf) {
 	$this->mpdf = $mpdf;
 	$this->tablecascadeCSS = array();
 	$this->listcascadeCSS = array();
@@ -1574,4 +1574,4 @@ function PreviewBlockCSS($tag,$attr) {
 
 }	// end of class
 
-?>
\ No newline at end of file
+?>
diff --git a/include/mpdf/classes/gif.php b/include/mpdf/classes/gif.php
index 582de0d6f49ecf5fa8743b2685ea018c934decb4..2087a97d34ae660acb02b8c0bb8cf69e39906a85 100755
--- a/include/mpdf/classes/gif.php
+++ b/include/mpdf/classes/gif.php
@@ -26,7 +26,7 @@ class CGIFLZW
 	///////////////////////////////////////////////////////////////////////////
 
 	// CONSTRUCTOR
-	function CGIFLZW()
+	function __construct()
 	{
 		$this->MAX_LZW_BITS = 12;
 		unSet($this->Next);
@@ -240,7 +240,7 @@ class CGIFCOLORTABLE
 	///////////////////////////////////////////////////////////////////////////
 
 	// CONSTRUCTOR
-	function CGIFCOLORTABLE()
+	function __construct()
 	{
 		unSet($this->m_nColors);
 		unSet($this->m_arColors);
@@ -327,7 +327,7 @@ class CGIFFILEHEADER
 	///////////////////////////////////////////////////////////////////////////
 
 	// CONSTRUCTOR
-	function CGIFFILEHEADER()
+	function __construct()
 	{
 		unSet($this->m_lpVer);
 		unSet($this->m_nWidth);
@@ -402,20 +402,6 @@ class CGIFIMAGEHEADER
 
 	///////////////////////////////////////////////////////////////////////////
 
-	// CONSTRUCTOR
-	function CGIFIMAGEHEADER()
-	{
-		unSet($this->m_nLeft);
-		unSet($this->m_nTop);
-		unSet($this->m_nWidth);
-		unSet($this->m_nHeight);
-		unSet($this->m_bLocalClr);
-		unSet($this->m_bInterlace);
-		unSet($this->m_bSorted);
-		unSet($this->m_nTableSize);
-		unSet($this->m_colorTable);
-	}
-
 	///////////////////////////////////////////////////////////////////////////
 
 	function load($lpData, &$hdrLen)
@@ -473,15 +459,8 @@ class CGIFIMAGE
 
 	///////////////////////////////////////////////////////////////////////////
 
-	function CGIFIMAGE()
+	function __construct()
 	{
-		unSet($this->m_disp);
-		unSet($this->m_bUser);
-		unSet($this->m_bTrans);
-		unSet($this->m_nDelay);
-		unSet($this->m_nTrans);
-		unSet($this->m_lpComm);
-		unSet($this->m_data);
 		$this->m_gih = new CGIFIMAGEHEADER();
 		$this->m_lzw = new CGIFLZW();
 	}
@@ -647,7 +626,7 @@ class CGIF
 	///////////////////////////////////////////////////////////////////////////
 
 	// CONSTRUCTOR
-	function CGIF()
+	function __construct()
 	{
 		$this->m_gfh     = new CGIFFILEHEADER();
 		$this->m_img     = new CGIFIMAGE();
@@ -697,4 +676,4 @@ class CGIF
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-?>
\ No newline at end of file
+?>
diff --git a/include/mpdf/classes/grad.php b/include/mpdf/classes/grad.php
index b5db60204c705fe2650fd6b3ec0844393a0e468b..c43c3e06fab6da011cbc1139e5449a0175e9b06f 100755
--- a/include/mpdf/classes/grad.php
+++ b/include/mpdf/classes/grad.php
@@ -4,7 +4,7 @@ class grad {
 
 var $mpdf = null;
 
-function grad(&$mpdf) {
+function __construct(&$mpdf) {
 	$this->mpdf = $mpdf;
 }
 
@@ -720,4 +720,4 @@ function parseBackgroundGradient($bg) {
 
 }
 
-?>
\ No newline at end of file
+?>
diff --git a/include/mpdf/classes/indic.php b/include/mpdf/classes/indic.php
index e747dedef69317c2587e09e4813cf5258388825b..c99e6eb4515b3a3a22f01c73204505d56a3cdcab 100755
--- a/include/mpdf/classes/indic.php
+++ b/include/mpdf/classes/indic.php
@@ -2,11 +2,6 @@
 
 class indic {
 
-function indic() {
-
-}
-
-
 function substituteIndic($earr, $lang, $font) {
 	global $voltdata;
 
@@ -430,4 +425,4 @@ function substituteIndic($earr, $lang, $font) {
 
 }
 
-?>
\ No newline at end of file
+?>
diff --git a/include/mpdf/classes/ttfontsuni.php b/include/mpdf/classes/ttfontsuni.php
index f639b005b38e802e6c6ff1531bf3d12e84af2c0f..70be745a641097e7f28ef3d9469a5a010cb54222 100755
--- a/include/mpdf/classes/ttfontsuni.php
+++ b/include/mpdf/classes/ttfontsuni.php
@@ -79,7 +79,7 @@ var $TTCFonts;
 var $maxUniChar;
 var $kerninfo;
 
-	function TTFontFile() {
+	function __construct() {
 		$this->maxStrLenRead = 200000;	// Maximum size of glyf table to read in as string (otherwise reads each glyph from file)
 	}
 
@@ -2062,4 +2062,4 @@ PCLT - not recommended
 }
 
 
-?>
\ No newline at end of file
+?>
diff --git a/include/mpdf/classes/wmf.php b/include/mpdf/classes/wmf.php
index e5f5e3c1b985f047e4b0eed0bacdfd7c94735af3..5182d33979ad020ddfac0db9ca3db915d46359f4 100755
--- a/include/mpdf/classes/wmf.php
+++ b/include/mpdf/classes/wmf.php
@@ -5,7 +5,7 @@ class wmf {
 var $mpdf = null;
 var $gdiObjectArray;
 
-function wmf(&$mpdf) {
+function __construct(&$mpdf) {
 	$this->mpdf = $mpdf;
 }
 
@@ -233,4 +233,4 @@ function _DeleteGDIObject($idx) {
 
 }
 
-?>
\ No newline at end of file
+?>
diff --git a/include/mpdf/mpdf.php b/include/mpdf/mpdf.php
index 9c7fe98ad44cd7a9848a0890d6583bfeefd52710..fa2ff8f152f82ea67265520bf797387fb75dd2f3 100755
--- a/include/mpdf/mpdf.php
+++ b/include/mpdf/mpdf.php
@@ -827,7 +827,7 @@ var $innerblocktags;
 // **********************************
 // **********************************
 
-function mPDF($mode='',$format='A4',$default_font_size=0,$default_font='',$mgl=15,$mgr=15,$mgt=16,$mgb=16,$mgh=9,$mgf=9, $orientation='P') {
+function __construct($mode='',$format='A4',$default_font_size=0,$default_font='',$mgl=15,$mgr=15,$mgt=16,$mgb=16,$mgh=9,$mgf=9, $orientation='P') {
 
 /*-- BACKGROUNDS --*/
 		if (!class_exists('grad', false)) { include(_MPDF_PATH.'classes/grad.php'); }
@@ -1431,7 +1431,6 @@ function _getPageFormat($format) {
 			case 'A': {$format=array(314.65,504.57 );	 break;}		//	'A' format paperback size 111x178mm
 			case 'DEMY': {$format=array(382.68,612.28 );  break;}		//	'Demy' format paperback size 135x216mm
 			case 'ROYAL': {$format=array(433.70,663.30 );  break;}	//	'Royal' format paperback size 153x234mm
-			default: $format = false;
 		}
 	return $format;
 }
diff --git a/include/pear/Crypt/AES.php b/include/pear/Crypt/AES.php
index 84de2d9acf8223294c6ce0f1e5fea7e4748ab900..771d87aee685605af0ce4d65b2552de8fa45a232 100644
--- a/include/pear/Crypt/AES.php
+++ b/include/pear/Crypt/AES.php
@@ -175,7 +175,7 @@ class Crypt_AES extends Crypt_Rijndael {
      * @return Crypt_AES
      * @access public
      */
-    function Crypt_AES($mode = CRYPT_AES_MODE_CBC)
+    function __construct($mode = CRYPT_AES_MODE_CBC)
     {
         if ( !defined('CRYPT_AES_MODE') ) {
             switch (true) {
@@ -237,7 +237,7 @@ class Crypt_AES extends Crypt_Rijndael {
         }
 
         if (CRYPT_AES_MODE == CRYPT_AES_MODE_INTERNAL) {
-            parent::Crypt_Rijndael($this->mode);
+            parent::__construct($this->mode);
         }
 
     }
diff --git a/include/pear/Crypt/Hash.php b/include/pear/Crypt/Hash.php
index 3b506164ea93102292b2073119945ce893911e16..77bf2b53441bfdbc46a772b0c7ae9485b0687a68 100644
--- a/include/pear/Crypt/Hash.php
+++ b/include/pear/Crypt/Hash.php
@@ -143,7 +143,7 @@ class Crypt_Hash {
      * @return Crypt_Hash
      * @access public
      */
-    function Crypt_Hash($hash = 'sha1')
+    function __construct($hash = 'sha1')
     {
         if ( !defined('CRYPT_HASH_MODE') ) {
             switch (true) {
diff --git a/include/pear/Crypt/Rijndael.php b/include/pear/Crypt/Rijndael.php
index a8510007afe1abac110b552c0d4a5fa3ce02c892..e35d96383ad1f0168ae67f86e4b860b5379c6dfe 100644
--- a/include/pear/Crypt/Rijndael.php
+++ b/include/pear/Crypt/Rijndael.php
@@ -448,7 +448,7 @@ class Crypt_Rijndael {
      * @return Crypt_Rijndael
      * @access public
      */
-    function Crypt_Rijndael($mode = CRYPT_RIJNDAEL_MODE_CBC)
+    function __construct($mode = CRYPT_RIJNDAEL_MODE_CBC)
     {
         switch ($mode) {
             case CRYPT_RIJNDAEL_MODE_ECB:
diff --git a/include/pear/Mail/RFC822.php b/include/pear/Mail/RFC822.php
index abf1000d9f84293d444053121107d4cfaa20f2d8..0ad24d7d80d31d3c1471804b6a39f21b94b937a1 100644
--- a/include/pear/Mail/RFC822.php
+++ b/include/pear/Mail/RFC822.php
@@ -149,7 +149,7 @@ class Mail_RFC822 {
      *
      * @return object Mail_RFC822 A new Mail_RFC822 object.
      */
-    function Mail_RFC822($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null)
+    function __construct($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null)
     {
         if (isset($address))        $this->address        = $address;
         if (isset($default_domain)) $this->default_domain = $default_domain;
diff --git a/include/pear/Mail/mail.php b/include/pear/Mail/mail.php
index a8b4b5dbeef6c0b194fa9a2036af40c2feb5869a..3c79da7f5e86b2b666b4d281e9631ff75f829002 100644
--- a/include/pear/Mail/mail.php
+++ b/include/pear/Mail/mail.php
@@ -64,7 +64,7 @@ class Mail_mail extends Mail {
      *
      * @param array $params Extra arguments for the mail() function.
      */
-    function Mail_mail($params = null)
+    function __construct($params = null)
     {
         // The other mail implementations accept parameters as arrays.
         // In the interest of being consistent, explode an array into
diff --git a/include/pear/Mail/mimeDecode.php b/include/pear/Mail/mimeDecode.php
index 29095c9605e270af4b885ad0181a1dcd1ab6800f..9b1e208be17859b5380910fd0ce9f77aff1d7ada 100644
--- a/include/pear/Mail/mimeDecode.php
+++ b/include/pear/Mail/mimeDecode.php
@@ -149,7 +149,7 @@ class Mail_mimeDecode extends PEAR
      * @param string The input to decode
      * @access public
      */
-    function Mail_mimeDecode(&$input)
+    function __construct(&$input)
     {
         list($header, $body)   = $this->_splitBodyHeader($input);
 
diff --git a/include/pear/Mail/mock.php b/include/pear/Mail/mock.php
index 61570ba408cdcec0b6cd5814f080d4aa78581a45..a1bf9b803dee25fd232bb86fb15638c8fe26ca48 100644
--- a/include/pear/Mail/mock.php
+++ b/include/pear/Mail/mock.php
@@ -84,7 +84,7 @@ class Mail_mock extends Mail {
      * @param array Hash containing any parameters.
      * @access public
      */
-    function Mail_mock($params)
+    function __construct($params)
     {
         if (isset($params['preSendCallback']) &&
             is_callable($params['preSendCallback'])) {
diff --git a/include/pear/Mail/sendmail.php b/include/pear/Mail/sendmail.php
index b056575e99274f886b1473b5ee35f002d2699329..77dbe1fe7fb2b5b60f4745697f1c1bb12b00c3fe 100644
--- a/include/pear/Mail/sendmail.php
+++ b/include/pear/Mail/sendmail.php
@@ -56,7 +56,7 @@ class Mail_sendmail extends Mail {
      *              defaults.
      * @access public
      */
-    function Mail_sendmail($params)
+    function __construct($params)
     {
         if (isset($params['sendmail_path'])) {
             $this->sendmail_path = $params['sendmail_path'];
diff --git a/include/pear/Mail/smtp.php b/include/pear/Mail/smtp.php
index 75171891ea61351ed3ac3530228b549ad4a14a31..877803d959ffce6c3d01161d99049bdf83212f49 100644
--- a/include/pear/Mail/smtp.php
+++ b/include/pear/Mail/smtp.php
@@ -188,7 +188,7 @@ class Mail_smtp extends Mail {
      *              defaults.
      * @access public
      */
-    function Mail_smtp($params)
+    function __construct($params)
     {
         if (isset($params['host'])) $this->host = $params['host'];
         if (isset($params['port'])) $this->port = $params['port'];
@@ -346,7 +346,7 @@ class Mail_smtp extends Mail {
         }
 
         include_once 'Net/SMTP.php';
-        $this->_smtp = &new Net_SMTP($this->host,
+        $this->_smtp = new Net_SMTP($this->host,
                                      $this->port,
                                      $this->localhost);
 
diff --git a/include/pear/Math/BigInteger.php b/include/pear/Math/BigInteger.php
index 37acb1fe300e23864b627197622d0ddf91e20f15..f91c246b1a43c8f75fb43ad9d0f6d0b8fd2ed623 100644
--- a/include/pear/Math/BigInteger.php
+++ b/include/pear/Math/BigInteger.php
@@ -256,7 +256,7 @@ class Math_BigInteger {
      * @return Math_BigInteger
      * @access public
      */
-    function Math_BigInteger($x = 0, $base = 10)
+    function __construct($x = 0, $base = 10)
     {
         if ( !defined('MATH_BIGINTEGER_MODE') ) {
             switch (true) {
diff --git a/include/pear/PEAR.php b/include/pear/PEAR.php
index 2aa85259d62dc69c0cad3f38320bc82fdcf28af9..9708fcd5ef024dccf126a7c1dc1797c9d6832a60 100644
--- a/include/pear/PEAR.php
+++ b/include/pear/PEAR.php
@@ -146,7 +146,7 @@ class PEAR
      * @access public
      * @return void
      */
-    function PEAR($error_class = null)
+    function __construct($error_class = null)
     {
         $classname = strtolower(get_class($this));
         if ($this->_debug) {
@@ -247,7 +247,7 @@ class PEAR
      * @access  public
      * @return  bool    true if parameter is an error
      */
-    function isError($data, $code = null)
+    static function isError($data, $code = null)
     {
         if (!is_a($data, 'PEAR_Error')) {
             return false;
@@ -469,7 +469,7 @@ class PEAR
      * @see PEAR::setErrorHandling
      * @since PHP 4.0.5
      */
-    function &raiseError($message = null,
+    static function &raiseError($message = null,
                          $code = null,
                          $mode = null,
                          $options = null,
@@ -823,7 +823,7 @@ class PEAR_Error
      * @access public
      *
      */
-    function PEAR_Error($message = 'unknown error', $code = null,
+    function __construct($message = 'unknown error', $code = null,
                         $mode = null, $options = null, $userinfo = null)
     {
         if ($mode === null) {
diff --git a/include/pear/PEAR/FixPHP5PEARWarnings.php b/include/pear/PEAR/FixPHP5PEARWarnings.php
index be5dc3ce707c3e06189b89395819ae49edbab19c..32807c29057d25dcd03a1f5ce8f834aabcef4240 100644
--- a/include/pear/PEAR/FixPHP5PEARWarnings.php
+++ b/include/pear/PEAR/FixPHP5PEARWarnings.php
@@ -1,7 +1,7 @@
 <?php
 if ($skipmsg) {
-    $a = &new $ec($code, $mode, $options, $userinfo);
+    $a = new $ec($code, $mode, $options, $userinfo);
 } else {
-    $a = &new $ec($message, $code, $mode, $options, $userinfo);
+    $a = new $ec($message, $code, $mode, $options, $userinfo);
 }
-?>
\ No newline at end of file
+?>
diff --git a/include/staff/system.inc.php b/include/staff/system.inc.php
index 6988261eab4f0746d9d0be78762330714efecf73..ee70faefb3dc4fd878342e65edf65bf28865d34f 100644
--- a/include/staff/system.inc.php
+++ b/include/staff/system.inc.php
@@ -41,6 +41,14 @@ $extensions = array(
             'name' => 'fileinfo',
             'desc' => __('Used to detect file types for uploads')
             ),
+        'apcu' => array(
+            'name' => 'APCu',
+            'desc' => __('Improves overall performance')
+            ),
+        'Zend Opcache' => array(
+            'name' => 'Zend Opcache',
+            'desc' => __('Improves overall performance')
+            ),
         );
 
 ?>
diff --git a/include/upgrader/prereq.inc.php b/include/upgrader/prereq.inc.php
index ddb19ee2112ee9dd066d5c22a9b4e0ba793bc3a2..7ab7b4c5b5b98dd7cb272b34854fecb69c4fe558 100644
--- a/include/upgrader/prereq.inc.php
+++ b/include/upgrader/prereq.inc.php
@@ -15,7 +15,7 @@ if(!defined('OSTSCPINC') || !$thisstaff || !$thisstaff->isAdmin()) die('Access D
             <?php echo __('These items are necessary in order to run the latest version of osTicket.');?>
             <ul class="progress">
                 <li class="<?php echo $upgrader->check_php()?'yes':'no'; ?>">
-                <?php echo sprintf(__('%s or later'), 'PHP v5.3'); ?> - (<small><b><?php echo PHP_VERSION; ?></b></small>)</li>
+                <?php echo sprintf(__('%s or later'), 'PHP v5.4'); ?> - (<small><b><?php echo PHP_VERSION; ?></b></small>)</li>
                 <li class="<?php echo $upgrader->check_mysql()?'yes':'no'; ?>">
                 <?php echo __('MySQLi extension for PHP'); ?>- (<small><b><?php
                     echo extension_loaded('mysqli')?__('module loaded'):__('missing!'); ?></b></small>)</li>
diff --git a/include/upgrader/streams/core/15b30765-dd0022fb.task.php b/include/upgrader/streams/core/15b30765-dd0022fb.task.php
index 970136b1bc366f61c24a1915c03b957bed72d078..beafd9d7d03b693cd24fa0619983af19e2d14b38 100644
--- a/include/upgrader/streams/core/15b30765-dd0022fb.task.php
+++ b/include/upgrader/streams/core/15b30765-dd0022fb.task.php
@@ -262,7 +262,7 @@ class OldOneSixFile extends VerySimpleModel {
     );
 
     static function create($info) {
-        $I = parent::create($info);
+        $I = new static($info);
         $I->save();
         return $I;
     }
diff --git a/setup/inc/class.installer.php b/setup/inc/class.installer.php
index 24594ec404f9a8fd94ea87a2df2ec211c956a78d..85441fedd2566d87dd384814d472695a2d98bdb1 100644
--- a/setup/inc/class.installer.php
+++ b/setup/inc/class.installer.php
@@ -21,7 +21,7 @@ class Installer extends SetupWizard {
 
     var $config;
 
-    function Installer($configfile) {
+    function __construct($configfile) {
         $this->config =$configfile;
         $this->errors=array();
     }
diff --git a/setup/inc/install-prereq.inc.php b/setup/inc/install-prereq.inc.php
index 659b01c0f29dee918377b403087e07ae2012994c..bff091f6089e42e8c575b6f346b875f7f82dfe90 100644
--- a/setup/inc/install-prereq.inc.php
+++ b/setup/inc/install-prereq.inc.php
@@ -15,7 +15,7 @@ if(!defined('SETUPINC')) die('Kwaheri!');
             <?php echo __('These items are necessary in order to install and use osTicket.');?>
             <ul class="progress">
                 <li class="<?php echo $installer->check_php()?'yes':'no'; ?>">
-                <?php echo sprintf(__('%s or greater'), '<span class="ltr">PHP v5.3</span>');?> &mdash; <small class="ltr">(<b><?php echo PHP_VERSION; ?></b>)</small></li>
+                <?php echo sprintf(__('%s or greater'), '<span class="ltr">PHP v5.4</span>');?> &mdash; <small class="ltr">(<b><?php echo PHP_VERSION; ?></b>)</small></li>
                 <li class="<?php echo $installer->check_mysql()?'yes':'no'; ?>">
                 <?php echo __('MySQLi extension for PHP');?> &mdash; <small><b><?php
                     echo extension_loaded('mysqli')?__('module loaded'):__('missing!'); ?></b></small></li>
@@ -38,7 +38,9 @@ if(!defined('SETUPINC')) die('Kwaheri!');
                     echo __('recommended for plugins and language packs');?></li>
                 <li class="<?php echo extension_loaded('intl')?'yes':'no'; ?>">Intl <?php echo __('extension');?> &mdash; <?php
                     echo __('recommended for improved localization');?></li>
-                <li class="<?php echo extension_loaded('apc')?'yes':'no'; ?>">APC <?php echo __('extension');?> &mdash; <?php
+                <li class="<?php echo extension_loaded('apcu')?'yes':'no'; ?>">APCu <?php echo __('extension');?> &mdash; <?php
+                    echo __('(faster performance)');?></li>
+                <li class="<?php echo extension_loaded('Zend OPcache')?'yes':'no'; ?>">Zend OPcache <?php echo __('extension');?> &mdash; <?php
                     echo __('(faster performance)');?></li>
             </ul>
             <div id="bar">