
var fs = require('fs');
var path = require('path');
var gulp = require('gulp');
var through = require('through');

var clone = require('./clone');
var options = require('./options');
var depsline = require('./depsline');


goog = {
	dependencies_: {
	  pathIsModule: {}, // 1 to 1
	  nameToPath: {}, // 1 to 1
	  requires: {}, // 1 to many
	  visited: {}, // Used when resolving dependencies to prevent us from visiting file twice.
	  written: {}, // Used to keep track of script files we have written.
	  deferred: {}, // Used to track deferred module evaluations in old IEs
	},
	addDependency: function(relPath, provides, requires, opt_isModule) {
		if (relPath[0]!=='/') {
			if (!options.closureLibrary) {
				throw new Error('Missing Closure Library for ' + relPath + ' dependency.');
			}

			relPath = options.closureLibrary + '/closure/goog/' + relPath;
		}

	    var provide, require;
	    var filepath = path.normalize(relPath.replace(/\\/g, '/'));
	    var deps = goog.dependencies_;
	    for (var i = 0; provide = provides[i]; i++) {
	      deps.nameToPath[provide] = filepath;
	      deps.pathIsModule[filepath] = !!opt_isModule;
	    }
	    for (var j = 0; require = requires[j]; j++) {
	      if (!(filepath in deps.requires)) {
	        deps.requires[filepath] = {};
	      }
	      deps.requires[filepath][require] = true;
	    }
	}
}

global['goog'] = goog;
goog.dependencies = clone(goog.dependencies_);
var cachedDeps = clone(goog.dependencies_);
var cache = {};
var pending = [];
var inited = false;


exports.init = function(closureLibrary) {
	if (inited===false) {
		inited = true;

		if (closureLibrary) {
			require(closureLibrary + '/closure/goog/deps.js');
		}

		cachedDeps = clone(goog.dependencies_);
		goog.dependencies = clone(goog.dependencies_);
	}
}


exports.nameToPath = function(namespace) {
	return goog.dependencies.nameToPath[namespace];
}


exports.changed = function(filepath, force, fn) {
	var prev = cache[filepath]||'';
	cache[filepath] = depsline(filepath, fs.readFileSync(filepath, 'utf-8'));

	if (pending.length) {
		pending.push(fn);

	} else if (filepath.indexOf(options.closureLibrary)===0) {
		fn();

	} else if (prev!==cache[filepath] || force) {
		pending.push(fn);

		inited = true;
		goog.dependencies_ = clone(cachedDeps);

		gulp.src(options.globs).
		    pipe(through(function(file) {
		    	cache[file.path] = depsline(file.path, file.contents.toString());
		    	eval(cache[file.path]);

		    }, function() {
		    	var _pending = pending;
	    		pending = [];

	    		goog.dependencies = clone(goog.dependencies_);
	    		_pending.forEach(function(fn) { fn() });
		    }));

	} else {
		fn();
	}
};


exports.isReachable = function(filepath) {
	if (goog.dependencies.reachable===undefined) {
		goog.dependencies.reachable = {};

		var entry;
		var queue = [options.entry];

		while (queue.length) {
			if (entry = queue.pop()) {
				if (goog.dependencies.reachable[entry]===undefined) {
					goog.dependencies.reachable[entry] = true;

					queue = queue.concat(Object.keys(goog.dependencies.requires[entry]||{}).map(function(namespace) {
						return goog.dependencies.nameToPath[namespace];
					}));
				}
			}
		}
	}

	return !!goog.dependencies.reachable[filepath];
}

@@ -85,16 +85,17 @@
  through
+2
  = requi
@@ -105,16 +105,17 @@
 'through
+2
 ');%0A%0Avar
@@ -2324,16 +2324,21 @@
 (through
+2.obj
 (functio
@@ -2343,16 +2343,25 @@
 ion(file
+, enc, cb
 ) %7B%0A%09%09  
@@ -2465,30 +2465,8 @@
 );%0A%0A
-%09%09    %7D, function() %7B%0A
 %09%09  
@@ -2568,16 +2568,16 @@
 cies_);%0A
-
 %09    %09%09_
@@ -2616,16 +2616,39 @@
 n() %7D);%0A
+%09    %09%09cb(null, file);%0A
 %09%09    %7D)

Fix through dependency