<?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 http://maven.apache.org/xsd/xdoc-2.0.xsd">
    <properties>
        <title>Extending Log4j 2</title>
        <author email="rgoers@apache.org">Ralph Goers</author>
    </properties>
<!-- TODO: add in documentation regarding typed attributes -->
    <body>
      <section name="Extending Log4j">
        <p>
          Log4j 2 provides numerous ways that it can be manipulated and extended. This section includes an
          overview of the various ways that are directly supported by the Log4j 2 implementation.
        </p>
          <subsection name="LoggerContextFactory">
            <p>
              The <code>LoggerContextFactory</code> binds the Log4j API to its implementation. The Log4j
              <code>LogManager</code> locates a <code>LoggerContextFactory</code> by using java.util.ServiceLoader
              to locate all instances of <code>org.apache.logging.log4j.spi.Provider</code>. Each implementation must
              provide a class that extends<code>org.apache.logging.log4j.spi.Provider</code> and should have a
              no-arg constructor that delegates to Provider's constructor passing the <var>Priority</var>,
              the API versions it is compatible with, and the class that implements
              <code>org.apache.logging.log4j.spi.LoggerContextFactory</code>. Log4j will compare the current API
              version and if it is compatible the implementation will be added to the list of providers. The
              API version in <code>org.apache.logging.log4j.LogManager</code> is only changed when a feature is added
              to the API that implementations need to be aware of. If more than one valid implementation is located
              the value for the <var>Priority</var> will be used to identify the factory with the highest priority.
              Finally, the class that implements <code>org.apache.logging.log4j.spi.LoggerContextFactory</code> will be
              instantiated and bound to the LogManager. In Log4j 2 this is provided by <code>Log4jContextFactory</code>.
            </p>
            <p>
              Applications may change the LoggerContextFactory that will be used by
            </p>
            <ol>
              <li>Create a binding to the logging implementation.
              <ol style="list-style-type: lower-alpha">
                <li>Implement a new <code>LoggerContextFactory</code>.</li>
                <li>Implement a class that extends <code>org.apache.logging.spi.Provider.</code> with a no-arg
                  constructor that calls super-class's constructor with the <var>Priority</var>, the API version(s),
                  <code>LoggerContextFactory</code> class, and optionally, a <code>ThreadContextMap</code>
                  implementation class.</li>
                <li>Create a <code>META-INF/services/org.apache.logging.spi.Provider</code> file that contains the
                  name of the class that implements <code>org.apache.logging.spi.Provider</code>.
                </li>
              </ol></li>
              <li>Setting the system property <var>log4j2.loggerContextFactory</var> to the name of the
                <code>LoggerContextFactory</code> class to use.
              </li>
              <li>Setting the property "log4j2.loggerContextFactory" in a properties file named
                "log4j2.LogManager.properties" to the name of the LoggerContextFactory class to use. The properties
                file must be on the classpath.
              </li>
            </ol>
          </subsection>
          <subsection name="ContextSelector">
            <p>
              ContextSelectors are called by the
              <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/impl/Log4jContextFactory.html">Log4j
              LoggerContext factory</a>. They perform the actual work of
              locating or creating a LoggerContext, which is the anchor for Loggers and their configuration.
              ContextSelectors are free to implement any mechanism they desire to manage LoggerContexts. The
              default Log4jContextFactory checks for the presence of a System Property named "Log4jContextSelector".
              If found, the property is expected to contain the name of the Class that implements the
              ContextSelector to be used.
            </p>
            <p>
              Log4j provides five ContextSelectors:
            </p>
            <dl>
              <dt><a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/selector/BasicContextSelector.html">BasicContextSelector</a></dt>
              <dd>Uses either a LoggerContext that has been stored in a ThreadLocal or a common LoggerContext.</dd>
              <dt><a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/selector/ClassLoaderContextSelector.html">ClassLoaderContextSelector</a></dt>
              <dd>Associates LoggerContexts with the ClassLoader that created the caller of the getLogger call. This is
              the default ContextSelector.</dd>
              <dt><a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/selector/JndiContextSelector.html">JndiContextSelector</a></dt>
              <dd>Locates the LoggerContext by querying JNDI.</dd>
              <dt><a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/async/AsyncLoggerContextSelector.html">AsyncLoggerContextSelector</a></dt>
              <dd>Creates a LoggerContext that ensures that all loggers are AsyncLoggers.</dd>
              <dt><a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/osgi/BundleContextSelector.html">BundleContextSelector</a></dt>
              <dd>Associates LoggerContexts with the ClassLoader of the bundle that created the caller of the getLogger
              call. This is enabled by default in OSGi environments.</dd>
            </dl>
          </subsection>
          <subsection name="ConfigurationFactory">
            <p>
              Modifying the way in which logging can be configured is usually one of the areas with the most
              interest. The primary method for doing that is by implementing or extending a
              <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/ConfigurationFactory.html">ConfigurationFactory</a>.
              Log4j provides two ways of adding new ConfigurationFactories. The first is by defining the system
              property named "log4j.configurationFactory" to the name of the class that should be searched first
              for a configuration. The second method is by defining the ConfigurationFactory as a Plugin.
            </p>
            <p>
              All the ConfigurationFactories are then processed in order. Each factory is called on its
              getSupportedTypes method to determine the file extensions it supports. If a configuration file
              is located with one of the specified file extensions then control is passed to that
              ConfigurationFactory to load the configuration and create the Configuration object.
            </p>
            <p>
              Most Configuration extend the BaseConfiguration class. This class expects that the subclass will
              process the configuration file and create a hierarchy of Node objects. Each Node is fairly simple
              in that it consists of the name of the node, the name/value pairs associated with the node, The
              PluginType of the node and a List of all of its child Nodes. BaseConfiguration will then be
              passed the Node tree and instantiate the configuration objects from that.
            </p>
            <pre class="prettyprint linenums">
