Index: /main/trunk/greenstone2/perllib/cgiactions/metadataaction.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cgiactions/metadataaction.pm	(revision 27110)
+++ /main/trunk/greenstone2/perllib/cgiactions/metadataaction.pm	(revision 27111)
@@ -757,5 +757,5 @@
 			if(defined $parser->{'parameters'}->{'metapos'} && $parser->{'parameters'}->{'poscount'} == $parser->{'parameters'}->{'metapos'})
 			{
-				##print STDERR "**** got match!!\n";
+				##print STDERR "#### got match!!\n";
 				# Get the value and override the current value
 				my $metavalue = $parser->{'parameters'}->{'metavalue'};
@@ -778,4 +778,33 @@
 }
 
+# This method exists purely for catching invalid section numbers that the client
+# requested to edit. Once the parser has reached the end (the final </Archive> tag),
+# we've seen all the Sections in the doc.xml, and none of their section nums matched
+# if the metamode has not been set to 'done' by then.
+sub dxml_archive
+{
+    my ($tagname, $attrHash, $contextArray, $parentDataArray, $parser) = @_;
+    my $metamode = $parser->{'parameters'}->{'metamode'};
+    
+    my $curr_secnum = $parser->{'parameters'}->{'curr_section_num'};
+    my $opt_doc_secnum = $parser->{'parameters'}->{'secnum'};
+    
+#    print STDERR "@@@ $tagname Processing a closing </Archive> tag [$curr_secnum|$opt_doc_secnum]\n";
+    
+    if ($metamode ne "done" && $curr_secnum ne $opt_doc_secnum) {
+	print STDERR "@@@ $tagname Finished processing FINAL Section [$curr_secnum|$opt_doc_secnum]\n";
+
+	my $metaname = $parser->{'parameters'}->{'metaname'};
+	my $metavalue = $parser->{'parameters'}->{'metavalue'};
+	
+	print STDERR "@@@ Unknown requested section number $opt_doc_secnum\n";
+	print STDERR "\tas final section number in document was $curr_secnum\n";
+	print STDERR "\tMetadata value '$metavalue' for meta '$metaname'\n";
+	print STDERR "\tin section $opt_doc_secnum discarded.\n";
+    }
+    
+    # RAW is [$tagname => $attrHash] not $tagname => $attrHash!!
+    return [$tagname => $attrHash];
+}
 
 sub dxml_description
@@ -784,9 +813,30 @@
 	my $metamode = $parser->{'parameters'}->{'metamode'};
 
+	my $curr_secnum = $parser->{'parameters'}->{'curr_section_num'};
+	my $opt_doc_secnum = $parser->{'parameters'}->{'secnum'};
+	
 	print STDERR "**** Processing a closing </Description> tag \n";
+#	print STDERR "@@@ $tagname Processing a closing </Description> tag [$curr_secnum|$opt_doc_secnum]\n";
 	
 	# Accumulate the metadata
 
-	if (($metamode eq "accumulate") || ($metamode eq "override")) {
+	# We'll be accumulating metadata at this point if we haven't found and therefore
+	# haven't processed the metadata yet. 
+	# For subsections, this means that if we're at a matching subsection, but haven't 
+	# found the correct metaname to override in that subsection, we accumulate it as new
+	# meta in the subsection by adding it to the current description.
+	# If there's no subsection info for the metadata, it will accumulate at the top level
+	# section description if we hadn't found a matching metaname to override at this point.
+
+	# Both curr_secnum and opt_doc_secnum can be "". In the former case, it means we're now
+	# at the toplevel section. In the latter case, it means we want to process meta in the
+	# toplevel section. So the eq check between the values below will work in all cases.
+	
+	# The only time this won't work is if an opt_doc_secnum beyond the section numbers of
+	# this document has been provided. In that case, the metadata for that opt_doc_secnum
+	# won't get attached/accumulated to any part of the doc, not even its top-level section.
+
+	if ($curr_secnum eq $opt_doc_secnum 
+	    && ($metamode eq "accumulate" || $metamode eq "override")) {
 	    if ($metamode eq "override") {
 		print "No metadata value to override.  Switching 'metamode' to accumulate\n";
@@ -944,5 +994,6 @@
 	( _default => 'raw',
 	  'Metadata'    => \&dxml_metadata,
-	  'Description' => \&dxml_description);
+	  'Description' => \&dxml_description,
+	  'Archive'     => \&dxml_archive); # just for catching errors at end
 	  
     # Sets the parameters
