diff --git a/pom.xml b/pom.xml
index 6f409ee..7078493 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,5 +1,4 @@
-<?xml version='1.0' encoding='UTF-8'?>
-
+<?xml version="1.0" encoding="UTF-8"?>
 <!--
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
@@ -18,14 +17,13 @@
 specific language governing permissions and limitations
 under the License.
 -->
-
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
 
   <parent>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-plugins</artifactId>
-    <version>34</version>
+    <version>43</version>
     <relativePath />
   </parent>
 
@@ -37,15 +35,21 @@
   <description>The JDeps Plugin uses the jdeps tool to analyze classes for internal API calls.</description>
   <inceptionYear>2015</inceptionYear>
 
+  <contributors>
+    <contributor>
+      <name>Andrea Nenni</name>
+    </contributor>
+  </contributors>
+
   <prerequisites>
-    <maven>${mavenVersion}</maven>
+    <maven>3.6.3</maven>
   </prerequisites>
 
   <scm>
     <connection>scm:git:https://gitbox.apache.org/repos/asf/maven-jdeps-plugin.git</connection>
     <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/maven-jdeps-plugin.git</developerConnection>
-    <url>https://github.com/apache/maven-jdeps-plugin/tree/${project.scm.tag}</url>
     <tag>HEAD</tag>
+    <url>https://github.com/apache/maven-jdeps-plugin/tree/${project.scm.tag}</url>
   </scm>
   <issueManagement>
     <system>JIRA</system>
@@ -63,17 +67,11 @@
   </distributionManagement>
 
   <properties>
-    <mavenVersion>3.0</mavenVersion>
+    <mavenVersion>3.9.9</mavenVersion>
     <javaVersion>8</javaVersion>
     <project.build.outputTimestamp>2020-04-07T21:04:00Z</project.build.outputTimestamp>
   </properties>
 
-  <contributors>
-    <contributor>
-      <name>Andrea Nenni</name>
-    </contributor>
-  </contributors>
-
   <dependencies>
     <dependency>
       <groupId>org.apache.maven.plugin-tools</groupId>
@@ -85,33 +83,34 @@
       <groupId>org.apache.maven</groupId>
       <artifactId>maven-plugin-api</artifactId>
       <version>${mavenVersion}</version>
+      <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.maven</groupId>
       <artifactId>maven-core</artifactId>
       <version>${mavenVersion}</version>
+      <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.maven</groupId>
       <artifactId>maven-model</artifactId>
       <version>${mavenVersion}</version>
+      <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>org.codehaus.plexus</groupId>
       <artifactId>plexus-utils</artifactId>
-      <version>3.1.0</version>
     </dependency>
     <dependency>
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-lang3</artifactId>
-      <version>3.5</version>
+      <version>3.17.0</version>
     </dependency>
 
     <!-- TEST -->
     <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>4.13.2</version>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-api</artifactId>
       <scope>test</scope>
     </dependency>
   </dependencies>
diff --git a/src/it/basic/invoker.properties b/src/it/basic/invoker.properties
index b472579..6dd4341 100644
--- a/src/it/basic/invoker.properties
+++ b/src/it/basic/invoker.properties
@@ -15,5 +15,4 @@
 # specific language governing permissions and limitations
 # under the License.
 
-invoker.java.version=1.8+
 invoker.goals=process-classes
diff --git a/src/it/dependenciesToAnalyze/invoker.properties b/src/it/dependenciesToAnalyze/invoker.properties
index b472579..6dd4341 100644
--- a/src/it/dependenciesToAnalyze/invoker.properties
+++ b/src/it/dependenciesToAnalyze/invoker.properties
@@ -15,5 +15,4 @@
 # specific language governing permissions and limitations
 # under the License.
 
-invoker.java.version=1.8+
 invoker.goals=process-classes
diff --git a/src/it/includeClasspath/invoker.properties b/src/it/includeClasspath/invoker.properties
index f5d8d2d..a8ebbdb 100644
--- a/src/it/includeClasspath/invoker.properties
+++ b/src/it/includeClasspath/invoker.properties
@@ -15,6 +15,5 @@
 # specific language governing permissions and limitations
 # under the License.
 
-invoker.java.version=1.8+
 invoker.goals=process-classes
-invoker.buildResult=failure
\ No newline at end of file
+invoker.buildResult=failure
diff --git a/src/it/package/invoker.properties b/src/it/package/invoker.properties
index 9dc2e74..dd5b491 100644
--- a/src/it/package/invoker.properties
+++ b/src/it/package/invoker.properties
@@ -15,5 +15,4 @@
 # specific language governing permissions and limitations
 # under the License.
 
-invoker.java.version=1.8+
 invoker.goals=process-classes
diff --git a/src/it/unsupported-api_main/invoker.properties b/src/it/unsupported-api_main/invoker.properties
index 8017e40..615a700 100644
--- a/src/it/unsupported-api_main/invoker.properties
+++ b/src/it/unsupported-api_main/invoker.properties
@@ -15,6 +15,6 @@
 # specific language governing permissions and limitations
 # under the License.
 
-invoker.java.version=1.8
+invoker.java.version=8
 invoker.goals=process-classes
 invoker.buildResult=failure
diff --git a/src/it/unsupported-api_test/invoker.properties b/src/it/unsupported-api_test/invoker.properties
index cf5b902..9f76b3a 100644
--- a/src/it/unsupported-api_test/invoker.properties
+++ b/src/it/unsupported-api_test/invoker.properties
@@ -15,7 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 
-invoker.java.version=1.8
+invoker.java.version=8
 invoker.goals.1=process-classes
 invoker.buildResult.1=success
 
