var Consumer = require('vfs-socket/consumer').Consumer;
var inherits = require('util').inherits;
var spawn = require('child_process').spawn;

exports.Parent = Parent;

function Parent(fsOptions) {
    Consumer.call(this);
    var options = {};
    if (fsOptions.hasOwnProperty("gid")) {
        options.gid = fsOptions.gid;
        delete fsOptions.gid;
    }
    if (fsOptions.hasOwnProperty("uid")) {
        options.uid = fsOptions.uid;
        delete fsOptions.uid;
    }
    options.stdio = options.customFds = [-1, -1, 2];
    var args = [require.resolve('./child.js'), JSON.stringify(fsOptions)];
    var nodeBin = fsOptions.nodeBin || [process.execPath];
    var child;

    // Override Consumer's connect since the transport logic is internal to this module
    this.connect = connect.bind(this);
    function connect(callback) {
        try {
            child = spawn(nodeBin[0], args, options).on("error", tryNext);
        }
        catch (e) {
            return tryNext(e);
        }
        child.stdin.readable = true;
        Consumer.prototype.connect.call(this, [child.stdout, child.stdin], tryNext);
        child.on("exit", disconnect);
        child.stdin.resume();
        var _self = this;
        // try all possible locations of node before giving up
        function tryNext(err, vfs) {
            if (!child) return;
            child.removeListener("error", tryNext);
            child.on("error", function ignore() {});
            if (err && err.code == "ENOENT" && nodeBin.length > 1) {
                child = null;
                nodeBin.shift();
                _self.emit("error", err);
                _self.connect(callback);
            } else {
                callback(err, vfs);
            }
        }
    }

    // Override Consumer's disconnect to kill the child process afterwards
    this.disconnect = disconnect.bind(this);
    function disconnect() {
        if (!this.transport) return;
        Consumer.prototype.disconnect.apply(this, arguments);
        child.kill();
    }
    
    if (fsOptions.inProcess) {
        this.connect = function(callback) {
            var vfs = require('vfs-local')(fsOptions);
            setImmediate(function(){
                callback(null, vfs);
            });
        };
    }
}
inherits(Parent, Consumer);


@@ -133,16 +133,40 @@
 ).spawn;
+%0Avar fs = require(%22fs%22);
 %0A%0Aexport
@@ -868,13 +868,249 @@
     
-try %7B
+var _self = this;%0A        try %7B%0A            // Check if file exists first; spawn's ENOENT may arrive after other errors%0A            if (!fs.existsSync(nodeBin%5B0%5D))%0A                return tryNext(new Error(%22Couldn't find valid node binary%22));
 %0A   
@@ -1230,23 +1230,20 @@
  return 
-tryNext
+done
 (e);%0A   
@@ -1361,23 +1361,20 @@
 stdin%5D, 
-tryNext
+done
 );%0A     
@@ -1448,88 +1448,286 @@
     
-var _self = this;%0A        // try all possible locations of node before giving up
+%0A        function tryNext(err) %7B%0A             if (nodeBin.length %3E 1) %7B%0A                nodeBin.shift();%0A                _self.emit(%22error%22, err);%0A                _self.connect(callback);%0A             %7D else %7B%0A                 return done(err);%0A             %7D%0A        %7D%0A        
 %0A   
@@ -1736,31 +1736,28 @@
    function 
-tryNext
+done
 (err, vfs) %7B
@@ -1823,39 +1823,36 @@
 stener(%22error%22, 
-tryNext
+done
 );%0A            c
@@ -1888,88 +1888,18 @@
 ore(
+err
 ) %7B%7D);%0A
-            if (err && err.code == %22ENOENT%22 && nodeBin.length %3E 1) %7B%0A    
     
@@ -1936,109 +1936,83 @@
     
-  
-  nodeBin.shift();%0A                _self.emit(%22error%22, err);%0A                _self.connect(callback
+%0A            if (err && err.code == %22ENOENT%22) %7B%0A                tryNext(err
 );%0A 

Fix vfs not always connecting if first node binary in list doesn't exist