	string negotiatePreloaderStartup(StartupDetails &details) {
		TRACE_POINT();
		string result;
		try {
			result = readMessageLine(details);
		} catch (const SystemException &e) {
			throwPreloaderSpawnException("An error occurred while starting up "
				"the preloader. There was an I/O error while reading its "
				"handshake message: " + e.sys(),
				SpawnException::PRELOADER_STARTUP_PROTOCOL_ERROR,
				details);
		} catch (const TimeoutException &) {
			throwPreloaderSpawnException("An error occurred while starting up "
				"the preloader: it did not write a handshake message in time.",
				SpawnException::PRELOADER_STARTUP_TIMEOUT,
				details);
		}
		
		if (result == "I have control 1.0\n") {
			UPDATE_TRACE_POINT();
			sendStartupRequest(details);
			try {
				result = readMessageLine(details);
			} catch (const SystemException &e) {
				throwPreloaderSpawnException("An error occurred while starting up "
					"the preloader. There was an I/O error while reading its "
					"startup response: " + e.sys(),
					SpawnException::PRELOADER_STARTUP_PROTOCOL_ERROR,
					details);
			} catch (const TimeoutException &) {
				throwPreloaderSpawnException("An error occurred while starting up "
					"the preloader: it did not write a startup response in time.",
					SpawnException::PRELOADER_STARTUP_TIMEOUT,
					details);
			}
			if (result == "Ready\n") {
				return handleStartupResponse(details);
			} else if (result == "Error\n") {
				handleErrorResponse(details);
			} else {
				handleInvalidResponseType(details, result);
			}
		} else {
			UPDATE_TRACE_POINT();
			if (result == "Error\n") {
				handleErrorResponse(details);
			} else {
				handleInvalidResponseType(details, result);
			}
		}
		
		// Never reached, shut up compiler warning.
		abort();
		return "";
	}
	string negotiatePreloaderStartup(StartupDetails &details) {
		TRACE_POINT();
		string result;
		try {
			result = readMessageLine(details);
		} catch (const SystemException &e) {
			throwPreloaderSpawnException("An error occurred while starting up "
				"the preloader. There was an I/O error while reading its "
				"handshake message: " + e.sys(),
				SpawnException::PRELOADER_STARTUP_PROTOCOL_ERROR,
				details);
		} catch (const TimeoutException &) {
			throwPreloaderSpawnException("An error occurred while starting up "
				"the preloader: it did not write a handshake message in time.",
				SpawnException::PRELOADER_STARTUP_TIMEOUT,
				details);
		}
		
		if (result == "I have control 1.0\n") {
			UPDATE_TRACE_POINT();
			sendStartupRequest(details);
			try {
				result = readMessageLine(details);
			} catch (const SystemException &e) {
				throwPreloaderSpawnException("An error occurred while starting up "
					"the preloader. There was an I/O error while reading its "
					"startup response: " + e.sys(),
					SpawnException::PRELOADER_STARTUP_PROTOCOL_ERROR,
					details);
			} catch (const TimeoutException &) {
				throwPreloaderSpawnException("An error occurred while starting up "
					"the preloader: it did not write a startup response in time.",
					SpawnException::PRELOADER_STARTUP_TIMEOUT,
					details);
			}
			if (result == "Ready\n") {
				return handleStartupResponse(details);
			} else if (result == "Error\n") {
				handleErrorResponse(details);
			} else {
				handleInvalidResponseType(details, result);
			}
		} else {
			UPDATE_TRACE_POINT();
			if (result == "Error\n") {
				handleErrorResponse(details);
			} else {
				handleInvalidResponseType(details, result);
			}
		}
		
		 
		abort();
		return "";
	}