public CModel createModel(CCopasiDataModel dataModel) {
   try {
     dataModel.newModel();
   } catch (Exception e) {
     return null;
   }
   CModel model = dataModel.getModel();
   model.setVolumeUnit(CModel.fl);
   model.setTimeUnit(CModel.s);
   model.setQuantityUnit(CModel.fMol);
   CCompartment comp = model.createCompartment("CompartmentA");
   CMetab A = model.createMetabolite("A", comp.getObjectName());
   A.setInitialConcentration(2.0e-4);
   CMetab B = model.createMetabolite("B", comp.getObjectName());
   B.setInitialConcentration(0.0);
   CReaction react = model.createReaction("Decay_1");
   react.addSubstrate(A.getKey());
   react.addProduct(B.getKey());
   react.setReversible(false);
   react.setFunction("Mass action (irreversible)");
   react.setParameterValue("k1", 0.5);
   StringStdVector mapping = new StringStdVector();
   mapping.add(react.getChemEq().getSubstrate(0).getMetabolite().getKey());
   react.setParameterMappingVector(
       react.getFunction().getVariables().getParameter(1).getObjectName(), mapping);
   ;
   model.compileIfNecessary();
   ObjectStdVector changedObjects = new ObjectStdVector();
   changedObjects.add(comp.getObject(new CCopasiObjectName("Reference=InitialVolume")));
   changedObjects.add(A.getObject(new CCopasiObjectName("Reference=InitialConcentration")));
   changedObjects.add(B.getObject(new CCopasiObjectName("Reference=InitialConcentration")));
   changedObjects.add(
       react.getParameters().getParameter(0).getObject(new CCopasiObjectName("Reference=Value")));
   model.updateInitialValues(changedObjects);
   return model;
 }
  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;
  }