Index: gs3-extensions/html-to-expeditee/trunk/src/INSTALL-FOR-GREENSTONE3.sh
===================================================================
--- gs3-extensions/html-to-expeditee/trunk/src/INSTALL-FOR-GREENSTONE3.sh	(revision 26748)
+++ gs3-extensions/html-to-expeditee/trunk/src/INSTALL-FOR-GREENSTONE3.sh	(revision 26749)
@@ -25,7 +25,4 @@
 	> ../../web/WEB-INF/cgi/export-individual-expeditee.pl
 
-	cat src/cgi-bin/generate-collection-space.pl.in \
-    | sed "s%@FULL_PERL_EXE@%$FULL_PERL_EXE%g" \
-	> ../../web/WEB-INF/cgi/generate-collection-space.pl
 }
 
@@ -64,10 +61,2 @@
 	installPerlCGI
 fi
-
-if [ ! -f ../../web/WEB-INF/cgi/generate-collection-space.pl ] ; then
-	echo "Installing generate-collection-space.pl to cgi-bin directory"
-	installPerlCGI
-elif [ "src/cgi-bin/generate-collection-space.pl.in" -nt "../../web/WEB-INF/cgi/generate-collection-space.pl" ] ; then
-	echo "Installing latest version of generate-collection-space.pl to cgi-bin directory"
-	installPerlCGI
-fi
Index: gs3-extensions/html-to-expeditee/trunk/src/perllib/ExpediteeFrameIO.pm
===================================================================
--- gs3-extensions/html-to-expeditee/trunk/src/perllib/ExpediteeFrameIO.pm	(revision 26748)
+++ gs3-extensions/html-to-expeditee/trunk/src/perllib/ExpediteeFrameIO.pm	(revision 26749)
@@ -647,4 +647,7 @@
 	$y += 16; # y-value of text item in Expeditee is it's base line
 	$x += 4;
+	
+	my $link = $html_node->{'link'};
+	$attr->{'l'} = $link if defined $link;
 
 	my $data = $html_node->{'data'};
