function main( context ) {
	var requires;
	var options;
	var regexps;
	var order;
	var i;

	requires = [];
	regexps = [];
	options = context.options[ 0 ];
	order = DEFAULTS.order;
	if ( hasOwnProp( options, 'order' ) ) {
		order = options.order.slice();
	}
	for ( i = 0; i < order.length; i++ ) {
		if ( isRegExpString( order[ i ] ) ) {
			regexps.push( reFromString( order[ i ] ) );
		}
	}

	/**
	* Sorts `require` statements based on their ranks.
	*
	* @private
	* @param {Object} a - first require statement
	* @param {Object} b - second require statement
	* @returns {number} number indicating sort order
	*/
	function sortRequires( a, b ) {
		if ( a.rank < b.rank ) {
			return -1;
		}
		return 1;
	}

	/**
	* Fixes the lint error by reordering the require statements.
	*
	* @private
	* @param {Function} fixer - ESLint fixer
	* @returns {(Object|Null)} fix or null
	*/
	function fix( fixer ) {
		var requireDeclarations;
		var replacingText;
		var startRange;
		var endRange;
		var source;
		var elem;
		var txt;
		var i;

		replacingText = '';
		requireDeclarations = [];
		source = context.getSourceCode();

		// Get the text and rank for the require statements:
		for ( i = 0; i < requires.length; i++ ) {
			elem = requires[ i ].node.parent.parent;
			txt = source.getText( elem );
			if ( i === 0 ) {
				startRange = elem.range[ 0 ] - elem.loc.start.column;
			}
			endRange = elem.range[ 1 ];
			requireDeclarations.push({
				'text': txt,
				'rank': requires[i].rank
			});
		}

		// Sort the require statements:
		requireDeclarations.sort( sortRequires );

		// Build the replacement text:
		for ( i = 0; i < requireDeclarations.length; i++ ) {
			txt = requireDeclarations[ i ].text;
			if ( !txt.startsWith( 'var' ) ) {
				txt = 'var '+txt;
			}
			if ( !txt.endsWith( ';' ) ) {
				txt += ';';
			}
			replacingText += txt;
			if ( i < requireDeclarations.length-1 ) {
				replacingText += '\n';
			}
		}
		return fixer.replaceTextRange( [ startRange, endRange ], replacingText );// eslint-disable-line max-len
	}

	/**
	* Reports the error message.
	*
	* @private
	* @param {ObjectArray} errs - array of require statements that are not in order
	*/
	function report( errs ) {
		var curr;
		var msg;
		var i;
		for ( i = 0; i < errs.length; i++ ) {
			curr = errs[ i ];
			msg = '`require( \''+curr.name+'\' )` should come before `require( \''+curr.compared.name+'\' )`';
			context.report({
				'node': null,
				'message': msg,
				'loc': curr.node.loc,
				'fix': fix
			});
		}
	}

	/**
	* Checks for existence of require paths in the current program and registers them.
	*
	* @private
	* @param {ASTNode} node - node to examine
	*/
	function validate( node ) {
		var requirePath;
		var r;
		if ( node.callee.name === 'require' ) {
			requirePath = node.arguments[ 0 ].value;
			if ( isString( requirePath ) ) {
				r = rank( order, regexps, requirePath );
				if ( r !== -1 ) {
					// Register a require statement "node":
					requires.push({
						'name': requirePath,
						'node': node,
						'rank': r,
						'compared': null
					});
				}
			}
		}
	}

	/**
	* Callback invoked upon program exit.
	*
	* @private
	*/
	function finish() {
		var errs = analyze( requires );
		if ( errs.length ) {
			report( errs );
			requires.length = 0; // reset the require cache
		}
	}

	return {
		'CallExpression': validate,
		'Program:exit': finish
	};
}
Rule for validating `require()` calls follow a specified order.

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