diff --git a/src/main/java/org/apache/maven/plugins/jdeps/AbstractJDKInternalsMojo.java b/src/main/java/org/apache/maven/plugins/jdeps/AbstractJDKInternalsMojo.java
index cc43d99..82007d8 100644
--- a/src/main/java/org/apache/maven/plugins/jdeps/AbstractJDKInternalsMojo.java
+++ b/src/main/java/org/apache/maven/plugins/jdeps/AbstractJDKInternalsMojo.java
@@ -1,43 +1,39 @@
-package org.apache.maven.plugins.jdeps;
-
-/*
- * 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 java.nio.file.Path;
-import java.util.Set;
-
-import org.apache.maven.plugin.MojoFailureException;
-import org.codehaus.plexus.util.cli.Commandline;
-
-/**
- * Abstract Mojo for verifying code with jdkinternals
- *  
- * @author Robert Scholte
- */
-public abstract class AbstractJDKInternalsMojo extends AbstractJDepsMojo
-{
-
-    @Override
-    protected void addJDepsOptions( Commandline cmd, Set<Path> dependenciesToAnalyze )
-        throws MojoFailureException
-    {
-        super.addJDepsOptions( cmd, dependenciesToAnalyze );
-        cmd.createArg().setValue( "-jdkinternals" );
-    }
-}
+/*
+ * 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.
+ */
+package org.apache.maven.plugins.jdeps;
+
+import java.nio.file.Path;
+import java.util.Set;
+
+import org.apache.maven.plugin.MojoFailureException;
+import org.codehaus.plexus.util.cli.Commandline;
+
+/**
+ * Abstract Mojo for verifying code with jdkinternals
+ *
+ * @author Robert Scholte
+ */
+public abstract class AbstractJDKInternalsMojo extends AbstractJDepsMojo {
+
+    @Override
+    protected void addJDepsOptions(Commandline cmd, Set<Path> dependenciesToAnalyze) throws MojoFailureException {
+        super.addJDepsOptions(cmd, dependenciesToAnalyze);
+        cmd.createArg().setValue("-jdkinternals");
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/jdeps/AbstractJDepsMojo.java b/src/main/java/org/apache/maven/plugins/jdeps/AbstractJDepsMojo.java
index 73dd3b4..ab4a641 100644
--- a/src/main/java/org/apache/maven/plugins/jdeps/AbstractJDepsMojo.java
+++ b/src/main/java/org/apache/maven/plugins/jdeps/AbstractJDepsMojo.java
@@ -1,653 +1,561 @@
-package org.apache.maven.plugins.jdeps;
-
-/*
- * 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 java.io.File;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
+/*
+ * 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.
+ */
+package org.apache.maven.plugins.jdeps;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
 import java.util.StringTokenizer;
 
 import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.SystemUtils;
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.artifact.ArtifactUtils;
-import org.apache.maven.artifact.DependencyResolutionRequiredException;
-import org.apache.maven.execution.MavenSession;
-import org.apache.maven.plugin.AbstractMojo;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
-import org.apache.maven.plugins.jdeps.consumers.JDepsConsumer;
-import org.apache.maven.plugins.annotations.Component;
-import org.apache.maven.plugins.annotations.Parameter;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.toolchain.Toolchain;
-import org.apache.maven.toolchain.ToolchainManager;
-import org.codehaus.plexus.util.MatchPatterns;
-import org.codehaus.plexus.util.cli.CommandLineException;
-import org.codehaus.plexus.util.cli.CommandLineUtils;
-import org.codehaus.plexus.util.cli.Commandline;
-
-/**
- * Abstract Mojo for JDeps
- * 
- * @author Robert Scholte
- *
- */
-public abstract class AbstractJDepsMojo
-    extends AbstractMojo
-{
-
-    @Parameter( defaultValue = "${project}", readonly = true, required = true )
-    private MavenProject project;
-
-    @Parameter( defaultValue = "${session}", readonly = true, required = true )
-    private MavenSession session;
-
-    @Parameter( defaultValue = "${project.build.directory}", readonly = true, required = true )
-    private File outputDirectory;
-
-    /**
-     * Indicates whether the build will continue even if there are jdeps warnings.
-     */
-    @Parameter( defaultValue = "true", property = "jdeps.failOnWarning" )
-    private boolean failOnWarning;
-
-    /**
-     * Specifies the version when processing multi-release JAR files version should be an integer >=9 or base.
-     *
-     * @since 3.1.1
-     */
-    @Parameter( property = "jdeps.multiRelease" )
-    private String multiRelease;
-
-    /**
-     * Whether only the sources need to be compatible or also every dependency on the classpath.
-     *
-     * @since 3.1.3
-     */
-    @Parameter( defaultValue = "true", property = "jdeps.includeClasspath" )
-    private boolean includeClasspath;
-
-    /**
-     * Additional dependencies which should be analyzed besides the classes.
-     * Specify as {@code groupId:artifactId}, allowing ant-pattern.
-     * 
-     * E.g.
-     * <pre>
-     *   &lt;dependenciesToAnalyzeIncludes&gt;
-     *     &lt;include&gt;*:*&lt;/include&gt;
-     *     &lt;include&gt;org.foo.*:*&lt;/include&gt;
-     *     &lt;include&gt;com.foo.bar:*&lt;/include&gt;
-     *     &lt;include&gt;dot.foo.bar:utilities&lt;/include&gt;
-     *   &lt;/dependenciesToAnalyzeIncludes&gt;  
-     * </pre>
-     */
-    @Parameter
-    private List<String> dependenciesToAnalyzeIncludes;
-
-    /**
-     * Subset of {@link AbstractJDepsMojo#dependenciesToAnalyzeIncludes} which should be not analyzed.
-     * Specify as {@code groupId:artifactId}, allowing ant-pattern.
-     * 
-     * E.g.
-     * <pre>
-     *   &lt;dependenciesToAnalyzeExcludes&gt;
-     *     &lt;exclude&gt;org.foo.*:*&lt;/exclude&gt;
-     *     &lt;exclude&gt;com.foo.bar:*&lt;/exclude&gt;
-     *     &lt;exclude&gt;dot.foo.bar:utilities&lt;/exclude&gt;
-     *   &lt;/dependenciesToAnalyzeExcludes&gt;  
-     * </pre>
-     */
-    @Parameter
-    private List<String> dependenciesToAnalyzeExcludes;
-
-    /**
-     * Destination directory for DOT file output
-     */
-    @Parameter( property = "jdeps.dotOutput" )
-    private File dotOutput;
-    
-//    @Parameter( defaultValue = "false", property = "jdeps.summaryOnly" )
-//    private boolean summaryOnly;
-
-    /**
-     * <dl>
-     *   <dt>package</dt><dd>Print package-level dependencies excluding dependencies within the same archive<dd/>
-     *   <dt>class</dt><dd>Print class-level dependencies excluding dependencies within the same archive<dd/>
-     *   <dt>&lt;empty&gt;</dt><dd>Print all class level dependencies. Equivalent to -verbose:class -filter:none.<dd/>
-     * </dl>
-     */
-    @Parameter( property = "jdeps.verbose" )
-    private String verbose;
-
-    
-    /**
-     * Finds dependences matching the specified package name.
-     * 
-     * @since 3.1.1.
-     */
-    @Parameter
-    private List<String> packages;
-
-//    /**
-//     * A comma-separated list to find dependences in the given package (may be given multiple times)
-//     */
-//    @Parameter( property = "jdeps.pkgnames" )
-//    private String packageNames;
-//    
-//    /**
-//     * Finds dependences in packages matching pattern (-p and -e are exclusive)
-//     */
-//    @Parameter( property = "jdeps.regex" )
-//    private String regex;
-    
-    /**
-     * Restrict analysis to classes matching pattern. This option filters the list of classes to be analyzed. It can be
-     * used together with <code>-p</code> and <code>-e</code> which apply pattern to the dependences
-     */
-    @Parameter( property = "jdeps.include" )
-    private String include;
-    
-    /**
-     * Restrict analysis to APIs i.e. dependences from the signature of public and protected members of public classes
-     * including field type, method parameter types, returned type, checked exception types etc
-     */
-    @Parameter( defaultValue = "false", property = "jdeps.apionly" )
-    private boolean apiOnly;
-    
-    /**
-     * Show profile or the file containing a package
-     */
-    @Parameter( defaultValue = "false", property = "jdeps.profile" )
-    private boolean profile;
-    
-    /**
-     * Recursively traverse all dependencies. The {@code -R} option implies {@code -filter:none}.  If {@code -p},
-     * {@code -e}, {@code -f} option is specified, only the matching dependences are analyzed.
-     */
-    @Parameter( defaultValue = "false", property = "jdeps.recursive" )
-    private boolean recursive;
-
-    /**
-     * Specifies the root module for analysis.
-     * 
-     * @since JDK 1.9.0
-     */
-    @Parameter( property = "jdeps.module" )
-    private String module;
-    
-    @Component
-    private ToolchainManager toolchainManager;
-    
-    protected MavenProject getProject()
-    {
-        return project;
-    }
-
-    public void execute()
-        throws MojoExecutionException, MojoFailureException
-    {
-        if ( !new File( getClassesDirectory() ).exists() )
-        {
-            getLog().debug( "No classes to analyze" );
-            return;
-        }
-
-        String jExecutable;
-        try
-        {
-            jExecutable = getJDepsExecutable();
-        }
-        catch ( IOException e )
-        {
-            throw new MojoFailureException( "Unable to find jdeps command: " + e.getMessage(), e );
-        }
-
-//      Synopsis
-//      jdeps [options] classes ...
-        Commandline cmd = new Commandline();
-        cmd.setExecutable( jExecutable );
-
-        Set<Path> dependenciesToAnalyze = null;
-        try
-        {
-            dependenciesToAnalyze = getDependenciesToAnalyze( includeClasspath );
-        }
-        catch ( DependencyResolutionRequiredException e )
-        {
-            throw new MojoExecutionException( e.getMessage(), e );
-        }
-        addJDepsOptions( cmd, dependenciesToAnalyze );
-        addJDepsClasses( cmd, dependenciesToAnalyze );
-        
-        JDepsConsumer consumer = new JDepsConsumer();
-        executeJDepsCommandLine( cmd, outputDirectory, consumer );
-        
-        // @ TODO if there will be more goals, this should be pushed down to AbstractJDKInternals
-        if ( consumer.getOffendingPackages().size() > 0 )
-        {
-            final String ls = System.getProperty( "line.separator" );
-            
-            StringBuilder msg = new StringBuilder();
-            msg.append( "Found offending packages:" ).append( ls );
-            for ( Map.Entry<String, String> offendingPackage : consumer.getOffendingPackages().entrySet() )
-            {
-                msg.append( ' ' ).append( offendingPackage.getKey() )
-                   .append( " -> " ).append( offendingPackage.getValue() ).append( ls );
-            }
-            
-            if ( isFailOnWarning() )
-            {
-                throw new MojoExecutionException( msg.toString() );
-            }
-        }
-    }
-
-    protected void addJDepsOptions( Commandline cmd, Set<Path> dependenciesToAnalyze )
-        throws MojoFailureException
-    {
-        if ( dotOutput != null )
-        {
-            cmd.createArg().setValue( "-dotoutput" );
-            cmd.createArg().setFile( dotOutput );
-        }
-        
-//        if ( summaryOnly )
-//        {
-//            cmd.createArg().setValue( "-s" );
-//        }
-        
-        if ( verbose != null )
-        {
-            if ( "class".equals( verbose ) )
-            {
-                cmd.createArg().setValue( "-verbose:class" );
-            }
-            else if ( "package".equals( verbose ) )
-            {
-                cmd.createArg().setValue( "-verbose:package" );
-            }
-            else
-            {
-                cmd.createArg().setValue( "-v" );
-            }
-        }
-        
-        try
-        {
-            Collection<Path> cp = new ArrayList<>();
-            
-            for ( Path path : getClassPath() )
-            {
-                if ( !dependenciesToAnalyze.contains( path ) )
-                {
-                    cp.add( path );
-                }
-            }
-            
-            if ( !cp.isEmpty() )
-            {
-                cmd.createArg().setValue( "-cp" );
-
-                cmd.createArg().setValue( StringUtils.join( cp.iterator(), File.pathSeparator ) );
-            }
-            
-        }
-        catch ( DependencyResolutionRequiredException e )
-        {
-            throw new MojoFailureException( e.getMessage(), e );
-        }
-        
-        if ( packages != null )
-        {
-            for ( String pkgName : packages )
-            {
-                cmd.createArg().setValue( "-p" );
-                cmd.createArg().setValue( pkgName );
-            }
-        }
-        
-//        if ( packageNames != null )
-//        {
-//            for ( String pkgName : packageNames.split( "[,:;]" ) )
-//            {
-//                cmd.createArg().setValue( "-p" );
-//                cmd.createArg().setValue( pkgName );
-//            }
-//        }
-//        
-//        if ( regex != null )
-//        {
-//            cmd.createArg().setValue( "-e" );
-//            cmd.createArg().setValue( regex );
-//        }
-
-        if ( include != null )
-        {
-            cmd.createArg().setValue( "-include" );
-            cmd.createArg().setValue( include );
-        }
-
-        if ( profile )
-        {
-            cmd.createArg().setValue( "-P" );
-        }
-        
-        if ( module != null )
-        {
-            cmd.createArg().setValue( "-m" );
-            cmd.createArg().setValue( module );
-        }
-
-        if ( multiRelease != null )
-        {
-            cmd.createArg().setValue( "--multi-release" );
-            cmd.createArg().setValue( multiRelease );
-        }
-
-        if ( apiOnly )
-        {
-            cmd.createArg().setValue( "-apionly" );
-        }
-        
-        if ( recursive )
-        {
-            cmd.createArg().setValue( "-R" );
-        }
-        
-        // cmd.createArg().setValue( "-version" );
-    }
-    
-    protected Set<Path> getDependenciesToAnalyze( boolean includeClasspath )
-            throws DependencyResolutionRequiredException
-    {
-        Set<Path> jdepsClasses = new LinkedHashSet<>();
-        
-        jdepsClasses.add( Paths.get( getClassesDirectory() ) );
-
-        if ( includeClasspath )
-        {
-            jdepsClasses.addAll( getClassPath() );
-        }
-
-        if ( dependenciesToAnalyzeIncludes != null )
-        {
-            MatchPatterns includes = MatchPatterns.from( dependenciesToAnalyzeIncludes );
-            
-            MatchPatterns excludes;
-            if ( dependenciesToAnalyzeExcludes != null )
-            {
-                excludes = MatchPatterns.from( dependenciesToAnalyzeExcludes );
-            }
-            else
-            {
-                excludes = MatchPatterns.from( Collections.<String>emptyList() );
-            }
-
-            for ( Artifact artifact : project.getArtifacts() )
-            {
-                String versionlessKey = ArtifactUtils.versionlessKey( artifact );
-
-                if ( includes.matchesPatternStart( versionlessKey, true ) 
-                    && !excludes.matchesPatternStart( versionlessKey, true ) )
-                {
-                    jdepsClasses.add( artifact.getFile().toPath() );
-                }
-            }
-        }
-        
-        return jdepsClasses;
-    }
-    
-    protected void addJDepsClasses( Commandline cmd, Set<Path> dependenciesToAnalyze )
-    {
-        // <classes> can be a pathname to a .class file, a directory, a JAR file, or a fully-qualified class name.
-        for ( Path dependencyToAnalyze : dependenciesToAnalyze )
-        {
-            cmd.createArg().setFile( dependencyToAnalyze.toFile() );
-        }
-    }
-
-    private String getJDepsExecutable() throws IOException
-    {
-        Toolchain tc = getToolchain();
-
-        String jdepsExecutable = null;
-        if ( tc != null )
-        {
-            jdepsExecutable = tc.findTool( "jdeps" );
-        }
-
-        String jdepsCommand = "jdeps" + ( SystemUtils.IS_OS_WINDOWS ? ".exe" : "" );
-
-        File jdepsExe;
-
-        if ( StringUtils.isNotEmpty( jdepsExecutable ) )
-        {
-            jdepsExe = new File( jdepsExecutable );
-
-            if ( jdepsExe.isDirectory() )
-            {
-                jdepsExe = new File( jdepsExe, jdepsCommand );
-            }
-
-            if ( SystemUtils.IS_OS_WINDOWS && jdepsExe.getName().indexOf( '.' ) < 0 )
-            {
-                jdepsExe = new File( jdepsExe.getPath() + ".exe" );
-            }
-
-            if ( !jdepsExe.isFile() )
-            {
-                throw new IOException( "The jdeps executable '" + jdepsExe
-                    + "' doesn't exist or is not a file." );
-            }
-            return jdepsExe.getAbsolutePath();
-        }
-
-        jdepsExe = new File( SystemUtils.getJavaHome() + File.separator + ".." + File.separator + "sh", jdepsCommand );
-
-        // ----------------------------------------------------------------------
-        // Try to find jdepsExe from JAVA_HOME environment variable
-        // ----------------------------------------------------------------------
-        if ( !jdepsExe.exists() || !jdepsExe.isFile() )
-        {
-            Properties env = CommandLineUtils.getSystemEnvVars();
-            String javaHome = env.getProperty( "JAVA_HOME" );
-            if ( StringUtils.isEmpty( javaHome ) )
-            {
-                throw new IOException( "The environment variable JAVA_HOME is not correctly set." );
-            }
-            if ( ( !new File( javaHome ).getCanonicalFile().exists() )
-                || ( new File( javaHome ).getCanonicalFile().isFile() ) )
-            {
-                throw new IOException( "The environment variable JAVA_HOME=" + javaHome
-                    + " doesn't exist or is not a valid directory." );
-            }
-
-            jdepsExe = new File( javaHome + File.separator + "bin", jdepsCommand );
-        }
-
-        if ( !jdepsExe.getCanonicalFile().exists() || !jdepsExe.getCanonicalFile().isFile() )
-        {
-            throw new IOException( "The jdeps executable '" + jdepsExe
-                + "' doesn't exist or is not a file. Verify the JAVA_HOME environment variable." );
-        }
-
-        return jdepsExe.getAbsolutePath();
-    }
-    
-    private void executeJDepsCommandLine( Commandline cmd, File jOutputDirectory,
-                                            CommandLineUtils.StringStreamConsumer consumer )
-        throws MojoExecutionException
-    {
-        if ( getLog().isDebugEnabled() )
-        {
-            // no quoted arguments
-            getLog().debug( "Executing: " + CommandLineUtils.toString( cmd.getCommandline() ).replaceAll( "'", "" ) );
-        }
-
-        
-        CommandLineUtils.StringStreamConsumer err = new CommandLineUtils.StringStreamConsumer()
-        {
-            @Override
-            public void consumeLine( String line )
-            {
-                if ( !line.startsWith( "Picked up JAVA_TOOL_OPTIONS:" ) )
-                {
-                    super.consumeLine( line );
-                }
-            }
-        };
-        CommandLineUtils.StringStreamConsumer out;
-        if ( consumer != null )
-        {
-            out = consumer;
-        }
-        else
-        {
-            out = new CommandLineUtils.StringStreamConsumer();
-        }
-                        
-        try
-        {
-            int exitCode = CommandLineUtils.executeCommandLine( cmd, out, err );
-
-            String output = ( StringUtils.isEmpty( out.getOutput() ) ? null : '\n' + out.getOutput().trim() );
-
-            if ( exitCode != 0 )
-            {
-                if ( StringUtils.isNotEmpty( output ) )
-                {
-                    getLog().info( output );
-                }
-
-                StringBuilder msg = new StringBuilder( "\nExit code: " );
-                msg.append( exitCode );
-                if ( StringUtils.isNotEmpty( err.getOutput() ) )
-                {
-                    msg.append( " - " ).append( err.getOutput() );
-                }
-                msg.append( '\n' );
-                msg.append( "Command line was: " ).append( cmd ).append( '\n' ).append( '\n' );
-
-                throw new MojoExecutionException( msg.toString() );
-            }
-
-            if ( StringUtils.isNotEmpty( output ) )
-            {
-                getLog().info( output );
-            }
-        }
-        catch ( CommandLineException e )
-        {
-            throw new MojoExecutionException( "Unable to execute jdeps command: " + e.getMessage(), e );
-        }
-
-        // ----------------------------------------------------------------------
-        // Handle JDeps warnings
-        // ----------------------------------------------------------------------
-
-        if ( StringUtils.isNotEmpty( err.getOutput() ) && getLog().isWarnEnabled() )
-        {
-            getLog().warn( "JDeps Warnings" );
-
-            StringTokenizer token = new StringTokenizer( err.getOutput(), "\n" );
-            while ( token.hasMoreTokens() )
-            {
-                String current = token.nextToken().trim();
-
-                getLog().warn( current );
-            }
-        }
-    }
-    
-    private Toolchain getToolchain()
-    {
-        Toolchain tc = null;
-        if ( toolchainManager != null )
-        {
-            tc = toolchainManager.getToolchainFromBuildContext( "jdk", session );
-
-            if ( tc == null )
-            {
-                // Maven 3.2.6 has plugin execution scoped Toolchain Support
-                try
-                {
-                    Method getToolchainsMethod =
-                        toolchainManager.getClass().getMethod( "getToolchains", MavenSession.class, String.class,
-                                                               Map.class );
-
-                    @SuppressWarnings( "unchecked" )
-                    List<Toolchain> tcs =
-                        (List<Toolchain>) getToolchainsMethod.invoke( toolchainManager, session, "jdk",
-                                                                      Collections.singletonMap( "version", "[1.8,)" ) );
-
-                    if ( tcs != null && tcs.size() > 0 )
-                    {
-                        // pick up latest, jdeps of JDK9 has more options compared to JDK8
-                        tc = tcs.get( tcs.size() - 1 );
-                    }
-                }
-                catch ( NoSuchMethodException e )
-                {
-                    // ignore
-                }
-                catch ( SecurityException e )
-                {
-                    // ignore
-                }
-                catch ( IllegalAccessException e )
-                {
-                    // ignore
-                }
-                catch ( IllegalArgumentException e )
-                {
-                    // ignore
-                }
-                catch ( InvocationTargetException e )
-                {
-                    // ignore
-                }
-            }
-        }
-
-        return tc;
-    }
-
-    protected boolean isFailOnWarning()
-    {
-        return failOnWarning;
-    }
-    
-    protected abstract String getClassesDirectory();
-    
-    protected abstract Collection<Path> getClassPath() throws DependencyResolutionRequiredException;
-}
+import org.apache.commons.lang3.SystemUtils;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.artifact.DependencyResolutionRequiredException;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.jdeps.consumers.JDepsConsumer;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.toolchain.Toolchain;
+import org.apache.maven.toolchain.ToolchainManager;
+import org.codehaus.plexus.util.MatchPatterns;
+import org.codehaus.plexus.util.cli.CommandLineException;
+import org.codehaus.plexus.util.cli.CommandLineUtils;
+import org.codehaus.plexus.util.cli.Commandline;
+
+/**
+ * Abstract Mojo for JDeps
+ *
+ * @author Robert Scholte
+ *
+ */
+public abstract class AbstractJDepsMojo extends AbstractMojo {
+
+    @Parameter(defaultValue = "${project}", readonly = true, required = true)
+    private MavenProject project;
+
+    @Parameter(defaultValue = "${session}", readonly = true, required = true)
+    private MavenSession session;
+
+    @Parameter(defaultValue = "${project.build.directory}", readonly = true, required = true)
+    private File outputDirectory;
+
+    /**
+     * Indicates whether the build will continue even if there are jdeps warnings.
+     */
+    @Parameter(defaultValue = "true", property = "jdeps.failOnWarning")
+    private boolean failOnWarning;
+
+    /**
+     * Specifies the version when processing multi-release JAR files version should be an integer >=9 or base.
+     *
+     * @since 3.1.1
+     */
+    @Parameter(property = "jdeps.multiRelease")
+    private String multiRelease;
+
+    /**
+     * Whether only the sources need to be compatible or also every dependency on the classpath.
+     *
+     * @since 3.1.3
+     */
+    @Parameter(defaultValue = "true", property = "jdeps.includeClasspath")
+    private boolean includeClasspath;
+
+    /**
+     * Additional dependencies which should be analyzed besides the classes.
+     * Specify as {@code groupId:artifactId}, allowing ant-pattern.
+     *
+     * E.g.
+     * <pre>
+     *   &lt;dependenciesToAnalyzeIncludes&gt;
+     *     &lt;include&gt;*:*&lt;/include&gt;
+     *     &lt;include&gt;org.foo.*:*&lt;/include&gt;
+     *     &lt;include&gt;com.foo.bar:*&lt;/include&gt;
+     *     &lt;include&gt;dot.foo.bar:utilities&lt;/include&gt;
+     *   &lt;/dependenciesToAnalyzeIncludes&gt;
+     * </pre>
+     */
+    @Parameter
+    private List<String> dependenciesToAnalyzeIncludes;
+
+    /**
+     * Subset of {@link AbstractJDepsMojo#dependenciesToAnalyzeIncludes} which should be not analyzed.
+     * Specify as {@code groupId:artifactId}, allowing ant-pattern.
+     *
+     * E.g.
+     * <pre>
+     *   &lt;dependenciesToAnalyzeExcludes&gt;
+     *     &lt;exclude&gt;org.foo.*:*&lt;/exclude&gt;
+     *     &lt;exclude&gt;com.foo.bar:*&lt;/exclude&gt;
+     *     &lt;exclude&gt;dot.foo.bar:utilities&lt;/exclude&gt;
+     *   &lt;/dependenciesToAnalyzeExcludes&gt;
+     * </pre>
+     */
+    @Parameter
+    private List<String> dependenciesToAnalyzeExcludes;
+
+    /**
+     * Destination directory for DOT file output
+     */
+    @Parameter(property = "jdeps.dotOutput")
+    private File dotOutput;
+
+    //    @Parameter( defaultValue = "false", property = "jdeps.summaryOnly" )
+    //    private boolean summaryOnly;
+
+    /**
+     * <dl>
+     *   <dt>package</dt><dd>Print package-level dependencies excluding dependencies within the same archive<dd/>
+     *   <dt>class</dt><dd>Print class-level dependencies excluding dependencies within the same archive<dd/>
+     *   <dt>&lt;empty&gt;</dt><dd>Print all class level dependencies. Equivalent to -verbose:class -filter:none.<dd/>
+     * </dl>
+     */
+    @Parameter(property = "jdeps.verbose")
+    private String verbose;
+
+    /**
+     * Finds dependences matching the specified package name.
+     *
+     * @since 3.1.1.
+     */
+    @Parameter
+    private List<String> packages;
+
+    //    /**
+    //     * A comma-separated list to find dependences in the given package (may be given multiple times)
+    //     */
+    //    @Parameter( property = "jdeps.pkgnames" )
+    //    private String packageNames;
+    //
+    //    /**
+    //     * Finds dependences in packages matching pattern (-p and -e are exclusive)
+    //     */
+    //    @Parameter( property = "jdeps.regex" )
+    //    private String regex;
+
+    /**
+     * Restrict analysis to classes matching pattern. This option filters the list of classes to be analyzed. It can be
+     * used together with <code>-p</code> and <code>-e</code> which apply pattern to the dependences
+     */
+    @Parameter(property = "jdeps.include")
+    private String include;
+
+    /**
+     * Restrict analysis to APIs i.e. dependences from the signature of public and protected members of public classes
+     * including field type, method parameter types, returned type, checked exception types etc
+     */
+    @Parameter(defaultValue = "false", property = "jdeps.apionly")
+    private boolean apiOnly;
+
+    /**
+     * Show profile or the file containing a package
+     */
+    @Parameter(defaultValue = "false", property = "jdeps.profile")
+    private boolean profile;
+
+    /**
+     * Recursively traverse all dependencies. The {@code -R} option implies {@code -filter:none}.  If {@code -p},
+     * {@code -e}, {@code -f} option is specified, only the matching dependences are analyzed.
+     */
+    @Parameter(defaultValue = "false", property = "jdeps.recursive")
+    private boolean recursive;
+
+    /**
+     * Specifies the root module for analysis.
+     *
+     * @since JDK 1.9.0
+     */
+    @Parameter(property = "jdeps.module")
+    private String module;
+
+    @Component
+    private ToolchainManager toolchainManager;
+
+    protected MavenProject getProject() {
+        return project;
+    }
+
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        if (!new File(getClassesDirectory()).exists()) {
+            getLog().debug("No classes to analyze");
+            return;
+        }
+
+        String jExecutable;
+        try {
+            jExecutable = getJDepsExecutable();
+        } catch (IOException e) {
+            throw new MojoFailureException("Unable to find jdeps command: " + e.getMessage(), e);
+        }
+
+        //      Synopsis
+        //      jdeps [options] classes ...
+        Commandline cmd = new Commandline();
+        cmd.setExecutable(jExecutable);
+
+        Set<Path> dependenciesToAnalyze = null;
+        try {
+            dependenciesToAnalyze = getDependenciesToAnalyze(includeClasspath);
+        } catch (DependencyResolutionRequiredException e) {
+            throw new MojoExecutionException(e.getMessage(), e);
+        }
+        addJDepsOptions(cmd, dependenciesToAnalyze);
+        addJDepsClasses(cmd, dependenciesToAnalyze);
+
+        JDepsConsumer consumer = new JDepsConsumer();
+        executeJDepsCommandLine(cmd, outputDirectory, consumer);
+
+        // @ TODO if there will be more goals, this should be pushed down to AbstractJDKInternals
+        if (!consumer.getOffendingPackages().isEmpty()) {
+            final String ls = System.lineSeparator();
+
+            StringBuilder msg = new StringBuilder();
+            msg.append("Found offending packages:").append(ls);
+            for (Map.Entry<String, String> offendingPackage :
+                    consumer.getOffendingPackages().entrySet()) {
+                msg.append(' ')
+                        .append(offendingPackage.getKey())
+                        .append(" -> ")
+                        .append(offendingPackage.getValue())
+                        .append(ls);
+            }
+
+            if (isFailOnWarning()) {
+                throw new MojoExecutionException(msg.toString());
+            }
+        }
+    }
+
+    protected void addJDepsOptions(Commandline cmd, Set<Path> dependenciesToAnalyze) throws MojoFailureException {
+        if (dotOutput != null) {
+            cmd.createArg().setValue("-dotoutput");
+            cmd.createArg().setFile(dotOutput);
+        }
+
+        //        if ( summaryOnly )
+        //        {
+        //            cmd.createArg().setValue( "-s" );
+        //        }
+
+        if (verbose != null) {
+            if ("class".equals(verbose)) {
+                cmd.createArg().setValue("-verbose:class");
+            } else if ("package".equals(verbose)) {
+                cmd.createArg().setValue("-verbose:package");
+            } else {
+                cmd.createArg().setValue("-v");
+            }
+        }
+
+        try {
+            Collection<Path> cp = new ArrayList<>();
+
+            for (Path path : getClassPath()) {
+                if (!dependenciesToAnalyze.contains(path)) {
+                    cp.add(path);
+                }
+            }
+
+            if (!cp.isEmpty()) {
+                cmd.createArg().setValue("-cp");
+
+                cmd.createArg().setValue(StringUtils.join(cp.iterator(), File.pathSeparator));
+            }
+
+        } catch (DependencyResolutionRequiredException e) {
+            throw new MojoFailureException(e.getMessage(), e);
+        }
+
+        if (packages != null) {
+            for (String pkgName : packages) {
+                cmd.createArg().setValue("-p");
+                cmd.createArg().setValue(pkgName);
+            }
+        }
+
+        //        if ( packageNames != null )
+        //        {
+        //            for ( String pkgName : packageNames.split( "[,:;]" ) )
+        //            {
+        //                cmd.createArg().setValue( "-p" );
+        //                cmd.createArg().setValue( pkgName );
+        //            }
+        //        }
+        //
+        //        if ( regex != null )
+        //        {
+        //            cmd.createArg().setValue( "-e" );
+        //            cmd.createArg().setValue( regex );
+        //        }
+
+        if (include != null) {
+            cmd.createArg().setValue("-include");
+            cmd.createArg().setValue(include);
+        }
+
+        if (profile) {
+            cmd.createArg().setValue("-P");
+        }
+
+        if (module != null) {
+            cmd.createArg().setValue("-m");
+            cmd.createArg().setValue(module);
+        }
+
+        if (multiRelease != null) {
+            cmd.createArg().setValue("--multi-release");
+            cmd.createArg().setValue(multiRelease);
+        }
+
+        if (apiOnly) {
+            cmd.createArg().setValue("-apionly");
+        }
+
+        if (recursive) {
+            cmd.createArg().setValue("-R");
+        }
+
+        // cmd.createArg().setValue( "-version" );
+    }
+
+    protected Set<Path> getDependenciesToAnalyze(boolean includeClasspath)
+            throws DependencyResolutionRequiredException {
+        Set<Path> jdepsClasses = new LinkedHashSet<>();
+
+        jdepsClasses.add(Paths.get(getClassesDirectory()));
+
+        if (includeClasspath) {
+            jdepsClasses.addAll(getClassPath());
+        }
+
+        if (dependenciesToAnalyzeIncludes != null) {
+            MatchPatterns includes = MatchPatterns.from(dependenciesToAnalyzeIncludes);
+
+            MatchPatterns excludes;
+            if (dependenciesToAnalyzeExcludes != null) {
+                excludes = MatchPatterns.from(dependenciesToAnalyzeExcludes);
+            } else {
+                excludes = MatchPatterns.from(Collections.<String>emptyList());
+            }
+
+            for (Artifact artifact : project.getArtifacts()) {
+                String versionlessKey = ArtifactUtils.versionlessKey(artifact);
+
+                if (includes.matchesPatternStart(versionlessKey, true)
+                        && !excludes.matchesPatternStart(versionlessKey, true)) {
+                    jdepsClasses.add(artifact.getFile().toPath());
+                }
+            }
+        }
+
+        return jdepsClasses;
+    }
+
+    protected void addJDepsClasses(Commandline cmd, Set<Path> dependenciesToAnalyze) {
+        // <classes> can be a pathname to a .class file, a directory, a JAR file, or a fully-qualified class name.
+        for (Path dependencyToAnalyze : dependenciesToAnalyze) {
+            cmd.createArg().setFile(dependencyToAnalyze.toFile());
+        }
+    }
+
+    private String getJDepsExecutable() throws IOException {
+        Toolchain tc = getToolchain();
+
+        String jdepsExecutable = null;
+        if (tc != null) {
+            jdepsExecutable = tc.findTool("jdeps");
+        }
+
+        String jdepsCommand = "jdeps" + (SystemUtils.IS_OS_WINDOWS ? ".exe" : "");
+
+        File jdepsExe;
+
+        if (StringUtils.isNotEmpty(jdepsExecutable)) {
+            jdepsExe = new File(jdepsExecutable);
+
+            if (jdepsExe.isDirectory()) {
+                jdepsExe = new File(jdepsExe, jdepsCommand);
+            }
+
+            if (SystemUtils.IS_OS_WINDOWS && jdepsExe.getName().indexOf('.') < 0) {
+                jdepsExe = new File(jdepsExe.getPath() + ".exe");
+            }
+
+            if (!jdepsExe.isFile()) {
+                throw new IOException("The jdeps executable '" + jdepsExe + "' doesn't exist or is not a file.");
+            }
+            return jdepsExe.getAbsolutePath();
+        }
+
+        jdepsExe = new File(SystemUtils.getJavaHome() + File.separator + ".." + File.separator + "sh", jdepsCommand);
+
+        // ----------------------------------------------------------------------
+        // Try to find jdepsExe from JAVA_HOME environment variable
+        // ----------------------------------------------------------------------
+        if (!jdepsExe.exists() || !jdepsExe.isFile()) {
+            Properties env = CommandLineUtils.getSystemEnvVars();
+            String javaHome = env.getProperty("JAVA_HOME");
+            if (StringUtils.isEmpty(javaHome)) {
+                throw new IOException("The environment variable JAVA_HOME is not correctly set.");
+            }
+            if ((!new File(javaHome).getCanonicalFile().exists())
+                    || (new File(javaHome).getCanonicalFile().isFile())) {
+                throw new IOException("The environment variable JAVA_HOME=" + javaHome
+                        + " doesn't exist or is not a valid directory.");
+            }
+
+            jdepsExe = new File(javaHome + File.separator + "bin", jdepsCommand);
+        }
+
+        if (!jdepsExe.getCanonicalFile().exists()
+                || !jdepsExe.getCanonicalFile().isFile()) {
+            throw new IOException("The jdeps executable '" + jdepsExe
+                    + "' doesn't exist or is not a file. Verify the JAVA_HOME environment variable.");
+        }
+
+        return jdepsExe.getAbsolutePath();
+    }
+
+    private void executeJDepsCommandLine(
+            Commandline cmd, File jOutputDirectory, CommandLineUtils.StringStreamConsumer consumer)
+            throws MojoExecutionException {
+        if (getLog().isDebugEnabled()) {
+            // no quoted arguments
+            getLog().debug("Executing: "
+                    + CommandLineUtils.toString(cmd.getCommandline()).replaceAll("'", ""));
+        }
+
+        CommandLineUtils.StringStreamConsumer err = new CommandLineUtils.StringStreamConsumer() {
+            @Override
+            public void consumeLine(String line) {
+                if (!line.startsWith("Picked up JAVA_TOOL_OPTIONS:")) {
+                    super.consumeLine(line);
+                }
+            }
+        };
+        CommandLineUtils.StringStreamConsumer out;
+        if (consumer != null) {
+            out = consumer;
+        } else {
+            out = new CommandLineUtils.StringStreamConsumer();
+        }
+
+        try {
+            int exitCode = CommandLineUtils.executeCommandLine(cmd, out, err);
+
+            String output = (StringUtils.isEmpty(out.getOutput())
+                    ? null
+                    : '\n' + out.getOutput().trim());
+
+            if (exitCode != 0) {
+                if (StringUtils.isNotEmpty(output)) {
+                    getLog().info(output);
+                }
+
+                StringBuilder msg = new StringBuilder("\nExit code: ");
+                msg.append(exitCode);
+                if (StringUtils.isNotEmpty(err.getOutput())) {
+                    msg.append(" - ").append(err.getOutput());
+                }
+                msg.append('\n');
+                msg.append("Command line was: ").append(cmd).append('\n').append('\n');
+
+                throw new MojoExecutionException(msg.toString());
+            }
+
+            if (StringUtils.isNotEmpty(output)) {
+                getLog().info(output);
+            }
+        } catch (CommandLineException e) {
+            throw new MojoExecutionException("Unable to execute jdeps command: " + e.getMessage(), e);
+        }
+
+        // ----------------------------------------------------------------------
+        // Handle JDeps warnings
+        // ----------------------------------------------------------------------
+
+        if (StringUtils.isNotEmpty(err.getOutput()) && getLog().isWarnEnabled()) {
+            getLog().warn("JDeps Warnings");
+
+            StringTokenizer token = new StringTokenizer(err.getOutput(), "\n");
+            while (token.hasMoreTokens()) {
+                String current = token.nextToken().trim();
+
+                getLog().warn(current);
+            }
+        }
+    }
+
+    private Toolchain getToolchain() {
+        Toolchain tc = null;
+        if (toolchainManager != null) {
+            tc = toolchainManager.getToolchainFromBuildContext("jdk", session);
+
+            if (tc == null) {
+                // Maven 3.2.6 has plugin execution scoped Toolchain Support
+                try {
+                    Method getToolchainsMethod = toolchainManager
+                            .getClass()
+                            .getMethod("getToolchains", MavenSession.class, String.class, Map.class);
+
+                    @SuppressWarnings("unchecked")
+                    List<Toolchain> tcs = (List<Toolchain>) getToolchainsMethod.invoke(
+                            toolchainManager, session, "jdk", Collections.singletonMap("version", "[1.8,)"));
+
+                    if (tcs != null && !tcs.isEmpty()) {
+                        // pick up latest, jdeps of JDK9 has more options compared to JDK8
+                        tc = tcs.get(tcs.size() - 1);
+                    }
+                } catch (NoSuchMethodException
+                        | SecurityException
+                        | IllegalAccessException
+                        | IllegalArgumentException
+                        | InvocationTargetException e) {
+                    // ignore
+                }
+            }
+        }
+
+        return tc;
+    }
+
+    protected boolean isFailOnWarning() {
+        return failOnWarning;
+    }
+
+    protected abstract String getClassesDirectory();
+
+    protected abstract Collection<Path> getClassPath() throws DependencyResolutionRequiredException;
+}
diff --git a/src/main/java/org/apache/maven/plugins/jdeps/JDKInternalsMojo.java b/src/main/java/org/apache/maven/plugins/jdeps/JDKInternalsMojo.java
index 1cd2d72..f2acd55 100644
--- a/src/main/java/org/apache/maven/plugins/jdeps/JDKInternalsMojo.java
+++ b/src/main/java/org/apache/maven/plugins/jdeps/JDKInternalsMojo.java
@@ -1,65 +1,61 @@
-package org.apache.maven.plugins.jdeps;
-
-/*
- * 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 java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Collection;
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-import org.apache.maven.artifact.DependencyResolutionRequiredException;
-import org.apache.maven.plugins.annotations.LifecyclePhase;
-import org.apache.maven.plugins.annotations.Mojo;
-import org.apache.maven.plugins.annotations.ResolutionScope;
-
-/**
- * Check if main classes depend on internal JDK classes
- * 
- * @author Robert Scholte
- *
- */
-@Mojo( name = "jdkinternals", 
-       requiresDependencyResolution = ResolutionScope.COMPILE,
-       defaultPhase = LifecyclePhase.PROCESS_CLASSES, threadSafe = true )
-public class JDKInternalsMojo
-    extends AbstractJDepsMojo
-{
-
-    @Override
-    protected String getClassesDirectory()
-    {
-        return getProject().getBuild().getOutputDirectory();
-    }
-    
-    @Override
-    protected Collection<Path> getClassPath()
-        throws DependencyResolutionRequiredException
-    {
-        Set<Path> classPath = new LinkedHashSet<>( getProject().getCompileClasspathElements().size() );
-
-        for ( String elm : getProject().getCompileClasspathElements() )
-        {
-            classPath.add( Paths.get( elm ) );
-        }
-
-        return classPath;
-    }
-}
+/*
+ * 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.
+ */
+package org.apache.maven.plugins.jdeps;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.maven.artifact.DependencyResolutionRequiredException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+
+/**
+ * Check if main classes depend on internal JDK classes
+ *
+ * @author Robert Scholte
+ *
+ */
+@Mojo(
+        name = "jdkinternals",
+        requiresDependencyResolution = ResolutionScope.COMPILE,
+        defaultPhase = LifecyclePhase.PROCESS_CLASSES,
+        threadSafe = true)
+public class JDKInternalsMojo extends AbstractJDepsMojo {
+
+    @Override
+    protected String getClassesDirectory() {
+        return getProject().getBuild().getOutputDirectory();
+    }
+
+    @Override
+    protected Collection<Path> getClassPath() throws DependencyResolutionRequiredException {
+        Set<Path> classPath =
+                new LinkedHashSet<>(getProject().getCompileClasspathElements().size());
+
+        for (String elm : getProject().getCompileClasspathElements()) {
+            classPath.add(Paths.get(elm));
+        }
+
+        return classPath;
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/jdeps/TestJDKInternalsMojo.java b/src/main/java/org/apache/maven/plugins/jdeps/TestJDKInternalsMojo.java
index 966a7f2..47e626f 100644
--- a/src/main/java/org/apache/maven/plugins/jdeps/TestJDKInternalsMojo.java
+++ b/src/main/java/org/apache/maven/plugins/jdeps/TestJDKInternalsMojo.java
@@ -1,77 +1,72 @@
-package org.apache.maven.plugins.jdeps;
-
-/*
- * 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 java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Collection;
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-import org.apache.maven.artifact.DependencyResolutionRequiredException;
-import org.apache.maven.plugins.annotations.LifecyclePhase;
-import org.apache.maven.plugins.annotations.Mojo;
-import org.apache.maven.plugins.annotations.Parameter;
-import org.apache.maven.plugins.annotations.ResolutionScope;
-
-/**
- * Check if test classes depend on internal JDK classes
- * 
- * @author Robert Scholte
- *
- */
-@Mojo( name = "test-jdkinternals", 
-       requiresDependencyResolution = ResolutionScope.TEST,
-       defaultPhase = LifecyclePhase.PROCESS_TEST_CLASSES, threadSafe = true )
-public class TestJDKInternalsMojo
-    extends AbstractJDepsMojo
-{
-    /**
-     * Indicates whether the build will continue even if there are jdeps warnings.
-     */
-    @Parameter( defaultValue = "true", property = "jdeps.test.failOnWarning" )
-    private boolean failOnWarning;
-    
-    @Override
-    protected boolean isFailOnWarning()
-    {
-        return failOnWarning;
-    }
-    
-    @Override
-    protected String getClassesDirectory()
-    {
-        return getProject().getBuild().getTestOutputDirectory();
-    }
-    
-    @Override
-    protected Collection<Path> getClassPath()
-        throws DependencyResolutionRequiredException
-    {
-        Set<Path> classPath = new LinkedHashSet<>( getProject().getTestClasspathElements().size() );
-
-        for ( String elm : getProject().getTestClasspathElements() )
-        {
-            classPath.add( Paths.get( elm ) );
-        }
-
-        return classPath;
-    }
-}
+/*
+ * 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.
+ */
+package org.apache.maven.plugins.jdeps;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.maven.artifact.DependencyResolutionRequiredException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+
+/**
+ * Check if test classes depend on internal JDK classes
+ *
+ * @author Robert Scholte
+ *
+ */
+@Mojo(
+        name = "test-jdkinternals",
+        requiresDependencyResolution = ResolutionScope.TEST,
+        defaultPhase = LifecyclePhase.PROCESS_TEST_CLASSES,
+        threadSafe = true)
+public class TestJDKInternalsMojo extends AbstractJDepsMojo {
+    /**
+     * Indicates whether the build will continue even if there are jdeps warnings.
+     */
+    @Parameter(defaultValue = "true", property = "jdeps.test.failOnWarning")
+    private boolean failOnWarning;
+
+    @Override
+    protected boolean isFailOnWarning() {
+        return failOnWarning;
+    }
+
+    @Override
+    protected String getClassesDirectory() {
+        return getProject().getBuild().getTestOutputDirectory();
+    }
+
+    @Override
+    protected Collection<Path> getClassPath() throws DependencyResolutionRequiredException {
+        Set<Path> classPath =
+                new LinkedHashSet<>(getProject().getTestClasspathElements().size());
+
+        for (String elm : getProject().getTestClasspathElements()) {
+            classPath.add(Paths.get(elm));
+        }
+
+        return classPath;
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/jdeps/consumers/JDepsConsumer.java b/src/main/java/org/apache/maven/plugins/jdeps/consumers/JDepsConsumer.java
index a251785..d25a390 100644
--- a/src/main/java/org/apache/maven/plugins/jdeps/consumers/JDepsConsumer.java
+++ b/src/main/java/org/apache/maven/plugins/jdeps/consumers/JDepsConsumer.java
@@ -1,98 +1,87 @@
-package org.apache.maven.plugins.jdeps.consumers;
-
-/*
- * 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 java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.codehaus.plexus.util.cli.CommandLineUtils;
-import org.codehaus.plexus.util.cli.StreamConsumer;
-
-/**
- * Consumes the output of the jdeps tool
- *  
- * @author Robert Scholte
- *
- */
-public class JDepsConsumer
-    extends CommandLineUtils.StringStreamConsumer
-    implements StreamConsumer
-{
-
-    /**
-     * JDK8 Windows: JDK internal API (rt.jar)
-     * JDK8 Linux:   JDK internal API (JDK removed internal API)
-     * JDK9:         JDK internal API (java.base)
-     */
-    private static final Pattern JDKINTERNALAPI =
-        Pattern.compile( ".+->\\s([a-z\\.]+)\\s+(JDK (?:removed )?internal API.*)" );
-
-    /**
-     * <dl>
-     *  <dt>key</dt><dd>The offending package</dd>
-     *  <dt>value</dt><dd>Offending details</dd>
-     * </dl>
-     */
-    private Map<String, String> offendingPackages = new HashMap<String, String>();
-
-    private static final Pattern PROFILE = Pattern.compile( "\\s+->\\s([a-z\\.]+)\\s+(\\S+)" );
-
-    /**
-     * <dl>
-     *  <dt>key</dt><dd>The package</dd>
-     *  <dt>value</dt><dd>The profile</dd>
-     * </dl>
-     */
-    private Map<String, String> profiles = new HashMap<String, String>();
-
-    
-    public void consumeLine( String line )
-    {
-        super.consumeLine( line );
-        Matcher matcher;
-        
-        matcher = JDKINTERNALAPI.matcher( line );
-        if ( matcher.matches() )
-        {
-            offendingPackages.put( matcher.group( 1 ), matcher.group( 2 ) );
-            return;
-        }
-        
-        matcher = PROFILE.matcher( line );
-        if ( matcher.matches() )
-        {
-            profiles.put( matcher.group( 1 ), matcher.group( 2 ) );
-            return;
-        }
-    }
-
-    public Map<String, String> getOffendingPackages()
-    {
-        return offendingPackages;
-    }
-    
-    public Map<String, String> getProfiles()
-    {
-        return profiles;
-    }
-
-}
+/*
+ * 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.
+ */
+package org.apache.maven.plugins.jdeps.consumers;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.codehaus.plexus.util.cli.CommandLineUtils;
+import org.codehaus.plexus.util.cli.StreamConsumer;
+
+/**
+ * Consumes the output of the jdeps tool
+ *
+ * @author Robert Scholte
+ *
+ */
+public class JDepsConsumer extends CommandLineUtils.StringStreamConsumer implements StreamConsumer {
+
+    /**
+     * JDK8 Windows: JDK internal API (rt.jar)
+     * JDK8 Linux:   JDK internal API (JDK removed internal API)
+     * JDK9:         JDK internal API (java.base)
+     */
+    private static final Pattern JDKINTERNALAPI =
+            Pattern.compile(".+->\\s([a-z\\.]+)\\s+(JDK (?:removed )?internal API.*)");
+
+    /**
+     * <dl>
+     *  <dt>key</dt><dd>The offending package</dd>
+     *  <dt>value</dt><dd>Offending details</dd>
+     * </dl>
+     */
+    private Map<String, String> offendingPackages = new HashMap<String, String>();
+
+    private static final Pattern PROFILE = Pattern.compile("\\s+->\\s([a-z\\.]+)\\s+(\\S+)");
+
+    /**
+     * <dl>
+     *  <dt>key</dt><dd>The package</dd>
+     *  <dt>value</dt><dd>The profile</dd>
+     * </dl>
+     */
+    private Map<String, String> profiles = new HashMap<String, String>();
+
+    public void consumeLine(String line) {
+        super.consumeLine(line);
+        Matcher matcher;
+
+        matcher = JDKINTERNALAPI.matcher(line);
+        if (matcher.matches()) {
+            offendingPackages.put(matcher.group(1), matcher.group(2));
+            return;
+        }
+
+        matcher = PROFILE.matcher(line);
+        if (matcher.matches()) {
+            profiles.put(matcher.group(1), matcher.group(2));
+            return;
+        }
+    }
+
+    public Map<String, String> getOffendingPackages() {
+        return offendingPackages;
+    }
+
+    public Map<String, String> getProfiles() {
+        return profiles;
+    }
+}
diff --git a/src/test/java/org/apache/maven/plugins/jdeps/consumers/JDepsConsumerTest.java b/src/test/java/org/apache/maven/plugins/jdeps/consumers/JDepsConsumerTest.java
index ed60478..5c20cb1 100644
--- a/src/test/java/org/apache/maven/plugins/jdeps/consumers/JDepsConsumerTest.java
+++ b/src/test/java/org/apache/maven/plugins/jdeps/consumers/JDepsConsumerTest.java
@@ -1,94 +1,99 @@
-package org.apache.maven.plugins.jdeps.consumers;
-
-/*
- * 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 static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-public class JDepsConsumerTest
-{
-
-    private JDepsConsumer consumer;
-    
-    @Test
-    public void testJDKInterAPI()
-    {
-        
-        consumer = new JDepsConsumer();
-        consumer.consumeLine( "test-classes -> java.base" );
-        consumer.consumeLine( "   <unnamed> (test-classes)" );
-        consumer.consumeLine( "      -> java.io                                            " );
-        consumer.consumeLine( "      -> java.lang                                          " );
-        consumer.consumeLine( "      -> sun.misc                                           JDK internal API (java.base)" );
-        
-        assertEquals( 1, consumer.getOffendingPackages().size() );
-        assertEquals( "JDK internal API (java.base)", consumer.getOffendingPackages().get( "sun.misc" ) );
-        assertEquals( 0, consumer.getProfiles().size() );
-    }
-    
-    @Test
-    public void testJDKInternalAPI_Linux_Java8()
-    {
-        consumer = new JDepsConsumer();
-        consumer.consumeLine( "classes -> JDK removed internal API" );
-        consumer.consumeLine( "classes -> java.base" );
-        consumer.consumeLine( "   <unnamed>                                          -> java.io                                            java.base" );
-        consumer.consumeLine( "   <unnamed>                                          -> java.lang                                          java.base" );
-        consumer.consumeLine( "   <unnamed>                                          -> sun.misc                                           JDK internal API (JDK removed internal API)" );
-        
-        assertEquals( 1, consumer.getOffendingPackages().size() );
-        assertEquals( "JDK internal API (JDK removed internal API)", consumer.getOffendingPackages().get( "sun.misc" ) );
-        assertEquals( 0, consumer.getProfiles().size() );
-    }
-
-    @Test
-    public void testJDKInternalAPI_Java8_291()
-    {
-        consumer = new JDepsConsumer();
-        consumer.consumeLine( "classes -> JDK removed internal API" );
-        consumer.consumeLine( "classes -> java.base" );
-        consumer.consumeLine( "   <unnamed>                                          -> java.io                                            java.base" );
-        consumer.consumeLine( "   <unnamed>                                          -> java.lang                                          java.base" );
-        consumer.consumeLine( "   <unnamed>                                          -> sun.misc                                           JDK removed internal API" );
-        
-        assertEquals( 1, consumer.getOffendingPackages().size() );
-        assertEquals( "JDK removed internal API", consumer.getOffendingPackages().get( "sun.misc" ) );
-        assertEquals( 0, consumer.getProfiles().size() );
-    }
-
-    @Test
-    public void testProfile()
-    {
-        consumer = new JDepsConsumer();
-        consumer.consumeLine( "E:\\java-workspace\\apache-maven-plugins\\maven-jdeps-plugin\\target\\classes -> "
-            + "C:\\Program Files\\Java\\jdk1.8.0\\jre\\lib\\rt.jar (compact1)" );
-        consumer.consumeLine( "   <unnamed> (classes)" );
-        consumer.consumeLine( "      -> java.io                                            compact1" );
-        consumer.consumeLine( "      -> java.lang                                          compact1" );
-        consumer.consumeLine( "      -> sun.misc                                           JDK internal API (rt.jar)" );
-        
-        assertEquals( 1, consumer.getOffendingPackages().size() );
-        assertEquals( "JDK internal API (rt.jar)", consumer.getOffendingPackages().get( "sun.misc" ) );
-        assertEquals( 2, consumer.getProfiles().size() );
-        assertEquals( "compact1", consumer.getProfiles().get( "java.io" ) );
-        assertEquals( "compact1", consumer.getProfiles().get( "java.lang" ) );
-    }
-
-}
+/*
+ * 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.
+ */
+package org.apache.maven.plugins.jdeps.consumers;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class JDepsConsumerTest {
+
+    private JDepsConsumer consumer;
+
+    @Test
+    public void testJDKInterAPI() {
+
+        consumer = new JDepsConsumer();
+        consumer.consumeLine("test-classes -> java.base");
+        consumer.consumeLine("   <unnamed> (test-classes)");
+        consumer.consumeLine("      -> java.io                                            ");
+        consumer.consumeLine("      -> java.lang                                          ");
+        consumer.consumeLine(
+                "      -> sun.misc                                           JDK internal API (java.base)");
+
+        assertEquals(1, consumer.getOffendingPackages().size());
+        assertEquals(
+                "JDK internal API (java.base)", consumer.getOffendingPackages().get("sun.misc"));
+        assertEquals(0, consumer.getProfiles().size());
+    }
+
+    @Test
+    public void testJDKInternalAPI_Linux_Java8() {
+        consumer = new JDepsConsumer();
+        consumer.consumeLine("classes -> JDK removed internal API");
+        consumer.consumeLine("classes -> java.base");
+        consumer.consumeLine(
+                "   <unnamed>                                          -> java.io                                            java.base");
+        consumer.consumeLine(
+                "   <unnamed>                                          -> java.lang                                          java.base");
+        consumer.consumeLine(
+                "   <unnamed>                                          -> sun.misc                                           JDK internal API (JDK removed internal API)");
+
+        assertEquals(1, consumer.getOffendingPackages().size());
+        assertEquals(
+                "JDK internal API (JDK removed internal API)",
+                consumer.getOffendingPackages().get("sun.misc"));
+        assertEquals(0, consumer.getProfiles().size());
+    }
+
+    @Test
+    public void testJDKInternalAPI_Java8_291() {
+        consumer = new JDepsConsumer();
+        consumer.consumeLine("classes -> JDK removed internal API");
+        consumer.consumeLine("classes -> java.base");
+        consumer.consumeLine(
+                "   <unnamed>                                          -> java.io                                            java.base");
+        consumer.consumeLine(
+                "   <unnamed>                                          -> java.lang                                          java.base");
+        consumer.consumeLine(
+                "   <unnamed>                                          -> sun.misc                                           JDK removed internal API");
+
+        assertEquals(1, consumer.getOffendingPackages().size());
+        assertEquals("JDK removed internal API", consumer.getOffendingPackages().get("sun.misc"));
+        assertEquals(0, consumer.getProfiles().size());
+    }
+
+    @Test
+    public void testProfile() {
+        consumer = new JDepsConsumer();
+        consumer.consumeLine("E:\\java-workspace\\apache-maven-plugins\\maven-jdeps-plugin\\target\\classes -> "
+                + "C:\\Program Files\\Java\\jdk1.8.0\\jre\\lib\\rt.jar (compact1)");
+        consumer.consumeLine("   <unnamed> (classes)");
+        consumer.consumeLine("      -> java.io                                            compact1");
+        consumer.consumeLine("      -> java.lang                                          compact1");
+        consumer.consumeLine("      -> sun.misc                                           JDK internal API (rt.jar)");
+
+        assertEquals(1, consumer.getOffendingPackages().size());
+        assertEquals(
+                "JDK internal API (rt.jar)", consumer.getOffendingPackages().get("sun.misc"));
+        assertEquals(2, consumer.getProfiles().size());
+        assertEquals("compact1", consumer.getProfiles().get("java.io"));
+        assertEquals("compact1", consumer.getProfiles().get("java.lang"));
+    }
+}
