diff --git a/include/class.dept.php b/include/class.dept.php
index 5a2babdd3da4021a7b81c736a79210fdf11f1d97..2a4b6eb1bf32740eebcfabe032b29fb1168a01c2 100644
--- a/include/class.dept.php
+++ b/include/class.dept.php
@@ -89,22 +89,31 @@ class Dept {
         return $this->getNumStaff();
     }
 
-    function getAvailableMembers(){
-
-        if(!$this->members && $this->getNumStaff()){
-            $sql='SELECT m.staff_id FROM '.STAFF_TABLE.' m '
-                .'WHERE m.dept_id='.db_input($this->getId())
-                .' AND m.staff_id IS NOT NULL '
-                .'ORDER BY m.lastname, m.firstname';
-            if(($res=db_query($sql)) && db_num_rows($res)){
-                while(list($id)=db_fetch_row($res))
-                    if(($staff=Staff::lookup($id)) && $staff->isAvailable())
-                        $this->members[]= $staff;
+    function getMembers() {
+
+        if(!$this->members && $this->getNumStaff()) {
+            $sql='SELECT DISTINCT s.staff_id, s.dept_id FROM '.STAFF_TABLE.' s '
+                .' LEFT JOIN '.GROUP_DEPT_TABLE.' g ON(s.group_id=g.group_id) '
+                .' INNER JOIN '.DEPT_TABLE.' d ON(d.dept_id=s.dept_id OR d.manager_id=s.staff_id OR d.dept_id=g.dept_id) '
+                .' WHERE d.dept_id='.db_input($this->getId())
+                .' ORDER BY s.lastname, s.firstname';
+           
+            if(($res=db_query($sql)) && db_num_rows($res)) {
+                while(list($staffId, $deptId)=db_fetch_row($res)) {
+                    if(!$this->enableGroupMembership() 
+                            && $deptId!=$this->getId() 
+                            && $staffId!=$this->getManagerId()) continue;
+
+                    $this->members[] = Staff::lookup($staffId);
+                }
             }
         }
+
         return $this->members;
     }
 
+
+
     function getSLAId(){
         return $this->ht['sla_id'];
     }
@@ -179,6 +188,11 @@ class Dept {
     function noreplyAutoResp(){
          return ($this->ht['noreply_autoresp']);
     }
+
+
+    function enableGroupMembership() {
+        return ($this->ht['group_membership']);
+    }
    
     function getHashtable() {
         return $this->ht;
@@ -214,7 +228,8 @@ class Dept {
             db_query('UPDATE '.STAFF_TABLE.' SET dept_id='.db_input($cfg->getDefaultDeptId()).' WHERE dept_id='.db_input($id));
             //make help topic using the dept default to default-dept.
             db_query('UPDATE '.TOPIC_TABLE.' SET dept_id='.db_input($cfg->getDefaultDeptId()).' WHERE dept_id='.db_input($id));
-            
+            //Delete group access
+            db_query('DELETE FROM '.GROUP_DEPT_TABLE.' WHERE dept_id='.db_input($id));
         }
 
         return $num;
@@ -305,6 +320,7 @@ class Dept {
             .' ,manager_id='.db_input($vars['manager_id']?$vars['manager_id']:0)
             .' ,dept_name='.db_input(Format::striptags($vars['name']))
             .' ,dept_signature='.db_input(Format::striptags($vars['signature']))
+            .' ,group_membership='.db_input(isset($vars['group_membership'])?1:0)
             .' ,ticket_auto_response='.db_input(isset($vars['ticket_auto_response'])?$vars['ticket_auto_response']:1)
             .' ,message_auto_response='.db_input(isset($vars['message_auto_response'])?$vars['message_auto_response']:1);
 
diff --git a/include/class.group.php b/include/class.group.php
index 1b21dce29e4511b469c8dfb70386e7e940626d48..e53cb8538f57edbdb78548c52bfc8cb75e8c7626 100644
--- a/include/class.group.php
+++ b/include/class.group.php
@@ -19,13 +19,19 @@ class Group {
     var $id;
     var $ht;
 
+    var $members;
+    var $departments;
+
     function Group($id){
 
         $this->id=0;
         return $this->load($id);
     }
 
-    function load($id){
+    function load($id=0) {
+
+        if(!$id && !($id=$this->getId()))
+            return false;
 
         $sql='SELECT grp.*,grp.group_name as name, grp.group_enabled as isactive, count(staff.staff_id) as users '
             .'FROM '.GROUP_TABLE.' grp '
@@ -37,12 +43,13 @@ class Group {
         $this->ht=db_fetch_array($res);
         $this->id=$this->ht['group_id'];
         $this->members=array();
+        $this->departments = array();
 
         return $this->id;
     }
 
     function reload(){
-        return $this->load($this->getId());
+        return $this->load();
     }
 
     function getHashtable() {
@@ -73,17 +80,85 @@ class Group {
     function isActive(){
         return $this->isEnabled();
     }
+ 
+    //Get members of the group.
+    function getMembers() {
+
+        if(!$this->members && $this->getNumUsers()) {
+            $sql='SELECT staff_id FROM '.STAFF_TABLE
+                .' WHERE group_id='.db_input($this->getId()).' AND staff_id IS NOT NULL '
+                .' ORDER BY lastname, firstname';
+            if(($res=db_query($sql)) && db_num_rows($res)) {
+                while(list($id)=db_fetch_row($res))
+                    if(($staff=Staff::lookup($id)))
+                        $this->members[]= $staff;
+            }
+        }
 
+        return $this->members;
+    }
 
+    //Get departments the group is allowed to access.
+    function getDepartments() {
 
-    function update($vars,&$errors) {
+        if(!$this->departments) {
+            $sql='SELECT dept_id FROM '.GROUP_DEPT_TABLE
+                .' WHERE group_id='.db_input($this->getId());
+            if(($res=db_query($sql)) && db_num_rows($res)) {
+                while(list($id)=db_fetch_row($res))
+                    $this->departments[]= $id;
+            }
+        }
 
-        if(Group::save($this->getId(),$vars,$errors)){
-            $this->reload();
-            return true;
+        return $this->departments;
+    }
+
+        
+    function updateDeptAccess($depts) {
+
+        if($depts) {
+            foreach($depts as $k=>$id) {
+                $sql='INSERT IGNORE INTO '.GROUP_DEPT_TABLE
+                    .' SET group_id='.db_input($this->getId())
+                    .', dept_id='.db_input($id);
+                db_query($sql);
+            }
         }
 
-        return false;
+        $sql='DELETE FROM '.GROUP_DEPT_TABLE.' WHERE group_id='.db_input($this->getId());
+        if($depts) // just inserted departments IF any.
+            $sql.=' AND dept_id NOT IN('.implode(',', db_input($depts)).')';
+
+        db_query($sql);
+
+        return true;
+    }
+
+    function update($vars,&$errors) {
+
+        if(!Group::save($this->getId(),$vars,$errors))
+            return false;
+
+        $this->updateDeptAccess($vars['depts']);
+        $this->reload();
+        
+        return true;
+    }
+
+    function delete() {
+
+        //Can't delete with members
+        if($this->getNumUsers())
+            return false;
+
+        $res = db_query('DELETE FROM '.GROUP_TABLE.' WHERE group_id='.db_input($this->getId()).' LIMIT 1');
+        if(!$res || !db_affected_rows($res))
+            return false;
+
+        //Remove dept access entry.
+        db_query('DELETE FROM '.GROUP_DEPT_TABLE.' WHERE group_id='.db_input($this->getId()));
+
+        return true;
     }
 
     /*** Static functions ***/
@@ -99,9 +174,11 @@ class Group {
         return ($id && is_numeric($id) && ($g= new Group($id)) && $g->getId()==$id)?$g:null;
     }
 
+    function create($vars, &$errors) { 
+        if(($id=self::save(0,$vars,$errors)) && ($group=self::lookup($id)))
+            $group->updateDeptAccess($vars['depts']);
 
-    function create($vars,&$errors) { 
-        return self::save(0,$vars,$errors);
+        return $id;
     }
 
     function save($id,$vars,&$errors) {
@@ -119,19 +196,19 @@ class Group {
         
         if($errors) return false;
             
-        $sql=' SET updated=NOW(), group_name='.db_input(Format::striptags($vars['name'])).
-             ', group_enabled='.db_input($vars['isactive']).
-             ', dept_access='.db_input($vars['depts']?implode(',',$vars['depts']):'').
-             ', can_create_tickets='.db_input($vars['can_create_tickets']).
-             ', can_delete_tickets='.db_input($vars['can_delete_tickets']).
-             ', can_edit_tickets='.db_input($vars['can_edit_tickets']).
-             ', can_assign_tickets='.db_input($vars['can_assign_tickets']).
-             ', can_transfer_tickets='.db_input($vars['can_transfer_tickets']).
-             ', can_close_tickets='.db_input($vars['can_close_tickets']).
-             ', can_ban_emails='.db_input($vars['can_ban_emails']).
-             ', can_manage_premade='.db_input($vars['can_manage_premade']).
-             ', can_manage_faq='.db_input($vars['can_manage_faq']).
-             ', notes='.db_input($vars['notes']);
+        $sql=' SET updated=NOW() '
+            .', group_name='.db_input(Format::striptags($vars['name']))
+            .', group_enabled='.db_input($vars['isactive'])
+            .', can_create_tickets='.db_input($vars['can_create_tickets'])
+            .', can_delete_tickets='.db_input($vars['can_delete_tickets'])
+            .', can_edit_tickets='.db_input($vars['can_edit_tickets'])
+            .', can_assign_tickets='.db_input($vars['can_assign_tickets'])
+            .', can_transfer_tickets='.db_input($vars['can_transfer_tickets'])
+            .', can_close_tickets='.db_input($vars['can_close_tickets'])
+            .', can_ban_emails='.db_input($vars['can_ban_emails'])
+            .', can_manage_premade='.db_input($vars['can_manage_premade'])
+            .', can_manage_faq='.db_input($vars['can_manage_faq'])
+            .', notes='.db_input($vars['notes']);
             
         if($id) {
             
diff --git a/include/class.staff.php b/include/class.staff.php
index 6e163266dffda7f5f1b610ba0ef6556bfee7b1b4..669a41836511274b39889a8368962bdba2331e69 100644
--- a/include/class.staff.php
+++ b/include/class.staff.php
@@ -25,6 +25,8 @@ class Staff {
     var $id;
 
     var $dept;
+    var $departments;
+    var $group;
     var $teams;
     var $timezone;
     var $stats;
@@ -51,8 +53,9 @@ class Staff {
         
         $this->ht=db_fetch_array($res);
         $this->id  = $this->ht['staff_id'];
-        $this->teams = $this->ht['teams']= array();
-        $this->stats=array();
+        $this->teams = $this->ht['teams'] = array();
+        $this->group = $this->dept = null;
+        $this->departments = $this->stats = array();
 
         //WE have to patch info here to support upgrading from old versions.
         if(($time=strtotime($this->ht['passwdreset']?$this->ht['passwdreset']:$this->ht['added'])))
@@ -154,10 +157,6 @@ class Staff {
         return $this->ht['lastname'];
     }
     
-    function getGroupId() {
-        return $this->ht['group_id'];
-    }
-
     function getSignature() {
         return $this->ht['signature'];
     }
@@ -174,13 +173,46 @@ class Staff {
         return ($this->ht['change_passwd']);
     }
 
+    function getDepartments() {
+
+        if($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.
+        $sql='SELECT DISTINCT d.dept_id FROM '.STAFF_TABLE.' s '
+            .' LEFT JOIN '.GROUP_DEPT_TABLE.' g ON(s.group_id=g.group_id) '
+            .' INNER JOIN '.DEPT_TABLE.' d ON(d.dept_id=s.dept_id OR d.manager_id=s.staff_id OR d.dept_id=g.dept_id) '
+            .' WHERE s.staff_id='.db_input($this->getId());
+
+        $depts = array();
+        if(($res=db_query($sql)) && db_num_rows($res)) {
+            while(list($id)=db_fetch_row($res))
+                $depts[] = $id;
+        } else { //Neptune help us! (fallback)
+            $depts = array_merge($this->getGroup()->getDepartments(), array($this->getDeptId()));
+        }
+
+        $this->departments = array_filter(array_unique($depts));
+
+
+        return $this->departments;
+    }
+
     function getDepts() {
-        //Departments the user is allowed to access...based on the group they belong to + user's dept.
-        return array_filter(array_unique(array_merge(explode(',', $this->ht['dept_access']), array($this->getDeptId())))); //Neptune help us
+        return $this->getDepartments();
+    }
+     
+    function getGroupId() {
+        return $this->ht['group_id'];
     }
 
-    function getDepartments() {
-        return $this->getDepts();
+    function getGroup() {
+     
+        if(!$this->group && $this->getGroupId())
+            $this->group = Group::lookup($this->getGroupId());
+
+        return $this->group;
     }
 
     function getDeptId() {
diff --git a/include/class.ticket.php b/include/class.ticket.php
index 0d9a8ced06a145b71f218af47be20c58fbfa27a1..c5460953e136c8c2472c14c8497ba7e53dd365c4 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -866,7 +866,7 @@ class Ticket{
               
             //Only alerts dept members if the ticket is NOT assigned.
             if($cfg->alertDeptMembersONNewTicket() && !$this->isAssigned()) {
-                if(($members=$dept->getAvailableMembers()))
+                if(($members=$dept->getMembers()))
                     $recipients=array_merge($recipients, $members);
             }
             
@@ -877,6 +877,7 @@ class Ticket{
                 if(!is_object($staff) || !$staff->isAvailable() || in_array($staff->getEmail(),$sentlist)) continue;
                 $alert = str_replace("%staff",$staff->getFirstName(),$body);
                 $email->send($staff->getEmail(),$subj,$alert);
+                $sentlist[] = $staff->getEmail();
             }
            
            
@@ -1029,8 +1030,8 @@ class Ticket{
                 if(!is_object($staff) || !$staff->isAvailable() || in_array($staff->getEmail(),$sentlist)) continue;
                 $alert = str_replace('%staff', $staff->getFirstName(), $body);
                 $email->send($staff->getEmail(), $subj, $alert);
+                $sentlist[] = $staff->getEmail();
             }
-            print_r($sentlist);
         }
 
         return true;
@@ -1072,7 +1073,7 @@ class Ticket{
                     $recipients=array_merge($recipients, $members);
             } elseif($cfg->alertDeptMembersONOverdueTicket() && !$this->isAssigned()) {
                 //Only alerts dept members if the ticket is NOT assigned.
-                if(($members=$dept->getAvailableMembers()))
+                if(($members=$dept->getMembers()))
                     $recipients=array_merge($recipients, $members);
             }
             //Always alert dept manager??
@@ -1084,6 +1085,7 @@ class Ticket{
                 if(!is_object($staff) || !$staff->isAvailable() || in_array($staff->getEmail(),$sentlist)) continue;
                 $alert = str_replace("%staff",$staff->getFirstName(),$body);
                 $email->send($staff->getEmail(),$subj,$alert);
+                $sentlist[] = $staff->getEmail();
             }
 
         }
@@ -1200,7 +1202,7 @@ class Ticket{
                     $recipients+=$members;
             } elseif($cfg->alertDeptMembersONTransfer() && !$this->isAssigned()) {
                 //Only alerts dept members if the ticket is NOT assigned.
-                if(($members=$dept->getAvailableMembers()))
+                if(($members=$dept->getMembers()))
                     $recipients+=$members;
             }
 
@@ -1213,6 +1215,7 @@ class Ticket{
                 if(!is_object($staff) || !$staff->isAvailable() || in_array($staff->getEmail(),$sentlist)) continue;
                 $alert = str_replace("%staff",$staff->getFirstName(),$body);
                 $email->send($staff->getEmail(),$subj,$alert);
+                $sentlist[] = $staff->getEmail();
             }
          }
 
@@ -1361,7 +1364,7 @@ class Ticket{
                 if(!$staff || !$staff->getEmail() || !$staff->isAvailable() && in_array($staff->getEmail(),$sentlist)) continue;
                 $alert = str_replace("%staff",$staff->getFirstName(),$body);
                 $email->send($staff->getEmail(),$subj,$alert);
-                $sentlist[]=$staff->getEmail();
+                $sentlist[] = $staff->getEmail();
             }
         }
         
@@ -1544,7 +1547,7 @@ class Ticket{
                 if(in_array($staff->getEmail(),$sentlist) || ($thisstaff && $thisstaff->getId()==$staff->getId())) continue; 
                 $alert = str_replace('%staff',$staff->getFirstName(),$body);
                 $email->send($staff->getEmail(),$subj,$alert);
-                $sentlist[]=$staff->getEmail();
+                $sentlist[] = $staff->getEmail();
             }
         }
         
diff --git a/include/class.upgrader.php b/include/class.upgrader.php
index 4487e53b26844c8094b72406c5f739cb67702bf3..054377b1945d86a3c8911adfa7ac293ef2fc66d7 100644
--- a/include/class.upgrader.php
+++ b/include/class.upgrader.php
@@ -275,17 +275,21 @@ class Upgrader extends SetupWizard {
                                  'desc' => 'Transitioning to db-backed sessions');
                 break;
             case '98ae1ed2-e342f869': //v1.6 RC1-4 -> v1.6 RC5
-                $task[] = array('func' => 'migrateAPIKeys',
-                                'desc' => 'Migrating API keys to a new table');
+                $tasks[] = array('func' => 'migrateAPIKeys',
+                                 'desc' => 'Migrating API keys to a new table');
+                break;
+            case '435c62c3-5499e513':
+                $tasks[] = array('func' => 'migrateGroupDeptAccess',
+                                 'desc' => 'Migrating group\'s department access to a new table');
                 break;
         }
 
-        //Check IF SQL cleanup is exists. 
+        //Check IF SQL cleanup exists. 
         $file=$this->getSQLDir().$phash.'.cleanup.sql';
         if(file_exists($file)) 
-            $tasks[] = array('func' => 'cleanup', 'desc' => 'Post-upgrade cleanup!',
-                        'phash' => $phash);
-
+            $tasks[] = array('func' => 'cleanup',
+                             'desc' => 'Post-upgrade cleanup!',
+                             'phash' => $phash);
 
         return $tasks;
     }
@@ -336,7 +340,7 @@ class Upgrader extends SetupWizard {
 
         list($whitelist, $key) = db_fetch_row($res);
 
-        $ips=array_filter(explode(',', ereg_replace(' ', '', $whitelist)));
+        $ips=array_filter(array_map('trim', explode(',', $whitelist)));
         foreach($ips as $ip) {
             $sql='INSERT INTO '.API_KEY_TABLE.' SET created=NOW(), updated=NOW(), isactive=1 '
                 .',ipaddr='.db_input($ip)
@@ -346,5 +350,26 @@ class Upgrader extends SetupWizard {
 
         return 0;
     }
+
+    function migrateGroupDeptAccess($taskId) {
+
+        $res = db_query('SELECT group_id, dept_access FROM '.GROUP_TABLE);
+        if(!$res || !db_num_rows($res))
+            return 0;  //No groups??
+
+        while(list($groupId, $access) = db_fetch_row($res)) {
+            $depts=array_filter(array_map('trim', explode(',', $access)));
+            foreach($depts as $deptId) {
+                $sql='INSERT INTO '.GROUP_DEPT_TABLE
+                    .' SET dept_id='.db_input($deptId).', group_id='.db_input($groupId);
+                db_query($sql);
+            }
+        }
+
+        return 0;
+
+
+
+    }
 }
 ?>
diff --git a/include/staff/department.inc.php b/include/staff/department.inc.php
index 521cee9bf9e9eb7446420c26c4e0ab03a1c3ad69..a41c271b12a43d3bc046c87ae6ec84f27a4cb266 100644
--- a/include/staff/department.inc.php
+++ b/include/staff/department.inc.php
@@ -2,7 +2,7 @@
 if(!defined('OSTADMININC') || !$thisstaff || !$thisstaff->isAdmin()) die('Access Denied');
 $info=array();
 $qstr='';
-if($dept && $_REQUEST['a']!='add'){
+if($dept && $_REQUEST['a']!='add') {
     //Editing Department.
     $title='Update Department';
     $action='update';
@@ -10,7 +10,7 @@ if($dept && $_REQUEST['a']!='add'){
     $info=$dept->getInfo();
     $info['id']=$dept->getId();
     $qstr.='&id='.$dept->getId();
-}else {
+} else {
     $title='Add New Department';
     $action='create';
     $submit_text='Create Dept';
@@ -128,8 +128,9 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
                     <option value="0">&mdash; None &mdash;</option>
                     <option value="0" disabled="disabled">Select Department Manager (Optional)</option>
                     <?php
-                    $sql='SELECT staff_id,CONCAT_WS(" ",firstname,lastname) as name FROM '.STAFF_TABLE.' staff '.
-                         'WHERE dept_id='.db_input($dept->getId()).' ORDER by name';
+                    $sql='SELECT staff_id,CONCAT_WS(", ",lastname, firstname) as name '
+                        .' FROM '.STAFF_TABLE.' staff '
+                        .' ORDER by name';
                     if(($res=db_query($sql)) && db_num_rows($res)){
                         while(list($id,$name)=db_fetch_row($res)){
                             $selected=($info['manager_id'] && $id==$info['manager_id'])?'selected="selected"':'';
@@ -141,7 +142,18 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
                 &nbsp;<span class="error">&nbsp;<?php echo $errors['manager_id']; ?></span>
             </td>
         </tr>
-        <?php } ?>
+        <?php 
+        } ?>
+
+        <tr>
+            <td width="180">
+                Group Membership:
+            </td>
+            <td>
+                <input type="checkbox" name="group_membership" value="0" <?php echo $info['group_membership']?'checked="checked"':''; ?> >
+                Extend membership to groups with access. <i>(Alerts and  notices will include groups)</i>
+            </td>
+        </tr>
         <tr>
             <th colspan="2">
                 <em><strong>Auto Response Settings</strong>: Overwrite global auto-response settings for tickets routed to the Dept.</em>
@@ -197,7 +209,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
         <tr>
             <td colspan=2>
                 <textarea name="signature" cols="21" rows="5" style="width: 60%;"><?php echo $info['signature']; ?></textarea>
-                <br><em>Signature is made available as a choice, on ticket reply, for public departments.</em>
+                <br><em>Signature is made available as a choice, for public departments, on ticket reply.</em>
             </td>
         </tr>
     </tbody>
diff --git a/include/staff/group.inc.php b/include/staff/group.inc.php
index afb574f5f3cea7ff161dc34e90c05fa77f955b51..83220475de4bf388cd2368774a9cccaba1022896 100644
--- a/include/staff/group.inc.php
+++ b/include/staff/group.inc.php
@@ -8,7 +8,7 @@ if($group && $_REQUEST['a']!='add'){
     $submit_text='Save Changes';
     $info=$group->getInfo();
     $info['id']=$group->getId();
-    $info['depts']=$info['dept_access']?explode(',',$info['dept_access']):array();
+    $info['depts']=$group->getDepartments();
     $qstr.='&id='.$group->getId();
 }else {
     $title='Add New Group';
diff --git a/include/staff/tickets.inc.php b/include/staff/tickets.inc.php
index 63f2fb31c4a871f60ca13d3fff0f66e5a2c11ae9..8397a4988d504f7394afa6a6ba0a05da7584eb16 100644
--- a/include/staff/tickets.inc.php
+++ b/include/staff/tickets.inc.php
@@ -63,6 +63,7 @@ $qwhere ='';
 $depts=$thisstaff->getDepts();    
 $qwhere =' WHERE ( '
         .'  ticket.staff_id='.db_input($thisstaff->getId());
+
 if(!$thisstaff->showAssignedOnly())
     $qwhere.=' OR ticket.dept_id IN ('.($depts?implode(',',$depts):0).')';
 
diff --git a/scp/groups.php b/scp/groups.php
index 7a4f959169160f6f41f0ebce70db6c6ced266695..4a0b9f157960398ddb9bfc8683629af39a83d3a6 100644
--- a/scp/groups.php
+++ b/scp/groups.php
@@ -64,7 +64,7 @@ if($_POST){
                     }
                 }elseif($_POST['delete']){
                     foreach($_POST['ids'] as $k=>$v) {
-                        if(($t=Group::lookup($v)) && $t->delete())
+                        if(($g=Group::lookup($v)) && $g->delete())
                             $i++;
                     }