function createBundle( outDir, b, clbk ) {
	var isLarge;
	var minify;
	var bopts;
	var pkgs;
	var tmp;
	var i;
	var j;

	debug( 'Bundle: %s', b.name );

	// Determine the list of packages to include in the output bundle...
	debug( 'Resolving bundle package list...' );
	if ( b.include ) {
		pkgs = [];
		for ( i = 0; i < b.include.length; i++ ) {
			tmp = include( NAMES, b.include[ i ] );
			for ( j = 0; j < tmp.length; j++ ) {
				pkgs.push( tmp[ j ] );
			}
		}
	} else {
		pkgs = NAMES;
	}
	if ( b.exclude ) {
		for ( i = 0; i < b.exclude.length; i++ ) {
			pkgs = exclude( pkgs, b.exclude[ i ] );
		}
	}
	debug( 'Number of packages to bundle: %d.', pkgs.length );
	debug( 'Included packages: %s.', pkgs.join( ', ' ) );

	// Determine whether the output bundle will be large enough to cause possible issues when minifying...
	for ( i = 0; i < pkgs.length; i++ ) {
		if (
			pkgs[ i ].indexOf( '@stdlib/datasets' ) >= 0 ||
			pkgs[ i ].indexOf( '@stdlib/repl' ) >= 0
		) {
			isLarge = true;
			break;
		}
	}
	// Define bundle options...
	bopts = {
		'standalone': b.standalone,
		'namespace': b.namespace
	};
	if ( isLarge ) {
		if ( b.minified ) {
			bopts.transforms = [
				[ uglifyify, copy( UGLIFYIFY_OPTS ) ] // minify modules individually
			];
		}
		minify = false; // can encounter memory issues with uglify for bundles which, e.g., include large datasets
	} else {
		bopts.plugins = [
			packFlat    // bundle within a single scope (i.e., remove module wrappers)
		];
		minify = b.minified;
	}
	debug( 'Bundle options: %s', JSON.stringify( bopts ) );

	// Generate a bundle:
	debug( 'Generating bundle...' );
	tmp = null;
	bundle( pkgs, bopts, onBundle );

	/**
	* Callback invoked upon generating a bundle.
	*
	* @private
	* @param {(Error|null)} error - error object
	* @param {(string|Buffer)} [bundle] - output bundle
	* @returns {void}
	*/
	function onBundle( error, bundle ) {
		if ( error ) {
			debug( 'Encountered an error when generating bundle: %s', error.message );
			return done( error );
		}
		debug( 'Finished creating bundle: %s', b.name );
		tmp = bundle; // parent scope

		if ( b.raw ) {
			return writeBundle( bundle, false );
		}
		if ( minify ) {
			return minifyBundle( bundle );
		}
		// NOTE: we assume that, if we are supposed to neither write a "raw" bundle to file nor minify a generated bundle, then the generated bundle was minified during generation.
		writeBundle( bundle, true );
	}

	/**
	* Minifies a bundle and writes the bundle to file.
	*
	* @private
	* @param {(string|Buffer)} bundle - bundle to minify
	*/
	function minifyBundle( bundle ) {
		debug( 'Minifying...' );
		bundle = uglify.minify( bundle.toString() );
		debug( 'Finished minifying bundle: %s', b.name );
		debug( 'Minification errors: %s', ( bundle.error ) ? bundle.error : '(none)' );
		writeBundle( LICENSE_HEADER+bundle.code, true );
	}

	/**
	* Writes a bundle to file.
	*
	* @private
	* @param {(string|Buffer)} bundle - bundle to write to file
	* @param {boolean} isMinified - boolean indicating whether a bundle is minified
	* @returns {void}
	*/
	function writeBundle( bundle, isMinified ) {
		var fpath;
		if ( isMinified ) {
			fpath = join( outDir, b.name+'.min.js' );
			debug( 'Writing minified bundle to file: %s', fpath );
			return writeFile( fpath, bundle, onWriteMinify );
		}
		fpath = join( outDir, b.name+'.js' );
		debug( 'Writing bundle to file: %s', fpath );
		writeFile( fpath, bundle, onWrite );
	}

	/**
	* Callback invoked upon writing an un-minified bundle to file.
	*
	* @private
	* @param {Error} [error] - error object
	* @returns {void}
	*/
	function onWrite( error ) {
		if ( error ) {
			debug( 'Encountered an error when writing bundle to file: %s', error.message );
			return done( error );
		}
		debug( 'Finished writing bundle `%s` to file.', b.name );
		if ( minify ) {
			return minifyBundle( tmp );
		}
		done();
	}

	/**
	* Callback invoked upon writing a minified bundle to file.
	*
	* @private
	* @param {Error} [error] - error object
	* @returns {void}
	*/
	function onWriteMinify( error ) {
		if ( error ) {
			debug( 'Encountered an error when writing bundle to file: %s', error.message );
			return done( error );
		}
		debug( 'Finished writing minified bundle `%s` to file.', b.name );
		done();
	}

	/**
	* Callback invoked after generating a bundle.
	*
	* @private
	* @param {Error} [error] - error object
	* @returns {void}
	*/
	function done( error ) {
		if ( error ) {
			return clbk( error );
		}
		debug( 'Finished generating bundle.' );
		clbk();
	}
}
' // ignore "private" packages
	]
});
if ( instanceOf( NAMES, Error ) ) {
	throw NAMES;
}


// MAIN //

/**
Generates a bundle.

@private
@param {string} outDir - output directory
@param {Object} b - bundle specification
@param {string} b.name - bundle name
@param {string} b.standalone - UMD export name
@param {string} b.namespace - namespace type ('flat' or 'tree')
@param {boolean} b.raw - boolean indicating whether to write a raw bundle to file
@param {boolean} b.minify - boolean indicating whether to minify a bundle
@param {StringArray} [b.include] - list of packages (and/or namespaces) to include in the bundle
@param {StringArray} [b.exclude] - list of packages (and/or namespaces) to exclude from the bundle
@param {Callback} clbk - callback to invoke upon completion