text: /**/
  
  'use strict';
  
  var grunt = require('grunt');
  var path = require('path');
  
  
  /**/
  // 数据结构
  /* 
  {
  	task_name: {
  		files: [{
  			expand: true,
  			cwd: 'xx/front/src',
  			src: 'index.js' || ['index.js', 'option.js'] || '*.js' || ...,
  			dest: 'xx/resource/src'
  		}]
  	}
  } 
  */
  function preDisposeFiles (data, target) {
    var prop, obj;
    var files = [];
    if (grunt.util.kindOf(data) === 'object') {
      if ('src' in data || 'dest' in data) {
        obj = {};
        for (prop in data) {
          if (prop !== 'options') {
            obj[prop] = data[prop];
          }
        }
        files.push(obj);
      } else if (grunt.util.kindOf(data.files) === 'object') {
        for (prop in data.files) {
          files.push({src: data.files[prop], dest: grunt.config.process(prop)});
        }
      } else if (Array.isArray(data.files)) {
        grunt.util._.flatten(data.files).forEach(function(obj) {
          var prop;
          if ('src' in obj || 'dest' in obj) {
            files.push(obj);
          } else {
            for (prop in obj) {
              files.push({src: obj[prop], dest: grunt.config.process(prop)});
            }
          }
        });
      }
    } else {
      files.push({src: data, dest: grunt.config.process(target)});
    }
  
    // If no src/dest or files were specified, return an empty files array.
    if (files.length === 0) {
      // grunt.verbose.writeln('File: ' + '[no files]'.yellow);
      return [];
    }
  
    // Process all normalized file objects.
    files = grunt.util._(files).chain().forEach(function(obj) {
      if (!('src' in obj) || !obj.src) { return; }
      // Normalize .src properties to flattened array.
      if (Array.isArray(obj.src)) {
        obj.src = grunt.util._.flatten(obj.src);
      } else {
        obj.src = [obj.src];
      }
    }).map(function(obj) {
      // Build options object, removing unwanted properties.
      var expandOptions = grunt.util._.extend({}, obj);
      delete expandOptions.src;
      delete expandOptions.dest;
  
      // Expand file mappings.
      if (obj.expand) {
        return grunt.file.expandMapping(obj.src, obj.dest, expandOptions).map(function(mapObj) {
          // Copy obj properties to result.
          var result = grunt.util._.extend({}, obj);
          // Make a clone of the orig obj available.
          result.orig = grunt.util._.extend({}, obj);
          // Set .src and .dest, processing both as templates.
          result.src = grunt.config.process(mapObj.src);
          result.dest = grunt.config.process(mapObj.dest);
          // Remove unwanted properties.
          ['expand', 'cwd', 'flatten', 'rename', 'ext'].forEach(function(prop) {
            delete result[prop];
          });
          return result;
        });
      }
  
      // Copy obj properties to result, adding an .orig property.
      var result = grunt.util._.extend({}, obj);
      // Make a clone of the orig obj available.
      result.orig = grunt.util._.extend({}, obj);
  
      if ('src' in result) {
        // Expose an expand-on-demand getter method as .src.
        Object.defineProperty(result, 'src', {
          enumerable: true,
          get: function fn() {
            var src;
            if (!('result' in fn)) {
              src = obj.src;
              // If src is an array, flatten it. Otherwise, make it into an array.
              src = Array.isArray(src) ? grunt.util._.flatten(src) : [src];
              // Expand src files, memoizing result.
              fn.result = grunt.file.expand(expandOptions, src);
            }
            return fn.result;
          }
        });
      }
  
      if ('dest' in result) {
        result.dest = obj.dest;
      }
  
      return result;
    }).flatten().value();
  
    // Log this.file src and dest properties when --verbose is specified.
    if (grunt.option('verbose')) {
      files.forEach(function(obj) {
        var output = [];
        if ('src' in obj) {
          output.push(obj.src.length > 0 ? grunt.log.wordlist(obj.src) : '[no src]'.yellow);
        }
        if ('dest' in obj) {
          output.push('-> ' + (obj.dest ? String(obj.dest).cyan : '[no dest]'.yellow));
        }
        if (output.length > 0) {
          // grunt.verbose.writeln('Files: ' + output.join(' '));
        }
      });
    }
  
    return files;
  };
  
  
  function preDisposeOptions() {
    var args = [{}].concat(grunt.util.toArray(arguments));
    var options = grunt.util._.extend.apply(null, args);
    return options;
  };
  
  
  module.exports = {
  	files: preDisposeFiles,
  	options: preDisposeOptions
  };