function analyze(tree, providedOptions) {
    var scopeManager, referencer, options;

    options = updateDeeply(defaultOptions(), providedOptions);

    scopeManager = new _scopeManager2.default(options);

    referencer = new _referencer2.default(options, scopeManager);
    referencer.visit(tree);

    (0, _assert2.default)(scopeManager.__currentScope === null, 'currentScope should be null.');

    return scopeManager;
}
Main interface function. Takes an Esprima syntax tree and returns the
analyzed scopes.
@function analyze
@param {esprima.Tree} tree
@param {Object} providedOptions - Options that tailor the scope analysis
@param {boolean} [providedOptions.optimistic=false] - the optimistic flag
@param {boolean} [providedOptions.directive=false]- the directive flag
@param {boolean} [providedOptions.ignoreEval=false]- whether to check 'eval()' calls
@param {boolean} [providedOptions.nodejsScope=false]- whether the whole
script is executed under node.js environment. When enabled, escope adds
a function scope immediately following the global scope.
@param {boolean} [providedOptions.impliedStrict=false]- implied strict mode
(if ecmaVersion >= 5).
@param {string} [providedOptions.sourceType='script']- the source type of the script. one of 'script' and 'module'
@param {number} [providedOptions.ecmaVersion=5]- which ECMAScript version is considered
@param {Object} [providedOptions.childVisitorKeys=null] - Additional known visitor keys. See [esrecurse](https://github.com/estools/esrecurse)'s the `childVisitorKeys` option.
@param {string} [providedOptions.fallback='iteration'] - A kind of the fallback in order to encounter with unknown node. See [esrecurse](https://github.com/estools/esrecurse)'s the `fallback` option.
@return {ScopeManager}