@Plugin(name = "XMLConfigurationFactory", category = "ConfigurationFactory")
@Order(5)
public class XMLConfigurationFactory extends ConfigurationFactory {

    /**
     * Valid file extensions for XML files.
     */
    public static final String[] SUFFIXES = new String[] {".xml", "*"};

    /**
     * Returns the Configuration.
     * @param loggerContext The logger context.
     * @param source The InputSource.
     * @return The Configuration.
     */
    @Override
    public Configuration getConfiguration(final LoggerContext loggerContext, final ConfigurationSource source) {
        return new XmlConfiguration(loggerContext, source);
    }

    /**
     * Returns the file suffixes for XML files.
     * @return An array of File extensions.
     */
    public String[] getSupportedTypes() {
        return SUFFIXES;
    }
}</pre>
          </subsection>
          <subsection name="LoggerConfig">
            <p>
              LoggerConfig objects are where Loggers created by applications tie into the configuration. The Log4j
              implementation requires that all LoggerConfigs be based on the LoggerConfig class, so applications
              wishing to make changes must do so by extending the LoggerConfig class. To declare the new
              LoggerConfig, declare it as a Plugin of type "Core" and providing the name that applications
              should specify as the element name in the configuration. The LoggerConfig should also define
              a PluginFactory that will create an instance of the LoggerConfig.
            </p>
            <p>
              The following example shows how the root LoggerConfig simply extends a generic LoggerConfig.
            </p>
            <pre class="prettyprint linenums"><![CDATA[
@Plugin(name = "root", category = "Core", printObject = true)
public static class RootLogger extends LoggerConfig {

    @PluginFactory
    public static LoggerConfig createLogger(@PluginAttribute(value = "additivity", defaultBooleanValue = true) boolean additivity,
                                            @PluginAttribute(value = "level", defaultStringValue = "ERROR") Level level,
                                            @PluginElement("AppenderRef") AppenderRef[] refs,
                                            @PluginElement("Filters") Filter filter) {
        List<AppenderRef> appenderRefs = Arrays.asList(refs);
        return new LoggerConfig(LogManager.ROOT_LOGGER_NAME, appenderRefs, filter, level, additivity);
    }
}]]></pre>
          </subsection>
          <subsection name="LogEventFactory">
            <p>A LogEventFactory is used to generate LogEvents. Applications may replace the standard LogEventFactory
              by setting the value of the system property Log4jLogEventFactory to the name of the custom
              LogEventFactory class. </p>
            <p>Note: When log4j is configured to have <a href="async.html#AllAsync">all loggers asynchronous</a>,
              log events are pre-allocated in a ring buffer and the LogEventFactory is not used.</p>
          </subsection>
        <subsection name="MessageFactory">
          <p>A MessageFactory is used to generate Message objects. Applications may replace the standard
            ParameterizedMessageFactory (or ReusableMessageFactory in garbage-free mode)
            by setting the value of the system property log4j2.messageFactory to the name of the custom
            MessageFactory class. </p>
          <p>Flow messages for the <tt>Logger.entry()</tt> and <tt>Logger.exit()</tt> methods have a separate FlowMessageFactory.
            Applications may replace the DefaultFlowMessageFactory by setting the value of the system property
            log4j2.flowMessageFactory to the name of the custom FlowMessageFactory class.
          </p>
        </subsection>
          <subsection name="Lookups">
            <p>
              Lookups are the means in which parameter substitution is performed. During Configuration initialization
              an "Interpolator" is created that locates all the Lookups and registers them for use when a variable
              needs to be resolved. The interpolator matches the "prefix" portion of the variable name to a
              registered Lookup and passes control to it to resolve the variable.
            </p>
            <p>
              A Lookup must be declared using a Plugin annotation with a type of "Lookup". The name specified on
              the Plugin annotation will be used to match the prefix.  Unlike other Plugins, Lookups do not
              use a PluginFactory. Instead, they are required to provide a constructor that accepts no arguments.
              The example below shows a Lookup that will return the value of a System Property.
            </p>
            <p>The provided Lookups are documented here: <a href="./lookups.html">Lookups</a></p>
            <pre class="prettyprint linenums">
