public void analysisBody(final IProgressMonitor monitor, final Element obj) {
    if (obj instanceof InstanceObject) {
      SystemInstance root = ((InstanceObject) obj).getSystemInstance();
      monitor.beginTask(actionName, IProgressMonitor.UNKNOWN);
      final SOMIterator soms = new SOMIterator(root);
      while (soms.hasNext()) {
        final SystemOperationMode som = soms.nextSOM();
        OsateDebug.osateDebug("[DoBoundResourceAnalysisLogic] Analyze mode " + som.getName());

        //				final String somName = Aadl2Util.getPrintableSOMName(som);

        OsateDebug.osateDebug("[DoBoundResourceAnalysisLogic] Check Processor");
        errManager.infoSummaryReportOnly(root, som, "Processor Report");
        checkProcessorLoads(root, som);

        OsateDebug.osateDebug("[DoBoundResourceAnalysisLogic] Check Virtual Processor");
        errManager.infoSummaryReportOnly(root, som, "\nVirtual Processor Report");
        checkVirtualProcessorLoads(root, som);

        OsateDebug.osateDebug("[DoBoundResourceAnalysisLogic] Check RAM/ROM");
        errManager.infoSummaryReportOnly(root, som, "\nRAM/ROM Report");
        checkMemoryLoads(root, som);
      }
      monitor.done();

      if (root.getSystemOperationModes().size() == 1) {
        // Also report the results using a message dialog
        Dialog.showInfo("Resource Budget Statistics", errManager.getResultsMessages());
      }
    } else Dialog.showError("Bound Resource Analysis Error", "Can only check system instances");
  }
 protected final void postExecution(List<String> cmd) {
   boolean usesPok = cmd.stream().anyMatch(s -> s.equalsIgnoreCase("pok_c"));
   if (usesPok) {
     int i = cmd.indexOf("-o");
     String outputDirectory = cmd.get(i + 1);
     OsateDebug.osateDebug("output=" + outputDirectory);
     FileHelper.updatePokMakefile(outputDirectory + File.separatorChar + "generated-code");
   }
 }
  /**
   * check the load from components bound to the given memory The components can be threads or
   * higher level components.
   *
   * @param curMemory Component Instance of memory
   */
  protected void checkMemoryLoad(ComponentInstance curMemory, final SystemOperationMode som) {
    SystemInstance root = curMemory.getSystemInstance();
    final ComponentInstance currentMemory = curMemory;
    final String somName = som.getName();

    long timeBefore = System.currentTimeMillis();
    OsateDebug.osateDebug("[Memory] before get sw comps (memory=" + curMemory.getName() + ")");
    EList<ComponentInstance> boundComponents = InstanceModelUtil.getBoundSWComponents(curMemory);
    long timeAfter = System.currentTimeMillis();
    long period = timeAfter - timeBefore;
    OsateDebug.osateDebug("[CPU] after get sw comps, time taken=" + period + "ms");

    if (GetProperties.getROMCapacityInKB(curMemory, 0.0) > 0.0) {
      doMemoryLoad(curMemory, somName, boundComponents, true); // ROM
    }
    if (GetProperties.getRAMCapacityInKB(curMemory, 0.0) > 0.0) {
      doMemoryLoad(curMemory, somName, boundComponents, false); // RAM
    }
  }
  /**
   * check the load from connections bound to the given bus
   *
   * @param curBus Component Instance of bus
   * @param doBindings if true do bindings to all buses, if false do them only for EtherSwitch
   * @param somName String somName to be used in messages
   */
  protected double calcBandWidthLoad(SystemInstance root, final SystemOperationMode som) {
    double totalBandWidth = 0.0;
    EList<ConnectionInstance> connections = root.getAllConnectionInstances();
    EList<ConnectionInstance> budgetedConnections = new BasicEList<ConnectionInstance>();
    // filters out to use only Port connections or feature group connections
    // it also tries to be smart about not double accounting for budgets on FG that now show for
    // every port instance inside.
    ConnectionGroupIterator cgi = new ConnectionGroupIterator(connections);
    while (cgi.hasNext()) {
      ConnectionInstance obj = cgi.next();
      if (obj != null) budgetedConnections.add(obj);
    }
    for (ConnectionInstance connectionInstance : budgetedConnections) {
      if ((connectionInstance.getSource().getContainingComponentInstance() != null)
          && (!connectionInstance.getSource().getContainingComponentInstance().isActive(som))) {

        OsateDebug.osateDebug("[DoBoundResourceAnalysis] source not active in mode=" + som);
        continue;
      }

      if ((connectionInstance.getDestination().getContainingComponentInstance() != null)
          && (!connectionInstance
              .getDestination()
              .getContainingComponentInstance()
              .isActive(som))) {
        OsateDebug.osateDebug("[DoBoundResourceAnalysis] destination not active in mode=" + som);

        continue;
      }

      OsateDebug.osateDebug(
          "[DoBoundResourceAnalysis] source="
              + connectionInstance.getSource().getContainingComponentInstance());

      double budget = GetProperties.getBandWidthBudgetInKbps(connectionInstance, 0.0);
      double actual = calcBandwidthKBytesps(connectionInstance.getSource());
      String note = "";
      OsateDebug.osateDebug("[DoBoundResourceAnalysis] total=" + totalBandWidth);
      OsateDebug.osateDebug("[DoBoundResourceAnalysis] actual=" + actual);
      OsateDebug.osateDebug("[DoBoundResourceAnalysis] budget=" + budget);
      if (budget > 0) {
        if ((actual > 0) && (actual > budget)) {
          totalBandWidth += actual;
          note = "Actual bandwidth exceeds bandwidth budget. Using actual";

        } else {
          note = "Using budget bandwidth";
          totalBandWidth += budget;
        }
      } else {
        if (actual > 0) {
          totalBandWidth = totalBandWidth + actual;
          note = "No bandwidth budget. Using actual";
        } else {
          note = "No bandwidth budget or actual";
        }
      }
      detailedLog(connectionInstance, budget, actual, note);
    }
    OsateDebug.osateDebug("[DoBoundResourceAnalysis] res=" + totalBandWidth);
    return totalBandWidth;
  }
  /**
   * check the load from components bound to the given processor The components can be threads or
   * higher level components.
   *
   * @param curProcessor Component Instance of processor
   */
  protected void checkProcessorLoad(ComponentInstance curProcessor, final SystemOperationMode som) {
    boolean isCPUActive;

    if (curProcessor.getSubcomponent().getAllInModes().size() == 0) {
      isCPUActive = true;
    } else {
      isCPUActive = false;

      for (Mode mi : curProcessor.getSubcomponent().getAllInModes()) {
        // OsateDebug.osateDebug("somName=" + somName + " mi=" + mi);
        if (som.getName().equalsIgnoreCase(mi.getName())) {
          //	OsateDebug.osateDebug("cpu " + curProcessor.getName() +  "is active for mode" +
          // somName);
          isCPUActive = true;
        }
      }
    }

    if (isCPUActive == false) {
      return;
    }

    UnitLiteral mipsliteral = GetProperties.getMIPSUnitLiteral(curProcessor);
    double MIPScapacity = GetProperties.getMIPSCapacityInMIPS(curProcessor, 0.0);
    if (MIPScapacity == 0 && InstanceModelUtil.isVirtualProcessor(curProcessor)) {
      MIPScapacity = GetProperties.getMIPSBudgetInMIPS(curProcessor);
    }
    long timeBefore = System.currentTimeMillis();
    OsateDebug.osateDebug(
        "[CPU] before get sw comps (CPU="
            + curProcessor.getName()
            + ",cat="
            + curProcessor.getComponentClassifier().getCategory().getName()
            + ")");
    EList<ComponentInstance> boundComponents = InstanceModelUtil.getBoundSWComponents(curProcessor);
    long timeAfter = System.currentTimeMillis();
    long period = timeAfter - timeBefore;
    OsateDebug.osateDebug("[CPU] after get sw comps, time taken=" + period + "ms");

    if (boundComponents.size() == 0 && MIPScapacity > 0) {
      errManager.infoSummary(
          curProcessor,
          som.getName(),
          "No application components bound to "
              + curProcessor.getComponentInstancePath()
              + " with MIPS capacity "
              + GetProperties.toStringScaled(MIPScapacity, mipsliteral));
      return;
    }
    if (MIPScapacity == 0 && InstanceModelUtil.isVirtualProcessor(curProcessor)) {
      errManager.warningSummary(
          curProcessor,
          som.getName(),
          "Virtual processor "
              + curProcessor.getComponentInstancePath()
              + " has no MIPS capacity or budget.");
      return;
    }
    if (MIPScapacity == 0 && InstanceModelUtil.isProcessor(curProcessor)) {
      errManager.errorSummary(
          curProcessor,
          som.getName(),
          "Processor "
              + curProcessor.getComponentInstancePath()
              + " has no MIPS capacity but has bound components.");
    }
    if (InstanceModelUtil.isVirtualProcessor(curProcessor)) {
      logHeader(
          "\n\nDetailed Workload Report for Virtual Processor "
              + curProcessor.getComponentInstancePath()
              + " with Capacity "
              + GetProperties.toStringScaled(MIPScapacity, mipsliteral)
              + "\n\nComponent,Budget,Actual");
    } else {
      logHeader(
          "\n\nDetailed Workload Report for Processor "
              + curProcessor.getComponentInstancePath()
              + " with Capacity "
              + GetProperties.toStringScaled(MIPScapacity, mipsliteral)
              + "\n\nComponent,Budget,Actual");
    }
    double totalMIPS = 0.0;
    for (Iterator<ComponentInstance> it = boundComponents.iterator(); it.hasNext(); ) {
      ComponentInstance bci = (ComponentInstance) it.next();
      boolean isComponentActive;

      if ((som == null) || (bci.getSubcomponent().getAllInModes().size() == 0)) {
        isComponentActive = true;
      } else {
        isComponentActive = false;
        for (Mode mi : bci.getSubcomponent().getAllInModes()) {
          // OsateDebug.osateDebug("somName=" + somName + " mi=" + mi);
          if (som.getName().equalsIgnoreCase(mi.getName())) {
            //	OsateDebug.osateDebug("cpu " + curProcessor.getName() +  "is active for mode" +
            // somName);
            isComponentActive = true;
          }
        }
      }

      if (isComponentActive == true) {
        double actualmips = sumBudgets(bci, ResourceKind.MIPS, mipsliteral, true, som, "");
        totalMIPS += actualmips;
      }
    }
    logHeader("Total," + GetProperties.toStringScaled(totalMIPS, mipsliteral));
    if (totalMIPS > MIPScapacity) {
      errManager.errorSummary(
          curProcessor,
          som.getName(),
          "Total MIPS "
              + GetProperties.toStringScaled(totalMIPS, mipsliteral)
              + " of bound tasks exceeds MIPS capacity "
              + GetProperties.toStringScaled(MIPScapacity, mipsliteral)
              + " of "
              + curProcessor.getComponentInstancePath());
    } else if (totalMIPS == 0.0) {
      errManager.warningSummary(curProcessor, som.getName(), "Bound app's have no MIPS budget.");
    } else {
      errManager.infoSummary(
          curProcessor,
          som.getName(),
          "Total MIPS "
              + GetProperties.toStringScaled(totalMIPS, mipsliteral)
              + " of bound tasks within "
              + "MIPS capacity "
              + GetProperties.toStringScaled(MIPScapacity, mipsliteral)
              + " of "
              + curProcessor.getComponentInstancePath());
    }
  }