--- loncom/interface/loncoursegroups.pm	2006/05/18 18:35:13	1.19
+++ loncom/interface/loncoursegroups.pm	2006/07/07 16:48:21	1.40
@@ -1,3 +1,6 @@
+# The LearningOnline Network with CAPA
+#
+# $Id: loncoursegroups.pm,v 1.40 2006/07/07 16:48:21 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -31,7 +34,10 @@ use Apache::lonhtmlcommon;
 use Apache::lonlocal;
 use Apache::lonnavmaps;
 use Apache::longroup;
+use Apache::portfolio;
 use Apache::Constants qw(:common :http);
+use lib '/home/httpd/lib/perl/';
+use LONCAPA;
 
 sub handler {
     my ($r) = @_;
@@ -64,13 +70,18 @@ sub handler {
           &Apache::lonnet::allowed('mdg',$env{'request.course.id'});
     &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',
+                      homepage => $ucgpterm.' home page',
                     );
 
     my %idx = ();
@@ -78,62 +89,75 @@ sub handler {
     $idx{fullname} = &Apache::loncoursedata::CL_FULLNAME();
     $idx{udom} = &Apache::loncoursedata::CL_SDOM();
     $idx{uname} = &Apache::loncoursedata::CL_SNAME();
+    $idx{section} = &Apache::loncoursedata::CL_SECTION();
 
     my $rowColor1 = "#dddddd";
     my $rowColor2 = "#eeeeee";
 
     my $action = $env{'form.action'};
+    my $state = $env{'form.state'};
+    if ((!defined($action)) || ($action eq 'view')) {
+        if (!defined($state)) {
+            $state = 'view';
+        }
+    }
     if ($action eq 'create' || $action eq 'modify' || $action eq 'view') { 
         if ($view_permission || $manage_permission) {
-            &group_administration($r,$action,$cdom,$cnum,$function,$tabcol,
-                                  \%functions,\%idx,$view_permission,
-                                  $manage_permission,$rowColor1,$rowColor2);
+            &group_administration($r,$action,$state,$cdom,$cnum,$function,
+                                  $tabcol,\%functions,\%idx,$view_permission,
+                                  $manage_permission,$rowColor1,$rowColor2,
+                                  $gpterm,$ucgpterm,$crstype);
         } else {
-            $r->print(&mt('You do not have group administration '.
-                          'privileges in this course'));
+            $r->print(&mt('You do not have [_1] administration '.
+                          'privileges in this [_2]',$gpterm,lc($crstype)));
         }
     } 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 $pagename = "$crstype $ucgpterm".'s';
+    my $jscript = qq|
+function changeSort(caller) {
+    document.$state.sortby.value = caller;
+    document.$state.submit();
+}\n|;
+    $r->print(&header($pagename,$jscript,$action,$state));
     &Apache::lonhtmlcommon::add_breadcrumb
         ({href=>"/adm/coursegroups",
-          text=>"Course Groups",});
-    $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course Groups'));
-    &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,
-                    $view_permission,$manage_permission,$action,$rowColor1,
-                    $rowColor2);
+          text=>"$pagename"});
+    $r->print(&Apache::lonhtmlcommon::breadcrumbs($pagename));
+    &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=',
+      modify => '<a href="/adm/coursegroups?action=modify&refpage='.
+                         $env{'form.refpage'}.'&groupname=',
       view => '<a href="/adm/'.$cdom.'/'.$cnum.'/',
       delete => '<a href="/adm/coursegroups?action=delete&refpage='.
-                $env{'form.refpage'}.'&groupname=',
+                         $env{'form.refpage'}.'&groupname=',
     );
     my %lt = &Apache::lonlocal::texthash( 
                           modify => 'Modify',
                           view   => 'View',
                           delete => 'Delete',
                           act    => 'Action',
-                          gname  => 'Group Name',
+                          gname  => "$ucgpterm Name",
                           desc   => 'Description',
                           crea   => 'Creator',
                           crtd   => 'Created',
@@ -143,13 +167,13 @@ sub display_groups {
                           memb   => 'Members',
                           file   => 'Files',
                           dibd   => 'Discussion Boards',
-                          dius   => 'Disk Use',
-                          nogr   => 'No groups exist.',
-                          crng   => 'Create a new group',
+                          dius   => 'Disk Use (%)',
+                          nogr   => 'No '.$gpterm.'s exist.',
+                          crng   => 'Create a new '.$gpterm,
                           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 '.$gpterm.'s in this'.
+                                    lc($crstype).', you do not have privileges'.
+                                    'to create new '.$gpterm.'s.',
                      );
     if ($view_permission) {
         if (!defined($action)) {
@@ -157,29 +181,28 @@ sub display_groups {
         }
         my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum);
         if (%curr_groups) {
+            if ($manage_permission) {
+                $r->print('<br /><a href="/adm/coursegroups?action=create&refpage='.$env{'form.refpage'}.'">'.$lt{'crng'}.'</a>');
+            }
             $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'}</b></td>
+        <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}} = 
@@ -187,12 +210,27 @@ END
                                                          $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 $port_dir = &Apache::loncommon::propath($cdom,$cnum).$port_path;
+                my $totaldirs = 0;
+                my $totalfiles = 0;
+                &group_files($group,$port_dir,\$totalfiles,\$totaldirs);
+                $grp_info{$group}{'totalfiles'} = $totalfiles;
+                $grp_info{$group}{'totaldirs'} = $totaldirs;
+                my $diskuse = &Apache::lonnet::diskusage($cdom,$cnum,$port_dir);
+                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 +252,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;
@@ -248,19 +280,46 @@ END
                     } else {
                         $link .= $group.'/grppg';
                     }
-                    $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 ++;
+                    $link .= '">'.$lt{$action}.'</a>';
+                    if ($action eq 'view') { 
+                        if (($manage_permission) && 
+                            ($env{'form.refpage'} ne 'enrl')) {
+                            $link .= '&nbsp;&nbsp;'.$actionlinks{'modify'}.
+                                      $group.'">'.$lt{'modify'}.'</a>';
+                        }
+                    }
+                    $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"><nobr>'.&mt('Files: ').$totalfiles.'</nobr><br /><nobr>'.&mt('Folders: ').$totaldirs.'</nobr></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>');
             } else {
-                $r->print('<br /><br />'.$lt{'crng'});
+                $r->print('<br /><br />'.$lt{'alth'});
 
             }
         }
@@ -273,7 +332,7 @@ END
                 foreach my $group (@coursegroups) {
                     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">'.$group,'</a><font><br /><small>'.$description.'</small><br /><br />');
@@ -281,15 +340,17 @@ END
             }
         } else {
             $r->print(&mt('You are not currently a member of any '.
-                          'active groups in this course'));
+                          'active [_1]s in this [_2]',$gpterm,
+                          lc($crstype)));
         }
     }
     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,$function,$tabcol,$functions,$idx,
+        $view_permission,$manage_permission,$rowColor1,$rowColor2,$gpterm,
+        $ucgpterm,$crstype) = @_;
     my %sectioncount = ();
     my @tools = ();
     my @types = ();
