# Source: core/module-reference.js

    /**
     * @module montage/core/module-reference
     * @requires montage/core/core
     */
    var Montage = require("./core").Montage;

    /**
     * @class ModuleReference
     * @extends Montage
     */
    exports.ModuleReference = Montage.specialize( /** @lends ModuleReference.prototype */ {

        initWithIdAndRequire: {
            value: function (id, require) {
                if (!id || ! require) {
                    throw new Error("Module ID and require required");
                }
                this.id = id;
                this.require = require;

                return this;
            }
        },

        /**
         * The absolute id of the module within the `require` package
         * @property {string} value
         */
        id: {
            value: null
        },

        /**
         * The require of a package.
         * @property {function} value
         */
        require: {
            value: null
        },

        _exports: {
            value: null
        },
        /**
         * A promise for the exports of the module. The exports are loaded lazily
         * when the property is accessed.
         *
         * @returns {Promise.<Object>} The exports of the module.
         */
        exports: {
            get: function () {
                if (this._exports) {
                    return this._exports;
                }
                return (this._exports = this.require.async(this.id));
            }
        },

        /**
         * Resolves this module reference so that it can be required from
         * otherRequire.
         *
         * @function
         * @param {function} otherRequire - Require from another package that has
         * the package of this module as a dependency.
         * @returns {string} The module id to pass to otherRequire that results
         * in this module.
         * @throws {Error} If there is no mapping from this require inside
         * otherRequire.
         *
         * @example
         * var ref = new ModuleReference().initWithIdAndRequire("core/uuid", montageRequire);
         * ref.resolve(applicationRequire); // => "montage/core/uuid"
         *
         * @example
         * var ref = new ModuleReference().initWithIdAndRequire("ui/main.reel", applicationRequire);
         * ref.resolve(montageRequire); // => Error
         * // because there is no module id such that montageRequire(id) can
         * // return the module from inside your application
         */
        resolve: {
            value: function (otherRequire) {
                return otherRequire.identify(this.id, this.require);
            }
        },

        // Used for cross-frame detection, similar to Array.isArray, but just
        // a property as there's no need for complex logic.
        isModuleReference: {
            writable: false,
            configurable: false,
            value: true
        }
    });