You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by el...@apache.org on 2020/08/17 14:18:13 UTC

[maven-dependency-plugin] branch master updated: [MDEP-644] Add tgf, dot, graphml support for verboseGraphSerializer (#95)

This is an automated email from the ASF dual-hosted git repository.

elharo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-dependency-plugin.git


The following commit(s) were added to refs/heads/master by this push:
     new a66ffc7  [MDEP-644] Add tgf, dot, graphml support for verboseGraphSerializer (#95)
a66ffc7 is described below

commit a66ffc79132fe89b4d3ceb71700944ca819a4b27
Author: ian-lavallee <34...@users.noreply.github.com>
AuthorDate: Mon Aug 17 10:18:05 2020 -0400

    [MDEP-644] Add tgf, dot, graphml support for verboseGraphSerializer (#95)
    
    Add tgf, dot, graphml support for verboseGraphSerializer
---
 ...er.java => AbstractVerboseGraphSerializer.java} | 151 +------
 .../maven/plugins/dependency/tree/TreeMojo.java    |  21 +-
 .../tree/VerboseDependencyGraphBuilder.java        |  33 +-
 .../dependency/tree/VerboseGraphDotSerializer.java | 114 ++++++
 .../tree/VerboseGraphGraphmlSerializer.java        | 174 ++++++++
 .../tree/VerboseGraphTextSerializer.java           | 160 ++++++++
 .../dependency/tree/VerboseGraphTgfSerializer.java | 148 +++++++
 .../tree/VerboseGraphSerializerTest.java           | 445 ++++++++++++++++++++-
 .../unit/verbose-serializer-test/BasicCycle.txt    |   3 -
 .../unit/verbose-serializer-test/BasicTree.txt     |   3 -
 .../LargeGraphWithCycles.txt                       |  10 -
 .../unit/verbose-serializer-test/LargeTree.txt     |  11 -
 .../verbose-serializer-test/OptionalDependency.txt |   3 -
 .../unit/verbose-serializer-test/ScopeConflict.txt |   4 -
 .../verbose-serializer-test/VersionConflict.txt    |   4 -
 15 files changed, 1070 insertions(+), 214 deletions(-)

diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/VerboseGraphSerializer.java b/src/main/java/org/apache/maven/plugins/dependency/tree/AbstractVerboseGraphSerializer.java
similarity index 53%
rename from src/main/java/org/apache/maven/plugins/dependency/tree/VerboseGraphSerializer.java
rename to src/main/java/org/apache/maven/plugins/dependency/tree/AbstractVerboseGraphSerializer.java
index e786187..82ed864 100644
--- a/src/main/java/org/apache/maven/plugins/dependency/tree/VerboseGraphSerializer.java
+++ b/src/main/java/org/apache/maven/plugins/dependency/tree/AbstractVerboseGraphSerializer.java
@@ -33,45 +33,17 @@ import java.util.Queue;
 import java.util.Set;
 
 /**
- * Parses dependency graph and outputs in text format for end user to review.
+ * Base class for verbose Serializers
  */
-final class VerboseGraphSerializer
+abstract class AbstractVerboseGraphSerializer
 {
-    private static final String LINE_START_LAST_CHILD = "\\- ", LINE_START_CHILD = "+- ";
-    private static final String PRE_MANAGED_SCOPE = "preManagedScope", PRE_MANAGED_VERSION = "preManagedVersion",
+    protected static final String LINE_START_LAST_CHILD = "\\- ", LINE_START_CHILD = "+- ";
+    protected static final String PRE_MANAGED_SCOPE = "preManagedScope", PRE_MANAGED_VERSION = "preManagedVersion",
             MANAGED_SCOPE = "managedScope";
 
-    public String serialize( DependencyNode root )
-    {
-        Set<String> coordinateStrings = new HashSet<>();
-        Map<String, String> coordinateVersionMap = new HashMap<>();
-        StringBuilder builder = new StringBuilder();
-
-        // Use BFS to mirror how Maven resolves dependencies and use DFS to print the tree easily
-        Map<DependencyNode, String> nodeErrors = getNodeConflictMessagesBfs( root, coordinateStrings,
-                coordinateVersionMap );
-
-        // deal with root first
-        Artifact rootArtifact = root.getArtifact();
-        builder.append( rootArtifact.getGroupId() ).append( ":" ).append( rootArtifact.getArtifactId() ).append( ":" )
-                .append( rootArtifact.getExtension() ).append( ":" ).append( rootArtifact.getVersion() ).append(
-                        System.lineSeparator() );
+    public abstract String serialize( DependencyNode root );
 
-        for ( int i = 0; i < root.getChildren().size(); i++ )
-        {
-            if ( i == root.getChildren().size() - 1 )
-            {
-                dfsPrint( root.getChildren().get( i ), LINE_START_LAST_CHILD, false, builder, nodeErrors );
-            }
-            else
-            {
-                dfsPrint( root.getChildren().get( i ), LINE_START_CHILD, false, builder, nodeErrors );
-            }
-        }
-        return builder.toString();
-    }
-
-    private static String getDependencyCoordinate( DependencyNode node )
+    protected static String getDependencyCoordinate( DependencyNode node )
     {
         Artifact artifact = node.getArtifact();
 
@@ -140,7 +112,7 @@ final class VerboseGraphSerializer
         return null;
     }
 
-    private Map<DependencyNode, String> getNodeConflictMessagesBfs( DependencyNode root, Set<String> coordinateStrings
+    protected Map<DependencyNode, String> getNodeConflictMessagesBfs( DependencyNode root, Set<String> coordinateStrings
             , Map<String, String> coordinateVersionMap )
     {
         Map<DependencyNode, String> nodeErrors = new HashMap<>();
@@ -166,8 +138,11 @@ final class VerboseGraphSerializer
             }
             else if ( scopeConflict( node, coordinateStrings ) != null )
             {
-                nodeErrors.put( node, "omitted for conflict with "
-                        + scopeConflict( node, coordinateStrings ) );
+                nodeErrors.put( node, "omitted for conflict with " + scopeConflict( node, coordinateStrings ) );
+            }
+            else if ( versionConflict( node, coordinateVersionMap ) != null )
+            {
+                nodeErrors.put( node, "omitted for conflict with " + versionConflict( node, coordinateVersionMap ) );
             }
             else if ( versionConflict( node, coordinateVersionMap ) != null )
             {
@@ -219,106 +194,4 @@ final class VerboseGraphSerializer
         }
         return nodeErrors;
     }
-
-    private void dfsPrint( DependencyNode node, String start, boolean transitive, StringBuilder builder,
-                           Map<DependencyNode, String> nodeErrors )
-    {
-        builder.append( start );
-        if ( node.getArtifact() == null )
-        {
-            // Should never hit this condition with a proper graph sent in
-            builder.append( "Null Artifact Node" ).append( System.lineSeparator() );
-            callDfsPrint( node, start, builder, nodeErrors );
-        }
-
-        String coordString = "";
-        boolean messageAdded = false;
-
-        if ( transitive && node.getArtifact().getProperties().containsKey( PRE_MANAGED_VERSION ) )
-        {
-            coordString = coordString.concat( " - version managed from "
-                    + node.getArtifact().getProperties().get( PRE_MANAGED_VERSION ) );
-            messageAdded = true;
-        }
-
-        if ( transitive && node.getArtifact().getProperties().containsKey( PRE_MANAGED_SCOPE ) )
-        {
-            if ( messageAdded )
-            {
-                coordString = coordString.concat( "; " );
-            }
-            else
-            {
-                coordString = coordString.concat( " - " );
-                messageAdded = true;
-            }
-            coordString = coordString.concat( "scope managed from "
-                    + node.getArtifact().getProperties().get( PRE_MANAGED_SCOPE ) );
-        }
-
-        coordString = getDependencyCoordinate( node ) + coordString;
-
-        if ( !( node.getDependency().getScope().equals( "test" ) && transitive ) )
-        {
-            if ( node.getArtifact().getProperties().containsKey( "Cycle" ) )
-            {
-                if ( messageAdded )
-                {
-                    coordString = coordString.concat( "; " );
-                }
-                else
-                {
-                    coordString = coordString.concat( " - " );
-                }
-                coordString = coordString.concat( "omitted for cycle" );
-                builder.append( "(" ).append( coordString ).append( ")" ).append( System.lineSeparator() );
-            }
-            else if ( nodeErrors.get( node ) != null )
-            {
-                builder.append( "(" );
-                if ( messageAdded )
-                {
-                    builder.append( coordString ).append( "; " ).append( nodeErrors.get( node ) );
-                }
-                else
-                {
-                    builder.append( coordString ).append( " - " ).append( nodeErrors.get( node ) );
-                }
-                builder.append( ")" );
-                builder.append( System.lineSeparator() );
-            }
-            else
-            {
-                builder.append( coordString ).append( System.lineSeparator() );
-                callDfsPrint( node, start, builder, nodeErrors );
-            }
-        }
-    }
-
-    private void callDfsPrint( DependencyNode node, String start, StringBuilder builder,
-                               Map<DependencyNode, String> nodeErrors )
-    {
-        for ( int i = 0; i < node.getChildren().size(); i++ )
-        {
-            if ( start.endsWith( LINE_START_CHILD ) )
-            {
-                start = start.replace( LINE_START_CHILD, "|  " );
-            }
-            else if ( start.endsWith( LINE_START_LAST_CHILD ) )
-            {
-                start = start.replace( LINE_START_LAST_CHILD, "   " );
-            }
-
-            if ( i == node.getChildren().size() - 1 )
-            {
-                dfsPrint( node.getChildren().get( i ), start.concat( LINE_START_LAST_CHILD ), true, builder,
-                        nodeErrors );
-            }
-            else
-            {
-                dfsPrint( node.getChildren().get( i ), start.concat( LINE_START_CHILD ), true, builder,
-                        nodeErrors );
-            }
-        }
-    }
 }
diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/TreeMojo.java b/src/main/java/org/apache/maven/plugins/dependency/tree/TreeMojo.java
index 3b04067..1eb35b0 100644
--- a/src/main/java/org/apache/maven/plugins/dependency/tree/TreeMojo.java
+++ b/src/main/java/org/apache/maven/plugins/dependency/tree/TreeMojo.java
@@ -268,7 +268,7 @@ public class TreeMojo
                 // verboseGraphBuilder needs MavenProject project, RepositorySystemSession session,
                 // ProjectDependenciesResolver resolver
                 VerboseDependencyGraphBuilder builder = new VerboseDependencyGraphBuilder();
-                VerboseGraphSerializer serializer = new VerboseGraphSerializer();
+                AbstractVerboseGraphSerializer serializer = getSerializer();
 
                 org.eclipse.aether.graph.DependencyNode verboseRootNode = builder.buildVerboseGraph(
                         project, resolver, repoSession );
@@ -350,6 +350,25 @@ public class TreeMojo
 
     // private methods --------------------------------------------------------
 
+    private AbstractVerboseGraphSerializer getSerializer( )
+    {
+        if ( "graphml".equals( outputType ) )
+        {
+            return new VerboseGraphGraphmlSerializer();
+        }
+        else if ( "tgf".equals( outputType ) )
+        {
+            return new VerboseGraphTgfSerializer();
+        }
+        else if ( "dot".equals( outputType ) )
+        {
+            return new VerboseGraphDotSerializer();
+        }
+        else
+        {
+            return new VerboseGraphTextSerializer();
+        }
+    }
 
     private DependencyNode convertToCustomDependencyNode( org.eclipse.aether.graph.DependencyNode node )
     {
diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/VerboseDependencyGraphBuilder.java b/src/main/java/org/apache/maven/plugins/dependency/tree/VerboseDependencyGraphBuilder.java
index 9a5b50d..192c941 100644
--- a/src/main/java/org/apache/maven/plugins/dependency/tree/VerboseDependencyGraphBuilder.java
+++ b/src/main/java/org/apache/maven/plugins/dependency/tree/VerboseDependencyGraphBuilder.java
@@ -57,7 +57,7 @@ class VerboseDependencyGraphBuilder
             MANAGED_SCOPE = "managedScope";
 
     public DependencyNode buildVerboseGraph( MavenProject project, ProjectDependenciesResolver resolver,
-                                                         RepositorySystemSession repositorySystemSession )
+                                             RepositorySystemSession repositorySystemSession )
             throws DependencyResolutionException
     {
         DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
@@ -66,13 +66,12 @@ class VerboseDependencyGraphBuilder
         DependencySelector dependencySelector = new AndDependencySelector(
                 // ScopeDependencySelector takes exclusions. 'Provided' scope is not here to avoid
                 // false positive in LinkageChecker.
-                new ScopeDependencySelector(),
-                new ExclusionDependencySelector() );
+                new ScopeDependencySelector(), new ExclusionDependencySelector() );
 
         session.setDependencySelector( dependencySelector );
-        session.setDependencyGraphTransformer( new ChainedDependencyGraphTransformer(
-                new CycleBreakerGraphTransformer(), // Avoids StackOverflowError
-                new JavaDependencyContextRefiner() ) );
+        session.setDependencyGraphTransformer(
+                new ChainedDependencyGraphTransformer( new CycleBreakerGraphTransformer(), // Avoids StackOverflowError
+                        new JavaDependencyContextRefiner() ) );
         session.setDependencyManager( null );
 
         DependencyResolutionRequest request = new DefaultDependencyResolutionRequest();
@@ -152,26 +151,26 @@ class VerboseDependencyGraphBuilder
 
     private static String getDependencyManagementCoordinate( org.apache.maven.model.Dependency dependency )
     {
-        StringBuilder string = new StringBuilder();
-        string.append( dependency.getGroupId() ).append( ":" ).append( dependency.getArtifactId() )
-                .append( ":" ).append( dependency.getType() );
+        StringBuilder builder = new StringBuilder();
+        builder.append( dependency.getGroupId() ).append( ":" ).append( dependency.getArtifactId() ).append( ":" )
+                .append( dependency.getType() );
         if ( dependency.getClassifier() != null && !dependency.getClassifier().equals( "" ) )
         {
-            string.append( ":" ).append( dependency.getClassifier() );
+            builder.append( ":" ).append( dependency.getClassifier() );
         }
-        return string.toString();
+        return builder.toString();
     }
 
     private static String getDependencyManagementCoordinate( Artifact artifact )
     {
-        StringBuilder string = new StringBuilder();
-        string.append( artifact.getGroupId() ).append( ":" ).append( artifact.getArtifactId() ).append( ":" )
-                .append( artifact.getExtension() );
+        StringBuilder builder = new StringBuilder();
+        builder.append( artifact.getGroupId() ).append( ":" ).append( artifact.getArtifactId() ).append( ":" ).append(
+                artifact.getExtension() );
         if ( artifact.getClassifier() != null && !artifact.getClassifier().equals( "" ) )
         {
-            string.append( ":" ).append( artifact.getClassifier() );
+            builder.append( ":" ).append( artifact.getClassifier() );
         }
-        return string.toString();
+        return builder.toString();
     }
 
     private Dependency getProjectDependency( MavenProject project )
@@ -199,7 +198,7 @@ class VerboseDependencyGraphBuilder
         return newRoot;
     }
 
-    private void pruneTransitiveTestDependenciesDfs( DependencyNode node , Set<DependencyNode> visitedNodes )
+    private void pruneTransitiveTestDependenciesDfs( DependencyNode node, Set<DependencyNode> visitedNodes )
     {
         if ( !visitedNodes.contains( node ) )
         {
diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/VerboseGraphDotSerializer.java b/src/main/java/org/apache/maven/plugins/dependency/tree/VerboseGraphDotSerializer.java
new file mode 100644
index 0000000..fce1b4d
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/dependency/tree/VerboseGraphDotSerializer.java
@@ -0,0 +1,114 @@
+package org.apache.maven.plugins.dependency.tree;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.graph.DependencyNode;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+
+/**
+ * Parses dependency graph and outputs in DOT format for end user to review.
+ */
+class VerboseGraphDotSerializer extends AbstractVerboseGraphSerializer
+{
+    @Override
+    public String serialize( DependencyNode root )
+    {
+        Set<String> coordinateStrings = new HashSet<>();
+        Map<String, String> coordinateVersionMap = new HashMap<>();
+        Map<DependencyNode, String> nodeErrors = getNodeConflictMessagesBfs( root, coordinateStrings,
+                coordinateVersionMap );
+        Set<DependencyNode> visitedNodes = new HashSet<>();
+        Queue<DependencyNode> queue = new LinkedList<>();
+        queue.add( root );
+        Artifact rootArtifact = root.getArtifact();
+
+        StringBuilder result = new StringBuilder( "digraph" );
+        result.append( " \"" ).append( rootArtifact.getGroupId() ).append( ":" ).append(
+                rootArtifact.getArtifactId() ).append( ":" ).append( rootArtifact.getExtension() ).append( ":" ).append(
+                rootArtifact.getVersion() ).append( "\" {" ).append( "\n" );
+
+        while ( !queue.isEmpty() )
+        {
+            DependencyNode node = queue.poll();
+            for ( DependencyNode child : node.getChildren() )
+            {
+                result.append( " \"" );
+                String coordString = "";
+                boolean messageAdded = false;
+
+                if ( child.getArtifact().getProperties().containsKey( PRE_MANAGED_VERSION ) )
+                {
+                    coordString +=
+                            " - version managed from " + child.getArtifact().getProperties().get(
+                                    PRE_MANAGED_VERSION );
+                    messageAdded = true;
+                }
+                if ( child.getArtifact().getProperties().containsKey( PRE_MANAGED_SCOPE ) )
+                {
+                    if ( messageAdded )
+                    {
+                        coordString += "; ";
+                    }
+                    else
+                    {
+                        coordString += " - ";
+                        messageAdded = true;
+                    }
+                    coordString +=
+                            "scope managed from " + child.getArtifact().getProperties().get( PRE_MANAGED_SCOPE );
+                }
+                coordString = getDependencyCoordinate( child ) + coordString;
+                result.append( getDependencyCoordinate( node ) ).append( "\"" ).append( " -> \"" ).append(
+                        coordString );
+                if ( child.getArtifact().getProperties().containsKey( "Cycle" ) )
+                {
+                    if ( !messageAdded )
+                    {
+                        result.append( " -" );
+                    }
+                    result.append( " omitted due to cycle" );
+                }
+                else if ( nodeErrors.get( child ) != null )
+                {
+                    if ( !messageAdded )
+                    {
+                        result.append( " - " );
+                    }
+                    result.append( nodeErrors.get( child ) );
+                }
+                else if ( !visitedNodes.contains( child ) )
+                {
+                    visitedNodes.add( child );
+                    queue.add( child );
+                }
+                result.append( "\" ;" ).append( "\n" );
+            }
+        }
+        result.append( "}" );
+        return result.toString();
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/VerboseGraphGraphmlSerializer.java b/src/main/java/org/apache/maven/plugins/dependency/tree/VerboseGraphGraphmlSerializer.java
new file mode 100644
index 0000000..6f6e7e9
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/dependency/tree/VerboseGraphGraphmlSerializer.java
@@ -0,0 +1,174 @@
+package org.apache.maven.plugins.dependency.tree;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.graph.DependencyNode;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+
+/**
+ * Parses dependency graph and outputs in GraphML format for end user to review.
+ */
+public class VerboseGraphGraphmlSerializer extends AbstractVerboseGraphSerializer
+{
+    @Override
+    public String serialize( DependencyNode root )
+    {
+        Set<String> coordinateStrings = new HashSet<>();
+        Map<String, String> coordinateVersionMap = new HashMap<>();
+        Map<DependencyNode, String> nodeErrors = getNodeConflictMessagesBfs( root, coordinateStrings,
+                coordinateVersionMap );
+
+        Set<DependencyNode> visitedNodes = new HashSet<>();
+        Queue<DependencyNode> queue = new LinkedList<>();
+        queue.add( root );
+        StringBuilder result = new StringBuilder( "<?xml version=\"1.0\" encoding=\"UTF-8\"?> "
+                + "<graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\" "
+                + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
+                + "xmlns:y=\"http://www.yworks.com/xml/graphml\" "
+                + "xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns "
+                + "http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\">"
+                + "\n"
+                + "  <key for=\"node\" id=\"d0\" yfiles.type=\"nodegraphics\"/>"
+                + "\n"
+                + "  <key for=\"edge\" id=\"d1\" yfiles.type=\"edgegraphics\"/>"
+                + "\n"
+                + "<graph id=\"dependencies\" edgedefault=\"directed\">" + "\n" );
+
+        StringBuilder nodes = new StringBuilder();
+        StringBuilder edges = new StringBuilder();
+        while ( !queue.isEmpty() )
+        {
+            DependencyNode node = queue.poll();
+            nodes.append( getGraphmlNodeLine( node, nodeErrors ) );
+            if ( nodeErrors.get( node ) == null && !node.getArtifact().getProperties().containsKey( "Cycle" ) )
+            {
+                for ( DependencyNode child : node.getChildren() )
+                {
+                    if ( !visitedNodes.contains( child ) )
+                    {
+                        visitedNodes.add( child );
+                        queue.add( child );
+                    }
+                    edges.append( getGraphmlEdgeLine( node, child, nodeErrors ) );
+                }
+            }
+        }
+        result.append( nodes ).append( edges );
+        result.append( "</graph></graphml>" );
+        return result.toString();
+    }
+
+    private String getGraphmlEdgeLine( DependencyNode parent, DependencyNode child,
+                                       Map<DependencyNode, String> nodeErrors )
+    {
+        StringBuilder builder = new StringBuilder();
+        builder.append( "<edge source=\"" ).append( parent.hashCode() ).append( "\" target=\"" ).append(
+                child.hashCode() ).append( "\"><data key=\"d1\"><y:PolyLineEdge><y:EdgeLabel>" );
+
+
+        boolean messageAdded = false;
+
+        if ( child.getArtifact().getProperties().containsKey( PRE_MANAGED_SCOPE ) )
+        {
+            messageAdded = true;
+            builder.append( child.getArtifact().getProperties().get( MANAGED_SCOPE ) );
+            builder.append( ", scope managed from " ).append(
+                    child.getArtifact().getProperties().get( PRE_MANAGED_SCOPE ) );
+        }
+        else
+        {
+            builder.append( child.getDependency().getScope() );
+        }
+        if ( child.getArtifact().getProperties().containsKey( "Cycle" ) )
+        {
+            if ( messageAdded )
+            {
+                builder.append( "," );
+            }
+            builder.append( " omitted due to cycle" );
+        }
+        else if ( nodeErrors.get( child ) != null )
+        {
+            if ( messageAdded )
+            {
+                builder.append( "," );
+            }
+            builder.append( " " ).append( nodeErrors.get( child ) );
+        }
+        builder.append( "</y:EdgeLabel></y:PolyLineEdge></data></edge>" ).append( "\n" );
+        return builder.toString();
+    }
+
+    private String getGraphmlNodeLine( DependencyNode node, Map<DependencyNode, String> nodeErrors )
+    {
+        StringBuilder builder = new StringBuilder();
+        builder.append( "<node id=\"" ).append( node.hashCode() ).append(
+                "\"><data key=\"d0\"><y:ShapeNode>" + "<y:NodeLabel>" );
+
+        String coordString = "";
+        boolean messageAdded = false;
+
+        if ( node.getArtifact().getProperties().containsKey( PRE_MANAGED_VERSION ) )
+        {
+            coordString +=
+                    " - version managed from " + node.getArtifact().getProperties().get( PRE_MANAGED_VERSION );
+            messageAdded = true;
+        }
+        if ( node.getArtifact().getProperties().containsKey( PRE_MANAGED_SCOPE ) )
+        {
+            if ( messageAdded )
+            {
+                coordString += "; ";
+            }
+            else
+            {
+                coordString += " - ";
+                messageAdded = true;
+            }
+            coordString +=
+                    "scope managed from " + node.getArtifact().getProperties().get( PRE_MANAGED_SCOPE );
+        }
+        builder.append( getDependencyCoordinate( node ) ).append( coordString );
+        if ( node.getArtifact().getProperties().containsKey( "Cycle" ) )
+        {
+            if ( !messageAdded )
+            {
+                builder.append( " - " );
+            }
+            builder.append( "omitted due to cycle" );
+        }
+        else if ( nodeErrors.get( node ) != null )
+        {
+            if ( !messageAdded )
+            {
+                builder.append( " - " );
+            }
+            builder.append( nodeErrors.get( node ) );
+        }
+        builder.append( "</y:NodeLabel></y:ShapeNode></data></node>" ).append( "\n" );
+        return builder.toString();
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/VerboseGraphTextSerializer.java b/src/main/java/org/apache/maven/plugins/dependency/tree/VerboseGraphTextSerializer.java
new file mode 100644
index 0000000..70e41ee
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/dependency/tree/VerboseGraphTextSerializer.java
@@ -0,0 +1,160 @@
+package org.apache.maven.plugins.dependency.tree;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.graph.DependencyNode;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Parses dependency graph and outputs in text format for end user to review.
+ */
+class VerboseGraphTextSerializer extends AbstractVerboseGraphSerializer
+{
+    @Override
+    public String serialize( DependencyNode root )
+    {
+        Set<String> coordinateStrings = new HashSet<>();
+        Map<String, String> coordinateVersionMap = new HashMap<>();
+        Map<DependencyNode, String> nodeErrors = getNodeConflictMessagesBfs( root, coordinateStrings,
+                coordinateVersionMap );
+
+        StringBuilder builder = new StringBuilder();
+
+        // deal with root first
+        Artifact rootArtifact = root.getArtifact();
+        builder.append( rootArtifact.getGroupId() ).append( ":" ).append( rootArtifact.getArtifactId() ).append(
+                ":" ).append( rootArtifact.getExtension() ).append( ":" ).append( rootArtifact.getVersion() ).append(
+                "\n" );
+
+        for ( int i = 0; i < root.getChildren().size(); i++ )
+        {
+            if ( i == root.getChildren().size() - 1 )
+            {
+                dfsPrint( root.getChildren().get( i ), LINE_START_LAST_CHILD, builder, nodeErrors );
+            }
+            else
+            {
+                dfsPrint( root.getChildren().get( i ), LINE_START_CHILD, builder, nodeErrors );
+            }
+        }
+        return builder.toString();
+    }
+
+    private void dfsPrint( DependencyNode node, String start, StringBuilder builder,
+                           Map<DependencyNode, String> nodeErrors )
+    {
+        builder.append( start );
+        if ( node.getArtifact() == null )
+        {
+            // Should never hit this condition with a proper graph sent in
+            builder.append( "Null Artifact Node" ).append( "\n" );
+            callDfsPrint( node, start, builder, nodeErrors );
+        }
+
+        String coordString = "";
+        boolean messageAdded = false;
+
+        if ( node.getArtifact().getProperties().containsKey( PRE_MANAGED_VERSION ) )
+        {
+            coordString += " - version managed from "
+                    + node.getArtifact().getProperties().get( PRE_MANAGED_VERSION );
+            messageAdded = true;
+        }
+        if ( node.getArtifact().getProperties().containsKey( PRE_MANAGED_SCOPE ) )
+        {
+            if ( messageAdded )
+            {
+                coordString += "; ";
+            }
+            else
+            {
+                coordString += " - ";
+                messageAdded = true;
+            }
+            coordString +=
+                    "scope managed from " + node.getArtifact().getProperties().get( PRE_MANAGED_SCOPE );
+        }
+
+        coordString = getDependencyCoordinate( node ) + coordString;
+
+        if ( node.getArtifact().getProperties().containsKey( "Cycle" ) )
+        {
+            if ( messageAdded )
+            {
+                coordString += "; ";
+            }
+            else
+            {
+                coordString += " - ";
+            }
+            coordString += "omitted for cycle";
+            builder.append( "(" ).append( coordString ).append( ")" ).append( "\n" );
+        }
+        else if ( nodeErrors.get( node ) != null )
+        {
+            builder.append( "(" );
+            if ( messageAdded )
+            {
+                builder.append( coordString ).append( "; " ).append( nodeErrors.get( node ) );
+            }
+            else
+            {
+                builder.append( coordString ).append( " - " ).append( nodeErrors.get( node ) );
+            }
+            builder.append( ")" );
+            builder.append( "\n" );
+        }
+        else
+        {
+            builder.append( coordString ).append( "\n" );
+            callDfsPrint( node, start, builder, nodeErrors );
+        }
+    }
+
+    private void callDfsPrint( DependencyNode node, String start, StringBuilder builder,
+                               Map<DependencyNode, String> nodeErrors )
+    {
+        for ( int i = 0; i < node.getChildren().size(); i++ )
+        {
+            if ( start.endsWith( LINE_START_CHILD ) )
+            {
+                start = start.replace( LINE_START_CHILD, "|  " );
+            }
+            else if ( start.endsWith( LINE_START_LAST_CHILD ) )
+            {
+                start = start.replace( LINE_START_LAST_CHILD, "   " );
+            }
+
+            if ( i == node.getChildren().size() - 1 )
+            {
+                dfsPrint( node.getChildren().get( i ), start.concat( LINE_START_LAST_CHILD ), builder, nodeErrors );
+            }
+            else
+            {
+                dfsPrint( node.getChildren().get( i ), start.concat( LINE_START_CHILD ), builder, nodeErrors );
+            }
+        }
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/VerboseGraphTgfSerializer.java b/src/main/java/org/apache/maven/plugins/dependency/tree/VerboseGraphTgfSerializer.java
new file mode 100644
index 0000000..f44cfe6
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/dependency/tree/VerboseGraphTgfSerializer.java
@@ -0,0 +1,148 @@
+package org.apache.maven.plugins.dependency.tree;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.graph.DependencyNode;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Parses dependency graph and outputs in TGF format for end user to review.
+ */
+class VerboseGraphTgfSerializer extends AbstractVerboseGraphSerializer
+{
+
+    @Override
+    public String serialize( DependencyNode root )
+    {
+        Set<String> coordinateStrings = new HashSet<>();
+        Map<String, String> coordinateVersionMap = new HashMap<>();
+        Map<DependencyNode, String> nodeErrors = getNodeConflictMessagesBfs( root, coordinateStrings,
+                coordinateVersionMap );
+
+        StringBuilder nodes = new StringBuilder();
+        StringBuilder edges = new StringBuilder( "#" );
+        edges.append( "\n" );
+
+        // deal with root first
+        Artifact rootArtifact = root.getArtifact();
+        nodes.append( root.hashCode() ).append( " " ).append( rootArtifact.getGroupId() ).append( ":" ).append(
+                rootArtifact.getArtifactId() ).append( ":" ).append( rootArtifact.getExtension() ).append( ":" ).append(
+                rootArtifact.getVersion() ).append( "\n" );
+
+        for ( DependencyNode child : root.getChildren() )
+        {
+            edges.append( root.hashCode() ).append( " " ).append( child.hashCode() ).append( " " ).append(
+                    child.getDependency().getScope() ).append( "\n" );
+            serializeTgfDfs( child, nodeErrors, nodes, edges );
+        }
+
+        return nodes.append( edges ).toString();
+    }
+
+    private void serializeTgfDfs( DependencyNode node, Map<DependencyNode, String> nodeErrors, StringBuilder nodes,
+                                  StringBuilder edges )
+    {
+        nodes.append( node.hashCode() ).append( " " );
+        String coordString = "";
+        boolean messageAdded = false;
+
+        if ( node.getArtifact().getProperties().containsKey( PRE_MANAGED_VERSION ) )
+        {
+            coordString += " - version managed from " + node.getArtifact().getProperties().get( PRE_MANAGED_VERSION );
+            messageAdded = true;
+        }
+        if ( node.getArtifact().getProperties().containsKey( PRE_MANAGED_SCOPE ) )
+        {
+            if ( messageAdded )
+            {
+                coordString += "; ";
+            }
+            else
+            {
+                coordString += " - ";
+                messageAdded = true;
+            }
+            coordString +=
+                    "scope managed from " + node.getArtifact().getProperties().get( PRE_MANAGED_SCOPE );
+        }
+        coordString = getDependencyCoordinate( node ) + coordString;
+
+
+        if ( node.getArtifact().getProperties().containsKey( "Cycle" ) )
+        {
+            if ( messageAdded )
+            {
+                coordString += "; ";
+            }
+            else
+            {
+                coordString += " - ";
+            }
+            coordString += "omitted for cycle";
+            nodes.append( "(" ).append( coordString ).append( ")" ).append( "\n" );
+        }
+        else if ( nodeErrors.get( node ) != null )
+        {
+            nodes.append( "(" );
+            if ( messageAdded )
+            {
+                nodes.append( coordString ).append( "; " ).append( nodeErrors.get( node ) );
+            }
+            else
+            {
+                nodes.append( coordString ).append( " - " ).append( nodeErrors.get( node ) );
+            }
+            nodes.append( ")" ).append( "\n" );
+        }
+        else
+        {
+            nodes.append( coordString ).append( "\n" );
+            for ( DependencyNode child : node.getChildren() )
+            {
+                edges.append( node.hashCode() ).append( " " ).append( child.hashCode() ).append( " " );
+                if ( child.getArtifact().getProperties().get( MANAGED_SCOPE ) != null )
+                {
+                    edges.append( child.getArtifact().getProperties().get( MANAGED_SCOPE ) ).append( " managed from " )
+                            .append( child.getArtifact().getProperties().get( PRE_MANAGED_SCOPE ) );
+                }
+                else
+                {
+                    edges.append( child.getDependency().getScope() );
+                }
+
+                if ( child.getArtifact().getProperties().containsKey( "Cycle" ) )
+                {
+                    edges.append( " omitted for cycle" );
+                }
+                else if ( nodeErrors.get( child ) != null )
+                {
+                    edges.append( " " ).append( nodeErrors.get( child ) );
+                }
+                edges.append( "\n" );
+                serializeTgfDfs( child, nodeErrors, nodes, edges );
+            }
+        }
+    }
+}
diff --git a/src/test/java/org/apache/maven/plugins/dependency/tree/VerboseGraphSerializerTest.java b/src/test/java/org/apache/maven/plugins/dependency/tree/VerboseGraphSerializerTest.java
index d0abf3f..3af4dab 100644
--- a/src/test/java/org/apache/maven/plugins/dependency/tree/VerboseGraphSerializerTest.java
+++ b/src/test/java/org/apache/maven/plugins/dependency/tree/VerboseGraphSerializerTest.java
@@ -18,9 +18,8 @@ package org.apache.maven.plugins.dependency.tree;
  * under the License.
  */
 
-import org.apache.commons.io.FileUtils;
 import org.apache.maven.plugin.testing.AbstractMojoTestCase;
-import org.apache.maven.plugins.dependency.tree.VerboseGraphSerializer;
+import org.eclipse.aether.artifact.Artifact;
 import org.eclipse.aether.artifact.DefaultArtifact;
 import org.eclipse.aether.graph.DefaultDependencyNode;
 import org.eclipse.aether.graph.Dependency;
@@ -28,17 +27,23 @@ import org.eclipse.aether.graph.DependencyNode;
 import org.junit.Assert;
 import org.junit.Test;
 
-import java.io.File;
 import java.io.IOException;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 
 public class VerboseGraphSerializerTest extends AbstractMojoTestCase
 {
-    private final VerboseGraphSerializer serializer = new VerboseGraphSerializer();
+    private AbstractVerboseGraphSerializer serializer;
+
+    private static final String PRE_MANAGED_SCOPE = "preManagedScope", PRE_MANAGED_VERSION = "preManagedVersion",
+            MANAGED_SCOPE = "managedScope";
 
     @Test
     public void testBasicTree() throws IOException
     {
+        serializer = new VerboseGraphTextSerializer();
         DependencyNode root = new DefaultDependencyNode(
                 new Dependency( new DefaultArtifact( "com.google", "rootArtifact", "jar", "1.0.0" ), null)
         );
@@ -52,8 +57,8 @@ public class VerboseGraphSerializerTest extends AbstractMojoTestCase
         root.setChildren( Arrays.asList( left, right ) );
 
         String actual = serializer.serialize( root );
-        File file = new File(getBasedir(), "/target/test-classes/unit/verbose-serializer-test/BasicTree.txt");
-        String expected = FileUtils.readFileToString( file );
+        String expected = "com.google:rootArtifact:jar:1.0.0\n" + "+- org.apache:left:xml:0.1-SNAPSHOT:test\n"
+                + "\\- org.xyz:right:zip:1:provided\n";
 
         Assert.assertEquals(expected, actual);
     }
@@ -61,6 +66,7 @@ public class VerboseGraphSerializerTest extends AbstractMojoTestCase
     @Test
     public void testLargeTree() throws IOException
     {
+        serializer = new VerboseGraphTextSerializer();
         // Construct nodes for tree l1 = level 1 with the root being l0
         DependencyNode root = new DefaultDependencyNode(
                 new Dependency( new DefaultArtifact( "com.google", "rootArtifact", "jar", "1.0.0" ), null )
@@ -108,8 +114,12 @@ public class VerboseGraphSerializerTest extends AbstractMojoTestCase
         root.setChildren( Arrays.asList( l1left, l1right ) );
 
         String actual = serializer.serialize( root );
-        File file = new File(getBasedir(), "/target/test-classes/unit/verbose-serializer-test/LargeTree.txt");
-        String expected = FileUtils.readFileToString(file);
+        String expected = "com.google:rootArtifact:jar:1.0.0\n" + "+- org.apache:left:xml:0.1-SNAPSHOT:test\n"
+                + "|  +- org.maven:a4:jar:2.2.1:system\n" + "|  \\- com.google:a5:zip:0:import\n"
+                + "|     \\- com.xyz:a6:xml:1.2.1:provided\n" + "|        \\- com.example:a7:jar:2.2.2:provided\n"
+                + "|           +- com.comm:a7:jar:1:compile\n" + "|           |  \\- com.example:a8:xml:2.1:compile\n"
+                + "|           \\- (com.comm:a7:jar:1:compile - omitted for duplicate)\n"
+                + "\\- org.xyz:right:zip:1:provided\n" + "   \\- com.xyz:a9:xml:1.2:runtime\n";
 
         Assert.assertEquals(expected, actual);
     }
@@ -117,6 +127,7 @@ public class VerboseGraphSerializerTest extends AbstractMojoTestCase
     @Test
     public void testLargeGraphWithCycles() throws IOException
     {
+        serializer = new VerboseGraphTextSerializer();
         // Construct nodes for tree l1 = level 1 with the root being l0
         DependencyNode root = new DefaultDependencyNode(
                 new Dependency( new DefaultArtifact( "com.google", "rootArtifact", "jar", "1.0.0" ), null )
@@ -167,9 +178,12 @@ public class VerboseGraphSerializerTest extends AbstractMojoTestCase
         l5left.setChildren( Arrays.asList( l2left, l1right, l3 ) );
 
         String actual = serializer.serialize( root );
-        File file = new File(getBasedir(),
-                "/target/test-classes/unit/verbose-serializer-test/LargeGraphWithCycles.txt");
-        String expected = FileUtils.readFileToString(file);
+        String expected = "com.google:rootArtifact:jar:1.0.0\n" + "+- org.apache:left:xml:0.1-SNAPSHOT:test\n"
+                + "|  +- org.maven:a4:jar:2.2.1:system\n" + "|  \\- com.google:a5:zip:0:import\n"
+                + "|     \\- com.xyz:a6:xml:1.2.1:compile\n" + "|        \\- com.example:a7:jar:2.2.2:provided\n"
+                + "|           +- (com.comm:a7:jar:1:compile - omitted for introducing a cycle with org.maven:a4:"
+                + "jar:2.2.1:system)\n" + "|           \\- (com.comm:a7:jar:1:compile - omitted for duplicate)\n"
+                + "\\- org.xyz:right:zip:1:provided\n" + "   \\- com.xyz:a9:xml:1.2:runtime\n";
 
         Assert.assertEquals(expected, actual);
     }
@@ -177,6 +191,7 @@ public class VerboseGraphSerializerTest extends AbstractMojoTestCase
     @Test
     public void testTreeWithOptional() throws IOException
     {
+        serializer = new VerboseGraphTextSerializer();
         DependencyNode root = new DefaultDependencyNode(
                 new Dependency( new DefaultArtifact( "com.google", "rootArtifact", "jar", "1.0.0" ), "")
         );
@@ -190,9 +205,9 @@ public class VerboseGraphSerializerTest extends AbstractMojoTestCase
         root.setChildren( Arrays.asList( left, right ) );
 
         String actual = serializer.serialize( root );
-        File file = new File(getBasedir(),
-                "/target/test-classes/unit/verbose-serializer-test/OptionalDependency.txt");
-        String expected = FileUtils.readFileToString(file);
+        String expected = "com.google:rootArtifact:jar:1.0.0\n"
+                + "+- (org.apache:left:xml:0.1-SNAPSHOT:test - omitted due to optional dependency)\n"
+                + "\\- org.xyz:right:zip:1:provided\n";
 
         Assert.assertEquals(expected, actual);
     }
@@ -200,6 +215,7 @@ public class VerboseGraphSerializerTest extends AbstractMojoTestCase
     @Test
     public void testTreeWithScopeConflict() throws IOException
     {
+        serializer = new VerboseGraphTextSerializer();
         DependencyNode root = new DefaultDependencyNode(
                 new Dependency( new DefaultArtifact( "com.google", "rootArtifact", "jar", "1.0.0" ), null )
         );
@@ -217,8 +233,9 @@ public class VerboseGraphSerializerTest extends AbstractMojoTestCase
         root.setChildren( Arrays.asList( left, right ) );
 
         String actual = serializer.serialize( root );
-        File file = new File(getBasedir(), "/target/test-classes/unit/verbose-serializer-test/ScopeConflict.txt");
-        String expected = FileUtils.readFileToString(file);
+        String expected = "com.google:rootArtifact:jar:1.0.0\n" + "+- org.apache:left:xml:0.1-SNAPSHOT:test\n"
+                + "|  \\- (com.google:conflictArtifact:jar:1.0.0:compile - omitted for conflict with test)\n"
+                + "\\- com.google:conflictArtifact:jar:1.0.0:test\n";
 
         Assert.assertEquals(expected, actual);
     }
@@ -226,6 +243,7 @@ public class VerboseGraphSerializerTest extends AbstractMojoTestCase
     @Test
     public void testTreeWithVersionConflict() throws IOException
     {
+        serializer = new VerboseGraphTextSerializer();
         DependencyNode root = new DefaultDependencyNode(
                 new Dependency( new DefaultArtifact( "com.google", "rootArtifact", "jar", "1.0.0" ), "rootScope" )
         );
@@ -244,10 +262,399 @@ public class VerboseGraphSerializerTest extends AbstractMojoTestCase
         root.setChildren( Arrays.asList( left, right ) );
 
         String actual = serializer.serialize( root );
-        File file = new File(getBasedir(),
-                "/target/test-classes/unit/verbose-serializer-test/VersionConflict.txt");
-        String expected = FileUtils.readFileToString(file);
+        String expected = "com.google:rootArtifact:jar:1.0.0\n" + "+- org.apache:left:xml:0.1-SNAPSHOT:test\n"
+                + "|  \\- (org.apache:left:xml:0.3.1:compile - omitted for conflict with 0.1-SNAPSHOT)\n"
+                + "\\- com.google:artifact:jar:2.0.0:test\n";
+
+        Assert.assertEquals(expected, actual);
+    }
 
+    @Test
+    public void testDotOutput()
+    {
+        serializer = new VerboseGraphDotSerializer();
+        DependencyNode root = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.example", "root", "jar", "3.1.1" ), "" )
+        );
+
+        DependencyNode l1left = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.duplicate", "duplicate", "xml", "2" ), "compile" )
+        );
+        DependencyNode l2left = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.duplicate", "duplicate", "xml", "2" ), "compile" )
+        );
+        Artifact cycleArtifact = new DefaultArtifact( "org.cycle", "cycle", "zip", "3" );
+        cycleArtifact = cycleArtifact.setProperties( Collections.singletonMap( "Cycle", "true" ) );
+        DependencyNode l2middleLeft = new DefaultDependencyNode(
+                new Dependency( cycleArtifact, "compile" )
+        );
+
+        DependencyNode l1middle = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.apache", "maven", "jar", "1.0-SNAPSHOT" ), "test" )
+        );
+        // should have scope conflict with l1middle, check to make sure its not version
+        DependencyNode l2middleRight = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.apache", "maven-dependency", "jar", "1.0-SNAPSHOT" ), "compile" )
+        );
+
+        DependencyNode l1right = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.apache", "maven-dependency", "jar", "1.0-SNAPSHOT" ), "test" )
+        );
+        DependencyNode l5right = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.apache", "maven-dependency", "jar", "2.1" ), "test" )
+        );
+        DependencyNode l6right = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.abc", "shouldn't show", "xml", "1" ), "compile" )
+        );
+
+        Artifact scopeManaged = new DefaultArtifact( "org.scopeManaged", "scope-managed", "zip", "2.1" );
+        Map<String, String> artifactProperties = new HashMap<>( scopeManaged.getProperties() );
+        artifactProperties.put( PRE_MANAGED_SCOPE, "runtime" );
+        artifactProperties.put( MANAGED_SCOPE, "compile" );
+        scopeManaged = scopeManaged.setProperties( artifactProperties );
+        DependencyNode l2right = new DefaultDependencyNode(
+                new Dependency( scopeManaged, "scope" )
+        );
+
+        Artifact versionManaged = new DefaultArtifact( "org.versionManaged", "version-manged", "pom", "3.3.3" );
+        artifactProperties = new HashMap<>( versionManaged.getProperties() );
+        artifactProperties.put( PRE_MANAGED_VERSION, "1.1.0" );
+        versionManaged = versionManaged.setProperties( artifactProperties );
+        DependencyNode l3right = new DefaultDependencyNode(
+                new Dependency( versionManaged, "provided" )
+        );
+
+        Artifact scopeVersionManaged = new DefaultArtifact( "org.scopeVersionManaged", "scope-version-managed",
+                "xml", "2" );
+        artifactProperties = new HashMap<>( scopeVersionManaged.getProperties() );
+        artifactProperties.put( PRE_MANAGED_SCOPE, "runtime" );
+        artifactProperties.put( MANAGED_SCOPE, "compile" );
+        artifactProperties.put( PRE_MANAGED_VERSION, "3.1" );
+        scopeVersionManaged = scopeVersionManaged.setProperties( artifactProperties );
+
+        DependencyNode l4right = new DefaultDependencyNode(
+                new Dependency( scopeVersionManaged, "runtime" )
+        );
+
+
+        Dependency optionalDependency = new Dependency(
+                new DefaultArtifact( "org.apache", "optional", "jar", "1.1" ), "test" );
+        optionalDependency = optionalDependency.setOptional( true );
+        DependencyNode l1Optional = new DefaultDependencyNode( optionalDependency );
+
+        root.setChildren( Arrays.asList( l1left, l1middle, l1right, l1Optional ) );
+        l1left.setChildren( Arrays.asList( l2left, l2middleLeft ) );
+        l2left.setChildren( Collections.singletonList( l6right ) ); // l6right shouldn't show due to omitted parent node
+        l2middleLeft.setChildren( Collections.singletonList( l6right ) );
+        l1Optional.setChildren( Collections.singletonList( l6right ) );
+        l1middle.setChildren( Collections.singletonList( l2middleRight ) );
+        l1right.setChildren( Collections.singletonList( l2right ) );
+        l2right.setChildren( Collections.singletonList( l3right ) );
+        l3right.setChildren( Collections.singletonList( l4right ) );
+        l4right.setChildren( Collections.singletonList( l5right ) );
+        l5right.setChildren( Collections.singletonList( l6right ) );
+
+        String actual = serializer.serialize( root );
+        String expected = "digraph \"org.example:root:jar:3.1.1\" {"
+                + "\n"
+                + " \"org.example:root:jar:3.1.1\" -> \"org.duplicate:duplicate:xml:2:compile\" ;"
+                + "\n"
+                + " \"org.example:root:jar:3.1.1\" -> \"org.apache:maven:jar:1.0-SNAPSHOT:test\" ;"
+                + "\n"
+                + " \"org.example:root:jar:3.1.1\" -> \"org.apache:maven-dependency:jar:1.0-SNAPSHOT:test\" ;"
+                + "\n"
+                + " \"org.example:root:jar:3.1.1\" -> \"org.apache:optional:jar:1.1:test - omitted due to optional "
+                + "dependency\" ;" + "\n"
+                + " \"org.duplicate:duplicate:xml:2:compile\" -> \"org.duplicate:duplicate"
+                + ":xml:2:compile - omitted for duplicate\" ;" + "\n"
+                + " \"org.duplicate:duplicate:xml:2:compile\" -> \"org.cycle:cycle:zip:3:compile - omitted due "
+                + "to cycle\" ;" + "\n"
+                + " \"org.apache:maven:jar:1.0-SNAPSHOT:test\" -> \"org.apache:maven-dependency"
+                + ":jar:1.0-SNAPSHOT:compile - omitted for conflict with test\" ;" + "\n"
+                + " \"org.apache:maven-dependency:jar:1.0-SNAPSHOT:test\" -> \"org.scopeManaged:scope-managed:zip"
+                + ":2.1:compile - scope managed from runtime\" ;" + "\n"
+                + " \"org.scopeManaged:scope-managed:zip:2.1:compile\" -> \"org.versionManaged:version-manged:"
+                + "pom:3.3.3:provided - version managed from 1.1.0\" ;" + "\n"
+                + " \"org.versionManaged:version-manged:pom:3.3.3:provided\" -> \"org.scopeVersionManaged:"
+                + "scope-version-managed:xml:2:compile - version managed from 3.1; scope managed from runtime\" ;"
+                + "\n" + " \"org.scopeVersionManaged:scope-version-managed:xml:2:compile\" -> "
+                + "\"org.apache:maven-dependency:jar:2.1:test - omitted for conflict with 1.0-SNAPSHOT\" ;"
+                + "\n" + "}";
+        Assert.assertEquals(expected, actual);
+    }
+
+    @Test
+    public void testTgfOutput()
+    {
+        serializer = new VerboseGraphTgfSerializer();
+        DependencyNode root = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.example", "root", "jar", "3.1.1" ), "" )
+        );
+
+        DependencyNode l1left = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.duplicate", "duplicate", "xml", "2" ), "compile" )
+        );
+        DependencyNode l2left = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.duplicate", "duplicate", "xml", "2" ), "compile" )
+        );
+        Artifact cycleArtifact = new DefaultArtifact( "org.cycle", "cycle", "zip", "3" );
+        cycleArtifact = cycleArtifact.setProperties( Collections.singletonMap( "Cycle", "true" ) );
+        DependencyNode l2middleLeft = new DefaultDependencyNode(
+                new Dependency( cycleArtifact, "compile" )
+        );
+
+        DependencyNode l1middle = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.apache", "maven", "jar", "1.0-SNAPSHOT" ), "test" )
+        );
+        // should have scope conflict with l1middle, check to make sure its not version
+        DependencyNode l2middleRight = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.apache", "maven-dependency", "jar", "1.0-SNAPSHOT" ), "compile" )
+        );
+
+        DependencyNode l1right = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.apache", "maven-dependency", "jar", "1.0-SNAPSHOT" ), "test" )
+        );
+        DependencyNode l5right = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.apache", "maven-dependency", "jar", "2.1" ), "test" )
+        );
+        DependencyNode l6right = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.abc", "shouldn't show", "xml", "1" ), "compile" )
+        );
+
+        Artifact scopeManaged = new DefaultArtifact( "org.scopeManaged", "scope-managed", "zip", "2.1" );
+        Map<String, String> artifactProperties = new HashMap<>( scopeManaged.getProperties() );
+        artifactProperties.put( PRE_MANAGED_SCOPE, "runtime" );
+        artifactProperties.put( MANAGED_SCOPE, "compile" );
+        scopeManaged = scopeManaged.setProperties( artifactProperties );
+        DependencyNode l2right = new DefaultDependencyNode(
+                new Dependency( scopeManaged, "scope" )
+        );
+
+        Artifact versionManaged = new DefaultArtifact( "org.versionManaged", "version-manged", "pom", "3.3.3" );
+        artifactProperties = new HashMap<>( versionManaged.getProperties() );
+        artifactProperties.put( PRE_MANAGED_VERSION, "1.1.0" );
+        versionManaged = versionManaged.setProperties( artifactProperties );
+        DependencyNode l3right = new DefaultDependencyNode(
+                new Dependency( versionManaged, "provided" )
+        );
+
+        Artifact scopeVersionManaged = new DefaultArtifact( "org.scopeVersionManaged", "scope-version-managed",
+                "xml", "2" );
+        artifactProperties = new HashMap<>( scopeVersionManaged.getProperties() );
+        artifactProperties.put( PRE_MANAGED_SCOPE, "runtime" );
+        artifactProperties.put( MANAGED_SCOPE, "compile" );
+        artifactProperties.put( PRE_MANAGED_VERSION, "3.1" );
+        scopeVersionManaged = scopeVersionManaged.setProperties( artifactProperties );
+
+        DependencyNode l4right = new DefaultDependencyNode(
+                new Dependency( scopeVersionManaged, "runtime" )
+        );
+
+
+        Dependency optionalDependency = new Dependency(
+                new DefaultArtifact( "org.apache", "optional", "jar", "1.1" ), "test" );
+        optionalDependency = optionalDependency.setOptional( true );
+        DependencyNode l1Optional = new DefaultDependencyNode( optionalDependency );
+
+        root.setChildren( Arrays.asList( l1left, l1middle, l1right, l1Optional ) );
+        l1left.setChildren( Arrays.asList( l2left, l2middleLeft ) );
+        l2left.setChildren( Collections.singletonList( l6right ) ); // l6right shouldn't show due to omitted parent node
+        l2middleLeft.setChildren( Collections.singletonList( l6right ) );
+        l1Optional.setChildren( Collections.singletonList( l6right ) );
+        l1middle.setChildren( Collections.singletonList( l2middleRight ) );
+        l1right.setChildren( Collections.singletonList( l2right ) );
+        l2right.setChildren( Collections.singletonList( l3right ) );
+        l3right.setChildren( Collections.singletonList( l4right ) );
+        l4right.setChildren( Collections.singletonList( l5right ) );
+        l5right.setChildren( Collections.singletonList( l6right ) );
+
+        String actual = serializer.serialize( root );
+        String expected = root.hashCode() + " org.example:root:jar:3.1.1" + "\n"
+                + l1left.hashCode() + " org.duplicate:duplicate:xml:2:compile" + "\n"
+                + l2left.hashCode() + " (org.duplicate:duplicate:xml:2:compile - omitted for duplicate)"
+                + "\n" + l2middleLeft.hashCode()
+                + " (org.cycle:cycle:zip:3:compile - omitted for cycle)" + "\n"
+                + l1middle.hashCode() + " org.apache:maven:jar:1.0-SNAPSHOT:test" + "\n"
+                + l2middleRight.hashCode()
+                + " (org.apache:maven-dependency:jar:1.0-SNAPSHOT:compile - omitted for conflict with test)"
+                + "\n" + l1right.hashCode() + " org.apache:maven-dependency:jar:1.0-SNAPSHOT:test"
+                + "\n" + l2right.hashCode()
+                + " org.scopeManaged:scope-managed:zip:2.1:compile - scope managed from runtime"
+                + "\n" + l3right.hashCode()
+                + " org.versionManaged:version-manged:pom:3.3.3:provided - version managed from 1.1.0"
+                + "\n" + l4right.hashCode()
+                + " org.scopeVersionManaged:scope-version-managed:xml:2:compile - version managed from 3.1; "
+                + "scope managed from runtime" + "\n" + l5right.hashCode()
+                + " (org.apache:maven-dependency:jar:2.1:test - omitted for conflict with 1.0-SNAPSHOT)"
+                + "\n" + l1Optional.hashCode()
+                + " (org.apache:optional:jar:1.1:test - omitted due to optional dependency)"
+                + "\n" + "#" + "\n" + root.hashCode() + " " + l1left.hashCode()
+                + " compile" + "\n"
+                + l1left.hashCode() + " " + l2left.hashCode() + " compile omitted for duplicate"
+                + "\n" + l1left.hashCode() + " " + l2middleLeft.hashCode()
+                + " compile omitted for cycle" + "\n" + root.hashCode() + " " + l1middle.hashCode()
+                + " test" + "\n" + l1middle.hashCode() + " " + l2middleRight.hashCode()
+                + " compile omitted for conflict with test" + "\n" + root.hashCode() + " "
+                + l1right.hashCode() + " test" + "\n" + l1right.hashCode() + " " + l2right.hashCode()
+                + " compile managed from runtime" + "\n" + l2right.hashCode() + " "
+                + l3right.hashCode() + " provided" + "\n" + l3right.hashCode() + " "
+                + l4right.hashCode() + " compile managed from runtime" + "\n" + l4right.hashCode()
+                + " " + l5right.hashCode() + " test omitted for conflict with 1.0-SNAPSHOT" + "\n" +
+                root.hashCode() + " " + l1Optional.hashCode() + " test" + "\n";
+        Assert.assertEquals(expected, actual);
+    }
+
+    @Test
+    public void testGraphmlOutput()
+    {
+        serializer = new VerboseGraphGraphmlSerializer();
+        DependencyNode root = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.example", "root", "jar", "3.1.1" ), "" )
+        );
+
+        DependencyNode l1left = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.duplicate", "duplicate", "xml", "2" ), "compile" )
+        );
+        DependencyNode l2left = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.duplicate", "duplicate", "xml", "2" ), "compile" )
+        );
+        Artifact cycleArtifact = new DefaultArtifact( "org.cycle", "cycle", "zip", "3" );
+        cycleArtifact = cycleArtifact.setProperties( Collections.singletonMap( "Cycle", "true" ) );
+        DependencyNode l2middleLeft = new DefaultDependencyNode(
+                new Dependency( cycleArtifact, "compile" )
+        );
+
+        DependencyNode l1middle = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.apache", "maven", "jar", "1.0-SNAPSHOT" ), "test" )
+        );
+        // should have scope conflict with l1middle, check to make sure its not version
+        DependencyNode l2middleRight = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.apache", "maven-dependency", "jar", "1.0-SNAPSHOT" ), "compile" )
+        );
+
+        DependencyNode l1right = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.apache", "maven-dependency", "jar", "1.0-SNAPSHOT" ), "test" )
+        );
+        DependencyNode l5right = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.apache", "maven-dependency", "jar", "2.1" ), "test" )
+        );
+        DependencyNode l6right = new DefaultDependencyNode(
+                new Dependency( new DefaultArtifact( "org.abc", "shouldn't show", "xml", "1" ), "compile" )
+        );
+
+        Artifact scopeManaged = new DefaultArtifact( "org.scopeManaged", "scope-managed", "zip", "2.1" );
+        Map<String, String> artifactProperties = new HashMap<>( scopeManaged.getProperties() );
+        artifactProperties.put( PRE_MANAGED_SCOPE, "runtime" );
+        artifactProperties.put( MANAGED_SCOPE, "compile" );
+        scopeManaged = scopeManaged.setProperties( artifactProperties );
+        DependencyNode l2right = new DefaultDependencyNode(
+                new Dependency( scopeManaged, "scope" )
+        );
+
+        Artifact versionManaged = new DefaultArtifact( "org.versionManaged", "version-manged", "pom", "3.3.3" );
+        artifactProperties = new HashMap<>( versionManaged.getProperties() );
+        artifactProperties.put( PRE_MANAGED_VERSION, "1.1.0" );
+        versionManaged = versionManaged.setProperties( artifactProperties );
+        DependencyNode l3right = new DefaultDependencyNode(
+                new Dependency( versionManaged, "provided" )
+        );
+
+        Artifact scopeVersionManaged = new DefaultArtifact( "org.scopeVersionManaged", "scope-version-managed",
+                "xml", "2" );
+        artifactProperties = new HashMap<>( scopeVersionManaged.getProperties() );
+        artifactProperties.put( PRE_MANAGED_SCOPE, "runtime" );
+        artifactProperties.put( MANAGED_SCOPE, "compile" );
+        artifactProperties.put( PRE_MANAGED_VERSION, "3.1" );
+        scopeVersionManaged = scopeVersionManaged.setProperties( artifactProperties );
+
+        DependencyNode l4right = new DefaultDependencyNode(
+                new Dependency( scopeVersionManaged, "runtime" )
+        );
+
+        Dependency optionalDependency = new Dependency(
+                new DefaultArtifact( "org.apache", "optional", "jar", "1.1" ), "test" );
+        optionalDependency = optionalDependency.setOptional( true );
+        DependencyNode l1Optional = new DefaultDependencyNode( optionalDependency );
+
+        root.setChildren( Arrays.asList( l1left, l1middle, l1right, l1Optional ) );
+        l1left.setChildren( Arrays.asList( l2left, l2middleLeft ) );
+        l2left.setChildren( Collections.singletonList( l6right ) ); // l6right shouldn't show due to omitted parent node
+        l2middleLeft.setChildren( Collections.singletonList( l6right ) );
+        l1Optional.setChildren( Collections.singletonList( l6right ) );
+        l1middle.setChildren( Collections.singletonList( l2middleRight ) );
+        l1right.setChildren( Collections.singletonList( l2right ) );
+        l2right.setChildren( Collections.singletonList( l3right ) );
+        l3right.setChildren( Collections.singletonList( l4right ) );
+        l4right.setChildren( Collections.singletonList( l5right ) );
+        l5right.setChildren( Collections.singletonList( l6right ) );
+
+        String actual = serializer.serialize( root );
+        String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <graphml xmlns=\"http://graphml.graph"
+                + "drawing.org/xmlns\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:y=\"http://www.ywo"
+                + "rks.com/xml/graphml\" xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns http://graphml."
+                + "graphdrawing.org/xmlns/1.0/graphml.xsd\">" + "\n" + "  <key for=\"node\" id=\"d0\" "
+                + "yfiles.type=\"nodegraphics\"/>" + "\n" + "  <key for=\"edge\" id=\"d1\" yfiles"
+                + ".type=\"edgegraphics\"/>" + "\n"
+                + "<graph id=\"dependencies\" edgedefault=\"directed\">"
+                + "\n" + "<node id=\"" + root.hashCode() + "\"><data key=\"d0\"><y:ShapeNode>"
+                + "<y:NodeLabel>" + "org.example:root:jar:3.1.1</y:NodeLabel></y:ShapeNode></data></node>"
+                + "\n" + "<node id=\"" + l1left.hashCode() + "\"><data key=\"d0\"><y:ShapeNode>"
+                + "<y:NodeLabel>org.duplicate:duplicate:xml:" + "2:compile</y:NodeLabel></y:ShapeNode></data></node>"
+                + "\n"
+                + "<node id=\"" + l1middle.hashCode() + "\"><data key=\"d0\"><y:ShapeNode><y:NodeLabel>org.apache:"
+                + "maven:jar:1.0-SNAPSHOT:test</y:NodeLabel></y:ShapeNode></data></node>" + "\n"
+                + "<node id=\"" + l1right.hashCode() + "\"><data key=\"d0\"><y:ShapeNode><y:NodeLabel>org.apache:maven"
+                + "-dependency:jar:1.0-SNAPSHOT:test</y:NodeLabel></y:ShapeNode></data></node>" + "\n"
+                + "<node id=\"" + l1Optional.hashCode() + "\"><data key=\"d0\"><y:ShapeNode><y:NodeLabel>org.apache:"
+                + "optional:jar:1.1:test - omitted due to optional dependency</y:NodeLabel></y:ShapeNode></data></node>"
+                + "\n" + "<node id=\"" + l2left.hashCode() + "\"><data key=\"d0\"><y:ShapeNode>"
+                + "<y:NodeLabel>org.duplicate:duplicate:xml:2:compile - omitted for duplicate</y:NodeLabel>"
+                + "</y:ShapeNode></data></node>" + "\n" + "<node id=\"" + l2middleLeft.hashCode()
+                + "\"><data key=\"d0\"><y:ShapeNode><y:NodeLabel>org.cycle:cycle:zip:3:compile - omitted due to cycle"
+                + "</y:NodeLabel></y:ShapeNode></data></node>" + "\n"
+                + "<node id=\"" + l2middleRight.hashCode() + "\">"
+                + "<data key=\"d0\"><y:ShapeNode><y:NodeLabel>org.apache:maven-dependency:jar:1.0-SNAPSHOT:compile "
+                + "- omitted for conflict with test</y:NodeLabel></y:ShapeNode></data></node>" + "\n"
+                + "<node id=\"" + l2right.hashCode() + "\"><data key=\"d0\"><y:ShapeNode><y:NodeLabel>org.scopeManaged"
+                + ":scope-managed:zip:2.1:compile - scope managed from runtime</y:NodeLabel></y:ShapeNode></data>"
+                + "</node>" + "\n" + "<node id=\"" + l3right.hashCode() + "\"><data key=\"d0\">"
+                + "<y:ShapeNode><y:NodeLabel>org.versionManaged:version-manged:pom:3.3.3:provided - version managed "
+                + "from 1.1.0</y:NodeLabel></y:ShapeNode></data></node>" + "\n"
+                + "<node id=\"" + l4right.hashCode()
+                + "\"><data key=\"d0\"><y:ShapeNode><y:NodeLabel>org.scopeVersionManaged:scope-version-managed:xml:"
+                + "2:compile - version managed from 3.1; scope managed from runtime</y:NodeLabel></y:ShapeNode>"
+                + "</data></node>" + "\n" + "<node id=\"" + l5right.hashCode() + "\"><data key="
+                + "\"d0\"><y:ShapeNode><y:NodeLabel>org.apache:maven-dependency:jar:2.1:test - omitted for"
+                + " conflict with 1.0-SNAPSHOT</y:NodeLabel></y:ShapeNode></data></node>" + "\n"
+                + "<edge source=\"" + root.hashCode() + "\" target=\"" + l1left.hashCode()
+                + "\"><data key=\"d1\"><y:PolyLineEdge><y:EdgeLabel>compile</y:EdgeLabel></y:PolyLineEdge></data>"
+                + "</edge>" + "\n" + "<edge source=\"" + root.hashCode() + "\" target=\""
+                + l1middle.hashCode() + "\"><data key=\"d1\"><y:PolyLineEdge><y:EdgeLabel>test</y:EdgeLabel>"
+                + "</y:PolyLineEdge></data></edge>" + "\n" + "<edge source=\"" + root.hashCode()
+                + "\" target=\"" + l1right.hashCode() + "\"><data key=\"d1\"><y:PolyLineEdge><y:EdgeLabel>test"
+                + "</y:EdgeLabel></y:PolyLineEdge></data></edge>" + "\n" + "<edge source=\""
+                + root.hashCode() + "\" target=\"" + l1Optional.hashCode() + "\"><data key=\"d1\"><y:PolyLineEdge>"
+                + "<y:EdgeLabel>test omitted due to optional dependency</y:EdgeLabel></y:PolyLineEdge></data></edge>"
+                + "\n" + "<edge source=\"" + l1left.hashCode() + "\" target=\""
+                + l2left.hashCode() + "\"><data key=\"d1\"><y:PolyLineEdge><y:EdgeLabel>compile omitted "
+                + "for duplicate</y:EdgeLabel></y:PolyLineEdge></data></edge>" + "\n"
+                + "<edge source=\"" + l1left.hashCode() + "\" target=\"" + l2middleLeft.hashCode()
+                + "\"><data key=\"d1\"><y:PolyLineEdge><y:EdgeLabel>compile omitted due to cycle</y:EdgeLabel>"
+                + "</y:PolyLineEdge></data></edge>" + "\n" + "<edge source=\"" + l1middle.hashCode()
+                + "\" target=\""
+                + l2middleRight.hashCode() + "\"><data key=\"d1\"><y:PolyLineEdge><y:EdgeLabel>compile omitted"
+                + " for conflict with test</y:EdgeLabel></y:PolyLineEdge></data></edge>" + "\n"
+                + "<edge source=\"" + l1right.hashCode() + "\" target=\"" + l2right.hashCode() + "\"><data key=\"d1\">"
+                + "<y:PolyLineEdge><y:EdgeLabel>compile, scope managed from runtime</y:EdgeLabel></y:PolyLineEdge>"
+                + "</data></edge>" + "\n" + "<edge source=\"" + l2right.hashCode() + "\" target="
+                + "\"" + l3right.hashCode() + "\"><data key=\"d1\"><y:PolyLineEdge><y:EdgeLabel>provided"
+                + "</y:EdgeLabel></y:PolyLineEdge></data></edge>" + "\n" + "<edge source=\""
+                + l3right.hashCode() + "\" target=\"" + l4right.hashCode() + "\"><data key=\"d1\"><y:PolyLineEdge>"
+                + "<y:EdgeLabel>compile, scope managed from runtime</y:EdgeLabel></y:PolyLineEdge></data>"
+                + "</edge>" + "\n" + "<edge source=\"" + l4right.hashCode() + "\" target=\""
+                + l5right.hashCode() + "\"><data key=\"d1\"><y:PolyLineEdge><y:EdgeLabel>test omitted "
+                + "for conflict with 1.0-SNAPSHOT</y:EdgeLabel></y:PolyLineEdge></data></edge>" + "\n"
+                + "</graph></graphml>";
         Assert.assertEquals(expected, actual);
     }
 }
