     // =========================================================================
     // MARK: - Tag delimiters
     
-    /**
-    The delimiters for Mustache tags. All templates built with this
-    configuration are parsed using those delimiters.
-    
-    The default value is `("{{", "}}")`.
-    
-    Setting the tagDelimiterPair of a configuration affects all templates loaded
-    afterwards:
-    
-        // Globally, with Mustache.DefaultConfiguration:
-    
-        Mustache.DefaultConfiguration.tagDelimiterPair = ("<%", "%>")
-        let template1 = try! Template(string: "<% name %>)
-    
-        // Locally, using a TemplateRepository:
-    
-        let repository = TemplateRepository()
-        repository.configuration.tagDelimiterPair = ("[[", "]]")
-        let HTMLTemplate = try! repository.template(string: "[[ name ]]")
-    
-    You can also change the delimiters right in your templates using a "Set
-    Delimiter tag": `{{=[[ ]]=}}` changes delimiters to `[[` and `]]`.
-    */
+    /// The delimiters for Mustache tags. All templates built with this
+    /// configuration are parsed using those delimiters.
+    /// 
+    /// The default value is `("{{", "}}")`.
+    /// 
+    /// Setting the tagDelimiterPair of a configuration affects all templates
+    /// loaded afterwards:
+    /// 
+    ///     // Globally, with Mustache.DefaultConfiguration:
+    /// 
+    ///     Mustache.DefaultConfiguration.tagDelimiterPair = ("<%", "%>")
+    ///     let template = try! Template(string: "<% name %>)
+    /// 
+    ///     // Locally, using a TemplateRepository:
+    /// 
+    ///     let repository = TemplateRepository()
+    ///     repository.configuration.tagDelimiterPair = ("[[", "]]")
+    ///     let template = try! repository.template(string: "[[ name ]]")
+    /// 
+    /// You can also change the delimiters right in your templates using a "Set
+    /// Delimiter tag": `{{=[[ ]]=}}` changes delimiters to `[[` and `]]`.
     public var tagDelimiterPair: TagDelimiterPair
-    
 }
 
 
 // =============================================================================
 // MARK: - Default Configuration
 
-/**
-The default configuration that is used unless specified otherwise by a
-`TemplateRepository`.
-
-See also:
-
-- TemplateRepository
-*/
+/// The default configuration that is used unless specified otherwise by a
+/// TemplateRepository.
 public var DefaultConfiguration = Configuration()

// THE SOFTWARE.


/**
Configuration exposes properties that affect both the parsing and the rendering
of Mustache templates.


### What can be configured

Configuration covers:

- **Content type**: HTML templates escape rendered strings, while Text templates
  do not. Text templates are HTML-escaped as a whole when included in HTML
  templates.

- **Context stack**: values stored in a Configuration's context are readily
  available to templates.

- **Tag delimiters**: default Mustache delimiters are `{{` and `}}`. These are
  configurable.


### Usage

You setup a configuration *before* loading templates:

    // Template loaded later will not HTML-escape the rendered strings:
    Mustache.DefaultConfiguration.contentType = .Text
    
    // A text template
    let template = try! Template(string: "...")


### Configuration levels

There are three levels of configuration:

`Mustache.DefaultConfiguration` is a global variable that applies by default:

    Mustache.DefaultConfiguration.contentType = .Text

    // A text template
    let template = try! Template(named: "Document")

`TemplateRepository.configuration` only applies to templates loaded from the
template repository:

    let repository = TemplateRepository(directoryPath: "/path/to/templates")
    repository.configuration.contentType = .Text

    // A text template
    let template = try! repository.template(named: "Document")

Templates can also be configured individually. See the documentation of each
Configuration method for more details.
*/
public struct Configuration {
    
    // =========================================================================
    // MARK: - Factory Configuration
    
