package org.apache.maven.plugins.javadoc;

/*
 * 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 com.thoughtworks.qdox.JavaProjectBuilder;
import com.thoughtworks.qdox.library.ClassLibraryBuilder;
import com.thoughtworks.qdox.library.OrderedClassLibraryBuilder;
import com.thoughtworks.qdox.model.DocletTag;
import com.thoughtworks.qdox.model.JavaAnnotatedElement;
import com.thoughtworks.qdox.model.JavaAnnotation;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaConstructor;
import com.thoughtworks.qdox.model.JavaExecutable;
import com.thoughtworks.qdox.model.JavaField;
import com.thoughtworks.qdox.model.JavaGenericDeclaration;
import com.thoughtworks.qdox.model.JavaMember;
import com.thoughtworks.qdox.model.JavaMethod;
import com.thoughtworks.qdox.model.JavaParameter;
import com.thoughtworks.qdox.model.JavaType;
import com.thoughtworks.qdox.model.JavaTypeVariable;
import com.thoughtworks.qdox.parser.ParseException;
import com.thoughtworks.qdox.type.TypeResolver;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ClassUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.artifact.repository.ArtifactRepository;
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.project.MavenProject;
import org.apache.maven.settings.Settings;
import org.apache.maven.shared.invoker.MavenInvocationException;
import org.codehaus.plexus.components.interactivity.InputHandler;
import org.codehaus.plexus.languages.java.version.JavaVersion;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.StringUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Abstract class to fix Javadoc documentation and tags in source files.
 * <br>
 * See <a href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#wheretags">Where Tags
 * Can Be Used</a>.
 *
 * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
 * @since 2.6
 */
