     path = fs.path if fs and !path
     return
 
+  # TODO: howto validate a virtual file?
+  # fake a stat object.
+  # currently has only virtual folder object. (no virtual file yet)
+  #_validate: (file)-> file.hasOwnProperty('contents') and file.contents?
+  inspect: ->
+    name = 'File'
+    if @loaded()
+      name = 'Folder' if @isDirectory()
+    else
+      name += '?'
+    '<'+ name + ' ' + @_inspect() + '>'
+
   isDirectory: ->
     if @hasOwnProperty('isDir') and @isDir isnt undefined
       result = @isDir
     else
       result = super()
     result
+
+  toObject: (options, aExclude)->
+    if isString aExclude
+      aExclude = [aExclude]
+    else if !isArray aExclude
+      aExclude = []
+    aExclude.push 'contents' unless @hasOwnProperty('contents')
+    aExclude.push 'stat' unless @hasOwnProperty('stat')
+    @exportTo(options, aExclude)
 
   getContentSync: (aOptions)->
     aOptions = {} unless isObject aOptions

    if result
      @assign result
      @$cfgPath = result.$cfgPath if result.$cfgPath
      aContents = result.contents if result.contents
      if aOptions.recursive and @isDirectory()
        for vFile in aContents
          vFile.loadSync aOptions if vFile.isDirectory()
    result

  _getBufferSync: (aFile)->

    # TODO:whether export the non-enumerable $compiled attribute?
    result

  convertVirtualFolder: (aContents)->
    for k in aContents
      if k.path?
        k.base = @path
        setPrototypeOf k, @
    aContents

  loadConfig: (aOptions, aContents, done)->
    that = @
    processCfg = (err, aConfig)->
      return done(err) if err
      if aConfig
        that.assign aConfig
        if that.isDirectory()
          if aConfig.contents #virtual folder
            that.convertVirtualFolder(result.contents)
            aContents = result.contents
          if aOptions.recursive
            aContents = aContents.filter (f)->f.isDirectory()
            Promise.map aContents, (f)->
              f.load aOptions if f instanceof Resource
            .nodeify (err, result)->
              done(err, aConfig)
            return
      done(err, aConfig)
      return

    if !aOptions.stat.isDirectory()
