--- loncom/interface/loncommon.pm	2010/08/08 02:00:38	1.973
+++ loncom/interface/loncommon.pm	2011/12/27 20:14:32	1.1048
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # a pile of common routines
 #
-# $Id: loncommon.pm,v 1.973 2010/08/08 02:00:38 raeburn Exp $
+# $Id: loncommon.pm,v 1.1048 2011/12/27 20:14:32 foxr Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -154,6 +154,8 @@ sub ssi_with_retries {
 # ----------------------------------------------- Filetypes/Languages/Copyright
 my %language;
 my %supported_language;
+my %latex_language;		# For choosing hyphenation in <transl..>
+my %latex_language_bykey;	# for choosing hyphenation from metadata
 my %cprtag;
 my %scprtag;
 my %fe; my %fd; my %fm;
@@ -186,11 +188,15 @@ BEGIN {
             while (my $line = <$fh>) {
                 next if ($line=~/^\#/);
                 chomp($line);
-                my ($key,$two,$country,$three,$enc,$val,$sup)=(split(/\t/,$line));
+                my ($key,$two,$country,$three,$enc,$val,$sup,$latex)=(split(/\t/,$line));
                 $language{$key}=$val.' - '.$enc;
                 if ($sup) {
                     $supported_language{$key}=$sup;
                 }
+		if ($latex) {
+		    $latex_language_bykey{$key} = $latex;
+		    $latex_language{$two} = $latex;
+		}
             }
             close($fh);
         }
@@ -409,7 +415,7 @@ sub studentbrowser_javascript {
 <script type="text/javascript" language="Javascript">
 // <![CDATA[
     var stdeditbrowser;
-    function openstdbrowser(formname,uname,udom,roleflag,ignorefilter,courseadvonly) {
+    function openstdbrowser(formname,uname,udom,clicker,roleflag,ignorefilter,courseadvonly) {
         var url = '/adm/pickstudent?';
         var filter;
 	if (!ignorefilter) {
@@ -421,7 +427,8 @@ sub studentbrowser_javascript {
 	   }
         }
         url += 'form=' + formname + '&unameelement='+uname+
-                                    '&udomelement='+udom;
+                                    '&udomelement='+udom+
+                                    '&clicker='+clicker;
 	if (roleflag) { url+="&roles=1"; }
         if (courseadvonly) { url+="&courseadvonly=1"; }
         var title = 'Student_Browser';
@@ -435,15 +442,37 @@ sub studentbrowser_javascript {
 ENDSTDBRW
 }
 
+sub resourcebrowser_javascript {
+   unless ($env{'request.course.id'}) { return ''; }
+   return (<<'ENDRESBRW');
+<script type="text/javascript" language="Javascript">
+// <![CDATA[
+    var reseditbrowser;
+    function openresbrowser(formname,reslink) {
+        var url = '/adm/pickresource?form='+formname+'&reslink='+reslink;
+        var title = 'Resource_Browser';
+        var options = 'scrollbars=1,resizable=1,menubar=0';
+        options += ',width=700,height=500';
+        reseditbrowser = open(url,title,options,'1');
+        reseditbrowser.focus();
+    }
+// ]]>
+</script>
+ENDRESBRW
+}
+
 sub selectstudent_link {
-   my ($form,$unameele,$udomele,$courseadvonly)=@_;
-   my $callargs = "'".$form."','".$unameele."','".$udomele."'";
+   my ($form,$unameele,$udomele,$courseadvonly,$clickerid)=@_;
+   my $callargs = "'".&Apache::lonhtmlcommon::entity_encode($form)."','".
+                      &Apache::lonhtmlcommon::entity_encode($unameele)."','".
+                      &Apache::lonhtmlcommon::entity_encode($udomele)."'";
    if ($env{'request.course.id'}) {  
        if (!&Apache::lonnet::allowed('srm',$env{'request.course.id'})
 	   && !&Apache::lonnet::allowed('srm',$env{'request.course.id'}.
 					'/'.$env{'request.course.sec'})) {
 	   return '';
        }
+       $callargs.=",'".&Apache::lonhtmlcommon::entity_encode($clickerid)."'";
        if ($courseadvonly)  {
            $callargs .= ",'',1,1";
        }
@@ -452,7 +481,7 @@ sub selectstudent_link {
               &mt('Select User').'</a></span>';
    }
    if ($env{'request.role'}=~/^(au|dc|su)/) {
-       $callargs .= ",1"; 
+       $callargs .= ",'',1"; 
        return '<span class="LC_nobreak">'.
               '<a href="javascript:openstdbrowser('.$callargs.');">'.
               &mt('Select User').'</a></span>';
@@ -460,6 +489,19 @@ sub selectstudent_link {
    return '';
 }
 
+sub selectresource_link {
+   my ($form,$reslink,$arg)=@_;
+   
+   my $callargs = "'".&Apache::lonhtmlcommon::entity_encode($form)."','".
+                      &Apache::lonhtmlcommon::entity_encode($reslink)."'";
+   unless ($env{'request.course.id'}) { return $arg; }
+   return '<span class="LC_nobreak">'.
+              '<a href="javascript:openresbrowser('.$callargs.');">'.
+              $arg.'</a></span>';
+}
+
+
+
 sub authorbrowser_javascript {
     return <<"ENDAUTHORBRW";
 <script type="text/javascript" language="JavaScript">
@@ -596,6 +638,51 @@ ENDJS
 
 }
 
+sub javascript_array_indexof {
+    return <<ENDJS;
+<script type="text/javascript" language="JavaScript">
+// <![CDATA[
+
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
+        "use strict";
+        if (this === void 0 || this === null) {
+            throw new TypeError();
+        }
+        var t = Object(this);
+        var len = t.length >>> 0;
+        if (len === 0) {
+            return -1;
+        }
+        var n = 0;
+        if (arguments.length > 0) {
+            n = Number(arguments[1]);
+            if (n !== n) { // shortcut for verifying if it's NaN
+                n = 0;
+            } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
+                n = (n > 0 || -1) * Math.floor(Math.abs(n));
+            }
+        }
+        if (n >= len) {
+            return -1;
+        }
+        var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
+        for (; k < len; k++) {
+            if (k in t && t[k] === searchElement) {
+                return k;
+            }
+        }
+        return -1;
+    }
+}
+
+// ]]>
+</script>
+
+ENDJS
+
+}
+
 sub userbrowser_javascript {
     my $id_functions = &javascript_index_functions();
     return <<"ENDUSERBRW";
@@ -766,6 +853,9 @@ sub selectcourse_link {
    } elsif ($selecttype eq 'Course/Community') {
        $linktext = &mt('Select Course/Community');
        $type = '';
+   } elsif ($selecttype eq 'Select') {
+       $linktext = &mt('Select');
+       $type = '';
    }
    return '<span class="LC_nobreak">'
          ."<a href='"
@@ -1102,7 +1192,7 @@ sub help_open_topic {
     my ($topic, $text, $stayOnPage, $width, $height, $imgid) = @_;
     $text = "" if (not defined $text);
     $stayOnPage = 0 if (not defined $stayOnPage);
-    $width = 350 if (not defined $width);
+    $width = 500 if (not defined $width);
     $height = 400 if (not defined $height);
     my $filename = $topic;
     $filename =~ s/ /_/g;
@@ -1113,7 +1203,9 @@ sub help_open_topic {
     $topic=~s/\W/\_/g;
 
     if (!$stayOnPage) {
-	$link = "javascript:void(open('/adm/help/${filename}.hlp', 'Help_for_$topic', 'menubar=0,toolbar=1,scrollbars=1,width=$width,height=$height,resizable=yes'))";
+	$link = "javascript:openMyModal('/adm/help/${filename}.hlp',$width,$height,'yes');";
+    } elsif ($stayOnPage eq 'popup') {
+        $link = "javascript:void(open('/adm/help/${filename}.hlp', 'Help_for_$topic', 'menubar=0,toolbar=1,scrollbars=1,width=$width,height=$height,resizable=yes'))";
     } else {
 	$link = "/adm/help/${filename}.hlp";
     }
@@ -1146,27 +1238,22 @@ sub help_open_topic {
 # This is a quicky function for Latex cheatsheet editing, since it 
 # appears in at least four places
 sub helpLatexCheatsheet {
-    my ($topic,$text,$not_author) = @_;
+    my ($topic,$text,$not_author,$stayOnPage) = @_;
     my $out;
     my $addOther = '';
     if ($topic) {
-	$addOther = '<span>'.&Apache::loncommon::help_open_topic($topic,&mt($text),
-							       undef, undef, 600).
-								   '</span> ';
+	$addOther = '<span>'.&help_open_topic($topic,&mt($text),$stayOnPage, undef, 600).'</span> ';
     }
     $out = '<span>' # Start cheatsheet
 	  .$addOther
           .'<span>'
-	  .&Apache::loncommon::help_open_topic('Greek_Symbols',&mt('Greek Symbols'),
-					       undef,undef,600)
+	  .&help_open_topic('Greek_Symbols',&mt('Greek Symbols'),$stayOnPage,undef,600)
 	  .'</span> <span>'
-	  .&Apache::loncommon::help_open_topic('Other_Symbols',&mt('Other Symbols'),
-					       undef,undef,600)
+	  .&help_open_topic('Other_Symbols',&mt('Other Symbols'),$stayOnPage,undef,600)
 	  .'</span>';
     unless ($not_author) {
         $out .= ' <span>'
-	       .&Apache::loncommon::help_open_topic('Authoring_Output_Tags',&mt('Output Tags'),
-	                                            undef,undef,600)
+	       .&help_open_topic('Authoring_Output_Tags',&mt('Output Tags'),$stayOnPage,undef,600)
 	       .'</span>';
     }
     $out .= '</span>'; # End cheatsheet
@@ -1722,7 +1809,7 @@ sub create_workbook {
         return (undef);
     }
     #
-    $workbook->set_tempdir('/home/httpd/perl/tmp');
+    $workbook->set_tempdir(LONCAPA::tempdir());
     #
     my $format = &Apache::loncommon::define_excel_formats($workbook);
     return ($workbook,$filename,$format);
@@ -2274,12 +2361,16 @@ function changed_text(choice,currentform
 }
 
 function set_auth_radio_buttons(newvalue,currentform) {
+    var numauthchoices = currentform.login.length;
+    if (typeof numauthchoices  == "undefined") {
+        return;
+    } 
     var i=0;
-    while (i < currentform.login.length) {
+    while (i < numauthchoices) {
         if (currentform.login[i].value == newvalue) { break; }
         i++;
     }
-    if (i == currentform.login.length) {
+    if (i == numauthchoices) {
         return;
     }
     current.radiovalue = newvalue;
@@ -3142,11 +3233,29 @@ sub languagedescription {
 	    ($supported_language{$code}?' ('.&mt('interface available').')':'');
 }
 
+=pod
+
+=item * &plainlanguagedescription
+
+Returns both the plain language description (e.g. 'Creoles and Pidgins, English-based (Other)')
+and the language character encoding (e.g. ISO) separated by a ' - ' string.
+
+=cut
+
 sub plainlanguagedescription {
     my $code=shift;
     return $language{$code};
 }
 
+=pod
+
+=item * &supportedlanguagecode
+
+Returns the supported language code (e.g. sptutf maps to pt) given a language
+code.
+
+=cut
+
 sub supportedlanguagecode {
     my $code=shift;
     return $supported_language{$code};
@@ -3154,6 +3263,35 @@ sub supportedlanguagecode {
 
 =pod
 
+=item * &latexlanguage()
+
+Given a language key code returns the correspondnig language to use
+to select the correct hyphenation on LaTeX printouts.  This is undef if there
+is no supported hyphenation for the language code.
+
+=cut
+
+sub latexlanguage {
+    my $code = shift;
+    return $latex_language{$code};
+}
+
+=pod
+
+=item * &latexhyphenation()
+
+Same as above but what's supplied is the language as it might be stored
+in the metadata.
+
+=cut
+
+sub latexhyphenation {
+    my $key = shift;
+    return $latex_language_bykey{$key};
+}
+
+=pod
+
 =item * &copyrightids() 
 
 returns list of all copyrights
@@ -3411,22 +3549,24 @@ sub get_previous_attempt {
       }
       $prevattempts=&start_data_table().&start_data_table_header_row();
       $prevattempts.='<th>'.&mt('History').'</th>';
-      my %typeparts;
+      my (%typeparts,%lasthidden);
       my $showsurv=&Apache::lonnet::allowed('vas',$env{'request.course.id'});
       foreach my $key (sort(keys(%lasthash))) {
 	my ($ign,@parts) = split(/\./,$key);
 	if ($#parts > 0) {
 	  my $data=$parts[-1];
+          next if ($data eq 'foilorder');
 	  pop(@parts);
+          $prevattempts.='<th>'.&mt('Part ').join('.',@parts).'<br />'.$data.'&nbsp;</th>';
           if ($data eq 'type') {
               unless ($showsurv) {
                   my $id = join(',',@parts);
                   $typeparts{$ign.'.'.$id} = $lasthash{$key};
+                  if (($lasthash{$key} eq 'anonsurvey') || ($lasthash{$key} eq 'anonsurveycred')) {
+                      $lasthidden{$ign.'.'.$id} = 1;
+                  }
               }
-              delete($lasthash{$key});
-          } else {
-	      $prevattempts.='<th>'.&mt('Part ').join('.',@parts).'<br />'.$data.'&nbsp;</th>';
-          }
+          } 
 	} else {
 	  if ($#parts == 0) {
 	    $prevattempts.='<th>'.$parts[0].'</th>';
@@ -3436,7 +3576,6 @@ sub get_previous_attempt {
 	}
       }
       $prevattempts.=&end_data_table_header_row();
-      my %lasthidden;
       if ($getattempt eq '') {
 	for ($version=1;$version<=$returnhash{'version'};$version++) {
             my @hidden;
@@ -3444,11 +3583,6 @@ sub get_previous_attempt {
                 foreach my $id (keys(%typeparts)) {
                     if (($returnhash{$version.':'.$id.'.type'} eq 'anonsurvey') || ($returnhash{$version.':'.$id.'.type'} eq 'anonsurveycred')) {
                         push(@hidden,$id);
-                        $lasthidden{$id} = 1;
-                    } elsif ($lasthidden{$id}) {
-                        if (exists($returnhash{$version.':'.$id.'.award'})) {
-                            delete($lasthidden{$id});
-                        }
                     }
                 }
             }
@@ -3456,6 +3590,7 @@ sub get_previous_attempt {
                            '<td>'.&mt('Transaction [_1]',$version).'</td>';
             if (@hidden) {
                 foreach my $key (sort(keys(%lasthash))) {
+                    next if ($key =~ /\.foilorder$/);
                     my $hide;
                     foreach my $id (@hidden) {
                         if ($key =~ /^\Q$id\E/) {
@@ -3484,6 +3619,7 @@ sub get_previous_attempt {
                 }
             } else {
 	        foreach my $key (sort(keys(%lasthash))) {
+                    next if ($key =~ /\.foilorder$/);
 		    my $value = &format_previous_attempt_value($key,
 			            $returnhash{$version.':'.$key});
 		    $prevattempts.='<td>'.$value.'&nbsp;</td>';
@@ -3495,6 +3631,7 @@ sub get_previous_attempt {
       my @currhidden = keys(%lasthidden);
       $prevattempts.=&start_data_table_row().'<td>'.&mt('Current').'</td>';
       foreach my $key (sort(keys(%lasthash))) {
+          next if ($key =~ /\.foilorder$/);
           if (%typeparts) {
               my $hidden;
               foreach my $id (@currhidden) {
@@ -3546,10 +3683,33 @@ sub get_previous_attempt {
 
 sub format_previous_attempt_value {
     my ($key,$value) = @_;
-    if ($key =~ /timestamp/) {
+    if (($key =~ /timestamp/) || ($key=~/duedate/)) {
 	$value = &Apache::lonlocal::locallocaltime($value);
     } elsif (ref($value) eq 'ARRAY') {
 	$value = '('.join(', ', @{ $value }).')';
+    } elsif ($key =~ /answerstring$/) {
+        my %answers = &Apache::lonnet::str2hash($value);
+        my @anskeys = sort(keys(%answers));
+        if (@anskeys == 1) {
+            my $answer = $answers{$anskeys[0]};
+            if ($answer =~ m{\0}) {
+                $answer =~ s{\0}{,}g;
+            }
+            my $tag_internal_answer_name = 'INTERNAL';
+            if ($anskeys[0] eq $tag_internal_answer_name) {
+                $value = $answer; 
+            } else {
+                $value = $anskeys[0].'='.$answer;
+            }
+        } else {
+            foreach my $ans (@anskeys) {
+                my $answer = $answers{$ans};
+                if ($answer =~ m{\0}) {
+                    $answer =~ s{\0}{,}g;
+                }
+                $value .=  $ans.'='.$answer.'<br />';;
+            } 
+        }
     } else {
 	$value = &unescape($value);
     }
@@ -3828,7 +3988,9 @@ sub findallcourses {
         $udom = $env{'user.domain'};
     }
     if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {
-        my %roleshash = &Apache::lonnet::dump('roles',$udom,$uname);
+        my $extra = &Apache::lonnet::freeze_escape({'skipcheck' => 1});
+        my %roleshash = &Apache::lonnet::dump('roles',$udom,$uname,'.',undef,
+                                              $extra);
         if (!%roles) {
             %roles = (
                        cc => 1,
@@ -4242,8 +4404,7 @@ sub get_domainconf {
                     if (ref($domconfig{'login'}{$key}) eq 'HASH') {
                         if ($key eq 'loginvia') {
                             if (ref($domconfig{'login'}{'loginvia'}) eq 'HASH') {
-                                my @ids = &Apache::lonnet::current_machine_ids();
-                                foreach my $hostname (@ids) {
+                                foreach my $hostname (keys(%{$domconfig{'login'}{'loginvia'}})) {
                                     if (ref($domconfig{'login'}{'loginvia'}{$hostname}) eq 'HASH') {
                                         if ($domconfig{'login'}{'loginvia'}{$hostname}{'server'}) {
                                             my $server = $domconfig{'login'}{'loginvia'}{$hostname}{'server'};
@@ -4252,7 +4413,7 @@ sub get_domainconf {
 
                                                 $designhash{$udom.'.login.loginvia_'.$hostname} = $server.':'.$domconfig{'login'}{'loginvia'}{$hostname}{'custompath'};
                                             } else {
-                                                 $designhash{$udom.'.login.loginvia_'.$hostname} = $server.':'.$domconfig{'login'}{'loginvia'}{$hostname}{'serverpath'};
+                                                $designhash{$udom.'.login.loginvia_'.$hostname} = $server.':'.$domconfig{'login'}{'loginvia'}{$hostname}{'serverpath'};
                                             }
                                             if ($domconfig{'login'}{'loginvia'}{$hostname}{'exempt'}) {
                                                 $designhash{$udom.'.login.loginvia_exempt_'.$hostname} = $domconfig{'login'}{'loginvia'}{$hostname}{'exempt'};
@@ -4335,7 +4496,7 @@ sub get_legacy_domconf {
             close($fh);
         }
     }
-    if (-e '/home/httpd/html/adm/lonDomLogos/'.$udom.'.gif') {
+    if (-e $Apache::lonnet::perlvar{'lonDocRoot'}.'/adm/lonDomLogos/'.$udom.'.gif') {
         $legacyhash{$udom.'.login.domlogo'} = "/adm/lonDomLogos/$udom.gif";
     }
     return %legacyhash;
@@ -4393,7 +4554,10 @@ sub designparm {
         return $env{'environment.color.'.$which};
     }
     $domain=&determinedomain($domain);
-    my %domdesign = &get_domainconf($domain);
+    my %domdesign;
+    unless ($domain eq 'public') {
+        %domdesign = &get_domainconf($domain);
+    }
     my $output;
     if ($domdesign{$domain.'.'.$which} ne '') {
         $output = $domdesign{$domain.'.'.$which};
@@ -4418,27 +4582,39 @@ sub designparm {
 
 =item * &authorspace()
 
-Inputs: ./.
+Inputs: $url (usually will be undef).
 
-Returns: Path to the Construction Space of the current user's
-         accessed author space
-         The author space will be that of the current user
-         when accessing the own author space
-         and that of the co-author/assistent co-author
-         when accessing the co-author's/assistent co-author's
-         space
+Returns: Path to Construction Space containing the resource or 
+         directory being viewed (or for which action is being taken). 
+         If $url is provided, and begins /priv/<domain>/<uname>
+         the path will be that portion of the $context argument.
+         Otherwise the path will be for the author space of the current
+         user when the current role is author, or for that of the 
+         co-author/assistant co-author space when the current role 
+         is co-author or assistant co-author.
 
 =cut
 
 sub authorspace {
+    my ($url) = @_;
+    if ($url ne '') {
+        if ($url =~ m{^(/priv/$match_domain/$match_username/)}) {
+           return $1;
+        }
+    }
     my $caname = '';
-    if ($env{'request.role'} =~ /^ca|^aa/) {
-        (undef,$caname) =
+    my $cadom = '';
+    if ($env{'request.role'} =~ /^(?:ca|aa)/) {
+        ($cadom,$caname) =
             ($env{'request.role'}=~/($match_domain)\/($match_username)$/);
-    } else {
+    } elsif ($env{'request.role'} =~ m{^au\./($match_domain)/}) {
         $caname = $env{'user.name'};
+        $cadom = $env{'user.domain'};
     }
-    return '/priv/'.$caname.'/';
+    if (($caname ne '') && ($cadom ne '')) {
+        return "/priv/$cadom/$caname/";
+    }
+    return;
 }
 
 ##############################################
@@ -4456,7 +4632,7 @@ Returns: HTML div with $content
 sub head_subbox {
     my ($content)=@_;
     my $output =
-        '<div id="LC_head_subbox">'
+        '<div class="LC_head_subbox">'
        .$content
        .'</div>'
 }
@@ -4466,7 +4642,9 @@ sub head_subbox {
 
 =item * &CSTR_pageheader()
 
-Inputs: ./.
+Input: (optional) filename from which breadcrumb trail is built.
+       In most cases no input as needed, as $env{'request.filename'}
+       is appropriate for use in building the breadcrumb trail.
 
 Returns: HTML div with CSTR path and recent box
          To be included on Construction Space pages
@@ -4474,12 +4652,19 @@ Returns: HTML div with CSTR path and rec
 =cut
 
 sub CSTR_pageheader {
-    # this is for resources; directories have customtitle, and crumbs
-            # and select recent are created in lonpubdir.pm  
-    my ($uname,$thisdisfn)=
-        ($env{'request.filename'} =~ m|^/home/([^/]+)/public_html/(.*)|);
-    my $formaction='/priv/'.$uname.'/'.$thisdisfn;
-    $formaction=~s/\/+/\//g;
+    my ($trailfile) = @_;
+    if ($trailfile eq '') {
+        $trailfile = $env{'request.filename'};
+    }
+
+# this is for resources; directories have customtitle, and crumbs
+# and select recent are created in lonpubdir.pm
+
+    my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
+    my ($udom,$uname,$thisdisfn)=
+        ($trailfile =~ m{^\Q$londocroot\E/priv/([^/]+)/([^/]+)/(.*)$});
+    my $formaction = "/priv/$udom/$uname/$thisdisfn";
+    $formaction =~ s{/+}{/}g;
 
     my $parentpath = '';
     my $lastitem = '';
@@ -4496,7 +4681,7 @@ sub CSTR_pageheader {
         .'<b>'.&mt('Construction Space:').'</b> '
         .'<form name="dirs" method="post" action="'.$formaction
         .'" target="_top">' #FIXME lonpubdir: target="_parent"
-        .&Apache::lonhtmlcommon::crumbs($uname.'/'.$parentpath,'_top','/priv',undef,undef);
+        .&Apache::lonhtmlcommon::crumbs($uname.'/'.$parentpath,'_top','/priv/'.$udom,undef,undef);
 
     if ($lastitem) {
         $output .=
@@ -4702,7 +4887,7 @@ sub bodytag {
 
 sub dc_courseid_toggle {
     my ($dc_info) = @_;
-    return ' <span id="dccidtext" class="LC_cusr_subheading">'.
+    return ' <span id="dccidtext" class="LC_cusr_subheading LC_nobreak">'.
            '<a href="javascript:showCourseID();">'.
            &mt('(More ...)').'</a></span>'.
            '<div id="dccid" class="LC_dccid">'.$dc_info.'</div>';
@@ -4895,6 +5080,10 @@ form, .inline {
   text-decoration:none;
 }
 
+.LC_setting {
+  text-decoration:underline;
+}
+
 .LC_error {
   color: red;
   font-size: larger;
@@ -5059,14 +5248,16 @@ td.LC_table_cell_checkbox {
   overflow: hidden;
   margin: 0;
   padding: 0;
+  text-align: left;
 }
 
-#LC_head_subbox {
+.LC_head_subbox {
   clear:both;
   background: #F8F8F8; /* $sidebg; */
   border: 1px solid $sidebg;
   margin: 0 0 10px 0;      
   padding: 3px;
+  text-align: left;
 }
 
 .LC_fontsize_medium {
@@ -5089,6 +5280,7 @@ td.LC_table_cell_checkbox {
 
 li.LC_menubuttons_inline_text img,a {
   cursor:pointer;
+  text-decoration: none;
 }
 
 .LC_menubuttons_link {
@@ -5136,14 +5328,6 @@ table.LC_nested {
   width: 100%;
 }
 
-.ui-accordion,
-.ui-accordion table.LC_data_table,
-.ui-accordion table.LC_nested_outer{
-  border: 0px;
-  border-spacing: 0px;
-  margin: 3px;
-}
-
 table.LC_data_table tr th,
 table.LC_calendar tr th,
 table.LC_prior_tries tr th,
@@ -5259,22 +5443,6 @@ table.LC_nested tr td.LC_right_item {
   text-align: right;
 }
 
-.ui-accordion table.LC_nested tr.LC_odd_row td.LC_left_item,
-.ui-accordion table.LC_nested tr.LC_even_row td.LC_left_item {
-  text-align: right;
-  width: 40%;
-  padding-right:10px;
-  vertical-align: top;
-  padding: 5px;
-}
-
-.ui-accordion table.LC_nested tr.LC_odd_row td.LC_right_item,
-.ui-accordion table.LC_nested tr.LC_even_row td.LC_right_item {
-  text-align: left;
-  width: 60%;
-  padding: 2px 4px;
-}
-
 table.LC_nested tr.LC_odd_row td {
   background-color: #EEEEEE;
 }
@@ -5406,6 +5574,11 @@ span.LC_current_location {
   background: $pgbg;
 }
 
+span.LC_current_nav_location {
+  font-weight:bold;
+  background: $sidebg;
+}
+
 span.LC_parm_menu_item {
   font-size: larger;
 }
@@ -5433,6 +5606,14 @@ span.LC_parm_symb {
   color: #AAAAAA;
 }
 
+ul.LC_parm_parmlist li {
+  display: inline-block;
+  padding: 0.3em 0.8em;
+  vertical-align: top;
+  width: 150px;
+  border-top:1px solid $lg_border_color;
+}
+
 td.LC_parm_overview_level_menu,
 td.LC_parm_overview_map_menu,
 td.LC_parm_overview_parm_selectors,
@@ -6026,6 +6207,7 @@ fieldset > legend {
 
 #LC_nav_bar {
   float: left;
+  background-color: $pgbg_or_bgcolor;
   margin: 0 0 2px 0;
 }
 
@@ -6034,6 +6216,7 @@ fieldset > legend {
   padding: 0;
   font-weight: bold;
   text-align: center;
+  background-color: $pgbg_or_bgcolor;
 }
 
 #LC_nav_bar em {
@@ -6041,14 +6224,10 @@ fieldset > legend {
   font-style: normal;
 }
 
-/* Preliminary fix to hide nav_bar inside bookmarks window */
-#LC_bookmarks #LC_nav_bar {
-  display:none;
-}
-
 ol.LC_primary_menu {
   float: right;
   margin: 0;
+  background-color: $pgbg_or_bgcolor;
 }
 
 ol#LC_PathBreadcrumbs {
@@ -6076,6 +6255,30 @@ ol.LC_primary_menu a.LC_new_message {
   color: darkred;
 }
 
+ol.LC_docs_parameters {
+  margin-left: 0;
+  padding: 0;
+  list-style: none;
+}
+
+ol.LC_docs_parameters li {
+  margin: 0;
+  padding-right: 20px;
+  display: inline;
+}
+
+ol.LC_docs_parameters li:before {
+  content: "\\002022 \\0020";
+}
+
+li.LC_docs_parameters_title {
+  font-weight: bold;
+}
+
+ol.LC_docs_parameters li.LC_docs_parameters_title:before {
+  content: "";
+}
+
 ul#LC_secondary_menu {
   clear: both;
   color: $fontmenu;
@@ -6084,6 +6287,7 @@ ul#LC_secondary_menu {
   padding: 0;
   margin: 0;
   width: 100%;
+  text-align: left;
 }
 
 ul#LC_secondary_menu li {
@@ -6100,7 +6304,7 @@ ul.LC_TabContent {
   background: $sidebg;
   border-bottom: solid 1px $lg_border_color;
   list-style:none;
-  margin: 0 -10px;
+  margin: -1px -10px 0 -10px;
   padding: 0;
 }
 
@@ -6123,7 +6327,7 @@ ul.LC_TabContent li {
   padding: 0 16px 0 10px;
   background-color:$tabbg;
   border-bottom:solid 1px $lg_border_color;
-  border-right: solid 1px $font;
+  border-left: solid 1px $font;
 }
 
 ul.LC_TabContent .right {
@@ -6163,6 +6367,12 @@ ul.LC_TabContent li.active a {
   background:#FFFFFF;
   outline: none;
 }
+
+ul.LC_TabContent li.goback {
+  float: left;
+  border-left: none;
+}
+
 #maincoursedoc {
   clear:both;
 }
@@ -6217,17 +6427,15 @@ ul.LC_TabContentBigger li.active b {
   background:url('/adm/lonIcons/tabbgright.gif') right top no-repeat;
   color:$font;
   border: 0;
-  cursor:default;
 }
 
 
 ul.LC_CourseBreadcrumbs {
   background: $sidebg;
-  line-height: 32px;
+  height: 2em;
   padding-left: 10px;
-  margin: 0 0 10px 0;
+  margin: 0;
   list-style-position: inside;
-
 }
 
 ol#LC_MenuBreadcrumbs,
@@ -6269,6 +6477,11 @@ ol#LC_PathBreadcrumbs li a {
   padding: 0 10px 10px 10px;
 }
 
+.LC_DocsBox {
+  border: solid 1px $lg_border_color;
+  padding: 0 0 10px 10px;
+}
+
 .LC_AboutMe_Image {
   float:left;
   margin-right:10px;
@@ -6409,6 +6622,10 @@ a#LC_content_toolbar_changefolder_toggle
   background-image:url(/res/adm/pages/open-all-folders.gif);
 }
 
+a#LC_content_toolbar_edittoplevel {
+  background-image:url(/res/adm/pages/edittoplevel.gif);
+}
+
 ul#LC_toolbar li a:hover {
   background-position: bottom center;
 }
@@ -6473,10 +6690,55 @@ ul.LC_funclist li {
   line-height: 150%;
 }
 
-.ui-accordion .LC_advanced_toggle {
-  float: right;
-  font-size: 90%;
-  padding: 0px 4px
+.LC_hidden {
+  display: none;
+}
+
+.LCmodal-overlay {
+		position:fixed;
+		top:0;
+		right:0;
+		bottom:0;
+		left:0;
+		height:100%;
+		width:100%;
+		margin:0;
+		padding:0;
+		background:#999;
+		opacity:.75;
+		filter: alpha(opacity=75);
+		-moz-opacity: 0.75;
+		z-index:101;
+}
+
+* html .LCmodal-overlay {   
+		position: absolute;
+		height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px');
+}
+
+.LCmodal-window {
+		position:fixed;
+		top:50%;
+		left:50%;
+		margin:0;
+		padding:0;
+		z-index:102;
+	}
+
+* html .LCmodal-window {
+		position:absolute;
+}
+
+.LCclose-window {
+		position:absolute;
+		width:32px;
+		height:32px;
+		right:8px;
+		top:8px;
+		background:transparent url('/res/adm/pages/process-stop.png') no-repeat scroll right top;
+		text-indent:-99999px;
+		overflow:hidden;
+		cursor:pointer;
 }
 
 END
@@ -6537,8 +6799,24 @@ sub headtag {
 	&& !$args->{'only_body'}
 	&& !$args->{'frameset'}) {
 	$result .= &help_menu_js();
+        $result.=&modal_window();
+        $result.=&togglebox_script();
+        $result.=&wishlist_window();
+        $result.=&LCprogressbarUpdate_script();
+    } else {
+        if ($args->{'add_modal'}) {
+           $result.=&modal_window();
+        }
+        if ($args->{'add_wishlist'}) {
+           $result.=&wishlist_window();
+        }
+        if ($args->{'add_togglebox'}) {
+           $result.=&togglebox_script();
+        }
+        if ($args->{'add_progressbar'}) {
+           $result.=&LCprogressbarUpdate_script();
+        }
     }
-
     if (ref($args->{'redirect'})) {
 	my ($time,$url,$inhibit_continue) = @{$args->{'redirect'}};
 	$url = &Apache::lonenc::check_encrypt($url);
@@ -6652,7 +6930,7 @@ $args - additional optional args support
                                     should it have jsmath forced on by the
                                     current page
              bread_crumbs ->             Array containing breadcrumbs
-             bread_crumbs_components ->  if exists show it as headline else show only the breadcrumbs
+             bread_crumbs_component ->  if exists show it as headline else show only the breadcrumbs
 
 =back
 
@@ -6663,32 +6941,12 @@ $args - additional optional args support
 sub start_page {
     my ($title,$head_extra,$args) = @_;
     #&Apache::lonnet::logthis("start_page ".join(':',caller(0)));
-#SD
-#I don't see why we copy certain elements of %$args to %head_args
-#head args is passed to headtag() and this routine only reads those
-#keys that are needed. There doesn't happen any writes or any processing
-#of other keys.
-#proposal: just pass $args to headtag instead of \%head_args and delete 
-#marked lines
-#<- MARK
-    my %head_args;
-    foreach my $arg ('redirect','force_register','domain','function',
-		     'bgcolor','frameset','no_nav_bar','only_body',
-		     'no_auto_mt_title') {
-	if (defined($args->{$arg})) {
-	    $head_args{$arg} = $args->{$arg};
-	}
-    }
-#MARK ->
 
     $env{'internal.start_page'}++;
     my $result;
 
     if (! exists($args->{'skip_phases'}{'head'}) ) {
-        $result .= 
-                  &xml_begin() . &headtag($title,$head_extra,\%head_args);
-#replace prev line by
-#                 &xml_begin() . &headtag($title, $head_extra, $args);
+        $result .= &xml_begin() . &headtag($title, $head_extra, $args);
     }
     
     if (! exists($args->{'skip_phases'}{'body'}) ) {
@@ -6754,7 +7012,6 @@ sub end_page {
 	}
 	$result .= &Apache::lonxml::xmlend($target,$parser);
     }
-
     if ($args->{'frameset'}) {
 	$result .= '</frameset>';
     } else {
@@ -6773,6 +7030,281 @@ sub end_page {
     return $result;
 }
 
+sub wishlist_window {
+    return(<<'ENDWISHLIST');
+<script type="text/javascript">
+// <![CDATA[
+// <!-- BEGIN LON-CAPA Internal
+function set_wishlistlink(title, path) {
+    if (!title) {
+        title = document.title;
+        title = title.replace(/^LON-CAPA /,'');
+    }
+    if (!path) {
+        path = location.pathname;
+    }
+    Win = window.open('/adm/wishlist?mode=newLink&setTitle='+title+'&setPath='+path,
+                      'wishlistNewLink','width=560,height=350,scrollbars=0');
+}
+// END LON-CAPA Internal -->
+// ]]>
+</script>
+ENDWISHLIST
+}
+
+sub modal_window {
+    return(<<'ENDMODAL');
+<script type="text/javascript">
+// <![CDATA[
+// <!-- BEGIN LON-CAPA Internal
+var modalWindow = {
+	parent:"body",
+	windowId:null,
+	content:null,
+	width:null,
+	height:null,
+	close:function()
+	{
+	        $(".LCmodal-window").remove();
+	        $(".LCmodal-overlay").remove();
+	},
+	open:function()
+	{
+		var modal = "";
+		modal += "<div class=\"LCmodal-overlay\"></div>";
+		modal += "<div id=\"" + this.windowId + "\" class=\"LCmodal-window\" style=\"width:" + this.width + "px; height:" + this.height + "px; margin-top:-" + (this.height / 2) + "px; margin-left:-" + (this.width / 2) + "px;\">";
+		modal += this.content;
+		modal += "</div>";	
+
+		$(this.parent).append(modal);
+
+		$(".LCmodal-window").append("<a class=\"LCclose-window\"></a>");
+		$(".LCclose-window").click(function(){modalWindow.close();});
+		$(".LCmodal-overlay").click(function(){modalWindow.close();});
+	}
+};
+	var openMyModal = function(source,width,height,scrolling)
+	{
+		modalWindow.windowId = "myModal";
+		modalWindow.width = width;
+		modalWindow.height = height;
+		modalWindow.content = "<iframe width='"+width+"' height='"+height+"' frameborder='0' scrolling='"+scrolling+"' allowtransparency='true' src='" + source + "'>&lt/iframe>";
+		modalWindow.open();
+	};	
+// END LON-CAPA Internal -->
+// ]]>
+</script>
+ENDMODAL
+}
+
+sub modal_link {
+    my ($link,$linktext,$width,$height,$target,$scrolling)=@_;
+    unless ($width) { $width=480; }
+    unless ($height) { $height=400; }
+    unless ($scrolling) { $scrolling='yes'; }
+    return '<a href="'.$link.'" target="'.$target.'" onclick="openMyModal(\''.$link.'\','.$width.','.$height.',\''.$scrolling.'\'); return false;">'.
+           $linktext.'</a>';
+}
+
+sub modal_adhoc_script {
+    my ($funcname,$width,$height,$content)=@_;
+    return (<<ENDADHOC);
+<script type="text/javascript">
+// <![CDATA[
+        var $funcname = function()
+        {
+                modalWindow.windowId = "myModal";
+                modalWindow.width = $width;
+                modalWindow.height = $height;
+                modalWindow.content = '$content';
+                modalWindow.open();
+        };  
+// ]]>
+</script>
+ENDADHOC
+}
+
+sub modal_adhoc_inner {
+    my ($funcname,$width,$height,$content)=@_;
+    my $innerwidth=$width-20;
+    $content=&js_ready(
+               &start_page('Dialog',undef,{'only_body'=>1,'bgcolor'=>'#FFFFFF'}).
+                 &start_scrollbox($width.'px',$innerwidth.'px',$height.'px').
+                    $content.
+                 &end_scrollbox().
+               &end_page()
+             );
+    return &modal_adhoc_script($funcname,$width,$height,$content);
+}
+
+sub modal_adhoc_window {
+    my ($funcname,$width,$height,$content,$linktext)=@_;
+    return &modal_adhoc_inner($funcname,$width,$height,$content).
+           "<a href=\"javascript:$funcname();void(0);\">".$linktext."</a>";
+}
+
+sub modal_adhoc_launch {
+    my ($funcname,$width,$height,$content)=@_;
+    return &modal_adhoc_inner($funcname,$width,$height,$content).(<<ENDLAUNCH);
+<script type="text/javascript">
+// <![CDATA[
+$funcname();
+// ]]>
+</script>
+ENDLAUNCH
+}
+
+sub modal_adhoc_close {
+    return (<<ENDCLOSE);
+<script type="text/javascript">
+// <![CDATA[
+modalWindow.close();
+// ]]>
+</script>
+ENDCLOSE
+}
+
+sub togglebox_script {
+   return(<<ENDTOGGLE);
+<script type="text/javascript"> 
+// <![CDATA[
+function LCtoggleDisplay(id,hidetext,showtext) {
+   link = document.getElementById(id + "link").childNodes[0];
+   with (document.getElementById(id).style) {
+      if (display == "none" ) {
+          display = "inline";
+          link.nodeValue = hidetext;
+        } else {
+          display = "none";
+          link.nodeValue = showtext;
+       }
+   }
+}
+// ]]>
+</script>
+ENDTOGGLE
+}
+
+sub start_togglebox {
+    my ($id,$heading,$headerbg,$hidetext,$showtext)=@_;
+    unless ($heading) { $heading=''; } else { $heading.=' '; }
+    unless ($showtext) { $showtext=&mt('show'); }
+    unless ($hidetext) { $hidetext=&mt('hide'); }
+    unless ($headerbg) { $headerbg='#FFFFFF'; }
+    return &start_data_table().
+           &start_data_table_header_row().
+           '<td bgcolor="'.$headerbg.'">'.$heading.
+           '[<a id="'.$id.'link" href="javascript:LCtoggleDisplay(\''.$id.'\',\''.$hidetext.'\',\''.
+           $showtext.'\')">'.$showtext.'</a>]</td>'.
+           &end_data_table_header_row().
+           '<tr id="'.$id.'" style="display:none""><td>';
+}
+
+sub end_togglebox {
+    return '</td></tr>'.&end_data_table();
+}
+
+sub LCprogressbar_script {
+   my ($id)=@_;
+   return(<<ENDPROGRESS);
+<script type="text/javascript">
+// <![CDATA[
+\$('#progressbar$id').progressbar({
+  value: 0,
+  change: function(event, ui) {
+    var newVal = \$(this).progressbar('option', 'value');
+    \$('.pblabel', this).text(LCprogressTxt);
+  }
+});
+// ]]>
+</script>
+ENDPROGRESS
+}
+
+sub LCprogressbarUpdate_script {
+   return(<<ENDPROGRESSUPDATE);
+<style type="text/css">
+.ui-progressbar { position:relative; }
+.pblabel { position: absolute; width: 100%; text-align: center; line-height: 1.9em; }
+</style>
+<script type="text/javascript">
+// <![CDATA[
+var LCprogressTxt='---';
+
+function LCupdateProgress(percent,progresstext,id) {
+   LCprogressTxt=progresstext;
+   \$('#progressbar'+id).progressbar('value',percent);
+}
+// ]]>
+</script>
+ENDPROGRESSUPDATE
+}
+
+my $LClastpercent;
+my $LCidcnt;
+my $LCcurrentid;
+
+sub LCprogressbar {
+    my ($r)=(@_);
+    $LClastpercent=0;
+    $LCidcnt++;
+    $LCcurrentid=$$.'_'.$LCidcnt;
+    my $starting=&mt('Starting');
+    my $content=(<<ENDPROGBAR);
+<p>
+  <div id="progressbar$LCcurrentid">
+    <span class="pblabel">$starting</span>
+  </div>
+</p>
+ENDPROGBAR
+    &r_print($r,$content.&LCprogressbar_script($LCcurrentid));
+}
+
+sub LCprogressbarUpdate {
+    my ($r,$val,$text)=@_;
+    unless ($val) { 
+       if ($LClastpercent) {
+           $val=$LClastpercent;
+       } else {
+           $val=0;
+       }
+    }
+    if ($val<0) { $val=0; }
+    if ($val>100) { $val=0; }
+    $LClastpercent=$val;
+    unless ($text) { $text=$val.'%'; }
+    $text=&js_ready($text);
+    &r_print($r,<<ENDUPDATE);
+<script type="text/javascript">
+// <![CDATA[
+LCupdateProgress($val,'$text','$LCcurrentid');
+// ]]>
+</script>
+ENDUPDATE
+}
+
+sub LCprogressbarClose {
+    my ($r)=@_;
+    $LClastpercent=0;
+    &r_print($r,<<ENDCLOSE);
+<script type="text/javascript">
+// <![CDATA[
+\$("#progressbar$LCcurrentid").hide('slow'); 
+// ]]>
+</script>
+ENDCLOSE
+}
+
+sub r_print {
+    my ($r,$to_print)=@_;
+    if ($r) {
+      $r->print($to_print);
+      $r->rflush();
+    } else {
+      print($to_print);
+    }
+}
+
 sub html_encode {
     my ($result) = @_;
 
@@ -6780,6 +7312,7 @@ sub html_encode {
     
     return $result;
 }
+
 sub js_ready {
     my ($result) = @_;
 
@@ -6816,6 +7349,24 @@ sub validate_page {
     }
 }
 
+
+sub start_scrollbox {
+    my ($outerwidth,$width,$height,$id)=@_;
+    unless ($outerwidth) { $outerwidth='520px'; }
+    unless ($width) { $width='500px'; }
+    unless ($height) { $height='200px'; }
+    my ($table_id,$div_id);
+    if ($id ne '') {
+        $table_id = " id='table_$id'";
+        $div_id = " id='div_$id'";
+    }
+    return "<table style='width: $outerwidth; border: 1px solid none;'$table_id><tr><td style='width: $width;' bgcolor='#FFFFFF'><div style='overflow:auto; width:$width; height: $height;'$div_id>";
+}
+
+sub end_scrollbox {
+    return '</div></td></tr></table>';
+}
+
 sub simple_error_page {
     my ($r,$title,$msg) = @_;
     my $page =
@@ -6843,10 +7394,14 @@ sub simple_error_page {
     }
 
     sub start_data_table {
-	my ($add_class) = @_;
+	my ($add_class,$id) = @_;
 	my $css_class = (join(' ','LC_data_table',$add_class));
+        my $table_id;
+        if (defined($id)) {
+            $table_id = ' id="'.$id.'"';
+        }
 	&start_data_table_count();
-	return '<table class="'.$css_class.'">'."\n";
+	return '<table class="'.$css_class.'"'.$table_id.'>'."\n";
     }
 
     sub end_data_table {
@@ -6855,18 +7410,20 @@ sub simple_error_page {
     }
 
     sub start_data_table_row {
-	my ($add_class) = @_;
+	my ($add_class, $id) = @_;
 	$row_count[0]++;
 	my $css_class = ($row_count[0] % 2)?'LC_odd_row':'LC_even_row';
 	$css_class = (join(' ',$css_class,$add_class)) unless ($add_class eq '');
-	return  '<tr class="'.$css_class.'">'."\n";;
+        $id = (' id="'.$id.'"') unless ($id eq '');
+        return  '<tr class="'.$css_class.'"'.$id.'>'."\n";
     }
     
     sub continue_data_table_row {
-	my ($add_class) = @_;
+	my ($add_class, $id) = @_;
 	my $css_class = ($row_count[0] % 2)?'LC_odd_row':'LC_even_row';
-	$css_class = (join(' ',$css_class,$add_class)) unless ($add_class eq '');;
-	return  '<tr class="'.$css_class.'">'."\n";;
+	$css_class = (join(' ',$css_class,$add_class)) unless ($add_class eq '');
+        $id = (' id="'.$id.'"') unless ($id eq '');
+        return  '<tr class="'.$css_class.'"'.$id.'>'."\n";
     }
 
     sub end_data_table_row {
@@ -6971,7 +7528,7 @@ sub get_users_function {
         $function='admin';
     }
     if (($env{'request.role'}=~/^(au|ca|aa)/) ||
-        ($ENV{'REQUEST_URI'}=~/^(\/priv|\~)/)) {
+        ($ENV{'REQUEST_URI'}=~ m{/^(/priv)})) {
         $function='author';
     }
     return $function;
@@ -7029,7 +7586,8 @@ role status: active, previous or future.
 
 sub check_user_status {
     my ($udom,$uname,$cdom,$crs,$role,$sec) = @_;
-    my %userinfo = &Apache::lonnet::dump('roles',$udom,$uname);
+    my $extra = &Apache::lonnet::freeze_escape({'skipcheck' => 1});
+    my %userinfo = &Apache::lonnet::dump('roles',$udom,$uname,'.',undef,$extra);
     my @uroles = keys %userinfo;
     my $srchstr;
     my $active_chk = 'none';
@@ -7612,7 +8170,7 @@ sub get_secgrprole_info {
 }
 
 sub user_picker {
-    my ($dom,$srch,$forcenewuser,$caller,$cancreate,$usertype) = @_;
+    my ($dom,$srch,$forcenewuser,$caller,$cancreate,$usertype,$context) = @_;
     my $currdom = $dom;
     my %curr_selected = (
                         srchin => 'dom',
@@ -7703,10 +8261,15 @@ sub user_picker {
     $srchtypesel .= "\n  </select>\n";
 
     my ($newuserscript,$new_user_create);
-
+    my $context_dom = $env{'request.role.domain'};
+    if ($context eq 'requestcrs') {
+        if ($env{'form.coursedom'} ne '') { 
+            $context_dom = $env{'form.coursedom'};
+        }
+    }
     if ($forcenewuser) {
         if (ref($srch) eq 'HASH') {
-            if ($srch->{'srchby'} eq 'uname' && $srch->{'srchtype'} eq 'exact' && $srch->{'srchin'} eq 'dom' && $srch->{'srchdomain'} eq $env{'request.role.domain'}) {
+            if ($srch->{'srchby'} eq 'uname' && $srch->{'srchtype'} eq 'exact' && $srch->{'srchin'} eq 'dom' && $srch->{'srchdomain'} eq $context_dom) {
                 if ($cancreate) {
                     $new_user_create = '<p> <input type="submit" name="forcenew" value="'.&HTML::Entities::encode(&mt('Make new user "[_1]"',$srchterm),'<>&"').'" onclick="javascript:setSearch(\'1\','.$caller.');" /> </p>';
                 } else {
@@ -7745,7 +8308,7 @@ function setSearch(createnew,callingForm
             }
         }
         for (var i=0; i<callingForm.srchdomain.length; i++) {
-            if (callingForm.srchdomain.options[i].value == '$env{'request.role.domain'}') {
+            if (callingForm.srchdomain.options[i].value == '$context_dom') {
                 callingForm.srchdomain.selectedIndex = i;
             }
         }
@@ -8080,7 +8643,8 @@ sub get_standard_codeitems {
 
 =item * sorted_slots()
 
-Sorts an array of slot names in order of slot start time (earliest first). 
+Sorts an array of slot names in order of an optional sort key,
+default sort is by slot start time (earliest first). 
 
 Inputs:
 
@@ -8090,15 +8654,16 @@ slotsarr  - Reference to array of unsort
 
 slots     - Reference to hash of hash, where outer hash keys are slot names.
 
+sortkey   - Name of key in inner hash to be sorted on (e.g., starttime).
+
 =back
 
 Returns:
 
 =over 4
 
-sorted   - An array of slot names sorted by the start time of the slot.
-
-=back
+sorted   - An array of slot names sorted by a specified sort key 
+           (default sort key is start time of the slot).
 
 =back
 
@@ -8106,13 +8671,16 @@ sorted   - An array of slot names sorted
 
 
 sub sorted_slots {
-    my ($slotsarr,$slots) = @_;
+    my ($slotsarr,$slots,$sortkey) = @_;
+    if ($sortkey eq '') {
+        $sortkey = 'starttime';
+    }
     my @sorted;
     if ((ref($slotsarr) eq 'ARRAY') && (ref($slots) eq 'HASH')) {
         @sorted =
             sort {
                      if (ref($slots->{$a}) && ref($slots->{$b})) {
-                         return $slots->{$a}{'starttime'} <=> $slots->{$b}{'starttime'}
+                         return $slots->{$a}{$sortkey} <=> $slots->{$b}{$sortkey}
                      }
                      if (ref($slots->{$a})) { return -1;}
                      if (ref($slots->{$b})) { return 1;}
@@ -8122,6 +8690,131 @@ sub sorted_slots {
     return @sorted;
 }
 
+=pod
+
+=item * get_future_slots()
+
+Inputs:
+
+=over 4
+
+cnum - course number
+
+cdom - course domain
+
+now - current UNIX time
+
+symb - optional symb
+
+=back
+
+Returns:
+
+=over 4
+
+sorted_reservable - ref to array of student_schedulable slots currently 
+                    reservable, ordered by end date of reservation period.
+
+reservable_now - ref to hash of student_schedulable slots currently
+                 reservable.
+
+    Keys in inner hash are:
+    (a) symb: either blank or symb to which slot use is restricted.
+    (b) endreserve: end date of reservation period. 
+
+sorted_future - ref to array of student_schedulable slots reservable in
+                the future, ordered by start date of reservation period.
+
+future_reservable - ref to hash of student_schedulable slots reservable
+                    in the future.
+
+    Keys in inner hash are:
+    (a) symb: either blank or symb to which slot use is restricted.
+    (b) startreserve:  start date of reservation period.
+
+=back
+
+=cut
+
+sub get_future_slots {
+    my ($cnum,$cdom,$now,$symb) = @_;
+    my (%reservable_now,%future_reservable,@sorted_reservable,@sorted_future);
+    my %slots = &Apache::lonnet::get_course_slots($cnum,$cdom);
+    foreach my $slot (keys(%slots)) {
+        next unless($slots{$slot}->{'type'} eq 'schedulable_student');
+        if ($symb) {
+            next if (($slots{$slot}->{'symb'} ne '') && 
+                     ($slots{$slot}->{'symb'} ne $symb));
+        }
+        if (($slots{$slot}->{'starttime'} > $now) &&
+            ($slots{$slot}->{'endtime'} > $now)) {
+            if (($slots{$slot}->{'allowedsections'}) || ($slots{$slot}->{'allowedusers'})) {
+                my $userallowed = 0;
+                if ($slots{$slot}->{'allowedsections'}) {
+                    my @allowed_sec = split(',',$slots{$slot}->{'allowedsections'});
+                    if (!defined($env{'request.role.sec'})
+                        && grep(/^No section assigned$/,@allowed_sec)) {
+                        $userallowed=1;
+                    } else {
+                        if (grep(/^\Q$env{'request.role.sec'}\E$/,@allowed_sec)) {
+                            $userallowed=1;
+                        }
+                    }
+                    unless ($userallowed) {
+                        if (defined($env{'request.course.groups'})) {
+                            my @groups = split(/:/,$env{'request.course.groups'});
+                            foreach my $group (@groups) {
+                                if (grep(/^\Q$group\E$/,@allowed_sec)) {
+                                    $userallowed=1;
+                                    last;
+                                }
+                            }
+                        }
+                    }
+                }
+                if ($slots{$slot}->{'allowedusers'}) {
+                    my @allowed_users = split(',',$slots{$slot}->{'allowedusers'});
+                    my $user = $env{'user.name'}.':'.$env{'user.domain'};
+                    if (grep(/^\Q$user\E$/,@allowed_users)) {
+                        $userallowed = 1;
+                    }
+                }
+                next unless($userallowed);
+            }
+            my $startreserve = $slots{$slot}->{'startreserve'};
+            my $endreserve = $slots{$slot}->{'endreserve'};
+            my $symb = $slots{$slot}->{'symb'};
+            if (($startreserve < $now) &&
+                (!$endreserve || $endreserve > $now)) {
+                my $lastres = $endreserve;
+                if (!$lastres) {
+                    $lastres = $slots{$slot}->{'starttime'};
+                }
+                $reservable_now{$slot} = {
+                                           symb       => $symb,
+                                           endreserve => $lastres
+                                         };
+            } elsif (($startreserve > $now) &&
+                     (!$endreserve || $endreserve > $startreserve)) {
+                $future_reservable{$slot} = {
+                                              symb         => $symb,
+                                              startreserve => $startreserve
+                                            };
+            }
+        }
+    }
+    my @unsorted_reservable = keys(%reservable_now);
+    if (@unsorted_reservable > 0) {
+        @sorted_reservable = 
+            &sorted_slots(\@unsorted_reservable,\%reservable_now,'endreserve');
+    }
+    my @unsorted_future = keys(%future_reservable);
+    if (@unsorted_future > 0) {
+        @sorted_future =
+            &sorted_slots(\@unsorted_future,\%future_reservable,'startreserve');
+    }
+    return (\@sorted_reservable,\%reservable_now,\@sorted_future,\%future_reservable);
+}
 
 =pod
 
@@ -8263,68 +8956,313 @@ sub get_env_multiple {
 
 sub ask_for_embedded_content {
     my ($actionurl,$state,$allfiles,$codebase,$args)=@_;
-    my $upload_output = '
-   <form name="upload_embedded" action="'.$actionurl.'"
-                  method="post" enctype="multipart/form-data">';
-    $upload_output .= $state;
-    $upload_output .= '<b>Upload embedded files</b>:<br />'.&start_data_table();
-
+    my (%subdependencies,%dependencies,%mapping,%existing,%newfiles,%pathchanges);
     my $num = 0;
-    foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%{$allfiles})) {
+    my $numremref = 0;
+    my $numinvalid = 0;
+    my $numpathchg = 0;
+    my $numexisting = 0;
+    my ($output,$upload_output,$toplevel,$url,$udom,$uname,$getpropath);
+    if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) {
+        my $current_path='/';
+        if ($env{'form.currentpath'}) {
+            $current_path = $env{'form.currentpath'};
+        }
+        if ($actionurl eq '/adm/coursegrp_portfolio') {
+            $udom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+            $uname = $env{'course.'.$env{'request.course.id'}.'.num'};
+            $url = '/userfiles/groups/'.$env{'form.group'}.'/portfolio';
+        } else {
+            $udom = $env{'user.domain'};
+            $uname = $env{'user.name'};
+            $url = '/userfiles/portfolio';
+        }
+        $toplevel = $url.'/';
+        $url .= $current_path;
+        $getpropath = 1;
+    } elsif (($actionurl eq '/adm/upload') || ($actionurl eq '/adm/testbank') ||
+             ($actionurl eq '/adm/imsimport')) { 
+        my ($udom,$uname,$rest) = ($args->{'current_path'} =~ m{/priv/($match_domain)/($match_username)/?(.*)$});
+        $url = $Apache::lonnet::perlvar{'lonDocRoot'}."/priv/$udom/$uname/";
+        $toplevel = $url;
+        if ($rest ne '') {
+            $url .= $rest;
+        }
+    } elsif ($actionurl eq '/adm/coursedocs') {
+        if (ref($args) eq 'HASH') {
+           $url = $args->{'docs_url'};
+           $toplevel = $url;
+        }
+    }
+    my $now = time();
+    foreach my $embed_file (keys(%{$allfiles})) {
+        my $absolutepath;
+        if ($embed_file =~ m{^\w+://}) {
+            $newfiles{$embed_file} = 1;
+            $mapping{$embed_file} = $embed_file;
+        } else {
+            if ($embed_file =~ m{^/}) {
+                $absolutepath = $embed_file;
+                $embed_file =~ s{^(/+)}{};
+            }
+            if ($embed_file =~ m{/}) {
+                my ($path,$fname) = ($embed_file =~ m{^(.+)/([^/]*)$});
+                $path = &check_for_traversal($path,$url,$toplevel);
+                my $item = $fname;
+                if ($path ne '') {
+                    $item = $path.'/'.$fname;
+                    $subdependencies{$path}{$fname} = 1;
+                } else {
+                    $dependencies{$item} = 1;
+                }
+                if ($absolutepath) {
+                    $mapping{$item} = $absolutepath;
+                } else {
+                    $mapping{$item} = $embed_file;
+                }
+            } else {
+                $dependencies{$embed_file} = 1;
+                if ($absolutepath) {
+                    $mapping{$embed_file} = $absolutepath;
+                } else {
+                    $mapping{$embed_file} = $embed_file;
+                }
+            }
+        }
+    }
+    foreach my $path (keys(%subdependencies)) {
+        my %currsubfile;
+        if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) { 
+            my ($sublistref,$listerror) =
+                &Apache::lonnet::dirlist($url.$path,$udom,$uname,$getpropath);
+            if (ref($sublistref) eq 'ARRAY') {
+                foreach my $line (@{$sublistref}) {
+                    my ($file_name,$rest) = split(/\&/,$line,2);
+                    $currsubfile{$file_name} = 1;
+                }
+            }
+        } elsif (($actionurl eq '/adm/upload') || ($actionurl eq '/adm/testbank')) {
+            if (opendir(my $dir,$url.'/'.$path)) {
+                my @subdir_list = grep(!/^\./,readdir($dir));
+                map {$currsubfile{$_} = 1;} @subdir_list;
+            }
+        }
+        foreach my $file (keys(%{$subdependencies{$path}})) {
+            if ($currsubfile{$file}) {
+                my $item = $path.'/'.$file;
+                unless ($mapping{$item} eq $item) {
+                    $pathchanges{$item} = 1;
+                }
+                $existing{$item} = 1;
+                $numexisting ++;
+            } else {
+                $newfiles{$path.'/'.$file} = 1;
+            }
+        }
+    }
+    my %currfile;
+    if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) {
+        my ($dirlistref,$listerror) =
+            &Apache::lonnet::dirlist($url,$udom,$uname,$getpropath);
+        if (ref($dirlistref) eq 'ARRAY') {
+            foreach my $line (@{$dirlistref}) {
+                my ($file_name,$rest) = split(/\&/,$line,2);
+                $currfile{$file_name} = 1;
+            }
+        }
+    } elsif (($actionurl eq '/adm/upload') || ($actionurl eq '/adm/testbank')) {
+        if (opendir(my $dir,$url)) {
+            my @dir_list = grep(!/^\./,readdir($dir));
+            map {$currfile{$_} = 1;} @dir_list;
+        }
+    }
+    foreach my $file (keys(%dependencies)) {
+        if ($currfile{$file}) {
+            unless ($mapping{$file} eq $file) {
+                $pathchanges{$file} = 1;
+            }
+            $existing{$file} = 1;
+            $numexisting ++;
+        } else {
+            $newfiles{$file} = 1;
+        }
+    }
+    foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%newfiles)) {
         $upload_output .= &start_data_table_row().
-            '<td>'.$embed_file.'</td><td>';
+                          '<td><span class="LC_filename">'.$embed_file.'</span>';
+        unless ($mapping{$embed_file} eq $embed_file) {
+            $upload_output .= '<br /><span class="LC_info" style="font-size:smaller;">'.&mt('changed from: [_1]',$mapping{$embed_file}).'</span>';
+        }
+        $upload_output .= '</td><td>';
         if ($args->{'ignore_remote_references'}
             && $embed_file =~ m{^\w+://}) {
             $upload_output.='<span class="LC_warning">'.&mt("URL points to other server.").'</span>';
+            $numremref++;
         } elsif ($args->{'error_on_invalid_names'}
             && $embed_file ne &Apache::lonnet::clean_filename($embed_file,{'keep_path' => 1,})) {
 
-            $upload_output.='<span class="LC_warning">'.&mt("Invalid characters").'</span>';
-
+            $upload_output.='<span class="LC_warning">'.&mt('Invalid characters').'</span>';
+            $numinvalid++;
         } else {
-            $upload_output .='
-           <input name="embedded_item_'.$num.'" type="file" value="" />
-           <input name="embedded_orig_'.$num.'" type="hidden" value="'.&escape($embed_file).'" />';
-            my $attrib = join(':',@{$$allfiles{$embed_file}});
-            $upload_output .=
-                "\n\t\t".
-                '<input name="embedded_attrib_'.$num.'" type="hidden" value="'.
-                $attrib.'" />';
-            if (exists($$codebase{$embed_file})) {
-                $upload_output .=
-                    "\n\t\t".
-                    '<input name="codebase_'.$num.'" type="hidden" value="'.
-                    &escape($$codebase{$embed_file}).'" />';
-            }
-        }
-        $upload_output .= '</td>'.&Apache::loncommon::end_data_table_row();
-        $num++;
-    }
-    $upload_output .= &Apache::loncommon::end_data_table().'<br />
-   <input type ="hidden" name="number_embedded_items" value="'.$num.'" />
-   <input type ="submit" value="'.&mt('Upload Listed Files').'" />
-   '.&mt('(only files for which a location has been provided will be uploaded)').'
-   </form>';
-    return $upload_output;
+            $upload_output .= &embedded_file_element('upload_embedded',$num,
+                                                     $embed_file,\%mapping,
+                                                     $allfiles,$codebase);
+            $num++;
+        }
+        $upload_output .= '</td>'.&Apache::loncommon::end_data_table_row()."\n";
+    }
+    foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%existing)) {
+        $upload_output .= &start_data_table_row().
+                          '<td><span class="LC_filename">'.$embed_file.'</span></td>'.
+                          '<td><span class="LC_warning">'.&mt('Already exists').'</span></td>'.
+                          &Apache::loncommon::end_data_table_row()."\n";
+    }
+    if ($upload_output) {
+        $upload_output = &start_data_table().
+                         $upload_output.
+                         &end_data_table()."\n";
+    }
+    my $applies = 0;
+    if ($numremref) {
+        $applies ++;
+    }
+    if ($numinvalid) {
+        $applies ++;
+    }
+    if ($numexisting) {
+        $applies ++;
+    }
+    if ($num) {
+        $output = '<form name="upload_embedded" action="'.$actionurl.'"'.
+                  ' method="post" enctype="multipart/form-data">'."\n".
+                  $state.
+                  '<h3>'.&mt('Upload embedded files').
+                  ':</h3>'.$upload_output.'<br />'."\n".
+                  '<input type ="hidden" name="number_embedded_items" value="'.
+                  $num.'" />'."\n";
+        if ($actionurl eq '') {
+            $output .=  '<input type="hidden" name="phase" value="three" />';
+        }
+    } elsif ($applies) {
+        $output = '<b>'.&mt('Referenced files').'</b>:<br />';
+        if ($applies > 1) {
+            $output .=  
+                &mt('No files need to be uploaded, as one of the following applies to each reference:').'<ul>';
+            if ($numremref) {
+                $output .= '<li>'.&mt('reference is to a URL which points to another server').'</li>'."\n";
+            }
+            if ($numinvalid) {
+                $output .= '<li>'.&mt('reference is to file with a name containing invalid characters').'</li>'."\n";
+            }
+            if ($numexisting) {
+                $output .= '<li>'.&mt('reference is to an existing file at the specified location').'</li>'."\n";
+            }
+            $output .= '</ul><br />';
+        } elsif ($numremref) {
+            $output .= '<p>'.&mt('None to upload, as all references are to URLs pointing to another server.').'</p>';
+        } elsif ($numinvalid) {
+            $output .= '<p>'.&mt('None to upload, as all references are to files with names containing invalid characters.').'</p>';
+        } elsif ($numexisting) {
+            $output .= '<p>'.&mt('None to upload, as all references are to existing files.').'</p>';
+        }
+        $output .= $upload_output.'<br />';
+    }
+    my ($pathchange_output,$chgcount);
+    $chgcount = $num;
+    if (keys(%pathchanges) > 0) {
+        foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%pathchanges)) {
+            if ($num) {
+                $output .= &embedded_file_element('pathchange',$chgcount,
+                                                  $embed_file,\%mapping,
+                                                  $allfiles,$codebase);
+            } else {
+                $pathchange_output .= 
+                    &start_data_table_row().
+                    '<td><input type ="checkbox" name="namechange" value="'.
+                    $chgcount.'" checked="checked" /></td>'.
+                    '<td>'.$mapping{$embed_file}.'</td>'.
+                    '<td>'.$embed_file.
+                    &embedded_file_element('pathchange',$numpathchg,$embed_file,
+                                           \%mapping,$allfiles,$codebase).
+                    '</td>'.&end_data_table_row();
+            }
+            $numpathchg ++;
+            $chgcount ++;
+        }
+    }
+    if ($num) {
+        if ($numpathchg) {
+            $output .= '<input type ="hidden" name="number_pathchange_items" value="'.
+                       $numpathchg.'" />'."\n";
+        }
+        if (($actionurl eq '/adm/upload') || ($actionurl eq '/adm/testbank') || 
+            ($actionurl eq '/adm/imsimport')) {
+            $output .= '<input type="hidden" name="phase" value="three" />'."\n";
+        } elsif ($actionurl eq '/adm/portfolio' || $actionurl eq '/adm/coursegrp_portfolio') {
+            $output .= '<input type="hidden" name="action" value="upload_embedded" />';
+        }
+        $output .=  '<input type ="submit" value="'.&mt('Upload Listed Files').'" />'."\n".
+                    &mt('(only files for which a location has been provided will be uploaded)').'</form>'."\n";
+    } elsif ($numpathchg) {
+        my %pathchange = ();
+        $output .= &modify_html_form('pathchange',$actionurl,$state,\%pathchange,$pathchange_output);
+        if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) {
+            $output .= '<p>'.&mt('or').'</p>'; 
+        } 
+    }
+    return ($output,$num,$numpathchg);
+}
+
+sub embedded_file_element {
+    my ($context,$num,$embed_file,$mapping,$allfiles,$codebase) = @_;
+    return unless ((ref($mapping) eq 'HASH') && (ref($allfiles) eq 'HASH') &&
+                   (ref($codebase) eq 'HASH'));
+    my $output;
+    if ($context eq 'upload_embedded') {
+       $output = '<input name="embedded_item_'.$num.'" type="file" value="" />'."\n";
+    }
+    $output .= '<input name="embedded_orig_'.$num.'" type="hidden" value="'.
+               &escape($embed_file).'" />';
+    unless (($context eq 'upload_embedded') && 
+            ($mapping->{$embed_file} eq $embed_file)) {
+        $output .='
+        <input name="embedded_ref_'.$num.'" type="hidden" value="'.&escape($mapping->{$embed_file}).'" />';
+    }
+    my $attrib;
+    if (ref($allfiles->{$mapping->{$embed_file}}) eq 'ARRAY') {
+        $attrib = &escape(join(':',@{$allfiles->{$mapping->{$embed_file}}}));
+    }
+    $output .=
+        "\n\t\t".
+        '<input name="embedded_attrib_'.$num.'" type="hidden" value="'.
+        $attrib.'" />';
+    if (exists($codebase->{$mapping->{$embed_file}})) {
+        $output .=
+            "\n\t\t".
+            '<input name="codebase_'.$num.'" type="hidden" value="'.
+            &escape($codebase->{$mapping->{$embed_file}}).'" />';
+    }
+    return $output;
 }
 
 sub upload_embedded {
     my ($context,$dirpath,$uname,$udom,$dir_root,$url_root,$group,$disk_quota,
-        $current_disk_usage) = @_;
-    my $output;
+        $current_disk_usage,$hiddenstate,$actionurl) = @_;
+    my (%pathchange,$output,$modifyform,$footer,$returnflag);
     for (my $i=0; $i<$env{'form.number_embedded_items'}; $i++) {
         next if (!exists($env{'form.embedded_item_'.$i.'.filename'}));
         my $orig_uploaded_filename =
             $env{'form.embedded_item_'.$i.'.filename'};
-
-        $env{'form.embedded_orig_'.$i} =
-            &unescape($env{'form.embedded_orig_'.$i});
+        foreach my $type ('orig','ref','attrib','codebase') {
+            if ($env{'form.embedded_'.$type.'_'.$i} ne '') {
+                $env{'form.embedded_'.$type.'_'.$i} =
+                    &unescape($env{'form.embedded_'.$type.'_'.$i});
+            }
+        }
         my ($path,$fname) =
             ($env{'form.embedded_orig_'.$i} =~ m{(.*/)([^/]*)});
         # no path, whole string is fname
         if (!$fname) { $fname = $env{'form.embedded_orig_'.$i} };
-
-        $path = $env{'form.currentpath'}.$path;
         $fname = &Apache::lonnet::clean_filename($fname);
         # See if there is anything left
         next if ($fname eq '');
@@ -8336,12 +9274,12 @@ sub upload_embedded {
             if ($group ne '') {
                 $port_path = "groups/$group/$port_path";
             }
-            ($state,$msg) = &check_for_upload($path,$fname,$group,'embedded_item_'.$i,
+            ($state,$msg) = &check_for_upload($env{'form.currentpath'}.$path,
+                                              $fname,$group,'embedded_item_'.$i,
                                               $dir_root,$port_path,$disk_quota,
                                               $current_disk_usage,$uname,$udom);
             if ($state eq 'will_exceed_quota'
-                || $state eq 'file_locked'
-                || $state eq 'file_exists' ) {
+                || $state eq 'file_locked') {
                 $output .= $msg;
                 next;
             }
@@ -8355,31 +9293,53 @@ sub upload_embedded {
         # Check if extension is valid
         if (($fname =~ /\.(\w+)$/) &&
             (&Apache::loncommon::fileembstyle($1) eq 'hdn')) {
-            $output .= &mt('Invalid file extension ([_1]) - reserved for LONCAPA use - rename the file with a different extension and re-upload. ',$1);
+            $output .= &mt('Invalid file extension ([_1]) - reserved for LONCAPA use - rename the file with a different extension and re-upload. ',$1).'<br />';
             next;
         } elsif (($fname =~ /\.(\w+)$/) &&
                  (!defined(&Apache::loncommon::fileembstyle($1)))) {
-            $output .= &mt('Unrecognized file extension ([_1]) - rename the file with a proper extension and re-upload.',$1);
+            $output .= &mt('Unrecognized file extension ([_1]) - rename the file with a proper extension and re-upload.',$1).'<br />';
             next;
         } elsif ($fname=~/\.(\d+)\.(\w+)$/) {
-            $output .= &mt('File name not allowed - rename the file to remove the number immediately before the file extension([_1]) and re-upload.',$2);
+            $output .= &mt('File name not allowed - rename the file to remove the number immediately before the file extension([_1]) and re-upload.',$2).'<br />';
             next;
         }
 
         $env{'form.embedded_item_'.$i.'.filename'}=$fname;
         if ($context eq 'portfolio') {
-            my $result=
-                &Apache::lonnet::userfileupload('embedded_item_'.$i,'',
-                                                $dirpath.$path);
+            my $result;
+            if ($state eq 'existingfile') {
+                $result=
+                    &Apache::lonnet::userfileupload('embedded_item_'.$i,'existingfile',
+                                                    $dirpath.$env{'form.currentpath'}.$path);
+            } else {
+                $result=
+                    &Apache::lonnet::userfileupload('embedded_item_'.$i,'',
+                                                    $dirpath.
+                                                    $env{'form.currentpath'}.$path);
+                if ($result !~ m|^/uploaded/|) {
+                    $output .= '<span class="LC_error">'
+                               .&mt('An error occurred ([_1]) while trying to upload [_2] for embedded element [_3].'
+                               ,$result,$orig_uploaded_filename,$env{'form.embedded_orig_'.$i})
+                               .'</span><br />';
+                    next;
+                } else {
+                    $output .= &mt('Uploaded [_1]','<span class="LC_filename">'.
+                               $path.$fname.'</span>').'<br />';     
+                }
+            }
+        } elsif ($context eq 'coursedoc') {
+            my $result =
+                &Apache::lonnet::userfileupload('embedded_item_'.$i,'coursedoc',
+                                                $dirpath.'/'.$path);
             if ($result !~ m|^/uploaded/|) {
                 $output .= '<span class="LC_error">'
-                      .&mt('An error occurred ([_1]) while trying to upload [_2] for embedded element [_3].'
+                           .&mt('An error occurred ([_1]) while trying to upload [_2] for embedded element [_3].'
                            ,$result,$orig_uploaded_filename,$env{'form.embedded_orig_'.$i})
-                      .'</span><br />';
-                next;
+                           .'</span><br />';
+                    next;
             } else {
-                $output .= '<p>'.&mt('Uploaded [_1]','<span class="LC_filename">'.
-                           $path.$fname.'</span>').'</p>';     
+                $output .= &mt('Uploaded [_1]','<span class="LC_filename">'.
+                           $path.$fname.'</span>').'<br />';
             }
         } else {
 # Save the file
@@ -8387,12 +9347,12 @@ sub upload_embedded {
             my $fullpath = $dir_root.$dirpath.'/'.$path;
             my $dest = $fullpath.$fname;
             my $url = $url_root.$dirpath.'/'.$path.$fname;
-            my @parts=split(/\//,$fullpath);
+            my @parts=split(/\//,"$dirpath/$path");
             my $count;
             my $filepath = $dir_root;
-            for ($count=4;$count<=$#parts;$count++) {
-                $filepath .= "/$parts[$count]";
-                if ((-e $filepath)!=1) {
+            foreach my $subdir (@parts) {
+                $filepath .= "/$subdir";
+                if (!-e $filepath) {
                     mkdir($filepath,0770);
                 }
             }
@@ -8409,19 +9369,189 @@ sub upload_embedded {
                               &mt('An error occurred while writing the file [_1] for embedded element [_2].',$orig_uploaded_filename,$env{'form.embedded_orig_'.$i}).
                               '</span><br />';
                 } else {
-                    if ($context eq 'testbank') {
-                        $output .= &mt('Embedded file uploaded successfully:').
-                                   '&nbsp;<a href="'.$url.'">'.
-                                   $orig_uploaded_filename.'</a><br />';
-                    } else {
-                        $output .= '<span class=\"LC_fontsize_large\">'.
-                                   &mt('View embedded file: [_1]','<a href="'.$url.'">'.
-                                   $orig_uploaded_filename.'</a>').'</span><br />';
+                    $output .= &mt('Uploaded [_1]','<span class="LC_filename">'.
+                               $url.'</span>').'<br />';
+                    unless ($context eq 'testbank') {
+                        $footer .= &mt('View embedded file: [_1]',
+                                       '<a href="'.$url.'">'.$fname.'</a>').'<br />';
                     }
                 }
                 close($fh);
             }
         }
+        if ($env{'form.embedded_ref_'.$i}) {
+            $pathchange{$i} = 1;
+        }
+    }
+    if ($output) {
+        $output = '<p>'.$output.'</p>';
+    }
+    $output .= &modify_html_form('upload_embedded',$actionurl,$hiddenstate,\%pathchange);
+    $returnflag = 'ok';
+    if (keys(%pathchange) > 0) {
+        if ($context eq 'portfolio') {
+            $output .= '<p>'.&mt('or').'</p>';
+        } elsif ($context eq 'testbank') {
+            $output .=  '<p>'.&mt('Or [_1]continue[_2] the testbank import without modifying the reference(s).','<a href="javascript:document.testbankForm.submit();">','</a>').'</p>';
+            $returnflag = 'modify_orightml';
+        }
+    }
+    return ($output.$footer,$returnflag);
+}
+
+sub modify_html_form {
+    my ($context,$actionurl,$hiddenstate,$pathchange,$pathchgtable) = @_;
+    my $end = 0;
+    my $modifyform;
+    if ($context eq 'upload_embedded') {
+        return unless (ref($pathchange) eq 'HASH');
+        if ($env{'form.number_embedded_items'}) {
+            $end += $env{'form.number_embedded_items'};
+        }
+        if ($env{'form.number_pathchange_items'}) {
+            $end += $env{'form.number_pathchange_items'};
+        }
+        if ($end) {
+            for (my $i=0; $i<$end; $i++) {
+                if ($i < $env{'form.number_embedded_items'}) {
+                    next unless($pathchange->{$i});
+                }
+                $modifyform .=
+                    &start_data_table_row().
+                    '<td><input type ="checkbox" name="namechange" value="'.$i.'" '.
+                    'checked="checked" /></td>'.
+                    '<td>'.$env{'form.embedded_ref_'.$i}.
+                    '<input type="hidden" name="embedded_ref_'.$i.'" value="'.
+                    &escape($env{'form.embedded_ref_'.$i}).'" />'.
+                    '<input type="hidden" name="embedded_codebase_'.$i.'" value="'.
+                    &escape($env{'form.embedded_codebase_'.$i}).'" />'.
+                    '<input type="hidden" name="embedded_attrib_'.$i.'" value="'.
+                    &escape($env{'form.embedded_attrib_'.$i}).'" /></td>'.
+                    '<td>'.$env{'form.embedded_orig_'.$i}.
+                    '<input type="hidden" name="embedded_orig_'.$i.'" value="'.
+                    &escape($env{'form.embedded_orig_'.$i}).'" /></td>'.
+                    &end_data_table_row();
+            } 
+        }
+    } else {
+        $modifyform = $pathchgtable;
+        if (($actionurl eq '/adm/upload') || ($actionurl eq '/adm/testbank')) {
+            $hiddenstate .= '<input type="hidden" name="phase" value="four" />';
+        } elsif (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) {
+            $hiddenstate .= '<input type="hidden" name="action" value="modify_orightml" />';
+        }
+    }
+    if ($modifyform) {
+        return '<h3>'.&mt('Changes in content of HTML file required').'</h3>'."\n".
+               '<p>'.&mt('Changes need to be made to the reference(s) used for one or more of the dependencies, if your HTML file is to work correctly:').'<ol>'."\n".
+               '<li>'.&mt('For consistency between the reference(s) and the location of the corresponding stored file within LON-CAPA.').'</li>'."\n".
+               '<li>'.&mt('To change absolute paths to relative paths, or replace directory traversal via "../" within the original reference.').'</li>'."\n".
+               '</ol></p>'."\n".'<p>'.
+               &mt('LON-CAPA can make the required changes to your HTML file.').'</p>'."\n".
+               '<form method="post" name="refchanger" action="'.$actionurl.'">'.
+               &start_data_table()."\n".
+               &start_data_table_header_row().
+               '<th>'.&mt('Change?').'</th>'.
+               '<th>'.&mt('Current reference').'</th>'.
+               '<th>'.&mt('Required reference').'</th>'.
+               &end_data_table_header_row()."\n".
+               $modifyform.
+               &end_data_table().'<br />'."\n".$hiddenstate.
+               '<input type="submit" name="pathchanges" value="'.&mt('Modify HTML file').'" />'.
+               '</form>'."\n";
+    }
+    return;
+}
+
+sub modify_html_refs {
+    my ($context,$dirpath,$uname,$udom,$dir_root) = @_;
+    my $container;
+    if ($context eq 'portfolio') {
+        $container = $env{'form.container'};
+    } elsif ($context eq 'coursedoc') {
+        $container = $env{'form.primaryurl'};
+    } else {
+        $container = $Apache::lonnet::perlvar{'lonDocRoot'}.$env{'form.filename'};
+    }
+    my (%allfiles,%codebase,$output,$content);
+    my @changes = &get_env_multiple('form.namechange');
+    return unless (@changes > 0);
+    if (($context eq 'portfolio') || ($context eq 'coursedoc')) {
+        return unless ($container =~ m{^/uploaded/\Q$udom\E/\Q$uname\E/});
+        $content = &Apache::lonnet::getfile($container);
+        return if ($content eq '-1');
+    } else {
+        return unless ($container =~ /^\Q$dir_root\E/); 
+        if (open(my $fh,"<$container")) {
+            $content = join('', <$fh>);
+            close($fh);
+        } else {
+            return;
+        }
+    }
+    my ($count,$codebasecount) = (0,0);
+    my $mm = new File::MMagic;
+    my $mime_type = $mm->checktype_contents($content);
+    if ($mime_type eq 'text/html') {
+        my $parse_result = 
+            &Apache::lonnet::extract_embedded_items($container,\%allfiles,
+                                                    \%codebase,\$content);
+        if ($parse_result eq 'ok') {
+            foreach my $i (@changes) {
+                my $orig = &unescape($env{'form.embedded_orig_'.$i});
+                my $ref = &unescape($env{'form.embedded_ref_'.$i});
+                if ($allfiles{$ref}) {
+                    my $newname =  $orig;
+                    my ($attrib_regexp,$codebase);
+                    $attrib_regexp = &unescape($env{'form.embedded_attrib_'.$i});
+                    if ($attrib_regexp =~ /:/) {
+                        $attrib_regexp =~ s/\:/|/g;
+                    }
+                    if ($content =~ m{($attrib_regexp\s*=\s*['"]?)\Q$ref\E(['"]?)}) {
+                        my $numchg = ($content =~ s{($attrib_regexp\s*=\s*['"]?)\Q$ref\E(['"]?)}{$1$newname$2}gi);
+                        $count += $numchg;
+                    }
+                    if ($env{'form.embedded_codebase_'.$i} ne '') {
+                        $codebase = &unescape($env{'form.embedded_codebase_'.$i});
+                        my $numchg = ($content =~ s/(codebase\s*=\s*["']?)\Q$codebase\E(["']?)/$1.$2/i); #' stupid emacs
+                        $codebasecount ++;
+                    }
+                }
+            }
+            if ($count || $codebasecount) {
+                my $saveresult;
+                if ($context eq 'portfolio' || $context eq 'coursedoc') {
+                    my $url = &Apache::lonnet::store_edited_file($container,$content,$udom,$uname,\$saveresult);
+                    if ($url eq $container) {
+                        my ($fname) = ($container =~ m{/([^/]+)$});
+                        $output = '<p>'.&mt('Updated [quant,_1,reference] in [_2].',
+                                            $count,'<span class="LC_filename">'.
+                                            $fname.'</span>').'</p>'; 
+                    } else {
+                         $output = '<p class="LC_error">'.
+                                   &mt('Error: update failed for: [_1].',
+                                   '<span class="LC_filename">'.
+                                   $container.'</span>').'</p>';
+                    }
+                } else {
+                    if (open(my $fh,">$container")) {
+                        print $fh $content;
+                        close($fh);
+                        $output = '<p>'.&mt('Updated [quant,_1,reference] in [_2].',
+                                  $count,'<span class="LC_filename">'.
+                                  $container.'</span>').'</p>';
+                    } else {
+                         $output = '<p class="LC_error">'.
+                                   &mt('Error: could not update [_1].',
+                                   '<span class="LC_filename">'.
+                                   $container.'</span>').'</p>';
+                    }
+                }
+            }
+        } else {
+            &logthis('Failed to parse '.$container.
+                     ' to modify references: '.$parse_result);
+        }
     }
     return $output;
 }
@@ -8445,22 +9575,73 @@ sub check_for_existing {
 sub check_for_upload {
     my ($path,$fname,$group,$element,$portfolio_root,$port_path,
         $disk_quota,$current_disk_usage,$uname,$udom) = @_;
-    my $filesize = (length($env{'form.'.$element})) / 1000; #express in k (1024?)
+    my $filesize = length($env{'form.'.$element});
+    if (!$filesize) {
+        my $msg = '<span class="LC_error">'.
+                  &mt('Unable to upload [_1]. (size = [_2] bytes)', 
+                      '<span class="LC_filename">'.$fname.'</span>',
+                      $filesize).'<br />'.
+                  &mt('Either the file you attempted to upload was empty, or your web browser was unable to read its contents.').'<br />'.
+                  '</span>';
+        return ('zero_bytes',$msg);
+    }
+    $filesize =  $filesize/1000; #express in k (1024?)
     my $getpropath = 1;
-    my @dir_list = &Apache::lonnet::dirlist($portfolio_root.$path,$udom,$uname,
-                                            $getpropath);
+    my ($dirlistref,$listerror) =
+         &Apache::lonnet::dirlist($portfolio_root.$path,$udom,$uname,$getpropath);
     my $found_file = 0;
     my $locked_file = 0;
-    foreach my $line (@dir_list) {
-        my ($file_name)=split(/\&/,$line,2);
-        if ($file_name eq $fname){
-            $file_name = $path.$file_name;
-            if ($group ne '') {
-                $file_name = $group.$file_name;
-            }
-            $found_file = 1;
-            if (&Apache::lonnet::is_locked($file_name,$udom,$uname) eq 'true') {
-                $locked_file = 1;
+    my @lockers;
+    my $navmap;
+    if ($env{'request.course.id'}) {
+        $navmap = Apache::lonnavmaps::navmap->new();
+    }
+    if (ref($dirlistref) eq 'ARRAY') {
+        foreach my $line (@{$dirlistref}) {
+            my ($file_name,$rest)=split(/\&/,$line,2);
+            if ($file_name eq $fname){
+                $file_name = $path.$file_name;
+                if ($group ne '') {
+                    $file_name = $group.$file_name;
+                }
+                $found_file = 1;
+                if (&Apache::lonnet::is_locked($file_name,$udom,$uname,\@lockers) eq 'true') {
+                    foreach my $lock (@lockers) {
+                        if (ref($lock) eq 'ARRAY') {
+                            my ($symb,$crsid) = @{$lock};
+                            if ($crsid eq $env{'request.course.id'}) {
+                                if (ref($navmap)) {
+                                    my $res = $navmap->getBySymb($symb);
+                                    foreach my $part (@{$res->parts()}) { 
+                                        my ($slot_status,$slot_time,$slot_name)=$res->check_for_slot($part);
+                                        unless (($slot_status == $res->RESERVED) ||
+                                                ($slot_status == $res->RESERVED_LOCATION)) {
+                                            $locked_file = 1;
+                                        }
+                                    }
+                                } else {
+                                    $locked_file = 1;
+                                }
+                            } else {
+                                $locked_file = 1;
+                            }
+                        }
+                   }
+                } else {
+                    my @info = split(/\&/,$rest);
+                    my $currsize = $info[6]/1000;
+                    if ($currsize < $filesize) {
+                        my $extra = $filesize - $currsize;
+                        if (($current_disk_usage + $extra) > $disk_quota) {
+                            my $msg = '<span class="LC_error">'.
+                                      &mt('Unable to upload [_1]. (size = [_2] kilobytes). Disk quota will be exceeded if existing (smaller) file with same name (size = [_3] kilobytes) is replaced.',
+                                          '<span class="LC_filename">'.$fname.'</span>',$filesize,$currsize).'</span>'.
+                                      '<br />'.&mt('Disk quota is [_1] kilobytes. Your current disk usage is [_2] kilobytes.',
+                                                   $disk_quota,$current_disk_usage);
+                            return ('will_exceed_quota',$msg);
+                        }
+                    }
+                }
             }
         }
     }
@@ -8478,15 +9659,162 @@ sub check_for_upload {
             return ('file_locked',$msg);
         } else {
             my $msg = '<span class="LC_error">';
-            $msg .= &mt('Unable to upload [_1]. A file by that name was found in [_2].','<span class="LC_filename">'.$fname.'</span>',$port_path.$env{'form.currentpath'});
+            $msg .= &mt(' A file by that name: [_1] was found in [_2].','<span class="LC_filename">'.$fname.'</span>',$port_path.$env{'form.currentpath'});
             $msg .= '</span>';
-            $msg .= '<br />';
-            $msg .= &mt('To upload, rename or delete existing [_1] in [_2].','<span class="LC_filename">'.$fname.'</span>', $port_path.$env{'form.currentpath'});
-            return ('file_exists',$msg);
+            return ('existingfile',$msg);
         }
     }
 }
 
+sub check_for_traversal {
+    my ($path,$url,$toplevel) = @_;
+    my @parts=split(/\//,$path);
+    my $cleanpath;
+    my $fullpath = $url;
+    for (my $i=0;$i<@parts;$i++) {
+        next if ($parts[$i] eq '.');
+        if ($parts[$i] eq '..') {
+            $fullpath =~ s{([^/]+/)$}{};
+        } else {
+            $fullpath .= $parts[$i].'/';
+        }
+    }
+    if ($fullpath =~ /^\Q$url\E(.*)$/) {
+        $cleanpath = $1;
+    } elsif ($fullpath =~ /^\Q$toplevel\E(.*)$/) {
+        my $curr_toprel = $1;
+        my @parts = split(/\//,$curr_toprel);
+        my ($url_toprel) = ($url =~ /^\Q$toplevel\E(.*)$/);
+        my @urlparts = split(/\//,$url_toprel);
+        my $doubledots;
+        my $startdiff = -1;
+        for (my $i=0; $i<@urlparts; $i++) {
+            if ($startdiff == -1) {
+                unless ($urlparts[$i] eq $parts[$i]) {
+                    $startdiff = $i;
+                    $doubledots .= '../';
+                }
+            } else {
+                $doubledots .= '../';
+            }
+        }
+        if ($startdiff > -1) {
+            $cleanpath = $doubledots;
+            for (my $i=$startdiff; $i<@parts; $i++) {
+                $cleanpath .= $parts[$i].'/';
+            }
+        }
+    }
+    $cleanpath =~ s{(/)$}{};
+    return $cleanpath;
+}
+
+=pod
+
+=item * &get_turnedin_filepath()
+
+Determines path in a user's portfolio file for storage of files uploaded
+to a specific essayresponse or dropbox item.
+
+Inputs: 3 required + 1 optional.
+$symb is symb for resource, $uname and $udom are for current user (required).
+$caller is optional (can be "submission", if routine is called when storing
+an upoaded file when "Submit Answer" button was pressed).
+
+Returns array containing $path and $multiresp. 
+$path is path in portfolio.  $multiresp is 1 if this resource contains more
+than one file upload item.  Callers of routine should append partid as a 
+subdirectory to $path in cases where $multiresp is 1.
+
+Called by: homework/essayresponse.pm and homework/structuretags.pm
+
+=cut
+
+sub get_turnedin_filepath {
+    my ($symb,$uname,$udom,$caller) = @_;
+    my ($map,$resid,$resurl)=&Apache::lonnet::decode_symb($symb);
+    my $turnindir;
+    my %userhash = &Apache::lonnet::userenvironment($udom,$uname,'turnindir');
+    $turnindir = $userhash{'turnindir'};
+    my ($path,$multiresp);
+    if ($turnindir eq '') {
+        if ($caller eq 'submission') {
+            $turnindir = &mt('turned in');
+            $turnindir =~ s/\W+/_/g;
+            my %newhash = (
+                            'turnindir' => $turnindir,
+                          );
+            &Apache::lonnet::put('environment',\%newhash,$udom,$uname);
+        }
+    }
+    if ($turnindir ne '') {
+        $path = '/'.$turnindir.'/';
+        my ($multipart,$turnin,@pathitems);
+        my $navmap = Apache::lonnavmaps::navmap->new();
+        if (defined($navmap)) {
+            my $mapres = $navmap->getResourceByUrl($map);
+            if (ref($mapres)) {
+                my $pcslist = $mapres->map_hierarchy();
+                if ($pcslist ne '') {
+                    foreach my $pc (split(/,/,$pcslist)) {
+                        my $res = $navmap->getByMapPc($pc);
+                        if (ref($res)) {
+                            my $title = $res->compTitle();
+                            $title =~ s/\W+/_/g;
+                            if ($title ne '') {
+                                push(@pathitems,$title);
+                            }
+                        }
+                    }
+                }
+                my $maptitle = $mapres->compTitle();
+                $maptitle =~ s/\W+/_/g;
+                if ($maptitle ne '') {
+                    push(@pathitems,$maptitle);
+                }
+                unless ($env{'request.state'} eq 'construct') {
+                    my $res = $navmap->getBySymb($symb);
+                    if (ref($res)) {
+                        my $partlist = $res->parts();
+                        my $totaluploads = 0;
+                        if (ref($partlist) eq 'ARRAY') {
+                            foreach my $part (@{$partlist}) {
+                                my @types = $res->responseType($part);
+                                my @ids = $res->responseIds($part);
+                                for (my $i=0; $i < scalar(@ids); $i++) {
+                                    if ($types[$i] eq 'essay') {
+                                        my $partid = $part.'_'.$ids[$i];
+                                        if (&Apache::lonnet::EXT("resource.$partid.uploadedfiletypes") ne '') {
+                                            $totaluploads ++;
+                                        }
+                                    }
+                                }
+                            }
+                            if ($totaluploads > 1) {
+                                $multiresp = 1;
+                            }
+                        }
+                    }
+                }
+            } else {
+                return;
+            }
+        } else {
+            return;
+        }
+        my $restitle=&Apache::lonnet::gettitle($symb);
+        $restitle =~ s/\W+/_/g;
+        if ($restitle eq '') {
+            $restitle = ($resurl =~ m{/[^/]+$});
+            if ($restitle eq '') {
+                $restitle = time;
+            }
+        }
+        push(@pathitems,$restitle);
+        $path .= join('/',@pathitems);
+    }
+    return ($path,$multiresp);
+}
 
 =pod
 
@@ -10619,15 +11947,23 @@ sub init_user_environment {
 	    $env{'browser.interface'}=$form->{'interface'};
 	}
 
+        my %is_adv = ( is_adv => $env{'user.adv'} );
+        my %domdef;
+        unless ($domain eq 'public') {
+            %domdef = &Apache::lonnet::get_domain_defaults($domain);
+        }
+
         foreach my $tool ('aboutme','blog','portfolio') {
             $userenv{'availabletools.'.$tool} = 
-                &Apache::lonnet::usertools_access($username,$domain,$tool,'reload');
+                &Apache::lonnet::usertools_access($username,$domain,$tool,'reload',
+                                                  undef,\%userenv,\%domdef,\%is_adv);
         }
 
         foreach my $crstype ('official','unofficial','community') {
             $userenv{'canrequest.'.$crstype} =
                 &Apache::lonnet::usertools_access($username,$domain,$crstype,
-                                                  'reload','requestcourses');
+                                                  'reload','requestcourses',
+                                                  \%userenv,\%domdef,\%is_adv);
         }
 
 	$env{'user.environment'} = "$lonids/$cookie.id";
@@ -10706,6 +12042,36 @@ sub clean_symb {
     return ($symb,$enc);
 }
 
+sub build_release_hashes {
+    my ($checkparms,$checkresponsetypes,$checkcrstypes,$anonsurvey,$randomizetry) = @_;
+    return unless((ref($checkparms) eq 'HASH') && (ref($checkresponsetypes) eq 'HASH') &&
+                  (ref($checkcrstypes) eq 'HASH') && (ref($anonsurvey) eq 'HASH') &&
+                  (ref($randomizetry) eq 'HASH'));
+    foreach my $key (keys(%Apache::lonnet::needsrelease)) {
+        my ($item,$name,$value) = split(/:/,$key);
+        if ($item eq 'parameter') {
+            if (ref($checkparms->{$name}) eq 'ARRAY') {
+                unless(grep(/^\Q$name\E$/,@{$checkparms->{$name}})) {
+                    push(@{$checkparms->{$name}},$value);
+                }
+            } else {
+                push(@{$checkparms->{$name}},$value);
+            }
+        } elsif ($item eq 'resourcetag') {
+            if ($name eq 'responsetype') {
+                $checkresponsetypes->{$value} = $Apache::lonnet::needsrelease{$key}
+            }
+        } elsif ($item eq 'course') {
+            if ($name eq 'crstype') {
+                $checkcrstypes->{$value} = $Apache::lonnet::needsrelease{$key};
+            }
+        }
+    }
+    ($anonsurvey->{major},$anonsurvey->{minor}) = split(/\./,$Apache::lonnet::needsrelease{'parameter:type:anonsurvey'});
+    ($randomizetry->{major},$randomizetry->{minor}) = split(/\./,$Apache::lonnet::needsrelease{'parameter:type:randomizetry'});
+    return;
+}
+
 =pod
 
 =back