Index: src/main/java/hudson/maven/AbstractMavenBuild.java
===================================================================
--- src/main/java/hudson/maven/AbstractMavenBuild.java	(revision 0)
+++ src/main/java/hudson/maven/AbstractMavenBuild.java	(revision 0)
@@ -0,0 +1,146 @@
+package hudson.maven;
+
+import hudson.Util;
+import hudson.model.AbstractBuild;
+import hudson.model.AbstractProject;
+import hudson.model.BuildListener;
+import hudson.model.DependencyGraph;
+import hudson.model.Hudson;
+import hudson.model.Result;
+import hudson.model.Run;
+import hudson.model.Cause.UpstreamCause;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Calendar;
+import java.util.Set;
+
+public abstract class AbstractMavenBuild<P extends AbstractMavenProject<P,R>,R extends AbstractMavenBuild<P,R>> extends AbstractBuild<P, R>  {
+
+	/**
+     * Extra versbose debug switch.
+     */
+    public static boolean debug = false;
+    
+	protected AbstractMavenBuild(P job) throws IOException {
+		super(job);
+	}
+
+	public AbstractMavenBuild(P job, Calendar timestamp) {
+		super(job, timestamp);
+	}
+
+	public AbstractMavenBuild(P project, File buildDir) throws IOException {
+		super(project, buildDir);
+	}
+	
+	/**
+     * Schedules all the downstream builds.
+     *
+     * @param downstreams
+     *      List of downstream jobs that are already scheduled.
+     *      The method will add jobs that it triggered here,
+     *      and won't try to trigger jobs that are already in this list.
+     * @param listener
+     *      Where the progress reports go.
+     */
+    protected final void scheduleDownstreamBuilds(BuildListener listener) {
+        // trigger dependency builds
+        DependencyGraph graph = Hudson.getInstance().getDependencyGraph();
+        for( AbstractProject<?,?> down : getParent().getDownstreamProjects()) {
+//            if(downstreams.contains(down))
+//                continue; // already triggered
+
+            if(debug)
+                listener.getLogger().println("Considering whether to trigger "+down+" or not");
+
+            if(graph.hasIndirectDependencies(getProject(),down)) {
+                // if there's a longer dependency path to this project,
+                // then scheduling the build now is going to be a waste,
+                // so don't do that.
+                // let the longer path eventually trigger this build
+                if(debug)
+                    listener.getLogger().println(" -> No, because there's a longer dependency path");
+                continue;
+            }
+
+            // if the downstream module depends on multiple modules,
+            // only trigger them when all the upstream dependencies are updated.
+            boolean trigger = true;
+
+            if (down.isInQueue()) {
+            	if(debug)
+                    listener.getLogger().println(" -> No, because dependency is already in queue");
+            	trigger = false;
+            } else {
+	            AbstractBuild<?,?> dlb = down.getLastBuild(); // can be null.
+	            for (AbstractMavenProject up : Util.filter(down.getUpstreamProjects(),AbstractMavenProject.class)) {
+	            	Run ulb;
+	                if(up==getParent()) {
+	                    // the current build itself is not registered as lastSuccessfulBuild
+	                    // at this point, so we have to take that into account. ugly.
+	                    if(getResult()==null || !getResult().isWorseThan(Result.UNSTABLE))
+	                        ulb = this;
+	                    else
+	                        ulb = up.getLastSuccessfulBuild();
+	                } else
+	                    ulb = up.getLastSuccessfulBuild();
+	                if(ulb==null) {
+	                    // if no usable build is available from the upstream,
+	                    // then we have to wait at least until this build is ready
+	                    if(debug)
+	                        listener.getLogger().println(" -> No, because another upstream "+up+" for "+down+" has no successful build");
+	                    trigger = false;
+	                    break;
+	                }
+	
+	                // if no record of the relationship in the last build
+	                // is available, we'll just have to assume that the condition
+	                // for the new build is met, or else no build will be fired forever.
+	                if(dlb==null)   continue;
+	                int n = dlb.getUpstreamRelationship(up);
+	                if(n==-1)   continue;
+	
+	                assert ulb.getNumber()>=n;
+	
+	                if(ulb.getNumber()==n) {
+	                    // there's no new build of this upstream since the last build
+	                    // of the downstream, and the upstream build is in progress.
+	                    // The new downstream build should wait until this build is started
+	                    AbstractProject bup = getBuildingUpstream(graph, up);
+	                    if(bup!=null) {
+	                        if(debug)
+	                            listener.getLogger().println(" -> No, because another upstream "+bup+" for "+down+" is building");
+	                        trigger = false;
+	                        break;
+	                    }
+	                }
+	            }
+            }
+
+            if(trigger) {
+                listener.getLogger().println(Messages.MavenBuild_Triggering(down.getName()));
+                down.scheduleBuild(new UpstreamCause(this));
+            }
+        }
+    }
+    
+    /**
+     * Returns the project if any of the upstream project (or itself) is either
+     * building or is in the queue.
+     * <p>
+     * This means eventually there will be an automatic triggering of
+     * the given project (provided that all builds went smoothly.)
+     */
+    private AbstractProject getBuildingUpstream(DependencyGraph graph, AbstractProject project) {
+        Set<AbstractProject> tups = graph.getTransitiveUpstream(project);
+        tups.add(project);
+        for (AbstractProject tup : tups) {
+            if(tup!=getProject() && (tup.isBuilding() || tup.isInQueue()))
+                return tup;
+        }
+        return null;
+    }
+	
+
+}
Index: src/main/java/hudson/maven/AbstractMavenProject.java
===================================================================
--- src/main/java/hudson/maven/AbstractMavenProject.java	(revision 15307)
+++ src/main/java/hudson/maven/AbstractMavenProject.java	(working copy)
@@ -26,9 +26,11 @@
 import hudson.model.AbstractBuild;
 import hudson.model.AbstractProject;
 import hudson.model.Action;
