whole_func_string: function setup( io ) {
  	const SCSS_PATHS = [ path.join( '.', 'assets', 'stylesheets' ), path.join( '.', 'client' ) ];
  	const ROOT_DIR = path.resolve( __dirname, '..', '..' );
  	const PUBLIC_DIR = path.join( ROOT_DIR, 'public' );
  
  	let cssMake = null,
  		errors = '',
  		scheduleBuild = false;
  	const publicCssFiles = {}; // { path, hash } dictionary
  
  	function spawnMake() {
  		// If a build is already in progress schedule another build for later
  		if ( cssMake ) {
  			scheduleBuild = true;
  			return;
  		}
  
  		io.of( '/css-hot-reload' ).emit( 'css-hot-reload', { status: 'building' } );
  
  		debug( 'spawning %o', 'npm run build-css' );
  		cssMake = spawn( 'npm', [ 'run', 'build-css' ], {
  			shell: true,
  			cwd: ROOT_DIR,
  			stdio: [ 'ignore', 'pipe', 'pipe' ],
  		} );
  
  		errors = '';
  		cssMake.once( 'exit', onexit );
  		cssMake.stdout.setEncoding( 'utf8' );
  		cssMake.stderr.setEncoding( 'utf8' );
  		cssMake.stdout.on( 'data', onstdout );
  		cssMake.stderr.on( 'data', onstderr );
  	}
  
  	function onstdout( d ) {
  		debug( 'stdout %o', d.trim() );
  	}
  
  	function onstderr( stderr ) {
  		process.stderr.write( stderr );
  		// Note:
  		// Because we use make --jobs the error message is usually duplicated.
  		errors += stderr;
  	}
  
  	/**
  	 * Handle 'make build-css' success or failure
  	 * @param {Number} code The exit code
  	 */
  	function onexit( code ) {
  		let changedFiles;
  
  		cssMake.stderr.removeListener( 'data', onstderr );
  		cssMake.stdout.removeListener( 'data', onstdout );
  		cssMake = null;
  
  		if ( scheduleBuild ) {
  			// Handle new css build request
  			scheduleBuild = false;
  			spawnMake();
  		} else if ( 0 === code ) {
  			// 'make build-css' success
  			changedFiles = updateChangedCssFiles();
  			if ( 0 !== changedFiles.length ) {
  				debug( chalk.green( 'css reload' ) );
  				io.of( '/css-hot-reload' ).emit( 'css-hot-reload', {
  					status: 'reload',
  					changedFiles: changedFiles,
  				} );
  			} else {
  				debug( chalk.green( 'css up to date' ) );
  				io.of( '/css-hot-reload' ).emit( 'css-hot-reload', { status: 'up-to-date' } );
  			}
  		} else {
  			// 'make build-css' failed
  			debug( chalk.red( 'css build failed' ) );
  			io.of( '/css-hot-reload' ).emit( 'css-hot-reload', {
  				status: 'build-failed',
  				error: errors,
  			} );
  		}
  	}
  
  	/**
  	 * Updates the MD5 hash of the public CSS files and returns the changed ones
  	 * in a list.
  	 * @returns {Array} an array of changed files (string)
  	 */
  	function updateChangedCssFiles() {
  		let hash, filePath;
  		const changedFiles = [];
  		for ( filePath in publicCssFiles ) {
  			hash = md5File.sync( filePath );
  			if ( hash !== publicCssFiles[ filePath ] ) {
  				publicCssFiles[ filePath ] = hash;
  				changedFiles.push( path.basename( filePath ) );
  			}
  		}
  
  		return changedFiles;
  	}
  
  	// Initialize publicCssFiles
  
  	fs.readdirSync( PUBLIC_DIR ).forEach( function( file ) {
  		if ( '.css' === file.slice( -4 ) ) {
  			const fullPath = path.join( PUBLIC_DIR, file );
  			publicCssFiles[ fullPath ] = md5File.sync( fullPath );
  		}
  	} );
  
  	// Watch .scss files
  
  	const watcher = chokidar.watch( SCSS_PATHS, {
  		ignored: /^.*\.(js[x]?|md|json|unison\.tmp)$/,
  		usePolling: false,
  		persistent: true,
  	} );
  
  	// The add/addDir events are fired during initialization generating an
  	// avalanche of refreshes on the client so we stick to the change events
  	// only for now until we can exclude the initial add/addDir events.
  	watcher.on( 'all', function( event, filepath ) {
  		if ( 'change' === event && filepath.match( /^.*\.scss$/ ) ) {
  			spawnMake();
  		}
  	} );
  }
