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 void CompleteReaction(CReaction reaction, int numSubst, int numProd) {
    reaction.setReversible(false);
    // we need to get the function from the function database
    CFunctionDB funcDB = CCopasiRootContainer.getFunctionList();
    // it should be in the list of suitable functions
    // lets get all suitable functions for an irreversible reaction with  numSubst substrates and
    // numProd products
    CFunctionStdVector suitableFunctions =
        funcDB.suitableFunctions(numSubst, numProd, COPASI.TriFalse);
    int i;
    int iMax = (int) suitableFunctions.size();
    for (i = 0; i < iMax; ++i) {
      // we just assume that the only suitable function with Constant in
      // it's name is the one we want
      // if (suitableFunctions.get(i).getObjectName().indexOf("Constant") != -1) {
      if (suitableFunctions
          .get(i)
          .getObjectName()
          .contains("Mass action (irreversible)")) { // "Mass action (irreversible)"  //
        // "Michaelis-Menten"
        break;
      }
    }
    System.out.println("      Function: " + i + "/" + iMax);
    if (i < iMax) {
      // we set the function.
      // => the method should be smart enough to associate the reaction entities with the correct
      // function parameters
      reaction.setFunction(suitableFunctions.get(i));

      // TaskVectorN taskVector = dataModel.getTaskList();
      // dataModel.getTask(0).getProblem();
      CCopasiParameterGroup parameterGroup = reaction.getParameters();
      CCopasiParameter parameter;
      //  "Mass action (irreversible)" function has only one parameter k1
      parameter = parameterGroup.getParameter("k1");
      parameter.setDblValue(0.1);

      // michaelis-Menten
      /*
      parameter= parameterGroup.getParameter("V"); //  Michaelis-Menten has 2 parameters: V and Km
      parameter.setDblValue(20);
      parameter= parameterGroup.getParameter("Km"); //  "Mass action (irreversible)" function has only one parameter k1
      parameter.setDblValue(10);
      */
      //                    for (i = 0; i < parameterGroup.size(); i++) {
      //
      // //System.out.println(parameterGroup.getParameter(i).getObjectName());
      //                        parameterGroup.removeParameter(i);
      //                    }
      //                    String paramName;
      //                    i=0;
      //                    //for (i = 0; i < numSubst; i++) {
      //                        paramName = "k"+(i+1); //metabolite_"+i+"_K";
      //                        parameterGroup.addParameter(paramName, CCopasiParameter.DOUBLE);
      //                        CCopasiParameter parameter=parameterGroup.getParameter(paramName);
      //                        parameter.setDblValue(0.1);
      //                        changedObjects.add(parameter.getValueReference());
      //                    //}
    } else {
      System.err.println("Error. Could not find suitable function.");
      System.exit(1);
    }
  }
  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;
  }