+import hudson.model.DependencyGraph;
+import hudson.model.Hudson;
 import hudson.model.ItemGroup;
-import hudson.triggers.Trigger;
 import hudson.tasks.Maven.ProjectWithMaven;
+import hudson.triggers.Trigger;
 
 import java.util.HashSet;
 import java.util.Set;
@@ -65,4 +67,48 @@
     }
 
     protected abstract void addTransientActionsFromBuild(R lastBuild, Set<Class> added);
+    
+    @Override
+	public boolean isBuildBlocked() {
+		boolean blocked = super.isBuildBlocked();
+		if (!blocked) {
+			 DependencyGraph graph = Hudson.getInstance().getDependencyGraph();
+			 AbstractProject bup = getBuildingUpstream();
+             if(bup!=null) {
+                 return true;
+             }
+		}
+		return blocked;
+	}
+    
+    public String getWhyBlocked() {
+    	if (super.isBuildBlocked()) {
+    		return super.getWhyBlocked();
+    	} else {
+	    	AbstractProject bup = getBuildingUpstream();
+	    	String projectName = "";
+	        if(bup!=null) {
+	        	projectName = bup.getName();
+	        }
+	    	return "Upstream project is building: " + projectName;
+    	}
+    }
+    
+    /**
+     * Returns the project if any of the upstream project (or itself) is either
+     * building or is in the queue.
+     * <p>
+     * This means eventually there will be an automatic triggering of
+     * the given project (provided that all builds went smoothly.)
+     */
+    private AbstractProject getBuildingUpstream() {
+    	DependencyGraph graph = Hudson.getInstance().getDependencyGraph();
+        Set<AbstractProject> tups = graph.getTransitiveUpstream(this);
+        tups.add(this);
+        for (AbstractProject tup : tups) {
+            if(tup!=this && (tup.isBuilding() || tup.isInQueue()))
+                return tup;
+        }
+        return null;
+    }
 }
Index: src/main/java/hudson/maven/MavenBuild.java
===================================================================
--- src/main/java/hudson/maven/MavenBuild.java	(revision 15307)
+++ src/main/java/hudson/maven/MavenBuild.java	(working copy)
@@ -68,7 +68,7 @@
  * 
  * @author Kohsuke Kawaguchi
  */
