var fs = require("fs");
var Module = require("module");

var moduleStack = [];
var defaultCompile = module.constructor.prototype._compile;

module.constructor.prototype._compile = function(content, filename){  
    moduleStack.push(this);
    try {        
        return defaultCompile.call(this, content, filename);
    }
    finally {
        moduleStack.pop();
    }
};

global.define = function (id, injects, factory) {

    // infere the module
    var currentModule = moduleStack[moduleStack.length-1];
    var mod = currentModule || module.parent || require.main;
    
    // parse arguments
    if (!factory) {
        var defaultInjects = ["require", "exports", "module"];
        // two or less arguments
        factory = injects;
        if (factory) {
            // two args
            if (typeof id === "string") {
                if (id !== mod.id) {
                    throw new Error("Can not assign module to a different id than the current file");
                }
                // default injects
                injects = defaultInjects;
            }
            else{
                // anonymous, deps included
                injects = id;
            }
        }
        else {
            // only one arg, just the factory
            factory = id;
            injects = defaultInjects;
        }
    }

    var req = function(module, relativeId, callback) {
        if (Array.isArray(relativeId)) {
            // async require
            return callback.apply(this, relativeId.map(req))
        }
        
        var chunks = relativeId.split("!");
        var prefix;
        if (chunks.length >= 2) {
            prefix = chunks[0];
            relativeId = chunks.slice(1).join("!");
        }
        
        var fileName = Module._resolveFilename(relativeId, module);
        if (Array.isArray(fileName))
            fileName = fileName[0];
        
        if (prefix && prefix.indexOf("text") !== -1) {
            return fs.readFileSync(fileName, "utf8");
        } else
            return require(fileName);
    }.bind(this, mod);
    
    id = mod.id;
    if (typeof factory !== "function") {
        // we can just provide a plain object
        return mod.exports = factory;
    }
    
    var returned = factory.apply(mod.exports, injects.map(function (injection) {
        switch (injection) {
            // check for CommonJS injection variables
            case "require": return req;
            case "exports": return mod.exports;
            case "module": return mod;
            default:
                // a module dependency
                return req(injection);
        }
    }));
    
    if (returned) {
        // since AMD encapsulates a function/callback, it can allow the factory to return the exports.
        mod.exports = returned;
    }
};
@@ -398,22 +398,19 @@
 on (id, 
-inject
+dep
 s, facto
@@ -419,167 +419,152 @@
 ) %7B%0A
-%0A
     // 
-infere the
+Allow for anonymous
  module
+s
 %0A    
-var currentModule = moduleStack%5BmoduleStack.length-1%5D;%0A    var mod = currentModule %7C%7C module.parent %7C%7C require.main
+if (typeof id !== %22string%22) %7B%0A        factory = deps;%0A        deps = id;%0A        id = null
 ;%0A    
+%7D
 %0A    // 
 pars
@@ -563,69 +563,165 @@
  // 
-parse arguments%0A    if (!factory) %7B%0A        var defaultInject
+This module may not have dependencies%0A    if (deps && !Array.isArray(deps)) %7B%0A        factory = deps;%0A        deps = null;%0A    %7D%0A    if (!deps) %7B%0A        dep
 s = 
@@ -762,119 +762,158 @@
     
+%7D%0A%0A
     // 
-two or less arguments%0A        factory = injects;%0A        if (factory) %7B%0A            // two args%0A        
+infer the module%0A    var currentModule = moduleStack%5BmoduleStack.length-1%5D;%0A    var mod = currentModule %7C%7C module.parent %7C%7C require.main;%0A%0A%0A
     
@@ -942,32 +942,12 @@
 ing%22
-) %7B%0A                if (
+ && 
 id !
@@ -959,28 +959,16 @@
 d.id) %7B%0A
-            
         
@@ -1053,368 +1053,8 @@
 %22);%0A
-                %7D%0A                // default injects%0A                injects = defaultInjects;%0A            %7D%0A            else%7B%0A                // anonymous, deps included%0A                injects = id;%0A            %7D%0A        %7D%0A        else %7B%0A            // only one arg, just the factory%0A            factory = id;%0A            injects = defaultInjects;%0A        %7D%0A
     
@@ -2001,22 +2001,19 @@
 xports, 
-inject
+dep
 s.map(fu

handle arguments of define same way as requirejs