@@ -303,8 +364,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 +389,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,7 +405,11 @@ sub group_administration {
 
     if ($action eq 'modify') {
         if ($state eq '') {
-            $state = 'pick_group';
+            if (defined($env{'form.groupname'})) {
+                $state = 'pick_task';
+            } else {
+                $state = 'pick_group';
+            }
         } else {
             %stored = &retrieve_settings($cdom,$cnum,$groupname);
             if (ref($stored{'types'}) eq 'ARRAY') {
@@ -363,75 +430,60 @@ 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'}}) {
             unless ($role eq 'cc') {
@@ -440,15 +492,6 @@ sub group_administration {
             }
         }
     }
-    %{$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';
@@ -476,7 +519,7 @@ sub group_administration {
         }
         if (defined($env{'form.sectionpick'})) {
             @sections=&Apache::loncommon::get_env_multiple('form.sectionpick');
-            if (grep/^_all$/,@sections) {
+            if (grep/^all$/,@sections) {
                 @sections = sort {$a cmp $b} keys(%sectioncount);
             }
         }
@@ -560,11 +603,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;
                 }
@@ -596,8 +645,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;
@@ -667,19 +716,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 = document.'.$state.'.quota.value;
+    newquota.replace('.$space_trim.');
+    if (newquota == "" ) {
+        document.'.$state.'.quota.value = 0;
+        newquota = 0;       
+    }
+    var maxposs = '.$maxposs.';
+    if (newquota > maxposs) {
+        alert("The file repository 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 file repository should be enabled, but you have set the respository 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) {
@@ -705,7 +794,7 @@ function changeSort(caller) {
     @{$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'}}});
     }
@@ -723,8 +812,9 @@ function changeSort(caller) {
     }
 
     my $loaditems =  &onload_action($action,$state);
-    $r->print(&header('Course Groups Manager',
-		      $jscript,$action,$state,$page,$function,$loaditems));
+    my $crumbtitle = "$crstype $ucgpterm".'s'; 
+    $r->print(&header("$crumbtitle Manager",
+		      $jscript,$action,$state,$page,$loaditems));
 
     if ($env{'form.refpage'} eq 'enrl') {
         &Apache::lonhtmlcommon::add_breadcrumb
@@ -734,21 +824,21 @@ function changeSort(caller) {
     } else {
         &Apache::lonhtmlcommon::add_breadcrumb
        ({href=>"/adm/coursegroups",
-          text=>"Course Groups",
+          text=>"$crumbtitle",
           faq=>9,bug=>'Instructor Interface',});
     }
 
     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_group => $ucgpterm.'s',
                             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',
@@ -762,7 +852,7 @@ function changeSort(caller) {
     my %navbuttons = &Apache::lonlocal::texthash(
                              gtns => 'Go to next step',
                              gtps => 'Go to previous step',
-                             crgr => 'Create group',
+                             crgr => 'Create '.$gpterm,
                              mose => 'Modify settings',
                              gtpp => 'Go to previous page',
                              adme => 'Add members',
@@ -774,14 +864,15 @@ function changeSort(caller) {
                 &Apache::lonhtmlcommon::add_breadcrumb(
                    {text=>"$trail{$action}{$state}"});
                 $r->print(&Apache::lonhtmlcommon::breadcrumbs
-			  ('Course Groups Manager'));
+			  ("$crumbtitle Manager"));
                 &display_control($r,$cdom,$cnum,$tabcol,$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);
+                       \%stored,$granularity,$quota,$specificity,\@types,\@roles,
+                       \@sections,\%states,\%navbuttons,$rowColor1,$rowColor2,
+                       $gpterm,$ucgpterm,$crstype);
                 last;
             } else {
                 if (($state eq 'result') && ($i > 0)) {
@@ -797,12 +888,13 @@ function changeSort(caller) {
         }
     } elsif (($action eq 'view') && ($view_permission)) {
                         &Apache::lonhtmlcommon::add_breadcrumb(
-                   {text=>"View groups"});
+                   {text=>"View $gpterm".'s'});
+        my $crumbtitle = "$crstype $ucgpterm".'s Manager';
         $r->print(&Apache::lonhtmlcommon::breadcrumbs
-		  ('Course Groups Manager'));
-        &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,
-                        $view_permission,$manage_permission,$action,
-                        $rowColor1,$rowColor2);
+		  (&mt($crumbtitle)));
+        &display_groups($r,$cdom,$cnum,$functions,$idx,$view_permission,
+			$manage_permission,$action,$state,$gpterm,$ucgpterm,
+			$crstype);
 
     }
     $r->print(&footer());
@@ -821,7 +913,7 @@ sub retrieve_settings {
     my %stored;
 
     $stored{'description'} = 
-	&Apache::lonnet::unescape($groupinfo{'description'});
+	&unescape($groupinfo{'description'});
     $stored{'startdate'} = $groupinfo{'startdate'};
     $stored{'enddate'} = $groupinfo{'enddate'};
     if ($stored{'enddate'} == 0) {
@@ -831,6 +923,7 @@ sub retrieve_settings {
     $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') {
@@ -870,78 +963,86 @@ sub display_control {
     my ($r,$cdom,$cnum,$tabcol,$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)=@_;
+        $view_permission,$manage_permission,$stored,$granularity,$quota,
+        $specificity,$types,$roles,$sections,$states,$navbuttons,$rowColor1,
+        $rowColor2,$gpterm,$ucgpterm,$crstype) = @_;
     if ($action eq 'create') {
         if ($state eq 'pick_name') {
             &general_settings_form($r,$cdom,$cnum,$action,$tabcol,$state,$page,
                                    $functions,$tools,$toolprivs,$fixedprivs,
                                    $sectioncount,$stored,$states,$navbuttons,
-                                   $rowColor1,$rowColor2);
+                                   $rowColor1,$rowColor2,$gpterm,$ucgpterm,
+                                   $crstype);
         } elsif ($state eq 'pick_members') {
             &choose_members_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,
-                                 $groupname,$description,$granularity,
+                                 $groupname,$description,$granularity,$quota,
                                  $startdate,$enddate,$tools,$fixedprivs,
                                  $toolprivs,$functions,$users,$userdata,$idx,
                                  $stored,$states,$navbuttons,$rowColor1,
-                                 $rowColor2);
+                                 $rowColor2,$gpterm,$ucgpterm,$crstype);
         } elsif ($state eq 'pick_privs') {
             &choose_privs_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,
                                $startdate,$enddate,$tools,$functions,
                                $toolprivs,$fixedprivs,$userdata,$usertools,
                                $idx,$states,$stored,$sectioncount,$navbuttons,
-                               $rowColor1,$rowColor2);
+                               $rowColor1,$rowColor2,$gpterm,$ucgpterm,
+                               $crstype);
         } elsif ($state eq 'result') {
             &process_request($r,$cdom,$cnum,$tabcol,$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,$rowColor1,$rowColor2,
+                             $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);
+            &display_groups($r,$cdom,$cnum,$functions,$idx,$view_permission,
+			    $manage_permission,$action,$state,$gpterm,
+			    $ucgpterm,$crstype);
         } elsif ($state eq 'pick_task') {
-            &modify_menu($r,$groupname,$page);
+            &modify_menu($r,$groupname,$page,$gpterm);
         } elsif ($state eq 'change_settings') {
             &general_settings_form($r,$cdom,$cnum,$action,$tabcol,$state,$page,
                                    $functions,$tools,$toolprivs,$fixedprivs,
                                    $sectioncount,$stored,$states,$navbuttons,
-                                   $rowColor1,$rowColor2);
+                                   $rowColor1,$rowColor2,$gpterm,$ucgpterm,
+                                   $crstype);
         } elsif ($state eq 'change_members') {
             &change_members_form($r,$cdom,$cnum,$tabcol,$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,$rowColor1,$rowColor2,
+                                 $gpterm,$ucgpterm);
         } elsif ($state eq 'add_members') {
             &add_members_form($r,$tabcol,$action,$state,$page,$startdate,
                               $enddate,$groupname,$description,$granularity,
-                              $sectioncount,$tools,$functions,$stored,$states,
-                              $navbuttons,$rowColor1,$rowColor2);
+                              $quota,$sectioncount,$tools,$functions,$stored,
+                              $states,$navbuttons,$rowColor1,$rowColor2,$gpterm,
+                              $ucgpterm);
         } elsif ($state eq 'pick_members') {
             &choose_members_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,
-                                 $groupname,$description,$granularity,
+                                 $groupname,$description,$granularity,$quota,
                                  $startdate,$enddate,$tools,$fixedprivs,
                                  $toolprivs,$functions,$users,$userdata,$idx,
                                  $stored,$states,$navbuttons,$rowColor1,
-                                 $rowColor2);
+                                 $rowColor2,$gpterm,$ucgpterm,$crstype);
         } elsif ($state eq 'pick_privs') {
             &choose_privs_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,
                                $startdate,$enddate,$tools,$functions,
                                $toolprivs,$fixedprivs,$userdata,$usertools,
                                $idx,$states,$stored,$sectioncount,$navbuttons,
-                               $rowColor1,$rowColor2);
+                               $rowColor1,$rowColor2,$gpterm,$ucgpterm,$crstype);
         } elsif ($state eq 'change_privs') {
             &change_privs_form($r,$cdom,$cnum,$tabcol,$action,$state,$page,
                                $startdate,$enddate,$tools,$functions,
                                $toolprivs,$fixedprivs,$userdata,$usertools,
                                $memchg,$idx,$states,$stored,$sectioncount,
-                               $navbuttons,$rowColor1,$rowColor2);
+                               $navbuttons,$rowColor1,$rowColor2,$gpterm,
+                               $ucgpterm);
         } elsif ($state eq 'chgresult' || $state eq 'memresult' || 
                  $state eq 'addresult') {
             &process_request($r,$cdom,$cnum,$tabcol,$action,$state,$page,
@@ -949,19 +1050,19 @@ sub display_control {
                              $startdate,$enddate,$tools,$functions,
                              $toolprivs,$usertools,$idx,$types,$roles,
                              $sections,$states,$navbuttons,$memchg,
-                             $sectioncount,$stored,$rowColor1,$rowColor2);
+                             $sectioncount,$stored,$rowColor1,$rowColor2,
+                             $gpterm,$ucgpterm,$crstype);
         }
     }
 }
 
 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">
