--- loncom/interface/loncoursegroups.pm	2006/03/21 20:18:18	1.11
+++ loncom/interface/loncoursegroups.pm	2023/07/29 20:33:25	1.132
@@ -1,3 +1,6 @@
+# The LearningOnline Network with CAPA
+#
+# $Id: loncoursegroups.pm,v 1.132 2023/07/29 20:33:25 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -26,18 +29,26 @@ package Apache::loncoursegroups;
 
 use strict;
 use Apache::lonnet;
-use Apache::loncommon;
-use Apache::lonhtmlcommon;
+use Apache::loncommon();
+use Apache::lonhtmlcommon();
+use Apache::lonhtmlgateway;
 use Apache::lonlocal;
-use Apache::lonnavmaps;
+use Apache::lonnavmaps();
+use Apache::longroup();
+use Apache::portfolio();
+use Apache::lonuserutils();
 use Apache::Constants qw(:common :http);
+use HTML::Entities;
+use LONCAPA::map();
+use lib '/home/httpd/lib/perl/';
+use LONCAPA;
 
 sub handler {
     my ($r) = @_;
 
     &Apache::loncommon::content_type($r,'text/html');
     $r->send_http_header;
-                                                                                
+
     if ($r->header_only) {
         return OK;
     }
@@ -46,30 +57,33 @@ sub handler {
     if (! ($env{'request.course.fn'})) {
         # Not in a course
         $env{'user.error.msg'}=
-     "/adm/coursegroups:mdg:0:0:Cannot edit or view course groups";
+     "/adm/coursegroups:mdg:0:0:Cannot edit or view course/community groups";
         return HTTP_NOT_ACCEPTABLE;
     }
 
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                         ['action','refpage','state','groupname','branch']);
-    my $function = &Apache::loncommon::get_users_function();
-    my $tabcol = &Apache::loncommon::designparm($function.'.tabbg');
     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
 
     my $view_permission =
-          &Apache::lonnet::allowed('vcg',$env{'request.course.id'});
+          &Apache::lonnet::allowed('vcg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
     my $manage_permission =
-          &Apache::lonnet::allowed('mdg',$env{'request.course.id'});
+          &Apache::lonnet::allowed('mdg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
     &Apache::lonhtmlcommon::clear_breadcrumbs();
 
+    my $gpterm = &Apache::loncommon::group_term();
+    my $ucgpterm = $gpterm;
+    $ucgpterm =~ s/^(\w)/uc($1)/e;
+    my $crstype = &Apache::loncommon::course_type();
+
     my %functions = (
-                      email => 'E-mail',
-                      discussion => 'Discussion boards',
-                      chat => 'Chat',
-                      files => 'File repository',
-                      roster => 'Membership roster',
-                      homepage => 'Group home page',
+                      email => 'Send Messages', 
+                      discussion => 'Discussion Boards',
+                      chat => 'Chat Room',
+                      files => 'Group Portfolio',
+                      roster => 'Membership Roster',
+                      homepage => $ucgpterm.' home page',
                     );
 
     my %idx = ();
@@ -77,122 +91,202 @@ sub handler {
     $idx{fullname} = &Apache::loncoursedata::CL_FULLNAME();
     $idx{udom} = &Apache::loncoursedata::CL_SDOM();
     $idx{uname} = &Apache::loncoursedata::CL_SNAME();
-
-    my $rowColor1 = "#dddddd";
-    my $rowColor2 = "#eeeeee";
+    $idx{section} = &Apache::loncoursedata::CL_SECTION();
 
     my $action = $env{'form.action'};
-    if ($action eq 'create' || $action eq 'modify' || $action eq 'view') { 
+    my $state = $env{'form.state'};
+    if ((!defined($action)) || ($action eq 'view') || ($action eq 'modify') || ($action eq 'delete') || ($action eq 'reenable')) {
+        if (!defined($state)) {
+            $state = 'view';
+        }
+    }
+    if ($action eq 'create' || $action eq 'modify' || $action eq 'view' || 
+        $action eq 'delete' || $action eq 'reenable') { 
         if ($view_permission || $manage_permission) {
-            &group_administration($r,$action,$cdom,$cnum,$function,$tabcol,
-                                  \%functions,\%idx,$view_permission,
-                                  $manage_permission,$rowColor1,$rowColor2);
+            if ($state eq 'view') {
+                &print_main_menu($r,$cdom,$cnum,\%functions,\%idx,
+                                 $view_permission,$manage_permission,
+                                 $action,$state,$gpterm,$ucgpterm,$crstype);
+            } else {
+                &group_administration($r,$action,$state,$cdom,$cnum,
+                                      \%functions,\%idx,$view_permission,
+                                      $manage_permission,$gpterm,$ucgpterm,
+		   		      $crstype);
+            }
         } else {
-            $r->print(&mt('You do not have group administration '.
-                          'privileges in this course'));
+            $r->print('<div class="LC_warning">'
+                     .&mt('You do not have '.$gpterm.' administration '
+                         .'privileges in this '.lc($crstype).'.')
+                     .'</div>');
         }
     } else {
-        &print_main_menu($r,$cdom,$cnum,$function,$tabcol,\%functions,\%idx,
-                         $view_permission,$manage_permission,$action,
-                         $rowColor1,$rowColor2);
+        &print_main_menu($r,$cdom,$cnum,\%functions,\%idx,$view_permission,
+			 $manage_permission,$action,$state,$gpterm,$ucgpterm,
+			 $crstype);
     }
     return OK;
 }
 
 sub print_main_menu {
-    my ($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,$view_permission,
-        $manage_permission,$action,$rowColor1,$rowColor2) = @_;
-    $r->print(&header('Course Groups',undef,undef,undef,undef,$function));
+    my ($r,$cdom,$cnum,$functions,$idx,$view_permission,$manage_permission,
+	$action,$state,$gpterm,$ucgpterm,$crstype) = @_;
+    my $jscript = qq|
+function changeSort(caller) {
+    document.$state.sortby.value = caller;
+    document.$state.submit();
+}
+function openGroupRoster(group,status) {
+    var url = '/adm/grouproster?';
+    url += 'group='+group+'&amp;status='+status+'&amp;ref=popup';
+    var title = 'Group_Membership';
+    var options = 'scrollbars=1,resizable=1,menubar=0';
+    options += ',width=700,height=600';
+    rosterbrowser = open(url,title,options,'1');
+    rosterbrowser.focus();
+}\n|;
+    $r->print(&header('My Space',$jscript,$action,$state));
+    if ($env{'form.refpage'} eq 'cusr') {
+        &Apache::lonhtmlcommon::add_breadcrumb
+            ({href=>"/adm/createuser",
+              text=>"User Management"});
+    }
     &Apache::lonhtmlcommon::add_breadcrumb
         ({href=>"/adm/coursegroups",
-          text=>"Course Groups",});
-    $r->print(&Apache::lonhtmlcommon::breadcrumbs
-              (undef,'Course Groups'));
-    &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,
-                    $view_permission,$manage_permission,$action,$rowColor1,
-                    $rowColor2);
+          text=>"Groups"});
+    my $helpitem;
+    if ($manage_permission) {
+        $helpitem = 'Creating_Groups';
+    }
+    $r->print(&Apache::lonhtmlcommon::breadcrumbs('Groups',$helpitem));
+    &display_groups($r,$cdom,$cnum,$functions,$idx,$view_permission,
+		    $manage_permission,$action,$state,$gpterm,$ucgpterm,
+		    $crstype);
     $r->print(&footer());
     return;
 }
 
 sub display_groups {
-    my ($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,$view_permission,
-        $manage_permission,$action,$rowColor1,$rowColor2) = @_;
+    my ($r,$cdom,$cnum,$functions,$idx,$view_permission,
+        $manage_permission,$action,$state,$gpterm,$ucgpterm,$crstype) = @_;
     my %curr_groups = ();
     my %grp_info = ();
-
     my %actionlinks = (
-      modify => '<a href="/adm/coursegroups?action=modify&state=pick_task&refpage='.
-                $env{'form.refpage'}.'&groupname=',
-      view => '<a href="/adm/'.$cdom.'/'.$cnum.'/',
-      delete => '<a href="/adm/coursegroups?action=delete&refpage='.
-                $env{'form.refpage'}.'&groupname=',
+      modify   => '/adm/coursegroups?action=modify&refpage='.
+                  $env{'form.refpage'}.'&state=pick_task&groupname=',
+      view     => '',
+      delete   => '/adm/coursegroups?action=delete&refpage='.
+                  $env{'form.refpage'}.'&state=verify&groupname=',
+      reenable => '/adm/coursegroups?action=reenable&refpage='.
+                  $env{'form.refpage'}.'&state=verify&groupname=',
     );
     my %lt = &Apache::lonlocal::texthash( 
                           modify => 'Modify',
                           view   => 'View',
                           delete => 'Delete',
+                          reenable => 'Re-enable',
                           act    => 'Action',
                           gname  => 'Group Name',
-                          desc   => 'Description',
+                          desc   => 'Group Title',
                           crea   => 'Creator',
                           crtd   => 'Created',
                           last   => 'Last Modified',
-                          func   => 'Functionality',
-                          quot   => 'Quota (Mb)',
+                          func   => 'Collaborative Tools',
+                          quot   => 'Quota (MB)',
                           memb   => 'Members',
                           file   => 'Files',
                           dibd   => 'Discussion Boards',
-                          dius   => 'Disk Use',
+                          dius   => 'Disk Use (%)',
                           nogr   => 'No groups exist.',
                           crng   => 'Create a new group',
+                          redg   => 'Re-enable a deleted group',
                           alth   => 'Although your current role has privileges'.
-                                    ' to view any existing groups in this course,'.
-                                    ' you do not have privileges to create new'.
-                                    ' groups.',
+                                    ' to view any existing groups in this '.
+                                    lc($crstype).', you do not have privileges '.
+                                    'to create new groups.',
                      );
     if ($view_permission) {
         if (!defined($action)) {
             $action = 'view';
         }
-        my %curr_groups;
-        if (&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum)) {
+        my ($status,$reenable_link);
+        if ($action eq 'reenable') {
+            $status = 'deleted_groups';
+        } else {
+            if ($manage_permission) {
+                my %deleted_groups = 
+                    &Apache::longroup::coursegroups($cdom,$cnum,undef,'deleted_groups');
+                if (keys(%deleted_groups) > 0) {
+                    $reenable_link = '&nbsp;&nbsp;&nbsp;&nbsp;<a href="/adm/coursegroups?action=reenable&amp;refpage='.$env{'form.refpage'}.'">'.$lt{'redg'}.'</a>';
+                }
+            }
+        }
+        my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum,undef,
+                                                          $status);
+
+        if (%curr_groups) {
+            my $navmap=Apache::lonnavmaps::navmap->new();
+            if (!defined($navmap)) {
+                $r->print('<div class="LC_error">'.
+                          &mt('An error occurred retrieving information about resources in the course.').'<br />'.
+                          &mt('It is recommended that you [_1]re-initialize the course[_2] and then return to this page.','<a href="/adm/roles?selectrole=1&amp;newrole='.$env{'request.role'}.'&amp;orgurl=%2fadm%2fcoursegroups">','</a>').
+                          '</div>');
+                return;
+            }
+            if ($manage_permission) {
+                if ($action ne 'reenable') {
+                    $r->print('<br /><a href="/adm/coursegroups?action=create&amp;refpage='.$env{'form.refpage'}.'">'.$lt{'crng'}.'</a>');
+                }
+                if ($reenable_link) {
+                    $r->print($reenable_link);
+                }
+            }
             $r->print('<br /><br />');
-            $r->print(&Apache::lonhtmlcommon::start_pick_box());
+	    $r->print(&Apache::loncommon::start_data_table().
+		      &Apache::loncommon::start_data_table_header_row());
+		      
             $r->print(<<"END");
-      <table border="0" cellpadding="4" cellspacing="1">
-       <tr bgcolor="$tabcol" align="center">
-        <td><b>$lt{'act'}</b></td>
-        <td><b><a href="javascript:changeSort('groupname')">$lt{'gname'}</a></b></td>
-        <td><b><a href="javascript:changeSort('description')">$lt{'desc'}</a></b></td>
-        <td><b><a href="javascript:changeSort('creator')">$lt{'crea'}</a></b>
-        </td>
-        <td><b><a href="javascript:changeSort('creation')">$lt{'crtd'}</a></b>
-        </td>
-        <td><b><a href="javascript:changeSort('modified')">$lt{'last'}</a></b>
-        </td>
-        <td><b>$lt{'func'}</b>
-        </td>
-        <td><b><a href="javascript:changeSort('quota')">$lt{'quot'}</a></b></td>
-        <td><b><a href="javascript:changeSort('totalmembers)">$lt{'memb'}</a></b></td>
-        <td><b><a href="javascript:changeSort('totalfiles')">$lt{'file'}</a></b></td>
-        <td><b><a href="javascript:changeSort('boards')">$lt{'dibd'}</a></b></td>
-        <td><b><a href="javascript:changeSort('diskuse')">$lt{'dius'}</a></b></td>
-       </tr>
+        <th>$lt{'act'}</th>
+        <th><a href="javascript:changeSort('groupname')">$lt{'gname'}</a></th>
+        <th><a href="javascript:changeSort('description')">$lt{'desc'}</a></th>
+        <th><a href="javascript:changeSort('creator')">$lt{'crea'}</a></th>
+        <th><a href="javascript:changeSort('creation')">$lt{'crtd'}</a></th>
+        <th><a href="javascript:changeSort('modified')">$lt{'last'}</a></th>
+        <th>$lt{'func'}</th>
+        <th><a href="javascript:changeSort('quota')">$lt{'quot'}</a></th>
+        <th><a href="javascript:changeSort('totalmembers')">$lt{'memb'}</a></th>
+        <th><a href="javascript:changeSort('totalfiles')">$lt{'file'}</a></th>
+        <th><a href="javascript:changeSort('boards')">$lt{'dibd'}</a></th>
+        <th><a href="javascript:changeSort('diskuse')">$lt{'dius'}</a></th>
 END
+	    $r->print(&Apache::loncommon::end_data_table_header_row());
             my %Sortby = ();
             foreach my $group (sort(keys(%curr_groups))) {
                 %{$grp_info{$group}} = 
-                                  &Apache::loncommon::get_group_settings(
+                                  &Apache::longroup::get_group_settings(
                                                          $curr_groups{$group});
                 my $members_result = &group_members($cdom,$cnum,$group,
                                                     \%grp_info);
-                my $files_result = &group_files($group,\%grp_info); 
+                my $port_path = '/userfiles/groups/'.$group.'/portfolio';
+                my $totaldirs = 0;
+                my $totalfiles = 0;
+                &group_files($group,$port_path,\$totalfiles,\$totaldirs);
+                $grp_info{$group}{'totalfiles'} = $totalfiles;
+                $grp_info{$group}{'totaldirs'} = $totaldirs;
+                my $getpropath = 1;  
+                my $diskuse = &Apache::lonnet::diskusage($cdom,$cnum,$port_path,                                                         $getpropath);
+                if ($grp_info{$group}{'quota'} > 0) {
+                    my $pct_use = 0.1 * $diskuse/$grp_info{$group}{'quota'};
+                    $grp_info{$group}{'diskuse'} = sprintf("%.0f",$pct_use);
+                } else {
+                    $grp_info{$group}{'diskuse'} = 'N/A';
+                }
+                my ($groupboards,$boardshash)=&Apache::longroup::get_group_bbinfo(
+                                                               $cdom,$cnum,$group);
+                $grp_info{$group}{'boards'} = scalar(@{$groupboards});
                 if ($env{'form.sortby'} eq 'groupname') {
                     push(@{$Sortby{$group}},$group);
                 } elsif ($env{'form.sortby'} eq 'description') {
-                    push(@{$Sortby{$grp_info{$group}{'description'}}},
-                                                                     $group);
+                    push(@{$Sortby{$grp_info{$group}{'description'}}},$group);
                 } elsif ($env{'form.sortby'} eq 'creator') {
                     push(@{$Sortby{$grp_info{$group}{'creator'}}},$group);
                 } elsif ($env{'form.sortby'} eq 'creation') {
@@ -214,23 +308,17 @@ END
                     push(@{$Sortby{$group}},$group);
                 }
             }
-            my $rowNum = 0;
-            my $rowColor;
             foreach my $key (sort(keys(%Sortby))) {
                 foreach my $group (@{$Sortby{$key}}) {
-                    if ($rowNum %2 == 1) {
-                        $rowColor = $rowColor1;
-                    } else {
-                        $rowColor = $rowColor2;
-                    }
                     my $description = 
-                   &Apache::lonnet::unescape($grp_info{$group}{'description'});
+			&unescape($grp_info{$group}{'description'});
                     my $creator = $grp_info{$group}{'creator'};
                     my $creation = $grp_info{$group}{'creation'};
                     my $modified = $grp_info{$group}{'modified'}; 
                     my $quota = $grp_info{$group}{'quota'};
                     my $totalmembers = $grp_info{$group}{'totalmembers'};
                     my $totalfiles = $grp_info{$group}{'totalfiles'};
+                    my $totaldirs = $grp_info{$group}{'totaldirs'};
                     my $boards = $grp_info{$group}{'boards'};
                     my $diskuse = $grp_info{$group}{'diskuse'};
                     my $functionality;
@@ -242,54 +330,140 @@ END
                     if (!$functionality) {
                         $functionality = &mt('None available');
                     }
-                    my $link = $actionlinks{$action};
-                    if ($action eq 'modify' || $action eq 'delete') {
-                        $link .= $group;
+                    my $link;
+                    if ($action eq 'modify' || $action eq 'delete' || 
+                        $action eq 'reenable') {
+                        $link = '<a href="'.&HTML::Entities::encode($actionlinks{$action}.$group,'<>&"').
+                                '">'.$lt{$action}.'</a>';
                     } else {
-                        $link .= $group.'/grppg?register=1';
+                        $link =
+                            &Apache::longroup::get_group_link($cdom,$cnum,$group,$navmap,
+                                                              $view_permission);
+                        if ($link) {
+                            $link = '<a href="'.$link;
+                            $link .= (($link=~/\?/)?'&amp;':'?').'ref=grouplist';
+                            if (exists($env{'form.refpage'})) {
+                                $link .= '&amp;refpage='.$env{'form.refpage'};
+                            }
+                            $link .= '">'.$lt{$action}.'</a>';
+                        }
+                    }
+                    if ($action eq 'view') { 
+                        if ($manage_permission) { 
+                            $link .= '&nbsp;&nbsp;<a href="'.
+                                      &HTML::Entities::encode($actionlinks{'modify'}.$group,'<>&"').
+                                      '">'.$lt{'modify'}.'</a>&nbsp;&nbsp;<a href="'.
+                                      &HTML::Entities::encode($actionlinks{'delete'}.$group,'<>&"').
+                                      '">'.$lt{'delete'}.'</a>';
+                        }
                     }
-                    $link .= '">'.$lt{$action}.'</a>';  
-                    $r->print('<tr bgcolor="'.$rowColor.'"><td><small>'.$link.'</small></td><td><small>'.$group.'</small></td><td><small>'.$description.'</small></td><td><small>'.$creator.'</small></td><td><small>'. &Apache::lonnavmaps::timeToHumanString($creation).'</small></td><td><small>'. &Apache::lonnavmaps::timeToHumanString($modified).'</small></td><td><small>'.$functionality.'</small></td><td><small>'.$quota.'</small></td><td><small>'.$totalmembers.'</small></td><td><small>'.$totalfiles.'</small></td><td><small>'.$boards.'</small></td><td><small>'.$diskuse.'</small></td></tr>');
-                    $rowNum ++;
+                    $r->print(&Apache::loncommon::start_data_table_row('LC_data_table_dense').
+			      '<td>'.$link.'</td>'.
+			      '<td>'.$group.'</td>'.
+			      '<td>'.$description.'</td>'.
+			      '<td>'.$creator.'</td>'.
+			      '<td>'. &Apache::lonnavmaps::timeToHumanString($creation).'</td>'.
+			      '<td>'. &Apache::lonnavmaps::timeToHumanString($modified).'</td>'.
+			      '<td>'.$functionality.'</td>'.
+			      '<td align="right">'.$quota.'</td>'.
+			      '<td align="right">'.$totalmembers.'</td>'.
+			      '<td align="right">'.
+                                  '<span class="LC_nobreak">'.&mt('Files: [_1]',$totalfiles).'</span><br />'.
+                                  '<span class="LC_nobreak">'.&mt('Folders: [_1]',$totaldirs).'</span>'.
+                                  '</td>'.
+			      '<td align="right">'.$boards.'</td>'.
+			      '<td align="right">'.$diskuse.'</td>'.
+			      &Apache::loncommon::end_data_table_row());
+                }
+            }
+            $r->print(&Apache::loncommon::end_data_table());
+            $r->print('<input type="hidden" name="refpage" '.
+                      'value="'.$env{'form.refpage'}.'" />');
+            if ($action eq 'view') {
+                if (!defined($state)) {
+                    $state = 'view';
                 }
+                $r->print('<input type="hidden" name="state" value="'.
+                      $state.'" />');
             }
-            $r->print('</table>');
-            $r->print(&Apache::lonhtmlcommon::end_pick_box());
         } else {
             $r->print($lt{'nogr'});
             if ($manage_permission) {
-                $r->print('<br /><br /><a href="/adm/coursegroups?action=create&refpage='.$env{'form.refpage'}.'">'.$lt{'crng'}.'</a>');
+                $r->print('<br /><br /><a href="/adm/coursegroups?action=create&amp;refpage='.$env{'form.refpage'}.'">'.$lt{'crng'}.'</a>');
+                if ($action ne 'reenable') {
+                    if ($reenable_link) {
+                        $r->print($reenable_link);
+                    }
+                }
             } else {
-                $r->print('<br /><br />'.$lt{'crng'});
-
+                $r->print('<br /><br />'.$lt{'alth'});
             }
         }
     } else {
         my @coursegroups = split(/:/,$env{'request.course.groups'});
         if (@coursegroups > 0) {
+            my $numlinks = 0;
             $r->print('<br /><br />');
-            my %curr_groups;
-            if (&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum)) {
+            my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum);
+            if (%curr_groups) {
+                my $navmap=Apache::lonnavmaps::navmap->new();
+                if (!defined($navmap)) {
+                    $r->print('<div class="LC_error">'.
+                              &mt('An error occurred retrieving information about resources in the course.').'<br />'.
+                              &mt('It is recommended that you [_1]re-initialize the course[_2] and then return to this page.','<a href="/adm/roles?selectrole=1&amp;newrole='.$env{'request.role'}.'&amp;orgurl=%2fadm%2fcoursegroups">','</a>').
+                              '</div>');
+                    return;
+                }
                 foreach my $group (@coursegroups) {
-                    my %group_info =  &Apache::loncommon::get_group_settings(
+                    my %group_info =  &Apache::longroup::get_group_settings(
                                         $curr_groups{$group});
-                    my $description = &Apache::lonnet::unescape(
+                    my $description = &unescape(
                                         $group_info{description});
-                    my ($uname,$udom) = split(/:/,$group_info{creator});
-                    $r->print('<font size="+1"><a href="/adm/'.$udom.'/'.$uname.'/'.$group.'/grppg?register=1">'.$group,'</a><font><br /><small>'.$description.'</small><br /><br />');
+                    my ($link,$hidden) = 
+                        &Apache::longroup::get_group_link($cdom,$cnum,$group,$navmap,
+                                                          $view_permission);
+                    if ($link) {
+                        $link .= '&amp;ref=grouplist';
+                        $r->print('<span style="font-size: larger"><a href="'.$link.'">'.
+                                  $description.'</a></span><br /><br />');
+                        $numlinks ++;
+                    } elsif ($hidden) {
+                        my $numtools = 0;
+                        my $refarg = '&amp;ref=grouplist'; 
+                        my $output =
+                            &Apache::longroup::display_group_links($r,$env{'form.grade_target'},$group,'view',
+                                                                   $refarg,\$numtools,$hidden,%group_info);
+                        if ($numtools) {
+                            $r->print('<span style="font-size: larger">'.$description.'</a></span>'.
+                                      '<br />'.$output.'<br /><br />');
+                            $numlinks ++;
+                        }
+                    }
                 }
             }
+            if (!$numlinks) {
+                $r->print(
+                    '<p class="LC_info">'
+                   .&mt('You do not currently have access to any '.$gpterm.'s'
+                   .' in this '.lc($crstype).'.')
+                   .'</p>'
+                );
+            }
         } else {
-            $r->print(&mt('You are not currently a member of any '.
-                          'active groups in this course'));
+            $r->print(
+                '<p class="LC_info">'
+               .&mt('You are not currently a member of any active '.$gpterm.'s'
+                   .' in this '.lc($crstype).'.')
+               .'</p>'
+            );
         }
     }
     return;
 }
 
 sub group_administration {
-    my ($r,$action,$cdom,$cnum,$function,$tabcol,$functions,$idx,
-        $view_permission,$manage_permission,$rowColor1,$rowColor2) = @_;
+    my ($r,$action,$state,$cdom,$cnum,$functions,$idx,$view_permission,
+	$manage_permission,$gpterm,$ucgpterm,$crstype) = @_;
     my %sectioncount = ();
     my @tools = ();
     my @types = ();
@@ -303,8 +477,8 @@ sub group_administration {
     my %memchg;
     my @member_changes = ('deletion','expire','activate','reenable',
                           'changefunc','changepriv');
-    my $state = $env{'form.state'};
-    my ($groupname,$description,$startdate,$enddate,$granularity,$specificity);
+    my ($groupname,$description,$startdate,$enddate,$granularity,$specificity,
+        $quota,$validate_script);
 
     if (defined($env{'form.groupname'})) {
         $groupname = $env{'form.groupname'};
@@ -328,7 +502,9 @@ sub group_administration {
         if (defined($env{'form.specificity'})) {
             $specificity=$env{'form.specificity'};
         }
-
+        if (defined($env{'form.quota'})) {
+            $quota=$env{'form.quota'};
+        }
     }
     if (($action eq 'create') || (($action eq 'modify') 
         && (($state eq 'pick_privs') || ($state eq 'addresult')))) {
@@ -342,9 +518,11 @@ sub group_administration {
 
     if ($action eq 'modify') {
         if ($state eq '') {
-            $state = 'pick_group';
+            if (defined($env{'form.groupname'})) {
+                $state = 'pick_task';
+            }
         } else {
-            %stored = &retrieve_settings($cdom,$cnum,$groupname);
+            %stored = &retrieve_settings($cdom,$cnum,$groupname,$action);
             if (ref($stored{'types'}) eq 'ARRAY') {
                 @types = @{$stored{'types'}};
             }
@@ -363,89 +541,68 @@ sub group_administration {
                 $description = $stored{'description'};
                 $granularity = $stored{'granularity'};
                 $specificity =  $stored{'specificity'};
+                $quota = $stored{'quota'};
             }
         }
     }
 
-    my %toolprivs = ();
-    %{$toolprivs{'email'}} = (
-                                 sgm => 'Send group mail',
-                                 sgb => 'Broadcast mail',
-                             );
-    %{$toolprivs{'discussion'}} =  (
-                                     cgb => 'Create boards',
-                                     pgd => 'Post',
-                                     pag => 'Anon. posts',
-                                     rgi => 'Get identities', 
-                                     vgb => 'View boards',
-                                   );
-    %{$toolprivs{'chat'}} =  (
-                                pgc => 'Chat',
-                             );
-    %{$toolprivs{'files'}} =  (
-                                 rgf => 'Retrieve',
-                                 ugf => 'Upload',
-                                 dgf => 'Delete',
-                              );
-    %{$toolprivs{'roster'}} = (
-                                 vgm => 'View',
-                              );
-    %{$toolprivs{'homepage'}} = (
-                                vgh => 'View page',
-                                mgh => 'Modify page',
-                              );
-    my %fixedprivs = ();
-    %{$fixedprivs{'email'}} = ('sgm' => 1);
-    %{$fixedprivs{'discussion'}} = ('vgb' => 1);
-    %{$fixedprivs{'chat'}} = ('pgc' => 1);
-    %{$fixedprivs{'files'}} = ('rgf' => 1);
-    %{$fixedprivs{'roster'}} = ('vgm' => 1);
-    %{$fixedprivs{'homepage'}} = ('vgh' => 1);
-
-    my %elements = ();
-    %{$elements{'create'}} = ();
-    %{$elements{'modify'}} = ();
-    %{$elements{'create'}{'pick_name'}} = (
-        startdate_month => 'selectbox',
-        startdate_hour => 'selectbox',
-        enddate_month => 'selectbox',
-        enddate_hour => 'selectbox',
-        startdate_day => 'text',
-        startdate_year => 'text',
-        startdate_minute => 'text',
-        startdate_second => 'text',
-        enddate_day => 'text',
-        enddate_year => 'text',
-        enddate_minute => 'text',
-        enddate_second => 'text',
-        groupname => 'text',
-        description => 'text',
-        tool => 'checkbox',
-        granularity => 'radio',
-        no_end_date => 'checkbox',
-    );
-    %{$elements{'modify'}{'change_settings'}} = (
-                                   %{$elements{'create'}{'pick_name'}},
-                                                specificity => 'radio',
-                                                defpriv => 'checkbox',
-                                                autorole => 'checkbox',
-                                                autoadd => 'radio',
-                                                autodrop => 'radio',
-                                   );
+    my $toolprivs = &Apache::longroup::get_tool_privs($gpterm);
+
+    my $fixedprivs = &Apache::longroup::get_fixed_privs();
+
+    my %elements = 
+	(
+	 create => {
+	     pick_name => {
+		 startdate_month  => 'selectbox',
+		 startdate_hour   => 'selectbox',
+		 enddate_month    => 'selectbox',
+		 enddate_hour     => 'selectbox',
+		 startdate_day    => 'text',
+		 startdate_year   => 'text',
+		 startdate_minute => 'text',
+		 startdate_second => 'text',
+		 enddate_day      => 'text',
+		 enddate_year     => 'text',
+		 enddate_minute   => 'text',
+		 enddate_second   => 'text',
+		 groupname        => 'text',
+		 description      => 'text',
+                 quota            => 'text',
+		 tool             => 'checkbox',
+		 granularity      => 'radio',
+		 no_end_date      => 'checkbox',
+	     },
+	     pick_members => {
+		 member          => 'checkbox',
+		 defpriv         => 'checkbox',
+	     },
+	 },
+	 );
+    
+    $elements{'modify'} = {
+	change_settings => {
+	    %{$elements{'create'}{'pick_name'}},
+	    specificity => 'radio',
+	    defpriv     => 'checkbox',
+	    autorole    => 'checkbox',
+	    autoadd     => 'radio',
+	    autodrop    => 'radio',
+	},
+	add_members => {
+	    types       => 'selectbox',
+	    roles       => 'selectbox',
+	},
+    };
+
     if (ref($stored{'autorole'}) eq 'ARRAY') {
         foreach my $role (@{$stored{'autorole'}}) {
-            $elements{'modify'}{'change_settings'}{'sec_'.$role} = 'selectbox'; 
+            unless (($role eq 'cc') || ($role eq 'co')) {
+                $elements{'modify'}{'change_settings'}{'sec_'.$role} = 
+                                                                   'selectbox';
+            }
         }
     }
-    %{$elements{'create'}{'pick_members'}} = (
-        member => 'checkbox',
-        defpriv => 'checkbox',
-    );
-
-    %{$elements{'modify'}{'add_members'}} = (
-        types => 'selectbox',
-        roles => 'selectbox',
-    );
 
     if (($action eq 'create') && ($state eq 'pick_name')) {
         $elements{'create'}{'pick_name'}{'types'} = 'selectbox';
@@ -455,16 +612,14 @@ sub group_administration {
         (($state eq 'pick_name') || ($state eq 'pick_privs'))) ||
        (($action eq 'modify') && (($state eq 'change_settings') ||
                                   ($state eq 'add_members')))) {
-        my $numsections = &Apache::loncommon::get_sections($cdom,$cnum,
-                                                           \%sectioncount);
-        if ($numsections > 0) {
-            $elements{'create'}{'pick_name'}{'sectionpick'} = 'selectbox';
-            $elements{'modify'}{'change_mapping'}{'sectionpick'} = 'selectbox';
-            $elements{'modify'}{'add_members'}{'sectionpick'} = 'selectbox';
-        }
+        %sectioncount = &Apache::loncommon::get_sections($cdom,$cnum);
+        $elements{'create'}{'pick_name'}{'sectionpick'} = 'selectbox';
+        $elements{'modify'}{'change_mapping'}{'sectionpick'} = 'selectbox';
+        $elements{'modify'}{'add_members'}{'sectionpick'} = 'selectbox';
     }
 
-    if ($action eq 'create') {
+    if (($action eq 'create') || 
+        ($action eq 'modify' && $state eq 'pick_members')) {
         if (defined($env{'form.types'})) {
             @types=&Apache::loncommon::get_env_multiple('form.types');
         }
@@ -473,9 +628,6 @@ sub group_administration {
         }
         if (defined($env{'form.sectionpick'})) {
             @sections=&Apache::loncommon::get_env_multiple('form.sectionpick');
-            if (grep/^_all$/,@sections) {
-                @sections = sort {$a cmp $b} keys(%sectioncount);
-            }
         }
     }
 
@@ -516,7 +668,7 @@ sub group_administration {
                         $num_reenable ++;
                         next;
                     } elsif (($start > $now)) {
-                        $num_activate = 1;
+                        $num_activate ++;
                         next;
                     } else {
                         $num_expire ++;
@@ -557,11 +709,17 @@ sub group_administration {
     }
 
     if (($state eq 'pick_privs') || ($state eq 'change_privs') ||
-        (($specificity eq 'No') && 
-         (($state eq 'result') || ($state eq 'memresult')))) {
+         (($specificity eq 'No') && 
+          ($state eq 'memresult' || $state eq 'result' || $state eq 'addresult'))) { 
         foreach my $tool (@tools) {
             my @values = &Apache::loncommon::get_env_multiple('form.user_'.$tool);
             foreach my $user (@values) {
+                if ($state eq 'pick_privs' || $state eq 'result' 
+                    || $state eq 'addresult') {
+                    if (!grep(/^\Q$user\E$/,@members)) {
+                        next;
+                    }
+                }
                 unless(exists($usertools{$user}{$tool})) {
                     $usertools{$user}{$tool} = 1;
                 }
@@ -593,8 +751,8 @@ sub group_administration {
                         }
                         my @currtools = ();
                         if (@userprivs > 0) {
-                            foreach my $tool (sort(keys(%fixedprivs))) {
-                                foreach my $priv (keys(%{$fixedprivs{$tool}})) {
+                            foreach my $tool (sort(keys(%{$fixedprivs}))) {
+                                foreach my $priv (keys(%{$$fixedprivs{$tool}})) {
                                     if (grep/^$priv$/,@userprivs) {
                                         push(@currtools,$tool);
                                         last;
@@ -664,19 +822,59 @@ sub group_administration {
         && ($specificity eq 'Yes')) {
         foreach my $user (sort(keys(%usertools))) {
             foreach my $tool (keys(%{$usertools{$user}})) {
-                foreach my $priv (keys(%{$toolprivs{$tool}})) {
-                    unless (exists($fixedprivs{$tool}{$priv})) {
+                foreach my $priv (keys(%{$$toolprivs{$tool}})) {
+                    unless (exists($$fixedprivs{$tool}{$priv})) {
                         $elements{$action}{$state}{'userpriv_'.$priv} = 'checkbox';
                     }
                 }
             }
         }
     }
- 
+
+    if (($action eq 'create' && $state eq 'pick_name') || 
+        ($action eq 'modify' && $state eq 'change_settings')) {
+        my ($crsquota,$freespace,$maxposs) = &get_quota_constraints($action,\%stored);
+        my $space_trim = '/^\s*|\s*\$/g,""';
+        my $float_check = '/^([0-9]*\.?[0-9]*)$/';
+        $validate_script = '
+    var newquota = new String(document.'.$state.'.quota.value);
+    newquota.replace('.$space_trim.');
+    if (newquota == "" ) {
+        document.'.$state.'.quota.value = 0;
+        newquota = "0";
+    }
+    var maxposs = '.sprintf("%.2f",$maxposs).';
+    if (newquota > maxposs) {
+        alert("The group portfolio quota you entered for this group ("+newquota+" MB) exceeds the maximum possible ("+maxposs+" MB). Please enter a smaller number.");
+        return;
+    }
+    var re_quota = '.$float_check.';
+    var check_quota = newquota.match(re_quota);
+    if (check_quota == null) {
+        alert("The quota you entered contains invalid characters, the quota should only include numbers, with or without a decimal point.");
+        return;
+    }
+    if (newquota == 0) {
+        var warn_zero = 0;
+        for (var i=0; i<document.'.$state.'.tool.length; i++) {
+            if (document.'.$state.'.tool[i].value == "files") {
+                if (document.'.$state.'.tool[i].checked) {
+                    warn_zero = 1;
+                }
+            }
+        }
+        if (warn_zero == 1) {
+            alert("You have indicated that the group portfolio should be enabled, but you have set the repository quota to 0 MB.\nThis will prevent any upload of files.\nPlease set a value or disable the repository feature.");
+            return;
+        }
+    } 
+';
+    }
     my $jscript = &Apache::loncommon::check_uncheck_jscript();
     $jscript .= qq|
 function nextPage(formname,nextstate) {
     formname.state.value= nextstate;
+    $validate_script
     formname.submit();
 }
 function backPage(formname,prevstate) {
@@ -688,7 +886,7 @@ function changeSort(caller) {
     document.$state.sortby.value = caller;
     document.$state.submit();
 } 
-                                                                                      
+
 |;
     $jscript .= &Apache::lonhtmlcommon::set_form_elements(
                            \%{$elements{$action}{$state}},\%stored);
@@ -696,18 +894,20 @@ function changeSort(caller) {
     my %states = ();
     my %branchstates = ();
     @{$states{'create'}} = ('pick_name','pick_members','pick_privs','result');
-    @{$states{'modify'}} = ('pick_group','pick_task');
+    @{$states{'modify'}} = ('pick_task');
+    @{$states{'delete'}} = ('verify','result');
+    @{$states{'reenable'}} = ('verify','result');
     @{$branchstates{'noprivs'}} = ('result');
     @{$branchstates{'settings'}} = ('change_settings','chgresult');
     @{$branchstates{'members'}} = ('change_members','change_privs','memresult');
     @{$branchstates{'adds'}} = ('add_members','pick_members','pick_privs',
                                 'addresult');
-    
+
     if (defined($env{'form.branch'})) {
         push (@{$states{$action}},@{$branchstates{$env{'form.branch'}}});
     }
 
-    if (($action eq 'create') || ($action eq 'modify')) {
+    if (($action eq 'create') || ($action eq 'modify') || ($action eq 'delete') || ($action eq 'reenable')) {
         my $done = 0;
         my $i=0;
         while ($i<@{$states{$action}} && !$done) {
@@ -720,32 +920,43 @@ function changeSort(caller) {
     }
 
     my $loaditems =  &onload_action($action,$state);
-    $r->print(&header('Course Groups Manager',
-		      $jscript,$action,$state,$page,$function,$loaditems));
+    $r->print(&header("Groups Manager",
+		      $jscript,$action,$state,$page,$loaditems));
 
-    if ($env{'form.refpage'} eq 'enrl') {
+    if ($env{'form.refpage'} eq 'cusr') {
         &Apache::lonhtmlcommon::add_breadcrumb
-        ({href=>"/adm/dropadd",
-          text=>"Enrollment Manager",
+        ({href=>"/adm/createuser",
+          text=>"User Management",
           faq=>9,bug=>'Instructor Interface',});
-    } else {
+        if ($action eq 'modify' || $action eq 'delete') {
+            &Apache::lonhtmlcommon::add_breadcrumb
+            ({href=>"/adm/coursegroups?refpage=cusr&amp;action=$action",
+              text=>"Groups",
+              faq=>9,bug=>'Instructor Interface',});
+        }
+    } else { 
         &Apache::lonhtmlcommon::add_breadcrumb
-       ({href=>"/adm/coursegroups",
-          text=>"Course Groups",
-          faq=>9,bug=>'Instructor Interface',});
+          ({href=>"/adm/coursegroups",
+            text=>"Groups",
+            faq=>9,bug=>'Instructor Interface',});
+        if ($env{'form.refpage'} eq 'grouplist') {
+            &Apache::lonhtmlcommon::add_breadcrumb
+             ({href=>"/adm/$cdom/$cnum/$env{'form.groupname'}/smppg?ref=grouplist",
+               text=>&mt('Group').": $description",
+               no_mt=>1});
+        }
     }
 
     my %trail = ();
     %{$trail{'create'}} = &Apache::lonlocal::texthash (
-                            pick_name => 'Group Settings',
+                            pick_name => $ucgpterm.' Settings',
                             pick_members => 'Select Members',
                             pick_privs => 'Choose Privileges',
                             result => 'Creation Complete',
                           );
     %{$trail{'modify'}} = &Apache::lonlocal::texthash(
-                            pick_group => 'Groups',
                             pick_task => 'Choose Task',
-                            change_settings => 'Group Settings',
+                            change_settings => "$ucgpterm Settings",
                             change_members => 'Modify/Delete Members',
                             change_privs => 'Change Privileges',
                             change_mapping => 'Membership Mapping',
@@ -756,210 +967,567 @@ function changeSort(caller) {
                             memresult => 'Modifications Complete',
                             addresult => 'Additions Complete',
                           );
+    %{$trail{'delete'}} = &Apache::lonlocal::texthash(
+                            verify => 'Verify deletion',
+                            result => 'Deletion Complete'
+                          );
+    %{$trail{'reenable'}} = &Apache::lonlocal::texthash(
+                            verify => 'Verify Re-enable',
+                            result => 'Re-enabled'
+                          );
     my %navbuttons = &Apache::lonlocal::texthash(
-                             gtns => 'Go to next step',
-                             gtps => 'Go to previous step',
-                             crgr => 'Create group',
-                             mose => 'Modify settings',
-                             gtpp => 'Go to previous page',
+                             gtns => 'Next',#'Go to next step',
+                             gtps => 'Back',#'Go to previous step',
+                             crgr => 'Create '.$gpterm,
+                             mose => 'Save',#'Modify settings',
+                             gtpp => 'Back',#'Go to previous page',
                              adme => 'Add members',
     );
-    if ((($action eq 'create') || ($action eq 'modify')) &&
+    if ((($action eq 'create') || ($action eq 'modify') || ($action eq 'delete') || ($action eq 'reenable')) &&
               ($manage_permission)) {
         for (my $i=0; $i<@{$states{$action}}; $i++) {
             if ($state eq $states{$action}[$i]) {
                 &Apache::lonhtmlcommon::add_breadcrumb(
                    {text=>"$trail{$action}{$state}"});
                 $r->print(&Apache::lonhtmlcommon::breadcrumbs
-                     (undef,'Course Groups Manager'));
-                &display_control($r,$cdom,$cnum,$tabcol,$action,$state,$page,
+			  ("Groups Manager","Creating_Groups"));
+                &display_control($r,$cdom,$cnum,$action,$state,$page,
                        \%sectioncount,$groupname,$description,$functions,
-                       \@tools,\%toolprivs,\%fixedprivs,$startdate,$enddate,
+                       \@tools,$toolprivs,$fixedprivs,$startdate,$enddate,
                        \%users,\%userdata,$idx,\%memchg,\%usertools,
-                       $function,$view_permission,$manage_permission,
-                       \%stored,$granularity,$specificity,\@types,\@roles,
-                       \@sections,\%states,\%navbuttons,$rowColor1,$rowColor2);
+                       $view_permission,$manage_permission,
+                       \%stored,$granularity,$quota,$specificity,\@types,\@roles,
+                       \@sections,\%states,\%navbuttons,$gpterm,$ucgpterm,
+				 $crstype);
                 last;
             } else {
-                if (($state eq 'result') && ($i > 0)) {
-                    &Apache::lonhtmlcommon::add_breadcrumb(
+                if (($action eq 'create') || ($action eq 'modify')) {
+                    if (($state eq 'result') && ($i > 0)) {
+                        &Apache::lonhtmlcommon::add_breadcrumb(
     {href=>"javascript:backPage(document.$state,'$states{$action}[0]')",
       text=>"$trail{$action}{$states{$action}[$i]}"});
-                } else { 
-                    &Apache::lonhtmlcommon::add_breadcrumb(
+                    } else { 
+                        &Apache::lonhtmlcommon::add_breadcrumb(
      {href=>"javascript:backPage(document.$state,'$states{$action}[$i]')",
       text=>"$trail{$action}{$states{$action}[$i]}"});
+                    }
                 }
-            }
+            }             
         }
     } elsif (($action eq 'view') && ($view_permission)) {
                         &Apache::lonhtmlcommon::add_breadcrumb(
-                   {text=>"View groups"});
+                   {text=>"View $gpterm".'s'});
         $r->print(&Apache::lonhtmlcommon::breadcrumbs
-                     (undef,'Course Groups Manager'));
-        &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,
-                        $view_permission,$manage_permission,$action,
-                        $rowColor1,$rowColor2);
-
+		  ('Groups Manager'));
+        &display_groups($r,$cdom,$cnum,$functions,$idx,$view_permission,
+			$manage_permission,$action,$state,$gpterm,$ucgpterm,
+			$crstype);
     }
     $r->print(&footer());
     return;
 }
 
 sub retrieve_settings {
-    my ($cdom,$cnum,$groupname) = @_;
-    my %groupinfo;
-    my %stored;
+    my ($cdom,$cnum,$groupname,$action) = @_;
     my %curr_groups;
-    my $numgroups = &Apache::loncommon::coursegroups(\%curr_groups,$cdom,
-                                                             $cnum,$groupname);
-    if ($numgroups > 0) {
-        %groupinfo = &Apache::loncommon::get_group_settings(
-                                                     $curr_groups{$groupname});
-        $stored{'description'} = &Apache::lonnet::unescape(
-                                                    $groupinfo{'description'});
-        $stored{'startdate'} = $groupinfo{'startdate'};
-        $stored{'enddate'} = $groupinfo{'enddate'};
-        if ($stored{'enddate'} == 0) {
-            $stored{'no_end_date'} = 1;
-        }
-        $stored{'granularity'} = $groupinfo{'granularity'};
-        $stored{'specificity'} = $groupinfo{'specificity'};
-        $stored{'creation'} = $groupinfo{'creation'};
-        $stored{'creator'} = $groupinfo{'creator'};
-
-        foreach my $tool (sort(keys(%{$groupinfo{'functions'}}))) {
-            if ($groupinfo{functions}{$tool} eq 'on') {
-                push(@{$stored{tool}},$tool);
-            }
-        }
-        foreach my $role (@{$groupinfo{'roles'}}) {
-            push(@{$stored{roles}},$role);
-        }
-        foreach my $type (@{$groupinfo{'types'}}) {
-            push(@{$stored{types}},$type);
-        }
-        foreach my $section (@{$groupinfo{'sectionpick'}}) {
-            push(@{$stored{sectionpick}},$section);
-        }
-        foreach my $defpriv (@{$groupinfo{'defpriv'}}) {
-            push(@{$stored{defpriv}},$defpriv);
-        }
-        $stored{'autoadd'} = $groupinfo{'autoadd'};
-        $stored{'autodrop'} = $groupinfo{'autodrop'};
-        if (exists($groupinfo{'autosec'})) {
-            foreach my $role (sort(keys(%{$groupinfo{'autosec'}}))) {
-                foreach my $section (@{$groupinfo{'autosec'}{$role}}) {
-                    push (@{$stored{'sec_'.$role}},$section);
-                }
-                if (@{$groupinfo{'autosec'}{$role}} > 0) {
-                    push(@{$stored{'autorole'}},$role);
-                }
+    my $namespace;
+    if ($action eq 'reenable') {
+        $namespace = 'deleted_groups';
+    } else {
+        $namespace = 'coursegroups';
+    }
+    %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum,$groupname,
+                                                   $namespace);
+
+    return if (!%curr_groups);
+
+    my %groupinfo = 
+	&Apache::longroup::get_group_settings($curr_groups{$groupname});
+
+    my %stored;
+
+    $stored{'description'} = 
+	&unescape($groupinfo{'description'});
+    $stored{'startdate'} = $groupinfo{'startdate'};
+    $stored{'enddate'} = $groupinfo{'enddate'};
+    if ($stored{'enddate'} == 0) {
+	$stored{'no_end_date'} = 1;
+    }
+    $stored{'granularity'} = $groupinfo{'granularity'};
+    $stored{'specificity'} = $groupinfo{'specificity'};
+    $stored{'creation'} = $groupinfo{'creation'};
+    $stored{'creator'} = $groupinfo{'creator'};
+    $stored{'quota'} = $groupinfo{'quota'};
+
+    foreach my $tool (sort(keys(%{$groupinfo{'functions'}}))) {
+	if ($groupinfo{functions}{$tool} eq 'on') {
+	    push(@{$stored{tool}},$tool);
+	}
+    }
+    foreach my $role (@{$groupinfo{'roles'}}) {
+	push(@{$stored{roles}},$role);
+    }
+    foreach my $type (@{$groupinfo{'types'}}) {
+	push(@{$stored{types}},$type);
+    }
+    foreach my $section (@{$groupinfo{'sectionpick'}}) {
+	push(@{$stored{sectionpick}},$section);
+    }
+    foreach my $defpriv (@{$groupinfo{'defpriv'}}) {
+	push(@{$stored{defpriv}},$defpriv);
+    }
+    $stored{'autoadd'} = $groupinfo{'autoadd'};
+    $stored{'autodrop'} = $groupinfo{'autodrop'};
+    if (exists($groupinfo{'autosec'})) {
+	foreach my $role (sort(keys(%{$groupinfo{'autosec'}}))) {
+            if (ref($groupinfo{'autosec'}{$role}) eq 'ARRAY') {
+	        foreach my $section (@{$groupinfo{'autosec'}{$role}}) {
+
+	            push (@{$stored{'sec_'.$role}},$section);
+	        }
+	        if (@{$groupinfo{'autosec'}{$role}} > 0) {
+		    push(@{$stored{'autorole'}},$role);
+	        }
             }
-        }
+	}
     }
     return %stored;
 }
 
 sub display_control {
-    my ($r,$cdom,$cnum,$tabcol,$action,$state,$page,$sectioncount,$groupname,
+    my ($r,$cdom,$cnum,$action,$state,$page,$sectioncount,$groupname,
         $description,$functions,$tools,$toolprivs,$fixedprivs,$startdate,
-        $enddate,$users,$userdata,$idx,$memchg,$usertools,$function,
-        $view_permission,$manage_permission,$stored,$granularity,$specificity,
-        $types,$roles,$sections,$states,$navbuttons,$rowColor1,$rowColor2)=@_;
+        $enddate,$users,$userdata,$idx,$memchg,$usertools,
+        $view_permission,$manage_permission,$stored,$granularity,$quota,
+        $specificity,$types,$roles,$sections,$states,$navbuttons,
+	$gpterm,$ucgpterm,$crstype) = @_;
     if ($action eq 'create') {
         if ($state eq 'pick_name') {
-            &general_settings_form($r,$cdom,$cnum,$action,$tabcol,$state,$page,
+            &general_settings_form($r,$cdom,$cnum,$action,$state,$page,
                                    $functions,$tools,$toolprivs,$fixedprivs,
                                    $sectioncount,$stored,$states,$navbuttons,
-                                   $rowColor1,$rowColor2);
+                                   $gpterm,$ucgpterm,$crstype);
         } elsif ($state eq 'pick_members') {
-            &choose_members_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,
-                                 $groupname,$description,$granularity,
+            &choose_members_form($r,$cdom,$cnum,$action,$state,$page,
+                                 $groupname,$description,$granularity,$quota,
                                  $startdate,$enddate,$tools,$fixedprivs,
                                  $toolprivs,$functions,$users,$userdata,$idx,
-                                 $stored,$states,$navbuttons,$rowColor1,
-                                 $rowColor2);
+                                 $stored,$states,$navbuttons,$gpterm,$ucgpterm,
+				 $crstype);
         } elsif ($state eq 'pick_privs') {
-            &choose_privs_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,
+            &choose_privs_form($r,$cdom,$cnum,$action,$state,$page,
                                $startdate,$enddate,$tools,$functions,
                                $toolprivs,$fixedprivs,$userdata,$usertools,
                                $idx,$states,$stored,$sectioncount,$navbuttons,
-                               $rowColor1,$rowColor2);
+                               $gpterm,$ucgpterm,$crstype);
         } elsif ($state eq 'result') {
-            &process_request($r,$cdom,$cnum,$tabcol,$action,$state,$page,
+            &process_request($r,$cdom,$cnum,$action,$state,$page,
                              $groupname,$description,$specificity,$userdata,
                              $startdate,$enddate,$tools,$functions,
                              $toolprivs,$usertools,$idx,$types,$roles,
                              $sections,$states,$navbuttons,$memchg,
-                             $sectioncount,$stored,$rowColor1,$rowColor2);
+                             $sectioncount,$stored,$gpterm,$ucgpterm,$crstype);
         }
     } elsif ($action eq 'modify') {
         my $groupname = $env{'form.groupname'};
-        if ($state eq 'pick_group') {
-            &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,
-                            $view_permission,$manage_permission,$action,
-                            $rowColor1,$rowColor2);
-        } elsif ($state eq 'pick_task') {
-            &modify_menu($r,$groupname,$page);
+        if ($state eq 'pick_task') {
+            &modify_menu($r,$groupname,$page,$gpterm);
         } elsif ($state eq 'change_settings') {
-            &general_settings_form($r,$cdom,$cnum,$action,$tabcol,$state,$page,
+            &general_settings_form($r,$cdom,$cnum,$action,$state,$page,
                                    $functions,$tools,$toolprivs,$fixedprivs,
                                    $sectioncount,$stored,$states,$navbuttons,
-                                   $rowColor1,$rowColor2);
+                                   $gpterm,$ucgpterm,$crstype);
         } elsif ($state eq 'change_members') {
-            &change_members_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,
+            &change_members_form($r,$cdom,$cnum,$action,$state,$page,
                                  $groupname,$description,$startdate,$enddate,
                                  $tools,$fixedprivs,$functions,$users,
-                                 $userdata,$granularity,$specificity,$idx,
-                                 $states,$navbuttons,$rowColor1,$rowColor2);
+                                 $userdata,$granularity,$quota,$specificity,
+                                 $idx,$states,$navbuttons,$gpterm,$ucgpterm);
         } elsif ($state eq 'add_members') {
-            &add_members_form($r,$tabcol,$action,$state,$page,$startdate,
+            &add_members_form($r,$cdom,$cnum,$action,$state,$page,$startdate,
                               $enddate,$groupname,$description,$granularity,
-                              $sectioncount,$tools,$functions,$stored,$states,
-                              $navbuttons,$rowColor1,$rowColor2);
+                              $quota,$sectioncount,$tools,$functions,$stored,
+                              $states,$navbuttons,$gpterm,$ucgpterm,$crstype);
         } elsif ($state eq 'pick_members') {
-            &choose_members_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,
-                                 $groupname,$description,$granularity,
+            &choose_members_form($r,$cdom,$cnum,$action,$state,$page,
+                                 $groupname,$description,$granularity,$quota,
                                  $startdate,$enddate,$tools,$fixedprivs,
                                  $toolprivs,$functions,$users,$userdata,$idx,
-                                 $stored,$states,$navbuttons,$rowColor1,
-                                 $rowColor2);
+                                 $stored,$states,$navbuttons,$gpterm,$ucgpterm,
+				 $crstype);
         } elsif ($state eq 'pick_privs') {
-            &choose_privs_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,
+            &choose_privs_form($r,$cdom,$cnum,$action,$state,$page,
                                $startdate,$enddate,$tools,$functions,
                                $toolprivs,$fixedprivs,$userdata,$usertools,
                                $idx,$states,$stored,$sectioncount,$navbuttons,
-                               $rowColor1,$rowColor2);
+                               $gpterm,$ucgpterm,$crstype);
         } elsif ($state eq 'change_privs') {
-            &change_privs_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,
+            &change_privs_form($r,$cdom,$cnum,$action,$state,$page,
                                $startdate,$enddate,$tools,$functions,
                                $toolprivs,$fixedprivs,$userdata,$usertools,
                                $memchg,$idx,$states,$stored,$sectioncount,
-                               $navbuttons,$rowColor1,$rowColor2);
+                               $navbuttons,$gpterm,$ucgpterm);
         } elsif ($state eq 'chgresult' || $state eq 'memresult' || 
                  $state eq 'addresult') {
-            &process_request($r,$cdom,$cnum,$tabcol,$action,$state,$page,
+            &process_request($r,$cdom,$cnum,$action,$state,$page,
                              $groupname,$description,$specificity,$userdata,
                              $startdate,$enddate,$tools,$functions,
                              $toolprivs,$usertools,$idx,$types,$roles,
                              $sections,$states,$navbuttons,$memchg,
-                             $sectioncount,$stored,$rowColor1,$rowColor2);
+                             $sectioncount,$stored,$gpterm,$ucgpterm,$crstype);
+        }
+    } elsif ($action eq 'delete') {
+        my %stored = &retrieve_settings($cdom,$cnum,$groupname,$action);
+        if ($state eq 'verify') {
+            &verify_delete($r,$groupname,$state,$action,$page,$states,
+                           \%stored,$crstype);
+        } elsif ($state eq 'result') {
+            &delete_group($r,$cdom,$cnum,$groupname,$crstype);
+        }
+    } elsif ($action eq 'reenable') {
+        my %stored = &retrieve_settings($cdom,$cnum,$groupname,$action);
+        if ($state eq 'verify') {
+            &verify_reenable($r,$groupname,$state,$action,$page,$states,
+                           \%stored,$crstype);
+        } elsif ($state eq 'result') {
+            &reenable_group($r,$cdom,$cnum,$groupname,$crstype);
+        }
+    }
+}
+
+sub verify_delete {
+    my ($r,$groupname,$formname,$action,$page,$states,$stored,$crstype) = @_;
+    $r->print(&Apache::lonhtmlcommon::echo_form_input([]));
+    $r->print(&mt('You have requested deletion of the group [_1].'
+                 ,'<i>'.$stored->{'description'}.'</i>').
+              '<br /><br />'.&mt('When a group is deleted the following occurs:').'<ul>'.
+              '<li>'.&mt('All group membership is terminated.').'</li>'.
+              '<li>'.&mt('The group ceases to be available either for viewing or for modification of group settings and membership.').'</li>');
+    if ($crstype eq 'Community') {
+        $r->print( '<li>'.&mt("The group folder is removed from the folder containing it - normally this is the 'Community Groups' folder which contains folders for all groups in the community.").'</li>'.
+                   '</ul>'.&mt("Although a deleted group is no longer accessible, the group name used for the group will be reserved, and will not be available for assignment to a new group in the same community in the future."));
+    } else { 
+        $r->print( '<li>'.&mt("The group folder is removed from the folder containing it - normally this is the 'Course Groups' folder which contains folders for all groups in the course.").'</li>'.
+                   '</ul>'.&mt("Although a deleted group is no longer accessible, the group name used for the group will be reserved, and will not be available for assignment to a new group in the same course in the future."));
+    }
+    my $prevtext = &mt('Go back');
+    my $nexttext = &mt('Delete group');
+    my $prev;
+    if ($env{'form.refpage'} eq 'cusr')  {
+        $prev = 'view';
+    }
+    &display_navbuttons($r,$formname,$prev,$prevtext,
+                        $$states{$action}[$page+1],$nexttext);
+    return;
+}
+
+sub delete_group {
+    my ($r,$cdom,$cnum,$groupname,$crstype) = @_;
+    my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum,
+                                                           $groupname);
+    my $now = time;
+    my $num_users = 0;
+    my $num_fail = 0;
+    my $num_ok = 0;
+    my @deleted;
+    my @undeleted;
+    my %usersettings;
+    my $context = 'deletegroup';
+    foreach my $key (sort(keys(%membership))) {
+        if ($key =~ /^\Q$groupname\E:([^:]+:[^:]+)$/) {
+            my $user = $1;
+            my($end,$start,$userprivs) = split(/:/,$membership{$key},3);
+            if ($start != -1) {
+                $num_users ++;
+                $usersettings{$groupname.':'.$user} = $now.':-1:'.$userprivs;
+                if (&Apache::lonnet::modify_group_roles($cdom,$cnum,
+                                                        $groupname,$user,
+                                                        $now,'-1',$userprivs,
+                                                        '',$context)
+                    eq 'ok') {
+                    $num_ok ++;
+                    push(@deleted,$user);
+                } else {
+                    push(@undeleted,$user);
+                    $num_fail ++;
+                }
+            }
+        }
+    }
+    if ($num_ok > 0) {
+        my $roster_result = 
+            &Apache::lonnet::modify_coursegroup_membership($cdom,$cnum,
+                                                           \%usersettings);
+    }
+    if ($num_fail > 0) {
+        $r->print('<div class="LC_error">'
+                 .&mt('Group deletion failed because deletion of [_1] out of [_2] members failed.'
+                     ,$num_fail,$num_users)
+                 .'</div>');
+    } else {
+        my ($result,$message) = 
+             &Apache::lonnet::toggle_coursegroup_status($cdom,$cnum,
+                                                        $groupname,'delete');
+        if ($result eq 'ok') {
+            my $outcome = &modify_folders($cdom,$cnum,$groupname,$crstype);
+            if ($outcome eq '') {
+                my $message = &Apache::lonhtmlcommon::confirm_success(&mt('Group successfully deleted.'));
+                $message = &Apache::loncommon::confirmwrapper($message);
+                $r->print($message);
+            } else {
+                $r->print('<div class="LC_error">');
+                if ($crstype eq 'Community') {
+                    $r->print(&mt("Although the group was deleted, an error occurred when removing the group's folder from the 'Community Groups' folder: [_1]",$outcome));
+                } else {
+                    $r->print(&mt("Although the group was deleted, an error occurred when removing the group's folder from the 'Course Groups' folder: [_1]",$outcome));
+                }
+                $r->print('</div>');
+            }
+        } else {
+            my $msg = &Apache::lonhtmlcommon::confirm_success(&mt('Group deletion failed.'),1);
+            $msg = &Apache::loncommon::confirmwrapper($msg);
+            $r->print($msg);
+        }
+    }
+    return;
+}
+
+sub reenable_folder {
+    my ($cdom,$cnum,$groupname,$description,$crstype) = @_;
+    my $outcome;
+    my $crspath = '/uploaded/'.$cdom.'/'.$cnum.'/';
+    my $allgrpsmap = $crspath.'group_allfolders.sequence';
+    my $foldertitle;
+    if ($crstype eq 'Community') {
+        $foldertitle = &mt("Community Folder -[_1]",$description);
+    } else {
+        $foldertitle = &mt("Course Folder -[_1]",$description);
+    }
+    my $mapurl = $crspath.'group_folder_'.
+                   $groupname.'.sequence';
+    my ($errtext,$fatal)=&LONCAPA::map::mapread($allgrpsmap);
+    if ($fatal) {
+        $outcome='<div class="LC_error">'
+                .&mt('An error occurred when reading contents of parent folder to group:')
+                ."<br />($allgrpsmap): $errtext"
+                .'</div>';
+    } else {
+        my $idx=&LONCAPA::map::getresidx($mapurl);
+        $LONCAPA::map::resources[$idx] = $foldertitle.':'.$mapurl.
+                                         ':false:normal:res';
+        $LONCAPA::map::order[1+$#LONCAPA::map::order]=$idx;
+        my ($outtext,$errtext) = &LONCAPA::map::storemap($allgrpsmap,1,1);
+        if ($errtext) {
+            $outcome='<div class="LC_error">'
+                    .&mt('An error occurred when saving updated parent folder to group:'
+                        ,"<br />$allgrpsmap - $errtext")
+                    .'</div>';
+        } else {
+            my ($furl,$ferr) =
+                     &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
+        }
+    }
+    return $outcome;
+}
+
+sub modify_folders {
+    my ($cdom,$cnum,$groupname,$crstype) = @_;
+    my ($outcome,$groupmap,$groupmapres,$map,$id,$src);
+    my $navmap = Apache::lonnavmaps::navmap->new();
+    if (!defined($navmap)) {
+        $outcome = '<div class="LC_error">';
+        if ($crstype eq 'Community') {
+            $outcome .= &mt("Error reading community contents.").' '.
+                   &mt("You need to re-initialize the community.");
+        } else {
+            $outcome .= &mt("Error reading course contents.").' '.
+                   &mt("You need to re-initialize the course.");
+        }
+        $outcome .= '</div>';
+        return $outcome;
+    }
+    $groupmap = '/uploaded/'.$cdom.'/'.$cnum.'/'.'group_folder_'.
+                   $groupname.'.sequence';
+    $groupmapres = $navmap->getResourceByUrl($groupmap);
+    if ($groupmapres) {
+        ($map,$id,$src)=&Apache::lonnet::decode_symb($groupmapres->symb());
+    }
+    undef($navmap);
+    if ($map) {
+        $map = '/'.$map;
+        my ($errtext,$fatal) = &LONCAPA::map::mapread($map);
+        if ($fatal) {
+            $outcome='<div class="LC_error">'
+                    .&mt('An error occurred when reading contents of parent folder to group:')
+                    ."<br />($map): $errtext"
+                    .'</div>';
+        } else {
+            my $idx = 0;
+            my $grpidx;
+            foreach my $item (@LONCAPA::map::order) {
+                my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$item]);
+                $url=&LONCAPA::map::qtescape($url);
+                if ($url eq $groupmap) {
+                    $grpidx = $idx;
+                    last;
+                } else {
+                    $idx++;
+                }
+            }
+
+            if ($grpidx ne '') {
+                &LONCAPA::map::makezombie($LONCAPA::map::order[$grpidx]);
+                for (my $i=$grpidx;$i<$#LONCAPA::map::order;$i++) {
+                    $LONCAPA::map::order[$i] = $LONCAPA::map::order[$i+1];
+                }
+                $#LONCAPA::map::order--;
+                my ($outtext,$errtext) = &LONCAPA::map::storemap($map,1,1);
+                if ($errtext) {
+                    $outcome='<div class="LC_error">'
+                            .&mt('An error occurred when saving updated parent folder to group:')
+                            ."<br />$map - $errtext"
+                            .'</div>';
+                } else {
+                    my ($furl,$ferr) =
+                        &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
+                }  
+            }
+        }
+    }
+    return $outcome;
+}
+
+sub verify_reenable {
+    my ($r,$groupname,$formname,$action,$page,$states,$stored,$crstype) = @_;
+    $r->print(&Apache::lonhtmlcommon::echo_form_input([]));
+    $r->print(&mt('You have requested enabling the previously deleted group [_1].'
+                 ,'<i>'.$stored->{'description'}.'</i>').
+              '<br /><br />'.&mt('When a deleted group is re-enabled the following occurs:').'<ul>'.
+              '<li>'.&mt('Group settings and membership at the time the group was deleted are reinstated.').'</li><li>');
+    if ($crstype eq 'Community') {
+        $r->print(&mt("A group folder is added to the 'Community Groups' folder which contains folders for all groups in the community."));
+    } else {
+        $r->print(&mt("A group folder is added to the 'Course Groups' folder which contains folders for all groups in the course."));
+    }
+    $r->print('</li></ul>');
+    my $prevtext = &mt('Go back');
+    my $nexttext = &mt('Reenable group');
+    my $prev;
+    if ($env{'form.refpage'} eq 'cusr')  {
+        $prev = 'view';
+    }
+    &display_navbuttons($r,$formname,$prev,$prevtext,
+                        $$states{$action}[$page+1],$nexttext);
+    return;
+}
+
+sub reenable_group {
+    my ($r,$cdom,$cnum,$groupname,$crstype) = @_;
+    my %groups = 
+        &Apache::longroup::coursegroups($cdom,$cnum,$groupname,
+                                        'deleted_groups');
+    if (keys(%groups) == 0) {
+        $r->print(&mt('The group [_1] was not re-enabled, because it is not a deleted group.[_2]Perhaps it has already been re-enabled?','<i>'.$groupname.'</i>'),'<br />');
+        return;
+    }
+    my %groupinfo = 
+        &Apache::longroup::get_group_settings($groups{$groupname});
+    my $defstart = $groupinfo{'startdate'};
+    my $defend = $groupinfo{'enddate'};
+    my $showstart = &Apache::lonlocal::locallocaltime($defstart);
+    my $showend;
+    if ($defend == 0) {
+        $showend = &mt('No end date set');
+    } else {
+        $showend = &Apache::lonlocal::locallocaltime($defend);
+    }
+    my $description = &unescape($groupinfo{'description'});
+    my $num_users = 0;
+    my $num_ok = 0;
+    my $num_fail = 0;
+    my $context = 'reenablegroup';
+    my (%usersettings,@enabled,@unenabled);
+    my ($result,$message) =
+          &Apache::lonnet::toggle_coursegroup_status($cdom,$cnum,$groupname,
+                                                     'reenable');
+    if ($result eq 'ok') {
+        my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum,
+                                                           $groupname);
+        foreach my $key (sort(keys(%membership))) {
+            if ($key =~ /^\Q$groupname\E:([^:]+:[^:]+)$/) {
+                my $user = $1;
+                my($end,$start,$userprivs) = split(/:/,$membership{$key},3);
+                if (($start == -1) && ($end == $groupinfo{'modified'})) {
+                    $num_users ++;
+                    $usersettings{$groupname.':'.$user} = $defend.':'.
+                                                          $defstart.':'.
+                                                          $userprivs;
+                    if (&Apache::lonnet::modify_group_roles($cdom,$cnum,
+                                                            $groupname,$user,
+                                                            $defend,$defstart,
+                                                            $userprivs,'',
+$context) eq 'ok') {
+                        $num_ok ++;
+                        push(@enabled,$user);
+                    } else {
+                        push(@unenabled,$user);
+                        $num_fail ++;
+                    }
+                }
+            }
+        }
+        if ($num_users > 0) {
+            if ($num_ok > 0) {
+                my $roster_result =
+        &Apache::lonnet::modify_coursegroup_membership($cdom,$cnum,
+                                                       \%usersettings);
+                if ($roster_result eq 'ok') {
+                    $r->print('<div class="LC_success">'
+                             .&mt('Membership reinstated for [quant,_1,user], each with start and end dates for group access set to defaults: [_2] and [_3]',$num_ok,$showstart,$showend)
+                             .'</div>');
+                }
+            } else {
+                $r->print('<div class="LC_error">'
+                         .&mt('A problem occurred when trying to reinstate [_1] of the [_2] members of the pre-existing group.',$num_fail,$num_users)
+                         .'</div>');
+            }
+        } else {
+            $r->print('<div class="LC_info">'
+                     .&mt('There were no group members to reinstate, as none were removed when the group was deleted.')
+                     .'</div>');
+        }
+        my $outcome = &reenable_folder($cdom,$cnum,$groupname,$description,$crstype);
+        if ($outcome eq '') {
+            my $message = &Apache::lonhtmlcommon::confirm_success(&mt('Group successfully re-enabled.'));
+            $message = &Apache::loncommon::confirmwrapper($message);
+            $r->print($message);
+        } else {
+            $r->print('<div class="LC_error">');
+            if ($crstype eq 'Community') {
+                $r->print(&mt("Although the group was re-enabled, an error occurred when adding the group's folder to the 'Community Groups' folder: [_1]",$outcome));
+            } else {
+                $r->print(&mt("Although the group was re-enabled, an error occurred when adding the group's folder to the 'Course Groups' folder: [_1]",$outcome));
+            }
+            $r->print('</div>');
         }
+    } else {
+        my $message = &Apache::lonhtmlcommon::confirm_success(&mt('Re-enabling group failed.'),1);
+        $message = &Apache::loncommon::confirmwrapper($message);
+        $r->print($message);
     }
+    return;
 }
 
 sub header {
-    my ($bodytitle,$jscript,$action,$state,$page,$function,$loaditems) = @_;
+    my ($bodytitle,$jscript,$action,$state,$page,$loaditems) = @_;
     my $start_page=
 	&Apache::loncommon::start_page($bodytitle,
 				       '<script type="text/javascript">'.
 				       $jscript.'</script>',
-				       {'function'    => $function,
-					'add_entries' => $loaditems,});
+				       {'add_entries' => $loaditems,});
     my $output = <<"END";
 $start_page
-<form method="POST" name="$state">
+<form method="post" name="$state" action="">
 
 END
     if ($action eq 'create' || $action eq 'modify') {
@@ -975,23 +1543,22 @@ END
 
 sub onload_action {
     my ($action,$state) = @_;
-    my $loaditems;
+    my %loaditems;
     if ((defined($env{'form.origin'})) && ($action eq 'create') &&
                 ($state eq 'pick_name' || $state eq 'pick_members' || 
                  $state eq 'pick_privs')) {
         unless ($env{'form.origin'} eq '') {
-            $loaditems = 
-             'onload="javascript:setFormElements(document.'.$state.')"';
+	    $loaditems{'onload'} = 
+		'javascript:setFormElements(document.'.$state.')';
         }
     }
     if (($action eq 'modify') &&
                 ($state eq 'change_settings' || $state eq 'change_members' ||
-                 $state eq 'change_privs' || $state eq 'add_members' ||
-                 $state eq 'pick_members')) {
-            $loaditems =
-             'onload="javascript:setFormElements(document.'.$state.')"';
+                 $state eq 'change_privs' || $state eq 'add_members')) {
+	$loaditems{'onload'} = 
+	    'javascript:setFormElements(document.'.$state.')';
     }
-    return $loaditems;
+    return \%loaditems;
 }
 
 sub footer {
@@ -1018,6 +1585,24 @@ sub build_members_list {
 }
 
 sub group_files {
+    my ($group,$portpath,$numfiles,$numdirs) = @_;
+    my $dirptr=16384;
+    my ($dirlistref,$listerror) = 
+        &Apache::portfolio::get_dir_list($portpath,undef,$group);
+    if (ref($dirlistref) eq 'ARRAY') {
+        foreach my $line (@{$dirlistref}) {
+            my ($filename,$dom,undef,$testdir,undef,undef,undef,undef,$size,undef,$mtime,undef,undef,undef,$obs,undef)=split(/\&/,$line,16);
+            if (($filename !~ /^\.\.?$/) && ($filename !~ /\.meta$/ ) && ($filename !~ /(.*)\.(\d+)\.([^\.]*)$/) && ($filename ne 'no_such_dir')) { 
+                if ($dirptr&$testdir) {
+                    $portpath .= '/'.$filename;
+                    $$numdirs ++;
+                    &group_files($group,$portpath,$numfiles,$numdirs)
+                } else {
+                    $$numfiles ++;
+                }
+            }
+        }
+    }
     return;
 }
 
@@ -1025,240 +1610,309 @@ sub group_members {
     my ($cdom,$cnum,$group,$group_info) = @_;
     my %memberhash = &Apache::lonnet::get_group_membership($cdom,$cnum,$group);
     my $now = time;
-    my ($tmp)=keys(%memberhash);
-    if ($tmp=~/^error:/) {
-        $$group_info{'totalmembers'} = 'Unknown - an error occurred';
-        return $tmp;
-    }
-    my $now = time;
+    my %lt = &Apache::lonlocal::texthash (
+                                          active => 'active',
+                                          previous => 'previous',
+                                          future => 'future',
+    );
+    my %membercounts = (  
+                         active => 0,
+                         previous => 0,
+                         future => 0,
+                       );
     my $totalmembers = 0;
-    my $active = 0;
-    my $previous = 0;
-    my $future = 0;
-    foreach my $member (keys %memberhash) {
+    foreach my $member (keys(%memberhash)) {
         $totalmembers ++;
         my ($end,$start) = split(/:/,$memberhash{$member});
         unless ($start == -1) {
             if (($end!=0) && ($end<$now)) {
-                $previous ++;
+                $membercounts{previous} ++;
             } elsif (($start!=0) && ($start>$now)) {
-                $future ++;
+                $membercounts{future} ++;
             } else {
-               $active ++;
+                $membercounts{active} ++;
             }
         }
     }
     if ($totalmembers == 0) {
         $$group_info{$group}{'totalmembers'} = 'None';
     } else {
-        $$group_info{$group}{'totalmembers'} = $active.' - active<br />'.$previous.' -previous<br />'.$future.' -future';
+        foreach my $type ('active','previous','future') {
+            $$group_info{$group}{'totalmembers'} .= 
+               &open_list_window($group,$type,$membercounts{$type},$lt{$type});
+        }
     }
     return 'ok';
 }
 
+sub open_list_window {
+    my ($group,$status,$count,$text) = @_;
+    my $entry;
+    if ($count > 0) {
+        $entry = '<span class="LC_nobreak"><a href="javascript:openGroupRoster('.
+                 "'$group','$status'".')">'.$text.'</a>&nbsp;-&nbsp;'.$count.
+                 '</span><br />';
+    } else {
+        $entry = '<span class="LC_nobreak">'.$text.'&nbsp;-&nbsp;'.$count.'</span><br />';
+    }
+    return $entry;
+}
+
 
 sub general_settings_form {
-    my ($r,$cdom,$cnum,$action,$tabcol,$formname,$page,$functions,$tools,
+    my ($r,$cdom,$cnum,$action,$formname,$page,$functions,$tools,
         $toolprivs,$fixedprivs,$sectioncount,$stored,$states,$navbuttons,
-        $rowColor1,$rowColor2) = @_;
+        $gpterm,$ucgpterm,$crstype) = @_;
     my ($nexttext,$prevtext);
-    $r->print(' <br />
- <table width="100%" cellpadding="0" cellspacing="0" border="0">
-');
-    &groupsettings_options($r,$tabcol,$functions,$action,$formname,$stored,1);
-    $r->print(' 
-  <tr>
-   <td colspan="4">&nbsp;</td>
-  </tr>');
-    &access_date_settings($r,$tabcol,$action,$formname,$stored,2);
-    $r->print('
-  <tr>
-   <td colspan="4">&nbsp;</td>
-  </tr>');
+    &groupsettings_options($r,$functions,$action,$formname,$stored,1,
+                           $gpterm,$ucgpterm,$crstype);
+    &access_date_settings($r,$action,$formname,$stored,2,$gpterm,$ucgpterm);
     if ($action eq 'create') {
-        &membership_options($r,$action,$formname,$tabcol,$sectioncount,3);
+        &membership_options($r,$cdom,$cnum,$action,$formname,$sectioncount,3,
+                            $gpterm,$ucgpterm,$crstype);
         $nexttext = $$navbuttons{'gtns'};
     } else {
         my @available = ();
         my @unavailable = ();
         &check_tools($functions,$tools,\@available,\@unavailable);
         @{$tools} = sort(keys(%{$functions}));
-        &privilege_specificity($r,$tabcol,$rowColor1,$rowColor2,$action,
-                               3,$tools,$stored,$toolprivs,$fixedprivs,
-                               \@available,$formname);
-        $r->print('
-  <tr>
-   <td colspan="4">&nbsp;</td>
-  </tr>');
-        &mapping_options($r,$action,$formname,$page,$tabcol,$sectioncount,
-                         $states,$stored,$navbuttons,4,5,$rowColor1,
-                         $rowColor2);
+        &privilege_specificity($r,$action,3,$tools,$stored,$toolprivs,
+			       $fixedprivs,\@available,$formname,
+			       $gpterm,$ucgpterm,$functions,$crstype);
+        &mapping_options($r,$action,$formname,$page,$sectioncount,
+                         $states,$stored,$navbuttons,4,5,
+			 $gpterm,$ucgpterm,$crstype,$cdom,$cnum);
         $nexttext = $$navbuttons{'mose'};
     }
     $prevtext = $$navbuttons{'gtpp'};
     &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,
                         $$states{$action}[$page+1],$nexttext);
-    $r->print('
- </table>');
     return;
 }
 
 sub groupsettings_options {
-    my ($r,$tabcol,$functions,$action,$formname,$stored,$image) = @_;
+    my ($r,$functions,$action,$formname,$stored,$image,$gpterm,
+        $ucgpterm,$crstype) = @_;
     my %lt = &Apache::lonlocal::texthash(
-        'gdat' => 'Group open and close dates',
-        'sten' => 'Set a start date/time and end date/time for the group',
-        'gfun' => 'Group functionality',
-        'gnde' => 'Group name, description and available functionality',
-        'desc' => 'Description',
-        'func' => 'Functionality',
+        'gdat' => "Group access start and end dates",
+        'gnde' => "Group name, title and available collaborative tools",
+        'desc' => 'Group Title',
+        'func' => 'Collaborative Tools',
         'gnam' => 'Group Name',
-        'doyo' => 'Do you want to assign different functionality '.
-                  'to different group members?',
+        'lett' => 'Letters, numbers and underscore only',
+        'doyo' => 'Different subsets of the chosen collaborative tools '.
+                  'for different group members?',
+        'gran' => 'Granularity',
+        'dquo' => 'Disk quota',
+    );
+    my ($crsquota,$freespace,$maxposs) = &get_quota_constraints($action,$stored);
+    $r->print(&Apache::lonhtmlcommon::topic_bar($image,$lt{'gnde'}));
+
+    # Group Name
+    $r->print(&Apache::lonhtmlcommon::start_pick_box()
+             .&Apache::lonhtmlcommon::row_title($lt{'gnam'})
     );
-    &topic_bar($r,$tabcol,$image,$lt{'gnde'});
-    $r->print('
-   <tr>
-    <td>&nbsp;</td>
-    <td colspan="3">
-     <table border="0" cellpadding="2" cellspacing="2">
-      <tr>
-       <td><b>'.$lt{'gnam'}.':</b></td>
-       <td colspan="5">
-');
     if ($action eq 'create') {
-        $r->print('<input type="text" name="groupname" size="25" />');
+        $r->print('<input type="text" name="groupname" size="25" />'
+                 .' <span class="LC_nobreak">('
+                 .$lt{'lett'}.')</span>'
+        );
     } else {
         $r->print('<input type="hidden" name="groupname" value="'.
                          $env{'form.groupname'}.'" />'.$env{'form.groupname'});
     }
-    $r->print(<<"END");
-       </td>
-      <tr>
-      <tr>
-       <td><b>$lt{'desc'}:</b></td>
-       <td colspan="5"><input type="text" name="description" size="40"
-                                                    value="" />
-       </td>
-      <tr>
-      <tr>
-       <td><b>$lt{'func'}:</b></td>
-END
+    $r->print(&Apache::lonhtmlcommon::row_closure());
+
+    # Group Title
+    $r->print(&Apache::lonhtmlcommon::row_title($lt{'desc'})
+             .'<input type="text" name="description" size="40" value="" />'
+             .&Apache::lonhtmlcommon::row_closure()
+    );
+
+    # Collaborative Tools
     my $numitems = keys(%{$functions});
     my $halfnum = int($numitems/2);
     my $remnum = $numitems%2;
     if ($remnum) {
         $halfnum ++;
     }
-    my @allfunctions = sort(keys (%{$functions}));
-    for (my $i=0; $i<$halfnum; $i++) {
-        $r->print('<td><label><input type="checkbox" name="tool" value="'.
-                  $allfunctions[$i].'" />&nbsp;'.
-                   $$functions{$allfunctions[$i]}.'</label></td>
-                   <td>&nbsp;</td><td>&nbsp;</td>');
-    }
-    $r->print('<td><input type="button" value="check all" '.
-              'onclick="javascript:checkAll(document.'.$formname.'.tool)" />'.
-              '</td></tr><tr><td>&nbsp;</td>');
-    for (my $j=$halfnum; $j<@allfunctions; $j++) {
-        $r->print('<td><label><input type="checkbox" name="tool" value="'.
-                  $allfunctions[$j].'" />&nbsp;'.
-                  $$functions{$allfunctions[$j]}.'</label></td>
-                  <td>&nbsp;</td><td>&nbsp;</td>');
-    }
-    if ($remnum) {
-        $r->print('<td>&nbsp;</td>');
+    my @allfunctions = sort(keys(%{$functions}));
+
+    $r->print(&Apache::lonhtmlcommon::row_title($lt{'func'})
+             .'<div>'
+             .'<input type="button" value="'.&mt('check all').'"'
+             .' onclick="javascript:checkAll(document.'.$formname.'.tool)" />'
+             .'&nbsp;<input type="button" value="'.&mt('uncheck all').'"'
+             .' onclick="javascript:uncheckAll(document.'.$formname.'.tool)" />'
+             .'</div>'
+             .'<table cellpadding="5px"><tr>' # FIXME Get rid of inflexible table (-> float)
+    );
+    for (my $i=0; $i<@allfunctions; $i++) {
+        $r->print('<td><label><span class="LC_nobreak">'
+                 .'<input type="checkbox" name="tool" value="'
+                 .$allfunctions[$i].'" /> '
+                 .&mt($$functions{$allfunctions[$i]})
+                 .'</span></label></td>'
+        );
+        if ($i == $halfnum - 1) {
+            $r->print('</tr><tr>');
+        }
     }
-    $r->print('
-       <td>
-        <input type="button" value="uncheck all"
-          onclick="javascript:uncheckAll(document.'.$formname.'.tool)" />
-       </td>
-      </tr>
-      <tr>
-       <td><b>Granularity:</b></td>
-       <td colspan="9">'.$lt{'doyo'}.'&nbsp;<label><input type="radio" name="granularity" value="Yes" />'.&mt('Yes').'</label>&nbsp;<label><input type="radio" name="granularity" value="No" checked="checked" />'.&mt('No').'</label>');
+    $r->print('</tr></table>'
+             .&Apache::lonhtmlcommon::row_closure()
+    );
+
+    # Granularity
+    $r->print(&Apache::lonhtmlcommon::row_title($lt{'gran'})
+             .$lt{'doyo'}.'<br />'
+             .'<label>'
+             .'<input type="radio" name="granularity" value="Yes" />'.&mt('Yes')
+             .'</label>&nbsp;<label>'
+             .'<input type="radio" name="granularity" value="No" checked="checked" />'.&mt('No')
+             .'</label>'
+    );
     if ($action eq 'modify') {
-        $r->print('&nbsp;&nbsp;('.&mt('Currently set to "[_1]"',
-                                      $$stored{'granularity'}).')');
+        $r->print(' <span class="LC_nobreak">('
+                 .&mt('Currently set to [_1].'
+                     ,'"'.&mt($$stored{'granularity'}).'"')
+                 .')</span>'
+        );
     }
-    $r->print('
-       </td>
-      </tr>
-     </table>
-    </td>
-   </tr>
-');
+    $r->print(&Apache::lonhtmlcommon::row_closure());
+
+    # Disk Quota
+    $r->print(&Apache::lonhtmlcommon::row_title($lt{'dquo'}));
+    if ($action eq 'create') {
+        $r->print('<span class="LC_info">'
+                 .&mt('If you enable the group portfolio for the '.$gpterm
+                     .', allocate a disk quota.')
+                 .'</span>'
+        );
+    } else {
+        $r->print(&mt('Quota allocated to group portfolio:'));
+    } 
+    $r->print(' '.&mt('[_1] MB','<input type="text" name="quota" size="4" />'));
+    if ($action eq 'create') {
+        $r->print('<br />'
+                 .&mt('A total of [_1] MB can be divided amongst all '.$gpterm.'s in the '
+                     .lc($crstype).', and [_2] MB are currently unallocated.'
+                     ,$crsquota,sprintf("%.2f",$freespace))
+                 );
+    } else {
+        $r->print('&nbsp;&nbsp;('.&mt('The quota is currently [_1] MB',
+                                      $$stored{'quota'}).').');
+
+        $r->print('<br />'
+                 .&mt('The quota can be increased to [_1] MB, '
+                 .'by adding all unallocated space for '.$gpterm.'s in the '.lc($crstype).'.'
+                  ,sprintf("%.2f",$maxposs)));
+    }
+    $r->print(&Apache::lonhtmlcommon::row_closure(1));
+
+    $r->print(&Apache::lonhtmlcommon::end_pick_box());
+
     return;
 }
 
+sub get_quota_constraints {
+    my ($action,$stored) = @_;
+    my ($crsquota,$freespace,$maxposs); 
+    $crsquota = $env{'course.'.$env{'request.course.id'}.'.internal.coursequota'};
+    if ($crsquota eq '') {
+        my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+        my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+        my $crstype = &Apache::loncommon::course_type();
+        my %domdefs = &Apache::lonnet::get_domain_defaults($cdom);
+        my %coursehash = (
+            'internal.coursecode' => $env{'course.'.$env{'request.course.id'}.'.internal.coursecode'},
+            'internal.textbook'   => $env{'course.'.$env{'request.course.id'}.'.internal.textbook'},
+        );
+        my %staticdefaults = (
+                           coursequota   => 20,
+        );
+        my $quotatype = &Apache::lonuserutils::get_extended_type($cdom,$cnum,$crstype,\%coursehash);
+        if ($crsquota eq '') {
+            $crsquota = $domdefs{$quotatype.'coursequota'};
+            if ($crsquota eq '') {
+                $crsquota = $staticdefaults{'coursequota'};
+            }
+        }
+    }
+    $freespace = $crsquota - &Apache::longroup::sum_quotas();
+    if ($action eq 'create') {
+        $maxposs = $freespace;
+    } else {
+        $maxposs = $$stored{'quota'} + $freespace;
+    }
+    return ($crsquota,$freespace,$maxposs);
+}
+
 sub membership_options {
-    my ($r,$action,$state,$tabcol,$sectioncount,$image) = @_;
+    my ($r,$cdom,$cnum,$action,$state,$sectioncount,$image,$gpterm,$ucgpterm,$crstype)=@_;
     my %lt = &Apache::lonlocal::texthash(
-                'pipa' => 'Pick parameters to generate membership list',
-                'gmem' => 'Group membership options',
-                'picr' => 'Pick the criteria to use to build a list of '.
-                          'course users from which you will select ',
-                'meof' => 'members of the new group.',
-                'admg' => 'additional members of the group.',
-                'ifno' => 'If you do not wish to add members when you first '.
-                          'create the group, do not make any selections',  
+                'pipa' => 'Build a list of users for selection of group members',
+                'gmem' => 'Group membership selection list criteria:',
+                'picr' => 'Pick the criteria to use to build a list of course users from which you will select members of the new group.',
+                'pica' => 'Pick the criteria to use to build a list of course users from which you will select additional members of the group.',
+                'ifno' => 'If you do not wish to add members when you first create the group, there is no need to pick any criteria.', 
                 'acty' => 'Access types',
                 'coro' => 'Course roles',
                 'cose' => 'Course sections',
              );
+    if ($crstype eq 'Community') {
+        $lt{'picr'} = &mt('Pick the criteria to use to build a list of community participants from which you will select ');
+        $lt{'asub'} = &mt('A subsequent step will also allow you to specify automatic adding/dropping of group members triggered by specified user role and section [_1]changes[_2] in the course.','<i>','</i>');
+        $lt{'coro'} = &mt('Community roles');
+        $lt{'cose'} = &mt('Community sections');
+    } else {
+        $lt{'asub'} = &mt('A subsequent step will also allow you to specify automatic adding/dropping of group members triggered by specified user role and section [_1]changes[_2] in the course.','<i>','</i>');
+    }
     my %status_types = (
                    active => &mt('Currently has access'),
                    previous => &mt('Previously had access'),
                    future => &mt('Will have future access'),
                    );
-                                                                                 
-    my @roles = ('st','cc','in','ta','ep','cr');
+
+    my @roles = ('st');
+    if ($crstype eq 'Community') {
+        push(@roles,'co');
+    } else {
+        push(@roles,'cc');
+    }
+    push (@roles,('in','ta','ep','ad','cr'));
 
     my @sections = keys(%{$sectioncount});
 
-    &topic_bar($r,$tabcol,$image,$lt{'pipa'});
-    $r->print('
-   <tr>
-    <td>&nbsp;</td>
-    <td colspan="3">
-     <b>'.$lt{'gmem'}.'</b><br/>'.$lt{'picr'});
+    $r->print(&Apache::lonhtmlcommon::topic_bar($image,$lt{'pipa'}).'
+     <b>'.$lt{'gmem'}.'</b><br />');
     if ($action eq 'create') {
-        $r->print($lt{'meof'}.'<br />'.$lt{'ifno'});
+        $r->print($lt{'picr'}.'<br />'.$lt{'ifno'}.'<br />'.$lt{'asub'});
     } else {
-        $r->print($lt{'admg'});
+        $r->print($lt{'pica'});
     }
     $r->print('
      <br />
      <br />
-     <table border="0">
+     <table class="LC_status_selector">
       <tr>
-       <td><b>'.$lt{'acty'}.'</b></td>
-       <td>&nbsp;</td>
-       <td><b>'.$lt{'coro'}.'</b></td>');
-    if (@sections >0) {
-        $r->print('
-       <td>&nbsp;</td>
-       <td><b>'.$lt{'cose'}.'</b></td>
-       <td>&nbsp;</td>');
-    }
-    $r->print('</tr><tr>');
+       <th>'.$lt{'acty'}.'</th>
+       <th>'.$lt{'coro'}.'</th>
+       <th>'.$lt{'cose'}.'</th>
+      </tr><tr><td>');
     $r->print(&Apache::lonhtmlcommon::status_select_row(\%status_types));
-    $r->print('<td>&nbsp;</td>');
-    $r->print(&Apache::lonhtmlcommon::role_select_row(\@roles));
+    $r->print('</td><td>');
+    $r->print(&Apache::lonhtmlcommon::role_select_row(\@roles,undef,undef,1,$cdom,$cnum));
     if (@sections > 0) {
         @sections = sort {$a cmp $b} @sections;
-        unshift(@sections,'_all'); # Put 'all' at the front of the list
-        unshift(@sections,'_nosec'); # Put 'no sections' next
-        $r->print('<td>&nbsp;</td>
-                   <td colspan="3" align="center" valign="top">'.
-        &sections_selection(\@sections,'sectionpick').'</td>');
+        unshift(@sections,'none'); # Put 'no sections' next
+        unshift(@sections,'all'); # Put 'all' at the front of the list
+    } else {
+        @sections = ('all','none');
     }
-    $r->print('
+    $r->print('</td><td>'.
+              &sections_selection(\@sections,'sectionpick').'</td>
       </tr>
-     </table>
-    </td>
-   </tr>');
+     </table>');
     return;
 }
 
@@ -1270,26 +1924,24 @@ sub sections_selection {
         $numvisible = @{$sections};
     }
     foreach my $sec (@{$sections}) {
-        if ($sec eq '_all') {
-            $section_sel .= '  <option value="'.$sec.'" />all sections'."\n";
-        } elsif ($sec eq '_nosec') {
-            $section_sel .= '  <option value="'.$sec.'" />no section'."\n"; 
+        if ($sec eq 'all') {
+            $section_sel .= '  <option value="'.$sec.'">'.&mt('all sections').'</option>'."\n";
+        } elsif ($sec eq 'none') {
+            $section_sel .= '  <option value="'.$sec.'">'.&mt('no section').'</option>'."\n"; 
         } else {
-            $section_sel .= '  <option value="'.$sec.'" />'.$sec."\n";
+            $section_sel .= '  <option value="'.$sec.'">'.$sec."</option>\n";
         }
     }
     my $output = '
-        <select name="'.$elementname.'" multiple="true" size="'.$numvisible.'">
+        <select name="'.$elementname.'" multiple="multiple" size="'.$numvisible.'">
           '.$section_sel.'
         </select>';
     return $output;
 }
 
 sub access_date_settings {
-    my ($r,$tabcol,$action,$formname,$stored,$image) = @_;
-    my %lt = &Apache::lonlocal::texthash(
-                'sten' => 'Default start and end dates for group access',
-             );
+    my ($r,$action,$formname,$stored,$image,$gpterm,$ucgpterm) = @_;
+    my $sten = &mt("Default start and end dates for $gpterm access");
     my $starttime = time;
     my $endtime = time+(6*30*24*60*60); # 6 months from now, approx
     if ($action eq 'modify') {
@@ -1298,47 +1950,30 @@ sub access_date_settings {
             $endtime = $$stored{'enddate'};
         }
     }
-    my ($start_table,$end_table) = &date_setting_table
-                                    ($starttime,$endtime,$formname);
-    &topic_bar($r,$tabcol,$image,$lt{'sten'});
-    $r->print('
-   <tr>
-    <td>&nbsp;</td>
-    <td colspan="3">'.$start_table.'</td>
-   <tr>
-   <tr>
-    <td colspan="4">&nbsp;</td>
-   </tr>
-   <tr>
-    <td>&nbsp;</td>
-    <td colspan="3">'.$end_table.'</td>
-   <tr>');
+    my ($table) = &date_setting_table($starttime,$endtime,$formname);
+    $r->print(&Apache::lonhtmlcommon::topic_bar($image,$sten).'
+    '.$table.'
+    ');
     return;
 }
 
 sub choose_members_form {
-    my ($r,$cdom,$cnum,$tabcol,$action,$formname,$page,$groupname,$description,
-        $granularity,$startdate,$enddate,$tools,$fixedprivs,$toolprivs,
+    my ($r,$cdom,$cnum,$action,$formname,$page,$groupname,$description,
+        $granularity,$quota,$startdate,$enddate,$tools,$fixedprivs,$toolprivs,
         $functions,$users,$userdata,$idx,$stored,$states,$navbuttons,
-        $rowColor1,$rowColor2) = @_;
+        $gpterm,$ucgpterm,$crstype) = @_;
     my @regexps = ('user_','userpriv_','sec_');
     my %origmembers;
     $r->print(&Apache::lonhtmlcommon::echo_form_input(
          ['origin','action','state','page','member','specificity','branch',
           'defpriv','autorole','autoadd','autodrop','sortby','togglefunc'],
          \@regexps));
-    my $earlyout = &validate_groupname($groupname,$action,$cdom,$cnum);
-    $r->print('
-<table width="100%" cellpadding="0" cellspacing="0" border="0">
- <tr>
-  <td>&nbsp;</td>
-  <td colspan="3">
-');
+    my $earlyout = &validate_groupname($groupname,$action,$cdom,$cnum,$gpterm,
+                                       $ucgpterm,$crstype);
     if ($earlyout) {
-        $r->print($earlyout.'</td></tr>');
+	$r->print($earlyout);
         &display_navbuttons($r,$formname,$$states{$action}[$page-1],
                            $$navbuttons{'gtps'});
-        $r->print('</table>');
         return;
     } 
     my ($specimg,$memimg);
@@ -1346,10 +1981,9 @@ sub choose_members_form {
     my @unavailable = ();
     &check_tools($functions,$tools,\@available,\@unavailable);
     if ($action eq 'create') {
-        &print_current_settings($r,$action,$tabcol,$rowColor1,$rowColor2,
-                                $functions,$startdate,$enddate,$groupname,
-                                $description,$granularity,\@available,
-                                \@unavailable);
+        &print_current_settings($r,$action,$functions,$startdate,$enddate,
+				$groupname,$description,$granularity,$quota,
+				\@available,\@unavailable,$gpterm,$ucgpterm);
         $specimg = 4;
         $memimg = 5;
     } else {
@@ -1369,13 +2003,13 @@ sub choose_members_form {
             }
         }
     }
-    &privilege_specificity($r,$tabcol,$rowColor1,$rowColor2,$action,
-                          $specimg,$tools,$stored,$toolprivs,
-                          $fixedprivs,\@available,$formname);
-    my $newusers = &pick_new_members($r,$action,$formname,$tabcol,$rowColor1,
-                                    $rowColor2,\@available,$idx,$stored,
-                                    $memimg,$users,$userdata,$granularity,
-                                    \%origmembers);
+    &privilege_specificity($r,$action,$specimg,$tools,$stored,$toolprivs,
+                          $fixedprivs,\@available,$formname,$gpterm,$ucgpterm,
+                          $functions,$crstype);
+    my $newusers = &pick_new_members($r,$action,$formname,\@available,$idx,
+				     $stored,$memimg,$users,$userdata,
+				     $granularity,\%origmembers,$gpterm,
+				     $ucgpterm);
     if ($newusers || $action eq 'create') {
         &display_navbuttons($r,$formname,$$states{$action}[$page-1],
                             $$navbuttons{'gtps'},$$states{$action}[$page+1],
@@ -1384,34 +2018,29 @@ sub choose_members_form {
         &display_navbuttons($r,$formname,$$states{$action}[$page-1],
                             $$navbuttons{'gtps'});
     }
-    $r->print('</table>');
     return;
 }
 
 sub display_navbuttons {
     my ($r,$formname,$prev,$prevtext,$next,$nexttext) = @_;
-    $r->print('
-    <tr>
-     <td colspan="4">&nbsp;</td>
-    </tr>
-    <tr>
-     <td>&nbsp;</td>
-     <td colspan="3">');
+    $r->print('<div class="LC_navbuttons">');
     if ($prev) {
         $r->print('
       <input type="button" name="previous" value = "'.$prevtext.'"
     onclick="javascript:backPage(document.'.$formname.','."'".$prev."'".')"/>
    &nbsp;&nbsp;&nbsp;');
+    } elsif ($prevtext) {
+        $r->print('
+      <input type="button" name="previous" value = "'.$prevtext.'"
+    onclick="javascript:history.back()"/>
+   &nbsp;&nbsp;&nbsp;');
     }
     if ($next) {
         $r->print('
       <input type="button" name="next" value="'.$nexttext.'"
  onclick="javascript:nextPage(document.'.$formname.','."'".$next."'".')" />');
     }
-    $r->print('
-     </td>
-    </tr>
-');
+    $r->print('</div>');
 }
 
 sub check_tools {
@@ -1427,21 +2056,22 @@ sub check_tools {
 }
 
 sub print_current_settings {
-    my ($r,$action,$tabcol,$rowColor1,$rowColor2,$functions,$startdate,$enddate,
-           $groupname,$description,$granularity,$available,$unavailable) =@_;
+    my ($r,$action,$functions,$startdate,$enddate,$groupname,$description,
+	$granularity,$quota,$available,$unavailable,$gpterm,$ucgpterm) = @_;
 
     my %lt = &Apache::lonlocal::texthash(
         grna => 'Group Name',
-        desc => 'Description',
-        grfn => 'Group Functions',
+        desc => 'Group Title',
+        grfn => "Collaborative Tools",
         gran => 'Granularity',
+        quot => 'File quota',
         dfac => 'Default access dates',
-        ygrs => 'Your group selections',
-        tfwa => 'The following settings will apply to the group:',
-        difn => 'Different functionality<br />for different users:',
-        stda => 'Start date',
+        ygrs => "Your group selections - ",
+        tfwa => "The following settings will apply to the group:",
+        stda => 'Start date:',
         enda => 'End date:',
     );
+    $lt{'difn'} = &mt('Different collaborative tools[_1]for different members:','<br />');
     my $showstart = &Apache::lonlocal::locallocaltime($startdate);
     my $showend;
     if ($enddate == 0) {
@@ -1449,101 +2079,79 @@ sub print_current_settings {
     } else {
         $showend = &Apache::lonlocal::locallocaltime($enddate);
     }
-    $r->print('<table border="0" cellpadding="0" cellspacing="20">');
     if ($action eq 'create') {
         $r->print('
-<tr>
- <td><font face="arial,helvetica,sans-serif"><b>'.$lt{'ygrs'}.'</b></font>
+<div><span style="font-size: larger">'.$lt{'ygrs'}.'</span>
 <br />'.$lt{'tfwa'}.'
- </td>
-</tr>');
+</div>');
     }
-    $r->print('<tr><td>');
-    $r->print(&Apache::lonhtmlcommon::start_pick_box());
+    $r->print(&Apache::loncommon::start_data_table('LC_course_group_status').
+	      &Apache::loncommon::start_data_table_header_row());
     $r->print('
-<tr>
- <td>
-<table cellspacing="1" cellpadding="4">
- <tr bgcolor="'.$tabcol.'" align="center">
-  <td><b>'.$lt{'grna'}.'</b></td>
-  <td><b>'.$lt{'desc'}.'</b></td>
-  <td><b>'.$lt{'grfn'}.'</b></td>
-  <td><b>'.$lt{'gran'}.'</b></td>
-  <td><b>'.$lt{'dfac'}.'</b></td>
- </tr>
- <tr bgcolor="'.$rowColor2.'">
-  <td valign="top"><small>'.$groupname.'</small></td>
-  <td valign="top"><small>'.$description.'</small></td>
+  <th>'.$lt{'grna'}.'</th>
+  <th>'.$lt{'desc'}.'</th>
+  <th>'.$lt{'grfn'}.'</th>
+  <th>'.$lt{'gran'}.'</th>
+  <th>'.$lt{'quot'}.'</th>
+  <th>'.$lt{'dfac'}.'</th>
+');
+    $r->print(&Apache::loncommon::end_data_table_header_row().
+	      &Apache::loncommon::start_data_table_row('LC_data_table_dense'));
+    $r->print('
+  <td valign="top">'.$groupname.'</td>
+  <td valign="top">'.$description.'</td>
   <td>
 ');
+
     if (@{$available} > 0) {
-        $r->print('<small><b>Available:</b></small>
-                    <table cellpadding="" cellspacing="1"><tr>');
-        my $rowcell = int(@{$available}/2) + @{$available}%2;
+        $r->print('<b>'.&mt('Available for assignment to members:').'</b>');
+        $r->print('<ul>');
         for (my $i=0; $i<@{$available}; $i++) {
-            if (@{$available} > 3) {
-                if ($i==$rowcell) {
-                    $r->print('</tr><tr>');
-                }
-            }
-            $r->print('<td><small>'.$$functions{$$available[$i]}.
-                                          '</small></td><td>&nbsp;</td>');
-        }
-        if ((@{$available} > 3) && (@{$available}%2)) {
-            $r->print('<td>&nbsp;</td><td>&nbsp;</td>');
+            $r->print('<li>'.&mt($$functions{$$available[$i]}).'</li>');
         }
-        $r->print('</tr></table><br />');
+        $r->print('</ul>');
     }
+
     if (@{$unavailable} > 0) {
-        $r->print('<small><b>Unavailable:</b></small>
-                    <table cellpadding="0" cellspacing="1"  border="0"><tr>');
-        my $rowcell = int(@{$unavailable}/2) + @{$unavailable}%2;
-        for (my $j=0; $j<@{$unavailable}; $j++) {
-            if (@{$unavailable} > 3) {
-                if ($j==$rowcell) {
-                    $r->print('</tr><tr>');
-                }
-            }
-            $r->print('<td><small>'.$$functions{$$unavailable[$j]}.
-                                              '</small></td><td>&nbsp;</td>');
-        }
-        if ((@{$unavailable} > 3) && (@{$unavailable}%2)) {
-            $r->print('<td>&nbsp;</td><td>&nbsp;</td>');
+        $r->print('<b>'.&mt('Unavailable for assignment:').'</b>');
+        $r->print('<ul>');
+        for (my $i=0; $i<@{$unavailable}; $i++) {
+            $r->print('<li>'.&mt($$functions{$$unavailable[$i]}).'</li>');
         }
-        $r->print('</tr></table>');
+        $r->print('</ul>');
     }
+
+    my $quota_text=&mt('[_1] MB',$quota);
+    my $granu_text=&mt($granularity);
     $r->print(<<"END");
   </td>
-  <td valign="top"><small><b>$lt{'difn'}
-  </b> $granularity</small> 
-  <td valign="top"><small><b>$lt{'stda'}</b> $showstart<br />
-      <b>$lt{'enda'}</b> $showend</small>
+  <td valign="top"><b>$lt{'difn'}</b> $granu_text</td>
+  <td valign="top">$quota_text</td> 
+  <td valign="top"><b>$lt{'stda'}</b> $showstart<br />
+      <b>$lt{'enda'}</b> $showend
   </td>
- </tr>
-</table>
-</td>
-</tr>
 END
-    $r->print(&Apache::lonhtmlcommon::end_pick_box());
-    $r->print('</td></tr></table><br />');
+    $r->print(&Apache::loncommon::end_data_table_row().
+	      &Apache::loncommon::end_data_table());
     return;
 }
 
 sub pick_new_members {
-    my ($r,$action,$formname,$tabcol,$rowColor1,$rowColor2,$available,$idx,
-        $stored,$img,$users,$userdata,$granularity,$origmembers) = @_;
+    my ($r,$action,$formname,$available,$idx,$stored,$img,$users,$userdata,
+	$granularity,$origmembers,$gpterm,$ucgpterm) = @_;
     my %lt = &Apache::lonlocal::texthash(
-          'gpme' => 'Group membership',
+          'gpme' => "Group membership",
           'addm' => 'Add members',
-          'setf' => 'Set functionality',
-          'func' => 'Functionality',
-          'nome' => 'No members to add at this time.',
-          'nnew' => 'There are no users to add as new members, as all users'.
-                    ' matching the specified type(s), role(s), and/or '.
-                    'section(s) are already affiliated with this group.',
-          'yoma' =>  'You may need to use the '."'".'modify existing, past or '.
-                     'future members'."'".' page if you need to re-enable '.
-                     'or activate access for previous or future members.',
+          'setf' => 'Assign collaborative tools', 
+          'func' => 'Tools',
+          'nome' => 'No members to add at this time, as there are no users '.
+                     'matching the specified type(s), role(s) and section(s).',
+          'nnew' => "There are no users to add as new members, as all users".
+                    " matching the specified type(s), role(s), and ".
+                    "section(s) are already affiliated with this group.",
+          'yoma' =>  "You may need to use the 'modify existing, past or ".
+                     "future members' page if you need to re-enable ".
+                     "or activate access for previous or future members.",
     );
     my %members;
     my $totalusers = 0;
@@ -1567,61 +2175,51 @@ sub pick_new_members {
             $r->print(&check_uncheck_tools($r,$available));
         }
     }
-    &topic_bar($r,$tabcol,$img,$lt{'gpme'});
+    $r->print(&Apache::lonhtmlcommon::topic_bar($img,$lt{'gpme'}));
     if (keys(%members) > 0) {
         $r->print('
- <tr>
-  <td>&nbsp;</td>
-  <td colspan="3">
     <table>
      <tr>');
         &check_uncheck_buttons($r,$formname,'member',$lt{'addm'});
         if (@{$available} > 0 && $granularity eq 'Yes') {
-            $r->print('<td><nobr>
-     <fieldset><legend><b>'.$lt{'setf'}.'</b></legend>
-      <input type="button" value="check all"
+            $r->print('<td>
+     <fieldset><legend>'.$lt{'setf'}.'</legend>
+      <span class="LC_nobreak">
+      <input type="button" value="'.&mt('check all').'"
         onclick="javascript:checkAllTools(document.'.$formname.')" />
         &nbsp;&nbsp;
-      <input type="button" value="uncheck all"
+      <input type="button" value="'.&mt('uncheck all').'"
         onclick="javascript:uncheckAllTools(document.'.$formname.')" />
-     </fieldset></nobr></td>');
+      </span>
+     </fieldset></td>');
         }
         $r->print('</tr></table>
-  </td>
- </tr>
- <tr>
-  <td colspan="4">&nbsp;</td>
- </tr>
- <tr>
-  <td>&nbsp;</td>
-  <td colspan="3">
         ');
-        $r->print(&Apache::lonhtmlcommon::start_pick_box());
+        $r->print(&Apache::loncommon::start_data_table().
+		  &Apache::loncommon::start_data_table_header_row());
         $r->print('
-   <table border="0" cellpadding="4" cellspacing="1">
-    <tr bgcolor="'.$tabcol.'" align="center">
-     <td><b>'.&mt('Add?').'</b></td>
-     <td><b><a href="javascript:changeSort('."'fullname'".')">'.&mt('Name').'</a></b></td>
-     <td><b><a href="javascript:changeSort('."'username'".')">'.&mt('Username').'</a></b>
-     </td>
-     <td><b><a href="javascript:changeSort('."'domain'".')">'.&mt('Domain').'</a></b></td>
-     <td><b><a href="javascript:changeSort('."'id'".')">ID</a></b></td>
+     <th>'.&mt('Add?').'</b></td>
+     <th><a href="javascript:changeSort('."'fullname'".')">'.&mt('Name').'</a></td>
+     <th><a href="javascript:changeSort('."'username'".')">'.&mt('Username').'</a></td>
+     <th><a href="javascript:changeSort('."'domain'".')">'.&mt('Domain').'</a></td>
+     <th><a href="javascript:changeSort('."'id'".')">'.&mt('ID').'</a></td>
+     <th><a href="javascript:changeSort('."'section'".')">'.&mt('Section').'</a></td>
 ');
         if (@{$available} > 0) {
-            $r->print('<td><b>'.$lt{'func'}.'</b></td>');
+            $r->print('<th>'.$lt{'func'}.'</th>');
         }
-        $r->print('</tr>');
+        $r->print(&Apache::loncommon::end_data_table_header_row());
         if (@{$available} > 0) {
             if ($granularity eq 'Yes') {
-                $r->print('<tr bgcolor="#cccccc">
- <td colspan="5">&nbsp;</td>
- <td align="center"><small><nobr><b>'.&mt('All:').'</b>&nbsp;');
+                $r->print(&Apache::loncommon::start_data_table_row('LC_data_table_dense LC_data_table_highlight').'
+ <td colspan="6">&nbsp;</td>
+ <td align="center"><span class="LC_nobreak"><b>'.&mt('All:').'</b>&nbsp;');
                 foreach my $tool (@{$available}) {
                     $r->print('<label><input type="checkbox" name="togglefunc" '.
    'onclick="javascript:toggleTools(document.'.$formname.'.user_'.$tool.',this);"'.
    ' value="'.$tool.'">'.'<b>'.$tool.'</b></label>&nbsp;&nbsp;&nbsp;');
                 }
-                $r->print('</nobr></small></td></tr>');
+                $r->print('</span></td></tr>');
             }
         }
         my %Sortby = ();
@@ -1634,29 +2232,28 @@ sub pick_new_members {
                 push(@{$Sortby{$members{$user}[$$idx{udom}]}},$user);
             } elsif ($env{'form.sortby'} eq 'id') {
                 push(@{$Sortby{$members{$user}[$$idx{id}]}},$user);
+            } elsif ($env{'form.sortby'} eq 'section') {
+                push(@{$Sortby{$members{$user}[$$idx{section}]}},$user);
             } else {
                 push(@{$Sortby{$members{$user}[$$idx{fullname}]}},$user);
             }
         }
-        my $rowNum = 0;
-        my $rowColor;
         foreach my $key (sort(keys(%Sortby))) {
             foreach my $user (@{$Sortby{$key}}) {
-                if ($rowNum %2 == 1) {
-                    $rowColor = $rowColor1;
-                } else {
-                    $rowColor = $rowColor2;
-                }
                 my $id = $members{$user}[$$idx{id}];
                 my $fullname = $members{$user}[$$idx{fullname}];
                 my $udom = $members{$user}[$$idx{udom}];
                 my $uname = $members{$user}[$$idx{uname}];
-                $r->print('<tr bgcolor="'.$rowColor.'"><td align="right">
-   <input type="checkbox" name="member" value="'.$user.'" /></td><td><small>'.
-    $fullname.'</small></td><td><small>'.$uname.'</small></td><td><small>'.
-    $udom.'</small></td><td><small>'.$id.'</small></td>');
+                my $section = $members{$user}[$$idx{section}];
+                $r->print(&Apache::loncommon::start_data_table_row('LC_data_table_dense').
+			  '<td align="right"><input type="checkbox" name="member" value="'.$user.'" /></td>'.
+			  '<td>'.$fullname.'</td>'.
+			  '<td>'.$uname.'</td>'.
+			  '<td>'.$udom.'</td>'.
+			  '<td>'.$id.'</td>'.
+			  '<td>'.$section.'</td>');
                 if (@{$available} > 0) {
-                    $r->print('<td align="center"><nobr><small>'.
+                    $r->print('<td align="center"><span class="LC_nobreak">'.
                               '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');
                     foreach my $tool (@{$available}) {
                         if ($granularity eq 'Yes') {
@@ -1667,69 +2264,62 @@ sub pick_new_members {
                           $tool.'" value="'.$user.'" />'.$tool.'&nbsp;&nbsp;&nbsp;');
                         }
                     }
-                    $r->print('</small></nobr></td>');
+                    $r->print('</span></td>');
                 }
-                $r->print('</tr>'."\n");
-                $rowNum ++;
+                $r->print(&Apache::loncommon::end_data_table_row()."\n");
             }
         }
-        $r->print(&Apache::lonhtmlcommon::end_pick_box());
-        $r->print('
-     </td>
-    </tr>');
+        $r->print(&Apache::loncommon::end_data_table());
     } else {
-        $r->print('
-    <tr>
-     <td>&nbsp;</td>
-     <td colspan="3">
-');
         if ($totalusers > 0) {
             $r->print($lt{'nnew'}.'<br /><br />'.$lt{'yoma'});
         } else { 
             $r->print($lt{'nome'});
         }
-        $r->print('
-     </td>
-    </tr>');
     }
     return $newusers;
 }
 
 sub privilege_specificity {
-    my ($r,$tabcol,$rowColor1,$rowColor2,$action,$img,$tools,$stored,
-        $toolprivs,$fixedprivs,$available,$formname) = @_;
+    my ($r,$action,$img,$tools,$stored,$toolprivs,$fixedprivs,$available,
+	$formname,$gpterm,$ucgpterm,$functions,$crstype) = @_;
     my %lt = &Apache::lonlocal::texthash (
-      'uprv' => 'User privileges',
-      'frty' => 'For each type of functionality you have chosen to include, '.
-                'there is a set of standard privileges which apply to all '.
-                'of those for whom the functionality is enabled.',
-      'thar' => 'There are also additional privileges which can be set for '.
-                'some, or all, members. Please choose one of the following:',
-      'fort' => 'For the types of functionality you have chosen to include '.
-                'there are no additional privileges which can be set for some '.
-                'or all members.',
-      'eaty' => 'Each of the types of functionality includes standard '.
-                'privileges which apply to members with access to that '.
-                'functionality, and may also include additional privileges '.
+      'uprv' => 'User privileges for collaborative tools',
+      'frty' => 'For each collaborative tool you have chosen to include, '.
+                'there is a set of core privileges which all group members '.
+                'assigned use of the tool will receive.',
+      'thar' => 'For some tools there are also additional optional '.
+                 'privileges which can be set.',
+      'plch' => 'Choose one of the following:',
+      'fort' => 'For the collaborative tools you have chosen to include '.
+                'only core privileges are available, '.
+                'so there are no optional privileges to assign.',
+      'eaty' => 'Each collaborative tool includes core '.
+                'privileges assigned to all members with access to the '.
+                'tool. Some tools may also feature additional privileges '.
                 'which can be set for specific members.',
       'cutg' => 'Currently the group is configured ',
-      'sdif' => 'so different group members can receive different privileges.',
-      'sall' => 'so all group members will receive the same privileges.',
-      'algm' => 'All group members will receive the same privileges.',
-      'smgp' => 'Some group members will receive different privileges from '.
-                'others.',
-      'thwi' => 'These will be the privileges all group members receive, '. 
+      'sdif' => 'so different members can receive different optional privileges for a particular tool.',
+      'sall' => 'so all members will receive the same optional privileges for a particular tool.',
+      'algm' => 'All group members will receive the same privileges for any tool assigned to them, including the default set of optional privileges.',
+      'smgp' => 'Different group members may receive different privileges from '.
+                'others for the tools they have been assigned.',
+      'thwi' => 'These will be the privileges all group members receive for a particular assigned tool, '. 
                 'if you selected the first option above.',
-      'thes' => 'These will be the privileges given to members assigned '.   
-                'in the future, including via automatic group assignment '.
-                'for specific sections/roles ',
-      'asyo' => 'As you have chosen not to include any functionality in the '.
-                'group, no default user privileges settings need to be set.',
-      'plin' => 'Please indicate which <b>optional</b> privileges members '.
-                'will receive by default.',
+      'thes' => "These will be the privileges given to members assigned ".   
+                "in the future via automatic group assignment ".
+                "for users who receive specific sections/roles in the course ",
+      'asyo' => "As you have chosen not to include any collaborative tools ".
+                "in the group, no default optional privileges need to be set.",
+                'will receive by default for a specific tool.',
       'oppr' => 'Optional privileges',
       'defp' => 'The default privileges new members will receive are:', 
     );
+    $lt{'plin'} = &mt('Indicate which [_1]optional[_2] privileges members '.
+                      'will receive by default for a specific tool.','<b>','</b>');
+    if ($crstype eq 'Community') {
+        $lt{'thes'} = &mt('These will be the privileges given to members assigned in the future via automatic group assignment for users who receive specific sections/roles in the community '); 
+    }
     my $totaloptionalprivs = 0;
     foreach my $tool (@{$tools}) {
         foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
@@ -1738,14 +2328,9 @@ sub privilege_specificity {
             }
         }
     }
-    &topic_bar($r,$tabcol,$img,$lt{'uprv'});
-    $r->print('
- <tr>
-  <td>&nbsp;</td>
-  <td colspan="3">
-  ');
+    $r->print(&Apache::lonhtmlcommon::topic_bar($img,$lt{'uprv'}));
     if ((($action eq 'create') && (@{$available} > 0)) || 
-        (($action eq 'modify') && ($formname eq 'change_settings'))) {  
+        (($action eq 'modify') && ($formname eq 'change_settings'))) {
         my %specific = (
                       'No'  => 'checked="checked"',
                       'Yes' => '',
@@ -1753,7 +2338,7 @@ sub privilege_specificity {
         if ($action eq 'create') {
             $r->print($lt{'frty'}.'<br />');
             if ($totaloptionalprivs) {
-                $r->print($lt{'thar'});
+                $r->print($lt{'thar'}.'<br /><br />'.$lt{'plch'});
             } else {
                 $r->print($lt{'fort'});
             }
@@ -1769,23 +2354,16 @@ sub privilege_specificity {
         }
         if ($totaloptionalprivs) {
             $r->print('
-<br /><br /><label><nobr><input type="radio" name="specificity" value="No" '.$specific{'No'}.' />&nbsp;'.$lt{'algm'}.'</nobr></label><br/>
-<label><nobr><input type="radio" name="specificity" value="Yes" '.$specific{'Yes'}.' />&nbsp;'.$lt{'smgp'}.'</nobr></label>
-  </td>
- </tr>
- <tr>
-  <td colspan="4">&nbsp;</td>
- </tr>');
+<br />
+<label><span class="LC_nobreak"><input type="radio" name="specificity" value="No" '.$specific{'No'}.' />&nbsp;'.$lt{'algm'}.'</span></label><br />
+<label><span class="LC_nobreak"><input type="radio" name="specificity" value="Yes" '.$specific{'Yes'}.' />&nbsp;'.$lt{'smgp'}.'</span></label><br /><br />');
         } else {
             $r->print('<input type="hidden" name="specificity" value="No" />');
         }
         if ($totaloptionalprivs) {
-            $r->print('
- <tr>
-  <td>&nbsp;</td>
-  <td colspan="3">'.$lt{'plin'});
+            $r->print($lt{'plin'});
             if ($action eq 'create') {
-                $r->print(' '.$lt{'thwi'});
+                $r->print('<br />'.$lt{'thwi'});
             }
             $r->print('<br />'.$lt{'thes'});
             if ($action eq 'create') {
@@ -1794,30 +2372,22 @@ sub privilege_specificity {
                 $r->print('('.&mt('if enabled below').').');
             }
             $r->print('<br /><br />
-  </td>
- </tr>
- <tr>
-  <td>&nbsp;</td>
-  <td colspan="2"><table><tr>');
+  <table><tr>');
         &check_uncheck_buttons($r,$formname,'defpriv',$lt{'oppr'});
         $r->print('
     </tr>
    </table>
-  </td>
-  <td width="100%">&nbsp;</td>
- </tr><tr>
-  <td>&nbsp;</td>
-  <td colspan="3">
    <br />
 ');
         } else {
-            $r->print('<tr><td>&nbsp;</td><td colspan="3">'.$lt{'algm'}.'<br /><br />');
+            $r->print($lt{'algm'}.'<br /><br />');
         }
-        &default_privileges($r,$action,$tabcol,$rowColor1,$rowColor2,
-                            $tools,$toolprivs,$fixedprivs,$available);
+        &default_privileges($r,$action,$tools,$toolprivs,$fixedprivs,
+			    $available,$functions);
     } else {
         if ($action eq 'create') {
             $r->print($lt{'asyo'});
+            $r->print('<input type="hidden" name="specificity" value="No" />');
         } elsif ($action eq 'modify' && $formname eq 'pick_members') {
             my @defprivs;
             if (ref($$stored{'defpriv'}) eq 'ARRAY') {
@@ -1830,98 +2400,93 @@ sub privilege_specificity {
                 $r->print($lt{'sall'});
             }
             $r->print(' '.$lt{'defp'}.'<br /><br />');
-            &display_defprivs($r,$tabcol,$rowColor1,$rowColor2,$tools,
-                              $toolprivs,\@defprivs);
+            &display_defprivs($r,$tools,$toolprivs,\@defprivs);
         }
     }
-    $r->print('
-  </td>
- </tr>
-');
     return;
 }
 
 sub default_privileges {
-    my ($r,$action,$tabcol,$rowColor1,$rowColor2,$tools,$toolprivs,
-        $fixedprivs,$available) = @_;
+    my ($r,$action,$tools,$toolprivs,$fixedprivs,$available,$functions) = @_;
     my %lt = &Apache::lonlocal::texthash(
                                 'addp' => 'Additional privileges',
                                 'fixp' => 'Fixed privileges',
                                 'oppr' => 'Optional privileges',
-                                'func' => 'Function',
+                                'func' => 'Collaborative Tool',
     );
-    $r->print(&Apache::lonhtmlcommon::start_pick_box());
-    $r->print('<tr>
-                <td bgcolor="'.$tabcol.'" valign="top">
-                 <table cellspacing="0" cellpadding="1">
-                  <tr>
-                   <td valign="top"><b>'.$lt{'func'}.'</b></td>
-                  </tr>
-                  <tr>
-                   <td valign="top"><b>'.$lt{'fixp'}.'</b></td>
-                  </tr>
-                  <tr>
-                   <td valign="top"><b>'.$lt{'oppr'}.'</b></td>
-                  </tr>
-                 </table>
-                </td>
-    ');
+    $r->print(&Apache::lonhtmlcommon::start_pick_box('LC_group_priv_box').
+	      &Apache::lonhtmlcommon::row_title($lt{'func'},undef,
+     						'LC_groups_functionality'));
+    my @tableHeader;
+    if ((ref($functions) eq 'HASH') && (ref($tools) eq 'ARRAY')) {
+        @tableHeader = map { $functions->{$_}; } @{$tools};
+    }
+ $r->print(join('</td><td class="LC_groups_functionality">', @tableHeader));
+    $r->print(&Apache::lonhtmlcommon::row_closure(1));
+    my $fixed = '';
+    my $dynamic = '';
     foreach my $tool (@{$tools}) {
-        $r->print('<td align="center" valign="top">
-                    <table cellspacing="0" cellpadding="1">
-                     <tr bgcolor="#cccccc">
-                      <td colspan="2" align="center"><b>'.$tool.'</b></td>
-                     </tr>
-        ');
         my $privcount = 0;
-        my $fixed = '';
-        my $dynamic = '';
+	if ($dynamic ne '') {
+	    $dynamic .= '</td><td class="LC_groups_optional">';
+	}
+	$dynamic .= '<table class="LC_group_priv"><tr>';
         foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
             if (exists($$fixedprivs{$tool}{$priv})) {
-                $fixed .= '<input type="hidden" name="defpriv" value="'.$priv.'" />'.$$toolprivs{$tool}{$priv}.'&nbsp;';
+		if ($fixed ne '') {
+		    $fixed .= '</td><td class="LC_groups_fixed">';
+		}
+                $fixed .= '<input type="hidden" name="defpriv" value="'.$priv.'" />'
+                         .'<span class="LC_nobreak">'.&mt($$toolprivs{$tool}{$priv}).'&nbsp;';
                 if ($action eq 'modify') {
-                    if (grep/^$tool$/,@{$available}) {
+                    if (grep(/^$tool$/,@{$available})) {
                         $fixed .= '<small>'.&mt('(on)').'<small>&nbsp;';
                     } else {
                         $fixed .= '<small>'.&mt('(off)').'<small>&nbsp;';
                     }
                 }
+                $fixed .= '</span>';
             } else {
-                $privcount ++;
+                $privcount++;
                 if ($privcount == 3) {
                     $dynamic .= '</tr>
-                                 <tr bgcolor="'.$rowColor1.'">'."\n";
+                                 <tr>'."\n";
                 }
-                $dynamic .= '<td><label><input type="checkbox" name="defpriv" value="'.$priv.'" />'.$$toolprivs{$tool}{$priv}.'</label></td>'."\n";
+                $dynamic .= '<td><span class="LC_nobreak"><label><input type="checkbox" name="defpriv" value="'.$priv.'" />'.&mt($$toolprivs{$tool}{$priv}).'</label></span></td>'."\n";
             }
         }
-        if ($dynamic eq '') {
-            $dynamic = '<td>None</td>'."\n";
+        if ($privcount == 0) {
+            $dynamic .= '<td>'.&mt('None').'</td>'."\n";
         }
         if ($privcount < 3) {
-            $dynamic .= '</tr>
-                         <tr bgcolor="'.$rowColor1.'">
-                          <td colspan="2">&nbsp;</td>'."\n";
+            $dynamic .= '<td>&nbsp;</td>'."\n";
         } elsif ($privcount%2) {
             $dynamic = '<td>&nbsp;</td>'."\n";
         }
-        $r->print('<tr bgcolor="'.$rowColor2.'">
-                    <td colspan="2" align="center"><nobr>'.$fixed.'</nobr></td>
-                   </tr>
-                   <tr bgcolor="'.$rowColor1.'">'."\n".$dynamic.'</tr>'."\n".'</table>'."\n".'</td>
-        ');
+	$dynamic .= '</tr></table>';
     }
-    $r->print('</tr>'."\n");
-    $r->print(&Apache::lonhtmlcommon::end_pick_box());
+    $r->print(&Apache::lonhtmlcommon::row_title($lt{'fixp'},undef,
+						'LC_groups_fixed').
+	      $fixed.
+	      &Apache::lonhtmlcommon::row_closure(1));
+    $r->print(&Apache::lonhtmlcommon::row_title($lt{'oppr'},undef,
+						'LC_groups_optional').
+	      $dynamic.
+	      &Apache::lonhtmlcommon::end_pick_box());
     $r->print('<br />');
     return;
+
 }
 
 sub display_defprivs {
-    my ($r,$tabcol,$rowColor1,$rowColor2,$tools,$toolprivs,$defprivs) = @_;
+    my ($r,$tools,$toolprivs,$defprivs) = @_;
+    my $function = &Apache::loncommon::get_users_function();
+    my $tabcol = &Apache::loncommon::designparm($function.'.tabbg');
+    my $rowColor1 = "#dddddd";
+    my $rowColor2 = "#eeeeee";
     my %lt = &Apache::lonlocal::texthash(
                                 'priv' => 'Privileges',
-                                'func' => 'Function',
+                                'func' => 'Collaborative Tool',
     );
     $r->print(&Apache::lonhtmlcommon::start_pick_box());
     $r->print('<tr>');
@@ -1931,7 +2496,7 @@ sub display_defprivs {
         @{$currprivs{$tool}} = ();
         foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
             if (ref($defprivs) eq 'ARRAY') {
-                if (grep/^\Q$priv\E$/,@{$defprivs}) {
+                if (grep(/^\Q$priv\E$/,@{$defprivs})) {
                     push(@{$currprivs{$tool}},$priv);
                 }
             }
@@ -1987,13 +2552,13 @@ sub display_defprivs {
 
 
 sub change_members_form {
-    my ($r,$cdom,$cnum,$tabcol,$action,$formname,$page,$groupname,$description,
+    my ($r,$cdom,$cnum,$action,$formname,$page,$groupname,$description,
         $startdate,$enddate,$tools,$fixedprivs,$functions,$users,$userdata,
-        $granularity,$specificity,$idx,$states,$navbuttons,$rowColor1,
-        $rowColor2) = @_;
+        $granularity,$quota,$specificity,$idx,$states,$navbuttons,$gpterm,
+	$ucgpterm) = @_;
     my %lt = &Apache::lonlocal::texthash(
-                                         grse => 'Group settings',
-                                         mogm => 'Modify group membership',
+                                         grse => "$ucgpterm settings",
+                                         mogm => "Modify $gpterm membership",
                                         );
     my @regexps = ('user_','userpriv_');
     $r->print(&Apache::lonhtmlcommon::echo_form_input(
@@ -2008,44 +2573,34 @@ sub change_members_form {
     my $prevtext = $$navbuttons{'gtpp'};
     $r->print('
 <br />
-<table width="100%" cellpadding="0" cellspacing="0" border="0">
-');
-    &topic_bar($r,$tabcol,1,$lt{'grse'});
-    $r->print('
- <tr>
-  <td>&nbsp;</td>
-  <td colspan="3">
-');
-    &print_current_settings($r,$action,$tabcol,$rowColor1,$rowColor2,
-                            $functions,$startdate,$enddate,$groupname,
-                          $description,$granularity,\@available,\@unavailable);
-$r->print('
-</td></tr><tr><td colspan="4">&nbsp;</td></tr>');
-    &topic_bar($r,$tabcol,2,$lt{'mogm'});
-    $r->print('
- <tr>
-  <td>&nbsp;</td>
-  <td colspan="3">
 ');
-    &current_membership($r,$cdom,$cnum,$formname,$tabcol,$rowColor1,
-                        $rowColor2,$groupname,\@available,\@unavailable,
-                        $fixedprivs,$granularity,$specificity);
-    $r->print('</td>');
-    &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,
-                        $$states{$action}[$page+1],$nexttext);
-    $r->print('</table>');
+    $r->print(&Apache::lonhtmlcommon::topic_bar(1,$lt{'grse'}));
+    &print_current_settings($r,$action,$functions,$startdate,$enddate,
+			    $groupname,$description,$granularity,$quota,
+			    \@available,\@unavailable,$gpterm,$ucgpterm);
+    $r->print(&Apache::lonhtmlcommon::topic_bar(2,$lt{'mogm'}));
+    my $numcurrent = &current_membership($r,$cdom,$cnum,$formname,$groupname,
+                                         \@available,\@unavailable,$fixedprivs,
+			                 $granularity,$specificity);
+    if ($numcurrent > 0) {
+        &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,
+                            $$states{$action}[$page+1],$nexttext);
+    } else {
+        &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext);
+    }
     return;
 }
 
 sub current_membership {
-    my ($r,$cdom,$cnum,$formname,$tabcol,$rowColor1,$rowColor2,$groupname,
-        $available,$unavailable,$fixedprivs,$granularity,$specificity) = @_;
+    my ($r,$cdom,$cnum,$formname,$groupname,$available,$unavailable,
+	$fixedprivs,$granularity,$specificity) = @_;
     my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum,
                                                                    $groupname);
     my %lt = &Apache::lonlocal::texthash(
                                           'actn' => 'Action?',
                                           'name' => 'Name',
                                           'usnm' => 'Username',
+                                          'stid' => 'ID',
                                           'doma' => 'Domain',
                                           'stda' => 'Start Date',
                                           'enda' => 'End Date',
@@ -2053,319 +2608,222 @@ sub current_membership {
                                           'reen' => 'Re-enable',
                                           'acti' => 'Activate',
                                           'dele' => 'Delete',
-                                          'curf' => 'Current Functionality',
+                                          'curf' => 'Current Tool Set',
                                           'chpr' => 'Change Privileges' 
                                         );
-    if (keys(%membership) > 0) {
-        my %current = ();
-        my %allnames = ();
-        my $hastools = 0;
-        my $addtools = 0;
-        my $num_reenable = 0;
-        my $num_activate = 0;
-        my $num_expire - 0;
-        foreach my $key (sort(keys(%membership))) {
-            if ($key =~ /^\Q$groupname\E:([^:]+):([^:]+)$/) {
-                my $uname = $1;
-                my $udom = $2;
-                my $user = $uname.':'.$udom;
-                my($end,$start,@userprivs) = split(/:/,$membership{$key});
-                unless ($start == -1) {
-                    $allnames{$udom}{$uname} = 1;
-                    %{$current{$user}} = ();
-                    $current{$user}{uname} = $uname;
-                    $current{$user}{udom} = $udom;
-                    $current{$user}{start} = 
-                                     &Apache::lonlocal::locallocaltime($start);
-                    if ($end == 0) {
-                        $current{$user}{end} =  'No end date';
-                    } else {
-                        $current{$user}{end} = 
-                                     &Apache::lonlocal::locallocaltime($end);
-                    }
-                    my $now = time;
-                    if (($end > 0) && ($end < $now)) {
-                        $current{$user}{changestate} = 'reenable';
-                        $num_reenable++;
-                    } elsif (($start > $now)) {
-                        $current{$user}{changestate} = 'activate';
-                        $num_activate ++;
-                    } else {
-                        $current{$user}{changestate} = 'expire';
-                        $num_expire ++;
-                    }
-                    @{$current{$user}{currtools}} = ();
-                    @{$current{$user}{newtools}} = ();
-                    if (@userprivs > 0) {
-                        foreach my $tool (sort(keys(%{$fixedprivs}))) {
-                            foreach my $priv (keys(%{$$fixedprivs{$tool}})) {
-                                if (grep/^$priv$/,@userprivs) {
-                                    push(@{$current{$user}{currtools}},$tool);
-                                    last;
-                                }
-                            }
-                        }
-                        $hastools = 1;
-                    }
-                    if (@{$available} > 0) {
-                        if (@{$current{$user}{currtools}} > 0) {
-                            if ("@{$available}" ne "@{$current{$user}{currtools}}") {
-                                foreach my $tool (@{$available}) {
-                                    unless (grep/^$tool$/,@{$current{$user}{currtools}}) {
-                                        push(@{$current{$user}{newtools}},$tool);
-                                    }
-                                }
-                            }
-                        } else {
-                            @{$current{$user}{newtools}} = @{$available};
-                        }
-                        if (@{$current{$user}{newtools}} > 0) {
-                            $addtools = 1;
-                        }
-                    }
-                }
-            }
-        }
-        if (keys(%current) > 0) {
-            my %idhash;
-            foreach my $udom (keys(%allnames)) {
-                %{$idhash{$udom}} = &Apache::lonnet::idrget($udom,
-                                                keys(%{$allnames{$udom}}));
-                foreach my $uname (keys(%{$idhash{$udom}})) {
-                    $current{$uname.':'.$udom}{'id'} = $idhash{$udom}{$uname};
-                }
-                foreach my $uname (keys(%{$allnames{$udom}})) {
-                    $current{$uname.':'.$udom}{'fullname'} =
-                                &Apache::loncommon::plainname($uname,$udom,
-                                                                  'lastname');
-                }
-            }
-            $r->print('
- <tr>
-  <td>&nbsp;</td>
-  <td colspan="2">
+    my ($current,$num_items,$hastools,$addtools) =
+        &Apache::longroup::group_memberlist($cdom,$cnum,$groupname,$fixedprivs,
+                                            $available);
+    my $numcurrent = scalar(keys(%{$current}));
+    if ($numcurrent > 0) {
+        $r->print('
    <table>
     <tr>');
-            if ($num_expire) {
-                &check_uncheck_buttons($r,$formname,'expire',$lt{'expi'});
-            }
-            if ($num_reenable) {
-                &check_uncheck_buttons($r,$formname,'reenable',$lt{'reen'});
-            }
-            if ($num_activate) {
-                &check_uncheck_buttons($r,$formname,'activate',$lt{'acti'});
+        if ($num_items->{'active'}) {
+            &check_uncheck_buttons($r,$formname,'expire',$lt{'expi'});
+        }
+        if ($num_items->{'previous'}) {
+            &check_uncheck_buttons($r,$formname,'reenable',$lt{'reen'});
+        }
+        if ($num_items->{'future'}) {
+            &check_uncheck_buttons($r,$formname,'activate',$lt{'acti'});
+        }
+        &check_uncheck_buttons($r,$formname,'deletion',$lt{'dele'});
+        if (@{$available} > 0) {
+            if ($specificity eq 'Yes') {
+                &check_uncheck_buttons($r,$formname,'changepriv',$lt{'chpr'});
             }
-            &check_uncheck_buttons($r,$formname,'deletion',$lt{'dele'});
-            if (@{$available} > 0) {
-                if ($specificity eq 'Yes') {
-                    &check_uncheck_buttons($r,$formname,'changepriv',$lt{'chpr'});
-                }
-                if ($granularity eq 'Yes') {
-                    $r->print(&check_uncheck_tools($r,$available));
-                    $r->print('
+            if ($granularity eq 'Yes') {
+                $r->print(&check_uncheck_tools($r,$available));
+                $r->print('
      <td>
-      <nobr>
-       <fieldset><legend><b>'.$lt{'curf'}.'</b></legend>
-       <input type="button" value="check all"
+      <span class="LC_nobreak">
+       <fieldset><legend>'.$lt{'curf'}.'</legend>
+       <input type="button" value="'.&mt('check all').'"
        onclick="javascript:checkAllTools(document.'.$formname.')" />
        &nbsp;&nbsp;
-       <input type="button" value="uncheck all"
+       <input type="button" value="'.&mt('uncheck all').'"
         onclick="javascript:uncheckAllTools(document.'.$formname.')" />
       </fieldset>
-     </nobr>
+     </span>
     </td>
 ');
-                }
             }
-            $r->print(<<"END");
+        }
+        $r->print(<<"END");
    </tr>
   </table>
-  </td>
-  <td width="100%">&nbsp;</td>
- </tr>
- <tr>
-  <td colspan="4">&nbsp;</td>
- </tr>
- <tr>
-  <td>&nbsp;</td>
-  <td colspan="3">
+  <br />
 END
-            $r->print(&Apache::lonhtmlcommon::start_pick_box());
-            $r->print(<<"END");
-   <table border="0" cellpadding="4" cellspacing="1">
-    <tr bgcolor="$tabcol" align="center">
-     <td><b>$lt{'actn'}</b></td>
-     <td><b><a href="javascript:changeSort('fullname')">$lt{'name'}</a></b></td>
-     <td><b><a href="javascript:changeSort('username')">$lt{'usnm'}</a></b>
-     </td>
-     <td><b><a href="javascript:changeSort('domain')">$lt{'doma'}</a></b></td>
-     <td><b><a href="javascript:changeSort('id')">ID</a></b></td>
-     <td><b><a href="javascript:changeSort('start')">$lt{'stda'}</a></b></td>
-     <td><b><a href="javascript:changeSort('end')">$lt{'enda'}</a></b></td>
+        $r->print(&Apache::loncommon::start_data_table().
+		  &Apache::loncommon::start_data_table_header_row());
+        $r->print(<<"END");
+     <th>$lt{'actn'}</th>
+     <th><a href="javascript:changeSort('fullname')">$lt{'name'}</a></th>
+     <th><a href="javascript:changeSort('username')">$lt{'usnm'}</a></th>
+     <th><a href="javascript:changeSort('domain')">$lt{'doma'}</a></th>
+     <th><a href="javascript:changeSort('id')">$lt{'ID'}</a></th>
+     <th><a href="javascript:changeSort('start')">$lt{'stda'}</a></th>
+     <th><a href="javascript:changeSort('end')">$lt{'enda'}</a></th>
 END
-            my $colspan = 0;
-            if ($hastools) {
-                $r->print('<td><b>'.$lt{'curf'}.'</b></td>');
-                $colspan ++;  
-            }
-            if ($addtools) {
-                $r->print('<td><b>Additional Functionality</b></td>');
-                $colspan ++;
-            }
-            $r->print('</tr>');
-            if ($colspan) {
-                if ($granularity eq 'Yes') {
-                    $r->print('<tr bgcolor="#cccccc">
+        my $colspan = 0;
+        if ($hastools) {
+            $r->print('<th>'.$lt{'curf'}.'</th>');
+            $colspan++;  
+        }
+        if ($addtools) {
+            $r->print('<th>'.&mt('Additional Tools').'</th>');
+            $colspan++;
+        }
+        $r->print(&Apache::loncommon::end_data_table_header_row());
+        if ($colspan) {
+            if ($granularity eq 'Yes') {
+                $r->print(&Apache::loncommon::start_data_table_row('LC_data_table_dense LC_data_table_highlight').'
  <td colspan="7">&nbsp;</td>
- <td colspan="'.$colspan.'" align="center"><small><nobr><b>'.&mt('All:').
+ <td colspan="'.$colspan.'" align="center"><span class="LC_nobreak"><b>'.&mt('All:').
   '</b>&nbsp;');
-                    foreach my $tool (@{$available}) {
-                        $r->print('<label><input type="checkbox" name="togglefunc"'.
+                foreach my $tool (@{$available}) {
+                    $r->print('<label><input type="checkbox" name="togglefunc"'.
    ' onclick="javascript:toggleTools(document.'.$formname.'.user_'.$tool.',this);"'.
-   ' value="'.$tool.'">'.'<b>'.$tool.'</b></label>&nbsp;&nbsp;&nbsp;');
-                    }
-                    $r->print('</nobr></small></td></tr>');
+   ' value="'.$tool.'" />'.'<b>'.$tool.'</b></label>&nbsp;&nbsp;&nbsp;');
                 }
+                $r->print('</span></td></tr>');
             }
-            my %Sortby = ();
-            foreach my $user (sort(keys(%current))) {
-                if ($env{'form.sortby'} eq 'fullname') {
-                    push(@{$Sortby{$current{$user}{fullname}}},$user);
-                } elsif ($env{'form.sortby'} eq 'username') {
-                    push(@{$Sortby{$current{$user}{uname}}},$user);
-                } elsif ($env{'form.sortby'} eq 'domain') {
-                    push(@{$Sortby{$current{$user}{udom}}},$user);
-                } elsif ($env{'form.sortby'} eq 'id') {
-                    push(@{$Sortby{$current{$user}{id}}},$user);
-                } else {
-                    push(@{$Sortby{$current{$user}{fullname}}},$user);
-                }
+        }
+        my %Sortby = ();
+        foreach my $user (sort(keys(%{$current}))) {
+            if ($env{'form.sortby'} eq 'fullname') {
+                push(@{$Sortby{$$current{$user}{fullname}}},$user);
+            } elsif ($env{'form.sortby'} eq 'username') {
+                push(@{$Sortby{$$current{$user}{uname}}},$user);
+            } elsif ($env{'form.sortby'} eq 'domain') {
+                push(@{$Sortby{$$current{$user}{udom}}},$user);
+            } elsif ($env{'form.sortby'} eq 'id') {
+                push(@{$Sortby{$$current{$user}{id}}},$user);
+            } else {
+                push(@{$Sortby{$$current{$user}{fullname}}},$user);
             }
-            my $rowNum = 0;
-            my $rowColor;
-            foreach my $key (sort(keys(%Sortby))) {
-                foreach my $user (@{$Sortby{$key}}) {
-                    if ($rowNum %2 == 1) {
-                        $rowColor = $rowColor1;
-                    } else {
-                        $rowColor = $rowColor2;
-                    }
-                    my $id = $current{$user}{id};
-                    my $fullname = $current{$user}{fullname};
-                    my $udom = $current{$user}{udom};
-                    my $uname = $current{$user}{uname};
-                    my $start = $current{$user}{start};
-                    my $end = $current{$user}{end};
-                    $r->print('<tr bgcolor="'.$rowColor.'">
-                                <td><small>');
-                    if ($current{$user}{changestate} eq 'reenable') {
-                        $r->print('<nobr><label>'. 
+        }
+        foreach my $key (sort(keys(%Sortby))) {
+            foreach my $user (@{$Sortby{$key}}) {
+                my $id = $$current{$user}{id};
+                my $fullname = $$current{$user}{fullname};
+                my $udom = $$current{$user}{udom};
+                my $uname = $$current{$user}{uname};
+                my $start = $$current{$user}{start};
+                my $end = $$current{$user}{end};
+                $r->print(&Apache::loncommon::start_data_table_row('LC_data_table_dense').'
+                            <td>');
+                if ($$current{$user}{changestate} eq 'reenable') {
+                    $r->print('<span class="LC_nobreak"><label>'. 
    '<input type="checkbox" name="reenable" value="'.$user.'" />'.
-   $lt{'reen'}.'</label></nobr><br />');
-                    } elsif ($current{$user}{changestate} eq 'expire') {
-                        $r->print('<nobr><label>'.
+   $lt{'reen'}.'</label></span><br />');
+                } elsif ($$current{$user}{changestate} eq 'expire') {
+                    $r->print('<span class="LC_nobreak"><label>'.
    '<input type="checkbox" name="expire" value="'.$user.'" />'.
-   $lt{'expi'}.'</label></nobr><br />');
-                    } elsif ($current{$user}{changestate} eq 'activate') {
-                        $r->print('<nobr><label>'.
+   $lt{'expi'}.'</label></span><br />');
+                } elsif ($$current{$user}{changestate} eq 'activate') {
+                    $r->print('<span class="LC_nobreak"><label>'.
    '<input type="checkbox" name="activate" value="'.$user.'" />'.
-   $lt{'acti'}.'</label></nobr><br />');
-                    }
-                    $r->print('<nobr><label>'.
+   $lt{'acti'}.'</label></span><br />');
+                }
+                $r->print('<span class="LC_nobreak"><label>'.
    '<input type="checkbox" name="deletion" value="'.$user.'" />'.
-   $lt{'dele'}.'</label></nobr>');
-                    if ($specificity eq 'Yes') {
-                        $r->print('<br /><nobr><label>'.
+   $lt{'dele'}.'</label></span>');
+                if ($specificity eq 'Yes') {
+                    $r->print('<br /><span class="LC_nobreak"><label>'.
    '<input type="checkbox" name="changepriv" value="'.$user.'" />'.$lt{'chpr'}.
-   '</label></nobr>');
-                    }
-                    $r->print('
-   </td>
-   <td><small>'.
-    $fullname.'</small></td><td><small>'.$uname.'</small></td><td><small>'.
-    $udom.'</small></td><td><small>'.$id.'</small></td><td><small>'.$start.
-    '</small></td><td><small>'.$end.'</small></td>');
-                    if ($hastools) {
-                        $r->print('<td align="left"><small><nobr>'.
+   '</label></span>');
+                }
+                $r->print('
+   </td>'.
+   '<td>'.$fullname.'</td>'.
+   '<td>'.$uname.'</td>'.
+   '<td>'. $udom.'</td>'.
+   '<td>'.$id.'</td>'.
+   '<td>'.$start.'</td>'.
+   '<td>'.$end.'</td>');
+                if ($hastools) {
+                    $r->print('<td align="left"><span class="LC_nobreak">'.
                                   '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');
-                        foreach my $tool (@{$current{$user}{currtools}}) {
-                            if ($granularity eq 'Yes') {
-                                $r->print('<label><input type="checkbox" '. 
+                    foreach my $tool (@{$$current{$user}{currtools}}) {
+                        if ($granularity eq 'Yes') {
+                            $r->print('<label><input type="checkbox" '. 
                                        'checked="checked" '. 
                                        'name="user_'.$tool.'" value="'.
                                        $user.'" />'.$tool.'</label>');
-                             } else {
-                               $r->print('<input type="hidden" '.
+                         } else {
+                             $r->print('<input type="hidden" '.
                                        'checked="checked" '.
                                        'name="user_'.$tool.'" value="'.
                                        $user.'" />'.$tool);
-                             }
-                             $r->print('&nbsp;&nbsp;&nbsp;');
-                        }
-                        $r->print('</nobr></small></td>');
+                         }
+                         $r->print('&nbsp;&nbsp;&nbsp;');
                     }
-                    if ($addtools) {
-                        $r->print('<td align="left"><small>');
-                        if ($granularity eq 'Yes') {
-                            foreach my $tool (@{$current{$user}{newtools}}) {
-                                $r->print('<nobr><label><input type="checkbox"  
+                    $r->print('</span></td>');
+                }
+                if ($addtools) {
+                    $r->print('<td align="left">');
+                    if ($granularity eq 'Yes') {
+                        foreach my $tool (@{$$current{$user}{newtools}}) {
+                            $r->print('<span class="LC_nobreak"><label><input type="checkbox"
                                           name="user_'.$tool.'" value="'.
                                           $user.'" />'.$tool.
-                                          '</label></nobr>&nbsp;&nbsp;&nbsp;');
-                            }
-                        } else {
-                            foreach my $tool (@{$current{$user}{newtools}}) {
-                                $r->print('<nobr><input type="hidden" 
+                                          '</label></span>&nbsp;&nbsp;&nbsp;');
+                        }
+                    } else {
+                        foreach my $tool (@{$$current{$user}{newtools}}) {
+                            $r->print('<span class="LC_nobreak"><input type="hidden" 
                                           name="user_'. $tool.'" value="'.
                                           $user.'" />'.$tool.
-                                          '</nobr>&nbsp;&nbsp;&nbsp;');
-                            }
+                                          '</span>&nbsp;&nbsp;&nbsp;');
                         }
-                        $r->print('</small></td>');
                     }
-                    $r->print('</tr>'."\n");
-                    $rowNum ++;
+                    $r->print('</td>');
                 }
+                $r->print(&Apache::loncommon::end_data_table_row()."\n");
             }
-            $r->print(&Apache::lonhtmlcommon::end_pick_box());
-            $r->print('
-  </td>
- </tr>');
         }
+        $r->print(&Apache::loncommon::end_data_table());
+    } else {
+        $r->print(
+            '<p class="LC_info">'
+           .&mt('There are no active, future or previous group members to modify.')
+           .'</p>');
     }
-    return;
+    return $numcurrent;
 }
 
 sub check_uncheck_buttons {
     my ($r,$formname,$field,$title,$colspan) = @_;
     $r->print('
      <td '.$colspan.'>
-      <nobr>
        <fieldset>
-       <legend><b>'.$title.'</b></legend>
-       <input type="button" value="check all"
+       <legend>'.$title.'</legend>
+      <span class="LC_nobreak">
+       <input type="button" value="'.&mt('check all').'"
        onclick="javascript:checkAll(document.'.$formname.'.'.$field.')" />
        &nbsp;&nbsp;
-       <input type="button" value="uncheck all"
+       <input type="button" value="'.&mt('uncheck all').'"
        onclick="javascript:uncheckAll(document.'.$formname.'.'.$field.')" />
+      </span>
        </fieldset>
-      </nobr>
      </td>
 ');
 }
 
 
 sub change_privs_form {
-    my ($r,$cdom,$cnum,$tabcol,$action,$formname,$page,$startdate,$enddate,
-       $tools,$functions,$toolprivs,$fixedprivs,$userdata,$usertools,
-       $memchg,$idx,$states,$stored,$sectioncount,$navbuttons,$rowColor1,
-       $rowColor2) = @_;
+    my ($r,$cdom,$cnum,$action,$formname,$page,$startdate,$enddate,
+	$tools,$functions,$toolprivs,$fixedprivs,$userdata,$usertools,
+	$memchg,$idx,$states,$stored,$sectioncount,$navbuttons,$gpterm,
+	$ucgpterm) = @_;
     my @regexps = ('userpriv_');
     my $nexttext;
     my %lt = &Apache::lonlocal::texthash(
                'tode' => 'To be deleted',
                'toex' => 'To be expired',
-               'nome' => 'No members to be deleted or expired from the group.',
+               'nome' => "No members to be deleted or expired from the $gpterm.",
     );
     $r->print(&Apache::lonhtmlcommon::echo_form_input(
          ['origin','action','state','page','sortby'],\@regexps));
@@ -2374,43 +2832,40 @@ sub change_privs_form {
     } else {
         $nexttext = $$navbuttons{'mose'};
     }
-    $r->print('<br /><table width="100%" cellpadding="0" cellspacing="0" border="0">');
-    &topic_bar($r,$tabcol,3,&mt('Members to delete or expire'));
+    $r->print(&Apache::lonhtmlcommon::topic_bar(3,&mt('Members to delete or expire')));
     my $exp_or_del = 0;
     if (ref($$memchg{'deletion'}) eq 'ARRAY') {
         if (@{$$memchg{'deletion'}} > 0) {
-            $r->print('<tr><td>&nbsp;</td><td colspan="3"><b>'.$lt{'tode'}.':</b><br /><ul>');
+            $r->print('<b>'.$lt{'tode'}.':</b><br /><ul>');
             foreach my $user (@{$$memchg{'deletion'}}) {
                 $r->print('<li>'.$$userdata{$user}[$$idx{fullname}].
                           '&nbsp;('.$user.')</li>');
             }
-            $r->print('</ul></td><tr><td colspan="4">&nbsp;</td></tr>');
+            $r->print('</ul>');
             $exp_or_del += @{$$memchg{'deletion'}};
         }
     }
     if (ref($$memchg{'expire'}) eq 'ARRAY') {
         if (@{$$memchg{'expire'}} > 0) {
-            $r->print('<tr><td>&nbsp;</td><td colspan="3"><b>'.$lt{'toex'}.':</b><br /><ul>');
+            $r->print('<b>'.$lt{'toex'}.':</b><br /><ul>');
             foreach my $user (@{$$memchg{'expire'}}) {
                 $r->print('<li>'.$$userdata{$user}[$$idx{fullname}].
                           '&nbsp;('.$user.')</li>');
             }
-            $r->print('</ul></td><tr><td colspan="4">&nbsp;</td></tr>');
+            $r->print('</ul>');
             $exp_or_del += @{$$memchg{'expire'}};
         }
     }
     if (!$exp_or_del) {
-        $r->print('<tr><td>&nbsp;</td><td colspan="3">'.$lt{'nome'}.
-                  '</td></tr><tr><td colspan="4">&nbsp;</td></tr>');
+        $r->print('<p class="LC_info">'.$lt{'nome'}.'</p>');
     }
     
-    &topic_bar($r,$tabcol,4,&mt('Group member privileges'));
+    $r->print(&Apache::lonhtmlcommon::topic_bar(4,&mt('Setting optional privileges for specific group members')));
 
-    my $numchgs = &member_privileges_form($r,$tabcol,$action,$formname,$tools,
+    my $numchgs = &member_privileges_form($r,$action,$formname,$tools,
                                           $toolprivs,$fixedprivs,$userdata,
                                           $usertools,$idx,$memchg,$states,
-                                          $stored,$rowColor1,$rowColor2);
-    $r->print('</td></tr><tr><td colspan="4">&nbsp;</td></tr>');
+                                          $stored,$gpterm);
     my $prevtext = $$navbuttons{'gtps'};
     if ($numchgs || $exp_or_del) {
         &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,
@@ -2418,47 +2873,34 @@ sub change_privs_form {
     } else {
         &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext);
     }
-    $r->print('</table>');
     return;
 }
 
 sub add_members_form {
-    my ($r,$tabcol,$action,$formname,$page,$startdate,$enddate,$groupname,
-        $description,$granularity,$sectioncount,$tools,$functions,$stored,
-        $states,$navbuttons,$rowColor1,$rowColor2) = @_; 
-    $r->print(' <br />
-<table width="100%" cellpadding="0" cellspacing="0" border="0">
- <tr>
-  <td>&nbsp;</td>
-  <td colspan="3">
-');
+    my ($r,$cdom,$cnum,$action,$formname,$page,$startdate,$enddate,$groupname,
+        $description,$granularity,$quota,$sectioncount,$tools,$functions,
+        $stored,$states,$navbuttons,$gpterm,$ucgpterm,$crstype)=@_;
+    $r->print(' <br />');
     my @available = ();
     my @unavailable = ();
     &check_tools($functions,$tools,\@available,\@unavailable);
-    &print_current_settings($r,$action,$tabcol,$rowColor1,$rowColor2,
-                            $functions,$startdate,$enddate,$groupname,
-                            $description,$granularity,\@available,\@unavailable);
-    $r->print('
-   </td>
-  </tr>
-  <tr>
-   <td colspan="4">&nbsp;</td>
-  </tr>');
-
-    &membership_options($r,$action,$formname,$tabcol,$sectioncount,1);
+    &print_current_settings($r,$action,$functions,$startdate,$enddate,
+			    $groupname,$description,$granularity,$quota,
+			    \@available,\@unavailable,$gpterm,$ucgpterm);
+    &membership_options($r,$cdom,$cnum,$action,$formname,$sectioncount,1,$gpterm,
+                        $ucgpterm,$crstype);
     my $nexttext = $$navbuttons{'gtns'};
     my $prevtext = $$navbuttons{'gtpp'};
     &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,
                         $$states{$action}[$page+1],$nexttext);
-    $r->print('
- </table>');
     return;
 }
 
 sub choose_privs_form {
-    my ($r,$cdom,$cnum,$tabcol,$action,$formname,$page,$startdate,$enddate,
-       $tools,$functions,$toolprivs,$fixedprivs,$userdata,$usertools,$idx,
-       $states,$stored,$sectioncount,$navbuttons,$rowColor1,$rowColor2) = @_;
+    my ($r,$cdom,$cnum,$action,$formname,$page,$startdate,$enddate,
+	$tools,$functions,$toolprivs,$fixedprivs,$userdata,$usertools,$idx,
+	$states,$stored,$sectioncount,$navbuttons,$gpterm,$ucgpterm,
+	$crstype) = @_;
 
     my @regexps = ('userpriv_');
     my $nexttext;
@@ -2475,27 +2917,22 @@ sub choose_privs_form {
         $nexttext = $$navbuttons{'adme'};
     }
 
-    $r->print('<br /><table width="100%" cellpadding="0" cellspacing="0" border="0">');
-    &topic_bar($r,$tabcol,6,&mt('Group member privileges'));
+    $r->print(&Apache::lonhtmlcommon::topic_bar(6,&mt('Setting optional privileges for specific group members')));
 
-    &member_privileges_form($r,$tabcol,$action,$formname,$tools,$toolprivs,
+    &member_privileges_form($r,$action,$formname,$tools,$toolprivs,
                             $fixedprivs,$userdata,$usertools,$idx,undef,
-                            $states,$stored,$rowColor1,$rowColor2);
+                            $states,$stored,$gpterm);
 
-    $r->print('</td></tr><tr><td colspan="4">&nbsp;</td></tr>');
     if ($action eq 'create') {
-        if (keys(%{$sectioncount}) > 0) {
-            my $img1 = 7;
-            my $img2 = 8;
-            &mapping_options($r,$action,$formname,$page,$tabcol,$sectioncount,
-                             $states,$stored,$navbuttons,$img1,$img2,
-                             $rowColor1,$rowColor2);
-        }
+        my $img1 = 7;
+        my $img2 = 8;
+        &mapping_options($r,$action,$formname,$page,$sectioncount,
+                         $states,$stored,$navbuttons,$img1,$img2,
+                         $gpterm,$ucgpterm,$crstype,$cdom,$cnum);
     }
     my $prevtext = $$navbuttons{'gtps'};
     &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,
                         $$states{$action}[$page+1],$nexttext);
-    $r->print('</table>');
     return;
 }
 
@@ -2558,17 +2995,21 @@ function uncheckAllTools(formname) {
 }
 
 sub member_privileges_form {
-    my ($r,$tabcol,$action,$formname,$tools,$toolprivs,$fixedprivs,$userdata,
-        $usertools,$idx,$memchg,$states,$stored,$rowColor1,$rowColor2) = @_;
+    my ($r,$action,$formname,$tools,$toolprivs,$fixedprivs,$userdata,
+        $usertools,$idx,$memchg,$states,$stored,$gpterm) = @_;
     my %lt = &Apache::lonlocal::texthash(
             'addp' => 'Additional privileges',
-            'fixp' => 'Fixed privileges',
+            'fixp' => 'Core privileges',
             'oppr' => 'Optional privileges',
-            'func' => 'Function',
-            'forf' => 'For the functionality you have chosen to include '.
-                      'there are no optional privileges to set besides '.
-                      'the standard privileges.',
-            'algr' => 'All group members will receive the same privileges.',
+            'func' => 'Tool',
+            'forf' => 'For the collaborative tools included for group '.
+                      'members being added or modified, '. 
+                      'there are no optional privileges to set '.
+                      'for specific members.',
+            'algr' => 'All new group members will receive the same privileges.',
+            'ifex' => 'If previously expired members are being re-enabled, or '.
+                      'if access for future members is being activated now, '.
+                      'previously set privileges will be preserved.',
             'asno' => 'As no group members are being added, '.
                       'there are no specific user privileges to set.',
             'asng' => 'As no group tools will be made available to users, '.
@@ -2576,7 +3017,7 @@ sub member_privileges_form {
             'nogm' => 'No group member privileges to display or set, '.
                       'as you have not indicated that you will be activating,'.
                       ' re-enabling, changing privileges, or adding/removing '.
-                      'functionality for any current members ',
+                      'tools for any current members.',
             'full' => 'Fullname',
             'user' => 'Username',
             'doma' => 'Domain',
@@ -2589,7 +3030,9 @@ sub member_privileges_form {
         }
         $specificity = $env{'form.specificity'};
     } else {
-        @defprivs = @{$$stored{'defpriv'}};
+        if (defined($$stored{'defpriv'})) {
+            @defprivs = @{$$stored{'defpriv'}};
+        }
         $specificity = $$stored{'specificity'};
     }
     my @showtools;
@@ -2618,7 +3061,7 @@ sub member_privileges_form {
         }
         $numchgs = @currmembers;
         if (!$numchgs) {
-            $r->print('<tr><td>&nbsp;</td><td colspan="3">'.$lt{'nogm'}); 
+            $r->print($lt{'nogm'}); 
             return $numchgs;
         }
     }
@@ -2634,18 +3077,14 @@ sub member_privileges_form {
                 my %total;
                 if (keys(%{$usertools}) > 1) {
                     $r->print('
- <tr>
-  <td>&nbsp;</td>
-  <td colspan="3">
-   <table border="0" cellspacing="2" cellpadding="2" border="0">
+   <table border="0" cellspacing="2" cellpadding="2">
     <tr>
 ');
                     foreach my $tool (@{$tools}) {
                         if (@{$showboxes{$tool}} > 0) {
                             $r->print('<td valign="top">');
-                            $r->print('<table class="thinborder"><tr bgcolor="'.
-                                      $tabcol.'"><th colspan="'.$colspan.'">'.
-                                      $tool.'</th></tr><tr>');
+                            $r->print('<fieldset><legend>'.&mt($tool).'</legend>');
+                            $r->print('<table><tr>');
                             my $privcount = 0;
                             foreach my $priv (@{$showboxes{$tool}}) {
                                 $privcount ++;
@@ -2659,15 +3098,16 @@ sub member_privileges_form {
                                 } else {
                                     $r->print('<td>');
                                 }
-                                $r->print(qq|
-       <fieldset><legend><b>$$toolprivs{$tool}{$priv}</b></legend>
-       <nobr>
-       <input type="button" value="check all"
-         onclick="javascript:checkAll(document.$formname.userpriv_$priv)" />
-       &nbsp;
-       <input type="button" value="uncheck all"
-        onclick="javascript:uncheckAll(document.$formname.userpriv_$priv)" />
-      </nobr></fieldset><br />|);
+                                $r->print(
+ '<fieldset><legend>'.&mt($$toolprivs{$tool}{$priv}).'</legend>'
+.'<span class="LC_nobreak">'
+.' <input type="button" value="'.&mt('check all').'"'
+.' onclick="javascript:checkAll(document.'.$formname.'.userpriv_'.$priv.')" />'
+.'&nbsp;'
+.'<input type="button" value="'.&mt('uncheck all').'"'
+.' onclick="javascript:uncheckAll(document.'.$formname.'.userpriv_'.$priv.')" />'
+.'</span></fieldset><br />'
+                                );
                                 $r->print('</td>');
                                 if ($privcount < @{$showboxes{$tool}}) {
                                     if (@{$showboxes{$tool}} > 2) {
@@ -2679,67 +3119,53 @@ sub member_privileges_form {
                                     }
                                 }
                             }
-                            $r->print('</tr></table></td><td>&nbsp;</td>');
+                            $r->print('</tr></table></fieldset></td><td>&nbsp;</td>');
                         }
                     }
-                    $r->print('</tr></table></td></tr>');
-                    $r->print('<tr><td colspan="4">&nbsp;</td></tr>');
+                    $r->print('</tr></table>');
                 }
-                $r->print('<tr><td>&nbsp;</td><td colspan="3">');
-                $r->print(&Apache::lonhtmlcommon::start_pick_box());
+                $r->print(&Apache::loncommon::start_data_table().
+			  &Apache::loncommon::start_data_table_header_row());
                 $r->print(<<"END");
-   <tr bgcolor="$tabcol">
-    <th><b>$lt{'full'}</th>
-    <th><b>$lt{'user'}</th>
+    <th>$lt{'full'}</th>
+    <th>$lt{'user'}</th>
     <th>$lt{'doma'}</th>
     <th colspan="$numtools">$lt{'addp'}</th>
-  </tr>
 END
-                &member_privs_entries($r,$tabcol,$rowColor1,$rowColor2,
-                                      $usertools,$toolprivs,$fixedprivs,
+                $r->print(&Apache::loncommon::end_data_table_header_row());
+                &member_privs_entries($r,$usertools,$toolprivs,$fixedprivs,
                                       $userdata,$idx,\@showtools,\@defprivs,
                                       \@excluded);
-                $r->print('</td>');
-                $r->print(&Apache::lonhtmlcommon::end_pick_box());
-                $r->print('</td></tr>
- <tr>
-  <td colspan="4">&nbsp;</td>
- </tr>
-');
+                $r->print(&Apache::loncommon::end_data_table());
             } else {
-                $r->print('<tr><td>&nbsp;</td><td colspan="3">'.$lt{'forf'}.
-                          '<br />');
-                &display_defprivs($r,$tabcol,$rowColor1,$rowColor2,$tools,
-                            $toolprivs,\@defprivs);
-                                                                                      
+                $r->print($lt{'forf'}.'<br />');
+                &display_defprivs($r,$tools,$toolprivs,\@defprivs);
             }
         } else {
             if (keys(%{$usertools}) > 0) {
-                $r->print('<tr><td>&nbsp;</td><td colspan="3">'.$lt{'algr'}.
-                          '<br /><br />');
-                &display_defprivs($r,$tabcol,$rowColor1,$rowColor2,$tools,
-                            $toolprivs,\@defprivs);
+                $r->print($lt{'algr'}.'<br />'.$lt{'ifex'}.'<br /><br />');
+                &display_defprivs($r,$tools,$toolprivs,\@defprivs);
             } else {
-                $r->print('<tr><td>&nbsp;</td><td colspan="3">'.$lt{'asno'}.
-                          '<br />');
+                $r->print($lt{'asno'}.'<br />');
             }
         }
     } else {
-        $r->print('<tr><td>&nbsp;</td><td colspan="3">'.$lt{'asng'});
+        $r->print($lt{'asng'});
     }
     return $numchgs;
 }
 
 sub process_request {
-    my ($r,$cdom,$cnum,$tabcol,$action,$state,$page,$groupname,$description,
+    my ($r,$cdom,$cnum,$action,$state,$page,$groupname,$description,
         $specificity,$userdata,$startdate,$enddate,$tools,$functions,$toolprivs,
         $usertools,$idx,$types,$roles,$sections,$states,$navbuttons,$memchg,
-        $sectioncount,$stored,$rowColor1,$rowColor2) = @_;
+        $sectioncount,$stored,$gpterm,$ucgpterm,$crstype) = @_;
 
     $r->print(&Apache::lonhtmlcommon::echo_form_input(
                                  ['origin','action','state','page','sortby']));
 
-    my $earlyout = &validate_groupname($groupname,$action,$cdom,$cnum);
+    my $earlyout = &validate_groupname($groupname,$action,$cdom,$cnum,$gpterm,
+                                       $ucgpterm,$crstype);
     if ($earlyout) {
         $r->print('
 <table width="100%" cellpadding="0" cellspacing="0" border="0">
@@ -2774,7 +3200,9 @@ sub process_request {
             @defprivs = @temp; 
         }
     } else {
-        @defprivs = @{$$stored{'defpriv'}};
+        if (defined($$stored{'defpriv'})) {
+            @defprivs = @{$$stored{'defpriv'}};
+        }
     }
 
     my $outcome;
@@ -2783,13 +3211,15 @@ sub process_request {
                                      $description,$startdate,$enddate,
                                      $specificity,$functions,$tools,
                                      $sectioncount,$roles,$types,$sections,
-                                     \@defprivs,$stored); 
+                                     \@defprivs,$stored,$gpterm,$ucgpterm,
+                                     $crstype); 
     }
     if (($action eq 'create' && $outcome eq 'ok') || (($action eq 'modify') && 
        (($state eq 'memresult') || ($state eq 'addresult')))) {
         &process_membership($r,$cdom,$cnum,$action,$state,$groupname,$tools,
                             $enddate,$startdate,$userdata,$idx,$toolprivs,
-                            $usertools,$specificity,\@defprivs,$memchg);
+                            $usertools,$specificity,\@defprivs,$memchg,$gpterm,
+                            $ucgpterm,$crstype);
     }
     return;
 }
@@ -2797,7 +3227,7 @@ sub process_request {
 sub write_group_data {
     my ($r,$cdom,$cnum,$action,$state,$groupname,$description,$startdate,
         $enddate,$specificity,$functions,$tools,$sectioncount,$roles,$types,
-        $sections,$defprivs,$stored) = @_;
+        $sections,$defprivs,$stored,$gpterm,$ucgpterm,$crstype) = @_;
     my $now = time;
     my $creation = $now;
     my $creator = $env{'user.name'}.':'.$env{'user.domain'};
@@ -2805,12 +3235,36 @@ sub write_group_data {
         $creation = $$stored{'creation'};
         $creator = $$stored{'creator'};
     }
-    my $esc_description = &Apache::lonnet::escape($description);
+    my $esc_description = &escape($description);
     my @single_attributes = ('description','functions','startdate','enddate',
                              'creation','modified','creator','granularity',
-                             'specificity','autoadd','autodrop');
+                             'specificity','autoadd','autodrop','quota');
     my @mult_attributes = ('roles','types','sectionpick','defpriv');
-                                                                                    
+
+    my ($crsquota,$freespace,$maxposs) = &get_quota_constraints($action,
+                                                                $stored);
+    my $quota = $env{'form.quota'};
+    
+    $quota =~ s/^\s*([^\s]*)\s*$/$1/;
+    if ($quota eq '') {
+        $quota = 0;
+    }
+    if ($quota !~ /^\d*\.?\d*$/) {
+        $quota = 0;
+        $r->print('<div class="LC_warning">'
+                 .&mt('The value you entered for the quota for the group portfolio in this '.$gpterm
+                 .' contained invalid characters, so it has been set to 0 MB. You can change this by'
+                 .' modifying the '.$gpterm.' settings.')
+                 .'</div>');
+    }
+    if ($quota > $maxposs) {
+        $quota = $maxposs;
+        $r->print('<div class="LC_warning">'
+                 .&mt('The value you entered for the quota for the group portfolio in this '.$gpterm
+                 .' exceeded the maximum possible value, so it has been set to [_1] MB '
+                 .'(the maximum possible value).',sprintf("%.2f",$maxposs))
+                 .'</div>');
+    }
     my %groupinfo = (
                      description => $esc_description,
                      startdate => $startdate,
@@ -2822,7 +3276,9 @@ sub write_group_data {
                      specificity => $specificity,
                      autoadd => $env{'form.autoadd'},
                      autodrop => $env{'form.autodrop'},
+                     quota => $quota,
                    );
+
     foreach my $func (keys(%{$functions})) {
         my $status;
         if (grep(/^$func$/,@{$tools})) {
@@ -2849,14 +3305,11 @@ sub write_group_data {
     }
     my $autosec;
     my @autorole = &Apache::loncommon::get_env_multiple('form.autorole');
-                                                                                    
+
     foreach my $role (@autorole) {
         if (defined($env{'form.sec_'.$role})) {
             my @autosections=&Apache::loncommon::get_env_multiple('form.sec_'.
                                                                   $role);
-            if (grep/^_all$/,@autosections) {
-                @autosections = sort {$a cmp $b} keys(%{$sectioncount});
-            }
             $autosec .= '<role id="'.$role.'">';
             foreach my $sec (@autosections) {
                 $autosec .= '<section>'.$sec.'</section>';
@@ -2872,35 +3325,124 @@ sub write_group_data {
 
     if ($result eq 'ok') {
         if ($action eq 'create') {
-            my $put_result = &create_homepage($cdom,$cnum,$groupname,
-                                              \%groupinfo,$tools);
-            $r->print('Group '.$groupname.' was created.<br />');
-        } else {
-            $r->print('Group '.$groupname.' was updated.<br />');
+            my $result = &add_group_folder($cdom,$cnum,$now,$groupname,$action,
+                                           $description,$tools,\%groupinfo,
+                                           $gpterm,$ucgpterm,$crstype);
+            if ($result eq 'ok') {
+                my $msg = &Apache::lonhtmlcommon::confirm_success(&mt($ucgpterm.' [_1] was created.','<i>'.$groupname.'</i>'));
+                $msg = &Apache::loncommon::confirmwrapper($msg);
+                $r->print($msg);
+            } else {
+                my $msg = &Apache::lonhtmlcommon::confirm_success(&mt('A problem occurred when creating folders for the new '.$gpterm.' [_1]:'
+                                                                     ,'<i>'.$groupname.'</i>')
+                                                                     .'<br />'.$result,1);
+                $msg = &Apache::loncommon::confirmwrapper($msg);
+                $r->print($msg);
+            }
+        } elsif ($action eq 'modify') {
+            my (@oldtools,@newtools); 
+            if (ref($$stored{'tool'}) eq 'ARRAY') {
+                @oldtools = @{$$stored{'tool'}};
+            }
+            if (ref($tools) eq 'ARRAY') {
+                @newtools = @{$tools};
+            }
+            if (!grep(/^discussion$/,@oldtools) && 
+                 grep(/^discussion$/,@newtools)) {
+                my $crspath = '/uploaded/'.$cdom.'/'.$cnum.'/';
+                my $boardsmap = $crspath.'group_boards_'.$groupname.'.sequence';
+                my $navmap = Apache::lonnavmaps::navmap->new();
+                my ($bbmapres,$error);
+                if (defined($navmap)) {
+                    $bbmapres = $navmap->getResourceByUrl($boardsmap);
+                    undef($navmap);
+                    if (!$bbmapres) {
+                        my $grpmap = $crspath.'group_folder_'.$groupname.'.sequence';
+                        my $disctitle = &mt('Discussion Boards');
+                        my $outcome = &map_updater($cdom,$cnum,'group_boards_'.
+                                                   $groupname.'.sequence','bbseq',
+                                                   $disctitle,$grpmap);
+                        my ($furl,$ferr) = 
+                            &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
+                        # modify parameter
+                        if ($outcome eq 'ok') {
+                            $navmap = Apache::lonnavmaps::navmap->new();
+                            if (defined($navmap)) {
+                                my $parm_result = &parm_setter($navmap,$cdom,$boardsmap,
+                                                               $groupname);
+                                if ($parm_result) {
+                                    $error = &mt('An error occurred while setting parameters '
+                                             .'for Discussion Boards folder: '
+                                             .'[_1]',$parm_result);
+                                } else {
+                                    $r->print('<div class="LC_success">'.
+                                              &mt('Discussion Boards Folder created.')
+                                              .'</div>');
+                                }
+                                undef($navmap);
+                            } else {
+                                if ($crstype eq 'Community') {
+                                    $error = &mt("An error occurred while setting parameters '.
+                                             'for Discussion Boards folder: '.
+                                             'Could not retrieve community information");
+                                } else {
+                                    $error = &mt("An error occurred while setting parameters '.
+                                             'for Discussion Boards folder: '.
+                                             'Could not retrieve course information");
+                                }
+                            }
+                        } else {
+                            $r->print($outcome);
+                        }
+                    }
+                } else {
+                    $error = &mt("An error occurred while retrieving the contents of the group's folder.").'<br />';
+                    if ($crstype eq 'Community') {
+                        $error .= &mt("You need to re-initialize the community.");
+
+                    } else {
+                        $error .= &mt("You need to re-initialize the course.");
+                    }
+                }
+                if ($error ne '') {
+                    $r->print('<div class="LC_error">'.$error.'</div>');
+                }
+            }
+            my $message = &Apache::lonhtmlcommon::confirm_success(&mt($ucgpterm.' [_1] was updated.','<i>'.$groupname.'</i>'));
+            $message = &Apache::loncommon::confirmwrapper($message);
+            $r->print($message);
         }
     } else {
         my %actiontype = (
                           'create' => 'creating',
                           'modify' => 'modifying',
                          );
-        &Apache::lonnet::logthis('Failed to store group '.$groupname.
-                                 'in course: '.$cnum.' in domain: '.$cdom);
-        $r->print(&mt('An error occurred when [_1] the new group. '.
-                      'Please try again.',$actiontype{$action}));
+        &Apache::lonnet::logthis("Failed to store $gpterm $groupname ".
+                                 'in '.lc($crstype).': '.$cnum.
+                                 ' in domain: '.$cdom);
+        $r->print('<p class="LC_error">'
+                 .&mt('An error occurred when '.$actiontype{$action}.' the '.$gpterm.'. '
+                 .'Please try again.')
+                 .'</p');
     }
     return $result;
 }
 
 sub process_membership {
     my ($r,$cdom,$cnum,$action,$state,$groupname,$tools,$enddate,$startdate,
-        $userdata,$idx,$toolprivs,$usertools,$specificity,$defprivs,$memchg)=@_;
+        $userdata,$idx,$toolprivs,$usertools,$specificity,$defprivs,$memchg,
+        $gpterm,$ucgpterm,$crstype)=@_;
     my %usersettings = ();
     my %added= ();
     my %failed = ();
     my $num_ok = 0;
     my $num_fail = 0;
     my %group_privs = ();
+    my %curr_privs = ();
+    my %curr_start = ();
+    my %curr_end = ();
     my %tooltype = ();
+    my $context = 'processgroupmembership';
 
     foreach my $tool (@{$tools}) {
         foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
@@ -2918,7 +3460,7 @@ sub process_membership {
                 }
             } else {
                 if (@{$defprivs} > 0) {
-                    foreach my $priv (@{$defprivs}) {
+                    if (grep/^\Q$priv\E$/,@{$defprivs}) {
                         foreach my $user (sort(keys(%{$usertools}))) {
                             if ($$usertools{$user}{$tool}) {
                                 $group_privs{$user} .= $priv.':';
@@ -2938,6 +3480,7 @@ sub process_membership {
     my @expire = ();
     my @deletion = ();
     my @reenable = ();
+    my @unchanged = ();
     if ($state eq 'memresult') {
         if (ref($$memchg{'activate'}) eq 'ARRAY') {
             @activate = @{$$memchg{'activate'}};
@@ -2951,21 +3494,25 @@ sub process_membership {
         if (ref($$memchg{'reenable'}) eq 'ARRAY') {
             @reenable = @{$$memchg{'reenable'}};
         }
+        my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum,
+                                                                 $groupname);
+        foreach my $key (sort(keys(%membership))) {
+            if ($key =~ /^\Q$groupname\E:([^:]+:[^:]+)$/) {
+                ($curr_end{$1},$curr_start{$1},$curr_privs{$1}) = 
+                                                split(/:/,$membership{$key},3);
+            }
+        }
         if (@expire + @deletion > 0) {
-            my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum,
-                                                                   $groupname);
             foreach my $user (@expire) {
-                my ($currend,$currstart,@userprivs) = 
-                                  split(/:/,$membership{$groupname.':'.$user});
-                $group_privs{$user} = join(':',@userprivs); 
-                if ($currstart > $now) {
-                    $currstart = $now;
+                my $savestart = $curr_start{$user};
+                if ($savestart > $now) {
+                    $savestart = $now;
                 }
-                $usersettings{$groupname.':'.$user} = $now.':'.$currstart.':'.
-                                                      $group_privs{$user};
+                $usersettings{$groupname.':'.$user} = $now.':'.$savestart.':'.
+                                                      $curr_privs{$user};
                 if (&Apache::lonnet::modify_group_roles($cdom,$cnum,$groupname,
-                                                       $user,$now,$currstart,
-                                                       $group_privs{$user}) eq 'ok') {
+                                                       $user,$now,$savestart,
+                                                       $curr_privs{$user},'',$context) eq 'ok') {
                     push(@{$added{'expired'}},$user);
                     $num_ok ++;
                 } else {
@@ -2976,7 +3523,7 @@ sub process_membership {
             foreach my $user (@deletion) {
                 $usersettings{$groupname.':'.$user} = $now.':-1:';
                 if (&Apache::lonnet::modify_group_roles($cdom,$cnum,$groupname,
-                                                       $user,$now,'-1','')
+                                                       $user,$now,'-1','','',$context)
                                                          eq 'ok') {
                     push(@{$added{'deleted'}},$user);
                     $num_ok ++;
@@ -2989,21 +3536,39 @@ sub process_membership {
     }
 
     foreach my $user (sort(keys(%{$usertools}))) {
+        if ((grep(/^$user$/,@expire)) || (grep(/^$user$/,@deletion))) {
+            next;
+        }
         my $type;
         my $start = $startdate;
         my $end = $enddate;
         if ($state eq 'memresult') {
-            $type = 'modified';
             if (@activate > 0) {
                 if (grep/^$user$/,@activate) {
                     $start = $now;
+                    $end = $enddate;
                     $type = 'activated';
                 }
             }
             if (@reenable > 0) {
                 if (grep/^$user$/,@reenable) {
-                    $type = 'reenabled';
+                    $start = $startdate;
+                    $end = $enddate;
+                    $type = 're-enabled';
+                }
+            }
+            if ($type eq '') {
+                if ($curr_privs{$user} eq $group_privs{$user}) {
+                    push(@unchanged,$user);
+                    next;
+                }
+                if (exists($curr_start{$user})) {
+                    $start = $curr_start{$user};
                 }
+                if (exists($curr_end{$user})) {
+                    $end = $curr_end{$user};
+                }
+                $type = 'modified';
             }
         } else {
             $type = 'added';
@@ -3012,7 +3577,7 @@ sub process_membership {
                                               $group_privs{$user};
         if (&Apache::lonnet::modify_group_roles($cdom,$cnum,$groupname,
                                                 $user,$end,$start,
-                                                $group_privs{$user}) eq 'ok') {
+                                                $group_privs{$user},'',$context) eq 'ok') {
             push(@{$added{$type}},$user);
             $num_ok ++;
         } else {
@@ -3023,12 +3588,14 @@ sub process_membership {
     my $roster_result = &Apache::lonnet::modify_coursegroup_membership($cdom,
                                                        $cnum,\%usersettings);
     if ($num_ok) {
-        foreach my $type (sort(keys(%added))) { 
-            $r->print(&mt('The following users were successfully [_1]',$type));
-            if (!($type eq 'deleted' ||  $type eq 'expired')) {   
-                $r->print(&mt(' with the following privileges'));
+        my $msgall ='';
+        foreach my $type (sort(keys(%added))) {
+            my $message;
+            my $tmsg = "The following users were successfully $type"; 
+            if (!($type eq 'deleted' || $type eq 'expired')) {   
+                $tmsg .= ' with the following privileges';
             }
-            $r->print(':<br />');
+            $message .= &mt($tmsg.':').'<br/>';
             foreach my $user (@{$added{$type}}) {
                 my $privlist = '';
                 if (!($type eq 'deleted' ||  $type eq 'expired')) {
@@ -3044,56 +3611,87 @@ sub process_membership {
                     }
                     $privlist =~ s/, $//;
                 }
-                $r->print($$userdata{$user}[$$idx{fullname}].'&nbsp;-&nbsp;'.$user.$privlist.'<br />');
+                $message .= $$userdata{$user}[$$idx{fullname}].'&nbsp;-&nbsp;'.$user.$privlist.'<br />';
             }
+            $message .= '<br/>';
+            $message = &Apache::lonhtmlcommon::confirm_success($message);
+            $msgall .= $message;
         }
+        $msgall = &Apache::loncommon::confirmwrapper($msgall);
+        $r->print($msgall);
     }
     if ($num_fail) {
         foreach my $type (sort(keys(%failed))) {
-            $r->print(&mt('The following users could not be [_1], because an error occurred:<br />',$type));
+            $r->print('<div class="LC_error">'
+                     .&mt("The following users could not be $type, because an error occurred:")
+                     .'</div>');
             foreach my $user (@{$failed{$type}}) {
                 $r->print($$userdata{$user}[$$idx{fullname}].' - '.$user.'<br />');
             }
         }
+        $r->print('<br />');
     }
+# Is that really needed?
+#
+#    if (@unchanged > 0) {
+#        $r->print(&mt('No change occurred for the following users:').'<br />');
+#        foreach my $user (sort(@unchanged)) {
+#            $r->print($$userdata{$user}[$$idx{fullname}].' - '.$user.'<br />');
+#        }
+#        $r->print('<br />');
+#    }
     if ($roster_result eq 'ok') {
-        $r->print('<br />Group membership list updated.');
+        $r->print('<div class="LC_success">'
+                 .&mt($ucgpterm.' membership list updated.')
+                 .'</div>');
+	$r->print('<p class="LC_info">');
+        if ($crstype eq 'Community') {
+            $r->print(&mt("Any currently logged in community users affected by the changes you made"
+                     .' to group membership or privileges for the [_1] group will need to log out'
+                     .' and log back in for their LON-CAPA sessions to reflect these changes.'
+                     ,'<i>'.$groupname.'</i>'));
+
+        } else {  
+            $r->print(&mt("Any currently logged in course users affected by the changes you made"
+                     .' to group membership or privileges for the [_1] group will need to log out'
+                     .' and log back in for their LON-CAPA sessions to reflect these changes.'
+                     ,'<i>'.$groupname.'</i>'));
+        } 
+        $r->print('</p>');
     } else {
-        $r->print('<br />An error occurred while updating the group membership list -'.$roster_result.'<br />');
+        $r->print('<div class="LC_error">'
+                 .&mt("An error occurred while updating the $gpterm membership list:")
+                 .'<br />'.$roster_result
+                 .'</div>');
     }
     return;
 }
 
 sub mapping_options {
-    my ($r,$action,$formname,$page,$tabcol,$sectioncount,$states,$stored,
-        $navbuttons,$img1,$img2,$rowColor1,$rowColor2) = @_;
+    my ($r,$action,$formname,$page,$sectioncount,$states,$stored,
+        $navbuttons,$img1,$img2,$gpterm,$ucgpterm,$crstype,$cdom,$cnum) = @_;
     my %lt = &Apache::lonlocal::texthash(
-        'auto' => 'Settings for automatic group enrollment',
-        'gmma' => 'Group membership mapping to specific sections/roles',
-        'endi' => 'Enable/disable automatic group enrollment for '.
-                          'users in specified roles and sections',
-        'adds'  => 'If automatic group enrollment is enabled, when a user is assigned a course-wide or section-specific role, he/she will automatically be added as a member of the group, with start and end access dates defined by the default dates set for the group, unless he/she is already a group member, with access dates that permit either current or future group access.',
-        'drops'  => "If automatic group disenrollment is enabled, when a user's role is expired, access to the group will be terminated unless the user continues to have other course-wide or section-specific active or future roles which receive automatic membership in the group.",
-        'pirs' => 'Pick roles and sections for automatic group enrollment',
-        'curr' => 'Currently set to',
+        'auto' => "Settings for automatic $gpterm enrollment",
+        'gmma' => "$ucgpterm membership mapping to specific sections/roles",
+        'endi' => "Enable/disable automatic $gpterm enrollment for ".
+                          "users in specified roles and sections",
+        'adds'  => "If automatic $gpterm enrollment is enabled, when a user is newly assigned a ".lc($crstype)."-wide or section-specific role, he/she will automatically be added as a member of the $gpterm, with start and end access dates defined by the default dates set for the $gpterm, unless he/she is already a $gpterm member, with access dates that permit either current or future $gpterm access.",
+        'drops'  => "If automatic $gpterm disenrollment is enabled, when a user's role is expired, access to the $gpterm will be terminated unless the user continues to have other ".lc($crstype)."-wide or section-specific active or future roles which receive automatic membership in the $gpterm.",
+        'pirs' => "Pick roles and sections for automatic $gpterm enrollment",
         'on' => 'on',
         'off' => 'off',
-        'auad' => 'Automatically enable group membership when roles are added?',
-        'auex' => 'Automatically expire group membership when roles are removed?',
-        'mapr' => 'Mapping of roles and sections affected by automatic group enrollment/disenrollment follows scheme chosen below.',
+        'auad' => "Automatically enable $gpterm membership when roles are added?",
+        'auex' => "Automatically expire $gpterm membership when roles are removed?",
+        'mapr' => "Mapping of roles and sections affected by automatic $gpterm enrollment/disenrollment follows scheme chosen below.",
     );
-    &automapping($r,$action,$tabcol,$stored,\%lt,$img1);
-    $r->print('
-   <tr>
-    <td colspan="4">&nbsp;</td>
-   </tr>');
-    &mapping_settings($r,$tabcol,$rowColor1,$rowColor2,$sectioncount,\%lt,
-                                                       $stored,$img2);
+    &automapping($r,$action,$stored,\%lt,$img1);
+    &mapping_settings($r,$sectioncount,\%lt,$stored,$img2,$crstype,$cdom,$cnum,
+                      $action);
     return;
 }
 
 sub automapping {
-    my ($r,$action,$tabcol,$stored,$lt,$image) = @_;
+    my ($r,$action,$stored,$lt,$image) = @_;
     my $add = 'off';
     my $drop = 'off';
     if (exists($$stored{'autoadd'})) {
@@ -3102,171 +3700,141 @@ sub automapping {
     if (exists($$stored{'autodrop'})) {
         $drop = $$stored{'autodrop'};
     }
-    &topic_bar($r,$tabcol,$image,$$lt{'endi'});
-    $r->print('
-  <tr>
-   <td>&nbsp;</td>
-   <td colspan="3">
-    <b>'.$$lt{'gmma'}.':</b><br />'.$$lt{'adds'}.'<br />'.$$lt{'drops'}.'<br />
-   </td>
-  </tr>
-  <tr>
-   <td colspan="4">&nbsp;</td>
-  </tr>
-  <tr>
-   <td>&nbsp;</td>
-   <td colspan="3">
-   <nobr>'.$$lt{'auad'}.':&nbsp;
-    <input type="radio" name="autoadd" value="on" />on&nbsp;&nbsp;<input type="radio" name="autoadd" value="off" />off');
+    $r->print(&Apache::lonhtmlcommon::topic_bar($image,$$lt{'endi'}).'
+    <b>'.$$lt{'gmma'}.':</b><br />'.$$lt{'adds'}.'<br />'.$$lt{'drops'}.'<br /><br />
+   <span class="LC_nobreak">'.$$lt{'auad'}.':&nbsp;
+    <label><input type="radio" name="autoadd" value="on" />'.&mt('on').'&nbsp;&nbsp;</label><label><input type="radio" name="autoadd" value="off" checked="checked" />'.&mt('off').'</label>');
     if ($action eq 'modify') {
-        $r->print('&nbsp;&nbsp;&nbsp;&nbsp;('.$$lt{'curr'}.' <b>'.$$lt{$add}.'</b>)');
+        $r->print('&nbsp;&nbsp;&nbsp;&nbsp;('.&mt('Currently set to [_1].','<b>'.$$lt{$add}.'</b>').')');
     }
     $r->print('
-    </nobr>
-   </td>
-  </tr>
-  <tr>
-   <td>&nbsp;</td>
-   <td colspan="3">
-    <nobr>'.$$lt{'auex'}.':&nbsp;
-    <input type="radio" name="autodrop" value="on" />on&nbsp;&nbsp;<input type="radio" name="autodrop" value="off" />off');
+    </span><br />
+    <span class="LC_nobreak">'.$$lt{'auex'}.':&nbsp;
+    <label><input type="radio" name="autodrop" value="on" />'.&mt('on').'&nbsp;&nbsp;</label><label><input type="radio" name="autodrop" value="off" checked="checked" />'.&mt('off').'</label>');
     if ($action eq 'modify') {
-        $r->print('&nbsp;&nbsp;&nbsp;&nbsp;('.$$lt{'curr'}.' <b>'.$$lt{$drop}.'</b>)');
+        $r->print('&nbsp;&nbsp;&nbsp;&nbsp;('.&mt('Currently set to [_1].','<b>'.$$lt{$drop}.'</b>').')');
     }
-    $r->print('</nobr>
-   </td>
-  </tr>
-  <tr>
-   <td colspan="4">&nbsp;</td>
-  </tr>
-  <tr>
-   <td>&nbsp;</td>
-   <td colspan="3">'.$$lt{'mapr'}.'
-   </td>
-  </tr>
-');
+    $r->print('</span><br /><br />'.$$lt{'mapr'});
 }
 
 sub mapping_settings {
-    my ($r,$tabcol,$rowColor1,$rowColor2,$sectioncount,$lt,$stored,$image) = @_;
+    my ($r,$sectioncount,$lt,$stored,$image,$crstype,$cdom,$cnum,$action) = @_;
     my @sections = keys(%{$sectioncount});
     if (@sections > 0) {
         @sections = sort {$a cmp $b} @sections;
-        unshift(@sections,'_nosec'); # Put 'no sections' next
-        unshift(@sections,'_all'); # Put 'all' at the front of the list
+        unshift(@sections,'none'); # Put 'no sections' next
+        unshift(@sections,'all'); # Put 'all' at the front of the list
+    } else {
+        @sections = ('all','none');
     }
-    &topic_bar($r,$tabcol,$image,$$lt{'pirs'});
-    $r->print('
-   <tr>
-    <td>&nbsp;</td>
-    <td colspan="3">
-');
-    my @roles = &standard_roles();
-    my %customroles = &my_custom_roles();
-    $r->print(&Apache::lonhtmlcommon::start_pick_box());
+    $r->print(&Apache::lonhtmlcommon::topic_bar($image,$$lt{'pirs'}));
+    my @roles = &standard_roles($crstype);
+    my %customroles = &Apache::lonhtmlcommon::course_custom_roles($cdom,$cnum);
+    $r->print(&Apache::loncommon::start_data_table().
+	      &Apache::loncommon::start_data_table_header_row());
     $r->print('
-                <tr bgcolor="'.$tabcol.'">
                  <th>'.&mt('Active?').'</th>
                  <th>'.&mt('Role').'</th>');
     if (@sections > 0) {
-        $r->print('<th>'.&mt('Sections').'</th></tr>'."\n");
+        $r->print('<th>'.&mt('Sections').'</th>');
     }
-    my $rowNum = 0;
-    my $rowColor;
+    $r->print(&Apache::loncommon::end_data_table_header_row()."\n");
     foreach my $role (@roles) {
-        my $plrole=&Apache::lonnet::plaintext($role);
-        my $sections_sel;
-        if (@sections > 0) {
-            $sections_sel='<td>'.&sections_selection(\@sections,'sec_'.$role).
-                                                                       '</td>';
-        }
-        if ($rowNum %2 == 1) {
-            $rowColor = $rowColor1;
-        } else {
-            $rowColor = $rowColor2;
-        }
-        $r->print('<tr bgcolor="'.$rowColor.'"><td><input type="checkbox" '.
-                  'name="autorole" value="'.$role.'"></td><td>'.$plrole.
-                  '</td>'.$sections_sel.'</tr>');
-        $rowNum ++;
+        my $roletitle=&Apache::lonnet::plaintext($role,$crstype);
+        $r->print(&print_autorole_item($role,$roletitle,\@sections));
     }
+    my @customs;
     foreach my $role (sort(keys(%customroles))) {
-        my $sections_sel;
-        if (@sections > 0) {
-            $sections_sel = '<td>'.&sections_selection(\@sections,'sec_'.$role).
-                                                                        '</td>';
-        }
-        if ($rowNum %2 == 1) {
-            $rowColor = $rowColor1;
-        } else {
-            $rowColor = $rowColor2;
-        }
-        $r->print('<tr bgcolor="'.$rowColor.'"><td><input type="checkbox" '.
-                  'value="'.$role.'"></td><td>'.$role.'</td>'.
-                  $sections_sel.'</tr>');
-        $rowNum ++;
+        my ($roletitle) = ($role =~ m|^cr/[^/]+/[^/]+/(.+)$|);
+        push (@customs,$role);
+        $r->print(&print_autorole_item($role,$roletitle,\@sections));
     }
-    $r->print(&Apache::lonhtmlcommon::end_pick_box());
+    if ($action eq 'modify') {
+        foreach my $role (@{$$stored{'autorole'}}) {
+            if ((!grep(/^\Q$role\E$/,@customs)) && 
+                (!grep(/^\Q$role\E$/,@roles))) {
+                my $roletitle;
+                if ($role =~ /^cr/) {
+                    ($roletitle) = ($role =~ m|_([^_]+)$|);
+                } else {
+                    $roletitle = &Apache::lonnet::plaintext($role,$crstype);
+                }
+                $r->print(&print_autorole_item($role,$roletitle,\@sections));
+            }
+        }
+    }
+    $r->print(&Apache::loncommon::end_data_table());
     return;
 }
 
-sub standard_roles {
-    my @roles = ('st','ep','ta','in','cc');
-    return @roles;
-}
-
-sub my_custom_roles {
-    my %returnhash=();
-    my %rolehash=&Apache::lonnet::dump('roles');
-    foreach (keys %rolehash) {
-        if ($_=~/^rolesdef\_(\w+)$/) {
-            $returnhash{$1}=$1;
+sub print_autorole_item {
+    my ($role,$roletitle,$sections) = @_;
+    my $sections_sel;
+    if (@{$sections} > 0) {
+        if (($role eq 'cc') || ($role eq 'co')) {
+            $sections_sel = '<td align="right">'.
+                            &mt('all sections').'<input type="hidden" '.
+                            'name="sec_'.$role.'" value="all" /></td>';
+        } else {
+            $sections_sel='<td align="right">'.
+                          &sections_selection($sections,'sec_'.$role).
+                          '</td>';
         }
     }
-    return %returnhash;
+    my $output = &Apache::loncommon::start_data_table_row().
+                 '<td><input type="checkbox" '.
+                 'name="autorole" value="'.$role.'" />'.
+                 '</td><td>'.$roletitle.'</td>'.$sections_sel.
+                 &Apache::loncommon::end_data_table_row();
+    return $output;
+} 
+
+sub standard_roles {
+    my ($crstype) = @_;
+    my @roles = qw(in ta ep ad st);
+    if ($crstype eq 'Community') {
+        unshift(@roles,'co');
+    } else {
+        unshift(@roles,'cc');
+    }
+    return @roles;
 }
 
 sub modify_menu {
-    my ($r,$groupname,$page) = @_;
+    my ($r,$groupname,$page,$gpterm) = @_;
     my @menu =
-        (
-          { text => 'Modify default group settings',
-            help => 'Course_Modify_Group',
-            state => 'change_settings',
-            branch => 'settings',
+        ( { categorytitle =>'Group Actions',
+	items => [
+
+          { linktext => "Modify default $gpterm settings",
+            url => '/adm/coursegroups?action=modify&amp;refpage='.$env{'form.refpage'}.'&amp;groupname='.$groupname.'&amp;state=change_settings&amp;branch=settings',
+            icon => 'grp_settings.png',
+            alttext => "Modify default $gpterm settings",
+            permission => '1',
+            help => 'Course_Modify_Group',            
             },
-          { text => 'Modify access, tools and/or privileges for previous, '.
-                    'future, or current members',
+          { linktext => 'Modify access, tools and privileges for members',
+            url => '/adm/coursegroups?action=modify&amp;refpage='.$env{'form.refpage'}.'&amp;groupname='.$groupname.'&amp;state=change_members&amp;branch=members',
+            icon => 'grp_tools.png',
+            alttext => 'Modify access, tools and privileges for members',
+            permission => '1',
             help => 'Course_Modify_Group_Membership',
-            state => 'change_members',
-            branch => 'members',
             },
-          { text => 'Add member(s) to the group',
+          { linktext => "Add member(s) to the $gpterm",
+            url => '/adm/coursegroups?action=modify&amp;refpage='.$env{'form.refpage'}.'&amp;groupname='.$groupname.'&amp;state=add_members&amp;branch=adds',
+            icon => 'grp_add.png',
+            alttext =>  "Add member(s) to the $gpterm",
+            permission => '1',
             help => 'Course_Group_Add_Members',
-            state => 'add_members',
-            branch => 'adds',
-            },
-          );
-    my $menu_html = '';
-    foreach my $menu_item (@menu) {
-        $menu_html .=
-        '<p><font size="+1"><a href="/adm/coursegroups?action=modify&refpage='.$env{'form.refpage'}.'&groupname='.$groupname.'&state='.$menu_item->{'state'}.'&branch='.$menu_item->{'branch'}.'">';
-        $menu_html.= &mt($menu_item->{'text'}).'</a></font>';
-        if (exists($menu_item->{'help'})) {
-            $menu_html.=
-                &Apache::loncommon::help_open_topic($menu_item->{'help'});
-        }
-        $menu_html.='</p>'.$/;
-    }
-    $r->print($menu_html);
+            }]}
+          );   
+    $r->print(&Apache::lonhtmlcommon::generate_menu(@menu));
     return;
 }
 
 sub member_privs_entries {
-    my ($r,$tabcol,$rowColor1,$rowColor2,$usertools,$toolprivs,
-        $fixedprivs,$userdata,$idx,$showtools,$defprivs,$excluded) = @_;
-    my $rowColor;
-    my $rowNum = 0;
+    my ($r,$usertools,$toolprivs,$fixedprivs,$userdata,$idx,$showtools,
+	$defprivs,$excluded) = @_;
     foreach my $user (sort(keys(%{$usertools}))) {
         if (defined($excluded)) {
             if (ref($excluded) eq 'ARRAY') {
@@ -3276,19 +3844,27 @@ sub member_privs_entries {
             }
         }
         my ($uname,$udom) = split(/:/,$user);
-        if ($rowNum %2 == 1) {
-            $rowColor = $rowColor1;
-        } else {
-            $rowColor = $rowColor2;
-        }
-        $r->print('<tr bgcolor="'.$rowColor.'">
+        $r->print(&Apache::loncommon::start_data_table_row().'
                 <td>'.$$userdata{$user}[$$idx{fullname}].'</td>
                 <td>'.$uname.'</td>
                 <td>'.$udom.'</td>
-                <td valign="top"><table><tr><td><b>Function</b></td></tr><tr><td><b>Fixed</b></td></tr><tr><td><b>Optional</b></td></tr></table></td>');
+                <td valign="top">
+                  <table>
+                   <tr>
+                    <td><b>'.
+                    &mt('Collaborative Tool').'</b></td>
+                   </tr>
+                   <tr>
+                    <td><b>'.&mt('Fixed').'</b></td>
+                   </tr>
+                   <tr>
+                    <td><b>'.&mt('Optional').'</b></td>
+                   </tr>
+                  </table>
+                 </td>');
         foreach my $tool (@{$showtools}) {
             if (exists($$usertools{$user}{$tool})) {
-                $r->print('<td valign="top"><table><tr bgcolor="'.$tabcol.'"><td colspan="2" align="center"><b>'.$tool.'</b></td></tr>');
+                $r->print('<td valign="top"><table><tr><th colspan="2">'.$tool.'</th></tr>');
                 my $privcount = 0;
                 my $fixed = '';
                 my $dynamic = '';
@@ -3300,21 +3876,21 @@ sub member_privs_entries {
                         if ($privcount == 3) {
                             $dynamic .= '</tr><tr>';
                         }
-                        $dynamic .='<td><nobr><label><input type="checkbox" '.
+                        $dynamic .='<td><span class="LC_nobreak"><label><input type="checkbox" '.
                                'name="userpriv_'.$priv.'" value="'.$user.'"';
                         if (grep/^\Q$priv\E$/,@{$defprivs}) {
                             $dynamic .= ' checked="checked" ';
                         }
                         $dynamic .= ' />'.$$toolprivs{$tool}{$priv}.
-                                    '</label></nobr></td>';
+                                    '</label></span></td>';
                     }
                 }
-                $r->print('<tr><td colspan="2"><nobr>'.$fixed.'</nobr></td></tr><tr>'.$dynamic.'</tr></table></td>');
+                $r->print('<tr><td colspan="2"><span class="LC_nobreak">'.$fixed.'</span></td></tr><tr>'.$dynamic.'</tr></table></td>');
             } else {
-                $r->print('<td valign="top"><table width="100%"><tr bgcolor="'.$tabcol.'"><td colspan="2" align="center"><b>'.$tool.'</b></td></tr><tr><td>&nbsp;</td></tr><tr><td>&nbsp;</td></tr></table></td>');
+                $r->print('<td valign="top"><table width="100%"><tr><th colspan="2">'.$tool.'</th></tr><tr><td>&nbsp;</td></tr><tr><td>&nbsp;</td></tr></table></td>');
             }
         }
-        $rowNum ++;
+        $r->print(&Apache::loncommon::end_data_table_row());
     }
 }
 
@@ -3335,40 +3911,282 @@ sub date_setting_table {
                                                       'startdate',$starttime);
     my $endform = &Apache::lonhtmlcommon::date_setter($formname,
                                                       'enddate',$endtime);
-    my $perpetual = '<nobr><label><input type="checkbox" name="no_end_date" />
-                                                no ending date</label></nobr>';
-    my $start_table = '';
-    $start_table .= "<table>\n";
-    $start_table .= '<tr><td align="right">Default starting date for 
-                                           member access</td>'.
-        '<td>'.$startform.'</td>'.
-        '<td>&nbsp;</td>'."</tr>\n";
-    $start_table .= "</table>";
-    my $end_table = '';
-    $end_table .= "<table>\n";
-    $end_table .= '<tr><td align="right">Default ending date for 
-                                         member access</td>'.
-        '<td>'.$endform.'</td>'.
-        '<td>'.$perpetual.'</td>'."</tr>\n";
-    $end_table .= "</table>\n";
-    return ($start_table, $end_table);
+    my $perpetual = ' <span class="LC_nobreak"><label>'
+                   .'<input type="checkbox" name="no_end_date" />'
+                   .&mt('No end date')
+                   .'</label></span>';
+    my $table = &Apache::lonhtmlcommon::start_pick_box()
+               .&Apache::lonhtmlcommon::row_title(&mt('Start Date'))
+               .$startform
+               .&Apache::lonhtmlcommon::row_closure()
+               .&Apache::lonhtmlcommon::row_title(&mt('End Date'))
+               .$endform
+               .$perpetual
+               .&Apache::lonhtmlcommon::row_closure(1)
+               .&Apache::lonhtmlcommon::end_pick_box();
+    return $table;
+}
+
+sub add_group_folder {
+    my ($cdom,$cnum,$now,$groupname,$action,$description,$tools,$groupinfo,
+        $gpterm,$ucgpterm,$crstype) = @_;
+    if ($cdom eq '' || $cnum eq '') {
+        my $error = '<span class="LC_error">';
+        if ($crstype eq 'Community') { 
+            $error .= &mt("Error: invalid community domain or number - group folder creation failed.");
+        } else {
+            $error .= &mt("Error: invalid course domain or number - group folder creation failed.");
+        }
+        $error .= '</span>';
+        return $error;
+    }
+    my ($outcome,$allgrpsmap,$grpmap,$boardsmap,$grppage,$warning);
+    my $crspath = '/uploaded/'.$cdom.'/'.$cnum.'/';
+    $allgrpsmap = $crspath.'group_allfolders.sequence';
+    if ($action eq 'create') {
+        if (&get_folder_lock($cdom,$cnum,'group_allfolders',$now) eq 'ok') {
+            # check if group_allfolders.sequence exists.
+            my $mapcontents = &Apache::lonnet::getfile($allgrpsmap);
+            if ($mapcontents eq '-1') { #file does not exist;
+                my $grpstitle = &mt("$crstype $ucgpterm".'s');
+                my $topmap_url = '/'.$env{'course.'.$env{'request.course.id'}.'.url'};
+                $topmap_url =~ s|/+|/|g;
+                if ($topmap_url =~ m|^/uploaded|) {
+                    $outcome = &map_updater($cdom,$cnum,'group_allfolders.sequence',
+                                            'toplevelgroup',$grpstitle,$topmap_url);
+                } else {
+                    $outcome = '<span class="LC_warning">'
+                              .&mt('Non-standard course - folder for all groups not added.')
+                              .'</span>';
+                }
+                if ($outcome ne 'ok') {
+                    my $delresult = &release_folder_lock($cdom,$cnum,'group_allfolders');
+                    if ($delresult ne 'ok') {
+                        $warning = $delresult;
+                    }
+                    return $outcome.$warning;
+                }
+            }
+            my $delresult = &release_folder_lock($cdom,$cnum,'group_allfolders');
+            if ($delresult ne 'ok') {
+                $warning = $delresult ;
+            }
+        } else {
+            $outcome = '<span class="LC_error">'
+                      .&mt('Could not obtain exclusive lock to check status of the folder for all groups. No group folder added.')
+                      .'</span>';
+            return $outcome;
+        }
+        my $grpfolder = &mt($ucgpterm.' Folder - [_1]',$description);
+        $grppage='/adm/'.$cdom.'/'.$cnum.'/'.$groupname.'/smppg';
+        my $grptitle = &mt('Group homepage - [_1]',$description);
+        my ($discussions,$disctitle);
+        my $outcome = &map_updater($cdom,$cnum,'group_folder_'.$groupname.'.sequence',
+                                   'grpseq',$grpfolder,$allgrpsmap,$grppage,
+                                   $grptitle);
+        if ($outcome ne 'ok') {
+            return $outcome.$warning;
+        }
+        my $pageout = &create_homepage($cdom,$cnum,$groupname,$groupinfo,
+                                       $tools,$gpterm,$ucgpterm,$now);
+        # Link to folder for bulletin boards
+        $grpmap = $crspath.'group_folder_'.$groupname.'.sequence';
+        if (grep/^discussion$/,@{$tools}) {
+            $disctitle = &mt('Discussion Boards');
+            my $outcome = &map_updater($cdom,$cnum,'group_boards_'.$groupname.
+                                       '.sequence','bbseq',$disctitle,$grpmap);
+            if ($outcome ne 'ok') {
+                return $outcome.$warning;
+            }
+            $boardsmap = $crspath.'group_boards_'.$groupname.'.sequence';
+        }
+    } else {
+        #modify group folder if status of discussions tools is changed
+    }
+    my ($furl,$ferr)= &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
+    my $navmap = Apache::lonnavmaps::navmap->new();
+    if (!defined($navmap)) {
+        $warning .= '<span class="LC_error">';
+        if ($crstype eq 'Community') {
+            $warning .= &mt("Error retrieving community contents").
+                        ' '.&mt("You need to re-initialize the community.");
+        } else {
+            $warning  .= &mt("Error retrieving course contents").
+                         ' '.&mt("You need to re-initialize the course.");
+        }
+        $warning .= '</span>';
+        return $warning;
+    }
+    # modify parameters
+    my $parm_result;
+    if ($action eq 'create') {
+        if ($grpmap) {
+            $parm_result .= &parm_setter($navmap,$cdom,$grpmap,$groupname);
+        }
+        if ($grppage) {
+            $parm_result .= &parm_setter($navmap,$cdom,$grppage,$groupname);
+        }
+        if ($boardsmap) {
+            $parm_result .= &parm_setter($navmap,$cdom,$boardsmap,$groupname);
+        }
+    }
+    undef($navmap);
+    if ($parm_result) {
+        return $warning.$parm_result;
+    } else {
+        return 'ok';
+    }
+}
+
+sub get_folder_lock {
+    my ($cdom,$cnum,$folder_name,$now) = @_;  
+    # get lock for folder being edited.
+    my $lockhash = {
+                  $folder_name."\0".'locked_folder' => $now.':'.$env{'user.name'}.
+                                                     ':'.$env{'user.domain'},
+                   };
+    my $tries = 0;
+    my $gotlock = &Apache::lonnet::newput('coursegroups',$lockhash,$cdom,$cnum);
+
+    while (($gotlock ne 'ok') && $tries <3) {
+        $tries ++;
+        sleep(1);
+        $gotlock = &Apache::lonnet::newput('coursegroups',$lockhash,$cdom,$cnum);
+    }
+    return $gotlock;
+}
+
+sub release_folder_lock {
+    my ($cdom,$cnum,$folder_name) = @_;  
+    #  remove lock
+    my @del_lock = ($folder_name."\0".'locked_folder');
+    my $dellockoutcome=&Apache::lonnet::del('coursegroups',\@del_lock,$cdom,$cnum);
+    if ($dellockoutcome ne 'ok') {
+        return ('<div class="LC_error">'
+               .&mt('Warning: failed to release lock for folder: [_1].','<tt>'.$folder_name.'</tt>')
+               .'</div>'
+               );
+    } else {
+        return 'ok';
+    }
+}
+
+sub map_updater {
+    my ($cdom,$cnum,$newfile,$itemname,$itemtitle,$parentmap,$startsrc,
+        $starttitle,$endsrc,$endtitle) = @_;
+    my $outcome;
+    $env{'form.'.$itemname} = &new_map($startsrc,$starttitle,$endsrc,
+                                       $endtitle);
+    my $newmapurl=&Apache::lonnet::finishuserfileupload($cnum,$cdom,$itemname,
+                                                        $newfile);
+    if ($newmapurl !~ m|^/uploaded|) {
+        $outcome = '<div class="LC_error">'
+                  .&mt('Error uploading new folder.')." ($newfile): $newmapurl"
+                  .'</div>';
+        return $outcome;
+    }
+    my ($errtext,$fatal)=&LONCAPA::map::mapread($parentmap);
+    if ($fatal) {
+        $outcome = '<div class="LC_error">'
+                  .&mt('Error reading contents of parent folder.')." ($parentmap): $errtext"
+                  .'</div>';
+        return $outcome;
+    } else {
+        my $newidx=&LONCAPA::map::getresidx($newmapurl);
+        $LONCAPA::map::resources[$newidx] = $itemtitle.':'.$newmapurl.
+                                                 ':false:normal:res';
+        $LONCAPA::map::order[1+$#LONCAPA::map::order]=$newidx;
+        my ($outtext,$errtext) = &LONCAPA::map::storemap($parentmap,1,1);
+        if ($errtext) {
+            $outcome = '<div class="LC_error">'
+                      .&mt('Error saving updated parent folder.')." ($parentmap):  $errtext"
+                      .'</div>';
+            return $outcome;
+        }
+    }
+    return 'ok';
+}
+
+sub new_map {
+    my ($startsrc,$starttitle,$endsrc,$endtitle) = @_;
+    my $newmapstr = '
+<map>
+ <resource id="1" src="'.$startsrc.'" type="start" title="'.$starttitle.'"></resource>
+ <link from="1" to="2" index="1"></link>
+ <resource id="2" src="'.$endsrc.'" type="finish" title="'.$endtitle.'"></resource>
+</map>
+';
+    return $newmapstr;
+}
+
+sub parm_setter {
+    my ($navmap,$cdom,$url,$groupname,$crstype) = @_;
+    if (!defined($navmap)) {
+        my $allresults;
+        if ($crstype eq 'Community') { 
+            $allresults = &mt("Parameters not set for [_1] because the contents of the community could not be retrieved.",$url).' '.
+                          &mt("You need to reinitialize the community.");
+        } else {
+            $allresults = &mt("Parameters not set for [_1] because the contents of the course could not be retrieved.",$url).' '.
+                          &mt("You need to reinitialize the course.");
+
+        }
+        return '<div class="LC_warning">'.$allresults.'</div>';
+    }
+    my %hide_settings = (
+                           'course' =>  {
+                                          'num' => 13,
+                                          'set' => 'yes',
+                                        },
+                            'group' =>  {
+                                          'num' => 5,
+                                          'set' => 'no',
+                                          'extra' => $groupname,
+                                        },
+                        );
+    my $res = $navmap->getResourceByUrl($url);
+    my $allresults;
+    if ($res) {
+        my $symb = $res->symb();
+        foreach my $level (keys(%hide_settings)) {
+            my $parmresult =  
+                       &Apache::lonparmset::storeparm_by_symb($symb,
+                                                 '0_hiddenresource',
+                                                 $hide_settings{$level}{'num'},
+                                                 $hide_settings{$level}{'set'},
+                                                 'string_yesno',undef,$cdom,
+                                                 undef,undef,
+                                                 $hide_settings{$level}{'extra'});
+            if ($parmresult) {
+                $allresults .= $level.': '.$parmresult;
+            }
+        }
+    } else {
+        $allresults = '<div class="LC_warning">';
+        if ($crstype eq 'Community') {
+            $allresults .= &mt("Parameters not set for [_1] because the resource was not recognized as part of the community.",'<tt>'.$url.'</tt>');
+        } else {
+            $allresults .= &mt('Parameters not set for [_1] because the resource was not recognized as part of the course.','<tt>'.$url.'</tt>');
+        }
+        $allresults .= '</div>';
+    }
+    return $allresults;
 }
 
 sub create_homepage {
-    my ($cdom,$cnum,$name,$groupinfo,$tools) = @_;
+    my ($cdom,$cnum,$name,$groupinfo,$tools,$gpterm,$ucgpterm,$now) = @_;
     my $functionality = join(',',@{$tools});
-    my $content = &Apache::lonnet::unescape($$groupinfo{description});
-    $content=~s/\s+$//s;
-    $content=~s/^\s+//s;
-    $content=~s/\<br\s*\/*\>$//s;
-    $content=&Apache::lonfeedback::clear_out_html($content,1);
+    my $content = &unescape($$groupinfo{description});
+    chomp($content);
+    my $gateway = Apache::lonhtmlgateway->new();
+    $content = $gateway->process_incoming_html($content,1);
 
     my %pageinfo = (
-                     'aaa_title' => 'Group: '.$name,
+                     'aaa_title' => "$ucgpterm: $name",
                      'abb_links' => $functionality,
                      'bbb_content' => $content,
                      'ccc_webreferences' => '',
-                     'uploaded.lastmodified' => time,
+                     'uploaded.lastmodified' => $now,
                    );
    my $putresult = &Apache::lonnet::put('grppage_'.$name,\%pageinfo,$cdom,$cnum);
    return $putresult;
@@ -3410,79 +4228,56 @@ function toggleTools(field,caller) {
 }
 
 sub validate_groupname {
-    my ($groupname,$action,$cdom,$cnum) = @_;
-    my %sectioncount;
-    my $numsec=&Apache::loncommon::get_sections($cdom,$cnum,\%sectioncount);
-    my %curr_groups;
-    my $numgroups=&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum);
-                                                                                         
+    my ($groupname,$action,$cdom,$cnum,$gpterm,$ucgpterm,$crstype) = @_;
+    my %sectioncount = &Apache::loncommon::get_sections($cdom,$cnum);
+    my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum);
+    my %deleted_groups = &Apache::longroup::coursegroups($cdom,$cnum,undef,
+                                                         'deleted_groups');
+    if (my $tmp = &Apache::lonnet::error(%deleted_groups)) {
+        undef(%deleted_groups);
+        &Apache::lonnet::logthis('Error retrieving groups: '.$tmp.' in '.$cnum.':'.$cdom);
+    }
     my %lt = &Apache::lonlocal::texthash (
-                      igna => 'Invalid group name',
-                      tgne => 'The group name entered ',
-                      grna => 'Group names and section names used in a course '.
-                              'must be unique.',
-                      isno => 'is not a valid name.',
-                      gnmo => 'Group names may only contain letters, numbers '.
-                              'or underscores.',
-                      cnnb => 'can not be used as it is the name of ',
-                      inth => ' in this course.',
-                      thgr => '- does not correspond to the name of an existing'.  
-                              ' group ',    
+                      igna => "Invalid $gpterm name",
+                      grna => "$ucgpterm names and section names used in a ".
+                               "$crstype must be unique.",
+                      gnmo => "$ucgpterm names may only contain letters, ". 
+                              "numbers or underscores.",
     );
-                                                                                         
-    my $exitmsg = '<b>'.$lt{'igna'}.'</b><br /><br />'.$lt{'tgne'}.' "'.
-                  $groupname.'" ';
-    my $dupmsg = $lt{'grna'};
-    my $earlyout;
+
+    my $exitmsg = '<span class="LC_error">'.$lt{'igna'}.'</span><br /><br />';
+    my $nameshown = &Apache::loncommon::cleanup_html($groupname);
     if (($groupname eq '') || ($groupname =~ /\W/)) {
-        $earlyout = $exitmsg.$lt{'isno'}.'<br />'.$lt{'gnmo'};
-        return $earlyout;
-    }
-    if ($numsec) {
-        if (exists($sectioncount{$groupname})) {
-            $earlyout = $exitmsg.$lt{'cnnb'}.&mt('a section').$lt{'inth'}.
-                        '<br />'.$lt{'grna'};
-            return $earlyout;
-        }
-    }
-    if ($action eq 'create') {
-        if ($numgroups) {
-            if (exists($curr_groups{$groupname})) {
-                $earlyout = $exitmsg.$lt{'cnnb'}.&mt('an existing group').
-                            $lt{'inth'}.'<br />'.$lt{'grna'};
-                return $earlyout;
-            }
+        return $exitmsg.
+               &mt("The $gpterm name entered '[_1]' is not a valid name.",$nameshown).
+               '<br />'.$lt{'gnmo'};
+    } elsif ($groupname eq 'syllabus') {
+        return $exitmsg.
+               &mt("The $gpterm name entered '[_1]' is reserved for use by LON-CAPA.",$nameshown);
+    }
+    if (exists($sectioncount{$groupname})) {
+	return  $exitmsg.
+                &mt("The $gpterm name entered '[_1]' can not be used as it is the name of a section in this $crstype.",$nameshown).
+	        '<br />'.$lt{'grna'};
+    }
+    if ($action eq 'create') { 
+	if (exists($curr_groups{$groupname})) {
+	    return $exitmsg.
+                   &mt("The $gpterm name entered '[_1]' can not be used as it is the name of an existing $gpterm in this $crstype.",$nameshown).
+                  '<br />'.$lt{'grna'};
+        } elsif (exists($deleted_groups{$groupname})) {
+            return $exitmsg.
+                   &mt("The $gpterm name entered '[_1]' can not be used as it is the name of a $gpterm which previously existed in this $crstype.",$nameshown).
+                   '<br />'.$lt{'grna'};
         }
     } elsif ($action eq 'modify') {
         unless(exists($curr_groups{$groupname})) {
-            $earlyout = &mt('Group name:').' '.$groupname.$lt{'thgr'}.$lt{'inth'};
-            return $earlyout;
+            return &mt("$ucgpterm name: [_1] does not correspond to the name of an existing $gpterm in this $crstype.",$nameshown);
         }
     }
     return;
 }
 
-sub topic_bar {
-    my ($r,$tabcol,$imgnum,$title) = @_;
-    $r->print('
- <tr bgcolor="'.$tabcol.'">
-  <td>&nbsp;</td>
-  <td valign="middle" align="left">
-   <nobr>
-    <img src="/res/adm/pages/bl_step'.$imgnum.'.gif" valign="middle">&nbsp;
-   </nobr>
-  </td>
-  <th align="left"><nobr>'.$title.'<nobr>
-  </th>
-  <td width="100%">&nbsp;</td>
- </tr>
- <tr>
-  <td colspan="4">&nbsp;</td>
- </tr>
-');
-    return;
-}
-
 sub check_changes {
     my ($member_changes,$memchg) = @_;
     my %exclusions;
@@ -3522,3 +4317,4 @@ sub check_changes {
 }
 
 1;
+