@Plugin(name = "sys", category = "Lookup")
public class SystemPropertiesLookup implements StrLookup {

    /**
     * Lookup the value for the key.
     * @param key  the key to be looked up, may be null
     * @return The value for the key.
     */
    public String lookup(String key) {
        return System.getProperty(key);
    }

    /**
     * Lookup the value for the key using the data in the LogEvent.
     * @param event The current LogEvent.
     * @param key  the key to be looked up, may be null
     * @return The value associated with the key.
     */
    public String lookup(LogEvent event, String key) {
        return System.getProperty(key);
    }
}</pre>
          </subsection>
          <subsection name="Filters">
            <p>
              As might be expected, Filters are the used to reject or accept log events as they pass through the
              logging system. A Filter is declared using a Plugin annotation of type "Core" and an elementType of
              "filter". The name attribute on the Plugin annotation is used to specify the name of the element
              users should use to enable the Filter. Specifying the printObject attribute with a value of "true"
              indicates that a call to toString will format the arguments to the filter as the configuration
              is being processed. The Filter must also specify a PluginFactory method that will be called to
              create the Filter.
            </p>
            <p>
              The example below shows a Filter used to reject LogEvents based upon their logging level. Notice the
              typical pattern where all the filter methods resolve to a single filter method.
            </p>
            <pre class="prettyprint linenums">
@Plugin(name = "ThresholdFilter", category = "Core", elementType = "filter", printObject = true)
public final class ThresholdFilter extends AbstractFilter {

    private final Level level;

    private ThresholdFilter(Level level, Result onMatch, Result onMismatch) {
        super(onMatch, onMismatch);
        this.level = level;
    }

    public Result filter(Logger logger, Level level, Marker marker, String msg, Object[] params) {
        return filter(level);
    }

    public Result filter(Logger logger, Level level, Marker marker, Object msg, Throwable t) {
        return filter(level);
    }

    public Result filter(Logger logger, Level level, Marker marker, Message msg, Throwable t) {
        return filter(level);
    }