public abstract class AbstractFixJavadocMojo
    extends AbstractMojo
{
    /**
     * The vm line separator
     */
    private static final String EOL = System.getProperty( "line.separator" );

    /**
     * Tag name for &#64;author *
     */
    private static final String AUTHOR_TAG = "author";

    /**
     * Tag name for &#64;version *
     */
    private static final String VERSION_TAG = "version";

    /**
     * Tag name for &#64;since *
     */
    private static final String SINCE_TAG = "since";

    /**
     * Tag name for &#64;param *
     */
    private static final String PARAM_TAG = "param";

    /**
     * Tag name for &#64;return *
     */
    private static final String RETURN_TAG = "return";

    /**
     * Tag name for &#64;throws *
     */
    private static final String THROWS_TAG = "throws";

    /**
     * Tag name for &#64;link *
     */
    private static final String LINK_TAG = "link";

    /**
     * Tag name for {&#64;inheritDoc} *
     */
    private static final String INHERITED_TAG = "{@inheritDoc}";

    /**
     * Start Javadoc String i.e. <code>&#47;&#42;&#42;</code> *
     */
    private static final String START_JAVADOC = "/**";

    /**
     * End Javadoc String i.e. <code>&#42;&#47;</code> *
     */
    private static final String END_JAVADOC = "*/";

    /**
     * Javadoc Separator i.e. <code> &#42; </code> *
     */
    private static final String SEPARATOR_JAVADOC = " * ";

    /**
     * Inherited Javadoc i.e. <code>&#47;&#42;&#42; {&#64;inheritDoc} &#42;&#47;</code> *
     */
    private static final String INHERITED_JAVADOC = START_JAVADOC + " " + INHERITED_TAG + " " + END_JAVADOC;

    /**
     * <code>all</code> parameter used by {@link #fixTags} *
     */
    private static final String FIX_TAGS_ALL = "all";

    /**
     * <code>public</code> parameter used by {@link #level} *
     */
    private static final String LEVEL_PUBLIC = "public";

    /**
     * <code>protected</code> parameter used by {@link #level} *
     */
    private static final String LEVEL_PROTECTED = "protected";

    /**
     * <code>package</code> parameter used by {@link #level} *
     */
    private static final String LEVEL_PACKAGE = "package";

    /**
     * <code>private</code> parameter used by {@link #level} *
     */
    private static final String LEVEL_PRIVATE = "private";

    /**
     * The Clirr Maven plugin groupId <code>org.codehaus.mojo</code> *
     */
    private static final String CLIRR_MAVEN_PLUGIN_GROUPID = "org.codehaus.mojo";

    /**
     * The Clirr Maven plugin artifactId <code>clirr-maven-plugin</code> *
     */
    private static final String CLIRR_MAVEN_PLUGIN_ARTIFACTID = "clirr-maven-plugin";

    /**
     * The latest Clirr Maven plugin version <code>2.2.2</code> *
     */
    private static final String CLIRR_MAVEN_PLUGIN_VERSION = "2.2.2";

    /**
     * The Clirr Maven plugin goal <code>check</code> *
     */
    private static final String CLIRR_MAVEN_PLUGIN_GOAL = "check";

    /**
     * Java Files Pattern.
     */
    public static final String JAVA_FILES = "**\\/*.java";

    /**
     * Default version value.
     */
    public static final String DEFAULT_VERSION_VALUE = "\u0024Id: \u0024Id";

    // ----------------------------------------------------------------------
    // Mojo components
    // ----------------------------------------------------------------------

    /**
     * Input handler, needed for command line handling.
     */
    @Component
    private InputHandler inputHandler;

    // ----------------------------------------------------------------------
    // Mojo parameters
    // ----------------------------------------------------------------------

    /**
     * Version to compare the current code against using the
     * <a href="http://mojo.codehaus.org/clirr-maven-plugin/">Clirr Maven Plugin</a>.
     * <br/>
     * See <a href="#defaultSince">defaultSince</a>.
     */
    @Parameter ( property = "comparisonVersion", defaultValue = "(,${project.version})" )
    private String comparisonVersion;

    /**
     * Default value for the Javadoc tag <code>&#64;author</code>.
     * <br/>
     * If not specified, the <code>user.name</code> defined in the System properties will be used.
     */
    @Parameter ( property = "defaultAuthor" )
    private String defaultAuthor;

    /**
     * Default value for the Javadoc tag <code>&#64;since</code>.
     */
    @Parameter ( property = "defaultSince", defaultValue = "${project.version}" )
    private String defaultSince;

    /**
     * Default value for the Javadoc tag <code>&#64;version</code>.
     * <br/>
     * By default, it is <code>&#36;Id:&#36;</code>, corresponding to a
     * <a href="http://svnbook.red-bean.com/en/1.1/ch07s02.html#svn-ch-7-sect-2.3.4">SVN keyword</a>.
     * Refer to your SCM to use an other SCM keyword.
     */
    @Parameter ( property = "defaultVersion", defaultValue = DEFAULT_VERSION_VALUE )
    private String defaultVersion = "\u0024Id: \u0024"; // can't use default-value="\u0024Id: \u0024"

    /**
     * The file encoding to use when reading the source files. If the property
     * <code>project.build.sourceEncoding</code> is not set, the platform default encoding is used.
     */
    @Parameter ( property = "encoding", defaultValue = "${project.build.sourceEncoding}" )
    private String encoding;

    /**
     * Comma separated excludes Java files, i.e. <code>&#42;&#42;/&#42;Test.java</code>.
     */
    @Parameter ( property = "excludes" )
    private String excludes;

    /**
     * Comma separated tags to fix in classes, interfaces or methods Javadoc comments.
     * Possible values are:
     * <ul>
     * <li>all (fix all Javadoc tags)</li>
     * <li>author (fix only &#64;author tag)</li>
     * <li>version (fix only &#64;version tag)</li>
     * <li>since (fix only &#64;since tag)</li>
     * <li>param (fix only &#64;param tag)</li>
     * <li>return (fix only &#64;return tag)</li>
     * <li>throws (fix only &#64;throws tag)</li>
     * <li>link (fix only &#64;link tag)</li>
     * </ul>
     */
    @Parameter ( property = "fixTags", defaultValue = "all" )
    private String fixTags;

    /**
     * Flag to fix the classes or interfaces Javadoc comments according the <code>level</code>.
     */
    @Parameter ( property = "fixClassComment", defaultValue = "true" )
    private boolean fixClassComment;

    /**
     * Flag to fix the fields Javadoc comments according the <code>level</code>.
     */
    @Parameter ( property = "fixFieldComment", defaultValue = "true" )
    private boolean fixFieldComment;

    /**
     * Flag to fix the methods Javadoc comments according the <code>level</code>.
     */
    @Parameter ( property = "fixMethodComment", defaultValue = "true" )
    private boolean fixMethodComment;

    /**
     * <p>Flag to remove throws tags from unknown classes.</p>
     * <p><strong>NOTE:</strong>Since 3.1.0 the default value has been changed to {@code true}, 
     * due to JavaDoc 8 strictness. 
     */
    @Parameter ( property = "removeUnknownThrows", defaultValue = "true" )
    private boolean removeUnknownThrows;

    /**
     * Forcing the goal execution i.e. skip warranty messages (not recommended).
     */
    @Parameter ( property = "force" )
    private boolean force;

    /**
     * Flag to ignore or not Clirr.
     */
    @Parameter ( property = "ignoreClirr", defaultValue = "false" )
    protected boolean ignoreClirr;

    /**
     * Comma separated includes Java files, i.e. <code>&#42;&#42;/&#42;Test.java</code>.
     * <p/>
     * <strong>Note:</strong> default value is {@code **\/*.java}.
     */
    @Parameter ( property = "includes", defaultValue = JAVA_FILES )
    private String includes;

    /**
     * Specifies the access level for classes and members to show in the Javadocs.
     * Possible values are:
     * <ul>
     * <li><a href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#public">public</a>
     * (shows only public classes and members)</li>
     * <li><a href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#protected">protected</a>
     * (shows only public and protected classes and members)</li>
     * <li><a href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#package">package</a>
     * (shows all classes and members not marked private)</li>
     * <li><a href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#private">private</a>
     * (shows all classes and members)</li>
     * </ul>
     */
    @Parameter ( property = "level", defaultValue = "protected" )
    private String level;

    /**
     * The local repository where the artifacts are located, used by the tests.
     */
    @Parameter ( property = "localRepository" )
    private ArtifactRepository localRepository;

    /**
     * Output directory where Java classes will be rewritten.
     */
    @Parameter ( property = "outputDirectory", defaultValue = "${project.build.sourceDirectory}" )
    private File outputDirectory;

    /**
     * The Maven Project Object.
     */
    @Parameter( defaultValue = "${project}", readonly = true, required = true )
    private MavenProject project;

    @Parameter ( defaultValue = "${session}", readonly = true, required = true )
    private MavenSession session;

    /**
     * The current user system settings for use in Maven.
     */
    @Parameter( defaultValue = "${settings}", readonly = true, required = true )
    private Settings settings;

    // ----------------------------------------------------------------------
    // Internal fields
    // ----------------------------------------------------------------------

    /**
     * The current project class loader.
     */
    private ClassLoader projectClassLoader;

    /**
     * Split {@link #fixTags} by comma.
     *
     * @see #init()
     */
    private String[] fixTagsSplitted;

    /**
     * New classes found by Clirr.
     */
    private List<String> clirrNewClasses;

    /**
     * New Methods in a Class (the key) found by Clirr.
     */
    private Map<String, List<String>> clirrNewMethods;

    /**
     * List of classes where <code>&#42;since</code> is added. Will be used to add or not this tag in the methods.
     */
    private List<String> sinceClasses;

    /**
     * {@inheritDoc}
     */
    @Override
    public void execute()
        throws MojoExecutionException, MojoFailureException
    {
        if ( !fixClassComment && !fixFieldComment && !fixMethodComment )
        {
            getLog().info( "Specified to NOT fix classes, fields and methods. Nothing to do." );
            return;
        }

        // verify goal params
        init();

        if ( fixTagsSplitted.length == 0 )
        {
            getLog().info( "No fix tag specified. Nothing to do." );
            return;
        }

        // add warranty msg
        if ( !preCheck() )
        {
            return;
        }

        // run clirr
        try
        {
            executeClirr();
        }
        catch ( MavenInvocationException e )
        {
            if ( getLog().isDebugEnabled() )
            {
                getLog().error( "MavenInvocationException: " + e.getMessage(), e );
            }
            else
            {
                getLog().error( "MavenInvocationException: " + e.getMessage() );
            }
            getLog().info( "Clirr is ignored." );
        }

        // run qdox and process
        try
        {
            Collection<JavaClass> javaClasses = getQdoxClasses();

            if ( javaClasses != null )
            {
                for ( JavaClass javaClass : javaClasses )
                {
                    processFix( javaClass );
                }
         }
        }
        catch ( IOException e )
        {
            throw new MojoExecutionException( "IOException: " + e.getMessage(), e );
        }
    }

    // ----------------------------------------------------------------------
    // protected methods
    // ----------------------------------------------------------------------

    protected final MavenProject getProject()
    {
        return project;
    }    

    /**
     * @param p not null maven project.
     * @return the artifact type.
     */
    protected String getArtifactType( MavenProject p )
    {
        return p.getArtifact().getType();
    }

    /**
     * @param p not null maven project.
     * @return the list of source paths for the given project.
     */
    protected List<String> getProjectSourceRoots( MavenProject p )
    {
        return ( p.getCompileSourceRoots() == null
            ? Collections.<String>emptyList()
            : new LinkedList<>( p.getCompileSourceRoots() ) );
    }

    /**
     * @param p not null
     * @return the compile classpath elements
     * @throws DependencyResolutionRequiredException
     *          if any
     */
    protected List<String> getCompileClasspathElements( MavenProject p )
        throws DependencyResolutionRequiredException
    {
        return ( p.getCompileClasspathElements() == null
            ? Collections.<String>emptyList()
            : new LinkedList<>( p.getCompileClasspathElements() ) );
    }

    /**
     * @param javaExecutable not null
     * @return the fully qualify name of javaMethod with signature
     */
    protected static String getJavaMethodAsString( JavaExecutable javaExecutable )
    {
        return javaExecutable.getDeclaringClass().getFullyQualifiedName() + "#" + javaExecutable.getCallSignature();
    }

    // ----------------------------------------------------------------------
    // private methods
    // ----------------------------------------------------------------------

    /**
     * Init goal parameters.
     */
    private void init()
    {
        // defaultAuthor
        if ( StringUtils.isEmpty( defaultAuthor ) )
        {
            defaultAuthor = System.getProperty( "user.name" );
        }

        // defaultSince
        int i = defaultSince.indexOf( "-" + Artifact.SNAPSHOT_VERSION );
        if ( i != -1 )
        {
            defaultSince = defaultSince.substring( 0, i );
        }

        // fixTags
        if ( !FIX_TAGS_ALL.equalsIgnoreCase( fixTags.trim() ) )
        {
            String[] split = StringUtils.split( fixTags, "," );
            List<String> filtered = new LinkedList<>();
            for ( String aSplit : split )
            {
                String s = aSplit.trim();
                if ( JavadocUtil.equalsIgnoreCase( s, FIX_TAGS_ALL, AUTHOR_TAG, VERSION_TAG, SINCE_TAG, PARAM_TAG,
                                                   THROWS_TAG, LINK_TAG, RETURN_TAG ) )
                {
                    filtered.add( s );
                }
                else
                {
                    if ( getLog().isWarnEnabled() )
                    {
                        getLog().warn( "Unrecognized '" + s + "' for fixTags parameter. Ignored it!" );
                    }
                }
            }
            fixTags = StringUtils.join( filtered.iterator(), "," );
        }
        fixTagsSplitted = StringUtils.split( fixTags, "," );

        // encoding
        if ( StringUtils.isEmpty( encoding ) )
        {
            if ( getLog().isWarnEnabled() )
            {
                getLog().warn( "File encoding has not been set, using platform encoding " + ReaderFactory.FILE_ENCODING
                                   + ", i.e. build is platform dependent!" );
            }
            encoding = ReaderFactory.FILE_ENCODING;
        }

        // level
        level = level.trim();
        if ( !JavadocUtil.equalsIgnoreCase( level, LEVEL_PUBLIC, LEVEL_PROTECTED, LEVEL_PACKAGE, LEVEL_PRIVATE ) )
        {
            if ( getLog().isWarnEnabled() )
            {
                getLog().warn( "Unrecognized '" + level + "' for level parameter, using 'protected' level." );
            }
            level = "protected";
        }
    }

    /**
     * @return <code>true</code> if the user wants to proceed, <code>false</code> otherwise.
     * @throws MojoExecutionException if any
     */
    private boolean preCheck()
        throws MojoExecutionException
    {
        if ( force )
        {
            return true;
        }

        if ( outputDirectory != null && !outputDirectory.getAbsolutePath().equals(
            getProjectSourceDirectory().getAbsolutePath() ) )
        {
            return true;
        }

        if ( !settings.isInteractiveMode() )
        {
            getLog().error( "Maven is not attempt to interact with the user for input. "
                                + "Verify the <interactiveMode/> configuration in your settings." );
            return false;
        }

        getLog().warn( "" );
        getLog().warn( "    WARRANTY DISCLAIMER" );
        getLog().warn( "" );
        getLog().warn( "All warranties with regard to this Maven goal are disclaimed!" );
        getLog().warn( "The changes will be done directly in the source code." );
        getLog().warn( "The Maven Team strongly recommends the use of a SCM software BEFORE executing this goal." );
        getLog().warn( "" );

        while ( true )
        {
            getLog().info( "Are you sure to proceed? [Y]es [N]o" );

            try
            {
                String userExpression = inputHandler.readLine();
                if ( userExpression == null || JavadocUtil.equalsIgnoreCase( userExpression, "Y", "Yes" ) )
                {
                    getLog().info( "OK, let's proceed..." );
                    break;
                }
                if ( JavadocUtil.equalsIgnoreCase( userExpression, "N", "No" ) )
                {
                    getLog().info( "No changes in your sources occur." );
                    return false;
                }
            }
            catch ( IOException e )
            {
                throw new MojoExecutionException( "Unable to read from standard input.", e );
            }
        }

        return true;
    }

    /**
     * @return the source dir as File for the given project
     */
    private File getProjectSourceDirectory()
    {
        return new File( project.getBuild().getSourceDirectory() );
    }

    /**
     * Invoke Maven to run clirr-maven-plugin to find API differences.
     *
     * @throws MavenInvocationException if any
     */
    private void executeClirr()
        throws MavenInvocationException
    {
        if ( ignoreClirr )
        {
            getLog().info( "Clirr is ignored." );
            return;
        }

        String clirrGoal = getFullClirrGoal();

        // http://mojo.codehaus.org/clirr-maven-plugin/check-mojo.html
        File clirrTextOutputFile =
            FileUtils.createTempFile( "clirr", ".txt", new File( project.getBuild().getDirectory() ) );
        Properties properties = new Properties();
        properties.put( "textOutputFile", clirrTextOutputFile.getAbsolutePath() );
        properties.put( "comparisonVersion", comparisonVersion );
        properties.put( "failOnError", "false" );
        if ( JavaVersion.JAVA_SPECIFICATION_VERSION.isBefore( "8" ) )
        {
            // ensure that Java7 picks up TLSv1.2 when connecting with Central
            properties.put( "https.protocols", "TLSv1.2" );
        }

        File invokerDir = new File( project.getBuild().getDirectory(), "invoker" );
        invokerDir.mkdirs();
        File invokerLogFile = FileUtils.createTempFile( "clirr-maven-plugin", ".txt", invokerDir );
        new File( project.getBuild().getDirectory(), "invoker-clirr-maven-plugin.txt" );

        JavadocUtil.invokeMaven( getLog(), new File( localRepository.getBasedir() ), project.getFile(),
                                 Collections.singletonList( clirrGoal ), properties, invokerLogFile,
                                 session.getRequest().getGlobalSettingsFile() );

        try
        {
            if ( invokerLogFile.exists() )
            {
                String invokerLogContent =
                    StringUtils.unifyLineSeparators( FileUtils.fileRead( invokerLogFile, "UTF-8" ) );
                // see org.codehaus.mojo.clirr.AbstractClirrMojo#getComparisonArtifact()
                final String artifactNotFoundMsg = "Unable to find a previous version of the project in the repository";
                if ( invokerLogContent.contains( artifactNotFoundMsg ) )
                {
                    getLog().warn( "No previous artifact has been deployed, Clirr is ignored." );
                    return;
                }
            }
        }
        catch ( IOException e )
        {
            getLog().debug( "IOException: " + e.getMessage() );
        }

        try
        {
            parseClirrTextOutputFile( clirrTextOutputFile );
        }
        catch ( IOException e )
        {
            if ( getLog().isDebugEnabled() )
            {
                getLog().debug( "IOException: " + e.getMessage(), e );
            }
            getLog().info( "IOException when parsing Clirr output '" + clirrTextOutputFile.getAbsolutePath()
                               + "', Clirr is ignored." );
        }
    }

    /**
     * @param clirrTextOutputFile not null
     * @throws IOException if any
     */
    private void parseClirrTextOutputFile( File clirrTextOutputFile )
        throws IOException
    {
        if ( !clirrTextOutputFile.exists() )
        {
            if ( getLog().isInfoEnabled() )
            {
                getLog().info(
                    "No Clirr output file '" + clirrTextOutputFile.getAbsolutePath() + "' exists, Clirr is ignored." );
            }
            return;
        }

        if ( getLog().isInfoEnabled() )
        {
            getLog().info( "Clirr output file was created: " + clirrTextOutputFile.getAbsolutePath() );
        }

        clirrNewClasses = new LinkedList<>();
        clirrNewMethods = new LinkedHashMap<>();

        BufferedReader reader = null;
        try
        {
            reader = new BufferedReader( ReaderFactory.newReader( clirrTextOutputFile, "UTF-8" ) );

            for ( String line = reader.readLine(); line != null; line = reader.readLine() )
            {
                String[] split = StringUtils.split( line, ":" );
                if ( split.length != 4 )
                {
                    if ( getLog().isDebugEnabled() )
                    {
                        getLog().debug( "Unable to parse the clirr line: " + line );
                    }
                    continue;
                }

                int code;
                try
                {
                    code = Integer.parseInt( split[1].trim() );
                }
                catch ( NumberFormatException e )
                {
                    if ( getLog().isDebugEnabled() )
                    {
                        getLog().debug( "Unable to parse the clirr line: " + line );
                    }
                    continue;
                }

                // http://clirr.sourceforge.net/clirr-core/exegesis.html
                // 7011 - Method Added
                // 7012 - Method Added to Interface
                // 8000 - Class Added
                List<String> list;
                String[] splits2;
                // CHECKSTYLE_OFF: MagicNumber
                switch ( code )
                {
                    case 7011:
                        list = clirrNewMethods.get( split[2].trim() );
                        if ( list == null )
                        {
                            list = new ArrayList<>();
                        }
                        splits2 = StringUtils.split( split[3].trim(), "'" );
                        if ( splits2.length != 3 )
                        {
                            continue;
                        }
                        list.add( splits2[1].trim() );
                        clirrNewMethods.put( split[2].trim(), list );
                        break;

                    case 7012:
                        list = clirrNewMethods.get( split[2].trim() );
                        if ( list == null )
                        {
                            list = new ArrayList<>();
                        }
                        splits2 = StringUtils.split( split[3].trim(), "'" );
                        if ( splits2.length != 3 )
                        {
                            continue;
                        }
                        list.add( splits2[1].trim() );
                        clirrNewMethods.put( split[2].trim(), list );
                        break;

                    case 8000:
                        clirrNewClasses.add( split[2].trim() );
                        break;
                    default:
                        break;
                }
                // CHECKSTYLE_ON: MagicNumber
            }

            reader.close();
            reader = null;
        }
        finally
        {
            IOUtils.closeQuietly( reader );
        }
        if ( clirrNewClasses.isEmpty() && clirrNewMethods.isEmpty() )
        {
            getLog().info( "Clirr NOT found API differences." );
        }
        else
        {
            getLog().info( "Clirr found API differences, i.e. new classes/interfaces or methods." );
        }
    }

    /**
     * @param tag not null
     * @return <code>true</code> if <code>tag</code> is defined in {@link #fixTags}.
     */
    private boolean fixTag( String tag )
    {
        if ( fixTagsSplitted.length == 1 && fixTagsSplitted[0].equals( FIX_TAGS_ALL ) )
        {
            return true;
        }

        for ( String aFixTagsSplitted : fixTagsSplitted )
        {
            if ( aFixTagsSplitted.trim().equals( tag ) )
            {
                return true;
            }
        }

        return false;
    }

    /**
     * Calling Qdox to find {@link JavaClass} objects from the Maven project sources.
     * Ignore java class if Qdox has parsing errors.
     *
     * @return an array of {@link JavaClass} found by QDox
     * @throws IOException            if any
     * @throws MojoExecutionException if any
     */
    private Collection<JavaClass> getQdoxClasses()
        throws IOException, MojoExecutionException
    {
        if ( "pom".equalsIgnoreCase( project.getPackaging() ) )
        {
            getLog().warn( "This project has 'pom' packaging, no Java sources is available." );
            return null;
        }

        List<File> javaFiles = new LinkedList<>();
        for ( String sourceRoot : getProjectSourceRoots( project ) )
        {
            File f = new File( sourceRoot );
            if ( f.isDirectory() )
            {
                javaFiles.addAll( FileUtils.getFiles( f, includes, excludes, true ) );
            }
            else
            {
                if ( getLog().isWarnEnabled() )
                {
                    getLog().warn( f + " doesn't exist. Ignored it." );
                }
            }
        }

        ClassLibraryBuilder classLibraryBuilder = new OrderedClassLibraryBuilder();
        classLibraryBuilder.appendClassLoader( getProjectClassLoader() );

        JavaProjectBuilder builder = new JavaProjectBuilder( classLibraryBuilder );
        builder.setEncoding( encoding );
        for ( File f : javaFiles )
        {
            if ( !f.getAbsolutePath().toLowerCase( Locale.ENGLISH ).endsWith( ".java" ) && getLog().isWarnEnabled() )
            {
                getLog().warn( "'" + f + "' is not a Java file. Ignored it." );
                continue;
            }

            try
            {
                builder.addSource( f );
            }
            catch ( ParseException e )
            {
                if ( getLog().isWarnEnabled() )
                {
                    getLog().warn( "QDOX ParseException: " + e.getMessage() + ". Can't fix it." );
                }
            }
        }

        return builder.getClasses();
    }

    /**
     * @return the classLoader for the given project using lazy instantiation.
     * @throws MojoExecutionException if any
     */
    private ClassLoader getProjectClassLoader()
        throws MojoExecutionException
    {
        if ( projectClassLoader == null )
        {
            List<String> classPath;
            try
            {
                classPath = getCompileClasspathElements( project );
            }
            catch ( DependencyResolutionRequiredException e )
            {
                throw new MojoExecutionException( "DependencyResolutionRequiredException: " + e.getMessage(), e );
            }

            List<URL> urls = new ArrayList<>( classPath.size() );
            for ( String filename : classPath )
            {
                try
                {
                    urls.add( new File( filename ).toURL() );
                }
                catch ( MalformedURLException e )
                {
                    throw new MojoExecutionException( "MalformedURLException: " + e.getMessage(), e );
                }
            }

            projectClassLoader = new URLClassLoader( urls.toArray( new URL[urls.size()] ), null );
        }

        return projectClassLoader;
    }

    /**
     * Process the given {@link JavaClass}, ie add missing javadoc tags depending user parameters.
     *
     * @param javaClass not null
     * @throws IOException            if any
     * @throws MojoExecutionException if any
     */
    private void processFix( JavaClass javaClass )
        throws IOException, MojoExecutionException
    {
        // Skipping inner classes
        if ( javaClass.isInner() )
        {
            return;
        }

        File javaFile;
        try
        {
            javaFile = Paths.get( javaClass.getSource().getURL().toURI() ).toFile();
        }
        catch ( URISyntaxException e )
        {
            throw new MojoExecutionException( e.getMessage() );
        }
        
        // the original java content in memory
        final String originalContent = StringUtils.unifyLineSeparators( FileUtils.fileRead( javaFile, encoding ) );

        if ( getLog().isDebugEnabled() )
        {
            getLog().debug( "Analyzing " + javaClass.getFullyQualifiedName() );
        }

        final StringWriter stringWriter = new StringWriter();
        BufferedReader reader = null;
        boolean changeDetected = false;
        try
        {
            reader = new BufferedReader( new StringReader( originalContent ) );

            int lineNumber = 0;
            for ( String line = reader.readLine(); line != null; line = reader.readLine() )
            {
                lineNumber++;
                final String indent = autodetectIndentation( line );

                // fixing classes
                if ( javaClass.getComment() == null && javaClass.getAnnotations() != null
                    && !javaClass.getAnnotations().isEmpty() )
                {
                    if ( lineNumber == javaClass.getAnnotations().get( 0 ).getLineNumber() )
                    {
                        changeDetected |= fixClassComment( stringWriter, originalContent, javaClass, indent );

                        takeCareSingleComment( stringWriter, originalContent, javaClass );
                    }
                }
                else if ( lineNumber == javaClass.getLineNumber() )
                {
                    changeDetected |= fixClassComment( stringWriter, originalContent, javaClass, indent );

                    takeCareSingleComment( stringWriter, originalContent, javaClass );
                }

                // fixing fields
                if ( javaClass.getFields() != null )
                {
                    for ( JavaField field : javaClass.getFields() )
                    {
                        if ( lineNumber == field.getLineNumber() )
                        {
                            changeDetected |= fixFieldComment( stringWriter, javaClass, field, indent );
                        }
                    }
                }
                
                // fixing methods
                if ( javaClass.getConstructors() != null )
                {
                    for ( JavaConstructor method :  javaClass.getConstructors() )
                    {
                        if ( lineNumber == method.getLineNumber() )
                        {
                            changeDetected |= fixMethodComment( stringWriter, originalContent, method, indent );

                            takeCareSingleComment( stringWriter, originalContent, method );
                        }
                    }
                }
                

                // fixing methods
                for ( JavaMethod method :  javaClass.getMethods() )
                {
                    int methodLineNumber;
                    if ( method.getComment() == null && !method.getAnnotations().isEmpty() )
                    {
                        methodLineNumber = method.getAnnotations().get( 0 ).getLineNumber();
                    }
                    else
                    {
                        methodLineNumber = method.getLineNumber();
                    }
                    
                    if ( lineNumber == methodLineNumber )
                    {
                        changeDetected |= fixMethodComment( stringWriter, originalContent, method, indent );

                        takeCareSingleComment( stringWriter, originalContent, method );
                    }
                }

                stringWriter.write( line );
                stringWriter.write( EOL );
            }

            reader.close();
            reader = null;
        }
        finally
        {
            IOUtil.close( reader );
        }

        if ( changeDetected )
        {
            if ( getLog().isInfoEnabled() )
            {
                getLog().info( "Saving changes to " + javaClass.getFullyQualifiedName() );
            }

            if ( outputDirectory != null && !outputDirectory.getAbsolutePath().equals(
                    getProjectSourceDirectory().getAbsolutePath() ) )
            {
                String path = StringUtils.replace( javaFile.getAbsolutePath().replaceAll( "\\\\", "/" ),
                        project.getBuild().getSourceDirectory().replaceAll( "\\\\", "/" ), "" );
                javaFile = new File( outputDirectory, path );
                javaFile.getParentFile().mkdirs();
            }
            writeFile( javaFile, encoding, stringWriter.toString() );
        }
        else
        {
            if ( getLog().isDebugEnabled() ) 
            {
                getLog().debug( "No changes made to " + javaClass.getFullyQualifiedName() );
            }
        }
    }

    /**
     * Take care of block or single comments between Javadoc comment and entity declaration ie:
     * <br/>
     * <code>
     * <font color="#808080">1</font>&nbsp;<font color="#ffffff">&nbsp;</font>
     * <font color="#3f5fbf">&#47;&#42;&#42;</font><br />
     * <font color="#808080">2</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;{Javadoc&nbsp;Comment}</font><br />
     * <font color="#808080">3</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&#47;</font><br />
     * <font color="#808080">4</font>&nbsp;<font color="#ffffff">&nbsp;</font>
     * <font color="#3f7f5f">&#47;&#42;</font><br />
     * <font color="#808080">5</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font>
     * <font color="#3f7f5f">&#42;&nbsp;{Block&nbsp;Comment}</font><br />
     * <font color="#808080">6</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font>
     * <font color="#3f7f5f">&#42;&#47;</font><br />
     * <font color="#808080">7</font>&nbsp;<font color="#ffffff">&nbsp;</font>
     * <font color="#3f7f5f">&#47;&#47;&nbsp;{Single&nbsp;comment}</font><br />
     * <font color="#808080">8</font>&nbsp;<font color="#ffffff">&nbsp;</font>
     * <font color="#7f0055"><b>public&nbsp;</b></font><font color="#7f0055"><b>void&nbsp;</b></font>
     * <font color="#000000">dummyMethod</font><font color="#000000">(&nbsp;</font>
     * <font color="#000000">String&nbsp;s&nbsp;</font><font color="#000000">){}</font>
     * </code>
     *
     * @param stringWriter    not null
     * @param originalContent not null
     * @param entity          not null
     * @throws IOException if any
     * @see #extractOriginalJavadoc
     */
    private void takeCareSingleComment( final StringWriter stringWriter, final String originalContent,
                                        final JavaAnnotatedElement entity )
        throws IOException
    {
        if ( entity.getComment() == null )
        {
            return;
        }

        String javadocComment = trimRight( extractOriginalJavadoc( originalContent, entity ) );
        String extraComment = javadocComment.substring( javadocComment.indexOf( END_JAVADOC ) + END_JAVADOC.length() );
        if ( StringUtils.isNotEmpty( extraComment ) )
        {
            if ( extraComment.contains( EOL ) )
            {
                stringWriter.write( extraComment.substring( extraComment.indexOf( EOL ) + EOL.length() ) );
            }
            else
            {
                stringWriter.write( extraComment );
            }
            stringWriter.write( EOL );
        }
    }

    /**
     * Add/update Javadoc class comment.
     *
     * @param stringWriter
     * @param originalContent
     * @param javaClass
     * @param indent
     * @return {@code true} if the comment is updated, otherwise {@code false}
     * @throws MojoExecutionException
     * @throws IOException
     */
    private boolean fixClassComment( final StringWriter stringWriter, final String originalContent,
                                  final JavaClass javaClass, final String indent )
        throws MojoExecutionException, IOException
    {
        if ( !fixClassComment )
        {
            return false;
        }

        if ( !isInLevel( javaClass.getModifiers() ) )
        {
            return false;
        }

        // add
        if ( javaClass.getComment() == null )
        {
            addDefaultClassComment( stringWriter, javaClass, indent );
            return true;
        }

        // update
        return updateEntityComment( stringWriter, originalContent, javaClass, indent );
    }

    /**
     * @param modifiers list of modifiers (public, private, protected, package)
     * @return <code>true</code> if modifier is align with <code>level</code>.
     */
    private boolean isInLevel( List<String> modifiers )
    {
        if ( LEVEL_PUBLIC.equalsIgnoreCase( level.trim() ) )
        {
            return modifiers.contains( LEVEL_PUBLIC );
        }

        if ( LEVEL_PROTECTED.equalsIgnoreCase( level.trim() ) )
        {
            return ( modifiers.contains( LEVEL_PUBLIC ) || modifiers.contains( LEVEL_PROTECTED ) );
        }

        if ( LEVEL_PACKAGE.equalsIgnoreCase( level.trim() ) )
        {
            return !modifiers.contains( LEVEL_PRIVATE );
        }

        // should be private (shows all classes and members)
        return true;
    }

    /**
     * Add a default Javadoc for the given class, i.e.:
     * <br/>
     * <code>
     * <font color="#808080">1</font>&nbsp;<font color="#ffffff">&nbsp;</font>
     * <font color="#3f5fbf">&#47;&#42;&#42;</font><br />
     * <font color="#808080">2</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;{Comment&nbsp;based&nbsp;on&nbsp;the&nbsp;class&nbsp;name}</font><br />
     * <font color="#808080">3</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;</font><br />
     * <font color="#808080">4</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;</font><font color="#7f9fbf">@author&nbsp;</font>
     * <font color="#3f5fbf">X&nbsp;{added&nbsp;if&nbsp;addMissingAuthor}</font><br />
     * <font color="#808080">5</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;</font><font color="#7f9fbf">@version&nbsp;</font>
     * <font color="#3f5fbf">X&nbsp;{added&nbsp;if&nbsp;addMissingVersion}</font><br />
     * <font color="#808080">6</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;</font><font color="#7f9fbf">@since&nbsp;</font>
     * <font color="#3f5fbf">X&nbsp;{added&nbsp;if&nbsp;addMissingSince&nbsp;and&nbsp;new&nbsp;classes
     * from&nbsp;previous&nbsp;version}</font><br />
     * <font color="#808080">7</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&#47;</font><br />
     * <font color="#808080">8</font>&nbsp;<font color="#7f0055"><b>public&nbsp;class&nbsp;</b></font>
     * <font color="#000000">DummyClass&nbsp;</font><font color="#000000">{}</font></code>
     * </code>
     *
     * @param stringWriter not null
     * @param javaClass    not null
     * @param indent       not null
     * @see #getDefaultClassJavadocComment(JavaClass)
     * @see #appendDefaultAuthorTag(StringBuilder, String)
     * @see #appendDefaultSinceTag(StringBuilder, String)
     * @see #appendDefaultVersionTag(StringBuilder, String)
     */
    private void addDefaultClassComment( final StringWriter stringWriter, final JavaClass javaClass,
                                         final String indent )
    {
        StringBuilder sb = new StringBuilder();

        sb.append( indent ).append( START_JAVADOC );
        sb.append( EOL );
        sb.append( indent ).append( SEPARATOR_JAVADOC );
        sb.append( getDefaultClassJavadocComment( javaClass ) );
        sb.append( EOL );

        appendSeparator( sb, indent );

        appendDefaultAuthorTag( sb, indent );

        appendDefaultVersionTag( sb, indent );

        if ( fixTag( SINCE_TAG ) )
        {
            if ( !ignoreClirr )
            {
                if ( isNewClassFromLastVersion( javaClass ) )
                {
                    appendDefaultSinceTag( sb, indent );
                }
            }
            else
            {
                appendDefaultSinceTag( sb, indent );
                addSinceClasses( javaClass );
            }
        }

        sb.append( indent ).append( " " ).append( END_JAVADOC );
        sb.append( EOL );

        stringWriter.write( sb.toString() );
    }

    /**
     * Add Javadoc field comment, only for static fields or interface fields.
     *
     * @param stringWriter not null
     * @param javaClass    not null
     * @param field        not null
     * @param indent       not null
     * @return {@code true} if comment was updated, otherwise {@code false}
     * @throws IOException if any
     */
    private boolean fixFieldComment( final StringWriter stringWriter, final JavaClass javaClass, final JavaField field,
                                  final String indent )
        throws IOException
    {
        if ( !fixFieldComment )
        {
            return false;
        }

        if ( !javaClass.isInterface() && ( !isInLevel( field.getModifiers() ) || !field.isStatic() ) )
        {
            return false;
        }

        // add
        if ( field.getComment() == null )
        {
            addDefaultFieldComment( stringWriter, field, indent );
            return true;
        }

        // no update
        return false;
    }

    /**
     * Add a default Javadoc for the given field, i.e.:
     * <br/>
     * <code>
     * <font color="#808080">1</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#47;&#42;&#42;&nbsp;Constant&nbsp;</font><font color="#7f7f9f">&lt;code&gt;</font>
     * <font color="#3f5fbf">MY_STRING_CONSTANT=&#34;value&#34;</font>
     * <font color="#7f7f9f">&lt;/code&gt;&nbsp;</font><font color="#3f5fbf">&#42;&#47;</font><br />
     * <font color="#808080">2</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#7f0055"><b>public&nbsp;static&nbsp;final&nbsp;</b></font>
     * <font color="#000000">String&nbsp;MY_STRING_CONSTANT&nbsp;=&nbsp;</font>
     * <font color="#2a00ff">&#34;value&#34;</font><font color="#000000">;</font>
     * </code>
     *
     * @param stringWriter not null
     * @param field        not null
     * @param indent       not null
     * @throws IOException if any
     */
    private void addDefaultFieldComment( final StringWriter stringWriter, final JavaField field, final String indent )
        throws IOException
    {
        StringBuilder sb = new StringBuilder();

        sb.append( indent ).append( START_JAVADOC ).append( " " );
        sb.append( "Constant <code>" ).append( field.getName() );

        if ( StringUtils.isNotEmpty( field.getInitializationExpression() ) )
        {
            String qualifiedName = field.getType().getFullyQualifiedName();

            if ( qualifiedName.equals( Byte.TYPE.toString() ) || qualifiedName.equals( Short.TYPE.toString() )
                || qualifiedName.equals( Integer.TYPE.toString() ) || qualifiedName.equals( Long.TYPE.toString() )
                || qualifiedName.equals( Float.TYPE.toString() ) || qualifiedName.equals( Double.TYPE.toString() )
                || qualifiedName.equals( Boolean.TYPE.toString() ) || qualifiedName.equals(
                Character.TYPE.toString() ) )
            {
                sb.append( "=" );
                sb.append( field.getInitializationExpression().trim() );
            }

            if ( qualifiedName.equals( String.class.getName() ) )
            {
                StringBuilder value = new StringBuilder();
                String[] lines = getLines( field.getInitializationExpression() );
                for ( String line : lines )
                {
                    StringTokenizer token = new StringTokenizer( line.trim(), "\"\n\r" );
                    while ( token.hasMoreTokens() )
                    {
                        String s = token.nextToken();

                        if ( s.trim().equals( "+" ) )
                        {
                            continue;
                        }
                        if ( s.trim().endsWith( "\\" ) )
                        {
                            s += "\"";
                        }
                        value.append( s );
                    }
                }

                sb.append( "=\"" );
                // reduce the size
                // CHECKSTYLE_OFF: MagicNumber
                if ( value.length() < 40 )
                {
                    sb.append( value.toString() ).append( "\"" );
                }
                else
                {
                    sb.append( value.toString(), 0, 39 ).append( "\"{trunked}" );
                }
                // CHECKSTYLE_ON: MagicNumber
            }
        }

        sb.append( "</code> " ).append( END_JAVADOC );
        sb.append( EOL );

        stringWriter.write( sb.toString() );
    }

    /**
     * Add/update Javadoc method comment.
     *
     * @param stringWriter    not null
     * @param originalContent not null
     * @param javaExecutable      not null
     * @param indent          not null
     * @return {@code true} if comment was updated, otherwise {@code false}
     * @throws MojoExecutionException if any
     * @throws IOException            if any
     */
    private boolean fixMethodComment( final StringWriter stringWriter, final String originalContent,
                                   final JavaExecutable javaExecutable, final String indent )
        throws MojoExecutionException, IOException
    {
        if ( !fixMethodComment )
        {
            return false;
        }

        if ( !javaExecutable.getDeclaringClass().isInterface() && !isInLevel( javaExecutable.getModifiers() ) )
        {
            return false;
        }

        // add
        if ( javaExecutable.getComment() == null )
        {
            addDefaultMethodComment( stringWriter, javaExecutable, indent );
            return true;
        }

        // update
        return updateEntityComment( stringWriter, originalContent, javaExecutable, indent );
    }

    /**
     * Add in the buffer a default Javadoc for the given class:
     * <br/>
     * <code>
     * <font color="#808080">1</font>&nbsp;<font color="#ffffff">&nbsp;</font>
     * <font color="#3f5fbf">&#47;&#42;&#42;</font><br />
     * <font color="#808080">2</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;{Comment&nbsp;based&nbsp;on&nbsp;the&nbsp;method&nbsp;name}</font><br />
     * <font color="#808080">3</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;</font><br />
     * <font color="#808080">4</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;</font><font color="#7f9fbf">@param&nbsp;</font>
     * <font color="#3f5fbf">X&nbsp;{added&nbsp;if&nbsp;addMissingParam}</font><br />
     * <font color="#808080">5</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;</font><font color="#7f9fbf">@return&nbsp;</font>
     * <font color="#3f5fbf">X&nbsp;{added&nbsp;if&nbsp;addMissingReturn}</font><br />
     * <font color="#808080">6</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;</font><font color="#7f9fbf">@throws&nbsp;</font>
     * <font color="#3f5fbf">X&nbsp;{added&nbsp;if&nbsp;addMissingThrows}</font><br />
     * <font color="#808080">7</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;</font><font color="#7f9fbf">@since&nbsp;</font>
     * <font color="#3f5fbf">X&nbsp;{added&nbsp;if&nbsp;addMissingSince&nbsp;and&nbsp;new&nbsp;classes
     * from&nbsp;previous&nbsp;version}</font><br />
     * <font color="#808080">8</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&#47;</font><br />
     * <font color="#808080">9</font>&nbsp;<font color="#7f0055"><b>public&nbsp;</b></font>
     * <font color="#7f0055"><b>void&nbsp;</b></font><font color="#000000">dummyMethod</font>
     * <font color="#000000">(&nbsp;</font><font color="#000000">String&nbsp;s&nbsp;</font>
     * <font color="#000000">){}</font>
     * </code>
     *
     * @param stringWriter   not null
     * @param javaExecutable not null
     * @param indent         not null
     * @throws MojoExecutionException if any
     * @see #getDefaultMethodJavadocComment
     * @see #appendDefaultSinceTag(StringBuilder, String)
     */
    private void addDefaultMethodComment( final StringWriter stringWriter, final JavaExecutable javaExecutable,
                                          final String indent )
        throws MojoExecutionException
    {
        StringBuilder sb = new StringBuilder();

        // special case
        if ( isInherited( javaExecutable ) )
        {
            sb.append( indent ).append( INHERITED_JAVADOC );
            sb.append( EOL );

            stringWriter.write( sb.toString() );
            return;
        }

        sb.append( indent ).append( START_JAVADOC );
        sb.append( EOL );
        sb.append( indent ).append( SEPARATOR_JAVADOC );
        sb.append( getDefaultMethodJavadocComment( javaExecutable ) );
        sb.append( EOL );

        boolean separatorAdded = false;
        if ( fixTag( PARAM_TAG ) )
        {
            if ( javaExecutable.getParameters() != null )
            {
                for ( JavaParameter javaParameter : javaExecutable.getParameters() )
                {
                    separatorAdded = appendDefaultParamTag( sb, indent, separatorAdded, javaParameter );
                }
            }
            // is generic?
            if ( javaExecutable.getTypeParameters() != null )
            {
                for ( JavaTypeVariable<JavaGenericDeclaration> typeParam : javaExecutable.getTypeParameters() )
                {
                    separatorAdded = appendDefaultParamTag( sb, indent, separatorAdded, typeParam );
                }
            }
        }
        if ( javaExecutable instanceof JavaMethod )
        {
            JavaMethod javaMethod = (JavaMethod) javaExecutable;
            if ( fixTag( RETURN_TAG ) && javaMethod.getReturns() != null && !javaMethod.getReturns().isVoid() )
            {
                separatorAdded = appendDefaultReturnTag( sb, indent, separatorAdded, javaMethod );
            }
            
        }
        if ( fixTag( THROWS_TAG ) && javaExecutable.getExceptions() != null )
        {
            for ( JavaType exception : javaExecutable.getExceptions() )
            {
                separatorAdded = appendDefaultThrowsTag( sb, indent, separatorAdded, exception );
            }
        }
        if ( fixTag( SINCE_TAG ) && isNewMethodFromLastRevision( javaExecutable ) )
        {
            separatorAdded = appendDefaultSinceTag( sb, indent, separatorAdded );
        }

        sb.append( indent ).append( " " ).append( END_JAVADOC );
        sb.append( EOL );

        stringWriter.write( sb.toString() );
    }

    /**
     * @param stringWriter    not null
     * @param originalContent not null
     * @param entity          not null
     * @param indent          not null
     * @return the updated changeDetected flag
     * @throws MojoExecutionException if any
     * @throws IOException            if any
     */
    private boolean updateEntityComment( final StringWriter stringWriter, final String originalContent,
                                         final JavaAnnotatedElement entity, final String indent )
        throws MojoExecutionException, IOException
    {
        boolean changeDetected = false;
        
        String old = null;
        String s = stringWriter.toString();
        int i = s.lastIndexOf( START_JAVADOC );
        if ( i != -1 )
        {
            String tmp = s.substring( 0, i );
            if ( tmp.lastIndexOf( EOL ) != -1 )
            {
                tmp = tmp.substring( 0, tmp.lastIndexOf( EOL ) );
            }
            
            old = stringWriter.getBuffer().substring( i );

            stringWriter.getBuffer().delete( 0, stringWriter.getBuffer().length() );
            stringWriter.write( tmp );
            stringWriter.write( EOL );
        }
        else
        {
            changeDetected = true;
        }

        updateJavadocComment( stringWriter, originalContent, entity, indent );
        
        if ( changeDetected )
        {
            return true; // return now if we already know there's a change
        }
        
        return !stringWriter.getBuffer().substring( i ).equals( old );
    }

    /**
     * @param stringWriter    not null
     * @param originalContent not null
     * @param entity          not null
     * @param indent          not null
     * @throws MojoExecutionException if any
     * @throws IOException            if any
     */
    private void updateJavadocComment( final StringWriter stringWriter, final String originalContent,
                                       final JavaAnnotatedElement entity, final String indent )
        throws MojoExecutionException, IOException
    {
        if ( entity.getComment() == null && ( entity.getTags() == null || entity.getTags().isEmpty() ) )
        {
            return;
        }

        boolean isJavaExecutable = false;
        if ( entity instanceof JavaExecutable )
        {
            isJavaExecutable = true;
        }

        StringBuilder sb = new StringBuilder();

        // special case for inherited method
        if ( isJavaExecutable )
        {
            JavaExecutable javaMethod = (JavaExecutable) entity;

            if ( isInherited( javaMethod ) )
            {
                // QDOX-154 could be empty
                if ( StringUtils.isEmpty( javaMethod.getComment() ) )
                {
                    sb.append( indent ).append( INHERITED_JAVADOC );
                    sb.append( EOL );
                    stringWriter.write( sb.toString() );
                    return;
                }

                String javadoc = getJavadocComment( originalContent, javaMethod );

                // case: /** {@inheritDoc} */ or no tags
                if ( hasInheritedTag( javadoc ) && ( javaMethod.getTags() == null
                    || javaMethod.getTags().isEmpty() ) )
                {
                    sb.append( indent ).append( INHERITED_JAVADOC );
                    sb.append( EOL );
                    stringWriter.write( sb.toString() );
                    return;
                }

                if ( javadoc.contains( START_JAVADOC ) )
                {
                    javadoc = javadoc.substring( javadoc.indexOf( START_JAVADOC ) + START_JAVADOC.length() );
                }
                if ( javadoc.contains( END_JAVADOC ) )
                {
                    javadoc = javadoc.substring( 0, javadoc.indexOf( END_JAVADOC ) );
                }

                sb.append( indent ).append( START_JAVADOC );
                sb.append( EOL );
                if ( !javadoc.contains( INHERITED_TAG ) )
                {
                    sb.append( indent ).append( SEPARATOR_JAVADOC ).append( INHERITED_TAG );
                    sb.append( EOL );
                    appendSeparator( sb, indent );
                }
                javadoc = removeLastEmptyJavadocLines( javadoc );
                javadoc = alignIndentationJavadocLines( javadoc, indent );
                sb.append( javadoc );
                sb.append( EOL );
                if ( javaMethod.getTags() != null )
                {
                    for ( DocletTag docletTag : javaMethod.getTags() )
                    {
                        // Voluntary ignore these tags
                        if ( JavadocUtil.equals( docletTag.getName(), PARAM_TAG, RETURN_TAG, THROWS_TAG ) )
                        {
                            continue;
                        }

                        String s = getJavadocComment( originalContent, entity, docletTag );
                        s = removeLastEmptyJavadocLines( s );
                        s = alignIndentationJavadocLines( s, indent );
                        sb.append( s );
                        sb.append( EOL );
                    }
                }
                sb.append( indent ).append( " " ).append( END_JAVADOC );
                sb.append( EOL );

                if ( hasInheritedTag( sb.toString().trim() ) )
                {
                    sb = new StringBuilder();
                    sb.append( indent ).append( INHERITED_JAVADOC );
                    sb.append( EOL );
                    stringWriter.write( sb.toString() );
                    return;
                }

                stringWriter.write( sb.toString() );
                return;
            }
        }

        sb.append( indent ).append( START_JAVADOC );
        sb.append( EOL );

        // comment
        if ( StringUtils.isNotEmpty( entity.getComment() ) )
        {
            updateJavadocComment( sb, originalContent, entity, indent );
        }
        else
        {
            addDefaultJavadocComment( sb, entity, indent, isJavaExecutable );
        }

        // tags
        if ( entity.getTags() != null && !entity.getTags().isEmpty() )
        {
            updateJavadocTags( sb, originalContent, entity, indent, isJavaExecutable );
        }
        else
        {
            addDefaultJavadocTags( sb, entity, indent, isJavaExecutable );
        }

        sb = new StringBuilder( removeLastEmptyJavadocLines( sb.toString() ) ).append( EOL );

        sb.append( indent ).append( " " ).append( END_JAVADOC );
        sb.append( EOL );

        stringWriter.write( sb.toString() );
    }

    /**
     * @param sb              not null
     * @param originalContent not null
     * @param entity          not null
     * @param indent          not null
     * @throws IOException if any
     */
    private void updateJavadocComment( final StringBuilder sb, final String originalContent,
                                       final JavaAnnotatedElement entity, final String indent )
        throws IOException
    {
        String comment = getJavadocComment( originalContent, entity );
        comment = removeLastEmptyJavadocLines( comment );
        comment = alignIndentationJavadocLines( comment, indent );

        if ( comment.contains( START_JAVADOC ) )
        {
            comment = comment.substring( comment.indexOf( START_JAVADOC ) + START_JAVADOC.length() );
            comment = indent + SEPARATOR_JAVADOC + comment.trim();
        }
        if ( comment.contains( END_JAVADOC ) )
        {
            comment = comment.substring( 0, comment.indexOf( END_JAVADOC ) );
        }

        if ( fixTag( LINK_TAG ) )
        {
            comment = replaceLinkTags( comment, entity );
        }

        String[] lines = getLines( comment );
        for ( String line : lines )
        {
            sb.append( indent ).append( " " ).append( line.trim() );
            sb.append( EOL );
        }
    }

    static String replaceLinkTags( String comment, JavaAnnotatedElement entity )
    {
        StringBuilder resolvedComment = new StringBuilder();
        // scan comment for {@link someClassName} and try to resolve this
        Matcher linktagMatcher = Pattern.compile( "\\{@link\\s" ).matcher( comment );
        int startIndex = 0;
        while ( linktagMatcher.find() )
        {
            int startName = linktagMatcher.end();
            resolvedComment.append( comment, startIndex, startName );
            int endName = comment.indexOf( "}", startName );
            if ( endName >= 0 )
            {
                String name;
                String link = comment.substring( startName, endName );
                int hashIndex = link.indexOf( '#' );
                if ( hashIndex >= 0 )
                {
                    name = link.substring( 0, hashIndex );
                }
                else
                {
                    name = link;
                }
                if ( StringUtils.isNotBlank( name ) )
                {
                    String typeName;
                    if ( entity instanceof JavaClass )
                    {
                        JavaClass clazz = (JavaClass) entity;
                        typeName =
                            TypeResolver.byClassName( clazz.getBinaryName(), clazz.getJavaClassLibrary(),
                                                      clazz.getSource().getImports() ).resolveType( name.trim() );
                    }
                    else if ( entity instanceof JavaMember )
                    {
                        JavaClass clazz = ( (JavaMember) entity ).getDeclaringClass();
                        typeName =
                            TypeResolver.byClassName( clazz.getBinaryName(), clazz.getJavaClassLibrary(),
                                                      clazz.getSource().getImports() ).resolveType( name.trim() );
                    }
                    else
                    {
                        typeName = null;
                    }

                    if ( typeName == null )
                    {
                        typeName = name.trim();
                    }
                    else
                    {
                        typeName = typeName.replaceAll( "\\$", "." );
                    }
                    //adjust name for inner classes
                    resolvedComment.append( typeName );
                }
                if ( hashIndex >= 0 )
                {
                    resolvedComment.append( link.substring( hashIndex ).trim() );
                }
                startIndex = endName;
            }
            else
            {
                startIndex = startName;
            }

        }
        resolvedComment.append( comment.substring( startIndex ) );
        return resolvedComment.toString();

    }

    /**
     * @param sb           not null
     * @param entity       not null
     * @param indent       not null
     * @param isJavaExecutable
     */
    private void addDefaultJavadocComment( final StringBuilder sb, final JavaAnnotatedElement entity,
                                           final String indent, final boolean isJavaExecutable )
    {
        sb.append( indent ).append( SEPARATOR_JAVADOC );
        if ( isJavaExecutable )
        {
            sb.append( getDefaultMethodJavadocComment( (JavaExecutable) entity ) );
        }
        else
        {
            sb.append( getDefaultClassJavadocComment( (JavaClass) entity ) );
        }
        sb.append( EOL );
    }

    /**
     * @param sb              not null
     * @param originalContent not null
     * @param entity          not null
     * @param indent          not null
     * @param isJavaExecutable
     * @throws IOException            if any
     * @throws MojoExecutionException if any
     */
    private void updateJavadocTags( final StringBuilder sb, final String originalContent,
                                    final JavaAnnotatedElement entity, final String indent,
                                    final boolean isJavaExecutable )
        throws IOException, MojoExecutionException
    {
        appendSeparator( sb, indent );

        // parse tags
        JavaEntityTags javaEntityTags = parseJavadocTags( originalContent, entity, indent, isJavaExecutable );

        // update and write tags
        updateJavadocTags( sb, entity, isJavaExecutable, javaEntityTags );

        // add missing tags...
        addMissingJavadocTags( sb, entity, indent, isJavaExecutable, javaEntityTags );
    }

    /**
     * Parse entity tags
     *
     * @param originalContent not null
     * @param entity          not null
     * @param indent          not null
     * @param isJavaMethod
     * @return an instance of {@link JavaEntityTags}
     * @throws IOException if any
     */
    JavaEntityTags parseJavadocTags( final String originalContent, final JavaAnnotatedElement entity,
                                             final String indent, final boolean isJavaMethod )
        throws IOException
    {
        JavaEntityTags javaEntityTags = new JavaEntityTags( entity, isJavaMethod );
        for ( DocletTag docletTag : entity.getTags() )
        {
            String originalJavadocTag = getJavadocComment( originalContent, entity, docletTag );
            originalJavadocTag = removeLastEmptyJavadocLines( originalJavadocTag );
            originalJavadocTag = alignIndentationJavadocLines( originalJavadocTag, indent );

            javaEntityTags.getNamesTags().add( docletTag.getName() );

            if ( isJavaMethod )
            {
                List<String> params = docletTag.getParameters();
                if ( params.size() < 1 )
                {
                    continue;
                }

                String paramName = params.get( 0 );
                switch ( docletTag.getName() ) 
                {
                    case PARAM_TAG:
                        javaEntityTags.putJavadocParamTag( paramName, docletTag.getValue(), originalJavadocTag );
                        break;
                    case RETURN_TAG:
                        javaEntityTags.setJavadocReturnTag( originalJavadocTag );
                        break;
                    case THROWS_TAG:
                        javaEntityTags.putJavadocThrowsTag( paramName, originalJavadocTag );
                        break;
                    default:
                        javaEntityTags.getUnknownTags().add( originalJavadocTag );
                        break;
                }
            }
            else
            {
                javaEntityTags.getUnknownTags().add( originalJavadocTag );
            }
        }

        return javaEntityTags;
    }

    /**
     * Write tags according javaEntityTags.
     *
     * @param sb             not null
     * @param entity         not null
     * @param isJavaExecutable
     * @param javaEntityTags not null
     */
    private void updateJavadocTags( final StringBuilder sb, final JavaAnnotatedElement entity,
                                    final boolean isJavaExecutable, final JavaEntityTags javaEntityTags )
    {
        for ( DocletTag docletTag : entity.getTags() )
        {
            if ( isJavaExecutable )
            {
                JavaExecutable javaExecutable = (JavaExecutable) entity;

                List<String> params = docletTag.getParameters();
                if ( params.size() < 1 )
                {
                    continue;
                }

                if ( docletTag.getName().equals( PARAM_TAG ) )
                {
                    writeParamTag( sb, javaExecutable, javaEntityTags, params.get( 0 ), docletTag.getValue() );
                }
                else if ( docletTag.getName().equals( RETURN_TAG ) && javaExecutable instanceof JavaMethod )
                {
                    writeReturnTag( sb, (JavaMethod) javaExecutable, javaEntityTags );
                }
                else if ( docletTag.getName().equals( THROWS_TAG ) )
                {
                    writeThrowsTag( sb, javaExecutable, javaEntityTags, params );
                }
                else
                {
                    // write unknown tags
                    for ( Iterator<String> it = javaEntityTags.getUnknownTags().iterator(); it.hasNext(); )
                    {
                        String originalJavadocTag = it.next();
                        String simplified = StringUtils.removeDuplicateWhitespace( originalJavadocTag ).trim();

                        if ( simplified.contains( "@" + docletTag.getName() ) )
                        {
                            it.remove();
                            sb.append( originalJavadocTag );
                            sb.append( EOL );
                        }
                    }
                }
            }
            else
            {
                for ( Iterator<String> it = javaEntityTags.getUnknownTags().iterator(); it.hasNext(); )
                {
                    String originalJavadocTag = it.next();
                    String simplified = StringUtils.removeDuplicateWhitespace( originalJavadocTag ).trim();

                    if ( simplified.contains( "@" + docletTag.getName() ) )
                    {
                        it.remove();
                        sb.append( originalJavadocTag );
                        sb.append( EOL );
                    }
                }
            }

            if ( sb.toString().endsWith( EOL ) )
            {
                sb.delete( sb.toString().lastIndexOf( EOL ), sb.toString().length() );
            }

            sb.append( EOL );
        }
    }

    private void writeParamTag( final StringBuilder sb, final JavaExecutable javaExecutable,
                                final JavaEntityTags javaEntityTags, String paramName, String paramValue )
    {
        if ( !fixTag( PARAM_TAG ) )
        {
            // write original param tag if found
            String originalJavadocTag = javaEntityTags.getJavadocParamTag( paramValue );
            if ( originalJavadocTag != null )
            {
                sb.append( originalJavadocTag );
            }
            return;
        }

        boolean found = false;
        JavaParameter javaParam = javaExecutable.getParameterByName( paramName );
        if ( javaParam == null )
        {
            // is generic?
            List<JavaTypeVariable<JavaGenericDeclaration>> typeParams = javaExecutable.getTypeParameters();
            for ( JavaTypeVariable<JavaGenericDeclaration> typeParam : typeParams )
            {
                if ( typeParam.getGenericValue().equals( paramName ) )
                {
                    found = true;
                }
            }
        }
        else
        {
            found = true;
        }

        if ( !found )
        {
            if ( getLog().isWarnEnabled() )
            {
                getLog().warn(
                    "Fixed unknown param '" + paramName + "' defined in " + getJavaMethodAsString( javaExecutable ) );
            }

            if ( sb.toString().endsWith( EOL ) )
            {
                sb.delete( sb.toString().lastIndexOf( EOL ), sb.toString().length() );
            }
        }
        else
        {
            String originalJavadocTag = javaEntityTags.getJavadocParamTag( paramValue );
            if ( originalJavadocTag != null )
            {
                sb.append( originalJavadocTag );
                String s = "@" + PARAM_TAG + " " + paramName;
                if ( StringUtils.removeDuplicateWhitespace( originalJavadocTag ).trim().endsWith( s ) )
                {
                    sb.append( " " );
                    sb.append( getDefaultJavadocForType( javaParam.getJavaClass() ) );
                }
            }
        }
    }

    private void writeReturnTag( final StringBuilder sb, final JavaMethod javaMethod,
                                 final JavaEntityTags javaEntityTags )
    {
        String originalJavadocTag = javaEntityTags.getJavadocReturnTag();
        if ( originalJavadocTag == null )
        {
            return;
        }

        if ( !fixTag( RETURN_TAG ) )
        {
            // write original param tag if found
            sb.append( originalJavadocTag );
            return;
        }

        if ( StringUtils.isNotEmpty( originalJavadocTag ) && javaMethod.getReturns() != null
            && !javaMethod.getReturns().isVoid() )
        {
            sb.append( originalJavadocTag );
            if ( originalJavadocTag.trim().endsWith( "@" + RETURN_TAG ) )
            {
                sb.append( " " );
                sb.append( getDefaultJavadocForType( javaMethod.getReturns() ) );
            }
        }
    }

    void writeThrowsTag( final StringBuilder sb, final JavaExecutable javaExecutable,
                                 final JavaEntityTags javaEntityTags, final List<String> params )
    {
        String exceptionClassName = params.get( 0 );

        String originalJavadocTag = javaEntityTags.getJavadocThrowsTag( exceptionClassName );
        if ( originalJavadocTag == null )
        {
            return;
        }

        if ( !fixTag( THROWS_TAG ) )
        {
            // write original param tag if found
            sb.append( originalJavadocTag );
            return;
        }

        if ( javaExecutable.getExceptions() != null )
        {
            for ( JavaType exception : javaExecutable.getExceptions() )
            {
                if ( exception.getValue().endsWith( exceptionClassName ) )
                {
                    originalJavadocTag = StringUtils.replace( originalJavadocTag, exceptionClassName,
                                                              exception.getFullyQualifiedName() );
                    if ( StringUtils.removeDuplicateWhitespace( originalJavadocTag ).trim().endsWith(
                        "@" + THROWS_TAG + " " + exception.getValue() ) )
                    {
                        originalJavadocTag += " if any.";
                    }

                    sb.append( originalJavadocTag );

                    // added qualified name
                    javaEntityTags.putJavadocThrowsTag( exception.getValue(), originalJavadocTag );

                    return;
                }
            }
        }

        Class<?> clazz = getClass( javaExecutable.getDeclaringClass(), exceptionClassName );
        
        if ( clazz != null )
        {
            if ( RuntimeException.class.isAssignableFrom( clazz ) )
            {
                sb.append( StringUtils.replace( originalJavadocTag, exceptionClassName, clazz.getName() ) );

                // added qualified name
                javaEntityTags.putJavadocThrowsTag( clazz.getName(), originalJavadocTag );
            }
            else if ( Throwable.class.isAssignableFrom( clazz ) )
            {
                getLog().debug( "Removing '" + originalJavadocTag + "'; Throwable not specified by "
                    + getJavaMethodAsString( javaExecutable ) + " and it is not a RuntimeException." );
            }
            else
            {
                getLog().debug( "Removing '" + originalJavadocTag + "'; It is not a Throwable" );
            }
        }
        else if ( removeUnknownThrows )
        {
            getLog().warn( "Ignoring unknown throws '" + exceptionClassName + "' defined on "
                    + getJavaMethodAsString( javaExecutable ) );
        }
        else
        {
            getLog().warn( "Found unknown throws '" + exceptionClassName + "' defined on "
                    + getJavaMethodAsString( javaExecutable ) );
            
            sb.append( originalJavadocTag );
            
            if ( params.size() == 1 )
            {
                sb.append( " if any." );
            }
            
            javaEntityTags.putJavadocThrowsTag( exceptionClassName, originalJavadocTag );
        }
    }

    /**
     * Add missing tags not already written.
     *
     * @param sb             not null
     * @param entity         not null
     * @param indent         not null
     * @param isJavaExecutable
     * @param javaEntityTags not null
     * @throws MojoExecutionException if any
     */
    private void addMissingJavadocTags( final StringBuilder sb, final JavaAnnotatedElement entity,
                                        final String indent, final boolean isJavaExecutable,
                                        final JavaEntityTags javaEntityTags )
        throws MojoExecutionException
    {
        if ( isJavaExecutable )
        {
            JavaExecutable javaExecutable = (JavaExecutable) entity;

            if ( fixTag( PARAM_TAG ) )
            {
                if ( javaExecutable.getParameters() != null )
                {
                    for ( JavaParameter javaParameter : javaExecutable.getParameters() )
                    {
                        if ( !javaEntityTags.hasJavadocParamTag( javaParameter.getName() ) )
                        {
                            appendDefaultParamTag( sb, indent, javaParameter );
                        }
                    }
                }
                // is generic?
                if ( javaExecutable.getTypeParameters() != null )
                {
                    for ( JavaTypeVariable<JavaGenericDeclaration> typeParam : javaExecutable.getTypeParameters() )
                    {
                        if ( !javaEntityTags.hasJavadocParamTag( "<" + typeParam.getName() + ">" ) )
                        {
                            appendDefaultParamTag( sb, indent, typeParam );
                        }
                    }
                }
            }

            if ( javaExecutable instanceof JavaMethod )
            {
                JavaMethod javaMethod = (JavaMethod) javaExecutable; 
                if ( fixTag( RETURN_TAG ) && StringUtils.isEmpty( javaEntityTags.getJavadocReturnTag() )
                    && javaMethod.getReturns() != null && !javaMethod.getReturns().isVoid() )
                {
                    appendDefaultReturnTag( sb, indent, javaMethod );
                }
            }

            if ( fixTag( THROWS_TAG ) && javaExecutable.getExceptions() != null )
            {
                for ( JavaType exception : javaExecutable.getExceptions() )
                {
                    if ( javaEntityTags.getJavadocThrowsTag( exception.getValue(), true ) == null )
                    {
                        appendDefaultThrowsTag( sb, indent, exception );
                    }
                }
            }
        }
        else
        {
            if ( !javaEntityTags.getNamesTags().contains( AUTHOR_TAG ) )
            {
                appendDefaultAuthorTag( sb, indent );
            }
            if ( !javaEntityTags.getNamesTags().contains( VERSION_TAG ) )
            {
                appendDefaultVersionTag( sb, indent );
            }
        }

        if ( fixTag( SINCE_TAG ) && !javaEntityTags.getNamesTags().contains( SINCE_TAG ) )
        {
            if ( !isJavaExecutable )
            {
                if ( !ignoreClirr )
                {
                    if ( isNewClassFromLastVersion( (JavaClass) entity ) )
                    {
                        appendDefaultSinceTag( sb, indent );
                    }
                }
                else
                {
                    appendDefaultSinceTag( sb, indent );
                    addSinceClasses( (JavaClass) entity );
                }
            }
            else
            {
                if ( !ignoreClirr )
                {
                    if ( isNewMethodFromLastRevision( (JavaExecutable) entity ) )
                    {
                        appendDefaultSinceTag( sb, indent );
                    }
                }
                else if ( sinceClasses != null )
                {
                    if ( entity instanceof JavaMember
                        && !sinceClassesContains( ( (JavaMember) entity ).getDeclaringClass() ) )
                    {
                        appendDefaultSinceTag( sb, indent );
                    }
                    else if ( entity instanceof JavaClass
                        && !sinceClassesContains( ( (JavaClass) entity ).getDeclaringClass() ) )
                    {
                        appendDefaultSinceTag( sb, indent );
                    }
                }
            }
        }
    }

    /**
     * @param sb           not null
     * @param entity       not null
     * @param indent       not null
     * @param isJavaExecutable
     * @throws MojoExecutionException if any
     */
    private void addDefaultJavadocTags( final StringBuilder sb, final JavaAnnotatedElement entity,
                                        final String indent, final boolean isJavaExecutable )
        throws MojoExecutionException
    {
        boolean separatorAdded = false;
        if ( isJavaExecutable )
        {
            JavaExecutable javaExecutable = (JavaExecutable) entity;

            if ( fixTag( PARAM_TAG ) && javaExecutable.getParameters() != null )
            {
                for ( JavaParameter javaParameter : javaExecutable.getParameters() )
                {
                    separatorAdded = appendDefaultParamTag( sb, indent, separatorAdded, javaParameter );
                }
            }

            if ( javaExecutable instanceof JavaMethod && fixTag( RETURN_TAG ) )
            {
                JavaMethod javaMethod = (JavaMethod) javaExecutable;
                if ( javaMethod.getReturns() != null && !javaMethod.getReturns().isVoid() )
                {
                    separatorAdded = appendDefaultReturnTag( sb, indent, separatorAdded, javaMethod );
                }
            }

            if ( fixTag( THROWS_TAG ) && javaExecutable.getExceptions() != null )
            {
                for ( JavaType exception : javaExecutable.getExceptions() )
                {
                    separatorAdded = appendDefaultThrowsTag( sb, indent, separatorAdded, exception );
                }
            }
        }
        else
        {
            separatorAdded = appendDefaultAuthorTag( sb, indent, separatorAdded );

            separatorAdded = appendDefaultVersionTag( sb, indent, separatorAdded );
        }

        if ( fixTag( SINCE_TAG ) )
        {
            if ( !isJavaExecutable )
            {
                JavaClass javaClass = (JavaClass) entity;

                if ( !ignoreClirr )
                {
                    if ( isNewClassFromLastVersion( javaClass ) )
                    {
                        separatorAdded = appendDefaultSinceTag( sb, indent, separatorAdded );
                    }
                }
                else
                {
                    separatorAdded = appendDefaultSinceTag( sb, indent, separatorAdded );

                    addSinceClasses( javaClass );
                }
            }
            else
            {
                JavaExecutable javaExecutable = (JavaExecutable) entity;

                if ( !ignoreClirr )
                {
                    if ( isNewMethodFromLastRevision( javaExecutable ) )
                    {
                        separatorAdded = appendDefaultSinceTag( sb, indent, separatorAdded );
                    }
                }
                else
                {
                    if ( sinceClasses != null && !sinceClassesContains( javaExecutable.getDeclaringClass() ) )
                    {
                        separatorAdded = appendDefaultSinceTag( sb, indent, separatorAdded );
                    }
                }
            }
        }
    }

    /**
     * @param sb             not null
     * @param indent         not null
     * @param separatorAdded
     * @return true if separator has been added.
     */
    private boolean appendDefaultAuthorTag( final StringBuilder sb, final String indent, boolean separatorAdded )
    {
        if ( !fixTag( AUTHOR_TAG ) )
        {
            return separatorAdded;
        }

        if ( !separatorAdded )
        {
            appendSeparator( sb, indent );
            separatorAdded = true;
        }

        appendDefaultAuthorTag( sb, indent );
        return separatorAdded;
    }

    /**
     * @param sb     not null
     * @param indent not null
     */
    private void appendDefaultAuthorTag( final StringBuilder sb, final String indent )
    {
        if ( !fixTag( AUTHOR_TAG ) )
        {
            return;
        }

        sb.append( indent ).append( " * @" ).append( AUTHOR_TAG ).append( " " );
        sb.append( defaultAuthor );
        sb.append( EOL );
    }

    /**
     * @param sb             not null
     * @param indent         not null
     * @param separatorAdded
     * @return true if separator has been added.
     */
    private boolean appendDefaultSinceTag( final StringBuilder sb, final String indent, boolean separatorAdded )
    {
        if ( !fixTag( SINCE_TAG ) )
        {
            return separatorAdded;
        }

        if ( !separatorAdded )
        {
            appendSeparator( sb, indent );
            separatorAdded = true;
        }

        appendDefaultSinceTag( sb, indent );
        return separatorAdded;
    }

    /**
     * @param sb     not null
     * @param indent not null
     */
    private void appendDefaultSinceTag( final StringBuilder sb, final String indent )
    {
        if ( !fixTag( SINCE_TAG ) )
        {
            return;
        }

        sb.append( indent ).append( " * @" ).append( SINCE_TAG ).append( " " );
        sb.append( defaultSince );
        sb.append( EOL );
    }

    /**
     * @param sb             not null
     * @param indent         not null
     * @param separatorAdded
     * @return true if separator has been added.
     */
    private boolean appendDefaultVersionTag( final StringBuilder sb, final String indent, boolean separatorAdded )
    {
        if ( !fixTag( VERSION_TAG ) )
        {
            return separatorAdded;
        }

        if ( !separatorAdded )
        {
            appendSeparator( sb, indent );
            separatorAdded = true;
        }

        appendDefaultVersionTag( sb, indent );
        return separatorAdded;
    }

    /**
     * @param sb     not null
     * @param indent not null
     */
    private void appendDefaultVersionTag( final StringBuilder sb, final String indent )
    {
        if ( !fixTag( VERSION_TAG ) )
        {
            return;
        }

        sb.append( indent ).append( " * @" ).append( VERSION_TAG ).append( " " );
        sb.append( defaultVersion );
        sb.append( EOL );
    }

    /**
     * @param sb             not null
     * @param indent         not null
     * @param separatorAdded
     * @param typeParam  not null
     * @return true if separator has been added.
     */
    private boolean appendDefaultParamTag( final StringBuilder sb, final String indent, boolean separatorAdded,
                                           final JavaParameter typeParam )
    {
        if ( !fixTag( PARAM_TAG ) )
        {
            return separatorAdded;
        }

        if ( !separatorAdded )
        {
            appendSeparator( sb, indent );
            separatorAdded = true;
        }

        appendDefaultParamTag( sb, indent, typeParam );
        return separatorAdded;
    }

    /**
     * @param sb             not null
     * @param indent         not null
     * @param separatorAdded
     * @param typeParameter  not null
     * @return true if separator has been added.
     */
    private boolean appendDefaultParamTag( final StringBuilder sb, final String indent, boolean separatorAdded,
                                           final JavaTypeVariable<JavaGenericDeclaration> typeParameter )
    {
        if ( !fixTag( PARAM_TAG ) )
        {
            return separatorAdded;
        }

        if ( !separatorAdded )
        {
            appendSeparator( sb, indent );
            separatorAdded = true;
        }

        appendDefaultParamTag( sb, indent, typeParameter );
        return separatorAdded;
    }

    /**
     * @param sb            not null
     * @param indent        not null
     * @param typeParam not null
     */
    private void appendDefaultParamTag( final StringBuilder sb, final String indent, final JavaParameter typeParam )
    {
        if ( !fixTag( PARAM_TAG ) )
        {
            return;
        }

        sb.append( indent ).append( " * @" ).append( PARAM_TAG ).append( " " );
        sb.append( typeParam.getName() );
        sb.append( " " );
        sb.append( getDefaultJavadocForType( typeParam.getJavaClass() ) );
        sb.append( EOL );
    }

    /**
     * @param sb            not null
     * @param indent        not null
     * @param typeParameter not null
     */
    private void appendDefaultParamTag( final StringBuilder sb, final String indent,
                                        final JavaTypeVariable<JavaGenericDeclaration> typeParameter )
    {
        if ( !fixTag( PARAM_TAG ) )
        {
            return;
        }

        sb.append( indent ).append( " * @" ).append( PARAM_TAG ).append( " " );
        sb.append( "<" ).append( typeParameter.getName() ).append( ">" );
        sb.append( " " );
        sb.append( getDefaultJavadocForType( typeParameter ) );
        sb.append( EOL );
    }

    /**
     * @param sb             not null
     * @param indent         not null
     * @param separatorAdded
     * @param javaMethod     not null
     * @return true if separator has been added.
     */
    private boolean appendDefaultReturnTag( final StringBuilder sb, final String indent, boolean separatorAdded,
                                            final JavaMethod javaMethod )
    {
        if ( !fixTag( RETURN_TAG ) )
        {
            return separatorAdded;
        }

        if ( !separatorAdded )
        {
            appendSeparator( sb, indent );
            separatorAdded = true;
        }

        appendDefaultReturnTag( sb, indent, javaMethod );
        return separatorAdded;
    }

    /**
     * @param sb         not null
     * @param indent     not null
     * @param javaMethod not null
     */
    private void appendDefaultReturnTag( final StringBuilder sb, final String indent, final JavaMethod javaMethod )
    {
        if ( !fixTag( RETURN_TAG ) )
        {
            return;
        }

        sb.append( indent ).append( " * @" ).append( RETURN_TAG ).append( " " );
        sb.append( getDefaultJavadocForType( javaMethod.getReturns() ) );
        sb.append( EOL );
    }

    /**
     * @param sb             not null
     * @param indent         not null
     * @param separatorAdded
     * @param exception      not null
     * @return true if separator has been added.
     */
    private boolean appendDefaultThrowsTag( final StringBuilder sb, final String indent, boolean separatorAdded,
                                            final JavaType exception )
    {
        if ( !fixTag( THROWS_TAG ) )
        {
            return separatorAdded;
        }

        if ( !separatorAdded )
        {
            appendSeparator( sb, indent );
            separatorAdded = true;
        }

        appendDefaultThrowsTag( sb, indent, exception );
        return separatorAdded;
    }

    /**
     * @param sb        not null
     * @param indent    not null
     * @param exception not null
     */
    private void appendDefaultThrowsTag( final StringBuilder sb, final String indent, final JavaType exception )
    {
        if ( !fixTag( THROWS_TAG ) )
        {
            return;
        }

        sb.append( indent ).append( " * @" ).append( THROWS_TAG ).append( " " );
        sb.append( exception.getFullyQualifiedName() );
        sb.append( " if any." );
        sb.append( EOL );
    }

    /**
     * @param sb     not null
     * @param indent not null
     */
    private void appendSeparator( final StringBuilder sb, final String indent )
    {
        sb.append( indent ).append( " *" );
        sb.append( EOL );
    }

    /**
     * Verify if a method has <code>&#64;java.lang.Override()</code> annotation or if it is an inherited method
     * from an interface or a super class. The goal is to handle <code>&#123;&#64;inheritDoc&#125;</code> tag.
     *
     * @param javaMethod not null
     * @return <code>true</code> if the method is inherited, <code>false</code> otherwise.
     * @throws MojoExecutionException if any
     */
    private boolean isInherited( JavaExecutable javaMethod )
        throws MojoExecutionException
    {
        if ( javaMethod.getAnnotations() != null )
        {
            for ( JavaAnnotation annotation : javaMethod.getAnnotations() )
            {
                if ( annotation.toString().equals( "@java.lang.Override()" ) )
                {
                    return true;
                }
            }
        }

        Class<?> clazz = getClass( javaMethod.getDeclaringClass().getFullyQualifiedName() );

        List<Class<?>> interfaces = ClassUtils.getAllInterfaces( clazz );
        for ( Class<?> intface : interfaces )
        {
            if ( isInherited( intface, javaMethod ) )
            {
                return true;
            }
        }

        List<Class<?>> classes = ClassUtils.getAllSuperclasses( clazz );
        for ( Class<?> superClass : classes )
        {
            if ( isInherited( superClass, javaMethod ) )
            {
                return true;
            }
        }

        return false;
    }

    /**
     * @param clazz      the Java class object, not null
     * @param javaMethod the QDox JavaMethod object not null
     * @return <code>true</code> if <code>javaMethod</code> exists in the given <code>clazz</code>,
     *         <code>false</code> otherwise.
     * @see #isInherited(JavaExecutable)
     */
    private boolean isInherited( Class<?> clazz, JavaExecutable javaMethod )
    {
        for ( Method method : clazz.getDeclaredMethods() )
        {
            if ( !method.getName().equals( javaMethod.getName() ) )
            {
                continue;
            }

            if ( method.getParameterTypes().length != javaMethod.getParameters().size() )
            {
                continue;
            }

            boolean found = false;
            int j = 0;
            for ( Class<?> paramType : method.getParameterTypes() )
            {
                String name1 = paramType.getName();
                String name2 = javaMethod.getParameters().get( j++ ).getType().getFullyQualifiedName();
                found = name1.equals( name2 ); // TODO check algo, seems broken (only takes in account the last param)
            }

            return found;
        }

        return false;
    }

    /**
     * @param clazz
     * @return
     */
    private String getDefaultJavadocForType( JavaClass clazz )
    {
        StringBuilder sb = new StringBuilder();

        if ( !JavaTypeVariable.class.isAssignableFrom( clazz.getClass() ) && clazz.isPrimitive() )
        {
            if ( clazz.isArray() )
            {
                sb.append( "an array of " ).append( clazz.getComponentType().getCanonicalName() );
            }
            else
            {
                sb.append( "a " ).append( clazz.getCanonicalName() );
            }
            return sb.append( "." ).toString();
        }

        StringBuilder javadocLink = new StringBuilder();
        try
        {
            getClass( clazz.getCanonicalName() );

            javadocLink.append( "{@link " );
            
            if ( clazz.isArray() )
            {
                javadocLink.append( clazz.getComponentType().getCanonicalName() );
            }
            else
            {
                javadocLink.append( clazz.getCanonicalName() );
            }
            javadocLink.append( "}" );
        }
        catch ( Exception e )
        {
            javadocLink.append( clazz.getValue() );
        }

        if ( clazz.isArray() )
        {
            sb.append( "an array of " ).append( javadocLink ).append( " objects." );
        }
        else
        {
            sb.append( "a " ).append( javadocLink ).append( " object." );
        }

        return sb.toString();
    }
    
    private String getDefaultJavadocForType( JavaTypeVariable<JavaGenericDeclaration> typeParameter )
    {
        return "a " + typeParameter.getName() + " object.";
    }

    /**
     * Check under Clirr if this given class is newer from the last version.
     *
     * @param javaClass a given class not null
     * @return <code>true</code> if Clirr said that this class is added from the last version,
     *         <code>false</code> otherwise or if {@link #clirrNewClasses} is null.
     */
    private boolean isNewClassFromLastVersion( JavaClass javaClass )
    {
        return ( clirrNewClasses != null ) && clirrNewClasses.contains( javaClass.getFullyQualifiedName() );
    }

    /**
     * Check under Clirr if this given method is newer from the last version.
     *
     * @param javaExecutable a given method not null
     * @return <code>true</code> if Clirr said that this method is added from the last version,
     *         <code>false</code> otherwise or if {@link #clirrNewMethods} is null.
     * @throws MojoExecutionException if any
     */
    private boolean isNewMethodFromLastRevision( JavaExecutable javaExecutable )
        throws MojoExecutionException
    {
        if ( clirrNewMethods == null )
        {
            return false;
        }

        List<String> clirrMethods = clirrNewMethods.get( javaExecutable.getDeclaringClass().getFullyQualifiedName() );
        if ( clirrMethods == null )
        {
            return false;
        }

        for ( String clirrMethod : clirrMethods )
        {
            // see net.sf.clirr.core.internal.checks.MethodSetCheck#getMethodId(JavaType clazz, Method method)
            String retrn = "";
            if ( javaExecutable instanceof JavaMethod && ( (JavaMethod) javaExecutable ).getReturns() != null )
            {
                retrn = ( (JavaMethod) javaExecutable ).getReturns().getFullyQualifiedName();
            }
            StringBuilder params = new StringBuilder();
            for ( JavaParameter parameter : javaExecutable.getParameters() )
            {
                if ( params.length() > 0 )
                {
                    params.append( ", " );
                }
                params.append( parameter.getResolvedFullyQualifiedName() );
            }
            if ( clirrMethod.contains( retrn + " " ) && clirrMethod.contains( javaExecutable.getName() + "(" )
                && clirrMethod.contains( "(" + params.toString() + ")" ) )
            {
                return true;
            }
        }

        return false;
    }

    /**
     * @param className not null
     * @return the Class corresponding to the given class name using the project classloader.
     * @throws MojoExecutionException if class not found
     * @see ClassUtils#getClass(ClassLoader, String, boolean)
     * @see #getProjectClassLoader()
     */
    private Class<?> getClass( String className )
        throws MojoExecutionException
    {
        try
        {
            return ClassUtils.getClass( getProjectClassLoader(), className, false );
        }
        catch ( ClassNotFoundException e )
        {
            throw new MojoExecutionException( "ClassNotFoundException: " + e.getMessage(), e );
        }
    }

    /**
     * Returns the Class object assignable for {@link RuntimeException} class and associated with the given
     * exception class name.
     *
     * @param currentClass       not null
     * @param exceptionClassName not null, an exception class name defined as:
     *                           <ul>
     *                           <li>exception class fully qualified</li>
     *                           <li>exception class in the same package</li>
     *                           <li>exception inner class</li>
     *                           <li>exception class in java.lang package</li>
     *                           </ul>
     * @return the class if found, otherwise {@code null}.
     * @see #getClass(String)
     */
    private Class<?> getClass( JavaClass currentClass, String exceptionClassName )
    {
        String[] potentialClassNames =
            new String[]{ exceptionClassName, currentClass.getPackage().getName() + "." + exceptionClassName,
                currentClass.getPackage().getName() + "." + currentClass.getName() + "$" + exceptionClassName,
                "java.lang." + exceptionClassName };

        Class<?> clazz = null;
        for ( String potentialClassName : potentialClassNames )
        {
            try
            {
                clazz = getClass( potentialClassName );
            }
            catch ( MojoExecutionException e )
            {
                // nop
            }
            if ( clazz != null )
            {
                return clazz;
            }
        }

        return null;
    }

    /**
     * @param javaClass not null
     */
    private void addSinceClasses( JavaClass javaClass )
    {
        if ( sinceClasses == null )
        {
            sinceClasses = new ArrayList<>();
        }
        sinceClasses.add( javaClass.getFullyQualifiedName() );
    }

    private boolean sinceClassesContains( JavaClass javaClass )
    {
        return sinceClasses.contains( javaClass.getFullyQualifiedName() );
    }

    // ----------------------------------------------------------------------
    // Static methods
    // ----------------------------------------------------------------------

    /**
     * Write content into the given javaFile and using the given encoding.
     * All line separators will be unified.
     *
     * @param javaFile not null
     * @param encoding not null
     * @param content  not null
     * @throws IOException if any
     */
    private static void writeFile( final File javaFile, final String encoding, final String content )
        throws IOException
    {
        String unified = StringUtils.unifyLineSeparators( content );
        FileUtils.fileWrite( javaFile, encoding, unified );
    }

    /**
     * @return the full clirr goal, i.e. <code>groupId:artifactId:version:goal</code>. The clirr-plugin version
     *         could be load from the pom.properties in the clirr-maven-plugin dependency.
     */
    private static String getFullClirrGoal()
    {
        StringBuilder sb = new StringBuilder();

        sb.append( CLIRR_MAVEN_PLUGIN_GROUPID ).append( ":" ).append( CLIRR_MAVEN_PLUGIN_ARTIFACTID ).append( ":" );

        String clirrVersion = CLIRR_MAVEN_PLUGIN_VERSION;
        InputStream resourceAsStream = null;
        try
        {
            String resource = "META-INF/maven/" + CLIRR_MAVEN_PLUGIN_GROUPID + "/" + CLIRR_MAVEN_PLUGIN_ARTIFACTID
                + "/pom.properties";
            resourceAsStream = AbstractFixJavadocMojo.class.getClassLoader().getResourceAsStream( resource );

            if ( resourceAsStream != null )
            {
                Properties properties = new Properties();
                properties.load( resourceAsStream );
                resourceAsStream.close();
                resourceAsStream = null;
                if ( StringUtils.isNotEmpty( properties.getProperty( "version" ) ) )
                {
                    clirrVersion = properties.getProperty( "version" );
                }
            }
        }
        catch ( IOException e )
        {
            // nop
        }
        finally
        {
            IOUtil.close( resourceAsStream );
        }

        sb.append( clirrVersion ).append( ":" ).append( CLIRR_MAVEN_PLUGIN_GOAL );

        return sb.toString();
    }

    /**
     * Default comment for class.
     *
     * @param javaClass not null
     * @return a default comment for class.
     */
    private static String getDefaultClassJavadocComment( final JavaClass javaClass )
    {
        StringBuilder sb = new StringBuilder();

        sb.append( "<p>" );
        if ( javaClass.isAbstract() )
        {
            sb.append( "Abstract " );
        }

        sb.append( javaClass.getName() );

        if ( !javaClass.isInterface() )
        {
            sb.append( " class." );
        }
        else
        {
            sb.append( " interface." );
        }

        sb.append( "</p>" );

        return sb.toString();
    }

    /**
     * Default comment for method with taking care of getter/setter in the javaMethod name.
     *
     * @param javaExecutable not null
     * @return a default comment for method.
     */
    private static String getDefaultMethodJavadocComment( final JavaExecutable javaExecutable )
    {
        if ( javaExecutable instanceof JavaConstructor )
        {
            return "<p>Constructor for " + javaExecutable.getName() + ".</p>";
        }
        
        if ( javaExecutable.getName().length() > 3 && ( javaExecutable.getName().startsWith( "get" )
            || javaExecutable.getName().startsWith( "set" ) ) )
        {
            String field = StringUtils.lowercaseFirstLetter( javaExecutable.getName().substring( 3 ) );

            JavaClass clazz = javaExecutable.getDeclaringClass();

            if ( clazz.getFieldByName( field ) == null )
            {
                return "<p>" + javaExecutable.getName() + ".</p>";
            }

            StringBuilder sb = new StringBuilder();

            sb.append( "<p>" );
            if ( javaExecutable.getName().startsWith( "get" ) )
            {
                sb.append( "Getter " );
            }
            else if ( javaExecutable.getName().startsWith( "set" ) )
            {
                sb.append( "Setter " );
            }
            sb.append( "for the field <code>" ).append( field ).append( "</code>.</p>" );

            return sb.toString();
        }

        return "<p>" + javaExecutable.getName() + ".</p>";
    }

    /**
     * Try to find if a Javadoc comment has an {@link #INHERITED_TAG} for instance:
     * <pre>
     * &#47;&#42;&#42; {&#64;inheritDoc} &#42;&#47;
     * </pre>
     * or
     * <pre>
     * &#47;&#42;&#42;
     * &#32;&#42; {&#64;inheritDoc}
     * &#32;&#42;&#47;
     * </pre>
     *
     * @param content not null
     * @return <code>true</code> if the content has an inherited tag, <code>false</code> otherwise.
     */
    private static boolean hasInheritedTag( final String content )
    {
        final String inheritedTagPattern =
            "^\\s*(\\/\\*\\*)?(\\s*(\\*)?)*(\\{)@inheritDoc\\s*(\\})(\\s*(\\*)?)*(\\*\\/)?$";
        return Pattern.matches( inheritedTagPattern, StringUtils.removeDuplicateWhitespace( content ) );
    }

    /**
     * Workaround for QDOX-146 about whitespace.
     * Ideally we want to use <code>entity.getComment()</code>
     * <br/>
     * For instance, with the following snippet:
     * <br/>
     * <p/>
     * <code>
     * <font color="#808080">1</font>&nbsp;<font color="#ffffff"></font><br />
     * <font color="#808080">2</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#47;&#42;&#42;</font><br />
     * <font color="#808080">3</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;Dummy&nbsp;Javadoc&nbsp;comment.</font><br />
     * <font color="#808080">4</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;</font><font color="#7f9fbf">@param&nbsp;</font>
     * <font color="#3f5fbf">s&nbsp;a&nbsp;String</font><br />
     * <font color="#808080">5</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&#47;</font><br />
     * <font color="#808080">6</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#7f0055"><b>public&nbsp;</b></font><font color="#7f0055"><b>void&nbsp;</b></font>
     * <font color="#000000">dummyMethod</font><font color="#000000">(&nbsp;</font>
     * <font color="#000000">String&nbsp;s&nbsp;</font><font color="#000000">){}</font><br />
     * </code>
     * <p/>
     * <br/>
     * The return will be:
     * <br/>
     * <p/>
     * <code>
     * <font color="#808080">1</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;Dummy&nbsp;Javadoc&nbsp;comment.</font><br />
     * </code>
     *
     * @param javaClassContent original class content not null
     * @param entity           not null
     * @return the javadoc comment for the entity without any tags.
     * @throws IOException if any
     */
    static String getJavadocComment( final String javaClassContent, final JavaAnnotatedElement entity )
        throws IOException
    {
        if ( entity.getComment() == null )
        {
            return "";
        }

        String originalJavadoc = extractOriginalJavadocContent( javaClassContent, entity );

        StringBuilder sb = new StringBuilder();
        BufferedReader lr = new BufferedReader( new StringReader( originalJavadoc ) );
        String line;
        while ( ( line = lr.readLine() ) != null )
        {
            String l = StringUtils.removeDuplicateWhitespace( line.trim() );
            if ( l.startsWith( "* @" ) || l.startsWith( "*@" ) )
            {
                break;
            }
            sb.append( line ).append( EOL );
        }

        return trimRight( sb.toString() );
    }

    /**
     * Work around for QDOX-146 about whitespace.
     * Ideally we want to use <code>docletTag.getValue()</code>
     * <br/>
     * For instance, with the following snippet:
     * <br/>
     * <p/>
     * <code>
     * <font color="#808080">1</font>&nbsp;<font color="#ffffff"></font><br />
     * <font color="#808080">2</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#47;&#42;&#42;</font><br />
     * <font color="#808080">3</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;Dummy&nbsp;Javadoc&nbsp;comment.</font><br />
     * <font color="#808080">4</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;</font><font color="#7f9fbf">@param&nbsp;</font>
     * <font color="#3f5fbf">s&nbsp;a&nbsp;String</font><br />
     * <font color="#808080">5</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&#47;</font><br />
     * <font color="#808080">6</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#7f0055"><b>public&nbsp;</b></font><font color="#7f0055"><b>void&nbsp;</b></font>
     * <font color="#000000">dummyMethod</font><font color="#000000">(&nbsp;</font>
     * <font color="#000000">String&nbsp;s&nbsp;</font><font color="#000000">){}</font><br />
     * </code>
     * <p/>
     * <br/>
     * The return will be:
     * <br/>
     * <p/>
     * <code>
     * <font color="#808080">1</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;</font><font color="#7f9fbf">@param&nbsp;</font>
     * <font color="#3f5fbf">s&nbsp;a&nbsp;String</font><br />
     * </code>
     *
     * @param javaClassContent original class content not null
     * @param entity           not null
     * @param docletTag        not null
     * @return the javadoc comment for the entity without Javadoc tags.
     * @throws IOException if any
     */
    String getJavadocComment( final String javaClassContent, final JavaAnnotatedElement entity,
                                      final DocletTag docletTag )
        throws IOException
    {
        if ( docletTag.getValue() == null || docletTag.getParameters().isEmpty() )
        {
            return "";
        }

        String originalJavadoc = extractOriginalJavadocContent( javaClassContent, entity );

        StringBuilder sb = new StringBuilder();
        BufferedReader lr = new BufferedReader( new StringReader( originalJavadoc ) );
        String line;
        boolean found = false;
        
        // matching first line of doclettag
        Pattern p = Pattern.compile( "(\\s*\\*\\s?@" + docletTag.getName() + ")\\s+"
            + "(\\Q" + docletTag.getValue().split( "\r\n|\r|\n" )[0] + "\\E)" );
        
        while ( ( line = lr.readLine() ) != null )
        {
            Matcher m = p.matcher( line );
            if ( m.matches() )
            {
                if ( fixTag( LINK_TAG ) )
                {
                    line = replaceLinkTags( line, entity );
                }
                sb.append( line ).append( EOL );
                found = true;
            }
            else
            {
                if ( line.trim().startsWith( "* @" ) || line.trim().startsWith( "*@" ) )
                {
                    found = false;
                }
                if ( found )
                {
                    if ( fixTag( LINK_TAG ) )
                    {
                        line = replaceLinkTags( line, entity );
                    }
                    sb.append( line ).append( EOL );
                }
            }
        }

        return trimRight( sb.toString() );
    }

    /**
     * Extract the original Javadoc and others comments up to {@link #START_JAVADOC} form the entity. This method
     * takes care of the Javadoc indentation. All javadoc lines will be trimmed on right.
     * <br/>
     * For instance, with the following snippet:
     * <br/>
     * <p/>
     * <code>
     * <font color="#808080">1</font>&nbsp;<font color="#ffffff"></font><br />
     * <font color="#808080">2</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#47;&#42;&#42;</font><br />
     * <font color="#808080">3</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;Dummy&nbsp;Javadoc&nbsp;comment.</font><br />
     * <font color="#808080">4</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;</font><font color="#7f9fbf">@param&nbsp;</font>
     * <font color="#3f5fbf">s&nbsp;a&nbsp;String</font><br />
     * <font color="#808080">5</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&#47;</font><br />
     * <font color="#808080">6</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#7f0055"><b>public&nbsp;</b></font><font color="#7f0055"><b>void&nbsp;</b></font>
     * <font color="#000000">dummyMethod</font><font color="#000000">(&nbsp;</font>
     * <font color="#000000">String&nbsp;s&nbsp;</font><font color="#000000">){}</font><br />
     * </code>
     * <p/>
     * <br/>
     * The return will be:
     * <br/>
     * <p/>
     * <code>
     * <font color="#808080">1</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#47;&#42;&#42;</font><br />
     * <font color="#808080">2</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;Dummy&nbsp;Javadoc&nbsp;comment.</font><br />
     * <font color="#808080">3</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;</font><font color="#7f9fbf">@param&nbsp;</font>
     * <font color="#3f5fbf">s&nbsp;a&nbsp;String</font><br />
     * <font color="#808080">4</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&#47;</font><br />
     * </code>
     *
     * @param javaClassContent not null
     * @param entity           not null
     * @return return the original javadoc as String for the current entity
     * @throws IOException if any
     */
    static String extractOriginalJavadoc( final String javaClassContent, final JavaAnnotatedElement entity )
        throws IOException
    {
        if ( entity.getComment() == null )
        {
            return "";
        }

        String[] javaClassContentLines = getLines( javaClassContent );
        List<String> list = new LinkedList<>();
        for ( int i = entity.getLineNumber() - 2; i >= 0; i-- )
        {
            String line = javaClassContentLines[i];

            list.add( trimRight( line ) );
            if ( line.trim().startsWith( START_JAVADOC ) )
            {
                break;
            }
        }

        Collections.reverse( list );

        return StringUtils.join( list.iterator(), EOL );
    }

    /**
     * Extract the Javadoc comment between {@link #START_JAVADOC} and {@link #END_JAVADOC} form the entity. This method
     * takes care of the Javadoc indentation. All javadoc lines will be trimmed on right.
     * <br/>
     * For instance, with the following snippet:
     * <br/>
     * <p/>
     * <code>
     * <font color="#808080">1</font>&nbsp;<font color="#ffffff"></font><br />
     * <font color="#808080">2</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#47;&#42;&#42;</font><br />
     * <font color="#808080">3</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;Dummy&nbsp;Javadoc&nbsp;comment.</font><br />
     * <font color="#808080">4</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;</font><font color="#7f9fbf">@param&nbsp;</font>
     * <font color="#3f5fbf">s&nbsp;a&nbsp;String</font><br />
     * <font color="#808080">5</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&#47;</font><br />
     * <font color="#808080">6</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#7f0055"><b>public&nbsp;</b></font><font color="#7f0055"><b>void&nbsp;</b></font>
     * <font color="#000000">dummyMethod</font><font color="#000000">(&nbsp;</font>
     * <font color="#000000">String&nbsp;s&nbsp;</font><font color="#000000">){}</font><br />
     * </code>
     * <p/>
     * <br/>
     * The return will be:
     * <br/>
     * <p/>
     * <code>
     * <font color="#808080">1</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;Dummy&nbsp;Javadoc&nbsp;comment.</font><br />
     * <font color="#808080">2</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font>
     * <font color="#3f5fbf">&#42;&nbsp;</font><font color="#7f9fbf">@param&nbsp;</font>
     * <font color="#3f5fbf">s&nbsp;a&nbsp;String</font><br />
     * </code>
     *
     * @param javaClassContent not null
     * @param entity           not null
     * @return return the original javadoc as String for the current entity
     * @throws IOException if any
     */
    static String extractOriginalJavadocContent( final String javaClassContent,
                                                         final JavaAnnotatedElement entity )
        throws IOException
    {
        if ( entity.getComment() == null )
        {
            return "";
        }

        String originalJavadoc = extractOriginalJavadoc( javaClassContent, entity );
        int index = originalJavadoc.indexOf( START_JAVADOC );
        if ( index != -1 )
        {
            originalJavadoc = originalJavadoc.substring( index + START_JAVADOC.length() );
        }
        index = originalJavadoc.indexOf( END_JAVADOC );
        if ( index != -1 )
        {
            originalJavadoc = originalJavadoc.substring( 0, index );
        }
        if ( originalJavadoc.startsWith( "\r\n" ) )
        {
            originalJavadoc = originalJavadoc.substring( 2 );
        }
        else if ( originalJavadoc.startsWith( "\n" ) || originalJavadoc.startsWith( "\r" ) )
        {
            originalJavadoc = originalJavadoc.substring( 1 );
        }

        return trimRight( originalJavadoc );
    }

    /**
     * @param content not null
     * @return the content without last lines containing javadoc separator (ie <code> * </code>)
     * @throws IOException if any
     * @see #getJavadocComment(String, JavaAnnotatedElement, DocletTag)
     */
    private static String removeLastEmptyJavadocLines( final String content )
        throws IOException
    {
        if ( !content.contains( EOL ) )
        {
            return content;
        }

        String[] lines = getLines( content );
        if ( lines.length == 1 )
        {
            return content;
        }

        List<String> linesList = new LinkedList<>( Arrays.asList( lines ) );

        Collections.reverse( linesList );

        for ( Iterator<String> it = linesList.iterator(); it.hasNext(); )
        {
            String line = it.next();

            if ( line.trim().equals( "*" ) )
            {
                it.remove();
            }
            else
            {
                break;
            }
        }

        Collections.reverse( linesList );

        return StringUtils.join( linesList.iterator(), EOL );
    }

    /**
     * @param content not null
     * @return the javadoc comment with the given indentation
     * @throws IOException if any
     * @see #getJavadocComment(String, JavaAnnotatedElement, DocletTag)
     */
    private static String alignIndentationJavadocLines( final String content, final String indent )
        throws IOException
    {
        StringBuilder sb = new StringBuilder();
        for ( String line : getLines( content ) )
        {
            if ( sb.length() > 0 )
            {
                sb.append( EOL );
            }
            if ( !line.trim().startsWith( "*" ) )
            {
                line = "*" + line;
            }
            sb.append( indent ).append( " " ).append( trimLeft( line ) );
        }

        return sb.toString();
    }

    /**
     * Autodetect the indentation of a given line:
     * <pre>
     * autodetectIndentation( null ) = "";
     * autodetectIndentation( "a" ) = "";
     * autodetectIndentation( "    a" ) = "    ";
     * autodetectIndentation( "\ta" ) = "\t";
     * </pre>
     *
     * @param line not null
     * @return the indentation for the given line.
     */
    private static String autodetectIndentation( final String line )
    {
        if ( StringUtils.isEmpty( line ) )
        {
            return "";
        }

        return line.substring( 0, line.indexOf( trimLeft( line ) ) );
    }

    /**
     * @param content not null
     * @return an array of all content lines
     * @throws IOException if any
     */
    private static String[] getLines( final String content )
        throws IOException
    {
        List<String> lines = new LinkedList<>();

        BufferedReader reader = new BufferedReader( new StringReader( content ) );
        String line = reader.readLine();
        while ( line != null )
        {
            lines.add( line );
            line = reader.readLine();
        }

        return lines.toArray( new String[lines.size()] );
    }

    /**
     * Trim a given line on the left:
     * <pre>
     * trimLeft( null ) = "";
     * trimLeft( "  " ) = "";
     * trimLeft( "a" ) = "a";
     * trimLeft( "    a" ) = "a";
     * trimLeft( "\ta" ) = "a";
     * trimLeft( "    a    " ) = "a    ";
     * </pre>
     *
     * @param text
     * @return the text trimmed on left side or empty if text is null.
     */
    private static String trimLeft( final String text )
    {
        if ( StringUtils.isEmpty( text ) || StringUtils.isEmpty( text.trim() ) )
        {
            return "";
        }

        String textTrimmed = text.trim();
        return text.substring( text.indexOf( textTrimmed ) );
    }

    /**
     * Trim a given line on the right:
     * <pre>
     * trimRight( null ) = "";
     * trimRight( "  " ) = "";
     * trimRight( "a" ) = "a";
     * trimRight( "a\t" ) = "a";
     * trimRight( "    a    " ) = "    a";
     * </pre>
     *
     * @param text
     * @return the text trimmed on tight side or empty if text is null.
     */
    private static String trimRight( final String text )
    {
        if ( StringUtils.isEmpty( text ) || StringUtils.isEmpty( text.trim() ) )
        {
            return "";
        }

        String textTrimmed = text.trim();
        return text.substring( 0, text.indexOf( textTrimmed ) + textTrimmed.length() );
    }


    /**
     * Wrapper class for the entity's tags.
     */
    class JavaEntityTags
    {
        private final JavaAnnotatedElement entity;

        private final boolean isJavaMethod;

        /**
         * List of tag names.
         */
        private List<String> namesTags;

        /**
         * Map with java parameter as key and original Javadoc lines as values.
         */
        private Map<String, String> tagParams;
        
        private Set<String> documentedParams = new HashSet<>();

        /**
         * Original javadoc lines.
         */
        private String tagReturn;

        /**
         * Map with java throw as key and original Javadoc lines as values.
         */
        private Map<String, String> tagThrows;

        /**
         * Original javadoc lines for unknown tags.
         */
        private List<String> unknownsTags;

        JavaEntityTags( JavaAnnotatedElement entity, boolean isJavaMethod )
        {
            this.entity = entity;
            this.isJavaMethod = isJavaMethod;
            this.namesTags = new LinkedList<>();
            this.tagParams = new LinkedHashMap<>();
            this.tagThrows = new LinkedHashMap<>();
            this.unknownsTags = new LinkedList<>();
        }

        public List<String> getNamesTags()
        {
            return namesTags;
        }

        public String getJavadocReturnTag()
        {
            return tagReturn;
        }

        public void setJavadocReturnTag( String s )
        {
            tagReturn = s;
        }

        public List<String> getUnknownTags()
        {
            return unknownsTags;
        }

        public void putJavadocParamTag( String paramName, String paramValue, String originalJavadocTag )
        {
            documentedParams.add( paramName );
            tagParams.put( paramValue, originalJavadocTag );
        }

        public String getJavadocParamTag( String paramValue )
        {
            String originalJavadocTag = tagParams.get( paramValue );
            if ( originalJavadocTag == null && getLog().isWarnEnabled() )
            {
                getLog().warn( getMessage( paramValue, "javaEntityTags.tagParams" ) );
            }
            return originalJavadocTag;
        }

        public boolean hasJavadocParamTag( String paramName )
        {
            return documentedParams.contains( paramName );
        }

        public void putJavadocThrowsTag( String paramName, String originalJavadocTag )
        {
            tagThrows.put( paramName, originalJavadocTag );
        }

        public String getJavadocThrowsTag( String paramName )
        {
            return getJavadocThrowsTag( paramName, false );
        }

        public String getJavadocThrowsTag( String paramName, boolean nullable )
        {
            String originalJavadocTag = tagThrows.get( paramName );
            if ( !nullable && originalJavadocTag == null && getLog().isWarnEnabled() )
            {
                getLog().warn( getMessage( paramName, "javaEntityTags.tagThrows" ) );
            }

            return originalJavadocTag;
        }

        private String getMessage( String paramName, String mapName )
        {
            StringBuilder msg = new StringBuilder();
            msg.append( "No param '" ).append( paramName ).append( "' key found in " ).append( mapName )
            .append( " for the entity: " );
            if ( isJavaMethod )
            {
                JavaMethod javaMethod = (JavaMethod) entity;
                msg.append( getJavaMethodAsString( javaMethod ) );
            }
            else
            {
                JavaClass javaClass = (JavaClass) entity;
                msg.append( javaClass.getFullyQualifiedName() );
            }

            return msg.toString();
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public String toString()
        {
            StringBuilder sb = new StringBuilder();

            sb.append( "namesTags=" ).append( namesTags ).append( "\n" );
            sb.append( "tagParams=" ).append( tagParams ).append( "\n" );
            sb.append( "tagReturn=" ).append( tagReturn ).append( "\n" );
            sb.append( "tagThrows=" ).append( tagThrows ).append( "\n" );
            sb.append( "unknownsTags=" ).append( unknownsTags ).append( "\n" );

            return sb.toString();
        }
    }
}
