content/xdoc/developers/mojo-api-specification.xml (73 lines of code) (raw):
<?xml version="1.0"?>
<!--
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.
-->
<document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 https://maven.apache.org/xsd/xdoc-2.0.xsd">
<properties>
<title>Mojo API Specification</title>
<author email="jdcasey@apache.org">John Casey</author>
</properties>
<body>
<section name="Introduction">
<p>Maven plugins can be written in Java or any of a
number of scripting languages. Plugins consists of one or more Mojos,
each one being the implementation for one of the plugin's <b>goals</b>.</p>
<p>NOTE: this documentation covers Mojo API introduced in Maven 2 and used by Maven 3. It does not cover the <a href="https://maven.apache.org/ref/4-LATEST/api/index.html">new Maven 4 API</a>.</p>
<p>Although the requirements on Mojos are minimal by design, there are
still a very few requirements that Mojo developers must keep in mind:</p>
<ol>
<li>a Mojo must have a method named <code>execute</code> which
declares no parameters, and has a void return type. If this method
throws an exception, that exception must either be a derivative of
<code>java.lang.RuntimeException</code>, or a derivative of
<a href="/ref/current/maven-plugin-api/apidocs/org/apache/maven/plugin/MojoExecutionException.html"><code>org.apache.maven.plugin.MojoExecutionException</code></a>. It goes
without saying that in the latter case, the execute method must declare
that it throws this exception.</li>
<li> Additionally, Mojos must declare a field
for each goal <b>parameter</b> they specify, and these parameter fields will be
populated before <code>execute()</code> is called.</li>
<li>Finally, all Mojos must be accompanied by metadata in <code>META-INF/maven/plugin.xml</code>
describing parameters, lifecycle bindings, etc. This descriptor will be
covered in more detail below.</li>
</ol>
<subsection name="Mojo Code">
<p>Basically, these Mojo requirements are embodied by the
<a href="/ref/current/maven-plugin-api/apidocs/org/apache/maven/plugin/Mojo.html"><code>org.apache.maven.plugin.Mojo</code> interface</a>, which the Mojo
must implement.<br />
Usually this is done by extending its
<a href="/ref/current/maven-plugin-api/apidocs/org/apache/maven/plugin/AbstractMojo.html">abstract base class counterpart <code>org.apache.maven.plugin.AbstractMojo</code></a>.<br />
The Mojo will have access to the standard Maven user-feedback mechanism,
<a href="/ref/current/maven-plugin-api/apidocs/org/apache/maven/plugin/logging/Log.html"><code>org.apache.maven.plugin.logging.Log</code></a>,
so the Mojo can communicate important events to the console or other log sink.
</p>
</subsection>
<subsection name="The Descriptor and Annotations">
<p>As mentioned before, each Plugin - or packaged set of Mojos - must
provide a <a href="/ref/current/maven-plugin-api/plugin.html"><code>META-INF/maven/plugin.xml</code> descriptor file</a>
inside the Plugin jar file.<br />
Fortunately, Maven also provides a set of Java annotations
(named <a href="/plugin-tools/maven-plugin-tools-annotations/index.html">Maven Plugin Tools Java5 Annotations</a>)
and tools (named <a href="/plugin-tools/">Plugin Tools</a>) to generate
this descriptor, so developers don't have to worry about directly
authoring or maintaining a separate XML metadata file.
</p>
</subsection>
<subsection name="Project Descriptor (POM) Requirements">
<p>The POM must declare a packaging element which describes this project as a Maven plugin project:
<code><packaging>maven-plugin</packaging></code></p>
</subsection>
</section>
<!--section name="The Descriptor and Annotations">
<p>In addition to the normal Java requirements in terms of interfaces
and/or abstract base classes which need to be implemented, a plugin
descriptor must accompany these classes inside the plugin jar. This
descriptor file is used to provide metadata about the parameters and
other component requirements for a set of Mojos so that Maven can
initialize the Mojo and validate its configuration before executing
it. As such, the plugin descriptor has a certain set of information
that is required for each Mojo specification to be valid, as well as
requirements for the overall plugin descriptor itself.</p>
<p>NOTE: In the following discussion, bolded items are the descriptor's
element name along with a Mojo Javadoc tag (if applicable) supporting
that piece of the plugin descriptor. A couple of examples are:
<b>someElement
(@annotation parameterName="parameterValue")</b>
or
<b>someOtherElement (@annotation <rawAnnotationValue>)</b>
.
</p>
<p><b>NOTE:</b> since maven-plugin-plugin 3.0, it is now possible to use
<a href="/plugin-tools/maven-plugin-tools-annotations/index.html">Maven Plugin Tools Java 5 Annotations</a> equivalent
to <a href="/plugin-tools/maven-plugin-tools-java/index.html">Mojo Javadoc tags</a>.
See
<a href="/plugin-tools/maven-plugin-plugin/examples/using-annotations.html">Using annotations documentation</a>.
</p>
<p>The plugin descriptor (see <a href="/ref/current/maven-plugin-api/plugin.html">descriptor reference</a>)
must be provided in a jar resource with the path:
<code>META-INF/maven/plugin.xml</code>, and it must contain the following:
</p>
<table>
<tr>
<th>Descriptor Element</th>
<th>Required?</th>
<th>Notes</th>
</tr>
<tr>
<td><code>mojos</code></td>
<td>Yes</td>
<td>Descriptors for each Mojo provided by the plugin, each inside a
<b><code>mojo</code></b>
sub-element. Mojo descriptors are covered in detail
below. Obviously, a plugin without any declared Mojos doesn't
make sense, so the
<b><code>mojos</code></b>
element is required, along with
at least one
<b><code>mojo</code></b>
sub-element.
</td>
</tr>
<tr>
<td><code>dependencies</code></td>
<td>Yes</td>
<td>A set of dependencies which the plugin requires in order to
function. Each dependency is provided inside a
<b><code>dependency</code></b>
sub-element. Dependency specifications are covered below. Since
all plugins must have a dependency on
<code>maven-plugin-api</code>
, this element is effectively
required.
<i>Using the plugin toolset, these dependencies can be
extracted from the POM's dependencies.</i>
</td>
</tr>
</table>
<p>Each Mojo specified inside a plugin descriptor must provide the
following (annotations specified here are at the class level):</p>
<table>
<!== Annotations listed by specific, autodetect and Javadoc, all alphabetical ==>
<tr>
<th>Descriptor Element</th>
<th>Mojo Javadoc tag</th>
<th>Required?</th>
<th>Notes</th>
</tr>
<tr>
<td><code>aggregator</code></td>
<td><code>@aggregator</code></td>
<td>No</td>
<td>Flags this Mojo to run it in a multi module way, i.e. aggregate the build with the set of
projects listed as modules.</td>
</tr>
<tr>
<td><code>configurator</code></td>
<td><code>@configurator <roleHint></code></td>
<td>No</td>
<td>The configurator type to use when injecting parameter values into this Mojo. The value is
normally deduced from the Mojo's implementation language, but can be specified to allow a
custom ComponentConfigurator implementation to be used. <i>NOTE: This will only be used in
very special cases, using a highly controlled vocabulary of possible values. (Elements
like this are why it's a good idea to use the descriptor tools.)</i>
</td>
</tr>
<tr>
<td><code>execute</code></td>
<td>
<ul>
<li><code>@execute phase="<phaseName>"
lifecycle="<lifecycleId>"</code></li>
<li><code>@execute phase="<phaseName>"</code></li>
<li><code>@execute goal="<goalName>"</code></li>
</ul>
</td>
<td>No</td>
<td>When this goal is invoked, it will first invoke a parallel lifecycle, ending at the given
phase. If a goal is provided instead of a phase, that goal will be executed in isolation.
The execution of either will not affect the current project, but instead make available the
<code>${executedProject}</code> expression if required. An alternate lifecycle can also be
provided: for more information see the documentation on the
<a href="../guides/introduction/introduction-to-the-lifecycle.html">build lifecycle</a>.</td>
</tr>
<tr>
<td><code>executionStrategy</code></td>
<td><code>@executionStrategy <strategy></code></td>
<td>No</td>
<td>Specify the execution strategy. <i>NOTE: Unsupported since Maven 3.0.</i></td>
</tr>
<tr>
<td><code>goal</code></td>
<td><code>@goal <goalName></code></td>
<td>Yes</td>
<td>The name for the Mojo that users will reference from the command line to execute the Mojo
directly, or inside a POM in order to provide Mojo-specific configuration.</td>
</tr>
<tr>
<td><code>inheritByDefault</code></td>
<td><code>@inheritByDefault <true|false></code></td>
<td>No. Default: <code>true</code></td>
<td>Specify that the Mojo is inherited. <i>NOTE: Unsupported since Maven 3.0.</i></td>
</tr>
<tr>
<td><code>instantiationStrategy</code></td>
<td><code>@instantiationStrategy <per-lookup></code></td>
<td>No. Default: <code>per-lookup</code></td>
<td>Specify the instantiation strategy.</td>
</tr>
<tr>
<td><code>phase</code></td>
<td><code>@phase <phaseName></code></td>
<td>No</td>
<td>
Defines a default phase to bind a mojo execution to if the user does not explicitly set a phase in the POM.
<em>Note:</em> This annotation will not automagically make a mojo run when the plugin declaration is added
to the POM. It merely enables the user to omit the <code><phase></code> element from the surrounding
<code><execution></code> element.
</td>
</tr>
<tr>
<td><code>requiresDependencyResolution</code></td>
<td><code>@requiresDependencyResolution <requiredClassPath></code></td>
<td>No</td>
<td>
Flags this Mojo as requiring the dependencies in the specified class path to be resolved before it can
execute. The matrix below illustrates which values for <i><requiredClassPath></i> (first column) are
supported and which dependency scopes (first row) they will request to resolve:
<table>
<tr>
<td></td>
<td>system</td>
<td>provided</td>
<td>compile</td>
<td>runtime</td>
<td>test</td>
</tr>
<tr>
<td><code>compile</code></td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td><code>runtime</code></td>
<td>-</td>
<td>-</td>
<td>X</td>
<td>X</td>
<td>-</td>
</tr>
<tr>
<td><code>compile+runtime</code> (since Maven 3.0)</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>-</td>
</tr>
<tr>
<td><code>test</code></td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
</tr>
</table>
If this annotation is present but no scope is specified, the scope defaults to <code>runtime</code>. If
the annotation is not present at all, the mojo must not make any assumptions about the artifacts associated
with a Maven project.
</td>
</tr>
<tr>
<td><code>requiresDependencyCollection</code></td>
<td><code>@requiresDependencyCollection <requiredClassPath></code></td>
<td>No</td>
<td>
Flags this mojo as requiring information about the dependencies that would make up the specified class path.
As the name suggests, this annotation is similar to <code>@requiresDependencyResolution</code> and supports
the same values for <i><requiredClassPath></i>. The important difference is that this annotation will
not resolve the files for the dependencies, i.e. the artifacts associated with a Maven project can lack a
file. As such, this annotation is meant for mojos that only want to analyze the set of transitive
dependencies, in particular during early lifecycle phases where full dependency resolution might fail due to
projects which haven't been built yet. A mojo may use both this annotation and <code>@requiresDependencyResolution</code>
at the same time. The resolution state of any dependency that is collected but not requested to be resolved
is undefined. Since Maven 3.0.
</td>
</tr>
<tr>
<td><code>requiresDirectInvocation</code></td>
<td><code>@requiresDirectInvocation <true|false></code></td>
<td>No. Default: <code>false</code></td>
<td>Flags this Mojo to be invoke directly. <i>NOTE: Unsupported since Maven 3.0.</i></td>
</tr>
<tr>
<td><code>requiresOnline</code></td>
<td><code>@requiresOnline <true|false></code></td>
<td>No. Default: <code>false</code></td>
<td>Flags this Mojo to require online mode for its operation.</td>
</tr>
<tr>
<td><code>requiresProject</code></td>
<td><code>@requiresProject <true|false></code></td>
<td>No. Default: <code>true</code></td>
<td>Flags this Mojo to run inside of a project.</td>
</tr>
<tr>
<td><code>requiresReports</code></td>
<td><code>@requiresReports <true|false></code></td>
<td>No. Default: <code>false</code></td>
<td>Flags this Mojo to require reports. <i>NOTE: Unsupported since Maven 3.0.</i></td>
</tr>
<tr>
<td><code>threadSafe</code></td>
<td><code>@threadSafe <true|false></code></td>
<td>No. Default: <code>false</code></td>
<td>
Marks this mojo as being thread-safe, i.e. the mojo safely supports concurrent execution during parallel builds.
Mojos without this annotation will make Maven output a warning when used during a parallel build session.
The short-hand notation <code>@threadSafe</code> without a tag value is equivalent to <code>@threadSafe true</code>.
Since Maven 3.0.
</td>
</tr>
<!== Autodetect ==>
<tr>
<td><code>description</code></td>
<td>none (detected)</td>
<td>No</td>
<td>The description of this Mojo's functionality. <i>Using the toolset, this will be the
class-level Javadoc description provided. NOTE: While this is not a required part of the
Mojo specification, it SHOULD be provided to enable future tool support for browsing, etc.
and for clarity.</i>
</td>
</tr>
<tr>
<td><code>implementation</code></td>
<td>none (detected)</td>
<td>Yes</td>
<td>The Mojo's fully-qualified class name (or script path in the case of non-Java Mojos).</td>
</tr>
<tr>
<td><code>language</code></td>
<td>none (detected)</td>
<td>No. Default: <code>java</code></td>
<td>The implementation language for this Mojo (Java, beanshell, etc.).</td>
</tr>
<!== Javadoc ==>
<tr>
<td><code>deprecated</code></td>
<td><code>@deprecated <deprecated-text></code></td>
<td>No</td>
<td>Description with the reason of Mojo deprecation. Similar to Javadoc deprecated.
This will trigger a warning when a user tries to use a Mojo marked as deprecated.
</td>
</tr>
<tr>
<td><code>since</code></td>
<td><code>@since <since-text></code></td>
<td>No</td>
<td>Specify the version when the Mojo was added to the API. Similar to Javadoc since.</td>
</tr>
</table>
<p>Each Mojo specifies the parameters that it expects in order to work.
These parameters are the Mojo's link to the outside world, and
will be satisfied through a combination of POM/project values, plugin
configurations (from the POM and configuration defaults), and System
properties.</p>
<p>NOTE[1]: For this discussion on Mojo parameters, a single
annotation may span multiple elements in the descriptor's specification
for that parameter. Duplicate annotation declarations in this section
will be used to detail each parameter of an annotation separately.</p>
<p>NOTE[2]: In many cases, simply annotating a Mojo field with
<b>@parameter</b>
will be enough to allow injection of a value for that
parameter using POM configuration elements. The discussion below
shows advanced usage for this annotation, along with others.
</p>
<p>Each parameter for a Mojo must be specified in the
plugin descriptor as follows:</p>
<table>
<!== Annotations listed by specific, autodetect and Javadoc, all alphabetical ==>
<tr>
<th>Descriptor Element</th>
<th>Mojo Javadoc tag</th>
<th>Required?</th>
<th>Notes</th>
</tr>
<tr>
<td><code>alias</code></td>
<td><code>@parameter alias="myAlias"</code></td>
<td>No</td>
<td>Specifies an alias which can be used to configure this parameter from the POM. This is
primarily useful to improve user-friendliness, where Mojo field names are not intuitive to
the user or are otherwise not conducive to configuration via the POM.</td>
</tr>
<tr>
<td><code>configuration</code></td>
<td><code>@component role="..." roleHint="..."</code></td>
<td>No</td>
<td>Populates the field with an instance of a Plexus component. This is like declaring a
<i>requirement</i> in a Plexus component. The default requirement will have a role equal
to the declared type of the field, and will use the role hint "default". You can customise
either of these by providing a <code>role</code> and/or <code>roleHint</code> parameter.
<i>e.g.</i>
<code>@component role="org.apache.maven.artifact.ArtifactHandler"
roleHint="ear"</code>. <b>Note:</b> This is identical to the deprecated
form of parameter: <code>@parameter
expression="${component.yourpackage.YourComponentClass#roleHint}"</code>. </td>
</tr>
<tr>
<td><code>configuration</code></td>
<td>maven-plugin-plugin 2.x:<br /><code>@parameter expression="${aSystemProperty}"
default-value="${anExpression}"</code><br /><br />
maven-plugin-plugin 3.x:<br /><code>@parameter property="aSystemProperty"
default-value="${anExpression}"</code></td>
<td>No</td>
<td><p>Specifies the expressions used to calculate the value to be injected into this parameter of
the Mojo at buildtime.</p>
<p>The expression given by <code>default-value</code> is commonly used to refer to
specific elements in the POM, such as <code>${project.resources}</code>, which refers to the list of
resources meant to accompany the classes in the resulting JAR file. Of course, the default value need not
be an expression but can also be a simple constant like <code>true</code> or <code>1.5</code>. And for
parameters of type <code>String</code> one can mix expressions with literal values, e.g.
<code>${project.artifactId}-${project.version}-special</code>.</p>
<p>The system property given by <code>property</code> in maven-plugin-plugin 3.x or <code>expression</code>
in maven-plugin-plugin 2.x
enables users to override the default value from the command line via <code>-DaSystemProperty=value</code>.</p>
<p><i>NOTE: If neither <code>default-value</code> nor <code>property</code> or <code>expression</code> are specified,
the parameter can only be configured from the POM. The use of '${' and '}' in default value is required to delimit actual expressions
which may be evaluated.</i></p>
</td>
</tr>
<tr>
<td><code>editable</code></td>
<td><code>@readonly</code></td>
<td>No</td>
<td>Specifies that this parameter cannot be configured directly by the user (as in the case of
POM-specified configuration). This is useful when you want to force the user to use common
POM elements rather than plugin configurations, as in the case where you want to use the
artifact's final name as a parameter. In this case, you want the user to modify
<build><finalName/></build> rather than specifying
a value for finalName directly in the plugin configuration section. It is also useful to
ensure that - for example - a List-typed parameter which expects items of type Artifact
doesn't get a List full of Strings. <i>NOTE: Specification of this annotation flags the
parameter as non-editable; there is no true/false value.</i>
</td>
</tr>
<tr>
<td><code>required</code></td>
<td><code>@required</code></td>
<td>No</td>
<td>Whether this parameter is required for the Mojo to function. This is used to validate the
configuration for a Mojo before it is injected, and before the Mojo is executed from some
half-state. <i>NOTE: Specification of this annotation flags the parameter as required; there
is no true/false value.</i>
</td>
</tr>
<!== Autodetect ==>
<tr>
<td><code>description</code></td>
<td>none (detected)</td>
<td>No</td>
<td>The description of this parameter's use inside the Mojo. <i>Using the toolset, this is
detected as the Javadoc description for the field. NOTE: While this is not a required part
of the parameter specification, it SHOULD be provided to enable future tool support for
browsing, etc. and for clarity.</i>
</td>
</tr>
<tr>
<td><code>name</code></td>
<td>none (detected)</td>
<td>Yes</td>
<td>The name of the parameter, to be used in configuring this parameter from the Mojo's
declared defaults (discussed below) or from the POM. <i>Using the toolset, this is detected
as the Java field name.</i>
</td>
</tr>
<tr>
<td><code>type</code></td>
<td>none (detected)</td>
<td>Yes</td>
<td>The Java type for this parameter. This is used to validate the result of any expressions
used to calculate the value which should be injected into the Mojo for this parameter.
<i>Using the toolset, this is detected as the class of the Java field corresponding to
this parameter.</i>
</td>
</tr>
<!== Javadoc ==>
<tr>
<td><code>deprecated</code></td>
<td><code>@deprecated <deprecated-text></code></td>
<td>No</td>
<td>Description with the reason of parameter deprecation. Similar to Javadoc deprecated.
This will trigger a warning when a user tries to configure a parameter marked as deprecated.
</td>
</tr>
<tr>
<td><code>since</code></td>
<td><code>@since <since-text></code></td>
<td>No</td>
<td>Specify the version when the Mojo was added to the API. Similar to Javadoc since.</td>
</tr>
</table>
<p>The final component of a plugin descriptor is the dependencies. This
enables the plugin to function independently of its POM (or at least
to declare the libraries it needs to run). Dependencies are taken from
the
<b>runtime</b>
scope of the plugin's calculated dependencies (from
the POM). Dependencies are specified in exactly the same manner as in
the POM, except for the <scope> element (all dependencies in the
plugin descriptor are assumed to be runtime, because this is a
runtime profile for the plugin).
</p>
</section-->
<!--section name="Plugin Tools">
<p>By now, we've mentioned the plugin tools several times without telling
you what they are or how to use them. Instead of manually writing (and
maintaining) the metadata detailed above, Maven ships with some
tools to aid in this task. In fact, the only thing a plugin developer
needs to do is declare his project to be a plugin from within the POM.
Once this is done, Maven will call the appropriate descriptor
generators, etc. to produce an artifact that is ready for use within
Maven builds. Optional metadata can be injected via Javadoc annotation
(and possibly JDK5 annotations in the future) as described above,
enabling richer interactions between the Mojo and the user. The
section below describes the changes to the POM which are necessary to
create plugin artifacts.</p>
</section-->
<!--section name="Project Descriptor (POM) Requirements">
<p>From the POM, Maven plugin projects look quite similar to any other
project. For pure Java plugins, the differences are even smaller than
for script-based plugins. The following details the POM elements
which are necessary to build a Maven plugin artifact.</p>
<table>
<tr>
<th>POM Element</th>
<th>Required for Java Mojos?</th>
<th>Sample Declaration</th>
<th>Notes</th>
</tr>
<tr>
<td>packaging</td>
<td>Yes</td>
<td>
<code><packaging>
maven-plugin
</packaging></code>
</td>
<td>The POM must declare a packaging element which describes this
project as a Maven plugin project.</td>
</tr>
<tr>
<td>scriptSourceDirectory</td>
<td>No</td>
<td>
<code><scriptSourceDirectory>
src/main/scripts
</scriptSourceDirectory></code>
</td>
<td>In the case of script-based Mojos (which are not covered in
detail within this document), the POM must include an additional
element to distinguish script sources from (optional) Java
supporting classes. This element is <code>scriptSourceDirectory</code>,
inside the <code>build</code> section. This directory is included in the list
of resources which accompany any compiled code in the resulting
artifact. It is specified separately from the resources in the
build section to denote its special status as an alternate source
directory for scripts.</td>
</tr>
</table>
<p>After making the changes above, the developer can simply call</p>
<code>mvn install</code>
<p>
to install the plugin to
the local repository. (Any of the other standard lifecycle targets like
package, deploy, etc. are also available in like fashion.)
</p>
</section-->
<!--section name="IDE integration">
<p>If you're using JetBrains IntelliJ IDEA to develop your plugin,
you can use the following to configure the javadoc annotations as live
templates.</p>
<ol>
<li>Download <a href="./maven.xml">this file</a>,
and place it in <code>$USER_HOME/.IntelliJIdea/config/templates</code></li>
<li>(re)startup IntelliJ IDEA (templates are loaded on startup)</li>
<li>add the following list to Settings -> IDE -> Errors -> General
-> Unknown javadoc tags -> Additional javadoc tags
<ul>
<li>aggregator, execute, goal, phase, requiresDirectInvocation,
requiresProject, requiresReports, requiresOnline, parameter,
component, required, readonly</li>
</ul>
</li>
</ol>
</section-->
<section name="Resources">
<p>This section simply gives a listing of pointers for more
information.</p>
<ul>
<li>Maven Plugin API [
<a href="/ref/current/maven-plugin-api/apidocs/index.html">link</a>
]
</li>
<li>MojoDescriptor API [
<a href="/ref/current/maven-plugin-api/apidocs/org/apache/maven/plugin/descriptor/MojoDescriptor.html">link</a>
]
</li>
</ul>
</section>
</body>
</document>