    /**
    Returns a factory configuration.
    
    Its contentType is HTML, baseContext empty, tag delimiters `{{` and `}}`.
    
    For example:
    
        // Make sure the template repository uses factory configuration,
        // regardless of changes made to `Mustache.DefaultConfiguration`:
    
        let repository = TemplateRepository(directoryPath: "/path/to/templates")
        repository.configuration = Configuration()


    */
    public init() {
        contentType = .html
        baseContext = Context()

    // =========================================================================
    // MARK: - Content Type
    
    /// The content type of strings rendered by templates built with this
    /// configuration.
    /// 
    /// It affects the HTML-escaping of your data:
    /// 
    /// - The `.html` content type has templates render HTML. This is the
    ///   default behavior. HTML template escape the input of variable tags such
    ///   as `{{name}}`. Use triple mustache tags `{{{content}}}` in order to
    ///   avoid HTML-escaping.
    /// 
    /// - The `.text` content type has templates render text. They do not
    ///   HTML-escape their input: `{{name}}` and `{{{name}}}` have identical,
    ///   non-escaped, renderings.
    /// 
    /// GRMustache safely keeps track of the content type of templates: should a
    /// HTML template embed a text template, the content of the text template
    /// would be HTML-escaped, as a whole.
    /// 
    /// Setting the contentType of a configuration affects the contentType of
    /// all templates loaded afterwards:
    /// 
    ///     // Globally, with Mustache.DefaultConfiguration:
    /// 
    ///     Mustache.DefaultConfiguration.contentType = .text
    ///     let textTemplate = try! Template(named: "Script")
    /// 
    ///     // Locally, using a TemplateRepository:
    /// 
    ///     let repository = TemplateRepository(bundle: Bundle.main)
    ///     repository.configuration.contentType = .html
    ///     let HTMLTemplate = try! repository.template(named: "HTMLDocument")
    /// 
    /// In order to set the content type of an individual templates, use pragma tags
    /// right in the content of your templates:
    /// 
    /// - `{{% CONTENT_TYPE:TEXT }}` turns a template into a text template.
    /// - `{{% CONTENT_TYPE:HTML }}` turns a template into a HTML template.
    /// 
    /// For example:
    /// 
    ///     {{! This template renders a bash script. }}
    ///     {{% CONTENT_TYPE:TEXT }}
    ///     export LANG={{ENV.LANG}}
    ///     ...
    /// 
    /// These pragmas must be found early in the template (before any value
    /// tag). Should several pragmas be found in a template content, the last
    /// one wins.
    public var contentType: ContentType
    
    
    // =========================================================================
    // MARK: - Context Stack
    
    /// The base context for templates rendering. All templates built with this
    /// configuration can access values stored in the base context.
    /// 
    /// The default base context is empty.
    /// 
    /// You can set it to some custom context, or extend it with the
    /// `extendBaseContext(_)` and `register(_:forKey:)` methods.
    /// 
    ///     // Globally, with Mustache.DefaultConfiguration:
    /// 
    ///     Mustache.DefaultConfiguration.baseContext = Context(["foo": "bar"])
    /// 
    ///     // "bar"
    ///     let template1 = try! Template(string: "{{foo}}")
    ///     try! template1.render()
    /// 
    ///     // Locally, using a TemplateRepository:
    ///     
    ///     let repository = TemplateRepository(bundle: Bundle.main)
    ///     repository.configuration.baseContext = Context(["foo": "bar"])
    ///     
    ///     // "bar"
    ///     let template2 = try! repository.template(string: "{{foo}}")
    ///     try! template2.render()
    /// 
    /// The base context can also be set for individual templates:
    /// 
    ///     let template3 = try! Template(string: "{{foo}}")
    ///     template3.baseContext = Context(["foo": "bar"])
    ///     
    ///     // "bar"
    ///     try! template3.render()
    /// 
    /// - seealso: extendBaseContext(_)
    /// - seealso: register(_:forKey:)
    public var baseContext: Context
    
    /// Extends the base context with the provided value. All templates built
    /// with this configuration can access the value.
    /// 
    ///     // Globally, with Mustache.DefaultConfiguration:
    /// 
    ///     Mustache.DefaultConfiguration.extendBaseContext(["foo": "bar"])
    /// 
    ///     // "bar"
    ///     let template1 = try! Template(string: "{{foo}}")
    ///     try! template1.render()
    /// 
    ///     // Locally, using a TemplateRepository:
    ///     
    ///     let repository = TemplateRepository(bundle: Bundle.main)
    ///     repository.configuration.extendBaseContext(["foo": "bar"])
    ///     
    ///     // "bar"
    ///     let template2 = try! repository.template(string: "{{foo}}")
    ///     try! template2.render()
    /// 
    /// The base context can also be extended for individual templates:
    /// 
    ///     let template3 = try! Template(string: "{{foo}}")
    ///     template3.extendBaseContext(["foo": "bar"])
    ///     
    ///     // "bar"
    ///     try! template3.render()
    /// 
    /// - parameter value: The value pushed on the top of the context stack.
    /// 
    /// - seealso: baseContext
    /// - seealso: register(_:forKey:)
    public mutating func extendBaseContext(_ value: Any?) {
        baseContext = baseContext.extendedContext(value)
    }
    
    /// Registers a key/value pair in the base context. All renderings will be
    /// able to access the provided value through this key.
    /// 
    /// Registered keys are looked up first when evaluating Mustache tags.
    /// 
    ///     // Globally, with Mustache.DefaultConfiguration:
    /// 
    ///     Mustache.DefaultConfiguration.register("bar", forKey: "foo")
    /// 
    ///     // Renders "bar"
    ///     let template1 = try! Template(string: "{{foo}}")
    ///     try! template1.render()
    /// 
    ///     // Renders "bar" again, because the registered value "bar" has priority.
    ///     try! template1.render(["foo": "qux"])
    /// 
    ///     // Locally, using a TemplateRepository:
    ///     
    ///     let repository = TemplateRepository(bundle: Bundle.main)
    ///     repository.configuration.register("bar", forKey: "foo")
    ///     
    ///     // "bar"
    ///     let template2 = try! repository.template(string: "{{foo}}")
    ///     try! template2.render()
    /// 
    /// Keys can also be registered in the base context of individual templates:
    /// 
    ///     let template3 = try! Template(string: "{{foo}}")
    ///     template3.register("bar", forKey: "foo")
    ///     
    ///     // "bar"
    ///     try! template3.render()
    /// 
    /// 
    /// - parameter key: An identifier.
    /// - parameter value: The value registered for *key*.
    /// 
    /// - seealso: baseContext
    /// - seealso: extendBaseContext(_)
    public mutating func register(_ value: Any?, forKey key: String) {
        baseContext = baseContext.extendedContext(withRegisteredValue: value, forKey: key)
    }
