function main( context ) {
	var options;
	var opts;

	opts = copy( DEFAULTS );
	options = context.options[ 0 ];
	if ( hasOwnProp( options, 'builtinGlobals' ) ) {
		opts.builtinGlobals = options.builtinGlobals;
	}
	if ( hasOwnProp( options, 'globalsWhitelist' ) ) {
		opts.globalsWhitelist = options.globalsWhitelist;
	}

	/**
	* Reports the error message.
	*
	* @private
	* @param {ASTNode} node - node to report
	* @param {string} msg - message to report
	*/
	function report( node, msg ) {
		context.report({
			'node': node,
			'message': msg
		});
	}

	/**
	* Finds variables in a given scope and flag redeclared ones.
	*
	* @private
	* @param {Object} scope - eslint-scope scope object.
	*/
	function findVariablesInScope( scope ) {
		var hasBuiltin;
		var variable;
		var count;
		var ids;
		var i;
		var j;
		var l;

		for ( i = 0; i < scope.variables.length; i++ ) {
			variable = scope.variables[ i ];
			ids = variable.identifiers;
			hasBuiltin = opts.builtinGlobals && hasProp( variable, 'writeable' );
			if ( hasBuiltin ) {
				if ( contains( opts.globalsWhitelist, variable.name ) ) {
					hasBuiltin = false;
				}
			}
			l = ids.length;
			count = ( (hasBuiltin) ? 1 : 0 ) + l;
			if ( count >= 2 ) {
				ids.sort( ascending );
				for ( j = ( (hasBuiltin) ? 0 : 1 ); j < l; j++ ) {
					report( ids[j], variable.name+' is already defined' );
				}
			}
		}
	}

	/**
	* Finds variables in the current scope.
	*
	* @private
	* @param {ASTNode} node - program node.
	*/
	function checkForGlobal( node ) {
		var parserOptions = context.parserOptions;
		var ecmaFeatures = parserOptions.ecmaFeatures || {};
		var scope = context.getScope();

		// Node.js environment or modules have a special scope:
		if ( ecmaFeatures.globalReturn || node.sourceType === 'module' ) {
			findVariablesInScope( scope.childScopes[0] );
		} else {
			findVariablesInScope( scope );
		}
	}

	/**
	* Finds variables in the current scope.
	*
	* @private
	*/
	function checkForBlock() {
		findVariablesInScope( context.getScope() );
	}

	return {
		'Program': checkForGlobal,
		'FunctionDeclaration': checkForBlock,
		'FunctionExpression': checkForBlock
	};
}
Rule for validating that there are no variable redeclarations.

@param {Object} context - ESLint context
@returns {Object} validators