Index: src/main/groovy/org/gradle/api/tasks/diagnostics/AsciiGraphRenderer.java
===================================================================
--- src/main/groovy/org/gradle/api/tasks/diagnostics/AsciiGraphRenderer.java	(revision 0)
+++ src/main/groovy/org/gradle/api/tasks/diagnostics/AsciiGraphRenderer.java	(revision 0)
@@ -0,0 +1,61 @@
+package org.gradle.api.tasks.diagnostics;
+
+import org.gradle.api.dependencies.report.IvyDependencyGraph;
+import org.gradle.api.dependencies.report.IvyDependency;
+
+import java.io.*;
+
+/**
+ * Simple dependency graph renderer that emits an ASCII tree.
+ *
+ * @author Phil Messenger
+ */
+public class AsciiGraphRenderer implements DependencyGraphRenderer {
+
+    public void render(IvyDependencyGraph graph, OutputStream output) throws IOException
+    {
+        OutputStreamWriter writer = new OutputStreamWriter(output);
+
+        render(graph.getRoot(), 1, writer);
+
+        writer.close();
+    }
+
+    private void render(IvyDependency node, int depth, Writer writer) throws IOException
+    {
+        writer.write(getIndent(depth));
+		writer.write(node.toString());
+		writer.write("\n");
+
+		for(IvyDependency dep : node.getDependencies())
+		{
+			render(dep, depth + 1, writer);
+		}
+    }
+
+
+    /**
+	 * Generate an approriate tab-indented string for the supplied depth
+	 *
+	 * @param depth
+	 * @return
+	 */
+	private String getIndent(int depth)
+	{
+		StringBuilder buffer = new StringBuilder();
+
+		for(int x = 0; x < depth - 1; x++)
+		{
+            if(x > 0)
+            {
+                buffer.append("|");
+            }
+
+			buffer.append("\t");
+		}
+
+		buffer.append("|-----");
+
+		return buffer.toString();
+	}
+}
Index: src/main/groovy/org/gradle/api/tasks/diagnostics/GraphvizGraphRenderer.java
===================================================================
--- src/main/groovy/org/gradle/api/tasks/diagnostics/GraphvizGraphRenderer.java	(revision 0)
+++ src/main/groovy/org/gradle/api/tasks/diagnostics/GraphvizGraphRenderer.java	(revision 0)
@@ -0,0 +1,57 @@
+package org.gradle.api.tasks.diagnostics;
+
+import org.gradle.api.dependencies.report.IvyDependencyGraph;
+import org.gradle.api.dependencies.report.IvyDependency;
+
+import java.io.OutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.Set;
+import java.util.HashSet;
+
+/**
+ * DependencyGraphRenderer that emits simple graphviz dot notation for a dependency
+ * tree.
+ *
+ * @author Phil Messenger
+ */
+public class GraphvizGraphRenderer implements DependencyGraphRenderer
+{
+    public void render(IvyDependencyGraph graph, OutputStream output) throws IOException
+    {
+        OutputStreamWriter writer = new OutputStreamWriter(output);
+
+        writer.write("digraph " + graph.getConf() + " {\n");
+
+		Set<String> edges = new HashSet<String>();
+
+		buildDotDependencyTree(graph.getRoot(), edges);
+
+		for(String edge : edges)
+		{
+			writer.write(edge + "\n");
+		}
+
+		writer.write("}\n" );
+    }
+
+    /**
+     * @todo - need to check name escaping?
+     * 
+     * @param root
+     * @param edges
+     */
+    private void buildDotDependencyTree(IvyDependency root, Set<String> edges)
+	{
+		for(IvyDependency dep : root.getDependencies())
+		{
+			String edge = "\"" + root.getName() + "\" -> \"" + dep.getName().replace('-', '_') + "\";";
+			edges.add(edge);
+		}
+
+		for(IvyDependency dep : root.getDependencies())
+		{
+			buildDotDependencyTree(dep, edges);
+		}
+	}
+}
Index: src/main/groovy/org/gradle/api/tasks/diagnostics/DependencyGraphRenderer.java
===================================================================
--- src/main/groovy/org/gradle/api/tasks/diagnostics/DependencyGraphRenderer.java	(revision 0)
+++ src/main/groovy/org/gradle/api/tasks/diagnostics/DependencyGraphRenderer.java	(revision 0)
@@ -0,0 +1,15 @@
+package org.gradle.api.tasks.diagnostics;
+
+import org.gradle.api.dependencies.report.IvyDependencyGraph;
+
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * Specifies the contract for Dependency graph renderer
+ *
+ * @author Phil Messenger
+ */
+public interface DependencyGraphRenderer {
+    void render(IvyDependencyGraph graph, OutputStream output) throws IOException;
+}
Index: src/main/groovy/org/gradle/api/tasks/diagnostics/ShowDependenciesTask.java
===================================================================
--- src/main/groovy/org/gradle/api/tasks/diagnostics/ShowDependenciesTask.java	(revision 0)
+++ src/main/groovy/org/gradle/api/tasks/diagnostics/ShowDependenciesTask.java	(revision 0)
@@ -0,0 +1,106 @@
+package org.gradle.api.tasks.diagnostics;
+
+import org.gradle.api.internal.DefaultTask;
+import org.gradle.api.internal.dependencies.BaseDependencyManager;
+import org.gradle.api.internal.dependencies.DefaultDependencyResolver;
+import org.gradle.api.Project;
+import org.gradle.api.TaskAction;
+import org.gradle.api.Task;
+import org.gradle.api.GradleException;
+import org.gradle.api.dependencies.report.IvyDependencyGraphBuilder;
+import org.gradle.api.dependencies.report.IvyDependencyGraph;
+
+import java.util.List;
+import java.io.File;
+import java.io.OutputStream;
+import java.io.FileOutputStream;
+
+/**
+ * Task to show a dependency tree for a project. Can be configured to output to a file,
+ * and to optionally output a graphviz compatible "dot" graph.
+ *
+ * @author Phil Messenger
+ */
+public class ShowDependenciesTask extends DefaultTask
+{
+
+    DependencyGraphRenderer renderer = new AsciiGraphRenderer();
+
+    File outputFile;
+
+    String conf = "runtime";
+
+    /**
+     * Set the configuration to build a dependency report for
+     *
+     * @param conf
+     */
+    public void setConf(String conf)
+    {
+        this.conf = conf;
+    }
+
+    /**
+     * Set the outputfile to write the dependency report to. If unset,
+     * standard out will be used
+     *
+     * @param outputFile
+     */
+    public void setOutputFile(File outputFile)
+    {
+        this.outputFile = outputFile;
+    }
+
+    /**
+     * Set the renderer to use to build a report. If unset, AsciiGraphRenderer will be used.
+     * 
+     * @param renderer
+     */
+    public void setRenderer(DependencyGraphRenderer renderer)
+    {
+        this.renderer = renderer;
+    }
+
+    public ShowDependenciesTask(Project project, String name) {
+        super(project, name);
+        setDagNeutral(true);
+        doFirst(new TaskAction() {
+            public void execute(Task task) {
+                Project project = task.getProject();
+
+                IvyDependencyGraphBuilder graphBuilder = new IvyDependencyGraphBuilder();
+
+                BaseDependencyManager depManager = (BaseDependencyManager) project.getDependencies();
+
+                depManager.resolve(conf, false, true);
+
+                DefaultDependencyResolver resolver = (DefaultDependencyResolver) depManager.getDependencyResolver();
+
+                try {
+                    IvyDependencyGraph graph = graphBuilder.buildGraph(project, resolver.getLastResolveReport(), conf);
+
+                    OutputStream outputStream = System.out;
+
+                    if(outputFile != null)
+                    {
+                        outputStream = new FileOutputStream(outputFile);
+                    }
+                    try
+                    {
+                        renderer.render(graph, System.out);
+                    }
+                    finally
+                    {
+                        if(outputFile != null)
+                        {
+                            outputStream.close();
+                        }
+                    }
+                } catch (Exception e) {
+                    throw new GradleException(e);
+                }
+            }
+        });
+    }
+
+}
Index: src/main/groovy/org/gradle/api/dependencies/report/IvyDependencyGraphBuilder.java
===================================================================
--- src/main/groovy/org/gradle/api/dependencies/report/IvyDependencyGraphBuilder.java	(revision 0)
+++ src/main/groovy/org/gradle/api/dependencies/report/IvyDependencyGraphBuilder.java	(revision 0)
@@ -0,0 +1,70 @@
+package org.gradle.api.dependencies.report;
+
+import org.gradle.api.Project;
+import org.apache.ivy.Ivy;
+import org.apache.ivy.core.cache.ResolutionCacheManager;
+import org.apache.ivy.core.resolve.ResolveOptions;
+import org.apache.ivy.core.resolve.IvyNode;
+import org.apache.ivy.core.resolve.IvyNodeCallers;
+import org.apache.ivy.core.module.id.ModuleId;
+import org.apache.ivy.core.report.ResolveReport;
+import org.dom4j.Document;
+import org.dom4j.Node;
+import org.dom4j.io.SAXReader;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.io.File;
+
+/**
+ * Builds a collection of IvyDependencyGraphs for a given project.
+ *
+ * @author Phil Messenger
+ */
+public class IvyDependencyGraphBuilder
+{
+
+    private IvyDependency processNode(IvyNode node, IvyDependencyGraph graph, String conf)
+    {
+        String name = node.getResolvedId().getName();
+        String group = node.getResolvedId().getOrganisation();
+        String revision = node.getResolvedId().getRevision();
+
+        IvyDependency ivyDependency = graph.findOrCreateDependeny(name, group, revision);
+
+        Collection<IvyNode> dependencies = node.getDependencies(conf, new String[] { conf });
+
+        for(IvyNode dependency : dependencies)
+        {
+            IvyDependency retDep = processNode(dependency, graph, conf);
+            
+            ivyDependency.addDependency(retDep);
+        }
+
+        return ivyDependency;
+    }
+
+    /**
+     * This method builds a collection of Graphs for each Ivy dependency (xml) report.
+     * @return
+     * @throws Exception
+     */
+    public IvyDependencyGraph buildGraph(Project project, ResolveReport report, String conf) throws Exception
+    {
+		IvyDependencyGraph graph = new IvyDependencyGraph();
+
+        List<IvyNode> dependencies = report.getDependencies();
+
+        IvyDependency root = graph.findOrCreateDependeny(project.property("group").toString(), project.getName(), project.property("version").toString());
+
+        graph.setRoot(root);
+
+        for(IvyNode dependency : dependencies)
+        {
+            root.addDependency(processNode(dependency, graph, conf));
+        }
+
+        return graph;
+    }
+}
Index: src/main/groovy/org/gradle/api/dependencies/report/IvyDependency.java
===================================================================
--- src/main/groovy/org/gradle/api/dependencies/report/IvyDependency.java	(revision 0)
+++ src/main/groovy/org/gradle/api/dependencies/report/IvyDependency.java	(revision 0)
@@ -0,0 +1,101 @@
+package org.gradle.api.dependencies.report;
+
+import java.util.Set;
+import java.util.HashSet;
+
+/**
+ * Domain object that represents a node in a IvyDependencyGraph.
+ *
+ * @author Phil Messenger
+ */
+public class IvyDependency
+{
+    public Set<IvyDependency> getDependencies()
+	{
+		return dependencies;
+	}
+
+	public void setDependencies(Set<IvyDependency> dependencies)
+	{
+		this.dependencies = dependencies;
+	}
+
+	@Override
+	public int hashCode()
+	{
+		return (getOrganisation() + getName() + getRev()).hashCode();
+	}
+
+	private String organisation;
+	private String name;
+	private String rev;
+
+	private Set<IvyDependency> dependencies = new HashSet<IvyDependency>();
+
+	public IvyDependency(String name, String organisation, String revision)
+	{
+		this.setOrganisation(organisation);
+		this.setRev(revision);
+		this.setName(name);
+	}
+
+	public String toString()
+	{
+		return getOrganisation() + ":" + getName() + ":" + getRev();
+	}
+
+	public boolean equals(Object o)
+	{
+		if(o instanceof IvyDependency)
+		{
+			if(((IvyDependency) o).getOrganisation().equals(getOrganisation()))
+			{
+				if(((IvyDependency) o).getName().equals(getName()))
+				{
+					if(((IvyDependency) o).getRev().equals(getRev()))
+					{
+						return true;
+					}
+				}
+
+			}
+		}
+
+		return false;
+	}
+
+	public void addDependency(IvyDependency dependency)
+	{
+		dependencies.add(dependency);
+	}
+
+	public void setOrganisation(String organisation)
+	{
+		this.organisation = organisation;
+	}
+
+	public String getOrganisation()
+	{
+		return organisation;
+	}
+
+	public void setName(String name)
+	{
+		this.name = name;
+	}
+
+	public String getName()
+	{
+		return name;
+	}
+
+	public void setRev(String rev)
+	{
+		this.rev = rev;
+	}
+
+	public String getRev()
+	{
+		return rev;
+	}
+}
Index: src/main/groovy/org/gradle/api/dependencies/report/IvyDependencyGraph.java
===================================================================
--- src/main/groovy/org/gradle/api/dependencies/report/IvyDependencyGraph.java	(revision 0)
+++ src/main/groovy/org/gradle/api/dependencies/report/IvyDependencyGraph.java	(revision 0)
@@ -0,0 +1,72 @@
+package org.gradle.api.dependencies.report;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * A graph of Ivy dependencies found in a project.
+ *
+ * @author Phil Messenger
+ */
+public class IvyDependencyGraph
+{
+    Map<String, IvyDependency> dependencyCache = new HashMap<String, IvyDependency>();
+
+    IvyDependency root;
+    private String conf;
+
+    public void setRoot(IvyDependency root)
+    {
+        this.root = root;
+    }
+
+    public IvyDependency getRoot()
+    {
+        return root;
+    }
+
+    public void add(IvyDependency parent, IvyDependency toAdd)
+    {
+        parent.addDependency(toAdd);
+    }
+
+    /**
+     * Finds an existing dependency matching the name, org and revision. If a depdendency can't be found,
+     * a new dependency is created.
+     * 
+     * @param name
+     * @param organisation
+     * @param revision
+     * @return
+     */
+    public IvyDependency findOrCreateDependeny(String name, String organisation, String revision)
+    {
+        String id = buildId(name, organisation, revision);
+
+        IvyDependency dep = dependencyCache.get(id);
+
+        if(dep == null)
+        {
+            dep = new IvyDependency(name, organisation, revision);
+
+            dependencyCache.put(id, dep);
+        }
+
+        return dep;
+    }
+
+    private String buildId(String name, String organisation, String revision)
+    {
+        return organisation + ":" + name + ":" + revision;
+    }
+
+    public void setConf(String text)
+    {
+        this.conf = text;
+    }
+
+    public String getConf()
+    {
+        return this.conf;
+    }
+}
Index: src/main/groovy/org/gradle/api/internal/dependencies/DefaultDependencyResolver.java
===================================================================
--- src/main/groovy/org/gradle/api/internal/dependencies/DefaultDependencyResolver.java	(revision 1145)
+++ src/main/groovy/org/gradle/api/internal/dependencies/DefaultDependencyResolver.java	(working copy)
@@ -36,10 +36,17 @@
 public class DefaultDependencyResolver implements IDependencyResolver {
     private static Logger logger = LoggerFactory.getLogger(DefaultDependencyResolver.class);
 
+    private ResolveReport lastResolveReport;
+
     Map<String, List<File>> resolveCache = new HashMap<String, List<File>>();
 
     Report2Classpath report2Classpath;
 
+    public ResolveReport getLastResolveReport()
+    {
+        return lastResolveReport;
+    }
+
     public DefaultDependencyResolver(Report2Classpath report2Classpath) {
         this.report2Classpath = report2Classpath;
     }
@@ -57,6 +64,7 @@
         ResolveReport resolveReport = null;
         try {
             resolveReport = ivy.resolve(moduleDescriptor, resolveOptions);
+            lastResolveReport = resolveReport;
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
