@SuppressWarnings({"unchecked", "unchecked"})
  // private mxGraphModel ExtractGraphFromSTD_INPUT() {
  private DirectedGraph<Object, ObjectEdge> ExtractGraphFromSTD_INPUT() {
    ActivityPort stdInput = getInput("STD_INPUT");
    ActivityPort inputfile = getInput("INPUT_FILE_BASE");

    /* @Todo: Reads directly from STD_INPUT. Should (be better) read from file (lots of .log .dot, .dat are generated by vivado workflow */
    Collection<String> lines = UtilStr.SeparateComponents((String) stdInput.getValue(), "\n");
    String startString = "<<BEGIN>><<" + (String) inputfile.getValue() + "_graph_minimized>>";
    String stopString = "<<END>><<" + (String) inputfile.getValue() + "_graph_minimized>>";
    boolean reading = false;

    // rebuild circuit graph
    DirectedGraph<Object, ObjectEdge> graph =
        new DefaultDirectedGraph<Object, ObjectEdge>(ObjectEdge.class);
    Map<String, Object> vertexMap = new HashMap<String, Object>();

    // mxGraphModel circuitGraph = new mxGraphModel();
    // circuitGraph.setCreateIds(false);
    // circuitGraph.beginUpdate();
    // Object rootCell = circuitGraph.getRoot();
    for (String line : lines) {
      if (reading) {
        if (line.equals(stopString)) {
          reading = false;
          break;
        } else {
          // rebuild graph
          Collection<String> wordsCollection = UtilStr.SeparateComponents(line, " ");
          String[] words = wordsCollection.toArray(new String[wordsCollection.size()]);
          int index = 1;
          int i;
          switch (words[0]) {
            case "Vertex":
              mxCell vertexCell = new mxCell();
              vertexCell.setVertex(true);
              vertexCell.setId(words[1]);
              switch (words[2]) {
                case "cell":
                  PLDConfigurableElement pldCell = new PLDConfigurableElement("Cell_0");
                  pldCell.setName(words[5]);
                  pldCell.setInitialValue(words[4]);
                  pldCell.setComponentType(ElectricalComponentType.INTRACHIP);
                  pldCell.setDescription(words[3]);
                  i = 6;
                  while ((i < words.length) && !words[i].equals("=>")) {
                    // String name, Direction direction, Long address, Integer bit, Boolean
                    // mandatory
                    // PhysicalPortPin  pin = new PhysicalPortPin(words[i], Direction.UNKNOWN, 0L,
                    // 0, true);
                    CPSPort pin =
                        new CPSPort(
                            words[i],
                            Direction.UNKNOWN,
                            0L,
                            0,
                            true); // PhysicalPortPin(words[i], Direction.UNKNOWN, 0L, 0, true);
                    if (pldCell.getInterfaceComponent().getChannels().size() == 0) {
                      pldCell
                          .getInterfaceComponent()
                          .getChannels()
                          .add(new ChannelPrimitive("default chanel"));
                    }
                    ChannelAbstract channel =
                        pldCell.getInterfaceComponent().getChannels().iterator().next();
                    channel.getPorts().add(pin);
                    vertexMap.put(words[i], pin);
                    i++;
                  }
                  while (i < words.length - 1) {
                    i++;
                    words[i] = words[i].replaceAll("@", " ");
                    int indexOfEqualSignal = words[i].indexOf("=");
                    String property = words[i].substring(0, indexOfEqualSignal);
                    String propValue = words[i].substring(indexOfEqualSignal + 1);
                    // Boolean isConst, String name, String defaultValue, String type, Direction
                    // direction
                    DiscreteVariable attribute =
                        new DiscreteVariable(
                            false, property, propValue, "UNKNOWN", Direction.UNKNOWN);
                    pldCell.getExtraAttributes().add(attribute);
                  }
                  // pldCell.getInterfaceElectrical().setElectricalFeature(new ElectricalFeature());
                  vertexCell.setValue(pldCell);
                  vertexMap.put(words[1], pldCell);
                  System.out.println("Vertex cell: " + pldCell);
                  graph.addVertex(pldCell);
                  break;
                case "port":
                  // Vertex <NodoIdx> port <Direction> <Name>
                  // EX: Vertex node18 port IN SA
                  Long address = Long.parseLong(words[1].replace("node", ""));
                  Direction dir = Direction.valueOf(words[3]);
                  // String name, Direction direction, Long address, Integer bit, Boolean mandatory
                  PhysicalPortPin pin = new PhysicalPortPin(words[4], dir, address, 0, true);
                  i = 5; // to be ++
                  while (i < words.length - 1) {
                    i++;
                    words[i] = words[i].replaceAll("@", " ");
                    int indexOfEqualSignal = words[i].indexOf("=");
                    String property = words[i].substring(0, indexOfEqualSignal);
                    String propValue = words[i].substring(indexOfEqualSignal + 1);
                    // Boolean isConst, String name, String defaultValue, String type, Direction
                    // direction
                    DiscreteVariable attribute =
                        new DiscreteVariable(
                            false, property, propValue, "UNKNOWN", Direction.UNKNOWN);
                    pin.getExtraAttributes().add(attribute);
                  }
                  vertexCell.setValue(pin);
                  vertexMap.put(words[1], pin); // nodeX
                  vertexMap.put(words[4], pin); // real name
                  System.out.println("Vertex port: " + pin);
                  graph.addVertex(pin);
                  break;
                default:
                  break;
              }
              // circuitGraph.add(rootCell, vertexCell, index++);
              break;
            case "Edge":
              // mxCell edgeCell = new mxCell();
              // edgeCell.setEdge(true);
              // edgeCell.setId(circuitGraph.createId(edgeCell));
              // mxCell source = (mxCell) circuitGraph.getCell(words[1]);
              // assert source != null;
              // edgeCell.setSource(source);
              // mxCell target = (mxCell) circuitGraph.getCell(words[2]);
              // assert target != null;
              // edgeCell.setTarget(target);
              String sourcePinOrPortStr = words[3];
              PhysicalPortPin sourcePinPort, targetPinPort;
              if (sourcePinOrPortStr.indexOf(":") > -1) {
                // is a CELL:PIN (takes only the pin part)
                sourcePinOrPortStr =
                    sourcePinOrPortStr.substring(sourcePinOrPortStr.indexOf(":") + 1);
                sourcePinPort = (PhysicalPortPin) vertexMap.get(sourcePinOrPortStr);
                assert sourcePinPort != null;
                sourcePinPort.setDirection(
                    Direction.OUT); // it is an OUT PIN, so we can read from it
              } else {
                sourcePinPort = (PhysicalPortPin) vertexMap.get(sourcePinOrPortStr);
                assert sourcePinPort != null;
                sourcePinPort.setDirection(
                    Direction.IN); // it is an IN PORT, so we can read from it
              }
              String targetPinOrPortStr = words[4];
              if (targetPinOrPortStr.indexOf(":") > -1) { // is a CELL:PIN (takes only the pin part)
                targetPinOrPortStr =
                    targetPinOrPortStr.substring(targetPinOrPortStr.indexOf(":") + 1);
                targetPinPort = (PhysicalPortPin) vertexMap.get(targetPinOrPortStr);
                assert targetPinPort != null;
                targetPinPort.setDirection(Direction.IN); // it is an IN PIN, so we can write to it
              } else {
                targetPinPort = (PhysicalPortPin) vertexMap.get(targetPinOrPortStr);
                assert targetPinPort != null;
                targetPinPort.setDirection(
                    Direction.OUT); // it is an OUT PORT, so we can write to it
              }
              PhysicalCommunicationNet hardwareNet =
                  new PhysicalCommunicationNet(sourcePinPort, targetPinPort);
              // edgeCell.setValue(hardwareNet);
              //                            i = 5; // to be ++
              //                            while (i < words.length - 1) {
              //                                i++;
              //                                words[i] = words[i].replaceAll("@", " ");
              //                                int indexOfEqualSignal = words[i].indexOf("=");
              //                                String property = words[i].substring(0,
              // indexOfEqualSignal);
              //                                String propValue =
              // words[i].substring(indexOfEqualSignal + 1);
              //                                //Boolean isConst, String name, String defaultValue,
              // String type, Direction direction
              //                                DiscreteVariable attribute = new
              // DiscreteVariable(false, property, propValue, "UNKNOWN", Direction.UNKNOWN);
              //                                //pin.getExtraAttributes().add(attribute);
              //                                /**
              //                                 * @TODO: where net properties are inserted into? *
              //                                 */
              //                            }
              // circuitGraph.add(rootCell, edgeCell, index++);
              Object vSource = vertexMap.get(words[1]);
              Object vTarget = vertexMap.get(words[2]);
              System.out.println(
                  "Edge: "
                      + vSource
                      + " -> "
                      + vTarget
                      + "   << "
                      + sourcePinOrPortStr
                      + " -> "
                      + targetPinOrPortStr
                      + "  >>");
              ObjectEdge edge = graph.addEdge(vSource, vTarget);
              edge.setUserObject(hardwareNet);
              break;
            default:
              Logger.getGlobal()
                  .warning(
                      "Error: Line not recognized when expecting to rebuild the circuit graph: "
                          + line);
              break;
          }
        }
      } else if (line.equals(startString)) {
        reading = true;
      }
    }
    // circuitGraph.endUpdate();
    //        return circuitGraph;
    return graph;
  }
  private CModel CreateBiochemicalReactions(
      DirectedGraph<Object, ObjectEdge> circuitGraph, String inputFileBase) {
    CCopasiDataModel dataModel = CCopasiRootContainer.addDatamodel();
    CModel model = dataModel.getModel();
    // set the units for the model
    model.setTimeUnit(CModel.s);
    model.setVolumeUnit(CModel.microl);
    model.setQuantityUnit(CModel.nMol);
    /* we have to keep a set of all the initial values that are changed during the model building process.
    They are needed after the model has been built to make sure all initialvalues are set to the correct initial value */
    ObjectStdVector changedObjects = new ObjectStdVector();
    CCompartment compartment = model.createCompartment("tube", 10.0);
    CCopasiObject object = compartment.getInitialValueReference();
    changedObjects.add(object);

    // create metabolites for all inputs
    // Object root = circuitGraph.getRoot();
    Map<String, CMetab> metabolitesMap = new HashMap<String, CMetab>();
    for (Object vertexObj : circuitGraph.vertexSet()) {
      if (vertexObj instanceof PhysicalPortPin) {
        PhysicalPortPin pin = (PhysicalPortPin) vertexObj;
        int cmet;
        cmet = CMetab.REACTIONS;
        //                if (pin.getDirection() == Direction.OUT) {
        //                    cmet = CMetab.REACTIONS;
        //                } else {
        //                    cmet = CMetab.FIXED;
        //                }
        CMetab metabolite =
            model.createMetabolite(fixId(pin.getName()), compartment.getObjectName(), 10.0, cmet);
        System.out.println("Metabolite: " + fixId(pin.getName()));
        metabolitesMap.put(pin.getName(), metabolite);
        changedObjects.add(metabolite.getInitialValueReference());
      } else if (vertexObj instanceof PLDConfigurableElement) {
        PLDConfigurableElement pldCell = (PLDConfigurableElement) vertexObj;
        for (ChannelAbstract channel :
            pldCell.getInterfaceComponent().getChannels()) { //   .getPins()) {
          for (CPSPort pin : channel.getPorts()) { //   .getPins()) {
            // if (pin.getDirection() == Direction.OUT) { // output pins will became a metabolite
            int cmet;
            cmet = CMetab.REACTIONS;
            CMetab metabolite =
                model.createMetabolite(
                    fixId(pin.getName()), compartment.getObjectName(), 10.0, cmet);
            System.out.println("Metabolite: " + fixId(pin.getName()));
            metabolitesMap.put(pin.getName(), metabolite);
            changedObjects.add(metabolite.getInitialValueReference());
            // }
          }
        }
      }
    }
    //        for (Object vertexObj : circuitGraph.vertexSet()) {
    //            if (vertexObj instanceof PLDConfigurableCellElement) {
    //                PLDConfigurableCellElement pldCell = (PLDConfigurableCellElement) vertexObj;
    //                for (HardwarePortPin pin : pldCell.getInterfaceComponent().getPins()) {
    //                    CMetab metabolite;
    //                    if (pin.getDirection() == Direction.IN) { // output pins will became a
    // metabolite
    //                        Set<ObjectEdge> edges = circuitGraph.edgesOf(vertexObj);
    //                        for (ObjectEdge edge : edges) {
    //                            HardwareCommunicationNet hardwareNet = (HardwareCommunicationNet)
    // edge.getUserObject();
    //                            for (HardwarePortBase port : hardwareNet.getTargets()) {
    //                                if (port.equals(pin)) {
    //                                    hardwareNet.getSource();
    //                                    //metabolite = hardwareNet.getSource();
    //                                }
    //                            }
    //                        }
    //                    }
    //                }
    //            }
    //        }

    // create chemical reactions
    for (Object vertex : circuitGraph.vertexSet()) {
      if (vertex instanceof PLDConfigurableElement) {
        PLDConfigurableElement pldCell = (PLDConfigurableElement) vertex;
        CReaction reaction = model.createReaction("reaction_" + fixId(pldCell.getName()));
        System.out.println("Reaction: " + reaction.getKey());
        CChemEq chemEquation = reaction.getChemEq();
        int func;
        int numSubst = 0;
        int numProd = 0;
        for (ChannelAbstract channel : pldCell.getInterfaceComponent().getChannels()) {
          for (CPSPort pin : channel.getPorts()) {
            CMetab met = metabolitesMap.get(pin.getName());
            assert met != null;
            if (pin.getDirection() == Direction.OUT) {
              func = CChemEq.PRODUCT;
              numProd++;
            } else {
              func = CChemEq.SUBSTRATE;
              numSubst++;
            }
            chemEquation.addMetabolite(met.getKey(), 1.0, func);
            System.out.println("      Metabolite: " + fixId(pin.getName()) + "  " + func);
          }
          CompleteReaction(reaction, numSubst, numProd);
        }
      }
    }
    for (ObjectEdge edge : circuitGraph.edgeSet()) {
      PhysicalCommunicationNet net = (PhysicalCommunicationNet) edge.getUserObject();
      CReaction reaction =
          model.createReaction("reaction_transfer_" + fixId(net.getSource().getName()));
      System.out.println("Reaction: " + reaction.getKey());
      CChemEq chemEquation = reaction.getChemEq();
      CMetab metSubs = metabolitesMap.get(net.getSource().getName());
      chemEquation.addMetabolite(metSubs.getKey(), 1.0, CChemEq.SUBSTRATE);
      int numSubst = 1;
      int numProd = net.getTargets().size();
      for (PhysicalPortBase targetport : net.getTargets()) {
        CMetab metProd = metabolitesMap.get(targetport.getName());
        chemEquation.addMetabolite(metProd.getKey(), 1.0, CChemEq.PRODUCT);
      }
      CompleteReaction(reaction, numSubst, numProd);
    }

    model.compileIfNecessary();

    // now that we are done building the model, we have to make sure all initial values are updated
    // according to their dependencies
    model.updateInitialValues(changedObjects);
    // save the model to a COPASI file
    String filename = Traits.getTEMP_PATHNAME() + inputFileBase + "_chemical_reactions.cps";

    dataModel.saveModel(filename, true);
    // export the model to an SBML file and we want SBML L2V3
    try {
      // String SBML = dataModel.exportSBMLToString();
      // System.out.println("NAO OCORREU CORE DUMP NO JNI!!!: "+SBML);
      // dataModel.exportSBML(Traits.getTEMP_PATHNAME() + inputFileBase +
      // "_chemical_reactions.xml");
      // dataModel.exportSBML(Traits.getTEMP_PATHNAME() + inputFileBase + "_chemical_reactions.xml",
      // true, 2, 3);
    } catch (java.lang.Exception ex) {
      System.err.println("Error. Exporting the model to SBML failed.");
    }
    return model;
  }