--- loncom/interface/loncoursegroups.pm	2006/07/19 23:28:20	1.53
+++ loncom/interface/loncoursegroups.pm	2009/11/06 19:49:26	1.104
@@ -1,6 +1,6 @@
 # The LearningOnline Network with CAPA
 #
-# $Id: loncoursegroups.pm,v 1.53 2006/07/19 23:28:20 raeburn Exp $
+# $Id: loncoursegroups.pm,v 1.104 2009/11/06 19:49:26 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -29,13 +29,14 @@ package Apache::loncoursegroups;
 
 use strict;
 use Apache::lonnet;
-use Apache::loncommon;
-use Apache::lonhtmlcommon;
+use Apache::loncommon();
+use Apache::lonhtmlcommon();
 use Apache::lonlocal;
-use Apache::lonnavmaps;
-use Apache::longroup;
-use Apache::portfolio;
+use Apache::lonnavmaps();
+use Apache::longroup();
+use Apache::portfolio();
 use Apache::Constants qw(:common :http);
+use LONCAPA::map();
 use lib '/home/httpd/lib/perl/';
 use LONCAPA;
 
@@ -53,7 +54,7 @@ sub handler {
     if (! ($env{'request.course.fn'})) {
         # Not in a course
         $env{'user.error.msg'}=
-     "/adm/coursegroups:mdg:0:0:Cannot edit or view course groups";
+     "/adm/coursegroups:mdg:0:0:Cannot edit or view course/community groups";
         return HTTP_NOT_ACCEPTABLE;
     }
 
@@ -74,11 +75,11 @@ sub handler {
     my $crstype = &Apache::loncommon::course_type();
 
     my %functions = (
-                      email => 'E-mail',
-                      discussion => 'Discussion boards',
-                      chat => 'Chat',
-                      files => 'File repository',
-                      roster => 'Membership roster',
+                      email => 'Send Messages', 
+                      discussion => 'Discussion Boards',
+                      chat => 'Chat Room',
+                      files => 'Group Portfolio',
+                      roster => 'Membership Roster',
                       homepage => $ucgpterm.' home page',
                     );
 
@@ -91,12 +92,13 @@ sub handler {
 
     my $action = $env{'form.action'};
     my $state = $env{'form.state'};
-    if ((!defined($action)) || ($action eq 'view') || ($action eq 'modify')) {
+    if ((!defined($action)) || ($action eq 'view') || ($action eq 'modify') || ($action eq 'delete') || ($action eq 'reenable')) {
         if (!defined($state)) {
             $state = 'view';
         }
     }
-    if ($action eq 'create' || $action eq 'modify' || $action eq 'view') { 
+    if ($action eq 'create' || $action eq 'modify' || $action eq 'view' || 
+        $action eq 'delete' || $action eq 'reenable') { 
         if ($view_permission || $manage_permission) {
             if ($state eq 'view') {
                 &print_main_menu($r,$cdom,$cnum,\%functions,\%idx,
@@ -109,8 +111,10 @@ sub handler {
 		   		      $crstype);
             }
         } else {
-            $r->print(&mt('You do not have [_1] administration '.
-                          'privileges in this [_2]',$gpterm,lc($crstype)));
+            $r->print('<div class="LC_warning">'
+                     .&mt('You do not have '.$gpterm.' administration '
+                         .'privileges in this '.lc($crstype).'.')
+                     .'</div>');
         }
     } else {
         &print_main_menu($r,$cdom,$cnum,\%functions,\%idx,$view_permission,
@@ -127,17 +131,30 @@ sub print_main_menu {
 function changeSort(caller) {
     document.$state.sortby.value = caller;
     document.$state.submit();
+}
+function openGroupRoster(group,status) {
+    var url = '/adm/grouproster?';
+    url += 'group='+group+'&status='+status+'&ref=popup';
+    var title = 'Group Membership';
+    var options = 'scrollbars=1,resizable=1,menubar=0';
+    options += ',width=700,height=600';
+    rosterbrowser = open(url,title,options,'1');
+    rosterbrowser.focus();
 }\n|;
-    $r->print(&header('Groups',$jscript,$action,$state));
-    if ($env{'form.refpage'} eq 'enrl') {
+    $r->print(&header('My Space',$jscript,$action,$state));
+    if ($env{'form.refpage'} eq 'cusr') {
         &Apache::lonhtmlcommon::add_breadcrumb
-            ({href=>"/adm/dropadd",
-              text=>"Enrollment Manager"});
+            ({href=>"/adm/createuser",
+              text=>"User Management"});
     }
     &Apache::lonhtmlcommon::add_breadcrumb
         ({href=>"/adm/coursegroups",
           text=>"Groups"});
-    $r->print(&Apache::lonhtmlcommon::breadcrumbs('Groups'));
+    my $helpitem;
+    if ($manage_permission) {
+        $helpitem = 'Creating_Groups';
+    }
+    $r->print(&Apache::lonhtmlcommon::breadcrumbs('Groups',$helpitem));
     &display_groups($r,$cdom,$cnum,$functions,$idx,$view_permission,
 		    $manage_permission,$action,$state,$gpterm,$ucgpterm,
 		    $crstype);
@@ -155,12 +172,15 @@ sub display_groups {
                          $env{'form.refpage'}.'&state=pick_task&groupname=',
       view => '<a href="/adm/'.$cdom.'/'.$cnum.'/',
       delete => '<a href="/adm/coursegroups?action=delete&refpage='.
-                         $env{'form.refpage'}.'&groupname=',
+                         $env{'form.refpage'}.'&state=verify&groupname=',
+      reenable => '<a href="/adm/coursegroups?action=reenable&refpage='.
+                         $env{'form.refpage'}.'&state=verify&groupname=',
     );
     my %lt = &Apache::lonlocal::texthash( 
                           modify => 'Modify',
                           view   => 'View',
                           delete => 'Delete',
+                          reenable => 'Re-enable',
                           act    => 'Action',
                           gname  => 'Group Name',
                           desc   => 'Group Title',
@@ -175,20 +195,38 @@ sub display_groups {
                           dius   => 'Disk Use (%)',
                           nogr   => 'No groups exist.',
                           crng   => 'Create a new group',
+                          redg   => 'Re-enable a deleted group',
                           alth   => 'Although your current role has privileges'.
-                                    ' to view any existing groups in this'.
-                                    lc($crstype).', you do not have privileges'.
+                                    ' to view any existing groups in this '.
+                                    lc($crstype).', you do not have privileges '.
                                     'to create new groups.',
                      );
     if ($view_permission) {
         if (!defined($action)) {
             $action = 'view';
         }
-        my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum);
+        my ($status,$reenable_link);
+        if ($action eq 'reenable') {
+            $status = 'deleted_groups';
+        } else {
+            if ($manage_permission) {
+                my %deleted_groups = 
+                    &Apache::longroup::coursegroups($cdom,$cnum,undef,'deleted_groups');
+                if (keys(%deleted_groups) > 0) {
+                    $reenable_link = '&nbsp;&nbsp;&nbsp;&nbsp;<a href="/adm/coursegroups?action=reenable&amp;refpage='.$env{'form.refpage'}.'">'.$lt{'redg'}.'</a>';
+                }
+            }
+        }
+        my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum,undef,
+                                                          $status);
+
         if (%curr_groups) {
             if ($manage_permission) {
-                if (!exists($env{'form.refpage'})) { 
-                    $r->print('<br /><a href="/adm/coursegroups?action=create">'.$lt{'crng'}.'</a>');
+                if ($action ne 'reenable') {
+                    $r->print('<br /><a href="/adm/coursegroups?action=create&amp;refpage='.$env{'form.refpage'}.'">'.$lt{'crng'}.'</a>');
+                }
+                if ($reenable_link) {
+                    $r->print($reenable_link);
                 }
             }
             $r->print('<br /><br />');
@@ -218,13 +256,13 @@ END
                 my $members_result = &group_members($cdom,$cnum,$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);
+                &group_files($group,$port_path,\$totalfiles,\$totaldirs);
                 $grp_info{$group}{'totalfiles'} = $totalfiles;
                 $grp_info{$group}{'totaldirs'} = $totaldirs;
-                my $diskuse = &Apache::lonnet::diskusage($cdom,$cnum,$port_dir);
+                my $getpropath = 1;  
+                my $diskuse = &Apache::lonnet::diskusage($cdom,$cnum,$port_path,                                                         $getpropath);
                 if ($grp_info{$group}{'quota'} > 0) {
                     my $pct_use = 0.1 * $diskuse/$grp_info{$group}{'quota'};
                     $grp_info{$group}{'diskuse'} = sprintf("%.0f",$pct_use);
@@ -282,7 +320,8 @@ END
                         $functionality = &mt('None available');
                     }
                     my $link = $actionlinks{$action};
-                    if ($action eq 'modify' || $action eq 'delete') {
+                    if ($action eq 'modify' || $action eq 'delete' || 
+                        $action eq 'reenable') {
                         $link .= $group;
                     } else {
                         $link .= $group.'/smppg?ref=grouplist';
@@ -292,10 +331,11 @@ END
                     }
                     $link .= '">'.$lt{$action}.'</a>';
                     if ($action eq 'view') { 
-                        if (($manage_permission) && 
-                            ($env{'form.refpage'} ne 'enrl')) {
+                        if ($manage_permission) { 
                             $link .= '&nbsp;&nbsp;'.$actionlinks{'modify'}.
-                                      $group.'">'.$lt{'modify'}.'</a>';
+                                      $group.'">'.$lt{'modify'}.'</a>'.
+                                     '&nbsp;&nbsp;'.$actionlinks{'delete'}.
+                                      $group.'">'.$lt{'delete'}.'</a>';
                         }
                     }
                     $r->print(&Apache::loncommon::start_data_table_row('LC_data_table_dense').
@@ -308,7 +348,10 @@ END
 			      '<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">'.
+                                  '<span class="LC_nobreak">'.&mt('Files: [_1]',$totalfiles).'</span><br />'.
+                                  '<span class="LC_nobreak">'.&mt('Folders: [_1]',$totaldirs).'</span>'.
+                                  '</td>'.
 			      '<td align="right">'.$boards.'</td>'.
 			      '<td align="right">'.$diskuse.'</td>'.
 			      &Apache::loncommon::end_data_table_row());
@@ -327,12 +370,14 @@ END
         } else {
             $r->print($lt{'nogr'});
             if ($manage_permission) {
-                if (!exists($env{'form.refpage'})) {
-                    $r->print('<br /><br /><a href="/adm/coursegroups?action=create">'.$lt{'crng'}.'</a>');
+                $r->print('<br /><br /><a href="/adm/coursegroups?action=create&amp;refpage='.$env{'form.refpage'}.'">'.$lt{'crng'}.'</a>');
+                if ($action ne 'reenable') {
+                    if ($reenable_link) {
+                        $r->print($reenable_link);
+                    }
                 }
             } else {
                 $r->print('<br /><br />'.$lt{'alth'});
-
             }
         }
     } else {
@@ -350,9 +395,7 @@ END
                 }
             }
         } else {
-            $r->print(&mt('You are not currently a member of any '.
-                          'active [_1]s in this [_2]',$gpterm,
-                          lc($crstype)));
+            $r->print(&mt('You are not currently a member of any active '.$gpterm.'s in this '.lc($crstype).'.'));
         }
     }
     return;
@@ -366,7 +409,6 @@ sub group_administration {
     my @types = ();
     my @roles = ();
     my @sections = ();
-    my @buildsections = ();
     my %users = ();
     my %userdata = ();
     my @members = ();
@@ -420,7 +462,7 @@ sub group_administration {
                 $state = 'pick_task';
             }
         } else {
-            %stored = &retrieve_settings($cdom,$cnum,$groupname);
+            %stored = &retrieve_settings($cdom,$cnum,$groupname,$action);
             if (ref($stored{'types'}) eq 'ARRAY') {
                 @types = @{$stored{'types'}};
             }
@@ -495,7 +537,7 @@ sub group_administration {
 
     if (ref($stored{'autorole'}) eq 'ARRAY') {
         foreach my $role (@{$stored{'autorole'}}) {
-            unless ($role eq 'cc') {
+            unless (($role eq 'cc') || ($role eq 'co')) {
                 $elements{'modify'}{'change_settings'}{'sec_'.$role} = 
                                                                    'selectbox';
             }
@@ -526,16 +568,11 @@ sub group_administration {
         }
         if (defined($env{'form.sectionpick'})) {
             @sections=&Apache::loncommon::get_env_multiple('form.sectionpick');
-            if (grep/^all$/,@sections) {
-                @buildsections = sort {$a cmp $b} keys(%sectioncount);
-            } else {
-                @buildsections = @sections;
-            }
         }
     }
 
     if (($state eq 'pick_members') || ($state eq 'pick_privs') || ($state eq 'change_privs')) {
-        &build_members_list($cdom,$cnum,\@types,\@roles,\@buildsections,\%users,
+        &build_members_list($cdom,$cnum,\@types,\@roles,\@sections,\%users,
                             \%userdata);
     }
     if ($state eq 'pick_members') {
@@ -748,7 +785,7 @@ sub group_administration {
     }
     var maxposs = '.sprintf("%.2f",$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.");
+        alert("The group portfolio quota you entered for this group ("+newquota+" Mb) exceeds the maximum possible ("+maxposs+" Mb). Please enter a smaller number.");
         return;
     }
     var re_quota = '.$float_check.';
@@ -767,7 +804,7 @@ sub group_administration {
             }
         }
         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.");
+            alert("You have indicated that the group portfolio 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;
         }
     } 
@@ -798,6 +835,8 @@ function changeSort(caller) {
     my %branchstates = ();
     @{$states{'create'}} = ('pick_name','pick_members','pick_privs','result');
     @{$states{'modify'}} = ('pick_task');
+    @{$states{'delete'}} = ('verify','result');
+    @{$states{'reenable'}} = ('verify','result');
     @{$branchstates{'noprivs'}} = ('result');
     @{$branchstates{'settings'}} = ('change_settings','chgresult');
     @{$branchstates{'members'}} = ('change_members','change_privs','memresult');
@@ -808,7 +847,7 @@ function changeSort(caller) {
         push (@{$states{$action}},@{$branchstates{$env{'form.branch'}}});
     }
 
-    if (($action eq 'create') || ($action eq 'modify')) {
+    if (($action eq 'create') || ($action eq 'modify') || ($action eq 'delete') || ($action eq 'reenable')) {
         my $done = 0;
         my $i=0;
         while ($i<@{$states{$action}} && !$done) {
@@ -824,14 +863,14 @@ function changeSort(caller) {
     $r->print(&header("Groups Manager",
 		      $jscript,$action,$state,$page,$loaditems));
 
-    if ($env{'form.refpage'} eq 'enrl') {
+    if ($env{'form.refpage'} eq 'cusr') {
         &Apache::lonhtmlcommon::add_breadcrumb
-        ({href=>"/adm/dropadd",
-          text=>"Enrollment Manager",
+        ({href=>"/adm/createuser",
+          text=>"User Management",
           faq=>9,bug=>'Instructor Interface',});
-        if ($action eq 'modify') {
+        if ($action eq 'modify' || $action eq 'delete') {
             &Apache::lonhtmlcommon::add_breadcrumb
-            ({href=>"/adm/coursegroups?refpage=enrl&action=modify",
+            ({href=>"/adm/coursegroups?refpage=cusr&action=$action",
               text=>"Groups",
               faq=>9,bug=>'Instructor Interface',});
         }
@@ -840,6 +879,11 @@ function changeSort(caller) {
           ({href=>"/adm/coursegroups",
             text=>"Groups",
             faq=>9,bug=>'Instructor Interface',});
+        if ($env{'form.refpage'} eq 'grouplist') {
+            &Apache::lonhtmlcommon::add_breadcrumb
+             ({href=>"/adm/$cdom/$cnum/$env{'form.groupname'}/smppg?ref=grouplist",
+               text=>"Group: $description",});
+        }
     }
 
     my %trail = ();
@@ -862,22 +906,30 @@ function changeSort(caller) {
                             memresult => 'Modifications Complete',
                             addresult => 'Additions Complete',
                           );
+    %{$trail{'delete'}} = &Apache::lonlocal::texthash(
+                            verify => 'Verify deletion',
+                            result => 'Deletion Complete'
+                          );
+    %{$trail{'reenable'}} = &Apache::lonlocal::texthash(
+                            verify => 'Verify Re-enable',
+                            result => 'Re-enabled'
+                          );
     my %navbuttons = &Apache::lonlocal::texthash(
-                             gtns => 'Go to next step',
-                             gtps => 'Go to previous step',
+                             gtns => 'Next',#'Go to next step',
+                             gtps => 'Back',#'Go to previous step',
                              crgr => 'Create '.$gpterm,
-                             mose => 'Modify settings',
-                             gtpp => 'Go to previous page',
+                             mose => 'Save',#'Modify settings',
+                             gtpp => 'Back',#'Go to previous page',
                              adme => 'Add members',
     );
-    if ((($action eq 'create') || ($action eq 'modify')) &&
+    if ((($action eq 'create') || ($action eq 'modify') || ($action eq 'delete') || ($action eq 'reenable')) &&
               ($manage_permission)) {
         for (my $i=0; $i<@{$states{$action}}; $i++) {
             if ($state eq $states{$action}[$i]) {
                 &Apache::lonhtmlcommon::add_breadcrumb(
                    {text=>"$trail{$action}{$state}"});
                 $r->print(&Apache::lonhtmlcommon::breadcrumbs
-			  ("Groups Manager"));
+			  ("Groups Manager","Creating_Groups"));
                 &display_control($r,$cdom,$cnum,$action,$state,$page,
                        \%sectioncount,$groupname,$description,$functions,
                        \@tools,$toolprivs,$fixedprivs,$startdate,$enddate,
@@ -888,16 +940,18 @@ function changeSort(caller) {
 				 $crstype);
                 last;
             } else {
-                if (($state eq 'result') && ($i > 0)) {
-                    &Apache::lonhtmlcommon::add_breadcrumb(
+                if (($action eq 'create') || ($action eq 'modify')) {
+                    if (($state eq 'result') && ($i > 0)) {
+                        &Apache::lonhtmlcommon::add_breadcrumb(
     {href=>"javascript:backPage(document.$state,'$states{$action}[0]')",
       text=>"$trail{$action}{$states{$action}[$i]}"});
-                } else { 
-                    &Apache::lonhtmlcommon::add_breadcrumb(
+                    } else { 
+                        &Apache::lonhtmlcommon::add_breadcrumb(
      {href=>"javascript:backPage(document.$state,'$states{$action}[$i]')",
       text=>"$trail{$action}{$states{$action}[$i]}"});
+                    }
                 }
-            }
+            }             
         }
     } elsif (($action eq 'view') && ($view_permission)) {
                         &Apache::lonhtmlcommon::add_breadcrumb(
@@ -907,15 +961,22 @@ function changeSort(caller) {
         &display_groups($r,$cdom,$cnum,$functions,$idx,$view_permission,
 			$manage_permission,$action,$state,$gpterm,$ucgpterm,
 			$crstype);
-
     }
     $r->print(&footer());
     return;
 }
 
 sub retrieve_settings {
-    my ($cdom,$cnum,$groupname) = @_;
-    my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum,$groupname);
+    my ($cdom,$cnum,$groupname,$action) = @_;
+    my %curr_groups;
+    my $namespace;
+    if ($action eq 'reenable') {
+        $namespace = 'deleted_groups';
+    } else {
+        $namespace = 'coursegroups';
+    }
+    %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum,$groupname,
+                                                   $namespace);
 
     return if (!%curr_groups);
 
@@ -960,6 +1021,7 @@ sub retrieve_settings {
 	foreach my $role (sort(keys(%{$groupinfo{'autosec'}}))) {
             if (ref($groupinfo{'autosec'}{$role}) eq 'ARRAY') {
 	        foreach my $section (@{$groupinfo{'autosec'}{$role}}) {
+
 	            push (@{$stored{'sec_'.$role}},$section);
 	        }
 	        if (@{$groupinfo{'autosec'}{$role}} > 0) {
@@ -1021,10 +1083,10 @@ sub display_control {
                                  $userdata,$granularity,$quota,$specificity,
                                  $idx,$states,$navbuttons,$gpterm,$ucgpterm);
         } elsif ($state eq 'add_members') {
-            &add_members_form($r,$action,$state,$page,$startdate,
+            &add_members_form($r,$cdom,$cnum,$action,$state,$page,$startdate,
                               $enddate,$groupname,$description,$granularity,
                               $quota,$sectioncount,$tools,$functions,$stored,
-                              $states,$navbuttons,$gpterm,$ucgpterm);
+                              $states,$navbuttons,$gpterm,$ucgpterm,$crstype);
         } elsif ($state eq 'pick_members') {
             &choose_members_form($r,$cdom,$cnum,$action,$state,$page,
                                  $groupname,$description,$granularity,$quota,
@@ -1053,7 +1115,346 @@ sub display_control {
                              $sections,$states,$navbuttons,$memchg,
                              $sectioncount,$stored,$gpterm,$ucgpterm,$crstype);
         }
+    } elsif ($action eq 'delete') {
+        my %stored = &retrieve_settings($cdom,$cnum,$groupname,$action);
+        if ($state eq 'verify') {
+            &verify_delete($r,$groupname,$state,$action,$page,$states,
+                           \%stored,$crstype);
+        } elsif ($state eq 'result') {
+            &delete_group($r,$cdom,$cnum,$groupname,$crstype);
+        }
+    } elsif ($action eq 'reenable') {
+        my %stored = &retrieve_settings($cdom,$cnum,$groupname,$action);
+        if ($state eq 'verify') {
+            &verify_reenable($r,$groupname,$state,$action,$page,$states,
+                           \%stored,$crstype);
+        } elsif ($state eq 'result') {
+            &reenable_group($r,$cdom,$cnum,$groupname,$crstype);
+        }
+    }
+}
+
+sub verify_delete {
+    my ($r,$groupname,$formname,$action,$page,$states,$stored,$crstype) = @_;
+    $r->print(&Apache::lonhtmlcommon::echo_form_input([]));
+    $r->print(&mt('You have requested deletion of the group [_1].'
+                 ,'<i>'.$stored->{'description'}.'</i>').
+              '<br /><br />'.&mt('When a group is deleted the following occurs:').'<ul>'.
+              '<li>'.&mt('All group membership is terminated.').'</li>'.
+              '<li>'.&mt('The group ceases to be available either for viewing or for modification of group settings and membership.').'</li>');
+    if ($crstype eq 'Community') {
+        $r->print( '<li>'.&mt("The group folder is removed from the folder containing it - normally this is the 'Community Groups' folder which contains folders for all groups in the community.").'</li>'.
+                   '</ul>'.&mt("Although a deleted group is no longer accessible, the group name used for the group will be reserved, and will not be available for assignment to a new group in the same community in the future."));
+    } else { 
+        $r->print( '<li>'.&mt("The group folder is removed from the folder containing it - normally this is the 'Course Groups' folder which contains folders for all groups in the course.").'</li>'.
+                   '</ul>'.&mt("Although a deleted group is no longer accessible, the group name used for the group will be reserved, and will not be available for assignment to a new group in the same course in the future."));
+    }
+    my $prevtext = &mt('Go back');
+    my $nexttext = &mt('Delete group');
+    my $prev;
+    if ($env{'form.refpage'} eq 'cusr')  {
+        $prev = 'view';
+    }
+    &display_navbuttons($r,$formname,$prev,$prevtext,
+                        $$states{$action}[$page+1],$nexttext);
+    return;
+}
+
+sub delete_group {
+    my ($r,$cdom,$cnum,$groupname,$crstype) = @_;
+    my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum,
+                                                           $groupname);
+    my $now = time;
+    my $num_users = 0;
+    my $num_fail = 0;
+    my $num_ok = 0;
+    my @deleted;
+    my @undeleted;
+    my %usersettings;
+    my $context = 'deletegroup';
+    foreach my $key (sort(keys(%membership))) {
+        if ($key =~ /^\Q$groupname\E:([^:]+:[^:]+)$/) {
+            my $user = $1;
+            my($end,$start,$userprivs) = split(/:/,$membership{$key},3);
+            if ($start != -1) {
+                $num_users ++;
+                $usersettings{$groupname.':'.$user} = $now.':-1:'.$userprivs;
+                if (&Apache::lonnet::modify_group_roles($cdom,$cnum,
+                                                        $groupname,$user,
+                                                        $now,'-1',$userprivs,
+                                                        '',$context)
+                    eq 'ok') {
+                    $num_ok ++;
+                    push(@deleted,$user);
+                } else {
+                    push(@undeleted,$user);
+                    $num_fail ++;
+                }
+            }
+        }
+    }
+    if ($num_ok > 0) {
+        my $roster_result = 
+            &Apache::lonnet::modify_coursegroup_membership($cdom,$cnum,
+                                                           \%usersettings);
+    }
+    if ($num_fail > 0) {
+        $r->print('<div class="LC_error">'
+                 .&mt('Group deletion failed because deletion of [_1] out of [_2] members failed.'
+                     ,$num_fail,$num_users)
+                 .'</div>');
+    } else {
+        my ($result,$message) = 
+             &Apache::lonnet::toggle_coursegroup_status($cdom,$cnum,
+                                                        $groupname,'delete');
+        if ($result eq 'ok') {
+            my $outcome = &modify_folders($cdom,$cnum,$groupname,$crstype);
+            if ($outcome eq '') {
+                $r->print('<div class="LC_success">'
+                         .&mt('Group successfully deleted.')
+                         .'</div>');
+            } else {
+                $r->print('<div class="LC_error">');
+                if ($crstype eq 'Comunity') {
+                    $r->print(&mt("Although the group was deleted, an error occurred when removing the group's folder from the 'Community Groups' folder: [_1]",$outcome));
+                } else {
+                    $r->print(&mt("Although the group was deleted, an error occurred when removing the group's folder from the 'Course Groups' folder: [_1]",$outcome));
+                }
+                $r->print('</div>');
+            }
+        } else {
+            $r->print('<div class="LC_error">'
+                     .&mt('Group deletion failed.')
+                     .'</div>');
+        }
+    }
+    return;
+}
+
+sub reenable_folder {
+    my ($cdom,$cnum,$groupname,$description,$crstype) = @_;
+    my $outcome;
+    my $crspath = '/uploaded/'.$cdom.'/'.$cnum.'/';
+    my $allgrpsmap = $crspath.'group_allfolders.sequence';
+    my $foldertitle;
+    if ($crstype eq 'Community') {
+        $foldertitle = &mt("Community Folder -[_1]",$description);
+    } else {
+        $foldertitle = &mt("Course Folder -[_1]",$description);
+    }
+    my $mapurl = $crspath.'group_folder_'.
+                   $groupname.'.sequence';
+    my ($errtext,$fatal)=&LONCAPA::map::mapread($allgrpsmap);
+    if ($fatal) {
+        $outcome='<div class="LC_error">'
+                .&mt('An error occurred when reading contents of parent folder to group:')
+                ."<br />($allgrpsmap): $errtext"
+                .'</div>';
+    } else {
+        my $idx=&LONCAPA::map::getresidx($mapurl);
+        $LONCAPA::map::resources[$idx] = $foldertitle.':'.$mapurl.
+                                         ':false:normal:res';
+        $LONCAPA::map::order[1+$#LONCAPA::map::order]=$idx;
+        my ($outtext,$errtext) = &LONCAPA::map::storemap($allgrpsmap,1);
+        if ($errtext) {
+            $outcome='<div class="LC_error">'
+                    .&mt('An error occurred when saving updated parent folder to group:'
+                        ,"<br />$allgrpsmap - $errtext")
+                    .'</div>';
+        } else {
+            my ($furl,$ferr) =
+                     &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
+        }
     }
+    return $outcome;
+}
+
+sub modify_folders {
+    my ($cdom,$cnum,$groupname,$crstype) = @_;
+    my ($outcome,$groupmap,$groupmapres,$map,$id,$src);
+    my $navmap = Apache::lonnavmaps::navmap->new();
+    if (!defined($navmap)) {
+        $outcome = '<div class="LC_error">';
+        if ($crstype eq 'Community') {
+            $outcome .= &mt("Error reading community contents.").' '.
+                   &mt("You need to re-initialize the community.");
+        } else {
+            $outcome .= &mt("Error reading course contents.").' '.
+                   &mt("You need to re-initialize the course.");
+        }
+        $outcome .= '</div>';
+        return $outcome;
+    }
+    $groupmap = '/uploaded/'.$cdom.'/'.$cnum.'/'.'group_folder_'.
+                   $groupname.'.sequence';
+    $groupmapres = $navmap->getResourceByUrl($groupmap);
+    if ($groupmapres) {
+        ($map,$id,$src)=&Apache::lonnet::decode_symb($groupmapres->symb());
+    }
+    undef($navmap);
+    if ($map) {
+        $map = '/'.$map;
+        my ($errtext,$fatal) = &LONCAPA::map::mapread($map);
+        if ($fatal) {
+            $outcome='<div class="LC_error">'
+                    .&mt('An error occurred when reading contents of parent folder to group:')
+                    ."<br />($map): $errtext"
+                    .'</div>';
+        } else {
+            my $idx = 0;
+            my $grpidx;
+            foreach my $item (@LONCAPA::map::order) {
+                my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$item]);
+                $url=&LONCAPA::map::qtescape($url);
+                if ($url eq $groupmap) {
+                    $grpidx = $idx;
+                    last;
+                } else {
+                    $idx++;
+                }
+            }
+
+            if ($grpidx ne '') {
+                &LONCAPA::map::makezombie($LONCAPA::map::order[$grpidx]);
+                for (my $i=$grpidx;$i<$#LONCAPA::map::order;$i++) {
+                    $LONCAPA::map::order[$i] = $LONCAPA::map::order[$i+1];
+                }
+                $#LONCAPA::map::order--;
+                my ($outtext,$errtext) = &LONCAPA::map::storemap($map,1);
+                if ($errtext) {
+                    $outcome='<div class="LC_error">'
+                            .&mt('An error occurred when saving updated parent folder to group:')
+                            ."<br />$map - $errtext"
+                            .'</div>';
+                } else {
+                    my ($furl,$ferr) =
+                        &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
+                }  
+            }
+        }
+    }
+    return $outcome;
+}
+
+sub verify_reenable {
+    my ($r,$groupname,$formname,$action,$page,$states,$stored,$crstype) = @_;
+    $r->print(&Apache::lonhtmlcommon::echo_form_input([]));
+    $r->print(&mt('You have requested enabling the previously deleted group [_1].'
+                 ,'<i>'.$stored->{'description'}.'</i>').
+              '<br /><br />'.&mt('When a deleted group is re-enabled the following occurs:').'<ul>'.
+              '<li>'.&mt('Group settings and membership at the time the group was deleted are reinstated.').'</li><li>');
+    if ($crstype eq 'Community') {
+        $r->print(&mt("A group folder is added to the 'Community Groups' folder which contains folders for all groups in the community."));
+    } else {
+        $r->print(&mt("A group folder is added to the 'Course Groups' folder which contains folders for all groups in the course."));
+    }
+    $r->print('</li></ul>');
+    my $prevtext = &mt('Go back');
+    my $nexttext = &mt('Reenable group');
+    my $prev;
+    if ($env{'form.refpage'} eq 'cusr')  {
+        $prev = 'view';
+    }
+    &display_navbuttons($r,$formname,$prev,$prevtext,
+                        $$states{$action}[$page+1],$nexttext);
+    return;
+}
+
+sub reenable_group {
+    my ($r,$cdom,$cnum,$groupname,$crstype) = @_;
+    my %groups = 
+        &Apache::longroup::coursegroups($cdom,$cnum,$groupname,
+                                        'deleted_groups');
+    if (keys(%groups) == 0) {
+        $r->print(&mt('The group [_1] was not re-enabled, because it is not a deleted group.[_2]Perhaps it has already been re-enabled?','<i>'.$groupname.'</i>'),'<br />');
+        return;
+    }
+    my %groupinfo = 
+        &Apache::longroup::get_group_settings($groups{$groupname});
+    my $defstart = $groupinfo{'startdate'};
+    my $defend = $groupinfo{'enddate'};
+    my $showstart = &Apache::lonlocal::locallocaltime($defstart);
+    my $showend;
+    if ($defend == 0) {
+        $showend = &mt('No end date set');
+    } else {
+        $showend = &Apache::lonlocal::locallocaltime($defend);
+    }
+    my $description = &unescape($groupinfo{'description'});
+    my $num_users = 0;
+    my $num_ok = 0;
+    my $num_fail = 0;
+    my $context = 'reenablegroup';
+    my (%usersettings,@enabled,@unenabled);
+    my ($result,$message) =
+          &Apache::lonnet::toggle_coursegroup_status($cdom,$cnum,$groupname,
+                                                     'reenable');
+    if ($result eq 'ok') {
+        my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum,
+                                                           $groupname);
+        foreach my $key (sort(keys(%membership))) {
+            if ($key =~ /^\Q$groupname\E:([^:]+:[^:]+)$/) {
+                my $user = $1;
+                my($end,$start,$userprivs) = split(/:/,$membership{$key},3);
+                if (($start == -1) && ($end == $groupinfo{'modified'})) {
+                    $num_users ++;
+                    $usersettings{$groupname.':'.$user} = $defend.':'.
+                                                          $defstart.':'.
+                                                          $userprivs;
+                    if (&Apache::lonnet::modify_group_roles($cdom,$cnum,
+                                                            $groupname,$user,
+                                                            $defend,$defstart,
+                                                            $userprivs,'',
+$context) eq 'ok') {
+                        $num_ok ++;
+                        push(@enabled,$user);
+                    } else {
+                        push(@unenabled,$user);
+                        $num_fail ++;
+                    }
+                }
+            }
+        }
+        if ($num_users > 0) {
+            if ($num_ok > 0) {
+                my $roster_result =
+        &Apache::lonnet::modify_coursegroup_membership($cdom,$cnum,
+                                                       \%usersettings);
+                if ($roster_result eq 'ok') {
+                    $r->print('<div class="LC_success">'
+                             .&mt('Membership reinstated for [quant,_1,user], each with start and end dates for group access set to defaults: [_2] and [_3]',$num_ok,$showstart,$showend)
+                             .'</div>');
+                }
+            } else {
+                $r->print('<div class="LC_error">'
+                         .&mt('A problem occurred when trying to reinstate [_1] of the [_2] members of the pre-existing group.',$num_fail,$num_users)
+                         .'</div>');
+            }
+        } else {
+            $r->print('<div class="LC_info">'
+                     .&mt('There were no group members to reinstate, as none were removed when the group was deleted.')
+                     .'</div>');
+        }
+        my $outcome = &reenable_folder($cdom,$cnum,$groupname,$description,$crstype);
+        if ($outcome eq '') {
+            $r->print('<div class="LC_success">'
+                     .&mt('Group successfully re-enabled.')
+                     .'</div>');
+        } else {
+            $r->print('<div class="LC_error">');
+            if ($crstype eq 'Comunity') {
+                $r->print(&mt("Although the group was re-enabled, an error occurred when adding the group's folder to the 'Community Groups' folder: [_1]",$outcome));
+            } else {
+                $r->print(&mt("Although the group was re-enabled, an error occurred when adding the group's folder to the 'Course Groups' folder: [_1]",$outcome));
+            }
+            $r->print('</div>');
+        }
+    } else {
+        $r->print('<div class="LC_error">'
+                 .&mt('Re-enabling group failed.')
+                 .'</div>');
+    }
+    return;
 }
 
 sub header {
@@ -1065,7 +1466,7 @@ sub header {
 				       {'add_entries' => $loaditems,});
     my $output = <<"END";
 $start_page
-<form method="POST" name="$state">
+<form method="post" name="$state">
 
 END
     if ($action eq 'create' || $action eq 'modify') {
@@ -1123,16 +1524,16 @@ sub build_members_list {
 }
 
 sub group_files {
-    my ($group,$currdir,$numfiles,$numdirs) = @_;
+    my ($group,$portpath,$numfiles,$numdirs) = @_;
     my $dirptr=16384;
-    my @dir_list=&Apache::portfolio::get_dir_list($currdir,$group);
+    my @dir_list=&Apache::portfolio::get_dir_list($portpath,undef,$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;
+                $portpath .= '/'.$filename;
                 $$numdirs ++;
-                &group_files($numfiles,$numdirs)
+                &group_files($group,$portpath,$numfiles,$numdirs)
             } else {
                 $$numfiles ++;
             }
@@ -1145,39 +1546,54 @@ sub group_members {
     my ($cdom,$cnum,$group,$group_info) = @_;
     my %memberhash = &Apache::lonnet::get_group_membership($cdom,$cnum,$group);
     my $now = time;
-    my ($tmp)=keys(%memberhash);
-    if ($tmp=~/^error:/) {
-        $$group_info{'totalmembers'} = 'Unknown - an error occurred';
-        return $tmp;
-    }
+    my %lt = &Apache::lonlocal::texthash (
+                                          active => 'active',
+                                          previous => 'previous',
+                                          future => 'future',
+    );
+    my %membercounts = (  
+                         active => 0,
+                         previous => 0,
+                         future => 0,
+                       );
     my $totalmembers = 0;
-    my $active = 0;
-    my $previous = 0;
-    my $future = 0;
     foreach my $member (keys %memberhash) {
         $totalmembers ++;
         my ($end,$start) = split(/:/,$memberhash{$member});
         unless ($start == -1) {
             if (($end!=0) && ($end<$now)) {
-                $previous ++;
+                $membercounts{previous} ++;
             } elsif (($start!=0) && ($start>$now)) {
-                $future ++;
+                $membercounts{future} ++;
             } else {
-               $active ++;
+                $membercounts{active} ++;
             }
         }
     }
     if ($totalmembers == 0) {
         $$group_info{$group}{'totalmembers'} = 'None';
     } else {
-        $$group_info{$group}{'totalmembers'} = '<nobr>'.$active.
-            '&nbsp;-&nbsp;active</nobr><br /><nobr>'.$previous.
-            '&nbsp;-&nbsp;previous</nobr><br /><nobr>'.$future.
-            '&nbsp;-&nbsp;future</nobr>';
+        foreach my $type ('active','previous','future') {
+            $$group_info{$group}{'totalmembers'} .= 
+               &open_list_window($group,$type,$membercounts{$type},$lt{$type});
+        }
     }
     return 'ok';
 }
 
+sub open_list_window {
+    my ($group,$status,$count,$text) = @_;
+    my $entry;
+    if ($count > 0) {
+        $entry = '<span class="LC_nobreak"><a href="javascript:openGroupRoster('.
+                 "'$group','$status'".')">'.$text.'</a>&nbsp;-&nbsp;'.$count.
+                 '</span><br />';
+    } else {
+        $entry = '<span class="LC_nobreak">'.$text.'&nbsp;-&nbsp;'.$count.'</span><br />';
+    }
+    return $entry;
+}
+
 
 sub general_settings_form {
     my ($r,$cdom,$cnum,$action,$formname,$page,$functions,$tools,
@@ -1188,8 +1604,8 @@ sub general_settings_form {
                            $gpterm,$ucgpterm,$crstype);
     &access_date_settings($r,$action,$formname,$stored,2,$gpterm,$ucgpterm);
     if ($action eq 'create') {
-        &membership_options($r,$action,$formname,$sectioncount,3,$gpterm,
-			    $ucgpterm);
+        &membership_options($r,$cdom,$cnum,$action,$formname,$sectioncount,3,
+                            $gpterm,$ucgpterm,$crstype);
         $nexttext = $$navbuttons{'gtns'};
     } else {
         my @available = ();
@@ -1198,10 +1614,10 @@ sub general_settings_form {
         @{$tools} = sort(keys(%{$functions}));
         &privilege_specificity($r,$action,3,$tools,$stored,$toolprivs,
 			       $fixedprivs,\@available,$formname,
-			       $gpterm,$ucgpterm);
+			       $gpterm,$ucgpterm,$functions,$crstype);
         &mapping_options($r,$action,$formname,$page,$sectioncount,
                          $states,$stored,$navbuttons,4,5,
-			 $gpterm,$ucgpterm,$crstype);
+			 $gpterm,$ucgpterm,$crstype,$cdom,$cnum);
         $nexttext = $$navbuttons{'mose'};
     }
     $prevtext = $$navbuttons{'gtpp'};
@@ -1222,34 +1638,34 @@ sub groupsettings_options {
         'lett' => 'Letters, numbers and underscore only',
         'doyo' => 'Different subsets of the chosen collaborative tools '.
                   'for different group members?',
+        'gran' => 'Granularity',
+        'dquo' => 'Disk quota',
     );
     my ($crsquota,$freespace,$maxposs) = &get_quota_constraints($action,$stored);
-    &topic_bar($r,$image,$lt{'gnde'});
-    $r->print('
-     <table class="LC_descriptive_input">
-      <tr>
-       <td class="LC_description">'.$lt{'gnam'}.':</td>
-       <td colspan="5">
-');
+    $r->print(&Apache::lonhtmlcommon::topic_bar($image,$lt{'gnde'}));
+
+    # Group Name
+    $r->print(&Apache::lonhtmlcommon::start_pick_box()
+             .&Apache::lonhtmlcommon::row_title($lt{'gnam'})
+    );
     if ($action eq 'create') {
-        $r->print('<input type="text" name="groupname" size="25" />&nbsp;('.
-                  $lt{'lett'}.')');
+        $r->print('<input type="text" name="groupname" size="25" />'
+                 .' <span class="LC_nobreak">('
+                 .$lt{'lett'}.')</span>'
+        );
     } else {
         $r->print('<input type="hidden" name="groupname" value="'.
                          $env{'form.groupname'}.'" />'.$env{'form.groupname'});
     }
-    $r->print(<<"END");
-       </td>
-      <tr>
-      <tr>
-       <td class="LC_description">$lt{'desc'}:</td>
-       <td colspan="5"><input type="text" name="description" size="40"
-                                                    value="" />
-       </td>
-      <tr>
-      <tr>
-       <td class="LC_description">$lt{'func'}:</td>
-END
+    $r->print(&Apache::lonhtmlcommon::row_closure());
+
+    # Group Title
+    $r->print(&Apache::lonhtmlcommon::row_title($lt{'desc'})
+             .'<input type="text" name="description" size="40" value="" />'
+             .&Apache::lonhtmlcommon::row_closure()
+    );
+
+    # Collaborative Tools
     my $numitems = keys(%{$functions});
     my $halfnum = int($numitems/2);
     my $remnum = $numitems%2;
@@ -1257,66 +1673,80 @@ END
         $halfnum ++;
     }
     my @allfunctions = sort(keys (%{$functions}));
-    for (my $i=0; $i<$halfnum; $i++) {
-        $r->print('<td><label><input type="checkbox" name="tool" value="'.
-                  $allfunctions[$i].'" />&nbsp;'.
-                   $$functions{$allfunctions[$i]}.'</label></td>
-                   <td>&nbsp;</td><td>&nbsp;</td>');
-    }
-    $r->print('<td><input type="button" value="check all" '.
-              'onclick="javascript:checkAll(document.'.$formname.'.tool)" />'.
-              '</td></tr><tr><td>&nbsp;</td>');
-    for (my $j=$halfnum; $j<@allfunctions; $j++) {
-        $r->print('<td><label><input type="checkbox" name="tool" value="'.
-                  $allfunctions[$j].'" />&nbsp;'.
-                  $$functions{$allfunctions[$j]}.'</label></td>
-                  <td>&nbsp;</td><td>&nbsp;</td>');
-    }
-    if ($remnum) {
-        $r->print('<td>&nbsp;</td>');
+
+    $r->print(&Apache::lonhtmlcommon::row_title($lt{'func'})
+             .'<div>'
+             .'<input type="button" value="'.&mt('check all').'"'
+             .' onclick="javascript:checkAll(document.'.$formname.'.tool)" />'
+             .'&nbsp;<input type="button" value="'.&mt('uncheck all').'"'
+             .' onclick="javascript:uncheckAll(document.'.$formname.'.tool)" />'
+             .'</div>'
+             .'<table cellpadding="5px"><tr>' # FIXME Get rid of inflexible table (-> float)
+    );
+    for (my $i=0; $i<@allfunctions; $i++) {
+        $r->print('<td><label><span class="LC_nobreak">'
+                 .'<input type="checkbox" name="tool" value="'
+                 .$allfunctions[$i].'" /> '
+                 .&mt($$functions{$allfunctions[$i]})
+                 .'</span></label></td>'
+        );
+        if ($i == $halfnum - 1) {
+            $r->print('</tr><tr>');
+        }
     }
-    $r->print('
-       <td>
-        <input type="button" value="uncheck all"
-          onclick="javascript:uncheckAll(document.'.$formname.'.tool)" />
-       </td>
-      </tr>
-      <tr>
-       <td class="LC_description">'.&mt('Granularity:').'</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>');
+    $r->print('</tr></table>'
+             .&Apache::lonhtmlcommon::row_closure()
+    );
+
+    # Granularity
+    $r->print(&Apache::lonhtmlcommon::row_title($lt{'gran'})
+             .$lt{'doyo'}.'<br />'
+             .'<label>'
+             .'<input type="radio" name="granularity" value="Yes" />'.&mt('Yes')
+             .'</label>&nbsp;<label>'
+             .'<input type="radio" name="granularity" value="No" checked="checked" />'.&mt('No')
+             .'</label>'
+    );
     if ($action eq 'modify') {
-        $r->print('&nbsp;&nbsp;('.&mt('Currently set to "[_1]"',
-                                      $$stored{'granularity'}).')');
+        $r->print(' <span class="LC_nobreak">('
+                 .&mt('Currently set to [_1].'
+                     ,'"'.&mt($$stored{'granularity'}).'"')
+                 .')</span>'
+        );
     }
-    $r->print('
-       </td>
-      </tr>
-      <tr>
-       <td class="LC_description">'.&mt('Disk quota: ').'</td><td colspan="10">');
+    $r->print(&Apache::lonhtmlcommon::row_closure());
+
+    # Disk Quota
+    $r->print(&Apache::lonhtmlcommon::row_title($lt{'dquo'}));
     if ($action eq 'create') {
-        $r->print(&mt('If you enable the file repository for the [_1], allocate a disk quota.',$gpterm));
+        $r->print('<span class="LC_info">'
+                 .&mt('If you enable the group portfolio for the '.$gpterm
+                     .', allocate a disk quota.')
+                 .'</span>'
+        );
     } else {
-        $r->print(&mt('Quota allocated to file repository:'));
+        $r->print(&mt('Quota allocated to group portfolio:'));
     } 
-    $r->print('&nbsp;<input type="text" name="quota" size="4" />Mb');
+    $r->print(' '.&mt('[_1] Mb','<input type="text" name="quota" size="4" />'));
     if ($action eq 'create') {
-        $r->print('<br />'.
-                  &mt('A total of [_1] Mb can be divided amongst all [_2]s in the '.
-                  '[_3], and [_4] Mb are currently unallocated.',$crsquota,
-                  $gpterm,lc($crstype),sprintf("%.2f",$freespace)));
+        $r->print('<br />'
+                 .&mt('A total of [_1] Mb can be divided amongst all '.$gpterm.'s in the '
+                     .lc($crstype).', and [_2] Mb are currently unallocated.'
+                     ,$crsquota,sprintf("%.2f",$freespace))
+                 );
     } else {
         $r->print('&nbsp;&nbsp;('.&mt('The quota is currently [_1] Mb',
                                       $$stored{'quota'}).').');
 
-        $r->print('<br />'.&mt('The quota can be increased to [_1] Mb, '.
-                  'by adding all unallocated space for [_2]s in the [_3].',
-                  sprintf("%.2f",$maxposs),$gpterm,lc($crstype)));
+        $r->print('<br />'
+                 .&mt('The quota can be increased to [_1] Mb, '
+                 .'by adding all unallocated space for '.$gpterm.'s in the '.lc($crstype).'.'
+                  ,sprintf("%.2f",$maxposs)));
     }
-    $r->print('
-       </td>
-      </tr>
-     </table>
-');
+    $r->print(&Apache::lonhtmlcommon::row_closure(1));
+
+    $r->print(&Apache::lonhtmlcommon::end_pick_box());
+
     return;
 }
 
@@ -1337,40 +1767,48 @@ sub get_quota_constraints {
 }
 
 sub membership_options {
-    my ($r,$action,$state,$sectioncount,$image,$gpterm,$ucgpterm) = @_;
-    my $crstype = &Apache::loncommon::course_type();
+    my ($r,$cdom,$cnum,$action,$state,$sectioncount,$image,$gpterm,$ucgpterm,$crstype)=@_;
     my %lt = &Apache::lonlocal::texthash(
                 'pipa' => 'Build a list of users for selection of group members',
-                'gmem' => "Group membership selection list criteria:",
-                'picr' => 'Pick the criteria to use to build a list of '.
-                          lc($crstype).' 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, there is no need to pick any criteria.",
-                'asub' => "A subsequent step will also allow you to specify automatic adding/dropping of group members triggered by specified user role and section <i>changes</i> in the course.",
+                'gmem' => 'Group membership selection list criteria:',
+                'picr' => 'Pick the criteria to use to build a list of course users from which you will select members of the new group.',
+                'pica' => 'Pick the criteria to use to build a list of course users from which you will select additional members of the group.',
+                'ifno' => 'If you do not wish to add members when you first create the group, there is no need to pick any criteria.', 
+                'asub' => 'A subsequent step will also allow you to specify automatic adding/dropping of group members triggered by specified user role and section <i>changes</i> in the course.',
                 'acty' => 'Access types',
-                'coro' => $crstype.' roles',
-                'cose' => $crstype.' sections',
+                'coro' => 'Course roles',
+                'cose' => 'Course sections',
              );
+    if ($crstype eq 'Community') {
+        $lt{'picr'} = &mt('Pick the criteria to use to build a list of community participants from which you will select ');
+        $lt{'asub'} = &mt('A subsequent step will also allow you to specify automatic adding/dropping of group members triggered by specified user role and section [_1]changes[_2] in the course.','<i>','</i>');
+        $lt{'coro'} = &mt('Community roles');
+        $lt{'cose'} = &mt('Community sections');
+    } else {
+        $lt{'asub'} = &mt('A subsequent step will also allow you to specify automatic adding/dropping of group members triggered by specified user role and section [_1]changes[_2] in the course.','<i>','</i>');
+    }
     my %status_types = (
                    active => &mt('Currently has access'),
                    previous => &mt('Previously had access'),
                    future => &mt('Will have future access'),
                    );
 
-    #FIXME need to plumb around for the various cr roles defined by the user
-    my @roles = ('st','cc','in','ta','ep');
+    my @roles = ('st');
+    if ($crstype eq 'Community') {
+        push(@roles,'co');
+    } else {
+        push(@roles,'cc');
+    }
+    push (@roles,('in','ta','ep','ad','cr'));
 
     my @sections = keys(%{$sectioncount});
 
-    &topic_bar($r,$image,$lt{'pipa'});
-    $r->print('
-     <b>'.$lt{'gmem'}.'</b><br />'.$lt{'picr'});
+    $r->print(&Apache::lonhtmlcommon::topic_bar($image,$lt{'pipa'}).'
+     <b>'.$lt{'gmem'}.'</b><br />');
     if ($action eq 'create') {
-        $r->print($lt{'meof'}.'<br />'.$lt{'ifno'}.'<br />'.$lt{'asub'});
+        $r->print($lt{'picr'}.'<br />'.$lt{'ifno'}.'<br />'.$lt{'asub'});
     } else {
-        $r->print($lt{'admg'});
+        $r->print($lt{'pica'});
     }
     $r->print('
      <br />
@@ -1383,7 +1821,7 @@ sub membership_options {
       </tr><tr><td>');
     $r->print(&Apache::lonhtmlcommon::status_select_row(\%status_types));
     $r->print('</td><td>');
-    $r->print(&Apache::lonhtmlcommon::role_select_row(\@roles));
+    $r->print(&Apache::lonhtmlcommon::role_select_row(\@roles,undef,undef,1,$cdom,$cnum));
     if (@sections > 0) {
         @sections = sort {$a cmp $b} @sections;
         unshift(@sections,'none'); # Put 'no sections' next
@@ -1415,7 +1853,7 @@ sub sections_selection {
         }
     }
     my $output = '
-        <select name="'.$elementname.'" multiple="true" size="'.$numvisible.'">
+        <select name="'.$elementname.'" multiple="multiple" size="'.$numvisible.'">
           '.$section_sel.'
         </select>';
     return $output;
@@ -1423,9 +1861,7 @@ sub sections_selection {
 
 sub access_date_settings {
     my ($r,$action,$formname,$stored,$image,$gpterm,$ucgpterm) = @_;
-    my %lt = &Apache::lonlocal::texthash(
-                'sten' => "Default start and end dates for $gpterm access",
-             );
+    my $sten = &mt("Default start and end dates for $gpterm access");
     my $starttime = time;
     my $endtime = time+(6*30*24*60*60); # 6 months from now, approx
     if ($action eq 'modify') {
@@ -1435,8 +1871,7 @@ sub access_date_settings {
         }
     }
     my ($table) = &date_setting_table($starttime,$endtime,$formname);
-    &topic_bar($r,$image,$lt{'sten'});
-    $r->print('
+    $r->print(&Apache::lonhtmlcommon::topic_bar($image,$sten).'
     '.$table.'
     ');
     return;
@@ -1489,7 +1924,8 @@ sub choose_members_form {
         }
     }
     &privilege_specificity($r,$action,$specimg,$tools,$stored,$toolprivs,
-                          $fixedprivs,\@available,$formname,$gpterm,$ucgpterm);
+                          $fixedprivs,\@available,$formname,$gpterm,$ucgpterm,
+                          $functions,$crstype);
     my $newusers = &pick_new_members($r,$action,$formname,\@available,$idx,
 				     $stored,$memimg,$users,$userdata,
 				     $granularity,\%origmembers,$gpterm,
@@ -1513,6 +1949,11 @@ sub display_navbuttons {
       <input type="button" name="previous" value = "'.$prevtext.'"
     onclick="javascript:backPage(document.'.$formname.','."'".$prev."'".')"/>
    &nbsp;&nbsp;&nbsp;');
+    } elsif ($prevtext) {
+        $r->print('
+      <input type="button" name="previous" value = "'.$prevtext.'"
+    onclick="javascript:history.back()"/>
+   &nbsp;&nbsp;&nbsp;');
     }
     if ($next) {
         $r->print('
@@ -1548,7 +1989,7 @@ sub print_current_settings {
         ygrs => "Your group selections - ",
         tfwa => "The following settings will apply to the group:",
         difn => 'Different collaborative tools<br />for different members:',
-        stda => 'Start date',
+        stda => 'Start date:',
         enda => 'End date:',
     );
     my $showstart = &Apache::lonlocal::locallocaltime($startdate);
@@ -1581,46 +2022,31 @@ sub print_current_settings {
   <td valign="top">'.$description.'</td>
   <td>
 ');
+
     if (@{$available} > 0) {
-        $r->print(&mt('<b>Available for assignment to members:</b>').
-                    '<table class="LC_group_priv"><tr>');
-        my $rowcell = int(@{$available}/2) + @{$available}%2;
+        $r->print('<b>'.&mt('Available for assignment to members:').'</b>');
+        $r->print('<ul>');
         for (my $i=0; $i<@{$available}; $i++) {
-            if (@{$available} > 3) {
-                if ($i==$rowcell) {
-                    $r->print('</tr><tr>');
-                }
-            }
-            $r->print('<td>'.$$functions{$$available[$i]}.
-		      '</td><td>&nbsp;</td>');
+            $r->print('<li>'.&mt($$functions{$$available[$i]}).'</li>');
         }
-        if ((@{$available} > 3) && (@{$available}%2)) {
-            $r->print('<td>&nbsp;</td><td>&nbsp;</td>');
-        }
-        $r->print('</tr></table><br />');
+        $r->print('</ul>');
     }
+
     if (@{$unavailable} > 0) {
-        $r->print(&mt('<b>Unavailable for assignment:</b>').
-                    '<table class="LC_group_priv"><tr>');
-        my $rowcell = int(@{$unavailable}/2) + @{$unavailable}%2;
-        for (my $j=0; $j<@{$unavailable}; $j++) {
-            if (@{$unavailable} > 3) {
-                if ($j==$rowcell) {
-                    $r->print('</tr><tr>');
-                }
-            }
-            $r->print('<td>'.$$functions{$$unavailable[$j]}.
-		      '</td><td>&nbsp;</td>');
+        $r->print('<b>'.&mt('Unavailable for assignment:').'</b>');
+        $r->print('<ul>');
+        for (my $i=0; $i<@{$unavailable}; $i++) {
+            $r->print('<li>'.&mt($$functions{$$unavailable[$i]}).'</li>');
         }
-        if ((@{$unavailable} > 3) && (@{$unavailable}%2)) {
-            $r->print('<td>&nbsp;</td><td>&nbsp;</td>');
-        }
-        $r->print('</tr></table>');
+        $r->print('</ul>');
     }
+
+    my $quota_text=&mt('[_1] Mb',$quota);
+    my $granu_text=&mt($granularity);
     $r->print(<<"END");
   </td>
-  <td valign="top"><b>$lt{'difn'}</b> $granularity</td>
-  <td valign="top">$quota Mb</td> 
+  <td valign="top"><b>$lt{'difn'}</b> $granu_text</td>
+  <td valign="top">$quota_text</td> 
   <td valign="top"><b>$lt{'stda'}</b> $showstart<br />
       <b>$lt{'enda'}</b> $showend
   </td>
@@ -1643,9 +2069,9 @@ sub pick_new_members {
           'nnew' => "There are no users to add as new members, as all users".
                     " matching the specified type(s), role(s), and ".
                     "section(s) are already affiliated with this group.",
-          'yoma' =>  'You may need to use the '."'".'modify existing, past or '.
-                     'future members'."'".' page if you need to re-enable '.
-                     'or activate access for previous or future members.',
+          'yoma' =>  "You may need to use the 'modify existing, past or ".
+                     "future members' page if you need to re-enable ".
+                     "or activate access for previous or future members.",
     );
     my %members;
     my $totalusers = 0;
@@ -1669,7 +2095,7 @@ sub pick_new_members {
             $r->print(&check_uncheck_tools($r,$available));
         }
     }
-    &topic_bar($r,$img,$lt{'gpme'});
+    $r->print(&Apache::lonhtmlcommon::topic_bar($img,$lt{'gpme'}));
     if (keys(%members) > 0) {
         $r->print('
     <table>
@@ -1677,14 +2103,14 @@ sub pick_new_members {
         &check_uncheck_buttons($r,$formname,'member',$lt{'addm'});
         if (@{$available} > 0 && $granularity eq 'Yes') {
             $r->print('<td>
-     <fieldset><legend><b>'.$lt{'setf'}.'</b></legend>
-      <nobr>
-      <input type="button" value="check all"
+     <fieldset><legend>'.$lt{'setf'}.'</legend>
+      <span class="LC_nobreak">
+      <input type="button" value="'.&mt('check all').'"
         onclick="javascript:checkAllTools(document.'.$formname.')" />
         &nbsp;&nbsp;
-      <input type="button" value="uncheck all"
+      <input type="button" value="'.&mt('uncheck all').'"
         onclick="javascript:uncheckAllTools(document.'.$formname.')" />
-      </nobr>
+      </span>
      </fieldset></td>');
         }
         $r->print('</tr></table>
@@ -1707,13 +2133,13 @@ sub pick_new_members {
             if ($granularity eq 'Yes') {
                 $r->print(&Apache::loncommon::start_data_table_row('LC_data_table_dense LC_data_table_highlight').'
  <td colspan="6">&nbsp;</td>
- <td align="center"><nobr><b>'.&mt('All:').'</b>&nbsp;');
+ <td align="center"><span class="LC_nobreak"><b>'.&mt('All:').'</b>&nbsp;');
                 foreach my $tool (@{$available}) {
                     $r->print('<label><input type="checkbox" name="togglefunc" '.
    'onclick="javascript:toggleTools(document.'.$formname.'.user_'.$tool.',this);"'.
    ' value="'.$tool.'">'.'<b>'.$tool.'</b></label>&nbsp;&nbsp;&nbsp;');
                 }
-                $r->print('</nobr></td></tr>');
+                $r->print('</span></td></tr>');
             }
         }
         my %Sortby = ();
@@ -1747,7 +2173,7 @@ sub pick_new_members {
 			  '<td>'.$id.'</td>'.
 			  '<td>'.$section.'</td>');
                 if (@{$available} > 0) {
-                    $r->print('<td align="center"><nobr>'.
+                    $r->print('<td align="center"><span class="LC_nobreak">'.
                               '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');
                     foreach my $tool (@{$available}) {
                         if ($granularity eq 'Yes') {
@@ -1758,7 +2184,7 @@ sub pick_new_members {
                           $tool.'" value="'.$user.'" />'.$tool.'&nbsp;&nbsp;&nbsp;');
                         }
                     }
-                    $r->print('</nobr></td>');
+                    $r->print('</span></td>');
                 }
                 $r->print(&Apache::loncommon::end_data_table_row()."\n");
             }
@@ -1776,7 +2202,7 @@ sub pick_new_members {
 
 sub privilege_specificity {
     my ($r,$action,$img,$tools,$stored,$toolprivs,$fixedprivs,$available,
-	$formname,$gpterm,$ucgpterm) = @_;
+	$formname,$gpterm,$ucgpterm,$functions,$crstype) = @_;
     my %lt = &Apache::lonlocal::texthash (
       'uprv' => 'User privileges for collaborative tools',
       'frty' => 'For each collaborative tool you have chosen to include, '.
@@ -1810,6 +2236,9 @@ sub privilege_specificity {
       'oppr' => 'Optional privileges',
       'defp' => 'The default privileges new members will receive are:', 
     );
+    if ($crstype eq 'Community') {
+        $lt{'thes'} = &mt('These will be the privileges given to members assigned in the future via automatic group assignment for users who receive specific sections/roles in the community '); 
+    }
     my $totaloptionalprivs = 0;
     foreach my $tool (@{$tools}) {
         foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
@@ -1818,9 +2247,9 @@ sub privilege_specificity {
             }
         }
     }
-    &topic_bar($r,$img,$lt{'uprv'});
+    $r->print(&Apache::lonhtmlcommon::topic_bar($img,$lt{'uprv'}));
     if ((($action eq 'create') && (@{$available} > 0)) || 
-        (($action eq 'modify') && ($formname eq 'change_settings'))) {  
+        (($action eq 'modify') && ($formname eq 'change_settings'))) {
         my %specific = (
                       'No'  => 'checked="checked"',
                       'Yes' => '',
@@ -1845,8 +2274,8 @@ sub privilege_specificity {
         if ($totaloptionalprivs) {
             $r->print('
 <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><br /><br />');
+<label><span class="LC_nobreak"><input type="radio" name="specificity" value="No" '.$specific{'No'}.' />&nbsp;'.$lt{'algm'}.'</span></label><br />
+<label><span class="LC_nobreak"><input type="radio" name="specificity" value="Yes" '.$specific{'Yes'}.' />&nbsp;'.$lt{'smgp'}.'</span></label><br /><br />');
         } else {
             $r->print('<input type="hidden" name="specificity" value="No" />');
         }
@@ -1873,10 +2302,11 @@ sub privilege_specificity {
             $r->print($lt{'algm'}.'<br /><br />');
         }
         &default_privileges($r,$action,$tools,$toolprivs,$fixedprivs,
-			    $available);
+			    $available,$functions);
     } else {
         if ($action eq 'create') {
             $r->print($lt{'asyo'});
+            $r->print('<input type="hidden" name="specificity" value="No" />');
         } elsif ($action eq 'modify' && $formname eq 'pick_members') {
             my @defprivs;
             if (ref($$stored{'defpriv'}) eq 'ARRAY') {
@@ -1896,7 +2326,7 @@ sub privilege_specificity {
 }
 
 sub default_privileges {
-    my ($r,$action,$tools,$toolprivs,$fixedprivs,$available) = @_;
+    my ($r,$action,$tools,$toolprivs,$fixedprivs,$available,$functions) = @_;
     my %lt = &Apache::lonlocal::texthash(
                                 'addp' => 'Additional privileges',
                                 'fixp' => 'Fixed privileges',
@@ -1905,8 +2335,12 @@ sub default_privileges {
     );
     $r->print(&Apache::lonhtmlcommon::start_pick_box('LC_group_priv_box').
 	      &Apache::lonhtmlcommon::row_title($lt{'func'},undef,
-						'LC_groups_functionality'));
-    $r->print(join('</td><td class="LC_groups_functionality">',@{$tools}));
+     						'LC_groups_functionality'));
+    my @tableHeader;
+    foreach my $key (sort(keys(%{$functions}))){
+        push (@tableHeader,&mt($functions->{$key}));
+    }   
+ $r->print(join('</td><td class="LC_groups_functionality">', @tableHeader));
     $r->print(&Apache::lonhtmlcommon::row_closure(1));
     my $fixed = '';
     my $dynamic = '';
@@ -1921,7 +2355,8 @@ sub default_privileges {
 		if ($fixed ne '') {
 		    $fixed .= '</td><td class="LC_groups_fixed">';
 		}
-                $fixed .= '<input type="hidden" name="defpriv" value="'.$priv.'" /><nobr>'.$$toolprivs{$tool}{$priv}.'&nbsp;';
+                $fixed .= '<input type="hidden" name="defpriv" value="'.$priv.'" />'
+                         .'<span class="LC_nobreak">'.&mt($$toolprivs{$tool}{$priv}).'&nbsp;';
                 if ($action eq 'modify') {
                     if (grep(/^$tool$/,@{$available})) {
                         $fixed .= '<small>'.&mt('(on)').'<small>&nbsp;';
@@ -1929,18 +2364,18 @@ sub default_privileges {
                         $fixed .= '<small>'.&mt('(off)').'<small>&nbsp;';
                     }
                 }
-                $fixed .= '</nobr>';
+                $fixed .= '</span>';
             } else {
                 $privcount++;
                 if ($privcount == 3) {
                     $dynamic .= '</tr>
                                  <tr>'."\n";
                 }
-                $dynamic .= '<td><nobr><label><input type="checkbox" name="defpriv" value="'.$priv.'" />'.$$toolprivs{$tool}{$priv}.'</label></nobr></td>'."\n";
+                $dynamic .= '<td><span class="LC_nobreak"><label><input type="checkbox" name="defpriv" value="'.$priv.'" />'.&mt($$toolprivs{$tool}{$priv}).'</label></span></td>'."\n";
             }
         }
         if ($privcount == 0) {
-            $dynamic .= '<td>None</td>'."\n";
+            $dynamic .= '<td>'.&mt('None').'</td>'."\n";
         }
         if ($privcount < 3) {
             $dynamic .= '<td>&nbsp;</td>'."\n";
@@ -2058,11 +2493,11 @@ sub change_members_form {
     $r->print('
 <br />
 ');
-    &topic_bar($r,1,$lt{'grse'});
+    $r->print(&Apache::lonhtmlcommon::topic_bar(1,$lt{'grse'}));
     &print_current_settings($r,$action,$functions,$startdate,$enddate,
 			    $groupname,$description,$granularity,$quota,
 			    \@available,\@unavailable,$gpterm,$ucgpterm);
-    &topic_bar($r,2,$lt{'mogm'});
+    $r->print(&Apache::lonhtmlcommon::topic_bar(2,$lt{'mogm'}));
     my $numcurrent = &current_membership($r,$cdom,$cnum,$formname,$groupname,
                                          \@available,\@unavailable,$fixedprivs,
 			                 $granularity,$specificity);
@@ -2120,15 +2555,15 @@ sub current_membership {
                 $r->print(&check_uncheck_tools($r,$available));
                 $r->print('
      <td>
-      <nobr>
-       <fieldset><legend><b>'.$lt{'curf'}.'</b></legend>
-       <input type="button" value="check all"
+      <span class="LC_nobreak">
+       <fieldset><legend>'.$lt{'curf'}.'</legend>
+       <input type="button" value="'.&mt('check all').'"
        onclick="javascript:checkAllTools(document.'.$formname.')" />
        &nbsp;&nbsp;
-       <input type="button" value="uncheck all"
+       <input type="button" value="'.&mt('uncheck all').'"
         onclick="javascript:uncheckAllTools(document.'.$formname.')" />
       </fieldset>
-     </nobr>
+     </span>
     </td>
 ');
             }
@@ -2163,14 +2598,14 @@ END
             if ($granularity eq 'Yes') {
                 $r->print(&Apache::loncommon::start_data_table_row('LC_data_table_dense LC_data_table_highlight').'
  <td colspan="7">&nbsp;</td>
- <td colspan="'.$colspan.'" align="center"><nobr><b>'.&mt('All:').
+ <td colspan="'.$colspan.'" align="center"><span class="LC_nobreak"><b>'.&mt('All:').
   '</b>&nbsp;');
                 foreach my $tool (@{$available}) {
                     $r->print('<label><input type="checkbox" name="togglefunc"'.
    ' onclick="javascript:toggleTools(document.'.$formname.'.user_'.$tool.',this);"'.
    ' value="'.$tool.'" />'.'<b>'.$tool.'</b></label>&nbsp;&nbsp;&nbsp;');
                 }
-                $r->print('</nobr></td></tr>');
+                $r->print('</span></td></tr>');
             }
         }
         my %Sortby = ();
@@ -2198,25 +2633,25 @@ END
                 $r->print(&Apache::loncommon::start_data_table_row('LC_data_table_dense').'
                             <td>');
                 if ($$current{$user}{changestate} eq 'reenable') {
-                    $r->print('<nobr><label>'. 
+                    $r->print('<span class="LC_nobreak"><label>'. 
    '<input type="checkbox" name="reenable" value="'.$user.'" />'.
-   $lt{'reen'}.'</label></nobr><br />');
+   $lt{'reen'}.'</label></span><br />');
                 } elsif ($$current{$user}{changestate} eq 'expire') {
-                    $r->print('<nobr><label>'.
+                    $r->print('<span class="LC_nobreak"><label>'.
    '<input type="checkbox" name="expire" value="'.$user.'" />'.
-   $lt{'expi'}.'</label></nobr><br />');
+   $lt{'expi'}.'</label></span><br />');
                 } elsif ($$current{$user}{changestate} eq 'activate') {
-                    $r->print('<nobr><label>'.
+                    $r->print('<span class="LC_nobreak"><label>'.
    '<input type="checkbox" name="activate" value="'.$user.'" />'.
-   $lt{'acti'}.'</label></nobr><br />');
+   $lt{'acti'}.'</label></span><br />');
                 }
-                $r->print('<nobr><label>'.
+                $r->print('<span class="LC_nobreak"><label>'.
    '<input type="checkbox" name="deletion" value="'.$user.'" />'.
-   $lt{'dele'}.'</label></nobr>');
+   $lt{'dele'}.'</label></span>');
                 if ($specificity eq 'Yes') {
-                    $r->print('<br /><nobr><label>'.
+                    $r->print('<br /><span class="LC_nobreak"><label>'.
    '<input type="checkbox" name="changepriv" value="'.$user.'" />'.$lt{'chpr'}.
-   '</label></nobr>');
+   '</label></span>');
                 }
                 $r->print('
    </td>'.
@@ -2227,7 +2662,7 @@ END
    '<td>'.$start.'</td>'.
    '<td>'.$end.'</td>');
                 if ($hastools) {
-                    $r->print('<td align="left"><nobr>'.
+                    $r->print('<td align="left"><span class="LC_nobreak">'.
                                   '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');
                     foreach my $tool (@{$$current{$user}{currtools}}) {
                         if ($granularity eq 'Yes') {
@@ -2243,23 +2678,23 @@ END
                          }
                          $r->print('&nbsp;&nbsp;&nbsp;');
                     }
-                    $r->print('</nobr></td>');
+                    $r->print('</span></td>');
                 }
                 if ($addtools) {
                     $r->print('<td align="left">');
                     if ($granularity eq 'Yes') {
                         foreach my $tool (@{$$current{$user}{newtools}}) {
-                            $r->print('<nobr><label><input type="checkbox"
+                            $r->print('<span class="LC_nobreak"><label><input type="checkbox"
                                           name="user_'.$tool.'" value="'.
                                           $user.'" />'.$tool.
-                                          '</label></nobr>&nbsp;&nbsp;&nbsp;');
+                                          '</label></span>&nbsp;&nbsp;&nbsp;');
                         }
                     } else {
                         foreach my $tool (@{$$current{$user}{newtools}}) {
-                            $r->print('<nobr><input type="hidden" 
+                            $r->print('<span class="LC_nobreak"><input type="hidden" 
                                           name="user_'. $tool.'" value="'.
                                           $user.'" />'.$tool.
-                                          '</nobr>&nbsp;&nbsp;&nbsp;');
+                                          '</span>&nbsp;&nbsp;&nbsp;');
                         }
                     }
                     $r->print('</td>');
@@ -2279,14 +2714,14 @@ sub check_uncheck_buttons {
     $r->print('
      <td '.$colspan.'>
        <fieldset>
-       <legend><b>'.$title.'</b></legend>
-      <nobr>
-       <input type="button" value="check all"
+       <legend>'.$title.'</legend>
+      <span class="LC_nobreak">
+       <input type="button" value="'.&mt('check all').'"
        onclick="javascript:checkAll(document.'.$formname.'.'.$field.')" />
        &nbsp;&nbsp;
-       <input type="button" value="uncheck all"
+       <input type="button" value="'.&mt('uncheck all').'"
        onclick="javascript:uncheckAll(document.'.$formname.'.'.$field.')" />
-      </nobr>
+      </span>
        </fieldset>
      </td>
 ');
@@ -2312,7 +2747,7 @@ sub change_privs_form {
     } else {
         $nexttext = $$navbuttons{'mose'};
     }
-    &topic_bar($r,3,&mt('Members to delete or expire'));
+    $r->print(&Apache::lonhtmlcommon::topic_bar(3,&mt('Members to delete or expire')));
     my $exp_or_del = 0;
     if (ref($$memchg{'deletion'}) eq 'ARRAY') {
         if (@{$$memchg{'deletion'}} > 0) {
@@ -2340,7 +2775,7 @@ sub change_privs_form {
         $r->print($lt{'nome'}.'<br />');
     }
     
-    &topic_bar($r,4,&mt('Setting optional privileges for specific group members'));
+    $r->print(&Apache::lonhtmlcommon::topic_bar(4,&mt('Setting optional privileges for specific group members')));
 
     my $numchgs = &member_privileges_form($r,$action,$formname,$tools,
                                           $toolprivs,$fixedprivs,$userdata,
@@ -2357,9 +2792,9 @@ sub change_privs_form {
 }
 
 sub add_members_form {
-    my ($r,$action,$formname,$page,$startdate,$enddate,$groupname,
+    my ($r,$cdom,$cnum,$action,$formname,$page,$startdate,$enddate,$groupname,
         $description,$granularity,$quota,$sectioncount,$tools,$functions,
-        $stored,$states,$navbuttons,$gpterm,$ucgpterm)=@_; 
+        $stored,$states,$navbuttons,$gpterm,$ucgpterm,$crstype)=@_;
     $r->print(' <br />');
     my @available = ();
     my @unavailable = ();
@@ -2367,7 +2802,8 @@ sub add_members_form {
     &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);
+    &membership_options($r,$cdom,$cnum,$action,$formname,$sectioncount,1,$gpterm,
+                        $ucgpterm,$crstype);
     my $nexttext = $$navbuttons{'gtns'};
     my $prevtext = $$navbuttons{'gtpp'};
     &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,
@@ -2396,7 +2832,7 @@ sub choose_privs_form {
         $nexttext = $$navbuttons{'adme'};
     }
 
-    &topic_bar($r,6,&mt('Setting optional privileges for specific group members'));
+    $r->print(&Apache::lonhtmlcommon::topic_bar(6,&mt('Setting optional privileges for specific group members')));
 
     &member_privileges_form($r,$action,$formname,$tools,$toolprivs,
                             $fixedprivs,$userdata,$usertools,$idx,undef,
@@ -2407,7 +2843,7 @@ sub choose_privs_form {
         my $img2 = 8;
         &mapping_options($r,$action,$formname,$page,$sectioncount,
                          $states,$stored,$navbuttons,$img1,$img2,
-                         $gpterm,$ucgpterm,$crstype);
+                         $gpterm,$ucgpterm,$crstype,$cdom,$cnum);
     }
     my $prevtext = $$navbuttons{'gtps'};
     &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext,
@@ -2485,7 +2921,10 @@ sub member_privileges_form {
                       'members being added or modified, '. 
                       'there are no optional privileges to set '.
                       'for specific members.',
-            'algr' => 'All group members will receive the same privileges.',
+            'algr' => 'All new group members will receive the same privileges.',
+            'ifex' => 'If previously expired members are being re-enabled, or '.
+                      'if access for future members is being activated now, '.
+                      'previously set privileges will be preserved.',
             'asno' => 'As no group members are being added, '.
                       'there are no specific user privileges to set.',
             'asng' => 'As no group tools will be made available to users, '.
@@ -2559,9 +2998,8 @@ sub member_privileges_form {
                     foreach my $tool (@{$tools}) {
                         if (@{$showboxes{$tool}} > 0) {
                             $r->print('<td valign="top">');
-                            $r->print('<table class="thinborder"><tr>'.
-				      '<th colspan="'.$colspan.'">'.
-                                      $tool.'</th></tr><tr>');
+                            $r->print('<fieldset><legend>'.&mt($tool).'</legend>');
+                            $r->print('<table><tr>');
                             my $privcount = 0;
                             foreach my $priv (@{$showboxes{$tool}}) {
                                 $privcount ++;
@@ -2575,15 +3013,16 @@ sub member_privileges_form {
                                 } else {
                                     $r->print('<td>');
                                 }
-                                $r->print(qq|
-       <fieldset><legend><b>$$toolprivs{$tool}{$priv}</b></legend>
-       <nobr>
-       <input type="button" value="check all"
-         onclick="javascript:checkAll(document.$formname.userpriv_$priv)" />
-       &nbsp;
-       <input type="button" value="uncheck all"
-        onclick="javascript:uncheckAll(document.$formname.userpriv_$priv)" />
-      </nobr></fieldset><br />|);
+                                $r->print(
+ '<fieldset><legend>'.&mt($$toolprivs{$tool}{$priv}).'</legend>'
+.'<span class="LC_nobreak">'
+.' <input type="button" value="'.&mt('check all').'"'
+.' onclick="javascript:checkAll(document.'.$formname.'.userpriv_'.$priv.')" />'
+.'&nbsp;'
+.'<input type="button" value="'.&mt('uncheck all').'"'
+.' onclick="javascript:uncheckAll(document.'.$formname.'.userpriv_'.$priv.')" />'
+.'</span></fieldset><br />'
+                                );
                                 $r->print('</td>');
                                 if ($privcount < @{$showboxes{$tool}}) {
                                     if (@{$showboxes{$tool}} > 2) {
@@ -2595,7 +3034,7 @@ sub member_privileges_form {
                                     }
                                 }
                             }
-                            $r->print('</tr></table></td><td>&nbsp;</td>');
+                            $r->print('</tr></table></fieldset></td><td>&nbsp;</td>');
                         }
                     }
                     $r->print('</tr></table>');
@@ -2619,7 +3058,7 @@ END
             }
         } else {
             if (keys(%{$usertools}) > 0) {
-                $r->print($lt{'algr'}.'<br /><br />');
+                $r->print($lt{'algr'}.'<br />'.$lt{'ifex'}.'<br /><br />');
                 &display_defprivs($r,$tools,$toolprivs,\@defprivs);
             } else {
                 $r->print($lt{'asno'}.'<br />');
@@ -2695,7 +3134,7 @@ sub process_request {
         &process_membership($r,$cdom,$cnum,$action,$state,$groupname,$tools,
                             $enddate,$startdate,$userdata,$idx,$toolprivs,
                             $usertools,$specificity,\@defprivs,$memchg,$gpterm,
-                            $ucgpterm);
+                            $ucgpterm,$crstype);
     }
     return;
 }
@@ -2727,11 +3166,19 @@ sub write_group_data {
     }
     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));
+        $r->print('<div class="LC_warning">'
+                 .&mt('The value you entered for the quota for the group portfolio in this '.$gpterm
+                 .' contained invalid characters, so it has been set to 0 Mb. You can change this by'
+                 .' modifying the '.$gpterm.' settings.')
+                 .'</div>');
     }
     if ($quota > $maxposs) {
         $quota = $maxposs;
-        $r->print(&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,sprintf("%.2f",$maxposs)));
+        $r->print('<div class="LC_warning">'
+                 .&mt('The value you entered for the quota for the group portfolio in this '.$gpterm
+                 .' exceeded the maximum possible value, so it has been set to [_1] Mb '
+                 .'(the maximum possible value).',sprintf("%.2f",$maxposs))
+                 .'</div>');
     }
     my %groupinfo = (
                      description => $esc_description,
@@ -2796,12 +3243,89 @@ sub write_group_data {
             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));
+            if ($result eq 'ok') {
+                $r->print('<div class="LC_success">'
+                         .&mt($ucgpterm.' [_1] was created.','<i>'.$groupname.'</i>')
+                         .'</div>');
+            } else {
+                $r->print('<div class="LC_error">'
+                         .&mt('A problem occurred when creating folders for the new '.$gpterm.' [_1]:'
+                             ,'<i>'.$groupname.'</i>')
+                         .'<br />'.$result
+                         .'</div>');
+            }
+        } elsif ($action eq 'modify') {
+            my (@oldtools,@newtools); 
+            if (ref($$stored{'tool'}) eq 'ARRAY') {
+                @oldtools = @{$$stored{'tool'}};
+            }
+            if (ref($tools) eq 'ARRAY') {
+                @newtools = @{$tools};
+            }
+            if (!grep(/^discussion$/,@oldtools) && 
+                 grep(/^discussion$/,@newtools)) {
+                my $crspath = '/uploaded/'.$cdom.'/'.$cnum.'/';
+                my $boardsmap = $crspath.'group_boards_'.$groupname.'.sequence';
+                my $navmap = Apache::lonnavmaps::navmap->new();
+                my ($bbmapres,$error);
+                if (defined($navmap)) {
+                    $bbmapres = $navmap->getResourceByUrl($boardsmap);
+                    undef($navmap);
+                    if (!$bbmapres) {
+                        my $grpmap = $crspath.'group_folder_'.$groupname.'.sequence';
+                        my $disctitle = &mt('Discussion Boards');
+                        my $outcome = &map_updater($cdom,$cnum,'group_boards_'.
+                                                   $groupname.'.sequence','bbseq',
+                                                   $disctitle,$grpmap);
+                        my ($furl,$ferr) = 
+                            &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
+                        # modify parameter
+                        if ($outcome eq 'ok') {
+                            $navmap = Apache::lonnavmaps::navmap->new();
+                            if (defined($navmap)) {
+                                my $parm_result = &parm_setter($navmap,$cdom,$boardsmap,
+                                                               $groupname);
+                                if ($parm_result) {
+                                    $error = &mt('An error occurred while setting parameters '
+                                             .'for Discussion Boards folder: '
+                                             .'[_1]',$parm_result);
+                                } else {
+                                    $r->print('<div class="LC_success">'.
+                                              &mt('Discussion Boards Folder created.')
+                                              .'</div>');
+                                }
+                                undef($navmap);
+                            } else {
+                                if ($crstype eq 'Community') {
+                                    $error = &mt("An error occurred while setting parameters '.
+                                             'for Discussion Boards folder: '.
+                                             'Could not retrieve community information");
+                                } else {
+                                    $error = &mt("An error occurred while setting parameters '.
+                                             'for Discussion Boards folder: '.
+                                             'Could not retrieve course information");
+                                }
+                            }
+                        } else {
+                            $r->print($outcome);
+                        }
+                    }
+                } else {
+                    $error = &mt("An error occurred while retrieving the contents of the group's folder.").'<br />';
+                    if ($crstype eq 'Community') {
+                        $error .= &mt("You need to re-initialize the community.");
+
+                    } else {
+                        $error .= &mt("You need to re-initialize the course.");
+                    }
+                }
+                if ($error ne '') {
+                    $r->print('<div class="LC_error">'.$error.'</div>');
+                }
             }
-            $r->print(&mt('[_1] [_2] was created.<br />',$ucgpterm,$groupname));
-        } else {
-            $r->print(&mt('[_1] [_2] was updated.<br />',$ucgpterm,$groupname));
+            $r->print('<div class="LC_success">'
+                     .&mt($ucgpterm.' [_1] was updated.','<i>'.$groupname.'</i>')
+                     .'</div>');
         }
     } else {
         my %actiontype = (
@@ -2811,8 +3335,10 @@ sub write_group_data {
         &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));
+        $r->print('<div class="LC_error">'
+                 .&mt('An error occurred when [_1] the '.$gpterm.'. '
+                 .'Please try again.',$actiontype{$action})
+                 .'</div>');
     }
     return $result;
 }
@@ -2820,7 +3346,7 @@ sub write_group_data {
 sub process_membership {
     my ($r,$cdom,$cnum,$action,$state,$groupname,$tools,$enddate,$startdate,
         $userdata,$idx,$toolprivs,$usertools,$specificity,$defprivs,$memchg,
-        $gpterm,$ucgpterm)=@_;
+        $gpterm,$ucgpterm,$crstype)=@_;
     my %usersettings = ();
     my %added= ();
     my %failed = ();
@@ -2831,6 +3357,7 @@ sub process_membership {
     my %curr_start = ();
     my %curr_end = ();
     my %tooltype = ();
+    my $context = 'processgroupmembership';
 
     foreach my $tool (@{$tools}) {
         foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) {
@@ -2900,7 +3427,7 @@ sub process_membership {
                                                       $curr_privs{$user};
                 if (&Apache::lonnet::modify_group_roles($cdom,$cnum,$groupname,
                                                        $user,$now,$savestart,
-                                                       $curr_privs{$user}) eq 'ok') {
+                                                       $curr_privs{$user},'',$context) eq 'ok') {
                     push(@{$added{'expired'}},$user);
                     $num_ok ++;
                 } else {
@@ -2911,7 +3438,7 @@ sub process_membership {
             foreach my $user (@deletion) {
                 $usersettings{$groupname.':'.$user} = $now.':-1:';
                 if (&Apache::lonnet::modify_group_roles($cdom,$cnum,$groupname,
-                                                       $user,$now,'-1','')
+                                                       $user,$now,'-1','','',$context)
                                                          eq 'ok') {
                     push(@{$added{'deleted'}},$user);
                     $num_ok ++;
@@ -2965,7 +3492,7 @@ sub process_membership {
                                               $group_privs{$user};
         if (&Apache::lonnet::modify_group_roles($cdom,$cnum,$groupname,
                                                 $user,$end,$start,
-                                                $group_privs{$user}) eq 'ok') {
+                                                $group_privs{$user},'',$context) eq 'ok') {
             push(@{$added{$type}},$user);
             $num_ok ++;
         } else {
@@ -3004,7 +3531,9 @@ sub process_membership {
     }
     if ($num_fail) {
         foreach my $type (sort(keys(%failed))) {
-            $r->print(&mt('The following users could not be [_1], because an error occurred:<br />',$type));
+            $r->print('<div class="LC_error">'
+                     .&mt("The following users could not be $type, because an error occurred:")
+                     .'</div>');
             foreach my $user (@{$failed{$type}}) {
                 $r->print($$userdata{$user}[$$idx{fullname}].' - '.$user.'<br />');
             }
@@ -3012,24 +3541,42 @@ sub process_membership {
         $r->print('<br />');
     }
     if (@unchanged > 0) {
-        $r->print(&mt('No change occurred for the following users:<br />'));
+        $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('[_1] membership list updated.',$ucgpterm));
-	$r->print('<p>'.&mt("Any currently logged in course users affected by the changes you made to group membership or privileges for the [_1] group will need to log out and log back in for their LON-CAPA sessions to reflect these changes.",$groupname).'</p>');
+        $r->print('<div class="LC_success">'
+                 .&mt($ucgpterm.' membership list updated.')
+                 .'</div>');
+	$r->print('<p class="LC_info">');
+        if ($crstype eq 'Community') {
+            $r->print(&mt("Any currently logged in community users affected by the changes you made"
+                     .' to group membership or privileges for the [_1] group will need to log out'
+                     .' and log back in for their LON-CAPA sessions to reflect these changes.'
+                     ,'<i>'.$groupname.'</i>'));
+
+        } else {  
+            $r->print(&mt("Any currently logged in course users affected by the changes you made"
+                     .' to group membership or privileges for the [_1] group will need to log out'
+                     .' and log back in for their LON-CAPA sessions to reflect these changes.'
+                     ,'<i>'.$groupname.'</i>'));
+        } 
+        $r->print('</p>');
     } else {
-        $r->print('<br />'.&mt('An error occurred while updating the [_1] membership list -',$gpterm).$roster_result.'<br />');
+        $r->print('<div class="LC_error">'
+                 .&mt("An error occurred while updating the $gpterm membership list:")
+                 .'<br />'.$roster_result
+                 .'</div>');
     }
     return;
 }
 
 sub mapping_options {
     my ($r,$action,$formname,$page,$sectioncount,$states,$stored,
-        $navbuttons,$img1,$img2,$gpterm,$ucgpterm,$crstype) = @_;
+        $navbuttons,$img1,$img2,$gpterm,$ucgpterm,$crstype,$cdom,$cnum) = @_;
     my %lt = &Apache::lonlocal::texthash(
         'auto' => "Settings for automatic $gpterm enrollment",
         'gmma' => "$ucgpterm membership mapping to specific sections/roles",
@@ -3038,7 +3585,6 @@ sub mapping_options {
         'adds'  => "If automatic $gpterm enrollment is enabled, when a user is newly assigned a ".lc($crstype)."-wide or section-specific role, he/she will automatically be added as a member of the $gpterm, with start and end access dates defined by the default dates set for the $gpterm, unless he/she is already a $gpterm member, with access dates that permit either current or future $gpterm access.",
         'drops'  => "If automatic $gpterm disenrollment is enabled, when a user's role is expired, access to the $gpterm will be terminated unless the user continues to have other ".lc($crstype)."-wide or section-specific active or future roles which receive automatic membership in the $gpterm.",
         'pirs' => "Pick roles and sections for automatic $gpterm enrollment",
-        'curr' => 'Currently set to',
         'on' => 'on',
         'off' => 'off',
         'auad' => "Automatically enable $gpterm membership when roles are added?",
@@ -3046,7 +3592,8 @@ sub mapping_options {
         'mapr' => "Mapping of roles and sections affected by automatic $gpterm enrollment/disenrollment follows scheme chosen below.",
     );
     &automapping($r,$action,$stored,\%lt,$img1);
-    &mapping_settings($r,$sectioncount,\%lt,$stored,$img2,$crstype);
+    &mapping_settings($r,$sectioncount,\%lt,$stored,$img2,$crstype,$cdom,$cnum,
+                      $action);
     return;
 }
 
@@ -3060,26 +3607,25 @@ sub automapping {
     if (exists($$stored{'autodrop'})) {
         $drop = $$stored{'autodrop'};
     }
-    &topic_bar($r,$image,$$lt{'endi'});
-    $r->print('
+    $r->print(&Apache::lonhtmlcommon::topic_bar($image,$$lt{'endi'}).'
     <b>'.$$lt{'gmma'}.':</b><br />'.$$lt{'adds'}.'<br />'.$$lt{'drops'}.'<br /><br />
-   <nobr>'.$$lt{'auad'}.':&nbsp;
-    <label><input type="radio" name="autoadd" value="on" />on&nbsp;&nbsp;</label><label><input type="radio" name="autoadd" value="off" checked="checked" />off</label>');
+   <span class="LC_nobreak">'.$$lt{'auad'}.':&nbsp;
+    <label><input type="radio" name="autoadd" value="on" />'.&mt('on').'&nbsp;&nbsp;</label><label><input type="radio" name="autoadd" value="off" checked="checked" />'.&mt('off').'</label>');
     if ($action eq 'modify') {
-        $r->print('&nbsp;&nbsp;&nbsp;&nbsp;('.$$lt{'curr'}.' <b>'.$$lt{$add}.'</b>)');
+        $r->print('&nbsp;&nbsp;&nbsp;&nbsp;('.&mt('Currently set to [_1].','<b>'.$$lt{$add}.'</b>').')');
     }
     $r->print('
-    </nobr><br />
-    <nobr>'.$$lt{'auex'}.':&nbsp;
-    <label><input type="radio" name="autodrop" value="on" />on&nbsp;&nbsp;</label><label><input type="radio" name="autodrop" value="off" checked="checked" />off</label>');
+    </span><br />
+    <span class="LC_nobreak">'.$$lt{'auex'}.':&nbsp;
+    <label><input type="radio" name="autodrop" value="on" />'.&mt('on').'&nbsp;&nbsp;</label><label><input type="radio" name="autodrop" value="off" checked="checked" />'.&mt('off').'</label>');
     if ($action eq 'modify') {
-        $r->print('&nbsp;&nbsp;&nbsp;&nbsp;('.$$lt{'curr'}.' <b>'.$$lt{$drop}.'</b>)');
+        $r->print('&nbsp;&nbsp;&nbsp;&nbsp;('.&mt('Currently set to [_1].','<b>'.$$lt{$drop}.'</b>').')');
     }
-    $r->print('</nobr><br /><br />'.$$lt{'mapr'});
+    $r->print('</span><br /><br />'.$$lt{'mapr'});
 }
 
 sub mapping_settings {
-    my ($r,$sectioncount,$lt,$stored,$image,$crstype) = @_;
+    my ($r,$sectioncount,$lt,$stored,$image,$crstype,$cdom,$cnum,$action) = @_;
     my @sections = keys(%{$sectioncount});
     if (@sections > 0) {
         @sections = sort {$a cmp $b} @sections;
@@ -3088,9 +3634,9 @@ sub mapping_settings {
     } else {
         @sections = ('all','none');
     }
-    &topic_bar($r,$image,$$lt{'pirs'});
-    my @roles = &standard_roles();
-    my %customroles = &my_custom_roles();
+    $r->print(&Apache::lonhtmlcommon::topic_bar($image,$$lt{'pirs'}));
+    my @roles = &standard_roles($crstype);
+    my %customroles = &Apache::lonhtmlcommon::course_custom_roles($cdom,$cnum);
     $r->print(&Apache::loncommon::start_data_table().
 	      &Apache::loncommon::start_data_table_header_row());
     $r->print('
@@ -3101,55 +3647,64 @@ sub mapping_settings {
     }
     $r->print(&Apache::loncommon::end_data_table_header_row()."\n");
     foreach my $role (@roles) {
-        my $plrole=&Apache::lonnet::plaintext($role,$crstype);
-        my $sections_sel;
-        if (@sections > 0) {
-            if ($role eq 'cc') {
-                $sections_sel = '<td align="right">'.
-                                &mt('all sections').'<input type="hidden" '. 
-                                'name="sec_cc" value="all" /></td>';
-            } else { 
-                $sections_sel='<td align="right">'.
-                              &sections_selection(\@sections,'sec_'.$role).
-                              '</td>';
-            }
-        }
-        $r->print(&Apache::loncommon::start_data_table_row().
-		  '<td><input type="checkbox" '.
-                  'name="autorole" value="'.$role.'" /></td><td>'.$plrole.
-                  '</td>'.$sections_sel.
-		  &Apache::loncommon::end_data_table_row());
+        my $roletitle=&Apache::lonnet::plaintext($role,$crstype);
+        $r->print(&print_autorole_item($role,$roletitle,\@sections));
     }
+    my @customs;
     foreach my $role (sort(keys(%customroles))) {
-        my $sections_sel;
-        if (@sections > 0) {
-            $sections_sel = 
-		'<td>'.&sections_selection(\@sections,'sec_'.$role).'</td>';
-        }
-        $r->print(&Apache::loncommon::start_data_table_row().
-		  '<td><input type="checkbox" '.
-                  'value="'.$role.'" /></td><td>'.&mt('Custom role: ').
-                  '<i>'.$role.'</i></td>'.$sections_sel.
-		  &Apache::loncommon::end_data_table_row());
+        my ($roletitle) = ($role =~ m|^cr/[^/]+/[^/]+/(.+)$|);
+        push (@customs,$role);
+        $r->print(&print_autorole_item($role,$roletitle,\@sections));
+    }
+    if ($action eq 'modify') {
+        foreach my $role (@{$$stored{'autorole'}}) {
+            if ((!grep(/^\Q$role\E$/,@customs)) && 
+                (!grep(/^\Q$role\E$/,@roles))) {
+                my $roletitle;
+                if ($role =~ /^cr/) {
+                    ($roletitle) = ($role =~ m|_([^_]+)$|);
+                } else {
+                    $roletitle = &Apache::lonnet::plaintext($role,$crstype);
+                }
+                $r->print(&print_autorole_item($role,$roletitle,\@sections));
+            }
+        }
     }
     $r->print(&Apache::loncommon::end_data_table());
     return;
 }
 
-sub standard_roles {
-    my @roles = ('cc','in','ta','ep','st');
-    return @roles;
-}
-
-sub my_custom_roles {
-    my %returnhash=();
-    my %rolehash=&Apache::lonnet::dump('roles');
-    foreach (keys %rolehash) {
-        if ($_=~/^rolesdef\_(\w+)$/) {
-            $returnhash{$1}=$1;
+sub print_autorole_item {
+    my ($role,$roletitle,$sections) = @_;
+    my $sections_sel;
+    if (@{$sections} > 0) {
+        if (($role eq 'cc') || ($role eq 'co')) {
+            $sections_sel = '<td align="right">'.
+                            &mt('all sections').'<input type="hidden" '.
+                            'name="sec_'.$role.'" value="all" /></td>';
+        } else {
+            $sections_sel='<td align="right">'.
+                          &sections_selection($sections,'sec_'.$role).
+                          '</td>';
         }
     }
-    return %returnhash;
+    my $output = &Apache::loncommon::start_data_table_row().
+                 '<td><input type="checkbox" '.
+                 'name="autorole" value="'.$role.'" />'.
+                 '</td><td>'.$roletitle.'</td>'.$sections_sel.
+                 &Apache::loncommon::end_data_table_row();
+    return $output;
+} 
+
+sub standard_roles {
+    my ($crstype) = @_;
+    my @roles = qw(in ta ep ad st);
+    if ($crstype eq 'Community') {
+        unshift(@roles,'co');
+    } else {
+        unshift(@roles,'cc');
+    }
+    return @roles;
 }
 
 sub modify_menu {
@@ -3232,16 +3787,16 @@ sub member_privs_entries {
                         if ($privcount == 3) {
                             $dynamic .= '</tr><tr>';
                         }
-                        $dynamic .='<td><nobr><label><input type="checkbox" '.
+                        $dynamic .='<td><span class="LC_nobreak"><label><input type="checkbox" '.
                                'name="userpriv_'.$priv.'" value="'.$user.'"';
                         if (grep/^\Q$priv\E$/,@{$defprivs}) {
                             $dynamic .= ' checked="checked" ';
                         }
                         $dynamic .= ' />'.$$toolprivs{$tool}{$priv}.
-                                    '</label></nobr></td>';
+                                    '</label></span></td>';
                     }
                 }
-                $r->print('<tr><td colspan="2"><nobr>'.$fixed.'</nobr></td></tr><tr>'.$dynamic.'</tr></table></td>');
+                $r->print('<tr><td colspan="2"><span class="LC_nobreak">'.$fixed.'</span></td></tr><tr>'.$dynamic.'</tr></table></td>');
             } else {
                 $r->print('<td valign="top"><table width="100%"><tr><th colspan="2">'.$tool.'</th></tr><tr><td>&nbsp;</td></tr><tr><td>&nbsp;</td></tr></table></td>');
             }
@@ -3267,17 +3822,19 @@ sub date_setting_table {
                                                       'startdate',$starttime);
     my $endform = &Apache::lonhtmlcommon::date_setter($formname,
                                                       'enddate',$endtime);
-    my $perpetual = 
-	'<nobr><label><input type="checkbox" name="no_end_date" />'.
-	&mt('None').'</label></nobr>';
-    my $table = "<table class=\"LC_descriptive_input\">\n".
-	'<tr><td class="LC_description">'.&mt('Start:').'</td>'.
-        '<td>'.$startform.'</td>'.
-        '<td>&nbsp;</td>'."</tr>\n".
-	'<tr><td class="LC_description">'.&mt('End:').'</td>'.
-        '<td>'.$endform.'</td>'.
-        '<td>'.$perpetual.'</td>'."</tr>\n".
-	"</table>\n";
+    my $perpetual = ' <span class="LC_nobreak"><label>'
+                   .'<input type="checkbox" name="no_end_date" />'
+                   .&mt('No end date')
+                   .'</label></span>';
+    my $table = &Apache::lonhtmlcommon::start_pick_box()
+               .&Apache::lonhtmlcommon::row_title(&mt('Start Date'))
+               .$startform
+               .&Apache::lonhtmlcommon::row_closure()
+               .&Apache::lonhtmlcommon::row_title(&mt('End Date'))
+               .$endform
+               .$perpetual
+               .&Apache::lonhtmlcommon::row_closure(1)
+               .&Apache::lonhtmlcommon::end_pick_box();
     return $table;
 }
 
@@ -3285,52 +3842,72 @@ 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 $error = '<span class="LC_error">';
+        if ($crstype eq 'Community') { 
+            $error .= &mt("Error: invalid community domain or number - group folder creation failed.");
+        } else {
+            $error .= &mt("Error: invalid course domain or number - group folder creation failed.");
+        }
+        $error .= '</span>';
+        return $error;
     }
-    my ($outcome,$allgrpsmap,$grpmap,$boardsmap,$grppage);
-    my $navmap = Apache::lonnavmaps::navmap->new();
+    my ($outcome,$allgrpsmap,$grpmap,$boardsmap,$grppage,$warning);
     my $crspath = '/uploaded/'.$cdom.'/'.$cnum.'/';
     $allgrpsmap = $crspath.'group_allfolders.sequence';
-    my $topmap = $navmap->getResourceByUrl($allgrpsmap);
-    undef($navmap);
     if ($action eq 'create') {
-    # check if group_allfolders.sequence exists.
-        if (!$topmap) {
-            my $grpstitle = &mt('[_1] [_2]s',$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,'group_allfolders.sequence',
-                                        'toplevelgroup',$grpstitle,$topmap_url);
+        if (&get_folder_lock($cdom,$cnum,'group_allfolders',$now) eq 'ok') {
+            # check if group_allfolders.sequence exists.
+            my $mapcontents = &Apache::lonnet::getfile($allgrpsmap);
+            if ($mapcontents eq '-1') { #file does not exist;
+                my $grpstitle = &mt("$crstype $ucgpterm".'s');
+                my $topmap_url = '/'.$env{'course.'.$env{'request.course.id'}.'.url'};
+                $topmap_url =~ s|/+|/|g;
+                if ($topmap_url =~ m|^/uploaded|) {
+                    $outcome = &map_updater($cdom,$cnum,'group_allfolders.sequence',
+                                            'toplevelgroup',$grpstitle,$topmap_url);
+                } else {
+                    $outcome = '<span class="LC_warning">'
+                              .&mt('Non-standard course - folder for all groups not added.')
+                              .'</span>';
+                }
                 if ($outcome ne 'ok') {
-                    return $outcome;
+                    my $delresult = &release_folder_lock($cdom,$cnum,'group_allfolders');
+                    if ($delresult ne 'ok') {
+                        $warning = $delresult;
+                    }
+                    return $outcome.$warning;
                 }
-            } else {
-                $outcome = &mt('Non-standard course - folder for all groups not added.');
-                return $outcome;
             }
+            my $delresult = &release_folder_lock($cdom,$cnum,'group_allfolders');
+            if ($delresult ne 'ok') {
+                $warning = $delresult ;
+            }
+        } else {
+            $outcome = '<span class="LC_error">'
+                      .&mt('Could not obtain exclusive lock to check status of the folder for all groups. No group folder added.')
+                      .'</span>';
+            return $outcome;
         }
-        my $grpfolder = &mt('[_1] Folder -',$ucgpterm,).$description;
+        my $grpfolder = &mt($ucgpterm.' Folder - [_1]',$description);
         $grppage='/adm/'.$cdom.'/'.$cnum.'/'.$groupname.'/smppg';
-        my $grptitle = &mt('Group homepage').' - '.$description;
-        my ($seqid,$discussions,$disctitle);
+        my $grptitle = &mt('Group homepage - [_1]',$description);
+        my ($discussions,$disctitle);
         my $outcome = &map_updater($cdom,$cnum,'group_folder_'.$groupname.'.sequence',
                                    'grpseq',$grpfolder,$allgrpsmap,$grppage,
                                    $grptitle);
         if ($outcome ne 'ok') {
-            return $outcome;
+            return $outcome.$warning;
         }
         my $pageout = &create_homepage($cdom,$cnum,$groupname,$groupinfo,
                                        $tools,$gpterm,$ucgpterm,$now);
         # Link to folder for bulletin boards
         $grpmap = $crspath.'group_folder_'.$groupname.'.sequence';
         if (grep/^discussion$/,@{$tools}) {
-            $seqid = $now + 1;
             $disctitle = &mt('Discussion Boards');
             my $outcome = &map_updater($cdom,$cnum,'group_boards_'.$groupname.
                                        '.sequence','bbseq',$disctitle,$grpmap);
             if ($outcome ne 'ok') {
-                return $outcome;
+                return $outcome.$warning;
             }
             $boardsmap = $crspath.'group_boards_'.$groupname.'.sequence';
         }
@@ -3338,13 +3915,22 @@ sub add_group_folder {
         #modify group folder if status of discussions tools is changed
     }
     my ($furl,$ferr)= &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
-    $navmap = Apache::lonnavmaps::navmap->new();
+    my $navmap = Apache::lonnavmaps::navmap->new();
+    if (!defined($navmap)) {
+        $warning .= '<span class="LC_error">';
+        if ($crstype eq 'Community') {
+            $warning .= &mt("Error retrieving community contents").
+                        ' '.&mt("You need to re-initialize the community.");
+        } else {
+            $warning  .= &mt("Error retrieving course contents").
+                         ' '.&mt("You need to re-initialize the course.");
+        }
+        $warning .= '</span>';
+        return $warning;
+    }
     # modify parameters
     my $parm_result;
     if ($action eq 'create') {
-        if ($allgrpsmap) { 
-            $parm_result .= &parm_setter($navmap,$cdom,$allgrpsmap,$groupname);
-        }
         if ($grpmap) {
             $parm_result .= &parm_setter($navmap,$cdom,$grpmap,$groupname);
         }
@@ -3355,8 +3941,42 @@ sub add_group_folder {
             $parm_result .= &parm_setter($navmap,$cdom,$boardsmap,$groupname);
         }
     }
+    undef($navmap);
     if ($parm_result) {
-        return $parm_result;
+        return $warning.$parm_result;
+    } else {
+        return 'ok';
+    }
+}
+
+sub get_folder_lock {
+    my ($cdom,$cnum,$folder_name,$now) = @_;  
+    # get lock for folder being edited.
+    my $lockhash = {
+                  $folder_name."\0".'locked_folder' => $now.':'.$env{'user.name'}.
+                                                     ':'.$env{'user.domain'},
+                   };
+    my $tries = 0;
+    my $gotlock = &Apache::lonnet::newput('coursegroups',$lockhash,$cdom,$cnum);
+
+    while (($gotlock ne 'ok') && $tries <3) {
+        $tries ++;
+        sleep(1);
+        $gotlock = &Apache::lonnet::newput('coursegroups',$lockhash,$cdom,$cnum);
+    }
+    return $gotlock;
+}
+
+sub release_folder_lock {
+    my ($cdom,$cnum,$folder_name) = @_;  
+    #  remove lock
+    my @del_lock = ($folder_name."\0".'locked_folder');
+    my $dellockoutcome=&Apache::lonnet::del('coursegroups',\@del_lock,$cdom,$cnum);
+    if ($dellockoutcome ne 'ok') {
+        return ('<div class="LC_error">'
+               .&mt('Warning: failed to release lock for folder: [_1].','<tt>'.$folder_name.'</tt>')
+               .'</div>'
+               );
     } else {
         return 'ok';
     }
@@ -3371,21 +3991,27 @@ sub map_updater {
     my $newmapurl=&Apache::lonnet::finishuserfileupload($cnum,$cdom,$itemname,
                                                         $newfile);
     if ($newmapurl !~ m|^/uploaded|) {
-        $outcome = &mt('Error uploading new folder.')." ($newfile): $newmapurl".'<br />';
+        $outcome = '<div class="LC_error">'
+                  .&mt('Error uploading new folder.')." ($newfile): $newmapurl"
+                  .'</div>';
         return $outcome;
-    } 
-    my ($errtext,$fatal)=&Apache::lonratedt::mapread($parentmap);
+    }
+    my ($errtext,$fatal)=&LONCAPA::map::mapread($parentmap);
     if ($fatal) {
-        $outcome = &mt('Error reading contents of parent folder')." ($parentmap): $errtext".'<br />';
+        $outcome = '<div class="LC_error">'
+                  .&mt('Error reading contents of parent folder.')." ($parentmap): $errtext"
+                  .'</div>';
         return $outcome;
     } else {
-        my $newidx=&Apache::lonratedt::getresidx($newmapurl);
-        $Apache::lonratedt::resources[$newidx] = $itemtitle.':'.$newmapurl.
+        my $newidx=&LONCAPA::map::getresidx($newmapurl);
+        $LONCAPA::map::resources[$newidx] = $itemtitle.':'.$newmapurl.
                                                  ':false:normal:res';
-        $Apache::lonratedt::order[1+$#Apache::lonratedt::order]=$newidx;
-        my ($outtext,$errtext) = &Apache::lonratedt::storemap($parentmap,1);
+        $LONCAPA::map::order[1+$#LONCAPA::map::order]=$newidx;
+        my ($outtext,$errtext) = &LONCAPA::map::storemap($parentmap,1);
         if ($errtext) {
-            $outcome = &mt('Error storing updated parent folder')." ($parentmap):  $errtext".'<br />';
+            $outcome = '<div class="LC_error">'
+                      .&mt('Error saving updated parent folder.')." ($parentmap):  $errtext"
+                      .'</div>';
             return $outcome;
         }
     }
@@ -3405,8 +4031,19 @@ sub new_map {
 }
 
 sub parm_setter {
-    my ($navmap,$cdom,$url,$groupname) = @_;
-    my $allresults;
+    my ($navmap,$cdom,$url,$groupname,$crstype) = @_;
+    if (!defined($navmap)) {
+        my $allresults;
+        if ($crstype eq 'Community') { 
+            $allresults = &mt("Parameters not set for [_1] because the contents of the community could not be retrieved.",$url).' '.
+                          &mt("You need to reinitialize the community.");
+        } else {
+            $allresults = &mt("Parameters not set for [_1] because the contents of the course could not be retrieved.",$url).' '.
+                          &mt("You need to reinitialize the course.");
+
+        }
+        return '<div class="LC_warning">'.$allresults.'</div>';
+    }
     my %hide_settings = (
                            'course' =>  {
                                           'num' => 13,
@@ -3419,18 +4056,30 @@ sub parm_setter {
                                         },
                         );
     my $res = $navmap->getResourceByUrl($url);
-    my $symb = $res->symb();
-    foreach my $level (keys(%hide_settings)) {
-        my $parmresult =  &Apache::lonparmset::storeparm_by_symb($symb,
+    my $allresults;
+    if ($res) {
+        my $symb = $res->symb();
+        foreach my $level (keys(%hide_settings)) {
+            my $parmresult =  
+                       &Apache::lonparmset::storeparm_by_symb($symb,
                                                  '0_hiddenresource',
                                                  $hide_settings{$level}{'num'},
                                                  $hide_settings{$level}{'set'},
                                                  'string_yesno',undef,$cdom,
                                                  undef,undef,
                                                  $hide_settings{$level}{'extra'});
-        if ($parmresult) {
-            $allresults .= $level.': '.$parmresult;
+            if ($parmresult) {
+                $allresults .= $level.': '.$parmresult;
+            }
         }
+    } else {
+        $allresults = '<div class="LC_warning">';
+        if ($crstype eq 'Community') {
+            $allresults .= &mt("Parameters not set for [_1] because the resource was not recognized as part of the community.",'<tt>'.$url.'</tt>');
+        } else {
+            $allresults .= &mt('Parameters not set for [_1] because the resource was not recognized as part of the course.','<tt>'.$url.'</tt>');
+        }
+        $allresults .= '</div>';
     }
     return $allresults;
 }
@@ -3494,7 +4143,12 @@ sub validate_groupname {
     my ($groupname,$action,$cdom,$cnum,$gpterm,$ucgpterm,$crstype) = @_;
     my %sectioncount = &Apache::loncommon::get_sections($cdom,$cnum);
     my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum);
-
+    my %deleted_groups = &Apache::longroup::coursegroups($cdom,$cnum,undef,
+                                                         'deleted_groups');
+    if (my $tmp = &Apache::lonnet::error(%deleted_groups)) {
+        undef(%deleted_groups);
+        &Apache::lonnet::logthis('Error retrieving groups: '.$tmp.' in '.$cnum.':'.$cdom);
+    }
     my %lt = &Apache::lonlocal::texthash (
                       igna => "Invalid $gpterm name",
                       tgne => "The $gpterm name entered ",
@@ -3521,12 +4175,14 @@ sub validate_groupname {
 	return $exitmsg.$lt{'cnnb'}.&mt('a section').$lt{'inth'}.
 	    '<br />'.$lt{'grna'};
     }
-    if ($action eq 'create' 
-	&& exists($curr_groups{$groupname})) {
-
-	return $exitmsg.$lt{'cnnb'}.&mt('an existing [_1]',$gpterm).
-	    $lt{'inth'}.'<br />'.$lt{'grna'};
-
+    if ($action eq 'create') { 
+	if (exists($curr_groups{$groupname})) {
+	    return $exitmsg.$lt{'cnnb'}.&mt('an existing [_1]',$gpterm).
+	           $lt{'inth'}.'.<br />'.$lt{'grna'};
+        } elsif (exists($deleted_groups{$groupname})) {
+            return $exitmsg.$lt{'cnnb'}.&mt('a [_1] which previously existed',$gpterm).
+                   $lt{'inth'}.'.<br />'.$lt{'grna'};
+        }
     } elsif ($action eq 'modify') {
         unless(exists($curr_groups{$groupname})) {
             $earlyout = &mt('[_1] name:',$ucgpterm).' '.$groupname.$lt{'thgr'}.
@@ -3537,18 +4193,6 @@ sub validate_groupname {
     return;
 }
 
-sub topic_bar {
-    my ($r,$imgnum,$title) = @_;
-    $r->print('
-<div class="LC_topic_bar">
-    <img alt="'.&mt('Step [_1]',$imgnum).
-	      '"src="/res/adm/pages/bl_step'.$imgnum.'.gif" />&nbsp;
-    <span>'.$title.'</span>
-</div>
-');
-    return;
-}
-
 sub check_changes {
     my ($member_changes,$memchg) = @_;
     my %exclusions;