/*
 * 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.jlink;

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

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.Optional;

import org.apache.commons.io.FileUtils;
import org.apache.maven.artifact.Artifact;
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.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
import org.apache.maven.toolchain.Toolchain;
import org.apache.maven.toolchain.ToolchainPrivate;
import org.apache.maven.toolchain.java.DefaultJavaToolChain;
import org.codehaus.plexus.archiver.Archiver;
import org.codehaus.plexus.archiver.ArchiverException;
import org.codehaus.plexus.archiver.zip.ZipArchiver;
import org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor;
import org.codehaus.plexus.languages.java.jpms.LocationManager;
import org.codehaus.plexus.languages.java.jpms.ResolvePathsRequest;
import org.codehaus.plexus.languages.java.jpms.ResolvePathsResult;
import org.codehaus.plexus.languages.java.version.JavaVersion;

import static java.util.Collections.singletonMap;

/**
 * The JLink goal is intended to create a Java Run Time Image file based on
 * <a href="https://openjdk.java.net/jeps/282">https://openjdk.java.net/jeps/282</a>,
 * <a href="https://openjdk.java.net/jeps/220">https://openjdk.java.net/jeps/220</a>.
 *
 * @author Karl Heinz Marbaise <a href="mailto:khmarbaise@apache.org">khmarbaise@apache.org</a>
 */
@Mojo(name = "jlink", requiresDependencyResolution = ResolutionScope.RUNTIME, defaultPhase = LifecyclePhase.PACKAGE)
public class JLinkMojo extends AbstractJLinkMojo {
    @Component
    private LocationManager locationManager;

    /**
     * <p>
     * Specify the requirements for this jdk toolchain. This overrules the toolchain selected by the
     * maven-toolchain-plugin.
     * </p>
     * <strong>note:</strong> requires at least Maven 3.3.1
     */
    @Parameter
    private Map<String, String> jdkToolchain;

    /**
     * This is intended to strip debug information out. The command line equivalent of <code>jlink</code> is:
     * <code>-G, --strip-debug</code> strip debug information.
     */
    @Parameter(defaultValue = "false")
    private boolean stripDebug;

    /**
     * Here you can define the compression of the resources being used. The command line equivalent is:
     * <code>-c, --compress=&lt;level&gt;</code>.
     *
     * <p>The valid values for the level depend on the JDK:</p>
     *
     * <p>For JDK 9+:</p>
     * <ul>
     *     <li>0:  No compression. Equivalent to zip-0.</li>
     *     <li>1:  Constant String Sharing</li>
     *     <li>2:  Equivalent to zip-6.</li>
     * </ul>
     *
     * <p>For JDK 21+, those values are deprecated and to be removed in a future version.
     * The supported values are:<br>
     * {@code zip-[0-9]}, where {@code zip-0} provides no compression,
     * and {@code zip-9} provides the best compression.<br>
     * Default is {@code zip-6}.</p>
     */
    @Parameter
    private String compress;

    /**
     * Should the plugin generate a launcher script by means of jlink? The command line equivalent is:
     * <code>--launcher &lt;name&gt;=&lt;module&gt;[/&lt;mainclass&gt;]</code>. The valid values for the level are:
     * <code>&lt;name&gt;=&lt;module&gt;[/&lt;mainclass&gt;]</code>.
     */
    @Parameter
    private String launcher;

    /**
     * These JVM arguments will be appended to the {@code lib/modules} file.<br>
     * <strong>This parameter requires at least JDK 14.<br></strong>
     *
     * <p>The command line equivalent is: {@code jlink --add-options="..."}.</p>
     *
     * <p>Example:</p>
     *
     * <pre>
     *   &lt;addOptions&gt;
     *     &lt;addOption&gt;-Xmx256m&lt;/addOption&gt;
     *     &lt;addOption&gt;--enable-preview&lt;/addOption&gt;
     *     &lt;addOption&gt;-Dvar=value&lt;/addOption&gt;
     *   &lt;/addOptions&gt;
     * </pre>
     *
     * <p>Above example will result in {@code jlink --add-options="-Xmx256m" --enable-preview -Dvar=value"}.</p>
     */
    @Parameter
    private List<String> addOptions;

