Index: main/maven-plugin/src/main/java/hudson/maven/MavenModuleSet.java
===================================================================
--- main/maven-plugin/src/main/java/hudson/maven/MavenModuleSet.java	(revision 17902)
+++ main/maven-plugin/src/main/java/hudson/maven/MavenModuleSet.java	(working copy)
@@ -442,6 +442,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: main/maven-plugin/src/main/java/hudson/maven/AbstractMavenProject.java
===================================================================
--- main/maven-plugin/src/main/java/hudson/maven/AbstractMavenProject.java	(revision 17902)
+++ main/maven-plugin/src/main/java/hudson/maven/AbstractMavenProject.java	(working copy)
@@ -23,22 +23,38 @@
  */
 package hudson.maven;
 
+import hudson.Util;
 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.model.Descriptor.FormException;
+import hudson.tasks.BuildStepDescriptor;
+import hudson.tasks.BuildWrappers;
+import hudson.tasks.Publisher;
+import hudson.tasks.Maven.ProjectWithMaven;
 import hudson.triggers.Trigger;
 import hudson.tasks.Maven.ProjectWithMaven;
 
+import java.io.IOException;
 import java.util.HashSet;
 import java.util.Set;
 
+import javax.servlet.ServletException;
+
+import net.sf.json.JSONObject;
+
+import org.kohsuke.stapler.StaplerRequest;
+import org.kohsuke.stapler.StaplerResponse;
+
 /**
  * Common part between {@link MavenModule} and {@link MavenModuleSet}.
  *
  * @author Kohsuke Kawaguchi
  */
-public abstract class AbstractMavenProject<P extends AbstractMavenProject<P,R>,R extends AbstractBuild<P,R>> extends AbstractProject<P,R>
+public abstract class AbstractMavenProject<P extends AbstractProject<P,R>,R extends AbstractBuild<P,R>> extends AbstractProject<P,R>
     implements ProjectWithMaven {
     protected AbstractMavenProject(ItemGroup parent, String name) {
         super(parent, name);
@@ -63,6 +79,61 @@
             }
         }
     }
+    
+    private boolean blockBuildWhenUpstreamBuilding = true;
 
     protected abstract void addTransientActionsFromBuild(R lastBuild, Set<Class> added);
+    
+    @Override
+	public boolean isBuildBlocked() {
+		boolean blocked = super.isBuildBlocked();
+		if (!blocked && blockBuildWhenUpstreamBuilding) {
+			 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;
+    }
+    
+    public boolean blockBuildWhenUpstreamBuilding() {
+    	return blockBuildWhenUpstreamBuilding;
+    }
+    
+    protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException {
+        super.submit(req,rsp);
+        blockBuildWhenUpstreamBuilding = req.hasParameter("maven.blockBuildWhenUpstreamBuilding");
+    }
 }
Index: main/maven-plugin/src/main/java/hudson/maven/MavenBuild.java
===================================================================
--- main/maven-plugin/src/main/java/hudson/maven/MavenBuild.java	(revision 17902)
+++ main/maven-plugin/src/main/java/hudson/maven/MavenBuild.java	(working copy)
@@ -71,7 +71,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.
@@ -515,113 +515,10 @@
 
         public void cleanUp(BuildListener listener) throws Exception {
             if(getResult().isBetterOrEqualTo(Result.SUCCESS))
-                scheduleDownstreamBuilds(listener,new HashSet<AbstractProject>());
+                scheduleDownstreamBuilds(listener);
         }
     }
 
-    /**
-     * 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;
-        }
-        return null;
-    }
-
     private static final int MAX_PROCESS_CACHE = 5;
 
     protected static final ProcessCache mavenProcessCache = new ProcessCache(MAX_PROCESS_CACHE);
@@ -630,4 +527,9 @@
      * Set true to produce debug output.
      */
     public static boolean debug = false;
+    
+    @Override
+    public MavenModule getParent() {// don't know why, but javac wants this
+        return super.getParent();
+    }
 }
Index: main/maven-plugin/src/main/java/hudson/maven/MavenModuleSetBuild.java
===================================================================
--- main/maven-plugin/src/main/java/hudson/maven/MavenModuleSetBuild.java	(revision 17902)
+++ main/maven-plugin/src/main/java/hudson/maven/MavenModuleSetBuild.java	(working copy)
@@ -29,6 +29,7 @@
 import hudson.Util;
 import hudson.EnvVars;
 import hudson.FilePath.FileCallable;
+import hudson.matrix.MatrixConfiguration;
 import hudson.maven.MavenBuild.ProxyImpl2;
 import hudson.maven.reporters.MavenFingerprinter;
 import hudson.model.AbstractBuild;
@@ -96,7 +97,7 @@
  *
  * @author Kohsuke Kawaguchi
  */
-public final class MavenModuleSetBuild extends AbstractBuild<MavenModuleSet,MavenModuleSetBuild> {
+public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,MavenModuleSetBuild> {
     /**
      * {@link MavenReporter}s that will contribute project actions.
      * Can be null if there's none.
@@ -504,10 +505,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);
                 }
             }
 
@@ -767,4 +765,9 @@
      * Extra versbose debug switch.
      */
     public static boolean debug = false;
+    
+    @Override
+    public MavenModuleSet getParent() {// don't know why, but javac wants this
+        return super.getParent();
+    }
 }
Index: main/maven-plugin/src/main/java/hudson/maven/reporters/MavenArtifactRecord.java
===================================================================
--- main/maven-plugin/src/main/java/hudson/maven/reporters/MavenArtifactRecord.java	(revision 17902)
+++ main/maven-plugin/src/main/java/hudson/maven/reporters/MavenArtifactRecord.java	(working copy)
@@ -119,8 +119,8 @@
         deployer.deploy(main.getFile(),main,deploymentRepository,embedder.getLocalRepository());
 
         for (MavenArtifact aa : attachedArtifacts) {
-            logger.println(Messages.MavenArtifact_DeployingAttachedArtifact(main.getFile().getName()));
             Artifact a = aa.toArtifact(handlerManager,factory, parent);
+            logger.println(Messages.MavenArtifact_DeployingAttachedArtifact(a.getFile().getName()));
             deployer.deploy(a.getFile(),a,deploymentRepository,embedder.getLocalRepository());
         }
     }
Index: main/maven-plugin/src/main/resources/hudson/maven/MavenModuleSet/configure-entries.jelly
===================================================================
--- main/maven-plugin/src/main/resources/hudson/maven/MavenModuleSet/configure-entries.jelly	(revision 17902)
+++ main/maven-plugin/src/main/resources/hudson/maven/MavenModuleSet/configure-entries.jelly	(working copy)
@@ -73,6 +73,8 @@
         checked="${!it.aggregatorStyleBuild}" />
       <f:optionalBlock name="maven.usePrivateRepository" title="${%Use private Maven repository}" help="/help/maven/private-repository.html"
         checked="${it.usesPrivateRepository()}" />
+      <f:optionalBlock name="maven.blockBuildWhenUpstreamBuilding" title="${%Block build when dependency building}" help="/help/maven/block-upstream-building.html"
+        checked="${it.blockBuildWhenUpstreamBuilding()}" />
     </f:advanced>
   </f:section>
 
