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/api.tickets.php b/include/api.tickets.php
index e762fb18a9d18ac7aff49550366ae3eb58981b7b..e2ee066aefff68921a26dc4bfbd28b62008b7a8e 100644
--- a/include/api.tickets.php
+++ b/include/api.tickets.php
@@ -129,7 +129,7 @@ class TicketApiController extends ApiController {
         # Create the ticket with the data (attempt to anyway)
         $errors = array();
 
-        $ticket = Ticket::create2($data, $errors, $data['source'], $autorespond, $alert);
+        $ticket = Ticket::create($data, $errors, $data['source'], $autorespond, $alert);
         # Return errors (?)
         if (count($errors)) {
             if(isset($errors['errno']) && $errors['errno'] == 403)
diff --git a/include/class.attachment.php b/include/class.attachment.php
index 95e2fe24292bd772970f65012f903f5c27d991d7..15f3fd9b1dec6de619247e1158771a73434ba797 100644
--- a/include/class.attachment.php
+++ b/include/class.attachment.php
@@ -130,14 +130,14 @@ extends InstrumentedList {
                 $fileId = $file['id'];
             elseif (isset($file['tmp_name']) && ($F = AttachmentFile::upload($file)))
                 $fileId = $F->getId();
-            elseif ($F = AttachmentFile::createFile($file))
+            elseif ($F = AttachmentFile::create($file))
                 $fileId = $F->getId();
             else
                 continue;
 
             $_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.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.dept.php b/include/class.dept.php
index 495380b9124ffa97dbf2d7f80c613b59eb6ed8e5..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;
     }
 
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 bb1bce0add96777963130c8585be2548109f64e3..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();
@@ -896,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']);
@@ -1288,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);
@@ -1297,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);
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.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 6439f798d6632e77bd99a5e068b51a3197dfbc5d..a7b8eb64807d010e1b6b0f1b3db11c5f76a986d5 100644
--- a/include/class.file.php
+++ b/include/class.file.php
@@ -293,7 +293,7 @@ class AttachmentFile extends VerySimpleModel {
                     'tmp_name'=>$file['tmp_name'],
                     );
 
