--- loncom/interface/lonmenu.pm	2011/11/30 18:34:25	1.315.2.15
+++ loncom/interface/lonmenu.pm	2012/05/29 19:41:27	1.369.2.13
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Routines to control the menu
 #
-# $Id: lonmenu.pm,v 1.315.2.15 2011/11/30 18:34:25 raeburn Exp $
+# $Id: lonmenu.pm,v 1.369.2.13 2012/05/29 19:41:27 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -26,10 +26,6 @@
 # http://www.lon-capa.org/
 #
 #
-# There is one parameter controlling the action of this module:
-#
-# environment.remote - if this is 'on', the routines controll the remote
-# control, otherwise they render the main window controls; 
 
 =head1 NAME
 
@@ -37,7 +33,8 @@ Apache::lonmenu
 
 =head1 SYNOPSIS
 
-Coordinates the response to clicking an image.
+Loads contents of /home/httpd/lonTabs/mydesk.tab, 
+used to generate inline menu, and Main Menu page. 
 
 This is part of the LearningOnline Network with CAPA project
 described at http://www.lon-capa.org.
@@ -76,10 +73,19 @@ It is set to 'done' in the BEGIN block o
 =item @primary_menu
 
 The elements of this array reference arrays that are made up of the components
-of those lines of mydesk.tab that start with prim.
+of those lines of mydesk.tab that start with prim:.
 It is used by primary_menu() to generate the corresponding menu.
 It gets filled in the BEGIN block of this module.
 
+=item %primary_sub_menu
+
+The keys of this hash reference are the names of items in the primary_menu array 
+which have sub-menus.  For each key, the corresponding value is a reference to
+an array containing components extracted from lines in mydesk.tab which begin
+with primsub:.
+This hash, which is used by primary_menu to generate sub-menus, is populated in
+the BEGIN block.
+
 =item @secondary_menu
 
 The elements of this array reference arrays that are made up of the components
@@ -109,36 +115,21 @@ entries from mydesk.tab
 
 Same as primary_menu() but operates on @secondary_menu.
 
-=item show_return_link()
-
-=item registerurl()
+=item create_submenu()
 
-This gets called in the header section
+Creates XHTML for unordered list of sub-menu items which belong to a
+particular top-level menu item. Uses hover pseudo class in css to display
+dropdown list when mouse hovers over top-level item. Support for IE6
+(no hover psuedo class) via LC_hoverable class for <li> tag for top-
+level item, which employs jQuery to handle behavior on mouseover.
+
+Inputs: 4 - (a) link and (b) target for anchor href in top level item,
+            (c) title for text wrapped by anchor tag in top level item.
+            (d) reference to array of arrays of sub-menu items.
 
 =item innerregister()
 
-This gets called in order to register a URL, both with the Remote
-and in the body of the document
-
-=item loadevents()
-
-=item unloadevents()
-
-=item startupremote()
-
-=item setflags()
-
-=item maincall()
-
-=item load_remote_msg()
-
-=item get_menu_name()
-
-=item reopenmenu()
-
-=item open()
-
-Open the menu
+This gets called in order to register a URL in the body of the document
 
 =item clear()
 
@@ -156,12 +147,11 @@ The javascript is usually similar to "go
 
 =item rawconfig()
 
-=item close()
-
-=item footer()
-
 =item utilityfunctions()
 
+Output from this routine is a number of javascript functions called by
+items in the inline menu, and in some cases items in the Main Menu page. 
+
 =item serverform()
 
 =item constspaceform()
@@ -186,11 +176,13 @@ use Apache::lonhtmlcommon();
 use Apache::loncommon();
 use Apache::lonenc();
 use Apache::lonlocal;
+use Apache::lonmsg();
 use LONCAPA qw(:DEFAULT :match);
 use HTML::Entities();
+use Apache::lonwishlist();
 
 use vars qw(@desklines %category_names %category_members %category_positions 
-            $readdesk @primary_menu @secondary_menu);
+            $readdesk @primary_menu %primary_submenu @secondary_menu %secondary_submenu);
 
 my @inlineremote;
 
@@ -205,15 +197,15 @@ sub prep_menuitem {
     } else {             # textual Link
         $link = &mt($$menuitem[3]);
     }
-    return '<li><a'
+    return '<li><a' 
            # highlighting for new messages
-           . ( $$menuitem[4] eq 'newmsg' ? ' class="LC_new_message"' : '')
+           . ( $$menuitem[4] eq 'newmsg' ? ' class="LC_new_message"' : '') 
            . qq| href="$$menuitem[0]" target="_top">$link</a></li>|;
 }
 
 # primary_menu() evaluates @primary_menu and returns XHTML for the menu
 # that contains following links:
