docs: function compile( bundleData, bundleFile, config, callback ) {
  	var baseDir = config['path'] || path.dirname(bundleFile);
  	var encoder, profileEncoder = [], profileLoader = [], bundleLoader;
  
  	// Compile stages
  	var openBundle = function( cb ) {
  		return function() {
  
  			// Create encoder
  			encoder = new BinaryEncoder(
  					bundleFile,
  					{
  						'name' 			: bundleData['name'],
  						'base_dir' 		: baseDir,
  						'log'			: config['log'] || 0x00,
  						'sparse'		: config['sparse'],
  					}
  				);
  
  			// Add profiles
  			for (var i=0; i<profileEncoder.length; i++) {
  				encoder.addProfile( profileEncoder[i] );
  			}
  
  			// We are ready
  			cb();
  		}
  	}
  
  	var loadBundles = function( cb ) {
  		return function() {
  			// Load a bundle by specs
  			bundleLoader.addBySpecs( bundleData );
  			// Solve dependencies and load resources
  			bundleLoader.load( cb );
  		}
  	}
  
  	var compileExports = function( cb ) {
  		return function() {
  			// Get the bundle to encode
  			var bundle = bundleLoader.bundles[ bundleData['name'] ];
  
  			// Encode resources
  			for (var k in bundle.resources) {
  				encoder.encode( bundle.resources[k], k );
  			}
  
  			// Embed blobs
  			for (var k in bundle.blobs) {
  				encoder.embedBlob( bundle.blobs[k][0], k, bundle.blobs[k][1] );
  			}
  
  			// We are done
  			cb();
  		}
  	}
  
  	var closeBundle = function( cb ) {
  		return function() {
  			// Close & Complete
  			encoder.close();
  			cb();
  		}
  	}
  
  	// Check for profileTable/profileLoader
  	if (config['profileEncoder'] || config['profileLoader']) {
  
  		// Check for missing arguments
  		if (!config['profileEncoder']) {
  			callback( "Got 'profileLoader' but missing 'profileEncoder' in the arguments" );
  			return;
  		}
  		if (!config['profileLoader']) {
  			callback( "Got 'profileEncoder' but missing 'profileLoader' in the arguments" );
  			return;
  		}
  
  		// Fetch
  		profileEncoder = config['profileEncoder'];
  		profileLoader = config['profileLoader'];
  
  		// Make sure it's array
  		if (!(profileEncoder instanceof Array))
  			profileEncoder = [ profileEncoder ];
  		if (!(profileLoader instanceof Array))
  			profileLoader = [ profileLoader ];
  
  	} else {
  
  		// Identify some important information
  		var profile = config['profile'] || bundleData['profile'];
  		if (!profile) {
  			callback( "No jbb profile was specified!");
  			return;
  		}
  
  		// Make sure it's array
  		if (typeof profile === 'string')
  			profile = [ profile ];
  
  		// Require
  		for (var i=0; i<profile.length; i++) {
  			var pname = profile[i];
  			if (pname[0] == ".") {
  				profileEncoder.push( require( path.join(process.cwd(), pname, '/profile-encode') ) );
  				profileLoader.push( require( path.join(process.cwd(), pname, "/profile-loader") ) );
  			} else {
  				profileEncoder.push( require('jbb-profile-'+pname+'/profile-encode') );
  				profileLoader.push( require('jbb-profile-'+pname+"/profile-loader") );
  			}
  		}
  
  	}
  
  	// Load profile table and compiler helper
  	bundleLoader = new BundlesLoader( baseDir );
  	for (var i=0; i<profileLoader.length; i++) {
  		bundleLoader.addProfileLoader( profileLoader[i] );
  	}
  
  	// Chained initialization of profile loaders
  	var context = { 'remaining': profileLoader.length }
  	var init_callback = (function() {
  		if (--this.remaining == 0) {
  			openBundle(
  				loadBundles(
  					compileExports(
  						closeBundle( callback || function(){} )
  						) 
  					) 
  			)();
  		}
  	}).bind(context);
  
  	// Initialize profile compiler with the specs file
  	for (var i=0; i<profileLoader.length; i++) {
  		if (!profileLoader[i].initialize) {
  			init_callback();
  		} else {
  			profileLoader[i].initialize( init_callback, bundleData );
  		}
  	}
  
  }