/*
  * are processors of connection endpoints the same and are connected to the
  * current bus
  */
 protected boolean hasSwitchLoopback(ConnectionInstance pci, ComponentInstance curBus) {
   ComponentInstance srcHW = InstanceModelUtil.getHardwareComponent(pci.getSource());
   ComponentInstance dstHW = InstanceModelUtil.getHardwareComponent(pci.getDestination());
   if (srcHW == null || dstHW == null) return false;
   if (srcHW == dstHW && InstanceModelUtil.connectedToBus(srcHW, curBus)) {
     return true;
   }
   return false;
 }
 protected boolean hasConnectionSource(
     EList<ConnectionInstance> connections, ConnectionInstance conni) {
   ConnectionInstanceEnd src = conni.getSource();
   for (ConnectionInstance connectionInstance : connections) {
     if (connectionInstance.getSource() == src) {
       return true;
     }
   }
   return false;
 }
  /**
   * 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 void checkBandWidthLoad(final ComponentInstance curBus, SystemOperationMode som) {
    UnitLiteral kbspsliteral = GetProperties.getKBytespsUnitLiteral(curBus);
    double Buscapacity = GetProperties.getBandWidthCapacityInKbps(curBus, 0.0);
    boolean doBroadcast = GetProperties.isBroadcastProtocol(curBus);
    SystemInstance root = curBus.getSystemInstance();
    double totalBandWidth = 0.0;
    EList<ConnectionInstance> budgetedConnections = InstanceModelUtil.getBoundConnections(curBus);

    // 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)
    	{
    		if (InstanceModelUtil.isBoundToBus(obj, curBus)||
    				// we derived a bus connection from the connection end bindings
    			(!InstanceModelUtil.hasBusBinding(obj)&&InstanceModelUtil.connectedByBus(obj, curBus)) )
    		{
    			if ((obj.getSource().isActive(som)) && (obj.getDestination().isActive(som)))
    			{
    				budgetedConnections.add(obj);
    			}
    		}
    	}
    }*/
    if (doBroadcast) {
      budgetedConnections = filterSameSourceConnections(budgetedConnections);
    }
    if (Buscapacity == 0) {
      if (!budgetedConnections.isEmpty()) {
        errManager.warningSummary(
            curBus,
            som.getName(),
            curBus.getComponentInstancePath() + " has no capacity but bound connections");
      } else {
        errManager.warningSummary(
            curBus, som.getName(), curBus.getComponentInstancePath() + " has no capacity");
        return;
      }
    }
    if (budgetedConnections.isEmpty()) {
      errManager.infoSummary(
          curBus,
          som.getName(),
          curBus.getComponentInstancePath()
              + " with bandwidth capacity "
              + Buscapacity
              + "KBytesps has no bound connections");
      return;
    }
    if (som != null) {
      errManager.logInfo(
          "\n\nConnection Budget Details for bus "
              + curBus.getFullName()
              + " in mode "
              + som.getName()
              + " with capacity "
              + Buscapacity
              + "KBytesps\n");
    } else {
      errManager.logInfo(
          "\n\nConnection Budget Details for bus "
              + curBus.getFullName()
              + " with capacity "
              + Buscapacity
              + "KBytesps\n");
    }

    errManager.logInfo("Connection,Budget,Actual (Data Size * Sender Rate),Note");
    for (ConnectionInstance connectionInstance : budgetedConnections) {
      double budget = 0.0;
      double actual = 0.0;

      if ((!connectionInstance.getSource().isActive(som))
          || (!connectionInstance.getDestination().isActive(som))) {
        continue;
      }

      // we have a binding, is it to the current bus
      budget = GetProperties.getBandWidthBudgetInKbps(connectionInstance, 0.0);
      actual = calcBandwidthKBytesps(connectionInstance.getSource());
      String note = "";
      if (budget > 0) {
        if ((actual > 0) && (actual > budget)) {
          totalBandWidth += actual;
          note = "Actual bandwidth exceeds bandwidth budget. Using actual";
        } else {
          totalBandWidth += budget;
          note = "Using budget bandwidth";
        }
      } else {
        if (actual > 0) {
          totalBandWidth += actual;
          note = "No bandwidth budget. Using actual";
        } else {
          note = "No bandwidth budget or actual bandwidth from port data size&rate";
        }
      }
      detailedLog(connectionInstance, budget, actual, note);
    }
    detailedLog(null, totalBandWidth, kbspsliteral);
    if (totalBandWidth > Buscapacity) {
      errManager.errorSummary(
          curBus,
          som.getName(),
          curBus.getComponentInstancePath()
              + " bandwidth capacity "
              + Buscapacity
              + " KBytesps exceeded by connection bandwidth budget totals "
              + totalBandWidth
              + " Kbps");
    } else if (totalBandWidth > 0.0 && Buscapacity > 0.0) {
      errManager.infoSummary(
          curBus,
          som.getName(),
          curBus.getComponentInstancePath()
              + " bandwidth capacity "
              + Buscapacity
              + " KBytesps sufficient for connection bandwidth  budget totals "
              + totalBandWidth
              + " Kbps");
    }
  }
  /**
   * 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;
  }