Index: src/java/org/apache/nutch/fetcher/Fetcher.java
===================================================================
--- src/java/org/apache/nutch/fetcher/Fetcher.java	(revision 537923)
+++ src/java/org/apache/nutch/fetcher/Fetcher.java	(working copy)
@@ -285,78 +285,75 @@
       datum.setFetchTime(System.currentTimeMillis());
       if (pstatus != null) datum.getMetaData().put(Nutch.WRITABLE_PROTO_STATUS_KEY, pstatus);
 
-      if (content == null) {
-        String url = key.toString();
-        content = new Content(url, url, new byte[0], "", new Metadata(), this.conf);
-      }
-      Metadata metadata = content.getMetadata();
-      // add segment to metadata
-      metadata.set(Nutch.SEGMENT_NAME_KEY, segmentName);
-      // add score to content metadata so that ParseSegment can pick it up.
-      try {
-        scfilters.passScoreBeforeParsing(key, datum, content);
-      } catch (Exception e) {
-        if (LOG.isWarnEnabled()) {
-          e.printStackTrace(LogUtil.getWarnStream(LOG));
-          LOG.warn("Couldn't pass score, url " + key + " (" + e + ")");
-        }
-      }
-
-      /* Note: Fetcher will only follow meta-redirects coming from the
-       * original URL. */ 
       ParseResult parseResult = null;
