diff --git a/include/ajax.reports.php b/include/ajax.reports.php
index e9e660a8c69b36f0c876ca63724b8735789aae94..b9b5362f3ba2ff9b5034df6ce41db38af5fcc263 100644
--- a/include/ajax.reports.php
+++ b/include/ajax.reports.php
@@ -42,11 +42,11 @@ class OverviewReportAjaxAPI extends AjaxController {
         $groups = array(
             "dept" => array(
                 "table" => DEPT_TABLE,
-                "pk" => "dept_id",
-                "sort" => 'T1.dept_name',
-                "fields" => 'T1.dept_name',
+                "pk" => "id",
+                "sort" => 'T1.name',
+                "fields" => 'T1.name',
                 "headers" => array(__('Department')),
-                "filter" => ('T1.dept_id IN ('.implode(',', db_input($thisstaff->getDepts())).')')
+                "filter" => ('T1.id IN ('.implode(',', db_input($thisstaff->getDepts())).')')
             ),
             "topic" => array(
                 "table" => TOPIC_TABLE,
diff --git a/include/class.dept.php b/include/class.dept.php
index 6e819e087f8785f1b1724a9d033c00ebd669954f..d80ceb28aa44c2aa3db88a423dc6fecbec858d13 100644
--- a/include/class.dept.php
+++ b/include/class.dept.php
@@ -18,22 +18,35 @@ class Dept extends VerySimpleModel {
 
     static $meta = array(
         'table' => DEPT_TABLE,
-        'pk' => array('dept_id'),
+        'pk' => array('id'),
         'joins' => array(
+            'email' => array(
+                'constraint' => array('email_id' => 'EmailModel.email_id'),
+                'null' => true,
+             ),
             'sla' => array(
                 'constraint' => array('sla_id' => 'SLA.sla_id'),
                 'null' => true,
             ),
             'manager' => array(
+                'null' => true,
                 'constraint' => array('manager_id' => 'Staff.staff_id'),
             ),
+            'members' => array(
+                'null' => true,
+                'list' => true,
+                'reverse' => 'Staff.dept',
+            ),
             'groups' => array(
+                'null' => true,
+                'list' => true,
                 'reverse' => 'GroupDeptAccess.dept'
             ),
         ),
     );
 
     var $members;
+    var $_groupids;
     var $config;
 
     var $template;
@@ -55,17 +68,17 @@ class Dept extends VerySimpleModel {
     }
 
     function getId() {
-        return $this->dept_id;
+        return $this->id;
     }
 
     function getName() {
-        return $this->dept_name;
+        return $this->name;
     }
 
     function getLocalName($locale=false) {
         $tag = $this->getTranslateTag();
         $T = CustomDataTranslation::translate($tag);
-        return $T != $tag ? $T : $this->dept_name;
+        return $T != $tag ? $T : $this->name;
     }
     static function getLocalById($id, $subtag, $default) {
         $tag = _H(sprintf('dept.%s.%s', $subtag, $id));
@@ -101,7 +114,7 @@ class Dept extends VerySimpleModel {
                 ->filter(Q::any(array(
                     'dept_id' => $this->getId(),
                     new Q(array(
-                        'group__depts__dept_id' => $this->getId(),
+                        'group__depts__id' => $this->getId(),
                         'group__depts__group_membership' => self::ALERTS_DEPT_AND_GROUPS,
                     )),
                     'staff_id' => $this->manager_id
@@ -179,7 +192,7 @@ class Dept extends VerySimpleModel {
     }
 
     function getSignature() {
-        return $this->dept_signature;
+        return $this->signature;
     }
 
     function canAppendSignature() {
@@ -227,7 +240,12 @@ class Dept extends VerySimpleModel {
     }
 
     function getHashtable() {
-        return $this->ht;
+        $ht = $this->ht;
+        if (static::$meta['joins'])
+            foreach (static::$meta['joins'] as $k => $v)
+                unset($ht[$k]);
+
+        return $ht;
     }
 
     function getInfo() {
@@ -235,18 +253,19 @@ class Dept extends VerySimpleModel {
     }
 
     function getAllowedGroups() {
-        if ($this->groups)
-            return $this->groups;
 
-        $groups = GroupDept::objects()
-            ->filter(array('dept_id' => $this->getId()))
-            ->values_flat('group_id');
+        if (!isset($this->_groupids)) {
+            $this->_groupids = array();
 
-        foreach ($groups as $row) {
-            list($id) = $row;
-            $this->groups[] = $id;
+            $groups = GroupDeptAccess::objects()
+                ->filter(array('dept_id' => $this->getId()))
+                ->values_flat('group_id');
+
+            foreach ($groups as $row)
+                $this->_groupids[] = $row[0];
         }
-        return $this->groups;
+
+        return $this->_groupids;
     }
 
     function updateGroups($groups_ids) {
@@ -292,7 +311,7 @@ class Dept extends VerySimpleModel {
 
         parent::delete();
         $id = $this->getId();
-        $sql='DELETE FROM '.DEPT_TABLE.' WHERE dept_id='.db_input($id).' LIMIT 1';
+        $sql='DELETE FROM '.DEPT_TABLE.' WHERE id='.db_input($id).' LIMIT 1';
         if(db_query($sql) && ($num=db_affected_rows())) {
             // DO SOME HOUSE CLEANING
             //Move tickets to default Dept. TODO: Move one ticket at a time and send alerts + log notes.
@@ -322,8 +341,8 @@ class Dept extends VerySimpleModel {
     /*----Static functions-------*/
 	static function getIdByName($name) {
         $row = static::objects()
-            ->filter(array('dept_name'=>$name))
-            ->values_flat('dept_id')
+            ->filter(array('name'=>$name))
+            ->values_flat('id')
             ->first();
 
         return $row ? $row[0] : 0;
@@ -343,36 +362,51 @@ class Dept extends VerySimpleModel {
     }
 
     static function getDepartments( $criteria=null) {
+        static $depts = null;
+
+        if (!isset($depts) || $criteria) {
+            $depts = array();
+            $query = self::objects();
+            if (isset($criteria['publiconly']))
+                $query->filter(array(
+                            'ispublic' => ($criteria['publiconly'] ? 1 : 0)));
+
+            if ($manager=$criteria['manager'])
+                $query->filter(array(
+                            'manager_id' => is_object($manager)?$manager->getId():$manager));
+
+            $query->order_by('name')
+                ->values_flat('id', 'name');
+
+            $names = array();
+            foreach ($query as $row)
+                $names[$row[0]] = $row[1];
+
+            // Fetch local names
+            foreach (CustomDataTranslation::getDepartmentNames(array_keys($names)) as $id=>$name) {
+                // Translate the department
+                $names[$id] = $name;
+            }
 
-        $depts = self::objects();
-        if ($criteria['publiconly'])
-            $depts->filter(array('public' => 1));
-
-        if ($manager=$criteria['manager'])
-            $depts->filter(array('manager_id' => is_object($manager)?$manager->getId():$manager));
-
-        $depts->order_by('dept_name')
-            ->values_flat('dept_id', 'dept_name');
+            if ($criteria)
+                return $names;
 
-        $names = array();
-        foreach ($depts as $row) {
-            list($id, $name) = $row;
-            $names[$id] = $name;
+            $depts = $names;
         }
 
-        // Fetch local names
-        foreach (CustomDataTranslation::getDepartmentNames(array_keys($names)) as $id=>$name) {
-            // Translate the department
-            $names[$id] = $name;
-        }
-        return $names;
+        return $depts;
     }
 
-    function getPublicDepartments() {
-        return self::getDepartments(array('publiconly'=>true));
+    static function getPublicDepartments() {
+        static $depts =null;
+
+        if (!$depts)
+            $depts = self::getDepartments(array('publiconly'=>true));
+
+        return $depts;
     }
 
-    static function create($vars, &$errors=array()) {
+    static function create($vars=false, &$errors=array()) {
         $dept = parent::create($vars);
         $dept->created = SqlFunction::NOW();
         return $dept;
@@ -393,7 +427,7 @@ class Dept extends VerySimpleModel {
     function update($vars, &$errors) {
         global $cfg;
 
-        if (isset($this->dept_id) && $this->getId() != $vars['id'])
+        if (isset($this->id) && $this->getId() != $vars['id'])
             $errors['err']=__('Missing or invalid Dept ID (internal error).');
 
         if (!$vars['name']) {
@@ -401,7 +435,7 @@ class Dept extends VerySimpleModel {
         } elseif (strlen($vars['name'])<4) {
             $errors['name']=__('Name is too short.');
         } elseif (($did=static::getIdByName($vars['name']))
-                && (!isset($this->dept_id) || $did!=$this->getId())) {
+                && (!isset($this->id) || $did!=$this->getId())) {
             $errors['name']=__('Department already exists');
         }
 
@@ -418,8 +452,8 @@ class Dept extends VerySimpleModel {
         $this->sla_id = isset($vars['sla_id'])?$vars['sla_id']:0;
         $this->autoresp_email_id = isset($vars['autoresp_email_id'])?$vars['autoresp_email_id']:0;
         $this->manager_id = $vars['manager_id']?$vars['manager_id']:0;
-        $this->dept_name = Format::striptags($vars['name']);
-        $this->dept_signature = Format::sanitize($vars['signature']);
+        $this->name = Format::striptags($vars['name']);
+        $this->signature = Format::sanitize($vars['signature']);
         $this->group_membership = $vars['group_membership'];
         $this->ticket_auto_response = isset($vars['ticket_auto_response'])?$vars['ticket_auto_response']:1;
         $this->message_auto_response = isset($vars['message_auto_response'])?$vars['message_auto_response']:1;
@@ -427,7 +461,7 @@ class Dept extends VerySimpleModel {
         if ($this->save())
             return $this->updateSettings($vars);
 
-        if (isset($this->dept_id))
+        if (isset($this->id))
             $errors['err']=sprintf(__('Unable to update %s.'), __('this department'))
                .' '.__('Internal error occurred');
         else
@@ -445,7 +479,7 @@ class GroupDeptAccess extends VerySimpleModel {
         'pk' => array('dept_id', 'group_id'),
         'joins' => array(
             'dept' => array(
-                'constraint' => array('dept_id' => 'Dept.dept_id'),
+                'constraint' => array('dept_id' => 'Dept.id'),
             ),
             'group' => array(
                 'constraint' => array('group_id' => 'Group.group_id'),
diff --git a/include/class.staff.php b/include/class.staff.php
index 8a79df61e5f5603075b627049f4a3e8ce3cfe8d7..473dc42d23e82616e15890cfe68dfaea58508a79 100644
--- a/include/class.staff.php
+++ b/include/class.staff.php
@@ -31,7 +31,7 @@ implements AuthenticatedUser {
         'select_related' => array('group'),
         'joins' => array(
             'dept' => array(
-                'constraint' => array('dept_id' => 'Dept.dept_id'),
+                'constraint' => array('dept_id' => 'Dept.id'),
             ),
             'group' => array(
                 'constraint' => array('group_id' => 'Group.group_id'),
@@ -202,28 +202,30 @@ implements AuthenticatedUser {
 
     function getDepartments() {
 
-        if (isset($this->departments))
-            return $this->departments;
-
-        // Departments the staff is "allowed" to access...
-        // based on the group they belong to + user's primary dept + user's managed depts.
-        $dept_ids = array();
-        $depts = Dept::objects()
-            ->filter(Q::any(array(
-                'dept_id' => $this->dept_id,
-                'groups__group_id' => $this->group_id,
-                'manager_id' => $this->getId(),
-            )))
-            ->values_flat('dept_id');
-
-        foreach ($depts as $row) {
-            list($id) = $row;
-            $dept_ids[] = $id;
-        }
-        if (!$dept_ids) { //Neptune help us! (fallback)
-            $dept_ids = array_merge($this->getGroup()->getDepartments(), array($this->getDeptId()));
+        if (!isset($this->departments)) {
+
+            // Departments the staff is "allowed" to access...
+            // based on the group they belong to + user's primary dept + user's managed depts.
+            $dept_ids = array();
+            $depts = Dept::objects()
+                ->filter(Q::any(array(
+                    'id' => $this->dept_id,
+                    'groups__group_id' => $this->group_id,
+                    'manager_id' => $this->getId(),
+                )))
+                ->values_flat('id');
+
+            foreach ($depts as $row)
+                $dept_ids[] = $row[0];
+
+            if (!$dept_ids) { //Neptune help us! (fallback)
+                $dept_ids = array_merge($this->getGroup()->getDepartments(), array($this->getDeptId()));
+            }
+
+            $this->departments = array_filter(array_unique($dept_ids));
         }
-        return $this->departments = array_filter(array_unique($dept_ids));
+
+        return $this->departments;
     }
 
     function getDepts() {
diff --git a/include/class.ticket.php b/include/class.ticket.php
index 5bdec7646de19b257870924cdfdcdf90b8bddb6f..8422e8eef42ca79c87a53ef894911f2b121786dc 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -51,7 +51,7 @@ class TicketModel extends VerySimpleModel {
                 'null' => true,
             ),
             'dept' => array(
-                'constraint' => array('dept_id' => 'Dept.dept_id'),
+                'constraint' => array('dept_id' => 'Dept.id'),
             ),
             'sla' => array(
                 'constraint' => array('sla_id' => 'SlaModel.id'),
diff --git a/include/class.topic.php b/include/class.topic.php
index 36df233a187841e11227a2961dc920a34c2aed2e..8bc814c8dd9afe512db91c7c4020f7b7ba09a3c9 100644
--- a/include/class.topic.php
+++ b/include/class.topic.php
@@ -40,6 +40,12 @@ class Topic extends VerySimpleModel {
                     'page_id' => 'Page.id',
                 ),
             ),
+            'dept' => array(
+                'null' => true,
+                'constraint' => array(
+                    'dept_id' => 'Dept.id',
+                ),
+            ),
             'priority' => array(
                 'null' => true,
                 'constraint' => array(
diff --git a/include/client/tickets.inc.php b/include/client/tickets.inc.php
index 58ac63af651345554c0f0ab120727179ad80af0c..8ebae5be121324e0a2221a51d66c0c65e6684b96 100644
--- a/include/client/tickets.inc.php
+++ b/include/client/tickets.inc.php
@@ -25,7 +25,7 @@ if(isset($_REQUEST['status'])) { //Query string status has nothing to do with th
 }
 
 $sortOptions=array('id'=>'`number`', 'subject'=>'cdata.subject',
-                    'status'=>'status.name', 'dept'=>'dept_name','date'=>'ticket.created');
+                    'status'=>'status.name', 'dept'=>'dept.name','date'=>'ticket.created');
 $orderWays=array('DESC'=>'DESC','ASC'=>'ASC');
 //Sorting options...
 $order_by=$order=null;
@@ -46,7 +46,7 @@ $$x=' class="'.strtolower($order).'" ';
 
 $qselect='SELECT ticket.ticket_id,ticket.`number`,ticket.dept_id,isanswered, '
     .'dept.ispublic, cdata.subject,'
-    .'dept_name, status.name as status, status.state, ticket.source, ticket.created ';
+    .'dept.name as dept_name, status.name as status, status.state, ticket.source, ticket.created ';
 
 $qfrom='FROM '.TICKET_TABLE.' ticket '
       .' LEFT JOIN '.TICKET_STATUS_TABLE.' status
diff --git a/include/i18n/en_US/department.yaml b/include/i18n/en_US/department.yaml
index 34d135a7d00c6859d7c92d3d6a7586e5d622447a..1ad9aa4c963bea220616063e86d333074cc9097a 100644
--- a/include/i18n/en_US/department.yaml
+++ b/include/i18n/en_US/department.yaml
@@ -12,23 +12,23 @@
 # The very first group listed in this document will be the primary
 # department of the initial staff member -- the administrator.
 ---
-- dept_id: 1
-  dept_name: Support
-  dept_signature: |
+- id: 1
+  name: Support
+  signature: |
     Support Department
   ispublic: 1
   group_membership: 1
 
-- dept_id: 2
-  dept_name: Sales
-  dept_signature: |
+- id: 2
+  name: Sales
+  signature: |
     Sales and Customer Retention
   ispublic: 1
   sla_id: 1
   group_membership: 1
 
-- dept_id: 3
-  dept_name: Maintenance
+- id: 3
+  name: Maintenance
   dept_signature: |
     Maintenance Department
   ispublic: 0
diff --git a/include/staff/cannedresponse.inc.php b/include/staff/cannedresponse.inc.php
index ad0d784fb5e0babcce5366938c7d0d5516dbe0fa..57276a6df94fbb504869a5213631005a515a108b 100644
--- a/include/staff/cannedresponse.inc.php
+++ b/include/staff/cannedresponse.inc.php
@@ -56,9 +56,8 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
                 <select name="dept_id">
                     <option value="0">&mdash; <?php echo __('All Departments');?> &mdash;</option>
                     <?php
-                    $sql='SELECT dept_id, dept_name FROM '.DEPT_TABLE.' dept ORDER by dept_name';
-                    if(($res=db_query($sql)) && db_num_rows($res)) {
-                        while(list($id,$name)=db_fetch_row($res)) {
+                    if (($depts=Dept::getDepartments())) {
+                        foreach($depts as $id => $name) {
                             $selected=($info['dept_id'] && $id==$info['dept_id'])?'selected="selected"':'';
                             echo sprintf('<option value="%d" %s>%s</option>',$id,$selected,$name);
                         }
diff --git a/include/staff/cannedresponses.inc.php b/include/staff/cannedresponses.inc.php
index fe63868ba71655d7f596961a52abcf2e33593c66..8f729bb0cb68f5fb03680e62326b229cb77c5b4a 100644
--- a/include/staff/cannedresponses.inc.php
+++ b/include/staff/cannedresponses.inc.php
@@ -2,7 +2,7 @@
 if(!defined('OSTSCPINC') || !$thisstaff) die('Access Denied');
 
 $qstr='';
-$sql='SELECT canned.*, count(attach.file_id) as files, dept.dept_name as department '.
+$sql='SELECT canned.*, count(attach.file_id) as files, dept.name as department '.
      ' FROM '.CANNED_TABLE.' canned '.
      ' LEFT JOIN '.DEPT_TABLE.' dept ON (dept.dept_id=canned.dept_id) '.
      ' LEFT JOIN '.ATTACHMENT_TABLE.' attach
diff --git a/include/staff/departments.inc.php b/include/staff/departments.inc.php
index ba2d04707bc23d6c699951a048ad75d6fe07dcc1..20018b8dabde7baa4df3475a0951cd8681dca5f6 100644
--- a/include/staff/departments.inc.php
+++ b/include/staff/departments.inc.php
@@ -1,50 +1,47 @@
 <?php
-if(!defined('OSTADMININC') || !$thisstaff->isAdmin()) die('Access Denied');
+if (!defined('OSTADMININC') || !$thisstaff->isAdmin())
+    die('Access Denied');
 
 $qstr='';
-$sql='SELECT dept.dept_id,dept_name,email.email_id,email.email,email.name as email_name,ispublic,count(staff.staff_id) as users '.
-     ',CONCAT_WS(" ",mgr.firstname,mgr.lastname) as manager,mgr.staff_id as manager_id,dept.created,dept.updated  FROM '.DEPT_TABLE.' dept '.
-     ' LEFT JOIN '.STAFF_TABLE.' mgr ON dept.manager_id=mgr.staff_id '.
-     ' LEFT JOIN '.EMAIL_TABLE.' email ON dept.email_id=email.email_id '.
-     ' LEFT JOIN '.STAFF_TABLE.' staff ON dept.dept_id=staff.dept_id ';
+$sortOptions=array(
+    'name' => 'name',
+    'type' => 'ispublic',
+    'members'=> 'members_count',
+    'email'=> 'email__name',
+    'manager'=>'manager__lastname'
+    );
 
-$sql.=' WHERE 1';
-$sortOptions=array('name'=>'dept.dept_name','type'=>'ispublic','users'=>'users','email'=>'email_name, email.email','manager'=>'manager');
-$orderWays=array('DESC'=>'DESC','ASC'=>'ASC');
-$sort=($_REQUEST['sort'] && $sortOptions[strtolower($_REQUEST['sort'])])?strtolower($_REQUEST['sort']):'name';
-//Sorting options...
-if($sort && $sortOptions[$sort]) {
-    $order_column =$sortOptions[$sort];
+$orderWays = array('DESC'=>'DESC', 'ASC'=>'ASC');
+$sort = ($_REQUEST['sort'] && $sortOptions[strtolower($_REQUEST['sort'])]) ? strtolower($_REQUEST['sort']) : 'name';
+if ($sort && $sortOptions[$sort]) {
+    $order_column = $sortOptions[$sort];
 }
-$order_column=$order_column?$order_column:'dept.dept_name';
 
-if($_REQUEST['order'] && $orderWays[strtoupper($_REQUEST['order'])]) {
-    $order=$orderWays[strtoupper($_REQUEST['order'])];
+$order_column = $order_column ? $order_column : 'name';
+
+if ($_REQUEST['order'] && isset($orderWays[strtoupper($_REQUEST['order'])])) {
+    $order = $orderWays[strtoupper($_REQUEST['order'])];
+} else {
+    $order = 'ASC';
 }
-$order=$order?$order:'ASC';
 
-if($order_column && strpos($order_column,',')){
+if ($order_column && strpos($order_column,',')) {
     $order_column=str_replace(','," $order,",$order_column);
 }
 $x=$sort.'_sort';
 $$x=' class="'.strtolower($order).'" ';
-$order_by="$order_column $order ";
-
+$page = ($_GET['p'] && is_numeric($_GET['p'])) ? $_GET['p'] : 1;
+$count = Dept::objects()->count();
+$pageNav = new Pagenate($count, $page, PAGE_LIMIT);
+$_qstr = $qstr.'&sort='.urlencode($_REQUEST['sort']).'&order='.urlencode($_REQUEST['order']);
+$pageNav->setURL('departments.php', $_qstr);
+$showing = $pageNav->showing().' '._N('department', 'departments', $count);
 $qstr.='&order='.($order=='DESC'?'ASC':'DESC');
-
-$query="$sql GROUP BY dept.dept_id ORDER BY $order_by";
-$res=db_query($query);
-if($res && ($num=db_num_rows($res)))
-    $showing=sprintf(_N('Showing %d department', 'Showing %d departments',
-        $num),$num);
-else
-    $showing=__('No departments found!');
-
 ?>
 <div class="pull-left" style="width:700px;padding-top:5px;">
  <h2><?php echo __('Departments');?></h2>
  </div>
-<div class="pull-left flush-right" style="padding-top:5px;padding-right:5px;">
+<div class="pull-right flush-right" style="padding-top:5px;padding-right:5px;">
     <b><a href="departments.php?a=add" class="Icon newDepartment"><?php echo __('Add New Department');?></a></b></div>
 <div class="clear"></div>
 <form action="departments.php" method="POST" name="depts">
@@ -56,61 +53,76 @@ else
     <thead>
         <tr>
             <th width="7px">&nbsp;</th>
-            <th width="180"><a <?php echo $name_sort; ?> href="departments.php?<?php echo $qstr; ?>&sort=name"><?php echo __('Name');?></a></th>
+            <th width="200"><a <?php echo $name_sort; ?> href="departments.php?<?php echo $qstr; ?>&sort=name"><?php echo __('Name');?></a></th>
             <th width="80"><a  <?php echo $type_sort; ?> href="departments.php?<?php echo $qstr; ?>&sort=type"><?php echo __('Type');?></a></th>
-            <th width="70"><a  <?php echo $users_sort; ?>href="departments.php?<?php echo $qstr; ?>&sort=users"><?php echo __('Users');?></a></th>
+            <th width="70"><a  <?php echo $members_sort; ?>href="departments.php?<?php echo $qstr; ?>&sort=members"><?php echo __('Members');?></a></th>
             <th width="300"><a  <?php echo $email_sort; ?> href="departments.php?<?php echo $qstr; ?>&sort=email"><?php echo __('Email Address');?></a></th>
-            <th width="200"><a  <?php echo $manager_sort; ?> href="departments.php?<?php echo $qstr; ?>&sort=manager"><?php echo __('Department Manager');?></a></th>
+            <th width="180"><a  <?php echo $manager_sort; ?> href="departments.php?<?php echo $qstr; ?>&sort=manager"><?php echo __('Manager');?></a></th>
         </tr>
     </thead>
     <tbody>
     <?php
-        $total=0;
-        $ids=($errors && is_array($_POST['ids']))?$_POST['ids']:null;
-        if($res && db_num_rows($res)):
+        $ids= ($errors && is_array($_POST['ids'])) ? $_POST['ids'] : null;
+        if ($count) {
+            $depts = Dept::objects()
+                ->annotate(array(
+                        'members_count' => SqlAggregate::COUNT('members', true),
+                ))
+                ->order_by(sprintf('%s%s',
+                            strcasecmp($order, 'DESC') ? '' : '-',
+                            $order_column))
+                ->limit($pageNav->getLimit())
+                ->offset($pageNav->getStart());
             $defaultId=$cfg->getDefaultDeptId();
             $defaultEmailId = $cfg->getDefaultEmail()->getId();
             $defaultEmailAddress = (string) $cfg->getDefaultEmail();
-            while ($row = db_fetch_array($res)) {
+            foreach ($depts as $dept) {
+                $id = $dept->getId();
                 $sel=false;
-                if($ids && in_array($row['dept_id'],$ids))
+                if($ids && in_array($dept->getId(), $ids))
                     $sel=true;
 
-                if ($row['email_id'])
-                    $row['email']=$row['email_name']?($row['email_name'].' <'.$row['email'].'>'):$row['email'];
-                elseif($defaultEmailId) {
-                    $row['email_id'] = $defaultEmailId;
-                    $row['email'] = $defaultEmailAddress;
+                if ($dept->email) {
+                    $email = (string) $dept->email;
+                    $emailId = $dept->email->getId();
+                } else {
+                    $emailId = $defaultEmailId;
+                    $email = $defaultEmailAddress;
                 }
 
-                $default=($defaultId==$row['dept_id'])?' <small>'.__('(Default)').'</small>':'';
+                $default= ($defaultId == $dept->getId()) ?' <small>'.__('(Default)').'</small>' : '';
                 ?>
-            <tr id="<?php echo $row['dept_id']; ?>">
+            <tr id="<?php echo $id; ?>">
                 <td width=7px>
-                  <input type="checkbox" class="ckb" name="ids[]" value="<?php echo $row['dept_id']; ?>"
-                            <?php echo $sel?'checked="checked"':''; ?>  <?php echo $default?'disabled="disabled"':''; ?> >
+                  <input type="checkbox" class="ckb" name="ids[]"
+                  value="<?php echo $id; ?>"
+                  <?php echo $sel? 'checked="checked"' : ''; ?>
+                  <?php echo $default? 'disabled="disabled"' : ''; ?> >
                 </td>
-                <td><a href="departments.php?id=<?php echo $row['dept_id']; ?>"><?php echo $row['dept_name']; ?></a>&nbsp;<?php echo $default; ?></td>
-                <td><?php echo $row['ispublic']?__('Public'):'<b>'.__('Private').'</b>'; ?></td>
+                <td><a href="departments.php?id=<?php echo $id; ?>"><?php
+                echo $dept->getName(); ?></a>&nbsp;<?php echo $default; ?></td>
+                <td><?php echo $dept->isPublic() ? __('Public') :'<b>'.__('Private').'</b>'; ?></td>
                 <td>&nbsp;&nbsp;
                     <b>
-                    <?php if($row['users']>0) { ?>
-                        <a href="staff.php?did=<?php echo $row['dept_id']; ?>"><?php echo $row['users']; ?></a>
+                    <?php if ($dept->members_count) { ?>
+                        <a href="staff.php?did=<?php echo $id; ?>"><?php echo $dept->members_count; ?></a>
                     <?php }else{ ?> 0
                     <?php } ?>
                     </b>
                 </td>
-                <td><span class="ltr"><a href="emails.php?id=<?php echo $row['email_id']; ?>"><?php
-                    echo Format::htmlchars($row['email']); ?></a></span></td>
-                <td><a href="staff.php?id=<?php echo $row['manager_id']; ?>"><?php echo $row['manager']; ?>&nbsp;</a></td>
+                <td><span class="ltr"><a href="emails.php?id=<?php echo $emailId; ?>"><?php
+                    echo Format::htmlchars($email); ?></a></span></td>
+                <td><a href="staff.php?id=<?php echo $dept->manager_id; ?>"><?php
+                    echo $dept->manager_id ? $dept->manager : ''; ?>&nbsp;</a></td>
             </tr>
             <?php
-            } //end of while.
-        endif; ?>
+            } //end of foreach.
+        } ?>
     <tfoot>
      <tr>
         <td colspan="6">
-            <?php if($res && $num){ ?>
+            <?php
+            if ($count) { ?>
             <?php echo __('Select');?>:&nbsp;
             <a id="selectAll" href="#ckb"><?php echo __('All');?></a>&nbsp;&nbsp;
             <a id="selectNone" href="#ckb"><?php echo __('None');?></a>&nbsp;&nbsp;
@@ -123,18 +135,18 @@ else
     </tfoot>
 </table>
 <?php
-if($res && $num): //Show options..
-?>
-<p class="centered" id="actions">
-    <input class="button" type="submit" name="make_public" value="<?php echo __('Make Public');?>" >
-    <input class="button" type="submit" name="make_private" value="<?php echo __('Make Private');?>" >
-    <input class="button" type="submit" name="delete" value="<?php echo __('Delete Dept(s)');?>" >
-</p>
+if ($count): //Show options..
+    echo '<div>&nbsp;'.__('Page').':'.$pageNav->getPageLinks().'&nbsp;</div>';
+    ?>
+    <p class="centered" id="actions">
+        <input class="button" type="submit" name="delete" value="<?php echo
+        __('Delete');
+        ?>" >
+    </p>
 <?php
 endif;
 ?>
 </form>
-
 <div style="display:none;" class="dialog" id="confirm-action">
     <h3><?php echo __('Please Confirm');?></h3>
     <a class="close" href=""><i class="icon-remove-circle"></i></a>
diff --git a/include/staff/directory.inc.php b/include/staff/directory.inc.php
index 6d127962a2f9d30a9b5ed655333f170cac453ce9..cb212ec6505cc2469f2bf3771e351f138ab6ddf9 100644
--- a/include/staff/directory.inc.php
+++ b/include/staff/directory.inc.php
@@ -1,7 +1,7 @@
 <?php
 if(!defined('OSTSTAFFINC') || !$thisstaff || !$thisstaff->isStaff()) die('Access Denied');
 $qstr='';
-$select='SELECT staff.*,CONCAT_WS(" ",firstname,lastname) as name,dept.dept_name as dept ';
+$select='SELECT staff.*,CONCAT_WS(" ",firstname,lastname) as name,dept.name as dept ';
 $from='FROM '.STAFF_TABLE.' staff '.
       'LEFT JOIN '.DEPT_TABLE.' dept ON(staff.dept_id=dept.dept_id) ';
 $where='WHERE staff.isvisible=1 ';
@@ -28,7 +28,7 @@ if($_REQUEST['did'] && is_numeric($_REQUEST['did'])) {
     $qstr.='&did='.urlencode($_REQUEST['did']);
 }
 
-$sortOptions=array('name'=>'staff.firstname,staff.lastname','email'=>'staff.email','dept'=>'dept.dept_name',
+$sortOptions=array('name'=>'staff.firstname,staff.lastname','email'=>'staff.email','dept'=>'dept.name',
                    'phone'=>'staff.phone','mobile'=>'staff.mobile','ext'=>'phone_ext',
                    'created'=>'staff.created','login'=>'staff.lastlogin');
 $orderWays=array('DESC'=>'DESC','ASC'=>'ASC');
@@ -68,10 +68,10 @@ $query="$select $from $where GROUP BY staff.staff_id ORDER BY $order_by LIMIT ".
         <select name="did" id="did">
              <option value="0">&mdash; <?php echo __('All Departments');?> &mdash;</option>
              <?php
-             $sql='SELECT dept.dept_id, dept.dept_name,count(staff.staff_id) as users  '.
+             $sql='SELECT dept.dept_id, dept.name as dept,count(staff.staff_id) as users  '.
                   'FROM '.DEPT_TABLE.' dept '.
                   'INNER JOIN '.STAFF_TABLE.' staff ON(staff.dept_id=dept.dept_id AND staff.isvisible=1) '.
-                  'GROUP By dept.dept_id HAVING users>0 ORDER BY dept_name';
+                  'GROUP By dept.dept_id HAVING users>0 ORDER BY dept.name';
              if(($res=db_query($sql)) && db_num_rows($res)){
                  while(list($id,$name, $users)=db_fetch_row($res)){
                      $sel=($_REQUEST['did'] && $_REQUEST['did']==$id)?'selected="selected"':'';
diff --git a/include/staff/email.inc.php b/include/staff/email.inc.php
index 9d2e3f89c566b28d2df5eae293b548de28732bf0..e556d39b643f874d21a79e50be6c02fcf9fbf0e3 100644
--- a/include/staff/email.inc.php
+++ b/include/staff/email.inc.php
@@ -84,12 +84,11 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
 			    <option value="0" selected="selected">&mdash; <?php
                 echo __('System Default'); ?> &mdash;</option>
 			    <?php
-			    $sql='SELECT dept_id, dept_name FROM '.DEPT_TABLE.' dept ORDER by dept_name';
-			    if(($res=db_query($sql)) && db_num_rows($res)){
-				while(list($id,$name)=db_fetch_row($res)){
-				    $selected=($info['dept_id'] && $id==$info['dept_id'])?'selected="selected"':'';
-				    echo sprintf('<option value="%d" %s>%s</option>',$id,$selected,$name);
-				}
+                if (($depts=Dept::getDepartments())) {
+                    foreach ($depts as $id => $name) {
+				        $selected=($info['dept_id'] && $id==$info['dept_id'])?'selected="selected"':'';
+				        echo sprintf('<option value="%d" %s>%s</option>',$id,$selected,$name);
+				    }
 			    }
 			    ?>
 			</select>
diff --git a/include/staff/emails.inc.php b/include/staff/emails.inc.php
index e94c7c2cc9dce43382b795c5883ccd4e65b095fd..7b772d3e0f173802cabf564fdad4a35aedc32f6b 100644
--- a/include/staff/emails.inc.php
+++ b/include/staff/emails.inc.php
@@ -2,12 +2,6 @@
 if(!defined('OSTADMININC') || !$thisstaff->isAdmin()) die('Access Denied');
 
 $qstr='';
-$sql='SELECT email.*,dept.dept_name as department,priority_desc as priority '.
-     ' FROM '.EMAIL_TABLE.' email '.
-     ' LEFT JOIN '.DEPT_TABLE.' dept ON (dept.dept_id=email.dept_id) '.
-     ' LEFT JOIN '.TICKET_PRIORITY_TABLE.' pri ON (pri.priority_id=email.priority_id) ';
-$sql.=' WHERE 1';
-
 $sortOptions = array(
         'email' => 'email',
         'dept' => 'dept__name',
diff --git a/include/staff/settings-system.inc.php b/include/staff/settings-system.inc.php
index a095fbf6ab63ef1ddb4bb98caf7ee369fd8bf5f0..956d1555c3a0ba30df719fd496a54cefddb3533f 100644
--- a/include/staff/settings-system.inc.php
+++ b/include/staff/settings-system.inc.php
@@ -50,9 +50,8 @@ $gmtime = Misc::gmtime();
                 <select name="default_dept_id">
                     <option value="">&mdash; <?php echo __('Select Default Department');?> &mdash;</option>
                     <?php
-                    $sql='SELECT dept_id,dept_name FROM '.DEPT_TABLE.' WHERE ispublic=1';
-                    if(($res=db_query($sql)) && db_num_rows($res)){
-                        while (list($id, $name) = db_fetch_row($res)){
+                    if (($depts=Dept::getPublicDepartments())) {
+                        foreach ($depts as $id => $name) {
                             $selected = ($config['default_dept_id']==$id)?'selected="selected"':''; ?>
                             <option value="<?php echo $id; ?>"<?php echo $selected; ?>><?php echo $name; ?> <?php echo __('Dept');?></option>
                         <?php
@@ -110,12 +109,12 @@ $gmtime = Misc::gmtime();
             <td width="180"><?php echo __('Default Name Formatting'); ?>:</td>
             <td>
                 <select name="name_format">
-<?php foreach (PersonsName::allFormats() as $n=>$f) {
-    list($desc, $func) = $f;
-    $selected = ($config['name_format'] == $n) ? 'selected="selected"' : ''; ?>
-                    <option value="<?php echo $n; ?>" <?php echo $selected;
-                        ?>><?php echo __($desc); ?></option>
-<?php } ?>
+                <?php foreach (PersonsName::allFormats() as $n=>$f) {
+                    list($desc, $func) = $f;
+                    $selected = ($config['name_format'] == $n) ? 'selected="selected"' : ''; ?>
+                                    <option value="<?php echo $n; ?>" <?php echo $selected;
+                                        ?>><?php echo __($desc); ?></option>
+                <?php } ?>
                 </select>
                 <i class="help-tip icon-question-sign" href="#default_name_formatting"></i>
             </td>
@@ -131,24 +130,30 @@ $gmtime = Misc::gmtime();
             <td>
                 <select name="default_locale">
                     <option value=""><?php echo __('Use Language Preference'); ?></option>
-<?php foreach (Internationalization::allLocales() as $code=>$name) { ?>
+                    <?php
+                    foreach (Internationalization::allLocales() as $code=>$name) { ?>
                     <option value="<?php echo $code; ?>" <?php
                         if ($code == $config['default_locale'])
                             echo 'selected="selected"';
                     ?>><?php echo $name; ?></option>
-<?php } ?>
+
+                    <?php
+                    } ?>
                 </select>
             </td>
         </tr>
         <tr><td width="220" class="required"><?php echo __('Default Time Zone');?>:</td>
             <td>
                 <select name="default_timezone" id="timezone-dropdown">
-<?php foreach (DateTimeZone::listIdentifiers() as $zone) { ?>
+                <?php
+                foreach (DateTimeZone::listIdentifiers() as $zone) { ?>
                     <option value="<?php echo $zone; ?>" <?php
                     if ($config['default_timezone'] == $zone)
                         echo 'selected="selected"';
                     ?>><?php echo str_replace('/',' / ',$zone); ?></option>
-<?php } ?>
+
+                <?php
+                } ?>
                 </select>
                 <button class="action-button" onclick="javascript:
     $('head').append($('<script>').attr('src', '<?php
diff --git a/include/staff/templates/tickets.tmpl.php b/include/staff/templates/tickets.tmpl.php
index 67f59864dd13692813ea64850ae5a87842397bed..31872def97e03e8c9b94616ce57587d964bf4a6e 100644
--- a/include/staff/templates/tickets.tmpl.php
+++ b/include/staff/templates/tickets.tmpl.php
@@ -1,7 +1,7 @@
 <?php
 
 $select ='SELECT ticket.ticket_id,ticket.`number`,ticket.dept_id,ticket.staff_id,ticket.team_id, ticket.user_id '
-        .' ,dept.dept_name,status.name as status,ticket.source,ticket.isoverdue,ticket.isanswered,ticket.created '
+        .' ,dept.name as department, status.name as status,ticket.source,ticket.isoverdue,ticket.isanswered,ticket.created '
         .' ,CAST(GREATEST(IFNULL(ticket.lastmessage, 0), IFNULL(ticket.reopened, 0), ticket.created) as datetime) as effective_date '
         .' ,CONCAT_WS(" ", staff.firstname, staff.lastname) as staff, team.name as team '
         .' ,IF(staff.staff_id IS NULL,team.name,CONCAT_WS(" ", staff.lastname, staff.firstname)) as assigned '
@@ -156,7 +156,7 @@ if ($results) { ?>
             </td>
             <?php
             if ($user) { ?>
-            <td><?php echo Format::truncate($row['dept_name'], 40); ?></td>
+            <td><?php echo Format::truncate($row['department'], 40); ?></td>
             <td>&nbsp;<?php echo $assigned; ?></td>
             <?php
             } else { ?>
diff --git a/include/staff/tickets.inc.php b/include/staff/tickets.inc.php
index 5f852956dd1f570195bf3efb7f6d480df7ace91d..a1591aa36ea3f763601b59a3b824ee34c095bc9a 100644
--- a/include/staff/tickets.inc.php
+++ b/include/staff/tickets.inc.php
@@ -75,7 +75,7 @@ $tickets->filter(Q::any($visibility));
 
 // Select pertinent columns
 // ------------------------------------------------------------
-$tickets->values('lock__lock_id', 'staff_id', 'isoverdue', 'team_id', 'ticket_id', 'number', 'cdata__subject', 'user__default_email__address', 'source', 'cdata__:priority__priority_color', 'cdata__:priority__priority_desc', 'status__name', 'status__state', 'dept_id', 'dept__dept_name', 'user__name', 'lastupdate');
+$tickets->values('lock__lock_id', 'staff_id', 'isoverdue', 'team_id', 'ticket_id', 'number', 'cdata__subject', 'user__default_email__address', 'source', 'cdata__:priority__priority_color', 'cdata__:priority__priority_desc', 'status__name', 'status__state', 'dept_id', 'dept__name', 'user__name', 'lastupdate');
 
 // Apply requested quick filter
 
@@ -240,7 +240,7 @@ $_SESSION[':Q:tickets'] = $tickets;
                     $flag='overdue';
 
                 $lc='';
-                $dept = Dept::getLocalById($T['dept_id'], 'name', $T['dept__dept_name']);
+                $dept = Dept::getLocalById($T['dept_id'], 'name', $T['dept__name']);
                 if($showassigned) {
                     if($T['staff_id'])
                         $lc=sprintf('<span class="Icon staffAssigned">%s</span>',Format::truncate((string) new PersonsName($T['staff__firstname'], $T['staff__lastname']),40));
diff --git a/setup/inc/streams/core/install-mysql.sql b/setup/inc/streams/core/install-mysql.sql
index f32ff6d74962ad72ed72886ef9fcefb145d1e039..a23a71b65082e5a2c9cd8b17153dd8824db8d36a 100644
--- a/setup/inc/streams/core/install-mysql.sql
+++ b/setup/inc/streams/core/install-mysql.sql
@@ -197,22 +197,22 @@ CREATE TABLE `%TABLE_PREFIX%list_items` (
 
 DROP TABLE IF EXISTS `%TABLE_PREFIX%department`;
 CREATE TABLE `%TABLE_PREFIX%department` (
-  `dept_id` int(11) unsigned NOT NULL auto_increment,
+  `id` int(11) unsigned NOT NULL auto_increment,
   `tpl_id` int(10) unsigned NOT NULL default '0',
   `sla_id` int(10) unsigned NOT NULL default '0',
   `email_id` int(10) unsigned NOT NULL default '0',
   `autoresp_email_id` int(10) unsigned NOT NULL default '0',
   `manager_id` int(10) unsigned NOT NULL default '0',
-  `dept_name` varchar(128) NOT NULL default '',
-  `dept_signature` text NOT NULL,
+  `name` varchar(128) NOT NULL default '',
+  `signature` text NOT NULL,
   `ispublic` tinyint(1) unsigned NOT NULL default '1',
   `group_membership` tinyint(1) NOT NULL default '0',
   `ticket_auto_response` tinyint(1) NOT NULL default '1',
   `message_auto_response` tinyint(1) NOT NULL default '0',
   `updated` datetime NOT NULL,
   `created` datetime NOT NULL,
-  PRIMARY KEY  (`dept_id`),
-  UNIQUE KEY `dept_name` (`dept_name`),
+  PRIMARY KEY  (`id`),
+  UNIQUE KEY `name` (`name`),
   KEY `manager_id` (`manager_id`),
   KEY `autoresp_email_id` (`autoresp_email_id`),
   KEY `tpl_id` (`tpl_id`)