--- loncom/interface/domainprefs.pm	2017/11/01 08:56:25	1.160.6.84.2.8
+++ loncom/interface/domainprefs.pm	2017/05/22 07:58:46	1.300
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Handler to set domain-wide configuration settings
 #
-# $Id: domainprefs.pm,v 1.160.6.84.2.8 2017/11/01 08:56:25 raeburn Exp $
+# $Id: domainprefs.pm,v 1.300 2017/05/22 07:58:46 droeschl Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -104,8 +104,8 @@ $datatable  - HTML containing form eleme
 
 In the case of course requests, radio buttons are displayed for each institutional
 affiliate type (and also default, and _LC_adv) for each of the course types 
-(official, unofficial, community, and textbook).  In each case the radio buttons 
-allow the selection of one of four values:
+(official, unofficial, community, textbook, and placement).  
+In each case the radio buttons allow the selection of one of four values:  
 
 0, approval, validate, autolimit=N (where N is blank, or a positive integer).
 which have the following effects:
@@ -170,10 +170,12 @@ use Apache::loncoursequeueadmin();
 use LONCAPA qw(:DEFAULT :match);
 use LONCAPA::Enrollment;
 use LONCAPA::lonauthcgi();
+use LONCAPA::SSL;
 use File::Copy;
 use Locale::Language;
 use DateTime::TimeZone;
 use DateTime::Locale;
+use Time::HiRes qw( sleep );
 
 my $registered_cleanup;
 my $modified_urls;
@@ -217,7 +219,7 @@ sub handler {
                 'serverstatuses','requestcourses','helpsettings',
                 'coursedefaults','usersessions','loadbalancing',
                 'requestauthor','selfenrollment','inststatus',
-                'ltitools'],$dom);
+                'ltitools','ssl','trust'],$dom);
     if (ref($domconfig{'ltitools'}) eq 'HASH') {
         my %encconfig =
             &Apache::lonnet::get_dom('encconfig',['ltitools'],$dom);
@@ -236,7 +238,7 @@ sub handler {
                        'usercreation','selfcreation','usermodification','scantron',
                        'requestcourses','requestauthor','coursecategories',
                        'serverstatuses','helpsettings','coursedefaults',
-                       'ltitools','selfenrollment','usersessions');
+                       'ltitools','selfenrollment','usersessions','ssl','trust');
     my %existing;
     if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
         %existing = %{$domconfig{'loadbalancing'}};
@@ -466,6 +468,14 @@ sub handler {
                   print => \&print_selfenrollment,
                   modify => \&modify_selfenrollment,
                  },