-        return static::createFile($info, $ft, $deduplicate);
+        return static::create($info, $ft, $deduplicate);
     }
 
     static function uploadLogo($file, &$error, $aspect_ratio=2) {
@@ -327,7 +327,7 @@ class AttachmentFile extends VerySimpleModel {
         return false;
     }
 
-    static function createFile(&$file, $ft='T', $deduplicate=true) {
+    static function create(&$file, $ft='T', $deduplicate=true) {
         if (isset($file['encoding'])) {
             switch ($file['encoding']) {
             case 'base64':
@@ -380,7 +380,7 @@ class AttachmentFile extends VerySimpleModel {
             $file['type'] = 'application/octet-stream';
 
 
-        $f = static::create(array(
+        $f = new static(array(
             'type' => strtolower($file['type']),
             'name' => $file['name'],
             'key' => $file['key'],
@@ -445,7 +445,7 @@ class AttachmentFile extends VerySimpleModel {
     }
 
     static function __create($file, &$errors) {
-        return static::createFile($file);
+        return static::create($file);
     }
 
     /**
diff --git a/include/class.filter.php b/include/class.filter.php
index 9a31e510fa37b52a435ce193d34dd1c6da078fad..20bac5ce53b856d13d439a0afedd8e8abe1ab97a 100644
--- a/include/class.filter.php
+++ b/include/class.filter.php
@@ -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,
diff --git a/include/class.forms.php b/include/class.forms.php
index 02e918575cede1efb9cc4d334d450a1cbf4e4a8b..479d5f2ba8f2971f8b5d367afd8dc9b7662b337f 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -2651,7 +2651,7 @@ class FileUploadField extends FormField {
         if ($file['size'] > $config['size'])
             throw new FileUploadError(__('File size is too large'));
 
-        if (!$F = AttachmentFile::createFile($file))
+        if (!$F = AttachmentFile::create($file))
             throw new FileUploadError(__('Unable to save file'));
 
         return $F;
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 427ecbbe9ecf1bc97e5711574cd4899774a9f350..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(
diff --git a/include/class.mailfetch.php b/include/class.mailfetch.php
index 9410c95d09dd2bae0c7bc779321d757c3fc0a475..325300f7b6e09e310324e6002d2f72844b75552e 100644
--- a/include/class.mailfetch.php
+++ b/include/class.mailfetch.php
@@ -792,7 +792,7 @@ class MailFetcher {
             // NOTE: This might not be a "ticket"
             $ticket = $thread->getObject();
         }
-        elseif (($ticket=Ticket::create2($vars, $errors, 'Email'))) {
+        elseif (($ticket=Ticket::create($vars, $errors, 'Email'))) {
             $message = $ticket->getLastMessage();
         }
         else {
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 3c381d1217f77961aa6dd2d1f4951137b414177c..cbb73ee296c201a5be10a329f55e6a63e3f17c31 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,24 @@ class ModelMeta implements ArrayAccess {
     static $model_cache;
 
     var $model;
+    var $meta = array();
+    var $new;
+    var $subclasses = array();
 
     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;
         }
 
         if (!$meta['view']) {
@@ -85,13 +92,30 @@ class ModelMeta implements ArrayAccess {
                 $meta['foreign_keys'][$j['local']] = $field;
         }
         unset($j);
-        $this->base = $meta;
+        $this->meta = $meta;
     }
 
-    function extend($meta) {
-        if ($meta instanceof self)
-            $meta = $meta->base;
-        return $meta + $this->base + self::$base;
+    function extend(ModelMeta $child, $meta) {
+        $this->subclasses[$child->model] = $child;
+        return $meta + $this->meta + 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,20 +183,20 @@ 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]))
+        if (!isset($this->meta[$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');
@@ -181,20 +205,33 @@ class ModelMeta implements ArrayAccess {
     function setupLazy($what) {
         switch ($what) {
         case 'fields':
-            $this->base['fields'] = self::inspectFields();
+            $this->meta['fields'] = self::inspectFields();
             break;
-        case 'newInstance':
-            $class_repr = sprintf(
+        default:
+            throw new Exception($what . ': No such meta-data');
+        }
+    }
+
+    /**
+     * 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.
+     */
+    function newInstance($props=false) {
+        if (!isset($this->new)) {
+            $this->new = 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');
         }
+        // TODO: Compare timing between unserialize() and
+        //       ReflectionClass::newInstanceWithoutConstructor
+        $instance = unserialize($this->new);
+        // Hydrate if props were included
+        if (is_array($props)) {
+            $instance->ht = $props;
+        }
+        return $instance;
     }
 
     function inspectFields() {
@@ -232,8 +269,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) {
@@ -354,7 +395,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 +417,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 +450,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;
     }
@@ -587,17 +630,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)
@@ -1480,19 +1512,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);
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.role.php b/include/class.role.php
index 005bc0ff580ef074823274c4c81323aaa669098d..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;
     }
diff --git a/include/class.search.php b/include/class.search.php
index 69d21401c2546eb1b43f2ae6d2826671b0369ccb..25617b27bf401995c9bd14c5afda2ba2d36e346f 100644
--- a/include/class.search.php
+++ b/include/class.search.php
@@ -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;
     }
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.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 b511f633a18b138cfbc8f9d1dd7d499162a0d902..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;
     }
@@ -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);
diff --git a/include/class.task.php b/include/class.task.php
index 1aecea0236fc3744fb4c492a72e86010196a9bf0..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'],
diff --git a/include/class.team.php b/include/class.team.php
index 1e772d16d7ea38315fa04bc461a55cfb2b8ff375..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;
     }
diff --git a/include/class.thread.php b/include/class.thread.php
index 0bb394aab18fe497ad920b981e976af49ef9cc4f..f0a92c78b108fad7e70e9e71dd9a4c3e1ed102b9 100644
--- a/include/class.thread.php
+++ b/include/class.thread.php
@@ -534,10 +534,7 @@ class Thread extends VerySimpleModel {
     }
 
     static function create($vars=false) {
-        // $vars is expected to be an array
-        assert(is_array($vars));
-
-        $inst = parent::create($vars);
+        $inst = new static($vars);
         $inst->created = SqlFunction::NOW();
         return $inst;
     }
@@ -964,14 +961,14 @@ implements TemplateVariable {
             $fileId = $file;
         elseif ($file instanceof AttachmentFile)
             $fileId = $file->getId();
-        elseif ($F = AttachmentFile::createFile($file))
+        elseif ($F = AttachmentFile::create($file))
             $fileId = $F->getId();
         elseif (is_array($file) && isset($file['id']))
             $fileId = $file['id'];
         else
             return false;
 
-        $att = Attachment::create(array(
+        $att = new Attachment(array(
             'type' => 'H',
             'object_id' => $this->getId(),
             'file_id' => $fileId,
@@ -1067,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,
         ));
@@ -1359,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'],
@@ -1703,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;
@@ -1721,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(),
@@ -2586,7 +2583,6 @@ implements TemplateVariable {
 
 // Ticket thread class
 class TicketThread extends ObjectThread {
-
     static function create($ticket=false) {
         assert($ticket !== false);
 
diff --git a/include/class.ticket.php b/include/class.ticket.php
index 6008a6eaaf8d4171116e33facc6f32431b7ba5ce..9d32abcdecaea4b559f069f53f92329fcf3dd741 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -3001,7 +3001,7 @@ implements RestrictedAccess, Threadable {
      *
      *  $autorespond and $alertstaff overrides config settings...
      */
-    static function create2($vars, &$errors, $origin, $autorespond=true,
+    static function create($vars, &$errors, $origin, $autorespond=true,
             $alertstaff=true) {
         global $ost, $cfg, $thisclient, $thisstaff;
 
@@ -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::create2($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 731ea0e1c55acbc5844a064867b9c2ece1743088..63e72558daad50fb50157916112b20e075c67e84 100644
--- a/include/class.topic.php
+++ b/include/class.topic.php
@@ -278,7 +278,7 @@ implements TemplateVariable {
     /*** Static functions ***/
 
     static function create($vars=array()) {
-        $topic = parent::create($vars);
+        $topic = new static($vars);
         $topic->created = SqlFunction::NOW();
         return $topic;
     }
@@ -506,14 +506,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 77786de45afc1b361f1e95aa4060bc74330fdd3a..711fe1d0cd66fc656623e3fc2d9066f800598948 100644
--- a/include/class.translation.php
+++ b/include/class.translation.php
@@ -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 37df892c32f326f05cc7a53aa35b42945381710c..87fb63c89be95b0cab01f8beb838a111e1b06841 100644
--- a/include/class.upgrader.php
+++ b/include/class.upgrader.php
@@ -87,7 +87,7 @@ class Upgrader {
 
         //Create a ticket to make the system warm and happy.
         $errors = array();
-        Ticket::create2($vars, $errors, 'api', false, false);
+        Ticket::create($vars, $errors, 'api', false, false);
     }
 
     function getMode() {
diff --git a/include/class.user.php b/include/class.user.php
index 4d106e27ca6a247149f0580f17ba6094b3020573..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;
@@ -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/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/include/upgrader/streams/core/934954de-f1ccd3bb.task.php b/include/upgrader/streams/core/934954de-f1ccd3bb.task.php
index 74a4006fd5f9df168fa7ac1fee6e913e3dadc9b5..041bfad9a33730283e1203d6711bbafcaa27a548 100644
--- a/include/upgrader/streams/core/934954de-f1ccd3bb.task.php
+++ b/include/upgrader/streams/core/934954de-f1ccd3bb.task.php
@@ -7,7 +7,7 @@ class FileImport extends MigrationTask {
         $i18n = new Internationalization('en_US');
         $files = $i18n->getTemplate('file.yaml')->getData();
         foreach ($files as $f) {
-            if (!($file = AttachmentFile::createFile($f)))
+            if (!($file = AttachmentFile::create($f)))
                 continue;
 
             // Ensure the new files are never deleted (attached to Disk)
diff --git a/open.php b/open.php
index 8359edbf3cf8777883b4fa3117d5133753c02224..a081c29c9bb47c4417432a1567e65d5d50fd8fd9 100644
--- a/open.php
+++ b/open.php
@@ -39,7 +39,7 @@ if ($_POST) {
     // submitted will be displayed back to the user
     Draft::deleteForNamespace('ticket.client.'.substr(session_id(), -12));
     //Ticket::create...checks for errors..
-    if(($ticket=Ticket::create2($vars, $errors, SOURCE))){
+    if(($ticket=Ticket::create($vars, $errors, SOURCE))){
         $msg=__('Support ticket request created');
         // Drop session-backed form data
         unset($_SESSION[':form-data']);
diff --git a/setup/inc/class.installer.php b/setup/inc/class.installer.php
index 4142f778534987f2a155295b55290cb4bb2625e8..85441fedd2566d87dd384814d472695a2d98bdb1 100644
--- a/setup/inc/class.installer.php
+++ b/setup/inc/class.installer.php
@@ -288,7 +288,7 @@ class Installer extends SetupWizard {
         $errors = array();
         $ticket_vars = $i18n->getTemplate('templates/ticket/installed.yaml')
             ->getData();
-        $ticket = Ticket::create2($ticket_vars, $errors, 'api', false, false);
+        $ticket = Ticket::create($ticket_vars, $errors, 'api', false, false);
 
         if ($ticket
             && ($org = Organization::objects()->order_by('id')->one())