Index: gs3-extensions/html-to-expeditee/trunk/src/perllib/cgiactions/CollectionSpaceAction.pm
===================================================================
--- gs3-extensions/html-to-expeditee/trunk/src/perllib/cgiactions/CollectionSpaceAction.pm	(revision 26748)
+++ gs3-extensions/html-to-expeditee/trunk/src/perllib/cgiactions/CollectionSpaceAction.pm	(revision 26749)
@@ -49,5 +49,5 @@
 my $action_table =
 { 
-    "generate-frame"     => { 'compulsory-args' => [ "fn", "json" ],
+    "generate-frame"     => { 'compulsory-args' => [ "fn", "json","cl" ],
 			      'optional-args'   => [] }, 
 };
Index: gs3-extensions/html-to-expeditee/trunk/src/src/cgi-bin/generate-collection-space.pl.in
===================================================================
--- gs3-extensions/html-to-expeditee/trunk/src/src/cgi-bin/generate-collection-space.pl.in	(revision 26748)
+++ 	(revision )
@@ -1,294 +1,0 @@
-#!/cygdrive/c/strawberry/perl/bin/perl -w
-
-# Need to specify the full path of Perl above, e.g. for Windows something like
-#!C:\\Perl32\\bin\\perl -w
-
-use strict;
-
-# Set this to 1 to work around IIS 6 craziness
-my $iis6_mode = 0;
-
-
-# IIS 6: for some reason, IIS runs this script with the working directory set to the Greenstone
-#   directory rather than the cgi-bin directory, causing lots of stuff to fail
-if ($iis6_mode)
-{
-    # Change into cgi-bin directory
-    chdir("cgi-bin");
-}
-
-
-# We use require and an eval here (instead of "use") to catch any errors loading the module (for IIS)
-eval("require \"gsdlCGI.pm\"");
-if ($@)
-{
-    print STDOUT "Content-type:text/plain\n\n";
-    print STDOUT "ERROR: $@\n";
-    exit 0;
-}
-
-sub generate_html_form
-{
-	# First create an overlay frame containing CL links.
-
-	# Then create frames with document links and images.
-
-	my ($isGSDL2,$site,$collect,$cl) = @_;
-
-	my $html_form = <<EOT;
-<html>
-	<head>
-		<title>Generate Collection Space for $collect</title>
-		<base href=".."/>
-
-		<link type="text/css" href="ext/html-to-expeditee/jquery/css/le-frog/jquery-ui-1.8.16.custom.css" rel="stylesheet" />
-		<script type="text/javascript" src="ext/html-to-expeditee/jquery/js/jquery-1.6.2.min.js"></script>
-		<script type="text/javascript" src="ext/html-to-expeditee/jquery/js/jquery-ui-1.8.16.custom.min.js"></script>
-		<script type="text/javascript" src="ext/html-to-expeditee/js/gsajax-min.js"></script>
-		<script type="text/javascript" src="ext/html-to-expeditee/js/html-to-expeditee.js"></script>
-
-	</head>
-	<body>
-	<form class="ui-widget">
-	
-		<p style="font-size: 16px; width: 550px; text-align: justify;">Generate a Collection Space to make it easier to view documents in GlamED/Expeditee. Before running this script you must have already converted the Greenstone collection to an Expeditee frameset. If you have <b>NOT</b> done this, click <a href="html-to-expeditee.pl?site=$site&collect=$collect&cl=CL1" target="_blank">here</a></p>
-	
-		Generate a Collection Space for <input type="text" class="ui-corner-all" style="padding: 4px;" name="collect" value="$collect" id="collect"/> using the classifier <input type="text" class="ui-corner-all" style="padding: 4px;" name="cl" value="$cl" id="cl"/>
-		
-		<input value="$site" name="site" id="site" type="hidden"> <input value="Go" id="go" class="ui-button ui-widget ui-state-default ui-corner-all" type="submit">
-	</form>
-	
-	<script type="text/javascript">
-		var clPages = [];
-		var numClPages;
-	
-		\$(function(){
-			\$('#progress').progressbar();
-			
-			\$('#go').button().click(function(){
-				var collect = document.getElementById("collect").value;
-				
-				if(collect.match(/^\\s*\$/)){
-					alert("No collection specified");
-					return false;
-				}
-				
-				var cl = document.getElementById("cl").value;
-				if(cl.match(/^\\s*\$/)){
-					alert("No classifier specified");
-					return false;
-				}
-				
-				if(cl.match(/^\\d+\$/)){
-					cl = "CL" + cl;
-				}
-				
-				var gs2 = $isGSDL2;
-				
-				var url;
-				if(gs2){
-					url = "library.cgi";
-					url += "?c=" + collect + "&a=d&cl=" + cl;
-				}else{
-					url = "library";
-					url += "?c=" + collect + "&a=b&rt=s&s=ClassifierBrowse&cl=" + cl;
-					url += "&excerptid=gs_content";
-				}
-				
-				/* processing animation */
-				
-				clPages = [];
-				var outstandingURLs = [];
-				var visitedURLs = {};
-				
-				outstandingURLs.push(url);
-				visitedURLs[url] = 1;
-				
-				while(outstandingURLs.length>0){
-					
-					url = outstandingURLs.shift();
-					
-					var clHtml = urlGetSync(url);
-					
-					var aElems;
-					var workingTrav = document.getElementById("workingTraverse");
-					workingTrav.innerHTML = clHtml;
-					aElems = workingTrav.getElementsByTagName("a");
-					
-					var actionRE = new RegExp("(\\\\/)(?:document|browse)(\\\\/)");
-					var clRE = new RegExp("(\\\\/)browse\\\\/" + cl + "(\\\\/\\\\d+)+(\$)");
-					var docRE = new RegExp("(?:\\\\/)document\\\\/(.*?)(?:\$)");
-		  
-					for(var i = 0; i < aElems.length; i++){
-						var aElem = aElems[i];
-						var href = aElem.href;
-						
-						if(href && href.match(actionRE)){
-							if(href.match(clRE)){
-								if(!visitedURLs[href]){
-									var clPage = href;
-									console.log("Found a new cl link: " + clPage);
-									visitedURLs[clPage] = 1;
-									clPages.push(clPage);
-								}
-							}
-						}
-					}
-				}
-				
-				numClPages = clPages.length;
-				
-				var iframe = document.getElementById("iframe");
-				
-				var url = clPages.shift();
-				
-				iframe.src = url;
-				
-				var progressbar = document.getElementById("progressbar");
-				progressbar.style.dispay = "block";
-				
-				
-			return false; });
-		});
-		
-		function pageLoaded(){
-		
-			var iframe = document.getElementById("iframe");
-			
-			if(iframe.src){
-				if(iframe.style.display != "block"){
-					iframe.height = "90%";
-					iframe.style.display = "block";
-				}
-				
-				var iframeDoc;
-				
-				if(iframe.contentDocument){
-					/* FF */
-					iframeDoc = iframe.contentDocument;
-				}else if(iframe.contentWindow){
-					/* IE */
-					iframeDoc = iframe.contentWindow.document;
-				}
-				
-				var frameNum = (numClPages - clPages.length);
-				var progressPercent = frameNum/numClPages * 100;
-				
-				\$(function(){
-					\$('#progressbar').progressbar({ value: 0 });
-				});
-				
-				var gsContent = iframeDoc.getElementById("gs_content");
-				
-				//Need to change htmlToExpeditee code to account for links
-				var expFrameTree = htmlToExpeditee(gsContent);
-				var expFrame = JSON.stringify(expFrameTree);
-				
-				var collect = document.getElementById("collect").value;
-				var site = document.getElementById("site").value;
-				
-				var url = "cgi-bin/generate-collection-space.pl";
-				var params = "c=" + collect;
-				
-				if(site.match(/\\w/)){
-					params += "&site=" + site;
-				}
-				
-				params += "&a=generate-frame&fn=" + frameNum;
-				params += "&json=" + escape(expFrame);
-				
-				var clHtml = urlPostSync(url,params);
-				
-				if(!clHtml.match(/html-to-expeditee saved frame/)){
-					alert("Error processing url: " + url);s
-				}
-				
-				if(clPages.length > 0){
-					var clPage = clPages.shift();
-					
-					var cl = document.getElementById("cl").value;
-					
-					var gs2 = $isGSDL2;
-					
-					iframe.src = clPage;
-					console.log("iframe url: " + iframe.src + " ****");
-				}else{
-				
-					var progressbar = document.getElementById("progressbar");
-					progressbar.style.display = "none";
-					
-					iframe.style.display = "none";
-					delete iframe.src;
-				}
-				
-				
-			}
-			
-			
-		}
-	</script>
-
-	<div id="progressbar" width="100%" style="display: none; margin: 10px; height: 10px;"></div>
-	
-	<div id="workingTraverse" style="display: none"></div>
-	
-	<hr style="margin: 10px;">
-	
-	<iframe width="100%" id="iframe" style="display: none;" onload="pageLoaded()"></iframe>
-</body>
-</html>	
-EOT
-	
-	print "Content-type:text/html\n\n";
-	print $html_form;
-}
-
-sub main
-{
-	my $gsdl_cgi = new gsdlCGI();
-
-    # Load the Greenstone modules that we need to use
-    $gsdl_cgi->setup_gsdl();
-
-    my $gsdlhome = $ENV{'GSDLHOME'};    
-    $gsdl_cgi->checked_chdir($gsdlhome);
-
-    require cgiactions::CollectionSpaceAction;
-	
-	$gsdl_cgi->parse_cgi_args();
-
-	# We don't want the gsdlCGI module to return errors and warnings in XML
-    $gsdl_cgi->{'xml'} = 0;
-	
-	my $fn = $gsdl_cgi->clean_param("fn");
-	
-	if(defined $fn){
-		#Generate a frame.
-		my $action = new CollectionSpaceAction($gsdl_cgi,$iis6_mode);
-		$action->do_action();
-	}else{
-		my $collect = $gsdl_cgi->clean_param("collect");
-		my $cl = $gsdl_cgi->clean_param("cl");
-	
-		#Establish collect_dir using defining 'site' along the way if GS3
-		my $site = undef;
-		my $isGSDL2 = undef;
-	
-		if($gsdl_cgi->greenstone_version() == 2){
-			$isGSDL2 = 1;
-		}else{
-			$isGSDL2 = 0;
-		
-			#GS3 makes use of 'site'
-			$site = $gsdl_cgi->clean_param("site");
-		
-			if(!defined $site){
-				$gsdl_cgi->generate_error("No site specified.");
-			}
-		}
-	
-		generate_html_form($isGSDL2,$site,$collect,$cl);
-	}
-}
-
-&main();
Index: gs3-extensions/html-to-expeditee/trunk/src/src/cgi-bin/html-to-expeditee.pl.in
===================================================================
--- gs3-extensions/html-to-expeditee/trunk/src/src/cgi-bin/html-to-expeditee.pl.in	(revision 26748)
+++ gs3-extensions/html-to-expeditee/trunk/src/src/cgi-bin/html-to-expeditee.pl.in	(revision 26749)
@@ -1,7 +1,6 @@
- #!/cygdrive/c/strawberry/perl/bin/perl -w
+#!/cygdrive/c/strawberry/perl/bin/perl -w
 
 # Need to specify the full path of Perl above, e.g. for Windows something like
 #!C:\\Perl32\\bin\\perl -w
-
 
 use strict;
@@ -29,428 +28,505 @@
 }
 
