Index: conf/nutch-default.xml
===================================================================
--- conf/nutch-default.xml	(revision 1324658)
+++ conf/nutch-default.xml	(working copy)
@@ -1349,4 +1349,13 @@
   your credentials.
   </description>
 </property>
+
+<property>
+  <name>generate.max.depth</name>
+  <value>-1</value>
+  <description>max depth of crawler, filter urls with this factor in generate.
+        set -1 to skip this filter.
+  </description>
+</property>
+
 </configuration>
Index: src/java/org/apache/nutch/metadata/Nutch.java
===================================================================
--- src/java/org/apache/nutch/metadata/Nutch.java	(revision 1324658)
+++ src/java/org/apache/nutch/metadata/Nutch.java	(working copy)
@@ -39,6 +39,8 @@
 
   public static final String SCORE_KEY = "nutch.crawl.score";
 
+  public static final String DEPTH_KEY = "nutch.crawl.depth";
+
   public static final String GENERATE_TIME_KEY = "_ngt_";
 
   public static final Text WRITABLE_GENERATE_TIME_KEY = new Text(GENERATE_TIME_KEY);
Index: src/java/org/apache/nutch/crawl/CrawlDatum.java
===================================================================
--- src/java/org/apache/nutch/crawl/CrawlDatum.java	(revision 1324658)
+++ src/java/org/apache/nutch/crawl/CrawlDatum.java	(working copy)
@@ -120,6 +120,7 @@
   private byte retries;
   private int fetchInterval;
   private float score = 0.0f;
+  private int depth=0;
   private byte[] signature = null;
   private long modifiedTime;
   private org.apache.hadoop.io.MapWritable metaData;
@@ -194,6 +195,9 @@
   public float getScore() { return score; }
   public void setScore(float score) { this.score = score; }
 
+  public int getDepth() { return depth; }
+  public void setDepth(int depth) { this.depth=depth; }
+
   public byte[] getSignature() {
     return signature;
   }
@@ -288,6 +292,12 @@
         status = STATUS_DB_UNFETCHED;
       
     }
+    try{
+    	depth=in.readInt();
+    }
+    catch(Exception e){
+    	depth=0;
+    }
   }
 
   /** The number of bytes into a CrawlDatum that the score is stored. */
@@ -314,6 +324,7 @@
     } else {
       out.writeBoolean(false);
     }
+    out.writeInt(depth);
   }
 
   /** Copy the contents of another instance into this instance. */
@@ -330,6 +341,7 @@
     } else {
       this.metaData = null;
     }
+    this.depth=that.depth;
   }
 
 
@@ -419,6 +431,7 @@
       }
     }
     buf.append('\n');
+    buf.append("Depth: " + getDepth() + "\n");
     return buf.toString();
   }
   
Index: src/java/org/apache/nutch/crawl/Generator.java
===================================================================
--- src/java/org/apache/nutch/crawl/Generator.java	(revision 1324658)
+++ src/java/org/apache/nutch/crawl/Generator.java	(working copy)
@@ -135,6 +135,7 @@
     private String restrictStatus = null;
     private int maxNumSegments = 1;
     int currentsegmentnum = 1;
+    private int maxDepth=-1;
 
     public void configure(JobConf job) {
       curTime = job.getLong(GENERATOR_CUR_TIME, System.currentTimeMillis());
@@ -163,6 +164,7 @@
       restrictStatus = job.get(GENERATOR_RESTRICT_STATUS, null);
       maxNumSegments = job.getInt(GENERATOR_MAX_NUM_SEGMENTS, 1);
       segCounts = new int[maxNumSegments];
+      maxDepth=job.getInt("generate.max.depth", -1);
     }
 
     public void close() {}
@@ -185,6 +187,12 @@
       }
       CrawlDatum crawlDatum = value;
 
+      //check depth
+      if(maxDepth!= -1 && crawlDatum.getDepth()>maxDepth){
+          LOG.debug("-depth rejected '" + url.toString());
+    	  return;
+      }
+
       // check fetch schedule
       if (!schedule.shouldFetch(url, crawlDatum, curTime)) {
         LOG.debug("-shouldFetch rejected '" + url + "', fetchTime="
Index: src/java/org/apache/nutch/parse/ParseOutputFormat.java
===================================================================
--- src/java/org/apache/nutch/parse/ParseOutputFormat.java	(revision 1324658)
+++ src/java/org/apache/nutch/parse/ParseOutputFormat.java	(working copy)
@@ -241,6 +241,7 @@
               target.setScore(0.0f);
             }
 
+	    target.setDepth(Integer.parseInt(parse.getData().getContentMeta().get(Nutch.DEPTH_KEY))+1);
             targets.add(new SimpleEntry(targetUrl, target));
 
             // OVerwrite URL in Outlink object with normalized URL (NUTCH-1174)
Index: src/plugin/scoring-opic/src/java/org/apache/nutch/scoring/opic/OPICScoringFilter.java
===================================================================
--- src/plugin/scoring-opic/src/java/org/apache/nutch/scoring/opic/OPICScoringFilter.java	(revision 1324658)
+++ src/plugin/scoring-opic/src/java/org/apache/nutch/scoring/opic/OPICScoringFilter.java	(working copy)
@@ -100,11 +100,13 @@
   /** Store a float value of CrawlDatum.getScore() under Fetcher.SCORE_KEY. */
   public void passScoreBeforeParsing(Text url, CrawlDatum datum, Content content) {
     content.getMetadata().set(Nutch.SCORE_KEY, "" + datum.getScore());
+    content.getMetadata().set(Nutch.DEPTH_KEY, "" + datum.getDepth());
   }
 
   /** Copy the value from Content metadata under Fetcher.SCORE_KEY to parseData. */
   public void passScoreAfterParsing(Text url, Content content, Parse parse) {
     parse.getData().getContentMeta().set(Nutch.SCORE_KEY, content.getMetadata().get(Nutch.SCORE_KEY));
+    parse.getData().getContentMeta().set(Nutch.DEPTH_KEY, content.getMetadata().get(Nutch.DEPTH_KEY));
   }
 
   /** Get a float value from Fetcher.SCORE_KEY, divide it by the number of outlinks and apply. */
