     else
       callback null, filenames
 
-  loadContent = (filepath, callback) ->
-    ### Load content plugin for *filepath*. ###
-
-    env.logger.verbose "loading #{ filepath.relative }"
-
-    # any file not matched to a plugin will be handled by the static file plug
-    plugin =
-      class: StaticFile
-      group: 'files'
-
-    # iterate backwards over all content plugins and check if any plugin can handle this file
-    for i in [env.contentPlugins.length - 1..0] by -1
-      if minimatch filepath.relative, env.contentPlugins[i].pattern, minimatchOptions
-        plugin = env.contentPlugins[i]
-        break
-
-    # have the plugin's factory method create our instance
-    plugin.class.fromFile env, filepath, (error, instance) ->
-      # keep some references to the plugin and file used to create this instance
-      instance?.__plugin = plugin
-      instance?.__filename = filepath.full
-      callback error, instance
-
   createInstance = (filepath, callback) ->
     ### Create plugin or subtree instance for *filepath*. ###
-    async.waterfall [
-      async.apply fs.lstat, filepath.full
-      (stats, callback) ->
-        basename = path.basename filepath.relative
-
-        # recursively map directories to content tree instances
-        if stats.isDirectory()
-          ContentTree.fromDirectory env, filepath.full, (error, result) ->
-            result.parent = tree
-            tree[basename] = result
-            tree._.directories.push result # add instance to the directory group of its parent
-            callback error
-
-        # map files to content plugins
-        else if stats.isFile()
-          loadContent filepath, (error, instance) ->
-            if not error
-              instance.parent = tree
-              tree[basename] = instance
-              tree._[instance.__plugin.group].push instance
-            callback error
-
-        # This should never happen™
-        else
-          callback new Error "Invalid file #{ filepath.full }."
-
-    ], callback
+    setImmediate ->
+      async.waterfall [
+        async.apply fs.lstat, filepath.full
+        (stats, callback) ->
+          basename = path.basename filepath.relative
+
+          # recursively map directories to content tree instances
+          if stats.isDirectory()
+            ContentTree.fromDirectory env, filepath.full, (error, result) ->
+              result.parent = tree
+              tree[basename] = result
+              tree._.directories.push result # add instance to the directory group of its parent
+              callback error
+
+          # map files to content plugins
+          else if stats.isFile()
+            loadContent env, filepath, (error, instance) ->
+              if not error
+                instance.parent = tree
+                tree[basename] = instance
+                tree._[instance.__plugin.group].push instance
+              callback error
+
+          # This should never happen™
+          else
+            callback new Error "Invalid file #{ filepath.full }."
+      ], callback
 
   createInstances = (filenames, callback) ->
     # NOTE: the file limit is not really enforced here since this is a recursive function
     #       but won't be a problem in 99% of cases, patches welcome :-)
+    # TODO: actually this has to be fixed, we want an error to stop instance creation
     async.forEachLimit filenames, env.config._fileLimit, createInstance, callback
 
   async.waterfall [

  tree = new ContentTree env, reldir

  env.logger.verbose "creating content tree from #{ directory }"

  # options passed to minimatch for ignore and plugin matching
  minimatchOptions =
    dot: false

  readDirectory = (callback) ->
    fs.readdir directory, callback


### Exports ###

module.exports = {ContentTree, ContentPlugin, loadContent}
