Index: /main/trunk/greenstone2/perllib/cgiactions/metadataaction.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cgiactions/metadataaction.pm	(revision 27175)
+++ /main/trunk/greenstone2/perllib/cgiactions/metadataaction.pm	(revision 27176)
@@ -48,5 +48,5 @@
 	"get-import-metadata" => { 
 		'compulsory-args' => [ "d", "metaname" ],
-		'optional-args'   => [ ] },
+		'optional-args'   => [ "metapos" ] },
 
 	"get-archives-metadata" => { 
@@ -85,5 +85,5 @@
 	"set-import-metadata" => { 
 		'compulsory-args' => [ "metaname", "metavalue" ],
-		'optional-args'   => [ "d", "f", "metamode" ] }, # metamode can be "accumulate", "override", or "unique-id". Also need to add the ability to specify a previous metadata value to overwrite (because we can't use metapos)
+		'optional-args'   => [ "d", "f", "metamode", "metapos", "prevmetavalue" ] }, # metamode can be "accumulate", "override", or "unique-id". Also need to add the ability to specify a previous metadata value to overwrite (because we can't use metapos). Metapos now supported, but assumes you are working with a Simple (instead of Complex) collection
 				 
 	#SET METHODS (ARRAY)
@@ -111,5 +111,5 @@
 	"remove-import-metadata" => { 
 		'compulsory-args' => [ "d", "metaname", "metavalue" ], #TODO: add f argument
-		'optional-args'   => [ ] },
+		'optional-args'   => [ "metapos" ] }, # only provide metapos arg for SIMPLE collections
 					 
 	"remove-archives-metadata" => { 
@@ -314,6 +314,9 @@
 	my $docid     = $self->{'d'};
 	my $metaname  = $self->{'metaname'};
+	my $metapos = $self->{'metapos'};
+	$metapos = 0 if (!defined $metapos); # gets the first value by default since metapos defaults to 0
+
 	my $infodbtype = $self->{'infodbtype'};
-    if (!defined $docid) 
+	if (!defined $docid) 
 	{
 		$gsdl_cgi->generate_error("No docid (d=...) specified.\n");
@@ -339,5 +342,5 @@
 	my $metadata_xml_filename = &util::filename_cat($import_dirname, "metadata.xml");
 
-	$gsdl_cgi->generate_ok_message($self->get_metadata_from_metadata_xml($gsdl_cgi, $metadata_xml_filename, $metaname, $import_tailname));
+	$gsdl_cgi->generate_ok_message($self->get_metadata_from_metadata_xml($gsdl_cgi, $metadata_xml_filename, $metaname, $metapos, $import_tailname));
 
     # Release the lock once it is done
@@ -348,5 +351,5 @@
 {
 	my $self = shift @_;
-	my ($gsdl_cgi, $metadata_xml_filename, $metaname, $src_file) = @_;
+	my ($gsdl_cgi, $metadata_xml_filename, $metaname, $metapos, $src_file) = @_;
 	
 	my @rules = 
@@ -377,5 +380,5 @@
 		close(MIN);	
 
-		$parser->parse($xml_in, {metaname => $metaname, src_file => $src_file});
+		$parser->parse($xml_in, {metaname => $metaname, metapos => $metapos, src_file => $src_file});
 		
 		if(defined $parser->{'pad'}->{'metavalue'})
@@ -394,7 +397,26 @@
 	my ($tagname, $attrHash, $contextArray, $parentDataArray, $parser) = @_;
 
-	if (($parser->{'parameters'}->{'src_file'} eq $parser->{'parameters'}->{'current_file'}) && ($attrHash->{'name'} eq $parser->{'parameters'}->{'metaname'}))
+	# no subsection support yet in metadata.xml
+
+	if (($parser->{'parameters'}->{'src_file'} eq $parser->{'parameters'}->{'current_file'}) && $parser->{'parameters'}->{'metaname'} eq $attrHash->{'name'})
 	{
-		$parser->{'pad'}->{'metavalue'} = $attrHash->{'_content'};
+		if (!defined $parser->{'parameters'}->{'poscount'})
+		{
+			$parser->{'parameters'}->{'poscount'} = 0;
+		}
+		else
+		{
+			$parser->{'parameters'}->{'poscount'}++;
+		}
+	
+		# gets the first value by default, since metapos defaults to 0
+		if (($parser->{'parameters'}->{'poscount'} == $parser->{'parameters'}->{'metapos'}))
+		{
+		    if($parser->{'parameters'}->{'metapos'} > 0) {
+			print STDERR "@@@@ WARNING: non-zero metapos.\n";
+			print STDERR "@@@@ Assuming SIMPLE collection and proceeding to retrieve the import meta at".$parser->{'parameters'}->{'metapos'}.".\n";
+		    }
+		    $parser->{'pad'}->{'metavalue'} = $attrHash->{'_content'};
+		}
 	}
 }
@@ -540,6 +562,4 @@
     }
     my $metavalue = $self->{'metavalue'};
-    my $metamode  = $self->{'metamode'} || "accumulate";
-    my $append_or_not = ($metamode eq "accumulate") ? " \"append\"" : "";
 
     # Generate the dbkey    
@@ -555,5 +575,5 @@
 
     # Set the new value
-    my $cmd = "gdbmset \"$infodb_file_path\" \"$dbkey\" \"$metavalue\"$append_or_not";
+    my $cmd = "gdbmset \"$infodb_file_path\" \"$dbkey\" \"$metavalue\"";
     my $status = system($cmd);
     if ($status != 0) {
@@ -624,5 +644,9 @@
 	$doc_rec->{$metaname}->[$metapos] = $metavalue;
     }
-    elsif (defined $metamode && $metamode eq "accumulate") {
+    elsif (defined $metamode && $metamode eq "override") {
+	$doc_rec->{$metaname} = [ $metavalue ];	
+    }
+    else { # default for index was to override, but because accumulate is less destructive, 
+	# and because accumulate is the default for archives and import, that's the new default for index too
 	if(defined $doc_rec->{$metaname}) {
 	    push(@{$doc_rec->{$metaname}}, $metavalue); # accumulate the value for that metaname
@@ -630,8 +654,4 @@
 	    $doc_rec->{$metaname} = [ $metavalue ];
 	}
-
-    }
-    else { # default for index was to override
-	$doc_rec->{$metaname} = [ $metavalue ];
     }
  
@@ -665,5 +685,5 @@
 	# as yet no support for setting subsection metadata in metadata.xml
 	if ((defined $docid_secnum) && ($docid_secnum !~ m/^\s*$/)) {
-	    $gsdl_cgi->generate_ok_message("*** Unable to set import metadata for subsections at this stage.\n");
+	    $gsdl_cgi->generate_message("*** No support yet for setting import metadata at subsections level.\n");
 	    return;
 	}
@@ -688,34 +708,10 @@
     }
 
-    # Obtain where the metadata.xml is from the archiveinfo-doc.gdb file
-    # If the doc oid is not specified, we assume the metadata.xml is next to the specified "f"
-    my $metadata_xml_file;
-    my $import_filename = undef;
-    if (defined $docid) {
-	my $arcinfo_doc_filename = &dbutil::get_infodb_file_path($infodbtype, "archiveinf-doc", $archive_dir);
-	my $doc_rec = &dbutil::read_infodb_entry($infodbtype, $arcinfo_doc_filename, $docid_root);
-
-	# This now stores the full pathname
-	$import_filename = $doc_rec->{'src-file'}->[0];	
-    }
-    else {
-        $import_filename = &util::filename_cat($collect_dir,$collect,$import_file);
-    }
-
-    # figure out correct metadata.xml file [?]
-    # Assuming the metadata.xml file is next to the source file
-    # Note: This will not work if it is using the inherited metadata from the parent folder
-    my ($import_tailname, $import_dirname) = File::Basename::fileparse($import_filename);
-    my $metadata_xml_filename = &util::filename_cat($import_dirname,"metadata.xml");
-
-    # Edit the metadata.xml
-    # Modified by Jeffrey from DL Consulting
-    # Handle the case where there is one metadata.xml file for multiple FileSets
-    # The XML filter needs to know whether it is in the right FileSet
-    # TODO: This doesn't fix the problem where the metadata.xml is not next to the src file.
-    # TODO: This doesn't handle the common metadata (where FileName doesn't point to a single file)
-    $self->edit_metadata_xml($gsdl_cgi, $metadata_xml_filename,
-			     $metaname, $metavalue, $metamode, $import_tailname);
-
+    # adding metapos and prevmetavalue support to import_metadata subroutines
+    my $metapos   = $self->{'metapos'}; # don't force undef to 0. Undef has meaning when metamode=override
+    my $prevmetavalue = $self->{'prevmetavalue'};
+
+    my $arcinfo_doc_filename = &dbutil::get_infodb_file_path($infodbtype, "archiveinf-doc", $archive_dir);
+    my $metadata_xml_filename = $self->set_import_metadata_entry($gsdl_cgi, $arcinfo_doc_filename, $infodbtype, $docid_root, $metaname, $metapos,$metavalue, $metamode,$prevmetavalue, $collect, $collect_dir); # at this point, docid_root = docid
 
     my $mess = "set-import-metadata successful: Key[$docid] -> $metadata_xml_filename\n";
@@ -749,8 +745,6 @@
     my $prevmetavalue = $self->{'prevmetavalue'};
     
-    my $metapos    = $self->{'metapos'}; # Don't append "|| undef", since if metapos=0 it will then be set to undef
-
-    # Don't set metapos=0 if it's undefined, as doing so will interfere when overriding all values for a metaname
-    # (all values for a metaname should get overridden if metamode=override combined with no user-defined metapos)
+    my $metapos    = $self->{'metapos'}; # don't force undef to 0. Undef has meaning when metamode=override
+                                  # Don't append "|| undef", since if metapos=0 it will then be set to undef
 
     my $metamode   = $self->{'metamode'};
@@ -804,5 +798,5 @@
     my $docid     = $self->{'d'};
     my $metaname  = $self->{'metaname'};
-    my $metapos   = $self->{'metapos'};
+    my $metapos   = $self->{'metapos'}; # undef has meaning
     my $metavalue = $self->{'metavalue'};
     my $infodbtype = $self->{'infodbtype'};
@@ -1020,5 +1014,5 @@
 	my $metaname  = $doc_array_rec->{'metaname'};
 	if(defined $metaname) {
-	    my $metapos   = $doc_array_rec->{'metapos'};
+	    my $metapos   = $doc_array_rec->{'metapos'}; # can legitimately be undef
 	    my $metavalue = $doc_array_rec->{'metavalue'};
 	    my $metamode = $doc_array_rec->{'metamode'} || $self->{'metamode'};
@@ -1139,11 +1133,7 @@
 	    my $dbkey = "$docid.$metaname";
 	    my $metavalue = $doc_array_rec->{'metavalue'};
-	    # no metapos for live_meta, so can default metamode to accumulate
-	    my $metamode  = $doc_array_rec->{'metamode'} || $self->{'metamode'} || "accumulate";
-	
-	    my $append_or_not = ($metamode eq "accumulate") ? " \"append\"" : "";
 
 	    # Set the new value
-	    my $cmd = "gdbmset \"$infodb_file_path\" \"$dbkey\" \"$metavalue\"$append_or_not";
+	    my $cmd = "gdbmset \"$infodb_file_path\" \"$dbkey\" \"$metavalue\"";
 	    $status = system($cmd);
 
@@ -1152,14 +1142,10 @@
 	    foreach my $metatable_rec ( @$metatable ) {
 		$metaname  = $metatable_rec->{'metaname'};
-		my $metamode = $metatable_rec->{'metamode'} || $doc_array_rec->{'metamode'} || $self->{'metamode'} || "accumulate";
-		my $append_or_not = ($metamode eq "accumulate") ? " \"append\"" : "";
 		my $dbkey = "$docid.$metaname";
 
 		my $metavals = $metatable_rec->{'metavals'}; # a sub-subarray
 		foreach my $metavalue ( @$metavals ) {
-		     my $cmd = "gdbmset \"$infodb_file_path\" \"$dbkey\" \"$metavalue\"$append_or_not";
+		     my $cmd = "gdbmset \"$infodb_file_path\" \"$dbkey\" \"$metavalue\"";
 		     $status = system($cmd);
-		     $append_or_not = " \"append\"";  # even if metamode=override, need to accumulate all subsequent 
-		     # metavals for this metaname, else the just-assigned metavalue for this metaname will be lost
 		}
 	    }
@@ -1621,11 +1607,10 @@
 	if(defined $metaname) {
 	    
-	    my $metapos   = $doc_array_rec->{'metapos'} || 0;
+	    my $metapos   = $doc_array_rec->{'metapos'}; # don't force undef to 0. Undef has meaning when metamode=override
+
 	    my $metamode  = $doc_array_rec->{'metamode'} || $self->{'metamode'};
 	    my $metavalue = $doc_array_rec->{'metavalue'};
 	    my $prevmetavalue = $self->{'prevmetavalue'}; # to make this sub behave as _set_archives_metadata
 	    
-	    # Some sanity checks
-	    $metapos = 0 if (!defined $metapos);
 	    
 	    if ((!defined $metamode) || ($metamode =~ m/^\s*$/)) {
@@ -1882,5 +1867,5 @@
 		}
 		
-		# if overriding but no metapos, then clear all the meta for this metaname
+		# if overriding (for set-meta) but no metapos, then clear all the meta for this metaname
 		if ((defined $parser->{'parameters'}->{'metamode'}) && ($parser->{'parameters'}->{'metamode'} eq "override") && (!defined $parser->{'parameters'}->{'metapos'})) {		    
 		    return [];
@@ -1917,5 +1902,5 @@
 	# file.  
 	# So, skip anything with a .* in it as it is too general
-#	print STDERR "@@@@ Skipping entry in metadata.xml where FileName=.* as it is too general\n";
+##	print STDERR "@@@@ Skipping entry in metadata.xml where FileName=.* as it is too general\n";
 	return [$tagname => $attrHash];
     }
@@ -1929,13 +1914,37 @@
     my $name_attr = $attrHash->{'name'};
     if (($name_attr eq $metaname) && ($metamode eq "override")) {
-        # Get the value and override the current value
+
+	# now metadata.xml functions need to keep track of metapos
+	if (!defined $parser->{'parameters'}->{'poscount'}) 
+	{ 
+	    $parser->{'parameters'}->{'poscount'} = 0; 
+	} 
+	else 
+	{ 
+	    $parser->{'parameters'}->{'poscount'}++; 
+	} 
+
+	# If either the metapos or prevmetavalue is set,
+        # get the value and override the current value
 	my $metavalue = $parser->{'parameters'}->{'metavalue'};
-	$attrHash->{'_content'} = $metavalue;
-
-##	print STDERR "**** overriding metadata.xml\n";
-
-	# Don't want it to wipe out any other pieces of metadata
-	$parser->{'parameters'}->{'metamode'} = "done";
-    }
+
+	if(defined $parser->{'parameters'}->{'prevmetavalue'} && $parser->{'parameters'}->{'prevmetavalue'} eq $attrHash->{'_content'})
+	{
+	    $attrHash->{'_content'} = $metavalue;
+
+	    ##	print STDERR "**** overriding metadata.xml\n";
+	    
+	    # Don't want it to wipe out any other pieces of metadata
+	    $parser->{'parameters'}->{'metamode'} = "done";
+	}
+	elsif(defined $parser->{'parameters'}->{'metapos'} && $parser->{'parameters'}->{'poscount'} == $parser->{'parameters'}->{'metapos'})
+	{
+	    $attrHash->{'_content'} = $metavalue;
+	    $parser->{'parameters'}->{'metamode'} = "done";
+	}
+    } 
+
+    # mxml_description will process the metadata if metadata is accumulate, 
+    # or if we haven't found the metadata to override
 
     # RAW is [$tagname => $attrHash] not $tagname => $attrHash!!
@@ -1970,7 +1979,12 @@
     # multiple FileSets, it will add to all of them
     if (($metamode eq "accumulate") || ($metamode eq "override")) {
+
 	# if metamode was "override" but get to here then it failed to
 	# find an item to override, in which case it should append its 
 	# value to the end, just like the "accumulate" mode
+
+	if ($metamode eq "override") {
+	    print "No metadata value to override.  Switching 'metamode' to accumulate\n";
+	}
 
 	# tack a new metadata tag on to the end of the <Metadata>+ block
@@ -2103,5 +2117,5 @@
 {
     my $self = shift @_;
-    my ($gsdl_cgi, $metadata_xml_filename, $metaname, $metavalue, $metamode, $src_file) = @_;
+    my ($gsdl_cgi, $metadata_xml_filename, $metaname, $metapos, $metavalue, $metamode, $src_file, $prevmetavalue) = @_;
 
     # Set the call-back functions for the metadata tags
@@ -2175,7 +2189,9 @@
 
 			$parser->filter($xml_in, $MOUT, { metaname => $metaname,
+							  metapos => $metapos,
 				      metavalue => $metavalue,
 				      metamode => $metamode,
 				      src_file => $src_file,
+				      prevmetavalue => $prevmetavalue,
 				      current_file => undef} );
 			close($MOUT);	    
@@ -2268,5 +2284,15 @@
 	my $docid = $doc_array_rec->{'docid'};
 	
-	push(@all_docids,$docid);
+	my ($docid_root,$docid_secnum);
+	if(defined $docid) {	
+	    ($docid_root,$docid_secnum) = ($docid =~ m/^(.*?)(\..*)?$/);	
+	    # as yet no support for setting subsection metadata in metadata.xml
+	    if ((defined $docid_secnum) && ($docid_secnum !~ m/^\s*$/)) {
+		$gsdl_cgi->generate_message("*** docid: $docid. No support yet for setting import metadata at subsections level.\n");
+		next; # skip this docid in for loop
+	    }
+	}
+
+	push(@all_docids,$docid); # docid_root rather
 	
 	my $metaname = $doc_array_rec->{'metaname'};
@@ -2274,5 +2300,6 @@
 	    my $metamode = $doc_array_rec->{'metamode'} || $self->{'metamode'};
 	    my $metavalue = $doc_array_rec->{'metavalue'};
-	    
+	    $metavalue =~ s/&lt;(.*?)&gt;/<$1>/g;
+
 	    if ((!defined $metamode) || ($metamode =~ m/^\s*$/)) {
 		# make "accumulate" the default (less destructive, as won't actually 
@@ -2280,6 +2307,10 @@
 		$metamode = "accumulate";
 	    }
-	    
-	    $self->set_import_metadata_entry($gsdl_cgi, $arcinfo_doc_filename, $infodbtype, $docid, $metaname, $metavalue, $metamode);
+
+	    # adding metapos and prevmetavalue support to import_metadata subroutines
+	    my $metapos   = $doc_array_rec->{'metapos'}; # don't force undef to 0. Undef has meaning when metamode=override
+	    my $prevmetavalue = $self->{'prevmetavalue'};
+
+	    $self->set_import_metadata_entry($gsdl_cgi, $arcinfo_doc_filename, $infodbtype, $docid_root, $metaname, $metapos, $metavalue, $metamode, $prevmetavalue, $collect, $collect_dir); # at this point, docid_root = docid
 	    
 	} elsif (defined $doc_array_rec->{'metatable'}) { # if no metaname, we expect a metatable
@@ -2294,9 +2325,14 @@
 		    $metamode = "accumulate";
 		}
-		# no metapos for import
+
+		# No support for metapos and prevmetavalue in the JSON metatable substructure
+		my $metapos = undef; 
+		my $prevmetavalue = undef;
 		my $metavals = $metatable_rec->{'metavals'}; # a sub-subarray
 		
 		foreach my $metavalue ( @$metavals ) {
-		    $self->set_import_metadata_entry($gsdl_cgi, $arcinfo_doc_filename, $infodbtype, $docid, $metaname, $metavalue, $metamode);
+		    $metavalue =~ s/&lt;(.*?)&gt;/<$1>/g;
+
+		    $self->set_import_metadata_entry($gsdl_cgi, $arcinfo_doc_filename, $infodbtype, $docid_root, $metaname, $metapos, $metavalue, $metamode, $prevmetavalue, $collect, $collect_dir); # at this point, docid_root = docid
 		    if($metamode eq "override") { # now, having overridden the first metavalue of the metaname, 
 			# need to accumulate subsequent metavals for this metaname, else the just-assigned
@@ -2318,5 +2354,34 @@
 {
     my $self = shift @_;
-    my ($gsdl_cgi, $arcinfo_doc_filename, $infodbtype, $docid, $metaname, $metavalue, $metamode) = @_;
+    my ($gsdl_cgi, $arcinfo_doc_filename, $infodbtype, $docid, $metaname, $metapos, $metavalue, $metamode, $prevmetavalue, $collect, $collect_dir) = @_;
+
+    my $info_mess = <<RAWEND;
+****************************
+  set_import_metadata_entry()
+****************************
+collect = $collect
+collect_dir = $collect_dir
+infodbtype = $infodbtype
+arcinfo_doc_filename = $arcinfo_doc_filename
+docid = $docid
+metaname = $metaname
+metapos = $metapos
+metavalue = $metavalue
+metamode = $metamode
+prevmetavalue = $prevmetavalue
+****************************
+RAWEND
+
+    $gsdl_cgi->generate_message($info_mess);
+
+    # import works with metadata.xml which can have inherited metadata
+    # so setting or removing at a metapos can have unintended effects for a COMPLEX collection
+    # (a collection that has or can have inherited metadata). Metapos has expected behaviour for
+    # a SIMPLE collection, which is one that doesn't have inherited metadata. Assume caller knows 
+    # what they're doing if they provide a metapos.
+    if(defined $metapos) {
+	print STDERR "@@@@ WARNING: metapos defined.\n";
+	print STDERR "@@@@ Assuming SIMPLE collection and proceeding to modify the import meta at $metapos.\n";
+    }
 
     # Obtain where the metadata.xml is from the archiveinfo-doc.gdb file
@@ -2325,8 +2390,15 @@
     my $import_filename = undef;
     
-    my $doc_rec = &dbutil::read_infodb_entry($infodbtype, $arcinfo_doc_filename, $docid);
-
-    # This now stores the full pathname
-    $import_filename = $doc_rec->{'src-file'}->[0];	
+    if (defined $docid) {
+	# my $arcinfo_doc_filename = &dbutil::get_infodb_file_path($infodbtype, "archiveinf-doc", $archive_dir);
+	my $doc_rec = &dbutil::read_infodb_entry($infodbtype, $arcinfo_doc_filename, $docid);
+
+	# This now stores the full pathname
+	$import_filename = $doc_rec->{'src-file'}->[0];	
+    } else { # only for set_import_meta, not the case when calling method is set_import_metadata_array
+	     # as the array version of the method doesn't support the -f parameter yet
+	my $import_file  = $self->{'f'};
+	$import_filename = &util::filename_cat($collect_dir,$collect,$import_file);
+    }
     
     # figure out correct metadata.xml file [?]
@@ -2336,6 +2408,23 @@
     my $metadata_xml_filename = &util::filename_cat($import_dirname,"metadata.xml");
     
-    $self->edit_metadata_xml($gsdl_cgi, $metadata_xml_filename, $metaname, $metavalue, $metamode, $import_tailname);
-    return 1;
+    # If we're overriding everything, then $metamode=override combined with $metapos=undefined
+    # in which case, we need to remove all metavalues for the metaname at the given (sub)section
+    # Thereafter, we will finally be able to set the overriding metavalue for this metaname
+    if(!defined $metapos && $metamode eq "override") {
+##	print STDERR "@@@ REMOVING all import metadata for $metaname\n";
+	$self->remove_from_metadata_xml($gsdl_cgi, $metadata_xml_filename, $metaname, $metapos, undef, $import_tailname, $metamode); # we're removing all values, so metavalue=undef
+
+    }
+
+    # Edit the metadata.xml
+    # Modified by Jeffrey from DL Consulting
+    # Handle the case where there is one metadata.xml file for multiple FileSets
+    # The XML filter needs to know whether it is in the right FileSet
+    # TODO: This doesn't fix the problem where the metadata.xml is not next to the src file.
+    # TODO: This doesn't handle the common metadata (where FileName doesn't point to a single file)
+    $self->edit_metadata_xml($gsdl_cgi, $metadata_xml_filename, $metaname, 
+			     $metapos, $metavalue, $metamode, $import_tailname, $prevmetavalue);
+    #return 0;
+    return $metadata_xml_filename;
 }
 
@@ -2365,6 +2454,22 @@
 	
 	my $metaname = $self->{'metaname'};
+	my $metapos = $self->{'metapos'};
 	my $metavalue = $self->{'metavalue'};
-	$metavalue =~ s/&lt;(.*?)&gt;/<$1>/g;
+	if(defined $metavalue) {
+	    $metavalue =~ s/&lt;(.*?)&gt;/<$1>/g;
+	} elsif (!defined $metapos) { # if given no metavalue or metapos to delete, default to deleting the 1st
+	    $metapos = 0;
+	}
+	my $metamode = $self->{'metamode'} || undef;
+
+	# import works with metadata.xml which can have inherited metadata
+	# so setting or removing at a metapos can have unintended effects for a COMPLEX collection
+	# (a collection that has or can have inherited metadata). Metapos has expected behaviour for
+	# a SIMPLE collection, which is one that doesn't have inherited metadata. Assume caller knows 
+	# what they're doing if they provide a metapos.
+	if(defined $metapos) {
+	    print STDERR "@@@@ WARNING: metapos defined.\n";
+	    print STDERR "@@@@ Assuming SIMPLE collection and proceeding to modify the import meta at $metapos.\n";
+	}
 	
 	# Obtain where the metadata.xml is from the archiveinfo-doc.gdb file
@@ -2392,5 +2497,5 @@
 	my $metadata_xml_filename = &util::filename_cat($import_dirname,"metadata.xml");
 	
-	$self->remove_from_metadata_xml($gsdl_cgi, $metadata_xml_filename, $metaname, $metavalue, $import_tailname);
+	$self->remove_from_metadata_xml($gsdl_cgi, $metadata_xml_filename, $metaname, $metapos, $metavalue, $import_tailname, $metamode); # metamode has no meaning for removing meta, but is used by set_meta when overriding All
 	
 	my $mess = "remove-import-metadata successful: Key[$docid] -> $metadata_xml_filename\n";
@@ -2429,6 +2534,8 @@
 {
 	my $self = shift @_;
-	my ($gsdl_cgi, $metadata_xml_filename, $metaname, $metavalue, $src_file) = @_;
-	
+	my ($gsdl_cgi, $metadata_xml_filename, $metaname, $metapos, $metavalue, $src_file, $metamode) = @_;
+	# metamode generally has no meaning for removing meta, but is used by set_meta 
+	# when overriding all metavals for a metaname, in which case remove_meta is called with metamode
+
 	# Set the call-back functions for the metadata tags
 	my @rules = 
@@ -2471,5 +2578,5 @@
 		else {
 			binmode($MOUT,":utf8");
-			$parser->filter($xml_in, $MOUT, {metaname => $metaname, metavalue => $metavalue, src_file => $src_file, current_file => undef});
+			$parser->filter($xml_in, $MOUT, {metaname => $metaname, metapos => $metapos, metavalue => $metavalue, src_file => $src_file, metamode => $metamode, current_file => undef});
 			close($MOUT);	    
 		}
@@ -2481,7 +2588,33 @@
 	my ($tagname, $attrHash, $contextArray, $parentDataArray, $parser) = @_;
 
-	if ((defined $parser->{'parameters'}->{'metavalue'}) && ($parser->{'parameters'}->{'src_file'} eq $parser->{'parameters'}->{'current_file'}) && ($attrHash->{'name'} eq $parser->{'parameters'}->{'metaname'}) && ($attrHash->{'_content'} eq $parser->{'parameters'}->{'metavalue'}))
+	# metadata.xml does not handle subsections
+
+	# since metadata.xml now has to deal with metapos, we keep track of the metadata position
+	if (($parser->{'parameters'}->{'src_file'} eq $parser->{'parameters'}->{'current_file'}) 
+	    && $parser->{'parameters'}->{'metaname'} eq $attrHash->{'name'})
 	{
-	    return [];
+		if (!defined $parser->{'parameters'}->{'poscount'})
+		{
+			$parser->{'parameters'}->{'poscount'} = 0;
+		}
+		else
+		{
+			$parser->{'parameters'}->{'poscount'}++;
+		}
+
+		# if overriding but no metapos, then clear all the meta for this metaname
+		if ((defined $parser->{'parameters'}->{'metamode'}) && ($parser->{'parameters'}->{'metamode'} eq "override") && (!defined $parser->{'parameters'}->{'metapos'})) {
+		    return [];
+		}
+	
+		if ((defined $parser->{'parameters'}->{'metapos'}) && ($parser->{'parameters'}->{'poscount'} == $parser->{'parameters'}->{'metapos'}))
+		{
+		    return [];
+		}
+
+		if ((defined $parser->{'parameters'}->{'metavalue'}) && ($attrHash->{'_content'} eq $parser->{'parameters'}->{'metavalue'}))
+		{
+		    return [];
+		}		
 	}
 
@@ -2660,5 +2793,6 @@
 
     # Obtain the specified metadata pos
-    if(!defined $metapos && !defined $metavalue) { #$metapos = 0 if (!defined $metapos);
+    # if no metavalue or metapos to delete, default to deleting the 1st value for the metaname
+    if(!defined $metapos && !defined $metavalue) {
 	    $metapos = 0;
     }
@@ -2788,4 +2922,8 @@
     my $metamode = "accumulate";
 
+    # metapos/prevmetavalue were never before used in this subroutine, so set them to undefined
+    my $metapos   = undef;
+    my $prevmetavalue = undef;
+
     #=======================================================================#
     # set_import_metadata [START]
@@ -2829,6 +2967,6 @@
     # TODO: This doesn't fix the problem where the metadata.xml is not next to the src file.
     # TODO: This doesn't handle the common metadata (where FileName doesn't point to a single file)
-    $self->edit_metadata_xml($gsdl_cgi, $metadata_xml_filename,
-                             $metaname, $metavalue, $metamode, $import_tailname);
+    $self->edit_metadata_xml($gsdl_cgi, $metadata_xml_filename, $metaname,
+			     $metapos, $metavalue, $metamode, $import_tailname, $prevmetavalue);
     #=======================================================================#
     # set_import_metadata [END]
