anchor.diff:  
   The <<getting-started, jooby console>> takes care of all configuration steps required by the
   annotation processing tool.
  -
  -=== Parameters
  -
  -HTTP parameter provision is available via `*Param` annotations.
  -
  -==== Header
  -
  -Provisioning of headers is available via javadoc:annotations.HeaderParam[] annotation:
  -
  -.Headers
  -[source, java, role = "primary"]
  -----
  -public class MyController {
  -
  -  @GET
  -  public Object provisioning(@HeaderParam String token) {  // <1>
  -    ...
  -  }
  -}
  -----
  -
  -.Kotlin
  -[source, kotlin, role = "secondary"]
  -----
  -class MyController {
  -
  -  @GET
  -  fun provisioning(@HeaderParam token: String) : Any {  // <1>
  -    ...
  -  }
  -}
  -----
  -
  -<1> Access to HTTP header named `token`
  -
  -Compared to JAX-RS the parameter name on `@*Param` annotation is completely optional, but required for
  -non valid Java names:
  -
  -
  -.Non valid Java name
  -[source, java, role = "primary"]
  -----
  -public class MyController {
  -
  -  @GET
  -  public Object provisioning(@HeaderParam("Last-Modified-Since") long lastModifiedSince) {
  -    ...
  -  }
  -}
  -----
  -
  -.Kotlin
  -[source, kotlin, role = "secondary"]
  -----
  -class MyController {
  -
  -  @GET
  -  fun provisioning(@HeaderParam("Last-Modified-Since") lastModifiedSince: Long) : Any {
  -    ...
  -  }
  -}
  -----
  -
  -==== Cookie
  -
  -Provisioning of cookies is available via javadoc:annotations.CookieParam[] annotation:
  -
  -.Cookies
  -[source, java, role = "primary"]
  -----
  -public class MyController {
  -
  -  @GET
  -  public Object provisioning(@CookieParam String token) {  // <1>
  -    ...
  -  }
  -}
  -----
  -
  -.Kotlin
  -[source, kotlin, role = "secondary"]
  -----
  -class MyController {
  -
  -  @GET
  -  fun provisioning(@CookieParam token: String) : Any {  // <1>
  -    ...
  -  }
  -}
  -----
  -
  -<1> Access to cookie named `token`
  -
  -Compared to JAX-RS the parameter name on `@*Param` annotation is completely optional, but required for
  -non valid Java names:
  -
  -
  -.Non valid Java name
  -[source, java, role = "primary"]
  -----
  -public class MyController {
  -
  -  @GET
  -  public Object provisioning(@CookieParam("token-id") String tokenId) {
  -    ...
  -  }
  -}
  -----
  -
  -.Kotlin
  -[source, kotlin, role = "secondary"]
  -----
  -class MyController {
  -
  -  @GET
  -  fun provisioning(@CookieParam("token-id") tokenId: String) : Any {
  -    ...
  -  }
  -}
  -----
  -
  -==== Path
  -
  -For path parameters the javadoc:annotations.PathParam[] annotation is required:
  -
  -.PathParam
  -[source, java, role = "primary"]
  -----
  -public class MyController {
  -
  -  @Path("/{id}")
  -  public Object provisioning(@PathParam String id) {
  -    ...
  -  }
  -}
  -----
  -
  -.Kotlin
  -[source, kotlin, role = "secondary"]
  -----
  -class MyController {
  -
  -  @Path("/{id}")
  -  fun provisioning(@PathParam id: String) : Any {
  -    ...
  -  }
  -}
  -----
  -
  -==== Query
  -
  -For query parameters the javadoc:annotations.QueryParam[] annotation is required:
  -
  -.QueryParam
  -[source, java, role = "primary"]
  -----
  -public class MyController {
  -
  -  @Path("/")
  -  public Object provisioning(@QueryParam String q) {
  -    ...
  -  }
  -}
  -----
  -
  -.Kotlin
  -[source, kotlin, role = "secondary"]
  -----
  -class MyController {
  -
  -  @Path("/")
  -  fun provisioning(@QueryParam q: String) : Any {
  -    ...
  -  }
  -}
  -----
  -
  -==== Formdata/Multipart
  -
  -For formdata/multipart parameters the javadoc:annotations.FormParam[] annotation is required:
  -
  -.QueryParam
  -[source, java, role = "primary"]
  -----
  -public class MyController {
  -
  -  @Path("/")
  -  @POST
  -  public Object provisioning(@FormParam String username) {
  -    ...
  -  }
  -}
  -----
  -
  -.Kotlin
  -[source, kotlin, role = "secondary"]
  -----
  -class MyController {
  -
  -  @Path("/")
  -  @POST
  -  fun provisioning(@FormParam username: String) : Any {
  -    ...
  -  }
  -}
  -----
  -
  -==== Body
  -
  -Body parameter doesn't require an annotation:
  -
  -.HTTP Body
  -[source, java, role = "primary"]
  -----
  -public class MyController {
  -
  -  @Path("/")
  -  @POST
  -  public Object provisioning(MyObject body) {
  -    ...
  -  }
  -}
  -----
  -
  -.Kotlin
  -[source, kotlin, role = "secondary"]
  -----
  -class MyController {
  -
  -  @Path("/")
  -  @POST
  -  fun provisioning(body: MyObject) : Any {
  -    ...
  -  }
  -}
  -----
  -
  -==== Flash
  -
  -Provisioning of flash attribute is available via javadoc:annotations.FlashParam[] annotation:
  -
  -.Flash
  -[source, java, role = "primary"]
  -----
  -public class MyController {
  -
  -  @GET
  -  public Object provisioning(@FlashParam String success) {  // <1>
  -    ...
  -  }
  -}
  -----
  -
  -.Kotlin
  -[source, kotlin, role = "secondary"]
  -----
  -class MyController {
  -
  -  @GET
  -  fun provisioning(@FlashParam success: String) : Any {  // <1>
  -    ...
  -  }
  -}
  -----
  -
  -<1> Access to flash named `success`
  -
  -==== Session
  -
  -Provisioning of session attribute is available via javadoc:annotations.SessionParam[] annotation:
  -
  -.Session Attribute
  -[source, java, role = "primary"]
  -----
  -public class MyController {
  -
  -  @GET
  -  public Object provisioning(@SessionParam String userId) {  // <1>
  -    ...
  -  }
  -}
  -----
  -
  -.Kotlin
  -[source, kotlin, role = "secondary"]
  -----
  -class MyController {
  -
  -  @GET
  -  fun provisioning(@SessionParam userId: String) : Any {  // <1>
  -    ...
  -  }
  -}
  -----
  -
  -<1> Access to session attribute named `userId`
  -
  -Provisioning of javadoc:Session[] is available too:
  -
  -.Session Attribute
  -[source, java, role = "primary"]
  -----
  -public class MyController {
  -
  -  @GET
  -  public Object provisioning(Session session) {  // <1>
  -    ...
  -  }
  -}
  -----
  -
  -.Kotlin
  -[source, kotlin, role = "secondary"]
  -----
  -class MyController {
  -
  -  @GET
  -  fun provisioning(session: Session) : Any {  // <1>
  -    ...
  -  }
  -}
  -----
  -
  -<1> If no session exists yet, new session will be created
  -
  -To avoid this, just use `java.util.Optional<Session>` as type.
  -
  -==== Context
  -
  -Provisioning of context attributes is available via javadoc:annotations.ContextParam[] annotation:
  -
  -.Context Attribute
  -[source, java, role = "primary"]
  -----
  -public class MyController {
  -
  -  @GET
  -  public Object provisioning(@ContextParam String userId) {  // <1>
  -    ...
  -  }
  -}
  -----
  -
  -.Kotlin
  -[source, kotlin, role = "secondary"]
  -----
  -class MyController {
  -
  -  @GET
  -  fun provisioning(@ContextParam userId: String) : Any {  // <1>
  -    ...
  -  }
  -}
  -----
  -
  -<1> Access to context attribute named `userId`
  -
  -Provisioning of all javadoc:Context[getAttributes, text="attributes"] is available too:
  -
  -.Context Attributes
  -[source, java, role = "primary"]
  -----
  -public class MyController {
  -
  -  @GET
  -  public Object provisioning(@ContextParam Map<String, Object> attributes) {  // <1>
  -    ...
  -  }
  -}
  -----
  -
  -.Kotlin
  -[source, kotlin, role = "secondary"]
  -----
  -class MyController {
  -
  -  @GET
  -  fun provisioning(@ContextParam attributes: Map<String, Object>) : Any {  // <1>
  -    ...
  -  }
  -}
  -----
  -
  -<1> All context attributes must be set as arguments. They must be declared as `Map<String, Object>`
   
   === Registration
   
  