    /**
     * Limit the universe of observable modules. The following gives an example of the configuration which can be used
     * in the <code>pom.xml</code> file.
     *
     * <pre>
     *   &lt;limitModules&gt;
     *     &lt;limitModule&gt;mod1&lt;/limitModule&gt;
     *     &lt;limitModule&gt;xyz&lt;/limitModule&gt;
     *     .
     *     .
     *   &lt;/limitModules&gt;
     * </pre>
     *
     * This configuration is the equivalent of the command line option:
     * <code>--limit-modules &lt;mod&gt;[,&lt;mod&gt;...]</code>
     */
    @Parameter
    private List<String> limitModules;

    /**
     * <p>
     * Usually this is not necessary, cause this is handled automatically by the given dependencies.
     * </p>
     * <p>
     * By using the --add-modules you can define the root modules to be resolved. The configuration in
     * <code>pom.xml</code> file can look like this:
     * </p>
     *
     * <pre>
     * &lt;addModules&gt;
     *   &lt;addModule&gt;mod1&lt;/addModule&gt;
     *   &lt;addModule&gt;first&lt;/addModule&gt;
     *   .
     *   .
     * &lt;/addModules&gt;
     * </pre>
     *
     * The command line equivalent for jlink is: <code>--add-modules &lt;mod&gt;[,&lt;mod&gt;...]</code>.
     */
    @Parameter
    private List<String> addModules;

    /**
     * Define the plugin module path to be used. There can be defined multiple entries separated by either {@code ;} or
     * {@code :}. The jlink command line equivalent is: <code>--plugin-module-path &lt;modulepath&gt;</code>
     */
    @Parameter
    private String pluginModulePath;

    /**
     * The output directory for the resulting Run Time Image. The created Run Time Image is stored in non compressed
     * form. This will later being packaged into a <code>zip</code> file. <code>--output &lt;path&gt;</code>
     *
     * <p>The {@link #classifier} is appended as a subdirecty if it exists,
     * otherwise {@code default} will be used as subdirectory.
     * This ensures that multiple executions using classifiers will not overwrite the previous run’s image.</p>
     */
    @Parameter(defaultValue = "${project.build.directory}/maven-jlink", required = true, readonly = true)
    private File outputDirectoryImage;

    @Parameter(defaultValue = "${project.build.directory}", required = true, readonly = true)
    private File buildDirectory;

    @Parameter(defaultValue = "${project.build.outputDirectory}", required = true, readonly = true)
    private File outputDirectory;

    /**
     * The byte order of the generated Java Run Time image. <code>--endian &lt;little|big&gt;</code>. If the endian is
     * not given the default is: <code>native</code>.
     */
    // TODO: Should we define either little or big as default? or should we left as it.
    @Parameter
    private String endian;

    /**
     * Include additional paths on the <code>--module-path</code> option. Project dependencies and JDK modules are
     * automatically added.
     */
    @Parameter
    private List<String> modulePaths;

    /**
     * Add the option <code>--bind-services</code> or not.
     */
    @Parameter(defaultValue = "false")
    private boolean bindServices;

    /**
     * You can disable a plugin by using this option. <code>--disable-plugin pluginName</code>.
     */
    @Parameter
    private String disablePlugin;

    /**
     * <code>--ignore-signing-information</code>
     */
    @Parameter(defaultValue = "false")
    private boolean ignoreSigningInformation;

    /**
     * This will suppress to have an <code>includes</code> directory in the resulting Java Run Time Image. The JLink
     * command line equivalent is: <code>--no-header-files</code>
     */
    @Parameter(defaultValue = "false")
    private boolean noHeaderFiles;

