@Override
 public Object apply(List<Object> args, Context context) throws ParseException {
   File outFile = null;
   String editor = getEditor();
   try {
     outFile = File.createTempFile("stellar_shell", "out");
     if (args.size() > 0) {
       String arg = (String) args.get(0);
       try (PrintWriter pw = new PrintWriter(outFile)) {
         IOUtils.write(arg, pw);
       }
     }
   } catch (IOException e) {
     String message = "Unable to create temp file: " + e.getMessage();
     LOG.error(message, e);
     throw new IllegalStateException(message, e);
   }
   Optional<Object> console = context.getCapability(CONSOLE, false);
   try {
     PausableInput.INSTANCE.pause();
     // shut down the IO for the console
     ProcessBuilder processBuilder = new ProcessBuilder(editor, outFile.getAbsolutePath());
     processBuilder.redirectInput(ProcessBuilder.Redirect.INHERIT);
     processBuilder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
     processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
     try {
       Process p = processBuilder.start();
       // wait for termination.
       p.waitFor();
       try (BufferedReader br = new BufferedReader(new FileReader(outFile))) {
         String ret = IOUtils.toString(br).trim();
         return ret;
       }
     } catch (Exception e) {
       String message = "Unable to read output: " + e.getMessage();
       LOG.error(message, e);
       return null;
     }
   } finally {
     try {
       PausableInput.INSTANCE.unpause();
       if (console.isPresent()) {
         ((Console) console.get()).pushToInputStream("\b\n");
       }
     } catch (IOException e) {
       LOG.error("Unable to unpause: " + e.getMessage(), e);
     }
     if (outFile.exists()) {
       outFile.delete();
     }
   }
 }
 @Override
 public Object apply(List<Object> args, Context context) throws ParseException {
   Map<String, StellarExecutor.VariableResult> variables =
       (Map<String, StellarExecutor.VariableResult>)
           context.getCapability(StellarExecutor.SHELL_VARIABLES).get();
   if (args.size() == 0) {
     return null;
   }
   String variable = (String) args.get(0);
   if (variable == null) {
     return null;
   }
   StellarExecutor.VariableResult result = variables.get(variable);
   if (result != null && result.getExpression() != null) {
     return result.getExpression();
   }
   return null;
 }
 @Override
 public Object apply(List<Object> args, Context context) throws ParseException {
   Map<String, StellarExecutor.VariableResult> variables =
       (Map<String, StellarExecutor.VariableResult>)
           context.getCapability(StellarExecutor.SHELL_VARIABLES).get();
   LinkedHashMap<String, String> ret = new LinkedHashMap<>();
   for (Object arg : args) {
     if (arg == null) {
       continue;
     }
     String variable = (String) arg;
     StellarExecutor.VariableResult result = variables.get(variable);
     if (result != null && result.getExpression() != null) {
       ret.put(variable, result.getExpression());
     }
   }
   return ret;
 }
    @Override
    public Object apply(List<Object> args, Context context) throws ParseException {

      Map<String, StellarExecutor.VariableResult> variables =
          (Map<String, StellarExecutor.VariableResult>)
              context.getCapability(StellarExecutor.SHELL_VARIABLES).get();
      String[] headers = {"VARIABLE", "VALUE", "EXPRESSION"};
      String[][] data = new String[variables.size()][3];
      int wordWrap = -1;
      if (args.size() > 0) {
        wordWrap = ConversionUtils.convert(args.get(0), Integer.class);
      }
      int i = 0;
      for (Map.Entry<String, StellarExecutor.VariableResult> kv : variables.entrySet()) {
        StellarExecutor.VariableResult result = kv.getValue();
        data[i++] =
            new String[] {
              toWrappedString(kv.getKey().toString(), wordWrap),
              toWrappedString(result.getResult(), wordWrap),
              toWrappedString(result.getExpression(), wordWrap)
            };
      }
      return FlipTable.of(headers, data);
    }