@@ -1023,6 +1124,21 @@ sub build_members_list {
 }
 
 sub group_files {
+    my ($group,$currdir,$numfiles,$numdirs) = @_;
+    my $dirptr=16384;
+    my @dir_list=&Apache::portfolio::get_dir_list($currdir,$group);
+    foreach my $line (@dir_list) {
+        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) {
+                $currdir .= '/'.$filename;
+                $$numdirs ++;
+                &group_files($numfiles,$numdirs)
+            } else {
+                $$numfiles ++;
+            }
+        }
+    }
     return;
 }
 
@@ -1035,7 +1151,6 @@ sub group_members {
         $$group_info{'totalmembers'} = 'Unknown - an error occurred';
         return $tmp;
     }
-    my $now = time;
     my $totalmembers = 0;
     my $active = 0;
     my $previous = 0;
@@ -1065,23 +1180,15 @@ sub group_members {
 sub general_settings_form {
     my ($r,$cdom,$cnum,$action,$tabcol,$formname,$page,$functions,$tools,
         $toolprivs,$fixedprivs,$sectioncount,$stored,$states,$navbuttons,
-        $rowColor1,$rowColor2) = @_;
+        $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,$tabcol,$functions,$action,$formname,$stored,1,
+                           $gpterm,$ucgpterm,$crstype);
+    &access_date_settings($r,$tabcol,$action,$formname,$stored,2,$gpterm,
+                          $ucgpterm);
     if ($action eq 'create') {
-        &membership_options($r,$action,$formname,$tabcol,$sectioncount,3);
+        &membership_options($r,$action,$formname,$sectioncount,3,$gpterm,
+			    $ucgpterm);
         $nexttext = $$navbuttons{'gtns'};
     } else {
         my @available = ();
@@ -1090,38 +1197,34 @@ sub general_settings_form {
         @{$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>');
+                               \@available,$formname,$gpterm,$ucgpterm);
         &mapping_options($r,$action,$formname,$page,$tabcol,$sectioncount,
                          $states,$stored,$navbuttons,4,5,$rowColor1,
-                         $rowColor2);
+                         $rowColor2,$gpterm,$ucgpterm,$crstype);
         $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,$tabcol,$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',
+        'gdat' => "$ucgpterm open and close dates",
+        'sten' => "Set a start date/time and end date/time for the $gpterm",
+        'gfun' => "$ucgpterm functionality",
+        'gnde' => "$ucgpterm name, description and available functionality",
         'desc' => 'Description',
         'func' => 'Functionality',
-        'gnam' => 'Group Name',
-        'doyo' => 'Do you want to assign different functionality '.
-                  'to different group members?',
+        'gnam' => "$ucgpterm Name",
+        'doyo' => "Do you want to assign different functionality ".
+                  "to different $gpterm members?",
     );
-    &topic_bar($r,$tabcol,$image,$lt{'gnde'});
+    my ($crsquota,$freespace,$maxposs) = &get_quota_constraints($action,$stored);
+    &topic_bar($r,$image,$lt{'gnde'});
     $r->print('
    <tr>
     <td>&nbsp;</td>
@@ -1181,8 +1284,8 @@ END
        </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>');
+       <td><b>'.&mt('Granularity:').'</b></td>
+       <td colspan="10">'.$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>');
     if ($action eq 'modify') {
         $r->print('&nbsp;&nbsp;('.&mt('Currently set to "[_1]"',
                                       $$stored{'granularity'}).')');
@@ -1190,6 +1293,30 @@ END
     $r->print('
        </td>
       </tr>
+      <tr>
+       <td valign="top">'.&mt('<b>Disk quota:</b> ').'</td><td colspan="10">');
+    if ($action eq 'create') {
+        $r->print(&mt('If you enable the file repository for the [_1], allocate a disk quota.',$gpterm));
+    } else {
+        $r->print(&mt('Quota allocated to file repository:'));
+    } 
+    $r->print('&nbsp;<input type="text" name="quota" size="4" />Mb');
+    if ($action eq 'create') {
+        $r->print('<br />'.
+                  &mt('A total of [_1] Mb is shared between all [_2]s in the '.
+                  '[_3], and [_4] Mb are currently unallocated.',$crsquota,
+                  $gpterm,lc($crstype),$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 [_2]s in the [_3].',
+                  $maxposs,$gpterm,lc($crstype)));
+    }
+    $r->print('
+       </td>
+      </tr>
      </table>
     </td>
    </tr>
@@ -1197,20 +1324,38 @@ END
     return;
 }
 
+sub get_quota_constraints {
+    my ($action,$stored) = @_;
+    my ($crsquota,$freespace,$maxposs); 
+    $crsquota = $env{'course.'.$env{'request.course.id'}.'.internal.coursequota'};
+    if ($crsquota eq '') {
+        $crsquota = 20;
+    }
+    $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,$action,$state,$sectioncount,$image,$gpterm,$ucgpterm) = @_;
+    my $crstype = &Apache::loncommon::course_type();
     my %lt = &Apache::lonlocal::texthash(
                 'pipa' => 'Pick parameters to generate membership list',
-                'gmem' => 'Group membership options',
+                'gmem' => "$ucgpterm 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',  
+                          lc($crstype).' users from which you will select ',
+                'meof' => "members of the new $gpterm.",
+                'admg' => "additional members of the $gpterm.",
+                'ifno' => "If you do not wish to add members when you first ".
+                          "create the $gpterm, do not make any selections.",
+                'asub' => "A subsequent step will also allow you to specify automatic adding/dropping of $gpterm members triggered by specified role and section changes.",
                 'acty' => 'Access types',
-                'coro' => 'Course roles',
-                'cose' => 'Course sections',
+                'coro' => $crstype.' roles',
+                'cose' => $crstype.' sections',
              );
     my %status_types = (
                    active => &mt('Currently has access'),
@@ -1218,52 +1363,44 @@ sub membership_options {
                    future => &mt('Will have future access'),
                    );
 
-    my @roles = ('st','cc','in','ta','ep','cr');
+    #FIXME need to plumb around for the various cr roles defined by the user
+    my @roles = ('st','cc','in','ta','ep');
 
     my @sections = keys(%{$sectioncount});
 
-    &topic_bar($r,$tabcol,$image,$lt{'pipa'});
+    &topic_bar($r,$image,$lt{'pipa'});
     $r->print('
-   <tr>
-    <td>&nbsp;</td>
-    <td colspan="3">
-     <b>'.$lt{'gmem'}.'</b><br/>'.$lt{'picr'});
+     <b>'.$lt{'gmem'}.'</b><br />'.$lt{'picr'});
     if ($action eq 'create') {
-        $r->print($lt{'meof'}.'<br />'.$lt{'ifno'});
+        $r->print($lt{'meof'}.'<br />'.$lt{'ifno'}.'<br />'.$lt{'asub'});
     } else {
         $r->print($lt{'admg'});
     }
     $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>');
+       <th>'.$lt{'acty'}.'</th>
+       <th>'.$lt{'coro'}.'</th>');
     if (@sections >0) {
         $r->print('
-       <td>&nbsp;</td>
-       <td><b>'.$lt{'cose'}.'</b></td>
-       <td>&nbsp;</td>');
+       <th>'.$lt{'cose'}.'</th>');
     }
-    $r->print('</tr><tr>');
+    $r->print('</tr><tr><td>');
     $r->print(&Apache::lonhtmlcommon::status_select_row(\%status_types));
-    $r->print('<td>&nbsp;</td>');
+    $r->print('</td><td>');
     $r->print(&Apache::lonhtmlcommon::role_select_row(\@roles));
     if (@sections > 0) {
         @sections = sort {$a cmp $b} @sections;
-        unshift(@sections,'all'); # Put 'all' at the front of the list
         unshift(@sections,'none'); # Put 'no sections' next
-        $r->print('<td>&nbsp;</td>
-                   <td colspan="3" align="center" valign="top">'.
+        unshift(@sections,'all'); # Put 'all' at the front of the list
+        $r->print('</td><td>'.
         &sections_selection(\@sections,'sectionpick').'</td>');
     }
     $r->print('
       </tr>
-     </table>
-    </td>
-   </tr>');
+     </table>');
     return;
 }
 
@@ -1276,11 +1413,11 @@ sub sections_selection {
     }
     foreach my $sec (@{$sections}) {
         if ($sec eq 'all') {
-            $section_sel .= '  <option value="'.$sec.'" />all sections'."\n";
+            $section_sel .= '  <option value="'.$sec.'" selected="selected">'.&mt('all sections').'</option>'."\n";
         } elsif ($sec eq 'none') {
-            $section_sel .= '  <option value="'.$sec.'" />no section'."\n"; 
+            $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 = '
@@ -1291,9 +1428,9 @@ sub sections_selection {
 }
 
 sub access_date_settings {
-    my ($r,$tabcol,$action,$formname,$stored,$image) = @_;
+    my ($r,$tabcol,$action,$formname,$stored,$image,$gpterm,$ucgpterm) = @_;
     my %lt = &Apache::lonlocal::texthash(
-                'sten' => 'Default start and end dates for group access',
+                'sten' => "Default start and end dates for $gpterm access",
              );
     my $starttime = time;
     my $endtime = time+(6*30*24*60*60); # 6 months from now, approx
@@ -1305,7 +1442,7 @@ sub access_date_settings {
     }
     my ($start_table,$end_table) = &date_setting_table
                                     ($starttime,$endtime,$formname);
-    &topic_bar($r,$tabcol,$image,$lt{'sten'});
+    &topic_bar($r,$image,$lt{'sten'});
     $r->print('
    <tr>
     <td>&nbsp;</td>
@@ -1323,27 +1460,20 @@ sub access_date_settings {
 
 sub choose_members_form {
     my ($r,$cdom,$cnum,$tabcol,$action,$formname,$page,$groupname,$description,
-        $granularity,$startdate,$enddate,$tools,$fixedprivs,$toolprivs,
+        $granularity,$quota,$startdate,$enddate,$tools,$fixedprivs,$toolprivs,
         $functions,$users,$userdata,$idx,$stored,$states,$navbuttons,
-        $rowColor1,$rowColor2) = @_;
+        $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>');
         &display_navbuttons($r,$formname,$$states{$action}[$page-1],
                            $$navbuttons{'gtps'});
-        $r->print('</table>');
         return;
     } 
     my ($specimg,$memimg);
@@ -1351,10 +1481,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 {
@@ -1376,11 +1505,11 @@ sub choose_members_form {
     }
     &privilege_specificity($r,$tabcol,$rowColor1,$rowColor2,$action,
                           $specimg,$tools,$stored,$toolprivs,
-                          $fixedprivs,\@available,$formname);
+                          $fixedprivs,\@available,$formname,$gpterm,$ucgpterm);
     my $newusers = &pick_new_members($r,$action,$formname,$tabcol,$rowColor1,
                                     $rowColor2,\@available,$idx,$stored,
                                     $memimg,$users,$userdata,$granularity,
-                                    \%origmembers);
+                                    \%origmembers,$gpterm,$ucgpterm);
     if ($newusers || $action eq 'create') {
         &display_navbuttons($r,$formname,$$states{$action}[$page-1],
                             $$navbuttons{'gtps'},$$states{$action}[$page+1],
@@ -1389,7 +1518,6 @@ sub choose_members_form {
         &display_navbuttons($r,$formname,$$states{$action}[$page-1],
                             $$navbuttons{'gtps'});
     }
-    $r->print('</table>');
     return;
 }
 
@@ -1432,18 +1560,19 @@ 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',
+        grna => "$ucgpterm Name",
         desc => 'Description',
-        grfn => 'Group Functions',
+        grfn => "$ucgpterm Functions",
         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:',
+        ygrs => "Your $gpterm selections",
+        tfwa => "The following settings will apply to the $gpterm:",
+        difn => 'Different functionality<br />for different members:',
         stda => 'Start date',
         enda => 'End date:',
     );
@@ -1454,35 +1583,31 @@ 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>'.$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>
+        $r->print('<b>Available:</b>
                     <table cellpadding="" cellspacing="1"><tr>');
         my $rowcell = int(@{$available}/2) + @{$available}%2;
         for (my $i=0; $i<@{$available}; $i++) {
@@ -1491,8 +1616,8 @@ sub print_current_settings {
                     $r->print('</tr><tr>');
                 }
             }
-            $r->print('<td><small>'.$$functions{$$available[$i]}.
-                                          '</small></td><td>&nbsp;</td>');
+            $r->print('<td>'.$$functions{$$available[$i]}.
+		      '</td><td>&nbsp;</td>');
         }
         if ((@{$available} > 3) && (@{$available}%2)) {
             $r->print('<td>&nbsp;</td><td>&nbsp;</td>');
@@ -1500,7 +1625,7 @@ sub print_current_settings {
         $r->print('</tr></table><br />');
     }
     if (@{$unavailable} > 0) {
-        $r->print('<small><b>Unavailable:</b></small>
+        $r->print('<b>Unavailable:</b>
                     <table cellpadding="0" cellspacing="1"  border="0"><tr>');
         my $rowcell = int(@{$unavailable}/2) + @{$unavailable}%2;
         for (my $j=0; $j<@{$unavailable}; $j++) {
@@ -1509,8 +1634,8 @@ sub print_current_settings {
                     $r->print('</tr><tr>');
                 }
             }
-            $r->print('<td><small>'.$$functions{$$unavailable[$j]}.
-                                              '</small></td><td>&nbsp;</td>');
+            $r->print('<td>'.$$functions{$$unavailable[$j]}.
+		      '</td><td>&nbsp;</td>');
         }
         if ((@{$unavailable} > 3) && (@{$unavailable}%2)) {
             $r->print('<td>&nbsp;</td><td>&nbsp;</td>');
@@ -1519,33 +1644,30 @@ sub print_current_settings {
     }
     $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> $granularity</td>
+  <td valign="top">$quota Mb</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) = @_;
+        $stored,$img,$users,$userdata,$granularity,$origmembers,$gpterm,
+        $ucgpterm) = @_;
     my %lt = &Apache::lonlocal::texthash(
-          'gpme' => 'Group membership',
+          'gpme' => "$ucgpterm 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.',
+          '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 $gpterm.",
           '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.',
@@ -1572,7 +1694,7 @@ sub pick_new_members {
             $r->print(&check_uncheck_tools($r,$available));
         }
     }
-    &topic_bar($r,$tabcol,$img,$lt{'gpme'});
+    &topic_bar($r,$img,$lt{'gpme'});
     if (keys(%members) > 0) {
         $r->print('
  <tr>
@@ -1611,6 +1733,7 @@ sub pick_new_members {
      </td>
      <td><b><a href="javascript:changeSort('."'domain'".')">'.&mt('Domain').'</a></b></td>
      <td><b><a href="javascript:changeSort('."'id'".')">ID</a></b></td>
+     <td><b><a href="javascript:changeSort('."'section'".')">Section</a></b></td>
 ');
         if (@{$available} > 0) {
             $r->print('<td><b>'.$lt{'func'}.'</b></td>');
@@ -1619,7 +1742,7 @@ sub pick_new_members {
         if (@{$available} > 0) {
             if ($granularity eq 'Yes') {
                 $r->print('<tr bgcolor="#cccccc">
- <td colspan="5">&nbsp;</td>
+ <td colspan="6">&nbsp;</td>
  <td align="center"><small><nobr><b>'.&mt('All:').'</b>&nbsp;');
                 foreach my $tool (@{$available}) {
                     $r->print('<label><input type="checkbox" name="togglefunc" '.
@@ -1639,6 +1762,8 @@ 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);
             }
@@ -1656,10 +1781,12 @@ sub pick_new_members {
                 my $fullname = $members{$user}[$$idx{fullname}];
                 my $udom = $members{$user}[$$idx{udom}];
                 my $uname = $members{$user}[$$idx{uname}];
+                my $section = $members{$user}[$$idx{section}];
                 $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>');
+    $udom.'</small></td><td><small>'.$id.'</small></td>'.
+			  '<td><small>'.$section.'</small></td>');
                 if (@{$available} > 0) {
                     $r->print('<td align="center"><nobr><small>'.
                               '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');
@@ -1702,7 +1829,7 @@ sub pick_new_members {
 
 sub privilege_specificity {
     my ($r,$tabcol,$rowColor1,$rowColor2,$action,$img,$tools,$stored,
-        $toolprivs,$fixedprivs,$available,$formname) = @_;
+        $toolprivs,$fixedprivs,$available,$formname,$gpterm,$ucgpterm) = @_;
     my %lt = &Apache::lonlocal::texthash (
       'uprv' => 'User privileges',
       'frty' => 'For each type of functionality you have chosen to include, '.
@@ -1717,19 +1844,19 @@ sub privilege_specificity {
                 'privileges which apply to members with access to that '.
                 'functionality, and may also include 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, '. 
-                '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.',
+      'cutg' => "Currently the $gpterm is configured ",
+      'sdif' => "so different $gpterm members can receive different privileges.",
+      'sall' => "so all $gpterm members will receive the same privileges.",
+      'algm' => "All $gpterm members will receive the same privileges.",
+      'smgp' => "Some $gpterm members will receive different privileges from ".
+                "others.",
+      'thwi' => "These will be the privileges all $gpterm members receive, ". 
+                "if you selected the first option above.",
+      'thes' => "These will be the privileges given to members assigned ".   
+                "in the future, including via automatic $gpterm assignment ".
+                "for specific sections/roles ",
+      'asyo' => "As you have chosen not to include any functionality in the ".
+                "$gpterm, no default user privileges settings need to be set.",
       'plin' => 'Please indicate which <b>optional</b> privileges members '.
                 'will receive by default.',
       'oppr' => 'Optional privileges',
@@ -1743,12 +1870,7 @@ sub privilege_specificity {
             }
         }
     }
-    &topic_bar($r,$tabcol,$img,$lt{'uprv'});
-    $r->print('
- <tr>
-  <td>&nbsp;</td>
-  <td colspan="3">
-  ');
+    &topic_bar($r,$img,$lt{'uprv'});
     if ((($action eq 'create') && (@{$available} > 0)) || 
         (($action eq 'modify') && ($formname eq 'change_settings'))) {  
         my %specific = (
@@ -1774,21 +1896,14 @@ 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 /><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>');
         } 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'});
             }
@@ -1799,24 +1914,15 @@ 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);
@@ -1839,10 +1945,6 @@ sub privilege_specificity {
                               $toolprivs,\@defprivs);
         }
     }
-    $r->print('
-  </td>
- </tr>
-');
     return;
 }
 
@@ -1994,11 +2096,11 @@ sub display_defprivs {
 sub change_members_form {
     my ($r,$cdom,$cnum,$tabcol,$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,$rowColor1,
+        $rowColor2,$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(
@@ -2015,18 +2117,18 @@ sub change_members_form {
 <br />
 <table width="100%" cellpadding="0" cellspacing="0" border="0">
 ');
-    &topic_bar($r,$tabcol,1,$lt{'grse'});
+    &topic_bar($r,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);
+    &print_current_settings($r,$action,$functions,$startdate,$enddate,
+			    $groupname,$description,$granularity,$quota,
+			    \@available,\@unavailable,$gpterm,$ucgpterm);
 $r->print('
 </td></tr><tr><td colspan="4">&nbsp;</td></tr>');
-    &topic_bar($r,$tabcol,2,$lt{'mogm'});
+    &topic_bar($r,2,$lt{'mogm'});
     $r->print('
  <tr>
   <td>&nbsp;</td>
@@ -2061,113 +2163,33 @@ sub current_membership {
                                           'curf' => 'Current Functionality',
                                           '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('
+    my ($current,$hastools,$addtools,$num_reenable,$num_activate,$num_expire) =
+        &Apache::longroup::group_memberlist($cdom,$cnum,$groupname,$fixedprivs,
+                                            $available);
+    if (keys(%{$current}) > 0) {
+        $r->print('
  <tr>
   <td>&nbsp;</td>
   <td colspan="2">
    <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_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'});
+        }
+        &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>
@@ -2180,9 +2202,9 @@ sub current_membership {
      </nobr>
     </td>
 ');
-                }
             }
-            $r->print(<<"END");
+        }
+        $r->print(<<"END");
    </tr>
   </table>
   </td>
@@ -2195,8 +2217,8 @@ sub current_membership {
   <td>&nbsp;</td>
   <td colspan="3">
 END
-            $r->print(&Apache::lonhtmlcommon::start_pick_box());
-            $r->print(<<"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>
@@ -2208,135 +2230,134 @@ END
      <td><b><a href="javascript:changeSort('start')">$lt{'stda'}</a></b></td>
      <td><b><a href="javascript:changeSort('end')">$lt{'enda'}</a></b></td>
 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('<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">
  <td colspan="7">&nbsp;</td>
  <td colspan="'.$colspan.'" align="center"><small><nobr><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>');
                 }
+                $r->print('</nobr></small></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);
+        }
+        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 {
-                    push(@{$Sortby{$current{$user}{fullname}}},$user);
+                    $rowColor = $rowColor2;
                 }
-            }
-            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>'. 
+                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>'. 
    '<input type="checkbox" name="reenable" value="'.$user.'" />'.
    $lt{'reen'}.'</label></nobr><br />');
-                    } elsif ($current{$user}{changestate} eq 'expire') {
-                        $r->print('<nobr><label>'.
+                } elsif ($$current{$user}{changestate} eq 'expire') {
+                    $r->print('<nobr><label>'.
    '<input type="checkbox" name="expire" value="'.$user.'" />'.
    $lt{'expi'}.'</label></nobr><br />');
-                    } elsif ($current{$user}{changestate} eq 'activate') {
-                        $r->print('<nobr><label>'.
+                } elsif ($$current{$user}{changestate} eq 'activate') {
+                    $r->print('<nobr><label>'.
    '<input type="checkbox" name="activate" value="'.$user.'" />'.
    $lt{'acti'}.'</label></nobr><br />');
-                    }
-                    $r->print('<nobr><label>'.
+                }
+                $r->print('<nobr><label>'.
    '<input type="checkbox" name="deletion" value="'.$user.'" />'.
    $lt{'dele'}.'</label></nobr>');
-                    if ($specificity eq 'Yes') {
-                        $r->print('<br /><nobr><label>'.
+                if ($specificity eq 'Yes') {
+                    $r->print('<br /><nobr><label>'.
    '<input type="checkbox" name="changepriv" value="'.$user.'" />'.$lt{'chpr'}.
    '</label></nobr>');
-                    }
-                    $r->print('
+                }
+                $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>'.
+                if ($hastools) {
+                    $r->print('<td align="left"><small><nobr>'.
                                   '&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('</nobr></small></td>');
+                }
+                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"
                                           name="user_'.$tool.'" value="'.
                                           $user.'" />'.$tool.
                                           '</label></nobr>&nbsp;&nbsp;&nbsp;');
-                            }
-                        } else {
-                            foreach my $tool (@{$current{$user}{newtools}}) {
-                                $r->print('<nobr><input type="hidden" 
+                        }
+                    } else {
+                        foreach my $tool (@{$$current{$user}{newtools}}) {
+                            $r->print('<nobr><input type="hidden" 
                                           name="user_'. $tool.'" value="'.
                                           $user.'" />'.$tool.
                                           '</nobr>&nbsp;&nbsp;&nbsp;');
-                            }
                         }
-                        $r->print('</small></td>');
                     }
-                    $r->print('</tr>'."\n");
-                    $rowNum ++;
+                    $r->print('</small></td>');
                 }
+                $r->print('</tr>'."\n");
+                $rowNum ++;
             }
-            $r->print(&Apache::lonhtmlcommon::end_pick_box());
-            $r->print('
+        }
+        $r->print(&Apache::lonhtmlcommon::end_pick_box());
+        $r->print('
   </td>
  </tr>');
-        }
     }
     return;
 }
@@ -2364,13 +2385,13 @@ 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) = @_;
+       $rowColor2,$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));
@@ -2380,7 +2401,7 @@ sub change_privs_form {
         $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'));
+    &topic_bar($r,3,&mt('Members to delete or expire'));
     my $exp_or_del = 0;
     if (ref($$memchg{'deletion'}) eq 'ARRAY') {
         if (@{$$memchg{'deletion'}} > 0) {
@@ -2409,12 +2430,13 @@ sub change_privs_form {
                   '</td></tr><tr><td colspan="4">&nbsp;</td></tr>');
     }
     
-    &topic_bar($r,$tabcol,4,&mt('Group member privileges'));
+    &topic_bar($r,4,&mt('[_1] member privileges',$ucgpterm));
 
     my $numchgs = &member_privileges_form($r,$tabcol,$action,$formname,$tools,
                                           $toolprivs,$fixedprivs,$userdata,
                                           $usertools,$idx,$memchg,$states,
-                                          $stored,$rowColor1,$rowColor2);
+                                          $stored,$rowColor1,$rowColor2,
+                                          $gpterm);
     $r->print('</td></tr><tr><td colspan="4">&nbsp;</td></tr>');
     my $prevtext = $$navbuttons{'gtps'};
     if ($numchgs || $exp_or_del) {
@@ -2429,41 +2451,28 @@ sub change_privs_form {
 
 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">
-');
+        $description,$granularity,$quota,$sectioncount,$tools,$functions,
+        $stored,$states,$navbuttons,$rowColor1,$rowColor2,$gpterm,$ucgpterm)=@_; 
+    $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,$action,$formname,$sectioncount,1,$gpterm,$ucgpterm);
     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) = @_;
+       $states,$stored,$sectioncount,$navbuttons,$rowColor1,$rowColor2,
+       $gpterm,$ucgpterm,$crstype) = @_;
 
     my @regexps = ('userpriv_');
     my $nexttext;
@@ -2481,11 +2490,11 @@ sub choose_privs_form {
     }
 
     $r->print('<br /><table width="100%" cellpadding="0" cellspacing="0" border="0">');
-    &topic_bar($r,$tabcol,6,&mt('Group member privileges'));
+    &topic_bar($r,6,&mt('[_1] member privileges',$ucgpterm));
 
     &member_privileges_form($r,$tabcol,$action,$formname,$tools,$toolprivs,
                             $fixedprivs,$userdata,$usertools,$idx,undef,
-                            $states,$stored,$rowColor1,$rowColor2);
+                            $states,$stored,$rowColor1,$rowColor2,$gpterm);
 
     $r->print('</td></tr><tr><td colspan="4">&nbsp;</td></tr>');
     if ($action eq 'create') {
@@ -2494,7 +2503,7 @@ sub choose_privs_form {
             my $img2 = 8;
             &mapping_options($r,$action,$formname,$page,$tabcol,$sectioncount,
                              $states,$stored,$navbuttons,$img1,$img2,
-                             $rowColor1,$rowColor2);
+                             $rowColor1,$rowColor2,$gpterm,$ucgpterm,$crstype);
         }
     }
     my $prevtext = $$navbuttons{'gtps'};
@@ -2564,7 +2573,8 @@ function uncheckAllTools(formname) {
 
 sub member_privileges_form {
     my ($r,$tabcol,$action,$formname,$tools,$toolprivs,$fixedprivs,$userdata,
-        $usertools,$idx,$memchg,$states,$stored,$rowColor1,$rowColor2) = @_;
+        $usertools,$idx,$memchg,$states,$stored,$rowColor1,$rowColor2,
+        $gpterm) = @_;
     my %lt = &Apache::lonlocal::texthash(
             'addp' => 'Additional privileges',
             'fixp' => 'Fixed privileges',
@@ -2573,15 +2583,15 @@ sub member_privileges_form {
             '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.',
-            '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, '.
-                      'there are no specific user privileges to set.',
-            '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 ',
+            'algr' => "All $gpterm members will receive the same privileges.",
+            'asno' => "As no $gpterm members are being added, ".
+                      "there are no specific user privileges to set.",
+            'asng' => "As no $gpterm tools will be made available to users, ".
+                      "there are no specific user privileges to set.",
+            'nogm' => "No $gpterm 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 ",
             'full' => 'Fullname',
             'user' => 'Username',
             'doma' => 'Domain',
@@ -2740,12 +2750,14 @@ sub process_request {
     my ($r,$cdom,$cnum,$tabcol,$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,$rowColor1,$rowColor2,$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">
@@ -2791,13 +2803,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);
     }
     return;
 }
@@ -2805,7 +2819,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'};
@@ -2813,12 +2827,28 @@ 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(&mt('The value you entered for the quota for the file repository in this [_1] contained invalid characters, so it has been set to 0 Mb. You can change this by modifying the [_1] settings.<br />',$gpterm));
+    }
+    if ($quota > $maxposs) {
+        $quota = $maxposs;
+        $r->print(&mt('The value you entered for the quota for the file repository in this [_1] exceeded the maximum possible value, so it has been set to [_2] Mb (the maximum possible value).<br />',$gpterm,$maxposs));
+    }
     my %groupinfo = (
                      description => $esc_description,
                      startdate => $startdate,
@@ -2830,7 +2860,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})) {
@@ -2877,34 +2909,43 @@ 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 />');
+            my $result = &add_group_folder($cdom,$cnum,$now,$groupname,$action,
+                                           $description,$tools,\%groupinfo,
+                                           $gpterm,$ucgpterm,$crstype);
+            if ($result ne 'ok') {
+                $r->print(&mt('A problem occurred when creating folders for the new [_1]. [_2].<br />',$gpterm,$result));
+            }
+            $r->print(&mt('[_1] [_2] was created.<br />',$ucgpterm,$groupname));
         } else {
-            $r->print('Group '.$groupname.' was updated.<br />');
+            $r->print(&mt('[_1] [_2] was updated.<br />',$ucgpterm,$groupname));
         }
     } 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(&mt('An error occurred when [_1] the [_2]. '.
+                      'Please try again.',$actiontype{$action},$gpterm));
     }
     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)=@_;
     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 = ();
 
     foreach my $tool (@{$tools}) {
@@ -2923,7 +2964,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.':';
@@ -2943,6 +2984,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'}};
@@ -2956,21 +2998,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}) eq 'ok') {
                     push(@{$added{'expired'}},$user);
                     $num_ok ++;
                 } else {
@@ -2994,22 +3040,40 @@ 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) {
+                    $start = $startdate;
+                    $end = $enddate;
                     $type = 'reenabled';
                 }
             }
+            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';
         }
@@ -3030,7 +3094,7 @@ sub process_membership {
     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')) {   
+            if (!($type eq 'deleted' || $type eq 'expired')) {   
                 $r->print(&mt(' with the following privileges'));
             }
             $r->print(':<br />');
@@ -3051,6 +3115,7 @@ sub process_membership {
                 }
                 $r->print($$userdata{$user}[$$idx{fullname}].'&nbsp;-&nbsp;'.$user.$privlist.'<br />');
             }
+            $r->print('<br />');
         }
     }
     if ($num_fail) {
@@ -3060,32 +3125,42 @@ sub process_membership {
                 $r->print($$userdata{$user}[$$idx{fullname}].' - '.$user.'<br />');
             }
         }
+        $r->print('<br />');
+    }
+    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 />'.&mt('Group membership list updated.'));
+        $r->print('<br />'.&mt('[_1] membership list updated.',$ucgpterm));
+	$r->print('<p>'.&mt("For full access to all of [_1]'s privileges, users will need to log out and log back in.",$groupname).'</p>');
     } else {
-        $r->print('<br />'.&mt('An error occurred while updating the group membership list -').$roster_result.'<br />');
+        $r->print('<br />'.&mt('An error occurred while updating the [_1] membership list -',$gpterm).$roster_result.'<br />');
     }
     return;
 }
 
 sub mapping_options {
     my ($r,$action,$formname,$page,$tabcol,$sectioncount,$states,$stored,
-        $navbuttons,$img1,$img2,$rowColor1,$rowColor2) = @_;
+        $navbuttons,$img1,$img2,$rowColor1,$rowColor2,$gpterm,$ucgpterm,
+        $crstype) = @_;
     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',
+        '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 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",
         'curr' => 'Currently set to',
         '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('
@@ -3093,7 +3168,7 @@ sub mapping_options {
     <td colspan="4">&nbsp;</td>
    </tr>');
     &mapping_settings($r,$tabcol,$rowColor1,$rowColor2,$sectioncount,\%lt,
-                                                       $stored,$img2);
+                      $stored,$img2,$crstype);
     return;
 }
 
@@ -3107,7 +3182,7 @@ sub automapping {
     if (exists($$stored{'autodrop'})) {
         $drop = $$stored{'autodrop'};
     }
-    &topic_bar($r,$tabcol,$image,$$lt{'endi'});
+    &topic_bar($r,$image,$$lt{'endi'});
     $r->print('
   <tr>
    <td>&nbsp;</td>
@@ -3153,14 +3228,15 @@ sub automapping {
 }
 
 sub mapping_settings {
-    my ($r,$tabcol,$rowColor1,$rowColor2,$sectioncount,$lt,$stored,$image) = @_;
+    my ($r,$tabcol,$rowColor1,$rowColor2,$sectioncount,$lt,$stored,$image,
+        $crstype) = @_;
     my @sections = keys(%{$sectioncount});
     if (@sections > 0) {
         @sections = sort {$a cmp $b} @sections;
         unshift(@sections,'none'); # Put 'no sections' next
         unshift(@sections,'all'); # Put 'all' at the front of the list
     }
-    &topic_bar($r,$tabcol,$image,$$lt{'pirs'});
+    &topic_bar($r,$image,$$lt{'pirs'});
     $r->print('
    <tr>
     <td>&nbsp;</td>
@@ -3179,7 +3255,7 @@ sub mapping_settings {
     my $rowNum = 0;
     my $rowColor;
     foreach my $role (@roles) {
-        my $plrole=&Apache::lonnet::plaintext($role);
+        my $plrole=&Apache::lonnet::plaintext($role,$crstype);
         my $sections_sel;
         if (@sections > 0) {
             if ($role eq 'cc') {
@@ -3239,10 +3315,10 @@ sub my_custom_roles {
 }
 
 sub modify_menu {
-    my ($r,$groupname,$page) = @_;
+    my ($r,$groupname,$page,$gpterm) = @_;
     my @menu =
         (
-          { text => 'Modify default group settings',
+          { text => "Modify default $gpterm settings",
             help => 'Course_Modify_Group',
             state => 'change_settings',
             branch => 'settings',
@@ -3253,7 +3329,7 @@ sub modify_menu {
             state => 'change_members',
             branch => 'members',
             },
-          { text => 'Add member(s) to the group',
+          { text => "Add member(s) to the $gpterm",
             help => 'Course_Group_Add_Members',
             state => 'add_members',
             branch => 'adds',
@@ -3366,21 +3442,175 @@ sub date_setting_table {
     return ($start_table, $end_table);
 }
 
+sub add_group_folder {
+    my ($cdom,$cnum,$now,$groupname,$action,$description,$tools,$groupinfo,
+        $gpterm,$ucgpterm,$crstype) = @_;
+    if ($cdom eq '' || $cnum eq '') {
+        return &mt('Error: invalid course domain or number - group folder creation failed');  
+    }
+    my ($outcome,$allgrpsmap,$grpmap,$boardsmap,$grppage);
+    my $navmap = Apache::lonnavmaps::navmap->new();
+    my $crspath = '/uploaded/'.$cdom.'/'.$cnum.'/';
+    $allgrpsmap = $crspath.'default_0.sequence';
+    my $topmap = $navmap->getResourceByUrl($allgrpsmap);
+    undef($navmap);
+    if ($action eq 'create') {
+    # check if default_0.sequence exists.
+        if (!$topmap) {
+            my $grpstitle = &mt('[_1] [_2]',$crstype,$ucgpterm);
+            my $topmap_url = '/'.$env{'course.'.$env{'request.course.id'}.'.url'};
+            $topmap_url =~ s|/+|/|g;
+            if ($topmap_url =~ m|^/uploaded|) {
+                $outcome = &map_updater($cdom,$cnum,'default_0.sequence',
+                                        'toplevelgroup',$grpstitle,$topmap_url);
+                if ($outcome ne 'ok') {
+                    return $outcome;
+                }
+            } else {
+                $outcome = &mt('Non-standard course - group folder not added.');
+                return $outcome;
+            }
+        }
+        my $grpfolder = &mt('[_1] Folder -',$ucgpterm,).$description;
+        $grppage='/adm/'.$cdom.'/'.$cnum.'/'.$groupname.'/grppg';
+        my $grptitle = &mt('Group homepage').' - '.$description;
+        my ($seqid,$discussions,$disctitle);
+        my $outcome = &map_updater($cdom,$cnum,'default_'.$now.'.sequence',
+                                   'grpseq',$grpfolder,$allgrpsmap,$grppage,
+                                   $grptitle);
+        if ($outcome ne 'ok') {
+            return $outcome;
+        }
+        my $pageout = &create_homepage($cdom,$cnum,$groupname,$groupinfo,
+                                       $tools,$gpterm,$ucgpterm,$now);
+        # Link to folder for bulletin boards
+        $grpmap = $crspath.'default_'.$now.'.sequence';
+        if (grep/^discussion$/,@{$tools}) {
+            $seqid = $now + 1;
+            $disctitle = &mt('Discussion Boards');
+            my $outcome = &map_updater($cdom,$cnum,'default_'.$seqid.
+                                       '.sequence','bbseq',$disctitle,$grpmap);
+            if ($outcome ne 'ok') {
+                return $outcome;
+            }
+            $boardsmap = $crspath.'default_'.$seqid.'.sequence';
+        }
+    } else {
+        #modify group folder if status of discussions tools is changed
+    }
+    my ($furl,$ferr)= &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
+    $navmap = Apache::lonnavmaps::navmap->new();
+    # modify parameters
+    my $parm_result;
+    if ($action eq 'create') {
+        if ($allgrpsmap) { 
+            $parm_result .= &parm_setter($navmap,$cdom,$allgrpsmap,$groupname);
+        }
+        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);
+        }
+    }
+    if ($parm_result) {
+        return $parm_result;
+    } 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 = &mt('Error uploading new folder.')." ($newfile): $newmapurl".'<br />';
+        return $outcome;
+    } 
+    my ($errtext,$fatal)=&Apache::lonratedt::mapread($parentmap);
+    if ($fatal) {
+        $outcome = &mt('Error reading contents of parent folder')." ($parentmap): $errtext".'<br />';
+        return $outcome;
+    } else {
+        my $newidx=&Apache::lonratedt::getresidx($newmapurl);
+        $Apache::lonratedt::resources[$newidx] = $itemtitle.':'.$newmapurl.
+                                                 ':false:normal:res';
+        $Apache::lonratedt::order[1+$#Apache::lonratedt::order]=$newidx;
+        my ($outtext,$errtext) = &Apache::lonratedt::storemap($parentmap,1);
+        if ($errtext) {
+            $outcome = &mt('Error storing updated parent folder')." ($parentmap):  $errtext".'<br />';
+            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) = @_;
+    my $allresults;
+    my %hide_settings = (
+                           'course' =>  {
+                                          'num' => 13,
+                                          'set' => 'yes',
+                                        },
+                            'group' =>  {
+                                          'num' => 5,
+                                          'set' => 'no',
+                                          'extra' => $groupname,
+                                        },
+                        );
+    my $res = $navmap->getResourceByUrl($url);
+    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;
+        }
+    }
+    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});
+    my $content = &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 %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;
@@ -3422,22 +3652,22 @@ function toggleTools(field,caller) {
 }
 
 sub validate_groupname {
-    my ($groupname,$action,$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 %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",
+                      tgne => "The $gpterm name entered ",
+                      grna => "$ucgpterm names and section names used in a ".
+                               "$crstype must be unique.",
+                      isno => "is not a valid name.",
+                      gnmo => "$ucgpterm names may only contain letters, ". 
+                              "numbers or underscores.",
+                      cnnb => "can not be used as it is the name of ",
+                      inth => " in this $crstype", 
+                      thgr => "- does not correspond to the name of an ".
+                              "existing $gpterm",    
     );
 
     my $exitmsg = '<b>'.$lt{'igna'}.'</b><br /><br />'.$lt{'tgne'}.' "'.
@@ -3455,12 +3685,13 @@ sub validate_groupname {
     if ($action eq 'create' 
 	&& exists($curr_groups{$groupname})) {
 
-	return $exitmsg.$lt{'cnnb'}.&mt('an existing group').
+	return $exitmsg.$lt{'cnnb'}.&mt('an existing [_1]',$gpterm).
 	    $lt{'inth'}.'<br />'.$lt{'grna'};
 
     } elsif ($action eq 'modify') {
         unless(exists($curr_groups{$groupname})) {
-            $earlyout = &mt('Group name:').' '.$groupname.$lt{'thgr'}.$lt{'inth'};
+            $earlyout = &mt('[_1] name:',$ucgpterm).' '.$groupname.$lt{'thgr'}.
+                        $lt{'inth'};
             return $earlyout;
         }
     }
@@ -3468,22 +3699,12 @@ sub validate_groupname {
 }
 
 sub topic_bar {
-    my ($r,$tabcol,$imgnum,$title) = @_;
+    my ($r,$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>
+<div class="LC_topic_bar">
+    <img src="/res/adm/pages/bl_step'.$imgnum.'.gif" />&nbsp;
+    <span>'.$title.'<span>
+</div>
 ');
     return;
 }