var App = function () {

var app_instance;

app_instance = function () {
    var app         = {},
        definitions = {},
        constants   = {},
        overwrites  = {};

    app.define = function (constant, definition) {
        if (definitions[constant] !== undefined) {
            throw "Constant '" + constant + "' already defined."
        }
        if (typeof definition !== 'function') {
            throw "Definition has to be a function."
        }

        definitions[constant] = definition;
    };

    app.require = function (constant) {
        if (overwrites[constant]) {
            return overwrites[constant]();
        }

        if (constants[constant] === undefined) {
            if (definitions[constant] === undefined) {
                throw "Constant '" + constant + "' not defined."
            }
            constants[constant] = definitions[constant]();
        }

        return constants[constant];
    };

    app.overwrite = function(constant, definition) {
        overwrites[constant] = definition;
    }

    app.reset = function(constant) {
        delete overwrites[constant];
    }

    app.resetDefinitions = function () {
        constants = {};
    };

    return app;
}

return {
    Mediators: {},
    induce: function (scope) {
        scope.app = app_instance();
    }
};

}();

App.induce(window);