/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.maven.plugins.javadoc;

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;

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.commons.text.StringEscapeUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.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;

/**
 * Abstract class to fix Javadoc documentation and tags in source files.
 *
 * @see <a href="https://docs.oracle.com/en/java/javase/17/docs/specs/javadoc/doc-comment-spec.html#where-tags-can-be-used">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>public (shows only public classes and members)</li>
     * <li>protected (shows only public and protected classes and members)</li>
     * <li>package (shows all classes and members not marked private)</li>
     * <li>private (shows all classes and members)</li>
     * </ul>
     * @see <a href="https://docs.oracle.com/en/java/javase/17/docs/specs/man/javadoc.html#options-for-javadoc">private, protected, public, package options for Javadoc</a>
     */
    @Parameter(property = "level", defaultValue = "protected")
    private String level;

    /**
     * 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 (defaultAuthor == null || defaultAuthor.isEmpty()) {
            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 (encoding == null || encoding.isEmpty()) {
            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(),
                session.getRepositorySession().getLocalRepository().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()]), ClassLoader.getPlatformClassLoader());
        }

        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 (extraComment != null && !extraComment.isEmpty()) {
            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(StringEscapeUtils.escapeHtml4(
                        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("=\"");
                String escapedValue = StringEscapeUtils.escapeHtml4(value.toString());
                // reduce the size
                // CHECKSTYLE_OFF: MagicNumber
                if (escapedValue.length() < 40) {
                    sb.append(escapedValue).append("\"");
                } else {
                    sb.append(escapedValue, 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 ((originalJavadocTag != null && !originalJavadocTag.isEmpty())
                && 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
     */
    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.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 (line == null || line.isEmpty()) {
            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 ((text == null || text.isEmpty()) || 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 ((text == null || text.isEmpty()) || 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();
        }
    }
}
