Index: pom.xml
===================================================================
--- pom.xml	(revision 37111)
+++ pom.xml	(working copy)
@@ -10,7 +10,7 @@
 	<artifactId>doxygen</artifactId>
 	<packaging>hpi</packaging>
 	<name>Hudson Doxygen Plug-in</name>
-	<version>0.7-SNAPSHOT</version>
+	<version>0.7-Matrix</version>
 	<url>http://wiki.hudson-ci.org/display/HUDSON/Doxygen+Plugin</url>
 
     <licenses>
Index: src/main/java/hudson/plugins/doxygen/DoxygenArchiver.java
===================================================================
--- src/main/java/hudson/plugins/doxygen/DoxygenArchiver.java	(revision 37111)
+++ src/main/java/hudson/plugins/doxygen/DoxygenArchiver.java	(working copy)
@@ -1,37 +1,57 @@
 package hudson.plugins.doxygen;
 
+import hudson.AbortException;
 import hudson.Extension;
 import hudson.FilePath;
 import hudson.Launcher;
-import hudson.tasks.*;
-import hudson.util.FormValidation;
-import hudson.model.AbstractBuild;
-import hudson.model.AbstractItem;
-import hudson.model.AbstractProject;
+import hudson.matrix.MatrixAggregatable;
+import hudson.matrix.MatrixAggregator;
+import hudson.matrix.MatrixConfiguration;
+import hudson.matrix.MatrixRun;
+import hudson.matrix.MatrixBuild;
+import hudson.matrix.MatrixProject;
 import hudson.model.Action;
 import hudson.model.BuildListener;
-import hudson.model.DirectoryBrowserSupport;
 import hudson.model.ProminentProjectAction;
 import hudson.model.Result;
+import hudson.model.AbstractBuild;
+import hudson.model.AbstractItem;
+import hudson.model.AbstractProject;
+import hudson.model.DirectoryBrowserSupport;
+import hudson.model.Hudson;
+import hudson.model.Label;
 import hudson.model.Run;
+import hudson.tasks.BuildStepDescriptor;
+import hudson.tasks.BuildStepMonitor;
+import hudson.tasks.Publisher;
+import hudson.tasks.Recorder;
+import hudson.util.FormValidation;
 
 import java.io.File;
 import java.io.IOException;
 import java.io.Serializable;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import javax.servlet.ServletException;
 
 import net.sf.json.JSONObject;
-import org.kohsuke.stapler.*;
+
+import org.kohsuke.stapler.AncestorInPath;
+import org.kohsuke.stapler.DataBoundConstructor;
+import org.kohsuke.stapler.QueryParameter;
+import org.kohsuke.stapler.StaplerRequest;
+import org.kohsuke.stapler.StaplerResponse;
 
 /**
  * 
  * @author Gregory Boissinot
  */