    @Override
    public Result filter(LogEvent event) {
        return filter(event.getLevel());
    }

    private Result filter(Level level) {
        return level.isAtLeastAsSpecificAs(this.level) ? onMatch : onMismatch;
    }

    @Override
    public String toString() {
        return level.toString();
    }

    /**
     * Create a ThresholdFilter.
     * @param loggerLevel The log Level.
     * @param match The action to take on a match.
     * @param mismatch The action to take on a mismatch.
     * @return The created ThresholdFilter.
     */
    @PluginFactory
    public static ThresholdFilter createFilter(@PluginAttribute(value = "level", defaultStringValue = "ERROR") Level level,
                                               @PluginAttribute(value = "onMatch", defaultStringValue = "NEUTRAL") Result onMatch,
                                               @PluginAttribute(value = "onMismatch", defaultStringValue = "DENY") Result onMismatch) {
        return new ThresholdFilter(level, onMatch, onMismatch);
    }
}</pre>
          </subsection>
          <subsection name="Appenders">
            <p>
              Appenders are passed an event, (usually) invoke a Layout to format the event, and then "publish"
              the event in whatever manner is desired. Appenders are declared as Plugins with a type of "Core"
              and an elementType of "appender". The name attribute on the Plugin annotation specifies the name
              of the element users must provide in their configuration to use the Appender. Appenders should
              specify printObject as "true" if the toString method renders the values of the attributes passed
              to the Appender.
            </p>
            <p>
              Appenders must also declare a PluginFactory method that will create the appender. The example
              below shows an Appender named "Stub" that can be used as an initial template.
            </p>
            <p>
              Most Appenders use Managers. A manager actually "owns" the resources, such as an OutputStream or
              socket. When a reconfiguration occurs a new Appender will be created. However, if nothing significant
              in the previous Manager has changed, the new Appender will simply reference it instead of creating a
              new one. This insures that events are not lost while a reconfiguration is taking place without
              requiring that logging pause while the reconfiguration takes place.
            </p>
            <pre class="prettyprint linenums"><![CDATA[
@Plugin(name = "Stub", category = "Core", elementType = "appender", printObject = true)
public final class StubAppender extends AbstractOutputStreamAppender<StubManager> {

    private StubAppender(String name,
                         Layout<? extends Serializable> layout,
                         Filter filter,
                         boolean ignoreExceptions,
                         StubManager  manager) {
        super(name, layout, filter, ignoreExceptions, true, manager);
    }

    @PluginFactory
    public static StubAppender createAppender(@PluginAttribute("name") String name,
                                              @PluginAttribute("ignoreExceptions") boolean ignoreExceptions,
                                              @PluginElement("Layout") Layout layout,
                                              @PluginElement("Filters") Filter filter) {

        if (name == null) {
            LOGGER.error("No name provided for StubAppender");
            return null;
        }

        StubManager manager = StubManager.getStubManager(name);
        if (manager == null) {
            return null;
        }
        if (layout == null) {
            layout = PatternLayout.createDefaultLayout();
        }
        return new StubAppender(name, layout, filter, ignoreExceptions, manager);
    }
}]]></pre>
          </subsection>
          <subsection name="Layouts">
            <p>
              Layouts perform the formatting of events into the printable text that is written by Appenders to
              some destination. All Layouts must implement the Layout interface. Layouts that format the
              event into a String should extend AbstractStringLayout, which will take care of converting the
              String into the required byte array.
            </p>
            <p>
              Every Layout must declare itself as a plugin using the Plugin annotation. The type must be "Core",
              and the elementType must be "layout". printObject should be set to true if the plugin's toString
              method will provide a representation of the object and its parameters. The name of the plugin must
              match the value users should use to specify it as an element in their Appender configuration.
              The plugin also must provide a static method annotated as a PluginFactory and with each of the
              methods parameters annotated with PluginAttr or PluginElement as appropriate.
            </p>
            <pre class="prettyprint linenums">
@Plugin(name = "SampleLayout", category = "Core", elementType = "layout", printObject = true)
public class SampleLayout extends AbstractStringLayout {

