From 3dfe1a7f4f44e93b0d93fe47fca4b682975b854c Mon Sep 17 00:00:00 2001
From: Tim Steiner <tsteiner2@unl.edu>
Date: Thu, 29 Mar 2007 15:28:02 +0000
Subject: [PATCH] Massively massive update.  Updates for NMC Framework r35,
 Voting approval, etc

---
 .../ApprovalbodyadminController.php           |  16 +-
 .../ApprovalbodymanagerController.php         |  63 ++++-
 .../ApprovalchainmanagerController.php        | 218 ++++++++++++++++--
 application/controllers/AuthController.php    |  37 ++-
 .../controllers/ConflictController.php        |  10 +-
 .../controllers/CourseadminController.php     |  15 +-
 application/controllers/HomeController.php    |  36 ++-
 .../controllers/NewrequestController.php      |  38 ++-
 application/controllers/TestController.php    |  11 +-
 .../controllers/TestformController.php        |  16 +-
 .../controllers/UseradminController.php       |  20 +-
 .../library/ApprovalAction/AutoApprove.php    |   8 -
 .../library/ApprovalAction/Interface.php      |  21 --
 .../library/ApprovalActionRow/Interface.php   |  52 +++++
 .../library/ApprovalActionTable/Interface.php |  33 +++
 application/models/rows/ApprovalAction.php    |   6 +-
 .../models/rows/ApprovalActionAuto.php        |  29 ++-
 .../models/rows/ApprovalActionDelegate.php    |  71 ++++++
 .../rows/ApprovalActionSingleApprover.php     |  45 ++++
 .../models/rows/ApprovalActionVote.php        |  81 +++++++
 .../models/rows/ApprovalActionsVoteVote.php   |  35 +++
 application/models/rows/ApprovalBody.php      |   2 +-
 application/models/rows/ApprovalChain.php     |  97 +++++++-
 application/models/rows/ApprovalLink.php      |   5 +-
 application/models/rows/CourseCode.php        |  19 +-
 .../models/rows/CourseCrosslisting.php        |   4 +-
 application/models/rows/CourseGeneration.php  |   9 +-
 .../models/rows/DefaultApprovalChain.php      |  21 ++
 application/models/rows/Group.php             |  10 +-
 application/models/rows/Request.php           |  91 +++++++-
 application/models/rows/RequestStack.php      |   9 +
 application/models/rows/RequestType.php       |   2 +-
 application/models/tables/ActivityTypes.php   |   7 +-
 application/models/tables/ApprovalActions.php |  24 +-
 .../models/tables/ApprovalActionsAbstract.php |  16 +-
 .../models/tables/ApprovalActionsAuto.php     |  29 ++-
 .../models/tables/ApprovalActionsDelegate.php |  68 ++++++
 .../tables/ApprovalActionsSingleApprover.php  |  64 +++++
 .../models/tables/ApprovalActionsVote.php     |  83 +++++++
 .../tables/ApprovalActionsVoteVotes.php       |  45 ++++
 application/models/tables/ApprovalBodies.php  |  13 +-
 .../models/tables/ApprovalBodyRoles.php       |   8 +-
 application/models/tables/ApprovalChains.php  |  16 +-
 application/models/tables/ApprovalLinks.php   |   9 +-
 application/models/tables/Assets.php          |   6 +-
 application/models/tables/Auth.php            |  29 ++-
 application/models/tables/Colleges.php        |   8 +-
 .../models/tables/CourseActivities.php        |  20 +-
 application/models/tables/CourseCodes.php     |  13 +-
 application/models/tables/CourseCredits.php   |  12 +-
 .../models/tables/CourseCrosslistings.php     |  45 ++--
 application/models/tables/CourseDetails.php   |  11 +-
 .../models/tables/CourseDfRemovals.php        |  13 +-
 .../models/tables/CourseEsDesignations.php    |   9 +-
 .../models/tables/CourseGenerations.php       |  71 +++---
 .../models/tables/CourseGradTieIns.php        |  11 +-
 .../models/tables/CoursePrerequisites.php     |  13 +-
 application/models/tables/Courses.php         |  13 +-
 .../models/tables/DefaultApprovalChains.php   |  57 +++++
 application/models/tables/Departments.php     |   7 +-
 application/models/tables/Files.php           |  12 +-
 .../models/tables/GroupImpliedMemberships.php |  17 +-
 .../models/tables/GroupMemberships.php        |   7 +-
 application/models/tables/Groups.php          |  13 +-
 application/models/tables/People.php          |  21 +-
 application/models/tables/RequestFiles.php    |  11 +-
 application/models/tables/RequestStacks.php   |   9 +-
 application/models/tables/RequestStates.php   |   6 +-
 application/models/tables/RequestTypes.php    |  18 +-
 application/models/tables/Requests.php        |  57 +++--
 application/models/tables/Users.php           |   9 +-
 .../approval_actions/ApprovalActionAuto.xhtml |  16 +-
 application/views/approval_body_manager.xhtml |  59 +++--
 .../views/approval_chain_manager.xhtml        | 140 +++++++++--
 application/views/home.xhtml                  | 135 +++++++++++
 application/views/my_home.xhtml               | 111 ---------
 document_root/css/approval_body_manager.css   |   1 +
 document_root/css/approval_chain_manager.css  |  13 +-
 document_root/css/home.css                    |   0
 document_root/css/manager.css                 |  11 +
 document_root/index.php                       |  35 ++-
 document_root/javascript/Base.js              | 106 +++++++++
 .../javascript/approval_chain_manager.js      |  77 +++++--
 document_root/javascript/home.js              |  20 ++
 document_root/javascript/index.js             | 161 ++++++++++++-
 85 files changed, 2256 insertions(+), 659 deletions(-)
 delete mode 100644 application/library/ApprovalAction/AutoApprove.php
 delete mode 100644 application/library/ApprovalAction/Interface.php
 create mode 100644 application/library/ApprovalActionRow/Interface.php
 create mode 100644 application/library/ApprovalActionTable/Interface.php
 create mode 100644 application/models/rows/ApprovalActionDelegate.php
 create mode 100644 application/models/rows/ApprovalActionSingleApprover.php
 create mode 100644 application/models/rows/ApprovalActionVote.php
 create mode 100644 application/models/rows/ApprovalActionsVoteVote.php
 create mode 100644 application/models/rows/DefaultApprovalChain.php
 create mode 100644 application/models/tables/ApprovalActionsDelegate.php
 create mode 100644 application/models/tables/ApprovalActionsSingleApprover.php
 create mode 100644 application/models/tables/ApprovalActionsVote.php
 create mode 100644 application/models/tables/ApprovalActionsVoteVotes.php
 create mode 100644 application/models/tables/DefaultApprovalChains.php
 create mode 100755 application/views/home.xhtml
 delete mode 100644 application/views/my_home.xhtml
 create mode 100644 document_root/css/approval_body_manager.css
 create mode 100755 document_root/css/home.css
 create mode 100644 document_root/css/manager.css
 create mode 100644 document_root/javascript/Base.js
 create mode 100644 document_root/javascript/home.js