-public class DoxygenArchiver extends Recorder implements Serializable {
+public class DoxygenArchiver extends Recorder implements Serializable,MatrixAggregatable  {
 
 	private static final long serialVersionUID = 1L;
-
+	private static final Logger LOGGER = Logger.getLogger(DoxygenArchiver.class.getName());
+	
 	@Extension
 	public static final DoxygenArchiverDescriptor DESCRIPTOR = new DoxygenArchiverDescriptor();
 
@@ -49,6 +69,11 @@
 	 * The publishing type : with the doxyfile or directly the html directory
 	 */ 
 	private transient String publishType;
+	
+	
+	public String runOnChild;
+	
+	public String folderWhereYouRunDoxygen;
 
 	/**
 	 * The doxygen html directory
@@ -107,12 +132,19 @@
 		public boolean isApplicable(Class<? extends AbstractProject> jobType) {
 			return true;
 		}
+		
+		public boolean isMatrixProject(AbstractProject<?, ?> project) {
+			return project instanceof MatrixProject;
+		}
+				
 	}
 
 	@DataBoundConstructor
-	public DoxygenArchiver(String doxyfilePath, boolean keepAll) {
+	public DoxygenArchiver(String doxyfilePath, boolean keepAll,String runOnChild,String folderWhereYouRunDoxygen) {
 		this.doxyfilePath = doxyfilePath.trim();
 		this.keepAll = keepAll;
+		this.runOnChild = (null != runOnChild)?runOnChild.trim():null;
+		this.folderWhereYouRunDoxygen = folderWhereYouRunDoxygen;
 	}
 
 	@Override
@@ -139,6 +171,16 @@
 	public boolean perform(AbstractBuild<?, ?> build, Launcher launcher,
 			BuildListener listener) throws InterruptedException, IOException {
 
+		// Check if this project is a matrix project .. then build will be taken from some child and not from here 
+		if (! (build.getProject() instanceof MatrixConfiguration)){
+			return _perform(build,launcher,listener);
+		}
+		return true;
+	}
+
+	
+	private boolean _perform(AbstractBuild<?, ?> build, Launcher launcher,BuildListener listener){
+		
 		if ((build.getResult().equals(Result.SUCCESS))
 				|| (build.getResult().equals(Result.UNSTABLE))) {
 
@@ -146,8 +188,37 @@
 
 			try {
 				DoxygenDirectoryParser parser = new DoxygenDirectoryParser(
-						publishType, doxyfilePath, doxygenHtmlDirectory);
-				FilePath doxygenGeneratedDir = build.getWorkspace().act(parser);
+						publishType, doxyfilePath, doxygenHtmlDirectory,folderWhereYouRunDoxygen);
+				
+				
+				
+				// If we are matrix project then we will take from the node as we passed,
+				// otherwise from current build 
+				FilePath doxygenGeneratedDir = null;
+				if ((getDescriptor().isMatrixProject(build.getProject())) && (null != runOnChild)){
+					MatrixBuild _thebuild = (MatrixBuild)build;					
+					Label childLabel = Hudson.getInstance().getLabel(runOnChild);
+					
+					// If label is an instance label it is easy to locate the computer .. but if label is 
+					// a group label, we need to find some slave that runs the build and that it is assigned to 
+					// that label
+					for (MatrixRun run : _thebuild.getRuns()){
+						// Check if this run runs on the node that is assigned this label 
+						if (run.getBuiltOn().getAssignedLabels().contains(childLabel)){														
+							doxygenGeneratedDir = run.getWorkspace().act(parser);
+							LOGGER.log(Level.INFO,"Selected node is " + run.getBuiltOn().getDisplayName());
+							break;
+						}
+					} 	
+					// If we got here and did not assign the directory .. it means that build does not run on this node, or group of nodes 
+					if (null == doxygenGeneratedDir){
+						LOGGER.log(Level.CONFIG,"Project " + build.getProject().getDisplayName() + " is not build on any node that is assigned label " + runOnChild);
+						throw new AbortException("Build does not run on any node with label" + runOnChild);
+					}
+				}else{
+					doxygenGeneratedDir = build.getWorkspace().act(parser);
+				}
+
 
 				listener.getLogger().println(
 						"The determined Doxygen directory is '"
@@ -191,7 +262,9 @@
 		}
 		return true;
 	}
-
+	
+	
+	
 	public BuildStepMonitor getRequiredMonitorService() {
 		return BuildStepMonitor.STEP;
 	}
@@ -282,4 +355,15 @@
 		}
 	}
 
+	public MatrixAggregator createAggregator(MatrixBuild build,
+			Launcher launcher, BuildListener listener) {
+		
+		return new MatrixAggregator(build,launcher,listener) {
+			
+			 public boolean endBuild() throws InterruptedException, IOException {
+				 return DoxygenArchiver.this._perform(build, launcher, listener);
+			 }
+		};
+	}
+
 }
Index: src/main/java/hudson/plugins/doxygen/DoxygenDirectoryParser.java
===================================================================
--- src/main/java/hudson/plugins/doxygen/DoxygenDirectoryParser.java	(revision 37111)
+++ src/main/java/hudson/plugins/doxygen/DoxygenDirectoryParser.java	(working copy)
@@ -43,11 +43,20 @@
     private String publishType;
     private String doxygenHtmlDirectory;
     private String doxyfilePath;
+    private String folderWhereYouRunDoxygen;
     
     public DoxygenDirectoryParser(String publishType, String doxyfilePath, String doxygenHtmlDirectory){
     	this.publishType=publishType;
     	this.doxyfilePath=doxyfilePath;
     	this.doxygenHtmlDirectory=doxygenHtmlDirectory;
+    	this.folderWhereYouRunDoxygen = null;
+    }
+    
+    public DoxygenDirectoryParser(String publishType, String doxyfilePath, String doxygenHtmlDirectory,String folderWhereYouRunDoxygen){
+    	this.publishType=publishType;
+    	this.doxyfilePath=doxyfilePath;
+    	this.doxygenHtmlDirectory=doxygenHtmlDirectory;
+    	this.folderWhereYouRunDoxygen = folderWhereYouRunDoxygen;
     }
     
     public FilePath invoke(java.io.File workspace, VirtualChannel channel) throws IOException {
@@ -115,7 +124,14 @@
     	String outputDirectory = doxyfileInfos.get(DOXYGEN_KEY_OUTPUT_DIRECTORY);    	
     	String doxyGenDir = null;
     	if (outputDirectory!= null && outputDirectory.trim().length() != 0){
-    		doxyGenDir = outputDirectory;    		
+    		
+    		// Check if need to append the path from where doxygen is run 
+    		if ((null != this.folderWhereYouRunDoxygen) && (!this.folderWhereYouRunDoxygen.isEmpty())){
+    			doxyGenDir = this.folderWhereYouRunDoxygen + File.separator + outputDirectory;
+    		}else{
+    			doxyGenDir = outputDirectory;
+    		}
+    		    		
     	}
     	
     	String outputHTML      = doxyfileInfos.get(DOXYGEN_KEY_HTML_OUTPUT);
@@ -124,7 +140,12 @@
     		LOGGER.log(Level.INFO,"The "+DOXYGEN_KEY_HTML_OUTPUT+" tag is not present or is left blank." + DOXYGEN_DEFAULT_HTML_OUTPUT+ " will be used as the default path.");
     	}
     	else {
-    		doxyGenDir = (doxyGenDir!=null)?(doxyGenDir+ File.separator + outputHTML):outputHTML;
+    		// Check if folderWhereYouRunDoxygen is specified, because then the gen dir is calculated relative to it 
+    		if ((null != this.folderWhereYouRunDoxygen) && (!this.folderWhereYouRunDoxygen.isEmpty())){
+    			doxyGenDir = (folderWhereYouRunDoxygen+ File.separator + outputHTML);
+    		}else{
+    			doxyGenDir = (doxyGenDir!=null)?(doxyGenDir+ File.separator + outputHTML):outputHTML;
+    		}
     		return new FilePath(base, doxyGenDir);
     	}    	
     	
@@ -287,7 +308,8 @@
 		if (isDoxygenGenerateHtml()){
 			
 			//Retrieve the generated doxygen directory from the build
-			doxygenGeneratedDir = getDoxygenGeneratedDir(base);                
+			doxygenGeneratedDir = getDoxygenGeneratedDir(base);     
+			LOGGER.log(Level.INFO,"Selected Directory path is " + doxygenGeneratedDir);
 			if (!doxygenGeneratedDir.exists()){
 		        throw new AbortException("The directory '"+ doxygenGeneratedDir + "' doesn't exist.");
 			}
Index: src/main/resources/hudson/plugins/doxygen/DoxygenArchiver/config.jelly
===================================================================
--- src/main/resources/hudson/plugins/doxygen/DoxygenArchiver/config.jelly	(revision 37111)
+++ src/main/resources/hudson/plugins/doxygen/DoxygenArchiver/config.jelly	(working copy)
@@ -1,10 +1,24 @@
 <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout"
          xmlns:t="/lib/hudson" xmlns:f="/lib/form">
-
+   
     <f:entry title="Doxyfile path" help="/plugin/doxygen/DoxygenArchiver/doxyfilePath.html">
         <f:textbox field="doxyfilePath"/>
     </f:entry>
-
+   
+   <j:if test="${descriptor.isMatrixProject(it)}">  
+   	   <j:set var="dep" value="${app.labels}"/>  
+	   <f:entry title="${%Node}" help="/plugin/doxygen/DoxygenArchiver/slaves.html">
+	    <select class="setting-input"  name="runOnChild">
+	      <j:forEach var="s" items="${app.labels}">
+	        <j:if test="${s.isAssignable()}">
+	          <f:option selected="${s.name==instance.runOnChild}" value="${s.name}"
+	            >${s.name} <j:if test="${!empty(s.description)}">(${s.description})</j:if></f:option>
+	        </j:if>
+	      </j:forEach>
+	    </select>
+	  </f:entry>
+  </j:if>
+         
 
     <f:block>
         <f:entry help="/plugin/doxygen/DoxygenArchiver/keepall.html">
@@ -13,5 +27,12 @@
             <label/>
         </f:entry>
     </f:block>
+    
+    <f:advanced>
+    <f:entry title="${%FolderWhereYouRunDoxygen}" help="/plugin/doxygen/DoxygenArchiver/FolderWhereYouRunDoxygen.html">
+      <f:textbox field="folderWhereYouRunDoxygen"/>
+    </f:entry>    
+  	</f:advanced>
+  
 
 </j:jelly>
\ No newline at end of file
Index: src/main/resources/hudson/plugins/doxygen/DoxygenArchiver/config.properties
===================================================================
--- src/main/resources/hudson/plugins/doxygen/DoxygenArchiver/config.properties	(revision 0)
+++ src/main/resources/hudson/plugins/doxygen/DoxygenArchiver/config.properties	(revision 0)
@@ -0,0 +1,24 @@
+# The MIT License
+#
+# Copyright (c) 2004-2010, Sun Microsystems, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+Node=Take DoxyGen files from Slave
+FolderWhereYouRunDoxygen=Folder from which doxygen is run
Index: src/main/webapp/DoxygenArchiver/FolderWhereYouRunDoxygen.html
===================================================================
--- src/main/webapp/DoxygenArchiver/FolderWhereYouRunDoxygen.html	(revision 0)
+++ src/main/webapp/DoxygenArchiver/FolderWhereYouRunDoxygen.html	(revision 0)
@@ -0,0 +1,4 @@
+<div>
+  <p> Give the path from where you run doxygen relative to the <a href='ws/'>root of the workspace</a>       
+  </p>
+</div>
\ No newline at end of file
Index: src/main/webapp/DoxygenArchiver/slaves.html
===================================================================
--- src/main/webapp/DoxygenArchiver/slaves.html	(revision 0)
+++ src/main/webapp/DoxygenArchiver/slaves.html	(revision 0)
@@ -0,0 +1,5 @@
+<div>
+<p>
+Sometimes  <i>Doxygen</i> tool is available only on certain Node. You can specify node that DoxyGen files will be taken from
+</p>
+</div>
\ No newline at end of file
Index: src/test/java/hudson/plugins/doxygen/DoxygenArchiverTest.java
===================================================================
--- src/test/java/hudson/plugins/doxygen/DoxygenArchiverTest.java	(revision 37111)
+++ src/test/java/hudson/plugins/doxygen/DoxygenArchiverTest.java	(working copy)
@@ -23,7 +23,7 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-
+ 
 public class DoxygenArchiverTest extends AbstractWorkspaceTest {
 
      