    protected SampleLayout(boolean locationInfo, boolean properties, boolean complete,
                           Charset charset) {
    }

    @PluginFactory
    public static SampleLayout createLayout(@PluginAttribute("locationInfo") boolean locationInfo,
                                            @PluginAttribute("properties") boolean properties,
                                            @PluginAttribute("complete") boolean complete,
                                            @PluginAttribute(value = "charset", defaultStringValue = "UTF-8") Charset charset) {
        return new SampleLayout(locationInfo, properties, complete, charset);
    }
}</pre>
          </subsection>
          <subsection name="PatternConverters">
            <p>
              PatternConverters are used by the PatternLayout to format the log event into a printable String. Each
              Converter is responsible for a single kind of manipulation, however Converters are free to format
              the event in complex ways. For example, there are several converters that manipulate Throwables and
              format them in various ways.
            </p>
            <p>
              A PatternConverter must first declare itself as a Plugin using the standard Plugin annotation but
              must specify value of "Converter" on the type attribute. Furthermore, the Converter must also
              specify the ConverterKeys attribute to define the tokens that can be specified in the pattern
              (preceded by a '%' character) to identify the Converter.
            </p>
            <p>
              Unlike most other Plugins, Converters do not use a PluginFactory. Instead, each Converter is
              required to provide a static newInstance method that accepts an array of Strings as the only
              parameter. The String array are the values that are specified within the curly braces that can
              follow the converter key.
            </p>
            <p>
              The following shows the skeleton of a Converter plugin.
            </p>
            <pre class="prettyprint linenums">
@Plugin(name = "query", category = "Converter")
@ConverterKeys({"q", "query"})
public final class QueryConverter extends LogEventPatternConverter {

    public QueryConverter(String[] options) {
    }

