/*
 *  var context = new Context
 *    , require = context.makeRequireFunction()
 *    , defineFoo = context.makeDefineFunction('foo')
 *    , defineBar = context.makeDefineFunction('bar')
 *    , define;
 *
 *  (function(define) {
 *    define(function() {
 *      return 'foo';
 *    });
 *  )(defineFoo);
 *
 *  (function(define) {
 *    define(['exports'], function(exports) {
 *      exports.bar = true;
 *    });
 *  })(defineBar);
 *
 *  require(['foo', 'bar'], function(foo, bar) {
 *    console.log('foo =', foo, 'bar =', bar);
 *  });
 */

function Context() {
  this.modules = {};
  this.definitions = {};
  this.aliases = {};
}

Context.prototype = {
  makeRequireFunction: function() {
    var self = this
      , require = self.require
      , boundRequire = function() { require.apply(self, arguments); }
      , setConfig = self.setConfig
      , boundSetConfig = function() { setConfig.apply(self, arguments); };

    boundRequire.config = boundSetConfig;

    return boundRequire;
  }
, makeDefineFunction: function(moduleId) {
    var self = this
      , define = self.define
      , definitions = self.definitions
      , modules = self.modules;

    return function() {
      var args = arguments
        , definition = function() {
            var module = define.apply(self, args);
            return module;
          };

      definitions[moduleId] = definition;
    };
  }
, require: function(deps, callback, exports) {
    var context = {}  // TODO: context of callbacks for require() and define()
      , args = [];

    for(var i in deps) {
      var moduleId = deps[i]
        , aliases = this.aliases
        , registeredModuleId = aliases[moduleId] || moduleId
        , module = (moduleId == 'exports' ? exports : this.load(registeredModuleId));

      args[i] = module;
    }

    callback.apply(context, args);
  }
, define: function(deps, callback) {
    if (typeof deps == 'function') {
      callback = deps;
      deps = [];
    }

    var context = {}  // TODO: context of callbacks for require() and define()
      , module
      , exports = {}
      , onRequire = function() {
          var args = arguments;

          module = callback.apply(context, args);

          var hasReturnedModule = (typeof module != 'undefined')
            , hasFilledExports = Object.keys(exports).length;

          if (!hasReturnedModule && hasFilledExports)
            module = exports;
        };

    this.require(deps, onRequire, exports);

    return module;
  }
, setConfig: function(config) {
    var aliases = this.aliases
      , newAliases = config.paths;

    for(var alias in newAliases) {
      var real = newAliases[alias];
      aliases[alias] = real;
    }
  }
, load: function(moduleId) {
    var module = this.modules[moduleId];

    if (module)
      return module;

    var definition = this.definitions[moduleId];

    if (!definition)
      throw new Error('no definition for module \'' + moduleId + '\'');

    module = this.modules[moduleId] = definition();

    return module;
  }
};

exports.Context = Context;

@@ -1800,24 +1800,101 @@
 ule;%0A    %7D%0A%0A
+    // TODO: optimize by not creating args if !callback%0A%0A    if (callback)%0A  
     callback
@@ -2037,24 +2037,97 @@
  %5B%5D;%0A    %7D%0A%0A
+    var module%0A      , onRequire%0A      , exports;%0A%0A    if (callback) %7B%0A  
     var cont
@@ -2126,32 +2126,33 @@
 var context = %7B%7D
+;
   // TODO: conte
@@ -2198,30 +2198,14 @@
 e()%0A
-      , module
 %0A     
- ,
  exp
@@ -2213,24 +2213,23 @@
 rts = %7B%7D
+;
 %0A     
- ,
  onRequi
@@ -2238,34 +2238,32 @@
  = function() %7B%0A
-  
         var args
@@ -2277,34 +2277,32 @@
 ments;%0A%0A        
-  
 module = callbac
@@ -2330,26 +2330,24 @@
 );%0A%0A        
- 
- 
 var hasRetur
@@ -2399,18 +2399,16 @@
         
-  
 , hasFil
@@ -2458,18 +2458,16 @@
         
- 
- 
 if (!has
@@ -2502,18 +2502,16 @@
 xports)%0A
-  
         
@@ -2530,30 +2530,34 @@
 xports;%0A    
+  %7D;%0A
     %7D
-;
 %0A%0A    this.r

handle define() and require() with no callback function