private void extractLauncher(URL sourceLauncher, File targetLauncher) {
    checkNotNull(sourceLauncher);
    checkNotNull(targetLauncher);

    InputStream is = null;
    OutputStream os = null;

    try {
      targetLauncher.getParentFile().mkdirs();

      if (!targetLauncher.exists()) {
        Files.touch(targetLauncher);
      }

      is = sourceLauncher.openStream();
      os = new FileOutputStream(targetLauncher);

      ByteStreams.copy(is, os);
    } catch (IOException e) {
      throw new OperaRunnerException("Cannot write file to disk: " + e.getMessage());
    } finally {
      Closeables.closeQuietly(is);
      Closeables.closeQuietly(os);
    }

    logger.fine("New launcher copied to " + targetLauncher.getPath());
  }
  private void init() {
    try {
      binary =
          new OperaLauncherBinary(
              settings.getLauncher().getPath(), arguments.toArray(new String[arguments.size()]));
    } catch (IOException e) {
      throw new OperaRunnerException("Unable to start launcher: " + e.getMessage());
    }

    logger.fine("Waiting for launcher connection on port " + launcherPort);

    ServerSocket listenerServer = null;
    try {
      // Setup listener server
      listenerServer = new ServerSocket(launcherPort);
      // TODO(andreastt): Unsafe int cast
      listenerServer.setSoTimeout((int) OperaIntervals.LAUNCHER_CONNECT_TIMEOUT.getMs());

      // Try to connect
      protocol = new OperaLauncherProtocol(listenerServer.accept());

      // We did it!
      logger.fine("Connected with launcher on port " + launcherPort);

      // Do the handshake!
      LauncherHandshakeRequest.Builder request = LauncherHandshakeRequest.newBuilder();
      ResponseEncapsulation res =
          protocol.sendRequest(MessageType.MSG_HELLO, request.build().toByteArray());

      // Are we happy?
      if (res.isSuccess()) {
        logger.finer("Got launcher handshake: " + res.getResponse().toString());
      } else {
        throw new OperaRunnerException(
            "Did not get launcher handshake: " + res.getResponse().toString());
      }
    } catch (SocketTimeoutException e) {
      throw new OperaRunnerException(
          "Timeout waiting for launcher to connect on port " + launcherPort, e);
    } catch (IOException e) {
      throw new OperaRunnerException("Unable to listen to launcher port " + launcherPort, e);
    } finally {
      Closeables.closeQuietly(listenerServer);
    }
  }