'use strict';

var isCallable    = require('es5-ext/lib/Object/is-callable')
  , isCopy        = require('es5-ext/lib/Object/is-copy')
  , deferred      = require('deferred')
  , resolve       = require('path').resolve
  , readFile      = require('next/lib/fs/read-file')
  , lint          = require('./lint')
  , normalizeSrc  = require('./_normalize-source')
  , normalizeOpts = require('./_options/normalize')
  , readOptions   = require('./_options/read')

  , lintFile;

lintFile = function (filename, options) {
	var filePromise, optsPromise, src, lintOpts, promise, result, onchange;

	filePromise = readFile(filename, { watch: options.watch });
	optsPromise = readOptions(filename, options.watch);

	promise = deferred(filePromise, optsPromise)(function (data) {
		src = normalizeSrc(String(data[0]));
		lintOpts = data[1];
		if (options.watch) {
			filePromise.on('end', function () {
				optsPromise.close();
				promise.emit('end');
			});
		}
		return (result = lint(src, lintOpts));
	}, options.watch ? function (err) {
		optsPromise.close();
		return err;
	} : null);

	if (options.watch) {
		onchange = function () {
			var nresult = lint(src, lintOpts);
			if (!isCopy(result, nresult, Infinity)) {
				promise.value = result = nresult;
				promise.emit('change', result);
			}
		};

		filePromise.on('change', function (nsrc) {
			nsrc = normalizeSrc(String(nsrc));
			if (src !== nsrc) {
				src = nsrc;
				onchange();
			}
		});
		optsPromise.on('change', function (nopts) {
			lintOpts = nopts;
			onchange();
		});

		promise.close = function () {
			filePromise.close();
			optsPromise.close();
		};
	}
	return promise;
};
lintFile.returnsPromise = true;

module.exports = exports = function (filename/*, options, cb*/) {
	var options, cb;

	filename = resolve(String(filename));
	options = arguments[1];
	cb = arguments[2];
	if ((cb == null) && isCallable(options)) {
		cb = options;
		options = {};
	} else {
		options = normalizeOpts(options);
	}

	return lintFile(filename, options).cb(cb);
};
exports.returnsPromise = true;
exports.lintFile = lintFile;

@@ -11,16 +11,131 @@
 t';%0A%0Avar
+ compact       = require('es5-ext/lib/Object/compact')%0A  , extend        = require('es5-ext/lib/Object/extend')%0A  ,
  isCalla
@@ -181,24 +181,24 @@
 -callable')%0A
-
   , isCopy  
@@ -935,15 +935,41 @@
 s = 
-data%5B1%5D
+compact(extend(data%5B1%5D, options))
 ;%0A%09%09
@@ -1629,16 +1629,106 @@
 opts) %7B%0A
+%09%09%09nopts = compact(extend(nopts, options));%0A%09%09%09if (!isCopy(lintOpts, nopts, Infinity)) %7B%0A%09
 %09%09%09lintO
@@ -1743,16 +1743,17 @@
 pts;%0A%09%09%09
+%09
 onchange
@@ -1756,16 +1756,21 @@
 ange();%0A
+%09%09%09%7D%0A
 %09%09%7D);%0A%0A%09

Extend options