-
 sub generate_html_form
 {
-    my ($isGSDL2,$site,$collect,$cl) = @_;
-
-    my $html_form = <<EOT;
-<html>
-  <head>
-    <title>HTML to Expeditee Frames</title>
-
-    <base href=".." />
-
-    <link type="text/css" href="ext/html-to-expeditee/jquery/css/le-frog/jquery-ui-1.8.16.custom.css" rel="stylesheet" />
-    <script type="text/javascript" src="ext/html-to-expeditee/jquery/js/jquery-1.6.2.min.js"></script>
-    <script type="text/javascript" src="ext/html-to-expeditee/jquery/js/jquery-ui-1.8.16.custom.min.js"></script>
-    <script type="text/javascript" src="ext/html-to-expeditee/js/gsajax-min.js"></script>
-    <script type="text/javascript" src="ext/html-to-expeditee/js/html-to-expeditee.js"></script>
-
-  </head>
-  <body>
-    <form class="ui-widget">
-      Convert the collection 
-        <input type="text" 
-	       class="ui-corner-all" style="padding: 4px;"
-	       name="collect" value="$collect" id="collect" />
-      to Expeditee frames by traversing the classifier 
-        <input type="text" 
-	       class="ui-corner-all" style="padding: 4px;"
-               name="cl" value="$cl" id="cl" />
-
-        <input value="$site" name="site" id="site" type="hidden">
+	my($isGSDL2,$site,$collect,$cl) = @_;
+	
+	# first generate the document frames
+	# then generate the classifier browsing frames.
+	
+	my $html_form = <<EOT;
+	<html>
+		<head>
+			<title>HTML To Expeditee Frames</title>
+			<base href=".."/>
+			
+			<link type="text/css" href="ext/html-to-expeditee/jquery/css/le-frog/jquery-ui-1.8.16.custom.css" rel="stylesheet" />
+			<script type="text/javascript" src="ext/html-to-expeditee/jquery/js/jquery-1.6.2.min.js"></script>
+			<script type="text/javascript" src="ext/html-to-expeditee/jquery/js/jquery-ui-1.8.16.custom.min.js"></script>
+			<script type="text/javascript" src="ext/html-to-expeditee/js/gsajax-min.js"></script>
+			<script type="text/javascript" src="ext/html-to-expeditee/js/html-to-expeditee.js"></script>
+		</head>
+		<body>
+			<form class="ui-widget">
+				Convert the collection <input type="text" class="ui-corner-all" style="padding: 4px;" name="collect" value="$collect" id="collect" /> to Expeditee frames by traversing the classifier <input type="text" class="ui-corner-all" style="padding: 4px;" name="cl" value="$cl" id="cl" />
+
+				<input value="$site" name="site" id="site" type="hidden">
         
-		<p>
-		<input type="checkbox" id="checkBoxBrowsing" name="generate_browsing" value="generate_browsing">Generate Collection Space<br/>
-		</p>
-		
-		<p style="font-weight: bold;">Extra Expeditee Frame Output Options:</p>
-		<input type="checkbox" id="checkBoxFont" name="compute_font" value="compute_font">Compute Font<br/>
-		<input type="checkbox" id="checkBoxWidth" name="compute_width" value="compute_width">Compute Width<br/>
-		
-		<p><input value="Go" id="go" class="ui-button ui-widget ui-state-default ui-corner-all" type="submit"><p>
-
-    </form>
-    <script type="text/javascript">
-      var docOIDs = [];
-      var numDocOIDs;
-	  var compute_font = false;
-	  var compute_width = false;
-	  var generate_browsing = false;	//whether to generate a matching browsing frameset
-	  
-      \$(function() {
-	  \$('#progress').progressbar();
-	  
-	  \$('#go').button().click(function() { 
-	      var collect = document.getElementById("collect").value;
-	      if (collect.match(/^\\s*\$/)) {
-		  alert("No collection specified");
-		  return false;
-	      }
-
-	      var cl = document.getElementById("cl").value;
-	      if (cl.match(/^\\s*\$/)) {
-		  alert("No classifier specified");
-		  return false;
-	      }
-	      if (cl.match(/^\\d+\$/)) {
-	          cl = "CL" + cl;
-	      }
-		  
-		  compute_font = document.getElementById("checkBoxFont").checked;
-		  compute_width = document.getElementById("checkBoxWidth").checked;
-		  
-		  generate_browsing = document.getElementById("checkBoxBrowsing").checked;
-		  
-	      var gs2=$isGSDL2;
-
-	      var url;
-	      if (gs2) {
-	          url = "library.cgi";
-		  url += "?c="+collect +"&a=d&cl=" + cl;
-	      }
-	      else {
-	          url = "library";
-	          url += "?c="+collect +"&a=b&rt=s&s=ClassifierBrowse&cl=" + cl;
-	          url += "&excerptid=gs_content";
-	      }
-		  
-		  console.log("*** CHECKING URL: " + url);
-
-	      /* processing animation */
-		  
-	      docOIDs = [];
-	      var outstandingURLs = [];
-	      var visitedURLs = {};
-
-	      outstandingURLs.push(url);
-	      visitedURLs[url] = 1;
-
-	      while (outstandingURLs.length>0) {
-		  url = outstandingURLs.shift();
-	      
-		  var clHtml = urlGetSync(url);
-		  		  
-		  var aElems;
-		  var workingTrav = document.getElementById("workingTraverse");
-		  workingTrav.innerHTML = clHtml;
-		  aElems = workingTrav.getElementsByTagName("a");
-		  
-		  
-		  /* any links with a=(b|d) ... cl=??? => outstandingURLS */
-		  /* any links with a=d ... d=???  => docOIDS */
-
-/*	      
-		  var actionRE = new RegExp("(\\\\?|&)a=(?:d|b)(&|\$)");
-		  var clRE     = new RegExp("(\\\\?|&)cl=" + cl + "(\\\\.\\\\d+)+(&|\$)");
-		  var docRE    = new RegExp("(?:\\\\?|&)d=(.*?)(?:&|\$)");
-*/
-		  var actionRE = new RegExp("(\\\\/)(?:document|browse)(\\\\/)");
-		  var clRE     = new RegExp("(\\\\/)browse\\\\/" + cl + "(\\\\/\\\\d+)+(\$)");
-		  var docRE    = new RegExp("(?:\\\\/)document\\\\/(.*?)(?:\$)");
-		  
-		  for (var i=0; i<aElems.length; i++) {
-		      var aElem = aElems[i];
-		      var href=aElem.href;
-		      if (href && href.match(actionRE)) {
-			  if (href.match(clRE)) {
-			      if (!visitedURLs[href]) {	     
-			          console.log("found a new CL line: " + href);
-			          outstandingURLs.push(href);
-				  visitedURLs[href] = 1;
-			      } 
-			  }
-			  else if (href.match(docRE)) {
-				if(!visitedURLs[href]){
-			      var docMatch = docRE.exec(href);
-			      var docOID = docMatch[1];
-
-			      console.log("found a new doc line: " + docOID);
-				  visitedURLs[href] = 1;
-			      docOIDs.push(docOID);
-			  }
-			  }
-		      }
-		  }
-	      }
-
-	      numDocOIDs = docOIDs.length;
-
-	      var iframe = document.getElementById("iframe");
-
-	      var docOID = docOIDs.shift();
-	      //console.log("doc oid = " + docOID);
-	      
-	      var url;
-	      if (gs2) {
-	          url = "library.cgi";
-	          url += "?c="+collect +"&a=d&d=" + docOID;
-	      }
-	      else {
-	          url = "library";
-	          url += "?c="+collect +"&a=d&d=" + docOID;
-	          
-			  /** The line below has been commented out. This is because the incorrect page is being loaded up in the iframe (i.e. just the document image and heading is being displayed but not any html customizations made in the collectionConfig.xml file**/
-			  //url += "&ed=1&dt=hierarchy";
-	          // url += "&excerptid=gs_content";
-	      }
-	      
-	      //url += "&p.showExpediteeAttributes=1";
-		  url += "&p.showAssocFilePath=1";
-
-		  
-	      /* load iframe with document drawn from Greenstone collection */
-	      iframe.src = url;
-	      
-	      var progressbar = document.getElementById("progressbar");
-	      progressbar.style.display = "block";
-
-
-	      return false; });
-	 });
-      
-      function pageLoaded() 
-      {
-	  var iframe = document.getElementById("iframe");	  
-	  
-	  if (iframe.src) {
-	      if (iframe.style.display != "block") {
-		  iframe.height = "90%";
-		  iframe.style.display = "block";
-	      }
-
-	      var iframeDoc;
-	      if ( iframe.contentDocument ) 
-	      { /* FF */
-		    iframeDoc = iframe.contentDocument;
-	      }
-	      else if ( iframe.contentWindow ) 
-	      { /* IE */
-		    iframeDoc = iframe.contentWindow.document;
-	      }
-		  
-		  var xmlUrl = iframe.src + "&o=xml";
-		  
-		  var iter = (numDocOIDs - docOIDs.length);
-	      var progressPercent = iter/numDocOIDs * 100;
-		  
-		  /*Check if a frame-id metadata element already exists, 
-		  otherwise generate a new frame number based on the 
-		  number of documents to process.*/
-		  var frameNum = getMetadata(xmlUrl,'frameID');
-		  
-		  if(frameNum === null){
-			frameNum = iter;
-		  }
-		  
-	      \$(function() {
-		  \$('#progressbar').progressbar({ value: progressPercent })
-		 });
-
-	      var gsContent = iframeDoc.getElementById("gs_content");
-
-	      /*
-	      var gsContentPos = getElementPosition(gsContent); 
-	      var pxl = gsContentPos.xl;
-	      var pxr = gsContentPos.xr;
-	      */
-		  
-		  //Check if an assocfilepath annotation already exists on the page, otherwise obtain it from the xml.
-		  var assocElem = iframeDoc.getElementById('assocfilepath');
-		  var assoc = null;
-		  
-		  if(assocElem === undefined || assocElem === null){
-			assoc = getMetadata(xmlUrl,'assocfilepath');
-		  }
-
-	      var expFrameTree = htmlToExpeditee(gsContent,compute_font,compute_width);
-
-	      var expFrame = JSON.stringify(expFrameTree);
-		  //console.log(expFrame);
-	      //alert(expFrame);
-
-	      var collect = document.getElementById("collect").value;
-	      var site    = document.getElementById("site").value;
-
-	      var url = "cgi-bin/html-to-expeditee.pl";
-	      var params = "c=" + collect;
-	      if (site.match(/\\w/)) {
-			params += "&site=" + site;
-   	      }
-		  
-	      //params += "&a=generate-frame&fn=" + iter;
-		  params += "&a=generate-frame&fn=" + frameNum;
-	      params += "&json=" + escape(expFrame);
-		  
-		  //add an assocfilepath parameter but only if it is defined.
-		  if(assoc !== null){
-			params += "&assoc=" + assoc;
-		  }
-		  
-		  params += "&compute-font=" + compute_font;
-
-	      var clHtml = urlPostSync(url,params);
-
-	      if (!clHtml.match(/html-to-expeditee saved frame/)) {
-			alert("Error processing url: " + url);
-	      }
-
-	      if (docOIDs.length>0) {
-		  var docOID = docOIDs.shift();
-		  
-		  // console.log("doc oid = " + docOID);
-
-		 // is the following line used ????
-		  var cl = document.getElementById("cl").value;
-		  
-		  var gs2 = $isGSDL2;
- 	      	  var url;
-
-	      	  if (gs2) {
-	              url = "library.cgi";
-	              url += "?c="+collect +"&a=d&d=" + docOID;
-	     	  }
-	     	  else {
-	              url = "library";
-	              url += "?c="+collect +"&a=d&d=" + docOID;
-	              
-				  /** Refer to comment earlier in this code in regards to the commented out line below.**/
-				  //url += "&ed=1&dt=hierarchy";
-	              // url += "&excerptid=gs_content";
-	     	  }
-
-		  //url += "&p.showExpediteeAttributes=1";
-			url += "&p.showAssocFilePath=1";
-		  
-			iframe.src = url;
-	      }
-	      else {
-			var progressbar = document.getElementById("progressbar");
-			progressbar.style.display = "none";
-
-			iframe.style.display = "none";
-			delete iframe.src;
-	      }
-	  }
-	 
-      }
-	  
-	/**
-	* This method is used at this stage to retrieve assocfilepath
-	* and frame number metadata values from the document's xml.
-	**/
-	function getMetadata(xmlUrl,nameValue){
-	  
-		var metadata = null;
-		
-		 \$.ajax({
-			type: "GET",
-			async: false,
-			url: xmlUrl,
-			dataType: "xml",
-			success: function(xml){
+				<p>
+					<input type="checkbox" id="checkBoxBrowsing" name="generate_browsing" value="generate_browsing">Generate Collection Space<br/>
+				</p>
+		
+				<p style="font-weight: bold;">Extra Expeditee Frame Output Options:</p>
+				<input type="checkbox" id="checkBoxFont" name="compute_font" value="compute_font">Compute Font<br/>
+				<input type="checkbox" id="checkBoxWidth" name="compute_width" value="compute_width">Compute Width<br/>
+		
+				<p><input value="Go" id="go" class="ui-button ui-widget ui-state-default ui-corner-all" type="submit"></p>
+				</form>
 				
-								
-				\$(xml).find('metadata').each(function(){
-					
-					var name = \$(this).attr('name');
-					
-					if(name === nameValue){
-						if(metadata === null){
-							metadata = \$(this).text();
-							//console.log(metadata);
-						}
-						
-					}	
-				});
+				<script type="text/javascript">
+					var collect;
+					var site;
+					var cl;
+					var gs2;
+					
+					var docOIDs = [];
+					var clPages = [];
+					
+					var hashMapDocFrames = new Array();
+					
+					var numDocOIDs = 0;
+					var numClPages = 0;
+					
+					var currDocFrameNum;
+					var currClFrameNum;
+					
+					var compute_font = false;
+					var compute_width = false;
+					var generate_browsing = false;	//generate a matching collection space frameset
+					
+					\$(function(){
+						
+						\$('#progress').progressbar();
+						
+						\$('#go').button().click(function(){
+							
+							site = document.getElementById("site").value;
+							
+							collect = document.getElementById("collect").value;
+							
+							if(collect.match(/^\\s*\$/)){
+								alert("No collection specified");
+								return false;
+							}
+							
+							cl = document.getElementById("cl").value;
+							if(cl.match(/^\\s*\$/)){
+								alert("No classifier specified");
+								return false;
+							}
+							
+							compute_font = document.getElementById("checkBoxFont").checked;
+							compute_width = document.getElementById("checkBoxWidth").checked;
+							
+							generate_browsing = document.getElementById("checkBoxBrowsing").checked;
+							
+							gs2=$isGSDL2;
+							
+							var url;
+							
+							/*obtain url for classifier/browse page and grab all links (doc and CL links) from this page.*/
+							if(gs2){
+								url = "library.cgi";
+								url += "?c="+collect +"&a=d&cl=" + cl;
+							}else{
+								url = "library";
+								url += "?c="+collect +"&a=b&rt=s&s=ClassifierBrowse&cl=" + cl;\
+								url += "&excerptid=gs_content";
+							}
+							
+							docOIDs = [];
+							clPages = [];
+							
+							var outstandingURLs = [];
+							var visitedURLs = {};
+							
+							outstandingURLs.push(url);
+							visitedURLs[url] = 1;
+							
+							while(outstandingURLs.length > 0){
+								url = outstandingURLs.shift();
+								
+								var clHtml = urlGetSync(url);
+								
+								var workingTrav = document.getElementById("workingTraverse");
+								workingTrav.innerHTML = clHtml;
+								
+								var aElems = workingTrav.getElementsByTagName("a");
+								
+								/* any links with (document|browse)=> outstandingURLS */
+								/* any links with (document|browse)/CL[0-9]/[0-9] => clPages */
+								/* any links with (document) => docOIDs */
+								
+								var actionRE = new RegExp("(\\\\/)(?:document|browse)(\\\\/)");
+								var clRE     = new RegExp("(\\\\/)browse\\\\/" + cl + "(\\\\/\\\\d+)+(\$)");
+								var docRE    = new RegExp("(?:\\\\/)document\\\\/(.*?)(?:\$)");
+								
+								for(var i = 0; i < aElems.length; i++){
+									var aElem = aElems[i];
+									var href = aElem.href;
+									
+									if(href && href.match(actionRE)){
+										if(href.match(clRE)){
+											if(!visitedURLs[href]){
+												console.log("found a new CL line: " + href);
+												outstandingURLs.push(href);
+												visitedURLs[href] = 1;
+												clPages.push(href);
+											}
+										}else if(href.match(docRE)){
+											if(!visitedURLs[href]){
+												var docMatch = docRE.exec(href);
+												var docOID = docMatch[1];
+												
+												console.log("found a new doc line: " + docOID);
+												visitedURLs[href] = 1;
+												docOIDs.push(docOID);
+											}
+										}
+									}
+								}
+							}
+							
+							numDocOIDs = docOIDs.length;
+							numClPages = clPages.length;
+							var iframe = document.getElementById('iframe');
+							
+							startProcessing(iframe);		//Process documents
+														
+							return false;
+						});
+						
+					});
+					
+					function startProcessing(iframe){
+						
+						var docOID = docOIDs.shift();
+						
+						iframe.src = getDocumentUrl(docOID);
+						
+						var progressbar = document.getElementById('progressbar');
+						progressbar.style.display = 'block';					
+					}
+					
+										
+					function pageLoaded(){
+						var iframe = document.getElementById("iframe");
+						
+						if(iframe.src){
+							
+							if(iframe.style.display != 'block'){
+								iframe.height = '90%';
+								iframe.style.display = 'block';
+							}
+							
+							var iframeDoc;
+							
+							if(iframe.contentDocument){ /* FF and Chrome */
+								iframeDoc = iframe.contentDocument;
+							}else if(iframe.contentWindow){	/* IE */
+								iframeDoc = iframe.contentWindow.document;
+							}
+						
+							/*Check url - if it's a doc Url, call "writeDocument", otherwise call "writeClPage"*/
+							var clRE = new RegExp("(\\\\/)browse\\\\/" + cl + "(\\\\/\\\\d+)+(\$)");
+							
+							
+							if(iframe.src.match(clRE)){
+								writeClPage(iframe,iframeDoc);
+							}else{
+								writeDocument(iframe,iframeDoc);
+							}
+						}
+					}
+					
+					function writeDocument(iframe,iframeDoc){
+						
+						var xmlUrl = iframe.src + "&o=xml";
+						
+						var iter = (numDocOIDs - docOIDs.length);
+						var progressPercent = iter/numDocOIDs * 100;
+						
+						var frameNum = getMetadata(xmlUrl,'frameID');
+						
+						if(frameNum == null){
+							frameNum = iter;
+						}
+						
+						//Add docOID and matching frame number to an associative array for later use.
+						hashMapDocFrames[docOID] = frameNum;
+						
+						\$(function(){
+							\$('#progressbar').progressbar({ value: progressPercent });
+						});
+						
+						var gsContent = iframeDoc.getElementById("gs_content");
+						
+						var assocElem = iframeDoc.getElementById("assocfilepath");
+						
+						var assocElem = iframeDoc.getElementById('assocfilepath');
+						var assoc = null;
+						
+						if(assocElem === undefined || assocElem === null){
+							assoc = getMetadata(xmlUrl,'assocfilepath');
+						}
+						
+						var expFrameTree = htmlToExpeditee(gsContent,compute_font,compute_width);
+						
+						var expFrame = JSON.stringify(expFrameTree);
+						//console.log(expFrame);
+						
+						var url = "cgi-bin/html-to-expeditee.pl";
+						var params = "c=" + collect;
+						
+						if(site.match(/\\w/)){
+							params += "&site=" + site;
+						}
+						
+						params += "&a=generate-frame&fn=" + frameNum;
+						params += "&json=" + escape(expFrame);
+						
+						//Add an assocfilepath but only if it is defined
+						if(assoc !== null){
+							params += "&assoc=" + assoc;
+						}
+						
+						params += "&compute-font=" + compute_font;
+												
+						params += "&page-type=" + "document";
+											
+						
+						var clHtml = urlPostSync(url,params);
+						
+						if(!clHtml.match(/html-to-expeditee saved frame/)){
+							alert("ERROR PROCESSING URL: " + url);
+						}
+						
+						if(docOIDs.length > 0){
+							var docOID = docOIDs.shift();
+							iframe.src = getDocumentUrl(docOID);
+							
+						}else{
+							//start writing CL pages.
+							if(generate_browsing){
+								numClPages = clPages.length;
+							
+								var url = clPages.shift();
+								iframe.src = url;
+								writeClPage(iframe,iframeDoc);
+							}else{
+								//We are finished
+								finish(iframe);
+							}
+						}	
+					}
+					
+					function getDocumentUrl(docOID){
+						var url;
+						
+						if(gs2){
+							url = "library.cgi";
+						}else{
+							url = "library";
+						}
+						
+						url += "?c=" + collect + "&a=d&d=" + docOID;
+										
+						url += "&p.showAssocFilePath = 1";
+						
+						return url;
+					}
+					
+					function writeClPage(iframe,iframeDoc){
+						
+						var frameNum = numClPages - clPages.length;
+						var progressPercent = frameNum / numClPages * 100;
+						
+						\$(function(){
+							\$('#progressbar').progressbar({ value: progressPercent });
+						});
+						
+						var gsContent = iframeDoc.getElementById("gs_content");
+						var gsContentChildren = gsContent.getElementsByTagName('*');
+						
+						var docRE    = new RegExp("(?:\\\\/)document\\\\/(.*?)(?:\$)");
+						
+						//get rid of rectangles around nodes.
+						for(var i = 0; i < gsContentChildren.length; i++){
+							var child = gsContentChildren[i];
+							
+							if(child.tagName !== "IMG"){
+								child.setAttribute('rect','norect');
+							}
+							
+							if(child.tagName === "A"){
+								var aElem = child;
+								var aElemSrc = aElem.href;
+								
+								//if aElemSrc is a document url, then extract docOID then access hash map and get matching frame number.
+								if(aElemSrc.match(docRE)){
+									var docMatch = docRE.exec(aElemSrc);
+									var docOID = docMatch[1];
+									console.log("*** " + docOID);
+									var frameNum = hashMapDocFrames[docOID];
+									var aElemChildren = aElem.getElementsByTagName('*');
+									
+									for(var j = 0; j < aElemChildren.length; j++){
+										var aElemChild = aElemChildren[j];
+										var frameName = collect + frameNum;
+										//console.log("*** " + frameName);
+										//aElemChild.setAttribute("link",frameName);
+										//console.log(aElemChild.link);
+									}
+									
+								}else{
+									//TODO: Check if the link is a CL link.
+									//TODO: Make a hashmap for storing CL page frame numbers?
+								}
+							}
+						}
+						
+						//add link attribute to children nodes of <a> elements.
+						
+						
+						//TODO: Need to change htmlToExpeditee code to account for links
+						
+						
+						var expFrameTree = htmlToExpeditee(gsContent);
+						var expFrame = JSON.stringify(expFrameTree);
+						//console.log(expFrame);
+						
+						var url = "cgi-bin/html-to-expeditee.pl";
+						var params = "c=" + collect;
+						
+						if(site.match(/\\w/)){
+							params += "&site=" + site;
+						}
+						
+						params += "&cl=" + cl;
+						params += "&a=generate-frame&fn=" + frameNum;
+						params += "&json=" + escape(expFrame);
+						params += "&page-type=" + "clPage";
+						
+						var clHtml = urlPostSync(url,params);
+						
+						if(!clHtml.match(/html-to-expeditee saved frame/)){
+							alert("Error processing url: " + url);
+						}
+						
+						if(clPages.length > 0){
+							var clPage = clPages.shift();
+							iframe.src = clPage;
+						}else{
+							finish(iframe);
+						}
+					}
+					
+					function finish(iframe){
+						var progressbar = document.getElementById("progressbar");
+						progressbar.style.display = "none";
+						
+						iframe.style.display = "none";
+						delete iframe.src;
+					}
+					
+					/**
+					* This method is used at this stage to retrieve assocfilepath and
+					* frame number metadata values from the document's xml.
+					**/
+					function getMetadata(xmlUrl,nameValue){
+						var metadata = null;
+						
+						\$.ajax({
+							type: "GET",
+							async: false,
+							url: xmlUrl,
+							dataType: "xml",
+							success: function(xml){
+								\$(xml).find('metadata').each(function(){
+									var name = \$(this).attr('name');
+									
+									if(name === nameValue){
+										if(metadata === null){
+											metadata = \$(this).text();
+										}
+									}
+								});
+							}
+						});
+						
+						return metadata;
+					}
+					
+				</script>
 				
+				<div id="progressbar" width="100%" style="display: none; margin: 10px; height: 10px;"></div>
+				
+				<div id="workingTraverse" style="display: none"></div>
+				
+				<hr style="margin: 10px;">
+				
+				<iframe width="100%" id="iframe" style="display:none;" onload="pageLoaded()"></iframe>
+	</body>	
+</html>			
+EOT
+
+	print "Content-type:text/html\n\n";
+	print $html_form;
+}
+
+sub main
+{
+	my $gsdl_cgi = new gsdlCGI();
+	
+	#Load GS modules
+	$gsdl_cgi->setup_gsdl();
+	
+	my $gsdlhome = $ENV{'GSDLHOME'};
+	$gsdl_cgi->checked_chdir($gsdlhome);
+	
+	#TODO: Refactor so we only need to use HtmlToExpediteeAction
+	require cgiactions::HtmlToExpediteeAction;
+	require cgiactions::CollectionSpaceAction;
+	
+	$gsdl_cgi->parse_cgi_args();
+	$gsdl_cgi->{'xml'} = 0;
+	
+	my $fn = $gsdl_cgi->clean_param("fn");
+	
+	if(defined $fn){
+		#page_type can have two values: "document" or "clPage"
+		my $page_type = $gsdl_cgi->clean_param("page-type");
+		
+		if(defined $page_type){
+			my $action;
+			
+			if($page_type eq "document"){
+				$action = new HtmlToExpediteeAction($gsdl_cgi,$iis6_mode);
+			}elsif($page_type eq "clPage"){
+				$action = new CollectionSpaceAction($gsdl_cgi,$iis6_mode);
+			}else{
+				$gsdl_cgi->generate_error("Invalid page type specified. Must be 'document' or 'clPage'");
 			}
 			
-		  });
-		
-		return metadata;
-	  }
-
-    </script>
-
-    <div id="progressbar" width="100%" 
-          style="display: none; margin: 10px; height: 10px;"></div>
-    <div id="workingTraverse" style="display: none"></div>
-
-    <hr style="margin: 10px;">
-
-    <iframe width="100%" id="iframe" style="display: none;" 
-            onload="pageLoaded()"></iframe>
-
-  </body>
-</html>
-EOT
-
-    print "Content-type:text/html\n\n";
-    print $html_form;
+			$action->do_action();
+		}else{
+			$gsdl_cgi->generate_error("No page type specified. Must be 'document' or 'clPage'");
+		}
+		
+	}else{
+		# generate html form
+		my $collect = $gsdl_cgi->clean_param("collect");
+		my $cl = $gsdl_cgi->clean_param("cl");
+		
+		#Establish collect_dir using defining 'site' along the way if GS3
+		my $site = undef;
+		my $isGSDL2 = undef;
+		
+		if($gsdl_cgi->greenstone_version() == 2){
+			$isGSDL2 = 1;
+		}else{
+			$isGSDL2 = 0;
+			
+			#GS3 (and possible future versions) make use of 'site'
+			$site = $gsdl_cgi->clean_param("site");
+			
+			if(!defined $site){
+				$gsdl_cgi->generate_error("No site specified.");
+			}	
+		}
+		
+		generate_html_form($isGSDL2,$site,$collect,$cl);
+	}
 }
 
-sub main
-{
-
-#    $ENV{'QUERY_STRING'} = "a=...";set-import-metadata&c=espresso-music&d=HASH012d6f72cde5dc48162f4a1d.1&metaname=annotation&metapos=0&metavalue=adfadfad";
-#    $ENV{'REQUEST_METHOD'} = "GET";
-
-    my $gsdl_cgi = new gsdlCGI();
-
-    # Load the Greenstone modules that we need to use
-    $gsdl_cgi->setup_gsdl();
-
-    my $gsdlhome = $ENV{'GSDLHOME'};    
-    $gsdl_cgi->checked_chdir($gsdlhome);
-
-    require cgiactions::HtmlToExpediteeAction;
-    
-    # Useful debug statement for seeing what packages have been included
-####    printf("%-45s%-s\n",$_,$INC{$_}) foreach (sort keys %INC);
-    
-    $gsdl_cgi->parse_cgi_args();
-
-    # We don't want the gsdlCGI module to return errors and warnings in XML
-    $gsdl_cgi->{'xml'} = 0;
-
-    my $fn = $gsdl_cgi->clean_param("fn");     # frame number
-
-    if (defined $fn) {
-
-	my $action = new HtmlToExpediteeAction($gsdl_cgi,$iis6_mode);
-
-	$action->do_action();
-    }
-    else {
-	# generate form, pre-filled out with any useful values such
-	# as the collection and classifier value 
-
-	my $collect = $gsdl_cgi->clean_param("collect");   
-	my $cl = $gsdl_cgi->clean_param("cl"); 
-		
-	# Establish collect_dir using defining 'site' along the way if GS3
-
-	my $site = undef; 
-	my $isGSDL2 = undef;
-
-	if ($gsdl_cgi->greenstone_version() == 2) { 
-	    $isGSDL2 = 1;
-	}
-	else {
-	    $isGSDL2 = 0;
-	    
-	    # GS3 (and possible future versions) make use of 'site'
-	    $site = $gsdl_cgi->clean_param("site");   
-	    if (!defined $site) {
-		$gsdl_cgi->generate_error("No site specified.");
-	    }
-	}
-
-	generate_html_form($isGSDL2,$site,$collect,$cl);
-    }
-}
-
-
-
 &main();
Index: gs3-extensions/html-to-expeditee/trunk/src/src/js/html-to-expeditee.js
===================================================================
--- gs3-extensions/html-to-expeditee/trunk/src/src/js/html-to-expeditee.js	(revision 26748)
+++ gs3-extensions/html-to-expeditee/trunk/src/src/js/html-to-expeditee.js	(revision 26749)
@@ -122,10 +122,4 @@
 		font_size = getStyle(node,'font-size');
 		font_color = getStyle(node,'color');
-		
-		/*console.log("Retrieving node: " + node);
-	
-		console.log("Retrieving font family: " + font_family);
-		console.log("Retrieving font size: " + font_size);
-		console.log("Retrieving font color: " + font_color);*/
 	}
 	
@@ -160,5 +154,13 @@
 	    jsonNode.xr = pxr;
 	    jsonNode.yb = pyb;
-
+		
+		var link = node.link;
+		if(link !== null && link !== undefined){
+			jsonNode.link = link;
+			console.log("Adding link");
+		}else{
+			console.log("no link found");
+		}
+		
 	    var parent = node.parentNode;
 		
@@ -203,9 +205,5 @@
 			var parentPos = getElementPosition(parent);
 			var parentWidth = parentPos.xr - parentPos.xl;
-						
-			/*console.log("parent.xl: " + parentPos.xl);
-			console.log("parent.xr: " + parentPos.xr);
-			console.log("parent width: " + parentWidth);*/
-			
+
 			jsonNode.width = parentWidth;
 		}