+        'privacy' => 
+                 {text   => 'User Privacy',
+                  help   => 'Domain_Configuration_User_Privacy',
+                  header => [{col1 => 'Setting',
+                              col2 => 'Value',}],
+                  print => \&print_privacy,
+                  modify => \&modify_privacy,
+                 },
         'usersessions' =>
                  {text  => 'User session hosting/offloading',
                   help  => 'Domain_Configuration_User_Sessions',
@@ -489,7 +499,7 @@ sub handler {
                   print => \&print_loadbalancing,
                   modify => \&modify_loadbalancing,
                  },
-        'ltitools' =>
+        'ltitools' => 
                  {text => 'External Tools (LTI)',
                   help => 'Domain_Configuration_LTI_Tools',
                   header => [{col1 => 'Setting',
@@ -497,6 +507,44 @@ sub handler {
                   print => \&print_ltitools,
                   modify => \&modify_ltitools,
                  },
+        'ssl' =>
+                 {text  => 'LON-CAPA Network (SSL)',
+                  help  => 'Domain_Configuration_Network_SSL',
+                  header => [{col1 => 'Server',
+                              col2 => 'Certificate Status'},
+                             {col1 => 'Connections to other servers',
+                              col2 => 'Rules'},
+                             {col1 => 'Connections from other servers',
+                              col2 => 'Rules'},
+                             {col1 => "Replicating domain's published content",
+                              col2 => 'Rules'}],
+                  print => \&print_ssl,
+                  modify => \&modify_ssl,
+                 },
+        'trust' =>
+                 {text   => 'Trust Settings',
+                  help   => 'Domain_Configuration_Trust',
+                  header => [{col1 => "Access to this domain's content by others",
+                              col2 => 'Rules'},
+                             {col1 => "Access to other domain's content by this domain",
+                              col2 => 'Rules'},
+                             {col1 => "Enrollment in this domain's courses by others",
+                              col2 => 'Rules',},
+                             {col1 => "Co-author roles in this domain for others",
+                              col2 => 'Rules',},
+                             {col1 => "Co-author roles for this domain's users elsewhere",
+                              col2 => 'Rules',},
+                             {col1 => "Domain roles in this domain assignable to others",
+                              col2 => 'Rules'},
+                             {col1 => "Course catalog for this domain displayed elsewhere",
+                              col2 => 'Rules'},
+                             {col1 => "Requests for creation of courses in this domain by others",
+                              col2 => 'Rules'},
+                             {col1 => "Users in other domains can send messages to this domain",
+                              col2 => 'Rules'},],
+                  print => \&print_trust,
+                  modify => \&modify_trust,
+                 },
     );
     if (keys(%servers) > 1) {
         $prefs{'login'}  = { text   => 'Log-in page options',
@@ -675,6 +723,10 @@ sub process_changes {
         $output = &modify_loadbalancing($dom,%domconfig);
     } elsif ($action eq 'ltitools') {
         $output = &modify_ltitools($r,$dom,$action,$lastactref,%domconfig);
+    } elsif ($action eq 'ssl') {
+        $output = &modify_ssl($dom,$lastactref,%domconfig);
+    } elsif ($action eq 'trust') {
+        $output = &modify_trust($dom,$lastactref,%domconfig);
     }
     return $output;
 }
@@ -701,7 +753,7 @@ sub print_config_box {
         &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent);
         my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);
         $output =
-            &Apache::lonuserutils::custom_roledefs_js($context,$crstype,$formname,\%full,
+            &Apache::lonuserutils::custom_roledefs_js($context,$crstype,$formname,\%full, 
                                                       \@templateroles);
     }
     $output .=
@@ -738,8 +790,9 @@ sub print_config_box {
         $rowtotal ++;
         if (($action eq 'autoupdate') || ($action eq 'usercreation') || ($action eq 'selfcreation') ||
             ($action eq 'usermodification') || ($action eq 'defaults') || ($action eq 'coursedefaults') ||
-            ($action eq 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'directorysrch') ||
-            ($action eq 'helpsettings') || ($action eq 'contacts')) {
+            ($action eq 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'ssl') ||
+            ($action eq 'directorysrch') || ($action eq 'trust') || ($action eq 'helpsettings') ||
+            ($action eq 'contacts')) {
             $output .= $item->{'print'}->('top',$dom,$settings,\$rowtotal);
         } elsif ($action eq 'coursecategories') {
             $output .= $item->{'print'}->('top',$dom,$item,$settings,\$rowtotal);
@@ -769,15 +822,46 @@ sub print_config_box {
             $rowtotal ++;
         if (($action eq 'autoupdate') || ($action eq 'usercreation') ||
             ($action eq 'selfcreation') || ($action eq 'selfenrollment') ||
-            ($action eq 'usersessions') || ($action eq 'coursecategories') ||
-            ($action eq 'contacts') || ($action eq 'defaults')) {
+            ($action eq 'usersessions') || ($action eq 'coursecategories') || 
+            ($action eq 'trust') || ($action eq 'contacts') || ($action eq 'defaults')) {
             if ($action eq 'coursecategories') {
                 $output .= &print_coursecategories('middle',$dom,$item,$settings,\$rowtotal);
                 $colspan = ' colspan="2"';
+            } elsif ($action eq 'trust') {
+                $output .= $item->{'print'}->('shared',$dom,$settings,\$rowtotal);
             } else {
                 $output .= $item->{'print'}->('middle',$dom,$settings,\$rowtotal);
             }
-            $output .= '
+            if ($action eq 'trust') {
+                $output .= '
+            </table>
+          </td>
+         </tr>';
+                my @trusthdrs = qw(2 3 4 5 6 7);
+                my @prefixes = qw(enroll othcoau coaurem domroles catalog reqcrs);
+                for (my $i=0; $i<@trusthdrs; $i++) {
+                    $output .= '
+         <tr>
+           <td>
+            <table class="LC_nested">
+             <tr class="LC_info_row">
+              <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[$trusthdrs[$i]]->{'col1'}).'</td>
+              <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[$trusthdrs[$i]]->{'col2'}).'</td></tr>'.
+                           $item->{'print'}->($prefixes[$i],$dom,$settings,\$rowtotal).'
+            </table>
+          </td>
+         </tr>';
+                }
+                $output .= '
+         <tr>
+           <td>
+            <table class="LC_nested">
+             <tr class="LC_info_row">
+              <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[8]->{'col1'}).'</td>
+              <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[8]->{'col2'}).'</td></tr>'.
+                           $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
+            } else {
+                $output .= '
            </table>
           </td>
          </tr>
@@ -788,16 +872,39 @@ sub print_config_box {
               <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
               <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>
              </tr>'."\n";
-            if ($action eq 'coursecategories') {
-                $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal);
-            } else {
-                $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
+                if ($action eq 'coursecategories') {
+                    $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal);
+                } else {
+                    $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
+                }
             }
             $rowtotal ++;
         } elsif (($action eq 'usermodification') || ($action eq 'coursedefaults') ||
                  ($action eq 'defaults') || ($action eq 'directorysrch') ||
                  ($action eq 'helpsettings')) {
             $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
+        } elsif ($action eq 'ssl') {
+            $output .= $item->{'print'}->('connto',$dom,$settings,\$rowtotal).'
+            </table>
+          </td>
+         </tr>
+         <tr>
+           <td>
+            <table class="LC_nested">
+             <tr class="LC_info_row">
+              <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
+              <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col2'}).'</td></tr>'.
+                           $item->{'print'}->('connfrom',$dom,$settings,\$rowtotal).'
+            </table>
+          </td>
+         </tr>
+         <tr>
+           <td>
+            <table class="LC_nested">
+             <tr class="LC_info_row">
+              <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col1'}).'</td>
+              <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col2'}).'</td></tr>'.
+                           $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
         } elsif ($action eq 'login') {
             if ($numheaders == 4) {
                 $output .= &print_login('page',$dom,$confname,$phase,$settings,\$rowtotal).'
@@ -954,7 +1061,7 @@ sub print_config_box {
         if ($action eq 'quotas') {
             $output .= &print_quotas($dom,$settings,\$rowtotal,$action);
         } elsif (($action eq 'autoenroll') || ($action eq 'autocreate') || 
-                 ($action eq 'serverstatuses') || ($action eq 'loadbalancing') ||
+                 ($action eq 'serverstatuses') || ($action eq 'loadbalancing') || 
                  ($action eq 'ltitools')) {
             $output .= $item->{'print'}->($dom,$settings,\$rowtotal);
         } elsif ($action eq 'scantron') {
@@ -1759,7 +1866,7 @@ sub print_quotas {
     my $typecount = 0;
     my ($css_class,%titles);
     if ($context eq 'requestcourses') {
-        @usertools = ('official','unofficial','community','textbook');
+        @usertools = ('official','unofficial','community','textbook','placement');
         @options =('norequest','approval','validate','autolimit');
         %validations = &Apache::lonnet::auto_courserequest_checks($dom);
         %titles = &courserequest_titles();
@@ -2211,7 +2318,7 @@ sub print_studentcode {
     my ($settings,$rowtotal) = @_;
     my $rownum = 0; 
     my ($output,%current);
-    my @crstypes = ('official','unofficial','community','textbook');
+    my @crstypes = ('official','unofficial','community','textbook','placement');
     if (ref($settings) eq 'HASH') {
         if (ref($settings->{'uniquecode'}) eq 'HASH') {
             foreach my $type (@crstypes) {
@@ -2307,8 +2414,7 @@ sub print_textbookcourses {
                               ('&nbsp;'x2).
                               '<span class="LC_nobreak">'.&mt('Thumbnail:');
                 if ($image) {
-                    $datatable .= '<span class="LC_nobreak">'.
-                                  $imgsrc.
+                    $datatable .= $imgsrc.
                                   '<label><input type="checkbox" name="'.$type.'_image_del"'.
                                   ' value="'.$key.'" />'.&mt('Delete?').'</label></span> '.
                                   '<span class="LC_nobreak">&nbsp;'.&mt('Replace:').'&nbsp;';
@@ -2658,7 +2764,7 @@ sub print_autoupdate {
         my $locknamesettings;
         $datatable .= &insttypes_row($settings,$types,$usertypes,
                                      $dom,$numinrow,$othertitle,
-                                    'lockablenames',$rowtotal);
+                                    'lockablenames');
         $$rowtotal ++;
     } else {
         my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
@@ -2801,8 +2907,7 @@ sub print_directorysrch {
         if (ref($usertypes) eq 'HASH') {
             if (keys(%{$usertypes}) > 0) {
                 $datatable .= &insttypes_row($settings,$types,$usertypes,$dom,
-                                             $numinrow,$othertitle,'cansearch',
-                                             $rowtotal);
+                                             $numinrow,$othertitle,'cansearch');
                 $cansrchrow = 1;
             }
         }
@@ -3003,54 +3108,7 @@ sub print_contacts {
                           $to{$item}.'" /></td></tr>';
             $rownum ++;
         }
-    } elsif ($position eq 'bottom') {
-        $css_class = $rownum%2?' class="LC_odd_row"':'';
-        $datatable .= '<tr'.$css_class.'>'.
-                      '<td>'.&mt('Extra helpdesk form fields:').'<br />'.
-                      &mt('(e-mail, subject, and description always shown)').
-                      '</td><td class="LC_left_item">';
-        if ((ref($fields) eq 'ARRAY') && (ref($fieldtitles) eq 'HASH') &&
-            (ref($fieldoptions) eq 'HASH') && (ref($possoptions) eq 'HASH')) {
-            $datatable .= '<table><tr><th>'.&mt('Field').'</th><th>'.&mt('Status').'</th></tr>';
-            foreach my $field (@{$fields}) {
-                $datatable .= '<tr><td>'.$fieldtitles->{$field};
-                if (($field eq 'screenshot') || ($field eq 'cc')) {
-                    $datatable .= ' '.&mt('(logged-in users)');
-                }
-                $datatable .='</td><td>';
-                my $clickaction;
-                if ($field eq 'screenshot') {
-                    $clickaction = ' onclick="screenshotSize(this);"';
-                }
-                if (ref($possoptions->{$field}) eq 'ARRAY') {
-                    foreach my $option (@{$possoptions->{$field}}) {
-                        my $checked;
-                        if ($currfield{$field} eq $option) {
-                            $checked = ' checked="checked"';
-                        }
-                        $datatable .= '<span class="LC_nobreak"><label>'.
-                                      '<input type="radio" name="helpform_'.$field.'" '.
-                                      'value="'.$option.'"'.$checked.$clickaction.' />'.$fieldoptions->{$option}.
-                                      '</label></span>'.('&nbsp;'x2);
-                    }
-                }
-                if ($field eq 'screenshot') {
-                    my $display;
-                    if ($currfield{$field} eq 'no') {
-                        $display = ' style="display:none"';
-                    }
-                    $datatable .= '</td></tr><tr id="help_screenshotsize"'.$display.' />'.
-                                  '<td>'.&mt('Maximum size for upload (MB)').'</td><td>'.
-                                  '<input type="text" size="5" name="helpform_maxsize" value="'.$maxsize.'" />';
-                }
-                $datatable .= '</td></tr>';
-            }
-            $datatable .= '</table>';
-        }
-        $datatable .= '</td></tr>'."\n";
-        $rownum ++;
-    }
-    unless ($position eq 'top') {
+    } else {
         foreach my $type (@mailings) {
             $css_class = $rownum%2?' class="LC_odd_row"':'';
             $datatable .= '<tr'.$css_class.'>'.
@@ -3110,138 +3168,56 @@ sub print_contacts {
                                                    \%choices,$rownum);
         $datatable .= $reports;
     } elsif ($position eq 'bottom') {
-        my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
-        my (@posstypes,%usertypeshash);
-        if (ref($types) eq 'ARRAY') {
-            @posstypes = @{$types};
-        }
-        if (@posstypes) {
-            if (ref($usertypes) eq 'HASH') {
-                %usertypeshash = %{$usertypes};
-            }
-            my @overridden;
-            my $numinrow = 4;
-            if (ref($settings) eq 'HASH') {
-                if (ref($settings->{'overrides'}) eq 'HASH') {
-                    foreach my $key (sort(keys(%{$settings->{'overrides'}}))) {
-                        if (ref($settings->{'overrides'}{$key}) eq 'HASH') {
-                            push(@overridden,$key);
-                            foreach my $item (@contacts) {
-                                if ($settings->{'overrides'}{$key}{$item}) {
-                                    $checked{'override_'.$key}{$item} = ' checked="checked" ';
-                                }
-                            }
-                            $otheremails{'override_'.$key} = $settings->{'overrides'}{$key}{'others'};
-                            $bccemails{'override_'.$key} = $settings->{'overrides'}{$key}{'bcc'};
-                            $includeloc{'override_'.$key} = '';
-                            $includestr{'override_'.$key} = '';
-                            if ($settings->{'overrides'}{$key}{'include'} ne '') {
-                                ($includeloc{'override_'.$key},$includestr{'override_'.$key}) =
-                                    split(/:/,$settings->{'overrides'}{$key}{'include'},2);
-                                $includestr{'override_'.$key} = &unescape($includestr{'override_'.$key});
-                            }
+        $css_class = $rownum%2?' class="LC_odd_row"':'';
+        $datatable .= '<tr'.$css_class.'>'.
+                      '<td>'.&mt('Extra helpdesk form fields:').'<br />'.
+                      &mt('(e-mail, subject, and description always shown)').
+                      '</td><td class="LC_left_item">';
+        if ((ref($fields) eq 'ARRAY') && (ref($fieldtitles) eq 'HASH') &&
+            (ref($fieldoptions) eq 'HASH') && (ref($possoptions) eq 'HASH')) {
+            $datatable .= '<table><tr><th>'.&mt('Field').'</th><th>'.&mt('Status').'</th></tr>';
+            foreach my $field (@{$fields}) {
+                $datatable .= '<tr><td>'.$fieldtitles->{$field};
+                if (($field eq 'screenshot') || ($field eq 'cc')) {
+                    $datatable .= ' '.&mt('(logged-in users)');
+                }
+                $datatable .='</td><td>';
+                my $clickaction;
+                if ($field eq 'screenshot') {
+                    $clickaction = ' onclick="screenshotSize(this);"';
+                }
+                if (ref($possoptions->{$field}) eq 'ARRAY') {
+                    foreach my $option (@{$possoptions->{$field}}) {
+                        my $checked;
+                        if ($currfield{$field} eq $option) {
+                            $checked = ' checked="checked"';
                         }
+                        $datatable .= '<span class="LC_nobreak"><label>'.
+                                      '<input type="radio" name="helpform_'.$field.'" '.
+                                      'value="'.$option.'"'.$checked.$clickaction.' />'.$fieldoptions->{$option}.
+                                      '</label></span>'.('&nbsp;'x2);
                     }
                 }
-            }
-            my $customclass = 'LC_helpdesk_override';
-            my $optionsprefix = 'LC_options_helpdesk_';
-
-            my $onclicktypes = "toggleHelpdeskRow(this.form,'overrides','$customclass','$optionsprefix');";
-
-            $datatable .= &insttypes_row($settings,$types,$usertypes,$dom,
-                                         $numinrow,$othertitle,'overrides',
-                                         \$rownum,$onclicktypes,$customclass);
-            $rownum ++;
-            $usertypeshash{'default'} = $othertitle;
-            foreach my $status (@posstypes) {
-                my $css_class;
-                if ($rownum%2) {
-                    $css_class = 'LC_odd_row ';
-                }
-                $css_class .= $customclass;
-                my $rowid = $optionsprefix.$status;
-                my $hidden = 1;
-                my $currstyle = 'display:none';
-                if (grep(/^\Q$status\E$/,@overridden)) {
-                    $currstyle = 'display:table-row';
-                    $hidden = 0;
-                }
-                my $key = 'override_'.$status;
-                $datatable .= &overridden_helpdesk($checked{$key},$otheremails{$key},$bccemails{$key},
-                                                  $includeloc{$key},$includestr{$key},$status,$rowid,
-                                                  $usertypeshash{$status},$css_class,$currstyle,
-                                                  \@contacts,$short_titles);
-                unless ($hidden) {
-                    $rownum ++;
+                if ($field eq 'screenshot') {
+                    my $display;
+                    if ($currfield{$field} eq 'no') {
+                        $display = ' style="display:none"';
+                    }
+                    $datatable .= '</td></tr><tr id="help_screenshotsize"'.$display.' />'.
+                                  '<td>'.&mt('Maximum size for upload (MB)').'</td><td>'.
+                                  '<input type="text" size="5" name="helpform_maxsize" value="'.$maxsize.'" />';
                 }
+                $datatable .= '</td></tr>';
             }
+            $datatable .= '</table>';
         }
+        $datatable .= '</td></tr>'."\n";
+        $rownum ++;
     }
     $$rowtotal += $rownum;
     return $datatable;
 }
 
-sub overridden_helpdesk {
-    my ($checked,$otheremails,$bccemails,$includeloc,$includestr,$type,$rowid,
-        $typetitle,$css_class,$rowstyle,$contacts,$short_titles) = @_;
-    my $class = 'LC_left_item';
-    if ($css_class) {
-        $css_class = ' class="'.$css_class.'"';
-    }
-    if ($rowid) {
-        $rowid = ' id="'.$rowid.'"';
-    }
-    if ($rowstyle) {
-        $rowstyle = ' style="'.$rowstyle.'"';
-    }
-    my ($output,$description);
-    $description = &mt('Helpdesk requests from: [_1] in this domain (overrides default)',"<b>$typetitle</b>");
-    $output = '<tr'.$css_class.$rowid.$rowstyle.'>'.
-              "<td>$description</td>\n".
-              '<td class="'.$class.'" colspan="2">'.
-              '<fieldset><legend>'.&mt('E-mail recipient(s)').'</legend>'.
-              '<span class="LC_nobreak">';
-    if (ref($contacts) eq 'ARRAY') {
-        foreach my $item (@{$contacts}) {
-            my $check;
-            if (ref($checked) eq 'HASH') {
-               $check = $checked->{$item};
-            }
-            my $title;
-            if (ref($short_titles) eq 'HASH') {
-                $title = $short_titles->{$item};
-            }
-            $output .= '<label>'.
-                       '<input type="checkbox" name="override_'.$type.'"'.$check.
-                       ' value="'.$item.'" />'.$title.'</label>&nbsp;';
-        }
-    }
-    $output .= '</span><br />'.&mt('Others').':&nbsp;&nbsp;'.
-               '<input type="text" name="override_'.$type.'_others" '.
-               'value="'.$otheremails.'"  />';
-    my %locchecked;
-    foreach my $loc ('s','b') {
-        if ($includeloc eq $loc) {
-            $locchecked{$loc} = ' checked="checked"';
-            last;
-        }
-    }
-    $output .= '<br />'.&mt('Bcc:').('&nbsp;'x6).
-               '<input type="text" name="override_'.$type.'_bcc" '.
-               'value="'.$bccemails.'"  /></fieldset>'.
-               '<fieldset><legend>'.&mt('Optional added text').'</legend>'.
-               &mt('Text automatically added to e-mail:').' '.
-               '<input type="text" name="override_'.$type.'_includestr" value="'.$includestr.'" /><br >'.
-               '<span class="LC_nobreak">'.&mt('Location:').'&nbsp;'.
-               '<label><input type="radio" name="override_'.$type.'_includeloc" value="s"'.$locchecked{'s'}.' />'.&mt('in subject').'</label>'.
-               ('&nbsp;'x2).
-               '<label><input type="radio" name="override_'.$type.'_includeloc" value="b"'.$locchecked{'b'}.' />'.&mt('in body').'</label>'.
-               '</span></fieldset>'.
-               '</td></tr>'."\n";
-    return $output;
-}
-
 sub contacts_javascript {
     return <<"ENDSCRIPT";
 
@@ -3259,37 +3235,6 @@ function screenshotSize(field) {
     return;
 }
 
-function toggleHelpdeskRow(form,checkbox,target,prefix,docount) {
-    if (form.elements[checkbox].length != undefined) {
-        var count = 0;
-        if (docount) {
-            for (var i=0; i<form.elements[checkbox].length; i++) {
-                if (form.elements[checkbox][i].checked) {
-                    count ++;
-                }
-            }
-        }
-        for (var i=0; i<form.elements[checkbox].length; i++) {
-            var type = form.elements[checkbox][i].value;
-            if (document.getElementById(prefix+type)) {
-                if (form.elements[checkbox][i].checked) {
-                    document.getElementById(prefix+type).style.display = 'table-row';
-                    if (count % 2 == 1) {
-                        document.getElementById(prefix+type).className = target+' LC_odd_row';
-                    } else {
-                        document.getElementById(prefix+type).className = target;
-                    }
-                    count ++;
-                } else {
-                    document.getElementById(prefix+type).style.display = 'none';
-                }
-            }
-        }
-    }
-    return;
-}
-
-
 // ]]>
 </script>
 
@@ -3316,10 +3261,8 @@ sub print_helpsettings {
         my $css_class;
         my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_');
         my (%customroles,%ordered,%current);
-        if (ref($settings) eq 'HASH') {
-            if (ref($settings->{'adhoc'}) eq 'HASH') {
-                %current = %{$settings->{'adhoc'}};
-            }
+        if (ref($settings->{'adhoc'}) eq 'HASH') {
+            %current = %{$settings->{'adhoc'}};
         }
         my $count = 0;
         foreach my $key (sort(keys(%existing))) {
@@ -3904,7 +3847,7 @@ sub print_ltitools {
                 if (!$rolemaps{$role}) {
                     $selectnone = ' selected="selected"';
                 }
-                $datatable .= '<td align="center">'.
+                $datatable .= '<td align="center">'. 
                               &Apache::lonnet::plaintext($role,'Course').'<br />'.
                               '<select name="ltitools_roles_'.$role.'_'.$i.'">'.
                               '<option value=""'.$selectnone.'>'.&mt('Select').'</option>';
@@ -4076,7 +4019,7 @@ sub ltitools_names {
                                           'url'            => 'URL',
                                           'key'            => 'Key',
                                           'secret'         => 'Secret',
-                                          'icon'           => 'Icon',
+                                          'icon'           => 'Icon',   
                                           'user'           => 'Username:domain',
                                           'fullname'       => 'Full Name',
                                           'firstname'      => 'First Name',
@@ -4094,11 +4037,10 @@ sub ltitools_names {
                                           'roster'         => 'Tool can retrieve roster:',
                                           'crstarget'      => 'Display target',
                                           'crslabel'       => 'Course label',
-                                          'crstitle'       => 'Course title',
+                                          'crstitle'       => 'Course title', 
                                           'crslinktext'    => 'Link Text',
                                           'crsexplanation' => 'Explanation',
                                         );
-
     return %lt;
 }
 
@@ -4107,6 +4049,7 @@ sub print_coursedefaults {
     my ($css_class,$datatable,%checkedon,%checkedoff,%defaultchecked,@toggles);
     my $itemcount = 1;
     my %choices =  &Apache::lonlocal::texthash (
+        canuse_pdfforms      => 'Course/Community users can create/upload PDF forms',
         uploadquota          => 'Default quota for files uploaded directly to course/community using Course Editor (MB)',
         anonsurvey_threshold => 'Responder count needed before showing submissions for anonymous surveys',
         coursecredits        => 'Credits can be specified for courses',
@@ -4124,11 +4067,12 @@ sub print_coursedefaults {
                          );
     if ($position eq 'top') {
         %defaultchecked = (
+                            'canuse_pdfforms' => 'off',
                             'uselcmath'       => 'on',
                             'usejsme'         => 'on',
                             'canclone'        => 'none',
                           );
-        @toggles = ('uselcmath','usejsme');
+        @toggles = ('canuse_pdfforms','uselcmath','usejsme');
         ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,
                                                      \%choices,$itemcount);
         $css_class = $itemcount%2?' class="LC_odd_row"':'';
@@ -4207,7 +4151,7 @@ sub print_coursedefaults {
         my ($currdefresponder,%defcredits,%curruploadquota,%deftimeout,%currmysql);
         my $currusecredits = 0;
         my $postsubmitclient = 1;
-        my @types = ('official','unofficial','community','textbook');
+        my @types = ('official','unofficial','community','textbook','placement');
         if (ref($settings) eq 'HASH') {
             $currdefresponder = $settings->{'anonsurvey_threshold'};
             if (ref($settings->{'uploadquota'}) eq 'HASH') {
@@ -4364,7 +4308,7 @@ sub print_selfenrollment {
     my ($position,$dom,$settings,$rowtotal) = @_;
     my ($css_class,$datatable);
     my $itemcount = 1;
-    my @types = ('official','unofficial','community','textbook');
+    my @types = ('official','unofficial','community','textbook','placement');
     if (($position eq 'top') || ($position eq 'middle')) {
         my ($rowsref,$titlesref) = &Apache::lonuserutils::get_selfenroll_titles();
         my %descs = &Apache::lonuserutils::selfenroll_default_descs();
@@ -4587,15 +4531,14 @@ sub print_validation_rows {
 
 sub print_usersessions {
     my ($position,$dom,$settings,$rowtotal) = @_;
-    my ($css_class,$datatable,%checked,%choices);
-    my (%by_ip,%by_location,@intdoms);
-    &build_location_hashes(\@intdoms,\%by_ip,\%by_location);
+    my ($css_class,$datatable,$itemcount,%checked,%choices);
+    my (%by_ip,%by_location,@intdoms,@instdoms);
+    &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
 
     my @alldoms = &Apache::lonnet::all_domains();
     my %serverhomes = %Apache::lonnet::serverhomeIDs;
     my %servers = &Apache::lonnet::internet_dom_servers($dom);
     my %altids = &id_for_thisdom(%servers);
-    my $itemcount = 1;
     if ($position eq 'top') {
         if (keys(%serverhomes) > 1) {
             my %spareid = &current_offloads_to($dom,$settings,\%servers);
@@ -4608,118 +4551,256 @@ sub print_usersessions {
             $datatable .= &spares_row($dom,\%servers,\%spareid,\%serverhomes,\%altids,$curroffloadnow,$rowtotal);
         } else {
             $datatable .= '<tr'.$css_class.'><td colspan="2">'.
-                          &mt('Nothing to set here, as the cluster to which this domain belongs only contains one server.');
+                          &mt('Nothing to set here, as the cluster to which this domain belongs only contains one server.').
+                          '</td></tr>';
         }
     } else {
-        if (keys(%by_location) == 0) {
-            $datatable .= '<tr'.$css_class.'><td colspan="2">'.
-                          &mt('Nothing to set here, as the cluster to which this domain belongs only contains one institution.');
+        my %titles = &usersession_titles();
+        my ($prefix,@types);
+        if ($position eq 'bottom') {
+            $prefix = 'remote';
+            @types = ('version','excludedomain','includedomain');
         } else {
-            my %lt = &usersession_titles();
-            my $numinrow = 5;
-            my $prefix;
-            my @types;
-            if ($position eq 'bottom') {
-                $prefix = 'remote';
-                @types = ('version','excludedomain','includedomain');
-            } else {
-                $prefix = 'hosted';
-                @types = ('excludedomain','includedomain');
-            }
-            my (%current,%checkedon,%checkedoff);
-            my @lcversions = &Apache::lonnet::all_loncaparevs();
-            my @locations = sort(keys(%by_location));
-            foreach my $type (@types) {
-                $checkedon{$type} = '';
-                $checkedoff{$type} = ' checked="checked"';
-            }
-            if (ref($settings) eq 'HASH') {
-                if (ref($settings->{$prefix}) eq 'HASH') {
-                    foreach my $key (keys(%{$settings->{$prefix}})) {
-                        $current{$key} = $settings->{$prefix}{$key};
-                        if ($key eq 'version') {
-                            if ($current{$key} ne '') {
-                                $checkedon{$key} = ' checked="checked"';
-                                $checkedoff{$key} = '';
-                            }
-                        } elsif (ref($current{$key}) eq 'ARRAY') {
+            $prefix = 'hosted';
+            @types = ('excludedomain','includedomain');
+        }
+        ($datatable,$itemcount) = &rules_by_location($settings,$prefix,\%by_location,\%by_ip,\@types,\%titles);
+    }
+    $$rowtotal += $itemcount;
+    return $datatable;
+}
+
+sub rules_by_location {
+    my ($settings,$prefix,$by_location,$by_ip,$types,$titles) = @_; 
+    my ($datatable,$itemcount,$css_class);
+    if (keys(%{$by_location}) == 0) {
+        $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
+        $datatable = '<tr'.$css_class.'><td colspan="2">'.
+                     &mt('Nothing to set here, as the cluster to which this domain belongs only contains one institution.').
+                     '</td></tr>';
+        $itemcount = 1;
+    } else {
+        $itemcount = 0;
+        my $numinrow = 5;
+        my (%current,%checkedon,%checkedoff);
+        my @locations = sort(keys(%{$by_location}));
+        foreach my $type (@{$types}) {
+            $checkedon{$type} = '';
+            $checkedoff{$type} = ' checked="checked"';
+        }
+        if (ref($settings) eq 'HASH') {
+            if (ref($settings->{$prefix}) eq 'HASH') {
+                foreach my $key (keys(%{$settings->{$prefix}})) {
+                    $current{$key} = $settings->{$prefix}{$key};
+                    if ($key eq 'version') {
+                        if ($current{$key} ne '') {
                             $checkedon{$key} = ' checked="checked"';
                             $checkedoff{$key} = '';
                         }
+                    } elsif (ref($current{$key}) eq 'ARRAY') {
+                        $checkedon{$key} = ' checked="checked"';
+                        $checkedoff{$key} = '';
                     }
                 }
             }
-            foreach my $type (@types) {
-                next if ($type ne 'version' && !@locations);
-                $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
-                $datatable .= '<tr'.$css_class.'>
-                               <td><span class="LC_nobreak">'.$lt{$type}.'</span><br />
-                               <span class="LC_nobreak">&nbsp;
-                               <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedoff{$type}.' value="0" />'.&mt('Not in use').'</label>&nbsp;
-                               <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedon{$type}.' value="1" />'.&mt('In use').'</label></span></td><td>';
-                if ($type eq 'version') {
-                    my $selector = '<select name="'.$prefix.'_version">';
-                    foreach my $version (@lcversions) {
-                        my $selected = '';
-                        if ($current{'version'} eq $version) {
-                            $selected = ' selected="selected"';
-                        }
-                        $selector .= ' <option value="'.$version.'"'.
-                                     $selected.'>'.$version.'</option>';
+        }
+        foreach my $type (@{$types}) {
+            next if ($type ne 'version' && !@locations);
+            $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
+            $datatable .= '<tr'.$css_class.'>
+                           <td><span class="LC_nobreak">'.$titles->{$type}.'</span><br />
+                           <span class="LC_nobreak">&nbsp;
+                           <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedoff{$type}.' value="0" />'.&mt('Not in use').'</label>&nbsp;
+                           <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedon{$type}.' value="1" />'.&mt('In use').'</label></span></td><td>';
+            if ($type eq 'version') {
+                my @lcversions = &Apache::lonnet::all_loncaparevs();
+                my $selector = '<select name="'.$prefix.'_version">';
+                foreach my $version (@lcversions) {
+                    my $selected = '';
+                    if ($current{'version'} eq $version) {
+                        $selected = ' selected="selected"';
                     }
-                    $selector .= '</select> ';
-                    $datatable .= &mt('remote server must be version: [_1] or later',$selector);
-                } else {
-                    $datatable.= '<div><input type="button" value="'.&mt('check all').'" '.
-                                 'onclick="javascript:checkAll(document.display.'.$prefix.'_'.$type.')"'.
-                                 ' />'.('&nbsp;'x2).
-                                 '<input type="button" value="'.&mt('uncheck all').'" '.
-                                 'onclick="javascript:uncheckAll(document.display.'.$prefix.'_'.$type.')" />'.
-                                 "\n".
-                                 '</div><div><table>';
-                    my $rem;
-                    for (my $i=0; $i<@locations; $i++) {
-                        my ($showloc,$value,$checkedtype);
-                        if (ref($by_location{$locations[$i]}) eq 'ARRAY') {
-                            my $ip = $by_location{$locations[$i]}->[0];
-                            if (ref($by_ip{$ip}) eq 'ARRAY') {
-                                 $value = join(':',@{$by_ip{$ip}});
-                                $showloc = join(', ',@{$by_ip{$ip}});
-                                if (ref($current{$type}) eq 'ARRAY') {
-                                    foreach my $loc (@{$by_ip{$ip}}) {  
-                                        if (grep(/^\Q$loc\E$/,@{$current{$type}})) {
-                                            $checkedtype = ' checked="checked"';
-                                            last;
-                                        }
+                    $selector .= ' <option value="'.$version.'"'.
+                                 $selected.'>'.$version.'</option>';
+                }
+                $selector .= '</select> ';
+                $datatable .= &mt('remote server must be version: [_1] or later',$selector);
+            } else {
+                $datatable.= '<div><input type="button" value="'.&mt('check all').'" '.
+                             'onclick="javascript:checkAll(document.display.'.$prefix.'_'.$type.')"'.
+                             ' />'.('&nbsp;'x2).
+                             '<input type="button" value="'.&mt('uncheck all').'" '.
+                             'onclick="javascript:uncheckAll(document.display.'.$prefix.'_'.$type.')" />'.
+                             "\n".
+                             '</div><div><table>';
+                my $rem;
+                for (my $i=0; $i<@locations; $i++) {
+                    my ($showloc,$value,$checkedtype);
+                    if (ref($by_location->{$locations[$i]}) eq 'ARRAY') {
+                        my $ip = $by_location->{$locations[$i]}->[0];
+                        if (ref($by_ip->{$ip}) eq 'ARRAY') {
+                            $value = join(':',@{$by_ip->{$ip}});
+                            $showloc = join(', ',@{$by_ip->{$ip}});
+                            if (ref($current{$type}) eq 'ARRAY') {
+                                foreach my $loc (@{$by_ip->{$ip}}) {
+                                    if (grep(/^\Q$loc\E$/,@{$current{$type}})) {
+                                        $checkedtype = ' checked="checked"';
+                                        last;
                                     }
                                 }
                             }
                         }
-                        $rem = $i%($numinrow);
-                        if ($rem == 0) {
-                            if ($i > 0) {
-                                $datatable .= '</tr>';
-                            }
-                            $datatable .= '<tr>';
-                        }
-                        $datatable .= '<td class="LC_left_item">'.
-                                      '<span class="LC_nobreak"><label>'.
-                                      '<input type="checkbox" name="'.$prefix.'_'.$type.
-                                      '" value="'.$value.'"'.$checkedtype.' />'.$showloc.
-                                      '</label></span></td>';
                     }
-                    $rem = @locations%($numinrow);
-                    my $colsleft = $numinrow - $rem;
-                    if ($colsleft > 1 ) {
-                        $datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
-                                      '&nbsp;</td>';
-                    } elsif ($colsleft == 1) {
-                        $datatable .= '<td class="LC_left_item">&nbsp;</td>';
+                    $rem = $i%($numinrow);
+                    if ($rem == 0) {
+                        if ($i > 0) {
+                            $datatable .= '</tr>';
+                        }
+                        $datatable .= '<tr>';
+                    }
+                    $datatable .= '<td class="LC_left_item">'.
+                                  '<span class="LC_nobreak"><label>'.
+                                  '<input type="checkbox" name="'.$prefix.'_'.$type.
+                                  '" value="'.$value.'"'.$checkedtype.' />'.$showloc.
+                                  '</label></span></td>';
+                }
+                $rem = @locations%($numinrow);
+                my $colsleft = $numinrow - $rem;
+                if ($colsleft > 1 ) {
+                    $datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
+                                  '&nbsp;</td>';
+                } elsif ($colsleft == 1) {
+                    $datatable .= '<td class="LC_left_item">&nbsp;</td>';
+                }
+                $datatable .= '</tr></table>';
+            }
+            $datatable .= '</td></tr>';
+            $itemcount ++;
+        }
+    }
+    return ($datatable,$itemcount);
+}
+
+sub print_ssl {
+    my ($position,$dom,$settings,$rowtotal) = @_;
+    my ($css_class,$datatable);
+    my $itemcount = 1;
+    if ($position eq 'top') {
+        my $primary_id = &Apache::lonnet::domain($dom,'primary');
+        my $intdom = &Apache::lonnet::internet_dom($primary_id);
+        my $same_institution;
+        if ($intdom ne '') {
+            my $internet_names = &Apache::lonnet::get_internet_names($Apache::lonnet::perlvar{'lonHostID'});
+            if (ref($internet_names) eq 'ARRAY') {
+                if (grep(/^\Q$intdom\E$/,@{$internet_names})) {
+                    $same_institution = 1;
+                }
+            }
+        }
+        $css_class = $itemcount%2?' class="LC_odd_row"':'';
+        $datatable = '<tr'.$css_class.'><td colspan="2">';
+        if ($same_institution) {
+            my %domservers = &Apache::lonnet::get_servers($dom);
+            $datatable .= &LONCAPA::SSL::print_certstatus(\%domservers,'web','domprefs');
+        } else {
+            $datatable .= &mt("You need to be logged into one of your own domain's servers to display information about the status of LON-CAPA SSL certificates.");
+        }
+        $datatable .= '</td></tr>';
+        $itemcount ++;
+    } else {
+        my %titles = &ssl_titles();
+        my (%by_ip,%by_location,@intdoms,@instdoms);
+        &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
+        my @alldoms = &Apache::lonnet::all_domains();
+        my %serverhomes = %Apache::lonnet::serverhomeIDs;
+        my @domservers = &Apache::lonnet::get_servers($dom);
+        my %servers = &Apache::lonnet::internet_dom_servers($dom);
+        my %altids = &id_for_thisdom(%servers);
+        if (($position eq 'connto') || ($position eq 'connfrom')) {
+            my $legacy;
+            unless (ref($settings) eq 'HASH') {
+                my $name;
+                if ($position eq 'connto') {
+                    $name = 'loncAllowInsecure';
+                } else {
+                    $name = 'londAllowInsecure';
+                }
+                my $primarylibserv = &Apache::lonnet::domain($dom,'primary');
+                my @ids=&Apache::lonnet::current_machine_ids();
+                if (($primarylibserv ne '') && (!grep(/^\Q$primarylibserv\E$/,@ids))) {
+                    my %what = (
+                                   $name => 1,
+                               );
+                    my ($result,$returnhash) =
+                        &Apache::lonnet::get_remote_globals($primarylibserv,\%what);
+                    if ($result eq 'ok') {
+                        if (ref($returnhash) eq 'HASH') {
+                            $legacy = $returnhash->{$name};
+                        }
+                    }
+                } else {
+                    $legacy = $Apache::lonnet::perlvar{$name};
+                }
+            }
+            foreach my $type ('dom','intdom','other') {
+                my %checked;
+                $css_class = $itemcount%2?' class="LC_odd_row"':'';
+                $datatable .= '<tr'.$css_class.'><td>'.$titles{$type}.'</td>'.
+                              '<td class="LC_right_item">';
+                my $skip; 
+                if ($type eq 'dom') {
+                    unless (keys(%servers) > 1) {
+                        $datatable .= &mt('Nothing to set here, as there are no other servers/VMs');    
+                        $skip = 1;
+                    }
+                }
+                if ($type eq 'intdom') {
+                    unless (@instdoms > 1) {
+                        $datatable .= &mt('Nothing to set here, as there are no other domains for this institution');
+                        $skip = 1;
+                    } 
+                } elsif ($type eq 'other') {
+                    if (keys(%by_location) == 0) {
+                        $datatable .= &mt('Nothing to set here, as there are no other institutions');
+                        $skip = 1;
+                    }
+                }
+                unless ($skip) {
+                    $checked{'yes'} = ' checked="checked"'; 
+                    if (ref($settings) eq 'HASH') {
+                        if (ref($settings->{$position}) eq 'HASH') {
+                            if ($settings->{$position}->{$type} =~ /^(no|req)$/) {
+                                $checked{$1} = $checked{'yes'};
+                                delete($checked{'yes'}); 
+                            }
+                        }
+                    } else {
+                        if ($legacy == 0) {
+                            $checked{'req'} = $checked{'yes'};
+                            delete($checked{'yes'});    
+                        }
+                    }
+                    foreach my $option ('no','yes','req') {
+                        $datatable .= '<span class="LC_nobreak"><label>'.
+                                      '<input type="radio" name="'.$position.'_'.$type.'" '.
+                                      'value="'.$option.'"'.$checked{$option}.' />'.$titles{$option}.
+                                      '</label></span>'.('&nbsp;'x2);
                     }
-                    $datatable .= '</tr></table>';
                 }
                 $datatable .= '</td></tr>';
+                $itemcount ++; 
+            }
+        } else {
+            my $prefix = 'replication';
+            my @types = ('certreq','nocertreq');
+            if (keys(%by_location) == 0) {
+                $datatable .= '<tr'.$css_class.'><td>'.
+                              &mt('Nothing to set here, as there are no other institutions').
+                              '</td></tr>';
                 $itemcount ++;
+            } else {
+                ($datatable,$itemcount) = 
+                    &rules_by_location($settings,$prefix,\%by_location,\%by_ip,\@types,\%titles);
             }
         }
     }
@@ -4727,10 +4808,60 @@ sub print_usersessions {
     return $datatable;
 }
 
+sub ssl_titles {
+    return &Apache::lonlocal::texthash (
+               dom           => 'LON-CAPA servers/VMs from same domain',
+               intdom        => 'LON-CAPA servers/VMs from same "internet" domain',
+               other         => 'External LON-CAPA servers/VMs',
+               connto        => 'Connections to other servers',
+               connfrom      => 'Connections from other servers',
+               replication   => 'Replicating content to other institutions',
+               certreq       => 'Client certificate required, but specific domains exempt',
+               nocertreq     => 'No client certificate required, except for specific domains',
+               no            => 'SSL not used',
+               yes           => 'SSL Optional (used if available)',
+               req           => 'SSL Required',
+    );
+}
+
+sub print_trust {
+    my ($prefix,$dom,$settings,$rowtotal) = @_;
+    my ($css_class,$datatable,%checked,%choices);
+    my (%by_ip,%by_location,@intdoms,@instdoms);
+    &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
+    my $itemcount = 1;
+    my %titles = &trust_titles();
+    my @types = ('exc','inc');
+    if ($prefix eq 'top') {
+        $prefix = 'content';
+    } elsif ($prefix eq 'bottom') {
+        $prefix = 'msg';
+    }
+    ($datatable,$itemcount) = &rules_by_location($settings,$prefix,\%by_location,\%by_ip,\@types,\%titles);
+    $$rowtotal += $itemcount;
+    return $datatable;
+}
+
+sub trust_titles {
+    return &Apache::lonlocal::texthash(
+               content  => "Access to this domain's content by others",
+               shared   => "Access to other domain's content by this domain",
+               enroll   => "Enrollment in this domain's courses by others", 
+               othcoau  => "Co-author roles in this domain for others",
+               coaurem  => "Co-author roles for this domain's users elsewhere", 
+               domroles => "Domain roles in this domain assignable to others",
+               catalog  => "Course Catalog for this domain displayed elsewhere",
+               reqcrs   => "Requests for creation of courses in this domain by others",
+               msg      => "Users in other domains can send messages to this domain",
+               exc      => "Allow all, but exclude specific domains",
+               inc      => "Deny all, but include specific domains",
+           );
+} 
+
 sub build_location_hashes {
-    my ($intdoms,$by_ip,$by_location) = @_;
+    my ($intdoms,$by_ip,$by_location,$instdoms) = @_;
     return unless((ref($intdoms) eq 'ARRAY') && (ref($by_ip) eq 'HASH') &&
-                  (ref($by_location) eq 'HASH')); 
+                  (ref($by_location) eq 'HASH') && (ref($instdoms) eq 'ARRAY'));
     my %iphost = &Apache::lonnet::get_iphost();
     my $primary_id = &Apache::lonnet::domain($env{'request.role.domain'},'primary');
     my $primary_ip = &Apache::lonnet::get_host_ip($primary_id);
@@ -4747,7 +4878,13 @@ sub build_location_hashes {
             foreach my $id (@{$iphost{$ip}}) {
                 my $location = &Apache::lonnet::internet_dom($id);
                 if ($location) {
-                    next if (grep(/^\Q$location\E$/,@{$intdoms}));
+                    if (grep(/^\Q$location\E$/,@{$intdoms})) {
+                        my $dom = &Apache::lonnet::host_domain($id);
+                        unless (grep(/^\Q$dom\E/,@{$instdoms})) {
+                            push(@{$instdoms},$dom);
+                        }
+                        next;
+                    }
                     if (ref($by_ip->{$ip}) eq 'ARRAY') {
                         unless(grep(/^\Q$location\E$/,@{$by_ip->{$ip}})) {
                             push(@{$by_ip->{$ip}},$location);
@@ -5251,14 +5388,9 @@ sub loadbalancing_titles {
            '_LC_ipchange'    => &mt('Non-SSO users with IP mismatch'),
                      );
     my @alltypes = ('_LC_adv','_LC_author','_LC_internetdom','_LC_external','_LC_ipchangesso','_LC_ipchange');
-    my @available;
     if (ref($types) eq 'ARRAY') {
-        @available = @{$types};
+        unshift(@alltypes,@{$types},'default');
     }
-    unless (grep(/^default$/,@available)) {
-        push(@available,'default');
-    }
-    unshift(@alltypes,@available);
     my %titles;
     foreach my $type (@alltypes) {
         if ($type =~ /^_LC_/) {
@@ -5385,8 +5517,8 @@ sub contact_titles {
                    'adminemail'      => 'Default Server Admin E-mail address',
                    'errormail'       => 'Error reports to be e-mailed to',
                    'packagesmail'    => 'Package update alerts to be e-mailed to',
-                   'helpdeskmail'    => "Helpdesk requests from all users in this domain",
-                   'otherdomsmail'   => 'Helpdesk requests from users in other (unconfigured) domains',
+                   'helpdeskmail'    => "Helpdesk requests for this domain's users",
+                   'otherdomsmail'   => 'Helpdesk requests for other (unconfigured) domains',
                    'lonstatusmail'   => 'E-mail from nightly status check (warnings/errors)',
                    'requestsmail'    => 'E-mail from course requests requiring approval',
                    'updatesmail'     => 'E-mail from nightly check of LON-CAPA module integrity/updates',
@@ -5437,6 +5569,7 @@ sub tool_titles {
                      unofficial => 'Unofficial courses',
                      community  => 'Communities',
                      textbook   => 'Textbook courses',
+                     placement  => 'Placement tests',
                  );
     return %titles;
 }
@@ -5447,6 +5580,7 @@ sub courserequest_titles {
                                    unofficial => 'Unofficial',
                                    community  => 'Communities',
                                    textbook   => 'Textbook',
+                                   placement  => 'Placement tests',
                                    norequest  => 'Not allowed',
                                    approval   => 'Approval by Dom. Coord.',
                                    validate   => 'With validation',
@@ -5634,7 +5768,6 @@ sub print_selfcreation {
     my %radiohash;
     my $numinrow = 4;
     map { $radiohash{'cancreate_'.$_} = 1; } @selfcreate;
-    my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
     if ($position eq 'top') {
         my %choices = &Apache::lonlocal::texthash (
                                                       cancreate_login      => 'Institutional Login',
@@ -5650,11 +5783,13 @@ sub print_selfcreation {
                                                      \%choices,$itemcount,$onclick);
         $$rowtotal += $itemcount;
         
+        my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
+
         if (ref($usertypes) eq 'HASH') {
             if (keys(%{$usertypes}) > 0) {
                 $datatable .= &insttypes_row($createsettings,$types,$usertypes,
                                              $dom,$numinrow,$othertitle,
-                                             'statustocreate',$rowtotal);
+                                             'statustocreate',$$rowtotal);
                 $$rowtotal ++;
             }
         }
@@ -5699,22 +5834,16 @@ sub print_selfcreation {
         $$rowtotal ++;
     } elsif ($position eq 'middle') {
         my %domconf = &Apache::lonnet::get_dom('configuration',['usermodification'],$dom);
-        my @posstypes;
+        my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
+        $usertypes->{'default'} = $othertitle;
         if (ref($types) eq 'ARRAY') {
-            @posstypes = @{$types};
-        }
-        unless (grep(/^default$/,@posstypes)) {
-            push(@posstypes,'default');
-        }
-        my %usertypeshash;
-        if (ref($usertypes) eq 'HASH') {
-            %usertypeshash = %{$usertypes};
-        }
-        $usertypeshash{'default'} = $othertitle;
-        foreach my $status (@posstypes) {
-            $datatable .= &modifiable_userdata_row('selfcreate',$status,$domconf{'usermodification'},
-                                                   $numinrow,$$rowtotal,\%usertypeshash);
-            $$rowtotal ++;
+            push(@{$types},'default');
+            $usertypes->{'default'} = $othertitle;
+            foreach my $status (@{$types}) {
+                $datatable .= &modifiable_userdata_row('selfcreate',$status,$domconf{'usermodification'},
+                                                       $numinrow,$$rowtotal,$usertypes);
+                $$rowtotal ++;
+            }
         }
     } else {
         my %choices = &Apache::lonlocal::texthash (
@@ -5732,30 +5861,29 @@ sub print_selfcreation {
         my $onclick = "toggleDisplay(this.form,'emailoptions');";
         my $additional = '<div id="emailoptions" style="display: '.$display.'">';
         my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
-        my (@ordered,%usertypeshash);
-        if (ref($domdefaults{'inststatusguest'}) eq 'ARRAY') {
-            @ordered = @{$domdefaults{'inststatusguest'}};
-        }
-        if (@ordered) {
-            unless (grep(/^default$/,@ordered)) {
-                push(@ordered,'default');
-            }
-            if (ref($usertypes) eq 'HASH') {
-                %usertypeshash = %{$usertypes};
-            }
-            $usertypeshash{'default'} = $othertitle;
-            $additional .= '<table><tr>';
-            foreach my $status (@ordered) {
-                $additional .= '<th>'.$usertypeshash{$status}.'</th>';
-            }
-            $additional .= '</tr><tr>';
-            foreach my $status (@ordered) {
-                $additional .= '<td>'.&email_as_username($rowtotal,$processing,$status).'</td>';
+        my $usertypes = {};
+        my $order = [];
+        if ((ref($domdefaults{'inststatustypes'}) eq 'HASH') && (ref($domdefaults{'inststatusguest'}) eq 'ARRAY')) {
+            $usertypes = $domdefaults{'inststatustypes'};
+            $order = $domdefaults{'inststatusguest'};
+        }
+        if (ref($order) eq 'ARRAY') {
+            push(@{$order},'default');
+            if (@{$order} > 1) {
+                $usertypes->{'default'} = &mt('Other users');
+                $additional .= '<table><tr>';
+                foreach my $status (@{$order}) {
+                    $additional .= '<th>'.$usertypes->{$status}.'</th>';
+                }
+                $additional .= '</tr><tr>';
+                foreach my $status (@{$order}) {
+                    $additional .= '<td>'.&email_as_username($rowtotal,$processing,$status).'</td>';
+                }
+                $additional .= '</tr></table>';
+            } else {
+                $usertypes->{'default'} = &mt('All users');
+                $additional .= &email_as_username($rowtotal,$processing);
             }
-            $additional .= '</tr></table>';
-        } else {
-            $usertypeshash{'default'} = $othertitle;
-            $additional .= &email_as_username($rowtotal,$processing);
         }
         $additional .= '</div>'."\n";
 
@@ -5766,10 +5894,12 @@ sub print_selfcreation {
         $$rowtotal ++;
         my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info();
         $numinrow = 1;
-        foreach my $status (@ordered) {
-            $datatable .= &modifiable_userdata_row('cancreate','emailusername_'.$status,$settings,
-                                                   $numinrow,$$rowtotal,\%usertypeshash,$infofields,$infotitles);
-            $$rowtotal ++;
+        if (ref($order) eq 'ARRAY') {
+            foreach my $status (@{$order}) {
+                $datatable .= &modifiable_userdata_row('cancreate','emailusername_'.$status,$settings,
+                                                       $numinrow,$$rowtotal,$usertypes,$infofields,$infotitles);
+                $$rowtotal ++;
+            }
         }
         my ($emailrules,$emailruleorder) =
             &Apache::lonnet::inst_userrules($dom,'email');
@@ -5841,7 +5971,7 @@ sub email_as_username {
 sub captcha_choice {
     my ($context,$settings,$itemcount) = @_;
     my ($keyentry,$currpub,$currpriv,%checked,$rowname,$pubtext,$privtext,
-        $vertext,$currver); 
+        $vertext,$currver);
     my %lt = &captcha_phrases();
     $keyentry = 'hidden';
     if ($context eq 'cancreate') {
@@ -6173,7 +6303,7 @@ sub print_defaults {
                 $datatable .= '</table>';
             } else {
                 $datatable .= '<input type="text" name="'.$item.'" value="'.
-                              $defaults{$item}.'" size="3" onblur="javascript:warnIntAuth(this);" />';
+                              $defaults{$item}.'" size="3" onblur="javascript:warnIntAuth(this);" />'; 
             }
             $datatable .= '</td></tr>';
             $rownum ++;
@@ -6519,6 +6649,10 @@ sub print_coursecategories {
         my $toggle_catscomm_dom = ' checked="checked" ';
         my $can_catcomm_comm = ' ';
         my $can_catcomm_dom = ' checked="checked" ';
+        my $toggle_catsplace_place = ' ';
+        my $toggle_catsplace_dom = ' checked="checked" ';
+        my $can_catplace_place = ' ';
+        my $can_catplace_dom = ' checked="checked" ';
 
         if (ref($settings) eq 'HASH') {
             if ($settings->{'togglecats'} eq 'crs') {
@@ -6537,17 +6671,28 @@ sub print_coursecategories {
                 $can_catcomm_comm = $can_catcomm_dom;
                 $can_catcomm_dom = ' ';
             }
+            if ($settings->{'togglecatsplace'} eq 'place') {
+                $toggle_catsplace_place = $toggle_catsplace_dom;
+                $toggle_catsplace_dom = ' ';
+            }
+            if ($settings->{'categorizeplace'} eq 'place') {
+                $can_catplace_place = $can_catplace_dom;
+                $can_catplace_dom = ' ';
+            }
         }
         my %title = &Apache::lonlocal::texthash (
-                     togglecats     => 'Show/Hide a course in catalog',
-                     togglecatscomm => 'Show/Hide a community in catalog',
-                     categorize     => 'Assign a category to a course',
-                     categorizecomm => 'Assign a category to a community',
+                     togglecats      => 'Show/Hide a course in catalog',
+                     togglecatscomm  => 'Show/Hide a community in catalog',
+                     togglecatsplace => 'Show/Hide a placement test in catalog',
+                     categorize      => 'Assign a category to a course',
+                     categorizecomm  => 'Assign a category to a community',
+                     categorizeplace => 'Assign a category to a placement test',
                     );
         my %level = &Apache::lonlocal::texthash (
-                     dom  => 'Set in Domain',
-                     crs  => 'Set in Course',
-                     comm => 'Set in Community',
+                     dom   => 'Set in Domain',
+                     crs   => 'Set in Course',
+                     comm  => 'Set in Community',
+                     place => 'Set in Placement Test',
                     );
         $datatable = '<tr class="LC_odd_row">'.
                   '<td>'.$title{'togglecats'}.'</td>'.
@@ -6577,8 +6722,22 @@ sub print_coursecategories {
                   $can_catcomm_dom.' value="dom" />'.$level{'dom'}.'</label>&nbsp;'.
                   '<label><input type="radio" name="categorizecomm"'.
                   $can_catcomm_comm.'value="comm" />'.$level{'comm'}.'</label></span></td>'.
+                  '</tr><tr>'.
+                  '<td>'.$title{'togglecatsplace'}.'</td>'.
+                  '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
+                  '<input type="radio" name="togglecatsplace"'.
+                  $toggle_catsplace_dom.' value="dom" />'.$level{'dom'}.'</label>&nbsp;'.
+                  '<label><input type="radio" name="togglecatscomm"'.
+                  $toggle_catsplace_place.' value="comm" />'.$level{'place'}.'</label></span></td>'.
+                  '</tr><tr>'.
+                  '<td>'.$title{'categorizeplace'}.'</td>'.
+                  '<td class="LC_right_item"><span class="LC_nobreak">'.
+                  '<label><input type="radio" name="categorizeplace"'.
+                  $can_catplace_dom.' value="dom" />'.$level{'dom'}.'</label>&nbsp;'.
+                  '<label><input type="radio" name="categorizeplace"'.
+                  $can_catplace_place.'value="place" />'.$level{'place'}.'</label></span></td>'.
                   '</tr>';
-        $$rowtotal += 4;
+        $$rowtotal += 6;
     } else {
         my $css_class;
         my $itemcount = 1;
@@ -6603,12 +6762,15 @@ sub print_coursecategories {
                     my %default_names = (
                           instcode    => &mt('Official courses'),
                           communities => &mt('Communities'),
+                          placement   => &mt('Placement Tests'),
                     );
 
                     if ((!grep(/^instcode$/,@{$cats[0]})) || 
                         ($cathash->{'instcode::0'} eq '') ||
                         (!grep(/^communities$/,@{$cats[0]})) || 
-                        ($cathash->{'communities::0'} eq '')) {
+                        ($cathash->{'communities::0'} eq '') ||
+                        (!grep(/^placement$/,@{$cats[0]})) ||
+                        ($cathash->{'placement::0'} eq '')) {
                         $maxnum ++;
                     }
                     my $lastidx;
@@ -6629,7 +6791,7 @@ sub print_coursecategories {
                             $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
                         }
                         $datatable .= '</select></span></td><td>';
-                        if ($parent eq 'instcode' || $parent eq 'communities') {
+                        if ($parent eq 'instcode' || $parent eq 'communities' || $parent eq 'placement') {
                             $datatable .=  '<span class="LC_nobreak">'
                                            .$default_names{$parent}.'</span>';
                             if ($parent eq 'instcode') {
@@ -6652,7 +6814,7 @@ sub print_coursecategories {
                             $datatable .= '<label><input type="radio" name="'
                                           .$parent.'" value="0" />'
                                           .&mt('Do not display').'</label></span>';
-                            if ($parent eq 'communities') {
+                            if (($parent eq 'communities') || ($parent eq 'placement')) {
                                 $datatable .= '</td></tr></table>';
                             }
                             $datatable .= '</td>';
@@ -6684,7 +6846,7 @@ sub print_coursecategories {
                                   .'<input type="text" size="20" name="addcategory_name" value="" /></td>'
                                   .'</tr>'."\n";
                     $itemcount ++;
-                    foreach my $default ('instcode','communities') {
+                    foreach my $default ('instcode','communities','placement') {
                         if ((!grep(/^\Q$default\E$/,@{$cats[0]})) || ($cathash->{$default.'::0'} eq '')) {
                             $css_class = $itemcount%2?' class="LC_odd_row"':'';
                             my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','$default"."_pos','$lastidx'".');"';
@@ -6773,9 +6935,9 @@ sub print_serverstatuses {
 
 sub serverstatus_pages {
     return ('userstatus','lonstatus','loncron','server-status','codeversions',
-            'checksums','clusterstatus','metadata_keywords','metadata_harvest',
-            'takeoffline','takeonline','showenv','toggledebug','ping','domconf',
-            'uniquecodes','diskusage','coursecatalog');
+            'checksums','clusterstatus','certstatus','metadata_keywords',
+            'metadata_harvest','takeoffline','takeonline','showenv','toggledebug',
+            'ping','domconf','uniquecodes','diskusage','coursecatalog');
 }
 
 sub defaults_javascript {
@@ -6897,9 +7059,11 @@ sub coursecategories_javascript {
     }
     my $instcode_reserved = &mt('The name: [_1] is a reserved category.','"instcode"');
     my $communities_reserved = &mt('The name: [_1] is a reserved category.','"communities"');
+    my $placement_reserved = &mt('The name: [_1] is a reserved category.','"placement"');
     my $choose_again = "\n".&mt('Please use a different name for the new top level category.'); 
     &js_escape(\$instcode_reserved);
     &js_escape(\$communities_reserved);
+    &js_escape(\$placement_reserved);
     &js_escape(\$choose_again);
     $output = <<"ENDSCRIPT";
 <script type="text/javascript">
@@ -6969,6 +7133,10 @@ function categoryCheck(form) {
         alert('$communities_reserved\\n$choose_again');
         return false;
     }
+    if (form.elements['addcategory_name'].value == 'placement') {
+        alert('$placement_reserved\\n$choose_again');
+        return false;
+    }
     return true;
 }
 
@@ -6985,13 +7153,14 @@ sub initialize_categories {
     my %default_names = (
                       instcode    => 'Official courses (with institutional codes)',
                       communities => 'Communities',
+                      placement   => 'Placement Tests',
                         );
     my $select0 = ' selected="selected"';
     my $select1 = '';
-    foreach my $default ('instcode','communities') {
+    foreach my $default ('instcode','communities','placement') {
         $css_class = $itemcount%2?' class="LC_odd_row"':'';
         $chgstr = ' onchange="javascript:reorderCats(this.form,'."'',$default"."_pos','0'".');"';
-        if ($default eq 'communities') {
+        if (($default eq 'communities') || ($default eq 'placement')) {
             $select1 = $select0;
             $select0 = '';
         }
@@ -7237,13 +7406,11 @@ sub modifiable_userdata_row {
 }
 
 sub insttypes_row {
-    my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context,$rowtotal,$onclick,
-        $customcss,$rowstyle) = @_;
+    my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context,$rownum) = @_;
     my %lt = &Apache::lonlocal::texthash (
                       cansearch => 'Users allowed to search',
                       statustocreate => 'Institutional affiliation(s) able to create own account (login/SSO)',
                       lockablenames => 'User preference to lock name',
-                      overrides     => "Override domain's helpdesk settings based on requester's affiliation",
              );
     my $showdom;
     if ($context eq 'cansearch') {
@@ -7253,22 +7420,9 @@ sub insttypes_row {
     if ($context eq 'statustocreate') {
         $class = 'LC_right_item';
     }
-    my $css_class;
-    if ($$rowtotal%2) {
-        $css_class = 'LC_odd_row';
-    }
-    if ($customcss) {
-        $css_class .= ' '.$customcss;
-    }
-    $css_class =~ s/^\s+//;
-    if ($css_class) {
-        $css_class = ' class="'.$css_class.'"';
-    }
-    if ($rowstyle) {
-        $css_class .= ' style="'.$rowstyle.'"';
-    }
-    if ($onclick) {
-        $onclick = 'onclick="'.$onclick.'" ';
+    my $css_class = ' class="LC_odd_row"';
+    if ($rownum ne '') { 
+        $css_class = ($rownum%2? ' class="LC_odd_row"':'');
     }
     my $output = '<tr'.$css_class.'>'.
                  '<td>'.$lt{$context}.$showdom.
@@ -7290,10 +7444,6 @@ sub insttypes_row {
                         if (grep(/^\Q$types->[$i]\E$/,@{$settings->{$context}})) {
                             $check = ' checked="checked" ';
                         }
-                    } elsif (ref($settings->{$context}) eq 'HASH') {
-                        if (ref($settings->{$context}->{$types->[$i]}) eq 'HASH') {
-                            $check = ' checked="checked" ';
-                        }
                     } elsif ($context eq 'statustocreate') {
                         $check = ' checked="checked" ';
                     }
@@ -7308,38 +7458,29 @@ sub insttypes_row {
         $rem = @{$types}%($numinrow);
     }
     my $colsleft = $numinrow - $rem;
-    if ($context eq 'overrides') {
-        if ($colsleft > 1) {
-            $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">';
-        } else {
-            $output .= '<td class="LC_left_item">';
-        }
-        $output .= '&nbsp;';
+    if (($rem == 0) && (@{$types} > 0)) {
+        $output .= '<tr>';
+    }
+    if ($colsleft > 1) {
+        $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">';
     } else {
-        if (($rem == 0) && (@{$types} > 0)) {
-            $output .= '<tr>';
-        }
-        if ($colsleft > 1) {
-            $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">';
-        } else {
-            $output .= '<td class="LC_left_item">';
-        }
-        my $defcheck = ' ';
-        if (ref($settings) eq 'HASH') {  
-            if (ref($settings->{$context}) eq 'ARRAY') {
-                if (grep(/^default$/,@{$settings->{$context}})) {
-                    $defcheck = ' checked="checked" ';
-                }
-            } elsif ($context eq 'statustocreate') {
+        $output .= '<td class="LC_left_item">';
+    }
+    my $defcheck = ' ';
+    if (ref($settings) eq 'HASH') {  
+        if (ref($settings->{$context}) eq 'ARRAY') {
+            if (grep(/^default$/,@{$settings->{$context}})) {
                 $defcheck = ' checked="checked" ';
             }
+        } elsif ($context eq 'statustocreate') {
+            $defcheck = ' checked="checked" ';
         }
-        $output .= '<span class="LC_nobreak"><label>'.
-                   '<input type="checkbox" name="'.$context.'" '.
-                   'value="default"'.$defcheck.'/>'.
-                   $othertitle.'</label></span>';
     }
-    $output .= '</td></tr></table></td></tr>';
+    $output .= '<span class="LC_nobreak"><label>'.
+               '<input type="checkbox" name="'.$context.'" '.
+               'value="default"'.$defcheck.'/>'.
+               $othertitle.'</label></span></td>'.
+               '</tr></table></td></tr>';
     return $output;
 }
 
@@ -8328,7 +8469,7 @@ sub check_authorstatus {
 
 sub publishlogo {
     my ($r,$action,$formname,$dom,$confname,$subdir,$thumbwidth,$thumbheight,$savefileas) = @_;
-    my ($output,$fname,$logourl);
+    my ($output,$fname,$logourl,$madethumb);
     if ($action eq 'upload') {
         $fname=$env{'form.'.$formname.'.filename'};
         chop($env{'form.'.$formname});
@@ -8456,6 +8597,7 @@ $env{'user.name'}.':'.$env{'user.domain'
                                     $r->set_handlers('PerlCleanupHandler' => [\&notifysubscribed,@{$handlers}]);
                                     $registered_cleanup=1;
                                 }
+                                $madethumb = 1;
                             } else {
                                 print $logfile "\nUnable to write ".$copyfile.
                                                ':'.$!."\n";
@@ -8468,7 +8610,7 @@ $env{'user.name'}.':'.$env{'user.domain'
             $output = $versionresult;
         }
     }
-    return ($output,$logourl);
+    return ($output,$logourl,$madethumb);
 }
 
 sub logo_versioning {
@@ -8622,7 +8764,7 @@ sub modify_quotas {
         $context = $action;
     }
     if ($context eq 'requestcourses') {
-        @usertools = ('official','unofficial','community','textbook');
+        @usertools = ('official','unofficial','community','textbook','placement');
         @options =('norequest','approval','validate','autolimit');
         %validations = &Apache::lonnet::auto_courserequest_checks($dom);
         %titles = &courserequest_titles();
@@ -8671,7 +8813,7 @@ sub modify_quotas {
         my @approvalnotify = &Apache::loncommon::get_env_multiple('form.'.$context.'notifyapproval');
         @approvalnotify = sort(@approvalnotify);
         $confhash{'notify'}{'approval'} = join(',',@approvalnotify);
-        my @crstypes = ('official','unofficial','community','textbook');
+        my @crstypes = ('official','unofficial','community','textbook','placement');
         my @hasuniquecode = &Apache::loncommon::get_env_multiple('form.uniquecode');
         foreach my $type (@hasuniquecode) {
             if (grep(/^\Q$type\E$/,@crstypes)) {
@@ -8779,20 +8921,16 @@ sub modify_quotas {
                                     #FIXME need to obsolete item in RES space
                                 } elsif ($env{'form.'.$type.'_image_'.$i.'.filename'}) {
                                     my ($cdom,$cnum) = split(/_/,$key);
-                                    if (&Apache::lonnet::homeserver($cnum,$cdom) eq 'no_host') {
-                                        $errors .= '<li><span class="LC_error">'.&mt('Image not saved: could not find textbook course').'</li>';
-                                    } else { 
-                                        my ($imgurl,$error) = &process_textbook_image($r,$dom,$confname,$type.'_image_'.$i,
-                                                                                      $cdom,$cnum,$type,$configuserok,
-                                                                                      $switchserver,$author_ok);
-                                        if ($imgurl) {
-                                            $confhash{$type}{$key}{'image'} = $imgurl;
-                                            $changes{$type}{$key} = 1; 
-                                        }
-                                        if ($error) {
-                                            &Apache::lonnet::logthis($error);
-                                            $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
-                                        }
+                                    my ($imgurl,$error) = &process_textbook_image($r,$dom,$confname,$type.'_image_'.$i,
+                                                                                  $cdom,$cnum,$type,$configuserok,
+                                                                                  $switchserver,$author_ok);
+                                    if ($imgurl) {
+                                        $confhash{$type}{$key}{'image'} = $imgurl;
+                                        $changes{$type}{$key} = 1; 
+                                    }
+                                    if ($error) {
+                                        &Apache::lonnet::logthis($error);
+                                        $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
                                     } 
                                 } elsif ($domconfig{$action}{$type}{$key}{'image'}) {
                                     $confhash{$type}{$key}{'image'} = 
@@ -9326,7 +9464,7 @@ sub process_textbook_image {
         } elsif ($author_ok eq 'ok') {
             my ($result,$imageurl) =
                 &publishlogo($r,'upload',$caller,$dom,$confname,
-                             "$type/$cdom/$cnum/cover",$width,$height);
+                             "$type/$dom/$cnum/cover",$width,$height);
             if ($result eq 'ok') {
                 $url = $imageurl;
             } else {
@@ -9354,7 +9492,7 @@ sub modify_ltitools {
     map { $posslti{$_} = 1; } @ltiroles;
     my @allfields = ('fullname','firstname','lastname','email','user','roles');
     map { $possfield{$_} = 1; } @allfields;
-    my %lt = &ltitools_names();
+    my %lt = &ltitools_names(); 
     if ($env{'form.ltitools_add'}) {
         my $title = $env{'form.ltitools_add_title'};
         $title =~ s/(`)/'/g;
@@ -9391,7 +9529,7 @@ sub modify_ltitools {
                     }
                 } else {
                     if ($env{'form.ltitools_add_'.$item} ne '') {
-                        $confhash{$newid}{'display'}{$item} = $env{'form.ltitools_add_'.$item};
+                        $confhash{$newid}{'display'}{$item} = $env{'form.ltitools_add_'.$item}; 
                     }
                 }
             }
@@ -9409,7 +9547,7 @@ sub modify_ltitools {
             }
             if ($env{'form.ltitools_add_image.filename'} ne '') {
                 my ($imageurl,$error) =
-                    &process_ltitools_image($r,$dom,$confname,'ltitools_add_image',$newid,
+                    &process_ltitools_image($r,$dom,$confname,'ltitools_add_image',$dom,
                                             $configuserok,$switchserver,$author_ok);
                 if ($imageurl) {
                     $confhash{$newid}{'image'} = $imageurl;
@@ -9428,7 +9566,7 @@ sub modify_ltitools {
                             if (($choice ne '') && ($posslti{$choice})) {
                                 $confhash{$newid}{'roles'}{$role} = $choice;
                                 if ($role eq 'cc') {
-                                    $confhash{$newid}{'roles'}{'co'} = $choice;
+                                    $confhash{$newid}{'roles'}{'co'} = $choice; 
                                 }
                             }
                         }
@@ -9449,7 +9587,7 @@ sub modify_ltitools {
                 $confhash{$newid}{'custom'}{$name} = $value;
             }
         } else {
-            my $error = &mt('Failed to acquire unique ID for new external tool');
+            my $error = &mt('Failed to acquire unique ID for new external tool');   
             $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
         }
     }
@@ -9463,7 +9601,7 @@ sub modify_ltitools {
         my @newcustom = &Apache::loncommon::get_env_multiple('form.ltitools_customadd');
         if (@newcustom) {
             map { $customadds{$_} = 1; } @newcustom;
-        }
+        } 
         my %imgdeletions;
         my @todeleteimages = &Apache::loncommon::get_env_multiple('form.ltitools_image_del');
         if (@todeleteimages) {
@@ -9472,7 +9610,6 @@ sub modify_ltitools {
         my $maxnum = $env{'form.ltitools_maxnum'};
         for (my $i=0; $i<=$maxnum; $i++) {
             my $itemid = $env{'form.ltitools_id_'.$i};
-            $itemid =~ s/\D+//g;
             if (ref($domconfig{$action}{$itemid}) eq 'HASH') {
                 if ($deletions{$itemid}) {
                     if ($domconfig{$action}{$itemid}{'image'}) {
@@ -9640,7 +9777,7 @@ sub modify_ltitools {
                     }
                 }
                 my %customdels;
-                my @customdeletions = &Apache::loncommon::get_env_multiple('form.ltitools_customdel_'.$i);
+                my @customdeletions = &Apache::loncommon::get_env_multiple('form.ltitools_customdel_'.$i); 
                 if (@customdeletions) {
                     $changes{$itemid} = 1;
                 }
@@ -9649,7 +9786,7 @@ sub modify_ltitools {
                     foreach my $key (keys(%{$domconfig{$action}{$itemid}{'custom'}})) {
                         unless ($customdels{$key}) {
                             if ($env{'form.ltitools_customval_'.$key.'_'.$i} ne '') {
-                                $confhash{$itemid}{'custom'}{$key} = $env{'form.ltitools_customval_'.$key.'_'.$i};
+                                $confhash{$itemid}{'custom'}{$key} = $env{'form.ltitools_customval_'.$key.'_'.$i}; 
                             }
                             if ($domconfig{$action}{$itemid}{'custom'}{$key} ne $env{'form.ltitools_customval_'.$key.'_'.$i}) {
                                 $changes{$itemid} = 1;
@@ -9724,7 +9861,7 @@ sub modify_ltitools {
                 $bynum{$position} = $itemid;
             }
             foreach my $pos (sort { $a <=> $b } keys(%bynum)) {
-                my $itemid = $bynum{$pos};
+                my $itemid = $bynum{$pos}; 
                 if (ref($confhash{$itemid}) ne 'HASH') {
                     $resulttext .= '<li>'.&mt('Deleted: [_1]',$changes{$itemid}).'</li>';
                 } else {
@@ -9752,8 +9889,8 @@ sub modify_ltitools {
                     }
                     $resulttext .= '<li>'.&mt('Configurable in course:');
                     my @possconfig = ('label','title','target','linktext','explanation');
-                    my $numconfig = 0;
-                    if (ref($confhash{$itemid}{'crsconf'}) eq 'HASH') {
+                    my $numconfig = 0; 
+                    if (ref($confhash{$itemid}{'crsconf'}) eq 'HASH') { 
                         foreach my $item (@possconfig) {
                             if ($confhash{$itemid}{'crsconf'}{$item}) {
                                 $numconfig ++;
@@ -9780,7 +9917,7 @@ sub modify_ltitools {
                             $displaylist = &mt('Display target').':&nbsp;'.
                                            $confhash{$itemid}{'display'}{'target'}.',';
                         }
-                        foreach my $size ('width','height') {
+                        foreach my $size ('width','height') { 
                             if ($confhash{$itemid}{'display'}{$size}) {
                                 $displaylist .= ('&nbsp;'x2).$lt{$size}.':&nbsp;'.
                                                 $confhash{$itemid}{'display'}{$size}.',';
@@ -9817,7 +9954,7 @@ sub modify_ltitools {
                             }
                         }
                         if ($rolemaps) {
-                            $rolemaps =~ s/,$//;
+                            $rolemaps =~ s/,$//; 
                             $resulttext .= '<li>'.&mt('Role mapping:').$rolemaps.'</li>';
                         }
                     }
@@ -9826,12 +9963,12 @@ sub modify_ltitools {
                         if (keys(%{$confhash{$itemid}{'custom'}})) {
                             foreach my $key (sort(keys(%{$confhash{$itemid}{'custom'}}))) {
                                 $customlist .= $key.':'.$confhash{$itemid}{'custom'}{$key}.('&nbsp;'x2);
-                            }
+                            } 
                         }
                         if ($customlist) {
                             $resulttext .= '<li>'.&mt('Custom items').':'.$customlist.'</li>';
                         }
-                    }
+                    } 
                     $resulttext .= '</ul></li>';
                 }
             }
@@ -9892,7 +10029,7 @@ sub get_ltitools_id {
     my $tries = 0;
     my $gotlock = &Apache::lonnet::newput_dom('ltitools',$lockhash,$cdom);
     my ($id,$error);
-
+ 
     while (($gotlock ne 'ok') && ($tries<10)) {
         $tries ++;
         sleep (0.1);
@@ -10550,57 +10687,17 @@ sub modify_contacts {
                 my $value = $env{'form.helpform_'.$field};
                 $value =~ s/^\s+|\s+$//g;
                 if (grep(/^\Q$value\E$/,@{$possoptions->{$field}})) {
-                    $contacts_hash{'contacts'}{'helpform'}{$field} = $value;
+                    $contacts_hash{contacts}{'helpform'}{$field} = $value;
                     if ($field eq 'screenshot') {
                         $env{'form.helpform_maxsize'} =~ s/^\s+|\s+$//g;
                         if ($env{'form.helpform_maxsize'} =~ /^\d+\.?\d*$/) {
-                            $contacts_hash{'contacts'}{'helpform'}{'maxsize'} = $env{'form.helpform_maxsize'};
+                            $contacts_hash{contacts}{'helpform'}{'maxsize'} = $env{'form.helpform_maxsize'};
                         }
                     }
                 }
             }
         }
     }
-    my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
-    my (@statuses,%usertypeshash,@overrides);
-    if ((ref($types) eq 'ARRAY') && (@{$types} > 0)) {
-        @statuses = @{$types};
-        if (ref($usertypes) eq 'HASH') {
-            %usertypeshash = %{$usertypes};
-        }
-    }
-    if (@statuses) {
-        my @possoverrides = &Apache::loncommon::get_env_multiple('form.overrides');
-        foreach my $type (@possoverrides) {
-            if (($type ne '') && (grep(/^\Q$type\E$/,@statuses))) {
-                push(@overrides,$type);
-            }
-        }
-        if (@overrides) {
-            foreach my $type (@overrides) {
-                my @standard = &Apache::loncommon::get_env_multiple('form.override_'.$type);
-                foreach my $item (@contacts) {
-                    if (grep(/^\Q$item\E$/,@standard)) {
-                        $contacts_hash{'contacts'}{'overrides'}{$type}{$item} = 1;
-                        $newsetting{'override_'.$type}{$item} = 1;
-                    } else {
-                        $contacts_hash{'contacts'}{'overrides'}{$type}{$item} = 0;
-                        $newsetting{'override_'.$type}{$item} = 0;
-                    }
-                }
-                $contacts_hash{'contacts'}{'overrides'}{$type}{'others'} = $env{'form.override_'.$type.'_others'};
-                $contacts_hash{'contacts'}{'overrides'}{$type}{'bcc'} = $env{'form.override_'.$type.'_bcc'};
-                $newsetting{'override_'.$type}{'others'} = $env{'form.override_'.$type.'_others'};
-                $newsetting{'override_'.$type}{'bcc'} = $env{'form.override_'.$type.'_bcc'};
-                if (($env{'form.override_'.$type.'_includestr'} ne '') && ($env{'form.override_'.$type.'_includeloc'} =~ /^s|b$/)) {
-                    $includestr{$type} = $env{'form.override_'.$type.'_includestr'};
-                    $includeloc{$type} = $env{'form.override_'.$type.'_includeloc'};
-                    $contacts_hash{'contacts'}{'overrides'}{$type}{'include'} = $includeloc{$type}.':'.&escape($includestr{$type});
-                    $newsetting{'override_'.$type}{'include'} = $contacts_hash{'contacts'}{'overrides'}{$type}{'include'};
-                }
-            }
-        }
-    }
     if (keys(%currsetting) > 0) {
         foreach my $item (@contacts) {
             if ($to{$item} ne $currsetting{$item}) {
@@ -10655,33 +10752,6 @@ sub modify_contacts {
                 }
             }
         }
-        if (@statuses) {
-            if (ref($currsetting{'overrides'}) eq 'HASH') {
-                foreach my $key (keys(%{$currsetting{'overrides'}})) {
-                    if (ref($currsetting{'overrides'}{$key}) eq 'HASH') {
-                        if (ref($newsetting{'override_'.$key}) eq 'HASH') {
-                            foreach my $item (@contacts,'bcc','others','include') {
-                                if ($currsetting{'overrides'}{$key}{$item} ne $newsetting{'override_'.$key}{$item}) {
-                                    push(@{$changes{'overrides'}},$key);
-                                    last;
-                                }
-                            }
-                        } else {
-                            push(@{$changes{'overrides'}},$key);
-                        }
-                    }
-                }
-                foreach my $key (@overrides) {
-                    unless (exists($currsetting{'overrides'}{$key})) {
-                        push(@{$changes{'overrides'}},$key);
-                    }
-                }
-            } else {
-                foreach my $key (@overrides) {
-                    push(@{$changes{'overrides'}},$key);
-                }
-            }
-        }
     } else {
         my %default;
         $default{'supportemail'} = $Apache::lonnet::perlvar{'lonSupportEMail'};
@@ -10782,7 +10852,7 @@ sub modify_contacts {
                             $resulttext .= $bcctext.': <span class="LC_cusr_emph">'.$bcc{$type}.'</span>';
                         } elsif (!@text) {
                             $resulttext .= &mt('No one');
-                        }
+                        }   
                         if ($includestr{$type} ne '') {
                             if ($includeloc{$type} eq 'b') {
                                 $resulttext .= '<br />'.&mt('Text automatically added to e-mail body:').' '.$includestr{$type};
@@ -10796,60 +10866,6 @@ sub modify_contacts {
                     $resulttext .= '</li>';
                 }
             }
-            if (ref($changes{'overrides'}) eq 'ARRAY') {
-                my @deletions;
-                foreach my $type (@{$changes{'overrides'}}) {
-                    if ($usertypeshash{$type}) {
-                        if (grep(/^\Q$type\E/,@overrides)) {
-                            $resulttext .= '<li>'.&mt("Overrides based on requester's affiliation set for [_1]",
-                                                      $usertypeshash{$type}).'<ul><li>';
-                            if (ref($newsetting{'override_'.$type}) eq 'HASH') {
-                                my @text;
-                                foreach my $item (@contacts) {
-                                    if ($newsetting{'override_'.$type}{$item}) {
-                                        push(@text,$short_titles->{$item});
-                                    }
-                                }
-                                if ($newsetting{'override_'.$type}{'others'} ne '') {
-                                    push(@text,$newsetting{'override_'.$type}{'others'});
-                                }
-
-                                if (@text) {
-                                    $resulttext .= &mt('Helpdesk e-mail sent to: [_1]',
-                                                       '<span class="LC_cusr_emph">'.join(', ',@text).'</span>');
-                                }
-                                if ($newsetting{'override_'.$type}{'bcc'} ne '') {
-                                    my $bcctext;
-                                    if (@text) {
-                                        $bcctext = '&nbsp;'.&mt('with Bcc to');
-                                    } else {
-                                        $bcctext = '(Bcc)';
-                                    }
-                                    $resulttext .= $bcctext.': <span class="LC_cusr_emph">'.$newsetting{'override_'.$type}{'bcc'}.'</span>';
-                                } elsif (!@text) {
-                                     $resulttext .= &mt('Helpdesk e-mail sent to no one');
-                                }
-                                $resulttext .= '</li>';
-                                if ($newsetting{'override_'.$type}{'include'} ne '') {
-                                    my ($loc,$str) = split(/:/,$newsetting{'override_'.$type}{'include'});
-                                    if ($loc eq 'b') {
-                                        $resulttext .= '<li>'.&mt('Text automatically added to e-mail body:').' '.&unescape($str).'</li>';
-                                    } elsif ($loc eq 's') {
-                                        $resulttext .= '<li>'.&mt('Text automatically added to e-mail subject:').' '.&unescape($str).'</li>';
-                                    }
-                                }
-                            }
-                            $resulttext .= '</li></ul></li>';
-                        } else {
-                            push(@deletions,$usertypeshash{$type});
-                        }
-                    }
-                }
-                if (@deletions) {
-                    $resulttext .= '<li>'.&mt("Overrides based on requester's affiliation discontinued for: [_1]",
-                                              join(', ',@deletions)).'</li>';
-                }
-            }
             my @offon = ('off','on');
             if ($changes{'reporterrors'}) {
                 $resulttext .= '<li>'.
@@ -10905,6 +10921,7 @@ sub modify_contacts {
                                    &mt('Max size for file uploaded to help form by logged-in user set to [_1] MB.',
                                        $contacts_hash{'contacts'}{'helpform'}{'maxsize'}).
                                    '</li>';
+
                 }
             }
             $resulttext .= '</ul>';
@@ -11498,7 +11515,7 @@ sub modify_selfcreation {
         $save_usercreate{'cancreate'}{'shibenv'} = $cancreate{'shibenv'};
     }
     $save_usercreate{'cancreate'}{'emailusername'} = $cancreate{'emailusername'};
-    $save_usercreate{'email_rule'} = \@email_rule;
+    $save_usercreate{'emailrule'} = \@email_rule;
 
     my %userconfig_hash = (
             usercreation     => \%save_usercreate,
@@ -12319,6 +12336,15 @@ sub modify_coursecategories {
         if ($domconfig{'coursecategories'}{'categorizecomm'} ne $env{'form.categorizecomm'}) {
             $changes{'categorizecomm'} = 1;
             $domconfig{'coursecategories'}{'categorizecomm'} = $env{'form.categorizecomm'};
+
+        }
+        if ($domconfig{'coursecategories'}{'togglecatsplace'} ne $env{'form.togglecatsplace'}) {
+            $changes{'togglecatsplace'} = 1;
+            $domconfig{'coursecategories'}{'togglecatsplace'} = $env{'form.togglecatsplace'};
+        }
+        if ($domconfig{'coursecategories'}{'categorizeplace'} ne $env{'form.categorizeplace'}) {
+            $changes{'categorizeplace'} = 1;
+            $domconfig{'coursecategories'}{'categorizeplace'} = $env{'form.categorizeplace'};
         }
         foreach my $item (@catitems) {
             if (grep(/^\Q$env{'form.coursecat_'.$item}\E$/,@cattypes)) {
@@ -12333,11 +12359,15 @@ sub modify_coursecategories {
         $changes{'categorize'} = 1;
         $changes{'togglecatscomm'} = 1;
         $changes{'categorizecomm'} = 1;
+        $changes{'togglecatsplace'} = 1;
+        $changes{'categorizeplace'} = 1;
         $domconfig{'coursecategories'} = {
                                              togglecats => $env{'form.togglecats'},
                                              categorize => $env{'form.categorize'},
                                              togglecatscomm => $env{'form.togglecatscomm'},
                                              categorizecomm => $env{'form.categorizecomm'},
+                                             togglecatsplace => $env{'form.togglecatsplace'},
+                                             categorizeplace => $env{'form.categorizeplace'},
                                          };
         foreach my $item (@catitems) {
             if ($env{'form.coursecat_'.$item} ne 'std') {
@@ -12355,6 +12385,9 @@ sub modify_coursecategories {
         if (($domconfig{'coursecategories'}{'cats'}{'communities::0'} ne '')  && ($env{'form.communities'} == 0)) {
             push(@deletecategory,'communities::0');
         }
+        if (($domconfig{'coursecategories'}{'cats'}{'placement::0'} ne '')  && ($env{'form.placement'} == 0)) {
+            push(@deletecategory,'placement::0');
+        }
     }
     my (@predelcats,@predeltrails,%predelallitems,%sort_by_deltrail);
     if (ref($cathash) eq 'HASH') {
@@ -12417,9 +12450,23 @@ sub modify_coursecategories {
             $adds{$newitem} = 1;
         }
     }
+    if ($env{'form.placement'} eq '1') {
+        if (ref($cathash) eq 'HASH') {
+            my $newitem = 'placement::0';
+            if ($cathash->{$newitem} eq '') {
+                $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.placement_pos'};
+                $adds{$newitem} = 1;
+            }
+        } else {
+            my $newitem = 'placement::0';
+            $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.placement_pos'};
+            $adds{$newitem} = 1;
+        }
+    }
     if ($env{'form.addcategory_name'} ne '') {
         if (($env{'form.addcategory_name'} ne 'instcode') &&
-            ($env{'form.addcategory_name'} ne 'communities')) {
+            ($env{'form.addcategory_name'} ne 'communities') &&
+            ($env{'form.addcategory_name'} ne 'placement')) {
             my $newitem = &escape($env{'form.addcategory_name'}).'::0';
             $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.addcategory_pos'};
             $adds{$newitem} = 1;
@@ -13014,14 +13061,16 @@ sub modify_coursedefaults {
     my ($dom,$lastactref,%domconfig) = @_;
     my ($resulttext,$errors,%changes,%defaultshash);
     my %defaultchecked = (
+                           'canuse_pdfforms' => 'off',
                            'uselcmath'       => 'on',
                            'usejsme'         => 'on'
                          );
-    my @toggles = ('uselcmath','usejsme');
+    my @toggles = ('canuse_pdfforms','uselcmath','usejsme');
     my @numbers = ('anonsurvey_threshold','uploadquota_official','uploadquota_unofficial',
-                   'uploadquota_community','uploadquota_textbook','mysqltables_official',
-                   'mysqltables_unofficial','mysqltables_community','mysqltables_textbook');
-    my @types = ('official','unofficial','community','textbook');
+                   'uploadquota_community','uploadquota_textbook','uploadquota_placement',
+                   'mysqltables_official','mysqltables_unofficial','mysqltables_community',
+                   'mysqltables_textbook','mysqltables_placement');
+    my @types = ('official','unofficial','community','textbook','placement');
     my %staticdefaults = (
                            anonsurvey_threshold => 10,
                            uploadquota          => 500,
@@ -13206,10 +13255,10 @@ sub modify_coursedefaults {
     if ($putresult eq 'ok') {
         if (keys(%changes) > 0) {
             my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
-            if (($changes{'uploadquota'}) || ($changes{'postsubmit'}) ||
+            if (($changes{'canuse_pdfforms'}) || ($changes{'uploadquota'}) || ($changes{'postsubmit'}) ||
                 ($changes{'coursecredits'}) || ($changes{'uselcmath'}) || ($changes{'usejsme'}) ||
                 ($changes{'canclone'}) || ($changes{'mysqltables'})) {
-                foreach my $item ('uselcmath','usejsme') {
+                foreach my $item ('canuse_pdfforms','uselcmath','usejsme') { 
                     if ($changes{$item}) {
                         $domdefaults{$item}=$defaultshash{'coursedefaults'}{$item};
                     }
@@ -13260,7 +13309,13 @@ sub modify_coursedefaults {
             }
             $resulttext = &mt('Changes made:').'<ul>';
             foreach my $item (sort(keys(%changes))) {
-                if ($item eq 'uselcmath') {
+                if ($item eq 'canuse_pdfforms') {
+                    if ($env{'form.'.$item} eq '1') {
+                        $resulttext .= '<li>'.&mt("Course/Community users can create/upload PDF forms set to 'on'").'</li>';
+                    } else {
+                        $resulttext .= '<li>'.&mt('Course/Community users can create/upload PDF forms set to "off"').'</li>';
+                    }
+                } elsif ($item eq 'uselcmath') {
                     if ($env{'form.'.$item} eq '1') {
                         $resulttext .= '<li>'.&mt('Math preview uses LON-CAPA previewer (javascript), if supported by browser.').'</li>';
                     } else {
@@ -13280,7 +13335,7 @@ sub modify_coursedefaults {
                                        '<li>'.&mt('Official courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'official'}.'</b>').'</li>'.
                                        '<li>'.&mt('Unofficial courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'unofficial'}.'</b>').'</li>'.
                                        '<li>'.&mt('Textbook courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'textbook'}.'</b>').'</li>'.
-
+                                       '<li>'.&mt('Placement tests: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'placement'}.'</b>').'</li>'. 
                                        '<li>'.&mt('Communities: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'community'}.'</b>').'</li>'.
                                        '</ul>'.
                                        '</li>';
@@ -13293,6 +13348,7 @@ sub modify_coursedefaults {
                                        '<li>'.&mt('Official courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'official'}.'</b>').'</li>'.
                                        '<li>'.&mt('Unofficial courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'unofficial'}.'</b>').'</li>'.
                                        '<li>'.&mt('Textbook courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'textbook'}.'</b>').'</li>'.
+                                       '<li>'.&mt('Placement tests: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'placement'}.'</b>').'</li>'.
                                        '<li>'.&mt('Communities: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'community'}.'</b>').'</li>'.
                                        '</ul>'.
                                        '</li>';
@@ -13328,6 +13384,8 @@ sub modify_coursedefaults {
                                     $resulttext .= &mt('Unofficial courses');
                                 } elsif ($type eq 'textbook') {
                                     $resulttext .= &mt('Textbook courses');
+                                } elsif ($type eq 'placement') {
+                                    $resulttext .= &mt('Placement tests');
                                 }
                                 $resulttext .= ' -- '.$display.'</li>';
                             }
@@ -13379,7 +13437,7 @@ sub modify_coursedefaults {
 sub modify_selfenrollment {
     my ($dom,$lastactref,%domconfig) = @_;
     my ($resulttext,$errors,%changes,%selfenrollhash,%ordered);
-    my @types = ('official','unofficial','community','textbook');
+    my @types = ('official','unofficial','community','textbook','placement');
     my %titles = &tool_titles();
     my %descs = &Apache::lonuserutils::selfenroll_default_descs();
     ($ordered{'admin'},my $titlesref) = &Apache::lonuserutils::get_selfenroll_titles();
@@ -13626,8 +13684,8 @@ sub modify_usersessions {
                 );
     my @prefixes = ('remote','hosted','spares');
     my @lcversions = &Apache::lonnet::all_loncaparevs();
-    my (%by_ip,%by_location,@intdoms);
-    &build_location_hashes(\@intdoms,\%by_ip,\%by_location);
+    my (%by_ip,%by_location,@intdoms,@instdoms);
+    &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
     my @locations = sort(keys(%by_location));
     my (%defaultshash,%changes);
     foreach my $prefix (@prefixes) {
@@ -13930,6 +13988,298 @@ sub modify_usersessions {
                     }
                 }
                 $resulttext .= '</ul>';
+            } else {
+                $resulttext = $nochgmsg;
+            }
+        } else {
+            $resulttext = '<span class="LC_error">'.
+                          &mt('An error occurred: [_1]',$putresult).'</span>';
+        }
+    } else {
+        $resulttext = $nochgmsg;
+    }
+    return $resulttext;
+}
+
+sub modify_ssl {
+    my ($dom,$lastactref,%domconfig) = @_;
+    my (%by_ip,%by_location,@intdoms,@instdoms);
+    &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
+    my @locations = sort(keys(%by_location));
+    my %servers = &Apache::lonnet::internet_dom_servers($dom);
+    my (%defaultshash,%changes);
+    my $action = 'ssl';
+    my @prefixes = ('connto','connfrom','replication');
+    foreach my $prefix (@prefixes) {
+        $defaultshash{$action}{$prefix} = {};
+    }
+    my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
+    my $resulttext;
+    my %iphost = &Apache::lonnet::get_iphost();
+    my @reptypes = ('certreq','nocertreq');
+    my @connecttypes = ('dom','intdom','other');
+    my %types = (
+                  connto      => \@connecttypes,
+                  connfrom    => \@connecttypes,
+                  replication => \@reptypes,
+                );
+    foreach my $prefix (sort(keys(%types))) {
+        foreach my $type (@{$types{$prefix}}) {
+            if (($prefix eq 'connto') || ($prefix eq 'connfrom')) {
+                my $value = 'yes';
+                if ($env{'form.'.$prefix.'_'.$type} =~ /^(no|req)$/) {
+                    $value = $env{'form.'.$prefix.'_'.$type};
+                }
+                if (ref($domconfig{$action}{$prefix}) eq 'HASH') {
+                    if ($domconfig{$action}{$prefix}{$type} ne '') {
+                        if ($value ne $domconfig{$action}{$prefix}{$type}) {
+                            $changes{$prefix}{$type} = 1;
+                        }
+                        $defaultshash{$action}{$prefix}{$type} = $value;
+                    } else {
+                        $defaultshash{$action}{$prefix}{$type} = $value;
+                        $changes{$prefix}{$type} = 1;
+                    }
+                } else {
+                    $defaultshash{$action}{$prefix}{$type} = $value;
+                    $changes{$prefix}{$type} = 1;
+                }
+                if (($type eq 'dom') && (keys(%servers) == 1)) {
+                    delete($changes{$prefix}{$type});
+                } elsif (($type eq 'intdom') && (@instdoms == 1)) {
+                    delete($changes{$prefix}{$type});
+                } elsif (($type eq 'other') && (keys(%by_location) == 0)) { 
+                    delete($changes{$prefix}{$type});
+                }
+            } elsif ($prefix eq 'replication') {
+                if (@locations > 0) {
+                    my $inuse = $env{'form.'.$prefix.'_'.$type.'_inuse'};
+                    my @vals = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_'.$type);
+                    my @okvals;
+                    foreach my $val (@vals) {
+                        if ($val =~ /:/) {
+                            my @items = split(/:/,$val);
+                            foreach my $item (@items) {
+                                if (ref($by_location{$item}) eq 'ARRAY') {
+                                    push(@okvals,$item);
+                                }
+                            }
+                        } else {
+                            if (ref($by_location{$val}) eq 'ARRAY') {
+                                push(@okvals,$val);
+                            }
+                        }
+                    }
+                    @okvals = sort(@okvals);
+                    if (ref($domconfig{$action}) eq 'HASH') {
+                        if (ref($domconfig{$action}{$prefix}) eq 'HASH') {
+                            if (ref($domconfig{$action}{$prefix}{$type}) eq 'ARRAY') {
+                                if ($inuse == 0) {
+                                    $changes{$prefix}{$type} = 1;
+                                } else {
+                                    $defaultshash{$action}{$prefix}{$type} = \@okvals;
+                                    my @changed = &Apache::loncommon::compare_arrays($domconfig{$action}{$prefix}{$type},$defaultshash{$action}{$prefix}{$type});
+                                    if (@changed > 0) {
+                                        $changes{$prefix}{$type} = 1;
+                                    }
+                                }
+                            } else {
+                                if ($inuse == 1) {
+                                    $defaultshash{$action}{$prefix}{$type} = \@okvals;
+                                    $changes{$prefix}{$type} = 1;
+                                }
+                            }
+                        } else {
+                            if ($inuse == 1) {
+                                $defaultshash{$action}{$prefix}{$type} = \@okvals;
+                                $changes{$prefix}{$type} = 1;
+                            }
+                        }
+                    } else {
+                        if ($inuse == 1) {
+                            $defaultshash{$action}{$prefix}{$type} = \@okvals;
+                            $changes{$prefix}{$type} = 1;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    my $nochgmsg = &mt('No changes made to LON-CAPA SSL settings');
+    if (keys(%changes) > 0) {
+        my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
+                                                 $dom);
+        if ($putresult eq 'ok') {
+            if (ref($defaultshash{$action}) eq 'HASH') {
+                if (ref($defaultshash{$action}{'replication'}) eq 'HASH') {
+                    $domdefaults{'replication'} = $defaultshash{$action}{'replication'};
+                }
+                if (ref($defaultshash{$action}{'connto'}) eq 'HASH') {
+                    $domdefaults{'connto'} = $domconfig{$action}{'connto'};
+                }
+                if (ref($defaultshash{$action}{'connfrom'}) eq 'HASH') {
+                    $domdefaults{'connfrom'} = $domconfig{$action}{'connfrom'};
+                }
+            }
+            my $cachetime = 24*60*60;
+            &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
+            if (ref($lastactref) eq 'HASH') {
+                $lastactref->{'domdefaults'} = 1;
+            }
+            if (keys(%changes) > 0) {
+                my %titles = &ssl_titles();
+                $resulttext = &mt('Changes made:').'<ul>';
+                foreach my $prefix (@prefixes) {
+                    if (ref($changes{$prefix}) eq 'HASH') {
+                        $resulttext .= '<li>'.$titles{$prefix}.'<ul>';
+                        foreach my $type (@{$types{$prefix}}) {
+                            if (defined($changes{$prefix}{$type})) {
+                                my $newvalue;
+                                if (ref($defaultshash{$action}) eq 'HASH') {
+                                    if (ref($defaultshash{$action}{$prefix})) {
+                                        if (($prefix eq 'connto') || ($prefix eq 'connfrom')) {
+                                            $newvalue = $titles{$defaultshash{$action}{$prefix}{$type}};
+                                        } elsif (ref($defaultshash{$action}{$prefix}{$type}) eq 'ARRAY') {
+                                            if (@{$defaultshash{$action}{$prefix}{$type}} > 0) {
+                                                $newvalue = join(', ',@{$defaultshash{$action}{$prefix}{$type}});
+                                            }
+                                        }
+                                    }
+                                    if ($newvalue eq '') {
+                                        $resulttext .= '<li>'.&mt('[_1] set to: none',$titles{$type}).'</li>';
+                                    } else {
+                                        $resulttext .= '<li>'.&mt('[_1] set to: [_2].',$titles{$type},$newvalue).'</li>';
+                                    }
+                                }
+                            }
+                        }
+                        $resulttext .= '</ul>';
+                    }
+                }
+            } else {
+                $resulttext = $nochgmsg;
+            }
+        } else {
+            $resulttext = '<span class="LC_error">'.
+                          &mt('An error occurred: [_1]',$putresult).'</span>';
+        }
+    } else {
+        $resulttext = $nochgmsg;
+    }
+    return $resulttext;
+}
+
+sub modify_trust {
+    my ($dom,$lastactref,%domconfig) = @_;
+    my (%by_ip,%by_location,@intdoms,@instdoms);
+    &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
+    my @locations = sort(keys(%by_location));
+    my @prefixes = qw(content shared enroll othcoau coaurem domroles catalog reqcrs msg);
+    my @types = ('exc','inc');
+    my (%defaultshash,%changes);
+    foreach my $prefix (@prefixes) {
+        $defaultshash{'trust'}{$prefix} = {};
+    }
+    my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
+    my $resulttext;
+    foreach my $prefix (@prefixes) {
+        foreach my $type (@types) {
+            my $inuse = $env{'form.'.$prefix.'_'.$type.'_inuse'};
+            my @vals = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_'.$type);
+            my @okvals;
+            foreach my $val (@vals) {
+                if ($val =~ /:/) {
+                    my @items = split(/:/,$val);
+                    foreach my $item (@items) {
+                        if (ref($by_location{$item}) eq 'ARRAY') {
+                            push(@okvals,$item);
+                        }
+                    }
+                } else {
+                    if (ref($by_location{$val}) eq 'ARRAY') {
+                        push(@okvals,$val);
+                    }
+                }
+            }
+            @okvals = sort(@okvals);
+            if (ref($domconfig{'trust'}) eq 'HASH') {
+                if (ref($domconfig{'trust'}{$prefix}) eq 'HASH') {
+                    if (ref($domconfig{'trust'}{$prefix}{$type}) eq 'ARRAY') {
+                        if ($inuse == 0) {
+                            $changes{$prefix}{$type} = 1;
+                        } else {
+                            $defaultshash{'trust'}{$prefix}{$type} = \@okvals;
+                            my @changed = &Apache::loncommon::compare_arrays($domconfig{'trust'}{$prefix}{$type},$defaultshash{'trust'}{$prefix}{$type});
+                            if (@changed > 0) {
+                                $changes{$prefix}{$type} = 1;
+                            }
+                        }
+                    } else {
+                        if ($inuse == 1) {
+                            $defaultshash{'trust'}{$prefix}{$type} = \@okvals;
+                            $changes{$prefix}{$type} = 1;
+                        }
+                    }
+                } else {
+                    if ($inuse == 1) {
+                        $defaultshash{'trust'}{$prefix}{$type} = \@okvals;
+                        $changes{$prefix}{$type} = 1;
+                    }
+                }
+            } else {
+                if ($inuse == 1) {
+                    $defaultshash{'trust'}{$prefix}{$type} = \@okvals;
+                    $changes{$prefix}{$type} = 1;
+                }
+            }
+        }
+    }
+    my $nochgmsg = &mt('No changes made to trust settings.');
+    if (keys(%changes) > 0) {
+        my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
+                                                 $dom);
+        if ($putresult eq 'ok') {
+            if (ref($defaultshash{'trust'}) eq 'HASH') {
+                foreach my $prefix (@prefixes) {
+                    if (ref($defaultshash{'trust'}{$prefix}) eq 'HASH') {
+                        $domdefaults{'trust'.$prefix} = $defaultshash{'trust'}{$prefix};
+                    }
+                }
+            }
+            my $cachetime = 24*60*60;
+            &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
+            if (ref($lastactref) eq 'HASH') {
+                $lastactref->{'domdefaults'} = 1;
+            }
+            if (keys(%changes) > 0) {
+                my %lt = &trust_titles();
+                $resulttext = &mt('Changes made:').'<ul>';
+                foreach my $prefix (@prefixes) {
+                    if (ref($changes{$prefix}) eq 'HASH') {
+                        $resulttext .= '<li>'.$lt{$prefix}.'<ul>';
+                        foreach my $type (@types) {
+                            if (defined($changes{$prefix}{$type})) {
+                                my $newvalue;
+                                if (ref($defaultshash{'trust'}) eq 'HASH') {
+                                    if (ref($defaultshash{'trust'}{$prefix})) {
+                                        if (ref($defaultshash{'trust'}{$prefix}{$type}) eq 'ARRAY') {
+                                            if (@{$defaultshash{'trust'}{$prefix}{$type}} > 0) {
+                                                $newvalue = join(', ',@{$defaultshash{'trust'}{$prefix}{$type}});
+                                            }
+                                        }
+                                    }
+                                }
+                                if ($newvalue eq '') {
+                                    $resulttext .= '<li>'.&mt('[_1] set to: none',$lt{$type}).'</li>';
+                                } else {
+                                    $resulttext .= '<li>'.&mt('[_1] set to: [_2].',$lt{$type},$newvalue).'</li>';
+                                }
+                            }
+                        }
+                        $resulttext .= '</ul>';
+                    }
+                }
+                $resulttext .= '</ul>';
             } else {
                 $resulttext = $nochgmsg;
             }