Index: conf/nutch-default.xml
===================================================================
--- conf/nutch-default.xml	(revision 1633619)
+++ conf/nutch-default.xml	(working copy)
@@ -1073,6 +1073,21 @@
   </description>
 </property>
 
+<property>
+  <name>urlmeta.rule</name>
+  <value></value>
+  <description>
+    For use in conjuntion with urlmeta.tags. This property specifies to which outlinks 
+    injected metadata should be propagated. Default is empty, with metadata being
+    propagated to all outlinks. Other options are "host" and "domain", which cause metadata 
+    to be propagated only to urls with the same host or domain as the url with which the
+    metadata was originally injected. The final option is "prefix", which will index injected 
+    metadata for urls containing the injected url as a prefix. (NOTE: If "prefix" is the rule,
+    injected metadata will be propagated to all outlinks during the crawl; they will just not 
+    be indexed.)
+  </description>
+</property>
+
 <!-- parser properties -->
 
 <property>
Index: src/plugin/urlmeta/src/java/org/apache/nutch/indexer/urlmeta/URLMetaIndexingFilter.java
===================================================================
--- src/plugin/urlmeta/src/java/org/apache/nutch/indexer/urlmeta/URLMetaIndexingFilter.java	(revision 1633619)
+++ src/plugin/urlmeta/src/java/org/apache/nutch/indexer/urlmeta/URLMetaIndexingFilter.java	(working copy)
@@ -67,52 +67,65 @@
  */
 public class URLMetaIndexingFilter implements IndexingFilter {
 
-	private static final Logger LOG = LoggerFactory
-			.getLogger(URLMetaIndexingFilter.class);
-	private static final String CONF_PROPERTY = "urlmeta.tags";
-	private static String[] urlMetaTags;
-	private Configuration conf;
+  private static final Logger LOG = LoggerFactory
+      .getLogger(URLMetaIndexingFilter.class);
+  private static final String CONF_PROPERTY_TAGS = "urlmeta.tags";
+  private static final String CONF_PROPERTY_RULE = "urlmeta.rule";
+  private static String[] urlMetaTags;
+  private static String urlMetaRule;
+  private Configuration conf;
 
-	/**
-	 * This will take the metatags that you have listed in your "urlmeta.tags"
-	 * property, and looks for them inside the CrawlDatum object. If they exist,
-	 * this will add it as an attribute inside the NutchDocument.
-	 * 
-	 * @see IndexingFilter#filter
-	 */
-	public NutchDocument filter(NutchDocument doc, Parse parse, Text url,
-			CrawlDatum datum, Inlinks inlinks) throws IndexingException {
-		if (conf != null)
-			this.setConf(conf);
+  /**
+   * This will take the metatags that you have listed in your "urlmeta.tags"
+   * property, and looks for them inside the CrawlDatum object. If they exist,
+   * this will add it as an attribute inside the NutchDocument.
+   * 
+   * @see IndexingFilter#filter
+   */
+  public NutchDocument filter(NutchDocument doc, Parse parse, Text url,
+      CrawlDatum datum, Inlinks inlinks) throws IndexingException {
+    if (conf != null)
+      this.setConf(conf);
 
-		if (urlMetaTags == null || doc == null)
-			return doc;
+    if (urlMetaTags == null || doc == null)
+      return doc;
 
-		for (String metatag : urlMetaTags) {
-			Text metadata = (Text) datum.getMetaData().get(new Text(metatag));
+    // If the rule is "prefix", ensure that this url is prefixed by the injected
+    // url. Otherwise, don't index the injected metadata.
+    if (urlMetaRule.equals("prefix")
+        && url.toString()
+            .indexOf(
+                datum.getMetaData().get(new Text("urlmeta.injectedUrl"))
+                    .toString()) != 0) {
+      return doc;
+    }
 
-			if (metadata != null)
-				doc.add(metatag, metadata.toString());
-		}
+    for (String metatag : urlMetaTags) {
+      Text metadata = (Text) datum.getMetaData().get(new Text(metatag));
 
-		return doc;
-	}
+      if (metadata != null)
+        doc.add(metatag, metadata.toString());
+    }
 
-	/** Boilerplate */
-	public Configuration getConf() {
-		return conf;
-	}
+    return doc;
+  }
 
-	/**
-	 * handles conf assignment and pulls the value assignment from the
-	 * "urlmeta.tags" property
-	 */
-	public void setConf(Configuration conf) {
-		this.conf = conf;
+  /** Boilerplate */
+  public Configuration getConf() {
+    return conf;
+  }
 
-		if (conf == null)
-			return;
+  /**
+   * handles conf assignment and pulls the value assignment from the
+   * "urlmeta.tags" property
+   */
+  public void setConf(Configuration conf) {
+    this.conf = conf;
 
-		urlMetaTags = conf.getStrings(CONF_PROPERTY);
-	}
+    if (conf == null)
+      return;
+
+    urlMetaTags = conf.getStrings(CONF_PROPERTY_TAGS);
+    urlMetaRule = conf.get(CONF_PROPERTY_RULE);
+  }
 }
