Index: src/main/java/org/codehaus/mojo/castor/GenerateMojo.java
===================================================================
--- src/main/java/org/codehaus/mojo/castor/GenerateMojo.java	(revision 7227)
+++ src/main/java/org/codehaus/mojo/castor/GenerateMojo.java	(working copy)
@@ -19,6 +19,7 @@
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
@@ -77,6 +78,12 @@
     private File schemaDirectory;
 
     /**
+     * If true, the schema directory is scanned recursively for *.xsd files 
+     * @parameter default-value="false"
+     */
+    private boolean recursive = false;
+
+    /**
      * The directory to output the generated sources to
      * 
      * @parameter expression="${project.build.directory}/generated-sources/castor"
@@ -151,7 +158,7 @@
     private String packaging;
     
     /**
-     * Whether to generate Java classes fro imported XML schemas or not.
+     * Whether to generate Java classes from imported XML schemas or not.
      * @parameter default-value="false"
      */
     private boolean generateImportedSchemas = false;
@@ -195,6 +202,7 @@
 
         config();
 
+        getLog().info( "Processing " + staleXSDs.size() + " xsds");
         for ( Iterator i = staleXSDs.iterator(); i.hasNext(); )
         {
             File xsd = (File) i.next();
@@ -203,9 +211,19 @@
             {
 
                 processFile( xsd.getCanonicalPath() );
-                // make sure this is after the acutal processing, 
+
+                // copy stale xsd to timestamp directory 
+                File timeStampDir = getTimeStampDirectory(); 
+                if ( ( schema == null || !schema.exists() ) && recursive && !xsd.getParentFile().equals( schemaDirectory ) )
+                {
+                    // for a schema directory hierarchy preserve the relative path 
+                    String relativePath = xsd.getParentFile().getCanonicalPath().substring( schemaDirectory.getCanonicalPath().length() + 1 );
+                    timeStampDir = new File(timeStampDir, relativePath );
+                }
+
+                // make sure this is after the actual processing, 
                 //otherwise it if fails the computeStaleXSDs will think it completed.
-                FileUtils.copyFileToDirectory( xsd, getTimeStampDirectory() );
+                FileUtils.copyFileToDirectory( xsd, timeStampDir);
             }
             catch ( Exception e )
             {
@@ -271,7 +289,9 @@
 
     private SourceInclusionScanner getSourceInclusionScanner()
     {
-        return new StaleSourceScanner( staleMillis );
+        return new StaleSourceScanner( staleMillis,
+        		( recursive ? Collections.singleton( "**/*" ) : Collections.singleton( "*" ) ), 
+                Collections.EMPTY_SET );
     }
 
     private File getTimeStampDirectory()