func_code_string: function setup( io ) {
  	const SCSS_PATHS = [ path.join( '.', 'assets', 'stylesheets' ), path.join( '.', 'client' ) ];
  	const ROOT_DIR = path.resolve( __dirname, '..', '..' );
  	const PUBLIC_DIR = path.join( ROOT_DIR, 'public' );
  
  	let cssMake = null,
  		errors = '',
  		scheduleBuild = false;
  	const publicCssFiles = {}; // { path, hash } dictionary
  
  	function spawnMake() {
  		// If a build is already in progress schedule another build for later
  		if ( cssMake ) {
  			scheduleBuild = true;
  			return;
  		}
  
  		io.of( '/css-hot-reload' ).emit( 'css-hot-reload', { status: 'building' } );
  
  		debug( 'spawning %o', 'npm run build-css' );
  		cssMake = spawn( 'npm', [ 'run', 'build-css' ], {
  			shell: true,
  			cwd: ROOT_DIR,
  			stdio: [ 'ignore', 'pipe', 'pipe' ],
  		} );
  
  		errors = '';
  		cssMake.once( 'exit', onexit );
  		cssMake.stdout.setEncoding( 'utf8' );
  		cssMake.stderr.setEncoding( 'utf8' );
  		cssMake.stdout.on( 'data', onstdout );
  		cssMake.stderr.on( 'data', onstderr );
  	}
  
  	function onstdout( d ) {
  		debug( 'stdout %o', d.trim() );
  	}
  
  	function onstderr( stderr ) {
  		process.stderr.write( stderr );
  		// Note:
  		// Because we use make --jobs the error message is usually duplicated.
  		errors += stderr;
  	}
  
  	/**
  	 * Handle 'make build-css' success or failure
  	 * @param {Number} code The exit code
  	 */
  	function onexit( code ) {
  		let changedFiles;
  
  		cssMake.stderr.removeListener( 'data', onstderr );
  		cssMake.stdout.removeListener( 'data', onstdout );
  		cssMake = null;
  
  		if ( scheduleBuild ) {
  			// Handle new css build request
  			scheduleBuild = false;
  			spawnMake();
  		} else if ( 0 === code ) {
  			// 'make build-css' success
  			changedFiles = updateChangedCssFiles();
  			if ( 0 !== changedFiles.length ) {
  				debug( chalk.green( 'css reload' ) );
  				io.of( '/css-hot-reload' ).emit( 'css-hot-reload', {
  					status: 'reload',
  					changedFiles: changedFiles,
  				} );
  			} else {
  				debug( chalk.green( 'css up to date' ) );
  				io.of( '/css-hot-reload' ).emit( 'css-hot-reload', { status: 'up-to-date' } );
  			}
  		} else {
  			// 'make build-css' failed
  			debug( chalk.red( 'css build failed' ) );
  			io.of( '/css-hot-reload' ).emit( 'css-hot-reload', {
  				status: 'build-failed',
  				error: errors,
  			} );
  		}
  	}
  
  	/**
  	 * Updates the MD5 hash of the public CSS files and returns the changed ones
  	 * in a list.
  	 * @returns {Array} an array of changed files (string)
  	 */
  	function updateChangedCssFiles() {
  		let hash, filePath;
  		const changedFiles = [];
  		for ( filePath in publicCssFiles ) {
  			hash = md5File.sync( filePath );
  			if ( hash !== publicCssFiles[ filePath ] ) {
  				publicCssFiles[ filePath ] = hash;
  				changedFiles.push( path.basename( filePath ) );
  			}
  		}
  
  		return changedFiles;
  	}
  
  	// Initialize publicCssFiles
  
  	fs.readdirSync( PUBLIC_DIR ).forEach( function( file ) {
  		if ( '.css' === file.slice( -4 ) ) {
  			const fullPath = path.join( PUBLIC_DIR, file );
  			publicCssFiles[ fullPath ] = md5File.sync( fullPath );
  		}
  	} );
  
  	// Watch .scss files
  
  	const watcher = chokidar.watch( SCSS_PATHS, {
  		ignored: /^.*\.(js[x]?|md|json|unison\.tmp)$/,
  		usePolling: false,
  		persistent: true,
  	} );
  
  	// The add/addDir events are fired during initialization generating an
  	// avalanche of refreshes on the client so we stick to the change events
  	// only for now until we can exclude the initial add/addDir events.
  	watcher.on( 'all', function( event, filepath ) {
  		if ( 'change' === event && filepath.match( /^.*\.scss$/ ) ) {
  			spawnMake();
  		}
  	} );
  }
func_documentation_string: Initialize server CSS hot-reloading logic
  @param {Object} io socket io socket