@Override
 public void start(ThreadExitListener listener) throws ShellInvocationException {
   try {
     Link cl = Link.newLink(Isolate.currentIsolate(), isolate);
     sl = isolate.newStatusLink();
     isolate.start(cl);
     ObjectLinkMessage msg = ObjectLinkMessage.newMessage(this.cr);
     cl.send(msg);
   } catch (Exception ex) {
     throw new ShellInvocationException("Error starting isolate", ex);
   }
 }
 /**
  * The entry point that used to run the 'application' when the isolate is started. The actual
  * command is then passed to us in a Link message in the form of a CommandRunner object.
  *
  * @param args
  */
 public static void main(String[] args) {
   Link cl = Isolate.getLinks()[0];
   CommandRunner cr;
   try {
     ObjectLinkMessage message = (ObjectLinkMessage) cl.receive();
     cr = (CommandRunner) message.extract();
     Map<String, String> env = cr.getEnv();
     int envSize = (env == null) ? 0 : env.size();
     byte[][] binEnv = new byte[envSize * 2][];
     if (envSize > 0) {
       int i = 0;
       for (Map.Entry<String, String> entry : env.entrySet()) {
         binEnv[i++] = entry.getKey().getBytes();
         binEnv[i++] = entry.getValue().getBytes();
       }
     }
     NativeProcessEnvironment.setIsolateInitialEnv(binEnv);
   } catch (Exception e) {
     Unsafe.debugStackTrace(e.getMessage(), e);
     return;
   }
   cr.run();
 }
 public void waitFor() throws ShellInvocationException {
   try {
     while (true) {
       LinkMessage statusMsg = sl.receive();
       IsolateStatus status = statusMsg.extractStatus();
       if (status.getState().equals(IsolateStatus.State.EXITED)) {
         rc = status.getExitCode();
         break;
       }
     }
   } catch (Exception ex) {
     throw new ShellInvocationException("Error waiting for isolate", ex);
   }
 }