    public static QueryConverter newInstance(final String[] options) {
      return new QueryConverter(options);
    }
}</pre>
          </subsection>
          <subsection name="Plugin Builders">
            <p>
              Some plugins take a lot of optional configuration options. When a plugin takes many options, it is more
              maintainable to use a builder class rather than a factory method (see <i>Item 2: Consider a builder when
              faced with many constructor parameters</i> in <i>Effective Java</i> by Joshua Bloch). There are some other
              advantages to using an annotated builder class over an annotated factory method:
            </p>
            <ul>
              <li>Attribute names don't need to be specified if they match the field name.</li>
              <li>Default values can be specified in code rather than through an annotation (also allowing a
              runtime-calculated default value which isn't allowed in annotations).</li>
              <li>Adding new optional parameters doesn't require existing programmatic configuration to be refactored.</li>
              <li>Easier to write unit tests using builders rather than factory methods with optional parameters.</li>
              <li>Default values are specified via code rather than relying on reflection and injection, so they work
              programmatically as well as in a configuration file.</li>
            </ul>
            <p>
              Here is an example of a plugin factory from <code>ListAppender</code>:
            </p>
            <pre class="prettyprint linenums"><![CDATA[
@PluginFactory
public static ListAppender createAppender(
        @PluginAttribute("name") @Required(message = "No name provided for ListAppender") final String name,
        @PluginAttribute("entryPerNewLine") final boolean newLine,
        @PluginAttribute("raw") final boolean raw,
        @PluginElement("Layout") final Layout<? extends Serializable> layout,
        @PluginElement("Filter") final Filter filter) {
    return new ListAppender(name, filter, layout, newLine, raw);
}]]></pre>
            <p>
              Here is that same factory using a builder pattern instead:
            </p>
            <pre class="prettyprint linenums"><![CDATA[
@PluginBuilderFactory
public static Builder newBuilder() {
    return new Builder();
}

public static class Builder implements org.apache.logging.log4j.core.util.Builder<ListAppender> {

    @PluginBuilderAttribute
    @Required(message = "No name provided for ListAppender")
    private String name;

    @PluginBuilderAttribute
    private boolean entryPerNewLine;

    @PluginBuilderAttribute
    private boolean raw;

    @PluginElement("Layout")
    private Layout<? extends Serializable> layout;

    @PluginElement("Filter")
    private Filter filter;

    public Builder setName(final String name) {
        this.name = name;
        return this;
    }

    public Builder setEntryPerNewLine(final boolean entryPerNewLine) {
        this.entryPerNewLine = entryPerNewLine;
        return this;
    }

    public Builder setRaw(final boolean raw) {
        this.raw = raw;
        return this;
    }

    public Builder setLayout(final Layout<? extends Serializable> layout) {
        this.layout = layout;
        return this;
    }

    public Builder setFilter(final Filter filter) {
        this.filter = filter;
        return this;
    }

    @Override
    public ListAppender build() {
        return new ListAppender(name, filter, layout, entryPerNewLine, raw);
    }
}]]></pre>
            <p>
              The only difference in annotations is using <code>@PluginBuilderAttribute</code> instead of
              <code>@PluginAttribute</code> so that default values and reflection can be used instead of specifying
              them in the annotation. Either annotation can be used in a builder, but the former is better suited
              for field injection while the latter is better suited for parameter injection. Otherwise, the same
              annotations (<code>@PluginConfiguration</code>, <code>@PluginElement</code>, <code>@PluginNode</code>,
              and <code>@PluginValue</code>) are all supported on fields. Note that a factory method is still required
              to supply a builder, and this factory method should be annotated with <code>@PluginBuilderFactory</code>.
              <!-- TODO: this will change with LOG4J2-1188 -->
            </p>
            <p>
              When plugins are being constructed after a configuration has been parsed, a plugin builder will be used
              if available, otherwise a plugin factory method will be used as a fallback. If a plugin contains neither
              factory, then it cannot be used from a configuration file (it can still be used programmatically of
              course).
            </p>
            <p>
              Here is an example of using a plugin factory versus a plugin builder programmatically:
            </p>
            <pre class="prettyprint linenums"><![CDATA[
ListAppender list1 = ListAppender.createAppender("List1", true, false, null, null);
ListAppender list2 = ListAppender.newBuilder().setName("List1").setEntryPerNewLine(true).build();
]]></pre>
          </subsection>
        <subsection name="Custom ContextDataInjector">
          <p>
            The <code>ContextDataInjector</code> (introduced in Log4j 2.7) is responsible for
            populating the LogEvent's
            <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/LogEvent.html#getContextData()">context data</a>
            with key-value pairs or replacing it completely.
            The default implementation is ThreadContextDataInjector, which obtains context attributes from the ThreadContext.
          </p><p>
          Applications may replace the default ContextDataInjector by setting the value of the system property
          <tt>log4j2.contextDataInjector</tt> to the name of the custom ContextDataInjector class.
        </p><p>
          Implementors should be aware there are some subtleties related to thread-safety and implementing a
          context data injector in a garbage-free manner.
          See the <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/ContextDataInjector.html">ContextDataInjector</a>
          javadoc for detail.
        </p>
        </subsection>
        <subsection name="Custom ThreadContextMap implementations">
          <p>
            A garbage-free StringMap-based context map can be installed by setting system property <tt>log4j2.garbagefreeThreadContextMap</tt>
            to true. (Log4j must be <a href="garbagefree.html#Config">enabled</a> to use ThreadLocals.)
          </p><p>
            Any custom <tt>ThreadContextMap</tt> implementation can be installed by setting system property
            <tt>log4j2.threadContextMap</tt> to the fully qualified class name of the class implementing the
            ThreadContextMap interface. By also implementing the <tt>ReadOnlyThreadContextMap</tt> interface, your custom
            ThreadContextMap implementation will be accessible to applications via the
          <a href="../log4j-api/apidocs/org/apache/logging/log4j/ThreadContext.html#getThreadContextMap()">ThreadContext::getThreadContextMap</a>
            method.
          </p>
        </subsection>
          <subsection name="Custom Plugins">
            <p>See the <a href="plugins.html">Plugins</a> section of the manual.</p>
<!-- TODO: some documentation here! -->
          </subsection>
      </section>

    </body>
</document>