    /**
     * This will suppress to have the <code>man</code> directory in the resulting Java Run Time Image. The JLink command
     * line equivalent is: <code>--no-man-pages</code>
     */
    @Parameter(defaultValue = "false")
    private boolean noManPages;

    /**
     * Suggest providers that implement the given service types from the module path.
     *
     * <pre>
     * &lt;suggestProviders&gt;
     *   &lt;suggestProvider&gt;name-a&lt;/suggestProvider&gt;
     *   &lt;suggestProvider&gt;name-b&lt;/suggestProvider&gt;
     *   .
     *   .
     * &lt;/suggestProviders&gt;
     * </pre>
     *
     * The jlink command linke equivalent: <code>--suggest-providers [&lt;name&gt;,...]</code>
     */
    @Parameter
    private List<String> suggestProviders;

    /**
     * Includes the list of locales where langtag is a BCP 47 language tag.
     *
     * <p>This option supports locale matching as defined in RFC 4647.
     * Ensure that you add the module jdk.localedata when using this option.</p>
     *
     * <p>The command line equivalent is: <code>--include-locales=en,ja,*-IN</code>.</p>
     *
     * <pre>
     * &lt;includeLocales&gt;
     *   &lt;includeLocale&gt;en&lt;/includeLocale&gt;
     *   &lt;includeLocale&gt;ja&lt;/includeLocale&gt;
     *   &lt;includeLocale&gt;*-IN&lt;/includeLocale&gt;
     *   .
     *   .
     * &lt;/includeLocales&gt;
     * </pre>
     */
    @Parameter
    private List<String> includeLocales;

    /**
     * This will turn on verbose mode. The jlink command line equivalent is: <code>--verbose</code>
     */
    @Parameter(defaultValue = "false")
    private boolean verbose;

    /**
     * The JAR archiver needed for archiving the environments.
     */
    @Component(role = Archiver.class, hint = "zip")
    private ZipArchiver zipArchiver;

    /**
     * Set the JDK location to create a Java custom runtime image.
     */
    @Parameter
    private File sourceJdkModules;

    /**
     * Classifier to add to the artifact generated. If given, the artifact will be attached
     * as a supplemental artifact.
     * If not given this will create the main artifact which is the default behavior.
     * If you try to do that a second time without using a classifier the build will fail.
     */
    @Parameter
    private String classifier;

    /**
     * Name of the generated ZIP file in the <code>target</code> directory. This will not change the name of the
     * installed/deployed file.
     */
    @Parameter(defaultValue = "${project.build.finalName}", readonly = true)
    private String finalName;

    /**
     * Convenience interface for plugins to add or replace artifacts and resources on projects.
     */
    @Component
    private MavenProjectHelper projectHelper;

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
        failIfParametersAreNotInTheirValidValueRanges();

        setOutputDirectoryImage();

        ifOutputDirectoryExistsDelteIt();

        JLinkExecutor jLinkExec = getExecutor();
        Collection<String> modulesToAdd = new ArrayList<>();
        if (addModules != null) {
            modulesToAdd.addAll(addModules);
        }
        jLinkExec.addAllModules(modulesToAdd);

        Collection<String> pathsOfModules = new ArrayList<>();
        if (modulePaths != null) {
            pathsOfModules.addAll(modulePaths);
        }

        for (Entry<String, File> item : getModulePathElements().entrySet()) {
            getLog().info(" -> module: " + item.getKey() + " ( "
                    + item.getValue().getPath() + " )");

            // We use the real module name and not the artifact Id...
            modulesToAdd.add(item.getKey());
            pathsOfModules.add(item.getValue().getPath());
        }

        // The jmods directory of the JDK
        jLinkExec
                .getJmodsFolder(this.sourceJdkModules)
                .ifPresent(jmodsFolder -> pathsOfModules.add(jmodsFolder.getAbsolutePath()));
        jLinkExec.addAllModulePaths(pathsOfModules);