-public class MavenBuild extends AbstractBuild<MavenModule,MavenBuild> {
+public class MavenBuild extends AbstractMavenBuild<MavenModule,MavenBuild> {
     /**
      * {@link MavenReporter}s that will contribute project actions.
      * Can be null if there's none.
@@ -493,111 +493,8 @@
 
         public void cleanUp(BuildListener listener) throws Exception {
             if(getResult().isBetterOrEqualTo(Result.SUCCESS))
-                scheduleDownstreamBuilds(listener,new HashSet<AbstractProject>());
-        }
-    }
-
-    /**
-     * Schedules all the downstream builds.
-     *
-     * @param downstreams
-     *      List of downstream jobs that are already scheduled.
-     *      The method will add jobs that it triggered here,
-     *      and won't try to trigger jobs that are already in this list.
-     * @param listener
-     *      Where the progress reports go.
-     */
-    /*package*/ final void scheduleDownstreamBuilds(BuildListener listener, Set<AbstractProject> downstreams) {
-        // trigger dependency builds
-        DependencyGraph graph = Hudson.getInstance().getDependencyGraph();
-        for( AbstractProject<?,?> down : getParent().getDownstreamProjects()) {
-            if(downstreams.contains(down))
-                continue; // already triggered
-
-            if(debug)
-                listener.getLogger().println("Considering whether to trigger "+down+" or not");
-
-            if(graph.hasIndirectDependencies(getProject(),down)) {
-                // if there's a longer dependency path to this project,
-                // then scheduling the build now is going to be a waste,
-                // so don't do that.
-                // let the longer path eventually trigger this build
-                if(debug)
-                    listener.getLogger().println(" -> No, because there's a longer dependency path");
-                continue;
-            }
-
-            // if the downstream module depends on multiple modules,
-            // only trigger them when all the upstream dependencies are updated.
-            boolean trigger = true;
-
-            AbstractBuild<?,?> dlb = down.getLastBuild(); // can be null.
-            for (MavenModule up : Util.filter(down.getUpstreamProjects(),MavenModule.class)) {
-                MavenBuild ulb;
-                if(up==getProject()) {
-                    // the current build itself is not registered as lastSuccessfulBuild
-                    // at this point, so we have to take that into account. ugly.
-                    if(getResult()==null || !getResult().isWorseThan(Result.UNSTABLE))
-                        ulb = MavenBuild.this;
-                    else
-                        ulb = up.getLastSuccessfulBuild();
-                } else
-                    ulb = up.getLastSuccessfulBuild();
-                if(ulb==null) {
-                    // if no usable build is available from the upstream,
-                    // then we have to wait at least until this build is ready
-                    if(debug)
-                        listener.getLogger().println(" -> No, because another upstream "+up+" for "+down+" has no successful build");
-                    trigger = false;
-                    break;
-                }
-
-                // if no record of the relationship in the last build
-                // is available, we'll just have to assume that the condition
-                // for the new build is met, or else no build will be fired forever.
-                if(dlb==null)   continue;
-                int n = dlb.getUpstreamRelationship(up);
-                if(n==-1)   continue;
-
-                assert ulb.getNumber()>=n;
-
-                if(ulb.getNumber()==n) {
-                    // there's no new build of this upstream since the last build
-                    // of the downstream, and the upstream build is in progress.
-                    // The new downstream build should wait until this build is started
-                    AbstractProject bup = getBuildingUpstream(graph, up);
-                    if(bup!=null) {
-                        if(debug)
-                            listener.getLogger().println(" -> No, because another upstream "+bup+" for "+down+" is building");
-                        trigger = false;
-                        break;
-                    }
-                }
-            }
-
-            if(trigger) {
-                listener.getLogger().println(Messages.MavenBuild_Triggering(down.getName()));
-                downstreams.add(down);
-                down.scheduleBuild(new UpstreamCause(this));
-            }
-        }
-    }
-
-    /**
-     * Returns the project if any of the upstream project (or itself) is either
-     * building or is in the queue.
-     * <p>
-     * This means eventually there will be an automatic triggering of
-     * the given project (provided that all builds went smoothly.)
-     */
-    private AbstractProject getBuildingUpstream(DependencyGraph graph, AbstractProject project) {
-        Set<AbstractProject> tups = graph.getTransitiveUpstream(project);
-        tups.add(project);
-        for (AbstractProject tup : tups) {
-            if(tup!=getProject() && (tup.isBuilding() || tup.isInQueue()))
-                return tup;
+                scheduleDownstreamBuilds(listener);
         }
-        return null;
     }
 
     private static final int MAX_PROCESS_CACHE = 5;
Index: src/main/java/hudson/maven/MavenModuleSet.java
===================================================================
--- src/main/java/hudson/maven/MavenModuleSet.java	(revision 15307)
+++ src/main/java/hudson/maven/MavenModuleSet.java	(working copy)
@@ -438,6 +438,10 @@
     }
 
     protected void buildDependencyGraph(DependencyGraph graph) {
+    	Collection<MavenModule> modules = getModules();
+    	for (MavenModule m : modules) {
+    		m.buildDependencyGraph(graph);
+    	}
         publishers.buildDependencyGraph(this,graph);
         buildWrappers.buildDependencyGraph(this,graph);
     }
Index: src/main/java/hudson/maven/MavenModuleSetBuild.java
===================================================================
--- src/main/java/hudson/maven/MavenModuleSetBuild.java	(revision 15307)
+++ src/main/java/hudson/maven/MavenModuleSetBuild.java	(working copy)
@@ -25,11 +25,9 @@
 
 import hudson.AbortException;
 import hudson.FilePath;
-import hudson.FilePath.FileCallable;
 import hudson.Launcher;
 import hudson.Util;
-import hudson.tasks.BuildWrapper;
-import hudson.tasks.Maven.MavenInstallation;
+import hudson.FilePath.FileCallable;
 import hudson.maven.MavenBuild.ProxyImpl2;
 import hudson.maven.reporters.MavenFingerprinter;
 import hudson.model.AbstractBuild;
@@ -39,23 +37,15 @@
 import hudson.model.BuildListener;
 import hudson.model.Fingerprint;
 import hudson.model.Hudson;
-import hudson.model.Result;
 import hudson.model.ParametersAction;
+import hudson.model.Result;
 import hudson.model.Cause.UpstreamCause;
 import hudson.remoting.Channel;
 import hudson.remoting.VirtualChannel;
+import hudson.tasks.BuildWrapper;
+import hudson.tasks.Maven.MavenInstallation;
 import hudson.util.ArgumentListBuilder;
 import hudson.util.StreamTaskListener;
-import org.apache.maven.BuildFailureException;
-import org.apache.maven.embedder.MavenEmbedderException;
-import org.apache.maven.execution.MavenSession;
-import org.apache.maven.execution.ReactorManager;
-import org.apache.maven.lifecycle.LifecycleExecutionException;
-import org.apache.maven.monitor.event.EventDispatcher;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.project.ProjectBuildingException;
-import org.kohsuke.stapler.StaplerRequest;
-import org.kohsuke.stapler.StaplerResponse;
 
 import java.io.File;
 import java.io.IOException;
@@ -68,12 +58,23 @@
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
 import java.util.Properties;
+import java.util.Set;
+import java.util.Map.Entry;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import org.apache.maven.BuildFailureException;
+import org.apache.maven.embedder.MavenEmbedderException;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.execution.ReactorManager;
+import org.apache.maven.lifecycle.LifecycleExecutionException;
+import org.apache.maven.monitor.event.EventDispatcher;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectBuildingException;
+import org.kohsuke.stapler.StaplerRequest;
+import org.kohsuke.stapler.StaplerResponse;
+
 /**
  * {@link Build} for {@link MavenModuleSet}.
  *
@@ -91,7 +92,7 @@
  *
  * @author Kohsuke Kawaguchi
  */
-public final class MavenModuleSetBuild extends AbstractBuild<MavenModuleSet,MavenModuleSetBuild> {
+public final class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,MavenModuleSetBuild> {
     /**
      * {@link MavenReporter}s that will contribute project actions.
      * Can be null if there's none.
@@ -492,10 +493,7 @@
                 // schedule downstream builds. for non aggregator style builds,
                 // this is done by each module
                 if(getResult().isBetterOrEqualTo(Result.SUCCESS)) {
-                    for(AbstractProject down : getProject().getDownstreamProjects()) {
-                        listener.getLogger().println(Messages.MavenBuild_Triggering(down.getName()));
-                        down.scheduleBuild(new UpstreamCause(MavenModuleSetBuild.this));
-                    }
+                	scheduleDownstreamBuilds(listener);
                 }
             }
 
@@ -503,7 +501,7 @@
             performAllBuildStep(listener, project.getProperties(),false);
         }
     }
-
+    
     /**
      * Runs Maven and builds the project.
      *
@@ -752,8 +750,4 @@
 
     private static final Logger LOGGER = Logger.getLogger(MavenModuleSetBuild.class.getName());
 
-    /**
-     * Extra versbose debug switch.
-     */
-    public static boolean debug = false;
 }