-# About, Message, Roles, Help, Logout
+# About, Message, Personal, Roles, Help, Logout
 # @primary_menu is filled within the BEGIN block of this module with 
 # entries from mydesk.tab
 sub primary_menu {
@@ -235,16 +227,43 @@ sub primary_menu {
         next if    $$menuitem[4]        !~ /public/    ##we've a public user,
                 && $public;                            ##who should not see all
                                                        ##links
-        next if    $$menuitem[4]        eq 'onlypublic'# hide links which are
+        next if    $$menuitem[4]        eq 'onlypublic'# hide links which are 
                 && !$public;                           # only visible to public
                                                        # users
         next if    $$menuitem[4]        eq 'roles'     ##show links depending on
-                && &Apache::loncommon::show_course();  ##term 'Courses' or
+                && &Apache::loncommon::show_course();  ##term 'Courses' or 
         next if    $$menuitem[4]        eq 'courses'   ##'Roles' wanted
                 && !&Apache::loncommon::show_course(); ##
-
-
-        if ($$menuitem[3] eq 'Help') { # special treatment for helplink
+        
+        my $title = $menuitem->[3];
+        if (defined($primary_submenu{$title})) {
+            my ($link,$target);
+            if ($menuitem->[0] ne '') {
+                $link = $menuitem->[0];
+                $target = '_top';
+            } else {
+                $link = '#';
+            }
+            my @primsub;
+            if (ref($primary_submenu{$title}) eq 'ARRAY') {
+                foreach my $item (@{$primary_submenu{$title}}) {
+                    next if (($item->[2] eq 'wishlist') && 
+                             ((!&Apache::lonnet::allowed('bre',"/res/$env{'user.domain'}/")) &&
+                              (!&Apache::lonnet::allowed('bro',"/res/$env{'user.domain'}/"))));
+                    next if (($item->[2] eq 'reqcrs') && (!&check_for_rcrs()));
+                    next if ((($item->[2] eq 'portfolio') || 
+                             ($item->[2] eq 'blog')) && 
+                             (!&Apache::lonnet::usertools_access('','',$item->[2],
+                                                           undef,'tools')));
+                    push(@primsub,$item);
+                }
+                if (@primsub > 0) {
+                    $menu .= &create_submenu($link,$target,$title,\@primsub);
+                } elsif ($link) {
+                    $menu .= '<li><a href="'.$link.'" target="'.$target.'">'.&mt($title).'</a></li>';
+                }
+            }
+        } elsif ($$menuitem[3] eq 'Help') { # special treatment for helplink
             if ($public) {
                 my $origmail = $Apache::lonnet::perlvar{'lonSupportEMail'};
                 my $defdom = &Apache::lonnet::default_login_domain();
@@ -252,15 +271,17 @@ sub primary_menu {
                                                                   'helpdeskmail',
                                                                   $defdom,$origmail);
                 if ($to ne '') {
-                    $menu .= &prep_menuitem($menuitem);
+                    $menu .= &prep_menuitem($menuitem); 
                 }
             } else {
                 $menu .= '<li>'.&Apache::loncommon::top_nav_help('Help').'</li>';
             }
         } else {
-            $menu .= &prep_menuitem($menuitem);
+            $menu .= prep_menuitem($menuitem);
         }
     }
+    $menu =~ s/\[domain\]/$env{'user.domain'}/g;
+    $menu =~ s/\[user\]/$env{'user.name'}/g;
 
     return "<ol class=\"LC_primary_menu LC_right\">$menu</ol>";
 }
@@ -290,69 +311,96 @@ sub getauthor{
     return;
 }
 
-
 sub secondary_menu {
     my $menu;
 
     my $crstype = &Apache::loncommon::course_type();
-    my $crs_sec = $env{'request.course.id'} . ($env{'request.course.sec'}
+    my $crs_sec = $env{'request.course.id'} . ($env{'request.course.sec'} 
                                                ? "/$env{'request.course.sec'}"
                                                : '');
     my $canedit       = &Apache::lonnet::allowed('mdc', $env{'request.course.id'});
+    my $canviewroster = $env{'course.'.$env{'request.course.id'}.'.student_classlist_view'};
     my $canviewgrps   = &Apache::lonnet::allowed('vcg', $crs_sec);
-    my $author        = getauthor();
+    my $canmodifyuser = &Apache::lonnet::allowed('cst', $crs_sec);
+    my $canviewwnew   = &Apache::lonnet::allowed('whn', $crs_sec);
+    my $canmodpara    = &Apache::lonnet::allowed('opa', $crs_sec);
+    my $canvgr        = &Apache::lonnet::allowed('vgr', $crs_sec);
+    my $canmgr        = &Apache::lonnet::allowed('mgr', $crs_sec);
+    my $author        = &getauthor();
 
-    my $showlink = &show_return_link();
     my %groups = &Apache::lonnet::get_active_groups(
                      $env{'user.domain'}, $env{'user.name'},
                      $env{'course.' . $env{'request.course.id'} . '.domain'},
                      $env{'course.' . $env{'request.course.id'} . '.num'});
+
     foreach my $menuitem (@secondary_menu) {
         # evaluate conditions 
         next if    ref($menuitem)  ne 'ARRAY';
         next if    $$menuitem[4]   ne 'always'
                 && $$menuitem[4]   ne 'author'
                 && !$env{'request.course.id'};
-        next if    $$menuitem[4]   eq 'showreturn'
-                && !$showlink
-                && !($env{'request.state'} eq 'construct');
         next if    $$menuitem[4]   =~ /^mdc/
                 && !$canedit;
         next if    $$menuitem[4]  eq 'mdcCourse'
-                && $crstype eq 'Community';
+                && ($crstype eq 'Community');
         next if    $$menuitem[4]  eq 'mdcCommunity'
-                && $crstype ne 'Community';
-        next if    $$menuitem[4]  =~ /^remotenav/
-                && $env{'environment.remotenavmap'} ne 'on';
-        next if    $$menuitem[4]  =~ /noremotenav/
-                && $env{'environment.remotenavmap'} eq 'on';
-        next if $$menuitem[4] =~ /^(no|)remotenav$/ 
-                && $crstype eq 'Community';
-        next if $$menuitem[4] =~ /^(no|)remotenavCommunity$/ 
-                && $crstype ne 'Community';
-        next if    $$menuitem[4]   =~ /showgroups$/
-                && !$canviewgrps
-                && !%groups;
+                && ($crstype eq 'Course');
+        next if    $$menuitem[4]  eq 'nvgr'
+                && $canvgr;
+        next if    $$menuitem[4]  eq 'vgr'
+                && !$canvgr;
+        next if    $$menuitem[4]   eq 'cst'
+                && !$canmodifyuser;
+        next if    $$menuitem[4]   eq 'ncst'
+                && ($canmodifyuser || !$canviewroster);
+        next if    $$menuitem[4]   eq 'mgr'
+                && !$canmgr;
+        next if    $$menuitem[4]   eq 'nmgr'
+                && $canmgr;
+        next if    $$menuitem[4]   eq 'whn'
+                && !$canviewwnew;
+        next if    $$menuitem[4]   eq 'opa'
+                && !$canmodpara;
+        next if    $$menuitem[4]   eq 'nvcg'
+                && ($canviewgrps || !%groups);
         next if    $$menuitem[4]    eq 'author'
                 && !$author;
 
-        if ($$menuitem[3] eq 'Roles' && $env{'request.course.id'}) {
+        my $title = $menuitem->[3];
+        if (defined($secondary_submenu{$title})) {
+            my ($link,$target);
+            if ($menuitem->[0] ne '') {
+                $link = $menuitem->[0];
+                $target = '_top';
+            } else {
+                $link = '#';
+            }
+            my @scndsub;   
+            if (ref($secondary_submenu{$title}) eq 'ARRAY') {
+                foreach my $item (@{$secondary_submenu{$title}}) {
+                    if (ref($item) eq 'ARRAY') {
+                        next if ($item->[2] eq 'vgr' && !$canvgr);
+                        next if ($item->[2] eq 'opa' && !$canmodpara);
+                        next if ($item->[2] eq 'cst' && !$canmodifyuser);
+                        next if ($item->[2] eq 'mgr' && !$canmgr);
+                        next if ($item->[2] eq 'vcg' && !$canviewgrps);
+                        push(@scndsub,$item); 
+                    }
+                }
+                if (@scndsub > 0) {
+                    $menu .= &create_submenu($link,$target,$title,\@scndsub);
+                } elsif ($link) {
+                    $menu .= '<li><a href="'.$link.'" target="'.$target.'">'.&mt($title).'</a></li>';
+                }
+            }
+        } elsif ($$menuitem[3] eq 'Roles' && $env{'request.course.id'}) {
             # special treatment for role selector
             my $roles_selector = &roles_selector(
                         $env{'course.' . $env{'request.course.id'} . '.domain'},
                         $env{'course.' . $env{'request.course.id'} . '.num'}  );
 
-            $menu .= $roles_selector ? "<li>$roles_selector</li>"
+            $menu .= $roles_selector ? "<li style=\"padding: 0 0.8em;\">$roles_selector</li>"
                                      : '';
-        } elsif ($env{'environment.remotenavmap'} eq 'on') {
-            # open link using javascript when remote navmap is activated
-            my @items = @{$menuitem}; 
-            if ($menuitem->[4] eq 'remotenav') {
-                $items[0] = "javascript:gonav('$menuitem->[0]');";
-            } else {
-                $items[0] = "javascript:go('$menuitem->[0]');";
-            }
-            $menu .= &prep_menuitem(\@items);
         } else {
             $menu .= &prep_menuitem(\@$menuitem);
         }
@@ -368,9 +416,8 @@ sub secondary_menu {
             and (   $env{'request.noversionuri'} eq '' 
                  || !defined($env{'request.noversionuri'}))) 
         {
-            ($escurl = $env{'request.filename'}) =~ 
-                s{^/home/([^/]+)/public_html/(.*)$}{/priv/$1/$2};
-
+            my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
+            ($escurl = $env{'request.filename'}) =~ s{^\Q$londocroot\E}{};
             $escurl  = &escape($escurl);
         }    
         $menu =~ s/\[url\]/$escurl/g;
@@ -382,57 +429,39 @@ sub secondary_menu {
     return "<ul id=\"LC_secondary_menu\">$menu</ul>";
 }
 
-sub show_return_link {
-    if (($env{'request.noversionuri'} =~ m{^/adm/(viewclasslist|navmaps)($|\?)})
-        || ($env{'request.noversionuri'} =~ m{^/adm/.*/aboutme($|\?)})) {
-
-        return if ($env{'form.register'});
-    }
-    return (($env{'request.noversionuri'}=~m{^/(res|public)/} &&
-	     $env{'request.symb'} eq '')
-	    ||
-	    ($env{'request.noversionuri'}=~ m{^/cgi-bin/printout.pl})
-	    ||
-	    (($env{'request.noversionuri'}=~/^\/adm\//) &&
-	     ($env{'request.noversionuri'}!~/^\/adm\/wrapper\//) &&
-	     ($env{'request.noversionuri'}!~
-	      m[^/adm/.*/(smppg|bulletinboard)($|\?)])
-	     ));
-}
-
-
-sub registerurl {
-    my ($forcereg) = @_;
-    my $result = '';
-    if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { return ''; }
-    my $force_title='';
-    if ($env{'request.state'} eq 'construct') {
-	$force_title=&Apache::lonxml::display_title();
-    }
-    if (($env{'environment.remote'} eq 'off') ||
-        ((($env{'request.publicaccess'}) || 
-         (!&Apache::lonnet::is_on_map(
-	   &unescape($env{'request.noversionuri'})))) &&
-        (!$forcereg))) {
- 	return
-        $result
-       .'<script type="text/javascript">'."\n"
-       .'// <![CDATA['."\n"
-       .'function LONCAPAreg(){;} function LONCAPAstale(){}'."\n"
-       .'// ]]>'."\n"
-       .'</script>'
-       .$force_title;
+sub create_submenu {
+    my ($link,$target,$title,$submenu) = @_;
+    return unless (ref($submenu) eq 'ARRAY');
+    my $disptarget;
+    if ($target ne '') {
+        $disptarget = ' target="'.$target.'"';
+    }
+    my $menu = '<li class="LC_hoverable">'.
+               '<a href="'.$link.'"'.$disptarget.'>'. 
+               '<span class="LC_nobreak">'.&mt($title).
+               '<span class="LC_fontsize_small" style="font-weight:normal;">'.
+               ' &#9660;</span></span></a>'.
+               '<ul>';
+    my $count = 0;
+    my $numsub = scalar(@{$submenu});
+    foreach my $item (@{$submenu}) {
+        $count ++;
+        if (ref($item) eq 'ARRAY') {
+            my $borderbot;
+            if ($count == $numsub) {
+                $borderbot = 'border-bottom:1px solid black;';
+            }
+            $menu .= '<li style="margin:0;padding:0;'.
+                     $borderbot.'"><a href="'.$item->[0].'">'.
+                     &mt($item->[1]).'</a></li>';
+        }
     }
-# Graphical display after login only
-    if ($env{'request.registered'} && !$forcereg) { return ''; }
-    $result.=&innerregister($forcereg);
-    return $result.$force_title;
+    $menu .= '</ul></li>';
+    return $menu;
 }
 
 sub innerregister {
-    my ($forcereg,$titletable,$bread_crumbs) = @_;
-    my $result = '';
-    my ($uname,$thisdisfn);
+    my ($forcereg,$bread_crumbs) = @_;
     my $const_space = ($env{'request.state'} eq 'construct');
     my $is_const_dir = 0;
 
@@ -440,44 +469,26 @@ sub innerregister {
 
     $env{'request.registered'} = 1;
 
-    my $noremote = ($env{'environment.remote'} eq 'off');
-    
     undef(@inlineremote);
 
-    my $reopen=&Apache::lonmenu::reopenmenu();
+    my $resurl; 
+    if ( $env{'request.symb'} && $env{'request.course.id'} ) {
 
-    my $newmail='';
-
-    if (&Apache::lonmsg::newmail() && !$noremote) { 
-        # We have new mail and remote is up
-        $newmail= 'swmenu.setstatus("you have","messages");';
-    } 
-
-    my ($breadcrumb,$separator,$resurl);
-    if ($noremote
-	     && ($env{'request.symb'}) 
-	     && ($env{'request.course.id'})) {
-
-        (my $mapurl, my $rid,$resurl) = &Apache::lonnet::decode_symb(&Apache::lonnet::symbread());
+        (my $mapurl, my $rid, $resurl) = &Apache::lonnet::decode_symb(&Apache::lonnet::symbread());
         my $coursetitle = $env{'course.'.$env{'request.course.id'}.'.description'};
 
         my $maptitle = &Apache::lonnet::gettitle($mapurl);
         my $restitle = &Apache::lonnet::gettitle(&Apache::lonnet::symbread());
-        my $contentstext;
-        if ($env{'course.'.$env{'request.course.id'}.'.type'} eq 'Community') {
-            $contentstext = &mt('Community Contents');
-        } else {
-            $contentstext = &mt('Course Contents');
-        }
+
+#SD
+#course_type only Course and Community?
+#
         my @crumbs;
         unless (($forcereg) && ($env{'request.noversionuri'} eq '/adm/navmaps')
                 && ($mapurl eq $env{'course.'.$env{'request.course.id'}.'.url'})) {
-            my $navhref = "javascript:gopost('/adm/navmaps','')";
-            if ($env{'environment.remotenavmap'} eq 'on') {
-                 $navhref = "javascript:gonav('/adm/navmaps');";
-            }
-            @crumbs = ({text  => $contentstext,
-                        href  => $navhref});
+            @crumbs = ({text  => Apache::loncommon::course_type() 
+                                . ' Contents', 
+                        href  => "Javascript:gopost('/adm/navmaps','')"});
         }
         if ($mapurl ne $env{'course.'.$env{'request.course.id'}.'.url'}) { 
             push(@crumbs, {text  => '...',
@@ -492,29 +503,17 @@ sub innerregister {
 
         &Apache::lonhtmlcommon::clear_breadcrumbs();
         &Apache::lonhtmlcommon::add_breadcrumb(@crumbs);
-
-        #$breadcrumb .= &Apache::lonhtmlcommon::breadcrumbs(undef,undef,0);
-	unless (($env{'request.state'} eq 'edit') || ($newmail) ||
-		($env{'request.state'} eq 'construct') ||
-		($env{'form.register'})) {
-            $separator = &Apache::loncommon::head_subbox();
-        }
-        #
-    } elsif (!$const_space){
-        #a situation when we're looking at a resource outside of context of a
+    }elsif (! $const_space){
+        #a situation when we're looking at a resource outside of context of a 
         #course or construction space (e.g. with cumulative rights)
         &Apache::lonhtmlcommon::clear_breadcrumbs();
         &Apache::lonhtmlcommon::add_breadcrumb({text => 'View Resource'});
     }
-    if ($env{'request.state'} eq 'construct') {
-        $newmail = $titletable;
-    } 
-    my $timesync   = ( $noremote ? '' : 'swmenu.syncclock(1000*'.time.');' );
-    my $tablestart = ( $noremote ? '<table id="LC_menubuttons">' : '');
-    my $tableend   = ( $noremote ? '</table>' : '');
 # =============================================================================
 # ============================ This is for URLs that actually can be registered
-    if (($env{'request.noversionuri'}!~m{^/(res/)*adm/}) || ($forcereg)) {
+    return '' unless ( ($env{'request.noversionuri'}!~m{^/(res/)*adm/}) 
+                       || $forcereg );
+
 # -- This applies to homework problems for users with grading privileges
 	my $crs='/'.$env{'request.course.id'};
 	if ($env{'request.course.sec'}) {
@@ -524,23 +523,29 @@ sub innerregister {
 
         my $hwkadd='';
         if ($env{'request.symb'} ne '' &&
-	    $env{'request.filename'}=~/\.(problem|exam|quiz|assess|survey|form|task)$/) {
+	    $env{'request.filename'}=~/$LONCAPA::assess_re/) {
 	    if (&Apache::lonnet::allowed('mgr',$crs)) {
-		$hwkadd.=&switch('','',7,2,'pgrd.gif','problem[_1]','grades[_4]',
+		$hwkadd.=&switch('','',7,2,'pgrd.png','Content Grades','grades[_4]',
                        "gocmd('/adm/grades','gradingmenu')",
-                       'Modify user grades for this assessment resource');
+                       'Content Grades');
             } elsif (&Apache::lonnet::allowed('vgr',$crs)) {
-		$hwkadd.=&switch('','',7,2,'subm.gif','view sub-[_1]','missions[_1]',
+		$hwkadd.=&switch('','',7,2,'subm.png','Content Submissions','missions[_1]',
                        "gocmd('/adm/grades','submission')",
-		       'View user submissions for this assessment resource');
+		       'Content Submissions');
             }
 	}
 	if ($env{'request.symb'} ne '' &&
 	    &Apache::lonnet::allowed('opa',$crs)) {
-	    $hwkadd.=&switch('','',7,3,'pparm.gif','problem[_2]','parms[_2]',
+	    $hwkadd.=&switch('','',7,3,'pparm.png','Content Settings','parms[_2]',
 			     "gocmd('/adm/parmset','set')",
-			     'Modify parameter settings for this resource');
+			     'Content Settings');
 	}
+        if ($env{'request.symb'}=~/^uploaded/ &&
+            &Apache::lonnet::allowed('mdc',$crs)) {
+            $hwkadd.=&switch('','',7,4,'docs.png','Folder/Page Content','parms[_2]',
+                             "gocmd('/adm/coursedocs','direct')",
+                             'Folder/Page Content');
+        }
 # -- End Homework
         ###
         ### Determine whether or not to display the 'cstr' button for this
@@ -560,7 +565,7 @@ sub innerregister {
 #
                 # Set defaults for authors
                 my ($top,$bottom) = ('con-','struct');
-                my $action = "go('/priv/".$env{'user.name'}."');";
+                my $action = "go('/priv/".$env{'user.domain'}.'/'.$env{'user.name'}."');";
                 my $cadom  = $env{'request.role.domain'};
                 my $caname = $env{'user.name'};
                 my $desc = "Enter my construction space";
@@ -568,12 +573,12 @@ sub innerregister {
                 if ($env{'request.role'} =~ /^ca/) { 
                     ($cadom,$caname)=($env{'request.role'}=~/($match_domain)\/($match_username)$/);
                     ($top,$bottom) = ('co con-','struct');
-                    $action = "go('/priv/".$caname."');";
+                    $action = "go('/priv/".$cadom.'/'.$caname."');";
                     $desc = "Enter construction space as co-author";
                 } elsif ($env{'request.role'} =~ /^aa/) {
                     ($cadom,$caname)=($env{'request.role'}=~/($match_domain)\/($match_username)$/);
                     ($top,$bottom) = ('co con-','struct');
-                    $action = "go('/priv/".$caname."');";
+                    $action = "go('/priv/".$cadom.'/'.$caname."');";
                     $desc = "Enter construction space as assistant co-author";
                 }
                 # Check that we are on the correct machine
@@ -606,9 +611,13 @@ sub innerregister {
                     $uploaded = &is_course_upload($file,$cnum,$cdom);
                 }
                 if (!$uploaded) {
-                    $file=~s/^($match_domain)\/($match_username)/\/priv\/$2/;
+
+                    $file=~s{^(priv/$match_domain/$match_username)}{/$1};
+                    $file=~s{^($match_domain/$match_username)}{/priv/$1};
+
                     # Check that the user has permission to edit this resource
-                    ($cfuname,$cfudom)=&Apache::loncacc::constructaccess($file,$1);
+                    my $setpriv = 1;
+                    ($cfuname,$cfudom)=&Apache::loncacc::constructaccess($file,$setpriv);
                     if (defined($cfudom)) {
 		        $home=&Apache::lonnet::homeserver($cfuname,$cfudom);
 		        my $allowed=0;
@@ -638,7 +647,6 @@ sub innerregister {
                     my $bot = "go('$cfile')";
                     if ($switchserver) {
                         if ( $env{'request.symb'} && $env{'request.course.id'} ) {
-                            my ($mapurl,$rid,$resurl) = &Apache::lonnet::decode_symb(&Apache::lonnet::symbread());
                             $cfile = '/adm/switchserver?otherserver='.$home.'&amp;role='.
                                      &HTML::Entities::encode($env{'request.role'},'"<>&').'&amp;symb='.
                                      &HTML::Entities::encode($env{'request.symb'},'"<>&');
@@ -646,8 +654,8 @@ sub innerregister {
                         }
                     }
                     $editbutton=&switch
-                       ('','',6,1,'pcstr.gif','edit[_1]','resource[_2]',
-                       $bot,"Edit this resource");
+                       ('','',6,1,'pcstr.png','Edit','resource[_2]',
+                        $bot,"Edit this resource");
                     $noeditbutton = 0;
                 }
             } elsif ($editbutton eq '') {
@@ -662,7 +670,7 @@ sub innerregister {
                         my $cfile = &edit_course_upload($file,$cnum,$cdom);
                         if ($cfile) {
                             $editbutton=&switch
-                                        ('','',6,1,'pcstr.gif','edit[_1]',
+                                        ('','',6,1,'pcstr.png','Edit',
                                          'resource[_2]',"go('".$cfile."');",
                                          'Edit this resource');
                         }
@@ -690,9 +698,11 @@ sub innerregister {
 #
 # We are in construction space
 #
-	    my ($uname,$thisdisfn) =
-		($env{'request.filename'}=~m|^/home/([^/]+)/public_html/(.*)|);
-            my $currdir = '/priv/'.$uname.'/'.$thisdisfn;
+
+            my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
+	    my ($udom,$uname,$thisdisfn) =
+		($env{'request.filename'}=~m{^\Q$londocroot/priv/\E([^/]+)/([^/]+)/(.*)$});
+            my $currdir = '/priv/'.$udom.'/'.$uname.'/'.$thisdisfn;
             if ($currdir =~ m-/$-) {
                 $is_const_dir = 1;
             } else {
@@ -703,90 +713,76 @@ sub innerregister {
 # Probably should be in mydesk.tab
 #
                 $menuitems=(<<ENDMENUITEMS);
-s&6&1&list.gif&list[_1]&dir[_1]&golist('$esc_currdir')&List current directory
-s&6&2&rtrv.gif&retrieve[_1]&version[_1]&gocstr('/adm/retrieve','/~$uname/$cleandisfn')&Retrieve old version
-s&6&3&pub.gif&publish[_1]&resource[_3]&gocstr('/adm/publish','/~$uname/$cleandisfn')&Publish this resource
-s&7&1&del.gif&delete[_1]&resource[_2]&gocstr('/adm/cfile?action=delete','/~$uname/$cleandisfn')&Delete this resource
-s&7&2&prt.gif&prepare[_1]&printout[_1]&gocstr('/adm/printout','/~$uname/$cleandisfn')&Prepare a printable document
+s&6&1&list.png&Directory&dir[_1]&golist('$esc_currdir')&List current directory
+s&6&2&rtrv.png&Retrieve&version[_1]&gocstr('/adm/retrieve','/priv/$udom/$uname/$cleandisfn')&Retrieve old version
+s&6&3&pub.png&Publish&resource[_3]&gocstr('/adm/publish','/priv/$udom/$uname/$cleandisfn')&Publish this resource
+s&7&1&del.png&Delete&resource[_2]&gocstr('/adm/cfile?action=delete','/priv/$udom/$uname/$cleandisfn')&Delete this resource
+s&7&2&prt.png&Print&printout[_1]&gocstr('/adm/printout','/priv/$udom/$uname/$cleandisfn')&Prepare a printable document
 ENDMENUITEMS
             }
-            if ($noremote) {
                 if (ref($bread_crumbs) eq 'ARRAY') {
                     &Apache::lonhtmlcommon::clear_breadcrumbs();
                     foreach my $crumb (@{$bread_crumbs}){
                         &Apache::lonhtmlcommon::add_breadcrumb($crumb);
                     }
                 }
-            }
         } elsif ( defined($env{'request.course.id'}) && 
 		 $env{'request.symb'} ne '' ) {
 #
 # We are in a course and looking at a registred URL
 # Should probably be in mydesk.tab
 #
-
-            my %icon_text;
-            if ($noremote) {
-                %icon_text = &Apache::lonlocal::texthash (
-                               annotate => 'Notes',
-                               bookmark => 'Bookmark',
-                               catalog  => 'Info',
-                               evaluate => 'Evaluate',
-                               feedback => 'Communicate',
-                               printout => 'Print',
-                             );
-            }
 	    $menuitems=(<<ENDMENUITEMS);
 c&3&1
-s&2&1&back.gif&backward[_1]&&gopost('/adm/flip','back:'+currentURL)&Go to the previous resource in the course sequence&&1
-s&2&3&forw.gif&forward[_1]&&gopost('/adm/flip','forward:'+currentURL)&Go to the next resource in the course sequence&&3
+s&2&1&back.png&&&gopost('/adm/flip','back:'+currentURL)&Previous content resource&&1
+s&2&3&forw.png&&&gopost('/adm/flip','forward:'+currentURL)&Next content resource&&3
 c&6&3
 c&8&1
 c&8&2
-s&8&3&prt.gif&prepare[_1]&printout[_1]&gopost('/adm/printout',currentURL)&Prepare a printable document&&&$icon_text{'printout'}
-s&9&1&sbkm.gif&set[_1]&bookmark[_2]&set_bookmark()&Set a bookmark for this resource&&1&$icon_text{'bookmark'}
+s&8&3&prt.png&Print&printout[_1]&gopost('/adm/printout',currentURL)&Prepare a printable document
 ENDMENUITEMS
+            if (&Apache::lonnet::allowed('bre', $env{'request.course.id'}) eq 'F' && $env{'request.uri'} =~ /^\/res/) {
+                # wishlist is only available for users with access to resource-pool
+                # and links can only be set for resources within the resource-pool
+                $menuitems .= (<<ENDMENUITEMS);
+s&9&1&wishlist-link.png&Stored Links&wishlistlink[_2]&set_wishlistlink()&Save a link for this resource in your personal Stored Links repository&&1
+ENDMENUITEMS
+            }
 
 my $currentURL = &Apache::loncommon::get_symb();
 my ($symb_old,$symb_old_enc) = &Apache::loncommon::clean_symb($currentURL);
 my $annotation = &Apache::loncommon::get_annotation($symb_old,$symb_old_enc);
 $menuitems.="s&9&3&";
 if(length($annotation) > 0){
-	$menuitems.="anot2.gif";
+	$menuitems.="anot2.png";
 }else{
-	$menuitems.="anot.gif";
+	$menuitems.="anot.png";
 }
-$menuitems.="&anno-[_1]&tations[_1]&annotate()&";
-$menuitems.="Make notes and annotations about this resource&&1&$icon_text{'annotate'}\n";
+$menuitems.="&Notes&&annotate()&";
+$menuitems.="Make notes and annotations about this resource&&1\n";
 
-            unless ($noremote) { 
-                my $showreqcrs = &check_for_rcrs();
-                if ($showreqcrs) {
-                    $menuitems.="s&8&1&rcrs.gif&request[_1]&course[_16]".
-                                "&go('/adm/requestcourse')&Course requests\n";
-                }
-            }
             unless ($env{'request.noversionuri'}=~/\/(bulletinboard|smppg|navmaps|syllabus|aboutme|viewclasslist|portfolio)(\?|$)/) {
 		if ((!$env{'request.enc'}) && ($env{'request.noversionuri'} !~ m{^/adm/wrapper/ext/})) {
-                    my $tail;
-                    unless ($env{'request.state'} eq 'construct') {
-                        $tail = '&&&'.$icon_text{'catalog'};
-                    }
 		    $menuitems.=(<<ENDREALRES);
-s&6&3&catalog.gif&catalog[_2]&info[_1]&catalog_info()&Show Metadata$tail
+s&6&3&catalog.png&Info&info[_1]&catalog_info()&Show Metadata
 ENDREALRES
                 }
 	        $menuitems.=(<<ENDREALRES);
-s&8&1&eval.gif&evaluate[_1]&this[_1]&gopost('/adm/evaluate',currentURL,1)&Provide my evaluation of this resource&&&$icon_text{'evaluate'}
-s&8&2&fdbk.gif&feedback[_1]&discuss[_1]&gopost('/adm/feedback',currentURL,1)&Provide feedback messages or contribute to the course discussion about this resource&&&$icon_text{'feedback'}
+s&8&1&eval.png&Evaluate&this[_1]&gopost('/adm/evaluate',currentURL,1)&Provide my evaluation of this resource
+s&8&2&fdbk.png&Communicate&discuss[_1]&gopost('/adm/feedback',currentURL,1)&Provide feedback messages or contribute to the course discussion about this resource
 ENDREALRES
 	    }
         }
 	if ($env{'request.uri'} =~ /^\/res/) {
-            my $icontext = &mt('Print');
 	    $menuitems .= (<<ENDMENUITEMS);
-s&8&3&prt.gif&prepare[_1]&printout[_1]&gopost('/adm/printout',currentURL)&Prepare a printable document&&&$icontext
+s&8&3&prt.png&Print&printout[_1]&gopost('/adm/printout',currentURL)&Prepare a printable document
 ENDMENUITEMS
+            if (&Apache::lonnet::allowed('bre', $env{'request.course.id'}) eq 'F') {
+                # wishlist is only available for users with access to resource-pool
+                $menuitems .= (<<ENDMENUITEMS);
+s&9&1&wishlist-link.png&Stored Links&wishlistlink[_2]&set_wishlistlink()&Save a link for this resource in your personal Stored Links repository&&1
+ENDMENUITEMS
+            }
 	}
         my $buttons='';
         foreach (split(/\n/,$menuitems)) {
@@ -807,183 +803,47 @@ ENDMENUITEMS
             }
         }
 
-        if ($noremote) {
 	    my $addremote=0;
 	    foreach (@inlineremote) { if ($_ ne '') { $addremote=1; last;} }
-	    my $inlinebuttons='';
     if ($addremote) {
 
-        Apache::lonhtmlcommon::clear_breadcrumb_tools();
+        &Apache::lonhtmlcommon::clear_breadcrumb_tools();
 
-            Apache::lonhtmlcommon::add_breadcrumb_tool(
+            &Apache::lonhtmlcommon::add_breadcrumb_tool(
                 'navigation', @inlineremote[21,23]);
 
-        if(hidden_button_check() ne 'yes') {
-            Apache::lonhtmlcommon::add_breadcrumb_tool(
-                'tools', @inlineremote[93,91,81,82,83]);
+        my $countdown = &countdown_timer();
+        if (&hidden_button_check() eq 'yes') {
+            if ($countdown) {
+                &Apache::lonhtmlcommon::add_breadcrumb_tool('tools',$countdown);
+            }
+        } else {
+            my @tools = @inlineremote[93,91,81,82,83];
+            if ($countdown) {
+                unshift(@tools,$countdown);
+            }
+            &Apache::lonhtmlcommon::add_breadcrumb_tool(
+                'tools',@tools);
 
             #publish button in construction space
             if ($env{'request.state'} eq 'construct'){
-                Apache::lonhtmlcommon::add_breadcrumb_tool(
+                &Apache::lonhtmlcommon::add_breadcrumb_tool(
                      'advtools', $inlineremote[63]);
-            }else{
-                Apache::lonhtmlcommon::add_breadcrumb_tool(
+            } else {
+                &Apache::lonhtmlcommon::add_breadcrumb_tool(
                      'tools', $inlineremote[63]);
             }
-
+            
             unless ($env{'request.noversionuri'}=~ m{^/adm/(navmaps|viewclasslist)(\?|$)}) {
-                Apache::lonhtmlcommon::add_breadcrumb_tool(
-                    'advtools', @inlineremote[61,71,72,73,92]);
+                &Apache::lonhtmlcommon::add_breadcrumb_tool(
+                    'advtools', @inlineremote[61,71,72,73,74,92]);
             }
         }
-
-#       # Registered, textual output
-#        if ( $env{'environment.icons'} eq 'iconsonly' ) {
-#            $inlinebuttons = (<<ENDARROWSINLINE);
-#<tr><td>
-#$inlineremote[21] $inlineremote[23]
-#ENDARROWSINLINE
-#            if ( &hidden_button_check() ne 'yes' ) {
-#                $inlinebuttons .= (<<ENDINLINEICONS);
-#$inlineremote[61] $inlineremote[63]
-#$inlineremote[71] $inlineremote[72] $inlineremote[73]
-#$inlineremote[81] $inlineremote[82] $inlineremote[83]
-#$inlineremote[91] $inlineremote[92] $inlineremote[93]</td></tr>
-#ENDINLINEICONS
-#            }
-#        } else { # not iconsonly
-#            if ( $inlineremote[21] ne '' || $inlineremote[23] ne '' ) {
-#                $inlinebuttons = (<<ENDFIRSTLINE);
-#<tr><td>$inlineremote[21]</td><td>&nbsp;</td><td>$inlineremote[23]</td></tr>
-#ENDFIRSTLINE
-#            }
-#            if ( &hidden_button_check() ne 'yes' ) {
-#                foreach my $row ( 6 .. 9 ) {
-#                    if (   $inlineremote[ ${row} . '1' ] ne ''
-#                        || $inlineremote[ $row . '2' ] ne ''
-#                        || $inlineremote[ $row . '3' ] ne '' )
-#                    {
-#                        $inlinebuttons .= <<"ENDLINE";
-#<tr><td>$inlineremote["${row}1"]</td><td>$inlineremote["${row}2"]</td><td>$inlineremote["${row}3"]</td></tr>
-#ENDLINE
-#                    }
-#                }
-#            }
-#        }
     }
-        $breadcrumb = &Apache::lonhtmlcommon::breadcrumbs(undef,undef,0);
-	    $result =(<<ENDREGTEXT);
-<script type="text/javascript">
-// BEGIN LON-CAPA Internal
-</script>
-$timesync
-$breadcrumb
-<!-- $tablestart -->
-<!-- $inlinebuttons -->
-<!-- $tableend -->
-$newmail
-<!-- $separator -->
-<script type="text/javascript">
-// END LON-CAPA Internal
-</script>
-
-ENDREGTEXT
-# Registered, graphical output
-        } else {
-	    my $requri=&Apache::lonnet::clutter(&Apache::lonnet::fixversion((split(/\?/,$env{'request.noversionuri'}))[0]));
-	    $requri=&Apache::lonenc::check_encrypt(&unescape($requri));
-	    my $cursymb=&Apache::lonenc::check_encrypt($env{'request.symb'});
-	    my $navstatus=&get_nav_status();
-	    my $clearcstr;
-
-	    if ($env{'user.adv'}) { $clearcstr='clearbut(6,1)'; }
-	    $result = (<<ENDREGTHIS);
-     
-<script type="text/javascript">
-// <![CDATA[
-// BEGIN LON-CAPA Internal
-var swmenu=null;
-
-    function LONCAPAreg() {
-	  swmenu=$reopen;
-          swmenu.clearTimeout(swmenu.menucltim);
-          $timesync
-          $newmail
-          $buttons
-	  swmenu.currentURL="$requri";
-          swmenu.reloadURL=swmenu.currentURL+window.location.search;
-          swmenu.currentSymb="$cursymb";
-          swmenu.reloadSymb="$cursymb";
-          swmenu.currentStale=0;
-	  $navstatus
-          $hwkadd
-          $editbutton
-    }
-
-    function LONCAPAstale() {
-	  swmenu=$reopen
-          swmenu.currentStale=1;
-          if (swmenu.reloadURL!='' && swmenu.reloadURL!= null) { 
-             swmenu.switchbutton
-             (3,1,'reload.gif','return','location','go(reloadURL)','Return to the last known location in the course sequence');
-	  }
-          swmenu.clearbut(7,2);
-          swmenu.clearbut(7,3);
-          swmenu.menucltim=swmenu.setTimeout(
- 'clearbut(2,1);clearbut(2,3);clearbut(8,1);clearbut(8,2);clearbut(8,3);'+
- 'clearbut(9,1);clearbut(9,3);clearbut(6,3);$clearcstr',
-			  2000);
-      }
-
-// END LON-CAPA Internal 
-// ]]>
-</script>
-ENDREGTHIS
-        }
-# =============================================================================
-    } else {
-# ========================================== This can or will not be registered
-        if ($noremote) {
-# Not registered
-            $result= (<<ENDDONOTREGTEXT);
-ENDDONOTREGTEXT
-        } else {
-# Not registered, graphical
-           $result = (<<ENDDONOTREGTHIS);
-
-<script type="text/javascript">
-// <![CDATA[
-// BEGIN LON-CAPA Internal
-var swmenu=null;
 
-    function LONCAPAreg() {
-	  swmenu=$reopen
-          $timesync
-          swmenu.currentStale=1;
-          swmenu.clearbut(2,1);
-          swmenu.clearbut(2,3);
-          swmenu.clearbut(8,1);
-          swmenu.clearbut(8,2);
-          swmenu.clearbut(8,3);
-          if (swmenu.currentURL) {
-             swmenu.switchbutton
-              (3,1,'reload.gif','return','location','go(currentURL)');
- 	  } else {
-	      swmenu.clearbut(3,1);
-          }
-    }
-
-    function LONCAPAstale() {
-    }
-
-// END LON-CAPA Internal
-// ]]>
-</script>
-ENDDONOTREGTHIS
-       }
-# =============================================================================
-    }
-    return $result;
+    return   &Apache::lonhtmlcommon::scripttag('', 'start')
+           . &Apache::lonhtmlcommon::breadcrumbs(undef,undef,0)
+           . &Apache::lonhtmlcommon::scripttag('', 'end');
 }
 
 sub is_course_upload {
@@ -1022,19 +882,6 @@ sub edit_course_upload {
     return $cfile;
 }
 
-sub loadevents() {
-    if ($env{'request.state'} eq 'construct' ||
-	$env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { return ''; }
-    return 'LONCAPAreg();';
-}
-
-sub unloadevents() {
-    if ($env{'request.state'} eq 'construct' ||
-	$env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { return ''; }
-    return 'LONCAPAstale();';
-}
-
-
 sub startupremote {
     my ($lowerurl)=@_;
     if ($env{'environment.remote'} eq 'off') {
@@ -1052,25 +899,25 @@ sub startupremote {
 var timestart;
 function wheelswitch() {
     if (typeof(document.wheel) != 'undefined') {
-	if (typeof(document.wheel.spin) != 'undefined') {
-	    var date=new Date();
-	    var waited=Math.round(30-((date.getTime()-timestart)/1000));
-	    document.wheel.spin.value=$message;
-	}
+        if (typeof(document.wheel.spin) != 'undefined') {
+            var date=new Date();
+            var waited=Math.round(30-((date.getTime()-timestart)/1000));
+            document.wheel.spin.value=$message;
+        }
     }
-   if (window.status=='|') { 
-      window.status='/'; 
+   if (window.status=='|') {
+      window.status='/';
    } else {
       if (window.status=='/') {
          window.status='-';
       } else {
-         if (window.status=='-') { 
-            window.status='\\\\'; 
+         if (window.status=='-') {
+            window.status='\\\\';
          } else {
             if (window.status=='\\\\') { window.status='|'; }
          }
       }
-   } 
+   }
 }
 
 // ---------------------------------------------------------- The wait function
@@ -1081,9 +928,9 @@ function wait() {
       if (tim==0) {
          clearTimeout(canceltim);
          $configmenu
-         window.location='$lowerurl';  
+         window.location='$lowerurl';
       } else {
-	  window.location='/adm/remote?action=collapse&url=$esclowerurl';
+          window.location='/adm/remote?action=collapse&url=$esclowerurl';
       }
    } else {
       wheelswitch();
@@ -1157,13 +1004,13 @@ sub reopenmenu {
    my $menuname = &get_menu_name();
    my $nothing = &Apache::lonhtmlcommon::javascript_nothing();
    return('window.open('.$nothing.',"'.$menuname.'","",false);');
-} 
+}
 
 
 sub open {
     my $returnval='';
-    if ($env{'environment.remote'} eq 'off') { 
-	return
+    if ($env{'environment.remote'} eq 'off') {
+        return
         '<script type="text/javascript">'."\n"
        .'// <![CDATA['."\n"
        .'self.name="loncapaclient";'."\n"
@@ -1171,7 +1018,7 @@ sub open {
        .'</script>';
     }
     my $menuname = &get_menu_name();
-    
+
 #    unless (shift eq 'unix') {
 # resizing does not work on linux because of virtual desktop sizes
 #       $returnval.=(<<ENDRESIZE);
@@ -1197,13 +1044,8 @@ ENDOPEN
 
 sub clear {
     my ($row,$col)=@_;
-    unless ($env{'environment.remote'} eq 'off') {
-       if (($row<1) || ($row>13)) { return ''; }
-       return "\n".qq(window.status+='.';swmenu.clearbut($row,$col););
-   } else { 
-       $inlineremote[10*$row+$col]='';
-       return ''; 
-   }
+    $inlineremote[10*$row+$col]='';
+    return ''; 
 }
 
 # ============================================ Switch a button or create a link
@@ -1211,39 +1053,25 @@ sub clear {
 # The javascript is usually similar to "go('/adm/roles')" or "cstrgo(..)".
 
 sub switch {
-    my ($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat,$nobreak,$inlinetools)=@_;
+    my ($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat,$nobreak)=@_;
     $act=~s/\$uname/$uname/g;
     $act=~s/\$udom/$udom/g;
     $top=&mt($top);
     $bot=&mt($bot);
     $desc=&mt($desc);
-    if (($env{'environment.remote'} ne 'off') || ($env{'environment.icons'} eq 'classic')) {
-       $img=&mt($img);
-    }
     my $idx=10*$row+$col;
-    if ($cat ne '') {
-        $category_members{$cat}.=':'.$idx;
-    }
+    $category_members{$cat}.=':'.$idx;
 
-    unless ($env{'environment.remote'} eq 'off') {
-       if (($row<1) || ($row>13)) { return ''; }
-# Remote
-       return "\n".
- qq(window.status+='.';swmenu.switchbutton($row,$col,"$img","$top","$bot","$act","$desc"););
-   } else {
-# Inline Remote
-       if ($env{'environment.icons'} ne 'classic') {
-          $img=~s/\.gif$/\.png/;
-       }
-       if ($nobreak==2) { return ''; }
-       my $text=$top.' '.$bot;
-       $text=~s/\s*\-\s*//gs;
+# Inline Menu
+    if ($nobreak==2) { return ''; }
+    my $text=$top.' '.$bot;
+    $text=~s/\s*\-\s*//gs;
 
-       my $pic=
+    my $pic=
 	   '<img alt="'.$text.'" src="'.
 	   &Apache::loncommon::lonhttpdurl('/res/adm/pages/'.$img).
 	   '" align="'.($nobreak==3?'right':'left').'" class="LC_icon" />';
-       if ($env{'browser.interface'} eq 'faketextual') {
+    if ($env{'browser.interface'} eq 'faketextual') {
 # Main Menu
 	   if ($nobreak==3) {
 	       $inlineremote[$idx]="\n".
@@ -1262,21 +1090,22 @@ sub switch {
 		   '</a></td><td class="LC_menubuttons_text" colspan="3">'.
 		   '<a class="LC_menubuttons_link" href="javascript:'.$act.';"><span class="LC_menubuttons_inline_text">'.$desc.'</span></a></td></tr>';
 	   }
-       } else {
+    } else {
 # Inline Menu
-           if ($env{'environment.icons'} eq 'iconsonly') {
-              $inlineremote[$idx]='<a title="'.$desc.'" href="javascript:'.$act.';">'.$pic.'</a>';
-           } else {
-              my $icon_text = $desc;
-              if ($inlinetools) {
-                  $icon_text = $inlinetools.'&nbsp;';
-              }
-	      $inlineremote[$idx]=
-		   '<a title="'.$desc.'" class="LC_menubuttons_link" href="javascript:'.$act.';">'.$pic.
-		   '<span class="LC_menubuttons_inline_text">'.$icon_text.'&nbsp;</span></a>';
-           }
-       }
-   }
+        my @tools = (93,91,81,82,83);
+        unless ($env{'request.state'} eq 'construct') {
+            push(@tools,63);
+        }
+        if (($env{'environment.icons'} eq 'iconsonly') &&
+            (grep(/^$idx$/,@tools))) {
+            $inlineremote[$idx] =
+        '<a title="'.$desc.'" class="LC_menubuttons_link" href="javascript:'.$act.';">'.$pic.'</a>';
+        } else {
+            $inlineremote[$idx] =
+       '<a title="'.$desc.'" class="LC_menubuttons_link" href="javascript:'.$act.';">'.$pic.
+       '<span class="LC_menubuttons_inline_text">'.$top.'&nbsp;</span></a>';
+        }
+    }
     return '';
 }
 
@@ -1294,13 +1123,6 @@ sub secondlevel {
     return $output;
 }
 
-sub openmenu {
-    my $menuname = &get_menu_name();
-    if ($env{'environment.remote'} eq 'off') { return ''; }
-    my $nothing = &Apache::lonhtmlcommon::javascript_nothing();
-    return "window.open(".$nothing.",'".$menuname."');";
-}
-
 sub inlinemenu {
     undef(@inlineremote);
     undef(%category_members);
@@ -1343,13 +1165,7 @@ sub rawconfig {
 #
     my $textualoverride=shift;
     my $output='';
-    unless ($env{'environment.remote'} eq 'off') {
-       $output.=
- "window.status='Opening Remote Control';var swmenu=".&openmenu().
-"\nwindow.status='Configuring Remote Control ';";
-    } else {
-       unless ($textualoverride) { return ''; }
-    }
+    return '' unless $textualoverride;
     my $uname=$env{'user.name'};
     my $udom=$env{'user.domain'};
     my $adv=$env{'user.adv'};
@@ -1373,13 +1189,6 @@ sub rawconfig {
         my ($row,$col,$pro,$prt,$img,$top,$bot,$act,$desc,$cat)=split(/\:/,$line);
         $prt=~s/\$uname/$uname/g;
         $prt=~s/\$udom/$udom/g;
-        if ($env{'environment.remotenavmap'} eq 'on') {
-             unless ($env{'environment.remote'} eq 'on') {
-                 if ($img eq 'nav.gif') {
-                     $act = "gonav('/adm/navmaps','')";
-                 }
-             }
-        }
         if ($prt =~ /\$crs/) {
             next unless ($env{'request.course.id'});
             next if ($crstype eq 'Community');
@@ -1493,6 +1302,7 @@ sub rawconfig {
                                ($env{'request.role'}=~/($match_domain)\/($match_username)$/);
                     }                       
                     $act =~ s/\$caname/$caname/g;
+                    $act =~ s/\$cadom/$cadom/g;
                     my $home = &Apache::lonnet::homeserver($caname,$cadom);
 		    my $allowed=0;
 		    my @ids=&Apache::lonnet::current_machine_ids();
@@ -1530,13 +1340,6 @@ sub rawconfig {
           $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
         }
     }
-    unless ($env{'environment.remote'} eq 'off') {
-       $output.="\nwindow.status='Synchronizing Time';swmenu.syncclock(1000*".time.");\nwindow.status='Remote Control Configured.';";
-       if (&Apache::lonmsg::newmail()) { 
-	   $output.='swmenu.setstatus("you have","messages");';
-       }
-    }
-
     return $output;
 }
 
@@ -1584,29 +1387,6 @@ window.status='Done.';
 ENDCLOSE
 }
 
-# ====================================================================== Footer
-
-sub footer {
-
-}
-
-sub nav_control_js {
-    my $nav=($env{'environment.remotenavmap'} eq 'on');
-    return (<<NAVCONTROL);
-    var w_loncapanav_flag="$nav";
-
-
-function gonav(url) {
-   if (w_loncapanav_flag != 1) {
-      gopost(url,'');
-   }  else {
-      navwindow=window.open(url,
-                  "loncapanav","height=600,width=400,scrollbars=1"); 
-   }
-}
-NAVCONTROL
-}
-
 sub dc_popup_js {
     my %lt = &Apache::lonlocal::texthash(
                                           more => '(More ...)',
@@ -1618,13 +1398,13 @@ function showCourseID() {
     document.getElementById('dccid').style.display='block';
     document.getElementById('dccid').style.textAlign='left';
     document.getElementById('dccid').style.textFace='normal';
-    document.getElementById('dccidtext').innerHTML ='<a href="javascript:hideCourseID();">$lt{'less'}</a>';
+    document.getElementById('dccidtext').innerHTML ='<a href="javascript:hideCourseID();" class="LC_menubuttons_link">$lt{'less'}</a>';
     return;
 }
 
 function hideCourseID() {
     document.getElementById('dccid').style.display='none';
-    document.getElementById('dccidtext').innerHTML ='<a href="javascript:showCourseID()">$lt{'more'}</a>';
+    document.getElementById('dccidtext').innerHTML ='<a href="javascript:showCourseID()" class="LC_menubuttons_link">$lt{'more'}</a>';
     return;
 }
 
@@ -1632,22 +1412,36 @@ END
 
 }
 
+sub countdown_toggle_js {
+    return <<"END";
+
+function toggleCountdown() {
+    var countdownid = document.getElementById('duedatecountdown');
+    var currstyle = countdownid.style.display;
+    if (currstyle == 'inline') {
+        countdownid.style.display = 'none';
+        document.getElementById('ddcountcollapse').innerHTML='';
+        document.getElementById('ddcountexpand').innerHTML='&#9668;&nbsp;';
+    } else {
+        countdownid.style.display = 'inline';
+        document.getElementById('ddcountcollapse').innerHTML='&#9658;&nbsp;';
+        document.getElementById('ddcountexpand').innerHTML='';
+    }
+    return;
+}
+
+END
+}
+
 sub utilityfunctions {
-    my $caller = shift;
-    unless ($env{'environment.remote'} eq 'off' || 
-            $caller eq '/adm/menu') { 
-            return ''; }
-            
     my $currenturl=&Apache::lonnet::clutter(&Apache::lonnet::fixversion((split(/\?/,$env{'request.noversionuri'}))[0]));
-    if ($currenturl =~ m{^/adm/wrapper/ext/}) {
-        if ($env{'request.external.querystring'}) {
+    if ($currenturl =~ m{^/adm/wrapper/ext/}
+        && $env{'request.external.querystring'} ) {
             $currenturl .= ($currenturl=~/\?/)?'&':'?'.$env{'request.external.querystring'};
-        }
     }
     $currenturl=&Apache::lonenc::check_encrypt(&unescape($currenturl));
     
     my $currentsymb=&Apache::lonenc::check_encrypt($env{'request.symb'});
-    my $nav_control=&nav_control_js();
 
     my $dc_popup_cid;
     if ($env{'user.adv'} && exists($env{'user.role.dc./'.
@@ -1667,25 +1461,20 @@ sub utilityfunctions {
     my $end_page_annotate = 
         &Apache::loncommon::end_page({'js_ready' => 1});
 
-    my $start_page_bookmark = 
-        &Apache::loncommon::start_page('Bookmarks',undef,
-				       {'only_body' => 1,
-					'js_ready'  => 1,
-					'bgcolor'   => '#BBBBBB',});
-
-    my $end_page_bookmark = 
-        &Apache::loncommon::end_page({'js_ready' => 1});
-
     my $confirm_switch = &mt("Editing requires switching to the resource's home server.").'\n'.
                          &mt('Switch server?');
 
+    my $esc_url=&escape($currenturl);
+    my $esc_symb=&escape($currentsymb);
+
+    my $countdown = &countdown_toggle_js();
+
 return (<<ENDUTILITY)
 
-    var currentURL="$currenturl";
-    var reloadURL="$currenturl";
-    var currentSymb="$currentsymb";
+    var currentURL=unescape("$esc_url");
+    var reloadURL=unescape("$esc_url");
+    var currentSymb=unescape("$esc_symb");
 
-$nav_control
 $dc_popup_cid
 
 function go(url) {
@@ -1699,7 +1488,7 @@ function go(url) {
 function need_switchserver(url) {
     if (url!='' && url!= null) {
         if (confirm("$confirm_switch")) {
-            go(url);
+            go(url); 
         }
     }
     return;
@@ -1777,7 +1566,7 @@ function golist(url) {
 
 
 function catalog_info() {
-   loncatinfo=window.open(window.location.pathname+'.meta',"LONcatInfo",'height=320,width=280,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no');
+   openMyModal(window.location.pathname+'.meta',500,400,'yes');
 }
 
 function chat_win() {
@@ -1790,13 +1579,6 @@ function group_chat(group) {
    grpchat=window.open(url,winName,'height=320,width=280,resizable=yes,location=no,menubar=no,toolbar=no');
 }
 
-function edit_bookmarks() {
-   go('');
-   w_BookmarkPal_flag=1;
-   bookmarkpal=window.open("/adm/bookmarks",
-               "BookmarkPal", "width=500,height=505,scrollbars=0");
-}
-
 function annotate() {
    w_Annotator_flag=1;
    annotator=window.open('','Annotator','width=365,height=265,scrollbars=0');
@@ -1810,28 +1592,35 @@ function annotate() {
    annotator.document.close();
 }
 
-function set_bookmark() {
-   go('');
-   clienttitle=document.title;
-   clienthref=location.pathname;
-   w_bmquery_flag=1;
-   bmquery=window.open('','bmquery','width=365,height=165,scrollbars=0');
-   bmquery.document.write(
-   '$start_page_bookmark'
-   +'<center><form method="post"'
-   +' name="newlink" action="/adm/bookmarks" target="bmquery" '
-   +'> <table width="340" height="150" '
-   +'bgcolor="#FFFFFF" align="center"><tr><td>Link Name:<br /><input '
-   +'type="text" name="title" size="45" value="'+clienttitle+'" />'
-   +'<br />Address:<br /><input type="text" name="address" size="45" '
-   +'value="'+clienthref+'" /><br /><center><input type="submit" '
-   +'value="Save" /> <input type="button" value="Close" '
-   +'onclick="javascript:window.close();" /></center></td>'
-   +'</tr></table></form></center>'
-   +'$end_page_bookmark' );
-   bmquery.document.close();
+function open_StoredLinks_Import(rat) {
+   var newWin;
+   if (rat) {
+       newWin = window.open('/adm/wishlist?inhibitmenu=yes&mode=import&rat='+rat,
+                            'wishlistImport','scrollbars=1,resizable=1,menubar=0');
+   }
+   else {
+       newWin = window.open('/adm/wishlist?inhibitmenu=yes&mode=import',
+                            'wishlistImport','scrollbars=1,resizable=1,menubar=0');
+   }
+   newWin.focus();
 }
 
+(function (\$) {
+  \$(document).ready(function () {
+    \$.single=function(a){return function(b){a[0]=b;return a}}(\$([1]));
+    /*\@cc_on
+      if (!window.XMLHttpRequest) {
+        \$('.LC_hoverable').each(function () {
+          this.attachEvent('onmouseenter', function (evt) { \$.single(evt.srcElement).addClass('hover'); });
+          this.attachEvent('onmouseleave', function (evt) { \$.single(evt.srcElement).removeClass('hover'); });
+        });
+      }
+    \@*/
+  });
+}(jQuery));
+
+$countdown
+
 ENDUTILITY
 }
 
@@ -1864,23 +1653,10 @@ sub constspaceform {
 ENDCONSTSPACEFORM
 }
 
-
-sub get_nav_status {
-    my $navstatus="swmenu.w_loncapanav_flag=";
-    if ($env{'environment.remotenavmap'} eq 'on') {
-	$navstatus.="1";
-    } else {
-	$navstatus.="-1";
-    }
-    return $navstatus;
-}
-
 sub hidden_button_check {
-    my $hidden;
-    if ($env{'request.course.id'} eq '') {
-        return;
-    }
-    if ($env{'request.role.adv'}) {
+    if ( $env{'request.course.id'} eq ''
+         || $env{'request.role.adv'} ) {
+
         return;
     }
     my $buttonshide = &Apache::lonnet::EXT('resource.0.buttonshide');
@@ -2010,8 +1786,8 @@ sub get_all_courseroles {
         &Apache::lonnet::is_cached_new('getcourseroles',$cdom.'_'.$cnum);
     if (defined($cached)) {
         if (ref($result) eq 'HASH') {
-            if ((ref($result->{'roles'}) eq 'HASH') &&
-                (ref($result->{'seccount'}) eq 'HASH') &&
+            if ((ref($result->{'roles'}) eq 'HASH') && 
+                (ref($result->{'seccount'}) eq 'HASH') && 
                 (ref($result->{'privs'}) eq 'HASH')) {
                 %{$courseroles} = %{$result->{'roles'}};
                 %{$seccount} = %{$result->{'seccount'}};
@@ -2232,6 +2008,8 @@ sub required_privs {
              '/adm/populate'     => 'cst',
              '/adm/trackstudent' => 'vsa',
              '/adm/statistics'   => 'vgr',
+             '/adm/setblock'     => 'dcm',
+             '/adm/coursedocs'   => 'mdc',
            };
     unless ($env{'course.'.$env{'request.course.id'}.'.grading'} eq 'spreadsheet') {
         $privs->{'/adm/classcalc'}   = 'vgr',
@@ -2241,6 +2019,52 @@ sub required_privs {
     return $privs;
 }
 
+sub countdown_timer {
+    if (($env{'request.course.id'}) && ($env{'request.symb'} ne '') &&
+        ($env{'request.filename'}=~/$LONCAPA::assess_re/) &&
+        ($Apache::inputtags::status[-1] eq 'CAN_ANSWER')) {
+        my $duedate = &Apache::lonnet::EXT("resource.0.duedate");
+        my @interval=&Apache::lonnet::EXT("resource.0.interval");
+        my $hastimeleft;
+        if (@interval > 1) {
+            my $first_access=&Apache::lonnet::get_first_access($interval[1]);
+            if ($first_access > 0) {
+                if ($first_access+$interval[0] > time) {
+                    $hastimeleft = 1;
+                }
+            }
+        }
+        if (($duedate && $duedate > time) ||
+            (!$duedate && $hastimeleft)) {
+            my ($collapse,$expand,$alttxt,$title,$currdisp);
+            if (@interval > 1 && $hastimeleft) {
+                $currdisp = 'inline';
+                $collapse = '&#9658;&nbsp;';
+            } else {
+                $currdisp = 'none';
+                $expand = '&#9668;&nbsp;';
+            }
+            unless ($env{'environment.icons'} eq 'iconsonly') {
+                $alttxt = &mt('Timer');
+                $title = $alttxt.'&nbsp;';
+            }
+            my $desc = &mt('Countdown to due date/time');
+            return <<END;
+
+<a href="javascript:toggleCountdown();" class="LC_menubuttons_link">
+<span id="ddcountcollapse" class="LC_menubuttons_inline_text">
+$collapse
+</span></a>
+<span id="duedatecountdown" class="LC_menubuttons_inline_text" style="display: $currdisp;"></span>
+<a href="javascript:toggleCountdown();" class="LC_menubuttons_link">
+<span id="ddcountexpand" class="LC_menubuttons_inline_text" >$expand</span>
+<img src="/res/adm/pages/timer.png" title="$desc" class="LC_icon" alt="$alttxt" /><span class="LC_menubuttons_inline_text">$title</span></a>
+END
+        }
+    }
+    return;
+}
+
 # ================================================================ Main Program
 
 BEGIN {
@@ -2259,9 +2083,15 @@ BEGIN {
                     } elsif ($configline=~/^prim\:/) {
                         my @entries = (split(/\:/, $configline))[1..5];
                         push @primary_menu, \@entries;
+                    } elsif ($configline=~/^primsub\:/) {
+                        my ($parent,@entries) = (split(/\:/, $configline))[1..4];
+                        push (@{$primary_submenu{$parent}},\@entries);
                     } elsif ($configline=~/^scnd\:/) {
                         my @entries = (split(/\:/, $configline))[1..5];
                         push @secondary_menu, \@entries; 
+                    } elsif ($configline=~/^scndsub\:/) {
+                        my ($parent,@entries) = (split(/\:/, $configline))[1..4];
+                        push (@{$secondary_submenu{$parent}},\@entries);
                     } elsif ($configline) {
                         push(@desklines,$configline);
                     }