        List<String> jlinkArgs = createJlinkArgs(pathsOfModules, modulesToAdd);

        try {
            jLinkExec.executeJlink(jlinkArgs);
        } catch (IllegalStateException e) {
            throw new MojoFailureException("Unable to find jlink command: " + e.getMessage(), e);
        }

        File createZipArchiveFromImage = createZipArchiveFromImage(buildDirectory, outputDirectoryImage);

        if (hasClassifier()) {
            projectHelper.attachArtifact(getProject(), "jlink", getClassifier(), createZipArchiveFromImage);
        } else {
            if (projectHasAlreadySetAnArtifact()) {
                throw new MojoExecutionException("You have to use a classifier "
                        + "to attach supplemental artifacts to the project instead of replacing them.");
            }
            getProject().getArtifact().setFile(createZipArchiveFromImage);
        }
    }

    private List<File> getCompileClasspathElements(MavenProject project) {
        List<File> list = new ArrayList<>(project.getArtifacts().size() + 1);

        for (Artifact a : project.getArtifacts()) {
            getLog().debug("Artifact: " + a.getGroupId() + ":" + a.getArtifactId() + ":" + a.getVersion());
            list.add(a.getFile());
        }
        return list;
    }

    private Map<String, File> getModulePathElements() throws MojoFailureException {
        // For now only allow named modules. Once we can create a graph with ASM we can specify exactly the modules
        // and we can detect if auto modules are used. In that case, MavenProject.setFile() should not be used, so
        // you cannot depend on this project and so it won't be distributed.

        Map<String, File> modulepathElements = new HashMap<>();

        try {
            Collection<File> dependencyArtifacts = getCompileClasspathElements(getProject());

            ResolvePathsRequest<File> request = ResolvePathsRequest.ofFiles(dependencyArtifacts);

            Optional<Toolchain> toolchain = getToolchain();
            if (toolchain.isPresent()
                    && toolchain.orElseThrow(NoSuchElementException::new) instanceof DefaultJavaToolChain) {
                Toolchain toolcahin1 = toolchain.orElseThrow(NoSuchElementException::new);
                request.setJdkHome(new File(((DefaultJavaToolChain) toolcahin1).getJavaHome()));
            }

            ResolvePathsResult<File> resolvePathsResult = locationManager.resolvePaths(request);

            for (Map.Entry<File, JavaModuleDescriptor> entry :
                    resolvePathsResult.getPathElements().entrySet()) {
                JavaModuleDescriptor descriptor = entry.getValue();
                if (descriptor == null) {
                    String message = "The given dependency " + entry.getKey()
                            + " does not have a module-info.java file. So it can't be linked.";
                    getLog().error(message);
                    throw new MojoFailureException(message);
                }

                // Don't warn for automatic modules, let the jlink tool do that
                getLog().debug(" module: " + descriptor.name() + " automatic: " + descriptor.isAutomatic());
                if (modulepathElements.containsKey(descriptor.name())) {
                    getLog().warn("The module name " + descriptor.name() + " does already exists.");
                }
                modulepathElements.put(descriptor.name(), entry.getKey());
            }

            // This part is for the module in target/classes ? (Hacky..)
            // FIXME: Is there a better way to identify that code exists?
            if (outputDirectory.exists()) {
                List<File> singletonList = Collections.singletonList(outputDirectory);

                ResolvePathsRequest<File> singleModuls = ResolvePathsRequest.ofFiles(singletonList);

                ResolvePathsResult<File> resolvePaths = locationManager.resolvePaths(singleModuls);
                for (Entry<File, JavaModuleDescriptor> entry :
                        resolvePaths.getPathElements().entrySet()) {
                    JavaModuleDescriptor descriptor = entry.getValue();
                    if (descriptor == null) {
                        String message = "The given project " + entry.getKey()
                                + " does not contain a module-info.java file. So it can't be linked.";
                        getLog().error(message);
                        throw new MojoFailureException(message);
                    }
                    if (modulepathElements.containsKey(descriptor.name())) {
                        getLog().warn("The module name " + descriptor.name() + " does already exists.");
                    }
                    modulepathElements.put(descriptor.name(), entry.getKey());
                }
            }

        } catch (IOException e) {
            getLog().error(e.getMessage());
            throw new MojoFailureException(e.getMessage());
        }

        return modulepathElements;
    }

    private JLinkExecutor getExecutor() {
        return getJlinkExecutor();
    }

    private boolean projectHasAlreadySetAnArtifact() {
        if (getProject().getArtifact().getFile() != null) {
            return getProject().getArtifact().getFile().isFile();
        } else {
            return false;
        }
    }

    /**
     * @return true in case where the classifier is not {@code null} and contains something else than white spaces.
     */
    protected boolean hasClassifier() {
        boolean result = false;
        if (getClassifier() != null && !getClassifier().isEmpty()) {
            result = true;
        }

        return result;
    }

    private File createZipArchiveFromImage(File outputDirectory, File outputDirectoryImage)
            throws MojoExecutionException {
        zipArchiver.addDirectory(outputDirectoryImage);

        File resultArchive = getArchiveFile(outputDirectory, finalName, getClassifier(), "zip");

        zipArchiver.setDestFile(resultArchive);
        try {
            zipArchiver.createArchive();
        } catch (ArchiverException | IOException e) {
            getLog().error(e.getMessage(), e);
            throw new MojoExecutionException(e.getMessage(), e);
        }

        return resultArchive;
    }

    private void failIfParametersAreNotInTheirValidValueRanges() throws MojoFailureException {
        if (endian != null && (!"big".equals(endian) && !"little".equals(endian))) {
            String message = "The given endian parameter " + endian
                    + " does not contain one of the following values: 'little' or 'big'.";
            getLog().error(message);
            throw new MojoFailureException(message);
        }

        if (addOptions != null && !addOptions.isEmpty()) {
            requireJdk14();
        }
    }

    private void requireJdk14() throws MojoFailureException {
        // needs JDK 14+
        Optional<Toolchain> optToolchain = getToolchain();
        String java14reqMsg = "parameter 'addOptions' needs at least a Java 14 runtime or a Java 14 toolchain.";

        if (optToolchain.isPresent()) {
            Toolchain toolchain = optToolchain.orElseThrow(NoSuchElementException::new);
            if (!(toolchain instanceof ToolchainPrivate)) {
                getLog().warn("Unable to check toolchain java version.");
                return;
            }
            ToolchainPrivate toolchainPrivate = (ToolchainPrivate) toolchain;
            if (!toolchainPrivate.matchesRequirements(singletonMap("jdk", "14"))) {
                throw new MojoFailureException(java14reqMsg);
            }
        } else if (!JavaVersion.JAVA_VERSION.isAtLeast("14")) {
            throw new MojoFailureException(java14reqMsg);
        }
    }

    /**
     * Use a separate directory for each image.
     *
     * <p>Rationale: If a user creates multiple jlink artifacts using classifiers,
     * the directories should not overwrite themselves for each execution.</p>
     */
    private void setOutputDirectoryImage() {
        if (hasClassifier()) {
            final File classifiersDirectory = new File(outputDirectoryImage, "classifiers");
            outputDirectoryImage = new File(classifiersDirectory, classifier);
        } else {
            outputDirectoryImage = new File(outputDirectoryImage, "default");
        }
    }

    private void ifOutputDirectoryExistsDelteIt() throws MojoExecutionException {
        if (outputDirectoryImage.exists()) {
            // Delete the output folder of JLink before we start
            // otherwise JLink will fail with a message "Error: directory already exists: ..."
            try {
                getLog().debug("Deleting existing " + outputDirectoryImage.getAbsolutePath());
                FileUtils.forceDelete(outputDirectoryImage);
            } catch (IOException e) {
                getLog().error("IOException", e);
                throw new MojoExecutionException(
                        "Failure during deletion of " + outputDirectoryImage.getAbsolutePath() + " occured.");
            }
        }
    }

    protected List<String> createJlinkArgs(Collection<String> pathsOfModules, Collection<String> modulesToAdd) {
        List<String> jlinkArgs = new ArrayList<>();

        if (stripDebug) {
            jlinkArgs.add("--strip-debug");
        }

        if (bindServices) {
            jlinkArgs.add("--bind-services");
        }

        if (endian != null) {
            jlinkArgs.add("--endian");
            jlinkArgs.add(endian);
        }
        if (ignoreSigningInformation) {
            jlinkArgs.add("--ignore-signing-information");
        }
        if (compress != null) {
            jlinkArgs.add("--compress");
            jlinkArgs.add(compress);
        }
        if (launcher != null) {
            jlinkArgs.add("--launcher");
            jlinkArgs.add(launcher);
        }
        if (addOptions != null && !addOptions.isEmpty()) {
            jlinkArgs.add("--add-options");
            jlinkArgs.add(String.format("\"%s\"", String.join(" ", addOptions)));
        }

        if (disablePlugin != null) {
            jlinkArgs.add("--disable-plugin");
            jlinkArgs.add(disablePlugin);
        }
        if (pathsOfModules != null && !pathsOfModules.isEmpty()) {
            // @formatter:off
            jlinkArgs.add("--module-path");
            jlinkArgs.add(getPlatformDependSeparateList(pathsOfModules).replace("\\", "\\\\"));
            // @formatter:off
        }

        if (noHeaderFiles) {
            jlinkArgs.add("--no-header-files");
        }

        if (noManPages) {
            jlinkArgs.add("--no-man-pages");
        }

        if (hasSuggestProviders()) {
            jlinkArgs.add("--suggest-providers");
            String sb = getCommaSeparatedList(suggestProviders);
            jlinkArgs.add(sb);
        }

        if (hasLimitModules()) {
            jlinkArgs.add("--limit-modules");
            String sb = getCommaSeparatedList(limitModules);
            jlinkArgs.add(sb);
        }

        if (!modulesToAdd.isEmpty()) {
            jlinkArgs.add("--add-modules");
            // This must be name of the module and *NOT* the name of the
            // file! Can we somehow pre check this information to fail early?
            String sb = getCommaSeparatedList(modulesToAdd);
            jlinkArgs.add(sb.replace("\\", "\\\\"));
        }

        if (hasIncludeLocales()) {
            jlinkArgs.add("--add-modules");
            jlinkArgs.add("jdk.localedata");
            jlinkArgs.add("--include-locales");
            String sb = getCommaSeparatedList(includeLocales);
            jlinkArgs.add(sb);
        }

        if (pluginModulePath != null) {
            jlinkArgs.add("--plugin-module-path");
            StringBuilder sb = convertSeparatedModulePathToPlatformSeparatedModulePath(pluginModulePath);
            jlinkArgs.add(sb.toString().replace("\\", "\\\\"));
        }

        if (buildDirectory != null) {
            jlinkArgs.add("--output");
            jlinkArgs.add(outputDirectoryImage.getAbsolutePath());
        }

        if (verbose) {
            jlinkArgs.add("--verbose");
        }

        return Collections.unmodifiableList(jlinkArgs);
    }

    private boolean hasIncludeLocales() {
        return includeLocales != null && !includeLocales.isEmpty();
    }

    private boolean hasSuggestProviders() {
        return suggestProviders != null && !suggestProviders.isEmpty();
    }

    private boolean hasLimitModules() {
        return limitModules != null && !limitModules.isEmpty();
    }

    /**
     * {@inheritDoc}
     */
    protected String getClassifier() {
        return classifier;
    }
}
