function lint( pkgs, clbk ) {
	var results;
	var total;
	var opts;
	var idx;

	total = pkgs.length;
	idx = -1;

	opts = {
		'encoding': 'utf8'
	};
	results = [];
	return next();

	/**
	* Lints the next namespace.
	*
	* @private
	*/
	function next() {
		idx += 1;

		debug( 'Linting namespace: %s (%d of %d)', pkgs[ idx ].id, idx+1, total );

		debug( 'Reading file: %s', pkgs[ idx ].main );
		readFile( pkgs[ idx ].main, opts, onFile );
	}

	/**
	* Callback invoked upon reading file contents.
	*
	* @private
	* @param {(Error|null)} error - error object
	* @param {(string|Buffer)} file - file contents
	* @returns {void}
	*/
	function onFile( error, file ) {
		var errs;
		if ( error ) {
			debug( 'Encountered an error when reading file: %s', error.message );
			return done( error );
		}
		debug( 'Successfully read file.' );

		debug( 'Linting namespace...' );
		errs = analyze( file );
		debug( 'Finished linting namespace.' );
		if ( errs ) {
			debug( 'Found %d lint errors: %s', errs.length, JSON.stringify( errs ) );
			return done( null, errs );
		}
		done();
	}

	/**
	* Callback invoked upon linting a namespace.
	*
	* @private
	* @param {(Error|null)} error - error object
	* @param {ObjectArray} [errs] - lint errors
	* @returns {void}
	*/
	function done( error, errs ) {
		var i;
		if ( error ) {
			return clbk( error );
		}
		if ( errs ) {
			for ( i = 0; i < errs.length; i++ ) {
				errs[ i ].namespace = pkgs[ idx ].id;
				results.push( errs[ i ] );
			}
		}
		debug( 'Finished linting %d of %d namespaces.', idx+1, total );
		if ( idx === total-1 ) {
			debug( 'Finished linting.' );
			return clbk( null, results );
		}
		next();
	}
}
Asynchronously lints namespace aliases.

@private
@param {StringArray} pkgs - list of namespace packages
@param {Callback} clbk - callback to invoke upon completion
@returns {void}