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.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.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="https://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 );

        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<>();

        try ( BufferedReader 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

                // CHECKSTYLE_OFF: MagicNumber
                switch ( code )
                {
                    case 7011:
                        methodAdded( split );
                        break;
                    case 7012:
                        methodAdded( split );
                        break;
                    case 8000:
                        clirrNewClasses.add( split[2].trim() );
                        break;
                    default:
                        break;
                }
                // CHECKSTYLE_ON: MagicNumber
            }
        }
        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." );
        }
    }

    private void methodAdded( String[] split )
    {
        List<String> list = clirrNewMethods.get( split[2].trim() );
        if ( list == null )
        {
            list = new ArrayList<>();
        }
        String[] splits2 = StringUtils.split( split[3].trim(), "'" );
        if ( splits2.length != 3 )
        {
            return;
        }
        list.add( splits2[1].trim() );
        clirrNewMethods.put( split[2].trim(), list );
    }

    /**
     * @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 ).toURI().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();
        boolean changeDetected = false;
        try ( BufferedReader 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() )
                        {
                            final boolean commentUpdated =
                                    fixMethodComment( stringWriter, originalContent, method, indent );
                            if ( commentUpdated )
                            {
                                takeCareSingleComment( stringWriter, originalContent, method );
                            }
                            changeDetected |= commentUpdated;
                        }
                    }
                }
                

                // 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 )
                    {
                        final boolean commentUpdated =
                                fixMethodComment( stringWriter, originalContent, method, indent );
                        if ( commentUpdated )
                        {
                            takeCareSingleComment( stringWriter, originalContent, method );
                        }
                        changeDetected |= commentUpdated;
                    }
                }

                stringWriter.write( line );
                stringWriter.write( EOL );
            }
        }

        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 = entity instanceof JavaExecutable;

        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
        updateJavadocTags( sb, originalContent, 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 );
        }
    }

    private static final Pattern REPLACE_LINK_TAGS_PATTERN = Pattern.compile( "\\{@link\\s" );

    static String replaceLinkTags( String comment, JavaAnnotatedElement entity )
    {
        StringBuilder resolvedComment = new StringBuilder();
        // scan comment for {@link someClassName} and try to resolve this
        Matcher linktagMatcher = REPLACE_LINK_TAGS_PATTERN.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.getName() + ">" ).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.getFullyQualifiedName().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 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() + " class.";
    }

    /**
     * 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;
        
        String resource = "META-INF/maven/" + CLIRR_MAVEN_PLUGIN_GROUPID + "/" + CLIRR_MAVEN_PLUGIN_ARTIFACTID
                        + "/pom.properties";
         
        try ( InputStream resourceAsStream =
            AbstractFixJavadocMojo.class.getClassLoader().getResourceAsStream( resource ) )
        {

            if ( resourceAsStream != null )
            {
                Properties properties = new Properties();
                properties.load( resourceAsStream );
                if ( StringUtils.isNotEmpty( properties.getProperty( "version" ) ) )
                {
                    clirrVersion = properties.getProperty( "version" );
                }
            }
        }
        catch ( IOException e )
        {
            // nop
        }

        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();
        }
    }
}
