anchor.diff:    || builtins.isList x
     );
   
  +
     importIfPath = path:
       if isPath path then
         import path
       else
         path;
   
  +
     applyIfFunction = f: arg:
       if builtins.isFunction f then
         f arg
       else
         f;
   
  +
     isModule = m:
          (m ? config && isAttrs m.config && ! isOption m.config)
       || (m ? options && isAttrs m.options && ! isOption m.options);
  +
   
     # Convert module to a set which has imports / options and config
     # attributes.
  
positive.code:         operator = m: imap (moduleImport m) (getImports m);
        });
  
    selectDeclsAndDefs = modules:
      lib.concatMap (m:
        if m ? config || m ? options then
           [ (m.options or {}) ]
        ++ [ (m.config or {}) ]
        else
          [ m ]
      ) modules;
  
  
    moduleApply = funs: module:
      lib.mapAttrs (name: value:
  
negative.code: 
    fixMergeModules = initModules: {...}@args:
      lib.fix (result:
        # This trick avoids an infinite loop because names of attribute
        # are know and it is not required to evaluate the result of
        # moduleMerge to know which attributes are present as arguments.
        let module = { inherit (result) options config; }; in
        moduleMerge "" (
          moduleClosure initModules (module // args)
        )
      );
  
  
    # Visit all definitions to raise errors related to undeclared options.
    checkModule = path: {config, options, ...}@m:
  