diff --git a/DESCRIPTION b/DESCRIPTION
index e83260ccff9825f98bd0b617dbcf640237cbf981..dba45ba5d2a64f020c77931a75e7d90e3b8efb32 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,22 +1,24 @@
 Package: sybilSBML
 Type: Package
 Title: SBML Integration in Package 'Sybil'
-Version: 2.0.11
-Date: 2016-06-06
+Version: 3.0.1
+Date: 2016-12-16
 Authors@R: c(person(c("C.", "Jonathan"), "Fritzemeier", role = c("cre", "ctb"), email = "clausjonathan.fritzemeier@uni-duesseldorf.de"),
 			 person("Gabriel", "Gelius-Dietrich", role = c("aut", "ctb")),
-             person("Deya", "Alzoubi", role = "ctb"))
+             person("Deya", "Alzoubi", role = "ctb"),
+             person("Ardalan", "Habil", role = "ctb"))
 Maintainer: C. Jonathan Fritzemeier <clausjonathan.fritzemeier@uni-duesseldorf.de>
 Depends: R (>= 2.14.2), Matrix, sybil (>= 2.0.0)
 Imports: methods
-Description: 'SBML' (Systems Biology Markup Language) integration in 'sybil'. Many constraint based metabolic models are published in 'SBML' format ('*.xml'). Herewith is the ability to read and check 'SBML' files in 'sybil' provided.
+Description: 'SBML' (Systems Biology Markup Language) with FBC (Flux Balance Constraints) integration in 'sybil'. Many constraint based metabolic models are published in 'SBML' format ('*.xml'). Herewith is the ability to read, write, and check 'SBML' files in 'sybil' provided.
 License: GPL-3 | file LICENSE
 LazyLoad: yes
 Collate: generics.R sbmlPtrClass.R sbmlErrorClass.R sybilSBML.R
         uglyHack.R readSBMLmod.R zzz.R
-Packaged: 2015-06-06 07:11:55 UTC; jonathan
+Packaged: 2016-12-16 07:11:55 UTC; jonathan
 Author: C. Jonathan Fritzemeier [cre, ctb],
   Gabriel Gelius-Dietrich [aut, ctb],
-  Deya Alzoubi [ctb]
+  Deya Alzoubi [ctb],
+  Ardalan Habil [ctb]
 NeedsCompilation: yes
 Repository: CRAN
diff --git a/NAMESPACE b/NAMESPACE
index 26d265c425dbe35dfde3dc4f40632a6e2e3d3ef9..ef1a335a79643feaf6af3485646e34b13d8d8eea 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -48,5 +48,9 @@ getSBMLunitDefinitionsList,
 getSBMLCompartList,
 getSBMLSpeciesList,
 getSBMLReactionsList,
-readSBMLmod
+readSBMLmod,
+writeSBML,
+getSBMLFbcversion,
+getSBMLmodNotes,
+getSBMLmodAnnotation
 )
