diff --git a/include/class.dept.php b/include/class.dept.php
index 8f09237c4b37fc721d4a9a25367984414e9e9afd..99c79ec24a04e03b9f271eae68bc17af5aff9a26 100644
--- a/include/class.dept.php
+++ b/include/class.dept.php
@@ -61,11 +61,14 @@ implements TemplateVariable {
     var $autorespEmail;
 
     const ALERTS_DISABLED = 2;
+    const DISPLAY_DISABLED = 2;
     const ALERTS_DEPT_AND_EXTENDED = 1;
     const ALERTS_DEPT_ONLY = 0;
 
     const FLAG_ASSIGN_MEMBERS_ONLY = 0x0001;
     const FLAG_DISABLE_AUTO_CLAIM  = 0x0002;
+    const FLAG_ACTIVE = 0x0004;
+    const FLAG_ARCHIVED = 0x0008;
 
     function asVar() {
         return $this->getName();
@@ -128,6 +131,24 @@ implements TemplateVariable {
         return self::getNameById($this->getId());
     }
 
+    function getStatus() {
+        if($this->flags & self::FLAG_ACTIVE)
+          return __('Active');
+        elseif($this->flags & self::FLAG_ARCHIVED)
+          return __('Archived');
+        else
+          return __('Disabled');
+    }
+
+    function allowsReopen() {
+      return !($this->flags & self::FLAG_ARCHIVED);
+    }
+
+    function isActive()
+    {
+        return !!($this->flags & self::FLAG_ACTIVE);
+    }
+
     function getEmailId() {
         return $this->email_id;
     }
@@ -361,6 +382,7 @@ implements TemplateVariable {
 
         $ht['assign_members_only'] = $this->assignMembersOnly();
         $ht['disable_auto_claim'] =  $this->disableAutoClaim();
+        $ht['status'] = $this->getStatus();
         return $ht;
     }
 
@@ -465,7 +487,7 @@ implements TemplateVariable {
      *
      */
 
-    private function setFlag($flag, $val) {
+    public function setFlag($flag, $val) {
 
         if ($val)
             $this->flags |= $flag;
@@ -486,7 +508,7 @@ implements TemplateVariable {
     }
 
     function getNameById($id) {
-        $names = static::getDepartments();
+        $names = Dept::getDepartments();
         return $names[$id];
     }
 
@@ -500,8 +522,8 @@ implements TemplateVariable {
             : null;
     }
 
-    static function getDepartments( $criteria=null, $localize=true) {
-        static $depts = null;
+    static function getDepartments($criteria=null, $localize=true, $disabled=true) {
+        $depts = null;
 
         if (!isset($depts) || $criteria) {
             // XXX: This will upset the static $depts array
@@ -509,7 +531,7 @@ implements TemplateVariable {
             $query = self::objects();
             if (isset($criteria['publiconly']))
                 $query->filter(array(
-                            'ispublic' => ($criteria['publiconly'] ? 1 : 0)));
+                            'flags__hasbit' => Dept::FLAG_ACTIVE));
 
             if ($manager=$criteria['manager'])
                 $query->filter(array(
@@ -524,10 +546,15 @@ implements TemplateVariable {
             }
 
             $query->order_by('name')
-                ->values('id', 'pid', 'name', 'parent');
+                 ->values('id', 'pid', 'flags', 'name', 'parent');
 
             foreach ($query as $row)
-                $depts[$row['id']] = $row;
+            {
+              $display = ($row['flags'] & self::FLAG_ACTIVE);
+
+              $depts[$row['id']] = array('id' => $row['id'], 'pid'=>$row['pid'], 'name'=>$row['name'],
+                  'parent'=>$row['parent'], 'disabled' => !$display);
+            }
 
             $localize_this = function($id, $default) use ($localize) {
                 if (!$localize)
@@ -554,21 +581,32 @@ implements TemplateVariable {
                 // Fetch local names
                 $names[$id] = $localize_this($id, $name);
             }
-            asort($names);
 
-            // TODO: Use locale-aware sorting mechanism
+            // Apply requested filters
+            $requested_names = array();
+            foreach ($names as $id=>$n) {
+                $info = $depts[$id];
+                if (!$disabled && $info['disabled'])
+                    continue;
+                if ($disabled === self::DISPLAY_DISABLED && $info['disabled'])
+                    $n .= " - ".__("(disabled)");
 
+                $requested_names[$id] = $n;
+            }
+            asort($requested_names);
+
+            // TODO: Use locale-aware sorting mechanism
             if ($criteria)
-                return $names;
+                return $requested_names;
 
-            $depts = $names;
+            $depts = $requested_names;
         }
 
-        return $depts;
+        return $requested_names;
     }
 
     static function getPublicDepartments() {
-        static $depts =null;
+        $depts =null;
 
         if (!$depts)
             $depts = self::getDepartments(array('publiconly'=>true));
@@ -620,6 +658,10 @@ implements TemplateVariable {
         if ($vars['pid'] && !($p = static::lookup($vars['pid'])))
             $errors['pid'] = __('Department selection is required');
 
+        $dept = Dept::lookup($vars['pid']);
+        if($dept && !$dept->isActive())
+          $errors['dept_id'] = sprintf(__('%s selected must be active'), __('Parent Department'));
+
         // Format access update as [array(dept_id, role_id, alerts?)]
         $access = array();
         if (isset($vars['members'])) {
@@ -645,10 +687,27 @@ implements TemplateVariable {
         $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;
-        $this->flags = 0;
         $this->setFlag(self::FLAG_ASSIGN_MEMBERS_ONLY, isset($vars['assign_members_only']));
         $this->setFlag(self::FLAG_DISABLE_AUTO_CLAIM, isset($vars['disable_auto_claim']));
 
+        switch ($vars['status'])
+        {
+          case __('Active'):
+            $this->setFlag(self::FLAG_ACTIVE, true);
+            $this->setFlag(self::FLAG_ARCHIVED, false);
+            break;
+
+          case __('Disabled'):
+            $this->setFlag(self::FLAG_ACTIVE, false);
+            $this->setFlag(self::FLAG_ARCHIVED, false);
+            break;
+
+          case __('Archived'):
+            $this->setFlag(self::FLAG_ACTIVE, false);
+            $this->setFlag(self::FLAG_ARCHIVED, true);
+            break;
+        }
+
         $this->path = $this->getFullPath();
 
         $wasnew = $this->__new__;
@@ -736,7 +795,7 @@ extends Form {
                 'default' => 0,
                 'choices' =>
                     array(0 => '— '.__('Top-Level Department').' —')
-                    + Dept::getDepartments()
+                    + Dept::getPublicDepartments()
             )),
             'name' => new TextboxField(array(
                 'required' => true,
diff --git a/include/class.email.php b/include/class.email.php
index c1542113e4b7056ce1a9e578a96b2c7da76642fe..7df0f5ea3c2b1633945b15af749f44e7a76c1971 100644
--- a/include/class.email.php
+++ b/include/class.email.php
@@ -264,6 +264,14 @@ class Email extends VerySimpleModel {
         if(!$vars['name'])
             $errors['name']=__('Email name required');
 
+        $dept = Dept::lookup($vars['dept_id']);
+        if($dept && !$dept->isActive())
+          $errors['dept_id'] = '';
+
+        $topic = Topic::lookup($vars['topic_id']);
+        if($topic && !$topic->isActive())
+          $errors['topic_id'] = '';
+
         if($vars['mail_active'] || ($vars['smtp_active'] && $vars['smtp_auth'])) {
             if(!$vars['userid'])
                 $errors['userid']=__('Username missing');
diff --git a/include/class.filter.php b/include/class.filter.php
index 29f49d904949b2318dbd4da9d16c6ebed7f1f299..4adab820652638e91a6e20aea8ab33f09d054ba4 100644
--- a/include/class.filter.php
+++ b/include/class.filter.php
@@ -457,6 +457,22 @@ class Filter {
     }
 
     function save($id,$vars,&$errors) {
+      if ($this)
+      {
+        foreach ($this->getActions() as $A) {
+          if ($A->type == 'dept')
+              $dept = Dept::lookup($A->parseConfiguration($vars)['dept_id']);
+
+          if ($A->type == 'topic')
+              $topic = Topic::lookup($A->parseConfiguration($vars)['topic_id']);
+        }
+      }
+
+      if($dept && !$dept->isActive())
+        $errors['err'] = sprintf(__('%s selected for %s must be active'), __('Department'), __('Filter Action'));
+
+      if($topic && !$topic->isActive())
+        $errors['err'] = sprintf(__('%s selected for %s must be active'), __('Help Topic'), __('Filter Action'));
 
         if(!$vars['execorder'])
             $errors['execorder'] = __('Order required');
@@ -542,7 +558,7 @@ class Filter {
                 $I->setConfiguration($errors, $vars);
                 $I->save();
                 break;
-            case 'I': # exiting filter action
+            case 'I': # existing filter action
                 if ($I = FilterAction::lookup($info)) {
                     $I->setConfiguration($errors, $vars);
                     $I->sort = (int) $sort;
diff --git a/include/class.filter_action.php b/include/class.filter_action.php
index f5dc14abbc77740d58a368e434603568b6f64fca..dc4eeafd74cec987c07597f750a510cb3757f450 100644
--- a/include/class.filter_action.php
+++ b/include/class.filter_action.php
@@ -41,15 +41,28 @@ class FilterAction extends VerySimpleModel {
         return $this->_config;
     }
 
-    function setConfiguration(&$errors=array(), $source=false) {
-        $config = array();
-        foreach ($this->getImpl()->getConfigurationForm($source ?: $_POST)
-                ->getFields() as $name=>$field) {
-            if (!$field->hasData())
-                continue;
+    function parseConfiguration($source, &$errors=array())
+    {
+      if (!$source)
+        return $this->getConfiguration();
+
+      $config = array();
+      foreach ($this->getImpl()->getConfigurationForm($source)
+              ->getFields() as $name=>$field) {
+          if (!$field->hasData())
+              continue;
+          if($field->to_php($field->getClean()))
             $config[$name] = $field->to_php($field->getClean());
-            $errors = array_merge($errors, $field->errors());
-        }
+          else
+            $config[$name] = $field->getClean();
+
+          $errors = array_merge($errors, $field->errors());
+      }
+      return $config;
+    }
+
+    function setConfiguration(&$errors=array(), $source=false) {
+        $config = $this->parseConfiguration($source ?: $_POST, $errors);
         if (count($errors) === 0)
             $this->set('configuration', JsonDataEncoder::encode($config));
         return count($errors) === 0;
@@ -279,14 +292,11 @@ class FA_RouteDepartment extends TriggerAction {
 
     function getConfigurationOptions() {
         return array(
-            'dept_id' => new ChoiceField(array(
-                'configuration' => array(
-                    'prompt' => __('Unchanged'),
-                    'data' => array('quick-add' => 'department'),
-                ),
-                'choices' =>
-                    Dept::getDepartments() +
-                    array(':new:' => '— '.__('Add New').' —'),
+                'dept_id' => new DepartmentField(array(
+                    'configuration' => array(
+                        'prompt' => __('Unchanged'),
+                        'data' => array('quick-add' => 'department'),
+                    ),
                 'validators' => function($self, $clean) {
                     if ($clean === ':new:')
                         $self->addError(__('Select a department'));
diff --git a/include/class.forms.php b/include/class.forms.php
index c097dd995ab0f8e48336215bb6acf578e0dfb440..3278a128a872d7167820f3466bd83d5653c99548 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -2355,10 +2355,52 @@ class DepartmentField extends ChoiceField {
     function getChoices($verbose=false) {
         global $cfg;
 
+        $selected = self::getWidget();
+        if($selected && $selected->value)
+        {
+          if(is_array($selected->value))
+          {
+            foreach ($selected->value as $k => $v)
+            {
+              $current_id = $k;
+              $current_name = $v;
+            }
+          }
+          else {
+            $current_id = $selected->value;
+            $current_name = Dept::getNameById($current_id);
+            $addNew = true;
+          }
+        }
+
+        $active_depts = array();
+        if($current_id)
+          $active_depts = Dept::objects()
+            ->filter(array('flags__hasbit' => Dept::FLAG_ACTIVE))
+            ->values('id', 'name');
+
         $choices = array();
-        if (($depts = Dept::getDepartments()))
-            foreach ($depts as $id => $name)
-                $choices[$id] = $name;
+        if ($depts = Dept::getDepartments(null, true, Dept::DISPLAY_DISABLED))
+        {
+          //create array w/queryset
+          $active = array();
+          foreach ($active_depts as $dept)
+            $active[$dept['id']] = $dept['name'];
+
+          //add selected dept to list
+          $active[$current_id] = $current_name;
+
+
+          foreach ($depts as $id => $name)
+          {
+            $choices[$id] = $name;
+            if(!array_key_exists($id, $active) && $current_id)
+              unset($choices[$id]);
+          }
+
+        }
+        if($addNew)
+          $choices[':new:'] = '— '.__('Add New').' —';
 
         return $choices;
     }
diff --git a/include/class.staff.php b/include/class.staff.php
index e5ed7e77555e5bb72f1376d10de92bc9b579569d..5fa5293882b95973f7ed6330712b938dbfd99934 100644
--- a/include/class.staff.php
+++ b/include/class.staff.php
@@ -1002,6 +1002,10 @@ implements AuthenticatedUser, EmailContact, TemplateVariable {
         if(!$vars['role_id'])
             $errors['role_id']=__('Role for primary department is required');
 
+        $dept = Dept::lookup($vars['dept_id']);
+        if(!$dept->isActive())
+          $errors['dept_id'] = sprintf(__('%s selected must be active'), __('Department'));
+
         // Ensure we will still have an administrator with access
         if ($vars['isadmin'] !== '1' || $vars['islocked'] === '1') {
             $sql = 'select count(*), max(staff_id) from '.STAFF_TABLE
diff --git a/include/class.ticket.php b/include/class.ticket.php
index 7cc661f9595c6a68e4dc8ee8d47b04b7fd13ddda..3b4920f71e501dc384c48fbc108ce369225e171a 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -297,7 +297,8 @@ implements RestrictedAccess, Threadable {
     }
 
     function isReopenable() {
-        return $this->getStatus()->isReopenable();
+        return ($this->getStatus()->isReopenable()
+          && $this->getDept()->allowsReopen());
     }
 
     function isClosed() {
@@ -2780,6 +2781,10 @@ implements RestrictedAccess, Threadable {
             $errors['source'] = sprintf( __('Invalid source given - %s'),
                     Format::htmlchars($vars['source']));
 
+        $topic = Topic::lookup($vars['topicId']);
+        if($topic && !$topic->isActive())
+          $errors['topicId']= sprintf(__('%s selected must be active'), __('Help Topic'));
+
         // Validate dynamic meta-data
         $forms = DynamicFormEntry::forTicket($this->getId());
         foreach ($forms as $form) {
diff --git a/include/class.topic.php b/include/class.topic.php
index c25ab788a4288beaae3bd1163ecb72c6b2ea183f..fd865acf9e8621e0599ae6a69d4b780c1816ee64 100644
--- a/include/class.topic.php
+++ b/include/class.topic.php
@@ -67,6 +67,8 @@ implements TemplateVariable {
     const FORM_USE_PARENT = 4294967295;
 
     const FLAG_CUSTOM_NUMBERS = 0x0001;
+    const FLAG_ACTIVE = 0x0002;
+    const FLAG_ARCHIVED = 0x0004;
 
     const SORT_ALPHA = 'a';
     const SORT_MANUAL = 'm';
@@ -124,6 +126,11 @@ implements TemplateVariable {
         return $this->dept_id;
     }
 
+    function getDept() {
+
+        return $this->getDeptId() ? Dept::lookup($this->getDeptId()) : null;
+    }
+
     function getSLAId() {
         return $this->sla_id;
     }
@@ -172,30 +179,22 @@ implements TemplateVariable {
         return $this->isActive();
     }
 
-    /**
-     * Determine if the help topic is currently enabled. The ancestry of
-     * this topic will be considered to see if any of the parents are
-     * disabled. If any are disabled, then this topic will be considered
-     * disabled.
-     *
-     * Parameters:
-     * $chain - array<id:bool> recusion chain used to detect loops. The
-     *      chain should be maintained and passed to a parent's ::isActive()
-     *      method. When consulting a parent, if the local topic ID is a key
-     *      in the chain, then this topic has already been considered, and
-     *      there is a loop in the ancestry
-     */
-    function isActive(array $chain=array()) {
-        if (!$this->isactive)
-            return false;
+    function isActive()
+    {
+      return !!($this->flags & self::FLAG_ACTIVE);
+    }
 
-        if (!isset($chain[$this->getId()]) && ($p = $this->getParent())) {
-            $chain[$this->getId()] = true;
-            return $p->isActive($chain);
-        }
-        else {
-            return $this->isactive;
-        }
+    function getStatus() {
+      if($this->flags & self::FLAG_ACTIVE)
+        return 'Active';
+      elseif($this->flags & self::FLAG_ARCHIVED)
+        return 'Archived';
+      else
+        return 'Disabled';
+    }
+
+    function allowsReopen() {
+      return !($this->flags & self::FLAG_ARCHIVED);
     }
 
     function isPublic() {
@@ -209,6 +208,7 @@ implements TemplateVariable {
     function getInfo() {
         $base = $this->getHashtable();
         $base['custom-numbers'] = $this->hasFlag(self::FLAG_CUSTOM_NUMBERS);
+        $base['status'] = $this->getStatus();
         return $base;
     }
 
@@ -291,75 +291,91 @@ implements TemplateVariable {
         return $topic;
     }
 
-    static function getHelpTopics($publicOnly=false, $disabled=false, $localize=true) {
-        global $cfg;
-        static $topics, $names = array();
-
-        // If localization is specifically requested, then rebuild the list.
-        if (!$names || $localize) {
-            $objects = self::objects()->values_flat(
-                'topic_id', 'topic_pid', 'ispublic', 'isactive', 'topic'
-            )
-            ->order_by('sort');
-
-            // Fetch information for all topics, in declared sort order
-            $topics = array();
-            foreach ($objects as $T) {
-                list($id, $pid, $pub, $act, $topic) = $T;
-                $topics[$id] = array('pid'=>$pid, 'public'=>$pub,
-                    'disabled'=>!$act, 'topic'=>$topic);
-            }
-
-            $localize_this = function($id, $default) use ($localize) {
-                if (!$localize)
-                    return $default;
-
-                $tag = _H("topic.name.{$id}");
-                $T = CustomDataTranslation::translate($tag);
-                return $T != $tag ? $T : $default;
-            };
-
-            // Resolve parent names
-            foreach ($topics as $id=>$info) {
-                $name = $localize_this($id, $info['topic']);
-                $loop = array($id=>true);
-                $parent = false;
-                while (($pid = $info['pid']) && ($info = $topics[$info['pid']])) {
-                    $name = sprintf('%s / %s', $localize_this($pid, $info['topic']),
-                        $name);
-                    if ($parent && $parent['disabled'])
-                        // Cascade disabled flag
-                        $topics[$id]['disabled'] = true;
-                    if (isset($loop[$info['pid']]))
-                        break;
-                    $loop[$info['pid']] = true;
-                    $parent = $info;
-                }
-                $names[$id] = $name;
-            }
-        }
-
-        // Apply requested filters
-        $requested_names = array();
-        foreach ($names as $id=>$n) {
-            $info = $topics[$id];
-            if ($publicOnly && !$info['public'])
-                continue;
-            if (!$disabled && $info['disabled'])
-                continue;
-            if ($disabled === self::DISPLAY_DISABLED && $info['disabled'])
-                $n .= " - ".__("(disabled)");
-            $requested_names[$id] = $n;
-        }
+    /**
+     * setFlag
+     *
+     * Utility method to set/unset flag bits
+     *
+     */
+    public function setFlag($flag, $val) {
 
-        // If localization requested and the current locale is not the
-        // primary, the list may need to be sorted. Caching is ok here,
-        // because the locale is not going to be changed within a single
-        // request.
-        if ($localize && $cfg->getTopicSortMode() == self::SORT_ALPHA)
-            return Internationalization::sortKeyedList($requested_names);
+        if ($val)
+            $this->flags |= $flag;
+        else
+            $this->flags &= ~$flag;
+    }
 
-        return $requested_names;
+    static function getHelpTopics($publicOnly=false, $disabled=false, $localize=true) {
+      global $cfg;
+      static $topics, $names = array();
+
+      // If localization is specifically requested, then rebuild the list.
+      if (!$names || $localize) {
+          $objects = self::objects()->values_flat(
+              'topic_id', 'topic_pid', 'ispublic', 'flags', 'topic'
+          )
+          ->order_by('sort');
+
+          // Fetch information for all topics, in declared sort order
+          $topics = array();
+          foreach ($objects as $T) {
+              list($id, $pid, $pub, $flags, $topic) = $T;
+
+              $display = ($flags & self::FLAG_ACTIVE);
+              $topics[$id] = array('pid'=>$pid, 'public'=>$pub,
+                  'disabled'=>!$display, 'topic'=>$topic);
+          }
+
+          $localize_this = function($id, $default) use ($localize) {
+              if (!$localize)
+                  return $default;
+
+              $tag = _H("topic.name.{$id}");
+              $T = CustomDataTranslation::translate($tag);
+              return $T != $tag ? $T : $default;
+          };
+
+          // Resolve parent names
+          foreach ($topics as $id=>$info) {
+              $name = $localize_this($id, $info['topic']);
+              $loop = array($id=>true);
+              $parent = false;
+              while (($pid = $info['pid']) && ($info = $topics[$info['pid']])) {
+                  $name = sprintf('%s / %s', $localize_this($pid, $info['topic']),
+                      $name);
+                  if ($parent && $parent['disabled'])
+                      // Cascade disabled flag
+                      $topics[$id]['disabled'] = true;
+                  if (isset($loop[$info['pid']]))
+                      break;
+                  $loop[$info['pid']] = true;
+                  $parent = $info;
+              }
+              $names[$id] = $name;
+          }
+      }
+
+      // Apply requested filters
+      $requested_names = array();
+      foreach ($names as $id=>$n) {
+          $info = $topics[$id];
+          if ($publicOnly && !$info['public'])
+              continue;
+          if (!$disabled && $info['disabled'])
+              continue;
+          if ($disabled === self::DISPLAY_DISABLED && $info['disabled'])
+              $n .= " - ".__("(disabled)");
+          $requested_names[$id] = $n;
+      }
+
+      // If localization requested and the current locale is not the
+      // primary, the list may need to be sorted. Caching is ok here,
+      // because the locale is not going to be changed within a single
+      // request.
+      if ($localize && $cfg->getTopicSortMode() == self::SORT_ALPHA)
+          return Internationalization::sortKeyedList($requested_names);
+
+      return $requested_names;
     }
 
     static function getPublicHelpTopics() {
@@ -401,6 +417,10 @@ implements TemplateVariable {
                 && (!isset($this->topic_id) || $tid!=$this->getId()))
             $errors['topic']=__('Topic already exists');
 
+          $dept = Dept::lookup($vars['dept_id']);
+          if(!$dept->isActive())
+            $errors['dept_id'] = sprintf(__('%s selected must be active'), __('Department'));
+
         if (!is_numeric($vars['dept_id']))
             $errors['dept_id']=__('Department selection is required');
 
@@ -422,10 +442,28 @@ implements TemplateVariable {
         $this->ispublic = !!$vars['ispublic'];
         $this->sequence_id = $vars['custom-numbers'] ? $vars['sequence_id'] : 0;
         $this->number_format = $vars['custom-numbers'] ? $vars['number_format'] : '';
-        $this->flags = $vars['custom-numbers'] ? self::FLAG_CUSTOM_NUMBERS : 0;
+        $this->flags = $vars['custom-numbers'] ? self::FLAG_CUSTOM_NUMBERS : $this->flags;
         $this->noautoresp = !!$vars['noautoresp'];
         $this->notes = Format::sanitize($vars['notes']);
 
+        switch ($vars['status'])
+        {
+          case __('Active'):
+            $this->setFlag(self::FLAG_ACTIVE, true);
+            $this->setFlag(self::FLAG_ARCHIVED, false);
+            break;
+
+          case __('Disabled'):
+            $this->setFlag(self::FLAG_ACTIVE, false);
+            $this->setFlag(self::FLAG_ARCHIVED, false);
+            break;
+
+          case __('Archived'):
+            $this->setFlag(self::FLAG_ACTIVE, false);
+            $this->setFlag(self::FLAG_ARCHIVED, true);
+            break;
+        }
+
         //Auto assign ID is overloaded...
         if ($vars['assign'] && $vars['assign'][0] == 's') {
             $this->team_id = 0;
diff --git a/include/client/view.inc.php b/include/client/view.inc.php
index 2aa01d019bafc6a7390d7259bfcb775b7b5f682b..37548ca1e323206865c67a91c8d9409a2501b392 100644
--- a/include/client/view.inc.php
+++ b/include/client/view.inc.php
@@ -174,7 +174,8 @@ echo $attrs; ?>><?php echo $draft ?: $info['message'];
         print $attachments->render(array('client'=>true));
     } ?>
     </div>
-<?php if ($ticket->isClosed()) { ?>
+<?php
+  if ($ticket->isClosed() && $ticket->isReopenable()) { ?>
     <div class="warning-banner">
         <?php echo __('Ticket will be reopened on message post'); ?>
     </div>
diff --git a/include/staff/cannedresponse.inc.php b/include/staff/cannedresponse.inc.php
index 20818d994242254f10fe2c85e5747742e9a944ef..981eef289ab2f340940ba58651efa73338615c89 100644
--- a/include/staff/cannedresponse.inc.php
+++ b/include/staff/cannedresponse.inc.php
@@ -57,7 +57,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
                 <select name="dept_id">
                     <option value="0">&mdash; <?php echo __('All Departments');?> &mdash;</option>
                     <?php
-                    if (($depts=Dept::getDepartments())) {
+                    if (($depts=Dept::getDepartments(array('publiconly' => true)))) {
                         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/department.inc.php b/include/staff/department.inc.php
index 2ea8825e35c787bdcba95078a23e50f8e46f1192..19364945bd830c8878276526ac5be0c4391e38cf 100644
--- a/include/staff/department.inc.php
+++ b/include/staff/department.inc.php
@@ -59,14 +59,27 @@ $info = Format::htmlchars(($errors && $_POST) ? $_POST : $info);
             <td>
                 <select name="pid">
                     <option value="">&mdash; <?php echo __('Top-Level Department'); ?> &mdash;</option>
-<?php foreach (Dept::getDepartments() as $id=>$name) {
-    if ($info['id'] && $id == $info['id'])
-        continue; ?>
-                    <option value="<?php echo $id; ?>" <?php
-                    if ($info['pid'] == $id) echo 'selected="selected"';
-                    ?>><?php echo $name; ?></option>
-<?php } ?>
-                </select>
+                    <?php
+                    if($info['pid'])
+                      $current_name = Dept::getNameById($info['pid']);
+                    if ($depts=Dept::getPublicDepartments())
+                    {
+                      if(!array_key_exists($info['pid'], $depts) && $info['pid'])
+                      {
+                        $depts[$info['pid']] = $current_name;
+                        $warn = sprintf(__('%s selected must be active'), __('Parent Department'));
+                      }
+                    foreach ($depts as $id=>$name) {
+                        $selected=($info['pid'] && $id==$info['pid'])?'selected="selected"':'';
+                        echo sprintf('<option value="%d" %s>%s</option>',$id,$selected,$name);
+                    }
+                  }
+                  ?>
+              </select>
+              <?php
+              if($warn) { ?>
+                  &nbsp;<span class="error">*&nbsp;<?php echo $warn; ?></span>
+              <?php } ?>
             </td>
         </tr>
         <tr>
@@ -80,6 +93,16 @@ $info = Format::htmlchars(($errors && $_POST) ? $_POST : $info);
                 &nbsp;<span class="error">*&nbsp;<?php echo $errors['name']; ?></span>
             </td>
         </tr>
+        <tr>
+            <td width="180" class="required">
+                <?php echo __('Status');?>:
+            </td>
+            <td>
+                <input type="radio" name="status" value="Active" <?php echo $info['status'] == 'Active'?'checked="checked"':''; ?>> <?php echo __('Active'); ?>
+                <input type="radio" name="status" value="Disabled" <?php echo $info['status'] == 'Disabled'?'checked="checked"':''; ?>> <?php echo __('Disabled'); ?>
+                <input type="radio" name="status" value="Archived" <?php echo $info['status'] == 'Archived'?'checked="checked"':''; ?>> <?php echo __('Archived'); ?>
+            </td>
+        </tr>
         <tr>
             <td width="180" class="required">
                 <?php echo __('Type');?>:
diff --git a/include/staff/departments.inc.php b/include/staff/departments.inc.php
index 2924eea68f11acb94209187472eef9b1892c03e6..4fd4a34c9fe0870e6c006886bd5a23d88e68d5ec 100644
--- a/include/staff/departments.inc.php
+++ b/include/staff/departments.inc.php
@@ -5,6 +5,7 @@ if (!defined('OSTADMININC') || !$thisstaff->isAdmin())
 $qs = array();
 $sortOptions=array(
     'name' => 'name',
+    'status' => 'flags',
     'type' => 'ispublic',
     'members'=> 'members_count',
     'email'=> 'email__name',
@@ -53,9 +54,28 @@ $showing = $pageNav->showing().' '._N('department', 'departments', $count);
             </span>
             <div id="action-dropdown-more" class="action-dropdown anchor-right">
                 <ul id="actions">
+                    <li>
+                        <a class="confirm" data-name="enable" href="departments.php?a=enable">
+                            <i class="icon-ok-sign icon-fixed-width"></i>
+                            <?php echo __( 'Enable'); ?>
+                        </a>
+                    </li>
+                    <li>
+                        <a class="confirm" data-name="disable" href="departments.php?a=disable">
+                            <i class="icon-ban-circle icon-fixed-width"></i>
+                            <?php echo __( 'Disable'); ?>
+                        </a>
+                    </li>
+                    <li>
+                        <a class="confirm" data-name="archive" href="departments.php?a=archive">
+                            <i class="icon-folder-close icon-fixed-width"></i>
+                            <?php echo __( 'Archive'); ?>
+                        </a>
+                    </li>
                     <li class="danger"><a class="confirm" data-name="delete" href="departments.php?a=delete">
                         <i class="icon-trash icon-fixed-width"></i>
-                        <?php echo __('Delete'); ?></a></li>
+                        <?php echo __('Delete'); ?></a>
+                    </li>
                 </ul>
             </div>
         </div>
@@ -70,8 +90,11 @@ $showing = $pageNav->showing().' '._N('department', 'departments', $count);
         <tr>
             <th width="4%">&nbsp;</th>
             <th width="28%"><a <?php echo $name_sort; ?> href="departments.php?<?php echo $qstr; ?>&sort=name"><?php echo __('Name');?></a></th>
+            <th width="8%"><a <?php echo $status_sort; ?> href="departments.php?<?php echo $qstr;?>&sort=status"><?php echo __('Status');?></a></th>
+            <!-- <th style="padding-left:4px;vertical-align:middle" width="8%"><?php echo __('Status'); ?></th> -->
             <th width="8%"><a  <?php echo $type_sort; ?> href="departments.php?<?php echo $qstr; ?>&sort=type"><?php echo __('Type');?></a></th>
-            <th width="8%"><a  <?php echo $users_sort; ?>href="departments.php?<?php echo $qstr; ?>&sort=users"><?php echo __('Agents');?></a></th>
+            <!-- <th width="8%"><a  <?php echo $users_sort; ?>href="departments.php?<?php echo $qstr; ?>&sort=users"><?php echo __('Agents');?></a></th> -->
+            <th width="8%"><a  <?php echo $users_sort; ?>href="departments.php?<?php echo $qstr; ?>&sort=members"><?php echo __('Agents');?></a></th>
             <th width="30%"><a  <?php echo $email_sort; ?> href="departments.php?<?php echo $qstr; ?>&sort=email"><?php echo __('Email Address');?></a></th>
             <th width="22%"><a  <?php echo $manager_sort; ?> href="departments.php?<?php echo $qstr; ?>&sort=manager"><?php echo __('Manager');?></a></th>
         </tr>
@@ -115,8 +138,17 @@ $showing = $pageNav->showing().' '._N('department', 'departments', $count);
                   <?php echo $sel? 'checked="checked"' : ''; ?>
                   <?php echo $default? 'disabled="disabled"' : ''; ?> >
                 </td>
-                <td><a href="departments.php?id=<?php echo $id; ?>"><?php
-                echo Dept::getNameById($id); ?></a>&nbsp;<?php echo $default; ?></td>
+                <td>
+                  <a href="departments.php?id=<?php echo $id; ?>"><?php
+                echo Dept::getNameById($id); ?></a>&nbsp;<?php echo $default; ?>
+                </td>
+                <td><?php
+                  if($dept->getStatus() == __('Active'))
+                    echo $dept->getStatus();
+                  else
+                    echo '<b>'.$dept->getStatus();
+                  ?>
+                </td>
                 <td><?php echo $dept->isPublic() ? __('Public') :'<b>'.__('Private').'</b>'; ?></td>
                 <td>&nbsp;&nbsp;
                     <b>
@@ -136,7 +168,7 @@ $showing = $pageNav->showing().' '._N('department', 'departments', $count);
         } ?>
     <tfoot>
      <tr>
-        <td colspan="6">
+        <td colspan="7">
             <?php
             if ($count) { ?>
             <?php echo __('Select');?>:&nbsp;
@@ -170,6 +202,18 @@ endif;
         <?php echo sprintf(__('Are you sure you want to make %s <b>private</b> (internal)?'),
             _N('selected department', 'selected departments', 2));?>
     </p>
+    <p class="confirm-action" style="display:none;" id="enable-confirm">
+        <?php echo sprintf(__('Are you sure you want to <b>enable</b> %s?'),
+            _N('selected department', 'selected departments', 2));?>
+    </p>
+    <p class="confirm-action" style="display:none;" id="disable-confirm">
+        <?php echo sprintf(__('Are you sure you want to <b>disable</b> %s?'),
+            _N('selected department', 'selected departments', 2));?>
+    </p>
+    <p class="confirm-action" style="display:none;" id="archive-confirm">
+        <?php echo sprintf(__('Are you sure you want to <b>archive</b> %s?'),
+            _N('selected department', 'selected departments', 2));?>
+    </p>
     <p class="confirm-action" style="display:none;" id="delete-confirm">
         <font color="red"><strong><?php echo sprintf(__('Are you sure you want to DELETE %s?'),
             _N('selected department', 'selected departments', 2));?></strong></font>
diff --git a/include/staff/email.inc.php b/include/staff/email.inc.php
index 3653f06a7949bacc7d92d1b32a911c075abe07c0..86ac887a0ef9e93f28c82fc5cf58bdc109c3fb18 100644
--- a/include/staff/email.inc.php
+++ b/include/staff/email.inc.php
@@ -87,7 +87,13 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
 			    <option value="0" selected="selected">&mdash; <?php
                 echo __('System Default'); ?> &mdash;</option>
 			    <?php
-                if (($depts=Dept::getDepartments())) {
+                if ($depts=Dept::getPublicDepartments()) {
+                  if($info['dept_id'] && !array_key_exists($info['dept_id'], $depts))
+                  {
+                    $depts[$info['dept_id']] = $email->dept;
+                    $warn = sprintf(__('%s selected must be active'), __('Department'));
+                  }
+
                     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);
@@ -95,9 +101,12 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
 			    }
 			    ?>
 			</select>
+      <?php
+      if($warn) { ?>
+          &nbsp;<span class="error">*&nbsp;<?php echo $warn; ?></span>
+      <?php } ?>
 			<i class="help-tip icon-question-sign" href="#new_ticket_department"></i>
         </span>
-			&nbsp;<span class="error"><?php echo $errors['dept_id']; ?></span>
             </td>
         </tr>
         <tr>
@@ -133,12 +142,22 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
 			<select name="topic_id">
                 <option value="0" selected="selected">&mdash; <?php echo __('System Default'); ?> &mdash;</option>
 			    <?php
+                    $warn = '';
                     $topics = Topic::getHelpTopics();
+                    if($info['topic_id'] && !array_key_exists($info['topic_id'], $topics))
+                    {
+                      $topics[$info['topic_id']] = $email->topic;
+                      $warn = sprintf(__('%s selected must be active'), __('Help Topic'));
+                    }
                     while (list($id,$topic) = each($topics)) { ?>
                         <option value="<?php echo $id; ?>"<?php echo ($info['topic_id']==$id)?'selected':''; ?>><?php echo $topic; ?></option>
                     <?php
                     } ?>
 			</select>
+      <?php
+      if($warn) { ?>
+          &nbsp;<span class="error">*&nbsp;<?php echo $warn; ?></span>
+      <?php } ?>
 			<i class="help-tip icon-question-sign" href="#new_ticket_help_topic"></i>
 		</span>
                 <span class="error">
diff --git a/include/staff/filter.inc.php b/include/staff/filter.inc.php
index 2330fc47dc4ebeece8aa04e8365c71bb30bfb186..c04ad70142895307e615d6fce0f0eb654bc231bf 100644
--- a/include/staff/filter.inc.php
+++ b/include/staff/filter.inc.php
@@ -238,7 +238,25 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
                 <?php
                 $existing = array();
                 if ($filter) { foreach ($filter->getActions() as $A) {
+                    $_warn = '';
                     $existing[] = $A->type;
+                    if($A->type == 'dept')
+                    {
+                      $errors['topic_id'] = '';
+                      // $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
+                      $dept_config = $A->parseConfiguration($_POST);
+                      $dept = Dept::lookup($dept_config['dept_id']);
+                      if($dept && !$dept->isActive())
+                        $_warn = sprintf(__('%s must be active'), __('Department'));
+                    }
+                    elseif($A->type == 'topic')
+                    {
+                      $errors['dept_id'] = '';
+                      $topic_config = $A->parseConfiguration($_POST);
+                      $topic = Topic::lookup($topic_config['topic_id']);
+                      if($topic && !$topic->isActive())
+                        $_warn = sprintf(__('%s must be active'), __('Help Topic'));
+                    }
                 ?>
                 <tr style="background-color:white"><td><i class="icon-sort icon-large icon-muted"></i>
                     <?php echo $A->getImpl()->getName(); ?>:</td>
@@ -248,7 +266,9 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
                         // XXX: Drop this when the ORM supports proper caching
                         $form->isValid();
                         include STAFFINC_DIR . 'templates/dynamic-form-simple.tmpl.php';
-                        ?>
+                        if($_warn) {
+                            ?>&nbsp;<span class="error">*&nbsp;<?php echo $_warn; ?></span>
+                        <?php } ?>
                         <input type="hidden" name="actions[]" value="I<?php echo $A->getId(); ?>"/>
                         <div class="pull-right" style="position:absolute;top:2px;right:2px;">
                             <a href="#" title="<?php echo __('clear'); ?>" onclick="javascript:
diff --git a/include/staff/helptopic.inc.php b/include/staff/helptopic.inc.php
index 8cb90850d546d9080495833ea95de0d1f5376f1a..15a7cb2177a352ce240509bdf3c3de6adcb38e76 100644
--- a/include/staff/helptopic.inc.php
+++ b/include/staff/helptopic.inc.php
@@ -15,7 +15,7 @@ if($topic && $_REQUEST['a']!='add') {
     $title=__('Add New Help Topic');
     $action='create';
     $submit_text=__('Add Topic');
-    $info['isactive']=isset($info['isactive'])?$info['isactive']:1;
+    // $info['isactive']=isset($info['isactive'])?$info['isactive']:1;
     $info['ispublic']=isset($info['ispublic'])?$info['ispublic']:1;
     $qs += array('a' => $_REQUEST['a']);
     $forms = TicketForm::objects();
@@ -60,8 +60,9 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
                 <?php echo __('Status');?>:
             </td>
             <td>
-                <input type="radio" name="isactive" value="1" <?php echo $info['isactive']?'checked="checked"':''; ?>> <?php echo __('Active'); ?>
-                <input type="radio" name="isactive" value="0" <?php echo !$info['isactive']?'checked="checked"':''; ?>> <?php echo __('Disabled'); ?>
+                <input type="radio" name="status" value="Active" <?php echo $info['status'] == 'Active'?'checked="checked"':''; ?>> <?php echo __('Active'); ?>
+                <input type="radio" name="status" value="Disabled" <?php echo $info['status'] == 'Disabled'?'checked="checked"':''; ?>> <?php echo __('Disabled'); ?>
+                <input type="radio" name="status" value="Archived" <?php echo $info['status'] == 'Archived'?'checked="checked"':''; ?>> <?php echo __('Archived'); ?>
                 &nbsp;<span class="error">*&nbsp;</span> <i class="help-tip icon-question-sign" href="#status"></i>
             </td>
         </tr>
@@ -82,7 +83,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
             <td>
                 <select name="topic_pid">
                     <option value="">&mdash; <?php echo __('Top-Level Topic'); ?> &mdash;</option><?php
-                    $topics = Topic::getAllHelpTopics();
+                    $topics = Topic::getHelpTopics();
                     while (list($id,$topic) = each($topics)) {
                         if ($id == $info['topic_id'])
                             continue; ?>
@@ -122,13 +123,26 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
                 <select name="dept_id" data-quick-add="department">
                     <option value="0">&mdash; <?php echo __('System Default'); ?> &mdash;</option>
                     <?php
-                    foreach (Dept::getDepartments() as $id=>$name) {
+                    if($info['dept_id'])
+                      $current_name = Dept::getNameById($info['dept_id']);
+                    if ($depts=Dept::getPublicDepartments()) {
+                      if(!array_key_exists($info['dept_id'], $depts) && $info['dept_id'])
+                      {
+                        $depts[$info['dept_id']] = $current_name;
+                        $warn = sprintf(__('%s selected must be active'), __('Department'));
+                      }
+                    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);
-                    } ?>
+                    }
+                  }
+                  ?>
                     <option value="0" data-quick-add>&mdash; <?php echo __('Add New');?> &mdash;</option>
                 </select>
-                &nbsp;<span class="error">&nbsp;<?php echo $errors['dept_id']; ?></span>
+                <?php
+                if($warn) { ?>
+                    &nbsp;<span class="error">*&nbsp;<?php echo $warn; ?></span>
+                <?php } ?>
                 <i class="help-tip icon-question-sign" href="#department"></i>
             </td>
         </tr>
diff --git a/include/staff/helptopics.inc.php b/include/staff/helptopics.inc.php
index 0b5c58580c22ffdb3c7774db0ac170a904accf57..8978b97e36c1b94b678d006dade0a26310992949 100644
--- a/include/staff/helptopics.inc.php
+++ b/include/staff/helptopics.inc.php
@@ -41,6 +41,12 @@ $order_by = 'sort';
                                 <?php echo __( 'Disable'); ?>
                             </a>
                         </li>
+                        <li>
+                            <a class="confirm" data-name="archive" href="helptopics.php?a=archive">
+                                <i class="icon-folder-close icon-fixed-width"></i>
+                                <?php echo __( 'Archive'); ?>
+                            </a>
+                        </li>
                         <li class="danger">
                             <a class="confirm" data-name="delete" href="helptopics.php?a=delete">
                                 <i class="icon-trash icon-fixed-width"></i>
@@ -142,7 +148,13 @@ $order_by = 'sort';
                     <a href="helptopics.php?id=<?php echo $id; ?>"><?php
                     echo Topic::getTopicName($id); ?></a>&nbsp;
                 </td>
-                <td><?php echo $topic->isactive ? __('Active') : '<b>'.__('Disabled').'</b>'; ?></td>
+                <td><?php
+                  if($topic->getStatus() == __('Active'))
+                    echo $topic->getStatus();
+                  else
+                    echo '<b>'.$topic->getStatus();
+                  ?>
+                </td>
                 <td><?php echo $topic->ispublic ? __('Public') : '<b>'.__('Private').'</b>'; ?></td>
                 <td><?php echo $priority; ?></td>
                 <td><a href="departments.php?id=<?php echo $deptId;
@@ -189,6 +201,10 @@ endif;
         <?php echo sprintf(__('Are you sure you want to <b>disable</b> %s?'),
             _N('selected help topic', 'selected help topics', 2));?>
     </p>
+    <p class="confirm-action" style="display:none;" id="archive-confirm">
+        <?php echo sprintf(__('Are you sure you want to <b>archive</b> %s?'),
+            _N('selected help topic', 'selected help topics', 2));?>
+    </p>
     <p class="confirm-action" style="display:none;" id="delete-confirm">
         <font color="red"><strong><?php echo sprintf(__('Are you sure you want to DELETE %s?'),
             _N('selected help topic', 'selected help topics', 2));?></strong></font>
diff --git a/include/staff/staff.inc.php b/include/staff/staff.inc.php
index 4fce85b4f64ad7908964ca0614c6d34b7f73ab17..217daa065de2b514b2b11aac7b2cd246be4fde1f 100644
--- a/include/staff/staff.inc.php
+++ b/include/staff/staff.inc.php
@@ -228,15 +228,25 @@ if (count($bks) > 1) {
             <select name="dept_id" id="dept_id" data-quick-add="department">
               <option value="0">&mdash; <?php echo __('Select Department');?> &mdash;</option>
               <?php
-              foreach (Dept::getDepartments() as $id=>$name) {
-                $sel=($staff->dept_id==$id)?'selected="selected"':'';
-                echo sprintf('<option value="%d" %s>%s</option>',$id,$sel,$name);
+              if($depts = Dept::getPublicDepartments()) {
+                if($staff->dept_id && !array_key_exists($staff->dept_id, $depts))
+                {
+                  $depts[$staff->dept_id] = $staff->dept;
+                  $warn = sprintf(__('%s selected must be active'), __('Department'));
+                }
+                  foreach($depts as $id =>$name) {
+                    $sel=($staff->dept_id==$id)?'selected="selected"':'';
+                      echo sprintf('<option value="%d" %s>%s</option>',$id,$sel,$name);
+                  }
               }
               ?>
               <option value="0" data-quick-add>&mdash; <?php echo __('Add New');?> &mdash;</option>
             </select>
             <i class="offset help-tip icon-question-sign" href="#primary_department"></i>
-            <div class="error"><?php echo $errors['dept_id']; ?></div>
+            <?php
+            if($warn) { ?>
+                &nbsp;<span class="error">*&nbsp;<?php echo $warn; ?></span>
+            <?php } ?>
           </td>
           <td style="vertical-align:top">
             <select name="role_id" data-quick-add="role">
diff --git a/include/staff/ticket-edit.inc.php b/include/staff/ticket-edit.inc.php
index e15e8554d3d67afeea3ed47de83429638524dfbd..ecd09a6a2c1e00c6f28953deac3e500dca0a37e5 100644
--- a/include/staff/ticket-edit.inc.php
+++ b/include/staff/ticket-edit.inc.php
@@ -94,6 +94,11 @@ if ($_POST)
                     <option value="" selected >&mdash; <?php echo __('Select Help Topic');?> &mdash;</option>
                     <?php
                     if($topics=Topic::getHelpTopics()) {
+                      if(!array_key_exists($ticket->topic_id, $topics))
+                      {
+                        $topics[$ticket->topic_id] = $ticket->topic;
+                        $warn = sprintf(__('%s selected must be active'), __('Help Topic'));
+                      }
                         foreach($topics as $id =>$name) {
                             echo sprintf('<option value="%d" %s>%s</option>',
                                     $id, ($info['topicId']==$id)?'selected="selected"':'',$name);
@@ -101,7 +106,10 @@ if ($_POST)
                     }
                     ?>
                 </select>
-                &nbsp;<font class="error"><b>*</b>&nbsp;<?php echo $errors['topicId']; ?></font>
+                <?php
+                if($warn) { ?>
+                    &nbsp;<font class="error"><b>*</b>&nbsp;<?php echo $warn; ?></font>
+                <?php } ?>
             </td>
         </tr>
         <tr>
diff --git a/include/staff/ticket-open.inc.php b/include/staff/ticket-open.inc.php
index 6d383e580aa55714518ab59a7e6707f9b1402940..8507257557b26d2fbb33a1d36442021045e038d9 100644
--- a/include/staff/ticket-open.inc.php
+++ b/include/staff/ticket-open.inc.php
@@ -190,7 +190,7 @@ if ($_POST)
                 <select name="deptId">
                     <option value="" selected >&mdash; <?php echo __('Select Department'); ?>&mdash;</option>
                     <?php
-                    if($depts=Dept::getDepartments(array('dept_id' => $thisstaff->getDepts()))) {
+                    if($depts=Dept::getPublicDepartments()) {
                         foreach($depts as $id =>$name) {
                             if (!($role = $thisstaff->getRole($id))
                                 || !$role->hasPerm(Ticket::PERM_CREATE)
diff --git a/scp/departments.php b/scp/departments.php
index c1d860488f991d92291f73c0102bf16e0647964a..5bb8e0dd4986d8b4d66036a85a7d2f8b46808a5c 100644
--- a/scp/departments.php
+++ b/scp/departments.php
@@ -19,118 +19,196 @@ $dept=null;
 if($_REQUEST['id'] && !($dept=Dept::lookup($_REQUEST['id'])))
     $errors['err']=sprintf(__('%s: Unknown or invalid ID.'), __('department'));
 
-if($_POST){
-    switch(strtolower($_POST['do'])){
-        case 'update':
-            if(!$dept){
-                $errors['err']=sprintf(__('%s: Unknown or invalid'), __('department'));
-            }elseif($dept->update($_POST,$errors)){
-                $msg=sprintf(__('Successfully updated %s.'),
-                    __('this department'));
-            }elseif(!$errors['err']){
-                $errors['err'] = sprintf('%s %s',
-                    sprintf(__('Unable to update %s.'), __('this department')),
-                    __('Correct any errors below and try again.'));
-            }
-            break;
-        case 'create':
-            $_dept = Dept::create();
-            if(($_dept->update($_POST,$errors))){
-                $msg=sprintf(__('Successfully added %s.'),Format::htmlchars($_POST['name']));
-                $_REQUEST['a']=null;
-            }elseif(!$errors['err']){
-                $errors['err']=sprintf('%s %s',
-                    sprintf(__('Unable to add %s.'), __('this department')),
-                    __('Correct any errors below and try again.'));
-            }
-            break;
-        case 'mass_process':
-            if(!$_POST['ids'] || !is_array($_POST['ids']) || !count($_POST['ids'])) {
-                $errors['err'] = sprintf(__('You must select at least %s.'),
-                    __('one department'));
-            }elseif(in_array($cfg->getDefaultDeptId(),$_POST['ids'])) {
-                $errors['err'] = __('You cannot disable/delete a default department. Select a new default department and try again.');
-            }else{
-                $count=count($_POST['ids']);
-                switch(strtolower($_POST['a'])) {
-                    case 'make_public':
-                        $sql='UPDATE '.DEPT_TABLE.' SET ispublic=1 '
-                            .' WHERE dept_id IN ('.implode(',', db_input($_POST['ids'])).')';
-                        if(db_query($sql) && ($num=db_affected_rows())){
-                            if($num==$count)
-                                $msg=sprintf(__('Successfully made %s PUBLIC'),
-                                    _N('selected department', 'selected departments', $count));
-                            else
-                                $warn=sprintf(__(
-                                    /* Phrase will read:
-                                       <a> of <b> <selected objects> made PUBLIC */
-                                    '%1$d of %2$d %3$s made PUBLIC'), $num, $count,
-                                    _N('selected department', 'selected departments', $count));
-                        } else {
-                            $errors['err']=sprintf(__('Unable to make %s PUBLIC.'),
-                                _N('selected department', 'selected departments', $count));
-                        }
-                        break;
-                    case 'make_private':
-                        $sql='UPDATE '.DEPT_TABLE.' SET ispublic=0  '
-                            .' WHERE dept_id IN ('.implode(',', db_input($_POST['ids'])).') '
-                            .' AND dept_id!='.db_input($cfg->getDefaultDeptId());
-                        if(db_query($sql) && ($num=db_affected_rows())) {
-                            if($num==$count)
-                                $msg = sprintf(__('Successfully made %s PRIVATE'),
-                                    _N('selected department', 'selected epartments', $count));
-                            else
-                                $warn = sprintf(__(
-                                    /* Phrase will read:
-                                       <a> of <b> <selected objects> made PRIVATE */
-                                    '%1$d of %2$d %3$s made PRIVATE'), $num, $count,
+    if($_POST){
+        switch(strtolower($_POST['do'])){
+            case 'update':
+                if(!$dept){
+                    $errors['err']=sprintf(__('%s: Unknown or invalid'), __('department'));
+                }elseif($dept->update($_POST,$errors)){
+                    $msg=sprintf(__('Successfully updated %s.'),
+                        __('this department'));
+                }elseif(!$errors['err']){
+                    $errors['err'] = sprintf('%s %s',
+                        sprintf(__('Unable to update %s.'), __('this department')),
+                        __('Correct any errors below and try again.'));
+                }
+                break;
+            case 'create':
+                $_dept = Dept::create();
+                if(($_dept->update($_POST,$errors))){
+                    $msg=sprintf(__('Successfully added %s.'),Format::htmlchars($_POST['name']));
+                    $_REQUEST['a']=null;
+                }elseif(!$errors['err']){
+                    $errors['err']=sprintf('%s %s',
+                        sprintf(__('Unable to add %s.'), __('this department')),
+                        __('Correct any errors below and try again.'));
+                }
+                break;
+            case 'mass_process':
+                if(!$_POST['ids'] || !is_array($_POST['ids']) || !count($_POST['ids'])) {
+                    $errors['err'] = sprintf(__('You must select at least %s.'),
+                        __('one department'));
+                }elseif(in_array($cfg->getDefaultDeptId(),$_POST['ids'])) {
+                    $errors['err'] = __('You cannot disable/delete a default department. Select a new default department and try again.');
+                }else{
+                    $count=count($_POST['ids']);
+                    switch(strtolower($_POST['a'])) {
+                        case 'make_public':
+                            $sql='UPDATE '.DEPT_TABLE.' SET ispublic=1 '
+                                .' WHERE dept_id IN ('.implode(',', db_input($_POST['ids'])).')';
+                            if(db_query($sql) && ($num=db_affected_rows())){
+                                if($num==$count)
+                                    $msg=sprintf(__('Successfully made %s PUBLIC'),
+                                        _N('selected department', 'selected departments', $count));
+                                else
+                                    $warn=sprintf(__(
+                                        /* Phrase will read:
+                                           <a> of <b> <selected objects> made PUBLIC */
+                                        '%1$d of %2$d %3$s made PUBLIC'), $num, $count,
+                                        _N('selected department', 'selected departments', $count));
+                            } else {
+                                $errors['err']=sprintf(__('Unable to make %s PUBLIC.'),
                                     _N('selected department', 'selected departments', $count));
-                        } else {
-                            $errors['err'] = sprintf(__('Unable to make %s private. Possibly already private!'),
-                                _N('selected department', 'selected departments', $count));
-                        }
-                        break;
-                    case 'delete':
-                        //Deny all deletes if one of the selections has members in it.
-                        $sql='SELECT count(staff_id) FROM '.STAFF_TABLE
-                            .' WHERE dept_id IN ('.implode(',', db_input($_POST['ids'])).')';
-                        list($members)=db_fetch_row(db_query($sql));
-                        if($members)
-                            $errors['err']=__('Departments with agents can not be deleted. Move the agents first.');
-                        else {
-                            $i=0;
-                            foreach($_POST['ids'] as $k=>$v) {
-                                if($v!=$cfg->getDefaultDeptId() && ($d=Dept::lookup($v)) && $d->delete())
-                                    $i++;
                             }
-                            if($i && $i==$count)
-                                $msg = sprintf(__('Successfully deleted %s.'),
+                            break;
+                        case 'make_private':
+                            $sql='UPDATE '.DEPT_TABLE.' SET ispublic=0  '
+                                .' WHERE dept_id IN ('.implode(',', db_input($_POST['ids'])).') '
+                                .' AND dept_id!='.db_input($cfg->getDefaultDeptId());
+                            if(db_query($sql) && ($num=db_affected_rows())) {
+                                if($num==$count)
+                                    $msg = sprintf(__('Successfully made %s PRIVATE'),
+                                        _N('selected department', 'selected epartments', $count));
+                                else
+                                    $warn = sprintf(__(
+                                        /* Phrase will read:
+                                           <a> of <b> <selected objects> made PRIVATE */
+                                        '%1$d of %2$d %3$s made PRIVATE'), $num, $count,
+                                        _N('selected department', 'selected departments', $count));
+                            } else {
+                                $errors['err'] = sprintf(__('Unable to make %s private. Possibly already private!'),
                                     _N('selected department', 'selected departments', $count));
-                            elseif($i>0)
-                                $warn = sprintf(__(
-                                    /* Phrase will read:
-                                       <a> of <b> <selected objects> deleted */
-                                    '%1$d of %2$d %3$s deleted'), $i, $count,
+                            }
+                            break;
+                        case 'enable':
+                            $depts = Dept::objects()->filter(array(
+                              'id__in'=>$_POST['ids'],
+                            ))->exclude(array(
+                                'id'=>$cfg->getDefaultDeptId()
+                            ));
+                            foreach ($depts as $d)
+                            {
+                              $d->setFlag(Dept::FLAG_ARCHIVED, false);
+                              $d->setFlag(Dept::FLAG_ACTIVE, true);
+                              if($d->save())
+                                $num++;
+                            }
+
+                            if ($num > 0) {
+                                if($num==$count)
+                                    $msg = sprintf(__('Successfully enabled %s'),
+                                        _N('selected department', 'selected departments', $count));
+                                else
+                                    $warn = sprintf(__('%1$d of %2$d %3$s enabled'), $num, $count,
+                                        _N('selected department', 'selected departments', $count));
+                            } else {
+                                $errors['err'] = sprintf(__('Unable to enable %s'),
                                     _N('selected department', 'selected departments', $count));
-                            elseif(!$errors['err'])
-                                $errors['err'] = sprintf(__('Unable to delete %s.'),
+                            }
+                            break;
+                        case 'disable':
+                            $depts = Dept::objects()->filter(array(
+                              'id__in'=>$_POST['ids'],
+                            ))->exclude(array(
+                                'id'=>$cfg->getDefaultDeptId()
+                            ));
+                            foreach ($depts as $d)
+                            {
+                              $d->setFlag(Dept::FLAG_ARCHIVED, false);
+                              $d->setFlag(Dept::FLAG_ACTIVE, false);
+                              if($d->save())
+                                $num++;
+                            }
+                            if ($num > 0) {
+                                if($num==$count)
+                                    $msg = sprintf(__('Successfully disabled %s'),
+                                        _N('selected department', 'selected departments', $count));
+                                else
+                                    $warn = sprintf(__('%1$d of %2$d %3$s disabled'), $num, $count,
+                                        _N('selected department', 'selected departments', $count));
+                            } else {
+                                $errors['err'] = sprintf(__('Unable to disable %s'),
                                     _N('selected department', 'selected departments', $count));
-                        }
-                        break;
-                    default:
-                        $errors['err']=sprintf('%s - %s', __('Unknown action'), __('Get technical help!'));
+                            }
+                            break;
+                        case 'archive':
+                            $depts = Dept::objects()->filter(array(
+                              'id__in'=>$_POST['ids'],
+                            ))->exclude(array(
+                                'id'=>$cfg->getDefaultDeptId()
+                            ));
+                            foreach ($depts as $d)
+                            {
+                              $d->setFlag(Dept::FLAG_ARCHIVED, true);
+                              $d->setFlag(Dept::FLAG_ACTIVE, false);
+                              if($d->save())
+                                $num++;
+                            }
+                            if ($num > 0) {
+                                if($num==$count)
+                                    $msg = sprintf(__('Successfully archived %s'),
+                                        _N('selected department', 'selected departments', $count));
+                                else
+                                    $warn = sprintf(__('%1$d of %2$d %3$s archived'), $num, $count,
+                                        _N('selected department', 'selected departments', $count));
+                            } else {
+                                $errors['err'] = sprintf(__('Unable to archive %s'),
+                                    _N('selected department', 'departments', $count));
+                            }
+                            break;
+                        case 'delete':
+                            //Deny all deletes if one of the selections has members in it.
+                            $sql='SELECT count(staff_id) FROM '.STAFF_TABLE
+                                .' WHERE dept_id IN ('.implode(',', db_input($_POST['ids'])).')';
+                            list($members)=db_fetch_row(db_query($sql));
+                            if($members)
+                                $errors['err']=__('Departments with agents can not be deleted. Move the agents first.');
+                            else {
+                                $i=0;
+                                foreach($_POST['ids'] as $k=>$v) {
+                                    if($v!=$cfg->getDefaultDeptId() && ($d=Dept::lookup($v)) && $d->delete())
+                                        $i++;
+                                }
+                                if($i && $i==$count)
+                                    $msg = sprintf(__('Successfully deleted %s.'),
+                                        _N('selected department', 'selected departments', $count));
+                                elseif($i>0)
+                                    $warn = sprintf(__(
+                                        /* Phrase will read:
+                                           <a> of <b> <selected objects> deleted */
+                                        '%1$d of %2$d %3$s deleted'), $i, $count,
+                                        _N('selected department', 'selected departments', $count));
+                                elseif(!$errors['err'])
+                                    $errors['err'] = sprintf(__('Unable to delete %s.'),
+                                        _N('selected department', 'selected departments', $count));
+                            }
+                            break;
+                    }
                 }
-            }
-            break;
-        default:
-            $errors['err']=__('Unknown action');
-            break;
+                break;
+            default:
+                $errors['err']=__('Unknown action');
+                break;
+        }
     }
-}
 
 $page='departments.inc.php';
 $tip_namespace = 'staff.department';
 if($dept || ($_REQUEST['a'] && !strcasecmp($_REQUEST['a'],'add'))) {
+
+  if ($dept && ($pid=$dept->getParent()) && !$pid->isActive())
+    $warn = sprintf(__('%s is assigned a %s that is not active.'), __('Department'), __('Parent Department'));
+
     $page='department.inc.php';
 }
 
diff --git a/scp/filters.php b/scp/filters.php
index 9e4d63193bfa370b53ca3135d5c2b16c5d7e20ae..9f1a62da32fb5ee53fd7feeea81aa83202135d08 100644
--- a/scp/filters.php
+++ b/scp/filters.php
@@ -116,6 +116,22 @@ if($_POST){
 $page='filters.inc.php';
 $tip_namespace = 'manage.filter';
 if($filter || ($_REQUEST['a'] && !strcasecmp($_REQUEST['a'],'add'))) {
+  if($filter) {
+    foreach ($filter->getActions() as $A) {
+      if($A->type == 'dept')
+        $dept = Dept::lookup($A->parseConfiguration($_POST)['dept_id']);
+
+      if($A->type == 'topic')
+        $topic = Topic::lookup($A->parseConfiguration($_POST)['topic_id']);
+    }
+  }
+
+  if($dept && !$dept->isActive())
+    $warn = sprintf(__('%s is assigned a %s that is not active.'), __('Ticket Filter'), __('Department'));
+
+  if($topic && !$topic->isActive())
+    $warn = sprintf(__('%s is assigned a %s that is not active.'), __('Ticket Filter'), __('Help Topic'));
+
     $page='filter.inc.php';
 }
 
diff --git a/scp/helptopics.php b/scp/helptopics.php
index b00c231d500211a30c4ea30d35a2b8c87a7b38d4..c64a995f0faccec30add58e19940bd82a127620f 100644
--- a/scp/helptopics.php
+++ b/scp/helptopics.php
@@ -63,11 +63,16 @@ if($_POST){
 
                 switch(strtolower($_POST['a'])) {
                     case 'enable':
-                        $num = Topic::objects()->filter(array(
-                            'topic_id__in' => $_POST['ids'],
-                        ))->update(array(
-                            'isactive' => true,
+                        $topics = Topic::objects()->filter(array(
+                          'topic_id__in'=>$_POST['ids'],
                         ));
+                        foreach ($topics as $t)
+                        {
+                          $t->setFlag(Topic::FLAG_ARCHIVED, false);
+                          $t->setFlag(Topic::FLAG_ACTIVE, true);
+                          if($t->save())
+                            $num++;
+                        }
 
                         if ($num > 0) {
                             if($num==$count)
@@ -82,13 +87,18 @@ if($_POST){
                         }
                         break;
                     case 'disable':
-                        $num = Topic::objects()->filter(array(
-                            'topic_id__in'=>$_POST['ids'],
+                        $topics = Topic::objects()->filter(array(
+                          'topic_id__in'=>$_POST['ids'],
                         ))->exclude(array(
-                            'topic_id'=>$cfg->getDefaultTopicId(),
-                        ))->update(array(
-                            'isactive' => false,
+                            'topic_id'=>$cfg->getDefaultTopicId()
                         ));
+                        foreach ($topics as $t)
+                        {
+                          $t->setFlag(Topic::FLAG_ARCHIVED, false);
+                          $t->setFlag(Topic::FLAG_ACTIVE, false);
+                          if($t->save())
+                            $num++;
+                        }
                         if ($num > 0) {
                             if($num==$count)
                                 $msg = sprintf(__('Successfully disabled %s'),
@@ -101,6 +111,31 @@ if($_POST){
                                 _N('selected help topic', 'selected help topics', $count));
                         }
                         break;
+                    case 'archive':
+                        $topics = Topic::objects()->filter(array(
+                          'topic_id__in'=>$_POST['ids'],
+                        ))->exclude(array(
+                            'topic_id'=>$cfg->getDefaultTopicId()
+                        ));
+                        foreach ($topics as $t)
+                        {
+                          $t->setFlag(Topic::FLAG_ARCHIVED, true);
+                          $t->setFlag(Topic::FLAG_ACTIVE, false);
+                          if($t->save())
+                            $num++;
+                        }
+                        if ($num > 0) {
+                            if($num==$count)
+                                $msg = sprintf(__('Successfully archived %s'),
+                                    _N('selected help topic', 'selected help topics', $count));
+                            else
+                                $warn = sprintf(__('%1$d of %2$d %3$s archived'), $num, $count,
+                                    _N('selected help topic', 'selected help topics', $count));
+                        } else {
+                            $errors['err'] = sprintf(__('Unable to archive %s'),
+                                _N('selected help topic', 'selected help topics', $count));
+                        }
+                        break;
                     case 'delete':
                         $i = Topic::objects()->filter(array(
                             'topic_id__in'=>$_POST['ids']
@@ -150,7 +185,11 @@ if($_POST){
 
 $page='helptopics.inc.php';
 $tip_namespace = 'manage.helptopic';
-if($topic || ($_REQUEST['a'] && !strcasecmp($_REQUEST['a'],'add'))) {
+if($topic || ($_REQUEST['a'] && !strcasecmp($_REQUEST['a'],'add')))
+{
+    if ($topic && ($dept=$topic->getDept()) && !$dept->isActive())
+      $warn = sprintf(__('%s is assigned a %s that is not active.'), __('Help Topic'), __('Department'));
+
     $page='helptopic.inc.php';
 }
 
diff --git a/scp/staff.php b/scp/staff.php
index 9b2f4a999c6b6d65b10077dc3ededd2769129a89..fd744ab90e4ce965cd4e1e19e22eb5f0a24dd5bb 100644
--- a/scp/staff.php
+++ b/scp/staff.php
@@ -172,6 +172,10 @@ if($_POST){
 $page='staffmembers.inc.php';
 $tip_namespace = 'staff.agent';
 if($staff || ($_REQUEST['a'] && !strcasecmp($_REQUEST['a'],'add'))) {
+
+  if ($staff && ($pdept=$staff->getDept()) && !$pdept->isActive())
+    $warn = sprintf(__('%s is assigned a %s that is not active.'), __('Agent'), __('Primary Department'));
+
     $page='staff.inc.php';
 }
 
diff --git a/setup/inc/install-prereq.inc.php b/setup/inc/install-prereq.inc.php
index f4346e3f22b8a7c74f005e4dff530950c1ec8e19..97d7a13c48d6332f542e66486d39ee4d7a7f7cc6 100644
--- a/setup/inc/install-prereq.inc.php
+++ b/setup/inc/install-prereq.inc.php
@@ -9,7 +9,7 @@ if(!defined('SETUPINC')) die('Kwaheri!');
              <p><?php echo __('We are delighted you have chosen osTicket for your customer support ticketing system!');?></p>
             <p><?php echo __("The installer will guide you every step of the way in the installation process. You're minutes away from your awesome customer support system!");?></p>
             </div>
-            <h3><?php echo __('Prerequisites');?>:</h3>
+            <h2><?php echo __('Prerequisites');?></h3>
             <p><?php echo __("Before we begin, we'll check your server configuration to make sure you meet the minimum requirements to run the latest version of osTicket.");?></p>
             <h3><?php echo __('Required');?>: <font color="red"><?php echo $errors['prereq']; ?></font></h3>
             <?php echo __('These items are necessary in order to install and use osTicket.');?>