Index: src/plugin/urlmeta/src/java/org/apache/nutch/scoring/urlmeta/URLMetaScoringFilter.java
===================================================================
--- src/plugin/urlmeta/src/java/org/apache/nutch/scoring/urlmeta/URLMetaScoringFilter.java	(revision 1633619)
+++ src/plugin/urlmeta/src/java/org/apache/nutch/scoring/urlmeta/URLMetaScoringFilter.java	(working copy)
@@ -17,24 +17,28 @@
 
 package org.apache.nutch.scoring.urlmeta;
 
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.util.Collection;
-import java.util.Map.Entry;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map.Entry;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.conf.Configured;
 import org.apache.hadoop.io.Text;
 import org.apache.nutch.crawl.CrawlDatum;
 import org.apache.nutch.crawl.Inlinks;
 import org.apache.nutch.indexer.NutchDocument;
+import org.apache.nutch.indexer.urlmeta.URLMetaIndexingFilter;
 import org.apache.nutch.parse.Parse;
 import org.apache.nutch.parse.ParseData;
 import org.apache.nutch.protocol.Content;
 import org.apache.nutch.scoring.ScoringFilter;
 import org.apache.nutch.scoring.ScoringFilterException;
+import org.apache.nutch.util.URLUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * For documentation:
@@ -43,9 +47,13 @@
  */
 public class URLMetaScoringFilter extends Configured implements ScoringFilter {
 
-  private static final Logger LOG = LoggerFactory.getLogger(URLMetaScoringFilter.class);
-  private static final String CONF_PROPERTY = "urlmeta.tags";
+  private static final Logger LOG = LoggerFactory
+      .getLogger(URLMetaScoringFilter.class);
+  private static final String CONF_PROPERTY_TAGS = "urlmeta.tags";
+  private static final String CONF_PROPERTY_RULE = "urlmeta.rule";
+  private static final String URLMETA_INJECTED_URL = "urlmeta.injectedUrl";
   private static String[] urlMetaTags;
+  private static String urlMetaRule;
   private Configuration conf;
 
   /**
@@ -67,16 +75,48 @@
     while (targetIterator.hasNext()) {
       Entry<Text, CrawlDatum> nextTarget = targetIterator.next();
 
+      // Check if we are violating the "host" or "domain" rule for propagation.
+      // If so, don't propagate to this target.
+      try {
+        if (urlMetaRule.equals("host")
+            && !(new URL(fromUrl.toString()).getHost().equals(new URL(
+                nextTarget.getKey().toString()).getHost()))) {
+          continue;
+        } else if (urlMetaRule.equals("domain")
+            && !URLUtil.isSameDomainName(fromUrl.toString(), nextTarget
+                .getKey().toString())) {
+          continue;
+        }
+      } catch (MalformedURLException e) {
+        // ignore the exception
+      }
+
+      // If "prefix" is the rule, it is possible that a target may not match the
+      // injected prefix, but a future target may. Therefore, we must propagate
+      // the injected URL because we cannot reconstruct it. Also if "prefix" is
+      // the rule we must propagate all injected metadata so that it is not lost
+      // when the first non-matching target url is encountered. When "prefix" is
+      // the rule, the determination of whether or not to index injected
+      // metadata with a given url is made in URLMetaIndexingFilter.
+      if (urlMetaRule.equals("prefix")) {
+        nextTarget
+            .getValue()
+            .getMetaData()
+            .put(new Text(URLMETA_INJECTED_URL),
+                new Text(parseData.getMeta(URLMETA_INJECTED_URL)));
+      }
+
       for (String metatag : urlMetaTags) {
         String metaFromParse = parseData.getMeta(metatag);
 
         if (metaFromParse == null)
           continue;
 
-        nextTarget.getValue().getMetaData().put(new Text(metatag),
-            new Text(metaFromParse));
+        nextTarget.getValue().getMetaData()
+            .put(new Text(metatag), new Text(metaFromParse));
       }
     }
+
     return adjust;
   }
 
@@ -92,6 +132,11 @@
     if (urlMetaTags == null || content == null || datum == null)
       return;
 
+    if (urlMetaRule.equals("prefix")) {
+      content.getMetadata().set(URLMETA_INJECTED_URL,
+          datum.getMetaData().get(new Text(URLMETA_INJECTED_URL)).toString());
+    }
+
     for (String metatag : urlMetaTags) {
       Text metaFromDatum = (Text) datum.getMetaData().get(new Text(metatag));
 
@@ -113,6 +158,14 @@
     if (urlMetaTags == null || content == null || parse == null)
       return;
 
+    if (urlMetaRule.equals("prefix")) {
+      parse
+          .getData()
+          .getParseMeta()
+          .set(URLMETA_INJECTED_URL,
+              content.getMetadata().get(URLMETA_INJECTED_URL));
+    }
+
     for (String metatag : urlMetaTags) {
       String metaFromContent = content.getMetadata().get(metatag);
 
@@ -145,6 +198,11 @@
   /** Boilerplate */
   public void injectedScore(Text url, CrawlDatum datum)
       throws ScoringFilterException {
+
+    if (urlMetaRule.equals("prefix")) {
+      datum.getMetaData().put(new Text(URLMETA_INJECTED_URL), url);
+    }
+
     return;
   }
 
@@ -164,7 +222,8 @@
     if (conf == null)
       return;
 
-    urlMetaTags = conf.getStrings(CONF_PROPERTY);
+    urlMetaTags = conf.getStrings(CONF_PROPERTY_TAGS);
+    urlMetaRule = conf.get(CONF_PROPERTY_RULE);
   }
 
   /** Boilerplate */