diff --git a/R/readSBMLmod.R b/R/readSBMLmod.R
index fe1ebba72355814d7400f3cca3c6660803526007..56e9a4125cef71a77b5a0b31e686bdd60d1e1ea8 100644
--- a/R/readSBMLmod.R
+++ b/R/readSBMLmod.R
@@ -247,7 +247,13 @@ parseNotesReact <- function(notes) {
           gpr <- sub("GENE[_ ]?ASSOCIATION: *", "", fields_str[j])
           gene_rule <- sybil:::.parseBoolean(gpr)
           #print(gene_rule)
-      }
+    
+      }#Ardalan Habil
+      else if (grepl("GPR[_ ]?ASSOCIATION", fields_str[j])) {
+        gpr <- sub("GPR[_ ]?ASSOCIATION: *", "", fields_str[j])
+        gene_rule <- sybil:::.parseBoolean(gpr)
+      }  
+
       if (charmatch("SUBSYSTEM", fields_str[j], nomatch = -1) != -1) {
           subSyst <- sub("SUBSYSTEM: *", "", fields_str[j])
           subSyst <- sub("^S_", "", subSyst, perl = TRUE)
@@ -283,6 +289,14 @@ sbmldoc <- openSBMLfile(filename)
 
 message("OK")
 
+# warning if new Version/Level/
+SBMLlevel<- getSBMLlevel(sbmldoc)
+SBMLversion<- getSBMLversion(sbmldoc)
+FBCversion<-getSBMLFbcversion(sbmldoc)
+if(SBMLlevel == 3 && SBMLversion > 1)
+  warning(paste("No support for Level 3 Version ",SBMLversion))
+if (FBCversion > 2)
+  warning(paste("No support for Fbc Version ",FBCversion))
 
 #------------------------------------------------------------------------------#
 #                              check the model                                 #
@@ -380,6 +394,7 @@ if (mdesc == filename) {
 sybil::mod_desc(mod) <- mdesc
 
 
+
 #------------------------------------------------------------------------------#
 #                                   units                                      #
 #------------------------------------------------------------------------------#
@@ -398,7 +413,7 @@ if (is.null(compartmentsList)) {
 }
 
 missingId(compartmentsList)
-sybil::mod_compart(mod) <- compartmentsList[["id"]]
+comp_tmp_id <- compartmentsList[["id"]]
 
 
 #------------------------------------------------------------------------------#
@@ -430,6 +445,7 @@ missingId(metabolitesList)
 metSpIds        <- metabolitesList[["id"]]
 #nummet          <- getSBMLnumSpecies(sbmlmod)
 
+
 if (isTRUE(bndCond)) {
     metSpBnd <- metabolitesList[["boundaryCondition"]]
     met_id_pos <- !metSpBnd
@@ -485,12 +501,20 @@ gpr      <- character(numreact)
 hasNotes <- FALSE
 hasAnnot <- FALSE
 
+#FBC contraints @Ardalan Habil
+fbclowbnd<-reactionsList[["fbc_lowbnd"]]
+fbcuppbnd<-reactionsList[["fbc_uppbnd"]]
+fbcgprRules<-reactionsList[["fbc_gprRules"]]
+fbcObjectives<-reactionsList[["fbc_Objectives"]]
+
 for (i in 1 : numreact) {
 
     # the notes/annotations field
     notes <- reactionsList[["notes"]][i]
     annot <- reactionsList[["annotation"]][i]
-
+    
+    # Notes und Annotation can be null ( @Ardalan Habil)
+    if(!is.null( reactionsList[["notes"]])) 				
     if (nchar(notes) > 0) {
 
         hasNotes    <- TRUE
@@ -504,7 +528,7 @@ for (i in 1 : numreact) {
 
     }
     else {
-
+	 if(!is.null( reactionsList[["annotation"]]))	
         if (nchar(annot) > 0) {
             hasAnnot    <- TRUE
             pn <- regexpr("Pathway Name: [^<]+", annot, perl = TRUE)
@@ -512,7 +536,18 @@ for (i in 1 : numreact) {
         }
 
     }
-
+     
+    	
+
+    fbcgene_rule <- NA
+    if ( !is.null(fbcgprRules))
+    { 
+      fbcgene_rule<- sybil:::.parseBoolean(fbcgprRules[i])
+      
+      genes[[i]]  <- fbcgene_rule$gene      # list of genes
+      rules[i]    <- fbcgene_rule$rule       # rules
+      gpr[i]      <- fbcgprRules[i]  
+    }	
 
     # Check here if reactants and products lists exist, same for the stoichiometry slot
 
@@ -565,6 +600,16 @@ for (i in 1 : numreact) {
 #    }
 
     # the constraints
+  
+  #FBC contraints @Ardalan Habil
+  if ( !is.null(fbclowbnd) &&  !is.null(fbcuppbnd))
+  {
+    lbnd[i] <- checkupplowbnd(fbclowbnd[i])
+    ubnd[i] <- checkupplowbnd(fbcuppbnd[i])
+  }
+  #read from kinetic_law if fbc is empty 		
+  else
+  {
     parm <- reactionsList[["kinetic_law"]][[i]]
     if (is.null(parm)) {
         ubnd[i] <- def_bnd
@@ -591,10 +636,16 @@ for (i in 1 : numreact) {
             # reduced cost?  (sbml file)
         }
     }
-
+  }
+  #FBC Objective @Ardalan Habil
+    if(!is.null(fbcObjectives))
+    {
+      ocof[i]<-as.numeric(fbcObjectives[i])
+    }  
+    
+    
 }
 
-
 # ---------------------------------------------------------------------------- #
 # search for unused metabolites and unused reactions
 
@@ -877,7 +928,7 @@ else {
     rules  <- rules[SKIP_REACTION]
     gpr    <- gpr[SKIP_REACTION]
 
-    if (isTRUE(hasNotes)) {
+    if (isTRUE(hasNotes) ||  !is.null(fbcgprRules) ) {
         message("GPR mapping ... ", appendLF = FALSE)
 
         #allGenes <- unique(allGenes)
@@ -897,14 +948,13 @@ else {
             if ( (length(genes[[i]] == 1)) && (genes[[i]] != "") ) {
                 geneInd <- match(genes[[i]], allGenes)
                 rxnGeneMat[i, geneInd] <- TRUE
-                
-    			 # no use because new gprRule format
-#                for (j in 1 : length(geneInd)) {
-#                    pat  <- paste("x(", j, ")", sep = "")
-#                    repl <- paste("x[", geneInd[j], "]", sep = "")
-#    
-#                    rules[i] <- gsub(pat, repl, rules[i], fixed = TRUE)
-#                }
+    
+                for (j in 1 : length(geneInd)) {
+                    pat  <- paste("x(", j, ")", sep = "")
+                    repl <- paste("x[", geneInd[j], "]", sep = "")
+    
+                    rules[i] <- gsub(pat, repl, rules[i], fixed = TRUE)
+                }
             }
         }
 
@@ -970,6 +1020,63 @@ react_name_tmp   <- sub( "\\s+$",  "",  react_name_tmp, perl = TRUE)
 sybil::react_name(mod) <- react_name_tmp
 
 
+#------------------------------------------------------------------------------#
+#                             Reaction Attr  @Ardalan                          #
+#------------------------------------------------------------------------------#
+# Test for new Slots
+if( .hasSlot(mod,"mod_attr") &&  .hasSlot(mod,"comp_attr") &&  .hasSlot(mod,"met_attr")  &&  .hasSlot(mod,"react_attr") )
+  newSybil<-TRUE
+else newSybil<-FALSE
+
+numreact<-nummet <- sum(SKIP_REACTION)
+reactannotation <- reactionsList[["annotation"]][SKIP_REACTION]
+reactnotes <- reactionsList[["notes"]][SKIP_REACTION]
+if(newSybil)
+{  
+  sybil::react_attr(mod)  <-data.frame(row.names=1:numreact)
+  #Speed optimierung durch notes NULL falls nichts drin steht
+  
+  if( !is.null(reactannotation) && length(reactannotation)==numreact  )sybil::react_attr(mod)[['annotation']]<-reactannotation
+  if( !is.null(reactnotes) && length(reactnotes)==numreact  )sybil::react_attr(mod)[['notes']]<-reactnotes
+}
+
+
+#------------------------------------------------------------------------------#
+#                         Model Attr @Ardalan                                  #
+#------------------------------------------------------------------------------#
+
+modanno<-getSBMLmodAnnotation(sbmlmod)
+modnotes<-getSBMLmodNotes(sbmlmod)
+if(newSybil)
+{
+  sybil::mod_attr(mod)  <-data.frame(row.names=1)
+  if(nchar(modanno)>1)sybil::mod_attr(mod)[['annotation']]<-modanno
+  if(nchar(modnotes)>1)sybil::mod_attr(mod)[['notes']]<-modnotes
+  
+}  
+
+
+#------------------------------------------------------------------------------#
+#                         compartments Attr @Ardalan                           #
+#------------------------------------------------------------------------------#
+# Define SKIP_COMPARTMENT FALSE= HAS NO REFERENCE
+met_comp_tmp <- metabolitesList[["compartment"]][met_id_pos][SKIP_METABOLITE]
+SKIP_COMPARTMENT<- comp_tmp_id %in% unique(met_comp_tmp)
+
+  
+sybil::mod_compart(mod) <- comp_tmp_id[SKIP_COMPARTMENT]
+numcom<-length(mod_compart(mod))
+comannotation <- compartmentsList[["annotation"]][SKIP_COMPARTMENT]
+comnotes <- compartmentsList[["notes"]][SKIP_COMPARTMENT]
+if(newSybil)
+{ 
+  sybil::comp_attr(mod)  <-data.frame(row.names=1:numcom)
+  if( !is.null(comannotation) && length(comannotation)==numcom   )sybil::comp_attr(mod)[['annotation']]<-comannotation
+  if( !is.null(comnotes) && length(comnotes)==numcom  )sybil::comp_attr(mod)[['notes']]<-comnotes
+  
+}
+
+
 #------------------------------------------------------------------------------#
 #                             metabolite id's                                  #
 #------------------------------------------------------------------------------#
@@ -985,7 +1092,7 @@ sybil::met_id(mod) <- gsub("-",      "_",    met_id_tmp, fixed = TRUE)
 #                        metabolite compartments                               #
 #------------------------------------------------------------------------------#
 
-met_comp_tmp <- metabolitesList[["compartment"]][met_id_pos][SKIP_METABOLITE]
+#met_comp_tmp <- metabolitesList[["compartment"]][met_id_pos][SKIP_METABOLITE]
 
 sybil::met_comp(mod) <- match(met_comp_tmp, sybil::mod_compart(mod))
 
@@ -1002,6 +1109,69 @@ met_name_tmp   <- sub( "\\s+$",   "",  met_name_tmp, perl = TRUE)
 sybil::met_name(mod) <- met_name_tmp
 
 
+#------------------------------------------------------------------------------#
+#                             metabolite attr @Ardalan Habil                   #
+#------------------------------------------------------------------------------#
+
+#ChemicalFormula Charge Notes Annotation MetaID @Ardalan Habil
+
+metformula   <- metabolitesList[["chemicalFormula"]][met_id_pos][SKIP_METABOLITE]
+metcharge    <- metabolitesList[["charge"]][met_id_pos][SKIP_METABOLITE]
+
+metnotes <- metabolitesList[["notes"]][met_id_pos][SKIP_METABOLITE]
+metannotation <-   metabolitesList[["annotation"]][met_id_pos][SKIP_METABOLITE]
+
+
+metchargenote<-NULL
+metformulanote<-NULL
+# check metnotes for Formula and Charge
+if( !is.null(metnotes) && length(metnotes==nummet))
+{
+  pn <- regexpr("FORMULA: [^<]+", metnotes, perl = TRUE)
+  metformulanote <- substr(metnotes, (pn+9), pn + ((attr(pn, "match.length"))-1))
+  pn <- regexpr("CHARGE: [^<]+", metnotes, perl = TRUE)
+  metchargenote <- substr(metnotes, (pn+8), pn + ((attr(pn, "match.length"))-1))
+  metchargenote <- as.integer(metchargenote)
+  metchargenote[is.na(metchargenote)] <- 0
+}
+
+
+nummet <- sum(SKIP_METABOLITE)
+if(newSybil)
+{ 
+  # save attributes to met_attr slot
+  sybil::met_attr(mod)  <-data.frame(row.names=1:nummet)
+  if( !is.null(metformula) && length(metformula)==nummet)
+  {sybil::met_attr(mod)[['chemicalFormula']]<-metformula}
+  else{
+    if(length(metformulanote)==nummet)
+    { if(max(nchar(metformulanote)) >0)
+      sybil::met_attr(mod)[['chemicalFormula']]<-metformulanote 
+    }  
+  }
+  if( !is.null(metcharge) && length(metcharge)==nummet && sum(metcharge)!=0)
+  {sybil::met_attr(mod)[['charge']]<-metcharge}
+  else{
+    if(  length(metchargenote)==nummet)
+    {  if(max(nchar(metchargenote)) >0)
+      sybil::met_attr(mod)[['charge']]<-metchargenote 
+    }  
+  }
+  if( !is.null(metnotes) && length(metnotes)==nummet)sybil::met_attr(mod)[['notes']]<-metnotes 
+  if( !is.null(metannotation) && length(metannotation)==nummet)sybil::met_attr(mod)[['annotation']]<-metannotation
+  
+  # Save boundaryCondition when bndCond=FALSE
+  if (!isTRUE(bndCond)) {
+    metBnd <- metabolitesList[["boundaryCondition"]][met_id_pos][SKIP_METABOLITE]
+    # When all metBnd = False -> metabolite removed by extMetFlag
+    if( !is.null(metBnd) && length(metBnd)==nummet && !all(metBnd == FALSE) )sybil::met_attr(mod)[['boundaryCondition']]<-metBnd
+  }
+  
+  
+}
+
+
+
 #------------------------------------------------------------------------------#
 #                             check reversibilities                            #
 #------------------------------------------------------------------------------#
diff --git a/R/sybilSBML.R b/R/sybilSBML.R
index c76394e29b0bb1cb091909509bc362f977828512..b3eb40bee432ac7871489f4779c8fd2d086de6b1 100644
--- a/R/sybilSBML.R
+++ b/R/sybilSBML.R
@@ -1,280 +1,575 @@
-#------------------------------------------------------------------------------#
-#                          Link to libSBML for sybil                           #
-#------------------------------------------------------------------------------#
-
-#  sybilSBML.R
-#  Link to libSBML for sybil.
-#
-#  Copyright (C) 2010-2013 Gabriel Gelius-Dietrich, Dpt. for Bioinformatics,
-#  Institute for Informatics, Heinrich-Heine-University, Duesseldorf, Germany.
-#  All right reserved.
-#  Email: geliudie@uni-duesseldorf.de
-#
-#  This file is part of sybilSBML.
-#
-#  SybilSBML is free software: you can redistribute it and/or modify
-#  it under the terms of the GNU General Public License as published by
-#  the Free Software Foundation, either version 3 of the License, or
-#  (at your option) any later version.
-#
-#  SybilSBML is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with SybilSBML.  If not, see <http://www.gnu.org/licenses/>.
-
-
-#------------------------------------------------------------------------------#
-
-versionLibSBML <- function() {
-
-    version <- .Call("getLibSBMLversion", PACKAGE = "sybilSBML")
-    return(version)
-
-}
-
-
-#------------------------------------------------------------------------------#
-
-openSBMLfile <- function(fname, ptrtype = "sbml_doc") {
-
-    if ( file.exists(fname) == FALSE ) {
-        stop("file not found: ", sQuote(fname))
-    }
-
-    sbmlf <- .Call("readSBMLfile", PACKAGE = "sybilSBML",
-                   as.character(normalizePath(fname)[1]),
-                   as.character(ptrtype)
-             )
-
-    sbmlfP <- sbmlDocPointer(sbmlf)
-
-    return(sbmlfP)
-}
-
-
-#------------------------------------------------------------------------------#
-
-closeSBMLfile <- function(sbmlf) {
-
-    invisible(
-        .Call("delDocument", PACKAGE = "sybilSBML",
-              sbmlPointer(sbmlf)
-        )
-    )
-
-}
-
-
-#------------------------------------------------------------------------------#
-
-getSBMLmodel <- function(sbmlf, ptrtype = "sbml_mod") {
-
-    sbmlm <- .Call("getSBMLmodel", PACKAGE = "sybilSBML",
-                   sbmlPointer(sbmlf),
-                   as.character(ptrtype)
-             )
-
-    sbmlmP <- sbmlModPointer(sbmlm, sbmlf)
-
-    if (isTRUE(isNULLpointerSBML(sbmlmP))) {
-        sbmlmP <- NULL
-    }
-
-    return(sbmlmP)
-}
-
-
-#------------------------------------------------------------------------------#
-
-delSBMLmodel <- function(sbmlm) {
-
-    invisible(
-        .Call("delModel", PACKAGE = "sybilSBML",
-              sbmlPointer(sbmlm)
-        )
-    )
-
-}
-
-
-#------------------------------------------------------------------------------#
-
-getSBMLlevel <- function(sbmlf) {
-
-    level <- .Call("getSBMLlevel", PACKAGE = "sybilSBML",
-                   sbmlPointer(sbmlf)
-             )
-
-    return(level)
-}
-
-
-
-#------------------------------------------------------------------------------#
-
-getSBMLversion <- function(sbmlf) {
-
-    version <- .Call("getSBMLversion", PACKAGE = "sybilSBML",
-                     sbmlPointer(sbmlf)
-               )
-
-    return(version)
-}
-
-
-#------------------------------------------------------------------------------#
-
-validateSBMLdocument <- function(sbmlf) {
-
-    if (is(sbmlf, "character")) {
-        sbmlff <- openSBMLfile(fname = sbmlf)
-    }
-    else {
-        sbmlff <- sbmlf
-    }
-    
-    val <- .Call("validateDocument", PACKAGE = "sybilSBML",
-                 sbmlPointer(sbmlff)
-           )
-
-    if (is(sbmlf, "character")) {
-        val <- getSBMLerrors(sbmlff)
-        closeSBMLfile(sbmlff)
-    }
-
-    return(val)
-}
-
-
-#------------------------------------------------------------------------------#
-
-getSBMLerrors <- function(sbmlf) {
-
-    err <- .Call("getSBMLerrors", PACKAGE = "sybilSBML",
-                 sbmlPointer(sbmlf)
-           )
-
-    err <- sbmlError(err, sbmlf)
-
-    return(err)
-}
-
-
-#------------------------------------------------------------------------------#
-
-getSBMLmodId <- function(sbmlm) {
-
-    modid <- .Call("getSBMLmodId", PACKAGE = "sybilSBML",
-                   sbmlPointer(sbmlm)
-             )
-
-    return(modid)
-}
-
-
-#------------------------------------------------------------------------------#
-
-getSBMLmodName <- function(sbmlm) {
-
-    modn <- .Call("getSBMLmodName", PACKAGE = "sybilSBML",
-                  sbmlPointer(sbmlm)
-            )
-
-    return(modn)
-}
-
-
-#------------------------------------------------------------------------------#
-
-getSBMLnumCompart <- function(sbmlm) {
-
-    num <- .Call("getSBMLnumCompart", PACKAGE = "sybilSBML",
-                  sbmlPointer(sbmlm)
-            )
-
-    return(num)
-}
-
-
-#------------------------------------------------------------------------------#
-
-getSBMLnumSpecies <- function(sbmlm) {
-
-    num <- .Call("getSBMLnumSpecies", PACKAGE = "sybilSBML",
-                  sbmlPointer(sbmlm)
-            )
-
-    return(num)
-}
-
-
-#------------------------------------------------------------------------------#
-
-getSBMLnumReactions <- function(sbmlm) {
-
-    num <- .Call("getSBMLnumReactions", PACKAGE = "sybilSBML",
-                  sbmlPointer(sbmlm)
-            )
-
-    return(num)
-}
-
-
-#------------------------------------------------------------------------------#
-
-getSBMLunitDefinitionsList <- function(sbmlm) {
-
-    units <- .Call("getSBMLunitDefinitionsList", PACKAGE = "sybilSBML",
-                   sbmlPointer(sbmlm)
-             )
-
-    return(units)
-}
-
-
-#------------------------------------------------------------------------------#
-
-getSBMLCompartList <- function(sbmlm) {
-
-    comp <- .Call("getSBMLCompartList", PACKAGE = "sybilSBML",
-                  sbmlPointer(sbmlm)
-            )
-
-    return(comp)
-}
-
-
-#------------------------------------------------------------------------------#
-
-getSBMLSpeciesList <- function(sbmlm) {
-
-    spec <- .Call("getSBMLSpeciesList", PACKAGE = "sybilSBML",
-                  sbmlPointer(sbmlm)
-            )
-
-    return(spec)
-}
-
-
-#------------------------------------------------------------------------------#
-
-getSBMLReactionsList <- function(sbmlm) {
-
-    react <- .Call("getSBMLReactionsList", PACKAGE = "sybilSBML",
-                   sbmlPointer(sbmlm)
-             )
-
-    return(react)
-}
-
-
-
-
-
-
-
-
-
+#------------------------------------------------------------------------------#
+#                          Link to libSBML for sybil                           #
+#------------------------------------------------------------------------------#
+
+#  sybilSBML.R
+#  Link to libSBML for sybil.
+#
+#  Copyright (C) 2010-2013 Gabriel Gelius-Dietrich, Dpt. for Bioinformatics,
+#  Institute for Informatics, Heinrich-Heine-University, Duesseldorf, Germany.
+#  All right reserved.
+#  Email: geliudie@uni-duesseldorf.de
+#
+#  This file is part of sybilSBML.
+#
+#  SybilSBML is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation, either version 3 of the License, or
+#  (at your option) any later version.
+#
+#  SybilSBML is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with SybilSBML.  If not, see <http://www.gnu.org/licenses/>.
+
+
+#------------------------------------------------------------------------------#
+
+versionLibSBML <- function() {
+
+    version <- .Call("getLibSBMLversion", PACKAGE = "sybilSBML")
+    return(version)
+
+}
+
+
+#------------------------------------------------------------------------------#
+
+openSBMLfile <- function(fname, ptrtype = "sbml_doc") {
+
+    if ( file.exists(fname) == FALSE ) {
+        stop("file not found: ", sQuote(fname))
+    }
+
+    sbmlf <- .Call("readSBMLfile", PACKAGE = "sybilSBML",
+                   as.character(normalizePath(fname)[1]),
+                   as.character(ptrtype)
+             )
+
+    sbmlfP <- sbmlDocPointer(sbmlf)
+
+    return(sbmlfP)
+}
+
+
+#------------------------------------------------------------------------------#
+
+closeSBMLfile <- function(sbmlf) {
+
+    invisible(
+        .Call("delDocument", PACKAGE = "sybilSBML",
+              sbmlPointer(sbmlf)
+        )
+    )
+
+}
+
+
+#------------------------------------------------------------------------------#
+
+getSBMLmodel <- function(sbmlf, ptrtype = "sbml_mod") {
+
+    sbmlm <- .Call("getSBMLmodel", PACKAGE = "sybilSBML",
+                   sbmlPointer(sbmlf),
+                   as.character(ptrtype)
+             )
+
+    sbmlmP <- sbmlModPointer(sbmlm, sbmlf)
+
+    if (isTRUE(isNULLpointerSBML(sbmlmP))) {
+        sbmlmP <- NULL
+    }
+
+    return(sbmlmP)
+}
+
+
+#------------------------------------------------------------------------------#
+
+delSBMLmodel <- function(sbmlm) {
+
+    invisible(
+        .Call("delModel", PACKAGE = "sybilSBML",
+              sbmlPointer(sbmlm)
+        )
+    )
+
+}
+
+
+#------------------------------------------------------------------------------#
+
+getSBMLlevel <- function(sbmlf) {
+
+    level <- .Call("getSBMLlevel", PACKAGE = "sybilSBML",
+                   sbmlPointer(sbmlf)
+             )
+
+    return(level)
+}
+
+
+
+#------------------------------------------------------------------------------#
+
+getSBMLversion <- function(sbmlf) {
+
+    version <- .Call("getSBMLversion", PACKAGE = "sybilSBML",
+                     sbmlPointer(sbmlf)
+               )
+
+    return(version)
+}
+
+#------------------------------------------------------------------------------#
+
+getSBMLFbcversion <- function(sbmlf) {
+  
+  version <- .Call("getSBMLFbcversion", PACKAGE = "sybilSBML",
+                   sbmlPointer(sbmlf)
+  )
+  
+  return(version)
+}
+
+
+#------------------------------------------------------------------------------#
+
+validateSBMLdocument <- function(sbmlf) {
+
+    if (is(sbmlf, "character")) {
+        sbmlff <- openSBMLfile(fname = sbmlf)
+    }
+    else {
+        sbmlff <- sbmlf
+    }
+    
+    val <- .Call("validateDocument", PACKAGE = "sybilSBML",
+                 sbmlPointer(sbmlff)
+           )
+
+    if (is(sbmlf, "character")) {
+        val <- getSBMLerrors(sbmlff)
+        closeSBMLfile(sbmlff)
+    }
+
+    return(val)
+}
+
+
+#------------------------------------------------------------------------------#
+
+getSBMLerrors <- function(sbmlf) {
+
+    err <- .Call("getSBMLerrors", PACKAGE = "sybilSBML",
+                 sbmlPointer(sbmlf)
+           )
+
+    err <- sbmlError(err, sbmlf)
+
+    return(err)
+}
+
+
+#------------------------------------------------------------------------------#
+
+getSBMLmodId <- function(sbmlm) {
+
+    modid <- .Call("getSBMLmodId", PACKAGE = "sybilSBML",
+                   sbmlPointer(sbmlm)
+             )
+
+    return(modid)
+}
+
+
+#------------------------------------------------------------------------------#
+
+getSBMLmodName <- function(sbmlm) {
+
+    modn <- .Call("getSBMLmodName", PACKAGE = "sybilSBML",
+                  sbmlPointer(sbmlm)
+            )
+
+    return(modn)
+}
+
+#------------------------------------------------------------------------------#
+
+getSBMLmodNotes <- function(sbmlm) {
+  
+  modnotes <- .Call("getSBMLmodNotes", PACKAGE = "sybilSBML",
+                sbmlPointer(sbmlm)
+  )
+  
+  return(modnotes)
+}
+
+#------------------------------------------------------------------------------#
+
+getSBMLmodAnnotation <- function(sbmlm) {
+  
+  modanno <- .Call("getSBMLmodAnnotation", PACKAGE = "sybilSBML",
+                sbmlPointer(sbmlm)
+  )
+  
+  return(modanno)
+}
+
+
+#------------------------------------------------------------------------------#
+
+getSBMLnumCompart <- function(sbmlm) {
+
+    num <- .Call("getSBMLnumCompart", PACKAGE = "sybilSBML",
+                  sbmlPointer(sbmlm)
+            )
+
+    return(num)
+}
+
+
+#------------------------------------------------------------------------------#
+
+getSBMLnumSpecies <- function(sbmlm) {
+
+    num <- .Call("getSBMLnumSpecies", PACKAGE = "sybilSBML",
+                  sbmlPointer(sbmlm)
+            )
+
+    return(num)
+}
+
+
+#------------------------------------------------------------------------------#
+
+getSBMLnumReactions <- function(sbmlm) {
+
+    num <- .Call("getSBMLnumReactions", PACKAGE = "sybilSBML",
+                  sbmlPointer(sbmlm)
+            )
+
+    return(num)
+}
+
+
+#------------------------------------------------------------------------------#
+
+getSBMLunitDefinitionsList <- function(sbmlm) {
+
+    units <- .Call("getSBMLunitDefinitionsList", PACKAGE = "sybilSBML",
+                   sbmlPointer(sbmlm)
+             )
+
+    return(units)
+}
+
+
+#------------------------------------------------------------------------------#
+
+getSBMLCompartList <- function(sbmlm) {
+
+    comp <- .Call("getSBMLCompartList", PACKAGE = "sybilSBML",
+                  sbmlPointer(sbmlm)
+            )
+
+    return(comp)
+}
+
+
+#------------------------------------------------------------------------------#
+
+getSBMLSpeciesList <- function(sbmlm) {
+
+    spec <- .Call("getSBMLSpeciesList", PACKAGE = "sybilSBML",
+                  sbmlPointer(sbmlm)
+            )
+
+    return(spec)
+}
+
+
+#------------------------------------------------------------------------------#
+
+getSBMLReactionsList <- function(sbmlm) {
+
+    react <- .Call("getSBMLReactionsList", PACKAGE = "sybilSBML",
+                   sbmlPointer(sbmlm)
+             )
+
+    return(react)
+}
+
+
+#------------------------------------------------------------------------------#
+#export mod to SBML
+deformatSBMLid <- function(idstr) {
+  idstr <- gsub("-", "_DASH_", idstr, fixed = TRUE)
+  idstr <- gsub("(", "_LPAREN_", idstr, fixed = TRUE)
+  idstr <- gsub(")", "_RPAREN_", idstr, fixed = TRUE)
+  idstr <- gsub("[", "_", idstr, fixed = TRUE)
+  idstr <- gsub("]", "", idstr, fixed = TRUE)
+  idstr <- gsub(",", "_COMMA_", idstr, fixed = TRUE)
+  idstr <- gsub(".", "_PERIOD_", idstr, fixed = TRUE)
+  idstr <- gsub("'", "_APOS_", idstr, fixed = TRUE)
+  idstr <- sub("\\(e\\)$", "_e_", idstr)
+  idstr <- gsub("-", "_", idstr, fixed = TRUE)
+  return(idstr)
+}
+
+deformatGene<-function(idstr) {
+  idstr<-gsub("\\((\\S+)\\)", "\\1", idstr)
+  #idstr <- gsub("( ", "(", idstr, fixed = TRUE)
+  #idstr <- gsub(" (", "(", idstr, fixed = TRUE)
+  #idstr <- gsub(") ", ")", idstr, fixed = TRUE)
+  #idstr <- gsub(" )", ")", idstr, fixed = TRUE)
+  idstr <- gsub(":", "_", idstr, fixed = TRUE)
+  return(idstr)
+}
+
+writeSBML<- function(morg=NULL,level=2,version=4,fbcLevel=0,filename="export.xml",recoverExtMet=FALSE,printNotes=TRUE,printAnnos=TRUE,validation=FALSE ){
+  if(class(morg)!="modelorg"){
+    stop("morg has to be of class modelorg\n")
+  }
+  
+  ###right 
+  if(level==1)
+  { 
+    # test if Matrix has no double values
+    if( !all( S(morg) == floor(S(morg))) ) warning("Level 1 does not support double values")
+    fbcLevel=0
+      if(version != 2)
+      {
+        warning("just Level 1 Version 2 will be supported")
+        version=2
+      }
+  }else if (level==2)
+  { 
+    fbcLevel=0
+    if(version >5)
+    {
+      warning("Level 2 Version 5 will be supported")
+      version=5 
+    }
+    if(version < 1)
+    {
+      warning("Level 2 Version 1 will be supported")
+      version=1 
+    }  
+  }
+  else if (level==3)
+  { if(fbcLevel >2)fbcLevel=2
+  if(version != 1)
+  {
+    print("Level 3 Version 1 will be supported")
+    version=1 
+  }
+  
+  }else {
+    stop(" Support just for Level 1,2 and 3 \n")
+  }
+  
+  ##All GENES### 
+  allgenes<- unique(unlist(genes(morg)))
+  allgenes<-allgenes[allgenes != ""]
+  
+  
+  ##EXCHANGE REACTIONS##
+  ex <- findExchReact(morg)
+  ex_react<-NULL
+  # if recoverExtMet== FALSE => null for ex_react
+  if( (!is.null(ex)) && (recoverExtMet) )
+  {
+    if(!(all(diag(S(morg)[met_pos(ex), react_pos(ex)])==-1)))
+      stop("exchange reactions with Scoeff different than -1\n")
+    ex_react<-as.integer(react_pos(ex))
+  }
+  
+  ### Build wrapper for C Function #####
+  
+  
+  ##Met Attribute###
+  com_meta_id<- NULL
+  met_meta_id<- NULL
+  com_notes <- NULL
+  com_annotation<- NULL
+  met_notes<- NULL
+  met_anno<- NULL
+  met_bnd<- NULL
+  met_charge<-NULL
+  met_formula<-NULL
+  
+  react_notes<-NULL
+  react_anno<-NULL
+  
+  mod_notes<-NULL
+  mod_anno<-NULL
+  
+  #subsystem
+  # is subsystem Empty
+  if(length( colnames(subSys(morg)))==1 && colnames(subSys(morg))[1]=="" ) modhasubSys<-FALSE
+  else modhasubSys<-TRUE
+  
+  newsubS<- NULL
+
+  if( .hasSlot(morg,"mod_attr") &&  .hasSlot(morg,"comp_attr") &&  .hasSlot(morg,"met_attr")  &&  .hasSlot(morg,"react_attr") )
+    newSybil<-TRUE
+  else newSybil<-FALSE
+  ### Start newSybil attr
+  if(newSybil)
+  { 
+    if(("notes" %in% colnames(mod_attr(morg))) && (printNotes) ) mod_notes<-as.character(mod_attr(morg)[['notes']])
+    if(("annotation" %in% colnames(mod_attr(morg))) && (printAnnos) ) mod_annotation<-as.character(mod_attr(morg)[['annotation']])
+    
+    if(("notes" %in% colnames(comp_attr(morg)))    && (printNotes) ) com_notes<-as.character(as.list((comp_attr(morg)[['notes']])))
+    if(("annotation" %in% colnames(comp_attr(morg))) && (printAnnos)  ) com_annotation<-as.character(as.list((comp_attr(morg)[['annotation']])))
+    
+    if("charge" %in% colnames(met_attr(morg))) met_charge<- as.integer(as.list((met_attr(morg)[['charge']])))
+    if("chemicalFormula" %in% colnames(met_attr(morg))) met_formula<-as.character(as.list((met_attr(morg)[['chemicalFormula']])))
+    if(("annotation" %in% colnames(met_attr(morg))) && (printAnnos)) met_anno<-as.character(as.list((met_attr(morg)[['annotation']])))
+    if("boundaryCondition" %in% colnames(met_attr(morg))) met_bnd<-as.logical(as.list((met_attr(morg)[['boundaryCondition']])))
+    
+    if(("notes" %in% colnames(met_attr(morg))) && (printNotes) )
+    {   # delete Formular and charge from notes to do
+      met_notes<-as.character(as.list((met_attr(morg)[['notes']])))
+      if (!is.null(met_charge) || !is.null(met_formula))
+      {  
+        for ( i in 1:met_num(morg)) 
+        {
+          
+          if(nchar(met_notes[i])> 8)
+          { 
+            # Have Assocation in Notes?yes: replace no: append
+            
+            if (regexpr("html:p", met_notes[i], fixed = TRUE) == -1)tag <- "p"
+            else tag <- "html:p"
+            
+            
+            if (!is.null(met_formula))
+            {    
+              haveform<-grepl("FORMULA: [^<]+",met_notes[i])
+              #Have Gene if not ->no need to write in FBC2
+              if(haveform)
+              {  
+                if(fbcLevel==0)met_notes[i]<-sub("FORMULA: [^<]+",paste("FORMULA: ",met_formula[i], sep = ""), met_notes[i], perl = TRUE)
+                else met_notes[i]<-sub(paste("<",tag,">","FORMULA: [^<]+","</",tag,">",sep = ""),"",met_notes[i], perl = TRUE)
+              }    
+              else if(fbcLevel==0) met_notes[i]<-gsub("</notes>",paste("<",tag,">","FORMULA: ",met_formula[i],"</",tag,">","\n</notes>",sep = ""),met_notes[i])
+            }
+            if (!is.null(met_charge))
+            {    
+              havecharge<-grepl("CHARGE: [^<]+",met_notes[i])
+              #Have Subsystem
+              if(havecharge)
+              {  
+                if(fbcLevel !=0 || (level==2 && version==1 ))
+                  met_notes[i]<-sub(paste("<",tag,">","CHARGE: [^<]+","</",tag,">",sep = ""),"",met_notes[i], perl = TRUE)
+                else met_notes[i]<-sub("CHARGE: [^<]+",paste("CHARGE: ",met_charge[i], sep = ""), met_notes[i], perl = TRUE)
+                
+                
+              }  
+              else if(fbcLevel==0) if(level!=2 && version!=1) met_notes[i]<-gsub("</notes>",paste("<",tag,">","CHARGE: ",met_charge[i],"</",tag,">","\n</notes>",sep = ""),met_notes[i])
+            }
+          }
+        }  
+      }
+      
+    }
+    if(("annotation" %in% colnames(react_attr(morg))) && (printAnnos)) react_anno<-as.character(as.list((react_attr(morg)[['annotation']])))
+    
+    # Merge Notes with "our" Notes and make sure gpr Rules from gpr
+    if(("notes" %in% colnames(react_attr(morg))) && (printNotes))
+    {
+      react_notes<-as.character(as.list((react_attr(morg)[['notes']])))
+      # using
+      #  SubSystem EXISTIERT nicht colnames(subSys(ec))
+      
+      for ( i in 1:react_num(morg)) 
+      {
+        # using the for loop
+        if(modhasubSys)newsubS[i]<- paste(names(which(subSys(morg)[i,])), collapse=", ")   
+        if(nchar(react_notes[i])> 8)
+        { 
+          # Have Association in Notes? yes: replace no: append
+          
+          if (regexpr("html:p", react_notes[i], fixed = TRUE) == -1)tag <- "p"
+          else tag <- "html:p"
+          
+          havegene<-grepl("GENE[_ ]?ASSOCIATION: [^<]+",react_notes[i])
+          havesub<-grepl("SUBSYSTEM: [^<]+",react_notes[i])
+          
+          #Have Gene if not ->no need to write in FBC2
+          if(havegene)
+          {
+            if(fbcLevel==2) react_notes[i]<-sub(paste("<",tag,">","GENE[_ ]?ASSOCIATION: [^<]+","</",tag,">",sep = ""),"",react_notes[i], perl = TRUE)
+            else react_notes[i]<-sub("GENE[_ ]?ASSOCIATION: [^<]+",paste("GENE_ASSOCIATION: ",gpr(morg)[i], sep = ""), react_notes[i], perl = TRUE)
+          }
+          else if(fbcLevel!=2)react_notes[i]<-gsub("</notes>",paste("<",tag,">","GENE_ASSOCIATION: ",gpr(morg)[i],"</",tag,">","\n</notes>",sep = ""),react_notes[i])
+          
+          #Have Subsystem
+          if(havesub)react_notes[i]<-sub("SUBSYSTEM: [^<]+",paste("SUBSYSTEM: ",newsubS[i], sep = ""), react_notes[i], perl = TRUE)
+          else if(modhasubSys) react_notes[i]<-gsub("</notes>",paste("<",tag,">","SUBSYSTEM: ",newsubS[i],"</",tag,">","\n</notes>",sep = ""),react_notes[i])
+        }
+      }  
+    }  
+    
+    
+  } ####END newSybil attr
+  
+  # Subsystem
+  if(is.null(newsubS) && !(modhasubSys) ) for ( i in 1:react_num(morg)) {newsubS[i]<- paste(names(which(subSys(morg)[i,])), collapse=", ")}
+  
+  newmet_id <- paste0("M_", (deformatSBMLid(met_id(morg))))
+  #newmet_id <- sub("\\[(\\w)\\]$", "_\\1",  newmet_id) # append compartment id, if in postfix with square brkts
+  
+  newreact_id <- paste0("R_", deformatSBMLid(react_id(morg)))
+  newmet_comp<-mod_compart(morg)[met_comp(morg)]
+  
+  
+  success <-.Call("exportSBML", PACKAGE = "sybilSBML",
+                  as.integer(version),
+                  as.integer(level),
+                  as.integer(fbcLevel),
+                  as.character(filename),
+                  SYBIL_SETTINGS("MAXIMUM"),
+                  as.character(mod_desc(morg)),
+                  as.character(mod_name(morg)),
+                  as.character(mod_compart(morg)),
+                  as.character(newmet_id),
+                  as.character(met_name(morg)),
+                  as.character(newmet_comp),
+                  met_formula,
+                  met_charge,
+                  as.character(newreact_id),
+                  as.character(react_name(morg)),
+                  as.logical(react_rev(morg)),
+                  as.numeric(lowbnd(morg)),
+                  as.numeric(uppbnd(morg)),
+                  as.integer(obj_coef(morg)),
+                  as.character(newsubS),
+                  as.character(deformatGene(gpr(morg))),
+                  as.numeric(shrinkMatrix(morg,j=1:react_num(morg))),
+                  mod_notes,
+                  mod_anno,
+                  com_notes,   
+                  com_annotation, 
+                  met_notes,      
+                  met_anno,
+                  met_bnd,
+                  react_notes,
+                  react_anno,
+                  ex_react,
+                  as.character(deformatGene(allgenes))
+  )
+# SUCESS MESSAGES
+  if(success)
+  {
+    message(paste("Wrote file ",filename,"\n",sep=""), appendLF = FALSE);
+    if (validation)print(validateSBMLdocument(filename));
+  }  
+  else  message(paste("Could not write file ",filename,"\n",sep=""), appendLF = FALSE);
+  return (success)
+}
\ No newline at end of file
diff --git a/build/vignette.rds b/build/vignette.rds
new file mode 100644
index 0000000000000000000000000000000000000000..217b014b3aaa3d2181c33fc96a7045116045540b
Binary files /dev/null and b/build/vignette.rds differ
diff --git a/configure b/configure
index c935bad4b88e8c1b54ffc657c001f9f52a23033a..ba94dc2b4ec2da43b77e94e9fe8036692a4e4aab 100755
--- a/configure
+++ b/configure
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for sybilSBML 2.0.8.
+# Generated by GNU Autoconf 2.69 for sybilSBML 3.0.0.
 #
-# Report bugs to <geliudie@uni-duesseldorf.de>.
+# Report bugs to <clausjonathan.fritzemeier@uni-duesseldorf.de>.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -267,8 +267,8 @@ fi
     $as_echo "$0: be upgraded to zsh 4.3.4 or later."
   else
     $as_echo "$0: Please tell bug-autoconf@gnu.org and
-$0: geliudie@uni-duesseldorf.de about your system,
-$0: including any error possibly output before this
+$0: clausjonathan.fritzemeier@uni-duesseldorf.de about your
+$0: system, including any error possibly output before this
 $0: message. Then install a modern shell, or manually run
 $0: the script under such a shell if you do have one."
   fi
@@ -580,9 +580,9 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='sybilSBML'
 PACKAGE_TARNAME='sybilsbml'
-PACKAGE_VERSION='2.0.8'
-PACKAGE_STRING='sybilSBML 2.0.8'
-PACKAGE_BUGREPORT='geliudie@uni-duesseldorf.de'
+PACKAGE_VERSION='3.0.0'
+PACKAGE_STRING='sybilSBML 3.0.0'
+PACKAGE_BUGREPORT='clausjonathan.fritzemeier@uni-duesseldorf.de'
 PACKAGE_URL=''
 
 # Factoring default headers for most tests.
@@ -1230,7 +1230,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures sybilSBML 2.0.8 to adapt to many kinds of systems.
+\`configure' configures sybilSBML 3.0.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1291,7 +1291,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of sybilSBML 2.0.8:";;
+     short | recursive ) echo "Configuration of sybilSBML 3.0.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1315,7 +1315,7 @@ Some influential environment variables:
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
 
-Report bugs to <geliudie@uni-duesseldorf.de>.
+Report bugs to <clausjonathan.fritzemeier@uni-duesseldorf.de>.
 _ACEOF
 ac_status=$?
 fi
@@ -1378,7 +1378,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-sybilSBML configure 2.0.8
+sybilSBML configure 3.0.0
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1537,9 +1537,9 @@ $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
 $as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
     { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-( $as_echo "## ------------------------------------------ ##
-## Report this to geliudie@uni-duesseldorf.de ##
-## ------------------------------------------ ##"
+( $as_echo "## ----------------------------------------------------------- ##
+## Report this to clausjonathan.fritzemeier@uni-duesseldorf.de ##
+## ----------------------------------------------------------- ##"
      ) | sed "s/^/$as_me: WARNING:     /" >&2
     ;;
 esac
@@ -1676,11 +1676,78 @@ fi
   as_fn_set_status $ac_retval
 
 } # ac_fn_c_try_link
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
 cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by sybilSBML $as_me 2.0.8, which was
+It was created by sybilSBML $as_me 3.0.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3528,6 +3595,101 @@ else
 fi
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for readSBML in -lsbml" >&5
+$as_echo_n "checking for readSBML in -lsbml... " >&6; }
+if ${ac_cv_lib_sbml_readSBML+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsbml  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char readSBML ();
+int
+main ()
+{
+return readSBML ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_sbml_readSBML=yes
+else
+  ac_cv_lib_sbml_readSBML=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sbml_readSBML" >&5
+$as_echo "$ac_cv_lib_sbml_readSBML" >&6; }
+if test "x$ac_cv_lib_sbml_readSBML" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBSBML 1
+_ACEOF
+
+  LIBS="-lsbml $LIBS"
+
+else
+  as_fn_error $? "Could not link to libSBML:
+      use --with-sbml-lib or PKG_LIBS to specify the library path and the libraries to pass to the linker." "$LINENO" 5
+fi
+
+
+ac_fn_c_check_header_compile "$LINENO" "sbml/packages/fbc/common/FbcExtensionTypes.h" "ac_cv_header_sbml_packages_fbc_common_FbcExtensionTypes_h" "#include <sbml/SBMLTypes.h>
+"
+if test "x$ac_cv_header_sbml_packages_fbc_common_FbcExtensionTypes_h" = xyes; then :
+
+else
+  as_fn_error $? "Could not find specific FBC header of libSBML:
+      make sure your libSBML version is >= 5.13." "$LINENO" 5
+fi
+
+
+
+#AC_CHECK_LIB([sbml], [SBMLExtensionRegistry_getRegisteredPackages], ,
+#    AC_MSG_ERROR([Could not find specific FBC function of libSBML:
+#		make sure your libSBML version is >= 5.13.]))
+
+for ac_func in SBase_getPlugin SBMLExtensionRegistry_getRegisteredPackages GeneProductAssociation_setAssociation FbcReactionPlugin_getLowerFluxBound
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+else
+  as_fn_error $? "Could not find specific FBC function of libSBML:
+		make sure your libSBML version is >= 5.13." "$LINENO" 5
+fi
+done
+
+
+#AC_SEARCH_LIBS([SBase_getPlugin], [sbml], ,
+#    AC_MSG_ERROR([Could not find specific FBC function of libSBML:
+#      make sure your libSBML version is >= 5.13.]))
+
+#AC_SEARCH_LIBS([SBMLExtensionRegistry_getRegisteredPackages], [sbml], ,
+#    AC_MSG_ERROR([Could not find specific FBC function of libSBML:
+#      make sure your libSBML version is >= 5.13.]))
+
+
+
+#AC_SEARCH_LIBS([GeneProductAssociation_setAssociation], [sbml], ,
+#    AC_MSG_ERROR([Could not find specific FBC function of libSBML:
+#      make sure your libSBML version is >= 5.13.]))
+
+
 
 
 
@@ -4077,7 +4239,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by sybilSBML $as_me 2.0.8, which was
+This file was extended by sybilSBML $as_me 3.0.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -4124,13 +4286,13 @@ Usage: $0 [OPTION]... [TAG]...
 Configuration files:
 $config_files
 
-Report bugs to <geliudie@uni-duesseldorf.de>."
+Report bugs to <clausjonathan.fritzemeier@uni-duesseldorf.de>."
 
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-sybilSBML config.status 2.0.8
+sybilSBML config.status 3.0.0
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index c75e9c7e0a8012cf7e0f97754609a57bea301223..08faede40197a400f9e86fc8520a65aa90f60143 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([sybilSBML], [2.0.8], [geliudie@uni-duesseldorf.de])
+AC_INIT([sybilSBML], [3.0.0], [clausjonathan.fritzemeier@uni-duesseldorf.de])
 
 dnl # --------------------------------------------------------------------
 dnl # global (environment) variables
@@ -236,6 +236,38 @@ AC_SEARCH_LIBS([readSBML], [sbml], ,
     AC_MSG_ERROR([Could not link to libSBML:
       use --with-sbml-lib or PKG_LIBS to specify the library path and the libraries to pass to the linker.]))
 
+AC_CHECK_LIB([sbml], [readSBML], ,
+    AC_MSG_ERROR([Could not link to libSBML:
+      use --with-sbml-lib or PKG_LIBS to specify the library path and the libraries to pass to the linker.]))
+
+AC_CHECK_HEADER([sbml/packages/fbc/common/FbcExtensionTypes.h], ,
+ AC_MSG_ERROR([Could not find specific FBC header of libSBML:
+      make sure your libSBML version is >= 5.13.]),
+      [#include <sbml/SBMLTypes.h>])
+
+#AC_CHECK_LIB([sbml], [SBMLExtensionRegistry_getRegisteredPackages], ,
+#    AC_MSG_ERROR([Could not find specific FBC function of libSBML:
+#		make sure your libSBML version is >= 5.13.]))
+
+AC_CHECK_FUNCS([SBase_getPlugin SBMLExtensionRegistry_getRegisteredPackages GeneProductAssociation_setAssociation FbcReactionPlugin_getLowerFluxBound], ,
+	AC_MSG_ERROR([Could not find specific FBC function of libSBML:
+		make sure your libSBML version is >= 5.13.]))
+
+#AC_SEARCH_LIBS([SBase_getPlugin], [sbml], ,
+#    AC_MSG_ERROR([Could not find specific FBC function of libSBML:
+#      make sure your libSBML version is >= 5.13.]))
+
+#AC_SEARCH_LIBS([SBMLExtensionRegistry_getRegisteredPackages], [sbml], ,
+#    AC_MSG_ERROR([Could not find specific FBC function of libSBML:
+#      make sure your libSBML version is >= 5.13.]))
+
+
+
+#AC_SEARCH_LIBS([GeneProductAssociation_setAssociation], [sbml], ,
+#    AC_MSG_ERROR([Could not find specific FBC function of libSBML:
+#      make sure your libSBML version is >= 5.13.]))
+
+
 
 dnl # --------------------------------------------------------------------
 dnl # substitute src/Makevars
diff --git a/inst/NEWS.Rd b/inst/NEWS.Rd
index 6f08e633b3cc7acf365879f5cd7a815bfa64fadf..043c9615087a4614204fb3a54940ca80891369c3 100644
--- a/inst/NEWS.Rd
+++ b/inst/NEWS.Rd
@@ -4,7 +4,24 @@
 \title{sybilSBML News}
 \encoding{UTF-8}
 
-\newcommand{\CRANpkg}{\href{http://CRAN.R-project.org/package=#1}{\pkg{#1}}}
+\newcommand{\CRANpkg}{\href{https://cran.r-project.org/package=#1}{\pkg{#1}}}
+
+% ---------------------------------------------------------------------------- %
+\section{Changes in version 3.0.1 2016-12-16}{
+  \itemize{
+    \item sybilSBML now supports writing of SBML files.
+    \item The new FBC additional package for SBML is now fully integrated.
+    \item Urls in NEWS file are now in default style.
+  }
+}
+
+% ---------------------------------------------------------------------------- %
+\section{Changes in version 2.0.11 2015-07-03}{
+  \itemize{
+    \item \code{gprRules}-Slot in \code{modelorg} has changed. Thus 
+    \code{readSBMLmod} had to be updated.
+  }
+}
 
 % ---------------------------------------------------------------------------- %
 \section{Changes in version 2.0.11 2015-07-03}{
diff --git a/inst/doc/sybilSBML.R b/inst/doc/sybilSBML.R
new file mode 100644
index 0000000000000000000000000000000000000000..3b366b5520db2fc39b7fab091b74bf5767cf5bbf
--- /dev/null
+++ b/inst/doc/sybilSBML.R
@@ -0,0 +1,30 @@
+### R code from vignette source 'sybilSBML.Rnw'
+### Encoding: UTF-8
+
+###################################################
+### code chunk number 1: sybilSBML.Rnw:85-87 (eval = FALSE)
+###################################################
+## library(sybilSBML)
+## model <- readSBMLmod("<model>.xml")
+
+
+###################################################
+### code chunk number 2: sybilSBML.Rnw:103-106
+###################################################
+library(sybilSBML)
+mp     <- system.file(package = "sybilSBML", "extdata")
+ec_mod <- file.path(mp, "ecoli_core_model.xml")
+
+
+###################################################
+### code chunk number 3: sybilSBML.Rnw:109-110
+###################################################
+mod <- readSBMLmod(ec_mod, bndCond = FALSE)
+
+
+###################################################
+### code chunk number 4: sybilSBML.Rnw:123-124
+###################################################
+err <- validateSBMLdocument(ec_mod)
+
+
diff --git a/inst/doc/sybilSBML.Rnw b/inst/doc/sybilSBML.Rnw
new file mode 100644
index 0000000000000000000000000000000000000000..5d11fdf9e2ba00c73f9684559b42fd8f93fc0e5e
--- /dev/null
+++ b/inst/doc/sybilSBML.Rnw
@@ -0,0 +1,132 @@
+\documentclass[a4paper,headings=small]{scrartcl}
+\usepackage[english]{babel}
+\usepackage[T1]{fontenc}
+\usepackage[utf8]{inputenc}
+\usepackage{textcomp,lmodern}
+\typearea[current]{last}
+\usepackage{fixltx2e,mparhack,mathdots}
+
+\usepackage{natbib}
+%\usepackage{hyperref}
+
+\usepackage{microtype}
+
+\newcommand{\Comp}[1]{\texttt{#1}}
+% bash command prompt
+\DeclareRobustCommand{\PROMPTL}{\Comp{\$}}
+
+% just a bash command
+\DeclareRobustCommand{\COML}[1]{%
+    \small{\PROMPTL\Comp{ #1}}
+}
+% bash command with quote environment
+\DeclareRobustCommand{\COMML}[1]{%
+    \begin{quote}%
+        \small{\PROMPTL\Comp{ #1}}
+    \end{quote}
+}
+
+\addtolength{\skip\footins}{0.5\baselineskip}
+\usepackage{fnpos}
+
+
+% \hypersetup{
+% 	pdftitle = {sybilSBML -- Quick Start},
+% 	pdfauthor = {Gabriel Gelius-Dietrich},
+% 	pdfsubject = {SBML support for SyBiL},
+% 	pdfkeywords = {SBML},
+%     pdfborder = {0 0 0},
+%     pdfhighlight = {/N}
+% }
+
+
+\newcommand{\pkg}[1]{\emph{#1}}
+\newcommand{\CRANpkg}[1]{\href{http://CRAN.R-project.org/package=#1}{\pkg{#1}}}
+%\newcommand{\pkgname}{\CRANpkg{sybilSBML}}
+\newcommand{\pkgname}{\emph{sybilSBML}}
+\newcommand{\prgname}[1]{\textsc{#1}}
+
+
+\begin{document}
+\title{sybilSBML -- Quick Start}
+%\VignetteIndexEntry{Package sybilSBML -- Quick Start}
+%\VignettePackage{sybilSBML}
+\author{Gabriel Gelius-Dietrich}
+
+\maketitle
+
+
+\section{Introduction}
+
+The package \pkgname{} is an addition to package
+\pkg{sybil}\footnote{\texttt{http://CRAN.R-project.org/package=sybil}}
+providing support for
+metabolic networks written in SBML (Systems Biology Markup Language), in
+particular those developed by Bernhard \O. Palsson's
+lab\footnote{\texttt{http://gcrg.ucsd.edu/}} and those from the BiGG
+database\footnote{\texttt{http://bigg.ucsd.edu/}} \citep{Schellenberger:2010fk}.
+\nocite{Becker:2007uq,Schellenberger:2011fk}
+
+
+\section{Installation}
+
+The package \pkgname{} depends on a working installation of
+LibSBML \citep{Bornstein:2008uq} available from the SBML
+homepage\footnote{\texttt{http://www.sbml.org/}, libSBML version 5.6.0 or higher}
+(in particular libraries and header files).
+See \Comp{INSTALL} for installation instructions and platform specific details.
+
+
+\section{Usage}
+
+The package \pkgname{} provides the command \Comp{readSBMLmod()} which reads
+SBML formated files and returns instances of class \Comp{modelorg}.
+
+<<eval=FALSE>>=
+library(sybilSBML)
+model <- readSBMLmod("<model>.xml")
+@
+
+
+\section{Input files}
+
+The function \Comp{readSBMLmod()} reads metabolic network models written in
+SBML format (Systems Biology Markup Language).  Among the models available in
+this de-facto standard format are in particular those developed by
+Bernhard \O. Palsson's lab.
+
+The file \Comp{ecoli\_core\_model.xml} (in \Comp{extdata/}) contains an
+exemplarily metabolic network written in SBML for the core energy metabolism
+of \emph{E.~coli} \citep{Palsson:2006fk,Orth:2010fk}.
+The exact location of the file can be retrieved with the \Comp{system.file()}
+command:
+<<>>=
+library(sybilSBML)
+mp     <- system.file(package = "sybilSBML", "extdata")
+ec_mod <- file.path(mp, "ecoli_core_model.xml")
+@
+The model can be read in by using the command \Comp{readSBMLmod()}:
+<<print=true>>=
+mod <- readSBMLmod(ec_mod, bndCond = FALSE)
+@
+The metabolite id's of the SBML files are written in the format
+\Comp{M\_<metabolite abbreviation>\_<compartment abbreviation>}. The compartment
+abbreviation is a one letter abbreviation, e.\,g. \Comp{c} for cytosol.  All
+metabolites outside the system boundary belong to compartment \Comp{b}.  Those
+metabolites are transported into or outside the system.  As long as they are
+mentioned, the network is closed.  The function \Comp{readSBMLmod()} will remove
+them in order to produce an open network.
+
+\section{Validation of input files}
+
+SBML files can be validated by using the command \Comp{validateSBMLdocument()}:
+<<>>=
+err <- validateSBMLdocument(ec_mod)
+@
+The variable \Comp{err} is of class \Comp{sbmlError}, storing error messages
+generated by the validation procedure.
+
+\bibliographystyle{abbrvnat}
+\bibliography{sybilSBML}
+
+\end{document}
diff --git a/inst/doc/sybilSBML.pdf b/inst/doc/sybilSBML.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..fd54c3f9672b2e542000cb87bca02a4e8f84429a
Binary files /dev/null and b/inst/doc/sybilSBML.pdf differ
diff --git a/man/getSBMLFbcversion.Rd b/man/getSBMLFbcversion.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..5fadfd5f13a5ae2b2c8cf8c69fb975fde943bb29
--- /dev/null
+++ b/man/getSBMLFbcversion.Rd
@@ -0,0 +1,44 @@
+\name{getSBMLFbcversion}
+\alias{getSBMLFbcversion}
+
+\title{
+  Get SBML Version
+}
+
+\description{
+  Retrieve SBML FBC version of SBML file.
+}
+
+\usage{
+  getSBMLFbcversion(sbmlf)
+}
+
+\arguments{
+  \item{sbmlf}{
+    An object of class \code{\linkS4class{sbmlPtr}} as returned by
+    \code{\link{openSBMLfile}}. This is basically a pointer to a SBML document.
+  }
+}
+
+\value{
+  A single integer value containing the SBML FBC version of the SBML file.
+}
+
+\references{
+  Bornstein, B. J., Keating, S. M., Jouraku, A., and Hucka M. (2008)
+  LibSBML: An API Library for SBML. \emph{Bioinformatics} \bold{24},
+  880--881.
+}
+
+\author{
+  Gabriel Gelius-Dietrich <geliudie@uni-duesseldorf.de>
+
+  Maintainer: Claus Jonathan Fritzemeier <clausjonathan.fritzemeier@uni-duesseldorf.de>
+}
+
+
+\seealso{
+  \code{\link{openSBMLfile}}, \code{\linkS4class{sbmlPtr}}
+}
+
+\keyword{ IO }
\ No newline at end of file
diff --git a/man/getSBMLmodAnnotation.Rd b/man/getSBMLmodAnnotation.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..342af4fec419b91762dd801c1e036353171f8ee2
--- /dev/null
+++ b/man/getSBMLmodAnnotation.Rd
@@ -0,0 +1,44 @@
+\name{getSBMLmodAnnotation}
+\alias{getSBMLmodAnnotation}
+
+\title{
+  Get Model Annotation
+}
+
+\description{
+  Retrieve model annotation of a SBML model
+}
+
+\usage{
+  getSBMLmodAnnotation(sbmlm)
+}
+
+\arguments{
+  \item{sbmlm}{
+    An object of class \code{\linkS4class{sbmlPtr}} as returned by
+    \code{\link{getSBMLmodel}}. This is basically a pointer to a SBML model.
+  }
+}
+
+\value{
+  A single character string containing the model annotation of the SBML model.
+}
+
+\references{
+  Bornstein, B. J., Keating, S. M., Jouraku, A., and Hucka M. (2008)
+  LibSBML: An API Library for SBML. \emph{Bioinformatics} \bold{24},
+  880--881.
+}
+
+\author{
+  Gabriel Gelius-Dietrich <geliudie@uni-duesseldorf.de>
+
+  Maintainer: Claus Jonathan Fritzemeier <clausjonathan.fritzemeier@uni-duesseldorf.de>
+}
+
+
+\seealso{
+  \code{\link{getSBMLmodel}}, \code{\linkS4class{sbmlPtr}}
+}
+
+\keyword{ IO }
\ No newline at end of file
diff --git a/man/getSBMLmodNotes.Rd b/man/getSBMLmodNotes.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..005e8cf649ad9a0fd441d9cbe81eafa53a3bfb98
--- /dev/null
+++ b/man/getSBMLmodNotes.Rd
@@ -0,0 +1,44 @@
+\name{getSBMLmodNotes}
+\alias{getSBMLmodNotes}
+
+\title{
+  Get Model Note
+}
+
+\description{
+  Retrieve model notes of a SBML model
+}
+
+\usage{
+  getSBMLmodNotes(sbmlm)
+}
+
+\arguments{
+  \item{sbmlm}{
+    An object of class \code{\linkS4class{sbmlPtr}} as returned by
+    \code{\link{getSBMLmodel}}. This is basically a pointer to a SBML model.
+  }
+}
+
+\value{
+  A single character string containing the model notes of the SBML model.
+}
+
+\references{
+  Bornstein, B. J., Keating, S. M., Jouraku, A., and Hucka M. (2008)
+  LibSBML: An API Library for SBML. \emph{Bioinformatics} \bold{24},
+  880--881.
+}
+
+\author{
+  Gabriel Gelius-Dietrich <geliudie@uni-duesseldorf.de>
+
+  Maintainer: Claus Jonathan Fritzemeier <clausjonathan.fritzemeier@uni-duesseldorf.de>
+}
+
+
+\seealso{
+  \code{\link{getSBMLmodel}}, \code{\linkS4class{sbmlPtr}}
+}
+
+\keyword{ IO }
\ No newline at end of file
diff --git a/man/writeSBML.Rd b/man/writeSBML.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..6b94b13ab1ee793c32447acbbe8764ac526885a6
--- /dev/null
+++ b/man/writeSBML.Rd
@@ -0,0 +1,118 @@
+\name{writeSBML}
+\alias{writeSBML}
+
+\encoding{utf8}
+
+\title{Exports a Metabolic Network in SBML Format}
+
+\description{
+  The function exports a metabolic network from S4 object of the class \code{\link{modelorg}} in SBML format. The function returns TRUE if the SBML file is successfully built.
+}
+
+\usage{
+  writeSBML(morg=NULL,level=2,version=4,fbcLevel=0,
+             filename="export.xml",
+             recoverExtMet=FALSE,
+             printNotes=TRUE,
+             printAnnos=TRUE,
+             validation=FALSE)
+
+}
+
+\arguments{
+  \item{morg}{
+    An S4 object of the class \code{\link[sybil]{modelorg}}.
+  }
+  \item{level}{
+    A single integer value containing the SBML level for the exporting SBML file. \cr
+    Default: \code{2}.
+  }
+   \item{version}{
+    A single integer value containing the SBML version for the exporting SBML file. \cr
+    Default: \code{4}.
+  }
+  \item{fbcLevel}{
+    A single integer value containing the fbc package version for the exporting SBML file. \cr
+    Default: \code{2}.
+  }
+   \item{filename}{
+    SBML filename for exporting the model.
+    Default: \code{"export.xml"}.
+  }
+  \item{recoverExtMet}{
+    Boolean: recover external metabolites and refer them to compartment \code{"BOUNDARY"}.\cr 
+    Default: \code{FALSE}.
+  }
+  \item{printNotes}{
+    Boolean: print Notes from original SBML file .\cr
+    Default: \code{TRUE}.
+  }
+  \item{printAnnos}{
+    Boolean: print Annotations from original SBML file .\cr
+    Default: \code{TRUE}.
+  }
+  \item{validation}{
+    Boolean: print containing errors for xml file .\cr
+    Default: \code{TRUE}.
+  }
+
+}
+
+\details{
+  The library \code{libSBML} is used to export a \code{\link[sybil]{modelorg}}
+  to a SBML file.
+
+}
+
+\value{
+  A single boolean value for a successful export .
+}
+
+\references{
+  The BiGG database \url{http://bigg.ucsd.edu/}.
+
+  Bornstein, B. J., Keating, S. M., Jouraku, A., and Hucka M. (2008)
+  LibSBML: An API Library for SBML. \emph{Bioinformatics} \bold{24},
+  880--881.
+
+  Schellenberger, J., Park, J. O., Conrad, T. C., and Palsson, B. Ø., (2010)
+  BiGG: a Biochemical Genetic and Genomic knowledgebase of large scale metabolic
+  reconstructions. \emph{BMC Bioinformatics} \bold{11}, 213.
+
+  Becker, S. A., Feist, A. M., Mo, M. L., Hannum, G., Palsson, B. Ø.  and
+  Herrgard, M. J. (2007) Quantitative prediction of cellular metabolism with
+  constraint-based models: the COBRA Toolbox. \emph{Nat Protoc} \bold{2},
+  727--738.
+
+  Schellenberger, J., Que, R., Fleming, R. M. T., Thiele, I., Orth, J. D.,
+  Feist, A. M., Zielinski, D. C., Bordbar, A., Lewis, N. E., Rahmanian, S.,
+  Kang, J., Hyduke, D. R. and Palsson, B. Ø. (2011) Quantitative prediction of
+  cellular metabolism with constraint-based models: the COBRA Toolbox v2.0.
+  \emph{Nat Protoc} \bold{6}, 1290--1307.
+}
+
+\author{
+  Gabriel Gelius-Dietrich <geliudie@uni-duesseldorf.de>
+
+  Maintainer: Claus Jonathan Fritzemeier <clausjonathan.fritzemeier@uni-duesseldorf.de>
+}
+
+
+\note{
+  The function \code{writeSBML} makes use of the library
+  \code{libSBML} (\url{http://www.sbml.org}).
+}
+
+\seealso{
+  \code{\link{readSBMLmod}}
+}
+
+\examples{
+  dir  <- system.file(package = "sybilSBML", "extdata")
+  file <- file.path(dir, "ecoli_core_model.xml")
+  mod  <- readSBMLmod(file, bndCond = FALSE)
+  writeSBML(mod,level=3,version=1,fbcLevel=2)
+}
+
+\keyword{ IO }
+
diff --git a/src/init.c b/src/init.c
index 59a802a9e413e5c3ea02eab24e95b474ba715580..7e4b174aafb9654417111f7c416117caf8ca2610 100644
--- a/src/init.c
+++ b/src/init.c
@@ -1,66 +1,68 @@
-/* init.c
-   Link to libSBML for sybil.
- 
-   Copyright (C) 2010-2013 Gabriel Gelius-Dietrich, Dpt. for Bioinformatics,
-   Institute for Informatics, Heinrich-Heine-University, Duesseldorf, Germany.
-   All right reserved.
-   Email: geliudie@uni-duesseldorf.de
- 
-   This file is part of sybilSBML.
- 
-   SybilSBML is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
- 
-   SybilSBML is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
- 
-   You should have received a copy of the GNU General Public License
-   along with sybilSBML.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <R.h>
-#include <Rinternals.h>
-
-#include "sybilSBML.h"
-
-#include <R_ext/Rdynload.h>
-
-static const R_CallMethodDef callMethods[] = {
-    {"isSBMLdocptr",               (DL_FUNC) &isSBMLdocptr,               1},
-    {"isSBMLmodptr",               (DL_FUNC) &isSBMLmodptr,               1},
-    {"isNULLptr",                  (DL_FUNC) &isNULLptr,                  1},
-    {"getLibSBMLversion",          (DL_FUNC) &getLibSBMLversion,          0},
-    {"initSBML",                   (DL_FUNC) &initSBML,                   0},
-    {"delDocument",                (DL_FUNC) &delDocument,                1},
-    {"delModel",                   (DL_FUNC) &delModel,                   1},
-    {"readSBMLfile",               (DL_FUNC) &readSBMLfile,               2},
-    {"getSBMLlevel",               (DL_FUNC) &getSBMLlevel,               1},
-    {"getSBMLversion",             (DL_FUNC) &getSBMLversion,             1},
-    {"validateDocument",           (DL_FUNC) &validateDocument,           1},
-    {"getSBMLerrors",              (DL_FUNC) &getSBMLerrors,              1},
-    {"getSBMLmodel",               (DL_FUNC) &getSBMLmodel,               2},
-    {"getSBMLmodId",               (DL_FUNC) &getSBMLmodId,               1},
-    {"getSBMLmodName",             (DL_FUNC) &getSBMLmodName,             1},
-    {"getSBMLnumCompart",          (DL_FUNC) &getSBMLnumCompart,          1},
-    {"getSBMLnumSpecies",          (DL_FUNC) &getSBMLnumSpecies,          1},
-    {"getSBMLnumReactions",        (DL_FUNC) &getSBMLnumReactions,        1},
-    {"getSBMLunitDefinitionsList", (DL_FUNC) &getSBMLunitDefinitionsList, 1},
-    {"getSBMLCompartList",         (DL_FUNC) &getSBMLCompartList,         1},
-    {"getSBMLSpeciesList",         (DL_FUNC) &getSBMLSpeciesList,         1},
-    {"getSBMLReactionsList",       (DL_FUNC) &getSBMLReactionsList,       1},
-    {NULL, NULL, 0}
-};
-
-
-/* -------------------------------------------------------------------------- */
-
-void R_init_sybilSBML(DllInfo *info) {
-    R_registerRoutines(info, NULL, callMethods, NULL, NULL);
-    R_useDynamicSymbols(info, FALSE);
-}
-
-
+/* init.c
+   Link to libSBML for sybil.
+ 
+   Copyright (C) 2010-2013 Gabriel Gelius-Dietrich, Dpt. for Bioinformatics,
+   Institute for Informatics, Heinrich-Heine-University, Duesseldorf, Germany.
+   All right reserved.
+   Email: geliudie@uni-duesseldorf.de
+ 
+   This file is part of sybilSBML.
+ 
+   SybilSBML is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+ 
+   SybilSBML is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+ 
+   You should have received a copy of the GNU General Public License
+   along with sybilSBML.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <R.h>
+#include <Rinternals.h>
+
+#include "sybilSBML.h"
+
+#include <R_ext/Rdynload.h>
+
+static const R_CallMethodDef callMethods[] = {
+    {"isSBMLdocptr",               (DL_FUNC) &isSBMLdocptr,               1},
+    {"isSBMLmodptr",               (DL_FUNC) &isSBMLmodptr,               1},
+    {"isNULLptr",                  (DL_FUNC) &isNULLptr,                  1},
+    {"getLibSBMLversion",          (DL_FUNC) &getLibSBMLversion,          0},
+    {"initSBML",                   (DL_FUNC) &initSBML,                   0},
+    {"delDocument",                (DL_FUNC) &delDocument,                1},
+    {"delModel",                   (DL_FUNC) &delModel,                   1},
+    {"readSBMLfile",               (DL_FUNC) &readSBMLfile,               2},
+    {"getSBMLlevel",               (DL_FUNC) &getSBMLlevel,               1},
+    {"getSBMLversion",             (DL_FUNC) &getSBMLversion,             1},
+    {"validateDocument",           (DL_FUNC) &validateDocument,           1},
+    {"getSBMLerrors",              (DL_FUNC) &getSBMLerrors,              1},
+    {"getSBMLmodel",               (DL_FUNC) &getSBMLmodel,               2},
+    {"getSBMLmodId",               (DL_FUNC) &getSBMLmodId,               1},
+    {"getSBMLmodName",             (DL_FUNC) &getSBMLmodName,             1},
+    {"getSBMLmodNotes",            (DL_FUNC) &getSBMLmodNotes,            1},
+    {"getSBMLmodAnnotation",       (DL_FUNC) &getSBMLmodAnnotation,       1},
+    {"getSBMLnumCompart",          (DL_FUNC) &getSBMLnumCompart,          1},
+    {"getSBMLnumSpecies",          (DL_FUNC) &getSBMLnumSpecies,          1},
+    {"getSBMLnumReactions",        (DL_FUNC) &getSBMLnumReactions,        1},
+    {"getSBMLunitDefinitionsList", (DL_FUNC) &getSBMLunitDefinitionsList, 1},
+    {"getSBMLCompartList",         (DL_FUNC) &getSBMLCompartList,         1},
+    {"getSBMLSpeciesList",         (DL_FUNC) &getSBMLSpeciesList,         1},
+    {"getSBMLReactionsList",       (DL_FUNC) &getSBMLReactionsList,       1},
+    {"exportSBML",                 (DL_FUNC) &exportSBML,                 33},
+    {"getSBMLFbcversion",          (DL_FUNC) &getSBMLFbcversion,          1},
+    {NULL, NULL, 0}
+};
+
+
+/* -------------------------------------------------------------------------- */
+
+void R_init_sybilSBML(DllInfo *info) {
+    R_registerRoutines(info, NULL, callMethods, NULL, NULL);
+    R_useDynamicSymbols(info, FALSE);
+}
\ No newline at end of file
diff --git a/src/sybilSBML.c b/src/sybilSBML.c
index 2c89694af10869e8047f21fd5620d9e43c0c2be2..0eee3b09a9bb8259d8c3b962876ff95f36bf043c 100644
--- a/src/sybilSBML.c
+++ b/src/sybilSBML.c
@@ -1,1047 +1,2290 @@
-/* sybilSBML.c
-   Link to libSBML for sybil.
- 
-   Copyright (C) 2010-2013 Gabriel Gelius-Dietrich, Dpt. for Bioinformatics,
-   Institute for Informatics, Heinrich-Heine-University, Duesseldorf, Germany.
-   All right reserved.
-   Email: geliudie@uni-duesseldorf.de
- 
-   This file is part of sybilSBML.
- 
-   SybilSBML is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
- 
-   SybilSBML is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
- 
-   You should have received a copy of the GNU General Public License
-   along with sybilSBML.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-
-#include "sybilSBML.h"
-
-
-static SEXP tagSBMLmodel;
-static SEXP tagSBMLdocument;
-
-
-/* -------------------------------------------------------------------------- */
-/* Finalizer                                                                  */
-/* -------------------------------------------------------------------------- */
-
-/* -------------------------------------------------------------------------- */
-/* finalizer for sbml document objects */
-static void sbmlDocumentFinalizer (SEXP sbmldoc) {
-    if (!R_ExternalPtrAddr(sbmldoc)) {
-        return;
-    }
-    else {
-        delDocument(sbmldoc);
-    }
-}
-
-
-/* -------------------------------------------------------------------------- */
-/* finalizer for sbml model objects */
-/*
-static void sbmlModelFinalizer (SEXP sbmlmodel) {
-    if (!R_ExternalPtrAddr(sbmlmodel)) {
-        return;
-    }
-    else {
-        delModel(sbmlmodel);
-    }
-}
-*/
-
-
-/* -------------------------------------------------------------------------- */
-/* help functions                                                             */
-/* -------------------------------------------------------------------------- */
-
-/* check for pointer to sbml document */
-SEXP isSBMLdocptr(SEXP ptr) {
-
-    SEXP out = R_NilValue;
-
-    if ( (TYPEOF(ptr) == EXTPTRSXP) &&
-         (R_ExternalPtrTag(ptr) == tagSBMLdocument) ) {
-        out = Rf_ScalarLogical(1);
-    }
-    else {
-        out = Rf_ScalarLogical(0);
-    }
-
-    return out;
-}
-
-/* check for pointer to sbml model */
-SEXP isSBMLmodptr(SEXP ptr) {
-
-    SEXP out = R_NilValue;
-
-    if ( (TYPEOF(ptr) == EXTPTRSXP) &&
-         (R_ExternalPtrTag(ptr) == tagSBMLmodel) ) {
-        out = Rf_ScalarLogical(1);
-    }
-    else {
-        out = Rf_ScalarLogical(0);
-    }
-
-    return out;
-}
-
-/* check for NULL pointer */
-SEXP isNULLptr(SEXP ptr) {
-
-    SEXP out = R_NilValue;
-
-    if ( (TYPEOF(ptr) == EXTPTRSXP) &&
-         (R_ExternalPtrAddr(ptr) == NULL) ) {
-        out = Rf_ScalarLogical(1);
-    }
-    else {
-        out = Rf_ScalarLogical(0);
-    }
-
-    return out;
-}
-
-
-/* -------------------------------------------------------------------------- */
-/* API-Functions                                                              */
-/* -------------------------------------------------------------------------- */
-
-/* -------------------------------------------------------------------------- */
-/* initialize sybilSBML */
-SEXP initSBML(void) {
-    tagSBMLmodel    = Rf_install("TYPE_SBML_MODEL");
-    tagSBMLdocument = Rf_install("TYPE_SBML_DOCUMENT");
-    return R_NilValue;
-}
-
-
-/* -------------------------------------------------------------------------- */
-/* get libsbml version number (dotted version) */
-SEXP getLibSBMLversion() {
-
-    SEXP out = R_NilValue;
-
-    const char *vstr = getLibSBMLDottedVersion();
-
-    out = Rf_mkString(vstr);
-
-    return out;
-
-}
-
-
-/* -------------------------------------------------------------------------- */
-/* remove sbml document pointer */
-SEXP delDocument(SEXP sbmldoc) {
-
-    SEXP out = R_NilValue;
-    SBMLDocument_t *del = NULL;
-
-    checkDocument(sbmldoc);
-
-    del = R_ExternalPtrAddr(sbmldoc);
-
-    SBMLDocument_free(del);
-    R_ClearExternalPtr(sbmldoc);
-
-    return out;
-}
-
-
-/* -------------------------------------------------------------------------- */
-/* remove model pointer */
-SEXP delModel(SEXP sbmlmodel) {
-
-    SEXP out = R_NilValue;
-    /* Model_t *del = NULL; */
-
-    checkModel(sbmlmodel);
-
-    /* del = R_ExternalPtrAddr(sbmlmodel); */
-
-    /* Model_free(del); */
-    R_ClearExternalPtr(sbmlmodel);
-
-    return out;
-}
-
-
-/* -------------------------------------------------------------------------- */
-/* read SBML file */
-SEXP readSBMLfile(SEXP fname, SEXP ptrtype) {
-
-    SEXP sfext = R_NilValue;
-    SEXP ptr, class, file;
-    const char *rfname = CHAR(STRING_ELT(fname, 0));
-    
-    SBMLDocument_t *sbmldoc;
-
-    /* create sbml document pointer */
-    PROTECT(ptr = Rf_allocVector(STRSXP, 1));
-    SET_STRING_ELT(ptr, 0, STRING_ELT(ptrtype, 0));
-
-    PROTECT(class = Rf_allocVector(STRSXP, 1));
-    SET_STRING_ELT(class, 0, Rf_mkChar("sbml_doc_ptr"));
-
-    PROTECT(file = Rf_allocVector(STRSXP, 1));
-    SET_STRING_ELT(file, 0, Rf_mkChar("file_name"));
-
-    /* read the model xml file */
-    sbmldoc = readSBML(rfname);
-    
-    sfext = R_MakeExternalPtr(sbmldoc, tagSBMLdocument, R_NilValue);
-    PROTECT(sfext);
-    R_RegisterCFinalizerEx(sfext, sbmlDocumentFinalizer, TRUE);
-    Rf_setAttrib(ptr, class, sfext);
-    Rf_setAttrib(ptr, file, fname);
-    Rf_classgets(ptr, class);
-
-    UNPROTECT(4);
-
-    return ptr;
-}
-
-
-/* -------------------------------------------------------------------------- */
-/* get sbml document level */
-SEXP getSBMLlevel(SEXP sbmldoc) {
-
-    SEXP out = R_NilValue;
-    unsigned int level;
-    
-    checkDocument(sbmldoc);
-
-    level = SBMLDocument_getLevel(R_ExternalPtrAddr(sbmldoc));
-
-    out = Rf_ScalarInteger(level);
-
-    return out;
-}
-
-
-/* -------------------------------------------------------------------------- */
-/* get sbml document version */
-SEXP getSBMLversion(SEXP sbmldoc) {
-
-    SEXP out = R_NilValue;
-    unsigned int version;
-    
-    checkDocument(sbmldoc);
-
-    version = SBMLDocument_getVersion(R_ExternalPtrAddr(sbmldoc));
-
-    out = Rf_ScalarInteger(version);
-
-    return out;
-}
-
-
-/* -------------------------------------------------------------------------- */
-/* validate SBML document */
-SEXP validateDocument(SEXP sbmldoc) {
-
-    /*
-        this is adopted from Michael Lawrence: rsbml
-        Michael Lawrence (). rsbml: R support for SBML, using libsbml.
-        R package version 2.18.0. http://www.sbml.org
-        http://www.bioconductor.org/packages/release/bioc/html/rsbml.html
-    */
-    
-    SEXP out   = R_NilValue;
-
-    unsigned int validation;
-    
-    checkDocument(sbmldoc);
-
-    /* number or errors logged when reading SBML file */
-    validation  = SBMLDocument_getNumErrors(R_ExternalPtrAddr(sbmldoc));
-    /* number or errors from structural and mathematical tests */
-    validation += SBMLDocument_checkConsistency(R_ExternalPtrAddr(sbmldoc));
-
-    if (validation > 0) {
-        out = Rf_ScalarLogical(0);
-    }
-    else {
-        out = Rf_ScalarLogical(1);
-    }
-
-    return out;
-}
-
-
-/* -------------------------------------------------------------------------- */
-/* get SBML errors */
-SEXP getSBMLerrors(SEXP sbmldoc) {
-
-    /*
-        this is adopted from Michael Lawrence: rsbml
-        Michael Lawrence (). rsbml: R support for SBML, using libsbml.
-        R package version 2.18.0. http://www.sbml.org
-        http://www.bioconductor.org/packages/release/bioc/html/rsbml.html
-    */
-    
-    SEXP out   = R_NilValue;
-    SEXP listv = R_NilValue;
-    SEXP info  = R_NilValue;
-    SEXP warn  = R_NilValue;
-    SEXP error = R_NilValue;
-    SEXP fatal = R_NilValue;
-    SEXP class = R_NilValue;
-    SEXP el    = R_NilValue;
-
-    XMLError_t *sbml_err;
-
-    unsigned int nprob, i, ind;
-    int ninfo = 0, nwarn = 0, nerror = 0, nfatal = 0, nunknown = 0;
-    
-    checkDocument(sbmldoc);
-
-    nprob = SBMLDocument_getNumErrors(R_ExternalPtrAddr(sbmldoc));
-
-    /*
-    Rprintf("Model Errors: %i\n", nprob);
-    */
-
-    if (nprob > 0) {
-
-        /* check how many infos, warnings, errors and fatals we have */
-        for (i = 0; i < nprob; i++) {
-            sbml_err = (XMLError_t *) SBMLDocument_getError(R_ExternalPtrAddr(sbmldoc), i);
-            if (XMLError_isInfo(sbml_err)) {
-                ninfo++;
-            }
-            else if (XMLError_isWarning(sbml_err)) {
-                nwarn++;
-            }
-            else if (XMLError_isError(sbml_err)) {
-                nerror++;
-            }
-            else if (XMLError_isFatal(sbml_err)) {
-                nfatal++;
-            }
-            else {
-                nunknown++;
-            }
-        }
-
-        /*
-        Rprintf("number of infos: %i, warnings: %i, errors: %i, falals: %i, unknowns: %i\n",
-                ninfo, nwarn, nerror, nfatal, nunknown);
-        */
-
-        /*
-            out will be a list of four elements:
-              infos
-              warnings
-              errors
-              fatals
-            each of them is a list of three elements:
-              id
-              line
-              column
-              msg
-        */
-    
-        PROTECT(out =   Rf_allocVector(VECSXP, 4));
-
-        /* allocate space for each error list */
-        PROTECT(info  = Rf_allocVector(VECSXP, ninfo));
-        PROTECT(warn  = Rf_allocVector(VECSXP, nwarn));
-        PROTECT(error = Rf_allocVector(VECSXP, nerror));
-        PROTECT(fatal = Rf_allocVector(VECSXP, nfatal));
-
-        SET_VECTOR_ELT(out, 0, info);
-        SET_VECTOR_ELT(out, 1, warn);
-        SET_VECTOR_ELT(out, 2, error);
-        SET_VECTOR_ELT(out, 3, fatal);
-
-        PROTECT(listv = Rf_allocVector(STRSXP, 4));
-        SET_STRING_ELT(listv, 0, Rf_mkChar("infos"));
-        SET_STRING_ELT(listv, 1, Rf_mkChar("warnings"));
-        SET_STRING_ELT(listv, 2, Rf_mkChar("errors"));
-        SET_STRING_ELT(listv, 3, Rf_mkChar("fatals"));
-        Rf_setAttrib(out, R_NamesSymbol, listv);
-
-        /* get the error messages */
-        ninfo = 0, nwarn = 0, nerror = 0, nfatal = 0, nunknown = 0;
-        for (i = 0; i < nprob; i++) {
-            sbml_err = (XMLError_t *) SBMLDocument_getError(R_ExternalPtrAddr(sbmldoc), i);
-            el = R_NilValue;
-            ind = 0;
-            if (XMLError_isInfo(sbml_err)) {
-                ind = ninfo++;
-                el  = info;
-            }
-            else if (XMLError_isWarning(sbml_err)) {
-                ind = nwarn++;
-                el  = warn;
-            }
-            else if (XMLError_isError(sbml_err)) {
-                ind = nerror++;
-                el  = error;
-            }
-            else if (XMLError_isFatal(sbml_err)) {
-                ind = nfatal++;
-                el  = fatal;
-            }
-            else {
-                nunknown++;
-            }
-            SET_VECTOR_ELT(el, ind, generateProblemMsg(sbml_err));
-        }
-
-        /* make the list to be an instance of 'sbml_error' */
-        PROTECT(class = Rf_allocVector(STRSXP, 1));
-        SET_STRING_ELT(class, 0, Rf_mkChar("sbml_error"));
-        Rf_classgets(out, class);
-
-        UNPROTECT(7);
-
-    } /* end if nprob > 0 */
-    else {
-        out = Rf_ScalarLogical(1);
-    }
-
-    return out;
-}
-
-
-/* -------------------------------------------------------------------------- */
-/* get sbml model from sbml document */
-SEXP getSBMLmodel(SEXP sbmldoc, SEXP ptrtype) {
-
-    SEXP smext = R_NilValue;
-    SEXP ptr, class;
-    
-    Model_t *sbmlmodel;
-
-    checkDocument(sbmldoc);
-
-    /* create model pointer */
-    PROTECT(ptr = Rf_allocVector(STRSXP, 1));
-    SET_STRING_ELT(ptr, 0, STRING_ELT(ptrtype, 0));
-
-    PROTECT(class = Rf_allocVector(STRSXP, 1));
-    SET_STRING_ELT(class, 0, Rf_mkChar("sbml_model_ptr"));
-
-    /* get sbml model */
-    sbmlmodel = SBMLDocument_getModel(R_ExternalPtrAddr(sbmldoc));
-
-    smext = R_MakeExternalPtr(sbmlmodel, tagSBMLmodel, R_NilValue);
-    PROTECT(smext);
-    /* R_RegisterCFinalizerEx(smext, sbmlModelFinalizer, TRUE); */
-    Rf_setAttrib(ptr, class, smext);
-    Rf_classgets(ptr, class);
-
-    UNPROTECT(3);
-
-    return ptr;
-}
-
-
-/* -------------------------------------------------------------------------- */
-/* get model id */
-SEXP getSBMLmodId(SEXP sbmlmod) {
-
-    SEXP out = R_NilValue;
-    const char *mid;
-    
-    checkModel(sbmlmod);
-    
-    if (Model_isSetId(R_ExternalPtrAddr(sbmlmod))) {
-        mid = Model_getId(R_ExternalPtrAddr(sbmlmod));
-    }
-    else {
-        mid = "no_id";
-    }
-
-    out = Rf_mkString(mid);
-
-    return out;
-}
-
-
-/* -------------------------------------------------------------------------- */
-/* get model name */
-SEXP getSBMLmodName(SEXP sbmlmod) {
-
-    SEXP out = R_NilValue;
-    const char *mnm;
-    
-    checkModel(sbmlmod);
-
-    if (Model_isSetName(R_ExternalPtrAddr(sbmlmod))) {
-        mnm = Model_getName(R_ExternalPtrAddr(sbmlmod));
-    }
-    else {
-        mnm = "";
-    }
-
-    out = Rf_mkString(mnm);
-
-    return out;
-}
-
-
-/* -------------------------------------------------------------------------- */
-/* get number of compartments */
-SEXP getSBMLnumCompart(SEXP sbmlmod) {
-
-    SEXP out = R_NilValue;
-    unsigned int nc;
-    
-    checkModel(sbmlmod);
-
-    nc = Model_getNumCompartments(R_ExternalPtrAddr(sbmlmod));
-
-    out = Rf_ScalarInteger(nc);
-
-    return out;
-}
-
-
-/* -------------------------------------------------------------------------- */
-/* get number of species (metabolites) */
-SEXP getSBMLnumSpecies(SEXP sbmlmod) {
-
-    SEXP out = R_NilValue;
-    unsigned int nsp;
-    
-    checkModel(sbmlmod);
-
-    nsp = Model_getNumSpecies(R_ExternalPtrAddr(sbmlmod));
-
-    out = Rf_ScalarInteger(nsp);
-
-    return out;
-}
-
-
-/* -------------------------------------------------------------------------- */
-/* get number of reactions */
-SEXP getSBMLnumReactions(SEXP sbmlmod) {
-
-    SEXP out = R_NilValue;
-    unsigned int nr;
-    
-    checkModel(sbmlmod);
-
-    nr = Model_getNumReactions(R_ExternalPtrAddr(sbmlmod));
-
-    out = Rf_ScalarInteger(nr);
-
-    return out;
-}
-
-
-/* -------------------------------------------------------------------------- */
-/* get list of unit definitions */
-SEXP getSBMLunitDefinitionsList(SEXP sbmlmod) {
-
-    SEXP out       = R_NilValue;
-    SEXP class     = R_NilValue;
-    SEXP unl       = R_NilValue;
-    SEXP listv     = R_NilValue;
-    SEXP listn     = R_NilValue;
-
-    SEXP unitdefid = R_NilValue;
-    SEXP unitdef   = R_NilValue;
-
-    SEXP unitkind  = R_NilValue;
-    SEXP unitscale = R_NilValue;
-    SEXP unitexp   = R_NilValue;
-    SEXP unitmult  = R_NilValue;
-
-    unsigned int nud, nu, i, j;
-
-    /* ListOf_t *udl; */
-    UnitDefinition_t *udlel;
-    Unit_t *uel;
-
-    checkModel(sbmlmod);
-
-    /* udl = Model_getListOfUnitDefinitions(R_ExternalPtrAddr(sbmlmod)); */
-    nud = Model_getNumUnitDefinitions(R_ExternalPtrAddr(sbmlmod));
-    
-    if (nud > 0) {
-        PROTECT(unitdefid = Rf_allocVector(STRSXP, nud));
-        PROTECT(unitdef   = Rf_allocVector(VECSXP, nud));
-        for (i = 0; i < nud; i++) {
-            /* udlel = (UnitDefinition_t *) ListOf_get(udl, i); */
-            udlel = Model_getUnitDefinition(R_ExternalPtrAddr(sbmlmod), i);
-
-            /* id and unit */
-            if (UnitDefinition_isSetId(udlel)) {
-                SET_STRING_ELT(unitdefid, i, Rf_mkChar(UnitDefinition_getId(udlel)));
-
-                nu = UnitDefinition_getNumUnits(udlel);
-        
-                PROTECT(unitkind  = Rf_allocVector(STRSXP, nu));
-                PROTECT(unitscale = Rf_allocVector(INTSXP, nu));
-                PROTECT(unitexp   = Rf_allocVector(INTSXP, nu));
-                PROTECT(unitmult  = Rf_allocVector(REALSXP, nu));
-            
-                for (j = 0; j < nu; j++) {
-                    uel = UnitDefinition_getUnit(udlel, j);
-
-                    /* kind */
-                    if (Unit_isSetKind(uel)) {
-                        SET_STRING_ELT(unitkind, j, Rf_mkChar(UnitKind_toString(Unit_getKind(uel))));
-                    }
-                    else {
-                        SET_STRING_ELT(unitkind, j, Rf_mkChar("no_kind"));
-                    }
-            
-                    /* scale */
-                    if (Unit_isSetScale(uel)) {
-                        INTEGER(unitscale)[j] = Unit_getScale(uel);
-                    }
-                    else {
-                        INTEGER(unitscale)[j] = 0;
-                    }
-
-                    /* exponent */
-                    if (Unit_isSetExponent(uel)) {
-                        INTEGER(unitexp)[j] = Unit_getExponent(uel);
-                    }
-                    else {
-                        INTEGER(unitexp)[j] = 1;
-                    }
-
-                    /* multiplier */
-                    if (Unit_isSetMultiplier(uel)) {
-                        REAL(unitmult)[j] = Unit_getMultiplier(uel);
-                    }
-                    else {
-                        REAL(unitmult)[j] = 1;
-                    }
-
-                }
-
-                PROTECT(unl = Rf_allocVector(VECSXP, 4));
-                SET_VECTOR_ELT(unl, 0, unitkind);
-                SET_VECTOR_ELT(unl, 1, unitscale);
-                SET_VECTOR_ELT(unl, 2, unitexp);
-                SET_VECTOR_ELT(unl, 3, unitmult);
-
-                PROTECT(listn = Rf_allocVector(STRSXP, 4));
-                SET_STRING_ELT(listn, 0, Rf_mkChar("kind"));
-                SET_STRING_ELT(listn, 1, Rf_mkChar("scale"));
-                SET_STRING_ELT(listn, 2, Rf_mkChar("exponent"));
-                SET_STRING_ELT(listn, 3, Rf_mkChar("multiplier"));
-                Rf_setAttrib(unl, R_NamesSymbol, listn);
-            
-                SET_VECTOR_ELT(unitdef, i, unl);
-
-                UNPROTECT(6);
-            
-            }
-            else {
-                SET_STRING_ELT(unitdefid, i, Rf_mkChar("no_id"));
-            }
-        }
-    
-        PROTECT(out = Rf_allocVector(VECSXP, 2));
-        SET_VECTOR_ELT(out, 0, unitdefid);
-        SET_VECTOR_ELT(out, 1, unitdef);
-
-        PROTECT(listv = Rf_allocVector(STRSXP, 2));
-        SET_STRING_ELT(listv, 0, Rf_mkChar("definition_id"));
-        SET_STRING_ELT(listv, 1, Rf_mkChar("definition"));
-
-        Rf_setAttrib(out, R_NamesSymbol, listv);
-
-        /* make the list to be an instance of 'unit_definition' */
-        PROTECT(class = Rf_allocVector(STRSXP, 1));
-        SET_STRING_ELT(class, 0, Rf_mkChar("unit_definition"));
-        Rf_classgets(out, class);
-
-        UNPROTECT(5);
-    }
-    else {
-        out = R_NilValue;
-    }
-
-    return out;
-}
-
-
-/* -------------------------------------------------------------------------- */
-/* get list of compartments */
-SEXP getSBMLCompartList(SEXP sbmlmod) {
-
-    SEXP out      = R_NilValue;
-    SEXP class    = R_NilValue;
-    SEXP listv    = R_NilValue;
-    SEXP compid   = R_NilValue;
-    SEXP compname = R_NilValue;
-    SEXP compout  = R_NilValue;
-
-    unsigned int nc, i;
-
-    /* ListOf_t *cl; */
-    Compartment_t *clel;
-
-    checkModel(sbmlmod);
-
-    /* cl = Model_getListOfCompartments(R_ExternalPtrAddr(sbmlmod)); */
-    nc = Model_getNumCompartments(R_ExternalPtrAddr(sbmlmod));
-    
-    if (nc > 0) {
-        PROTECT(compid   = Rf_allocVector(STRSXP, nc));
-        PROTECT(compname = Rf_allocVector(STRSXP, nc));
-        PROTECT(compout  = Rf_allocVector(STRSXP, nc));
-
-        for (i = 0; i < nc; i++) {
-            /* clel = (Compartment_t *) ListOf_get(cl, i); */
-            clel = Model_getCompartment(R_ExternalPtrAddr(sbmlmod), i);
-            /* id */
-            if (Compartment_isSetId(clel)) {
-                SET_STRING_ELT(compid, i, Rf_mkChar(Compartment_getId(clel)));
-            }
-            else {
-                SET_STRING_ELT(compid, i, Rf_mkChar("no_id"));
-            }
-            /* name */
-            if (Compartment_isSetName(clel)) {
-                SET_STRING_ELT(compname, i, Rf_mkChar(Compartment_getName(clel)));
-            }
-            else {
-                SET_STRING_ELT(compname, i, Rf_mkChar(""));
-            }
-            /* outside */
-            if (Compartment_isSetOutside(clel)) {
-                SET_STRING_ELT(compout, i, Rf_mkChar(Compartment_getOutside(clel)));
-            }
-            else {
-                SET_STRING_ELT(compout, i, Rf_mkChar(""));
-            }
-        }
-    
-        PROTECT(out = Rf_allocVector(VECSXP, 3));
-        SET_VECTOR_ELT(out, 0, compid);
-        SET_VECTOR_ELT(out, 1, compname);
-        SET_VECTOR_ELT(out, 2, compout);
-
-        PROTECT(listv = Rf_allocVector(STRSXP, 3));
-        SET_STRING_ELT(listv, 0, Rf_mkChar("id"));
-        SET_STRING_ELT(listv, 1, Rf_mkChar("name"));
-        SET_STRING_ELT(listv, 2, Rf_mkChar("outside"));
-
-        Rf_setAttrib(out, R_NamesSymbol, listv);
-
-        /* make the list to be an instance of 'compartments_list' */
-        PROTECT(class = Rf_allocVector(STRSXP, 1));
-        SET_STRING_ELT(class, 0, Rf_mkChar("compartments_list"));
-        Rf_classgets(out, class);
-
-        UNPROTECT(6);
-    }
-    else {
-        out = R_NilValue;
-    }
-
-    return out;
-}
-
-
-/* -------------------------------------------------------------------------- */
-/* get list of species (metabolites) */
-SEXP getSBMLSpeciesList(SEXP sbmlmod) {
-
-    SEXP out       = R_NilValue;
-    SEXP class     = R_NilValue;
-    SEXP listv     = R_NilValue;
-    SEXP metid     = R_NilValue;
-    SEXP metname   = R_NilValue;
-    SEXP metcomp   = R_NilValue;
-    SEXP metcharge = R_NilValue;
-    SEXP metbndcnd = R_NilValue;
-
-    unsigned int nsp, i;
-
-    /* ListOf_t *spl; */
-    Species_t *splel;
-
-    checkModel(sbmlmod);
-
-    /* spl = Model_getListOfSpecies(R_ExternalPtrAddr(sbmlmod)); */
-    nsp = Model_getNumSpecies(R_ExternalPtrAddr(sbmlmod));
-    
-    if (nsp > 0) {
-        PROTECT(metid     = Rf_allocVector(STRSXP, nsp));
-        PROTECT(metname   = Rf_allocVector(STRSXP, nsp));
-        PROTECT(metcomp   = Rf_allocVector(STRSXP, nsp));
-        PROTECT(metcharge = Rf_allocVector(INTSXP, nsp));
-        PROTECT(metbndcnd = Rf_allocVector(LGLSXP, nsp));
-
-        for (i = 0; i < nsp; i++) {
-            /* splel = (Species_t *) ListOf_get(spl, i); */
-            splel = Model_getSpecies(R_ExternalPtrAddr(sbmlmod), i);
-            /* id */
-            if (Species_isSetId(splel)) {
-                SET_STRING_ELT(metid, i, Rf_mkChar(Species_getId(splel)));
-            }
-            else {
-                SET_STRING_ELT(metid, i, Rf_mkChar("no_id"));
-            }
-            /* name */
-            if (Species_isSetName(splel)) {
-                SET_STRING_ELT(metname, i, Rf_mkChar(Species_getName(splel)));
-            }
-            else {
-                SET_STRING_ELT(metname, i, Rf_mkChar(""));
-            }
-            /* compartment */
-            if (Species_isSetCompartment(splel)) {
-                SET_STRING_ELT(metcomp, i, Rf_mkChar(Species_getCompartment(splel)));
-            }
-            else {
-                SET_STRING_ELT(metcomp, i, Rf_mkChar(""));
-            }
-            /* charge */
-            if (Species_isSetCharge(splel)) {
-                INTEGER(metcharge)[i] = Species_getCharge(splel);
-            }
-            else {
-                INTEGER(metcharge)[i] = 0;
-            }
-            /* boundary condition */
-            if (Species_isSetBoundaryCondition(splel)) {
-                LOGICAL(metbndcnd)[i] = Species_getBoundaryCondition(splel);
-            }
-            else {
-                LOGICAL(metbndcnd)[i] = 0;
-            }
-        }
-    
-        PROTECT(out = Rf_allocVector(VECSXP, 5));
-        SET_VECTOR_ELT(out, 0, metid);
-        SET_VECTOR_ELT(out, 1, metname);
-        SET_VECTOR_ELT(out, 2, metcomp);
-        SET_VECTOR_ELT(out, 3, metcharge);
-        SET_VECTOR_ELT(out, 4, metbndcnd);
-
-        PROTECT(listv = Rf_allocVector(STRSXP, 5));
-        SET_STRING_ELT(listv, 0, Rf_mkChar("id"));
-        SET_STRING_ELT(listv, 1, Rf_mkChar("name"));
-        SET_STRING_ELT(listv, 2, Rf_mkChar("compartment"));
-        SET_STRING_ELT(listv, 3, Rf_mkChar("charge"));
-        SET_STRING_ELT(listv, 4, Rf_mkChar("boundaryCondition"));
-
-        Rf_setAttrib(out, R_NamesSymbol, listv);
-
-        /* make the list to be an instance of 'species_list' */
-        PROTECT(class = Rf_allocVector(STRSXP, 1));
-        SET_STRING_ELT(class, 0, Rf_mkChar("species_list"));
-        Rf_classgets(out, class);
-
-        UNPROTECT(8);
-    }
-    else {
-        out = R_NilValue;
-    }
-    
-    return out;
-}
-
-
-/* -------------------------------------------------------------------------- */
-/* get list of reactions */
-SEXP getSBMLReactionsList(SEXP sbmlmod) {
-
-    SEXP out         = R_NilValue;
-    SEXP class       = R_NilValue;
-    SEXP listv       = R_NilValue;
-    SEXP reactid     = R_NilValue;
-    SEXP reactname   = R_NilValue;
-    SEXP reactrev    = R_NilValue;
-    SEXP reactnotes  = R_NilValue;
-    SEXP reactannot  = R_NilValue;
-    SEXP reactreact  = R_NilValue;
-    SEXP reactprod   = R_NilValue;
-    SEXP reactkl     = R_NilValue;
-
-    SEXP parml       = R_NilValue;
-    SEXP parmn       = R_NilValue;
-    SEXP parmid      = R_NilValue;
-    SEXP parmval     = R_NilValue;
-    SEXP parmunit    = R_NilValue;
-
-    unsigned int nre, i, j, nreactant, nproduct, nparm;
-
-    /* ListOf_t *rel; */
-    Reaction_t *relel;
-    KineticLaw_t *kl;
-    Parameter_t *parm;
-
-    checkModel(sbmlmod);
-
-    /* rel = Model_getListOfReactions(R_ExternalPtrAddr(sbmlmod)); */
-    nre = Model_getNumReactions(R_ExternalPtrAddr(sbmlmod));
-
-    if (nre > 0) {
-        PROTECT(reactid     = Rf_allocVector(STRSXP, nre));
-        PROTECT(reactname   = Rf_allocVector(STRSXP, nre));
-        PROTECT(reactrev    = Rf_allocVector(LGLSXP, nre));
-        PROTECT(reactnotes  = Rf_allocVector(STRSXP, nre));
-        PROTECT(reactannot  = Rf_allocVector(STRSXP, nre));
-        PROTECT(reactreact  = Rf_allocVector(VECSXP, nre));
-        PROTECT(reactprod   = Rf_allocVector(VECSXP, nre));
-        PROTECT(reactkl     = Rf_allocVector(VECSXP, nre));
-
-        for (i = 0; i < nre; i++) {
-            /* relel = (Reaction_t *) ListOf_get(rel, i); */
-            relel = Model_getReaction(R_ExternalPtrAddr(sbmlmod), i);
-
-            nreactant = Reaction_getNumReactants(relel);
-            nproduct  = Reaction_getNumProducts(relel);
-
-            /* id */
-            if (Reaction_isSetId(relel)) {
-                SET_STRING_ELT(reactid, i, Rf_mkChar(Reaction_getId(relel)));
-            }
-            else {
-                SET_STRING_ELT(reactid, i, Rf_mkChar("no_id"));
-            }
-            /* name */
-            if (Reaction_isSetName(relel)) {
-                SET_STRING_ELT(reactname, i, Rf_mkChar(Reaction_getName(relel)));
-            }
-            else {
-                SET_STRING_ELT(reactname, i, Rf_mkChar(""));
-            }
-            /* reversible */
-            if (Reaction_isSetReversible(relel)) {
-                LOGICAL(reactrev)[i] = Reaction_getReversible(relel);
-            }
-            else {
-                LOGICAL(reactrev)[i] = 0;
-            }
-            /* notes */
-            if (SBase_isSetNotes((SBase_t *) relel)) {
-                SET_STRING_ELT(reactnotes, i, Rf_mkChar(SBase_getNotesString((SBase_t *) relel)));
-            }
-            else {
-                SET_STRING_ELT(reactnotes, i, Rf_mkChar(""));
-            }
-            /* annotation */
-            if (SBase_isSetAnnotation((SBase_t *) relel)) {
-                SET_STRING_ELT(reactannot, i, Rf_mkChar(SBase_getAnnotationString((SBase_t *) relel)));
-            }
-            else {
-                SET_STRING_ELT(reactannot, i, Rf_mkChar(""));
-            }
-
-            /* reactants */
-            SET_VECTOR_ELT(reactreact, i, getSpeciesReference(relel, nreactant, 0));
-
-            /* products */
-            SET_VECTOR_ELT(reactprod, i, getSpeciesReference(relel, nproduct, 1));
-
-            /* kineticLaw */
-            if (Reaction_isSetKineticLaw(relel)) {
-                kl = Reaction_getKineticLaw(relel);
-                nparm = KineticLaw_getNumParameters(kl);
-
-                if (nparm > 0) {
-                    PROTECT(parmid   = Rf_allocVector(STRSXP, nparm));
-                    PROTECT(parmval  = Rf_allocVector(REALSXP, nparm));
-                    PROTECT(parmunit = Rf_allocVector(STRSXP, nparm));
-
-                    for (j = 0; j < nparm; j++) {
-                        parm = KineticLaw_getParameter(kl, j);
-
-                        /* id */
-                        if (Parameter_isSetId(parm)) {
-                            SET_STRING_ELT(parmid, j, Rf_mkChar(Parameter_getId(parm)));
-                        }
-                        else {
-                            SET_STRING_ELT(parmid, j, Rf_mkChar("no_id"));
-                        }
-                        /* value */
-                        if (Parameter_isSetValue(parm)) {
-                            REAL(parmval)[j] = Parameter_getValue(parm);
-                        }
-                        else {
-                            REAL(parmval)[j] = 0;
-                        }
-                        /* units */
-                        if (Parameter_isSetUnits(parm)) {
-                            SET_STRING_ELT(parmunit, j, Rf_mkChar(Parameter_getUnits(parm)));
-                        }
-                        else {
-                            SET_STRING_ELT(parmunit, j, Rf_mkChar(""));
-                        }
-                    }
-            
-                    PROTECT(parml = Rf_allocVector(VECSXP, 3));
-                    SET_VECTOR_ELT(parml, 0, parmid);
-                    SET_VECTOR_ELT(parml, 1, parmval);
-                    SET_VECTOR_ELT(parml, 2, parmunit);
-
-                    PROTECT(parmn = Rf_allocVector(STRSXP, 3));
-                    SET_STRING_ELT(parmn, 0, Rf_mkChar("id"));
-                    SET_STRING_ELT(parmn, 1, Rf_mkChar("value"));
-                    SET_STRING_ELT(parmn, 2, Rf_mkChar("units"));
-                    Rf_setAttrib(parml, R_NamesSymbol, parmn);
-
-                    UNPROTECT(5);
-                }
-                else {
-                    parml = R_NilValue;
-                }
-                SET_VECTOR_ELT(reactkl, i, parml);
-            }
-            else {
-                SET_VECTOR_ELT(reactkl, i, R_NilValue);
-            }
-
-        }
-    
-        PROTECT(out = Rf_allocVector(VECSXP, 8));
-        SET_VECTOR_ELT(out, 0, reactid);
-        SET_VECTOR_ELT(out, 1, reactname);
-        SET_VECTOR_ELT(out, 2, reactrev);
-        SET_VECTOR_ELT(out, 3, reactnotes);
-        SET_VECTOR_ELT(out, 4, reactannot);
-        SET_VECTOR_ELT(out, 5, reactreact);
-        SET_VECTOR_ELT(out, 6, reactprod);
-        SET_VECTOR_ELT(out, 7, reactkl);
-
-        PROTECT(listv = Rf_allocVector(STRSXP, 8));
-        SET_STRING_ELT(listv, 0, Rf_mkChar("id"));
-        SET_STRING_ELT(listv, 1, Rf_mkChar("name"));
-        SET_STRING_ELT(listv, 2, Rf_mkChar("reversible"));
-        SET_STRING_ELT(listv, 3, Rf_mkChar("notes"));
-        SET_STRING_ELT(listv, 4, Rf_mkChar("annotation"));
-        SET_STRING_ELT(listv, 5, Rf_mkChar("reactants"));
-        SET_STRING_ELT(listv, 6, Rf_mkChar("products"));
-        SET_STRING_ELT(listv, 7, Rf_mkChar("kinetic_law"));
-
-        Rf_setAttrib(out, R_NamesSymbol, listv);
-
-        /* make the list to be an instance of 'reactions_list' */
-        PROTECT(class = Rf_allocVector(STRSXP, 1));
-        SET_STRING_ELT(class, 0, Rf_mkChar("reactions_list"));
-        Rf_classgets(out, class);
-
-        UNPROTECT(11);
-    }
-    else {
-        out = R_NilValue;
-    }
-
-    return out;
-}
+/* sybilSBML.c
+ Link to libSBML for sybil.
+ 
+ Copyright (C) 2010-2013 Gabriel Gelius-Dietrich, Dpt. for Bioinformatics,
+Institute for Informatics, Heinrich-Heine-University, Duesseldorf, Germany.
+All right reserved.
+Email: geliudie@uni-duesseldorf.de
+
+This file is part of sybilSBML.
+
+SybilSBML is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+SybilSBML is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with sybilSBML.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "sybilSBML.h"
+
+//new includes @Ardalan Habil
+#include <stdlib.h>
+#include <string.h>
+#include <sbml/xml/XMLTriple.h>
+#include <sbml/annotation/CVTerm.h>
+#include <sbml/annotation/RDFAnnotationParser.h>
+#include <sbml/annotation/ModelHistory.h>
+#include <sbml/math/ASTNode.h>
+#include <math.h>
+
+/* FBCv1includes  */
+
+#include <sbml/extension/SBMLExtensionRegister.h>
+#include <sbml/extension/SBMLDocumentPlugin.h>
+
+#include <sbml/packages/fbc/common/fbcfwd.h>
+
+/* FBC PLUGINS*/
+#include <sbml/packages/fbc/extension/FbcSBMLDocumentPlugin.h>
+#include <sbml/packages/fbc/extension/FbcModelPlugin.h>
+#include <sbml/packages/fbc/extension/FbcReactionPlugin.h>
+#include <sbml/packages/fbc/extension/FbcSpeciesPlugin.h>
+
+#include <sbml/packages/fbc/sbml/FluxBound.h>
+#include <sbml/packages/fbc/sbml/Objective.h>
+#include <sbml/packages/fbc/sbml/FluxObjective.h>
+#include <sbml/packages/fbc/sbml/GeneProduct.h>
+#include <sbml/packages/fbc/sbml/GeneProductRef.h>
+#include <sbml/packages/fbc/sbml/GeneProductAssociation.h>
+#include <sbml/packages/fbc/sbml/FbcAssociation.h>
+#include <sbml/packages/fbc/sbml/FbcAnd.h>
+#include <sbml/packages/fbc/sbml/FbcOr.h>
+
+
+static SEXP tagSBMLmodel;
+static SEXP tagSBMLdocument;
+
+
+/* -------------------------------------------------------------------------- */
+/* Finalizer                                                                  */
+/* -------------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------------- */
+/* finalizer for sbml document objects */
+static void sbmlDocumentFinalizer (SEXP sbmldoc) {
+  if (!R_ExternalPtrAddr(sbmldoc)) {
+    return;
+  }
+  else {
+    delDocument(sbmldoc);
+  }
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* finalizer for sbml model objects */
+/*
+static void sbmlModelFinalizer (SEXP sbmlmodel) {
+if (!R_ExternalPtrAddr(sbmlmodel)) {
+return;
+}
+else {
+delModel(sbmlmodel);
+}
+}
+*/
+
+
+/* -------------------------------------------------------------------------- */
+/* help functions                                                             */
+/* -------------------------------------------------------------------------- */
+
+/* check for pointer to sbml document */
+SEXP isSBMLdocptr(SEXP ptr) {
+  
+  SEXP out = R_NilValue;
+  
+  if ( (TYPEOF(ptr) == EXTPTRSXP) &&
+       (R_ExternalPtrTag(ptr) == tagSBMLdocument) ) {
+    out = Rf_ScalarLogical(1);
+  }
+  else {
+    out = Rf_ScalarLogical(0);
+  }
+  
+  return out;
+}
+
+/* check for pointer to sbml model */
+SEXP isSBMLmodptr(SEXP ptr) {
+  
+  SEXP out = R_NilValue;
+  
+  if ( (TYPEOF(ptr) == EXTPTRSXP) &&
+       (R_ExternalPtrTag(ptr) == tagSBMLmodel) ) {
+    out = Rf_ScalarLogical(1);
+  }
+  else {
+    out = Rf_ScalarLogical(0);
+  }
+  
+  return out;
+}
+
+/* check for NULL pointer */
+SEXP isNULLptr(SEXP ptr) {
+  
+  SEXP out = R_NilValue;
+  
+  if ( (TYPEOF(ptr) == EXTPTRSXP) &&
+       (R_ExternalPtrAddr(ptr) == NULL) ) {
+    out = Rf_ScalarLogical(1);
+  }
+  else {
+    out = Rf_ScalarLogical(0);
+  }
+  
+  return out;
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* Helper functions                                                           */
+/* -------------------------------------------------------------------------- */
+
+
+// append two string
+char * append_strings(const char * old, const char * new, const char* delim)
+{
+  // find the size of the string to allocate
+  size_t len = strlen(old) + strlen(new) + strlen(delim) + 1;
+  
+  // allocate a pointer to the new string
+  char *out = malloc(len);
+  
+  // concat both strings and return
+  sprintf(out, "%s%s%s", old, delim , new);
+  
+  return out;
+}
+
+
+
+// Parse Anntatation to modelorg
+const char* parseAnnotationTomorg(XMLNode_t* xml)
+{
+  const XMLNode_t* rdf =NULL;
+  const XMLNode_t* desc = NULL;
+  rdf = XMLNode_getChildForName(xml,"RDF");
+  if(rdf !=NULL) desc= XMLNode_getChildForName(rdf,"Description");
+  const char* annoString = "";
+  int firstelement=1;
+  if (desc!=NULL)
+  {
+    
+    int num=0;
+    for(num=0;num<XMLNode_getNumChildren(desc);num++)
+    {
+      const char* pref= XMLNode_getPrefix(XMLNode_getChild(desc,num));
+      
+      if( strcmp(pref,"bqbiol")==0 || strcmp(pref,"bqmodel")==0 )
+      { 
+        CVTerm_t* cv= CVTerm_createFromNode(XMLNode_getChild(desc,num));
+        if( CVTerm_getNumResources(cv)>0 )
+        { 
+          int numR=0;
+          if(strcmp(pref,"bqbiol")==0)
+          { 
+            const char* bioQual = append_strings("bqbiol",BiolQualifierType_toString( CVTerm_getBiologicalQualifierType(cv)),"_");
+            if(firstelement==0) annoString = append_strings(annoString,bioQual,";");
+            else
+            {
+              annoString = append_strings(annoString,bioQual,"");
+              firstelement=0;
+            }
+            
+          }
+          if(strcmp(pref,"bqmodel")==0)
+          { 
+            const char* modQual = append_strings("bqmodel",ModelQualifierType_toString( CVTerm_getModelQualifierType(cv)),"_");
+            if(firstelement==0)annoString = append_strings(annoString,modQual,";");
+            
+            else
+            {
+              annoString = append_strings(annoString,modQual,"");
+              firstelement=0;
+            }
+          }
+          
+          for(numR=0;numR<CVTerm_getNumResources(cv);numR++)
+          {
+            // sprintf(annoString+strlen(annoString),"__%s", CVTerm_getResourceURI(cv,numR));
+            annoString = append_strings(annoString,CVTerm_getResourceURI(cv,numR),";");  
+          }
+          
+        }
+      }
+      
+      
+    }  
+    return annoString;
+  }
+  else
+  {
+    return "";
+  }  
+  
+  
+  return "";
+}  
+
+
+
+/* -------------------------------------------------------------------------- */
+/* API-Functions                                                              */
+/* -------------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------------- */
+/* initialize sybilSBML */
+SEXP initSBML(void) {
+  tagSBMLmodel    = Rf_install("TYPE_SBML_MODEL");
+  tagSBMLdocument = Rf_install("TYPE_SBML_DOCUMENT");
+  return R_NilValue;
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* get libsbml version number (dotted version) */
+SEXP getLibSBMLversion() {
+  
+  SEXP out = R_NilValue;
+  
+  const char *vstr = getLibSBMLDottedVersion();
+  
+  out = Rf_mkString(vstr);
+  
+  return out;
+  
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* remove sbml document pointer */
+SEXP delDocument(SEXP sbmldoc) {
+  
+  SEXP out = R_NilValue;
+  SBMLDocument_t *del = NULL;
+  
+  checkDocument(sbmldoc);
+  
+  del = R_ExternalPtrAddr(sbmldoc);
+  
+  SBMLDocument_free(del);
+  R_ClearExternalPtr(sbmldoc);
+  
+  return out;
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* remove model pointer */
+SEXP delModel(SEXP sbmlmodel) {
+  
+  SEXP out = R_NilValue;
+  /* Model_t *del = NULL; */
+  
+  checkModel(sbmlmodel);
+  
+  /* del = R_ExternalPtrAddr(sbmlmodel); */
+  
+  /* Model_free(del); */
+  R_ClearExternalPtr(sbmlmodel);
+  
+  return out;
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* read SBML file */
+SEXP readSBMLfile(SEXP fname, SEXP ptrtype) {
+  
+  SEXP sfext = R_NilValue;
+  SEXP ptr, class, file;
+  const char *rfname = CHAR(STRING_ELT(fname, 0));
+  
+  SBMLDocument_t *sbmldoc;
+  
+  /* create sbml document pointer */
+  PROTECT(ptr = Rf_allocVector(STRSXP, 1));
+  SET_STRING_ELT(ptr, 0, STRING_ELT(ptrtype, 0));
+  
+  PROTECT(class = Rf_allocVector(STRSXP, 1));
+  SET_STRING_ELT(class, 0, Rf_mkChar("sbml_doc_ptr"));
+  
+  PROTECT(file = Rf_allocVector(STRSXP, 1));
+  SET_STRING_ELT(file, 0, Rf_mkChar("file_name"));
+  
+  /* read the model xml file */
+  sbmldoc = readSBML(rfname);
+  
+  sfext = R_MakeExternalPtr(sbmldoc, tagSBMLdocument, R_NilValue);
+  PROTECT(sfext);
+  R_RegisterCFinalizerEx(sfext, sbmlDocumentFinalizer, TRUE);
+  Rf_setAttrib(ptr, class, sfext);
+  Rf_setAttrib(ptr, file, fname);
+  Rf_classgets(ptr, class);
+  
+  UNPROTECT(4);
+  
+  return ptr;
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* get sbml document level */
+SEXP getSBMLlevel(SEXP sbmldoc) {
+  
+  SEXP out = R_NilValue;
+  unsigned int level;
+  
+  checkDocument(sbmldoc);
+  
+  level = SBMLDocument_getLevel(R_ExternalPtrAddr(sbmldoc));
+  
+  out = Rf_ScalarInteger(level);
+  
+  return out;
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* get sbml document version */
+SEXP getSBMLversion(SEXP sbmldoc) {
+  
+  SEXP out = R_NilValue;
+  unsigned int version;
+  
+  checkDocument(sbmldoc);
+  
+  version = SBMLDocument_getVersion(R_ExternalPtrAddr(sbmldoc));
+  
+  out = Rf_ScalarInteger(version);
+  
+  return out;
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+/* get sbml document  FBC version */
+SEXP getSBMLFbcversion(SEXP sbmldoc) {
+  
+  SEXP out = R_NilValue;
+  unsigned int version;
+  
+  checkDocument(sbmldoc);
+  //hierher
+  SBasePlugin_t * modelPlug= NULL;
+  modelPlug = SBase_getPlugin((SBase_t *)(R_ExternalPtrAddr(sbmldoc)), "fbc");
+  if( modelPlug != NULL) 
+  { 
+    if(strcmp("fbc",SBasePlugin_getPackageName(modelPlug) ) ==0)
+      version = SBasePlugin_getPackageVersion(modelPlug);
+    else version=0;
+  } else version=0;  
+  
+  out = Rf_ScalarInteger(version);
+  
+  return out;
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+/* validate SBML document */
+SEXP validateDocument(SEXP sbmldoc) {
+  
+  /*
+  this is adopted from Michael Lawrence: rsbml
+  Michael Lawrence (). rsbml: R support for SBML, using libsbml.
+  R package version 2.18.0. http://www.sbml.org
+  http://www.bioconductor.org/packages/release/bioc/html/rsbml.html
+  */
+  
+  SEXP out   = R_NilValue;
+  
+  unsigned int validation;
+  
+  checkDocument(sbmldoc);
+  
+  /* number or errors logged when reading SBML file */
+  validation  = SBMLDocument_getNumErrors(R_ExternalPtrAddr(sbmldoc));
+  /* number or errors from structural and mathematical tests */
+  validation += SBMLDocument_checkConsistency(R_ExternalPtrAddr(sbmldoc));
+  
+  if (validation > 0) {
+    out = Rf_ScalarLogical(0);
+  }
+  else {
+    out = Rf_ScalarLogical(1);
+  }
+  
+  return out;
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* get SBML errors */
+SEXP getSBMLerrors(SEXP sbmldoc) {
+  
+  /*
+  this is adopted from Michael Lawrence: rsbml
+  Michael Lawrence (). rsbml: R support for SBML, using libsbml.
+  R package version 2.18.0. http://www.sbml.org
+  http://www.bioconductor.org/packages/release/bioc/html/rsbml.html
+  */
+  
+  SEXP out   = R_NilValue;
+  SEXP listv = R_NilValue;
+  SEXP info  = R_NilValue;
+  SEXP warn  = R_NilValue;
+  SEXP error = R_NilValue;
+  SEXP fatal = R_NilValue;
+  SEXP class = R_NilValue;
+  SEXP el    = R_NilValue;
+  
+  XMLError_t *sbml_err;
+  
+  unsigned int nprob, i, ind;
+  int ninfo = 0, nwarn = 0, nerror = 0, nfatal = 0, nunknown = 0;
+  
+  checkDocument(sbmldoc);
+  
+  nprob = SBMLDocument_getNumErrors(R_ExternalPtrAddr(sbmldoc));
+  
+  /*
+  Rprintf("Model Errors: %i\n", nprob);
+  */
+  
+  if (nprob > 0) {
+    
+    /* check how many infos, warnings, errors and fatals we have */
+    for (i = 0; i < nprob; i++) {
+      sbml_err = (XMLError_t *) SBMLDocument_getError(R_ExternalPtrAddr(sbmldoc), i);
+      if (XMLError_isInfo(sbml_err)) {
+        ninfo++;
+      }
+      else if (XMLError_isWarning(sbml_err)) {
+        nwarn++;
+      }
+      else if (XMLError_isError(sbml_err)) {
+        nerror++;
+      }
+      else if (XMLError_isFatal(sbml_err)) {
+        nfatal++;
+      }
+      else {
+        nunknown++;
+      }
+    }
+    
+    /*
+    Rprintf("number of infos: %i, warnings: %i, errors: %i, falals: %i, unknowns: %i\n",
+            ninfo, nwarn, nerror, nfatal, nunknown);
+    */
+    
+    /*
+    out will be a list of four elements:
+    infos
+    warnings
+    errors
+    fatals
+    each of them is a list of three elements:
+    id
+    line
+    column
+    msg
+    */
+    
+    PROTECT(out =   Rf_allocVector(VECSXP, 4));
+    
+    /* allocate space for each error list */
+    PROTECT(info  = Rf_allocVector(VECSXP, ninfo));
+    PROTECT(warn  = Rf_allocVector(VECSXP, nwarn));
+    PROTECT(error = Rf_allocVector(VECSXP, nerror));
+    PROTECT(fatal = Rf_allocVector(VECSXP, nfatal));
+    
+    SET_VECTOR_ELT(out, 0, info);
+    SET_VECTOR_ELT(out, 1, warn);
+    SET_VECTOR_ELT(out, 2, error);
+    SET_VECTOR_ELT(out, 3, fatal);
+    
+    PROTECT(listv = Rf_allocVector(STRSXP, 4));
+    SET_STRING_ELT(listv, 0, Rf_mkChar("infos"));
+    SET_STRING_ELT(listv, 1, Rf_mkChar("warnings"));
+    SET_STRING_ELT(listv, 2, Rf_mkChar("errors"));
+    SET_STRING_ELT(listv, 3, Rf_mkChar("fatals"));
+    Rf_setAttrib(out, R_NamesSymbol, listv);
+    
+    /* get the error messages */
+    ninfo = 0, nwarn = 0, nerror = 0, nfatal = 0, nunknown = 0;
+    for (i = 0; i < nprob; i++) {
+      sbml_err = (XMLError_t *) SBMLDocument_getError(R_ExternalPtrAddr(sbmldoc), i);
+      el = R_NilValue;
+      ind = 0;
+      if (XMLError_isInfo(sbml_err)) {
+        ind = ninfo++;
+        el  = info;
+      }
+      else if (XMLError_isWarning(sbml_err)) {
+        ind = nwarn++;
+        el  = warn;
+      }
+      else if (XMLError_isError(sbml_err)) {
+        ind = nerror++;
+        el  = error;
+      }
+      else if (XMLError_isFatal(sbml_err)) {
+        ind = nfatal++;
+        el  = fatal;
+      }
+      else {
+        nunknown++;
+      }
+      SET_VECTOR_ELT(el, ind, generateProblemMsg(sbml_err));
+    }
+    
+    /* make the list to be an instance of 'sbml_error' */
+    PROTECT(class = Rf_allocVector(STRSXP, 1));
+    SET_STRING_ELT(class, 0, Rf_mkChar("sbml_error"));
+    Rf_classgets(out, class);
+    
+    UNPROTECT(7);
+    
+  } /* end if nprob > 0 */
+    else {
+      out = Rf_ScalarLogical(1);
+    }
+    
+    return out;
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* get sbml model from sbml document */
+SEXP getSBMLmodel(SEXP sbmldoc, SEXP ptrtype) {
+  
+  SEXP smext = R_NilValue;
+  SEXP ptr, class;
+  
+  Model_t *sbmlmodel;
+  
+  checkDocument(sbmldoc);
+  
+  /* create model pointer */
+  PROTECT(ptr = Rf_allocVector(STRSXP, 1));
+  SET_STRING_ELT(ptr, 0, STRING_ELT(ptrtype, 0));
+  
+  PROTECT(class = Rf_allocVector(STRSXP, 1));
+  SET_STRING_ELT(class, 0, Rf_mkChar("sbml_model_ptr"));
+  
+  /* get sbml model */
+  sbmlmodel = SBMLDocument_getModel(R_ExternalPtrAddr(sbmldoc));
+  
+  smext = R_MakeExternalPtr(sbmlmodel, tagSBMLmodel, R_NilValue);
+  PROTECT(smext);
+  /* R_RegisterCFinalizerEx(smext, sbmlModelFinalizer, TRUE); */
+  Rf_setAttrib(ptr, class, smext);
+  Rf_classgets(ptr, class);
+  
+  UNPROTECT(3);
+  
+  return ptr;
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* get model id */
+SEXP getSBMLmodId(SEXP sbmlmod) {
+  
+  SEXP out = R_NilValue;
+  const char *mid;
+  
+  checkModel(sbmlmod);
+  
+  if (Model_isSetId(R_ExternalPtrAddr(sbmlmod))) {
+    mid = Model_getId(R_ExternalPtrAddr(sbmlmod));
+  }
+  else {
+    mid = "no_id";
+  }
+  
+  out = Rf_mkString(mid);
+  
+  return out;
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* get model name */
+SEXP getSBMLmodName(SEXP sbmlmod) {
+  
+  SEXP out = R_NilValue;
+  const char *mnm;
+  
+  checkModel(sbmlmod);
+  
+  if (Model_isSetName(R_ExternalPtrAddr(sbmlmod))) {
+    mnm = Model_getName(R_ExternalPtrAddr(sbmlmod));
+  }
+  else {
+    mnm = "";
+  }
+  
+  out = Rf_mkString(mnm);
+  
+  return out;
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* get model notes */
+SEXP getSBMLmodNotes(SEXP sbmlmod) {
+  
+  SEXP out = R_NilValue;
+  const char *mnotes;
+  
+  checkModel(sbmlmod);
+  
+  if (SBase_isSetNotes((SBase_t *) R_ExternalPtrAddr(sbmlmod))) {
+  mnotes = SBase_getNotesString((SBase_t *)  R_ExternalPtrAddr(sbmlmod));
+  }
+  else {
+    mnotes = "";
+  }
+  
+  out = Rf_mkString(mnotes);
+  
+  return out;
+}
+
+/* -------------------------------------------------------------------------- */
+/* get model name */
+SEXP getSBMLmodAnnotation(SEXP sbmlmod) {
+  
+  SEXP out = R_NilValue;
+  const char *manno;
+  
+  checkModel(sbmlmod);
+  
+  if (SBase_isSetAnnotation((SBase_t *)  R_ExternalPtrAddr(sbmlmod))) {
+    XMLNode_t* xml = SBase_getAnnotation((SBase_t *)  R_ExternalPtrAddr(sbmlmod));
+    manno = parseAnnotationTomorg(xml);
+  }
+  else {
+    manno = "";
+  }
+  
+  out = Rf_mkString(manno);
+  
+  return out;
+}
+
+
+
+/* -------------------------------------------------------------------------- */
+/* get number of compartments */
+SEXP getSBMLnumCompart(SEXP sbmlmod) {
+  
+  SEXP out = R_NilValue;
+  unsigned int nc;
+  
+  checkModel(sbmlmod);
+  
+  nc = Model_getNumCompartments(R_ExternalPtrAddr(sbmlmod));
+  
+  out = Rf_ScalarInteger(nc);
+  
+  return out;
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* get number of species (metabolites) */
+SEXP getSBMLnumSpecies(SEXP sbmlmod) {
+  
+  SEXP out = R_NilValue;
+  unsigned int nsp;
+  
+  checkModel(sbmlmod);
+  
+  nsp = Model_getNumSpecies(R_ExternalPtrAddr(sbmlmod));
+  
+  out = Rf_ScalarInteger(nsp);
+  
+  return out;
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* get number of reactions */
+SEXP getSBMLnumReactions(SEXP sbmlmod) {
+  
+  SEXP out = R_NilValue;
+  unsigned int nr;
+  
+  checkModel(sbmlmod);
+  
+  nr = Model_getNumReactions(R_ExternalPtrAddr(sbmlmod));
+  
+  out = Rf_ScalarInteger(nr);
+  
+  return out;
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* get list of unit definitions */
+SEXP getSBMLunitDefinitionsList(SEXP sbmlmod) {
+  
+  SEXP out       = R_NilValue;
+  SEXP class     = R_NilValue;
+  SEXP unl       = R_NilValue;
+  SEXP listv     = R_NilValue;
+  SEXP listn     = R_NilValue;
+  
+  SEXP unitdefid = R_NilValue;
+  SEXP unitdef   = R_NilValue;
+  
+  SEXP unitkind  = R_NilValue;
+  SEXP unitscale = R_NilValue;
+  SEXP unitexp   = R_NilValue;
+  SEXP unitmult  = R_NilValue;
+  
+  unsigned int nud, nu, i, j;
+  
+  /* ListOf_t *udl; */
+  UnitDefinition_t *udlel;
+  Unit_t *uel;
+  
+  checkModel(sbmlmod);
+  
+  /* udl = Model_getListOfUnitDefinitions(R_ExternalPtrAddr(sbmlmod)); */
+  nud = Model_getNumUnitDefinitions(R_ExternalPtrAddr(sbmlmod));
+  
+  if (nud > 0) {
+    PROTECT(unitdefid = Rf_allocVector(STRSXP, nud));
+    PROTECT(unitdef   = Rf_allocVector(VECSXP, nud));
+    for (i = 0; i < nud; i++) {
+      /* udlel = (UnitDefinition_t *) ListOf_get(udl, i); */
+      udlel = Model_getUnitDefinition(R_ExternalPtrAddr(sbmlmod), i);
+      
+      /* id and unit */
+      if (UnitDefinition_isSetId(udlel)) {
+        SET_STRING_ELT(unitdefid, i, Rf_mkChar(UnitDefinition_getId(udlel)));
+        
+        nu = UnitDefinition_getNumUnits(udlel);
+        
+        PROTECT(unitkind  = Rf_allocVector(STRSXP, nu));
+        PROTECT(unitscale = Rf_allocVector(INTSXP, nu));
+        PROTECT(unitexp   = Rf_allocVector(INTSXP, nu));
+        PROTECT(unitmult  = Rf_allocVector(REALSXP, nu));
+        
+        for (j = 0; j < nu; j++) {
+          uel = UnitDefinition_getUnit(udlel, j);
+          
+          /* kind */
+          if (Unit_isSetKind(uel)) {
+            SET_STRING_ELT(unitkind, j, Rf_mkChar(UnitKind_toString(Unit_getKind(uel))));
+          }
+          else {
+            SET_STRING_ELT(unitkind, j, Rf_mkChar("no_kind"));
+          }
+          
+          /* scale */
+          if (Unit_isSetScale(uel)) {
+            INTEGER(unitscale)[j] = Unit_getScale(uel);
+          }
+          else {
+            INTEGER(unitscale)[j] = 0;
+          }
+          
+          /* exponent */
+          if (Unit_isSetExponent(uel)) {
+            INTEGER(unitexp)[j] = Unit_getExponent(uel);
+          }
+          else {
+            INTEGER(unitexp)[j] = 1;
+          }
+          
+          /* multiplier */
+          if (Unit_isSetMultiplier(uel)) {
+            REAL(unitmult)[j] = Unit_getMultiplier(uel);
+          }
+          else {
+            REAL(unitmult)[j] = 1;
+          }
+          
+        }
+        
+        PROTECT(unl = Rf_allocVector(VECSXP, 4));
+        SET_VECTOR_ELT(unl, 0, unitkind);
+        SET_VECTOR_ELT(unl, 1, unitscale);
+        SET_VECTOR_ELT(unl, 2, unitexp);
+        SET_VECTOR_ELT(unl, 3, unitmult);
+        
+        PROTECT(listn = Rf_allocVector(STRSXP, 4));
+        SET_STRING_ELT(listn, 0, Rf_mkChar("kind"));
+        SET_STRING_ELT(listn, 1, Rf_mkChar("scale"));
+        SET_STRING_ELT(listn, 2, Rf_mkChar("exponent"));
+        SET_STRING_ELT(listn, 3, Rf_mkChar("multiplier"));
+        Rf_setAttrib(unl, R_NamesSymbol, listn);
+        
+        SET_VECTOR_ELT(unitdef, i, unl);
+        
+        UNPROTECT(6);
+        
+      }
+      else {
+        SET_STRING_ELT(unitdefid, i, Rf_mkChar("no_id"));
+      }
+    }
+    
+    PROTECT(out = Rf_allocVector(VECSXP, 2));
+    SET_VECTOR_ELT(out, 0, unitdefid);
+    SET_VECTOR_ELT(out, 1, unitdef);
+    
+    PROTECT(listv = Rf_allocVector(STRSXP, 2));
+    SET_STRING_ELT(listv, 0, Rf_mkChar("definition_id"));
+    SET_STRING_ELT(listv, 1, Rf_mkChar("definition"));
+    
+    Rf_setAttrib(out, R_NamesSymbol, listv);
+    
+    /* make the list to be an instance of 'unit_definition' */
+    PROTECT(class = Rf_allocVector(STRSXP, 1));
+    SET_STRING_ELT(class, 0, Rf_mkChar("unit_definition"));
+    Rf_classgets(out, class);
+    
+    UNPROTECT(5);
+  }
+  else {
+    out = R_NilValue;
+  }
+  
+  return out;
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* get list of compartments */
+SEXP getSBMLCompartList(SEXP sbmlmod) {
+  
+  SEXP out        = R_NilValue;
+  SEXP class      = R_NilValue;
+  SEXP listv      = R_NilValue;
+  SEXP compid     = R_NilValue;
+  SEXP compname   = R_NilValue;
+  SEXP compannot  = R_NilValue;
+  SEXP compnotes  = R_NilValue;
+  SEXP compout    = R_NilValue;
+  
+  unsigned int nc, i;
+  
+  /* ListOf_t *cl; */
+  Compartment_t *clel;
+  
+  checkModel(sbmlmod);
+  
+  /* cl = Model_getListOfCompartments(R_ExternalPtrAddr(sbmlmod)); */
+  nc = Model_getNumCompartments(R_ExternalPtrAddr(sbmlmod));
+  
+  if (nc > 0) {
+    PROTECT(compid     = Rf_allocVector(STRSXP, nc));
+    PROTECT(compname   = Rf_allocVector(STRSXP, nc));
+    PROTECT(compannot  = Rf_allocVector(STRSXP, nc));
+    PROTECT(compnotes  = Rf_allocVector(STRSXP, nc));
+    
+    // Counter Variables	
+    int annocount=0;
+    int notescount=0;
+    
+    PROTECT(compout   = Rf_allocVector(STRSXP, nc));
+    
+    for (i = 0; i < nc; i++) {
+      clel = Model_getCompartment(R_ExternalPtrAddr(sbmlmod), i);
+      /* id */
+      if (Compartment_isSetId(clel)) {
+        SET_STRING_ELT(compid, i, Rf_mkChar(Compartment_getId(clel)));
+      }
+      else {
+        SET_STRING_ELT(compid, i, Rf_mkChar("no_id"));
+      }
+      /* name */
+      if (Compartment_isSetName(clel)) {
+        SET_STRING_ELT(compname, i, Rf_mkChar(Compartment_getName(clel)));
+      }
+      else {
+        SET_STRING_ELT(compname, i, Rf_mkChar(""));
+      }
+      /* outside */
+      if (Compartment_isSetOutside(clel)) {
+        SET_STRING_ELT(compout, i, Rf_mkChar(Compartment_getOutside(clel)));
+      }
+      else {
+        SET_STRING_ELT(compout, i, Rf_mkChar(""));
+      }
+      
+      /* NEW INFORMATIONS*/	
+      /* notes */
+      if (SBase_isSetNotes((SBase_t *) clel)) {
+        SET_STRING_ELT(compnotes, i, Rf_mkChar(SBase_getNotesString((SBase_t *) clel)));
+        notescount=notescount+1;
+      }
+      else {
+        SET_STRING_ELT(compnotes, i, Rf_mkChar(""));
+      }
+      
+      /* annotation */
+      if (SBase_isSetAnnotation((SBase_t *) clel)) {
+        XMLNode_t* xml = SBase_getAnnotation((SBase_t *) clel);
+        SET_STRING_ELT(compannot, i, Rf_mkChar(parseAnnotationTomorg(xml)));
+        annocount=annocount+1;
+      }
+      else {
+        SET_STRING_ELT(compannot, i, Rf_mkChar(""));
+      }
+      
+      
+    }
+    
+    // NULL if empty 
+    if (annocount==0)   compannot = R_NilValue;
+    if (notescount==0) compnotes  = R_NilValue;
+    
+    PROTECT(out = Rf_allocVector(VECSXP, 5));
+    SET_VECTOR_ELT(out, 0, compid);
+    SET_VECTOR_ELT(out, 1, compname);
+    SET_VECTOR_ELT(out, 2, compout);
+    SET_VECTOR_ELT(out, 3, compannot);
+    SET_VECTOR_ELT(out, 4, compnotes);
+    
+    
+    PROTECT(listv = Rf_allocVector(STRSXP, 5));
+    SET_STRING_ELT(listv, 0, Rf_mkChar("id"));
+    SET_STRING_ELT(listv, 1, Rf_mkChar("name"));
+    SET_STRING_ELT(listv, 2, Rf_mkChar("outside"));
+    SET_STRING_ELT(listv, 3, Rf_mkChar("annotation"));
+    SET_STRING_ELT(listv, 4, Rf_mkChar("notes"));
+    
+    
+    
+    Rf_setAttrib(out, R_NamesSymbol, listv);
+    
+    /* make the list to be an instance of 'compartments_list' */
+    PROTECT(class = Rf_allocVector(STRSXP, 1));
+    SET_STRING_ELT(class, 0, Rf_mkChar("compartments_list"));
+    Rf_classgets(out, class);
+    
+    UNPROTECT(8);
+  }
+  else {
+    out = R_NilValue;
+  }
+  
+  return out;
+}
+
+/* -------------------------------------------------------------------------- */
+/* get list of species (metabolites) */
+SEXP getSBMLSpeciesList(SEXP sbmlmod) {
+  
+  SEXP out       = R_NilValue;
+  SEXP class     = R_NilValue;
+  SEXP listv     = R_NilValue;
+  SEXP metid     = R_NilValue;
+  SEXP metname   = R_NilValue;
+  SEXP metcomp   = R_NilValue;
+  SEXP metcharge = R_NilValue;
+  SEXP metchemic = R_NilValue;
+  SEXP metbndcnd = R_NilValue;
+  SEXP metannot  = R_NilValue;
+  SEXP metnotes  = R_NilValue;
+  
+  unsigned int nsp, i;
+  
+  /* ListOf_t *spl; */
+  Species_t *splel;
+  
+  checkModel(sbmlmod);
+  
+  /* spl = Model_getListOfSpecies(R_ExternalPtrAddr(sbmlmod)); */
+  nsp = Model_getNumSpecies(R_ExternalPtrAddr(sbmlmod));
+  
+  
+  if (nsp > 0) {
+    PROTECT(metid     = Rf_allocVector(STRSXP, nsp));
+    PROTECT(metname   = Rf_allocVector(STRSXP, nsp));
+    PROTECT(metcomp   = Rf_allocVector(STRSXP, nsp));
+    PROTECT(metcharge = Rf_allocVector(INTSXP, nsp));
+    PROTECT(metchemic = Rf_allocVector(STRSXP, nsp));
+    PROTECT(metbndcnd = Rf_allocVector(LGLSXP, nsp));
+    PROTECT(metannot  = Rf_allocVector(STRSXP, nsp));
+    PROTECT(metnotes  = Rf_allocVector(STRSXP, nsp));
+    
+    int chcount=0;
+    int notescount=0;
+    int annotcount=0;
+    
+    for (i = 0; i < nsp; i++) {
+      /* splel = (Species_t *) ListOf_get(spl, i); */
+      splel = Model_getSpecies(R_ExternalPtrAddr(sbmlmod), i);
+      /* id */
+      if (Species_isSetId(splel)) {
+        SET_STRING_ELT(metid, i, Rf_mkChar(Species_getId(splel)));
+      }
+      else {
+        SET_STRING_ELT(metid, i, Rf_mkChar("no_id"));
+      }
+      /* name */
+      if (Species_isSetName(splel)) {
+        SET_STRING_ELT(metname, i, Rf_mkChar(Species_getName(splel)));
+      }
+      else {
+        SET_STRING_ELT(metname, i, Rf_mkChar(""));
+      }
+      /* compartment */
+      if (Species_isSetCompartment(splel)) {
+        SET_STRING_ELT(metcomp, i, Rf_mkChar(Species_getCompartment(splel)));
+      }
+      else {
+        SET_STRING_ELT(metcomp, i, Rf_mkChar(""));
+      }
+      /* charge */
+      if (Species_isSetCharge(splel)) {
+        INTEGER(metcharge)[i] = Species_getCharge(splel);
+      }
+      else {
+        INTEGER(metcharge)[i] = 0;
+      }
+      /* boundary condition */
+      if (Species_isSetBoundaryCondition(splel)) {
+        LOGICAL(metbndcnd)[i] = Species_getBoundaryCondition(splel);
+      }
+      else {
+        LOGICAL(metbndcnd)[i] = 0;
+      }
+      
+      
+      
+      /* notes */
+      if (SBase_isSetNotes((SBase_t *) splel)) {
+        SET_STRING_ELT(metnotes, i, Rf_mkChar(SBase_getNotesString((SBase_t *) splel)));
+        notescount=notescount+1;
+        
+      }
+      else {
+        SET_STRING_ELT(metnotes, i, Rf_mkChar(""));
+      }
+      
+      /* annotation */
+      if (SBase_isSetAnnotation((SBase_t *) splel)) {
+        //SET_STRING_ELT(metannot, i, Rf_mkChar(SBase_getAnnotationString((SBase_t *) splel)));
+        XMLNode_t* xml = SBase_getAnnotation((SBase_t *) splel);
+        annotcount=annotcount+1;
+        SET_STRING_ELT(metannot, i, Rf_mkChar(parseAnnotationTomorg(xml)));
+      }
+      else {
+        SET_STRING_ELT(metannot, i, Rf_mkChar(""));
+      }
+      
+      
+      /* FBC PLUGIN @ Ardalan */
+      SBasePlugin_t *SpeciesPlug = SBase_getPlugin((SBase_t *)(splel), "fbc");
+      
+      /* FBCcharge */
+      if (FbcSpeciesPlugin_isSetCharge(SpeciesPlug)) {
+        INTEGER(metcharge)[i] = FbcSpeciesPlugin_getCharge(SpeciesPlug);
+      }
+      
+      /* FBC chemicalFormula */
+      if (FbcSpeciesPlugin_isSetChemicalFormula(SpeciesPlug)) {
+        SET_STRING_ELT(metchemic, i, Rf_mkChar(FbcSpeciesPlugin_getChemicalFormula(SpeciesPlug)));
+        chcount=chcount+1;
+      }
+      else {
+        SET_STRING_ELT(metchemic, i, Rf_mkChar(""));
+      }
+      
+      
+    }
+    
+    // NULL if empty 
+    if (chcount==0)    metchemic = R_NilValue;
+    if (notescount==0) metnotes  = R_NilValue;
+    if (annotcount==0)  metannot  = R_NilValue;
+    
+    PROTECT(out = Rf_allocVector(VECSXP, 8));
+    SET_VECTOR_ELT(out, 0, metid);
+    SET_VECTOR_ELT(out, 1, metname);
+    SET_VECTOR_ELT(out, 2, metcomp);
+    SET_VECTOR_ELT(out, 3, metcharge);
+    SET_VECTOR_ELT(out, 4, metchemic);
+    SET_VECTOR_ELT(out, 5, metbndcnd);
+    SET_VECTOR_ELT(out, 6, metannot);
+    SET_VECTOR_ELT(out, 7, metnotes);
+    
+    
+    PROTECT(listv = Rf_allocVector(STRSXP, 8));
+    SET_STRING_ELT(listv, 0, Rf_mkChar("id"));
+    SET_STRING_ELT(listv, 1, Rf_mkChar("name"));
+    SET_STRING_ELT(listv, 2, Rf_mkChar("compartment"));
+    SET_STRING_ELT(listv, 3, Rf_mkChar("charge"));
+    SET_STRING_ELT(listv, 4, Rf_mkChar("chemicalFormula"));
+    SET_STRING_ELT(listv, 5, Rf_mkChar("boundaryCondition"));
+    SET_STRING_ELT(listv, 6, Rf_mkChar("annotation"));
+    SET_STRING_ELT(listv, 7, Rf_mkChar("notes"));
+    
+    
+    Rf_setAttrib(out, R_NamesSymbol, listv);
+    
+    /* make the list to be an instance of 'species_list' */
+    PROTECT(class = Rf_allocVector(STRSXP, 1));
+    SET_STRING_ELT(class, 0, Rf_mkChar("species_list"));
+    Rf_classgets(out, class);
+    
+    UNPROTECT(11);
+  }
+  else {
+    out = R_NilValue;
+  }
+  
+  return out;
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* get list of reactions */
+SEXP getSBMLReactionsList(SEXP sbmlmod) {
+  
+  SEXP out         = R_NilValue;
+  SEXP class       = R_NilValue;
+  SEXP listv       = R_NilValue;
+  SEXP reactid     = R_NilValue;
+  SEXP reactname   = R_NilValue;
+  SEXP reactrev    = R_NilValue;
+  SEXP reactnotes  = R_NilValue;
+  SEXP reactannot  = R_NilValue;
+  SEXP reactreact  = R_NilValue;
+  SEXP reactprod   = R_NilValue;
+  SEXP reactkl     = R_NilValue;
+  
+  SEXP parml       = R_NilValue;
+  SEXP parmn       = R_NilValue;
+  SEXP parmid      = R_NilValue;
+  SEXP parmval     = R_NilValue;
+  SEXP parmunit    = R_NilValue;
+  
+  SEXP fbclb       = R_NilValue; //lowerbnd
+  SEXP fbcup       = R_NilValue; //upperbnd
+  SEXP fbcgene     = R_NilValue; //fbc gene Rules
+  SEXP fbcobj      = R_NilValue; // fbc objective
+  
+  unsigned int nre, i, j, nreactant, nproduct, nparm;
+  
+  /* ListOf_t *rel; */
+  Reaction_t *relel;
+  KineticLaw_t *kl;
+  Parameter_t *parm;
+  
+  checkModel(sbmlmod);
+  
+  /* rel = Model_getListOfReactions(R_ExternalPtrAddr(sbmlmod)); */
+  nre = Model_getNumReactions(R_ExternalPtrAddr(sbmlmod));
+  
+  if (nre > 0) {
+    PROTECT(reactid     = Rf_allocVector(STRSXP, nre));
+    PROTECT(reactname   = Rf_allocVector(STRSXP, nre));
+    PROTECT(reactrev    = Rf_allocVector(LGLSXP, nre));
+    PROTECT(reactnotes  = Rf_allocVector(STRSXP, nre));
+    PROTECT(reactannot  = Rf_allocVector(STRSXP, nre));
+    PROTECT(reactreact  = Rf_allocVector(VECSXP, nre));
+    PROTECT(reactprod   = Rf_allocVector(VECSXP, nre));
+    PROTECT(reactkl     = Rf_allocVector(VECSXP, nre));
+    
+    PROTECT(fbclb       = Rf_allocVector(REALSXP, nre));
+    PROTECT(fbcup       = Rf_allocVector(REALSXP, nre));
+    PROTECT(fbcgene     = Rf_allocVector(STRSXP , nre));
+    PROTECT(fbcobj      = Rf_allocVector(REALSXP, nre));
+    
+    
+    int lbcount=0;
+    int upcount=0;
+    int genecount=0;
+    int objcount=0;
+    int annocount=0;
+    int notescount=0;
+    
+    /* Help Var for Fbc Objective*/
+    double Objcoeff =0;
+    const char* Objreaction = NULL;
+    char* objActiv = NULL;
+    int fbcversion = 0;
+    
+    /* FBC OBJECTIV @Ardalan*/
+    Objective_t * objective;
+    FluxObjective_t * fluxObjective;
+    SBasePlugin_t * modelPlug= NULL;
+    
+    modelPlug = SBase_getPlugin((SBase_t *)(R_ExternalPtrAddr(sbmlmod)), "fbc");
+    
+    // Read the Objectives when FBCPlugin for the model exists
+    if( modelPlug != NULL)
+    { 
+      
+      objActiv = FbcModelPlugin_getActiveObjectiveId(modelPlug);
+      int ob=0;
+      if(strcmp(objActiv,"") !=0)
+      {
+        for(ob; ob< FbcModelPlugin_getNumObjectives(modelPlug);ob++)
+        {
+          objective= FbcModelPlugin_getObjective(modelPlug,ob);
+          //printf("ObjectiveID: %s \n",  Objective_getId(objective) );
+          if(strcmp(objActiv,Objective_getId(objective))==0)
+          { // TODO mehrer FLUXOBJECTIVE; MAXimierung Minimirung? 
+            
+            //  int fob=0;
+            //  for(fob; ob<FbcModelPlugin_getNumObjectives(modelPlug);fob++ )
+            //  {  
+            fluxObjective= Objective_getFluxObjective(objective,0);
+            Objreaction=  FluxObjective_getReaction(fluxObjective) ;
+            Objcoeff =  FluxObjective_getCoefficient(fluxObjective);
+            
+            //printf("ReactionObjectiveID: %s \n",  Objreaction);
+            //printf("Coefficient: %f \n",  Objcoeff);
+            //  }
+          }  
+          
+        }  
+        
+      }
+      
+      
+      /* is FBC 1 */
+      
+      if(strcmp("fbc",SBasePlugin_getPackageName(modelPlug) ) ==0)
+        fbcversion = SBasePlugin_getPackageVersion(modelPlug);
+    }  
+    
+    
+    for (i = 0; i < nre; i++) {
+      /* relel = (Reaction_t *) ListOf_get(rel, i); */
+      relel = Model_getReaction(R_ExternalPtrAddr(sbmlmod), i);
+      
+      nreactant = Reaction_getNumReactants(relel);
+      nproduct  = Reaction_getNumProducts(relel);
+      
+      /* id */
+      if (Reaction_isSetId(relel)) {
+        SET_STRING_ELT(reactid, i, Rf_mkChar(Reaction_getId(relel)));
+      }
+      else {
+        SET_STRING_ELT(reactid, i, Rf_mkChar("no_id"));
+      }
+      /* name */
+      if (Reaction_isSetName(relel)) {
+        SET_STRING_ELT(reactname, i, Rf_mkChar(Reaction_getName(relel)));
+      }
+      else {
+        SET_STRING_ELT(reactname, i, Rf_mkChar(""));
+      }
+      /* reversible */
+      if (Reaction_isSetReversible(relel)) {
+        LOGICAL(reactrev)[i] = Reaction_getReversible(relel);
+      }
+      else {
+        LOGICAL(reactrev)[i] = 0;
+      }
+      /* notes */
+      if (SBase_isSetNotes((SBase_t *) relel)) {
+        SET_STRING_ELT(reactnotes, i, Rf_mkChar(SBase_getNotesString((SBase_t *) relel)));
+        notescount=notescount+1;
+      }
+      else {
+        SET_STRING_ELT(reactnotes, i, Rf_mkChar(""));
+      }
+      /* annotation */
+      if (SBase_isSetAnnotation((SBase_t *) relel)) {
+        //SET_STRING_ELT(reactannot, i, Rf_mkChar(SBase_getAnnotationString((SBase_t *) relel)));
+        XMLNode_t* xml = SBase_getAnnotation((SBase_t *) relel);
+        SET_STRING_ELT(reactannot, i, Rf_mkChar(parseAnnotationTomorg(xml)));
+        annocount=annocount+1;
+      }
+      else {
+        SET_STRING_ELT(reactannot, i, Rf_mkChar(""));
+      }
+      
+      /* FBC LEVEL 2 @Ardalan Habil*/
+      
+      /* ReactionPLugin for FBC 2 */
+      SBasePlugin_t *reactionPlug = SBase_getPlugin((SBase_t *)(relel), "fbc");
+      
+      
+      /* LOWERFLUXBOUND */
+      if (FbcReactionPlugin_isSetLowerFluxBound(reactionPlug)) 
+      {
+        parm = Model_getParameterById(R_ExternalPtrAddr (sbmlmod) ,FbcReactionPlugin_getLowerFluxBound(reactionPlug));
+        //printf("LowerFLUXBOUND: %f \n",  Parameter_getValue(parm));
+        REAL(fbclb)[i] = Parameter_getValue(parm);
+        lbcount=lbcount+1;
+      }
+      else{
+        REAL(fbclb)[i] = 0;
+      }      
+      
+      /* UPPERFLUXBOUND*/
+      if (FbcReactionPlugin_isSetUpperFluxBound(reactionPlug)) 
+      {
+        parm = Model_getParameterById(R_ExternalPtrAddr (sbmlmod) ,FbcReactionPlugin_getUpperFluxBound(reactionPlug));
+        //printf("UPPERFLUXBOUND: %f \n",  Parameter_getValue(parm));
+        REAL(fbcup)[i] = Parameter_getValue(parm);
+        upcount=upcount+1;
+      }
+      else{
+        REAL(fbcup)[i] = 0;
+      }
+      
+      /*FBC 1 read */
+      if (fbcversion==1)
+      {
+        /* Storing FBC1Bounds */
+        double fbc1lb=0;
+        double fbc1up=0;
+        
+        
+        int fluxb=0;
+        for(fluxb; fluxb< FbcModelPlugin_getNumFluxBounds(modelPlug);fluxb++)
+        {
+          FluxBound_t * currentFlux = FbcModelPlugin_getFluxBound(modelPlug,fluxb);
+          
+          const char * currentFluxType ;
+          const char * currentFluxReaction; 
+          
+          if (FluxBound_isSetReaction(currentFlux))  currentFluxReaction = FluxBound_getReaction(currentFlux);
+          else continue;
+          
+          if(strcmp(currentFluxReaction , Reaction_getId(relel) ) !=0) continue;
+          
+          
+          if (FluxBound_isSetOperation(currentFlux)) currentFluxType = FluxBound_getOperation(currentFlux);
+          else continue;  
+          
+          
+          if(strcmp("greaterEqual" , currentFluxType ) ==0)
+          {
+            lbcount=lbcount+1;
+            if (FluxBound_isSetValue(currentFlux))  fbc1lb = FluxBound_getValue(currentFlux);
+            else continue;
+          }  
+          
+          else if(strcmp("lessEqual" , currentFluxType ) ==0)
+          { 
+            upcount=upcount+1;
+            if (FluxBound_isSetValue(currentFlux))  fbc1up = FluxBound_getValue(currentFlux);
+            else continue;
+          }  
+          
+          else if(strcmp("equal" , currentFluxType ) ==0)  
+          {
+            if (FluxBound_isSetValue(currentFlux))
+            {
+              lbcount=lbcount+1;
+              upcount=upcount+1;
+              fbc1lb = FluxBound_getValue(currentFlux); 
+              fbc1up = FluxBound_getValue(currentFlux);
+            }
+            else continue;
+          }
+          
+        }  
+        
+        /* FBC 1 save Bounds */
+        REAL(fbclb)[i] = fbc1lb;
+        REAL(fbcup)[i] = fbc1up;
+        
+      }
+      
+      
+      /* FBC GENE */
+      if( FbcReactionPlugin_isSetGeneProductAssociation(reactionPlug) ) {
+        GeneProductAssociation_t* gpa = FbcReactionPlugin_getGeneProductAssociation(reactionPlug);
+        FbcAssociation_t* asso= (FbcAssociation_t*) GeneProductAssociation_getAssociation(gpa);
+        SET_STRING_ELT(fbcgene, i, Rf_mkChar(FbcAssociation_toInfix(asso)));
+        //printf("Gene: %s \n",   FbcAssociation_toInfix(asso));
+        genecount=genecount+1;
+      }
+      else {
+        SET_STRING_ELT(fbcgene, i, Rf_mkChar(""));
+      }
+      
+      /* FBC OBJECTIVES*/
+      if (Objreaction != NULL && strcmp(Objreaction , Reaction_getId(relel) )==0)     
+      {
+        
+        REAL(fbcobj)[i] = Objcoeff;
+        objcount=objcount+1;
+      }
+      else{
+        REAL(fbcobj)[i] = 0;
+      }      
+      
+      
+      /* reactants */
+      SET_VECTOR_ELT(reactreact, i, getSpeciesReference(relel, nreactant, 0));
+      
+      /* products */
+      SET_VECTOR_ELT(reactprod, i, getSpeciesReference(relel, nproduct, 1));
+      
+      /* kineticLaw */
+      if (Reaction_isSetKineticLaw(relel)) {
+        kl = Reaction_getKineticLaw(relel);
+        nparm = KineticLaw_getNumParameters(kl);
+        
+        if (nparm > 0) {
+          PROTECT(parmid   = Rf_allocVector(STRSXP, nparm));
+          PROTECT(parmval  = Rf_allocVector(REALSXP, nparm));
+          PROTECT(parmunit = Rf_allocVector(STRSXP, nparm));
+          
+          for (j = 0; j < nparm; j++) {
+            parm = KineticLaw_getParameter(kl, j);
+            
+            /* id */
+            if (Parameter_isSetId(parm)) {
+              SET_STRING_ELT(parmid, j, Rf_mkChar(Parameter_getId(parm)));
+            }
+            else {
+              SET_STRING_ELT(parmid, j, Rf_mkChar("no_id"));
+            }
+            /* value */
+            if (Parameter_isSetValue(parm)) {
+              REAL(parmval)[j] = Parameter_getValue(parm);
+            }
+            else {
+              REAL(parmval)[j] = 0;
+            }
+            /* units */
+            if (Parameter_isSetUnits(parm)) {
+              SET_STRING_ELT(parmunit, j, Rf_mkChar(Parameter_getUnits(parm)));
+            }
+            else {
+              SET_STRING_ELT(parmunit, j, Rf_mkChar(""));
+            }
+          }
+          
+          PROTECT(parml = Rf_allocVector(VECSXP, 3));
+          SET_VECTOR_ELT(parml, 0, parmid);
+          SET_VECTOR_ELT(parml, 1, parmval);
+          SET_VECTOR_ELT(parml, 2, parmunit);
+          
+          PROTECT(parmn = Rf_allocVector(STRSXP, 3));
+          SET_STRING_ELT(parmn, 0, Rf_mkChar("id"));
+          SET_STRING_ELT(parmn, 1, Rf_mkChar("value"));
+          SET_STRING_ELT(parmn, 2, Rf_mkChar("units"));
+          Rf_setAttrib(parml, R_NamesSymbol, parmn);
+          
+          UNPROTECT(5);
+        }
+        else {
+          parml = R_NilValue;
+        }
+        SET_VECTOR_ELT(reactkl, i, parml);
+      }
+      else {
+        SET_VECTOR_ELT(reactkl, i, R_NilValue);
+      }
+      
+      
+    }
+    
+    // NULL if empty
+    if(lbcount==0)   fbclb     = R_NilValue;
+    if(upcount==0)   fbcup     = R_NilValue;
+    if(genecount==0) fbcgene   = R_NilValue;
+    if(objcount==0)  fbcobj    = R_NilValue;
+    if(annocount==0) reactannot= R_NilValue;
+    if(notescount==0) reactnotes= R_NilValue;
+    
+    
+    PROTECT(out = Rf_allocVector(VECSXP, 12));
+    SET_VECTOR_ELT(out, 0, reactid);
+    SET_VECTOR_ELT(out, 1, reactname);
+    SET_VECTOR_ELT(out, 2, reactrev);
+    SET_VECTOR_ELT(out, 3, reactnotes);
+    SET_VECTOR_ELT(out, 4, reactannot);
+    SET_VECTOR_ELT(out, 5, reactreact);
+    SET_VECTOR_ELT(out, 6, reactprod);
+    SET_VECTOR_ELT(out, 7, reactkl);
+    SET_VECTOR_ELT(out, 8, fbclb);
+    SET_VECTOR_ELT(out, 9, fbcup);
+    SET_VECTOR_ELT(out, 10, fbcgene);
+    SET_VECTOR_ELT(out, 11, fbcobj);
+    
+    
+    PROTECT(listv = Rf_allocVector(STRSXP, 12));
+    SET_STRING_ELT(listv, 0, Rf_mkChar("id"));
+    SET_STRING_ELT(listv, 1, Rf_mkChar("name"));
+    SET_STRING_ELT(listv, 2, Rf_mkChar("reversible"));
+    SET_STRING_ELT(listv, 3, Rf_mkChar("notes"));
+    SET_STRING_ELT(listv, 4, Rf_mkChar("annotation"));
+    SET_STRING_ELT(listv, 5, Rf_mkChar("reactants"));
+    SET_STRING_ELT(listv, 6, Rf_mkChar("products"));
+    SET_STRING_ELT(listv, 7, Rf_mkChar("kinetic_law"));
+    SET_STRING_ELT(listv, 8, Rf_mkChar("fbc_lowbnd"));
+    SET_STRING_ELT(listv, 9, Rf_mkChar("fbc_uppbnd"));
+    SET_STRING_ELT(listv, 10, Rf_mkChar("fbc_gprRules"));
+    SET_STRING_ELT(listv, 11, Rf_mkChar("fbc_Objectives"));
+    
+    Rf_setAttrib(out, R_NamesSymbol, listv);
+    
+    /* make the list to be an instance of 'reactions_list' */
+    PROTECT(class = Rf_allocVector(STRSXP, 1));
+    SET_STRING_ELT(class, 0, Rf_mkChar("reactions_list"));
+    Rf_classgets(out, class);
+    
+    UNPROTECT(15);
+  }
+  else {
+    out = R_NilValue;
+  }
+  
+  return out;
+}
+
+/* -------------------------------------------------------------------------- */
+/* export SBML*/
+
+void ParseModtoAnno  (SBase_t* comp , char* Mannocopy)
+  
+{
+  
+  char delimiter[] = ";";
+  char *ptr;
+  ptr = strtok(Mannocopy, delimiter);
+  char* quali;
+  CVTerm_t *cv;
+  int first=0;
+  
+  while(ptr != NULL) {
+    
+    if(strncmp("bqbiol", ptr, strlen("bqbiol")) == 0)
+    {
+      if (first != 0){ SBase_addCVTerm((SBase_t*)comp, cv);CVTerm_free(cv);}
+      //CVTerm_free(cv);
+      quali  = strcpy(&ptr[0],&ptr[7]);
+      cv = CVTerm_createWithQualifierType(BIOLOGICAL_QUALIFIER);
+      CVTerm_setBiologicalQualifierTypeByString( cv, (const char*) quali); 
+      first=1;
+    }
+    else  if(strncmp("bqmodel", ptr, strlen("bqmodel")) == 0)
+    {
+      if (first != 0) { SBase_addCVTerm((SBase_t*)comp, cv);CVTerm_free(cv);}
+      //CVTerm_free(cv);
+      quali  = strcpy(&ptr[0],&ptr[8]);
+      cv = CVTerm_createWithQualifierType(MODEL_QUALIFIER);
+      CVTerm_setModelQualifierTypeByString( cv, (const char*) quali); 
+    }  
+    else
+    {
+      CVTerm_addResource(cv,ptr );
+    }  
+    
+    // naechsten Abschnitt erstellen
+    ptr = strtok(NULL, delimiter);
+  }
+  SBase_addCVTerm((SBase_t*)comp, cv);
+  
+}
+
+
+
+SEXP exportSBML (SEXP version, SEXP level,SEXP FbcLevel, SEXP filename,SEXP sybil_max, SEXP mod_desc, SEXP mod_name, SEXP mod_compart, SEXP met_id, SEXP met_name, SEXP met_comp, SEXP met_form,SEXP met_charge, SEXP react_id, SEXP react_name, SEXP react_rev, SEXP lowbnd, SEXP uppbnd, SEXP obj_coef, SEXP subSys, SEXP gpr, SEXP SMatrix, SEXP mod_notes, SEXP mod_anno, SEXP com_notes , SEXP com_anno, SEXP met_notes, SEXP met_anno, SEXP met_bnd , SEXP react_notes, SEXP react_anno, SEXP ex_react,SEXP allgenes)
+{
+  //Varaibles from R
+  const char* fname = CHAR(STRING_ELT(filename, 0));
+  const char* model_desc = CHAR(STRING_ELT(mod_desc, 0));
+  const char* model_name = CHAR(STRING_ELT(mod_name, 0));
+  
+  int SBMLlevel = INTEGER(level)[0];
+  int SBMLversion = INTEGER(version)[0];
+  int SBMLfbcversion = INTEGER(FbcLevel)[0];
+  double sybilmax = REAL(sybil_max)[0];
+  double sybilmin = sybilmax*(-1);
+  
+  // variable FBC
+  XMLNamespaces_t * fbc;
+  SBMLNamespaces_t * sbmlns;
+  FluxBound_t * fluxBound;
+  Objective_t * objective;
+  FluxObjective_t * fluxObjective;
+  SBMLDocumentPlugin_t * docPlug;
+  SBasePlugin_t * modelPlug;
+  SBasePlugin_t *reactionPlug;
+  SBasePlugin_t *SpeciesPlug ;
+  
+  FbcAssociation_t* asso;
+  
+  
+  // Variable inital
+  
+  SBMLDocument_t* sbmlDoc;
+  Model_t* model;
+  XMLNamespaces_t* xmlns;
+  
+  UnitDefinition_t* unitdef;
+  Unit_t* unit;
+  
+  Species_t *sp;
+  Reaction_t* reaction;
+  SpeciesReference_t* spr;
+  Compartment_t* comp;
+  KineticLaw_t* kl;
+  Parameter_t* para;
+  
+ // ASTNode_t* flux;
+  ASTNode_t* astMath;  
+  //ASTNode_t* ast;
+  //char* mathXMLString;
+  
+  /*---------------------------------------------------------------------------
+  *
+  * Creates an SBMLDocument object 
+  *
+  *---------------------------------------------------------------------------*/
+  
+  if (SBMLlevel == 1 || SBMLlevel == 2)
+  { 
+    sbmlDoc = SBMLDocument_createWithLevelAndVersion(SBMLlevel,SBMLversion);  
+    xmlns = (XMLNamespaces_t*) SBMLDocument_getNamespaces(sbmlDoc);
+    XMLNamespaces_add(xmlns, "http://www.w3.org/1999/xhtml", "html");
+  }
+  else if(SBMLlevel == 3) 
+  {
+    if(SBMLfbcversion == 0)
+    {
+      sbmlDoc = SBMLDocument_createWithLevelAndVersion(3,1);  
+      xmlns = (XMLNamespaces_t*) SBMLDocument_getNamespaces(sbmlDoc);
+      XMLNamespaces_add(xmlns, "http://www.w3.org/1999/xhtml", "html");
+      
+    } else {
+      
+      /* FBC LEVEL  */
+      /* get fbc registry entry */
+      SBMLExtension_t *sbmlext = SBMLExtensionRegistry_getExtension("fbc");
+      
+      /* create the sbml namespaces object with fbc */
+      fbc = XMLNamespaces_create();
+      XMLNamespaces_add(fbc, SBMLExtension_getURI(sbmlext, 3, 1,  SBMLfbcversion), "fbc");
+      
+      sbmlns = SBMLNamespaces_create(3, 1);
+      SBMLNamespaces_addNamespaces(sbmlns, fbc);
+      
+      
+      /* create the document */
+      sbmlDoc = SBMLDocument_createWithSBMLNamespaces(sbmlns);
+      
+      /* XHTML for notes*/
+      xmlns = (XMLNamespaces_t*) SBMLDocument_getNamespaces(sbmlDoc);
+      XMLNamespaces_add(xmlns, "http://www.w3.org/1999/xhtml", "html");
+      
+      /* set the fbc reqd attribute to false */
+      docPlug = (SBMLDocumentPlugin_t*)(SBase_getPlugin((SBase_t*)(sbmlDoc), "fbc"));
+      SBMLDocumentPlugin_setRequired(docPlug, 0);
+      
+    }
+    
+  }
+  
+  
+  /*---------------------------------------------------------------------------
+  *
+  * Creates a Model object inside the SBMLDocument object. 
+  *
+  *---------------------------------------------------------------------------*/
+  
+  model = SBMLDocument_createModel(sbmlDoc);
+  Model_setId(model,model_name);
+  
+  // Get a SBasePlugin_t object plugged in the model object.
+  if(SBMLfbcversion == 2)
+  {  
+    modelPlug = SBase_getPlugin((SBase_t *)(model), "fbc");
+    
+    // set the fbc strict attribute
+    FbcModelPlugin_setStrict(modelPlug, 1);
+  }
+  
+  // Model NOTERS
+  if (!Rf_isNull(mod_notes)) 
+  {  
+    char *Modnotes = (char*) CHAR(STRING_ELT(mod_notes, 0));
+    if ((Modnotes != NULL) && (Modnotes[0] != '\0')) 
+    {
+      //printf("Canno: %s", Cnotes);
+      SBase_setNotesString((SBase_t*) model , Modnotes);
+    }
+  }
+  
+  /*Annotation*/
+  if (!Rf_isNull(mod_anno) ) 
+  {  char *Manno   = (char*) CHAR(STRING_ELT(mod_anno, 0));
+    if((Manno != NULL) && (Manno[0] != '\0' )) 
+    {  
+      SBase_setMetaId((SBase_t*)model,model_name);
+      char Mannocopy[strlen(Manno)+1];
+      strcpy(Mannocopy,Manno);
+      // PARSING
+      ParseModtoAnno((SBase_t*)model, Mannocopy);
+      
+    }
+  }
+  
+  /*---------------------------------------------------------------------------
+  *
+  * Creates UnitDefinition objects inside the Model object.
+  *
+  *---------------------------------------------------------------------------*/
+  /*
+  unitdef = Model_createUnitDefinition(model);
+  UnitDefinition_setId(unitdef,"litre_per_mole_per_second");
+  
+  //  Creates an Unit inside the UnitDefinition object ("litre_per_mole_per_second") 
+  
+  unit = UnitDefinition_createUnit(unitdef);
+  Unit_setKind(unit,UNIT_KIND_MOLE);
+  Unit_setExponent(unit,-1);
+  
+  //  Creates an Unit inside the UnitDefinition object ("litre_per_mole_per_second") 
+  
+  unit = UnitDefinition_createUnit(unitdef);
+  Unit_setKind(unit,UNIT_KIND_LITRE);
+  Unit_setExponent(unit,1);
+  
+  //  Creates an Unit inside the UnitDefinition object ("litre_per_mole_per_second") 
+  
+  unit = UnitDefinition_createUnit(unitdef);
+  Unit_setKind(unit,UNIT_KIND_SECOND);
+  Unit_setExponent(unit,-1);
+  
+  */
+  
+  /*---------------------------------------------------------------------------
+  *
+  * Creates a Compartment object inside the Model object. 
+  *
+  *---------------------------------------------------------------------------*/
+  
+  const char *sName;
+  int i;
+  int hasBoundary=0;
+  for (i=0; i<LENGTH(mod_compart); i++) 
+  {
+    sName = CHAR(STRING_ELT(mod_compart, i));
+    comp = Model_createCompartment(model);
+    Compartment_setId(comp,sName);
+    Compartment_setConstant(comp,1);
+    if( strcmp(sName,"BOUNDARY")==0 || strcmp(sName,"Boundary")==0  || strcmp(sName,"boundary")==0)hasBoundary=1;
+    if (!Rf_isNull(com_notes) && Rf_length(com_notes) > 1) 
+    {  
+      char *Cnotes = (char*) CHAR(STRING_ELT(com_notes, i));
+      if ((Cnotes != NULL) && (Cnotes[0] != '\0')) 
+      {
+        //printf("Canno: %s", Cnotes);
+        SBase_setNotesString((SBase_t*)comp, Cnotes);
+      }
+    }
+    
+    
+    if (!Rf_isNull(com_anno) && Rf_length(com_anno) > 1  ) 
+    {  char *Manno   = (char*) CHAR(STRING_ELT(com_anno, i));
+      if((Manno != NULL) && (Manno[0] != '\0' )) 
+      {  
+        SBase_setMetaId((SBase_t*)comp, CHAR(STRING_ELT(mod_compart, i)));
+        char Mannocopy[strlen(Manno)+1];
+        strcpy(Mannocopy,Manno);
+        ParseModtoAnno((SBase_t*) comp,Mannocopy);
+        
+      }
+    }
+    
+  }
+  
+  
+  /* Boundary Compartment */
+  if(hasBoundary==0 && Rf_isNull(met_bnd) && Rf_length(met_bnd) <= 1 && !Rf_isNull(ex_react))
+  {  
+  comp = Model_createCompartment(model);
+  Compartment_setId(comp,"BOUNDARY");
+  Compartment_setConstant(comp,1);
+  hasBoundary=1;
+  }
+  /*---------------------------------------------------------------------------
+  *
+  * Creates Species objects inside the Model object. 
+  *
+  *---------------------------------------------------------------------------*/
+  for (i=0; i<LENGTH(met_name); i++) 
+  {
+    
+    
+    sp = Model_createSpecies(model);
+    Species_setId(sp,CHAR(STRING_ELT(met_id, i)));
+    Species_setName(sp,CHAR(STRING_ELT(met_name, i)));
+    Species_setCompartment(sp,CHAR(STRING_ELT(met_comp, i)));
+    Species_setHasOnlySubstanceUnits(sp, 0);
+    Species_setConstant(sp, 0);
+    
+    //Bondary Condition
+    if (!Rf_isNull(met_bnd) && Rf_length(met_bnd) > 1) Species_setBoundaryCondition(sp, LOGICAL(met_bnd)[i]);
+    else Species_setBoundaryCondition(sp, 0);
+      
+    
+    int hasNotes=0;
+    const char* metnote="";
+    if (!Rf_isNull(met_form) && Rf_length(met_form) > 1) 
+    {
+      if (SBMLfbcversion >0)
+      {  
+        SpeciesPlug = SBase_getPlugin((SBase_t *)(sp), "fbc");
+        FbcSpeciesPlugin_setChemicalFormula(SpeciesPlug, CHAR(STRING_ELT(met_form, i)));
+      }
+      
+      else{
+        metnote = append_strings(metnote,"<html:p>FORMULA: ","");
+        metnote =append_strings(metnote,CHAR(STRING_ELT(met_form, i)),"");
+        metnote =append_strings(metnote," </html:p>","");
+        hasNotes=1;
+      }
+    }
+    
+    if (!Rf_isNull(met_charge) && Rf_length(met_charge) > 1) 
+    {
+      if (SBMLfbcversion >0)
+      {
+        SpeciesPlug = SBase_getPlugin((SBase_t *)(sp), "fbc");
+        FbcSpeciesPlugin_setCharge(SpeciesPlug, INTEGER(met_charge)[i]);
+      }
+      else
+      {  
+        metnote = append_strings(metnote,"<html:p>CHARGE: ","");
+        char chint[256];
+        sprintf(chint, "%d", INTEGER(met_charge)[i]);
+        metnote =append_strings(metnote,chint,"");
+        metnote =append_strings(metnote," </html:p>","");
+        hasNotes=1;
+      }
+    }
+    
+    
+    if (!Rf_isNull(met_notes) && Rf_length(met_notes) > 1) 
+    {
+      char *Mnotes = (char*) CHAR(STRING_ELT(met_notes, i));
+      if ((Mnotes != NULL) && (Mnotes[0] != '\0')) 
+      {
+        SBase_setNotesString((SBase_t*)sp, Mnotes);
+        hasNotes=0;
+      }  
+      
+    }
+    
+    
+    if(hasNotes !=0 )SBase_setNotesString((SBase_t*)sp, metnote);
+    
+    if (!Rf_isNull(met_anno) && Rf_length(met_anno) > 1  ) 
+    {  char *Manno   = (char*) CHAR(STRING_ELT(met_anno, i));
+      
+      if((Manno != NULL) && (Manno[0] != '\0' )) 
+      {  
+
+        SBase_setMetaId((SBase_t*)sp, CHAR(STRING_ELT(met_id, i)));
+        
+        // COPY STRING  
+        char *Manno   = (char*) CHAR(STRING_ELT(met_anno, i));
+        char Mannocopy[strlen(Manno)+1];
+        strcpy(Mannocopy,Manno);
+        // PARSING
+        ParseModtoAnno((SBase_t*)sp, Mannocopy);
+        
+      }
+    }
+    
+    
+    
+  } 
+  /*---------------------------------------------------------------------------
+  *
+  * Creates Reaction objects inside the Model object. 
+  *
+  *---------------------------------------------------------------------------*/
+  
+  /*  LISTOFGENES
+  * 
+  */
+  if(SBMLfbcversion == 2 && Rf_length(gpr) > 1)
+  { 
+    if (!Rf_isNull(gpr) && Rf_length(gpr) > 1)
+    {  
+      modelPlug = SBase_getPlugin((SBase_t *)(model), "fbc");
+      //GeneProduct_t* gene;
+      char* genid = malloc( 100 );
+      
+      for (i=0; i<LENGTH(allgenes); i++)
+      {
+        GeneProduct_t* gene = GeneProduct_create(3,1,2);
+        sprintf(genid,"G_%s", CHAR(STRING_ELT(allgenes, i)));
+        GeneProduct_setId(gene ,genid);
+        GeneProduct_setLabel(gene ,CHAR(STRING_ELT(allgenes, i)));
+        FbcModelPlugin_addGeneProduct(modelPlug,gene);
+      }
+      free(genid);
+    }
+    /* 
+    ListOfParemters
+    */
+    
+    // create the Parameters
+    
+    para = Model_createParameter(model);
+    Parameter_setId(para, "default_lb");
+    Parameter_setConstant(para, 1);
+    Parameter_setValue(para, sybilmin);
+    SBase_setSBOTerm((SBase_t *)para,626);
+    
+    para = Model_createParameter(model);
+    Parameter_setId(para, "default_ub");
+    Parameter_setConstant(para, 1);
+    Parameter_setValue(para, sybilmax);
+    SBase_setSBOTerm((SBase_t *)para,626);
+    
+    para = Model_createParameter(model);
+    Parameter_setId(para, "default_0");
+    Parameter_setConstant(para, 1);
+    Parameter_setValue(para, 0);
+    SBase_setSBOTerm((SBase_t *)para,626);
+
+  }
+  
+  
+  // LOOP FOR REACTION
+  for (i=0; i<LENGTH(react_name); i++)
+  {
+    reaction = Model_createReaction(model);
+    
+    Reaction_setId(reaction, CHAR(STRING_ELT(react_id, i)));
+    Reaction_setName(reaction, CHAR(STRING_ELT(react_name, i)));
+    Reaction_setReversible(reaction,LOGICAL(react_rev)[i]);
+    Reaction_setFast(reaction, 0);
+    
+    if(SBMLfbcversion == 2)
+    {  
+      // FBCv2
+      reactionPlug = SBase_getPlugin((SBase_t *)(reaction), "fbc");    
+      GeneProductAssociation_t* gpa = GeneProductAssociation_create(3,1,2);
+      
+      //  FbcAnd_t * und= FbcAnd_create(3,1,2);
+      asso= FbcAssociation_parseFbcInfixAssociation(CHAR(STRING_ELT(gpr, i)),modelPlug);
+      GeneProductAssociation_setAssociation(gpa,asso);
+      FbcReactionPlugin_setGeneProductAssociation(reactionPlug,gpa);
+    }
+    
+    
+    
+    const char* notesString = "";
+    
+    
+    
+    if (!Rf_isNull(react_notes) && Rf_length(react_notes) > 1) 
+    {
+      char *Rnotes = (char*) CHAR(STRING_ELT(react_notes, i));
+      if ((Rnotes != NULL) && (Rnotes[0] != '\0')) 
+      {
+        //printf("Reaction Nores:%s ",Rnotes);
+        SBase_setNotesString((SBase_t*)reaction, Rnotes);
+      }  
+      
+    } 
+    else
+    { 
+      if(SBMLfbcversion == 0)
+      {
+        if (!Rf_isNull(gpr) && Rf_length(gpr) > 1)
+        {  
+          notesString = append_strings(notesString,"<html:p>GENE_ASSOCIATION: ","");
+          notesString =append_strings(notesString,CHAR(STRING_ELT(gpr, i)),"");
+          notesString =append_strings(notesString," </html:p>","");
+        }
+        if (!Rf_isNull(subSys) && Rf_length(subSys) > 1)
+        {  
+          notesString = append_strings(notesString,"<html:p>SUBSYSTEM: ","");
+          notesString =append_strings(notesString,CHAR(STRING_ELT(subSys, i)),"");
+          notesString =append_strings(notesString," </html:p>","");
+        }
+        
+        SBase_setNotesString((SBase_t*)reaction, notesString);
+      }
+    }
+    
+    const double *lower_bnd = REAL(lowbnd);
+    const double *upper_bnd = REAL(uppbnd);
+    
+    // KineticLaw
+    if(SBMLfbcversion == 0)
+    {  
+      kl = Reaction_createKineticLaw(reaction);
+      
+      astMath = ASTNode_createWithType(AST_NAME);
+      ASTNode_setName(astMath, "FLUX_VALUE");
+      
+      KineticLaw_setMath( kl, astMath);
+      
+      
+      para = KineticLaw_createParameter( kl );
+      Parameter_setId(para, "LOWER_BOUND");
+      Parameter_setValue( para, lower_bnd[i]);
+      //Parameter_setUnits( para, "litre_per_mole_per_second");
+      
+      para = KineticLaw_createParameter( kl );
+      Parameter_setId(para, "UPPER_BOUND");
+      Parameter_setValue( para, upper_bnd[i]);
+      //Parameter_setUnits( para, "litre_per_mole_per_second");
+      
+      para = KineticLaw_createParameter( kl );
+      Parameter_setId(para, "OBJECTIVE_COEFFICIENT");
+      Parameter_setValue( para, INTEGER(obj_coef)[i]);
+      
+      para = KineticLaw_createParameter( kl );
+      Parameter_setId(para, "FLUX_VALUE");
+      Parameter_setValue( para, 0);
+    }
+    
+
+    int isexchange=0;
+    int k;
+    if (Rf_isNull(met_bnd) && Rf_length(met_bnd) <= 1 && !Rf_isNull(ex_react))
+      for (k=0; k<LENGTH(ex_react); k++) 
+        if( i+1 == INTEGER(ex_react)[k]) 
+          isexchange=1;
+        
+      int j=0;
+      for (j=0; j<LENGTH(met_id); j++)
+      {
+        
+        int hash = LENGTH(met_id) * i + j;
+        if (REAL(SMatrix)[hash] != 0.00 )
+        {
+          
+          if(REAL(SMatrix)[hash] < 0.00)
+          {
+            spr = Reaction_createReactant(reaction);
+            SpeciesReference_setConstant(spr, 1);
+            SpeciesReference_setSpecies(spr,CHAR(STRING_ELT(met_id, j)));
+            SpeciesReference_setStoichiometry(spr, fabs(REAL(SMatrix)[hash]));
+            
+            //is Exchange Reaction
+            if(isexchange==1 && !Rf_isNull(ex_react))
+            {
+              /* Create boundary Species */
+              sp = Model_createSpecies(model);
+              
+              Species_setId(sp, append_strings(CHAR(STRING_ELT(met_id, j)),"BOUNDARY","_") );
+              Species_setName(sp,append_strings(CHAR(STRING_ELT(met_name, j)),"BOUNDARY"," ") );
+              
+              Species_setCompartment(sp,"BOUNDARY");
+              Species_setHasOnlySubstanceUnits(sp, 0);
+              Species_setBoundaryCondition(sp, 1);
+              Species_setConstant(sp, 1);
+              
+              /* Add boundary Species as Product */
+              spr = Reaction_createProduct(reaction);
+              SpeciesReference_setSpecies(spr,append_strings(CHAR(STRING_ELT(met_id, j)),"BOUNDARY","_") );
+              SpeciesReference_setStoichiometry(spr,1);
+              
+              SpeciesReference_setConstant(spr, 1);
+            }
+            
+            
+          }else{
+            spr = Reaction_createProduct(reaction);
+            SpeciesReference_setConstant(spr, 1);
+            SpeciesReference_setSpecies(spr,CHAR(STRING_ELT(met_id, j)));
+            SpeciesReference_setStoichiometry(spr, fabs(REAL(SMatrix)[hash]));  
+          }
+          
+        }  
+      }
+      
+      
+      
+      /*Annotation*/
+      if (!Rf_isNull(react_anno) && Rf_length(react_anno) > 1  ) 
+      {  char *Manno   = (char*) CHAR(STRING_ELT(react_anno, i));
+        if((Manno != NULL) && (Manno[0] != '\0' )) 
+        {  
+          SBase_setMetaId((SBase_t*)reaction, CHAR(STRING_ELT(react_id, i)));
+          char Mannocopy[strlen(Manno)+1];
+          strcpy(Mannocopy,Manno);
+          // PARSING
+          ParseModtoAnno((SBase_t*)reaction, Mannocopy);
+          
+        }
+      }
+      
+      
+      
+      /* FBC LEVEL 2 */
+      if(SBMLfbcversion == 2)
+      {  
+        // Get a SBasePlugin_t object plugged in the reaction object.
+        
+        reactionPlug = SBase_getPlugin((SBase_t *)(reaction), "fbc");
+        
+        const char* para_lb;
+        const char* para_ub;
+        
+        //default Parameter or new one
+        if (lower_bnd[i]<= sybilmin)
+        {
+          para_lb="default_lb";
+        }  
+        else if (lower_bnd[i] == 0)
+        {
+          para_lb="default_0";
+        }  
+        else
+        { //creacte Lower_bound Paramater
+          para = Model_createParameter(model);
+          Parameter_setId(para, append_strings(CHAR(STRING_ELT(react_id, i)),"lower_bound","_"));
+          Parameter_setConstant(para, 1);
+          Parameter_setValue(para, lower_bnd[i]);
+          SBase_setSBOTerm((SBase_t *)para,625);
+          
+          para_lb=append_strings(CHAR(STRING_ELT(react_id, i)),"lower_bound","_");
+          
+        }  
+        
+        if (upper_bnd[i] >= sybilmax)
+        {
+          para_ub="default_ub";
+        }
+        
+        else if (upper_bnd[i] == 0)
+        {
+          para_ub="default_0";
+        }  
+        
+        else
+        {
+          //creacte upper_bound Paramater
+          para = Model_createParameter(model);
+          Parameter_setId(para, append_strings(CHAR(STRING_ELT(react_id, i)),"upper_bound","_"));
+          Parameter_setConstant(para, 1);
+          Parameter_setValue(para, upper_bnd[i]);
+          SBase_setSBOTerm((SBase_t *)para,625);
+          
+          para_ub=append_strings(CHAR(STRING_ELT(react_id, i)),"upper_bound","_");
+        }  
+        
+        // set the flux bounds for this reaction
+        FbcReactionPlugin_setLowerFluxBound(reactionPlug, para_lb);
+        FbcReactionPlugin_setUpperFluxBound(reactionPlug, para_ub);
+        
+        // OBJECTIVES
+        if (INTEGER(obj_coef)[i]!=0)
+        {
+          objective = Objective_create(3, 1, 2);
+          Objective_setId(objective, "obj");
+          Objective_setType(objective, "maximize");
+          
+          fluxObjective = Objective_createFluxObjective(objective);
+          FluxObjective_setReaction(fluxObjective, CHAR(STRING_ELT(react_id, i)));
+          FluxObjective_setCoefficient(fluxObjective, INTEGER(obj_coef)[i]);
+          
+          FbcModelPlugin_addObjective(modelPlug, objective);
+          
+          // mark obj1 as active objective
+          FbcModelPlugin_setActiveObjectiveId(modelPlug, "obj");
+          
+        }  
+      }
+      
+      
+  }// ENDE REACTION
+  if(SBMLfbcversion == 1)
+  {  
+    
+    // FBC LEVEL 1 
+    
+    // Get a SBasePlugin_t object plugged in the model object.
+    
+    modelPlug = SBase_getPlugin((SBase_t *)(model), "fbc");
+    int ObjCounter = 0;
+    for (i=0; i<LENGTH(react_name); i++)
+    {
+      
+      const double *lower_bnd = REAL(lowbnd);
+      const double *upper_bnd = REAL(uppbnd);
+      
+      char buf[20];
+      // FBC1 FLUXBOUNDS
+      sprintf(buf, "LOWER_BOUND%d", i);
+      if (INTEGER(obj_coef)[i] != 1)
+      {  
+        fluxBound = FluxBound_create(3, 1, 1);
+        FluxBound_setId(fluxBound, buf);
+        FluxBound_setReaction(fluxBound, CHAR(STRING_ELT(react_id, i)));
+        FluxBound_setOperation(fluxBound, "greaterEqual");
+        FluxBound_setValue(fluxBound, lower_bnd[i]);
+        FbcModelPlugin_addFluxBound(modelPlug, fluxBound);
+        
+        //printf("Upper: %s\n", buf);
+        sprintf(buf, "UPPER_BOUND%d", i);
+        fluxBound = FluxBound_create(3, 1, 1);
+        FluxBound_setId(fluxBound, buf);
+        FluxBound_setReaction(fluxBound, CHAR(STRING_ELT(react_id, i)));
+        FluxBound_setOperation(fluxBound, "lessEqual");
+        FluxBound_setValue(fluxBound, upper_bnd[i]);
+        
+        FbcModelPlugin_addFluxBound(modelPlug, fluxBound);
+      }
+      
+      if (INTEGER(obj_coef)[i] == 1 && ObjCounter == 0)
+      {
+        sprintf(buf, "OBJ%d", i);
+        objective = Objective_create(3, 1, 1);
+        Objective_setId(objective, buf);
+        Objective_setType(objective, "maximize");
+        
+        fluxObjective = Objective_createFluxObjective(objective);
+        FluxObjective_setReaction(fluxObjective, CHAR(STRING_ELT(react_id, i)));
+        FluxObjective_setCoefficient(fluxObjective, 1);
+        
+        FbcModelPlugin_addObjective(modelPlug, objective);
+        FbcModelPlugin_setActiveObjectiveId(modelPlug, buf);
+        ObjCounter = ObjCounter +1;
+      }
+      
+      
+      
+    }  
+  }
+  
+  // write SBML file
+  int result = writeSBML(sbmlDoc, fname);
+  SEXP out = R_NilValue;
+  if (result)out = Rf_ScalarLogical(1);
+  else out = Rf_ScalarLogical(0);
+  
+  return out;
+}
+
+
+
+
+/* -------------------------------------------------------------------------- */
\ No newline at end of file
diff --git a/src/sybilSBML.h b/src/sybilSBML.h
index 03345246ae9388cac9daf15eb52cb152151da0ca..9fac9ea3f09297661487956e0deca29afa6a2976 100644
--- a/src/sybilSBML.h
+++ b/src/sybilSBML.h
@@ -1,100 +1,112 @@
-/* sybilSBML.h
-   Link to libSBML for sybil.
- 
-   Copyright (C) 2010-2013 Gabriel Gelius-Dietrich, Dpt. for Bioinformatics,
-   Institute for Informatics, Heinrich-Heine-University, Duesseldorf, Germany.
-   All right reserved.
-   Email: geliudie@uni-duesseldorf.de
- 
-   This file is part of sybilSBML.
- 
-   SybilSBML is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
- 
-   SybilSBML is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
- 
-   You should have received a copy of the GNU General Public License
-   along with sybilSBML.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "sbml.h"
-
-/* -------------------------------------------------------------------------- */
-/* help functions                                                             */
-/* -------------------------------------------------------------------------- */
-
-/* check for pointer to sbml document */
-SEXP isSBMLdocptr(SEXP ptr);
-
-/* check for pointer to sbml model */
-SEXP isSBMLmodptr(SEXP ptr);
-
-/* check for NULL pointer */
-SEXP isNULLptr(SEXP ptr);
-
-
-/* -------------------------------------------------------------------------- */
-/* API functions                                                              */
-/* -------------------------------------------------------------------------- */
-
-/* get libsbml version number (dotted version) */
-SEXP getLibSBMLversion();
-
-/* initialize sybilSBML */
-SEXP initSBML(void);
-
-/* remove sbml document pointer */
-SEXP delDocument(SEXP sbmldoc);
-
-/* remove model pointer */
-SEXP delModel(SEXP sbmlmodel);
-
-/* read SBML file */
-SEXP readSBMLfile(SEXP fname, SEXP ptrtype);
-
-/* get sbml document level */
-SEXP getSBMLlevel(SEXP sbmldoc);
-
-/* get sbml document version */
-SEXP getSBMLversion(SEXP sbmldoc);
-
-/* validate SBML document */
-SEXP validateDocument(SEXP sbmldoc);
-
-/* get SBML errors */
-SEXP getSBMLerrors(SEXP sbmldoc);
-
-/* get sbml model from sbml document */
-SEXP getSBMLmodel(SEXP sbmldoc, SEXP ptrtype);
-
-/* get model id */
-SEXP getSBMLmodId(SEXP sbmlmod);
-
-/* get model name */
-SEXP getSBMLmodName(SEXP sbmlmod);
-
-/* get number of compartments */
-SEXP getSBMLnumCompart(SEXP sbmlmod);
-
-/* get number of species (metabolites) */
-SEXP getSBMLnumSpecies(SEXP sbmlmod);
-
-/* get number of reactions */
-SEXP getSBMLnumReactions(SEXP sbmlmod);
-
-/* get list of unit definitions */
-SEXP getSBMLunitDefinitionsList(SEXP sbmlmod);
-
-/* get list of compartments */
-SEXP getSBMLCompartList(SEXP sbmlmod);
-
-/* get list of species (metabolites) */
-SEXP getSBMLSpeciesList(SEXP sbmlmod);
-
-/* get list of reactions */
-SEXP getSBMLReactionsList(SEXP sbmlmod);
+/* sybilSBML.h
+   Link to libSBML for sybil.
+ 
+   Copyright (C) 2010-2013 Gabriel Gelius-Dietrich, Dpt. for Bioinformatics,
+   Institute for Informatics, Heinrich-Heine-University, Duesseldorf, Germany.
+   All right reserved.
+   Email: geliudie@uni-duesseldorf.de
+ 
+   This file is part of sybilSBML.
+ 
+   SybilSBML is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+ 
+   SybilSBML is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+ 
+   You should have received a copy of the GNU General Public License
+   along with sybilSBML.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "sbml.h"
+
+/* -------------------------------------------------------------------------- */
+/* help functions                                                             */
+/* -------------------------------------------------------------------------- */
+
+/* check for pointer to sbml document */
+SEXP isSBMLdocptr(SEXP ptr);
+
+/* check for pointer to sbml model */
+SEXP isSBMLmodptr(SEXP ptr);
+
+/* check for NULL pointer */
+SEXP isNULLptr(SEXP ptr);
+
+
+/* -------------------------------------------------------------------------- */
+/* API functions                                                              */
+/* -------------------------------------------------------------------------- */
+
+/* get libsbml version number (dotted version) */
+SEXP getLibSBMLversion();
+
+/* initialize sybilSBML */
+SEXP initSBML(void);
+
+/* remove sbml document pointer */
+SEXP delDocument(SEXP sbmldoc);
+
+/* remove model pointer */
+SEXP delModel(SEXP sbmlmodel);
+
+/* read SBML file */
+SEXP readSBMLfile(SEXP fname, SEXP ptrtype);
+
+/* get sbml document level */
+SEXP getSBMLlevel(SEXP sbmldoc);
+
+/* get sbml document version */
+SEXP getSBMLversion(SEXP sbmldoc);
+
+/* get sbml document FBC version */
+SEXP getSBMLFbcversion(SEXP sbmldoc);
+
+/* validate SBML document */
+SEXP validateDocument(SEXP sbmldoc);
+
+/* get SBML errors */
+SEXP getSBMLerrors(SEXP sbmldoc);
+
+/* get sbml model from sbml document */
+SEXP getSBMLmodel(SEXP sbmldoc, SEXP ptrtype);
+
+/* get model id */
+SEXP getSBMLmodId(SEXP sbmlmod);
+
+/* get model name */
+SEXP getSBMLmodName(SEXP sbmlmod);
+
+/* get model notes */
+SEXP getSBMLmodNotes(SEXP sbmlmod);
+
+/* get model annotation */
+SEXP getSBMLmodAnnotation(SEXP sbmlmod);
+
+/* get number of compartments */
+SEXP getSBMLnumCompart(SEXP sbmlmod);
+
+/* get number of species (metabolites) */
+SEXP getSBMLnumSpecies(SEXP sbmlmod);
+
+/* get number of reactions */
+SEXP getSBMLnumReactions(SEXP sbmlmod);
+
+/* get list of unit definitions */
+SEXP getSBMLunitDefinitionsList(SEXP sbmlmod);
+
+/* get list of compartments */
+SEXP getSBMLCompartList(SEXP sbmlmod);
+
+/* get list of species (metabolites) */
+SEXP getSBMLSpeciesList(SEXP sbmlmod);
+
+/* get list of reactions */
+SEXP getSBMLReactionsList(SEXP sbmlmod);
+
+/* export Modelorg to SBML*/
+SEXP exportSBML (SEXP version, SEXP level,SEXP FbcLevel, SEXP filename,SEXP sybil_max, SEXP mod_desc, SEXP mod_name, SEXP mod_compart, SEXP met_id, SEXP met_name, SEXP met_comp, SEXP met_form,SEXP met_charge, SEXP react_id, SEXP react_name, SEXP react_rev, SEXP lowbnd, SEXP uppbnd, SEXP obj_coef, SEXP subSys, SEXP gpr, SEXP SMatrix, SEXP mod_notes, SEXP mod_anno, SEXP com_notes , SEXP com_anno, SEXP met_notes, SEXP met_anno, SEXP met_bnd , SEXP react_notes, SEXP react_anno, SEXP ex_react, SEXP allgenes);
\ No newline at end of file