diff --git a/src/test/resources/unit/verbose-serializer-test/BasicCycle.txt b/src/test/resources/unit/verbose-serializer-test/BasicCycle.txt
deleted file mode 100644
index 37d528b..0000000
--- a/src/test/resources/unit/verbose-serializer-test/BasicCycle.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-com.google:rootArtifact:jar:1.0.0
-+- (org.apache:left:xml:0.1-SNAPSHOT:test - omitted for introducing a cycle with com.google:rootArtifact:jar:1.0.0)
-\- org.xyz:right:zip:1:provided
diff --git a/src/test/resources/unit/verbose-serializer-test/BasicTree.txt b/src/test/resources/unit/verbose-serializer-test/BasicTree.txt
deleted file mode 100644
index c1c1c1e..0000000
--- a/src/test/resources/unit/verbose-serializer-test/BasicTree.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-com.google:rootArtifact:jar:1.0.0
-+- org.apache:left:xml:0.1-SNAPSHOT:test
-\- org.xyz:right:zip:1:provided
diff --git a/src/test/resources/unit/verbose-serializer-test/LargeGraphWithCycles.txt b/src/test/resources/unit/verbose-serializer-test/LargeGraphWithCycles.txt
deleted file mode 100644
index 87d3590..0000000
--- a/src/test/resources/unit/verbose-serializer-test/LargeGraphWithCycles.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-com.google:rootArtifact:jar:1.0.0
-+- org.apache:left:xml:0.1-SNAPSHOT:test
-|  +- org.maven:a4:jar:2.2.1:system
-|  \- com.google:a5:zip:0:import
-|     \- com.xyz:a6:xml:1.2.1:compile
-|        \- com.example:a7:jar:2.2.2:provided
-|           +- (com.comm:a7:jar:1:compile - omitted for introducing a cycle with org.maven:a4:jar:2.2.1:system)
-|           \- (com.comm:a7:jar:1:compile - omitted for duplicate)
-\- org.xyz:right:zip:1:provided
-   \- com.xyz:a9:xml:1.2:runtime
diff --git a/src/test/resources/unit/verbose-serializer-test/LargeTree.txt b/src/test/resources/unit/verbose-serializer-test/LargeTree.txt
deleted file mode 100644
index 6480fa6..0000000
--- a/src/test/resources/unit/verbose-serializer-test/LargeTree.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-com.google:rootArtifact:jar:1.0.0
-+- org.apache:left:xml:0.1-SNAPSHOT:test
-|  +- org.maven:a4:jar:2.2.1:system
-|  \- com.google:a5:zip:0:import
-|     \- com.xyz:a6:xml:1.2.1:provided
-|        \- com.example:a7:jar:2.2.2:provided
-|           +- com.comm:a7:jar:1:compile
-|           |  \- com.example:a8:xml:2.1:compile
-|           \- (com.comm:a7:jar:1:compile - omitted for duplicate)
-\- org.xyz:right:zip:1:provided
-   \- com.xyz:a9:xml:1.2:runtime
diff --git a/src/test/resources/unit/verbose-serializer-test/OptionalDependency.txt b/src/test/resources/unit/verbose-serializer-test/OptionalDependency.txt
deleted file mode 100644
index 4c4f11f..0000000
--- a/src/test/resources/unit/verbose-serializer-test/OptionalDependency.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-com.google:rootArtifact:jar:1.0.0
-+- (org.apache:left:xml:0.1-SNAPSHOT:test - omitted due to optional dependency)
-\- org.xyz:right:zip:1:provided
diff --git a/src/test/resources/unit/verbose-serializer-test/ScopeConflict.txt b/src/test/resources/unit/verbose-serializer-test/ScopeConflict.txt
deleted file mode 100644
index 81f2977..0000000
--- a/src/test/resources/unit/verbose-serializer-test/ScopeConflict.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-com.google:rootArtifact:jar:1.0.0
-+- org.apache:left:xml:0.1-SNAPSHOT:test
-|  \- (com.google:conflictArtifact:jar:1.0.0:compile - omitted for conflict with test)
-\- com.google:conflictArtifact:jar:1.0.0:test
diff --git a/src/test/resources/unit/verbose-serializer-test/VersionConflict.txt b/src/test/resources/unit/verbose-serializer-test/VersionConflict.txt
deleted file mode 100644
index 640e3f3..0000000
--- a/src/test/resources/unit/verbose-serializer-test/VersionConflict.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-com.google:rootArtifact:jar:1.0.0
-+- org.apache:left:xml:0.1-SNAPSHOT:test
-|  \- (org.apache:left:xml:0.3.1:compile - omitted for conflict with 0.1-SNAPSHOT)
-\- com.google:artifact:jar:2.0.0:test