positive.code: 
  The executor must be registered before the MVC route/controller.
  
  === Suspend functions
  
  For Kotlin users MVC routes are allowed to use suspend functions
  
  .Kotlin Coroutines
  [source, kotlin]
  ----
  class SuspendMvc {
    @GET
    @Path("/delay")
    suspend fun delayed(ctx: Context): String {
      delay(100)
      return ctx.getRequestPath()
    }
  }
  
  fun main(args: Array<String>) {
    runApp(args) {
      use(SuspendMvc())
    }
  }
  ----
  
  {love}
  
  === JAX-RS Annotations
  
  Alternative you can use JAX-RS annotations to define MVC routes.
  
negative.code: 
  The javadoc:Jooby[mvc, javax.inject.Provider] does the same job, might or might not delegate
  instantiation to a dependency injection framework but most important let you control lifecycle of
  MVC routes (Singleton vs Non-Singleton routes).
  
  === Parameters
  
  HTTP parameter provision is available via `*Param` annotations.
  
  ==== Header
  
  Provisioning of headers is available via javadoc:annotations.HeaderParam[] annotation:
  
  .Headers
  [source, java, role = "primary"]
  ----
  public class MyController {
  
    @GET
    public Object provisioning(@HeaderParam String token) {  // <1>
      ...
    }
  }
  ----
  
  .Kotlin
  [source, kotlin, role = "secondary"]
  ----
  class MyController {
  
    @GET
    fun provisioning(@HeaderParam token: String) : Any {  // <1>
      ...
    }
  }
  ----
  
  <1> Access to HTTP header named `token`
  
  Compared to JAX-RS the parameter name on `@*Param` annotation is completely optional, but required for
  non valid Java names:
  
  
  .Non valid Java name
  [source, java, role = "primary"]
  ----
  public class MyController {
  
    @GET
    public Object provisioning(@HeaderParam("Last-Modified-Since") long lastModifiedSince) {
      ...
    }
  }
  ----
  
  .Kotlin
  [source, kotlin, role = "secondary"]
  ----
  class MyController {
  
    @GET
    fun provisioning(@HeaderParam("Last-Modified-Since") lastModifiedSince: Long) : Any {
      ...
    }
  }
  ----
  
  ==== Cookie
  
  Provisioning of cookies is available via javadoc:annotations.CookieParam[] annotation:
  
  .Cookies
  [source, java, role = "primary"]
  ----
  public class MyController {
  
    @GET
    public Object provisioning(@CookieParam String token) {  // <1>
      ...
    }
  }
  ----
  
  .Kotlin
  [source, kotlin, role = "secondary"]
  ----
  class MyController {
  
    @GET
    fun provisioning(@CookieParam token: String) : Any {  // <1>
      ...
    }
  }
  ----
  
  <1> Access to cookie named `token`
  
  Compared to JAX-RS the parameter name on `@*Param` annotation is completely optional, but required for
  non valid Java names:
  
  
  .Non valid Java name
  [source, java, role = "primary"]
  ----
  public class MyController {
  
    @GET
    public Object provisioning(@CookieParam("token-id") String tokenId) {
      ...
    }
  }
  ----
  
  .Kotlin
  [source, kotlin, role = "secondary"]
  ----
  class MyController {
  
    @GET
    fun provisioning(@CookieParam("token-id") tokenId: String) : Any {
      ...
    }
  }
  ----
  
  ==== Path
  
  For path parameters the javadoc:annotations.PathParam[] annotation is required:
  
  .PathParam
  [source, java, role = "primary"]
  ----
  public class MyController {
  
    @Path("/{id}")
    public Object provisioning(@PathParam String id) {
      ...
    }
  }
  ----
  
  .Kotlin
  [source, kotlin, role = "secondary"]
  ----
  class MyController {
  
    @Path("/{id}")
    fun provisioning(@PathParam id: String) : Any {
      ...
    }
  }
  ----
  
  ==== Query
  
  For query parameters the javadoc:annotations.QueryParam[] annotation is required:
  
  .QueryParam
  [source, java, role = "primary"]
  ----
  public class MyController {
  
    @Path("/")
    public Object provisioning(@QueryParam String q) {
      ...
    }
  }
  ----
  
  .Kotlin
  [source, kotlin, role = "secondary"]
  ----
  class MyController {
  
    @Path("/")
    fun provisioning(@QueryParam q: String) : Any {
      ...
    }
  }
  ----
  
  ==== Formdata/Multipart
  
  For formdata/multipart parameters the javadoc:annotations.FormParam[] annotation is required:
  
  .QueryParam
  [source, java, role = "primary"]
  ----
  public class MyController {
  
    @Path("/")
    @POST
    public Object provisioning(@FormParam String username) {
      ...
    }
  }
  ----
  
  .Kotlin
  [source, kotlin, role = "secondary"]
  ----
  class MyController {
  
    @Path("/")
    @POST
    fun provisioning(@FormParam username: String) : Any {
      ...
    }
  }
  ----
  
  ==== Body
  
  Body parameter doesn't require an annotation:
  
  .HTTP Body
  [source, java, role = "primary"]
  ----
  public class MyController {
  
    @Path("/")
    @POST
    public Object provisioning(MyObject body) {
      ...
    }
  }
  ----
  
  .Kotlin
  [source, kotlin, role = "secondary"]
  ----
  class MyController {
  
    @Path("/")
    @POST
    fun provisioning(body: MyObject) : Any {
      ...
    }
  }
  ----
  
  ==== Flash
  
  Provisioning of flash attribute is available via javadoc:annotations.FlashParam[] annotation:
  
  .Flash
  [source, java, role = "primary"]
  ----
  public class MyController {
  
    @GET
    public Object provisioning(@FlashParam String success) {  // <1>
      ...
    }
  }
  ----
  
  .Kotlin
  [source, kotlin, role = "secondary"]
  ----
  class MyController {
  
    @GET
    fun provisioning(@FlashParam success: String) : Any {  // <1>
      ...
    }
  }
  ----
  
  <1> Access to flash named `success`
  
  ==== Session
  
  Provisioning of session attribute is available via javadoc:annotations.SessionParam[] annotation:
  
  .Session Attribute
  [source, java, role = "primary"]
  ----
  public class MyController {
  
    @GET
    public Object provisioning(@SessionParam String userId) {  // <1>
      ...
    }
  }
  ----
  
  .Kotlin
  [source, kotlin, role = "secondary"]
  ----
  class MyController {
  
    @GET
    fun provisioning(@SessionParam userId: String) : Any {  // <1>
      ...
    }
  }
  ----
  
  <1> Access to session attribute named `userId`
  
  Provisioning of javadoc:Session[] is available too:
  
  .Session Attribute
  [source, java, role = "primary"]
  ----
  public class MyController {
  
    @GET
    public Object provisioning(Session session) {  // <1>
      ...
    }
  }
  ----
  
  .Kotlin
  [source, kotlin, role = "secondary"]
  ----
  class MyController {
  
    @GET
    fun provisioning(session: Session) : Any {  // <1>
      ...
    }
  }
  ----
  
  <1> If no session exists yet, new session will be created
  
  To avoid this, just use `java.util.Optional<Session>` as type.
  
  ==== Context
  
  Provisioning of context attributes is available via javadoc:annotations.ContextParam[] annotation:
  
  .Context Attribute
  [source, java, role = "primary"]
  ----
  public class MyController {
  
    @GET
    public Object provisioning(@ContextParam String userId) {  // <1>
      ...
    }
  }
  ----
  
  .Kotlin
  [source, kotlin, role = "secondary"]
  ----
  class MyController {
  
    @GET
    fun provisioning(@ContextParam userId: String) : Any {  // <1>
      ...
    }
  }
  ----
  
  <1> Access to context attribute named `userId`
  
  Provisioning of all javadoc:Context[getAttributes, text="attributes"] is available too:
  
  .Context Attributes
  [source, java, role = "primary"]
  ----
  public class MyController {
  
    @GET
    public Object provisioning(@ContextParam Map<String, Object> attributes) {  // <1>
      ...
    }
  }
  ----
  
  .Kotlin
  [source, kotlin, role = "secondary"]
  ----
  class MyController {
  
    @GET
    fun provisioning(@ContextParam attributes: Map<String, Object>) : Any {  // <1>
      ...
    }
  }
  ----
  
  <1> All context attributes must be set as arguments. They must be declared as `Map<String, Object>`
  
  === Responses
  
  ==== Status Code
  
  The default status code is `Success(200)`, except for `void` methods with the `@DELETE` annotation which is set to `No Content(204)`.
  
  There are two options if you need a different status code:
  
  - Add a javadoc:Context[] parameter and set the javadoc:Context[setResponseCode, io.jooby.StatusCode]
  - Returns a javadoc:StatusCode[] instance
  
  ==== NonBlocking
  
  Method returning a `CompletableFuture`, `Single`, `Maybe`, `Flowable`, `Mono` or `Flux` is
  considered a non-blocking route.
  
  Kotlin suspend functions are supported too: 
  
  .Kotlin Coroutines
  [source, kotlin]
  ----
  class SuspendMvc {
    @GET
    @Path("/delay")
    suspend fun delayed(ctx: Context): String {
      delay(100)
      return ctx.getRequestPath()
    }
  }
  
  fun main(args: Array<String>) {
    runApp(args) {
      use(SuspendMvc())
    }
  }
  ----
  
  A non-blocking route run on the event loop (by default) where *blocking is NOT allowed*. For more 
  details please checkout the <<responses-nonblocking, non-blocking responses>> section.
  
  === Execution model
  
  