anchor.diff:  the Authentication class in link:#c-configuration-options[C.
   Configuration options]. All options with the prefix "auth" configure
   custom Authentication.
  +
  +=== ETag for dynamic content
  +
  +"ETag" or "entity tag" enables web application to make use of cached resources by allowing conditional requests from the client.
  +This is widely used for static resources like CSS or JS files.
  +
  +mangoo I/O offers this functionality for dynamic content as well. To make use of an entity tag, simply add the
  +following method at the returning response in your controller method.
  +
  +[NOTE]
  +If you are using a front-end HTTP server, please check the documentation on how it
  +handles ETag, as the popular nginx web server https://thinkingandcomputing.com/2014/09/27/enable-etag-nginx-resources-sent-gzip/[deliberately strips ETags] once gzip is applied.
  +
  +[source,java]
  +-----------------------------
  +public Response index() {
  +    return Response.withOk().andETag();
  +}
  +-----------------------------
  +
  +For more information on how ETag works, click https://en.wikipedia.org/wiki/HTTP_ETag[here].
  +
  +=== Administrative URLs
  +
  +mangoo I/O offers administrative URLs, which enables you to check certain application information via a web interface. The
  +following administrative URLs are available
  +
  +-------------------------------------------
  +/@routes
  +/@config
  +/@cache
  +/@health
  +-------------------------------------------
  +
  +[NOTE]
  +By default, the administrative URLs are enabled in dev mode and disabled in test and prod mode. You
  +can enable each administrative URL by setting the appropriate configuration value in your application.yaml.
  +see <<Configuration options>> for more information on this.
  +
  +==== /@routes
  +
  +Displays a list of all configured routes and their corresponding controllers and methods.
  +
  +==== /@config
  +
  +Displays a list of all configured properties and their corresponding values.
  +
  +[WARNING]
  +For security reasons the properties "application.secret", "smtp.username" and "smtp.password" is not available via the @config route.
  +
  +==== /@cache
  +
  +Displays a list of cache statistics including cache hits, cache misses, etc.
  +
  +==== /@health
  +
  +Displays a simple health check by returning "alive".
  +
  +== Working with JSON
  +
  +mangoo I/O uses https://github.com/boonproject/boon[boon] for parsing JSON. boon is a
  +http://rick-hightower.blogspot.de/2014/01/boon-json-in-five-minutes-faster-json.htm[very
  +fast] JSON handler with its main focus on serializing and deserializing of objects.
  +
  +=== JSON output
  +
  +Consider for example the following POJO.
  +
  +[source,java]
  +---------------------------------------------------------------
  +package models;
  +
  +public class Person {
  +    private String firstname;
  +    private String lastname;
  +    private int age;
  +
  +    public Person(String firstname, String lastname, int age) {
  +        this.firstname = firstname;
  +        this.lastname = lastname;
  +        this.age = age;
  +    }
  +
  +    public String getFirstname() {
  +        return firstname;
  +    }
  +
  +   public String getLastname() {
  +       return lastname;
  +    }
  +
  +    public int getAge() {
  +        return age;
  +    }
  +}
  +---------------------------------------------------------------
  +
  +To create a new person object and send it as a response you can simply can do this in
  +a controller
  +
  +[source,java]
  +----------------------------------------------------------
  +package controllers;
  +
  +import io.mangoo.routing.Response;
  +import models.Person;
  +
  +public class JsonController {
  +    public Response render() {
  +        Person person = new Person("Peter", "Parker", 24);
  +        return Response.withOk().andJsonBody(person);
  +    }
  +}
  +----------------------------------------------------------
  +
  +The output of the response will look as follows
  +
  +[source,json]
  +--------------------------
  +{
  +    "firstname" : "Peter",
  +    "lastname" : "Parker",
  +    "age" : 24
  +}
  +--------------------------
  +
  +=== JSON input
  +
  +To retrieve JSON which is send to your mangoo I/O application you have three options:
  +automatic object serialization, generic object convertion or working with the raw JSON
  +string.
  +
  +==== Automatic object convertion
  +
  +Consider the person class from above and the following JSON send to
  +mangoo I/O
  +
  +[source,json]
  +---------------------------
  +{
  +    "firstname" : "Petyr",
  +    "lastname" : "Baelish",
  +    "age" : 42
  +}
  +---------------------------
  +
  +To handle this JSON with automatic object convertion you can simply do this
  +in a controller.
  +
  +[source,java]
  +-----------------------------------------------
  +package controllers;
  +
  +import io.mangoo.routing.Response;
  +import models.Person;
  +
  +public class JsonController {
  +    public Response parse(Person person) {
  +        // TODO Do something with person object
  +        ...
  +    }
  +}
  +-----------------------------------------------
  +
  +You just pass the object you want to convert from the JSON request and
  +mangoo I/O automatically makes the serialization to your POJO, making it available
  +in your controller.
  +
  +==== Generic object convertion
  +
  +If you don't have a POJO and you want to retrieve the JSON content,
  +mangoo I/O offers you a generic way of retrieving the content through
  +the object body of a request to a Map<String, Object>.
  +
  +[source,java]
  +--------------------------------------------
  +package controllers;
  +
  +import io.mangoo.routing.Response;
  +
  +public class MyController {
  +    public Response parse(Body body) {
  +        Map<String, Object> myjson = body.asJSON();
  +        String foo = json.get("firstname");
  +    }
  +}
  +--------------------------------------------
  +
  +==== Handle raw JSON string
  +
  +If you don't want mangoo I/O to automatically convert a JSON input you
  +can also work with the raw JSON string. The body object contains the raw
  +values of a request. Here is an example
  +
  +[source,java]
  +-----------------------------------------
  +package controllers;
  +
  +import io.mangoo.routing.Response;
  +
  +public class MyController {
  +    public Response parse(Body body) {
  +        String content = body.asString();
  +        ...
  +    }
  +}
  +-----------------------------------------
  +
  +== Filters
  +
  +Filters are a way of executing code before each controller or each
  +method is executed. To execute a filter before a controller or method,
  +you can use the @FilterWith annotation. In fact, this is the only annotation
  +that comes from the mangoo I/O framework directly.
  +
  +[source,java]
  +---------------------------
  +@FilterWith(MyFilter.class)
  +---------------------------
  +
  +There are two types of filters in mangoo I/O: Controller/Method filters
  +and a global filter.
  +
  +=== Controller or method filter
  +
  +As mentioned, a filter can be added to a controller class or method. If
  +added to a controller class the filter will be exectued on every method
  +in the class. If added to a method, the filter will only be executed on
  +that method.
  +
  +[source,java]
  +----------------------------------------------------------
  +package controllers;
  +
  +import io.mangoo.annotations.FilterWith;
  +import io.mangoo.filters.AuthenticityFilter;
  +import io.mangoo.routing.Response;
  +
  +@FilterWith(MyFilter.class)
  +public class MyController {
  +
  +    public Response token() {
  +        return Response.withOk().andContent("foo", "bar");
  +    }
  +
  +    @FilterWith(AuthenticityFilter.class)
  +    public Response valid() {
  +        return Response.withOk().andContent("foo", "bar");
  +    }
  +}
  +----------------------------------------------------------
  +
  +On the above example, the Filter MyFilter will be executed when the
  +token() and the valid() method is called. The Filter AuthenticityFilter will
  +also be called, when the valid() method is called.
  +
  +You can assign multiple filters to a controller or a method.
  +
  +[source,java]
  +----------------------------------------------------------
  +@FilterWith({"MyFirstFilter.class, MySecondFilter.class"})
  +----------------------------------------------------------
  +
  +They are executed in order.
  +
  +==== Creating a filter
  +
  +A controller or method filter must implement the MangooFilter
  +interface.
  +
  +[source,java]
  +---------------------------------------------------------
  +package mangoo.io.filters;
  +
  +import io.mangoo.interfaces.MangooControllerFilter;
  +import io.mangoo.routing.bindings.Exchange;
  +
  +public class MyFilter implements MangooFilter {
  +
  +    @Override
  +    public Response filter(Request request, Response response) {
  +        //Do nothing for now
  +        return response;
  +    }
  +}
  +---------------------------------------------------------
  +
  +The main method of a filter is the filter method, which receives the
  +exchange class from mangoo I/O. This class gives you a handy way of manipulating
  +the request/response cycle. A long with other convenient methods, the
  +exchange class enables you access to the Unterdow HttpServerExchange
  +class.
  +
  +Here is an example of the AuthenticityFilter which is used for the CSRF checks,
  +showing you how to interact with the Undertow request/response cycle.
  +
  +[source,java]
  +-----------------------------------------------------------------------------------------------------
  +public class AuthenticityFilter implements MangooControllerFilter {
  +
  +    @Override
  +    public boolean filter(Exchange exchange) {
  +        if (!exchange.authenticityMatches()) {
  +            exchange.getHttpServerExchange().setResponseCode(StatusCodes.FORBIDDEN);
  +            exchange.getHttpServerExchange().getResponseSender().send(Templates.DEFAULT.forbidden());
  +
  +            return false;
  +        }
  +
  +        return true;
  +    }
  +}
  +-----------------------------------------------------------------------------------------------------
  +
  +As you can see in the example, you can change the status code, a long
  +with the content of the response inside a filter. The exchange.getHttpServerExchange()
  +offers even more method for customization.
  +
  +See the http://undertow.io/undertow-docs/undertow-docs-1.2.0/index.html[Undertow documentation] for
  +more information on the HttpServerExchange.
  +
  +One important part in a filter is the return value. If the filter method
  +returns true, it tells mangoo I/O to continue its executing and call
  +further filters. If the filter method
  +returns false mangoo I/O stops the execution of further filters
  +and controller method. One can say, that the request ends with the filter.
  +
  +=== Global filter
  +
  +Besides the controller class or method filter, there is a special filter
  +which can be executed globally. This means, that this filter is called on
  +every mapped request in the Routes class. This is useful if, for example, you have to
  +force the language for your application or if you have an application
  +that does not have any public content and requires authentication for
  +every request.
  +
  +A global filter works similar to a controller or method filter, but the
  +filter has to implement the MangooRequestFilter interface instead.
  +
  +[source,java]
  +------------------------------------------------------------
  +package filters;
  +
  +import io.mangoo.interfaces.MangooRequestFilter;
  +import io.mangoo.routing.bindings.Exchange;
  +
  +public class MyGlobalFilter implements MangooRequestFilter {
  +
  +    @Override
  +    public execute filter(Request request, Response response) {
  +        //Do nothing for now
  +        return response;
  +    }
  +}
  +------------------------------------------------------------
  +
  +[NOTE]
  +There can only be one global filter in your mangoo I/O application.
  +
  +== Logging
  +
  +mangoo I/O uses http://logback.qos.ch[Logback] for logging, enabling you
  +a variate of loggers to append to. If you are familiar with Log4j,
  +creating a new logger instance is trivial.
  +
  +[source,java]
  +-------------------------------------------------------------------------
  +private static final Logger LOG = LoggerFactory.getLogger(MyClass.class);
  +-------------------------------------------------------------------------
  +
  +You can configure your appenders in the logback.xml file located in
  +src/main/resources. By convention, there is also a special logback
  +configuration file for the prod mode. This file is called
  +logback.prod.xml and automatically used, when you are in prod mode. This file is
  +optional and if this file is not present, mangoo I/O will fallback to logback.xml
  +and further fallback to the logback settings from the logback base package.
  +
  +== Caching
  +
  +mangoo I/O uses https://github.com/google/guava/wiki/CachesExplained[Guava Cache] for storing and accessing values
  +in-memory. To use the cache in your application, simply inject the cache class.
  +
  +[source,java]
  +--------------------
  +@Inject
  +private Cache cache;
  +--------------------
  +
  +The cache offers some convenient functions for adding and removing values
  +from the cache.
  +
  +Check out the https://github.com/google/guava/wiki[Guava
  +documentation] on how to configure the cache.
  +
  +To use the cache, simply add or remove an entry by a specific key.
  +
  +[source,java]
  +--------------------
  +String foo = cache.get("myvalue", String.class);
  +--------------------
  +
  +One cool thing about the guava cache, is the option to pass a callable if the value is
  +not found in the cache.
  +
  +[source,java]
  +--------------------
  +// If the key wasn't in the "easy to compute" group, we need to
  +// do things the hard way.
  +  cache.get("myvalue", new Callable<Value>() {
  +    @Override
  +    public Value call() throws AnyException {
  +      return doThingsTheHardWay(key);
  +    }
  +  });
  +--------------------
  +
  +== Scheduling
  +
  +mangoo I/O uses the http://quartz-scheduler.org[Quartz Scheduler
  +Framework] for creating and executing periodic tasks. To create a new
  +task, create a simple Pojo that implements the Job interface from
  +Quartz.
  +
  +[source,java]
  +-----------------------------------------------------------------------------------------------------
  +package jobs;
  +
  +import org.quartz.Job;
  +import org.quartz.JobExecutionContext;
  +import org.quartz.JobExecutionException;
  +
  +import com.google.inject.Singleton;
  +
  +@Singleton
  +public class MyJob implements Job {
  +
  +    @Override
  +    public void execute(final JobExecutionContext jobExecutionContext) throws JobExecutionException {
  +        //Do nothing for now
  +    }
  +}
  +-----------------------------------------------------------------------------------------------------
  +
  +As this job is not scheduled or executed at all right now, you have to
  +tell the scheduler when to execute the task and to start the scheduler
  +itself. It is recommended to use the Lifecycle for scheduling tasks and
  +starting the scheduler.
  +
  +[source,java]
  +----------------------------------------------------------------------------------------------------------------------------------
  +package conf;
  +
  +import org.quartz.JobDetail;
  +import org.quartz.Trigger;
  +
  +import jobs.InfoJob;
  +import io.mangoo.interfaces.MangooLifecycle;
  +import io.mangoo.scheduler.MangooScheduler;
  +
  +import com.google.inject.Inject;
  +import com.google.inject.Singleton;
  +
  +@Singleton
  +public class Lifecycle implements MangooLifecycle {
  +
  +    @Inject
  +    private MangooScheduler mangooScheduler;
  +
  +    @Override
  +    public void applicationStarted() {
  +        JobDetail jobDetail = mangooScheduler.getJobDetail(MyJob.class, "MyJobDetail", "MyJobGroup");
  +        Trigger trigger = mangooScheduler.getTrigger("MyJobTrigger", "15 15 15 15 * ?", "MyTriggerGroup", "MyTriggerDescription");
  +
  +        mangooScheduler.schedule(jobDetail, trigger);
  +        mangooScheduler.start();
  +    }
  +}
  +----------------------------------------------------------------------------------------------------------------------------------
  +
  +To schedule the previously defined class, you have to create a JobDetail
  +and a Trigger which you pass to the scheduler. Once that is done, you
  +can start the scheduler by simply calling the start method.
  +
  +=== Custom Quartz Scheduler configuration
  +
  +If you require a custom configuration for quartz inside mangoo I/O you
  +can use the application.yaml to pass any option to quartz. Simply add the configuration option with the appropriate
  +prefix org.quartz.
  +
  +[source,yaml]
  +-------------------------------------
  +org:
  +  quartz:
  +    scheduler.instanceName=Foo
  +    scheduler.instanceId=Bar
  +-------------------------------------
  +
  +Check out the
  +http://quartz-scheduler.org/generated/2.2.1/html/qs-all/#page/Quartz_Scheduler_Documentation_Set%2F_qs_all.1.041.html%23[Quartz
  +Scheudler configuration documentation] for more information.
  +
  +== Sending eMails
  +
  +mangoo I/O uses the mature and well documentated
  +https://commons.apache.org/proper/commons-email/[Apache Commons Email].
  +to make sending eMails as easy as possible. If you want to send an eMail via mangoo I/O you need
  +the Mailer object. This can be easily injected in your controller.
  +
  +[source,java]
  +----------------------
  +@Inject
  +private Mailer mailer;
  +----------------------
  +
  +The Mailer object offers three functions for sending emails: sending a
  +plain text eMail, sending a html eMail and sending a multipart eMail.
  +Just create an eMail object you want to send and pass it to the appropiate mailer
  +function. You can check the
  +https://commons.apache.org/proper/commons-email/userguide.html[Apache
  +Commons Email documentation] on how to create the eMail objects you require.
  +
  +[NOTE]
  +You don't have to create any SMTP configuration programmatically as shown in the
  +Apache Commons Email documentation. This is all done via the application.yaml and passed to the Mailer class of your mangoo
  +I/O application, so you can set your host, port, username, password and ssl usage only once.
  +
  +Here is an example of how to send a plain text message.
  +
  +[source,java]
  +----------------------------------------------------
  +package mangoo.controllers;
  +
  +import io.mangoo.mail.Mailer;
  +import org.apache.commons.mail.Email;
  +import org.apache.commons.mail.SimpleEmail;
  +import com.google.inject.Inject;
  +
  +public class MailController {
  +
  +    @Inject
  +    private Mailer mailer;
  +
  +    public void mail() {
  +        Email email = new SimpleEmail();
  +        email.setFrom("user@gmail.com");
  +        email.setSubject("TestMail");
  +        email.setMsg("This is a test mail ... :-)");
  +        email.addTo("foo@bar.com");
  +
  +        mailer.send(email);
  +    }
  +}
  +----------------------------------------------------
  +
  +If you want an eMail with a message body that is rendered from a
  +template you can use the mangoo I/O TemplateEngine.
  +
  +[source,java]
  +------------------------------------------------------------------------------------------------------------------
  +package mangoo.controllers;
  +
  +import java.util.HashMap;
  +import java.util.Map;
  +
  +import io.mangoo.i18n.Messages;
  +import io.mangoo.mail.Mailer;
  +import io.mangoo.routing.bindings.Flash;
  +import io.mangoo.routing.bindings.Session;
  +import io.mangoo.templating.TemplateEngine;
  +
  +import org.apache.commons.mail.Email;
  +import org.apache.commons.mail.SimpleEmail;
  +
  +import com.google.inject.Inject;
  +
  +public class MailController {
  +
  +    @Inject
  +    private Mailer mailer;
  +
  +    @Inject
  +    private TemplateEngine templateEngine;
  +
  +    @Inject
  +    private Messages messages;
  +
  +    public void mail(Flash flash, Session session) {
  +        Map<String, Object> content = new HashMap<String, Object>();
  +        content.put("foo", "bar");
  +
  +        String message = templateEngine.render(flash, session, messages, "/myPackage", "myMailTemplate", content);
  +
  +        Email email = new SimpleEmail();
  +        email.setFrom("user@gmail.com");
  +        email.setSubject("TestMail");
  +        email.setMsg(message);
  +        email.addTo("foo@bar.com");
  +
  +        mailer.send(email);
  +    }
  +}
  +------------------------------------------------------------------------------------------------------------------
  +
  +== Using WebSockets
  +
  +Genereal information on using WebScokets can be found
  +http://en.wikipedia.org/wiki/WebSocket[here]. To use WebSockets in
  +mangoo I/O you have to extend the MangooWebSocket class in your WebSocket controller. Extending this
  +class offers you the entry points for using WebSockets methods.
  +
  +[source,java]
  +-------------------------------------------------------------------------------------------------
  +package controllers;
  +
  +import io.undertow.websockets.core.BufferedBinaryMessage;
  +import io.undertow.websockets.core.BufferedTextMessage;
  +import io.undertow.websockets.core.CloseMessage;
  +import io.undertow.websockets.core.WebSocketChannel;
  +import io.mangoo.interfaces.MangooWebSocket;
  +
  +public class WebSocketController extends MangooWebSocket {
  +    @Override
  +    protected void onFullTextMessage(WebSocketChannel channel, BufferedTextMessage message) {
  +        //Do nothing for now
  +    }
  +
  +    @Override
  +    protected void onFullBinaryMessage(WebSocketChannel channel, BufferedBinaryMessage message) {
  +        //Do nothing for now
  +    }
  +
  +    @Override
  +    protected void onFullPongMessage(WebSocketChannel channel, BufferedBinaryMessage message) {
  +        //Do nothing for now
  +    }
  +
  +    @Override
  +    protected void onCloseMessage(CloseMessage closeMessage,  WebSocketChannel channel) {
  +        //Do nothing for now
  +    }
  +}
  +-------------------------------------------------------------------------------------------------
  +
  +To use WebSockets on a specific request you have to map your WebSocket
  +Controller in the Routes class with an appropriate method.
  +
  +[source,java]
  +-----------------------------------------------------------------------------
  +Router.mapWebSocket().toUrl("/websocket").onClass(WebSocketController.class);
  +-----------------------------------------------------------------------------
  +
  +Now you can start creating an application to access your
  +WebScoketController at the URL "/websocket". Of course, you can have multiple
  +WebSocket controllers in your application, each mapped to a specific URL.
  +
  +== i18n Internationalization
  +
  +Translations in mangoo I/O are based on the standard Locale of Java. The
  +Locale is determined from each request from the Accept-Language header of
  +the request. If the Locale can not be determined from the request,
  +the default language of the application from application.yaml will be
  +used. If this configuration is not set, mangoo I/O will default to "en".
  +
  +If you want to force the language, you simply set the Locale in a filter
  +- see <<Filters>> for more information on filters.
  +
  +[source,java]
  +----------------------------------
  +Locale.setDefault(Locale.ENGLISH);
  +----------------------------------
  +
  +mangoo I/O offers you a convenient way of accessing translations. To get
  +hold of the translations simply inject the Messages class.
  +
  +[source,java]
  +---------------------------------------------------
  +package controllers;
  +
  +import com.google.inject.Inject;
  +
  +import io.mangoo.i18n.Messages;
  +import io.mangoo.routing.Response;
  +
  +public class I18nController {
  +
  +    @Inject
  +    private Messages messages;
  +
  +    public Response translation() {
  +        messages.get("my.translation");
  +        messages.get("my.othertranslation", "foo");
  +
  +         ...
  +    }
  +}
  +---------------------------------------------------
  +
  +The messages class offers you two methods of retrieving translations
  +from the resource bundle. In this example a translation is called with
  +and without passing optional parameters. The corresponding translation
  +entries in the resource bundle would look like this
  +
  +-----------------------------------------------------------------
  +my.translation=This is a translation
  +my.othertranslation=This is a translation with the paramater: {0}
  +-----------------------------------------------------------------
  +
  +Note the {0} which will be replaced by the passed paramter "foo".
  +
  +=== Translation in templates
  +
  +To access translation in a template, you can us a special tag a long with the key
  +for your translation.
  +
  +[source,html]
  +-------------------------
  +${i18n("my.translation")}
  +-------------------------
  +
  +To pass a parameter to the translation simply append the parameter
  +
  +[source,html]
  +-------------------------------------
  +${i18n("my.othertranslation", "foo")}
  +-------------------------------------
  +
  +If no key is found in the resource bundle the template will output an
  +empty value.
   
   == Handling static files and assets
   
  
positive.code: The Session class is automatically available in the template so you
  don't have to pass the class to the template via a controller.
  
  === Session encryption
  
  By default the values in the client-side cookie are signed with the
  application secret using SHA2(SHA-512), making manipulation of the
  
negative.code: create a key "success", "warning" or "error" in the flash class. Besides
  that, you can pass custom values to the flash class.
  
  ==== Flash in templates
  
  To access the flash values, simply call the appropriate key in your
  template.
  