-      if (parsing && status == CrawlDatum.STATUS_FETCH_SUCCESS) {
+      if (content != null) {
+        Metadata metadata = content.getMetadata();
+        // add segment to metadata
+        metadata.set(Nutch.SEGMENT_NAME_KEY, segmentName);
+        // add score to content metadata so that ParseSegment can pick it up.
         try {
-          parseResult = this.parseUtil.parse(content);
+          scfilters.passScoreBeforeParsing(key, datum, content);
         } catch (Exception e) {
-          LOG.warn("Error parsing: " + key + ": " + StringUtils.stringifyException(e));
+          if (LOG.isWarnEnabled()) {
+            e.printStackTrace(LogUtil.getWarnStream(LOG));
+            LOG.warn("Couldn't pass score, url " + key + " (" + e + ")");
+          }
         }
+        /* Note: Fetcher will only follow meta-redirects coming from the
+         * original URL. */ 
+        if (parsing && status == CrawlDatum.STATUS_FETCH_SUCCESS) {
+          try {
+            parseResult = this.parseUtil.parse(content);
+          } catch (Exception e) {
+            LOG.warn("Error parsing: " + key + ": " + StringUtils.stringifyException(e));
+          }
 
-        if (parseResult != null) {
-          for (Entry<Text, Parse> entry : parseResult) {
-            Text url = entry.getKey();
-            Parse parse = entry.getValue();
-            ParseStatus parseStatus = parse.getData().getStatus();
-            
-            if (!parseStatus.isSuccess()) {
-              LOG.warn("Error parsing: " + key + ": " + parseStatus);
-              parse = parseStatus.getEmptyParse(getConf());
-            }
+          if (parseResult != null) {
+            for (Entry<Text, Parse> entry : parseResult) {
+              Text url = entry.getKey();
+              Parse parse = entry.getValue();
+              ParseStatus parseStatus = parse.getData().getStatus();
+              
+              if (!parseStatus.isSuccess()) {
+                LOG.warn("Error parsing: " + key + ": " + parseStatus);
+                parse = parseStatus.getEmptyParse(getConf());
+              }
 
-            // Calculate page signature. For non-parsing fetchers this will
-            // be done in ParseSegment
-            byte[] signature = 
-              SignatureFactory.getSignature(getConf()).calculate(content, parse);
-            // Ensure segment name and score are in parseData metadata
-            parse.getData().getContentMeta().set(Nutch.SEGMENT_NAME_KEY, 
-                segmentName);
-            parse.getData().getContentMeta().set(Nutch.SIGNATURE_KEY, 
-                StringUtil.toHexString(signature));
-            // Pass fetch time to content meta
-            parse.getData().getContentMeta().set(Nutch.FETCH_TIME_KEY,
-                Long.toString(datum.getFetchTime()));
-            if (url.equals(key))
-              datum.setSignature(signature);
-            try {
-              scfilters.passScoreAfterParsing(url, content, parse);
-            } catch (Exception e) {
-              if (LOG.isWarnEnabled()) {
-                e.printStackTrace(LogUtil.getWarnStream(LOG));
-                LOG.warn("Couldn't pass score, url " + key + " (" + e + ")");
+              // Calculate page signature. For non-parsing fetchers this will
+              // be done in ParseSegment
+              byte[] signature = 
+                SignatureFactory.getSignature(getConf()).calculate(content, parse);
+              // Ensure segment name and score are in parseData metadata
+              parse.getData().getContentMeta().set(Nutch.SEGMENT_NAME_KEY, 
+                  segmentName);
+              parse.getData().getContentMeta().set(Nutch.SIGNATURE_KEY, 
+                  StringUtil.toHexString(signature));
+              // Pass fetch time to content meta
+              parse.getData().getContentMeta().set(Nutch.FETCH_TIME_KEY,
+                  Long.toString(datum.getFetchTime()));
+              if (url.equals(key))
+                datum.setSignature(signature);
+              try {
+                scfilters.passScoreAfterParsing(url, content, parse);
+              } catch (Exception e) {
+                if (LOG.isWarnEnabled()) {
+                  e.printStackTrace(LogUtil.getWarnStream(LOG));
+                  LOG.warn("Couldn't pass score, url " + key + " (" + e + ")");
+                }
               }
             }
+          } else {
+            byte[] signature = 
+              SignatureFactory.getSignature(getConf()).calculate(content, 
+                  new ParseStatus().getEmptyParse(conf));
+            datum.setSignature(signature);
           }
-        } else {
-          byte[] signature = 
-            SignatureFactory.getSignature(getConf()).calculate(content, 
-                new ParseStatus().getEmptyParse(conf));
-          datum.setSignature(signature);
         }
       }
 
       try {
         output.collect(key, new ObjectWritable(datum));
-        if (storingContent)
+        if (content != null && storingContent)
           output.collect(key, new ObjectWritable(content));
         if (parseResult != null) {
           for (Entry<Text, Parse> entry : parseResult) {
Index: src/java/org/apache/nutch/fetcher/Fetcher2.java
===================================================================
--- src/java/org/apache/nutch/fetcher/Fetcher2.java	(revision 537923)
+++ src/java/org/apache/nutch/fetcher/Fetcher2.java	(working copy)
@@ -647,72 +647,69 @@
       datum.setFetchTime(System.currentTimeMillis());
       if (pstatus != null) datum.getMetaData().put(Nutch.WRITABLE_PROTO_STATUS_KEY, pstatus);
 
-      if (content == null) {
-        String url = key.toString();
-        content = new Content(url, url, new byte[0], "", new Metadata(), this.conf);
-      }
-      Metadata metadata = content.getMetadata();
-      // add segment to metadata
-      metadata.set(Nutch.SEGMENT_NAME_KEY, segmentName);
-      // add score to content metadata so that ParseSegment can pick it up.
-      try {
-        scfilters.passScoreBeforeParsing(key, datum, content);
-      } catch (Exception e) {
-        if (LOG.isWarnEnabled()) {
-          e.printStackTrace(LogUtil.getWarnStream(LOG));
-          LOG.warn("Couldn't pass score, url " + key + " (" + e + ")");
-        }
-      }
-
-      /* Note: Fetcher will only follow meta-redirects coming from the
-       * original URL. */ 
       ParseResult parseResult = null;
-      if (parsing && status == CrawlDatum.STATUS_FETCH_SUCCESS) {
+      if (content != null) {
+        Metadata metadata = content.getMetadata();
+        // add segment to metadata
+        metadata.set(Nutch.SEGMENT_NAME_KEY, segmentName);
+        // add score to content metadata so that ParseSegment can pick it up.
         try {
-          parseResult = this.parseUtil.parse(content);
+          scfilters.passScoreBeforeParsing(key, datum, content);
         } catch (Exception e) {
-          LOG.warn("Error parsing: " + key + ": " + StringUtils.stringifyException(e));
+          if (LOG.isWarnEnabled()) {
+            e.printStackTrace(LogUtil.getWarnStream(LOG));
+            LOG.warn("Couldn't pass score, url " + key + " (" + e + ")");
+          }
         }
+        /* Note: Fetcher will only follow meta-redirects coming from the
+         * original URL. */ 
+        if (parsing && status == CrawlDatum.STATUS_FETCH_SUCCESS) {
+          try {
+            parseResult = this.parseUtil.parse(content);
+          } catch (Exception e) {
+            LOG.warn("Error parsing: " + key + ": " + StringUtils.stringifyException(e));
+          }
 
-        if (parseResult != null) {
-          for (Entry<Text, Parse> entry : parseResult) {
-            Text url = entry.getKey();
-            Parse parse = entry.getValue();
-            ParseStatus parseStatus = parse.getData().getStatus();
+          if (parseResult != null) {
+            for (Entry<Text, Parse> entry : parseResult) {
+              Text url = entry.getKey();
+              Parse parse = entry.getValue();
+              ParseStatus parseStatus = parse.getData().getStatus();
 
-            if (!parseStatus.isSuccess()) {
-              LOG.warn("Error parsing: " + key + ": " + parseStatus);
-              parse = parseStatus.getEmptyParse(getConf());
-            }
+              if (!parseStatus.isSuccess()) {
+                LOG.warn("Error parsing: " + key + ": " + parseStatus);
+                parse = parseStatus.getEmptyParse(getConf());
+              }
 
-            // Calculate page signature. For non-parsing fetchers this will
-            // be done in ParseSegment
-            byte[] signature = 
-              SignatureFactory.getSignature(getConf()).calculate(content, parse);
-            // Ensure segment name and score are in parseData metadata
-            parse.getData().getContentMeta().set(Nutch.SEGMENT_NAME_KEY, 
-                segmentName);
-            parse.getData().getContentMeta().set(Nutch.SIGNATURE_KEY, 
-                StringUtil.toHexString(signature));
-            // Pass fetch time to content meta
-            parse.getData().getContentMeta().set(Nutch.FETCH_TIME_KEY,
-                Long.toString(datum.getFetchTime()));
-            if (url.equals(key))
-              datum.setSignature(signature);
-            try {
-              scfilters.passScoreAfterParsing(url, content, parse);
-            } catch (Exception e) {
-              if (LOG.isWarnEnabled()) {
-                e.printStackTrace(LogUtil.getWarnStream(LOG));
-                LOG.warn("Couldn't pass score, url " + key + " (" + e + ")");
+              // Calculate page signature. For non-parsing fetchers this will
+              // be done in ParseSegment
+              byte[] signature = 
+                SignatureFactory.getSignature(getConf()).calculate(content, parse);
+              // Ensure segment name and score are in parseData metadata
+              parse.getData().getContentMeta().set(Nutch.SEGMENT_NAME_KEY, 
+                  segmentName);
+              parse.getData().getContentMeta().set(Nutch.SIGNATURE_KEY, 
+                  StringUtil.toHexString(signature));
+              // Pass fetch time to content meta
+              parse.getData().getContentMeta().set(Nutch.FETCH_TIME_KEY,
+                  Long.toString(datum.getFetchTime()));
+              if (url.equals(key))
+                datum.setSignature(signature);
+              try {
+                scfilters.passScoreAfterParsing(url, content, parse);
+              } catch (Exception e) {
+                if (LOG.isWarnEnabled()) {
+                  e.printStackTrace(LogUtil.getWarnStream(LOG));
+                  LOG.warn("Couldn't pass score, url " + key + " (" + e + ")");
+                }
               }
             }
+          } else {
+            byte[] signature = 
+              SignatureFactory.getSignature(getConf()).calculate(content, 
+                  new ParseStatus().getEmptyParse(conf));
+            datum.setSignature(signature);
           }
-        } else {
-          byte[] signature = 
-            SignatureFactory.getSignature(getConf()).calculate(content, 
-                new ParseStatus().getEmptyParse(conf));
-          datum.setSignature(signature);
         }
       }
 
Index: src/java/org/apache/nutch/indexer/Indexer.java
===================================================================
--- src/java/org/apache/nutch/indexer/Indexer.java	(revision 537913)
+++ src/java/org/apache/nutch/indexer/Indexer.java	(working copy)
@@ -152,7 +152,6 @@
     Inlinks inlinks = null;
     CrawlDatum dbDatum = null;
     CrawlDatum fetchDatum = null;
-    CrawlDatum redir = null;
     ParseData parseData = null;
     ParseText parseText = null;
     while (values.hasNext()) {
@@ -165,9 +164,9 @@
           dbDatum = datum;
         else if (CrawlDatum.hasFetchStatus(datum))
           fetchDatum = datum;
-        else if (CrawlDatum.STATUS_LINKED == datum.getStatus())
-          // redirected page
-          redir = datum;
+        else if (CrawlDatum.STATUS_LINKED == datum.getStatus() ||
+                 CrawlDatum.STATUS_SIGNATURE == datum.getStatus())
+          continue;
         else
           throw new RuntimeException("Unexpected status: "+datum.getStatus());
       } else if (value instanceof ParseData) {
@@ -178,11 +177,6 @@
         LOG.warn("Unrecognized type: "+value.getClass());
       }
     }      
-    if (redir != null) {
-      // XXX page was redirected - what should we do?
-      // XXX discard it for now
-      return;
-    }
 
     if (fetchDatum == null || dbDatum == null
         || parseText == null || parseData == null) {
@@ -257,6 +251,7 @@
         LOG.info("Indexer: adding segment: " + segments[i]);
       }
       job.addInputPath(new Path(segments[i], CrawlDatum.FETCH_DIR_NAME));
+      job.addInputPath(new Path(segments[i], CrawlDatum.PARSE_DIR_NAME));
       job.addInputPath(new Path(segments[i], ParseData.DIR_NAME));
       job.addInputPath(new Path(segments[i], ParseText.DIR_NAME));
     }
