diff --git a/bootstrap.php b/bootstrap.php
index 03007ba9b7f9f9e6db4d97afecc6a13560188833..41cd7cf4f5d700772919a697182d4eb50f882f1f 100644
--- a/bootstrap.php
+++ b/bootstrap.php
@@ -179,6 +179,7 @@ class Bootstrap {
 
     function loadCode() {
         #include required files
+        require_once INCLUDE_DIR.'class.util.php';
         require(INCLUDE_DIR.'class.signal.php');
         require(INCLUDE_DIR.'class.user.php');
         require(INCLUDE_DIR.'class.auth.php');
diff --git a/include/class.dynamic_forms.php b/include/class.dynamic_forms.php
index eaa20067974cf9afbce123e9296356b100cc2e42..8637598c23f3b05d3be1450a337a036ed9b1a772 100644
--- a/include/class.dynamic_forms.php
+++ b/include/class.dynamic_forms.php
@@ -53,11 +53,11 @@ class DynamicForm extends VerySimpleModel {
             $fields = &$this->_fields;
 
         if (!$fields) {
-            $fields = new ArrayObject();
+            $fields = new ListObject();
             foreach ($this->getDynamicFields() as $f)
-                // TODO: Index by field name or id
-                $fields[$f->get('id')] = $f->getImpl($f);
+                $fields->append($f->getImpl($f));
         }
+
         return $fields;
     }
 
diff --git a/include/class.user.php b/include/class.user.php
index c7c668caf98f5c4b1533b8bdcdc4293d91535d9d..3c4be441eda3ed7c7f6eaa900f8bf33b07040954 100644
--- a/include/class.user.php
+++ b/include/class.user.php
@@ -1089,45 +1089,12 @@ class UserAccountStatus {
 /*
  *  Generic user list.
  */
-class UserList implements  IteratorAggregate, ArrayAccess {
-    private $users;
-
-    function __construct($list = array()) {
-        $this->users = $list;
-    }
-
-    function add($user) {
-        $this->offsetSet(null, $user);
-    }
-
-    function offsetSet($offset, $value) {
-
-        if (is_null($offset))
-            $this->users[] = $value;
-        else
-            $this->users[$offset] = $value;
-    }
-
-    function offsetExists($offset) {
-        return isset($this->users[$offset]);
-    }
-
-    function offsetUnset($offset) {
-        unset($this->users[$offset]);
-    }
-
-    function offsetGet($offset) {
-        return isset($this->users[$offset]) ? $this->users[$offset] : null;
-    }
-
-    function getIterator() {
-        return new ArrayIterator($this->users);
-    }
+class UserList extends ListObject {
 
     function __toString() {
 
         $list = array();
-        foreach($this->users as $user) {
+        foreach($this->storage as $user) {
             if (is_object($user))
                 $list [] = $user->getName();
         }
@@ -1135,6 +1102,7 @@ class UserList implements  IteratorAggregate, ArrayAccess {
         return $list ? implode(', ', $list) : '';
     }
 }
+
 require_once(INCLUDE_DIR . 'class.organization.php');
 User::_inspect();
 UserAccount::_inspect();
diff --git a/include/class.util.php b/include/class.util.php
new file mode 100644
index 0000000000000000000000000000000000000000..8fb9b3967a4ec5cb4e6d2117c58ece03baa1b0fd
--- /dev/null
+++ b/include/class.util.php
@@ -0,0 +1,169 @@
+<?php
+/**
+ * Jared Hancock <jared@osticket.com>
+ * Copyright (c)  2014
+ *
+ * Lightweight implementation of the Python list in PHP. This allows for
+ * treating an array like a simple list of items. The numeric indexes are
+ * automatically updated so that the indeces of the list will alway be from
+ * zero and increasing positively.
+ *
+ * Negative indexes are supported which reference from the end of the list.
+ * Therefore $queue[-1] will refer to the last item in the list.
+ */
+class ListObject implements IteratorAggregate, ArrayAccess, Serializable, Countable {
+
+    protected $storage = array();
+
+    function __construct(array $array=array()) {
+        foreach ($array as $v)
+            $this->storage[] = $v;
+    }
+
+    function append($what) {
+        if (is_array($what))
+            return $this->extend($what);
+
+        $this->storage[] = $what;
+    }
+
+    function add($what) {
+        $this->append($what);
+    }
+
+    function extend($iterable) {
+        foreach ($iterable as $v)
+            $this->storage[] = $v;
+    }
+
+    function insert($i, $value) {
+        array_splice($this->storage, $i, 0, array($value));
+    }
+
+    function remove($value) {
+        if (!($k = $this->index($value)))
+            throw new OutOfRangeException('No such item in the list');
+        unset($this->storage[$k]);
+    }
+
+    function pop($at=false) {
+        if ($at === false)
+            return array_pop($this->storage);
+        elseif (!isset($this->storage[$at]))
+            throw new OutOfRangeException('Index out of range');
+        else {
+            $rv = array_splice($this->storage, $at, 1);
+            return $rv[0];
+        }
+    }
+
+    function slice($offset, $length=null) {
+        return array_slice($this->storage, $offset, $length);
+    }
+
+    function splice($offset, $length=0, $replacement=null) {
+        return array_splice($this->storage, $offset, $length, $replacement);
+    }
+
+    function index($value) {
+        return array_search($this->storage, $value);
+    }
+
+    /**
+     * Sort the list in place.
+     *
+     * Parameters:
+     * $key - (callable|int) A callable function to produce the sort keys
+     *      or one of the SORT_ constants used by the array_multisort
+     *      function
+     * $reverse - (bool) true if the list should be sorted descending
+     */
+    function sort($key=false, $reverse=false) {
+        if (is_callable($key)) {
+            $keys = array_map($key, $this->storage);
+            array_multisort($keys, $this->storage,
+                $reverse ? SORT_DESC : SORT_ASC);
+        }
+        elseif ($key) {
+            array_multisort($this->storage,
+                $reverse ? SORT_DESC : SORT_ASC, $key);
+        }
+        elseif ($reverse) {
+            rsort($this->storage);
+        }
+        else
+            sort($this->storage);
+    }
+
+    function reverse() {
+        return array_reverse($this->storage);
+    }
+
+    function filter($callable) {
+        $new = new static();
+        foreach ($this->storage as $i=>$v)
+            if ($callable($v, $i))
+                $new[] = $v;
+        return $new;
+    }
+
+    // IteratorAggregate
+    function getIterator() {
+        return new ArrayIterator($this->storage);
+    }
+
+    // Countable
+    function count($mode=COUNT_NORMAL) {
+        return count($this->storage, $mode);
+    }
+
+    // ArrayAccess
+    function offsetGet($offset) {
+        if (!is_int($offset))
+            throw new InvalidArgumentException('List indices should be integers');
+        elseif ($offset < 0)
+            $offset += count($this->storage);
+        if (!isset($this->storage[$offset]))
+            throw new OutOfBoundsException('List index out of range');
+        return $this->storage[$offset];
+    }
+    function offsetSet($offset, $value) {
+        if ($offset === null)
+            return $this->storage[] = $value;
+        elseif (!is_int($offset))
+            throw new InvalidArgumentException('List indices should be integers');
+        elseif ($offset < 0)
+            $offset += count($this->storage);
+
+        if (!isset($this->storage[$offset]))
+            throw new OutOfBoundsException('List assignment out of range');
+
+        $this->storage[$offset] = $value;
+    }
+    function offsetExists($offset) {
+        if (!is_int($offset))
+            throw new InvalidArgumentException('List indices should be integers');
+        elseif ($offset < 0)
+            $offset += count($this->storage);
+        return isset($this->storage[$offset]);
+    }
+    function offsetUnset($offset) {
+        if (!is_int($offset))
+            throw new InvalidArgumentException('List indices should be integers');
+        elseif ($offset < 0)
+            $offset += count($this->storage);
+        unset($this->storage[$offset]);
+    }
+
+    // Serializable
+    function serialize() {
+        return serialize($this->storage);
+    }
+    function unserialize($what) {
+        $this->storage = unserialize($what);
+    }
+
+    function __toString() {
+        return '['.implode(', ', $this->storage).']';
+    }
+}