private void handleFailure(final Result<? extends MpsatSynthesisChainResult> result) {
   String errorMessage = "Error: MPSat synthesis failed.";
   Throwable genericCause = result.getCause();
   if (genericCause != null) {
     // Exception was thrown somewhere in the chain task run() method (not in any of the subtasks)
     errorMessage += ERROR_CAUSE_PREFIX + genericCause.toString();
   } else {
     MpsatSynthesisChainResult returnValue = result.getReturnValue();
     Result<? extends Object> exportResult =
         (returnValue == null) ? null : returnValue.getExportResult();
     Result<? extends ExternalProcessResult> punfResult =
         (returnValue == null) ? null : returnValue.getPunfResult();
     Result<? extends ExternalProcessResult> mpsatResult =
         (returnValue == null) ? null : returnValue.getMpsatResult();
     if ((exportResult != null) && (exportResult.getOutcome() == Outcome.FAILED)) {
       errorMessage += "\n\nCould not export the model as a .g file.";
       Throwable exportCause = exportResult.getCause();
       if (exportCause != null) {
         errorMessage += ERROR_CAUSE_PREFIX + exportCause.toString();
       }
     } else if ((punfResult != null) && (punfResult.getOutcome() == Outcome.FAILED)) {
       errorMessage += "\n\nPunf could not build the unfolding prefix.";
       Throwable punfCause = punfResult.getCause();
       if (punfCause != null) {
         errorMessage += ERROR_CAUSE_PREFIX + punfCause.toString();
       } else {
         ExternalProcessResult punfReturnValue = punfResult.getReturnValue();
         if (punfReturnValue != null) {
           errorMessage += ERROR_CAUSE_PREFIX + new String(punfReturnValue.getErrors());
         }
       }
     } else if ((mpsatResult != null) && (mpsatResult.getOutcome() == Outcome.FAILED)) {
       errorMessage += "\n\nMPSat did not execute as expected.";
       Throwable mpsatCause = mpsatResult.getCause();
       if (mpsatCause != null) {
         errorMessage += ERROR_CAUSE_PREFIX + mpsatCause.toString();
       } else {
         ExternalProcessResult mpsatReturnValue = mpsatResult.getReturnValue();
         if (mpsatReturnValue != null) {
           String mpsatError = new String(mpsatReturnValue.getErrors());
           errorMessage += ERROR_CAUSE_PREFIX + mpsatError;
         }
       }
     } else {
       errorMessage += "\n\nMPSat chain task returned failure status without further explanation.";
     }
   }
   MainWindow mainWindow = Framework.getInstance().getMainWindow();
   JOptionPane.showMessageDialog(mainWindow, errorMessage, TITLE, JOptionPane.ERROR_MESSAGE);
 }
 private void handleSuccess(final Result<? extends MpsatSynthesisChainResult> result) {
   MpsatSynthesisChainResult returnValue = result.getReturnValue();
   final MpsatSynthesisMode mpsatMode = returnValue.getMpsatSettings().getMode();
   ExternalProcessResult mpsatReturnValue = returnValue.getMpsatResult().getReturnValue();
   switch (mpsatMode) {
     case COMPLEX_GATE_IMPLEMENTATION:
       handleSynthesisResult(mpsatReturnValue, false, RenderType.GATE);
       break;
     case GENERALISED_CELEMENT_IMPLEMENTATION:
       handleSynthesisResult(mpsatReturnValue, true, RenderType.BOX);
       break;
     case STANDARD_CELEMENT_IMPLEMENTATION:
       handleSynthesisResult(mpsatReturnValue, true, RenderType.GATE);
       break;
     case TECH_MAPPING:
       handleSynthesisResult(mpsatReturnValue, false, RenderType.GATE);
       break;
     default:
       MainWindow mainWindow = Framework.getInstance().getMainWindow();
       JOptionPane.showMessageDialog(
           mainWindow,
           "Warning: MPSat synthesis mode \'"
               + mpsatMode.getArgument()
               + "\' is not (yet) supported.",
           TITLE,
           JOptionPane.WARNING_MESSAGE);
       break;
   }
 }