anchor.diff:            # Remove undefined values that are coming from evalIf.
             optValues = evalProperties defs;
           in
  -          if decls == [] then handleOptionSets optionHandler name optAttrs
  +          if decls == [] then recurseInto name optAttrs
             else lib.addErrorContext "while evaluating the option ${name}:" (
  -            if tail decls != [] then throw "Multiple options."
  -            else export opt optValues
  +            export opt optValues
             )
         ) opts
      else lib.addErrorContext "while evaluating ${path}:" (notHandle opts);
  
positive.code:           test = partition isOption opts;
            decls = test.right; defs = test.wrong;
  
            # Return the option declaration and add missing default
            # attributes.
            opt = {
              inherit name;
              merge = mergeDefaultOption;
              apply = lib.id;
            } // (head decls);
  
            # Return the list of option sets.
            optAttrs = map delayProperties defs;
  
negative.code: rec {
  
  
    hasType = x: isAttrs x && x ? _type;
    typeOf = x: if hasType x then x._type else "";
  
    isOption = attrs: (typeOf attrs) == "option";
    mkOption = attrs: attrs // {
      _type = "option";
      # name (this is the name of the attributem it is automatically generated by the traversal)
      # default (value used when no definition exists)
      # example (documentation)
      # description (documentation)
      # type (option type, provide a default merge function and ensure type correctness)
      # merge (function used to merge definitions into one definition: [ /type/ ] -> /type/)
      # apply (convert the option value to ease the manipulation of the option result)
      # options (set of sub-options declarations & definitions)
    };
  
    # Make the option declaration more user-friendly by adding default
    # settings and some verifications based on the declaration content (like
    # type correctness).
    addOptionMakeUp = {name, recurseInto}: decl:
      let
        init = {
          inherit name;
          merge = mergeDefaultOption;
          apply = lib.id;
        };
  
        mergeFromType = opt:
          if decl ? type && decl.type ? merge then
            opt // { merge = decl.type.merge; }
          else
            opt;
  
        addDeclaration = opt: opt // decl;
  
        ensureMergeInputType = opt:
          if decl ? type then
            opt // {
              merge = list:
                if all decl.type.check list then
                  opt.merge list
                else
                  throw "One of the definitions has a bad type.";
            }
          else opt;
  
        ensureDefaultType = opt:
          if decl ? type && decl ? default then
            opt // {
              default =
                if decl.type.check decl.default then
                  decl.default
                else
                  throw "The default value has a bad type.";
            }
          else opt;
  
        handleOptionSets = opt:
          if decl ? type && decl.type.hasOptions then
            opt // {
              merge = list:
                decl.type.iter
                  (path: opts: recurseInto path (decl.options ++ [opts]))
                  opt.name
                  (opt.merge list);
              options = recurseInto (decl.type.docPath opt.name) decl.options;
            }
          else
            opt;
      in
        foldl (opt: f: f opt) init [
          # default settings
          mergeFromType
  
          # user settings
          addDeclaration
  
          # override settings
          ensureMergeInputType
          ensureDefaultType
          handleOptionSets
        ];
  
    # Merge a list of options containning different field.  This is useful to
    # separate the merge & apply fields from the interface.
    mergeOptionDecls = opts:
      if opts == [] then {}
      else if tail opts == [] then
        let opt = head opts; in
        if opt ? options then
          opt // { options = toList opt.options; }
        else
          opt
      else
        fold (opt1: opt2:
          lib.addErrorContext "opt1 = ${lib.showVal opt1}\nopt2 = ${lib.showVal opt2}" (
          # You cannot merge if two options have the same field.
          assert opt1 ? default -> ! opt2 ? default;
          assert opt1 ? example -> ! opt2 ? example;
          assert opt1 ? description -> ! opt2 ? description;
          assert opt1 ? merge -> ! opt2 ? merge;
          assert opt1 ? apply -> ! opt2 ? apply;
          assert opt1 ? type -> ! opt2 ? type;
          if opt1 ? options || opt2 ? options then
            opt1 // opt2 // {
              options =
                 (toList (attrByPath ["options"] [] opt1))
              ++ (toList (attrByPath ["options"] [] opt2));
            }
          else
            opt1 // opt2
        )) {} opts;
  
  
    # name (name of the type)
    # check (boolean function)
    # merge (default merge function)
    # iter (iterate on all elements contained in this type)
    # fold (fold all elements contained in this type)
    # hasOptions (boolean: whatever this option contains an option set)
    # path (path contatenated to the option name contained contained in the option set)
    isOptionType = attrs: (typeOf attrs) == "option-type";
    mkOptionType = attrs@{
      name
    , check ? (x: true)
    , merge ? mergeDefaultOption
    # Handle complex structure types.
    , iter ? (f: path: v: f path v)
    , fold ? (op: nul: v: op v nul)
    , docPath ? lib.id
    # If the type can contains option sets.
    , hasOptions ? false
    }: { _type = "option-type";
      inherit name check merge iter fold docPath hasOptions;
    };
  
  
    type = {
  
      infere = mkOptionType {
        name = "infered type";
      };
  
      enable = mkOptionType {
        name = "boolean";
        check = builtins.isBool;
        merge = fold lib.or false;
      };
  
      int = mkOptionType {
        name = "integer";
        check = builtins.isInt;
      };
  
      string = mkOptionType {
        name = "string";
        check = x: builtins ? isString -> builtins.isString x;
        merge = lib.concatStrings;
      };
  
      attrs = mkOptionType {
        name = "attribute set";
        check = builtins.isAttrs;
        merge = fold lib.mergeAttrs {};
      };
  
      # derivation is a reserved keyword.
      package = mkOptionType {
        name = "derivation";
        check = x: builtins.isAttrs x && x ? outPath;
      };
  
  
      list = elemType: mkOptionType {
        name = "list of ${elemType.name}s";
        check = value: isList value && all elemType.check value;
        merge = concatLists;
        iter = f: path: list: map (elemType.iter f (path + ".*")) list;
        fold = op: nul: list: lib.fold (e: l: elemType.fold op l e) nul list;
        docPath = path: elemType (path + ".*");
        inherit (elemType) hasOptions;
      };
  
      attrsOf = elemType: mkOptionType {
        name = "attribute set of ${elemType}s";
        check = x: builtins.isAttrs x
          && fold (e: v: v && elemType.check e) true (lib.attrValues x);
        merge = fold lib.mergeAttrs {};
        iter = f: path: set: lib.mapAttrs (name: elemType.iter f (path + "." + name)) set;
        fold = op: nul: set: fold (e: l: elemType.fold op l e) nul (lib.attrValues set);
        docPath = path: elemType (path + ".<name>");
        inherit (elemType) hasOptions;
      };
  
      uniq = elemType: mkOptionType {
        inherit (elemType) name check iter fold docPath hasOptions;
        merge = list:
          if tail list == [] then
            head list
          else
            throw "Multiple definitions. Only one is allowed for this option.";
      };
  
      nullOr = elemType: mkOptionType {
        inherit (elemType) name merge docPath hasOptions;
        check = x: builtins.isNull x || elemType.check x;
        iter = f: path: v: if v == null then v else elemType.iter f path v;
        fold = op: nul: v: if v == null then nul else elemType.fold op nul v;
      };
  
      optionSet = mkOptionType {
        name = "option set";
        check = x: builtins.isAttrs x;
        hasOptions = true;
      };
  
    };
  
  
    # !!! This function will be removed because this can be done with the
    # multiple option declarations.
    addDefaultOptionValues = defs: opts: opts //
      builtins.listToAttrs (map (defName:
        { name = defName;
  