Data
@param  {[type]}   assemble [description]
@param  {Function} next     [description]
@return {[type]}            [description]
function(assemble, next) {
      grunt.verbose.writeln('Assembling data'.cyan);

      // load data if specified
      var dataFiles = assemble.dataFiles;
      if (dataFiles && dataFiles.length > 0) {
        grunt.verbose.writeln(('\n' + 'Processing data...').grey);

        dataFiles.forEach(function(filepath) {
          var ext = path.extname(filepath);
          var filename = path.basename(filepath, ext);
          var fileReader = utils.dataFileReaderFactory(ext);
          var filecontent = grunt.file.read(filepath);

          //Skip empty data files, as they'd cause an error with compiler
          if (filecontent === '') {
            grunt.verbose.writeln('Reading ' + filepath + '...empty, ' + 'skipping'.yellow);
          } else {

            if (filename === 'data') {
              // if this is the base data file, load it into the options.data object directly
              assemble.options.data = _.extend({}, (assemble.options.data || {}), fileReader(filepath));
            } else {
              // otherwise it's an element in options.data
              var d = fileReader(filepath);
              var obj = null;
              if (d[filename]) {
                obj = d[filename];
              } else {
                obj = d;
              }

              if (_.isArray(obj)) {
                // if the object is an Array, union the results
                assemble.options.data[filename] = _.union((assemble.options.data[filename] || []), obj);
              } else {
                // extend the object
                assemble.options.data[filename] = _.extend({}, (assemble.options.data[filename] || {}), obj);
              }

            }
          }
        });
      }
      next(assemble);
    }