private String discoverAndroidSdkHome(
      AbstractBuild build, Launcher launcher, BuildListener listener) {
    final EnvVars envVars = Utils.getEnvironment(build, listener);
    final Map<String, String> buildVars = build.getBuildVariables();

    // SDK location
    Node node = Computer.currentComputer().getNode();
    String androidHome = Utils.expandVariables(envVars, buildVars, descriptor.androidHome);
    androidHome = SdkUtils.discoverAndroidHome(launcher, node, envVars, androidHome);
    return androidHome;
  }
  private void execute() {
    if (sourceFile == null) {
      printError("-i : No source file specified");
    }

    if (assembler == null || computer == null) {
      printError("-f : No format specified");
    }

    if (assembler.hasErrors()) {
      printError("Unable to execute file due to errors");
    }

    print("...preparing to execute program");

    if (trace) {
      print("...opening computer trace files");
      addTraceListeners();
    }

    computer.setExecutionSpeed(ExecutionSpeed.FULL);
    computer.setInstructions(assembler.getInstructions());

    computer.addComputerListener(
        new ComputerAdapter() {
          public void computerStarted(Computer computer) {
            print("...Execution started");
          }

          public void computerStopped(Computer computer) {
            print("...Execution complete");
          }
        });

    computer.execute();
  }
  private void addTraceListeners() {
    try {
      final PrintWriter memoryTrace = new PrintWriter(new FileWriter(baseFileName + ".mem"));
      final PrintWriter registerTrace = new PrintWriter(new FileWriter(baseFileName + ".reg"));
      final PrintWriter decoderTrace = new PrintWriter(new FileWriter(baseFileName + ".dec"));

      computer
          .getMemory()
          .addMemoryListener(
              new MemoryListener() {
                public void memoryReadFrom(Memory memory, int address, String value) {
                  memoryTrace.println("READ," + address + "," + value);
                }

                public void memoryWroteTo(Memory memory, int address, String value) {
                  memoryTrace.println("WRITE," + address + "," + value);
                }

                public void memoryError(Memory memory, Throwable error) {
                  memoryTrace.println("ERROR: " + error.getMessage());

                  printError(error.getMessage());
                }
              });

      computer
          .getRegisterStore()
          .addRegisterListener(
              new RegisterListener() {
                public void registerReadFrom(
                    RegisterStore registers, Register register, String value) {
                  registerTrace.println("READ," + register.getMnemonic() + "," + value);
                }

                public void registerWroteTo(
                    RegisterStore registers, Register register, String value) {
                  registerTrace.println("WRITE," + register.getMnemonic() + "," + value);
                }
              });

      computer
          .getInstructionDecoder()
          .addDecoderListener(
              new InstructionDecoderListener() {
                public void instructionDecoded(InstructionDecoder decoder, String instruction) {
                  decoderTrace.println(instruction);
                }

                public void decodeError(
                    InstructionDecoder decoder, String instruction, Throwable error) {
                  decoderTrace.println("Decoding '" + instruction + "'...");
                  decoderTrace.print("ERROR: " + error.getMessage());

                  printError(error.getMessage());
                }
              });

      computer.addComputerListener(
          new ComputerAdapter() {
            public void computerStopped(Computer computer) {
              // Close file output streams when execution is finished
              memoryTrace.close();
              registerTrace.close();
              decoderTrace.close();
            }

            public void computerError(Computer computer, Throwable error) {
              printError(error.getMessage());
            }
          });

    } catch (IOException e) {
      printError(e.getMessage());
    }
  }