diff --git a/application/controllers/ApprovalbodyadminController.php b/application/controllers/ApprovalbodyadminController.php
index 51d9a071..889f6063 100644
--- a/application/controllers/ApprovalbodyadminController.php
+++ b/application/controllers/ApprovalbodyadminController.php
@@ -2,6 +2,12 @@
 
 class ApprovalBodyAdminController extends Nmc_Controller_Action
 {
+
+    public function init()
+    {
+        $this->_registerPlugin(new Nmc_Controller_Action_Plugin_Authorize());
+    }
+
     public function indexAction()
     {
         $out = new Nmc_View();
@@ -15,7 +21,7 @@ class ApprovalBodyAdminController extends Nmc_Controller_Action
     public function editBodyAction()
     {
         $in = $this->getRequest();
-        $approvalBodyId = Zend_Filter::getInt($in->getParam(0));
+        $approvalBodyId = Zend_Filter_Int::filter($in->getParam(0));
 
         $out = new Nmc_View();
         $out->page = 'approval_body_admin';
@@ -30,7 +36,7 @@ class ApprovalBodyAdminController extends Nmc_Controller_Action
     public function editRoleAction()
     {
         $in = $this->getRequest();
-        $roleId = Zend_Filter::getInt($in->getParam(0));
+        $roleId = Zend_Filter_Int::filter($in->getParam(0));
 
         $out = new Nmc_View();
         $out->page = 'approval_body_admin';
@@ -45,7 +51,7 @@ class ApprovalBodyAdminController extends Nmc_Controller_Action
     public function addRoleAction()
     {
         $in = $this->getRequest();
-        $approvalBodyId = Zend_Filter::getInt($in->getParam(0));
+        $approvalBodyId = Zend_Filter_Int::filter($in->getParam(0));
         $parentApprovalBody = ApprovalBodies::getInstance()->find($approvalBodyId);
 
         $out = new Nmc_View();
@@ -62,7 +68,7 @@ class ApprovalBodyAdminController extends Nmc_Controller_Action
     public function editBodyPostAction()
     {
         $in = $this->getRequest();
-        $bodyId = Zend_Filter::getInt($in->getParam(0));
+        $bodyId = Zend_Filter_Int::filter($in->getParam(0));
         $body = ApprovalBodies::getInstance()->find($bodyId);
 
         if(!$body) {
@@ -82,7 +88,7 @@ class ApprovalBodyAdminController extends Nmc_Controller_Action
     public function editRolePostAction()
     {
         $in = $this->getRequest();
-        $roleId = Zend_Filter::getInt($in->getParam(0));
+        $roleId = Zend_Filter_Int::filter($in->getParam(0));
         if($roleId < 0) {
             $role = ApprovalBodyRoles::getInstance()->fetchNew();
             $role->approvalBody = abs($roleId);
diff --git a/application/controllers/ApprovalbodymanagerController.php b/application/controllers/ApprovalbodymanagerController.php
index 74cf1ae4..8493f984 100644
--- a/application/controllers/ApprovalbodymanagerController.php
+++ b/application/controllers/ApprovalbodymanagerController.php
@@ -2,6 +2,12 @@
 
 class ApprovalBodyManagerController extends Nmc_Controller_Action
 {
+
+    public function init()
+    {
+        $this->_registerPlugin(new Nmc_Controller_Action_Plugin_Authorize());
+    }
+
     public function indexAction()
     {
         return $this->listAction();
@@ -20,15 +26,68 @@ class ApprovalBodyManagerController extends Nmc_Controller_Action
     public function editBodyAction()
     {
         $in = $this->getRequest();
-        $approvalBodyId = Zend_Filter::getInt($in->getParam(0));
+        $approvalBodyId = Zend_Filter_Int::filter($in->getParam(0));
 
         $usersBodies = ApprovalBodies::getInstance()->fetchApprovalBodiesUserCanAdminister(Nmc_User::getInstance()->getUser());
-        $currentBody = ApprovalBodies::getInstance()->find($approvalBodyId);
+        $currentBody = ApprovalBodies::getInstance()->findOne($approvalBodyId);
+        $approvalChains = ApprovalChains::getInstance()->fetchWithApprovalBody($currentBody);
+        $requestTypes = RequestTypes::getInstance()->fetchAll();
+
+        $defaultChains = array();
+        foreach ($requestTypes as $requestType) {
+            $requestTypeId = $requestType->getPrimaryKey();
+            $defaultChain = DefaultApprovalChains::getInstance()->fetchWithBodyAndType($currentBody, $requestType);
+            $defaultChains[$requestTypeId] = $defaultChain;
+        }
 
         $out = new Nmc_View();
         $out->page = 'approval_body_manager';
         $out->usersBodies = $usersBodies;
         $out->currentBody = $currentBody;
+        $out->approvalChains = $approvalChains;
+        $out->defaultChains = $defaultChains;
+        $out->requestTypes = $requestTypes;
+        echo $out->render('index.xhtml');
+    }
+
+    public function editBodyPostAction()
+    {
+        $in = $this->getRequest();
+        $postData = $in->getPost();
+
+        $currentBodyId = $postData['bodyId'];
+        $currentBodyId = Zend_Filter_Int::filter($currentBodyId);
+        if ($currentBodyId > 0) {
+            $currentBody = ApprovalBodies::getInstance()->findOne($currentBodyId);
+        }
+
+        if (!$currentBody) {
+            throw new Exception('Invalid Approval Body specified.');
+        }
+
+        foreach($postData['edit'] as $requestId => $chainData) {
+            $requestId = Zend_Filter_Int::filter($requestId);
+            if ($requestId > 0) {
+                $requestType = RequestTypes::getInstance()->findOne($requestId);
+            }
+
+            $chainId = $chainData['chain'];
+            $chainId = Zend_Filter_Int::filter($chainId);
+            if ($chainId > 0) {
+                $chain = ApprovalChains::getInstance()->findOne($chainId);
+            }
+
+            if (!$requestType || !$chain) {
+                throw new Exception('Invalid request type or chain specified.');
+            }
+
+            $defaultApprovalChain = DefaultApprovalChains::getInstance()->fetchWithBodyAndType($currentBody, $requestType);
+            $defaultApprovalChain->approvalChain = $chain;
+            $defaultApprovalChain->save();
+        }
+
+        $out = new Nmc_View();
+        $out->refresh = '/ApprovalBodyManager/EditBody/' . $currentBodyId;
         echo $out->render('index.xhtml');
     }
 }
\ No newline at end of file
diff --git a/application/controllers/ApprovalchainmanagerController.php b/application/controllers/ApprovalchainmanagerController.php
index 1121acc1..fbf2769c 100644
--- a/application/controllers/ApprovalchainmanagerController.php
+++ b/application/controllers/ApprovalchainmanagerController.php
@@ -2,6 +2,12 @@
 
 class ApprovalChainManagerController extends Nmc_Controller_Action
 {
+
+    public function init()
+    {
+        $this->_registerPlugin(new Nmc_Controller_Action_Plugin_Authorize());
+    }
+
     public function indexAction()
     {
         return $this->listAction();
@@ -20,38 +26,216 @@ class ApprovalChainManagerController extends Nmc_Controller_Action
     public function editChainAction()
     {
         $in = $this->getRequest();
-        $chainId = Zend_Filter::getInt($in->getParam(0));
-        $chain = ApprovalChains::getInstance()->find($chainId);
+        $chainId = Zend_Filter_Int::filter($in->getParam(0));
+        if($chainId == 'new') {
+            $chain = ApprovalChains::getInstance()->fetchNew();
+        } else {
+            $chain = ApprovalChains::getInstance()->findOne($chainId);
+        }
 
         $approvalChains = ApprovalChains::getInstance()->fetchAll();
 
         $approvalActions = ApprovalActions::getInstance()->getAvailableActions();
-        $approvalActionList = array();
+        $approvalActionList = array('-1' => '--Select Action--');
         foreach ($approvalActions as $approvalAction) {
-            $approvalActionList[get_class($approvalAction)] = $approvalAction->getActionName();
+            $approvalActionList[$approvalAction->getRowReturnType()] = $approvalAction->getActionName();
         }
 
+        $user = Nmc_User::getInstance()->getUser();
+        $approvalBodies = ApprovalBodies::getInstance()->fetchApprovalBodiesUserCanAdminister($user);
+
         $out = new Nmc_View();
         $out->page = 'approval_chain_manager';
         $out->chain = $chain;
         $out->approvalChains = $approvalChains;
         $out->approvalActions = $approvalActionList;
         $out->approvalChain = $chain;
+        $out->approvalBodies = $approvalBodies;
         echo $out->render('index.xhtml');
     }
 
+    public function editChainPostAction()
+    {
+        $in = $this->getRequest();
+        $postData = $in->getPost();
+        $chainId = $postData['chainId'];
+        $ownerId = Zend_Filter_Int::filter($postData['ownerBody']);
+
+        $chainId = Zend_Filter_Int::filter($chainId);
+        if ($chainId > 0) {
+            $chain = ApprovalChains::getInstance()->findOne($chainId);
+        } else {
+            $chain = ApprovalChains::getInstance()->fetchNew();
+        }
+
+        $ownerBody = ApprovalBodies::getInstance()->findOne($ownerId);
+
+        $chain->name = $postData['name'];
+        $chain->ownerBody = $ownerBody;
+        $chain->description = '';
+        $chain->save();
+
+        $chainId = $chain->getPrimaryKey();
+
+        $view = new Nmc_View();
+        $view->refresh = '/ApprovalChainManager/EditChain/' . $chainId;
+
+        $out = $this->getResponse();
+        $out->setBody($view->render('index.xhtml'));
+    }
+
     public function addLinkPostAction()
     {
-        /*
-        $in = $this->getRequest()->getPost();
-        $chainId = Zend_Filter::getInt($in['chainId']);
-        $chain = ApprovalChains::getInstance()->find($chainId);
+        $in = $this->getRequest();
+        $postData = $in->getPost();
+
+        $chainId = Zend_Filter_Int::filter($postData['chainId']);
+        if ($chainId > 0) {
+            $chain = ApprovalChains::getInstance()->findOne($chainId);
+        } else {
+            throw new Exception('Attempted to edit invalid chain.');
+        }
+
+        $currentActionId = Zend_Filter_Int::filter($postData['currentAction']);
+        if ($currentActionId > 0) {
+            $currentAction = ApprovalActionsAbstract::getInstance()->findOne($currentActionId);
+        } else {
+            $currentAction = null;
+        }
+
+        $nextActionId = Zend_Filter_Int::filter($postData['nextAction']);
+        if ($nextActionId) {
+            $nextAction = ApprovalActionsAbstract::getInstance()->findOne($nextActionId);
+        } else {
+            $nextAction = null;
+        }
 
         $newLink = ApprovalLinks::getInstance()->fetchNew();
-        $newLink->currentAction = $in['currentAction'];
-        $newLink->currentState = $in['currentState'];
-        $newLink->nextAction = $in['nextAction'];
-        */
+        $newLink->name = '';
+        $newLink->description = '';
+        $newLink->chain = $chain->getPrimaryKey();
+        $newLink->currentAction = $currentAction;
+        if ($postData['currentState'] != '_null') {
+            $newLink->currentState = $postData['currentState'];
+        }
+        $newLink->nextAction = $nextAction;
+        $newLink->save();
+
+        $out = new Nmc_View();
+        $out->refresh = '/ApprovalChainManager/EditChain/' . $chain->getPrimaryKey();
+        $this->getResponse()->setBody($out->render('index.xhtml'));
+    }
+
+    public function editLinksPostAction()
+    {
+        $in = $this->getRequest();
+        $postData = $in->getPost();
+
+        $chainId = Zend_Filter_Int::filter($postData['chainId']);
+        if ($chainId > 0) {
+            $chain = ApprovalChains::getInstance()->findOne($chainId);
+        } else {
+            throw new Exception('Attempted to edit invalid chain.');
+        }
+
+        foreach ($postData['edit'] as $currentChainId => $currentLinkData) {
+
+            $currentActionId = Zend_Filter_Int::filter($currentLinkData['currentAction']);
+            if ($currentActionId > 0) {
+                $currentAction = ApprovalActionsAbstract::getInstance()->findOne($currentActionId);
+            } else {
+                $currentAction = null;
+            }
+
+            $nextActionId = Zend_Filter_Int::filter($currentLinkData['nextAction']);
+            if ($nextActionId > 0) {
+                $nextAction = ApprovalActionsAbstract::getInstance()->findOne($nextActionId);
+            } else {
+                $nextAction = null;
+            }
+
+
+            $currentLink = ApprovalLinks::getInstance()->findOne($currentChainId);
+
+            if($currentLinkData['delete']) {
+                $currentLink->delete();
+                break;
+            }
+
+            $currentLink->chain = $chain->getPrimaryKey();
+            $currentLink->currentAction = $currentAction;
+            if ($currentLinkData['currentState'] != '_null') {
+                $currentLink->currentState = $currentLinkData['currentState'];
+            }
+            $currentLink->nextAction = $nextAction;
+            $currentLink->save();
+        }
+
+        $out = new Nmc_View();
+        $out->refresh = '/ApprovalChainManager/EditChain/' . $chain->getPrimaryKey();
+        $this->getResponse()->setBody($out->render('index.xhtml'));
+    }
+
+    public function addActionPostAction()
+    {
+        $in = $this->getRequest();
+        $actionRowClass = $in->getPost('type');
+        $actionTableClass = 'ApprovalActions'
+                    . substr($actionRowClass, strlen('ApprovalAction'));
+        $actionTable = call_user_func(array($actionTableClass, 'getInstance'));
+
+        $newAction = $actionTable->fetchNew($in->getPost());
+        $newAction->name = $in->getPost('name');
+        $newAction->approvalChain = $in->getPost('chainId');
+        $newAction->save();
+
+        $out = new Nmc_View();
+        $out->refresh = '/ApprovalChainManager/EditChain/' . $in->getPost('chainId');
+        echo $out->render('index.xhtml');
+    }
+
+    public function editActionPostAction()
+    {
+        $in = $this->getRequest();
+
+        foreach($in->getPost('edit') as $actionId => $actionData) {
+            $action = ApprovalActionsAbstract::getInstance()->findOne($actionId);
+            if($actionData['delete'] == '1') {
+                $action->delete();
+                continue;
+            }
+
+            $action->name = $actionData['name'];
+            $action->updateFromForm($actionData);
+            $action->save();
+        }
+
+        $out = new Nmc_View();
+        $out->refresh = '/ApprovalChainManager/EditChain/' . $in->getPost('chainId');
+        echo $out->render('index.xhtml');
+    }
+
+    public function getActionDetailXMLAction()
+    {
+        $in = $this->getRequest();
+        $actionId = Zend_Filter_Int::filter($in->getParam(0));
+        $actionRow = ApprovalActionsAbstract::getInstance()->findOne($actionId);
+        $actionTable = $actionRow->getTable();
+        $results = $actionTable->getResultStatusStrings();
+
+        $out = new DOMDocument();
+        $element = $out->createElement('action');
+        $element->setAttribute('id', $actionRow->getPrimaryKey());
+        $element->setAttribute('name', $actionRow->name);
+        $element->setAttribute('className', get_class($actionRow));
+        foreach ($results as $result) {
+            $resultElement = $out->createElement('result');
+            $resultElement->setAttribute('name', $result);
+            $element->appendChild($resultElement);
+        }
+        $out->appendChild($element);
+        $this->getResponse()->setHeader('Content-type', 'application/xml');
+        $this->getResponse()->setBody($out->saveXML());
     }
 
     public function getActionListAction()
@@ -79,10 +263,16 @@ class ApprovalChainManagerController extends Nmc_Controller_Action
     {
         $in = $this->getRequest();
         $actionName = $in->getParam(0);
-        $className = 'ApprovalActions' . $actionName;
+        $className = 'ApprovalActions' . substr($actionName, strlen('ApprovalAction'));
         $action = call_user_method('getInstance', $className);
         $template = $action->getEditTemplate();
+
         $out = new Nmc_View();
-        echo $out->render($template);
+        $xhtml = $out->render($template);
+        $dom = new DOMDocument();
+        $dom->loadHTML($xhtml);
+        $dom->childNodes->item(1)->setAttribute('xmlns', 'http://www.w3.org/1999/xhtml');
+        header('Content-type: application/xhtml+xml');
+        echo $dom->saveXML();
     }
 }
\ No newline at end of file
diff --git a/application/controllers/AuthController.php b/application/controllers/AuthController.php
index 61d125c2..6e45e746 100644
--- a/application/controllers/AuthController.php
+++ b/application/controllers/AuthController.php
@@ -20,22 +20,36 @@ class AuthController extends Nmc_Controller_Action
         $out->title = 'Processing...';
 
         try {
-            $auth = new Nmc_Auth_Multi();
+            $auth = Nmc_Auth::getInstance();
+            $userName = $in->getRaw('user_name');
+            $password = $in->getRaw('password');
+
             $ldap = new Nmc_Ldap('ldap://localhost:10389');
-            $authTable = new Auth();
-            //$auth->push(new Nmc_Auth_Always());
-            $auth->push(new Nmc_Auth_Ldap($ldap));
-            $auth->push(new Nmc_Auth_Mysql($authTable));
-            $auth->login($in->getRaw('user_name'), $in->getRaw('password'));
-            Nmc_Registry_Session::getInstance()->userName = $in->getRaw('user_name');
-
-            $user = People::findByUserName($in->getRaw('user_name'));
+            $ldapAuth = new Nmc_Auth_Adapter_Ldap($ldap, $userName, $password);
+            $auth->pushAdapter($ldapAuth);
+
+            $dbTable = Auth::getInstance();
+            $dbAuth = new Nmc_Auth_Adapter_ZendDb($dbTable, $userName, $password);
+            $auth->pushAdapter($dbAuth);
+
+            $alwaysAuth = new Nmc_Auth_Adapter_Always(true, $userName);
+            $auth->pushAdapter($alwaysAuth);
+
+            $authResult = $auth->authenticate();
+            if (!$authResult->isValid()) {
+                $message = "No valid logins:\n" . implode("\n", $authResult->getMessages());
+                throw new Exception($messages);
+            }
+
+            Nmc_Registry_Session::getInstance()->userName = $userName;
+
+            $user = People::findByUserName($userName);
             if(!$user) {
                 $user = People::getInstance()->fetchNew();
                 $filter = 'uid='
-                        . strtr($in->getRaw('user_name'),
+                        . strtr($userName,
                                 array(',' => '', '=' => '', ' ' => ''));
-                $ldap->bind('uid=tsteiner2,ou=people,dc=unl,dc=edu', $in->getRaw('password'));
+                $ldap->bind('uid=tsteiner2,ou=people,dc=unl,dc=edu', $password);
                 $userInfo = $ldap->search('ou=people,dc=unl,dc=edu', $filter);
 
                 $departmentIn = $userInfo[0]['unlhrprimarydepartment'][0];
@@ -76,6 +90,7 @@ class AuthController extends Nmc_Controller_Action
     public function logoutAction()
     {
         Nmc_User::getInstance()->logout();
+        Nmc_Auth::getInstance()->clearIdentity();
         $out = new Nmc_View();
         $out->assign('location', '/');
         echo $out->render('index.xhtml');
diff --git a/application/controllers/ConflictController.php b/application/controllers/ConflictController.php
index f0d3880a..2b53cd38 100644
--- a/application/controllers/ConflictController.php
+++ b/application/controllers/ConflictController.php
@@ -2,6 +2,12 @@
 
 class ConflictController extends Nmc_Controller_Action
 {
+
+    public function init()
+    {
+        $this->_registerPlugin(new Nmc_Controller_Action_Plugin_Authorize());
+    }
+
     public function __construct(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response, array $invokeArgs = array())
     {
         parent::__construct($request, $response, $invokeArgs);
@@ -65,11 +71,11 @@ EOF;
     {
         $in = $this->getRequest();
         $ids = array();
-        for($i = 0; Zend_Filter::isInt($in->getParam($i)); $i++) {
+        for($i = 0; Zend_Filter_Int::filter($in->getParam($i)) > 0; $i++) {
             $ids[] = $in->getParam($i);
         }
         foreach($ids as $id) {
-            $id = Zend_Filter::getInt($id);
+            $id = Zend_Filter_Int::filter($id);
             $generation = CourseGenerations::getInstance()->find($id);
             $generation->delete();
         }
diff --git a/application/controllers/CourseadminController.php b/application/controllers/CourseadminController.php
index 84e44f6f..2aea5fe8 100644
--- a/application/controllers/CourseadminController.php
+++ b/application/controllers/CourseadminController.php
@@ -2,9 +2,9 @@
 
 class CourseAdminController extends Nmc_Controller_Action
 {
-    public function __construct(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response, array $invokeArgs = array())
+
+    public function init()
     {
-        parent::__construct($request, $response, $invokeArgs);
         $this->_registerPlugin(new Nmc_Controller_Action_Plugin_Authorize());
     }
 
@@ -21,8 +21,9 @@ class CourseAdminController extends Nmc_Controller_Action
         $in = $this->getRequest();
 
         $out = new Nmc_View_Unl();
-        if(Zend_Filter::isInt($in->getParam(0))) {
-            $course = CourseGenerations::getInstance()->find($in->getParam(0));
+        $courseId = Zend_Filter_Int::filter($in->getParam(0));
+        if($courseId > 0) {
+            $course = CourseGenerations::getInstance()->find($courseId);
             $crosslisting = $course->crosslistings[0];
         } else {
             $crosslisting = CourseCrosslistings::fetchBySubjectNumberLetter($in->getParam(0), $in->getParam(1), $in->getParam(2));
@@ -112,7 +113,7 @@ class CourseAdminController extends Nmc_Controller_Action
                 foreach($val as $type => $hours) {
                     if($type == 1) {
                         foreach(explode(' ', $hours) as $singeValue) {
-                            if(Zend_Filter::getDigits($hours) != '') {
+                            if(Zend_Filter_Digits::filter($hours) != '') {
                                 $newAttribute = CourseCredits::getInstance()->fetchNew();
                                 $newAttribute->type = $type;
                                 $newAttribute->hours = $singeValue;
@@ -121,7 +122,7 @@ class CourseAdminController extends Nmc_Controller_Action
                         }
                         continue;
                     }
-                    if(Zend_Filter::getDigits($hours) != '') {
+                    if(Zend_Filter_Digits::filter($hours) != '') {
                         $newAttribute = CourseCredits::getInstance()->fetchNew();
                         $newAttribute->type = $type;
                         $newAttribute->hours = $hours;
@@ -177,7 +178,7 @@ class CourseAdminController extends Nmc_Controller_Action
     public function deleteCourseAction()
     {
         $in = $this->getRequest();
-        $courseId = Zend_Filter::getInt($in->getParam(0));
+        $courseId = Zend_Filter_Int::filter($in->getParam(0));
 
         if($courseId > 0) {
             $course = CourseGenerations::getInstance()->find($courseId);
diff --git a/application/controllers/HomeController.php b/application/controllers/HomeController.php
index 688a68ed..6244bd94 100644
--- a/application/controllers/HomeController.php
+++ b/application/controllers/HomeController.php
@@ -3,16 +3,15 @@
 class HomeController extends Nmc_Controller_Action
 {
 
-    public function __construct(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response, array $invokeArgs = array())
+    public function init()
     {
-        parent::__construct($request, $response, $invokeArgs);
         $this->_registerPlugin(new Nmc_Controller_Action_Plugin_Authorize());
     }
 
     public function indexAction()
     {
         $user = Nmc_User::getInstance()->getUser();
-        $requests = Requests::getInstance()->getRequestsForUser($user);
+        $requests = Requests::getInstance()->getRequestsForUser($user, Requests::COMPLETED_REQUESTS_BOTH);
 
         $roles = ApprovalBodyRoles::getInstance()->fetchRolesForUser($user);
 
@@ -20,9 +19,38 @@ class HomeController extends Nmc_Controller_Action
         $out = new Nmc_View();
         $out->roles = $roles;
         $out->myRequests = $requests;
-        $out->page = 'my_home';
+        $out->page = 'home';
 
         echo $out->render('index.xhtml');
     }
 
+    public function submitDecisionsAction()
+    {
+        $in = $this->getRequest();
+        $postData = $in->getPost();
+
+        foreach ($postData['decisions'] as $requestId => $decision) {
+            if ($decision == '_null') {
+                continue;
+            }
+
+            $requestId = Zend_Filter_Int::filter($requestId);
+            if ($requestId < 1) {
+                continue;
+            }
+
+            $request = Requests::getInstance()->findOne($requestId);
+            if (!$request) {
+                continue;
+            }
+
+            $action = $request->getCurrentAction();
+            if (!$action) {
+                continue;
+            }
+
+            $action->userMadeDecision($request, Nmc_User::getInstance()->getUser(), $decision);
+        }
+    }
+
 }
\ No newline at end of file
diff --git a/application/controllers/NewrequestController.php b/application/controllers/NewrequestController.php
index db9ac4f5..574e9dc3 100644
--- a/application/controllers/NewrequestController.php
+++ b/application/controllers/NewrequestController.php
@@ -3,17 +3,11 @@
 class NewRequestController extends Nmc_Controller_Action
 {
 
-    public function __construct(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response, array $invokeArgs = array())
+    public function init()
     {
-        parent::__construct($request, $response, $invokeArgs);
         $this->_registerPlugin(new Nmc_Controller_Action_Plugin_Authorize());
     }
 
-    public function __destruct()
-    {
-
-    }
-
     public function indexAction()
     {
         return $this->SearchAction();
@@ -36,9 +30,9 @@ class NewRequestController extends Nmc_Controller_Action
     {
         $in = $this->_getAllParams();
 
-        $subject = Zend_Filter::getAlpha($in[0]);
-        $courseNumber = Zend_Filter::getDigits($in[1]);
-        $courseLetter = Zend_Filter::getAlpha($in[2]);
+        $subject = Zend_Filter_Alpha::filter($in[0]);
+        $courseNumber = Zend_Filter_Digits::filter($in[1]);
+        $courseLetter = Zend_Filter_Alpha::filter($in[2]);
 
         $course = CourseCrosslistings::fetchBySubjectNumberLetter($subject,
                                                                   $courseNumber,
@@ -70,10 +64,10 @@ class NewRequestController extends Nmc_Controller_Action
     {
         $in = $this->_getAllParams();
 
-        $type = Zend_Filter::getAlnum($in[0]);
-        $subject = Zend_Filter::getAlpha($in[1]);
-        $courseNumber = Zend_Filter::getDigits($in[2]);
-        $courseLetter = Zend_Filter::getAlpha($in[3]);
+        $type = Zend_Filter_Alnum::filter($in[0]);
+        $subject = Zend_Filter_Alpha::filter($in[1]);
+        $courseNumber = Zend_Filter_Digits::filter($in[2]);
+        $courseLetter = Zend_Filter_Alpha::filter($in[3]);
 
         $request = Requests::getInstance()->fetchNew();
         $request->owner = Nmc_User::getInstance()->getUser();
@@ -104,8 +98,8 @@ class NewRequestController extends Nmc_Controller_Action
     {
         $in = $this->_getAllParams();
 
-        $requestId = Zend_Filter::getInt($in[0]);
-        $request = Requests::getInstance()->find($requestId);
+        $requestId = Zend_Filter_Int::filter($in[0]);
+        $request = Requests::getInstance()->findOne($requestId);
         $course = $request->getCourseGeneration();
 
         $course = clone $course;
@@ -127,7 +121,7 @@ class NewRequestController extends Nmc_Controller_Action
 
 
 
-        $submit = Zend_Filter::getAlpha($_POST['submit']);
+        $submit = Zend_Filter_Alpha::filter($_POST['submit']);
 
         if(is_array($_POST['request'])) {
         foreach($_POST['request'] as $key => $val) {
@@ -170,7 +164,7 @@ class NewRequestController extends Nmc_Controller_Action
                 foreach($val as $type => $hours) {
                     if($type == 1) {
                         foreach(explode(' ', $hours) as $singeValue) {
-                            if(Zend_Filter::getDigits($hours) != '') {
+                            if(Zend_Filter_Digits::filter($hours) != '') {
                                 $newAttribute = CourseCredits::getInstance()->fetchNew();
                                 $newAttribute->type = $type;
                                 $newAttribute->hours = $singeValue;
@@ -179,7 +173,7 @@ class NewRequestController extends Nmc_Controller_Action
                         }
                         continue;
                     }
-                    if(Zend_Filter::getDigits($hours) != '') {
+                    if(Zend_Filter_Digits::filter($hours) != '') {
                         $newAttribute = CourseCredits::getInstance()->fetchNew();
                         $newAttribute->type = $type;
                         $newAttribute->hours = $hours;
@@ -249,7 +243,7 @@ class NewRequestController extends Nmc_Controller_Action
                 foreach($val as $type => $hours) {
                     if($type == 1) {
                         foreach(explode(' ', $hours) as $singeValue) {
-                            if(Zend_Filter::getDigits($hours) != '') {
+                            if(Zend_Filter_Digits::filter($hours) != '') {
                                 $newAttribute = CourseCredits::getInstance()->fetchNew();
                                 $newAttribute->type = $type;
                                 $newAttribute->hours = $singeValue;
@@ -258,7 +252,7 @@ class NewRequestController extends Nmc_Controller_Action
                         }
                         continue;
                     }
-                    if(Zend_Filter::getDigits($hours) != '') {
+                    if(Zend_Filter_Digits::filter($hours) != '') {
                         $newAttribute = CourseCredits::getInstance()->fetchNew();
                         $newAttribute->type = $type;
                         $newAttribute->hours = $hours;
@@ -580,6 +574,8 @@ class NewRequestController extends Nmc_Controller_Action
             $course->save();
             $request->save();
 
+            $request->consider();
+
             Nmc_Registry_Session::getInstance()->erase('course');
             Nmc_Registry_Session::getInstance()->erase('request');
 
diff --git a/application/controllers/TestController.php b/application/controllers/TestController.php
index 2197b245..5fe616aa 100644
--- a/application/controllers/TestController.php
+++ b/application/controllers/TestController.php
@@ -11,14 +11,9 @@ class TestController extends Nmc_Controller_Action
 
     public function indexAction()
     {
-        $a = ApprovalChains::getInstance()->find(1);
-
-        foreach ($a->approvalActions as $b) {}
-
-        $a->save();
-
-        header('Content-type: text/plain');
-        print_r($a);
+        $user2 = People::getInstance()->findOne(1);
+        $user = Nmc_User::getInstance()->getUser();
+        Nmc_User::getInstance()->login($user2);
     }
 }
 
diff --git a/application/controllers/TestformController.php b/application/controllers/TestformController.php
index 66b7281e..fa0dec5c 100644
--- a/application/controllers/TestformController.php
+++ b/application/controllers/TestformController.php
@@ -40,7 +40,7 @@ class TestFormController extends Nmc_Controller_Action
     public function viewAction()
     {
         $in = $this->getRequest();
-        $id = Zend_Filter::getInt($in->getParam(0));
+        $id = Zend_Filter_Int::filter($in->getParam(0));
         $table = new TestAddressBook();
         $record = $table->find($id);
 
@@ -60,7 +60,7 @@ class TestFormController extends Nmc_Controller_Action
     public function editAction()
     {
         $in = $this->getRequest();
-        $id = Zend_Filter::getInt($in->getParam(0));
+        $id = Zend_Filter_Int::filter($in->getParam(0));
         $table = new TestAddressBook();
         $record = $table->find($id);
 
@@ -73,7 +73,7 @@ class TestFormController extends Nmc_Controller_Action
     public function saveAction()
     {
         $in = $this->getRequest();
-        $id = Zend_Filter::getInt($in->getPost('id'));
+        $id = Zend_Filter_Int::filter($in->getPost('id'));
 
         $table = new TestAddressBook();
         if($id < 0) {
@@ -82,11 +82,11 @@ class TestFormController extends Nmc_Controller_Action
             $record = $table->find($id);
         }
 
-        $record->firstName = Zend_Filter::getAlnum($in->getPost('firstName'));
-        $record->lastName = Zend_Filter::getAlnum($in->getPost('lastName'));
-        $record->phone = Zend_Filter::getAlnum($in->getPost('phone'));
-        $record->address = Zend_Filter::getAlnum($in->getPost('address'));
-        $record->zip = Zend_Filter::getAlnum($in->getPost('zip'));
+        $record->firstName = Zend_Filter_Alnum::filter($in->getPost('firstName'));
+        $record->lastName = Zend_Filter_Alnum::filter($in->getPost('lastName'));
+        $record->phone = Zend_Filter_Alnum::filter($in->getPost('phone'));
+        $record->address = Zend_Filter_Alnum::filter($in->getPost('address'));
+        $record->zip = Zend_Filter_Alnum::filter($in->getPost('zip'));
         $record->save();
 
         if($id < 0) {
diff --git a/application/controllers/UseradminController.php b/application/controllers/UseradminController.php
index 2fbf70be..f2b0d3c4 100644
--- a/application/controllers/UseradminController.php
+++ b/application/controllers/UseradminController.php
@@ -2,6 +2,12 @@
 
 class UserAdminController extends Nmc_Controller_Action
 {
+
+    public function init()
+    {
+        $this->_registerPlugin(new Nmc_Controller_Action_Plugin_Authorize());
+    }
+
     public function indexAction()
     {
         $out = new Nmc_View();
@@ -17,7 +23,7 @@ class UserAdminController extends Nmc_Controller_Action
     public function editUserAction()
     {
         $in = $this->getRequest();
-        $userId = Zend_Filter::getInt($in->getParam(0));
+        $userId = Zend_Filter_Int::filter($in->getParam(0));
 
         if($in->getPost('Submit') == 'Submit') {
             return $this->editUserActionPost();
@@ -41,18 +47,18 @@ class UserAdminController extends Nmc_Controller_Action
     protected function editUserActionPost()
     {
         $in = $this->getRequest();
-        $userId = Zend_Filter::getInt($in->getParam(0));
+        $userId = Zend_Filter_Int::filter($in->getParam(0));
         if(!$userId) {
             $user = People::getInstance()->fetchNew();
         } else {
-            $user = People::getInstance()->find($userId);
+            $user = People::getInstance()->findOne($userId);
         }
 
         if($in->getPost('delete') == '1') {
             $user->delete();
         } else {
-            $user->firstName = Zend_Filter::getAlnum($in->getPost('firstName'));
-            $user->lastName = Zend_Filter::getAlnum($in->getPost('lastName'));
+            $user->firstName = Zend_Filter_Alnum::filter($in->getPost('firstName'));
+            $user->lastName = Zend_Filter_Alnum::filter($in->getPost('lastName'));
             $user->save();
         }
 
@@ -80,7 +86,7 @@ class UserAdminController extends Nmc_Controller_Action
     public function editGroupAction()
     {
         $in = $this->getRequest();
-        $groupId = Zend_Filter::getInt($in->getParam(0));
+        $groupId = Zend_Filter_Int::filter($in->getParam(0));
 
         if($in->getPost('Submit') == 'Submit') {
             return $this->editGroupActionPost();
@@ -106,7 +112,7 @@ class UserAdminController extends Nmc_Controller_Action
     protected function editGroupActionPost()
     {
         $in = $this->getRequest();
-        $groupId = Zend_Filter::getInt($in->getParam(0));
+        $groupId = Zend_Filter_Int::filter($in->getParam(0));
         if(!$groupId) {
             $group = Groups::getInstance()->fetchNew();
             $group->type = 1;
diff --git a/application/library/ApprovalAction/AutoApprove.php b/application/library/ApprovalAction/AutoApprove.php
deleted file mode 100644
index 4a0502b2..00000000
--- a/application/library/ApprovalAction/AutoApprove.php
+++ /dev/null
@@ -1,8 +0,0 @@
-<?php
-
-require_once 'ApprovalAction/Interface.php';
-
-class Application_ApprovalAction_AutoApprove implements Application_ApprovalAction_Interface
-{
-
-}
\ No newline at end of file
diff --git a/application/library/ApprovalAction/Interface.php b/application/library/ApprovalAction/Interface.php
deleted file mode 100644
index 6eab2037..00000000
--- a/application/library/ApprovalAction/Interface.php
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-
-interface Application_ApprovalAction_Interface
-{
-    /**
-     * Reutrns an array of strings, corresponding to the possible
-     * results of performing this action.
-     *
-     * @return array
-     */
-    public function getResultStatusStrings();
-
-    /**
-     * Initiates the action, causing it to begin processing the given request.
-     * When consideration finishes, the parent chain will be called again.
-     *
-     * @param Request $request
-     * @param ApprovalChain $parentChain
-     */
-    public function consider(Request $request, ApprovalChain $parentChain);
-}
diff --git a/application/library/ApprovalActionRow/Interface.php b/application/library/ApprovalActionRow/Interface.php
new file mode 100644
index 00000000..c081dd16
--- /dev/null
+++ b/application/library/ApprovalActionRow/Interface.php
@@ -0,0 +1,52 @@
+<?php
+
+interface Application_ApprovalActionRow_Interface
+{
+    /**
+     * Reutrns an array of strings, corresponding to the possible
+     * results of performing this action.  If a customized action can only
+     * result a subset of the possible results, return that subset.
+     *
+     * @return array
+     */
+    public function getResultStatusStrings();
+
+    /**
+     * Initiates the action, causing it to begin processing the given request.
+     * When consideration finishes, the parent chain will be called again.
+     *
+     * @param Request $request
+     * @param ApprovalChain $parentChain
+     */
+    public function consider(Request $request, ApprovalChain $parentChain);
+
+    /**
+     * Updates the current action object with the provided raw form data.
+     *
+     * @param Array $formData
+     */
+    public function updateFromForm($formData);
+
+    /**
+     * Let the action know that a user has made a decsion so that the approval
+     * process may continue.
+     *
+     * @param Request $request
+     * @param User $user
+     * @param string $decision
+     */
+    public function userMadeDecision(Request $request, User $user, $decision);
+
+    /**
+     * Returns the decision the user made on this request.
+     * Used when a request is not advanced by a single user, and the pending
+     * decision needs to be seen.
+     * May return null if no decision has been made, or if the user's action
+     * always advances the request.
+     *
+     * @param Request $request
+     * @param User $user
+     * @return string
+     */
+    public function getUserDecision(Request $request, User $user);
+}
diff --git a/application/library/ApprovalActionTable/Interface.php b/application/library/ApprovalActionTable/Interface.php
new file mode 100644
index 00000000..5d694325
--- /dev/null
+++ b/application/library/ApprovalActionTable/Interface.php
@@ -0,0 +1,33 @@
+<?php
+
+interface Application_ApprovalActionTable_Interface
+{
+    /**
+     * Returns the human friendly name of the given action.
+     *
+     * @return String
+     */
+    public function getActionName();
+
+    /**
+     * Returns an array of all possible outcomes from this action
+     *
+     * @return Array
+     */
+    public function getResultStatusStrings();
+
+    /**
+     * Returns the XHTML template used to edit the action's specific details
+     *
+     * @return String
+     */
+    public function getEditTemplate();
+
+    /**
+     * Instantiates a new action row object using the provided form data
+     *
+     * @param Array $formData
+     * @return Application_ApprovalActionRow_Interface
+     */
+    public function fetchNew($formData = null);
+}
\ No newline at end of file
diff --git a/application/models/rows/ApprovalAction.php b/application/models/rows/ApprovalAction.php
index 3c086a6e..80e84084 100644
--- a/application/models/rows/ApprovalAction.php
+++ b/application/models/rows/ApprovalAction.php
@@ -13,10 +13,6 @@ class ApprovalAction extends Nmc_Db_Table_Row
 
     public function getPrimaryKeyName($camelized = false)
     {
-        if ($camelized) {
-            return 'approvalActionId';
-        } else {
-            return 'approval_action_id';
-        }
+        return ApprovalActions::getInstance()->getPrimaryKeyName();
     }
 }
\ No newline at end of file
diff --git a/application/models/rows/ApprovalActionAuto.php b/application/models/rows/ApprovalActionAuto.php
index 3fb02063..e54f5563 100644
--- a/application/models/rows/ApprovalActionAuto.php
+++ b/application/models/rows/ApprovalActionAuto.php
@@ -1,6 +1,6 @@
 <?php
 
-require_once 'ApprovalAction/Interface.php';
+require_once 'ApprovalActionRow/Interface.php';
 
 /**
  * @foreignKey approvalActionId
@@ -8,7 +8,7 @@ require_once 'ApprovalAction/Interface.php';
  *
  */
 class ApprovalActionAuto extends ApprovalAction
-                         implements Application_ApprovalAction_Interface
+                         implements Application_ApprovalActionRow_Interface
 {
 
     public function getResultStatusStrings()
@@ -18,6 +18,29 @@ class ApprovalActionAuto extends ApprovalAction
 
     public function consider(Request $request, ApprovalChain $parentChain)
     {
-        //
+        $parentChain->advance($request, $this->result);
+    }
+
+    public function updateFromForm($formData)
+    {
+        $this->result = $formData['result'];
+    }
+
+    /**
+     * Let the action know that a user has made a decsion so that the approval
+     * process may continue.
+     *
+     * @param Request $request
+     * @param User $user
+     * @param string $decision
+     */
+    public function userMadeDecision(Request $request, User $user, $decision)
+    {
+        // since this is an automatic action, nothing needs to happen here.
+    }
+
+    public function getUserDecision(Request $request, User $user)
+    {
+        return null;
     }
 }
\ No newline at end of file
diff --git a/application/models/rows/ApprovalActionDelegate.php b/application/models/rows/ApprovalActionDelegate.php
new file mode 100644
index 00000000..952b2e85
--- /dev/null
+++ b/application/models/rows/ApprovalActionDelegate.php
@@ -0,0 +1,71 @@
+<?php
+
+require_once 'ApprovalActionRow/Interface.php';
+
+/**
+ * @foreignKey approvalActionId
+ * @tableClass ApprovalActionsDelegate
+ *
+ */
+class ApprovalActionDelegate extends ApprovalAction
+                             implements Application_ApprovalActionRow_Interface
+{
+
+    public function _init()
+    {
+        $delegateBodyRelation = new Nmc_Db_Table_Relation_HasOne(
+            ApprovalBodies::getInstance(),
+            $this,
+            'delegateBody',
+            'delegateBody',
+            true
+        );
+        $this->_registerRelation($delegateBodyRelation);
+    }
+
+    public function getResultStatusStrings()
+    {
+        return $this->getTable()->getResultStatusStrings();
+    }
+
+    public function consider(Request $request, ApprovalChain $parentChain)
+    {
+        // move the request to the delegate chain, then have it consider the request
+        $delegateBody = $this->delegateBody;
+        $delegateChainMap = DefaultApprovalChains::getInstance()->fetchWithBodyAndType($delegateBody, $request->type);
+        $delegateChain = $delegateChainMap->approvalChain;
+
+
+        $nextStack = RequestStacks::getInstance()->fetchNew();
+        $nextStack->previous = $request->stackPointer;
+        $nextStack->chain = $delegateChain;
+        $nextStack->save();
+
+        $request->stackPointer = $nextStack;
+        $request->save();
+    }
+
+    public function updateFromForm($formData)
+    {
+        $delegateBody = ApprovalBodies::getInstance()->findOne($formData['delegateBody']);
+        $this->delegateBody = $delegateBody;
+    }
+
+    /**
+     * Let the action know that a user has made a decsion so that the approval
+     * process may continue.
+     *
+     * @param Request $request
+     * @param User $user
+     * @param string $decision
+     */
+    public function userMadeDecision(Request $request, User $user, $decision)
+    {
+        // since this is an automatic action, nothing needs to happen here.
+    }
+
+    public function getUserDecision(Request $request, User $user)
+    {
+        return null;
+    }
+}
diff --git a/application/models/rows/ApprovalActionSingleApprover.php b/application/models/rows/ApprovalActionSingleApprover.php
new file mode 100644
index 00000000..99f87cef
--- /dev/null
+++ b/application/models/rows/ApprovalActionSingleApprover.php
@@ -0,0 +1,45 @@
+<?php
+
+require_once 'ApprovalActionRow/Interface.php';
+
+/**
+ * @foreignKey approvalActionId
+ * @tableClass ApprovalActionsSingleApprover
+ *
+ */
+class ApprovalActionSingleApprover extends ApprovalAction
+                                   implements Application_ApprovalActionRow_Interface
+{
+    public function getResultStatusStrings()
+    {
+        return $this->getTable()->getResultStatusStrings();
+    }
+
+    public function consider(Request $request, ApprovalChain $parentChain)
+    {
+        //$parentChain->advance($request, $this->result);
+    }
+
+    public function updateFromForm($formData)
+    {
+        //$this->result = $formData['result'];
+    }
+
+    /**
+     * Let the action know that a user has made a decsion so that the approval
+     * process may continue.
+     *
+     * @param Request $request
+     * @param User $user
+     * @param string $decision
+     */
+    public function userMadeDecision(Request $request, User $user, $decision)
+    {
+        $request->stackPointer->chain->advance($request, $decision);
+    }
+
+    public function getUserDecision(Request $request, User $user)
+    {
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/application/models/rows/ApprovalActionVote.php b/application/models/rows/ApprovalActionVote.php
new file mode 100644
index 00000000..b982c705
--- /dev/null
+++ b/application/models/rows/ApprovalActionVote.php
@@ -0,0 +1,81 @@
+<?php
+
+require_once 'ApprovalActionRow/Interface.php';
+
+/**
+ * @foreignKey approvalActionId
+ * @tableClass ApprovalActionsVote
+ *
+ */
+class ApprovalActionVote extends ApprovalAction
+                         implements Application_ApprovalActionRow_Interface
+{
+    /**
+     * Reutrns an array of strings, corresponding to the possible
+     * results of performing this action.  If a customized action can only
+     * result a subset of the possible results, return that subset.
+     *
+     * @return array
+     */
+    public function getResultStatusStrings()
+    {
+        return array('Approve' => 'Approve',
+                     'Deny'    => 'Deny',
+                     'Table'   => 'Table');
+    }
+
+    /**
+     * Initiates the action, causing it to begin processing the given request.
+     * When consideration finishes, the parent chain will be called again.
+     *
+     * @param Request $request
+     * @param ApprovalChain $parentChain
+     */
+    public function consider(Request $request, ApprovalChain $parentChain)
+    {
+        //
+    }
+
+    /**
+     * Updates the current action object with the provided raw form data.
+     *
+     * @param Array $formData
+     */
+    public function updateFromForm($formData)
+    {
+        //
+    }
+
+    /**
+     * Let the action know that a user has made a decsion so that the approval
+     * process may continue.
+     *
+     * @param Request $request
+     * @param User $user
+     * @param string $decision
+     */
+    public function userMadeDecision(Request $request, User $user, $decision)
+    {
+        $vote = ApprovalActionsVoteVotes::getInstance()->fetchByRequestUserAndAction($request, $user, $this);
+        if ($vote) {
+            $vote->vote = $decision;
+        } else {
+            $vote = ApprovalActionsVoteVotes::getInstance()->fetchNew();
+            $vote->vote = $decision;
+            $vote->request = $request;
+            $vote->user = $user;
+            $vote->approvalAction = $this;
+        }
+        $vote->save();
+    }
+
+    public function getUserDecision(Request $request, User $user)
+    {
+        $vote = ApprovalActionsVoteVotes::getInstance()->fetchByRequestUserAndAction($request, $user, $this);
+        if ($vote) {
+            return $vote->vote;
+        } else {
+            return null;
+        }
+    }
+}
\ No newline at end of file
diff --git a/application/models/rows/ApprovalActionsVoteVote.php b/application/models/rows/ApprovalActionsVoteVote.php
new file mode 100644
index 00000000..97f37cb8
--- /dev/null
+++ b/application/models/rows/ApprovalActionsVoteVote.php
@@ -0,0 +1,35 @@
+<?php
+
+class ApprovalActionsVoteVote extends Nmc_Db_Table_Row
+{
+
+    public function _init()
+    {
+        $userRelation = new Nmc_Db_Table_Relation_HasOne(
+            Users::getInstance(),
+            $this,
+            'user',
+            'user',
+            true
+        );
+        $this->_registerRelation($userRelation);
+
+        $voteActionRelation = new Nmc_Db_Table_Relation_HasOne(
+            ApprovalActionsAbstract::getInstance(),
+            $this,
+            'approvalAction',
+            'approvalAction',
+            true
+        );
+        $this->_registerRelation($voteActionRelation);
+
+        $requestRelation = new Nmc_Db_Table_Relation_HasOne(
+            Requests::getInstance(),
+            $this,
+            'request',
+            'request',
+            true
+        );
+        $this->_registerRelation($requestRelation);
+    }
+}
\ No newline at end of file
diff --git a/application/models/rows/ApprovalBody.php b/application/models/rows/ApprovalBody.php
index 59bcd410..8bea78ad 100644
--- a/application/models/rows/ApprovalBody.php
+++ b/application/models/rows/ApprovalBody.php
@@ -8,7 +8,7 @@ class ApprovalBody extends Nmc_Db_Table_Row
             new Nmc_Db_Table_Relation_HasMany(
                 ApprovalBodyRoles::getInstance(),
                 $this,
-                'approval_body',
+                'approvalBody',
                 'roles'
             )
         );
diff --git a/application/models/rows/ApprovalChain.php b/application/models/rows/ApprovalChain.php
index 2dbd20c1..54a0f342 100644
--- a/application/models/rows/ApprovalChain.php
+++ b/application/models/rows/ApprovalChain.php
@@ -8,8 +8,12 @@ class ApprovalChain extends Nmc_Db_Table_Row
         $linksRelation = new Nmc_Db_Table_Relation_HasMany(ApprovalLinks::getInstance(), $this, 'chain', 'approvalLinks');
         $this->_registerRelation($linksRelation);
 
-        $actionsRelation = new Nmc_Db_Table_Relation_HasMany(ApprovalActionsAbstract::getInstance(), $this, 'approval_chain', 'approvalActions');
+        $actionsRelation = new Nmc_Db_Table_Relation_HasMany(ApprovalActionsAbstract::getInstance(), $this, 'approvalChain', 'approvalActions');
         $this->_registerRelation($actionsRelation);
+
+        $ownerBodyRelation = new Nmc_Db_Table_Relation_HasOne(ApprovalBodies::getInstance(), $this, 'ownerBody', 'ownerBody', true);
+        $this->_registerRelation($ownerBodyRelation);
+
     }
 
     protected function _preSave()
@@ -30,14 +34,101 @@ class ApprovalChain extends Nmc_Db_Table_Row
         parent::_postSave();
     }
 
+    /**
+     * Advances the request through the chain as far as possible, if at all
+     *
+     * @param Request $request
+     */
+    public function consider(Request $request)
+    {
+        $currentAction = $this->getCurrentAction($request);
+
+        $foobar = $request->stackPointer->action;
+
+        if (!$currentAction instanceof ApprovalAction) {
+            $this->_exitChain($request);
+        } else {
+            $currentAction->consider($request, $this);
+        }
+
+    }
+
+    public function getCurrentAction(Request $request)
+    {
+        $previousAction = $request->stackPointer->action;
+        if (!$previousAction instanceof ApprovalAction) {
+            $currentAction = $this->_getFirstAction($request);
+        } else {
+            $currentAction = $this->_getNextAction($request);
+        }
+        return $currentAction;
+    }
+
+    protected function _getFirstAction(Request $request)
+    {
+        $db = $this->getTable()->getAdapter();
+        $where = array();
+        $where[] = $db->quoteInto('chain=?', $this->getPrimaryKey());
+        $where[] = 'currentAction IS NULL';
+        $where = implode(' AND ', $where);
+
+        $firstLink = ApprovalLinks::getInstance()->fetchRow($where);
+        $firstAction = $firstLink->nextAction;
+        return $firstAction;
+    }
+
+    protected function _getNextAction(Request $request)
+    {
+        $db = $this->getTable()->getAdapter();
+        $where = array();
+        $where[] = $db->quoteInto('chain=?', $this->getPrimaryKey());
+        $where[] = $db->quoteInto('currentAction=?', $request->stackPointer->action->getPrimaryKey());
+        $where[] = $db->quoteInto('currentState=?', $request->state);
+        $where = implode(' AND ', $where);
+
+        $nextLink = ApprovalLinks::getInstance()->fetchRow($where);
+        $nextAction = $nextLink->nextAction;
+        return $nextAction;
+    }
+
+    protected function _exitChain(Request $request)
+    {
+        //echo "Exiting Chain";
+        $request->stackPointer = $request->stackPointer->previous;
+        $request->save();
+
+        if (!$request->stackPointer) {
+            //request finished, finalize it!
+            $request->complete = 'yes';
+            $request->save();
+            return;
+        }
+
+        $request->stackPointer->chain->advance($request);
+    }
+
     /**
      * This function is called by ApprovalActions when a decision has been reached.
      * When called, the next ApprovalAction in the chain will be called
+     * Optionally, the new state of the request may be specified.
      *
      * @param Request $request
+     * @param String[optional] $newState
      */
-    public function advance(Request $request)
+    public function advance(Request $request, $newState = null)
     {
-        //
+        if ($newState) {
+            $request->state = $newState;
+        }
+
+        $request->stackPointer->action = $this->getCurrentAction($request);
+        $request->save();
+
+        if($request->stackPointer->action) {
+            $this->consider($request);
+        } else {
+            $this->_exitChain($request);
+        }
     }
+
 }
diff --git a/application/models/rows/ApprovalLink.php b/application/models/rows/ApprovalLink.php
index f37a68d3..efc70259 100644
--- a/application/models/rows/ApprovalLink.php
+++ b/application/models/rows/ApprovalLink.php
@@ -4,10 +4,11 @@ class ApprovalLink extends Nmc_Db_Table_Row {
 
     protected function _init()
     {
-        $currentActionRelation = new Nmc_Db_Table_Relation_HasOne(ApprovalActionsAbstract::getInstance(), $this, 'current_action', 'currentAction', true);
+        $currentActionRelation = new Nmc_Db_Table_Relation_HasOne(ApprovalActionsAbstract::getInstance(), $this, 'currentAction', 'currentAction', true);
         $currentActionRelation->setOverrideLocal(true);
         $this->_registerRelation($currentActionRelation);
-        $nextActionRelation = new Nmc_Db_Table_Relation_HasOne(ApprovalActionsAbstract::getInstance(), $this, 'next_action', 'nextAction', true);
+        $nextActionRelation = new Nmc_Db_Table_Relation_HasOne(ApprovalActionsAbstract::getInstance(), $this, 'nextAction', 'nextAction', true);
+        $nextActionRelation->setOverrideLocal(true);
         $this->_registerRelation($nextActionRelation);
     }
 
diff --git a/application/models/rows/CourseCode.php b/application/models/rows/CourseCode.php
index 03fc6bd2..472d341a 100644
--- a/application/models/rows/CourseCode.php
+++ b/application/models/rows/CourseCode.php
@@ -11,12 +11,12 @@ class CourseCode extends Nmc_Db_Table_Row
     {
         $db = $this->_table->getAdapter();
 
-        $order = 'subject, course_number, course_letter';
+        $order = array('subject', 'courseNumber', 'courseLetter');
 
         $where = array();
         $where[] = $db->quoteInto('subject = ?', $this->subject);
-        $where[] = $db->quoteInto('course_number = ?', $this->courseNumber);
-        $where[] = $db->quoteInto('course_letter > ?', $this->courseLetter);
+        $where[] = $db->quoteInto('courseNumber = ?', $this->courseNumber);
+        $where[] = $db->quoteInto('courseLetter > ?', $this->courseLetter);
         $where = implode(' AND ', $where);
 
         $row = $this->_table->fetchRow($where, $order);
@@ -26,7 +26,7 @@ class CourseCode extends Nmc_Db_Table_Row
 
         $where = array();
         $where[] = $db->quoteInto('subject = ?', $this->subject);
-        $where[] = $db->quoteInto('course_number > ?', $this->courseNumber);
+        $where[] = $db->quoteInto('courseNumber > ?', $this->courseNumber);
         $where = implode(' AND ', $where);
 
         $row = $this->_table->fetchRow($where, $order);
@@ -56,12 +56,12 @@ class CourseCode extends Nmc_Db_Table_Row
     {
         $db = $this->_table->getAdapter();
 
-        $order = 'subject DESC, course_number DESC, course_letter DESC';
+        $order = array('subject DESC', 'courseNumber DESC', 'courseLetter DESC');
 
         $where = array();
         $where[] = $db->quoteInto('subject = ?', $this->subject);
-        $where[] = $db->quoteInto('course_number = ?', $this->courseNumber);
-        $where[] = $db->quoteInto('course_letter < ?', $this->courseLetter);
+        $where[] = $db->quoteInto('courseNumber = ?', $this->courseNumber);
+        $where[] = $db->quoteInto('courseLetter < ?', $this->courseLetter);
         $where = implode(' AND ', $where);
 
         $row = $this->_table->fetchRow($where, $order);
@@ -71,7 +71,7 @@ class CourseCode extends Nmc_Db_Table_Row
 
         $where = array();
         $where[] = $db->quoteInto('subject = ?', $this->subject);
-        $where[] = $db->quoteInto('course_number < ?', $this->courseNumber);
+        $where[] = $db->quoteInto('courseNumber < ?', $this->courseNumber);
         $where = implode(' AND ', $where);
 
         $row = $this->_table->fetchRow($where, $order);
@@ -107,7 +107,8 @@ class CourseCode extends Nmc_Db_Table_Row
         switch($name) {
             case 'courseNumber':
                 $courseNumber = parent::_get('courseNumber');
-                if(Zend_Filter::isInt($courseNumber) && $courseNumber > 0) {
+                $courseNumber = Zend_Filter_Int::filter($courseNumber);
+                if($courseNumber > 0) {
                     return str_pad($courseNumber, 3, '0', STR_PAD_LEFT);
                 } else {
                     return $courseNumber;
diff --git a/application/models/rows/CourseCrosslisting.php b/application/models/rows/CourseCrosslisting.php
index 74bbdd02..8aed3ddf 100644
--- a/application/models/rows/CourseCrosslisting.php
+++ b/application/models/rows/CourseCrosslisting.php
@@ -11,7 +11,7 @@ class CourseCrosslisting extends Nmc_Db_Table_Row
     protected function _init()
     {
         $primaryKeyName = CourseCodes::getInstance()->getPrimaryKeyName(true);
-        $courseCode = CourseCodes::getInstance()->find($this->courseCode);
+        $courseCode = CourseCodes::getInstance()->findOne($this->courseCode);
         if($courseCode->$primaryKeyName) {
             $this->_subject = $courseCode->subject;
             $this->_courseNumber = $courseCode->courseNumber;
@@ -64,7 +64,7 @@ class CourseCrosslisting extends Nmc_Db_Table_Row
 
     public function getParentCourse()
     {
-        $parentCourse = CourseGenerations::getInstance()->find($this->generation);
+        $parentCourse = CourseGenerations::getInstance()->findOne($this->generation);
         return $parentCourse;
     }
 
diff --git a/application/models/rows/CourseGeneration.php b/application/models/rows/CourseGeneration.php
index f408ad2d..674fdb19 100644
--- a/application/models/rows/CourseGeneration.php
+++ b/application/models/rows/CourseGeneration.php
@@ -77,9 +77,10 @@ class CourseGeneration extends Asset
 
     protected function _save()
     {
+        $db = $this->getTable()->getAdapter();
         $parentTransaction = false;
         try {
-            $this->_db->beginTransaction();
+            $db->beginTransaction();
             $parentTransaction = true;
         } catch (PDOException $e) {
             if($e->getMessage() != 'There is already an active transaction') {
@@ -114,11 +115,11 @@ class CourseGeneration extends Asset
             parent::_save();
 
             if($parentTransaction) {
-                $this->_db->commit();
+                $db->commit();
             }
         } catch(Exception $e) {
             if($parentTransaction) {
-                $this->_db->rollBack();
+                $db->rollBack();
             }
 
             $this->course = $saveCourse;
@@ -142,7 +143,7 @@ class CourseGeneration extends Asset
             return null;
         }
 
-        $parentGeneration = CourseGenerations::getInstance()->find($this->parent);
+        $parentGeneration = CourseGenerations::getInstance()->findOne($this->parent);
         return $parentGeneration;
     }
 
diff --git a/application/models/rows/DefaultApprovalChain.php b/application/models/rows/DefaultApprovalChain.php
new file mode 100644
index 00000000..f2b63234
--- /dev/null
+++ b/application/models/rows/DefaultApprovalChain.php
@@ -0,0 +1,21 @@
+<?php
+
+
+/**
+ * @tableClass DefaultApprovalChains
+ *
+ */
+class DefaultApprovalChain extends Nmc_Db_Table_Row
+{
+    public function _init()
+    {
+        $approvalChainRelation = new Nmc_Db_Table_Relation_HasOne(
+            ApprovalChains::getInstance(),
+            $this,
+            'approvalChain',
+            'approvalChain',
+            true
+        );
+        $this->_registerRelation($approvalChainRelation);
+    }
+}
\ No newline at end of file
diff --git a/application/models/rows/Group.php b/application/models/rows/Group.php
index 6bd0f865..1963d398 100644
--- a/application/models/rows/Group.php
+++ b/application/models/rows/Group.php
@@ -20,13 +20,13 @@ class Group extends Nmc_Db_Table_Row
 
     public function addUser($user)
     {
-        $childGroup = Groups::getInstance()->find($user->primaryGroup);
+        $childGroup = Groups::getInstance()->findOne($user->primaryGroup);
         $this->addGroup($childGroup);
     }
 
     public function removeUser($user)
     {
-        $childGroup = Groups::getInstance()->find($user->primaryGroup);
+        $childGroup = Groups::getInstance()->findOne($user->primaryGroup);
         $this->removeGroup($childGroup);
     }
 
@@ -41,9 +41,11 @@ class Group extends Nmc_Db_Table_Row
 
     public function removeGroup(Group $group)
     {
+        $db = $this->getTable()->getAdapter();
+
         $where = array();
-        $where[] = $this->_db->quoteInto('parent_group = ?', $this->getPrimaryKey());
-        $where[] = $this->_db->quoteInto('child_group = ?', $group->getPrimaryKey());
+        $where[] = $db->quoteInto('parentGroup = ?', $this->getPrimaryKey());
+        $where[] = $db->quoteInto('childGroup = ?', $group->getPrimaryKey());
         $where = implode(' AND ', $where);
         $membership = GroupMemberships::getInstance()->fetchRow($where);
         $membership->delete();
diff --git a/application/models/rows/Request.php b/application/models/rows/Request.php
index bd599be1..9b24c71f 100644
--- a/application/models/rows/Request.php
+++ b/application/models/rows/Request.php
@@ -10,12 +10,9 @@ class Request extends Nmc_Db_Table_Row
         $ownerRelation = new Nmc_Db_Table_Relation_HasOne(Users::getInstance(), $this, 'owner', 'owner', true);
         $this->_registerRelation($ownerRelation);
 
-        $stackRelation = new Nmc_Db_Table_Relation_HasOne(RequestStacks::getInstance(), $this, 'stack_pointer', 'stackPointer', true);
+        $stackRelation = new Nmc_Db_Table_Relation_HasOne(RequestStacks::getInstance(), $this, 'stackPointer', 'stackPointer', true);
         $this->_registerRelation($stackRelation);
 
-        $stateRelation = new Nmc_Db_Table_Relation_HasOne(RequestStates::getInstance(), $this, 'state', 'state', true);
-        $this->_registerRelation($stateRelation);
-
         $typeRelation = new Nmc_Db_Table_Relation_HasOne(RequestTypes::getInstance(), $this, 'type', 'type', true);
         $this->_registerRelation($typeRelation);
     }
@@ -28,21 +25,22 @@ class Request extends Nmc_Db_Table_Row
     public function getCourseGeneration()
     {
         $returnValue = null;
+        $db = $this->getTable()->getAdapter();
 
-        $select = $this->_db->select();
+        $select = $db->select();
         $select->from(CourseGenerations::getInstance()->getTableName(),
                       CourseGenerations::getInstance()->getPrimaryKeyName());
         $select->join(Assets::getInstance()->getTableName(),
                         CourseGenerations::getInstance()->getTableName()
-                      . '.asset_id = '
+                      . '.assetId = '
                       . Assets::getInstance()->getTableName() . '.'
                       . Assets::getInstance()->getPrimaryKeyName());
-        $select->where($this->_db->quoteInto('request = ?', $this->getPrimaryKey()));
-        $select->order('creation_time DESC');
+        $select->where($db->quoteInto('request = ?', $this->getPrimaryKey()));
+        $select->order(array('creationTime DESC'));
 
-        $generations = $this->_db->fetchCol($select);
+        $generations = $db->fetchCol($select);
         if(count($generations) > 0) {
-            $returnValue = CourseGenerations::getInstance()->find($generations[0]);
+            $returnValue = CourseGenerations::getInstance()->findOne($generations[0]);
         }
 
         return $returnValue;
@@ -114,16 +112,85 @@ class Request extends Nmc_Db_Table_Row
         }
 
         // create the stack for this request and start its journy along the approval chain
-        $approvalBody = ApprovalBodies::getInstance()->fetchRootApprovalBody();
+        $rootBody = ApprovalBodies::getInstance()->fetchRootApprovalBody();
 
         $stack = RequestStacks::getInstance()->fetchNew();
-        $stack->chain = $this->type->approvalChain;
+        $stack->chain = DefaultApprovalChains::getInstance()->fetchWithBodyAndType($rootBody, $this->type)->approvalChain;
         $stack->action = null;
         $stack->save();
 
         $this->stackPointer = $stack;
         $this->state = null;
     }
+
+    /**
+     * Advances the Request through the Approval Bodies as much as possible, if at all
+     *
+     */
+    public function consider()
+    {
+        $stack = $this->stackPointer;
+        $chain = $stack->chain;
+        $chain->consider($this);
+    }
+
+    /**
+     * Returns the current ApprovalChain that the request is currently in.
+     * May return null if the request is no longer in any chains.
+     *
+     * @return ApprovalChain
+     */
+    public function getCurrentChain()
+    {
+        $stackPointer = $this->stackPointer;
+        if (!$stackPointer instanceof RequestStack) {
+            return null;
+        }
+
+        $chain = $stackPointer->chain;
+        if (!$chain instanceof ApprovalChain) {
+            return null;
+        }
+
+        return $chain;
+    }
+
+    /**
+     * Returns the current ApprovalAction pending for the request.
+     * May return null if no actions remain.
+     *
+     * @return ApprovalAction
+     */
+    public function getCurrentAction()
+    {
+        $chain = $this->getCurrentChain();
+        if (!$chain) {
+            return null;
+        }
+
+        $action = $chain->getCurrentAction($this);
+        if (!$action instanceof ApprovalAction) {
+            return null;
+        }
+
+        return $action;
+    }
+
+    /**
+     * Returns the ApprovalBody that is currently considering the requset.
+     * May return null if the request has reached the end of its chains.
+     *
+     * @return ApprovalBody
+     */
+    public function getCurrentApprovalBody()
+    {
+        $chain = $this->getCurrentChain();
+        if (!$chain) {
+            return null;
+        }
+
+        return $chain->ownerBody;
+    }
 }
 
 ?>
\ No newline at end of file
diff --git a/application/models/rows/RequestStack.php b/application/models/rows/RequestStack.php
index dde1429e..e7a90b54 100644
--- a/application/models/rows/RequestStack.php
+++ b/application/models/rows/RequestStack.php
@@ -9,5 +9,14 @@ class RequestStack extends Nmc_Db_Table_Row
 
         $chainRelation = new Nmc_Db_Table_Relation_HasOne(ApprovalChains::getInstance(), $this, 'chain', 'chain', true);
         $this->_registerRelation($chainRelation);
+
+        $previousRelaition = new Nmc_Db_Table_Relation_HasOne(
+            RequestStacks::getInstance(),
+            $this,
+            'previous',
+            'previous',
+            true
+        );
+        $this->_registerRelation($previousRelaition);
     }
 }
\ No newline at end of file
diff --git a/application/models/rows/RequestType.php b/application/models/rows/RequestType.php
index 3fa9495f..5d53bad8 100644
--- a/application/models/rows/RequestType.php
+++ b/application/models/rows/RequestType.php
@@ -4,7 +4,7 @@ class RequestType extends Nmc_Db_Table_Row
 {
     protected function _init()
     {
-        $chainRelation = new Nmc_Db_Table_Relation_HasOne(ApprovalChains::getInstance(), $this, 'approval_chain', 'approvalChain', true);
+        $chainRelation = new Nmc_Db_Table_Relation_HasOne(ApprovalChains::getInstance(), $this, 'approvalChain', 'approvalChain', true);
         $this->_registerRelation($chainRelation);
     }
 }
\ No newline at end of file
diff --git a/application/models/tables/ActivityTypes.php b/application/models/tables/ActivityTypes.php
index 2f85f3ce..8b4c7356 100644
--- a/application/models/tables/ActivityTypes.php
+++ b/application/models/tables/ActivityTypes.php
@@ -1,12 +1,9 @@
 <?php
 
-/**
- *
- * @primary activity_type_id
- *
- */
 class ActivityTypes extends Nmc_Db_Table
 {
+    protected $_primary = 'activityTypeId';
+
     /**
      * The one true instance
      *
diff --git a/application/models/tables/ApprovalActions.php b/application/models/tables/ApprovalActions.php
index 05bb60ef..4f73b759 100644
--- a/application/models/tables/ApprovalActions.php
+++ b/application/models/tables/ApprovalActions.php
@@ -1,12 +1,10 @@
 <?php
 
-/**
- * @rowClass ApprovalAction
- * @primary approval_action_id
- *
- */
 class ApprovalActions extends Nmc_Db_Table
 {
+    protected $_primary = 'approvalActionId';
+    protected $_rowClass = 'ApprovalAction';
+
     /**
      * The one true instance
      *
@@ -44,12 +42,26 @@ class ApprovalActions extends Nmc_Db_Table
             if ($file == 'ApprovalActions.php') {
                 continue;
             }
+            if ($file == 'ApprovalActionsAbstract.php') {
+                continue;
+            }
 
             $className = substr($file, 0, -1 * strlen('.php'));
             $class = call_user_func(array($className, 'getInstance'));
 
-            $actions[] = $class;
+            if($class instanceof Application_ApprovalActionTable_Interface) {
+                $actions[] = $class;
+            }
         }
         return $actions;
     }
+
+    public function getPrimaryKeyName($camelized = false)
+    {
+        if ($camelized) {
+            return 'approvalActionId';
+        } else {
+            return 'approvalActionId';
+        }
+    }
 }
\ No newline at end of file
diff --git a/application/models/tables/ApprovalActionsAbstract.php b/application/models/tables/ApprovalActionsAbstract.php
index 090b08a0..a620bc0b 100644
--- a/application/models/tables/ApprovalActionsAbstract.php
+++ b/application/models/tables/ApprovalActionsAbstract.php
@@ -1,12 +1,10 @@
 <?php
 
-/**
- * @rowClass ApprovalAction
- * @primary approval_action_id
- *
- */
 class ApprovalActionsAbstract extends Nmc_Db_Table
 {
+    protected $_primary = 'approvalActionId';
+    protected $_rowClass = 'ApprovalAction';
+
     /**
      * The one true instance
      *
@@ -33,12 +31,12 @@ class ApprovalActionsAbstract extends Nmc_Db_Table
         return parent::_setup();
     }
 
-    public function find($val)
+    public function findOne($val)
     {
         $db = $this->getAdapter();
 
         $parentTable = ApprovalActions::getInstance();
-        $parentRow = $parentTable->find($val);
+        $parentRow = $parentTable->findOne($val);
         $rowClass = $parentRow->className;
 
         // find out what the parent table is supposed to be (in the case of an extended row)
@@ -59,7 +57,7 @@ class ApprovalActionsAbstract extends Nmc_Db_Table
         $parentTable = ApprovalActions::getInstance();
         $parentRow = $parentTable->fetchRow($where, $order);
         if ($parentRow) {
-            return $this->find($parentRow->getPrimaryKey());
+            return $this->findOne($parentRow->getPrimaryKey());
         } else {
             return null;
         }
@@ -73,7 +71,7 @@ class ApprovalActionsAbstract extends Nmc_Db_Table
 
         foreach($parentRowset as $key => $row)
         {
-            $parentRowset[$key] = $this->find($row->getPrimaryKey());
+            $parentRowset[$key] = $this->findOne($row->getPrimaryKey());
         }
 
         return $parentRowset;
diff --git a/application/models/tables/ApprovalActionsAuto.php b/application/models/tables/ApprovalActionsAuto.php
index 467ebc5f..1ccbbd22 100644
--- a/application/models/tables/ApprovalActionsAuto.php
+++ b/application/models/tables/ApprovalActionsAuto.php
@@ -1,12 +1,13 @@
 <?php
 
-/**
- * @rowClass ApprovalActionAuto
- * @primary approval_action_auto_id
- *
- */
+require_once 'ApprovalActionTable/Interface.php';
+
 class ApprovalActionsAuto extends Nmc_Db_Table
+                          implements Application_ApprovalActionTable_Interface
 {
+    protected $_primary = 'approvalActionAutoId';
+    protected $_rowClass = 'ApprovalActionAuto';
+
     /**
      * The one true instance
      *
@@ -42,4 +43,22 @@ class ApprovalActionsAuto extends Nmc_Db_Table
     {
         return 'approval_actions/ApprovalActionAuto.xhtml';
     }
+
+    public function fetchNew($formData = null)
+    {
+        if (!$formData) {
+            return parent::fetchNew();
+        }
+
+        $new = parent::fetchNew();
+        $new->className = 'ApprovalActionAuto';
+        $new->result = $formData['result'];
+
+        return $new;
+    }
+
+    public function getPrimaryKeyName()
+    {
+        return ApprovalActions::getInstance()->getPrimaryKeyName();
+    }
 }
\ No newline at end of file
diff --git a/application/models/tables/ApprovalActionsDelegate.php b/application/models/tables/ApprovalActionsDelegate.php
new file mode 100644
index 00000000..ffb4732d
--- /dev/null
+++ b/application/models/tables/ApprovalActionsDelegate.php
@@ -0,0 +1,68 @@
+<?php
+
+require_once 'ApprovalActionTable/Interface.php';
+
+class ApprovalActionsDelegate extends Nmc_Db_Table
+                              implements Application_ApprovalActionTable_Interface
+{
+    protected $_primary = 'approvalActionDelegateId';
+    protected $_rowClass = 'ApprovalActionDelegate';
+
+    /**
+     * The one true instance
+     *
+     * @var ApprovalActionsDelegate
+     */
+    static protected $_instance;
+
+    /**
+     * Return the one true instance
+     *
+     * @return ApprovalActionsDelegate
+     */
+    static public function getInstance($config = array())
+    {
+        if (!self::$_instance) {
+            self::$_instance = new ApprovalActionsDelegate($config);
+        }
+        return self::$_instance;
+    }
+
+    public function getActionName()
+    {
+        return 'Delegate';
+    }
+
+    public function getResultStatusStrings()
+    {
+        return array('Approved' => 'Approved',
+                     'Denied' => 'Denied');
+    }
+
+    public function getEditTemplate()
+    {
+        return 'approval_actions/ApprovalActionDelegate.xhtml';
+    }
+
+    public function fetchNew($formData = null)
+    {
+        if (!$formData) {
+            return parent::fetchNew();
+        }
+
+        $delegateBodyId = $formData['delegateBody'];
+        $delegateBodyId = Zend_Filter_Int::filter($delegateBodyId);
+        $delegateBody = ApprovalBodies::getInstance()->findOne($delegateBodyId);
+
+        $new = parent::fetchNew();
+        $new->className = 'ApprovalActionDelegate';
+        $new->delegateBody = $delegateBody;
+
+        return $new;
+    }
+
+    public function getPrimaryKeyName()
+    {
+        return ApprovalActions::getInstance()->getPrimaryKeyName();
+    }
+}
\ No newline at end of file
diff --git a/application/models/tables/ApprovalActionsSingleApprover.php b/application/models/tables/ApprovalActionsSingleApprover.php
new file mode 100644
index 00000000..9d5d810c
--- /dev/null
+++ b/application/models/tables/ApprovalActionsSingleApprover.php
@@ -0,0 +1,64 @@
+<?php
+
+require_once 'ApprovalActionTable/Interface.php';
+
+class ApprovalActionsSingleApprover extends Nmc_Db_Table
+                                    implements Application_ApprovalActionTable_Interface
+{
+    protected $_primary = 'approvalActionSingleApproverId';
+    protected $_rowClass = 'ApprovalActionSingleApprover';
+
+    /**
+     * The one true instance
+     *
+     * @var ApprovalActionsSingleApprover
+     */
+    static protected $_instance;
+
+    /**
+     * Return the one true instance
+     *
+     * @return ApprovalActionsSingleApprover
+     */
+    static public function getInstance($config = array())
+    {
+        if (!self::$_instance) {
+            self::$_instance = new ApprovalActionsSingleApprover($config);
+        }
+        return self::$_instance;
+    }
+
+    public function getActionName()
+    {
+        return 'Single Approver';
+    }
+
+    public function getResultStatusStrings()
+    {
+        return array('Approved' => 'Approved',
+                     'Denied' => 'Denied');
+    }
+
+    public function getEditTemplate()
+    {
+        return 'approval_actions/ApprovalActionSingleApprover.xhtml';
+    }
+
+    public function fetchNew($formData = null)
+    {
+        if (!$formData) {
+            return parent::fetchNew();
+        }
+
+        $new = parent::fetchNew();
+        $new->className = 'ApprovalActionSingleApprover';
+        //$new->result = $formData['result'];
+
+        return $new;
+    }
+
+    public function getPrimaryKeyName()
+    {
+        return ApprovalActions::getInstance()->getPrimaryKeyName();
+    }
+}
\ No newline at end of file
diff --git a/application/models/tables/ApprovalActionsVote.php b/application/models/tables/ApprovalActionsVote.php
new file mode 100644
index 00000000..04c14cba
--- /dev/null
+++ b/application/models/tables/ApprovalActionsVote.php
@@ -0,0 +1,83 @@
+<?php
+
+require_once 'ApprovalActionTable/Interface.php';
+
+class ApprovalActionsVote extends Nmc_Db_Table
+                          implements Application_ApprovalActionTable_Interface
+{
+    protected $_primary = 'approvalActionVoteId';
+    protected $_rowClass = 'ApprovalActionVote';
+
+    /**
+     * The one true instance
+     *
+     * @var ApprovalActionsVote
+     */
+    static protected $_instance;
+
+    /**
+     * Return the one true instance
+     *
+     * @return ApprovalActionsVote
+     */
+    static public function getInstance($config = array())
+    {
+        if (!self::$_instance) {
+            self::$_instance = new ApprovalActionsVote($config);
+        }
+        return self::$_instance;
+    }
+
+    public function getPrimaryKeyName()
+    {
+        return ApprovalActions::getInstance()->getPrimaryKeyName();
+    }
+
+    /**
+     * Returns the human friendly name of the given action.
+     *
+     * @return String
+     */
+    public function getActionName()
+    {
+        return "Vote";
+    }
+
+    /**
+     * Returns an array of all possible outcomes from this action
+     *
+     * @return Array
+     */
+    public function getResultStatusStrings()
+    {
+        return array('Approve', 'Deny', 'Table');
+    }
+
+    /**
+     * Returns the XHTML template used to edit the action's specific details
+     *
+     * @return String
+     */
+    public function getEditTemplate()
+    {
+        return 'approval_actions/ApprovalActionVote.xhtml';
+    }
+
+    /**
+     * Instantiates a new action row object using the provided form data
+     *
+     * @param Array $formData
+     * @return Application_ApprovalActionRow_Interface
+     */
+    public function fetchNew($formData = null)
+    {
+        if (!$formData) {
+            return parent::fetchNew();
+        }
+
+        $new = parent::fetchNew();
+        $new->className = 'ApprovalActionVote';
+        $new->closed = 'No';
+        return $new;
+    }
+}
\ No newline at end of file
diff --git a/application/models/tables/ApprovalActionsVoteVotes.php b/application/models/tables/ApprovalActionsVoteVotes.php
new file mode 100644
index 00000000..7dffc9ce
--- /dev/null
+++ b/application/models/tables/ApprovalActionsVoteVotes.php
@@ -0,0 +1,45 @@
+<?php
+
+class ApprovalActionsVoteVotes extends Nmc_Db_Table
+{
+    protected $_primary = 'approvalActionsVoteVoteId';
+    protected $_rowClass = 'ApprovalActionsVoteVote';
+
+    /**
+     * The one true instance
+     *
+     * @var ApprovalActionsVoteVotes
+     */
+    static protected $_instance;
+
+    /**
+     * Return the one true instance
+     *
+     * @return ApprovalActionsVoteVotes
+     */
+    static public function getInstance($config = array())
+    {
+        if (!self::$_instance) {
+            self::$_instance = new ApprovalActionsVoteVotes($config);
+        }
+        return self::$_instance;
+    }
+
+    public function fetchNew()
+    {
+        $new = parent::fetchNew();
+        $new->time = time();
+        return $new;
+    }
+
+    public function fetchByRequestUserAndAction(Request $request, User $user, ApprovalAction $action)
+    {
+        $db = $this->getAdapter();
+        $where = array();
+        $where[] = $db->quoteInto('request=?', $request->getPrimaryKey());
+        $where[] = $db->quoteInto('user=?', $user->getPrimaryKey());
+        $where[] = $db->quoteInto('approvalAction=?', $action->getPrimaryKey());
+        $where = implode(' AND ', $where);
+        return $this->fetchRow($where);
+    }
+}
\ No newline at end of file
diff --git a/application/models/tables/ApprovalBodies.php b/application/models/tables/ApprovalBodies.php
index 91e08c8f..c18de343 100644
--- a/application/models/tables/ApprovalBodies.php
+++ b/application/models/tables/ApprovalBodies.php
@@ -1,13 +1,8 @@
 <?php
 
-
-/**
- *
- * @primary approval_body_id
- *
- */
 class ApprovalBodies extends Nmc_Db_Table
 {
+    protected $_primary = 'approvalBodyId';
     protected $_rowClass = 'ApprovalBody';
 
     /**
@@ -22,7 +17,7 @@ class ApprovalBodies extends Nmc_Db_Table
      *
      * @return ApprovalBodies
      */
-    public static function getInstance($config = null)
+    public static function getInstance($config = array())
     {
         if(!self::$_instance) {
             self::$_instance = new ApprovalBodies($config);
@@ -38,7 +33,7 @@ class ApprovalBodies extends Nmc_Db_Table
      */
     public function fetchRootApprovalBody()
     {
-        return $this->find(1);
+        return $this->findOne(1);
     }
 
     public function fetchApprovalBodiesUserCanAdminister(User $user)
@@ -49,7 +44,7 @@ class ApprovalBodies extends Nmc_Db_Table
             $groupIds [] = $group->getPrimaryKey();
         }
 
-        $where = $this->_db->quoteInto('admin_group IN (?)', $groupIds);
+        $where = $this->_db->quoteInto('adminGroup IN (?)', $groupIds);
         return $this->fetchAll($where);
     }
 }
diff --git a/application/models/tables/ApprovalBodyRoles.php b/application/models/tables/ApprovalBodyRoles.php
index bc8622e3..eea85c45 100644
--- a/application/models/tables/ApprovalBodyRoles.php
+++ b/application/models/tables/ApprovalBodyRoles.php
@@ -1,13 +1,9 @@
 <?php
 
-/**
- *
- * @rowClass ApprovalBodyRole
- * @primary approval_body_role_id
- *
- */
 class ApprovalBodyRoles extends Nmc_Db_Table
 {
+    protected $_primary = 'approvalBodyRoleId';
+    protected $_rowClass = 'ApprovalBodyRole';
 
     /**
      * The one true instance
diff --git a/application/models/tables/ApprovalChains.php b/application/models/tables/ApprovalChains.php
index cd617630..09bf8ccc 100644
--- a/application/models/tables/ApprovalChains.php
+++ b/application/models/tables/ApprovalChains.php
@@ -1,13 +1,10 @@
 <?php
 
-/**
- *
- * @primary approval_chain_id
- * @rowClass ApprovalChain
- *
- */
 class ApprovalChains extends Nmc_Db_Table
 {
+    protected $_primary = 'approvalChainId';
+    protected $_rowClass = 'ApprovalChain';
+
     /**
      * The one true instance
      *
@@ -27,6 +24,13 @@ class ApprovalChains extends Nmc_Db_Table
         }
         return self::$_instance;
     }
+
+    public function fetchWithApprovalBody(ApprovalBody $approvalBody, $order = null, $count = null, $offset = null)
+    {
+        $db = $this->getAdapter();
+        $where = $db->quoteInto('ownerBody=?', $approvalBody->getPrimaryKey());
+        return $this->fetchAll($where, $order, $count, $offset);
+    }
 }
 
 ?>
\ No newline at end of file
diff --git a/application/models/tables/ApprovalLinks.php b/application/models/tables/ApprovalLinks.php
index 618bd257..b3fec199 100644
--- a/application/models/tables/ApprovalLinks.php
+++ b/application/models/tables/ApprovalLinks.php
@@ -1,13 +1,10 @@
 <?php
 
-/**
- *
- * @rowClass ApprovalLink
- * @primary approval_link_id
- *
- */
 class ApprovalLinks extends Nmc_Db_Table
 {
+    protected $_primary = 'approvalLinkId';
+    protected $_rowClass = 'ApprovalLink';
+
     /**
      * The one true instance
      *
diff --git a/application/models/tables/Assets.php b/application/models/tables/Assets.php
index 71a01989..feb65441 100644
--- a/application/models/tables/Assets.php
+++ b/application/models/tables/Assets.php
@@ -1,12 +1,8 @@
 <?php
 
-/**
- *
- * @primary asset_id
- *
- */
 class Assets extends Nmc_Db_Table
 {
+    protected $_primary = 'assetId';
     protected $_rowClass = 'Asset';
 
     /**
diff --git a/application/models/tables/Auth.php b/application/models/tables/Auth.php
index 51ca2027..40255350 100644
--- a/application/models/tables/Auth.php
+++ b/application/models/tables/Auth.php
@@ -1,15 +1,28 @@
 <?php
 
-
-/**
- *
- * @table auth
- * @primary auth_id
- *
- */
-class Auth extends Zend_Db_Table
+class Auth extends Nmc_Db_Table
 {
+    protected $_name = 'auth';
+
+    /**
+     * The one true instance
+     *
+     * @var Auth
+     */
+    static protected $_instance;
 
+    /**
+     * Return the one true instance
+     *
+     * @return Auth
+     */
+    static public function getInstance($config = array())
+    {
+        if (!self::$_instance) {
+            self::$_instance = new Auth($config);
+        }
+        return self::$_instance;
+    }
 }
 
 ?>
\ No newline at end of file
diff --git a/application/models/tables/Colleges.php b/application/models/tables/Colleges.php
index 5df84e92..bc252aa5 100644
--- a/application/models/tables/Colleges.php
+++ b/application/models/tables/Colleges.php
@@ -1,12 +1,10 @@
 <?php
 
-/**
- * @rowClass College
- * @primary college_id
- *
- */
 class Colleges extends Nmc_Db_Table
 {
+    protected $_primary = 'collegeId';
+    protected $_rowClass = 'College';
+
     /**
      * The one true instance
      *
diff --git a/application/models/tables/CourseActivities.php b/application/models/tables/CourseActivities.php
index a716e035..54d67d10 100644
--- a/application/models/tables/CourseActivities.php
+++ b/application/models/tables/CourseActivities.php
@@ -1,23 +1,19 @@
 <?php
 
-
-/**
- *
- * @primary course_activity_id
- *
- */
 class CourseActivities extends Local_Db_CourseTableMany
 {
-    protected static $_instance;
+    protected $_primary = 'courseActivityId';
     protected $_rowClass = 'CourseActivity';
 
+    protected static $_instance;
+
     /**
      * Return the singleton instance of this class
      *
      * @param array $config
      * @return CourseActivities
      */
-    static public function getInstance($config = null)
+    static public function getInstance($config = array())
     {
         if(!self::$_instance) {
             self::$_instance = new CourseActivities($config);
@@ -30,7 +26,7 @@ class CourseActivities extends Local_Db_CourseTableMany
         $me = self::getInstance();
         $config = array('db'    => $me->_db,
                         'table' => $me,
-                        'data'  => array('course_generation' => $course->getPrimaryKey()));
+                        'data'  => array('courseGeneration' => $course->getPrimaryKey()));
         $newRecord = new CourseActivity($config);
         return $newRecord;
     }
@@ -42,16 +38,16 @@ class CourseActivities extends Local_Db_CourseTableMany
         } else {
             $activityTableInfo = ActivityTypes::getInstance()->info();
             $activityTableName = $activityTableInfo['name'];
-            $activityPrimary = $activityTableInfo['primary'];
+            $activityPrimary = $activityTableInfo['primary'][0];
 
             $select = $this->_db->select();
             $select->from($this->_name, '*');
             $select->join($activityTableName,
                             $this->_name . '.type = '
-                          . $activityTableName . '.short_name');
+                          . $activityTableName . '.shortName');
 
             $select->where($where);
-            $select->order($activityTableName . '.' . $activityPrimary);
+            $select->order(new Zend_Db_Expr($activityTableName . '.' . $activityPrimary));
             $select->limit($count, $offset);
             $resultData = $this->_db->fetchAll($select);
             $config = array();
diff --git a/application/models/tables/CourseCodes.php b/application/models/tables/CourseCodes.php
index b9b98ae7..19408ffb 100644
--- a/application/models/tables/CourseCodes.php
+++ b/application/models/tables/CourseCodes.php
@@ -1,13 +1,8 @@
 <?php
 
-/**
- *
- * @primary course_code_id
- *
- */
 class CourseCodes extends Nmc_Db_Table
 {
-
+    protected $_primary = 'courseCodeId';
     protected $_rowClass = 'CourseCode';
 
     /**
@@ -33,7 +28,7 @@ class CourseCodes extends Nmc_Db_Table
     public function fetchAll($where = null, $order = null, $count = null, $offset = null)
     {
         if(!$order) {
-            $order = 'subject, course_number, course_letter';
+            $order = array('subject', 'courseNumber', 'courseLetter');
         }
         return parent::fetchAll($where, $order, $count, $offset);
     }
@@ -42,8 +37,8 @@ class CourseCodes extends Nmc_Db_Table
     {
         $where = array();
         $where[] = $this->_db->quoteInto('subject = ?', $subject);
-        $where[] = $this->_db->quoteInto('course_number = ?', $number);
-        $where[] = $this->_db->quoteInto('course_letter = ?', $letter);
+        $where[] = $this->_db->quoteInto('courseNumber = ?', $number);
+        $where[] = $this->_db->quoteInto('courseLetter = ?', $letter);
         $where = implode(' AND ', $where);
 
         $result = $this->fetchRow($where);
diff --git a/application/models/tables/CourseCredits.php b/application/models/tables/CourseCredits.php
index e2309866..98c15472 100644
--- a/application/models/tables/CourseCredits.php
+++ b/application/models/tables/CourseCredits.php
@@ -1,22 +1,18 @@
 <?php
 
-/**
- *
- * @primary course_credit_id
- *
- */
 class CourseCredits extends Local_Db_CourseTableMany
 {
-    protected static $_instance;
+    protected $_primary = 'courseCreditId';
     protected $_rowClass = 'CourseCredit';
 
+    protected static $_instance;
     /**
      * Return the singleton instance of this class
      *
      * @param array $config
      * @return CourseCredits
      */
-    static public function getInstance($config = null)
+    static public function getInstance($config = array())
     {
         if(!self::$_instance) {
             self::$_instance = new CourseCredits($config);
@@ -29,7 +25,7 @@ class CourseCredits extends Local_Db_CourseTableMany
         $me = self::getInstance();
         $config = array('db'    => $me->_db,
                         'table' => $me,
-                        'data'  => array('course_generation' => $course->getPrimaryKey()));
+                        'data'  => array('courseGeneration' => $course->getPrimaryKey()));
         $newRecord = new CourseCredit($config);
         return $newRecord;
     }
diff --git a/application/models/tables/CourseCrosslistings.php b/application/models/tables/CourseCrosslistings.php
index f80091f4..4b7ca65f 100644
--- a/application/models/tables/CourseCrosslistings.php
+++ b/application/models/tables/CourseCrosslistings.php
@@ -1,22 +1,19 @@
 <?php
 
-/**
- *
- * @primary course_crosslisting_id
- *
- */
 class CourseCrosslistings extends Local_Db_CourseTableMany
 {
-    protected static $_instance;
+    protected $_primary = 'courseCrosslistingId';
     protected $_rowClass = 'CourseCrosslisting';
 
+    protected static $_instance;
+
     /**
      * Return the singleton instance of this class
      *
      * @param array $config
      * @return CourseCrosslistings
      */
-    static public function getInstance($config = null)
+    static public function getInstance($config = array())
     {
         if(!self::$_instance) {
             self::$_instance = new CourseCrosslistings($config);
@@ -43,22 +40,22 @@ class CourseCrosslistings extends Local_Db_CourseTableMany
         $assetsPrimaryKeyName = Assets::getInstance()->getPrimaryKeyName();
 
         $select = $db->select();
-        $select->from('creq_course_codes');
-        $select->join('creq_course_crosslistings',
-                      'creq_course_codes.' . $courseCodePrimaryKeyName . ' = creq_course_crosslistings.course_code',
+        $select->from('creqCourseCodes');
+        $select->join('creqCourseCrosslistings',
+                      'creqCourseCodes.' . $courseCodePrimaryKeyName . ' = creqCourseCrosslistings.courseCode',
                       $courseCrosslistingsPrimaryKeyName);
-        $select->join('creq_course_generations',
-                      'creq_course_crosslistings.generation = creq_course_generations.' . $courseGenerationsPrimaryKeyName);
-        $select->join('creq_assets',
-                      'creq_course_generations.asset_id = creq_assets.' . $assetsPrimaryKeyName);
-        $select->where('creq_course_generations.type = "official"');
+        $select->join('creqCourseGenerations',
+                      'creqCourseCrosslistings.generation = creqCourseGenerations.' . $courseGenerationsPrimaryKeyName);
+        $select->join('creqAssets',
+                      'creqCourseGenerations.assetId = creqAssets.' . $assetsPrimaryKeyName);
+        $select->where('creqCourseGenerations.type = "official"');
         $select->where($db->quoteInto('subject = ?', $subject));
-        $select->where($db->quoteInto('course_number = ?', $number));
-        $select->where($db->quoteInto('course_letter = ?', $letter));
-        $select->order('creation_time ASC');
+        $select->where($db->quoteInto('courseNumber = ?', $number));
+        $select->where($db->quoteInto('courseLetter = ?', $letter));
+        $select->order(array('creationTime DESC'));
 
         $row = $db->fetchRow($select);
-        $result = $me->find($row[$courseCrosslistingsPrimaryKeyName]);
+        $result = $me->findOne($row[$courseCrosslistingsPrimaryKeyName]);
 
 
         if($result instanceof Nmc_Db_Table_Row && $result->getPrimaryKey() == '') {
@@ -73,7 +70,7 @@ class CourseCrosslistings extends Local_Db_CourseTableMany
         $me = self::getInstance();
         $db = $me->getAdapter();
 
-        $where = $db->quoteInto('course_code = ?', $courseCodeId);
+        $where = $db->quoteInto('courseCode = ?', $courseCodeId);
         $self->fetchRow($where);
 
         if($result->getPrimaryKey() == '') {
@@ -88,7 +85,7 @@ class CourseCrosslistings extends Local_Db_CourseTableMany
         $me = self::getInstance();
         $config = array('db'    => $me->_db,
                         'table' => $me,
-                        'data'  => array('parent_course' => $course->getPrimaryKey()));
+                        'data'  => array('parentCourse' => $course->getPrimaryKey()));
         $newRecord = new CourseCrosslisting($config);
         return $newRecord;
     }
@@ -109,16 +106,16 @@ class CourseCrosslistings extends Local_Db_CourseTableMany
         } else {
             $courseCodeTableInfo = CourseCodes::getInstance()->info();
             $courseCodeTableName = $courseCodeTableInfo['name'];
-            $courseCodePrimary = $courseCodeTableInfo['primary'];
+            $courseCodePrimary = $courseCodeTableInfo['primary'][0];
 
             $select = $this->_db->select();
             $select->from($this->_name, '*');
             $select->join($courseCodeTableName,
-                            $this->_name . '.course_code = '
+                            $this->_name . '.courseCode = '
                           . $courseCodeTableName . '.' . $courseCodePrimary);
 
             $select->where($where);
-            $select->order('subject, course_number, course_letter');
+            $select->order(array('subject', 'courseNumber', 'courseLetter'));
             $select->limit($count, $offset);
             $resultData = $this->_db->fetchAll($select);
             $config = array();
diff --git a/application/models/tables/CourseDetails.php b/application/models/tables/CourseDetails.php
index dd41fa88..7fbf7f18 100644
--- a/application/models/tables/CourseDetails.php
+++ b/application/models/tables/CourseDetails.php
@@ -1,22 +1,19 @@
 <?php
 
-/**
- *
- * @primary course_detail_id
- *
- */
 class CourseDetails extends Local_Db_CourseTableOne
 {
-    protected static $_instance;
+    protected $_primary = 'courseDetailId';
     protected $_rowClass = 'CourseDetail';
 
+    protected static $_instance;
+
     /**
      * Return the singleton instance of this class
      *
      * @param array $config
      * @return CourseDetails
      */
-    static public function getInstance($config = null)
+    static public function getInstance($config = array())
     {
         if(!self::$_instance) {
             self::$_instance = new CourseDetails($config);
diff --git a/application/models/tables/CourseDfRemovals.php b/application/models/tables/CourseDfRemovals.php
index 5ee9df10..2a41f82a 100644
--- a/application/models/tables/CourseDfRemovals.php
+++ b/application/models/tables/CourseDfRemovals.php
@@ -1,22 +1,19 @@
 <?php
 
-/**
- *
- * @primary course_df_removal_id
- *
- */
 class CourseDfRemovals extends Local_Db_CourseTableMany
 {
-    protected static $_instance;
+    protected $_primary = 'courseDfRemovalId';
     protected $_rowClass = 'CourseDfRemoval';
 
+    protected static $_instance;
+
     /**
      * Return the singleton instance of this class
      *
      * @param array $config
      * @return CourseDfRemovals
      */
-    static public function getInstance($config = null)
+    static public function getInstance($config = array())
     {
         if(!self::$_instance) {
             self::$_instance = new CourseDfRemovals($config);
@@ -29,7 +26,7 @@ class CourseDfRemovals extends Local_Db_CourseTableMany
         $me = self::getInstance();
         $config = array('db'    => $me->_db,
                         'table' => $me,
-                        'data'  => array('course_generation_passed' => $course->getPrimaryKey()));
+                        'data'  => array('courseGenerationPassed' => $course->getPrimaryKey()));
         $newRecord = new CourseCredit($config);
         return $newRecord;
     }
diff --git a/application/models/tables/CourseEsDesignations.php b/application/models/tables/CourseEsDesignations.php
index 75c1ebf4..0e064c3c 100644
--- a/application/models/tables/CourseEsDesignations.php
+++ b/application/models/tables/CourseEsDesignations.php
@@ -1,12 +1,9 @@
 <?php
 
-
-/**
- * @primary course_es_designation_id
- *
- */
 class CourseEsDesignations extends Nmc_Db_Table
 {
+    protected $_primary = 'courseEsDesignationId';
+
     /**
      * The one true instance
      *
@@ -40,7 +37,7 @@ class CourseEsDesignations extends Nmc_Db_Table
         $db = $this->getAdapter();
 
         $where = array();
-        $where[] = $db->quoteInto('course_code = ?', $course->getPrimaryKey());
+        $where[] = $db->quoteInto('courseCode = ?', $course->getPrimaryKey());
         if ($college) {
             $where[] = $db->quoteInto('college = ?', $college->getPrimaryKey());
         }
diff --git a/application/models/tables/CourseGenerations.php b/application/models/tables/CourseGenerations.php
index 9410c3a9..43ad83d0 100644
--- a/application/models/tables/CourseGenerations.php
+++ b/application/models/tables/CourseGenerations.php
@@ -1,22 +1,19 @@
 <?php
 
-/**
- *
- * @primary course_generation_id
- *
- */
 class CourseGenerations extends Nmc_Db_Table
 {
-    protected static $_instance;
+    protected $_primary = 'courseGenerationId';
     protected $_rowClass = 'CourseGeneration';
 
+    protected static $_instance;
+
     /**
      * getInstance() - return singleton
      *
      * @param array $config
      * @return Nmc_Db_Table
      */
-    static public function getInstance($config = null)
+    static public function getInstance($config = array())
     {
         if(!self::$_instance) {
             self::$_instance = new CourseGenerations($config);
@@ -49,33 +46,33 @@ class CourseGenerations extends Nmc_Db_Table
     {
         $db = self::getInstance()->getAdapter();
         $sql = 'SELECT id FROM ('
-             . 'SELECT id, subject, course_number, course_letter FROM creq_course_generations '
+             . 'SELECT id, subject, courseNumber, courseLetter FROM creqCourseGenerations '
              . $db->quoteInto('WHERE subject >= ? ', $subject)
-             . $db->quoteInto('AND course_number >= ? ', $number)
-             . $db->quoteInto('AND course_letter > ? ', $letter)
+             . $db->quoteInto('AND courseNumber >= ? ', $number)
+             . $db->quoteInto('AND courseLetter > ? ', $letter)
              . 'UNION '
-             . 'SELECT id, subject, course_number, course_letter FROM creq_course_generations '
+             . 'SELECT id, subject, courseNumber, courseLetter FROM creqCourseGenerations '
              . $db->quoteInto('WHERE subject >= ? ', $subject)
-             . $db->quoteInto('AND course_number > ? ', $number)
+             . $db->quoteInto('AND courseNumber > ? ', $number)
              . 'UNION '
-             . 'SELECT id, subject, course_number, course_letter FROM creq_course_generations '
+             . 'SELECT id, subject, courseNumber, courseLetter FROM creqCourseGenerations '
              . $db->quoteInto('WHERE subject > ? ', $subject)
              . 'UNION '
-             . 'SELECT parent_course AS id, subject, course_number, course_letter FROM creq_course_crosslistings '
+             . 'SELECT parentCourse AS id, subject, courseNumber, courseLetter FROM creqCourseCrosslistings '
              . $db->quoteInto('WHERE subject >= ? ', $subject)
-             . $db->quoteInto('AND course_number >= ? ', $number)
-             . $db->quoteInto('AND course_letter > ? ', $letter)
+             . $db->quoteInto('AND courseNumber >= ? ', $number)
+             . $db->quoteInto('AND courseLetter > ? ', $letter)
              . 'UNION '
-             . 'SELECT parent_course AS id, subject, course_number, course_letter FROM creq_course_crosslistings '
+             . 'SELECT parentCourse AS id, subject, courseNumber, courseLetter FROM creqCourseCrosslistings '
              . $db->quoteInto('WHERE subject >= ? ', $subject)
-             . $db->quoteInto('AND course_number > ? ', $number)
+             . $db->quoteInto('AND courseNumber > ? ', $number)
              . 'UNION '
-             . 'SELECT parent_course AS id, subject, course_number, course_letter FROM creq_course_crosslistings '
+             . 'SELECT parentCourse AS id, subject, courseNumber, courseLetter FROM creqCourseCrosslistings '
              . $db->quoteInto('WHERE subject > ? ', $subject)
-             . 'ORDER BY subject, course_number, course_letter '
-             . ') AS sub_table LIMIT 1 ';
+             . 'ORDER BY subject, courseNumber, courseLetter '
+             . ') AS subTable LIMIT 1 ';
         $record = $db->fetchOne($sql);
-        $record = CourseGenerations::getInstance()->find($record);
+        $record = CourseGenerations::getInstance()->findOne($record);
         return $record;
     }
 
@@ -83,33 +80,33 @@ class CourseGenerations extends Nmc_Db_Table
     {
         $db = self::getInstance()->getAdapter();
         $sql = 'SELECT id FROM ('
-             . 'SELECT id, subject, course_number, course_letter FROM creq_course_generations '
+             . 'SELECT id, subject, courseNumber, courseLetter FROM creqCourseGenerations '
              . $db->quoteInto('WHERE subject <= ? ', $subject)
-             . $db->quoteInto('AND course_number <= ? ', $number)
-             . $db->quoteInto('AND course_letter < ? ', $letter)
+             . $db->quoteInto('AND courseNumber <= ? ', $number)
+             . $db->quoteInto('AND courseLetter < ? ', $letter)
              . 'UNION '
-             . 'SELECT id, subject, course_number, course_letter FROM creq_course_generations '
+             . 'SELECT id, subject, courseNumber, courseLetter FROM creqCourseGenerations '
              . $db->quoteInto('WHERE subject <= ? ', $subject)
-             . $db->quoteInto('AND course_number < ? ', $number)
+             . $db->quoteInto('AND courseNumber < ? ', $number)
              . 'UNION '
-             . 'SELECT id, subject, course_number, course_letter FROM creq_course_generations '
+             . 'SELECT id, subject, courseNumber, courseLetter FROM creqCourseGenerations '
              . $db->quoteInto('WHERE subject < ? ', $subject)
              . 'UNION '
-             . 'SELECT parent_course AS id, subject, course_number, course_letter FROM creq_course_crosslistings '
+             . 'SELECT parentCourse AS id, subject, courseNumber, courseLetter FROM creqCourseCrosslistings '
              . $db->quoteInto('WHERE subject <= ? ', $subject)
-             . $db->quoteInto('AND course_number <= ? ', $number)
-             . $db->quoteInto('AND course_letter < ? ', $letter)
+             . $db->quoteInto('AND courseNumber <= ? ', $number)
+             . $db->quoteInto('AND courseLetter < ? ', $letter)
              . 'UNION '
-             . 'SELECT parent_course AS id, subject, course_number, course_letter FROM creq_course_crosslistings '
+             . 'SELECT parentCourse AS id, subject, courseNumber, courseLetter FROM creqCourseCrosslistings '
              . $db->quoteInto('WHERE subject <= ? ', $subject)
-             . $db->quoteInto('AND course_number < ? ', $number)
+             . $db->quoteInto('AND courseNumber < ? ', $number)
              . 'UNION '
-             . 'SELECT parent_course AS id, subject, course_number, course_letter FROM creq_course_crosslistings '
+             . 'SELECT parentCourse AS id, subject, courseNumber, courseLetter FROM creqCourseCrosslistings '
              . $db->quoteInto('WHERE subject < ? ', $subject)
-             . 'ORDER BY subject DESC, course_number DESC, course_letter DESC '
-             . ') AS sub_table LIMIT 1 ';
+             . 'ORDER BY subject DESC, courseNumber DESC, courseLetter DESC '
+             . ') AS subTable LIMIT 1 ';
         $record = $db->fetchOne($sql);
-        $record = CourseGenerations::getInstance()->find($record);
+        $record = CourseGenerations::getInstance()->findOne($record);
         return $record;
     }
 
diff --git a/application/models/tables/CourseGradTieIns.php b/application/models/tables/CourseGradTieIns.php
index b070beee..13663b43 100644
--- a/application/models/tables/CourseGradTieIns.php
+++ b/application/models/tables/CourseGradTieIns.php
@@ -1,22 +1,19 @@
 <?php
 
-/**
- *
- * @primary course_grad_tie_in_id
- *
- */
 class CourseGradTieIns extends Local_Db_CourseTableOne
 {
-    protected static $_instance;
+    protected $_primary = 'courseGradTieInId';
     protected $_rowClass = 'CourseGradTieIn';
 
+    protected static $_instance;
+
     /**
      * Return the singleton instance of this class
      *
      * @param array $config
      * @return CourseGradTieIns
      */
-    static public function getInstance($config = null)
+    static public function getInstance($config = array())
     {
         if(!self::$_instance) {
             self::$_instance = new CourseGradTieIns($config);
diff --git a/application/models/tables/CoursePrerequisites.php b/application/models/tables/CoursePrerequisites.php
index 2f523f1d..033e8e53 100644
--- a/application/models/tables/CoursePrerequisites.php
+++ b/application/models/tables/CoursePrerequisites.php
@@ -1,22 +1,19 @@
 <?php
 
-/**
- *
- * @primary course_prerequisite_id
- *
- */
 class CoursePrerequisites extends Local_Db_CourseTableMany
 {
-    protected static $_instance;
+    protected $_primary = 'coursePrerequisiteId';
     protected $_rowClass = 'CoursePrerequisite';
 
+    protected static $_instance;
+
     /**
      * Return the singleton instance of this class
      *
      * @param array $config
      * @return CoursePrerequisites
      */
-    static public function getInstance($config = null)
+    static public function getInstance($config = array())
     {
         if(!self::$_instance) {
             self::$_instance = new CoursePrerequisites($config);
@@ -29,7 +26,7 @@ class CoursePrerequisites extends Local_Db_CourseTableMany
         $me = self::getInstance();
         $config = array('db'    => $me->_db,
                         'table' => $me,
-                        'data'  => array('parent_course' => $course->getPrimaryKey()));
+                        'data'  => array('parentCourse' => $course->getPrimaryKey()));
         $newRecord = new CourseCredit($config);
         return $newRecord;
     }
diff --git a/application/models/tables/Courses.php b/application/models/tables/Courses.php
index 25e6cf0a..d587fda9 100644
--- a/application/models/tables/Courses.php
+++ b/application/models/tables/Courses.php
@@ -1,22 +1,19 @@
 <?php
 
-/**
- *
- * @primary course_id
- *
- */
 class Courses extends Nmc_Db_Table
 {
-    protected static $_instance;
+    protected $_primary = 'courseId';
     protected $_rowClass = 'Course';
 
+    protected static $_instance;
+
     /**
      * Enter description here...
      *
-     * @param unknown_type $config
+     * @param array $config
      * @return Courses
      */
-    static public function getInstance($config = null)
+    static public function getInstance($config = array())
     {
         if(!self::$_instance) {
             self::$_instance = new Courses($config);
diff --git a/application/models/tables/DefaultApprovalChains.php b/application/models/tables/DefaultApprovalChains.php
new file mode 100644
index 00000000..a2e3ff49
--- /dev/null
+++ b/application/models/tables/DefaultApprovalChains.php
@@ -0,0 +1,57 @@
+<?php
+
+class DefaultApprovalChains extends Nmc_Db_Table
+{
+    protected $_primary = 'defaultApprovalChainId';
+    protected $_rowClass = 'DefaultApprovalChain';
+
+    /**
+     * The one true instance
+     *
+     * @var DefaultApprovalChains
+     */
+    static protected $_instance;
+
+    /**
+     * Return the one true instance
+     *
+     * @return DefaultApprovalChains
+     */
+    static public function getInstance($config = array())
+    {
+        if (!self::$_instance) {
+            self::$_instance = new DefaultApprovalChains($config);
+        }
+        return self::$_instance;
+    }
+
+    /**
+     * Fetches the default ApprovalChain for the given ApprovalBody and RequestType
+     * Optionally passed $order parameter to fetchRow call
+     *
+     * @param ApprovalBody $approvalBody
+     * @param RequestType $requestType
+     * @param String $order
+     * @return Nmc_Db_Table_Row
+     */
+    public function fetchWithBodyAndType(ApprovalBody $approvalBody,
+                                         RequestType $requestType,
+                                         $order = null)
+    {
+        $db = $this->getAdapter();
+
+        $where = array();
+        $where[] = $db->quoteInto('approvalBody=?', $approvalBody->getPrimaryKey());
+        $where[] = $db->quoteInto('requestType=?', $requestType->getPrimaryKey());
+        $where = implode(' AND ', $where);
+
+        $row = $this->fetchRow($where, $order);
+        if (!$row) {
+            $row = $this->fetchNew();
+            $row->approvalBody = $approvalBody;
+            $row->requestType = $requestType->getPrimaryKey();
+        }
+
+        return $row;
+    }
+}
\ No newline at end of file
diff --git a/application/models/tables/Departments.php b/application/models/tables/Departments.php
index fdcb8946..8e716a87 100644
--- a/application/models/tables/Departments.php
+++ b/application/models/tables/Departments.php
@@ -1,13 +1,8 @@
 <?php
 
-/**
- *
- * @primary department_id
- *
- */
 class Departments extends Nmc_Db_Table
 {
-
+    protected $_primary = 'departmentId';
     //protected $_rowClass = 'Department';
 
     /**
diff --git a/application/models/tables/Files.php b/application/models/tables/Files.php
index 43a45f72..29ce2d2c 100644
--- a/application/models/tables/Files.php
+++ b/application/models/tables/Files.php
@@ -1,15 +1,11 @@
 <?php
 
-/**
- *
- * @primary file_id
- * @rowClass File
- *
- */
 class Files extends Nmc_Db_Table
 {
+    protected $_primary = 'fileId';
+    protected $_rowClass = 'File';
+
     static protected $_instance;
-    //protected $_rowClass = 'File';
 
     /**
      * Returns the one true instance
@@ -17,7 +13,7 @@ class Files extends Nmc_Db_Table
      * @param array [optional] $config
      * @return Files
      */
-    static public function getInstance($config = null)
+    static public function getInstance($config = array())
     {
         if(!self::$_instance) {
             self::$_instance = new Files($config);
diff --git a/application/models/tables/GroupImpliedMemberships.php b/application/models/tables/GroupImpliedMemberships.php
index 76c07bbc..97e817e5 100644
--- a/application/models/tables/GroupImpliedMemberships.php
+++ b/application/models/tables/GroupImpliedMemberships.php
@@ -1,13 +1,10 @@
 <?php
 
-/**
- *
- * @primary group_implied_membership_id
- *
- */
 class GroupImpliedMemberships extends Nmc_Db_Table
 {
+    protected $_primary = 'groupImpliedMembershipId';
     protected $_rowClass = 'GroupImpliedMembership';
+
     protected static $_instance = null;
 
     /**
@@ -39,7 +36,7 @@ class GroupImpliedMemberships extends Nmc_Db_Table
      */
     public function fetchGroupsByUser(Person $user, $implied = true, $explicit = true)
     {
-        $primaryGroup = Groups::getInstance()->find($user->primaryGroup);
+        $primaryGroup = Groups::getInstance()->findOne($user->primaryGroup);
         return $this->fetchGroupsByChildGroup($primaryGroup, $implied, $explicit);
     }
 
@@ -55,7 +52,7 @@ class GroupImpliedMemberships extends Nmc_Db_Table
     {
         $db = $this->_db;
         $where = array();
-        $where[] = $db->quoteInto('child_group = ?', $group->getPrimaryKey());
+        $where[] = $db->quoteInto('childGroup = ?', $group->getPrimaryKey());
         if(!$implied && $explicit) {
             $where[] = "explicit = 'yes'";
         } else if($implied && !$explicit) {
@@ -91,7 +88,7 @@ class GroupImpliedMemberships extends Nmc_Db_Table
     {
         $db = $this->_db;
         $where = array();
-        $where[] = $db->quoteInto('parent_group = ?', $group->getPrimaryKey());
+        $where[] = $db->quoteInto('parentGroup = ?', $group->getPrimaryKey());
         if(!$implied && $explicit) {
             $where[] = "explicit = 'yes'";
         } else if($implied && !$explicit) {
@@ -133,8 +130,8 @@ class GroupImpliedMemberships extends Nmc_Db_Table
         $select = $this->_db->select();
         $select->from($usersTableName, $usersTablePrimary);
         $select->join($this->_name,
-                      $usersTableName . '.primary_group = ' . $this->_name . '.child_group');
-        $select->where($this->_db->quoteInto('parent_group = ?', $group->getPrimaryKey()));
+                      $usersTableName . '.primaryGroup = ' . $this->_name . '.childGroup');
+        $select->where($this->_db->quoteInto('parentGroup = ?', $group->getPrimaryKey()));
         if(!$implied && $explicit) {
             $select->where("explicit = 'yes'");
         } else if($implied && !$explicit) {
diff --git a/application/models/tables/GroupMemberships.php b/application/models/tables/GroupMemberships.php
index 43d587f8..673bf64e 100644
--- a/application/models/tables/GroupMemberships.php
+++ b/application/models/tables/GroupMemberships.php
@@ -1,12 +1,9 @@
 <?php
 
-/**
- *
- * @primary group_membership_id
- *
- */
 class GroupMemberships extends Nmc_Db_Table
 {
+    protected $_primary = 'groupMembershipId';
+
     protected static $_instance = null;
 
     /**
diff --git a/application/models/tables/Groups.php b/application/models/tables/Groups.php
index 02996805..c2f3607c 100644
--- a/application/models/tables/Groups.php
+++ b/application/models/tables/Groups.php
@@ -1,13 +1,10 @@
 <?php
 
-/**
- *
- * @primary group_id
- *
- */
 class Groups extends Nmc_Db_Table
 {
+    protected $_primary = 'groupId';
     protected $_rowClass = 'Group';
+
     /**
      * The one true instance
      *
@@ -48,15 +45,15 @@ class Groups extends Nmc_Db_Table
         $select = $db->select();
         $userTableInfo = Users::getInstance()->info();
         $userTableName = $userTableInfo['name'];
-        $select->from($userTableName, 'primary_group');
+        $select->from($userTableName, 'primaryGroup');
         $select->distinct();
         $primaryGroupIds = $db->fetchCol($select);
 
-        $extra_where = $db->quoteInto($this->_name . '.' . $this->_primary . ' NOT IN(?)', $primaryGroupIds);
+        $extraWhere = $db->quoteInto($this->_name . '.' . $this->_primary . ' NOT IN(?)', $primaryGroupIds);
         if($where) {
             $where .= ' AND ';
         }
-        $where .= $extra_where;
+        $where .= $extraWhere;
 
         return $this->fetchAll($where, $order, $count, $offset);
     }
diff --git a/application/models/tables/People.php b/application/models/tables/People.php
index c684b193..042c7c2c 100644
--- a/application/models/tables/People.php
+++ b/application/models/tables/People.php
@@ -1,15 +1,12 @@
 <?php
 
-/**
- *
- * @primary person_id
- *
- */
 class People extends Nmc_Db_Table
 {
-    static private $_instance;
+    protected $_primary = 'personId';
     protected $_rowClass = 'Person';
 
+    static private $_instance;
+
     /**
      * Return the one true instance
      *
@@ -34,18 +31,16 @@ class People extends Nmc_Db_Table
     static public function findByUserName($userName)
     {
         $me = self::getInstance();
-        $db = $me->_getDefaultAdapter();
+        $db = $me->getDefaultAdapter();
         $inflector = new Zend_Db_Inflector();
 
         $usersTable = Users::getInstance();
         $usersPrimaryKey = $usersTable->getPrimaryKeyName();
-        $usersPrimaryKey = $inflector->camelize($usersPrimaryKey);
-
 
-        $where = $db->quoteInto('user_name=?', $userName);
+        $where = $db->quoteInto('userName=?', $userName);
         $user = $usersTable->fetchRow($where);
 
-        $where = $db->quoteInto('user_id=?', $user->$usersPrimaryKey);
+        $where = $db->quoteInto('userId=?', $user->$usersPrimaryKey);
         return $me->fetchRow($where);
     }
 
@@ -57,10 +52,10 @@ class People extends Nmc_Db_Table
     public function findByUserId($userId)
     {
         if(is_array($userId)) {
-            $where = $this->_db->quoteInto('user_id IN (?)', $userId);
+            $where = $this->_db->quoteInto('userId IN (?)', $userId);
             return $this->fetchAll($where);
         } else {
-            $where = $this->_db->quoteInto('user_id=?', $userId);
+            $where = $this->_db->quoteInto('userId=?', $userId);
             return $this->fetchRow($where);
         }
     }
diff --git a/application/models/tables/RequestFiles.php b/application/models/tables/RequestFiles.php
index c65f2d8f..9a923c6a 100644
--- a/application/models/tables/RequestFiles.php
+++ b/application/models/tables/RequestFiles.php
@@ -1,16 +1,13 @@
 <?php
 
-/**
- *
- * @primary request_file_id
- *
- */
 class RequestFiles extends Nmc_Db_Table
 {
-    static protected $_instance;
+    protected $_primary = 'requestFileId';
     protected $_rowClass = 'RequestFile';
 
-    static public function getInstance($config = null)
+    static protected $_instance;
+
+    static public function getInstance($config = array())
     {
         if(!self::$_instance) {
             self::$_instance = new RequestFiles($config);
diff --git a/application/models/tables/RequestStacks.php b/application/models/tables/RequestStacks.php
index c2579373..4871b971 100644
--- a/application/models/tables/RequestStacks.php
+++ b/application/models/tables/RequestStacks.php
@@ -1,13 +1,10 @@
 <?php
 
-/**
- *
- * @rowClass RequestStack
- * @primary request_stack_id
- *
- */
 class RequestStacks extends Nmc_Db_Table
 {
+    protected $_primary = 'requestStackId';
+    protected $_rowClass = 'RequestStack';
+
     /**
      * The one true instance
      *
diff --git a/application/models/tables/RequestStates.php b/application/models/tables/RequestStates.php
index d8808bef..36c08937 100644
--- a/application/models/tables/RequestStates.php
+++ b/application/models/tables/RequestStates.php
@@ -1,11 +1,9 @@
 <?php
 
-/**
- * @primary request_state_id
- *
- */
 class RequestStates extends Nmc_Db_Table
 {
+    protected $_primary = 'requestStateId';
+
     /**
      * The one true instance
      *
diff --git a/application/models/tables/RequestTypes.php b/application/models/tables/RequestTypes.php
index 34a1cf0e..29e2ac5d 100644
--- a/application/models/tables/RequestTypes.php
+++ b/application/models/tables/RequestTypes.php
@@ -1,17 +1,14 @@
 <?php
 
-/**
- *
- * @primary request_type_id
- * @rowClass RequestType
- *
- */
 class RequestTypes extends Nmc_Db_Table
 {
+    protected $_primary = 'requestTypeId';
+    protected $_rowClass = 'RequestType';
+
     private static $_instance;
     private $_map;
 
-    public function __construct($config = null)
+    public function __construct($config = array())
     {
         parent::__construct($config);
         $contents = $this->fetchAll();
@@ -26,7 +23,7 @@ class RequestTypes extends Nmc_Db_Table
      * @param array $config
      * @return RequestTypes
      */
-    static public function getInstance($config = null)
+    static public function getInstance($config = array())
     {
         if(!self::$_instance) {
             self::$_instance = new RequestTypes($config);
@@ -54,11 +51,12 @@ class RequestTypes extends Nmc_Db_Table
      */
     public function fetchRequestType($type)
     {
-        if(!Zend_Filter::isInt($type)) {
+        $typeId = Zend_Filter_Int::filter($type);
+        if($typeId < 1) {
             $type = $this->stringToType($string);
         }
 
-        return $this->find($type);
+        return $this->findOne($type);
     }
 }
 
diff --git a/application/models/tables/Requests.php b/application/models/tables/Requests.php
index d7cb07a0..fe73426d 100644
--- a/application/models/tables/Requests.php
+++ b/application/models/tables/Requests.php
@@ -1,38 +1,48 @@
 <?php
 
-/**
- *
- * @primary request_id
- *
- */
-class Requests extends Nmc_Db_Table {
+class Requests extends Nmc_Db_Table
+{
+    protected $_primary = 'requestId';
+    protected $_rowClass = 'Request';
 
     protected static $_instance;
-    protected $_rowClass = 'Request';
+
+    const COMPLETED_REQUESTS_ONLY = 1;
+    const COMPLETED_REQUESTS_BOTH = 2;
+    const COMPLETED_REQUESTS_NO   = 3;
 
     /**
      * Return the one instance to rule them all
      *
      * @return Requests
      */
-    static public function getInstance()
+    static public function getInstance($config = array())
     {
         if(!self::$_instance) {
-            self::$_instance = new Requests();
+            self::$_instance = new Requests($config);
         }
         return self::$_instance;
     }
 
-    public function getRequestsForUser(Person $user)
+    public function fetchNew()
+    {
+        $new = parent::fetchNew();
+        $new->complete = 'no';
+        return $new;
+    }
+
+    public function getRequestsForUser(Person $user,
+                                       $completedRequests = self::COMPLETED_REQUESTS_NO)
     {
         $db = $this->getAdapter();
         $where = $db->quoteInto('owner = ?', $user->getPrimaryKey());
-        $requests = $this->fetchAllSorted($where);
+        $requests = $this->fetchAllSorted($where, $completedRequests);
 
         return $requests;
     }
 
-    public function fetchAllSorted($where = null)
+    public function fetchAllSorted($where = null,
+                                   $completedRequests = self::COMPLETED_REQUESTS_NO)
     {
         $db = $this->getAdapter();
 
@@ -44,14 +54,29 @@ class Requests extends Nmc_Db_Table {
         $select = $db->select();
         $select->distinct();
         $select->from($rq, '*');
-        $select->join($cg, $rq . '.' . $this->getPrimaryKeyName() . ' = ' . $cg . '.request');
-        $select->join($cx, $cg . '.' . CourseGenerations::getInstance()->getPrimaryKeyName() . ' = ' . $cx . '.generation');
-        $select->join($cc, $cx . '.course_code = ' . $cc . '.' . CourseCodes::getInstance()->getPrimaryKeyName());
+        $select->join($cg, $rq . '.' . $this->getPrimaryKeyName() . ' = ' . $cg . '.request', array());
+        $select->join($cx, $cg . '.' . CourseGenerations::getInstance()->getPrimaryKeyName() . ' = ' . $cx . '.generation', array());
+        $select->join($cc, $cx . '.courseCode = ' . $cc . '.' . CourseCodes::getInstance()->getPrimaryKeyName(), array());
         $select->where($cx . ".type = 'home listing'");
         if ($where) {
             $select->where($where);
         }
-        $select->order('subject, course_number, course_letter');
+
+        switch ($completedRequests) {
+            case self::COMPLETED_REQUESTS_NO:
+                $select->where("complete = 'no'");
+                break;
+
+            case self::COMPLETED_REQUESTS_ONLY:
+                $select->where("complete = 'yes'");
+                break;
+
+            case self::COMPLETED_REQUESTS_BOTH:
+            default:
+                break;
+        }
+
+        $select->order(array('subject', 'courseNumber', 'courseLetter'));
 
         $data = $db->fetchAll($select);
         $config['db'] = $db;
diff --git a/application/models/tables/Users.php b/application/models/tables/Users.php
index 117f2fd6..6a9491af 100644
--- a/application/models/tables/Users.php
+++ b/application/models/tables/Users.php
@@ -1,15 +1,12 @@
 <?php
 
-/**
- *
- * @primary user_id
- *
- */
 class Users extends Nmc_Db_Table
 {
-    static private $_instance;
+    protected $_primary = 'userId';
     protected $_rowClass = 'User';
 
+    static private $_instance;
+
     /**
      * Return the one true instance
      *
diff --git a/application/views/approval_actions/ApprovalActionAuto.xhtml b/application/views/approval_actions/ApprovalActionAuto.xhtml
index 13b62044..0611f72e 100644
--- a/application/views/approval_actions/ApprovalActionAuto.xhtml
+++ b/application/views/approval_actions/ApprovalActionAuto.xhtml
@@ -5,13 +5,15 @@ $currentSave = $current;
 $current['id'] = '';
 $current['value'] = null;
 if ($approvalAction) {
-    $current['id'] = '[' . $approvalAction->getPrimaryKey() . ']';
-    $current['value'] = $approvalAction->result;
+    echo $this->formSelect('edit[' . $approvalAction->getPrimaryKey() . '][result]',
+                           $approvalAction->result,
+                           null,
+                           ApprovalActionsAuto::getInstance()->getResultStatusStrings());
+} else {
+    echo $this->formSelect('result',
+                           null,
+                           null,
+                           ApprovalActionsAuto::getInstance()->getResultStatusStrings());
 }
 
-echo $this->formSelect('result' . $current['id'],
-                       $current['value'],
-                       null,
-                       ApprovalActionsAuto::getInstance()->getResultStatusStrings());
-
 $current = $currentSave;
\ No newline at end of file
diff --git a/application/views/approval_body_manager.xhtml b/application/views/approval_body_manager.xhtml
index 504eba24..d055504e 100644
--- a/application/views/approval_body_manager.xhtml
+++ b/application/views/approval_body_manager.xhtml
@@ -1,22 +1,41 @@
-<h2>Select an Approval Body:</h2>
+<div id="manager_menu">
+    <h2>Select an Approval Body:</h2>
 
-<ul>
-<?php foreach ($this->usersBodies as $approvalBody) { ?>
-<li>
-    <a href="/ApprovalBodyManager/EditBody/<?php echo $approvalBody->getPrimaryKey(); ?>">
-        <?php echo $approvalBody->name; ?>
-    </a>
-</li>
-<?php } ?>
-</ul>
+    <ul>
+        <?php foreach ($this->usersBodies as $approvalBody) { ?>
+        <li>
+            <a href="/ApprovalBodyManager/EditBody/<?php echo $approvalBody->getPrimaryKey(); ?>">
+                <?php echo $approvalBody->name; ?>
+            </a>
+        </li>
+        <?php } ?>
+    </ul>
+</div>
 
-<?php if($this->currentBody) { ?>
-<h1>Editing <?php echo $this->currentBody->name; ?></h1>
-<form method="post" action="/ApprovalBodyManager/EditBodyPost">
-<?php foreach (RequestTypes::getInstance()->fetchAll() as $requestType) { ?>
-<h2><?php echo $requestType->name; ?></h2>
-<?php } ?>
-
-</form>
-
-<?php } ?>
\ No newline at end of file
+<div id="manager_edit_pane">
+    <?php if($this->currentBody) { ?>
+    <h1>Editing <?php echo $this->currentBody->name; ?></h1>
+    <form method="post" action="/ApprovalBodyManager/EditBodyPost">
+        <?php echo $this->formHidden('bodyId', $this->currentBody->getPrimaryKey()); ?>
+        <table>
+            <tr>
+                <th>Request Type</th>
+                <th>Initial Approval Chain</th>
+            </tr>
+            <?php foreach ($this->requestTypes as $requestType) { ?>
+            <tr>
+                <td><?php echo $requestType->name; ?></td>
+                <td>
+                <?php echo $this->formSelect('edit[' . $requestType->getPrimaryKey() . '][chain]',
+                                             $this->defaultChains[$requestType->getPrimaryKey()]->approvalChain->getPrimaryKey(),
+                                             null,
+                                             array('_null' => '--Select Approval Chain--')
+                                             + $this->approvalChains->columnToArray('name', ApprovalChains::getInstance()->getPrimaryKeyName(true))); ?>
+                </td>
+            </tr>
+            <?php } ?>
+        </table>
+        <?php echo $this->formSubmit('submit', 'Update'); ?>
+    </form>
+    <?php } ?>
+</div>
\ No newline at end of file
diff --git a/application/views/approval_chain_manager.xhtml b/application/views/approval_chain_manager.xhtml
index 55d33f70..391bee3c 100644
--- a/application/views/approval_chain_manager.xhtml
+++ b/application/views/approval_chain_manager.xhtml
@@ -1,21 +1,52 @@
-<div id="select_chain">
+<div id="manager_menu">
     <h2>Select an Approval Chain</h2>
     <ul>
-    <?php foreach ($this->approvalChains as $approvalChain) { ?>
+        <li>
+            <a href="/ApprovalChainManager/EditChain/new">
+                --New Chain--
+            </a>
+        </li>
+        <?php foreach ($this->approvalChains as $approvalChain) { ?>
         <li>
             <a href="/ApprovalChainManager/EditChain/<?php echo $approvalChain->getPrimaryKey(); ?>">
                 <?php echo $approvalChain->name; ?>
             </a>
         </li>
-    <?php } ?>
+        <?php } ?>
     </ul>
 </div>
 
 
 <?php if ($this->approvalChain) { ?>
 
-<div id="edit_pane">
+<div id="manager_edit_pane">
     <h1>Editing Approval Chain <?php echo $this->approvalChain->name; ?></h1>
+    <div id="main_details">
+        <form method="post" action="/ApprovalChainManager/EditChainPost">
+        <?php echo $this->formHidden('chainId', $this->approvalChain->getPrimaryKey()); ?>
+            <label>
+                Chain Name:
+                <?php echo $this->formText('name', $this->approvalChain->name); ?>
+                Owner:
+                <?php
+                $ownerBody = $this->approvalChain->ownerBody;
+                if($ownerBody) {
+                    $ownerBodyId = $ownerBody->getPrimaryKey();
+                } else {
+                    $ownerBodyId = null;
+                }
+                echo $this->formSelect('ownerBody',
+                                       $ownerBodyId,
+                                       null,
+                                       $this->approvalBodies->columnToArray(
+                                           'name',
+                                           ApprovalBodies::getInstance()->getPrimaryKeyName(true)
+                                       )); ?>
+            </label>
+            <?php echo $this->formSubmit('submit', 'Update'); ?>
+        </form>
+    </div>
+
     <div id="select_links_or_actions">
         <a href="#" id="select_manage_links">Links</a>
         |
@@ -33,68 +64,129 @@
                     <th>Resulted In</th>
                     <th>Next Action</th>
                 </tr>
-                <?php foreach ($this->approvalChain->approvalLinks as $approvalLink) { ?>
                 <tr>
                     <td>
                         <?php echo $this->formSelect('currentAction',
                                                      null,
                                                      array('class' => 'actionSelectElement'),
-                                                     array_merge(array('_null' => '--Just Entered Chain--'),
-                                                                 $this->approvalActions)); ?>
+                                                     array('_null' => '--Just Entered Chain--')
+                                                     + $this->approvalChain->approvalActions->columnToArray('name', 'approvalActionId')); ?>
                     </td>
                     <td>
                         <?php echo $this->formSelect('currentState', null, null, array('_null' => '--N/A--')); ?>
                     </td>
                     <td>
                         <?php echo $this->formSelect('nextAction', null, null,
-                                                     array_merge(array('_null' => '--Exit Chain--'),
-                                                                 $this->approvalActions)); ?>
+                                                     array('_null' => '--Exit Chain--')
+                                                     + $this->approvalChain->approvalActions->columnToArray('name', 'approvalActionId')); ?>
                     </td>
                 </tr>
-                <?php } ?>
             </table>
 
             <?php echo $this->formSubmit('submit', 'Add Link', null); ?>
         </form>
 
-        <form method="post" action="/ApprovalChainManager/EditChainPost">
+        <form method="post" action="/ApprovalChainManager/EditLinksPost">
+            <?php echo $this->formHidden('chainId', $this->approvalChain->getPrimaryKey()); ?>
             <h2>Edit current Chains</h2>
             <table>
                 <tr>
                     <th>Previous Action</th>
                     <th>Resulted In</th>
                     <th>Next Action</th>
+                    <th>Delete</th>
                 </tr>
                 <?php foreach ($this->approvalChain->approvalLinks as $approvalLink) { ?>
                 <tr>
                     <td>
-                        <?php echo $this->formSelect('currentAction['. $approvalLink->getPrimaryKey() .']',
-                                                     $approvalLink->currentAction->className,
-                                                     array('class' => 'actionSelectElement'),
-                                                     array_merge(array('_null' => '--Just Entered Chain--'),
-                                                                 $this->approvalActions)); ?>
+                        <?php
+                        $currentAction = $approvalLink->currentAction;
+                        if($currentAction != null) {
+                            $currentActionId = $approvalLink->currentAction->getPrimaryKey();
+                            $resultStatusStrings = $currentAction->getTable()->getResultStatusStrings();
+                        } else {
+                            $currentActionId = '_null';
+                            $resultStatusStrings = array();
+                        }
+                        echo $this->formSelect('edit['. $approvalLink->getPrimaryKey() .'][currentAction]',
+                                               $currentActionId,
+                                               array('class' => 'actionSelectElement'),
+                                               array('_null' => '--Just Entered Chain--')
+                                               + $this->approvalChain->approvalActions->columnToArray('name', 'approvalActionId')); ?>
                     </td>
                     <td>
-                        <?php echo $this->formSelect('currentState', null, null, array('_null' => '--N/A--')); ?>
+                        <?php echo $this->formSelect('edit['. $approvalLink->getPrimaryKey() .'][currentState]',
+                                                     $approvalLink->currentState,
+                                                     null,
+                                                     array('_null' => '--N/A--')
+                                                     + $resultStatusStrings); ?>
                     </td>
                     <td>
-                        <?php echo $this->formSelect('nextAction', $approvalLink->nextAction->className, null,
-                                                     array_merge(array('_null' => '--Exit Chain--'),
-                                                                 $this->approvalActions)); ?>
+                        <?php
+                        $nextAction = $approvalLink->nextAction;
+                        if($nextAction != null) {
+                            $nextActionId = $approvalLink->nextAction->getPrimaryKey();
+                        } else {
+                            $nextActionId = '_null';
+                        }
+                        echo $this->formSelect('edit['. $approvalLink->getPrimaryKey() .'][nextAction]',
+                                               $nextActionId,
+                                               null,
+                                               array('_null' => '--Exit Chain--')
+                                               + $this->approvalChain->approvalActions->columnToArray('name', 'approvalActionId')); ?>
+                    </td>
+                    <td>
+                        <?php echo $this->formCheckbox('edit[' . $approvalLink->getPrimaryKey() . '][delete]'); ?>
                     </td>
                 </tr>
                 <?php } ?>
             </table>
+            <?php echo $this->formSubmit('submit', 'Update Links'); ?>
         </form>
     </div>
 
     <div id="manage_actions" style="display:none;">
-        <form>
+        <h2>Add New Action</h2>
+        <form action="/ApprovalChainManager/AddActionPost" method="post">
+            <?php echo $this->formHidden('chainId', $this->approvalChain->getPrimaryKey()); ?>
+            <div class="edit_approval_chain">
+                <label>
+                    Name: <?php echo $this->formText('name'); ?>
+                </label>
+                <label>
+                    Type: <?php echo $this->formSelect('type', null,
+                                                       array('class' => 'action_type_select'),
+                                                       $this->approvalActions); ?>
+                </label>
+                <div class="edit_approval_chain_specifics"></div>
+            </div>
+            <?php echo $this->formSubmit('submit', 'Create'); ?>
+        </form>
+        <h2>Edit Current Actions</h2>
+        <form action="/ApprovalChainManager/EditActionPost" method="post">
+            <?php echo $this->formHidden('chainId', $this->approvalChain->getPrimaryKey()); ?>
             <?php foreach ($this->approvalChain->approvalActions as $approvalAction) { ?>
-            <label>Name: <?php echo $this->formText('name[' . $approvalAction->getPrimaryKey() . ']', $approvalAction->name); ?></label>
-            <label>Type: <?php echo $this->formSelect('type[' . $approvalAction->getPrimaryKey() . ']', $approvalAction->className, null, $this->approvalActions); ?></label>
-            <?php include $approvalAction->getTable()->getEditTemplate(); ?>
+            <div class="edit_approval_chain">
+                <label>
+                    Name: <?php echo $this->formText('edit[' . $approvalAction->getPrimaryKey() . '][name]',
+                                                     $approvalAction->name); ?>
+                </label>
+                <label>
+                    Type: <?php echo $this->formSelect('edit[' . $approvalAction->getPrimaryKey() . '][type]',
+                                                       $approvalAction->className,
+                                                       array('class' => 'action_type_select'),
+                                                       $this->approvalActions); ?>
+                </label>
+                <label>
+                    Delete:
+                    <?php echo $this->formCheckbox('edit[' . $approvalAction->getPrimaryKey() . '][delete]'); ?>
+                </label>
+                <div class="edit_approval_chain_specifics">
+                    <?php include $approvalAction->getTable()->getEditTemplate(); ?>
+                </div>
+            </div>
             <?php } ?>
+            <?php echo $this->formSubmit('submit', 'Update'); ?>
         </form>
     </div>
 </div>
diff --git a/application/views/home.xhtml b/application/views/home.xhtml
new file mode 100755
index 00000000..f8506a05
--- /dev/null
+++ b/application/views/home.xhtml
@@ -0,0 +1,135 @@
+<div id="announcements" class="titled_box">
+    <div class="box_shadow_2">
+        <div class="tr"></div>
+        <div class="tl">
+            <h2>Announcements</h2>
+            <h3><em>User ID:</em> <?php echo Nmc_User::getInstance()->getUser()->getUserName(); ?></h3>
+        </div>
+        <div class="bl"></div>
+    </div>
+    <div class="content">
+        Welcome to Curriculum Action Request.  Items in your activity basket indicate.....
+    </div>
+</div>
+
+<div id="activity" class="titled_box">
+    <div class="box_shadow_2">
+        <div class="tr"></div>
+        <div class="tl">
+            <h2>Activity</h2>
+            <h3><em>Curent Roll:</em> Yourself</h3>
+        </div>
+        <div class="bl"></div>
+    </div>
+    <div class="content">
+        <?php if($this->myRequests->count() == 0) { ?>
+        <h2>You currently have no requests.</h2>
+        <?php } else { ?>
+        <table class="course_list">
+            <tr>
+                <th id="check">&#160;</th>
+                <th id="course">Course</th>
+                <th id="college">College</th>
+                <th id="type">Type</th>
+                <th id="approval_body">Approval Body</th>
+                <th id="status">Status</th>
+                <th id="view_edit">View/Edit</th>
+            </tr>
+            <?php
+            $row = 0;
+            foreach($this->myRequests as $request) {
+                $course = $request->getCourseGeneration();
+            ?>
+            <tr <?php echo (++$row % 2 ? 'class="odd"' : ''); ?>>
+                <td><input type="checkbox" /></td>
+                <td><?php echo $request->getCourseGeneration()->subject . ' '
+                             . $request->getCourseGeneration()->courseNumber
+                             . $request->getCourseGeneration()->courseLetter; ?></td>
+                <td>NONC</td>
+                <td><?php echo $request->type->name; ?></td>
+                <td><?php echo $request->getCurrentApprovalBody()->name; ?></td>
+                <td>
+                    <?php
+                    if ($request->complete == 'yes') {
+                        echo 'Complete - ' . $request->state;
+                    } else {
+                        echo $request->getCurrentAction()->name;
+                    }
+                    ?>
+                </td>
+                <td>
+                    <a href="/NewRequest/Load/<?php echo $request->getPrimaryKey(); ?>">
+                        View/Edit
+                    </a>
+                </td>
+            </tr>
+            <?php } ?>
+        </table>
+        <?php } ?>
+    </div>
+
+    <?php foreach($this->roles as $role) { ?>
+    <div class="box_shadow_2">
+        <div class="tr"></div>
+        <div class="tl">
+            <h2>Activity</h2>
+            <h3><em>Curent Roll:</em> <?php echo $role->name; ?></h3>
+        </div>
+        <div class="bl"></div>
+    </div>
+    <div class="content">
+        <?php if($role->getRequests()->count() == 0) { ?>
+        <h2>This role currently has no requests.</h2>
+        <?php } else { ?>
+        <form action="/Home/SubmitDecisions" method="post">
+            <table class="course_list">
+                <tr>
+                    <th id="check">&#160;</th>
+                    <th id="course">Course</th>
+                    <th id="college">College</th>
+                    <th id="type">Type</th>
+                    <th id="pending_action">Pending Action</th>
+                    <th id="status">Status</th>
+                    <th id="view_edit">View/Edit</th>
+                </tr>
+                <?php
+                $row = 0;
+                foreach($role->getRequests() as $request) {
+                    $course = $request->getCourseGeneration();
+                ?>
+                <tr <?php echo (++$row % 2 ? 'class="odd"' : ''); ?>>
+                    <td><input type="checkbox" /></td>
+                    <td><?php echo $request->getCourseGeneration()->subject . ' '
+                                 . $request->getCourseGeneration()->courseNumber
+                                 . $request->getCourseGeneration()->courseLetter; ?></td>
+                    <td>NONC</td>
+                    <td><?php echo $request->type->name; ?></td>
+                    <td><?php echo $request->getCurrentAction()->name; ?></td>
+                    <td>
+                        <?php
+                        if ($request->getCurrentAction()) {
+                            echo $this->formSelect('decisions[' . $request->getPrimaryKey() . ']',
+                                                   $request->getCurrentAction()->getUserDecision($request, Nmc_User::getInstance()->getUser()),
+                                                   array('class' => 'decision_selection'),
+                                                   array('_null' => "--Make a decision--")
+                                                   + $request->getCurrentAction()->getResultStatusStrings());
+                            //
+                        }
+                        ?>
+                    </td>
+                    <td>
+                        <a href="/NewRequest/Load/<?php echo $request->getPrimaryKey(); ?>">
+                            View/Edit
+                        </a>
+                    </td>
+                </tr>
+                <?php } ?>
+            </table>
+            <?php echo $this->formSubmit('submit', 'Submit Decisions'); ?>
+        </form>
+        <?php } ?>
+    </div>
+    <?php } ?>
+</div>
+
+<?php echo nl2br(Nmc_Registry_Session::getInstance()->loginError); ?>
\ No newline at end of file
diff --git a/application/views/my_home.xhtml b/application/views/my_home.xhtml
deleted file mode 100644
index 98adceba..00000000
--- a/application/views/my_home.xhtml
+++ /dev/null
@@ -1,111 +0,0 @@
-<div id="announcements" class="titled_box">
-    <div class="box_shadow_2">
-        <div class="tr"></div>
-        <div class="tl">
-            <h2>Announcements</h2>
-            <h3><em>User ID:</em> <?php echo Nmc_User::getInstance()->getUser()->getUserName(); ?></h3>
-        </div>
-        <div class="bl"></div>
-    </div>
-    <div class="content">
-        Welcome to Curriculum Action Request.  Items in your activity basket indicate.....
-    </div>
-</div>
-
-<div id="activity" class="titled_box">
-    <div class="box_shadow_2">
-        <div class="tr"></div>
-        <div class="tl">
-            <h2>Activity</h2>
-            <h3><em>Curent Roll:</em> Yourself</h3>
-        </div>
-        <div class="bl"></div>
-    </div>
-    <div class="content">
-        <?php if($this->myRequests->count() == 0) { ?>
-        <h2>You currently have no requests.</h2>
-        <?php } else { ?>
-        <table class="course_list">
-            <tr>
-                <th id="check">&#160;</th>
-                <th id="course">Course</th>
-                <th id="college">College</th>
-                <th id="type">Type</th>
-                <th id="status">Status</th>
-                <th id="view_edit">View/Edit</th>
-            </tr>
-            <?php
-            $row = 0;
-            foreach($this->myRequests as $request) {
-                $course = $request->getCourseGeneration();
-            ?>
-            <tr <?php echo (++$row % 2 ? 'class="odd"' : ''); ?>>
-                <td><input type="checkbox" /></td>
-                <td><?php echo $request->getCourseGeneration()->subject . ' '
-                             . $request->getCourseGeneration()->courseNumber
-                             . $request->getCourseGeneration()->courseLetter; ?></td>
-                <td>NONC</td>
-                <td><?php echo $request->type->name; ?></td>
-                <td><select><option>Submission</option></select></td>
-                <td>
-                    <a href="/NewRequest/Load/<?php echo $request->getPrimaryKey(); ?>">
-                        View/Edit
-                    </a>
-                </td>
-            </tr>
-            <?php } ?>
-        </table>
-        <?php } ?>
-    </div>
-
-    <?php foreach($this->roles as $role) { ?>
-    <div class="box_shadow_2">
-        <div class="tr"></div>
-        <div class="tl">
-            <h2>Activity</h2>
-            <h3><em>Curent Roll:</em> <?php echo $role->name; ?></h3>
-        </div>
-        <div class="bl"></div>
-    </div>
-    <div class="content">
-        <?php if($role->getRequests()->count() == 0) { ?>
-        <h2>This role currently has no requests.</h2>
-        <?php } else { ?>
-        <table class="course_list">
-            <tr>
-                <th id="check">&#160;</th>
-                <th id="course">Course</th>
-                <th id="college">College</th>
-                <th id="type">Type</th>
-                <th id="status">Status</th>
-                <th id="view_edit">View/Edit</th>
-            </tr>
-            <?php
-            $row = 0;
-            foreach($role->getRequests() as $request) {
-                $course = $request->getCourseGeneration();
-            ?>
-            <tr <?php echo (++$row % 2 ? 'class="odd"' : ''); ?>>
-                <td><input type="checkbox" /></td>
-                <td><?php echo $request->getCourseGeneration()->subject . ' '
-                             . $request->getCourseGeneration()->courseNumber
-                             . $request->getCourseGeneration()->courseLetter; ?></td>
-                <td>NONC</td>
-                <td><?php echo $request->type->name; ?></td>
-                <td><select><option>Submission</option></select></td>
-                <td>
-                    <a href="/NewRequest/Load/<?php echo $request->getPrimaryKey(); ?>">
-                        View/Edit
-                    </a>
-                </td>
-            </tr>
-            <?php } ?>
-        </table>
-        <?php } ?>
-    </div>
-    <?php } ?>
-</div>
-
-<?php print_r(array_keys($_SESSION['default'])); ?>
-
-<?php echo nl2br(Nmc_Registry_Session::getInstance()->loginError); ?>
\ No newline at end of file
diff --git a/document_root/css/approval_body_manager.css b/document_root/css/approval_body_manager.css
new file mode 100644
index 00000000..4983a917
--- /dev/null
+++ b/document_root/css/approval_body_manager.css
@@ -0,0 +1 @@
+@import "manager.css";
\ No newline at end of file
diff --git a/document_root/css/approval_chain_manager.css b/document_root/css/approval_chain_manager.css
index 95d7d071..c70450ec 100644
--- a/document_root/css/approval_chain_manager.css
+++ b/document_root/css/approval_chain_manager.css
@@ -1,11 +1,10 @@
-div#select_chain {
-    float: left;
-}
+@import "manager.css";
 
-div#select_chain ul {
-    list-style: none;
+div.edit_approval_chain {
+    border: 1px solid #ccc;
 }
 
-div#index_content div#edit_pane {
-    margin-left: 150px;
+div.edit_approval_chain_specifics {
+    margin: 5px;
+    border: 1px dashed #ccc;
 }
\ No newline at end of file
diff --git a/document_root/css/home.css b/document_root/css/home.css
new file mode 100755
index 00000000..e69de29b
diff --git a/document_root/css/manager.css b/document_root/css/manager.css
new file mode 100644
index 00000000..fbc9498f
--- /dev/null
+++ b/document_root/css/manager.css
@@ -0,0 +1,11 @@
+div#manager_menu {
+    float: left;
+}
+
+div#manager_menu ul {
+    list-style: none;
+}
+
+div#index_content div#manager_edit_pane {
+    margin-left: 150px;
+}
diff --git a/document_root/index.php b/document_root/index.php
index ba3bcdcf..4b89e539 100644
--- a/document_root/index.php
+++ b/document_root/index.php
@@ -1,15 +1,18 @@
 <?php
 
-require('./config.php');
+require './config.php';
 set_include_path(FRAMEWORK_PATH . '/library');
 set_include_path(get_include_path() . PATH_SEPARATOR . APPLICATION_PATH);
 set_include_path(get_include_path() . PATH_SEPARATOR . APPLICATION_PATH . '/library');
 set_include_path(get_include_path() . PATH_SEPARATOR . APPLICATION_PATH . '/models/rows');
 set_include_path(get_include_path() . PATH_SEPARATOR . APPLICATION_PATH . '/models/tables');
-require_once('Zend.php');
-spl_autoload_register(array('Zend', 'loadClass'));
+set_include_path(get_include_path() . PATH_SEPARATOR . PEAR_PATH);
+require_once('Zend/Loader.php');
+spl_autoload_register(array('Zend_Loader', 'loadClass'));
 spl_autoload_register(array('Nmc', 'loadApplicationClass'));
 
+Zend_Session::setSaveHandler(new Nmc_Session_SaveHandler_Memcached());
+
 //$appReg = Nmc_Registry_Application::getInstance();
 $db_config = array('host'      => $db_host,
                    'username'  => $db_user,
@@ -18,17 +21,35 @@ $db_config = array('host'      => $db_host,
 
 $db = Zend_Db::factory('PDO_MYSQL', $db_config);
 Zend_Db_Table::setDefaultAdapter($db);
-Zend::register('db', $db);
+Zend_Registry::set('db', $db);
+
+
+$cacheBackendOptions = array(
+);
+$cacheFrontendOptions = array(
+    'lifetime' => 600,
+    'automaticSerialization' => true
+);
+$cache = Zend_Cache::factory('Core', 'MemCached', $cacheFrontendOptions, $cacheBackendOptions);
+Zend_Registry::set('cache', $cache);
+
 
-$router = new Zend_Controller_RewriteRouter();
+
+
+$router = new Zend_Controller_Router_Rewrite();
 $default_route = new Zend_Controller_Router_Route(':controller/:action/:0/:1/:2/:3/:4/:5/:6/:7/:8/:9',
                                                   array(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL));
 $router->addRoute('compat_params', $default_route);
 
-$controller = Zend_Controller_Front::getInstance();
+$controller = Nmc_Controller_Front::getInstance();
 $controller->setRouter($router);
-$controller->setControllerDirectory(APPLICATION_PATH . '/controllers');
+$controller->addControllerDirectory(APPLICATION_PATH . '/controllers');
+$controller->addControllerDirectory(FRAMEWORK_PATH . '/controllers', 'framework');
+$controller->setNotFoundModule('framework');
+$controller->setNotFoundController('NotFound');
 $controller->throwExceptions(true);
+
+Zend_Session::start();
 $controller->dispatch();
 
 
diff --git a/document_root/javascript/Base.js b/document_root/javascript/Base.js
new file mode 100644
index 00000000..28123fd2
--- /dev/null
+++ b/document_root/javascript/Base.js
@@ -0,0 +1,106 @@
+/*
+	Base, version 1.0.2
+	Copyright 2006, Dean Edwards
+	License: http://creativecommons.org/licenses/LGPL/2.1/
+*/
+
+var Base = function() {
+	if (arguments.length) {
+		if (this == window) { // cast an object to this class
+			Base.prototype.extend.call(arguments[0], arguments.callee.prototype);
+		} else {
+			this.extend(arguments[0]);
+		}
+	}
+};
+
+Base.version = "1.0.2";
+
+Base.prototype = {
+	extend: function(source, value) {
+		var extend = Base.prototype.extend;
+		if (arguments.length == 2) {
+			var ancestor = this[source];
+			// overriding?
+			if ((ancestor instanceof Function) && (value instanceof Function) &&
+				ancestor.valueOf() != value.valueOf() && /\bbase\b/.test(value)) {
+				var method = value;
+			//	var _prototype = this.constructor.prototype;
+			//	var fromPrototype = !Base._prototyping && _prototype[source] == ancestor;
+				value = function() {
+					var previous = this.base;
+				//	this.base = fromPrototype ? _prototype[source] : ancestor;
+					this.base = ancestor;
+					var returnValue = method.apply(this, arguments);
+					this.base = previous;
+					return returnValue;
+				};
+				// point to the underlying method
+				value.valueOf = function() {
+					return method;
+				};
+				value.toString = function() {
+					return String(method);
+				};
+			}
+			return this[source] = value;
+		} else if (source) {
+			var _prototype = {toSource: null};
+			// do the "toString" and other methods manually
+			var _protected = ["toString", "valueOf"];
+			// if we are prototyping then include the constructor
+			if (Base._prototyping) _protected[2] = "constructor";
+			for (var i = 0; (name = _protected[i]); i++) {
+				if (source[name] != _prototype[name]) {
+					extend.call(this, name, source[name]);
+				}
+			}
+			// copy each of the source object's properties to this object
+			for (var name in source) {
+				if (!_prototype[name]) {
+					extend.call(this, name, source[name]);
+				}
+			}
+		}
+		return this;
+	},
+
+	base: function() {
+		// call this method from any other method to invoke that method's ancestor
+	}
+};
+
+Base.extend = function(_instance, _static) {
+	var extend = Base.prototype.extend;
+	if (!_instance) _instance = {};
+	// build the prototype
+	Base._prototyping = true;
+	var _prototype = new this;
+	extend.call(_prototype, _instance);
+	var constructor = _prototype.constructor;
+	_prototype.constructor = this;
+	delete Base._prototyping;
+	// create the wrapper for the constructor function
+	var klass = function() {
+		if (!Base._prototyping) constructor.apply(this, arguments);
+		this.constructor = klass;
+	};
+	klass.prototype = _prototype;
+	// build the class interface
+	klass.extend = this.extend;
+	klass.implement = this.implement;
+	klass.toString = function() {
+		return String(constructor);
+	};
+	extend.call(klass, _static);
+	// single instance
+	var object = constructor ? klass : _prototype;
+	// class initialisation
+	if (object.init instanceof Function) object.init();
+	return object;
+};
+
+Base.implement = function(_interface) {
+	if (_interface instanceof Function) _interface = _interface.prototype;
+	this.prototype.extend(_interface);
+};
diff --git a/document_root/javascript/approval_chain_manager.js b/document_root/javascript/approval_chain_manager.js
index 218faa2c..40a8c5de 100644
--- a/document_root/javascript/approval_chain_manager.js
+++ b/document_root/javascript/approval_chain_manager.js
@@ -1,16 +1,39 @@
-function loadApprovalChainManager()
+var actionTypeSelectAjaxResponder = AjaxClient.extend(
 {
-    loadXMLDoc('/ApprovalChainManager/GetActionList', saveActionList)
+    selectElement: null,
+
+    processResponse: function() {
+        var resultNodes = this.requestObject.responseXML.childNodes[0].childNodes;
+        var resultStrings = new Array();
+        for (var i = 0; i < resultNodes.length; i++) {
+            var resultNode = resultNodes[i];
+            resultStrings.push(resultNode.getAttribute("name"));
+        }
 
+        this.selectElement.options.length = 0;
+        for (var i = 0; i < resultStrings.length; i++) {
+            var resultString = resultStrings[i]
+            this.selectElement.add(new Option(resultString, resultString, false, false), null);
+        }
+    }
 
+});
+
+function loadApprovalChainManager()
+{
     var actionSelectElements = getElementsByClass('actionSelectElement');
     for(var i = 0; i < actionSelectElements.length; i++) {
         var actionSelectElement = actionSelectElements[i];
-        actionSelectElement.onchange = function() {updateActionResults(this);};
+        actionSelectElement.onchange = updateActionResults;
     }
 
     document.getElementById('select_manage_links').onclick = selectLinksOrActions;
     document.getElementById('select_manage_actions').onclick = selectLinksOrActions;
+
+    var actionTypeSelects = getElementsByClass('action_type_select');
+    for (var i = 0; i < actionTypeSelects.length; i++) {
+        actionTypeSelects[i].onchange = updateEditActionDetails;
+    }
 }
 
 addLoadEvent(loadApprovalChainManager);
@@ -59,28 +82,54 @@ function saveActionList(response)
 }
 
 
-function updateActionResults(actionSelectElement)
+function updateActionResults()
 {
-    var actionResultElement = actionSelectElement.parentNode;
+    var actionResultElement = this.parentNode;
     for(actionResultElement = actionResultElement.nextSibling;
         actionResultElement.nodeName != 'td';
         actionResultElement = actionResultElement.nextSibling);
 
     actionResultElement = actionResultElement.getElementsByTagName('select').item(0);
-    actionResultElement.options.length = 0;
 
-    if (actionSelectElement.value == '_null') {
+    if (this.value == '_null') {
+        actionResultElement.options.length = 0;
         actionResultElement.add(new Option('--N/A--', '_null', false, false), null);
+    } else {
+        var responder = new actionTypeSelectAjaxResponder();
+        responder.selectElement = actionResultElement;
+        responder.sendRequest('/ApprovalChainManager/GetActionDetailXML/' + this.value);
+    }
+}
+
+var actionTypeSelectBeingUpdated;
+function updateEditActionDetails()
+{
+    actionTypeSelectBeingUpdated = this;
+    var url = '/ApprovalChainManager/GetActionEditXhtml/' + this.value;
+    loadXMLDoc(url, updateEditActionDetailsResponse);
+}
+
+function updateEditActionDetailsResponse()
+{
+    if (req.readyState != 4) {
+        return;
+    }
+    if (req.status != 200) {
         return;
     }
 
-    for (var i = 0; i < _serverActionList.length; i++) {
-        if (_serverActionList[i].className == actionSelectElement.value) {
-            for (var j = 0; j < _serverActionList[i].results.length; j++) {
-                var resultName = _serverActionList[i].results[j];
-                actionResultElement.add(new Option(resultName, resultName, false, false), null);
-            }
-        }
+    var detailsDiv = actionTypeSelectBeingUpdated.parentNode.nextSibling.nextSibling;
+    while (detailsDiv.childNodes.length > 0) {
+        detailsDiv.removeChild(detailsDiv.childNodes[0]);
+    }
+
+    if(!req.responseXML) {
+        return;
+    }
+
+    var editXHTML = req.responseXML.childNodes[1].childNodes[0];
+    for (var i = 0; i < editXHTML.childNodes.length; i++) {
+        detailsDiv.appendChild(editXHTML.childNodes[i]);
     }
 
 }
\ No newline at end of file
diff --git a/document_root/javascript/home.js b/document_root/javascript/home.js
new file mode 100644
index 00000000..81239e0f
--- /dev/null
+++ b/document_root/javascript/home.js
@@ -0,0 +1,20 @@
+function onLoadHome()
+{
+    var decisionSelectBoxes = getElementsByClass('decision_selection');
+    for(var i = 0; i < decisionSelectBoxes.length; i++) {
+        var decisionSelectBox = decisionSelectBoxes[i];
+        decisionSelectBox.onchange = decisionSelectHandler;
+    }
+}
+
+addLoadEvent(onLoadHome);
+
+
+
+
+
+function decisionSelectHandler()
+{
+    // ???
+}
+
diff --git a/document_root/javascript/index.js b/document_root/javascript/index.js
index 15cabed1..d581b016 100644
--- a/document_root/javascript/index.js
+++ b/document_root/javascript/index.js
@@ -47,6 +47,163 @@ function getElementsByClass(searchClass,node,tag) {
 //end borrowed code
 
 
+
+/*
+	Base, version 1.0.2
+	Copyright 2006, Dean Edwards
+	License: http://creativecommons.org/licenses/LGPL/2.1/
+*/
+
+var Base = function() {
+	if (arguments.length) {
+		if (this == window) { // cast an object to this class
+			Base.prototype.extend.call(arguments[0], arguments.callee.prototype);
+		} else {
+			this.extend(arguments[0]);
+		}
+	}
+};
+
+Base.version = "1.0.2";
+
+Base.prototype = {
+	extend: function(source, value) {
+		var extend = Base.prototype.extend;
+		if (arguments.length == 2) {
+			var ancestor = this[source];
+			// overriding?
+			if ((ancestor instanceof Function) && (value instanceof Function) &&
+				ancestor.valueOf() != value.valueOf() && /\bbase\b/.test(value)) {
+				var method = value;
+			//	var _prototype = this.constructor.prototype;
+			//	var fromPrototype = !Base._prototyping && _prototype[source] == ancestor;
+				value = function() {
+					var previous = this.base;
+				//	this.base = fromPrototype ? _prototype[source] : ancestor;
+					this.base = ancestor;
+					var returnValue = method.apply(this, arguments);
+					this.base = previous;
+					return returnValue;
+				};
+				// point to the underlying method
+				value.valueOf = function() {
+					return method;
+				};
+				value.toString = function() {
+					return String(method);
+				};
+			}
+			return this[source] = value;
+		} else if (source) {
+			var _prototype = {toSource: null};
+			// do the "toString" and other methods manually
+			var _protected = ["toString", "valueOf"];
+			// if we are prototyping then include the constructor
+			if (Base._prototyping) _protected[2] = "constructor";
+			for (var i = 0; (name = _protected[i]); i++) {
+				if (source[name] != _prototype[name]) {
+					extend.call(this, name, source[name]);
+				}
+			}
+			// copy each of the source object's properties to this object
+			for (var name in source) {
+				if (!_prototype[name]) {
+					extend.call(this, name, source[name]);
+				}
+			}
+		}
+		return this;
+	},
+
+	base: function() {
+		// call this method from any other method to invoke that method's ancestor
+	}
+};
+
+Base.extend = function(_instance, _static) {
+	var extend = Base.prototype.extend;
+	if (!_instance) _instance = {};
+	// build the prototype
+	Base._prototyping = true;
+	var _prototype = new this;
+	extend.call(_prototype, _instance);
+	var constructor = _prototype.constructor;
+	_prototype.constructor = this;
+	delete Base._prototyping;
+	// create the wrapper for the constructor function
+	var klass = function() {
+		if (!Base._prototyping) constructor.apply(this, arguments);
+		this.constructor = klass;
+	};
+	klass.prototype = _prototype;
+	// build the class interface
+	klass.extend = this.extend;
+	klass.implement = this.implement;
+	klass.toString = function() {
+		return String(constructor);
+	};
+	extend.call(klass, _static);
+	// single instance
+	var object = constructor ? klass : _prototype;
+	// class initialisation
+	if (object.init instanceof Function) object.init();
+	return object;
+};
+
+Base.implement = function(_interface) {
+	if (_interface instanceof Function) _interface = _interface.prototype;
+	this.prototype.extend(_interface);
+};
+
+// End borrowed code
+
+
+var AjaxClient = Base.extend(
+{
+    requestObject: null,
+    method: 'get',
+
+    constructor: function()
+    {
+        if (window.XMLHttpRequest) {
+            this.requestObject = new XMLHttpRequest();
+        } else if (window.ActiveXObject) {
+            this.requestObject = new ActiveXObject("Microsoft.XMLHTTP");
+        }
+
+        if (this.requestObject) {
+            this.requestObject.onreadystatechange = this;
+        }
+    },
+
+    sendRequest: function(requestURL)
+    {
+        this.requestObject.open("GET", requestURL, true);
+        this.requestObject.send();
+    },
+
+    handleEvent: function(e)
+    {
+        if (this.requestObject.readyState != 4) {
+            return;
+        }
+        if (this.requestObject.status != 200) {
+            return;
+        }
+
+        this.processResponse();
+    },
+
+    processResponse: function()
+    {
+        alert(this.requestObject);
+    }
+});
+
+
+
+
+
 function loadXMLDoc(url, handler_function)
 {
     // branch for native XMLHttpRequest object
@@ -59,9 +216,9 @@ function loadXMLDoc(url, handler_function)
     } else if (window.ActiveXObject) {
         req = new ActiveXObject("Microsoft.XMLHTTP");
         if (req) {
-            eval( 'req.onreadystatechange = ' + handler_function +';' );
+            req.onreadystatechange = handler_function;
             req.open("GET", url, true);
             req.send();
         }
     }
-}
\ No newline at end of file
+}
-- 
GitLab