diff --git a/DESCRIPTION b/DESCRIPTION
index 08929709bd6f4d38c9507a931eff6e3fcdfa1aea..11f273698fc94253f1925577ff4fad25235171c3 100755
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,7 +1,7 @@
 Package: RMassBank
 Type: Package
 Title: Workflow to process tandem MS files and build MassBank records
-Version: 1.5.2.4
+Version: 1.9.5.2
 Authors@R: c(
     person(given = "RMassBank at Eawag", email = "massbank@eawag.ch",
     role=c("cre")),
@@ -25,6 +25,7 @@ License: Artistic-2.0
 SystemRequirements: OpenBabel
 biocViews: Bioinformatics, MassSpectrometry, Metabolomics, Software
 Depends: Rcpp
+Encoding: UTF-8
 Imports:
     XML,RCurl,rjson, rcdk,yaml,mzR,methods,Biobase,MSnbase,S4Vectors
 Suggests:
diff --git a/NAMESPACE b/NAMESPACE
index 7bc92695c2be9109588407fc10d3bc74b45ab767..45a2b984e5fe6ec2214e2559d0fc12757189e154 100755
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -2,6 +2,7 @@
 
 export(CTS.externalIdSubset)
 export(CTS.externalIdTypes)
+export(gatherPubChem)
 export(RmbDefaultSettings)
 export(RmbSettingsTemplate)
 export(add.formula)
@@ -66,6 +67,7 @@ export(makeMollist)
 export(makeRecalibration)
 export(mbWorkflow)
 export(msmsRead)
+export(msmsRead.RAW)
 export(msmsWorkflow)
 export(multiply.formula)
 export(newMbWorkspace)
diff --git a/R/RmbWorkspace.R b/R/RmbWorkspace.R
index 402aa123304da84bfdc5523b297edceefe3ba31e..13b504bd56334dec89dc8e6d51db179935f292e3 100755
--- a/R/RmbWorkspace.R
+++ b/R/RmbWorkspace.R
@@ -224,7 +224,7 @@ loadMsmsWorkspace <- function(fileName, loadSettings = FALSE)
 		{
 			if(exists(var, envir=tempEnv))
 				slot(w, var, check=FALSE) <- tempEnv[[var]]
-			classVersion(w) <- "1.0.0"
+			classVersion(w)["msmsWorkspace"] <- "1.0.0"
 		}
 		# Check if settings exist...
 		if((loadSettings == TRUE) && exists("RmbSettings", envir=tempEnv))
@@ -306,9 +306,15 @@ setMethod("show", "msmsWorkspace",
 								return(sapply(x$msmsdata, function(x) length(unique(x$childFilt[,1]))))
 							})
 							
-							PeakMat <- matrix(dummy1-dummy2,numspecs,numspecs)
+							whichok <- which(sapply(dummy1,length) != 0)
+							anyok <- whichok[1]
 							
-							tempids <- ids
+							dummy2 <- matrix(unlist(dummy2), ncol = length(dummy1[[anyok]]), byrow = TRUE)
+							dummy1 <- matrix(unlist(dummy1), ncol = length(dummy1[[anyok]]), byrow = TRUE)
+							
+							PeakMat <- dummy1-dummy2
+							
+							tempids <- ids[whichok]
 							cat("Peaks without annotation:\n")
 							sapply(split(PeakMat, rep(1:nrow(PeakMat), each = ncol(PeakMat))), function(x){
 								cat(" -", tempids[1], "\t number of peaks filtered:", x, "\n")
@@ -362,10 +368,16 @@ setMethod("show", "msmsWorkspace",
 																		sapply(x$msmsdata, function(x) length(unique(x$childFilt[,1]))), "\n")
 																		return(sapply(x$msmsdata, function(x) length(unique(x$childFilt[,1]))))
 																	})
-																	
-							PeakMat <- matrix(dummy4-dummy5,numspecs,numspecs)
 							
-							tempids <- ids
+							whichok <- which(sapply(dummy4,length) != 0)
+							anyok <- whichok[1]
+							
+							dummy5 <- matrix(unlist(dummy5), ncol = length(dummy4[[anyok]]), byrow = TRUE)
+							dummy4 <- matrix(unlist(dummy4), ncol = length(dummy4[[anyok]]), byrow = TRUE)
+							
+							PeakMat <- dummy4-dummy5
+							
+							tempids <- ids[whichok]
 							cat("Peaks without annotation in reanalyzed recalibrated peaks:\n")
 							sapply(split(PeakMat, rep(1:nrow(PeakMat), each = ncol(PeakMat))), function(x){
 								cat(" -", tempids[1], "\t number of peaks filtered:", x, "\n")
@@ -465,7 +477,7 @@ plotMbWorkspaces <- function(w1, w2=NULL){
 			lapply(x,function(y) y[['PK$PEAK']][,c("m/z","rel.int.")])
 		})
 		plot_title <- lapply(w2@compiled_ok,function(x){
-			lapply(x,function(y) y[['RECORD_TITLE']])
+			lapply(x,function(y) y[['ACCESSION']])
 		})
 	}
 	
@@ -476,7 +488,7 @@ plotMbWorkspaces <- function(w1, w2=NULL){
 	})
 	
 	plot_title <- lapply(w1@compiled_ok,function(x){
-		lapply(x,function(y) y[['RECORD_TITLE']])
+		lapply(x,function(y) y[['ACCESSION']])
 	})
 	
 	
diff --git a/R/RmbWorkspaceUpdate.R b/R/RmbWorkspaceUpdate.R
index 36e2eb110fbd0e2f00bdf175521a41cc17043f62..df02a646b96bef27bd89b5385ef552f2d6a93bf6 100644
--- a/R/RmbWorkspaceUpdate.R
+++ b/R/RmbWorkspaceUpdate.R
@@ -36,8 +36,8 @@
 					w.parent@aggregatedRcSpecs <- list()
 					w.parent@reanalyzedRcSpecs <- list()
 					w.parent@refilteredRcSpecs <- list()
-					w.old@specs <- w.old@recalibratedSpecs
-					w.old@analyzedSpecs <- w.old@analyzedRcSpecs
+					slot(w.old, "specs", check=FALSE) <- w.old@recalibratedSpecs
+					slot(w.old, "analyzedSpecs", check=FALSE) <- w.old@analyzedRcSpecs
 					w.parent.new <- updateObject(w.parent)
 					w.new@parent <- w.parent.new
 				}
@@ -58,7 +58,7 @@
 				set <- new("RmbSpectraSet")
 				# identifiers and properties
 				set@mz <- spec$mz$mzCenter
-				set@id <- as.integer(spec$id)
+				set@id <- as.character(as.integer(spec$id))
 				set@formula <- spec$formula
 				set@found <- as.logical(spec$foundOK)
 				# now parent and child MS
diff --git a/R/createMassBank.R b/R/createMassBank.R
index 600e1880f4d8ac22c75ab0afabacd6fa18ff42ee..d4ba4c191960280639c61c6b8063a2d3329c30ac 100755
--- a/R/createMassBank.R
+++ b/R/createMassBank.R
@@ -52,6 +52,19 @@ loadInfolist <- function(mb, fileName)
   # Legacy check for loading the Uchem format files.
   # Even if dbname_* are not used downstream of here, it's still good to keep them
   # for debugging reasons.
+  n <- colnames(mbdata_new)
+  cols <- c("id","dbcas","dataused")
+  
+  # Check if comma-separated or semicolon-separated
+  d <- setdiff(cols, n)
+  if(length(d)>0){
+		mbdata_new <- read.csv2(fileName, stringsAsFactors=FALSE)
+		n <- colnames(mbdata_new)
+		d2 <- setdiff(cols, n)
+		if(length(d2) > 0){
+			stop("Some columns are missing in the infolist.")
+		}
+	}
   if("dbname_d" %in% colnames(mbdata_new))
   {
     colnames(mbdata_new)[[which(colnames(mbdata_new)=="dbname_d")]] <- "dbname"
@@ -119,7 +132,7 @@ resetInfolists <- function(mb)
 #' Steps:
 #' 
 #' Step 1: Find which compounds don't have annotation information yet. For these
-#' 		 compounds, pull information from CTS (using gatherData).
+#' 		 compounds, pull information from several databases (using gatherData).
 #' 
 #' Step 2: If new compounds were found, then export the infolist.csv and stop the workflow.
 #' 		Otherwise, continue.
@@ -147,6 +160,9 @@ resetInfolists <- function(mb)
 #' @param infolist_path A path where to store newly downloaded compound informations,
 #' 			which should then be manually inspected.
 #' @param mb The \code{mbWorkspace} to work in.
+#' @param gatherData A variable denoting whether to retrieve information using several online databases \code{gatherData= "online"}
+#' or to use the local babel installation \code{gatherData= "babel"}. Note that babel is used either way, if a directory is given 
+#' in the settings
 #' @return The processed \code{mbWorkspace}.
 #' @seealso \code{\link{mbWorkspace-class}}
 #' @author Michael A. Stravs, Eawag <michael.stravs@@eawag.ch>
@@ -157,22 +173,30 @@ resetInfolists <- function(mb)
 #' 		
 #' }
 #' @export
-mbWorkflow <- function(mb, steps=c(1,2,3,4,5,6,7,8), infolist_path="./infolist.csv")
+mbWorkflow <- function(mb, steps=c(1,2,3,4,5,6,7,8), infolist_path="./infolist.csv", gatherData = "online")
 {
   # Step 1: Find which compounds don't have annotation information yet. For these
   # compounds, pull information from CTS (using gatherData).
   if(1 %in% steps)
   {
       mbdata_ids <- lapply(mb@aggregatedRcSpecs$specFound, function(spec) spec$id)
-	  
-	  message("mbWorkflow: Step 1. Gather info from CTS")
-	  
+	  if(gatherData == "online"){
+		message("mbWorkflow: Step 1. Gather info from several databases")
+	  } 
+	  if(gatherData == "babel"){
+		message("mbWorkflow: Step 1. Gather info using babel")
+	  }
       # Which IDs are not in mbdata_archive yet?
       new_ids <- setdiff(as.numeric(unlist(mbdata_ids)), mb@mbdata_archive$id)
       mb@mbdata <- lapply(new_ids, function(id) 
       {
         #print(id)
-        d <- gatherData(id)
+		if(gatherData == "online"){
+			d <- gatherData(id)
+		} 
+		if(gatherData == "babel"){
+			d <- gatherDataBabel(id)
+		}
         #print(d$dataused)
 		message(paste(id, ": ", d$dataused, sep=''))
         return(d)
@@ -324,10 +348,78 @@ createMolfile <- function(id_or_smiles, fileName = FALSE)
 	return(res)
 }
 
-# Retrieve annotation data for a compound, from the internet services Cactvs and CTS.
+
+
+# Retrieve annotation data for a compound, from the internet service Pubchem
+#' Retrieve supplemental annotation data from Pubchem
+#' 
+#' Retrieves annotation data for a compound from the internet service Pubchem 
+#' based on the inchikey generated by babel or Cactus
+#' 
+#' The data retrieved is the Pubchem CID, a synonym from the Pubchem database,
+#' the IUPAC name (using the preferred if available) and a Chebi link
+#' 
+#' @usage gatherPubChem(key)
+#' @param key An Inchi-Key
+#' @return Returns a list with 4 slots:
+#' \code{PcID} The Pubchem CID
+#' \code{Synonym} An arbitrary synonym for the compound name
+#' \code{IUPAC} A IUPAC-name (preferred if available)
+#' \code{Chebi} The identification number of the chebi database
+#' @author Erik Mueller
+#' @seealso \code{\link{mbWorkflow}}
+#' @references Pubchem REST:
+#' \url{https://pubchem.ncbi.nlm.nih.gov/pug_rest/PUG_REST.html}
+#' Chebi:
+#' \url{http://www.ebi.ac.uk/chebi}
+#' @examples
+#' 
+#' # Gather data for compound ID 131
+#' \dontrun{gatherPubChem("QEIXBXXKTUNWDK-UHFFFAOYSA-N")}
+#' 
+#' @export
+gatherPubChem <- function(key){
+	
+	PubChemData <- list()
+	
+	##Trycatches are there because pubchem has connection issues 1 in 50 times.
+	##Write NA into the respective fields if something goes wrong with the conenction or the data.
+	
+	##Retrieve Pubchem CID
+	tryCatch(
+		PubChemData$PcID <- getPcId(key),
+		error=function(e){
+		PubChemData$PcID <<- NA
+	})
+	
+	##Retrieve a synonym to the name
+	tryCatch(
+		PubChemData$Synonym <- getPcSynonym(key),
+		error=function(e){
+		PubChemData$Synonym <<- NA
+	})
+	
+	##Retrieve the IUPAC-name
+	tryCatch(
+		PubChemData$IUPAC <- getPcIUPAC(key),
+		error=function(e){
+		PubChemData$IUPAC <<- NA
+	})
+	
+	##Retrieve the Chebi-ID
+	tryCatch(
+		PubChemData$Chebi <- getPcCHEBI(key),
+		error=function(e){
+		PubChemData$Chebi <<- NA
+	})
+	
+	return(PubChemData)
+}
+
+# Retrieve annotation data for a compound, from the internet services Cactvs, Pubchem, Chemspider and CTS.
 #' Retrieve annotation data
 #' 
-#' Retrieves annotation data for a compound from the internet services CTS and
+#' Retrieves annotation data for a compound from the internet services CTS, Pubchem, Chemspider and
 #' Cactvs, based on the SMILES code and name of the compounds stored in the
 #' compound list.
 #' 
@@ -343,16 +435,22 @@ createMolfile <- function(id_or_smiles, fileName = FALSE)
 #' inserted empty and will be filled later on.
 #' 
 #' @usage gatherData(id)
+#' @aliases gatherData
 #' @param id The compound ID.
 #' @return Returns a list of type \code{list(id= \var{compoundID}, ...,
 #' 'ACCESSION' = '', 'RECORD_TITLE' = '', )} etc. %% ...
 #' @author Michael Stravs
 #' @seealso \code{\link{mbWorkflow}}
 #' @references Chemical Translation Service:
-#' \url{http://uranus.fiehnlab.ucdavis.edu:8080/cts/homePage} cactus Chemical
-#' Identifier Resolver: \url{http://cactus.nci.nih.gov/chemical/structure}
+#' \url{http://uranus.fiehnlab.ucdavis.edu:8080/cts/homePage} 
+#' cactus Chemical Identifier Resolver: 
+#' \url{http://cactus.nci.nih.gov/chemical/structure}
 #' MassBank record format:
 #' \url{http://www.massbank.jp/manuals/MassBankRecord_en.pdf}
+#' Pubchem REST:
+#' \url{https://pubchem.ncbi.nlm.nih.gov/pug_rest/PUG_REST.html}
+#' Chemspider InChI conversion:
+#' \url{https://www.chemspider.com/InChI.asmx}
 #' @examples
 #' 
 #' # Gather data for compound ID 131
@@ -361,106 +459,81 @@ createMolfile <- function(id_or_smiles, fileName = FALSE)
 #' @export
 gatherData <- function(id)
 { 
+	##Preamble: Is a babeldir supplied?
+	##If yes, use it
+	
 	.checkMbSettings()
+	usebabel=TRUE
+	babeldir <- getOption("RMassBank")$babeldir
+	
+	if(is.na(babeldir)){
+		usebabel=FALSE
+	}
+	
+	
+	##Get all useful information from the local "database" (from the CSV sheet)
 	
-	# Get all useful information from the local "database" (from the CSV sheet)
 	smiles <- findSmiles(id)
 	mass <- findMass(smiles)
 	dbcas <- findCAS(id)
 	dbname <- findName(id)
 	if(is.na(dbname)) dbname <- ""
+	if(is.na(dbcas)) dbcas <- ""
+	iupacName <- dbname
+	synonym <- dbname
 	formula <- findFormula(id)
-	# Convert SMILES to InChI key via Cactvs. CTS doesn't "interpret" the SMILES per se,
-	# it just matches identical known SMILES, so we need to convert to a "searchable" and
-	# standardized format beforehand.
-	inchikey <- getCactus(smiles, 'stdinchikey')
-	dataUsed <- "dbname"
 	
-	# Check whether we found a useful inchikey. If not, we will have to use the database
-	# name as search criterion.
-	if(!is.na(inchikey))
-	{
-		# Split the "InChiKey=" part off the key
+	##Convert SMILES to InChI key via Cactvs or babel. CTS doesn't "interpret" the SMILES per se,
+	##it just matches identical known SMILES, so we need to convert to a "searchable" and
+	##standardized format beforehand. Other databases are able to interpret the smiles.
+	
+	if(usebabel){
+		cmdinchikey <- paste0(babeldir, 'obabel -:"',smiles,'" ', '-oinchikey')
+		inchikey_split <- system(cmdinchikey, intern=TRUE, input=smiles, ignore.stderr=TRUE)
+	} else{
+		inchikey <- getCactus(smiles, 'stdinchikey')
+		##Split the "InChiKey=" part off the key
 		inchikey_split <- strsplit(inchikey, "=", fixed=TRUE)[[1]][[2]]
-		# Actually retrieve data from CTS (see the webaccess scripts)
-		infos <- getCtsRecord(inchikey_split)
-		
-		if(length(infos) == 0)
-			dataUsed <- "dbname"
-		else
-			dataUsed <- "smiles"
-		
-		## storedName <- infos$Name
-		## # Check if the name was found. If yes, OK. Otherwise, search again using
-		## # the DB name as start
-		## 
-		## if(nrow(infos$names) == 0 | length(infos$names) == 0)
-		##   dataUsed <- "dbname"
-		## if(storedName %in% c('Unknown','None'))
-		##   dataUsed <- "dbname"
 	}
 	
-	# if dataUsed is "dbname" here, this means we must find a better SMILES and
-	# regenerate the InChI key since the old one was not found in CTS.
-	if(dataUsed == "dbname")
-	{
-		infos <- getCtsKey(dbname, from="Chemical Name", to="InChIKey")
-		# heuristically determine best InChI key to use:
-		# use the one with most common Structure part,
-		# and use the one with no stereochemistry and neutral charge if possible
-		keys <- as.data.frame(infos)
-		subkeys <- strsplit(infos, ',')
-		df <- do.call(rbind,subkeys)
-		keys$structure <- df[,1]
-		keys$stereo <- df[,2]
-		keys$charge <- df[,3]
-		# most frequent structure part:
-		freq <- aggregate(keys$keys, by=list(keys$structure), length)
-		structure <- freq[which.max(freq[,"x"]),"Group.1"]
-		keys <- keys[keys$structure == structure,]
-		# put stereofree compounds first, then neutral compounds first
-		keys$Vst <- factor(keys$stereo, levels="UHFFFAOYSA")
-		keys$Vchg <- factor(keys$charge, levels="N")
-		keys <- keys[order(keys$Vst, keys$Vchg, na.last=T),]
-		# get key, at last
-		inchikey_split <- keys[1,"keys"]
-		
-		# get full dataset from CTS
-		inchikey_split <- infos$inchikey
-		infos <- getCtsRecord(inchikey_split)
-		# InChIcode to SMILES using CACTUS. Should never fail since it's a conversion
-		# of structure representations
-		smiles <- getCactus(infos$inchicode, 'smiles')
-		
+	##Use Pubchem to retrieve information
+	PcInfo <- gatherPubChem(inchikey_split)
+	
+	if(!is.null(PcInfo$Synonym) & !is.na(PcInfo$Synonym)){
+		synonym <- PcInfo$Synonym
 	}
 	
-	# Get ChemSpider ID from Cactvs, because it doesn't work properly from CTS
-	csid <- getCactus(inchikey_split, 'chemspider_id')
+	if(!is.null(PcInfo$IUPAC) & !is.na(PcInfo$IUPAC)){
+		iupacName <- PcInfo$IUPAC
+	}
 	
-	# Name sorting:
-	# TODO: when scoring is reimplemented in CTS, use scoring.
-	# in the meantime, we use the user-given name plus one systematic name ex CTS
-        ipreferred <- integer()
-        if (length(infos$synonyms) >0) {
-          ipreferred <- which(unlist(lapply(infos$synonyms, function(s) s$type == "IUPAC Name (Preferred)")))
-        }
-	if(length(ipreferred) == 0)
-	{
-		# no iupac in cts, find iupac from cactus
-		iupacName <- getCactus(infos$inchicode, 'iupac_name')
-		if(is.na(iupacName))
-		{
-			iupacName <- NULL
-			warning(paste0("Compound ID ",id,": no IUPAC name could be identified."))
-		}
+	##Get Chemspider-ID
+	csid <- getCSID(inchikey_split)
+	
+	if(is.na(csid)){
+		##Get ChemSpider ID from Cactus if the Chemspider page is down
+		csid <- getCactus(inchikey_split, 'chemspider_id')
 	}
-	else
+	
+	##Use CTS to retrieve information
+	CTSinfo <- getCtsRecord(inchikey_split)
+		
+	if((CTSinfo[1] == "Sorry, we couldn't find any matching results") || is.null(CTSinfo[1]))
 	{
-		iupacName <-infos$synonyms[[ipreferred[[1]]]][["name"]]
+		CTSinfo <- NA
 	}
-	# Eliminate duplicate names from our list of 3
-	names <- as.list(unique(c(dbname, iupacName)))
 	
+	##List the names
+	if(iupacName == ""){
+		warning(paste0("Compound ID ",id,": no IUPAC name could be identified."))
+	}
+	
+	names <- as.list(unique(c(dbname, synonym, iupacName)))
+	
+	##If no name is found, it must be supplied in one way or another
+	if(all(sapply(names, function(x) x == ""))){
+		stop("RMassBank wasn't able to extract a usable name for this compound from any database. Please supply a name manually.")
+	}
 	
 	# Start to fill the MassBank record.
 	# The top 4 entries will not go into the final record; they are used to identify
@@ -469,7 +542,7 @@ gatherData <- function(id)
 	mbdata[['id']] <- id
 	mbdata[['dbcas']] <- dbcas
 	mbdata[['dbname']] <- dbname
-	mbdata[['dataused']] <- dataUsed
+	mbdata[['dataused']] <- "smiles"
 	mbdata[['ACCESSION']] <- ""
 	mbdata[['RECORD_TITLE']] <- ""
 	mbdata[['DATE']] <- format(Sys.Date(), "%Y.%m.%d")
@@ -492,45 +565,81 @@ gatherData <- function(id)
 	mbdata[['CH$FORMULA']] <- formula
 	mbdata[['CH$EXACT_MASS']] <- mass
 	mbdata[['CH$SMILES']] <- smiles
-	mbdata[['CH$IUPAC']] <- infos$inchicode
+	
+	if(usebabel){
+		cmdinchi <- paste0(babeldir, 'obabel -:"',smiles,'" ', '-oinchi')
+		mbdata[['CH$IUPAC']] <- system(cmdinchi, intern=TRUE, input=smiles, ignore.stderr=TRUE)
+	} else{
+		mbdata[['CH$IUPAC']] <- getCactus(smiles, "stdinchi")
+	}
+	
+
 	
 	# Add all CH$LINK fields present in the compound datasets
 	link <- list()
 	# CAS
-	if("CAS" %in% CTS.externalIdTypes(infos))
-	{
-		# Prefer database CAS if it is also listed in the CTS results.
-		# otherwise take the shortest one.
-		cas <- CTS.externalIdSubset(infos,"CAS")
-		if(dbcas %in% cas)
+	if(!is.na(CTSinfo[1])){
+		if("CAS" %in% CTS.externalIdTypes(CTSinfo))
+		{
+			# Prefer database CAS if it is also listed in the CTS results.
+			# otherwise take the shortest one.
+			cas <- CTS.externalIdSubset(CTSinfo,"CAS")
+			if(dbcas %in% cas)
+				link[["CAS"]] <- dbcas
+			else
+				link[["CAS"]] <- cas[[which.min(nchar(cas))]]
+		} else{
+			if(dbcas != ""){
+				link[["CAS"]] <- dbcas
+			}
+		}
+	} else{
+		if(dbcas != ""){
 			link[["CAS"]] <- dbcas
-		else
-			link[["CAS"]] <- cas[[which.min(nchar(cas))]]
+		}
 	}
+	
+	
 	# CHEBI
-	if("ChEBI" %in% CTS.externalIdTypes(infos))
-	{
-		# Cut off front "CHEBI:" if present
-		chebi <- CTS.externalIdSubset(infos,"ChEBI")
+	if(is.na(PcInfo$Chebi[1])){
+		if(!is.na(CTSinfo[1])){
+			if("ChEBI" %in% CTS.externalIdTypes(CTSinfo))
+			{
+				# Cut off front "CHEBI:" if present
+				chebi <- CTS.externalIdSubset(CTSinfo,"ChEBI")
+				chebi <- chebi[[which.min(nchar(chebi))]]
+				chebi <- strsplit(chebi,":")[[1]]
+				link[["CHEBI"]] <- chebi[[length(chebi)]]
+			}
+		}
+	} else{
+		chebi <- PcInfo$Chebi
 		chebi <- chebi[[which.min(nchar(chebi))]]
 		chebi <- strsplit(chebi,":")[[1]]
-		chebi <- chebi[[length(chebi)]]
+		link[["CHEBI"]] <- chebi[[length(chebi)]]
 	}
-	
 	# HMDB
-	if("HMDB" %in% CTS.externalIdTypes(infos))
-		link[["HMDB"]] <- CTS.externalIdSubset(infos,"HMDB")[[1]]
-	# KEGG
-	if("KEGG" %in% CTS.externalIdTypes(infos))
-		link[["KEGG"]] <- CTS.externalIdSubset(infos,"KEGG")[[1]]
-	# LipidMAPS
-	if("LipidMAPS" %in% CTS.externalIdTypes(infos))
-		link[["LIPIDMAPS"]] <- CTS.externalIdSubset(infos,"LipidMAPS")[[1]]
+	if(!is.na(CTSinfo[1])){
+		if("HMDB" %in% CTS.externalIdTypes(CTSinfo))
+			link[["HMDB"]] <- CTS.externalIdSubset(CTSinfo,"HMDB")[[1]]
+		# KEGG
+		if("KEGG" %in% CTS.externalIdTypes(CTSinfo))
+			link[["KEGG"]] <- CTS.externalIdSubset(CTSinfo,"KEGG")[[1]]
+		# LipidMAPS
+		if("LipidMAPS" %in% CTS.externalIdTypes(CTSinfo))
+			link[["LIPIDMAPS"]] <- CTS.externalIdSubset(CTSinfo,"LipidMAPS")[[1]]
+	}
 	# PubChem CID
-	if("PubChem CID" %in% CTS.externalIdTypes(infos))
-	{
-		pc <- CTS.externalIdSubset(infos,"PubChem CID")
-		link[["PUBCHEM"]] <- paste0("CID:",min(pc))
+	if(is.na(PcInfo$PcID[1])){
+		if(!is.na(CTSinfo[1])){
+			if("PubChem CID" %in% CTS.externalIdTypes(CTSinfo))
+			{
+				pc <- CTS.externalIdSubset(CTSinfo,"PubChem CID")
+				link[["PUBCHEM"]] <- paste0("CID:",min(pc))
+			}
+		}
+	} else{
+		link[["PUBCHEM"]] <- PcInfo$PcID[1]
 	}
 	link[["INCHIKEY"]] <- inchikey_split
 	if(length(csid)>0) if(any(!is.na(csid))) link[["CHEMSPIDER"]] <- min(as.numeric(as.character(csid)))
@@ -540,9 +649,109 @@ gatherData <- function(id)
 	mbdata[['AC$INSTRUMENT_TYPE']] <- getOption("RMassBank")$annotations$instrument_type
 	
 	return(mbdata)  
-} # function gather.mbdata
-
+}
 
+# Retrieve annotation data for a compound, using only babel
+#' Retrieve annotation data
+#' 
+#' Retrieves annotation data for a compound by using babel,
+#' based on the SMILES code and name of the compounds stored in the
+#' compound list.
+#' 
+#' Composes the "upper part" of a MassBank record filled with chemical data
+#' about the compound: name, exact mass, structure, CAS no..  
+#' The instrument type is also written into this block (even
+#' if not strictly part of the chemical information). Additionally, index
+#' fields are added at the start of the record, which will be removed later:
+#' \code{id, dbcas, dbname} from the compound list.
+#' 
+#' Additionally, the fields \code{ACCESSION} and \code{RECORD_TITLE} are
+#' inserted empty and will be filled later on.
+#' 
+#' This function is an alternative to gatherData, in case CTS is down or if information
+#' on one or more of the compounds in the compound list are sparse
+#'
+#' @usage gatherDataBabel(id)
+#' @param id The compound ID.
+#' @return Returns a list of type \code{list(id= \var{compoundID}, ...,
+#' 'ACCESSION' = '', 'RECORD_TITLE' = '', )} etc. %% ...
+#' @author Michael Stravs, Erik Mueller
+#' @seealso \code{\link{mbWorkflow}}
+#' @references MassBank record format:
+#' \url{http://www.massbank.jp/manuals/MassBankRecord_en.pdf}
+#' @examples
+#' 
+#' # Gather data for compound ID 131
+#' \dontrun{gatherDataBabel(131)}
+#' 
+#' @export
+gatherDataBabel <- function(id){
+		.checkMbSettings()
+		babeldir <- getOption("RMassBank")$babeldir
+		smiles <- findSmiles(id)
+			
+		
+		# if no babeldir was set, throw an error that says that either CTS or babel have to be used
+		if(is.na(babeldir))
+		{
+			stop("No babeldir supplied; It is currently not possible to convert the information without either babel or CTS")
+		} else {
+			###Babel conversion
+			cmdinchikey <- paste0(babeldir, 'obabel -:"',smiles,'" ', '-oinchikey')
+			inchikey <- system(cmdinchikey, intern=TRUE, input=smiles, ignore.stderr=TRUE)
+			cmdinchi <- paste0(babeldir, 'obabel -:"',smiles,'" ', '-oinchi')
+			inchi <- system(cmdinchi, intern=TRUE, input=smiles, ignore.stderr=TRUE)
+			
+			##Read from Compoundlist
+			smiles <- findSmiles(id)
+			mass <- findMass(smiles)
+			dbcas <- findCAS(id)
+			dbname <- findName(id)
+			if(is.na(dbname)) dbname <- ""
+			if(is.na(dbcas)) dbcas <- ""
+			formula <- findFormula(id)
+			
+			##Create 
+			mbdata <- list()
+			mbdata[['id']] <- id
+			mbdata[['dbcas']] <- dbcas
+			mbdata[['dbname']] <- dbname
+			mbdata[['dataused']] <- "smiles"
+			mbdata[['ACCESSION']] <- ""
+			mbdata[['RECORD_TITLE']] <- ""
+			mbdata[['DATE']] <- format(Sys.Date(), "%Y.%m.%d")
+			mbdata[['AUTHORS']] <- getOption("RMassBank")$annotations$authors
+			mbdata[['LICENSE']] <- getOption("RMassBank")$annotations$license
+			mbdata[['COPYRIGHT']] <- getOption("RMassBank")$annotations$copyright
+			# Confidence annotation and internal ID annotation.
+			# The ID of the compound will be written like:
+			# COMMENT: EAWAG_UCHEM_ID 1234
+			# if annotations$internal_id_fieldname is set to "EAWAG_UCHEM_ID"
+			mbdata[["COMMENT"]] <- list()
+			mbdata[["COMMENT"]][["CONFIDENCE"]] <- getOption("RMassBank")$annotations$confidence_comment
+			mbdata[["COMMENT"]][["ID"]] <- id
+			# here compound info starts
+			mbdata[['CH$NAME']] <- as.list(dbname)
+			
+			# Currently we use a fixed value for Compound Class, since there is no useful
+			# convention of what should go there and what shouldn't, and the field is not used
+			# in search queries.
+			mbdata[['CH$COMPOUND_CLASS']] <- getOption("RMassBank")$annotations$compound_class
+			mbdata[['CH$FORMULA']] <- formula
+			mbdata[['CH$EXACT_MASS']] <- mass
+			mbdata[['CH$SMILES']] <- smiles
+			mbdata[['CH$IUPAC']] <- inchi
+			
+			link <- list()
+			if(dbcas != "")
+			link[["CAS"]] <- dbcas
+			link[["INCHIKEY"]] <- inchikey
+			mbdata[['CH$LINK']] <- link
+			mbdata[['AC$INSTRUMENT']] <- getOption("RMassBank")$annotations$instrument
+			mbdata[['AC$INSTRUMENT_TYPE']] <- getOption("RMassBank")$annotations$instrument_type
+		}
+		return(mbdata)
+}
 
 
 # Flatten the internal tree-like representation of MassBank data to a flat table.
@@ -798,7 +1007,8 @@ gatherCompound <- function(spec, refiltered, additionalPeaks = NULL)
     "mH" = "NEGATIVE",
     "mFA" = "NEGATIVE",
     "pM" = "POSITIVE",
-    "mM" = "NEGATIVE")
+    "mM" = "NEGATIVE",
+	"pNH4" = "POSITIVE")
   mode <- ion_modes[[imode]]
   
   # for format 2.01
@@ -859,7 +1069,8 @@ gatherSpectrum <- function(spec, msmsdata, ac_ms, ac_lc, refiltered, additionalP
     "mH" = "[M-H]-",
     "mFA" = "[M+HCOO-]-",
     "pM" = "[M]+",
-    "mM" = "[M]-")
+    "mM" = "[M]-",
+	"pNH4" = "[M+NH4]+")
   ac_ms[['FRAGMENTATION_MODE']] <- msmsdata$info$mode
   #ac_ms['PRECURSOR_TYPE'] <- precursor_types[spec$mode]
   ac_ms[['COLLISION_ENERGY']] <- msmsdata$info$ce
@@ -974,7 +1185,8 @@ gatherSpectrum <- function(spec, msmsdata, ac_ms, ac_lc, refiltered, additionalP
     "mH" = "-",
     "mFA" = "-",
     "pM" = "+",
-    "mM" = "-")
+    "mM" = "-",
+	"pNH4" = "+")
   type <- formula_tag[[spec$mode]]
   
   annotator <- getOption("RMassBank")$annotator
@@ -1551,6 +1763,8 @@ addPeaks <- function(mb, filename_or_dataframe)
 	cols <- c("cpdID", "scan", "mzFound", "int", "OK")
 	
 	n <- colnames(df)
+	
+	# Check if comma-separated or semicolon-separated
 	d <- setdiff(cols, n)
 	
 	if(length(d)>0){
diff --git a/R/leCsvAccess.R b/R/leCsvAccess.R
index 8f52b7b31f4dc719ee76d3d73f57e9463ecdce43..bbe5fa5e25217c9a571cd1a4b1e078d8e2936966 100755
--- a/R/leCsvAccess.R
+++ b/R/leCsvAccess.R
@@ -8,17 +8,20 @@ assign("listEnv", NULL, envir=.listEnvEnv)
 #' 
 #' The list is loaded into the variable \code{\var{compoundList}} in the environment
 #' \code{listEnv} (which defaults to the global environment) and used by
-#' the \code{findMz}, \code{findCAS}, ... functions.
+#' the \code{findMz}, \code{findCAS}, ... functions. The CSV file is required to have at least the following columns, which are used for 
+#' further processing and must be named correctly (but present in any order): \var{ID, Name, SMILES, RT,
+#' CAS}
 #' 
 #' resetList() clears a currently loaded list.
 #' 
 #' @aliases loadList resetList
-#' @usage loadList(path, listEnv=NULL)
+#' @usage loadList(path, listEnv=NULL, check=TRUE)
 #' 
-#' 			resetList()
+#' resetList()
 #' @param path Path to the CSV list.
 #' @param listEnv The environment to load the list into. By default, the namelist is loaded
 #' 		into an environment internally in RMassBank. 
+#' @param check A parameter that specifies whether the SMILES-Codes in the list should be checked for readability by rcdk.
 #' @return No return value.
 #' @author Michael Stravs
 #' @seealso \code{\link{findMz}}
@@ -28,29 +31,52 @@ assign("listEnv", NULL, envir=.listEnvEnv)
 #' \dontrun{loadList("mylist.csv")}
 #' 
 #' @export
-loadList <- function(path, listEnv = NULL)
+loadList <- function(path, listEnv = NULL, check = TRUE)
 {
 	if(is.null(listEnv))
 		listEnv <- .listEnvEnv
 	if(!file.exists(path))
 		stop("The supplied file does not exist, please supply a correct path")
-  compoundList <- read.csv(path, stringsAsFactors=FALSE)
-  # check whether the necessary columns are present
-  n <- colnames(compoundList)
-  cols <- c('ID', 'Name', 'SMILES', 'RT', 'CAS')
-  d <- setdiff(cols, n)
-  if(length(d)>0){
+	compoundList <- read.csv(path, stringsAsFactors=FALSE)
+	# check whether the necessary columns are present
+	n <- colnames(compoundList)
+	cols <- c('ID', 'Name', 'SMILES', 'RT', 'CAS')
+	d <- setdiff(cols, n)
+	if(length(d)>0){
 		compoundList <- read.csv2(path, stringsAsFactors=FALSE)
 		n <- colnames(compoundList)
 		d2 <- setdiff(cols, n)
 		if(length(d2) > 0){
-			stop("Some columns are missing in the compound list. Needs at least ID, Name, SMILES, RT.")
+			stop("Some columns are missing in the compound list. Needs at least ID, Name, SMILES, RT, CAS.")
+		}
+	}
+
+	
+	if(length(duplicated(compoundList$cpdID)) > 0)
+		stop("Duplicate compound IDs are present. Please check your list.")
+	assign("listEnv", listEnv, envir=.listEnvEnv) 
+	.listEnvEnv$listEnv$compoundList <- compoundList
+	
+	
+	###
+	###Test if all the IDs work
+	###
+	
+	if(check){
+		wrongID <- vector()
+		currEnvir <- environment()
+		sapply(compoundList[,"ID"], function(x){
+			tryCatch(
+				findMz(x),
+				error = function(e){
+					currEnvir$wrongID <- c(currEnvir$wrongID, x)
+				}
+			)
+		})
+		if(length(wrongID)){
+			stop(paste("Unable to interpret the SMILES-strings for ID(s)", paste(wrongID, collapse= " "), "\nPlease check these and load the list again."))
 		}
 	}
-  if(length(duplicated(compoundList$cpdID)) > 0)
-      stop("Duplicate compound IDs are present. Please check your list.")
-  assign("listEnv", listEnv, envir=.listEnvEnv) 
-  .listEnvEnv$listEnv$compoundList <- compoundList
 }
 
 #' @export
@@ -104,8 +130,8 @@ getMolecule <- function(smiles)
 #' Find the exact mass +/- a given margin for a given formula or its ions and adducts.
 #' 
 #' @param formula The molecular formula  in text or list format (see \code{\link{formulastring.to.list}}
-#' @param mode \code{"pH", "pNa", "pM", "mH", "mM", "mFA"} for different ions 
-#' 			([M+H]+, [M+Na]+, [M]+, [M-H]-, [M]-, [M+FA]-). "" for the uncharged molecule.
+#' @param mode \code{"pH", "pNa", "pM", "pNH4", "mH", "mM", "mFA"} for different ions 
+#' 			([M+H]+, [M+Na]+, [M]+, [M+NH4]+, [M-H]-, [M]-, [M+FA]-). "" for the uncharged molecule.
 #' @param ppm The ppm margin to add/subtract
 #' @param deltaMz The absolute mass to add/subtract. Cumulative with \code{ppm}
 #' @return A \code{list(mzMin=, mzCenter=, mzMax=)} with the masses.
@@ -115,11 +141,12 @@ getMolecule <- function(smiles)
 #' @export
 findMz.formula <- function(formula, mode="pH", ppm=10, deltaMz=0)
 {
-	if(!any(mode %in% c("pH","pNa","pM","mH","mFA","mM",""))) stop(paste("The ionization mode", mode, "is unknown."))
+	if(!any(mode %in% c("pH","pNa","pM","pNH4","mH","mFA","mM",""))) stop(paste("The ionization mode", mode, "is unknown."))
 	mzopt <- list(addition="", charge=0)
 	if(mode=="pH") mzopt <- list(addition="H", charge=1)
 	if(mode=="pNa") mzopt <- list(addition="Na", charge=1)
 	if(mode=="pM") mzopt <- list(addition="", charge=1)
+	if(mode=="pNH4") mzopt <- list(addition="NH4", charge=-1)
 	if(mode=="mH") mzopt <- list(addition="H-1", charge=-1)
 	if(mode=="mFA") mzopt <- list(addition="C1O2", charge=-1)
 	if(mode=="mM") mzopt <- list(addition="", charge=-1)
diff --git a/R/leMsMs.r b/R/leMsMs.r
index fe78544b19070bad3f95c534f2c5054f72410e18..34d9285ac37d76e7b334ec0a497f9e871b65dc48 100755
--- a/R/leMsMs.r
+++ b/R/leMsMs.r
@@ -88,87 +88,22 @@ msmsWorkflow <- function(w, mode="pH", steps=c(1:8), confirmMode = FALSE, newRec
   nProg <- 0
   nLen <- length(w@files)
   
+  if(readMethod == "minimal"){
+	##Edit options
+	opt <- getOption("RMassBank")
+	opt$recalibrator$MS1 <- "recalibrate.identity"
+	opt$recalibrator$MS2 <- "recalibrate.identity"
+	options(RMassBank=opt)
+	##Edit analyzemethod
+	analyzeMethod <- "intensity"
+  }
+
   # Step 1: acquire all MSMS spectra from files
   if(1 %in% steps)
   {
-	if(readMethod == "mzR"){
-		nProg <- 0
-		message("msmsWorkflow: Step 1. Acquire all MSMS spectra from files")
-		pb <- do.call(progressbar, list(object=NULL, value=0, min=0, max=nLen))
-		w@spectra <- as(lapply(w@files, function(fileName) {
-			
-			# Find compound ID
-			splitfn <- strsplit(fileName,'_')
-			splitsfn <- splitfn[[1]]
-			cpdID <- splitsfn[[length(splitsfn)-1]]
-			# Retrieve spectrum data
-			spec <- findMsMsHR(fileName, cpdID, mode, confirmMode, useRtLimit,
-		 		ppmFine = settings$findMsMsRawSettings$ppmFine,
-		 		mzCoarse = settings$findMsMsRawSettings$mzCoarse,
-		 		fillPrecursorScan = settings$findMsMsRawSettings$fillPrecursorScan,
-		 		rtMargin = settings$rtMargin,
-		 		deprofile = settings$deprofile)
-			gc()
-		
-			# Progress:
-			nProg <<- nProg + 1
-			pb <- do.call(progressbar, list(object=pb, value= nProg))
-		
-			return(spec)
-		} ), "SimpleList")
-		names(w@spectra) <- basename(as.character(w@files))
-		# close progress bar
-		do.call(progressbar, list(object=pb, close=TRUE))
-	}
-	
-	if(readMethod == "xcms"){
-		splitfn <- strsplit(w@files,'_')
-		cpdIDs <- sapply(splitfn, function(splitted){as.numeric(return(splitted[length(splitted)-1]))})
-		files <- list()
-		wfiles <- vector()
-			for(i in 1:length(unique(cpdIDs))) {
-			indices <- sapply(splitfn,function(a){return(unique(cpdIDs)[i] %in% a)})
-			files[[i]] <- w@files[indices]
-		}
-		
-		w@files <- sapply(files,function(files){return(files[1])})
-		
-		for(i in 1:length(unique(cpdIDs))){
-			specs <- list()
-			for(j in 1:length(files[[i]])){
-				specs[[j]] <- findMsMsHRperxcms.direct(files[[i]][j], unique(cpdIDs)[i], mode=mode, findPeaksArgs=findPeaksArgs, plots, MSe=MSe)
-			}
-			w@specs[[i]] <- unlist(specs,recursive=FALSE)
-		}
-		w@specs <- unlist(w@specs, recursive=FALSE)
-		names(w@specs) <- basename(as.character(w@files))
-	}
-	
-	##if(readMethod == "MassBank"){
-	##	for(i in 1:length(w@files)){
-	##		w <- addMB(w, w@files[i], mode)
-	##	}
-	##	names(w@specs) <- basename(as.character(w@files))
-	##}
-		
-	if(readMethod == "peaklist"){
-		splitfn <- strsplit(w@files,'_')
-		cpdIDs <- sapply(splitfn, function(splitted){as.numeric(return(splitted[2]))})
-		files <- list()
-		for(i in 1:length(unique(cpdIDs))) {
-			indices <- sapply(splitfn,function(a){return(unique(cpdIDs)[i] %in% a)})
-			files[[i]] <- w@files[indices]
-		}
-			
-		peaklist <- list()
-			
-		for(i in 1:length(w@files)){
-			peaklist <- read.csv(w@files[i], header = TRUE)
-			w <- addPeaksManually(w, cpdIDs[i], peaklist, mode=mode)
-		}
-		w@files <- sapply(files,function(file){return(file[1])})
-		names(w@specs) <- basename(as.character(w@files))
-	}
+    message("msmsWorkflow: Step 1. Acquire all MSMS spectra from files")
+	w <- msmsRead(w = w, files = w@files, readMethod=readMethod, mode=mode, confirmMode = confirmMode, useRtLimit = useRtLimit, 
+					Args = findPeaksArgs, settings = settings, progressbar = progressbar, MSe = MSe)
   }
   # Step 2: first run analysis before recalibration
   if(2 %in% steps)
@@ -189,7 +124,7 @@ msmsWorkflow <- function(w, mode="pH", steps=c(1:8), confirmMode = FALSE, newRec
 			  }), "SimpleList")
 	  for(f in w@files)
 		  w@spectra[[basename(as.character(f))]]@name <- basename(as.character(f))
-	  do.call(progressbar, list(object=pb, close=TRUE))
+	  suppressWarnings(do.call(progressbar, list(object=pb, close=TRUE)))
   }
   # Step 3: aggregate all spectra
   if(3 %in% steps)
@@ -573,7 +508,10 @@ analyzeMsMs.formula <- function(msmsPeaks, mode="pH", detail=FALSE, run="prelimi
 	} else if(mode == "mFA") {
 		allowed_additions <- "C2H3O2"
 		mode.charge <- -1
-	} else {
+	} else if(mode == "pNH4") {
+		allowed_additions <- "NH4"
+		mode.charge <- 1
+	} else{
           stop("mode = \"", mode, "\" not defined")
         }
     
@@ -759,6 +697,18 @@ analyzeMsMs.formula <- function(msmsPeaks, mode="pH", detail=FALSE, run="prelimi
 	return(child)
   }
   
+  # I believe these lines were fixed to remove a warning but in the refactored workflow "mzranges" doesn't exist anymore.
+  # Leave here for now 
+  ## mzranges <- t(sapply(shots, function(p) {
+  ##     if(!is.null(p$childRaw)){
+  ##       return(range(p$childRaw[,mzColname]))
+  ##     } else {
+  ##       return(c(NA,NA))
+  ##     }
+  ## }))
+  ## 
+  ## mzmin <- min(mzranges[,1], na.rm=TRUE)
+  ## mzmax <- max(mzranges[,2], na.rm=TRUE)
   children <- lapply(msmsPeaks@children, analyzeTandemShot)
   msmsPeaks@children <- as(children, "SimpleList")
   
@@ -781,7 +731,7 @@ analyzeMsMs.intensity <- function(msmsPeaks, mode="pH", detail=FALSE, run="preli
 		cut <- filterSettings$prelimCut
 		if(is.na(cut))
 		{
-			if(mode %in% c("pH", "pM", "pNa"))
+			if(mode %in% c("pH", "pM", "pNa", "pNH4"))
 				cut <- 1e4
 			else if(mode %in% c("mH", "mFA", "mM"))
 				cut <- 0
@@ -1456,9 +1406,9 @@ recalibrateSpectra <- function(mode, rawspec = NULL, rc = NULL, rc.ms1=NULL, w =
 						  colnames(p) <- c("mzFound", "int")
 						  drecal <- predict(rc.ms1, newdata= p)
 						  if(recalibrateBy == "dppm")
-							  p$mzRecal <- p$mz / ( 1 + drecal/1e6 )
+							  p$mzRecal <- p$mzFound / ( 1 + drecal/1e6 )
 						  else
-							  p$mzRecal <- p$mz - drecal
+							  p$mzRecal <- p$mzFound - drecal
 						  colnames(p) <- c("mz", "int", "mzRecal")
 					  }
 					  p <- as.matrix(p)
@@ -1485,9 +1435,9 @@ recalibrateSingleSpec <- function(spectrum, rc,
 		colnames(p) <- c("mzFound", "int")
 		drecal <- predict(rc, newdata= p)
 		if(recalibrateBy == "dppm")
-			p$mzRecal <- p$mz / ( 1 + drecal/1e6 )
+			p$mzRecal <- p$mzFound / ( 1 + drecal/1e6 )
 		else
-			p$mzRecal <- p$mz - drecal
+			p$mzRecal <- p$mzFound - drecal
 		# And rename them back so our "mz" column is
 		# called "mz" again
 		colnames(p) <- c("mz", "int", "mzRecal")
@@ -1824,9 +1774,9 @@ filterPeaksMultiplicity <- function(peaks, formulacol, recalcBest = TRUE)
 	# rename (because "formulacol" is not the actually correct name)
 	colnames(multInfo) <- c("cpdID", formulacol, "formulaMultiplicity")
 	
-	if(nrow(peaks) == 0)
+	if(!is.data.frame(peaks))
 	{
-		message("filterPeaksMultiplicity: no peaks to aggregate")
+		stop("filterPeaksMultiplicity: All peaks have been filtered.")
 		peaks <- cbind(peaks, data.frame(formulaMultiplicity=numeric()))
 	}
 	else
@@ -2075,8 +2025,8 @@ filterMultiplicity <- function(specs, archivename=NA, mode="pH", recalcBest = TR
 #' @usage  recalibrate.addMS1data(spec,mode="pH", recalibrateMS1Window = 
 #' 				getOption("RMassBank")$recalibrateMS1Window)
 #' @param spec A \code{aggregatedSpecs}-like object.
-#' @param mode \code{"pH", "pNa", "pM", "mH", "mM", "mFA"} for different ions 
-#' 			([M+H]+, [M+Na]+, [M]+, [M-H]-, [M]-, [M+FA]-).
+#' @param mode \code{"pH", "pNa", "pM", "pNH4",  "mH", "mM", "mFA"} for different ions 
+#' 			([M+H]+, [M+Na]+, [M]+,  [M+NH4]+, [M-H]-, [M]-, [M+FA]-).
 #' @param recalibrateMS1Window Window width to look for MS1 peaks to recalibrate (in ppm).
 #' @return A dataframe with columns \code{mzFound, formula, mzCalc, dppm, dbe, int,
 #' 		dppmBest, formulaCount, good, cpdID, scan, parentScan, dppmRc}. However,
diff --git a/R/leMsmsRaw.R b/R/leMsmsRaw.R
index 842fb037fbf6752fc6254146b17458611fc48c14..c91754fd09fd3c80c42b2b50d9462276552cc3c7 100755
--- a/R/leMsmsRaw.R
+++ b/R/leMsmsRaw.R
@@ -1,6 +1,15 @@
+## For generating the NAMESPACE
 #' @import mzR
-#  importClassesFrom mzR
-#  importMethodsFrom mzR
+# # importClassesFrom mzR ## Causes error 
+# # importMethodsFrom mzR 
+#' @import Rcpp ## Was not in manually written NAMESPACE ?
+#' @import RCurl 
+#' @import XML 
+#' @import methods 
+#' @import mzR 
+#' @import rcdk 
+#' @import rjson 
+#' @import yaml 
 NULL # This is required so that roxygen knows where the first manpage starts
 
 #' Extract MS/MS spectra for specified precursor
@@ -50,8 +59,8 @@ NULL # This is required so that roxygen knows where the first manpage starts
 #' 			(The parameters are distinct to clearly conceptually distinguish findMsMsHR.mass
 #' 			(a standalone useful function) from the cpdID based functions (workflow functions).)
 #' @param mode The processing mode (determines which ion/adduct is searched):
-#' 			\code{"pH", "pNa", "pM", "mH", "mM", "mFA"} for different ions 
-#' 			([M+H]+, [M+Na]+, [M]+, [M-H]-, [M]-, [M+FA]-). 
+#' 			\code{"pH", "pNa", "pM", "pNH4", "mH", "mM", "mFA"} for different ions 
+#' 			([M+H]+, [M+Na]+, [M]+, [M+NH4]+, [M-H]-, [M]-, [M+FA]-). 
 #' @param confirmMode Whether to use the highest-intensity precursor (=0), second-
 #' 			highest (=1), third-highest (=2)...
 #' @param useRtLimit Whether to respect retention time limits from the compound list.
@@ -103,7 +112,9 @@ findMsMsHR <- function(fileName = NULL, msRaw = NULL, cpdID, mode="pH",confirmMo
 		mzCoarse = getOption("RMassBank")$findMsMsRawSettings$mzCoarse,
 		fillPrecursorScan = getOption("RMassBank")$findMsMsRawSettings$fillPrecursorScan,
 		rtMargin = getOption("RMassBank")$rtMargin,
-		deprofile = getOption("RMassBank")$deprofile)
+		deprofile = getOption("RMassBank")$deprofile,
+		headerCache = NULL,
+		peaksCache = NULL)
 {
 	
 	# access data directly for finding the MS/MS data. This is done using
@@ -124,7 +135,7 @@ findMsMsHR <- function(fileName = NULL, msRaw = NULL, cpdID, mode="pH",confirmMo
 		rtLimits <- c(dbRt$RT - rtMargin, dbRt$RT + rtMargin) * 60
 	}
 	spectra <- findMsMsHR.mass(msRaw, mz, mzCoarse, limit.fine, rtLimits, confirmMode + 1,headerCache
-			,fillPrecursorScan, deprofile)
+			,fillPrecursorScan, deprofile, peaksCache)
 	# check whether a) spectrum was found and b) enough spectra were found
 	if(length(spectra) < (confirmMode + 1))
 		sp <- new("RmbSpectraSet", found=FALSE)
@@ -146,9 +157,18 @@ findMsMsHR <- function(fileName = NULL, msRaw = NULL, cpdID, mode="pH",confirmMo
 #' @export
 findMsMsHR.mass <- function(msRaw, mz, limit.coarse, limit.fine, rtLimits = NA, maxCount = NA,
 		headerCache = NULL, fillPrecursorScan = FALSE,
-		deprofile = getOption("RMassBank")$deprofile)
+		deprofile = getOption("RMassBank")$deprofile, peaksCache = NULL)
 {
-	eic <- findEIC(msRaw, mz, limit.fine, rtLimits)
+	eic <- findEIC(msRaw, mz, limit.fine, rtLimits, headerCache=headerCache, 
+			
+			
+			
+			
+			
+			
+			
+			
+			peaksCache=peaksCache)
 	#	if(!is.na(rtLimits))
 	#	{  
 	#		eic <- subset(eic, rt >= rtLimits[[1]] & rt <= rtLimits[[2]])
@@ -191,6 +211,9 @@ findMsMsHR.mass <- function(msRaw, mz, limit.coarse, limit.fine, rtLimits = NA,
 				return(FALSE)
 			})
 	validPrecursors <- validPrecursors[which(which_OK==TRUE)]
+	if(length(validPrecursors) == 0){
+		warning("No precursor was detected. It is recommended to try to use the setting fillPrecursorScan: TRUE in the ini-file")
+	}
 	# Crop the "EIC" to the valid precursor scans
 	eic <- eic[eic$scan %in% validPrecursors,]
 	# Order by intensity, descending
@@ -293,6 +316,7 @@ findMsMsHR.direct <- function(msRaw, cpdID, mode = "pH", confirmMode = 0, useRtL
 	stop("Support for this interface has been discontinued. Use findMsMsHR with the same parameters instead (use named parameter msRaw)")
 }
 
+
 #' Read in mz-files using XCMS
 #' 
 #' Picks peaks from mz-files and returns the pseudospectra that CAMERA creates with the help of XCMS
@@ -340,7 +364,7 @@ findMsMsHRperxcms.direct <- function(fileName, cpdID, mode="pH", findPeaksArgs =
 	if(MSe == FALSE){
 		## Fake MS1 from MSn scans
 		## xrmsmsAsMs <- msn2xcmsRaw(xrmsms)
-		suppressWarnings(xrs <- split(msn2xcmsRaw(xrmsms), f=xrmsms@msnCollisionEnergy))
+		suppressWarnings(xrs <- split(msn2xcmsRaw(xrmsms), f = xrmsms@msnCollisionEnergy))
 	} else{
 		xrs <- list()
 		xrs[[1]] <- xrmsms
@@ -353,7 +377,6 @@ findMsMsHRperxcms.direct <- function(fileName, cpdID, mode="pH", findPeaksArgs =
 	psp <- list()
 	spectra <- list()
 	whichmissing <- vector()
-	
 	metaspec <- list()
 	for(ID in 1:length(cpdID)){
 		spectra <- list()
@@ -435,7 +458,8 @@ findMsMsHRperxcms.direct <- function(fileName, cpdID, mode="pH", findPeaksArgs =
 #' @author Michael A. Stravs, Eawag <michael.stravs@@eawag.ch>
 #' @seealso findMsMsHR
 #' @export
-findEIC <- function(msRaw, mz, limit = NULL, rtLimit = NA, headerCache = NULL, floatingRecalibration = NULL)
+findEIC <- function(msRaw, mz, limit = NULL, rtLimit = NA, headerCache = NULL, floatingRecalibration = NULL,
+		peaksCache = NULL)
 {
 	# calculate mz upper and lower limits for "integration"
 	if(all(c("mzMin", "mzMax") %in% names(mz)))
@@ -447,6 +471,12 @@ findEIC <- function(msRaw, mz, limit = NULL, rtLimit = NA, headerCache = NULL, f
 		headerData <- as.data.frame(headerCache)
 	else
 		headerData <- as.data.frame(header(msRaw))
+	# Add row numbering because I'm not sure if seqNum or acquisitionNum correspond to anything really
+	if(nrow(headerData) > 0)
+		headerData$rowNum <- 1:nrow(headerData)
+	else
+		headerData$rowNum <- integer(0)
+	
 	# If RT limit is already given, retrieve only candidates in the first place,
 	# since this makes everything much faster.
 	if(all(!is.na(rtLimit)))
@@ -456,7 +486,11 @@ findEIC <- function(msRaw, mz, limit = NULL, rtLimit = NA, headerCache = NULL, f
 				,]
 	else
 		headerMS1 <- headerData[headerData$msLevel == 1,]
-	pks <- mzR::peaks(msRaw, headerMS1$seqNum)
+	if(is.null(peaksCache))
+		pks <- mzR::peaks(msRaw, headerMS1$seqNum)
+	else
+		pks <- peaksCache[headerData$rowNum]
+		
 	# Sum intensities in the given mass window for each scan
 	if(is.null(floatingRecalibration))
 	{
@@ -470,7 +504,7 @@ findEIC <- function(msRaw, mz, limit = NULL, rtLimit = NA, headerCache = NULL, f
 	}
 	intensity <- unlist(lapply(1:nrow(headerMS1), function(row)
 					{
-						peaktable <- mzR::peaks(msRaw, headerMS1[row,"acquisitionNum"])
+						peaktable <- pks[[row]]
 						sum(peaktable[
 										which((peaktable[,1] >= headerMS1[row,"mzMin"]) & (peaktable[,1] <= headerMS1[row,"mzMax"])),
 										2])
@@ -479,6 +513,12 @@ findEIC <- function(msRaw, mz, limit = NULL, rtLimit = NA, headerCache = NULL, f
 	return(data.frame(rt = headerMS1$retentionTime, intensity=intensity, scan=headerMS1$acquisitionNum))
 }
 
+
+makePeaksCache <- function(msRaw, headerCache) 
+{
+	mzR::peaks(msRaw, headerCache$seqNum)
+}
+
 #' Conversion of XCMS-pseudospectra into RMassBank-spectra
 #' 
 #' Converts a pseudospectrum extracted from XCMS using CAMERA into the msmsWorkspace(at)specs-format that RMassBank uses
@@ -734,7 +774,7 @@ addMB <- function(w, cpdID, fileName, mode){
 #' @examples \dontrun{
 #' 		c.msmsWSspecs(w1,w2)
 #' }
-#'export
+#'@export
 c.msmsWSspecs <- function(w1 = NA, w2 = NA){
 
 	if(class(w1) != "msmsWorkspace" || class(w2) != "msmsWorkspace"){
@@ -744,31 +784,44 @@ c.msmsWSspecs <- function(w1 = NA, w2 = NA){
 	cpdIDsw1 <- sapply(w1@specs, function(x) x$id)
 	cpdIDsw2 <- sapply(w2@specs, function(x) x$id)
 	
+	if(length(cpdIDsw2) == 0){
+		stop("w2 can't be empty.")
+	}
+	
+	if(length(cpdIDsw1) == 0){
+		w1@specs <- w2@specs
+		w1@files <- w2@files
+		return(w1)
+	}
+	
 	for(i in 1:length(cpdIDsw2)){
 		if(any(cpdIDsw2[i] == cpdIDsw1)){
-			index <- which(cpdIDsw2[i] == cpdIDsw1)
-			w1@specs[[index]]$peaks <- c(w1@specs[[index]]$peaks,w2@specs[[i]]$peaks)
-			w1@specs[[index]]$childScans <- c(w1@specs[[index]]$childScans,w2@specs[[i]]$childScans)
-			w1@specs[[index]]$childHeaders <- rbind(w1@specs[[index]]$childHeaders, w2@specs[[i]]$childHeaders)
-			
-			##Fake seqNums and/or acquisitionNums if the concatenation has doubled some of them
-			
-			seqNums <- w1@specs[[index]]$childHeaders[,"seqNum"]
-			if(length(seqNums) != length(unique(seqNums))){
-				w1@specs[[index]]$childHeaders[,"seqNum"] <- 2:(nrow(w1@specs[[index]]$childHeaders) + 1)
-				w1@specs[[index]]$childScans <- 2:(nrow(w1@specs[[index]]$childHeaders) + 1)
-			}
 			
+			index <- which(cpdIDsw2[i] == cpdIDsw1)
 			
-			acqNums <- w1@specs[[index]]$childHeaders[,"acquisitionNum"]
-			if(length(acqNums) != length(unique(acqNums))){
-				w1@specs[[index]]$childHeaders[,"acquisitionNum"] <- 2:(nrow(w1@specs[[index]]$childHeaders) + 1)
-			}		
+				w1@specs[[index]]$peaks <- c(w1@specs[[index]]$peaks,w2@specs[[i]]$peaks)
+				w1@specs[[index]]$childScans <- c(w1@specs[[index]]$childScans,w2@specs[[i]]$childScans)
+				w1@specs[[index]]$childHeaders <- rbind(w1@specs[[index]]$childHeaders, w2@specs[[i]]$childHeaders)
+				
+				##Fake seqNums and/or acquisitionNums if the concatenation has doubled some of them
+				
+				seqNums <- w1@specs[[index]]$childHeaders[,"seqNum"]
+				if(length(seqNums) != length(unique(seqNums))){
+					w1@specs[[index]]$childHeaders[,"seqNum"] <- 2:(nrow(w1@specs[[index]]$childHeaders) + 1)
+					w1@specs[[index]]$childScans <- 2:(nrow(w1@specs[[index]]$childHeaders) + 1)
+				}
+				
+				
+				acqNums <- w1@specs[[index]]$childHeaders[,"acquisitionNum"]
+				if(length(acqNums) != length(unique(acqNums))){
+					w1@specs[[index]]$childHeaders[,"acquisitionNum"] <- 2:(nrow(w1@specs[[index]]$childHeaders) + 1)
+				}
 		}
 		
 		if(all(cpdIDsw2[i] != cpdIDsw1)){
 			w1@specs[[length(w1@specs) + 1]] <- w2@specs[[i]]
+			w1@files <- c(w1@files,w2@files[i])
 		}
 	}
 	return(w1)
-}
\ No newline at end of file
+}
diff --git a/R/msmsRead.R b/R/msmsRead.R
index 63deb4431ae8b37cfe309eddbde09449fdaa8f67..2933204166f33ca673696f91f6a266249a77e17f 100644
--- a/R/msmsRead.R
+++ b/R/msmsRead.R
@@ -8,8 +8,8 @@
 #' workflow.
 #' 
 #' @param w A \code{msmsWorkspace} to work with.
-#' @param filetable The path to a .csv-file that contains the columns "files" and "cpdid" supplying
-#' 			the relationships between files and compound IDs. Either this or "files" need
+#' @param filetable The path to a .csv-file that contains the columns "Files" and "ID" supplying
+#' 			the relationships between files and compound IDs. Either this or the parameter "files" need
 #'			to be specified. 
 #' @param files A vector or list containing the filenames of the files that are to be read as spectra. 
 #'				For the IDs to be inferred from the filenames alone, there need to be exactly 2 underscores.
@@ -22,8 +22,8 @@
 #'        used to extract peaks. MassBank will read existing records, 
 #'        so that e.g. a recalibration can be performed, and "peaklist" 
 #'        just requires a CSV with two columns and the column header "mz", "int".
-#' @param mode \code{"pH", "pNa", "pM", "mH", "mM", "mFA"} for different ions 
-#' 			([M+H]+, [M+Na]+, [M]+, [M-H]-, [M]-, [M+FA]-).
+#' @param mode \code{"pH", "pNa", "pM", "pNH4", "mH", "mM", "mFA"} for different ions 
+#' 			([M+H]+, [M+Na]+, [M]+, [M+NH4]+, [M-H]-, [M]-, [M+FA]-).
 #' @param confirmMode Defaults to false (use most intense precursor). Value 1 uses
 #' 			the 2nd-most intense precursor for a chosen ion (and its data-dependent scans)
 #' 			, etc.
@@ -34,6 +34,7 @@
 #' @param progressbar The progress bar callback to use. Only needed for specialized applications.
 #' 			Cf. the documentation of \code{\link{progressBarHook}} for usage.
 #' @param MSe A boolean value that determines whether the spectra were recorded using MSe or not
+#' @param plots A boolean value that determines whether the pseudospectra in XCMS should be plotted
 #' @return The \code{msmsWorkspace} with msms-spectra read.
 #' @seealso \code{\link{msmsWorkspace-class}}, \code{\link{msmsWorkflow}}
 #' @author Michael Stravs, Eawag <michael.stravs@@eawag.ch>
@@ -41,11 +42,11 @@
 #' @export
 msmsRead <- function(w, filetable = NULL, files = NULL, cpdids = NULL, 
 					readMethod, mode, confirmMode = FALSE, useRtLimit = TRUE, 
-					Args = NULL, settings = getOption("RMassBank"), progressbar = "progressBarHook", MSe = FALSE){
+					Args = NULL, settings = getOption("RMassBank"), progressbar = "progressBarHook", MSe = FALSE, plots = FALSE){
 	
 	##Read the files and cpdids according to the definition
 	##All cases are silently accepted, as long as they can be handled according to one definition
-	if(!any(mode %in% c("pH","pNa","pM","mH","mFA","mM",""))) stop(paste("The ionization mode", mode, "is unknown."))
+	if(!any(mode %in% c("pH","pNa","pM","pNH4","mH","mFA","mM",""))) stop(paste("The ionization mode", mode, "is unknown."))
 	
 	if(is.null(filetable)){
 		##If no filetable is supplied, filenames must be named explicitly
@@ -74,14 +75,30 @@ msmsRead <- function(w, filetable = NULL, files = NULL, cpdids = NULL,
 	if(length(w@files) != length(cpdids)){
 		stop("There are a different number of cpdids than files")
 	}
-	if(!(readMethod %in% c("mzR","peaklist","xcms"))){
+	if(!(readMethod %in% c("mzR","peaklist","xcms","minimal"))){
 		stop("The supplied method does not exist")
 	}
 	if(!all(file.exists(w@files))){
 		stop("The supplied files ", paste(w@files[!file.exists(w@files)]), " don't exist")
 	}
-
+	
+	na.ids <- which(is.na(sapply(cpdids, findSmiles)))
+	
+	if(length(na.ids)){
+		stop("The supplied compound ids ", paste(cpdids[na.ids], collapse=" "), " don't have a corresponding smiles entry. Maybe they are missing from the compound list")
+	}
+	
 	##This should work
+	if(readMethod == "minimal"){
+		##Edit options
+		opt <- getOption("RMassBank")
+		opt$recalibrator$MS1 <- "recalibrate.identity"
+		opt$recalibrator$MS2 <- "recalibrate.identity"
+		options(RMassBank=opt)
+		##Edit analyzemethod
+		analyzeMethod <- "intensity"
+	}
+	
 	if(readMethod == "mzR"){
 		##Progressbar
 		nLen <- length(w@files)
@@ -89,28 +106,34 @@ msmsRead <- function(w, filetable = NULL, files = NULL, cpdids = NULL,
 		pb <- do.call(progressbar, list(object=NULL, value=0, min=0, max=nLen))
 		
 		count <- 1
-		w@specs <-  lapply(w@files, function(fileName){
-			spec <- findMsMsHR(fileName, cpdids[count], mode, confirmMode, useRtLimit,
-		 		ppmFine = settings$findMsMsRawSettings$ppmFine,
-		 		mzCoarse = settings$findMsMsRawSettings$mzCoarse,
-		 		fillPrecursorScan = settings$findMsMsRawSettings$fillPrecursorScan,
-		 		rtMargin = settings$rtMargin,
-		 		deprofile = settings$deprofile)
-			
-			## Progress:
-			nProg <<- nProg + 1
-			pb <- do.call(progressbar, list(object=pb, value= nProg))
-			
-			##Counting the index of cpdids
-			count <<- count + 1
-			return(spec)
-		})
-		names(w@specs) <- basename(as.character(w@files))
+		w@spectra <- as(lapply(w@files, function(fileName) {
+							
+							# Find compound ID
+							splitfn <- strsplit(fileName,'_')
+							splitsfn <- splitfn[[1]]
+							cpdID <- splitsfn[[length(splitsfn)-1]]
+							# Retrieve spectrum data
+							spec <- findMsMsHR(fileName = fileName, 
+									cpdID = cpdID, mode = mode, confirmMode = confirmMode, useRtLimit = useRtLimit,
+									ppmFine = settings$findMsMsRawSettings$ppmFine,
+									mzCoarse = settings$findMsMsRawSettings$mzCoarse,
+									fillPrecursorScan = settings$findMsMsRawSettings$fillPrecursorScan,
+									rtMargin = settings$rtMargin,
+									deprofile = settings$deprofile)
+							gc()
+														
+							# Progress:
+							nProg <<- nProg + 1
+							pb <- do.call(progressbar, list(object=pb, value= nProg))
+							
+							return(spec)
+						} ), "SimpleList")
+		names(w@spectra) <- basename(as.character(w@files))
 		return(w)
 	}
 	
 	##Peaklist-readmethod 
-	if(readMethod == "peaklist"){
+	if((readMethod == "peaklist") || (readMethod=="minimal")){
 		w <- createSpecsFromPeaklists(w, cpdids, filenames=w@files, mode=mode)
 		uIDs <- unique(cpdids)
 		files <- list()
@@ -148,12 +171,14 @@ msmsRead <- function(w, filetable = NULL, files = NULL, cpdids = NULL,
 		nProg <- 0
 		pb <- do.call(progressbar, list(object=NULL, value=0, min=0, max=nLen))
 		i <- 1
+		FileIDs <- vector()
+		metaSpec <- list()
 		dummyapply <- lapply(ufiles, function(currfile){
 			
 			dummySpecs[[i]] <<- newMsmsWorkspace()
 			dummySpecs[[i]]@specs <<- list()
 			FileIDs <<- cpdids[which(w@files == currfile)]
-			dummylinebreak <- capture.output(metaSpec <<- findMsMsHRperxcms.direct(currfile, FileIDs, mode=mode, findPeaksArgs=Args, MSe = MSe))
+			dummylinebreak <- capture.output(metaSpec <<- findMsMsHRperxcms.direct(currfile, FileIDs, mode=mode, findPeaksArgs=Args, plots, MSe = MSe))
 			
 			for(j in 1:length(FileIDs)){
 				dummySpecs[[i]]@specs[[length(dummySpecs[[i]]@specs)+1]] <<- metaSpec[[j]]
@@ -186,3 +211,136 @@ msmsRead <- function(w, filetable = NULL, files = NULL, cpdids = NULL,
 			return(w)
 	}
 }
+
+#' 
+#' Extracts and processes spectra from a list of xcms-Objects
+#' 
+#' The filenames of the raw LC-MS runs are read from the array \code{files} 
+#' in the global enviroment.
+#' See the vignette \code{vignette("RMassBank")} for further details about the
+#' workflow.
+#' 
+#' @param w A \code{msmsWorkspace} to work with.
+#' @param xRAW A list of xcmsRaw objects whose peaks should be detected and added to the workspace.
+#'				The relevant data must be in the MS1 data of the xcmsRaw object.  You can coerce the
+#'				msn-data in a usable object with the \code{msn2xcmsRaw} function of xcms.
+#' @param cpdids A vector or list containing the compound IDs of the files that are to be read as spectra.
+#'				The ordering of this and \code{files} implicitly assigns each ID to the corresponding file.
+#'				If this is supplied, then the IDs implicitly named in the filenames are ignored.
+#' @param mode \code{"pH", "pNa", "pM", "pNH4", "mH", "mM", "mFA"} for different ions 
+#' 			([M+H]+, [M+Na]+, [M]+, [M+NH4]+, [M-H]-, [M]-, [M+FA]-).
+#' @param findPeaksArgs A list of arguments that will be handed to the xcms-method findPeaks via do.call
+#' @param settings Options to be used for processing. Defaults to the options loaded via
+#' 			\code{\link{loadRmbSettings}} et al. Refer to there for specific settings.
+#' @param progressbar The progress bar callback to use. Only needed for specialized applications.
+#' 			Cf. the documentation of \code{\link{progressBarHook}} for usage.
+#' @param plots A boolean value that determines whether the pseudospectra in XCMS should be plotted
+#' @return The \code{msmsWorkspace} with msms-spectra read.
+#' @seealso \code{\link{msmsWorkspace-class}}, \code{\link{msmsWorkflow}}
+#' @author Michael Stravs, Eawag <michael.stravs@@eawag.ch>
+#' @author Erik Mueller, UFZ
+#' @export
+msmsRead.RAW <- function(w, xRAW = NULL, cpdids = NULL, mode, findPeaksArgs = NULL, 
+							settings = getOption("RMassBank"), progressbar = "progressBarHook", plots = FALSE){
+	
+	require(xcms)
+	
+	##xRAW will be coerced into a list of length 1 if it is an xcmsRaw-object
+	if(class(xRAW) == "xcmsRaw"){
+		xRAW <- list(xRAW)
+	}
+	
+	##Error messages
+	if((class(xRAW) != "list") || any(sapply(xRAW, function(x) class(x) != "xcmsRaw"))){
+		stop("No list of xcmsRaw-objects supplied")
+	}
+	
+	if(is.null(cpdids)){
+		stop("No cpdids supplied")
+	}
+		
+	#msnExist <- which(sapply(xRAW,function(x) length(x@msnPrecursorScan) != 0))
+	#print(length(msnExist))
+	#print(length(xRAW))
+	
+	#if(length(msnExist) != length(xRAW)){
+	#	stop(paste("No msn data in list elements", setdiff(1:length(xRAW),msnExist)))
+	#}
+	
+	require(CAMERA)
+	
+	parentMass <- findMz(cpdids[1], mode=mode)$mzCenter
+	if(is.na(parentMass)){
+		stop(paste("There was no matching entry to the supplied cpdID", cpdids[1] ,"\n Please check the cpdIDs and the compoundlist."))
+	}
+		
+	RT <- findRt(cpdids[1])$RT * 60
+	mzabs <- 0.1
+	
+	getRT <- function(xa) {
+		rt <- sapply(xa@pspectra, function(x) {median(peaks(xa@xcmsSet)[x, "rt"])})
+	}
+	
+	suppressWarnings(setReplicate <- xcmsSet(files=xRAW[[1]]@filepath, method="MS1"))
+	xsmsms <- as.list(replicate(length(xRAW),setReplicate))
+	candidates <- list()
+	anmsms <- list()
+	psp <- list()
+	spectra <- list()
+	whichmissing <- vector()
+	metaspec <- list()
+	for(i in 1:length(xRAW)){
+		devnull <- suppressWarnings(capture.output(peaks(xsmsms[[i]]) <- do.call(findPeaks,c(findPeaksArgs, object = xRAW[[i]]))))
+		
+		if (nrow(peaks(xsmsms[[i]])) == 0) { ##If there are no peaks
+			spectra[[i]] <- matrix(0,2,7)
+			next
+		} else{	
+			## Get pspec 
+			pl <- peaks(xsmsms[[i]])[,c("mz", "rt"), drop=FALSE]
+
+			## Best: find precursor peak
+			candidates[[i]] <- which( pl[,"mz", drop=FALSE] < parentMass + mzabs & pl[,"mz", drop=FALSE] > parentMass - mzabs
+							& pl[,"rt", drop=FALSE] < RT * 1.1 & pl[,"rt", drop=FALSE] > RT * 0.9 )
+			devnull <- capture.output(anmsms[[i]] <- xsAnnotate(xsmsms[[i]]))
+			devnull <- capture.output(anmsms[[i]] <- groupFWHM(anmsms[[i]]))
+
+				if(length(candidates[[i]]) > 0){
+				closestCandidate <- which.min (abs( RT - pl[candidates[[i]], "rt", drop=FALSE]))
+				psp[[i]] <- which(sapply(anmsms[[i]]@pspectra, function(x) {candidates[[i]][closestCandidate] %in% x}))
+				} else{psp[[i]] <- which.min( abs(getRT(anmsms[[i]]) - RT) )}
+				## Now find the pspec for compound       
+
+				## 2nd best: Spectrum closest to MS1
+				##psp <- which.min( abs(getRT(anmsms) - actualRT))
+
+				## 3rd Best: find pspec closest to RT from spreadsheet
+				##psp <- which.min( abs(getRT(anmsms) - RT) )
+				if((plots == TRUE) && (length(psp[[i]]) > 0)){
+					plotPsSpectrum(anmsms[[i]], psp[[i]], log=TRUE,  mzrange=c(0, findMz(cpdids[1])[[3]]), maxlabel=10)
+				}
+				if(length(psp[[i]]) != 0){
+					spectra[[i]] <- getpspectra(anmsms[[i]], psp[[i]])
+				} else {whichmissing <- c(whichmissing,i)}
+			}
+		}
+		if(length(spectra) != 0){
+			for(i in whichmissing){
+				spectra[[i]] <- matrix(0,2,7)
+			}
+		}
+		
+	if(length(w@specs) != 0){
+		w@specs <- c(w@specs,list(toRMB(spectra,cpdids[1],mode)))
+	} else {
+		w@specs[[1]] <- toRMB(spectra,cpdids[1],mode)
+	}
+	
+	if(all(w@files != xRAW[[1]]@filepath)){
+		w@files <- c(w@files,xRAW[[1]]@filepath)
+	} else{
+		w@files <- c(w@files,paste0(xRAW[[1]]@filepath,"_2"))
+	}
+	names(w@specs)[length(w@specs)] <- basename(w@files[length(w@files)])
+	return(w)
+}
\ No newline at end of file
diff --git a/R/settings_example.R b/R/settings_example.R
index 6070bdbbe5e2258c48d75107eb6abe517b8e357c..8dd50cc5d133b8b7ecae36337b624ac9dc28a838 100755
--- a/R/settings_example.R
+++ b/R/settings_example.R
@@ -344,8 +344,23 @@ loadRmbSettings <- function(file_or_list)
 		# Fix the YAML file to suit our needs
 		if(is.null(o$deprofile))
 			o$deprofile <- NA
-		if(is.null(o$babeldir))
+		if(is.null(o$babeldir)){
 			o$babeldir <- NA
+		} else{
+			##Check if babeldir exists
+			babelcheck <- gsub('\"','',o$babeldir)
+			if(substring(babelcheck, nchar(babelcheck)) == "\\"){
+				babelexists <- file.exists(substring(babelcheck, 1, nchar(babelcheck)-1))
+			} else{
+				babelexists <- file.exists(babelcheck)
+			}
+			
+			if(!babelexists){
+				stop("The babeldir does not exist. Please check the babeldir in the settings and adjust it accordingly.")
+			}
+		}
+
+
 		if(nchar(o$annotations$entry_prefix) != 2){
 			stop("The entry prefix must be of length 2")
 		}
diff --git a/R/validateMassBank.R b/R/validateMassBank.R
index a3894aa7dafaab6ace2094b56be9d68fc38bf03f..c9857b0cc4fa18908b32c832add8071e3498c718 100644
--- a/R/validateMassBank.R
+++ b/R/validateMassBank.R
@@ -2,21 +2,22 @@
 #' 
 #' Validates a plain text MassBank record, or recursively all
 #' records within a directory. The Unit Tests to be used are
-#' installed in RMassBank/inst/unitTests and currently include 
+#' installed in RMassBank/inst/validationTests and currently include 
 #' checks for NAs, peaks versus precursor, precursor mz, 
 #' precursor type, SMILES vs exact mass, total intensities and
 #' title versus type. The validation report is saved as 
 #' "report.html" in the working directory.
 #' 
 #' @aliases validate
-#' @usage validate(path)
+#' @usage validate(path, simple = TRUE)
 #' @param path The filepath to a single record, or a directory to search recursively
+#' @param simple If TRUE the function creates a simpler form of the RUnit .html report, better readable for humans. If FALSE it returns the unchanged RUnit report.
 #' @examples
 #' \dontrun{
 #' validate("/tmp/MassBank/OpenData/record/")
 #' }
 #' @export
-validate <- function(path) {
+validate <- function(path, simple = TRUE) {
 
         require(ontoCAT)
 		require(RUnit)
@@ -37,12 +38,12 @@ validate <- function(path) {
 	tests <- list()
 	for(i in 1:length(RMassBank.env$mb)){
 		if(RMassBank.env$mb[[i]]@compiled_ok[[1]][['AC$MASS_SPECTROMETRY']][['MS_TYPE']] == "MS2" || RMassBank.env$mb[[i]]@compiled_ok[[1]][['AC$MASS_SPECTROMETRY']][['MS_TYPE']] == "MS"){
-		tests[[i]] <- defineTestSuite(Files[i], dirs = system.file(package="RMassBank", "unitTests"), testFileRegexp = "runit.MS2.test.R",
+		tests[[i]] <- defineTestSuite(Files[i], dirs = system.file(package="RMassBank", "validationTests"), testFileRegexp = "runit.MS2.test.R",
                 #testFuncRegexp = "^test.+",
                 rngKind = "Marsaglia-Multicarry",
                 rngNormalKind = "Kinderman-Ramage")
 		} else{
-			tests[[i]] <- defineTestSuite(Files[i], dirs = system.file(package="RMassBank", "unitTests"), testFileRegexp = "^runit.MSn.test.[rR]$",
+			tests[[i]] <- defineTestSuite(Files[i], dirs = system.file(package="RMassBank", "validationTests"), testFileRegexp = "^runit.MSn.test.[rR]$",
                 #testFuncRegexp = "^test.+",
                 rngKind = "Marsaglia-Multicarry",
                 rngNormalKind = "Kinderman-Ramage")
@@ -50,9 +51,42 @@ validate <- function(path) {
 	}
 	print("Starting Tests")
 	# Testing the list of Testsuites
-	testData <- suppressWarnings(runTestSuite(tests))
+	testData <- suppressWarnings(runTestSuite(tests,verbose=0))
 	# Prints the HTML-record
-	printHTMLProtocol(testData, fileName = paste(getwd(),"/report.html", sep = ""))
+	printHTMLProtocol(testData, fileName = paste0(getwd(),"/report.html"))
+	if(simple){
+		fileConnection <- file(paste0(getwd(),"/report.html"), open = "r")
+		htmlFile <- readLines(fileConnection)
+		close(fileConnection)
+		htmlFile <- gsub(">test.NA", ">No NAs contained in peak list", htmlFile)
+		htmlFile <- gsub(">test.peaksvsprecursor", ">One peak m/z  with no noticable difference from the precursor mass", htmlFile)
+		htmlFile <- gsub(">test.precursormz", ">Mass of precursor m/z possible with given mass and type", htmlFile)
+		htmlFile <- gsub(">test.PrecursorType", ">Precursor type valid", htmlFile)
+		htmlFile <- gsub(">test.smilesvsexactmass", ">Smiles code represents a molecule with specified exact mass", htmlFile)
+		htmlFile <- gsub(">test.sumintensities", ">All intensies greater than zero", htmlFile)
+		htmlFile <- gsub(">test.TitleVsType", ">Precursor type are the same in the title and in the document", htmlFile)
+		htmlFile <- gsub("\\(1 checks\\)", "", htmlFile)
+		htmlFile <- gsub("\\({1}.{1,6}seconds\\)", "", htmlFile)
+		htmlFile <- gsub("Test Suite: ", "", htmlFile)
+		htmlFile <- gsub("h5", "h2", htmlFile)
+		##Remove ending
+		poshr <- grep("<hr>", htmlFile, fixed=TRUE)
+		poshr <- poshr[length(poshr)]
+		htmlFile <- htmlFile[1:(poshr)]
+		
+		ullines <- grep("<ul>", htmlFile)
+		htmlFile[ullines] <- gsub("</a><ul>", "</a></li>", htmlFile[ullines])
+		htmlFile[ullines] <- gsub("</li></ul></li></ul>", "</li></ul>", htmlFile[ullines])
+		htmlFile[ullines] <- gsub('<li><a href=".+">Test file: runit.MS2.test.R</a></li>', "", htmlFile[ullines])
+		htmlFile[ullines] <- gsub('</a>.+RMassBank/validationTests<br/>',"</a>", htmlFile[ullines])
+		
+		##Remove superfluous information
+		htmlFile <- gsub("Test function regexp: ^test.+<br/>Test file regexp: runit.MS2.test.R<br/>Involved directory:<br/>", "", htmlFile, fixed=TRUE)
+		
+		fileConnection <- file(paste0(getwd(),"/report.html"), open = "w")
+		writeLines(htmlFile, fileConnection)
+		close(fileConnection)
+	}
 	print(paste("Report for the file(s) finished"))
 }
 
@@ -140,3 +174,43 @@ smiles2mass <- function(SMILES){
 	mass <- get.exact.mass(massfromformula)
 	return(mass)
 }
+
+.unitTestRMB <- function(WD=getwd()){
+	require(RUnit)
+	library(RMassBank)
+	library(RMassBankData)
+	oldwd <- getwd()
+	setwd(WD)
+	w <- newMsmsWorkspace()
+	RmbDefaultSettings()
+	files <- list.files(system.file("spectra", package="RMassBankData"),
+		 ".mzML", full.names = TRUE)
+	basename(files)
+	# To make the workflow faster here, we use only 2 compounds:
+	w@files <- files
+	loadList(system.file("list/NarcoticsDataset.csv", 
+		package="RMassBankData"))
+	w <- msmsWorkflow(w, mode="pH", steps=c(1:4), archivename = 
+					"pH_narcotics")
+	w <- msmsWorkflow(w, mode="pH", steps=c(5:8), archivename = 
+			"pH_narcotics")	
+	w2 <- newMbWorkspace(w)
+	#w2 <- mbWorkflow(w2)
+	#w2 <- loadInfolist(w2, "infolist.csv")
+	#w2 <- mbWorkflow(w2)
+	
+	testSuite <- defineTestSuite("Electronic noise and formula calculation Test", dirs = system.file("unitTests", 
+		package="RMassBank"), testFileRegexp = "runit.EN_FC.R",
+					#testFuncRegexp = "^test.+",
+					rngKind = "Marsaglia-Multicarry",
+					rngNormalKind = "Kinderman-Ramage")
+					
+	testData <- suppressWarnings(runTestSuite(testSuite))
+	
+	file.remove(c("pH_narcotics_Failpeaks.csv","pH_narcotics.RData","pH_narcotics_RA.RData","pH_narcotics_RF.RData"))
+	
+	# Prints the HTML-record
+	printTextProtocol(testData)
+	setwd(oldwd)
+	return(testData)
+}
diff --git a/R/webAccess.R b/R/webAccess.R
index 2a7076e49d8b1e823620266a58eba960dcdd84d3..bf26e8dbe2ad4cd4216723992e86c12e5c3ac401 100755
--- a/R/webAccess.R
+++ b/R/webAccess.R
@@ -58,32 +58,55 @@ getCactus <- function(identifier, representation)
 #' Only the first result is returned currently. \bold{The function should be
 #' regarded as experimental and has not thoroughly been tested.}
 #' 
-#' @usage getPcId(search)
-#' @param search The search term.
+#' @usage getPcId(query, from = "inchikey")
+#' @param query ID to be converted
+#' @param from Type of input ID
 #' @return The PubChem CID (in string type).
-#' @author Michael Stravs
+#' @author Michael Stravs, Erik Mueller
 #' @seealso \code{\link{getCtsRecord}}, \code{\link{getCactus}}
 #' @references PubChem search: \url{http://pubchem.ncbi.nlm.nih.gov/} 
 #' 
-#' Entrez E-utilities: \url{http://www.ncbi.nlm.nih.gov/books/NBK25500/}
+#' Pubchem REST:
+#' \url{https://pubchem.ncbi.nlm.nih.gov/pug_rest/PUG_REST.html}
 #' @examples
-#' 
-#' # Benzene (again):
-#' # Currently broken: getPcId("benzene")
+#' getPcId("MKXZASYAUGDDCJ-NJAFHUGGSA-N")
 #' 
 #' @export
-getPcId <- function(search)
+getPcId <- function(query, from = "inchikey")
 {
-  
-  baseUrl <- "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/"
-  term <- paste(baseUrl, "esearch.fcgi?db=pccompound&term=", URLencode(search), sep='')
-  ret <-  getURL(term)
-  #ret <- paste(ret, collapse='')
-  xml <- xmlParseDoc(ret,asText=TRUE)
-  idNodes <- getNodeSet(xml, "/eSearchResult/IdList/Id")
-  
-  id <- xmlValue(idNodes[[1]])
-  return(id)
+	baseURL <- "http://pubchem.ncbi.nlm.nih.gov/rest/pug/compound"
+	url <- paste(baseURL, from, query, "description", "json", sep="/")
+	
+	errorvar <- 0
+	currEnvir <- environment()
+	
+	tryCatch(
+		data <- getURL(URLencode(url),timeout=5),
+		error=function(e){
+		currEnvir$errorvar <- 1
+	})
+	
+	if(errorvar){
+		return(NA)
+	}
+	
+	# This happens if the InChI key is not found:
+	r <- fromJSON(data)
+	
+	if(!is.null(r$Fault))
+	return(NA)
+	
+	titleEntry <- which(unlist(lapply(r$InformationList$Information, function(i) !is.null(i$Title))))
+	
+	titleEntry <- titleEntry[which.min(sapply(titleEntry, function(x)r$InformationList$Information[[x]]$CID))]
+
+	PcID <- r$InformationList$Information[[titleEntry]]$CID
+	
+	if(is.null(PcID)){
+		return(NA)
+	} else{
+		return(PcID)
+	}
 }
 
 # The following function is unfinished.
@@ -131,7 +154,6 @@ getPcId <- function(search)
 #' \url{http://cts.fiehnlab.ucdavis.edu}
 #' 
 #' @examples
-#' 
 #' data <- getCtsRecord("UHOVQNZJYSORNB-UHFFFAOYSA-N")
 #' # show all synonym "types"
 #' types <- unique(unlist(lapply(data$synonyms, function(i) i$type)))
@@ -142,7 +164,26 @@ getPcId <- function(search)
 getCtsRecord <- function(key)
 {
 	baseURL <- "http://cts.fiehnlab.ucdavis.edu/service/compound/"
-	data <- getURL(paste0(baseURL,key))
+	
+	errorvar <- 0
+	currEnvir <- environment()
+	
+	##tryCatch a CTS timeout
+	##
+	tryCatch(
+		{
+			data <- getURL(paste0(baseURL,key), timeout=7)
+		},
+		error=function(e){
+			currEnvir$errorvar <- 1
+		}
+	)
+  
+	if(errorvar){
+		warning("CTS seems to be currently unavailable or incapable of interpreting your request")
+		return(NULL)
+	}
+
 	r <- fromJSON(data)
 	if(length(r) == 1)
 		if(r == "You entered an invalid InChIKey")
@@ -159,17 +200,36 @@ getCtsRecord <- function(key)
 #' @return An unordered array with the resulting converted key(s). 
 #' 
 #' @examples 
-#' 	k <- getCtsKey("benzene", "Chemical Name", "InChIKey")
+#' k <- getCtsKey("benzene", "Chemical Name", "InChIKey")
 #' @author Michele Stravs, Eawag <stravsmi@@eawag.ch>
 #' @export
 getCtsKey <- function(query, from = "Chemical Name", to = "InChIKey")
 {
 	baseURL <- "http://cts.fiehnlab.ucdavis.edu/service/convert"
 	url <- paste(baseURL, from, to, query, sep='/')
-	data <- getURL(URLencode(url))
+	errorvar <- 0
+	currEnvir <- environment()
+	
+	##tryCatch a CTS timeout
+	##
+	tryCatch(
+		{
+			data <- getURL(URLencode(url), timeout=7)
+		},
+		error=function(e){
+			currEnvir$errorvar <- 1
+		}
+	)
+  
+	if(errorvar){
+		warning("CTS seems to be currently unavailable or incapable of interpreting your request")
+		return(NULL)
+	}
+	
+	
 	r <- fromJSON(data)
 	if(length(r) == 0)
-		return(FALSE)
+		return(NULL)
 	else
 	{
 		# read out the results in simplest form:
@@ -232,3 +292,177 @@ CTS.externalIdTypes <- function(data)
 								id[["name"]]
 							})))
 }
+
+.pubChemOnline <- function(){
+	baseURL <- "http://pubchem.ncbi.nlm.nih.gov/rest/pug/compound"
+	url <- paste(baseURL, "inchikey", "QEIXBXXKTUNWDK-UHFFFAOYSA-N", "description", "json", sep="/")
+	
+	errorvar <- 0
+	currEnvir <- environment()
+	tryCatch(
+		ret <- getURL(URLencode(url), timeout=5),
+		error=function(e){
+		currEnvir$errorvar <- 1
+	})
+  
+  if(errorvar){
+	warning("Pubchem is currently offline")
+	return(FALSE)
+  } else{
+	return(TRUE)
+  }
+}
+
+getPcCHEBI <- function(query, from = "inchikey")
+{
+	# Get the JSON-Data from Pubchem
+	baseURL <- "http://pubchem.ncbi.nlm.nih.gov/rest/pug/compound"
+	url <- paste(baseURL, from, query, "synonyms", "json", sep="/")
+	errorvar <- 0
+	currEnvir <- environment()
+	
+	tryCatch(
+		data <- getURL(URLencode(url),timeout=5),
+		error=function(e){
+		currEnvir$errorvar <- 1
+	})
+	
+	if(errorvar){
+		return(NA)
+	}
+	
+	r <- fromJSON(data)
+	
+	# This happens if the InChI key is not found:
+	if(!is.null(r$Fault))
+	return(NA)
+	
+	# Find the entries which contain Chebi-links
+	synonymEntry <- which(unlist(lapply(r$InformationList$Information, function(i) !is.null(i$Synonym))))
+	synonymList <- r$InformationList$Information[[synonymEntry]]$Synonym
+	matchChebi <- which(grepl("CHEBI:", synonymList, fixed=TRUE))
+	
+	# It doesn't matter if the db is down or if chebi isn't found, so return NA also
+	if(length(matchChebi) == 0){
+		return (NA) 
+	} else {
+		return (sapply(matchChebi, function(x) synonymList[[x]]))
+	}
+}
+
+##This fucntion uses the chemspider-interface to collect the CSID
+getCSID <- function(query)
+{
+	baseURL <- "http://www.chemspider.com/InChI.asmx/InChIKeyToCSID?inchi_key="
+	url <- paste0(baseURL, query)
+	
+	errorvar <- 0
+	currEnvir <- environment()
+	
+	tryCatch(
+		data <- getURL(URLencode(url), timeout=5),
+		error=function(e){
+		currEnvir$errorvar <- 1
+	})
+	
+	if(errorvar){
+		warning("Chemspider is currently offline")
+		return(NA)
+	}
+	
+	xml <- xmlParseDoc(data,asText=TRUE)
+	# the returned XML document contains only the root node called "string" which contains the correct CSID
+	idNodes <- getNodeSet(xml, "/")
+	id <- xmlValue(idNodes[[1]])
+	return(id)
+} 
+
+##This function returns a sensible name for the compound
+getPcSynonym <- function (query, from = "inchikey")
+{
+	# Get the JSON-Data from Pubchem
+	baseURL <- "http://pubchem.ncbi.nlm.nih.gov/rest/pug/compound"
+	url <- paste(baseURL, from, query, "description", "json", sep="/")
+	
+	errorvar <- 0
+	currEnvir <- environment()
+	
+	tryCatch(
+		data <- getURL(URLencode(url),timeout=5),
+		error=function(e){
+		currEnvir$errorvar <- 1
+	})
+	
+	if(errorvar){
+		return(NA)
+	}
+	
+	r <- fromJSON(data)
+	
+	# This happens if the InChI key is not found:
+	if(!is.null(r$Fault))
+	return(NA)
+	
+	# Find the synonym
+	
+	titleEntry <- which(unlist(lapply(r$InformationList$Information, function(i) !is.null(i$Title))))
+	
+	titleEntry <- titleEntry[which.min(sapply(titleEntry, function(x)r$InformationList$Information[[x]]$CID))]
+	
+	title <- r$InformationList$Information[[titleEntry]]$Title
+	
+	if(is.null(title)){
+		return(NA)
+	} else{
+		return(title)
+	}
+} 
+
+
+##A function to retrieve a IUPAC Name from Pubchem
+getPcIUPAC <- function (query, from = "inchikey")
+{
+	# Get the JSON-Data from Pubchem
+	baseURL <- "http://pubchem.ncbi.nlm.nih.gov/rest/pug/compound"
+	url <- paste(baseURL, from, query, "record", "json", sep="/")
+	
+	errorvar <- 0
+	currEnvir <- environment()
+	
+	tryCatch(
+		data <- getURL(URLencode(url),timeout=5),
+		error=function(e){
+		currEnvir$errorvar <- 1
+	})
+	
+	if(errorvar){
+		return(NA)
+	}
+	
+	r <- fromJSON(data)
+	
+	# This happens if the InChI key is not found:
+	if(!is.null(r$Fault))
+	return(NA)
+	
+	# Find the IUPAC-Names
+	if(!is.null(r$PC_Compounds[[1]]$props)){
+		IUPACIndex <- which(unlist(lapply(r$PC_Compounds[[1]]$props, function(i) (i$urn$label == "IUPAC Name"))))
+		if(length(IUPACIndex) > 0){
+			# Retrieve all IUPAC-Names
+			IUPACEntries <- lapply(IUPACIndex, function(x) r$PC_Compounds[[1]]$props[[x]])
+			if(!is.null(IUPACEntries)){
+				# Is there a preferred IUPAC-Name? If yes, retrieve that
+				PrefIUPAC <- which(unlist(lapply(IUPACEntries, function(x) x$urn$name == "Preferred")))
+			}	else{return(NA)}
+		}	else{return(NA)}
+	}	else{return(NA)}
+	
+
+	if(length(PrefIUPAC) == 1){
+		return(IUPACEntries[[PrefIUPAC]]$value$sval)
+	} else{
+		# Else it doesn't matter which
+		return(IUPACEntries[[1]]$value$sval)
+	}
+} 
diff --git a/inst/unitTests/runit.EN_FC.R b/inst/unitTests/runit.EN_FC.R
new file mode 100644
index 0000000000000000000000000000000000000000..1b6e5e43e960ca1e7a7440ad7ae1e9cf4c2f0718
--- /dev/null
+++ b/inst/unitTests/runit.EN_FC.R
@@ -0,0 +1,11 @@
+test.eletronicnoise <- function(){
+	failpeaks <- read.csv("pH_narcotics_Failpeaks.csv")
+	
+	checkTrue(!any(apply(failpeaks,1,function(x) all(x[2:4] == c(1738,2819,668,201.69144)))))
+}
+
+test.formulacalc <- function(){
+	failpeaks <- read.csv("pH_narcotics_Failpeaks.csv")
+	
+	checkTrue(!any(apply(failpeaks,1,function(x) all(x[2:4] == c(70,2758,321,56.04933)))))
+}
\ No newline at end of file
diff --git a/inst/unitTests/runit.MS2.instruments.R-disabled b/inst/validationTests/runit.MS2.instruments.R-disabled
similarity index 100%
rename from inst/unitTests/runit.MS2.instruments.R-disabled
rename to inst/validationTests/runit.MS2.instruments.R-disabled
diff --git a/inst/unitTests/runit.MS2.test.R b/inst/validationTests/runit.MS2.test.R
similarity index 95%
rename from inst/unitTests/runit.MS2.test.R
rename to inst/validationTests/runit.MS2.test.R
index bd93f5e9bfb5f8b2273a0d265224927e9cc4869f..8c4a5ee9a1811f9e8a77bebde05fbff3e8dee3f3 100644
--- a/inst/unitTests/runit.MS2.test.R
+++ b/inst/validationTests/runit.MS2.test.R
@@ -14,7 +14,7 @@ test.peaksvsprecursor <- function(){
 
 test.precursormz <- function(){
 	precursorlist <- c("[M+H]+","[M+Na]+","[M-H]-","[M+HCOO-]-","[M]+","[M]-")
-	if(is.na(RMassBank.env$mb[[RMassBank.env$testnumber]]@compiled_ok[[1]][['MS$FOCUSED_ION']][['PRECURSOR_TYPE']])){
+	if(is.na(RMassBank.env$mb[[RMassBank.env$testnumber]]@compiled_ok[[1]][['MS$FOCUSED_ION']][['PRECURSOR_TYPE']]) || is.na(RMassBank.env$mb[[RMassBank.env$testnumber]]@compiled_ok[[1]][['MS$FOCUSED_ION']][['PRECURSOR_M/Z']])){
 		checkTrue(TRUE)
 	} else{
 		precursor <- grep(RMassBank.env$mb[[RMassBank.env$testnumber]]@compiled_ok[[1]][['MS$FOCUSED_ION']][['PRECURSOR_TYPE']],precursorlist, value = TRUE, fixed = TRUE)
diff --git a/inst/unitTests/runit.MSn.test.slashes.R b/inst/validationTests/runit.MSn.test.slashes.R
similarity index 100%
rename from inst/unitTests/runit.MSn.test.slashes.R
rename to inst/validationTests/runit.MSn.test.slashes.R
diff --git a/man/c.msmsWSspecs.Rd b/man/c.msmsWSspecs.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..0258cde521b06f6538c0adafe2578db95272c941
--- /dev/null
+++ b/man/c.msmsWSspecs.Rd
@@ -0,0 +1,29 @@
+% Generated by roxygen2 (4.1.0): do not edit by hand
+% Please edit documentation in R/leMsmsRaw.R
+\name{c.msmsWSspecs}
+\alias{c.msmsWSspecs}
+\title{Concatenation of raw spectra in msmsWorkspace}
+\usage{
+c.msmsWSspecs(w1, w2)
+}
+\arguments{
+\item{w1,w2}{The msmsWorkspaces of which the spectra should be concatenated}
+}
+\value{
+The \code{msmsWorkspace} with the spectra of two workspaces concatenated into one. Please note that the spectra from w2 will be concatenated to w1 and not vice versa.
+}
+\description{
+Concatenates the (at)specs spectra of msmsWorkspace according to cpdIDs
+}
+\examples{
+\dontrun{
+		c.msmsWSspecs(w1,w2)
+}
+}
+\author{
+Erik Mueller
+}
+\seealso{
+\code{\link{addPeaksManually}}
+}
+
diff --git a/man/findEIC.Rd b/man/findEIC.Rd
index e28dc1790e9c23784f416bfccc511a78c1100f37..3e4cc06ac60f322168bb3bed7aab7d682dd7b368 100755
--- a/man/findEIC.Rd
+++ b/man/findEIC.Rd
@@ -1,43 +1,42 @@
+% Generated by roxygen2 (4.1.0): do not edit by hand
+% Please edit documentation in R/leMsmsRaw.R
 \name{findEIC}
 \alias{findEIC}
 \title{Extract EICs}
 \usage{
-  findEIC(msRaw, mz, limit = NULL, rtLimit = NA,
-    headerCache = NULL)
+findEIC(msRaw, mz, limit = NULL, rtLimit = NA, headerCache = NULL,
+  floatingRecalibration = NULL)
 }
 \arguments{
-  \item{msRaw}{The mzR file handle}
+\item{msRaw}{The mzR file handle}
 
-  \item{mz}{The mass or mass range to extract the EIC for:
-  either a single mass (with the range specified by
-  \code{limit} below) or a mass range in the form of
-  \code{c(min, max)}.}
+\item{mz}{The mass or mass range to extract the EIC for: either a single mass
+(with the range specified by \code{limit} below) or a mass range
+in the form of \code{c(min, max)}.}
 
-  \item{limit}{If a single mass was given for \code{mz}:
-  the mass window to extract.  A limit of 0.001 means that
-  the EIC will be returned for \code{[mz - 0.001, mz +
-  0.001]}.}
+\item{limit}{If a single mass was given for \code{mz}: the mass window to extract.
+A limit of 0.001 means that the EIC will be returned for \code{[mz - 0.001, mz + 0.001]}.}
 
-  \item{rtLimit}{If given, the retention time limits in
-  form \code{c(rtmin, rtmax)} in seconds.}
+\item{rtLimit}{If given, the retention time limits in form \code{c(rtmin, rtmax)} in seconds.}
 
-  \item{headerCache}{If present, the complete
-  \code{mzR::header(msRaw)}. Passing this value is useful
-  if spectra for multiple compounds should be extracted
-  from the same mzML file, since it avoids getting the data
-  freshly from \code{msRaw} for every compound.}
+\item{headerCache}{If present, the complete \code{mzR::header(msRaw)}. Passing
+this value is useful if spectra for multiple compounds should be
+extracted from the same mzML file, since it avoids getting the data
+freshly from \code{msRaw} for every compound.}
+
+\item{floatingRecalibration}{A fitting function that \code{predict()}s a mass shift based on the retention time. Can be used
+if a lockmass calibration is known (however you have to build the calibration yourself.)}
 }
 \value{
-  A \code{[rt, intensity, scan]} matrix (\code{scan} being
-  the scan number.)
+A \code{[rt, intensity, scan]} matrix (\code{scan} being the scan number.)
 }
 \description{
-  Extract EICs from raw data for a determined mass window.
+Extract EICs from raw data for a determined mass window.
 }
 \author{
-  Michael A. Stravs, Eawag <michael.stravs@eawag.ch>
+Michael A. Stravs, Eawag <michael.stravs@eawag.ch>
 }
 \seealso{
-  findMsMsHR
+findMsMsHR
 }
 
diff --git a/man/findMsMsHR.Rd b/man/findMsMsHR.Rd
index d4416a478e342a9f7f3e816f2dbb6a430d9ded50..ba78dc2fe8e2136709bb474539cce13505211be3 100755
--- a/man/findMsMsHR.Rd
+++ b/man/findMsMsHR.Rd
@@ -1,131 +1,108 @@
+% Generated by roxygen2 (4.1.0): do not edit by hand
+% Please edit documentation in R/leMsmsRaw.R
 \name{findMsMsHR}
 \alias{findMsMsHR}
 \alias{findMsMsHR.direct}
 \alias{findMsMsHR.mass}
 \title{Extract MS/MS spectra for specified precursor}
 \usage{
-  findMsMsHR(fileName, cpdID, mode="pH",confirmMode =0,
-    useRtLimit = TRUE, ppmFine =
-    getOption("RMassBank")$findMsMsRawSettings$ppmFine,
-    mzCoarse =
-    getOption("RMassBank")$findMsMsRawSettings$mzCoarse,
-    fillPrecursorScan =
-    getOption("RMassBank")$findMsMsRawSettings$fillPrecursorScan,
-    rtMargin = getOption("RMassBank")$rtMargin, deprofile =
-    getOption("RMassBank")$deprofile)
-
-  findMsMsHR.mass(msRaw, mz, limit.coarse, limit.fine,
-    rtLimits = NA, maxCount = NA, headerCache = NA,
-    fillPrecursorScan = FALSE, deprofile =
-    getOption("RMassBank")$deprofile)
-
-  findMsMsHR.direct(msRaw, cpdID, mode = "pH", confirmMode
-    = 0, useRtLimit = TRUE, ppmFine =
-    getOption("RMassBank")$findMsMsRawSettings$ppmFine,
-    mzCoarse =
-    getOption("RMassBank")$findMsMsRawSettings$mzCoarse,
-    fillPrecursorScan =
-    getOption("RMassBank")$findMsMsRawSettings$fillPrecursorScan,
-    rtMargin = getOption("RMassBank")$rtMargin, deprofile =
-    getOption("RMassBank")$deprofile, headerCache = NA)
+findMsMsHR(fileName, cpdID, mode="pH",confirmMode =0, useRtLimit = TRUE,
+		ppmFine = getOption("RMassBank")$findMsMsRawSettings$ppmFine,
+		mzCoarse = getOption("RMassBank")$findMsMsRawSettings$mzCoarse,
+		fillPrecursorScan = getOption("RMassBank")$findMsMsRawSettings$fillPrecursorScan,
+		rtMargin = getOption("RMassBank")$rtMargin,
+		deprofile = getOption("RMassBank")$deprofile)
+
+		findMsMsHR.mass(msRaw, mz, limit.coarse, limit.fine, rtLimits = NA, maxCount = NA,
+		headerCache = NULL, fillPrecursorScan = FALSE,
+		deprofile = getOption("RMassBank")$deprofile)
+
+findMsMsHR.direct(msRaw, cpdID, mode = "pH", confirmMode = 0, useRtLimit = TRUE,
+			ppmFine = getOption("RMassBank")$findMsMsRawSettings$ppmFine,
+			mzCoarse = getOption("RMassBank")$findMsMsRawSettings$mzCoarse,
+			fillPrecursorScan = getOption("RMassBank")$findMsMsRawSettings$fillPrecursorScan,
+			rtMargin = getOption("RMassBank")$rtMargin,
+			deprofile = getOption("RMassBank")$deprofile, headerCache = NULL)
 }
 \arguments{
-  \item{fileName}{The file to open and search the MS2
-  spectrum in.}
+\item{fileName}{The file to open and search the MS2 spectrum in.}
 
-  \item{msRaw}{The opened raw file (mzR file handle) to
-  search the MS2 spectrum in.}
+\item{cpdID}{The compound ID in the compound list (see \code{\link{loadList}})
+to use for formula lookup.}
 
-  \item{cpdID}{The compound ID in the compound list (see
-  \code{\link{loadList}}) to use for formula lookup.}
+\item{mode}{The processing mode (determines which ion/adduct is searched):
+\code{"pH", "pNa", "pM", "pNH4", "mH", "mM", "mFA"} for different ions
+([M+H]+, [M+Na]+, [M]+, [M+NH4]+, [M-H]-, [M]-, [M+FA]-).}
 
-  \item{mz}{The mass to use for spectrum search.}
+\item{confirmMode}{Whether to use the highest-intensity precursor (=0), second-
+highest (=1), third-highest (=2)...}
 
-  \item{ppmFine}{The limit in ppm to use for fine limit
-  (see below) calculation.}
+\item{useRtLimit}{Whether to respect retention time limits from the compound list.}
 
-  \item{mzCoarse}{The coarse limit to use for locating
-  potential MS2 scans: this tolerance is used when finding
-  scans with a suitable precursor ion value.}
+\item{ppmFine}{The limit in ppm to use for fine limit (see below) calculation.}
 
-  \item{limit.fine}{The fine limit to use for locating MS2
-  scans: this tolerance is used when locating an
-  appropriate analyte peak in the MS1 precursor spectrum.}
+\item{mzCoarse}{The coarse limit to use for locating potential MS2 scans:
+this tolerance is used when finding scans with a suitable precursor
+ion value.}
 
-  \item{limit.coarse}{Parameter in \code{findMsMsHR.mass}
-  corresponding to \code{mzCoarse}.  (The parameters are
-  distinct to clearly conceptually distinguish
-  findMsMsHR.mass (a standalone useful function) from the
-  cpdID based functions (workflow functions).)}
+\item{fillPrecursorScan}{If \code{TRUE}, the precursor scan will be filled from MS1 data.
+To be used for data where the precursor scan is not stored in the raw data.}
 
-  \item{mode}{The processing mode (determines which
-  ion/adduct is searched): \code{"pH", "pNa", "pM", "mH",
-  "mM", "mFA"} for different ions ([M+H]+, [M+Na]+, [M]+,
-  [M-H]-, [M]-, [M+FA]-).}
+\item{rtMargin}{The retention time tolerance to use.}
 
-  \item{confirmMode}{Whether to use the highest-intensity
-  precursor (=0), second- highest (=1), third-highest
-  (=2)...}
+\item{deprofile}{Whether deprofiling should take place, and what method should be
+used (cf. \code{\link{deprofile}})}
 
-  \item{useRtLimit}{Whether to respect retention time
-  limits from the compound list.}
+\item{msRaw}{The opened raw file (mzR file handle) to search the MS2 spectrum in.}
 
-  \item{rtLimits}{\code{c(min, max)}: Minimum and maximum
-  retention time to use when locating the MS2 scans.}
+\item{mz}{The mass to use for spectrum search.}
 
-  \item{headerCache}{If present, the complete
-  \code{mzR::header(msRaw)}. Passing this value is useful
-  if spectra for multiple compounds should be extracted
-  from the same mzML file, since it avoids getting the data
-  freshly from \code{msRaw} for every compound.}
+\item{limit.fine}{The fine limit to use for locating MS2 scans: this tolerance
+is used when locating an appropriate analyte peak in the MS1 precursor
+spectrum.}
 
-  \item{maxCount}{The maximal number of spectra groups to
-  return. One spectra group consists of all data-dependent
-  scans from the same precursor whose precursor mass
-  matches the specified search mass.}
+\item{limit.coarse}{Parameter in \code{findMsMsHR.mass} corresponding to \code{mzCoarse}.
+(The parameters are distinct to clearly conceptually distinguish findMsMsHR.mass
+(a standalone useful function) from the cpdID based functions (workflow functions).)}
 
-  \item{fillPrecursorScan}{If \code{TRUE}, the precursor
-  scan will be filled from MS1 data.  To be used for data
-  where the precursor scan is not stored in the raw data.}
+\item{rtLimits}{\code{c(min, max)}: Minimum and maximum retention time to use
+when locating the MS2 scans.}
 
-  \item{rtMargin}{The retention time tolerance to use.}
+\item{headerCache}{If present, the complete \code{mzR::header(msRaw)}. Passing
+this value is useful if spectra for multiple compounds should be
+extracted from the same mzML file, since it avoids getting the data
+freshly from \code{msRaw} for every compound.}
 
-  \item{deprofile}{Whether deprofiling should take place,
-  and what method should be used (cf.
-  \code{\link{deprofile}})}
+\item{maxCount}{The maximal number of spectra groups to return. One spectra group
+consists of all data-dependent scans from the same precursor whose precursor
+mass matches the specified search mass.}
 }
 \value{
-  For \code{findMsMsHR} and \code{findMsMsHR.direct}: A
-  "spectrum set", a list with items:
-  \item{foundOK}{\code{TRUE} if a spectrum was found,
-  \code{FALSE} otherwise.  Note: if \code{FALSE}, all other
-  values can be missing!} \item{parentScan}{The scan number
-  of the precursor scan.} \item{parentHeader}{The header
-  row of the parent scan, as returned by
-  \code{mzR::header}.} \item{childScans}{The scan numbers
-  of the data-dependent MS2 scans.} \item{childHeaders}{The
-  header rows of the MS2 scan, as returned by
-  \code{mzR::header}.} \item{parentPeak}{The MS1 precursor
-  spectrum as a 2-column matrix} \item{peaks}{A list of
-  2-column \code{mz, int} matrices of the MS2 scans.} For
-  \code{findMsMsHR.mass}: a list of "spectrum sets" as
-  defined above, sorted by decreasing precursor intensity.
+For \code{findMsMsHR} and \code{findMsMsHR.direct}: A "spectrum set", a list with items:
+			\item{foundOK}{\code{TRUE} if a spectrum was found, \code{FALSE} otherwise.
+				Note: if \code{FALSE}, all other values can be missing!}
+			\item{parentScan}{The scan number of the precursor scan.}
+			\item{parentHeader}{The header row of the parent scan, as returned by
+				\code{mzR::header}.}
+			\item{childScans}{The scan numbers of the data-dependent MS2 scans.}
+			\item{childHeaders}{The header rows of the MS2 scan, as returned by
+				\code{mzR::header}.}
+			\item{parentPeak}{The MS1 precursor spectrum as a 2-column matrix}
+			\item{peaks}{A list of  2-column \code{mz, int} matrices of the MS2 scans.}
+			For \code{findMsMsHR.mass}: a list of "spectrum sets" as defined above, sorted
+			by decreasing precursor intensity.
 }
 \description{
-  Extracts MS/MS spectra from LC-MS raw data for a
-  specified precursor, specified either via the RMassBank
-  compound list (see \code{\link{loadList}}) or via a mass.
+Extracts MS/MS spectra from LC-MS raw data for a specified precursor, specified
+either via the RMassBank compound list (see \code{\link{loadList}}) or via a mass.
 }
 \details{
-  Different versions of the function get the data from
-  different sources. Note that findMsMsHR and
-  findMsMsHR.direct differ mainly in that findMsMsHR opens
-  a file whereas findMsMs.direct uses an open file handle -
-  both are intended to be used in a full process which
-  involves compound lists etc. In contrast, findMsMsHR.mass
-  is a low-level function which uses the mass directly for
-  lookup and is intended for use as a standalone function
-  in unrelated applications.
+Different versions of the function get the data from different sources. Note that
+		findMsMsHR and findMsMsHR.direct differ mainly in that findMsMsHR opens a file
+		whereas findMsMs.direct uses an open file handle - both are intended to be used
+		in a full process which involves compound lists etc. In contrast, findMsMsHR.mass
+		is a low-level function which uses the mass directly for lookup and is intended for
+		use as a standalone function in unrelated applications.
 }
 \examples{
 \dontrun{
@@ -142,9 +119,9 @@
 }
 }
 \author{
-  Michael A. Stravs, Eawag <michael.stravs@eawag.ch>
+Michael A. Stravs, Eawag <michael.stravs@eawag.ch>
 }
 \seealso{
-  findEIC
+findEIC
 }
 
diff --git a/man/gatherData.Rd b/man/gatherData.Rd
index e900994e080a633ffeda52689334b23b58620bdd..f317433d7092f6dfe1c3907754ed50214db705d4 100755
--- a/man/gatherData.Rd
+++ b/man/gatherData.Rd
@@ -1,55 +1,55 @@
+% Generated by roxygen2 (4.1.0): do not edit by hand
+% Please edit documentation in R/createMassBank.R
 \name{gatherData}
 \alias{gatherData}
 \title{Retrieve annotation data}
 \usage{
-  gatherData(id)
+gatherData(id)
 }
 \arguments{
-  \item{id}{The compound ID.}
+\item{id}{The compound ID.}
 }
 \value{
-  Returns a list of type \code{list(id= \var{compoundID},
-  ..., 'ACCESSION' = '', 'RECORD_TITLE' = '', )} etc. %%
-  ...
+Returns a list of type \code{list(id= \var{compoundID}, ...,
+'ACCESSION' = '', 'RECORD_TITLE' = '', )} etc. %% ...
 }
 \description{
-  Retrieves annotation data for a compound from the
-  internet services CTS and Cactvs, based on the SMILES
-  code and name of the compounds stored in the compound
-  list.
+Retrieves annotation data for a compound from the internet services CTS, Pubchem, Chemspider and
+Cactvs, based on the SMILES code and name of the compounds stored in the
+compound list.
 }
 \details{
-  Composes the "upper part" of a MassBank record filled
-  with chemical data about the compound: name, exact mass,
-  structure, CAS no., links to PubChem, KEGG, ChemSpider.
-  The instrument type is also written into this block (even
-  if not strictly part of the chemical information).
-  Additionally, index fields are added at the start of the
-  record, which will be removed later: \code{id, dbcas,
-  dbname} from the compound list, \code{dataused} to
-  indicate the used identifier for CTS search
-  (\code{smiles} or \code{dbname}).
+Composes the "upper part" of a MassBank record filled with chemical data
+about the compound: name, exact mass, structure, CAS no., links to PubChem,
+KEGG, ChemSpider.  The instrument type is also written into this block (even
+if not strictly part of the chemical information). Additionally, index
+fields are added at the start of the record, which will be removed later:
+\code{id, dbcas, dbname} from the compound list, \code{dataused} to indicate
+the used identifier for CTS search (\code{smiles} or \code{dbname}).
 
-  Additionally, the fields \code{ACCESSION} and
-  \code{RECORD_TITLE} are inserted empty and will be filled
-  later on.
+Additionally, the fields \code{ACCESSION} and \code{RECORD_TITLE} are
+inserted empty and will be filled later on.
 }
 \examples{
 # Gather data for compound ID 131
 \dontrun{gatherData(131)}
 }
 \author{
-  Michael Stravs
+Michael Stravs
 }
 \references{
-  Chemical Translation Service:
-  \url{http://uranus.fiehnlab.ucdavis.edu:8080/cts/homePage}
-  cactus Chemical Identifier Resolver:
-  \url{http://cactus.nci.nih.gov/chemical/structure}
-  MassBank record format:
-  \url{http://www.massbank.jp/manuals/MassBankRecord_en.pdf}
+Chemical Translation Service:
+\url{http://uranus.fiehnlab.ucdavis.edu:8080/cts/homePage}
+cactus Chemical Identifier Resolver:
+\url{http://cactus.nci.nih.gov/chemical/structure}
+MassBank record format:
+\url{http://www.massbank.jp/manuals/MassBankRecord_en.pdf}
+Pubchem REST:
+\url{https://pubchem.ncbi.nlm.nih.gov/pug_rest/PUG_REST.html}
+Chemspider InChI conversion:
+\url{https://www.chemspider.com/InChI.asmx}
 }
 \seealso{
-  \code{\link{mbWorkflow}}
+\code{\link{mbWorkflow}}
 }
 
diff --git a/man/gatherDataBabel.Rd b/man/gatherDataBabel.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..4727d5b58ed78f4ea03cae15af63ea890dc90536
--- /dev/null
+++ b/man/gatherDataBabel.Rd
@@ -0,0 +1,49 @@
+% Generated by roxygen2 (4.1.0): do not edit by hand
+% Please edit documentation in R/createMassBank.R
+\name{gatherDataBabel}
+\alias{gatherDataBabel}
+\title{Retrieve annotation data}
+\usage{
+gatherDataBabel(id)
+}
+\arguments{
+\item{id}{The compound ID.}
+}
+\value{
+Returns a list of type \code{list(id= \var{compoundID}, ...,
+'ACCESSION' = '', 'RECORD_TITLE' = '', )} etc. %% ...
+}
+\description{
+Retrieves annotation data for a compound by using babel,
+based on the SMILES code and name of the compounds stored in the
+compound list.
+}
+\details{
+Composes the "upper part" of a MassBank record filled with chemical data
+about the compound: name, exact mass, structure, CAS no..
+The instrument type is also written into this block (even
+if not strictly part of the chemical information). Additionally, index
+fields are added at the start of the record, which will be removed later:
+\code{id, dbcas, dbname} from the compound list.
+
+Additionally, the fields \code{ACCESSION} and \code{RECORD_TITLE} are
+inserted empty and will be filled later on.
+
+This function is an alternative to gatherData, in case CTS is down or if information
+on one or more of the compounds in the compound list are sparse
+}
+\examples{
+# Gather data for compound ID 131
+\dontrun{gatherDataBabel(131)}
+}
+\author{
+Michael Stravs, Erik Mueller
+}
+\references{
+MassBank record format:
+\url{http://www.massbank.jp/manuals/MassBankRecord_en.pdf}
+}
+\seealso{
+\code{\link{mbWorkflow}}
+}
+
diff --git a/man/gatherPubChem.Rd b/man/gatherPubChem.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..c60864df1ab2b053e157097dca32dff2e1358f37
--- /dev/null
+++ b/man/gatherPubChem.Rd
@@ -0,0 +1,43 @@
+% Generated by roxygen2 (4.1.0): do not edit by hand
+% Please edit documentation in R/createMassBank.R
+\name{gatherPubChem}
+\alias{gatherPubChem}
+\title{Retrieve supplemental annotation data from Pubchem}
+\usage{
+gatherPubChem(key)
+}
+\arguments{
+\item{key}{An Inchi-Key}
+}
+\value{
+Returns a list with 4 slots:
+\code{PcID} The Pubchem CID
+\code{Synonym} An arbitrary synonym for the compound name
+\code{IUPAC} A IUPAC-name (preferred if available)
+\code{Chebi} The identification number of the chebi database
+}
+\description{
+Retrieves annotation data for a compound from the internet service Pubchem
+based on the inchikey generated by babel or Cactus
+}
+\details{
+The data retrieved is the Pubchem CID, a synonym from the Pubchem database,
+the IUPAC name (using the preferred if available) and a Chebi link
+}
+\examples{
+# Gather data for compound ID 131
+\dontrun{gatherPubChem("QEIXBXXKTUNWDK-UHFFFAOYSA-N")}
+}
+\author{
+Erik Mueller
+}
+\references{
+Pubchem REST:
+\url{https://pubchem.ncbi.nlm.nih.gov/pug_rest/PUG_REST.html}
+Chebi:
+\url{http://www.ebi.ac.uk/chebi}
+}
+\seealso{
+\code{\link{mbWorkflow}}
+}
+
diff --git a/man/getPcId.Rd b/man/getPcId.Rd
index 3a46b4a799b593b155219e891d38d539e2913c44..b9ece4025c8379916b0f07cf133c3606911d1e3a 100755
--- a/man/getPcId.Rd
+++ b/man/getPcId.Rd
@@ -1,37 +1,39 @@
+% Generated by roxygen2 (4.1.0): do not edit by hand
+% Please edit documentation in R/webAccess.R
 \name{getPcId}
 \alias{getPcId}
 \title{Search Pubchem CID}
 \usage{
-  getPcId(search)
+getPcId(query, from = "inchikey")
 }
 \arguments{
-  \item{search}{The search term.}
+\item{query}{ID to be converted}
+
+\item{from}{Type of input ID}
 }
 \value{
-  The PubChem CID (in string type).
+The PubChem CID (in string type).
 }
 \description{
-  Retrieves PubChem CIDs for a search term.
+Retrieves PubChem CIDs for a search term.
 }
 \details{
-  Only the first result is returned currently. \bold{The
-  function should be regarded as experimental and has not
-  thoroughly been tested.}
+Only the first result is returned currently. \bold{The function should be
+regarded as experimental and has not thoroughly been tested.}
 }
 \examples{
-# Benzene (again):
-# Currently broken: getPcId("benzene")
+getPcId("MKXZASYAUGDDCJ-NJAFHUGGSA-N")
 }
 \author{
-  Michael Stravs
+Michael Stravs, Erik Mueller
 }
 \references{
-  PubChem search: \url{http://pubchem.ncbi.nlm.nih.gov/}
+PubChem search: \url{http://pubchem.ncbi.nlm.nih.gov/}
 
-  Entrez E-utilities:
-  \url{http://www.ncbi.nlm.nih.gov/books/NBK25500/}
+Pubchem REST:
+\url{https://pubchem.ncbi.nlm.nih.gov/pug_rest/PUG_REST.html}
 }
 \seealso{
-  \code{\link{getCtsRecord}}, \code{\link{getCactus}}
+\code{\link{getCtsRecord}}, \code{\link{getCactus}}
 }
 
diff --git a/man/loadList.Rd b/man/loadList.Rd
index a4a77ec5886d1e96e09e47bf630cf1eab06539c8..dc735e952b458f85ead232810797b94742b0926b 100755
--- a/man/loadList.Rd
+++ b/man/loadList.Rd
@@ -1,42 +1,45 @@
+% Generated by roxygen2 (4.1.0): do not edit by hand
+% Please edit documentation in R/leCsvAccess.R
 \name{loadList}
 \alias{loadList}
 \alias{resetList}
 \title{Load compound list for RMassBank}
 \usage{
-  loadList(path, listEnv=NULL)
+loadList(path, listEnv=NULL, check=TRUE)
 
-  resetList()
+resetList()
 }
 \arguments{
-  \item{path}{Path to the CSV list.}
+\item{path}{Path to the CSV list.}
 
-  \item{listEnv}{The environment to load the list into. By
-  default, the namelist is loaded into an environment
-  internally in RMassBank.}
+\item{listEnv}{The environment to load the list into. By default, the namelist is loaded
+into an environment internally in RMassBank.}
+
+\item{check}{A parameter that specifies whether the SMILES-Codes in the list should be checked for readability by rcdk.}
 }
 \value{
-  No return value.
+No return value.
 }
 \description{
-  Loads a CSV compound list with compound IDs
+Loads a CSV compound list with compound IDs
 }
 \details{
-  The list is loaded into the variable
-  \code{\var{compoundList}} in the environment
-  \code{listEnv} (which defaults to the global environment)
-  and used by the \code{findMz}, \code{findCAS}, ...
-  functions.
+The list is loaded into the variable \code{\var{compoundList}} in the environment
+\code{listEnv} (which defaults to the global environment) and used by
+the \code{findMz}, \code{findCAS}, ... functions. The CSV file is required to have at least the following columns, which are used for
+further processing and must be named correctly (but present in any order): \var{ID, Name, SMILES, RT,
+CAS}
 
-  resetList() clears a currently loaded list.
+resetList() clears a currently loaded list.
 }
 \examples{
 ##
 \dontrun{loadList("mylist.csv")}
 }
 \author{
-  Michael Stravs
+Michael Stravs
 }
 \seealso{
-  \code{\link{findMz}}
+\code{\link{findMz}}
 }
 
diff --git a/man/mbWorkflow.Rd b/man/mbWorkflow.Rd
index 275ef1d8065e13d30a671792771f81e4acc485bd..592c609cc13ef3e89a1ba5d1f8222cf71038655b 100755
--- a/man/mbWorkflow.Rd
+++ b/man/mbWorkflow.Rd
@@ -1,63 +1,59 @@
+% Generated by roxygen2 (4.1.0): do not edit by hand
+% Please edit documentation in R/createMassBank.R
 \name{mbWorkflow}
 \alias{mbWorkflow}
 \title{MassBank record creation workflow}
 \usage{
-  mbWorkflow(mb, steps = c(1, 2, 3, 4, 5, 6, 7, 8),
-    infolist_path = "./infolist.csv")
+mbWorkflow(mb, steps = c(1, 2, 3, 4, 5, 6, 7, 8),
+  infolist_path = "./infolist.csv", gatherData = "online")
 }
 \arguments{
-  \item{steps}{Which steps in the workflow to perform.}
+\item{mb}{The \code{mbWorkspace} to work in.}
 
-  \item{infolist_path}{A path where to store newly
-  downloaded compound informations, which should then be
-  manually inspected.}
+\item{steps}{Which steps in the workflow to perform.}
 
-  \item{mb}{The \code{mbWorkspace} to work in.}
+\item{infolist_path}{A path where to store newly downloaded compound informations,
+which should then be manually inspected.}
+
+\item{gatherData}{A variable denoting whether to retrieve information using several online databases \code{gatherData= "online"}
+or to use the local babel installation \code{gatherData= "babel"}. Note that babel is used either way, if a directory is given
+in the settings}
 }
 \value{
-  The processed \code{mbWorkspace}.
+The processed \code{mbWorkspace}.
 }
 \description{
-  Uses data generated by \code{\link{msmsWorkflow}} to
-  create MassBank records.
+Uses data generated by \code{\link{msmsWorkflow}} to create MassBank records.
 }
 \details{
-  See the vignette \code{vignette("RMassBank")} for
-  detailed informations about the usage.
+See the vignette \code{vignette("RMassBank")} for detailed informations about the usage.
 
-  Steps:
+Steps:
 
-  Step 1: Find which compounds don't have annotation
-  information yet. For these compounds, pull information
-  from CTS (using gatherData).
+Step 1: Find which compounds don't have annotation information yet. For these
+		 compounds, pull information from several databases (using gatherData).
 
-  Step 2: If new compounds were found, then export the
-  infolist.csv and stop the workflow.  Otherwise, continue.
+Step 2: If new compounds were found, then export the infolist.csv and stop the workflow.
+		Otherwise, continue.
 
-  Step 3: Take the archive data (in table format) and
-  reformat it to MassBank tree format.
+Step 3: Take the archive data (in table format) and reformat it to MassBank tree format.
 
-  Step 4: Compile the spectra. Using the skeletons from the
-  archive data, create MassBank records per compound and
-  fill them with peak data for each spectrum.  Also, assign
-  accession numbers based on scan mode and relative scan
-  no.
+Step 4: Compile the spectra. Using the skeletons from the archive data, create
+  MassBank records per compound and fill them with peak data for each spectrum.
+  Also, assign accession numbers based on scan mode and relative scan no.
 
-  Step 5: Convert the internal tree-like representation of
-  the MassBank data into flat-text string arrays
-  (basically, into text-file style, but still in memory)
+Step 5: Convert the internal tree-like representation of the MassBank data into
+ flat-text string arrays (basically, into text-file style, but still in memory)
 
-  Step 6: For all OK records, generate a corresponding
-  molfile with the structure of the compound, based on the
-  SMILES entry from the MassBank record. (This molfile is
-  still in memory only, not yet a physical file)
+Step 6: For all OK records, generate a corresponding molfile with the structure
+  of the compound, based on the SMILES entry from the MassBank record. (This molfile
+  is still in memory only, not yet a physical file)
 
-  Step 7: If necessary, generate the appropriate
-  subdirectories, and actually write the files to disk.
+Step 7: If necessary, generate the appropriate subdirectories, and actually write
+  the files to disk.
 
-  Step 8: Create the list.tsv in the molfiles folder, which
-  is required by MassBank to attribute substances to their
-  corresponding structure molfiles.
+Step 8: Create the list.tsv in the molfiles folder, which is required by MassBank
+  to attribute substances to their corresponding structure molfiles.
 }
 \examples{
 \dontrun{
@@ -68,9 +64,9 @@
 }
 }
 \author{
-  Michael A. Stravs, Eawag <michael.stravs@eawag.ch>
+Michael A. Stravs, Eawag <michael.stravs@eawag.ch>
 }
 \seealso{
-  \code{\link{mbWorkspace-class}}
+\code{\link{mbWorkspace-class}}
 }
 
diff --git a/man/mbWorkspace-class.Rd b/man/mbWorkspace-class.Rd
index 8aeeedef41383e144982af94bb618fa83851e0f6..67e5cab7deddb25a8f8b2543f2e872abfa5fe383 100755
--- a/man/mbWorkspace-class.Rd
+++ b/man/mbWorkspace-class.Rd
@@ -1,37 +1,41 @@
-\docType{class}
-\name{mbWorkspace-class}
-\alias{mbWorkspace-class}
-\alias{show,mbWorkspace-method}
-\title{Workspace for \code{mbWorkflow} data}
-\description{
-  A workspace which stores input and output data for use
-  with \code{mbWorkflow}.
-}
-\details{
-  Slots: \describe{ \item{aggregatedRcSpecs,
-  refilteredRcSpecs}{The corresponding input data from
-  \code{\link{msmsWorkspace-class}}}
-  \item{additionalPeaks}{A list of additional peaks which
-  can be loaded using \code{\link{addPeaks}}.}
-  \item{mbdata, mbdata_archive, mbdata_relisted}{Infolist
-  data: Data for annotation of MassBank records, which can
-  be loaded using \code{\link{loadInfolists}}.}
-  \item{compiled, compiled_ok}{ Compiled tree-structured
-  MassBank records. \code{compiled_ok} contains only the
-  compounds with at least one valid spectrum.}
-  \item{mbfiles}{Compiled MassBank records in text
-  representation.} \item{molfile}{MOL files with the
-  compound structures.} \item{ok,problems}{Index lists for
-  internal use which denote which compounds have valid
-  spectra.} }
-
-  Methods: \describe{ \item{show}{Shows a brief summary of
-  the object. Currently only a stub.} }
-}
-\author{
-  Michael Stravs, Eawag <michael.stravs@eawag.ch>
-}
-\seealso{
-  \code{\link{mbWorkflow}}
-}
-
+\docType{class}
+\name{mbWorkspace-class}
+\alias{mbWorkspace-class}
+\alias{show,mbWorkspace-method}
+\title{Workspace for \code{mbWorkflow} data}
+\description{
+A workspace which stores input and output data for use with \code{mbWorkflow}.
+
+
+}
+\details{
+Slots:
+ \describe{
+	\item{aggregatedRcSpecs, refilteredRcSpecs}{The corresponding
+		 input data from \code{\link{msmsWorkspace-class}}}
+ \item{additionalPeaks}{A list of additional peaks which can be loaded
+		using \code{\link{addPeaks}}.}
+ \item{mbdata, mbdata_archive, mbdata_relisted}{Infolist data: Data for
+		annotation of MassBank records, which can be loaded using
+		\code{\link{loadInfolists}}.}
+ \item{compiled, compiled_ok}{
+		Compiled tree-structured MassBank records. \code{compiled_ok} contains
+		only the compounds with at least one valid spectrum.}
+ \item{mbfiles}{Compiled MassBank records in text representation.}
+ \item{molfile}{MOL files with the compound structures.}
+ \item{ok,problems}{Index lists for internal use which denote which compounds
+		have valid spectra.}
+}
+
+Methods:
+\describe{
+		\item{show}{Shows a brief summary of the object. Currently only a stub.}
+}
+}
+\author{
+Michael Stravs, Eawag <michael.stravs@eawag.ch>
+}
+\seealso{
+\code{\link{mbWorkflow}}
+}
+
diff --git a/man/msmsRead.RAW.Rd b/man/msmsRead.RAW.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..9d6d1c9cdfa93f1f729beb22778a2ec0d08889ae
--- /dev/null
+++ b/man/msmsRead.RAW.Rd
@@ -0,0 +1,52 @@
+% Generated by roxygen2 (4.1.0): do not edit by hand
+% Please edit documentation in R/msmsRead.R
+\name{msmsRead.RAW}
+\alias{msmsRead.RAW}
+\title{Extracts and processes spectra from a list of xcms-Objects}
+\usage{
+msmsRead.RAW(w, xRAW = NULL, cpdids = NULL, mode, findPeaksArgs = NULL,
+  settings = getOption("RMassBank"), progressbar = "progressBarHook",
+  plots = FALSE)
+}
+\arguments{
+\item{w}{A \code{msmsWorkspace} to work with.}
+
+\item{xRAW}{A list of xcmsRaw objects whose peaks should be detected and added to the workspace.
+The relevant data must be in the MS1 data of the xcmsRaw object.  You can coerce the
+msn-data in a usable object with the \code{msn2xcmsRaw} function of xcms.}
+
+\item{cpdids}{A vector or list containing the compound IDs of the files that are to be read as spectra.
+The ordering of this and \code{files} implicitly assigns each ID to the corresponding file.
+If this is supplied, then the IDs implicitly named in the filenames are ignored.}
+
+\item{mode}{\code{"pH", "pNa", "pM", "pNH4", "mH", "mM", "mFA"} for different ions
+([M+H]+, [M+Na]+, [M]+, [M+NH4]+, [M-H]-, [M]-, [M+FA]-).}
+
+\item{findPeaksArgs}{A list of arguments that will be handed to the xcms-method findPeaks via do.call}
+
+\item{settings}{Options to be used for processing. Defaults to the options loaded via
+\code{\link{loadRmbSettings}} et al. Refer to there for specific settings.}
+
+\item{progressbar}{The progress bar callback to use. Only needed for specialized applications.
+Cf. the documentation of \code{\link{progressBarHook}} for usage.}
+
+\item{plots}{A boolean value that determines whether the pseudospectra in XCMS should be plotted}
+}
+\value{
+The \code{msmsWorkspace} with msms-spectra read.
+}
+\description{
+The filenames of the raw LC-MS runs are read from the array \code{files}
+in the global enviroment.
+See the vignette \code{vignette("RMassBank")} for further details about the
+workflow.
+}
+\author{
+Michael Stravs, Eawag <michael.stravs@eawag.ch>
+
+Erik Mueller, UFZ
+}
+\seealso{
+\code{\link{msmsWorkspace-class}}, \code{\link{msmsWorkflow}}
+}
+
diff --git a/man/msmsRead.Rd b/man/msmsRead.Rd
index 0575bd3d29be11bc18c1b8804e89d7c5af48fcf4..14c1eba728aa936db3767108af7dae8c5b5145ed 100644
--- a/man/msmsRead.Rd
+++ b/man/msmsRead.Rd
@@ -1,85 +1,72 @@
+% Generated by roxygen2 (4.1.0): do not edit by hand
+% Please edit documentation in R/msmsRead.R
 \name{msmsRead}
 \alias{msmsRead}
 \title{Extracts and processes spectra from a specified file list, according to
 loaded options and given parameters.}
 \usage{
-  msmsRead(w, filetable = NULL, files = NULL,
-    cpdids = NULL, readMethod, mode, confirmMode = FALSE,
-    useRtLimit = TRUE, Args = NULL,
-    settings = getOption("RMassBank"),
-    progressbar = "progressBarHook", MSe = FALSE)
+msmsRead(w, filetable = NULL, files = NULL, cpdids = NULL, readMethod,
+  mode, confirmMode = FALSE, useRtLimit = TRUE, Args = NULL,
+  settings = getOption("RMassBank"), progressbar = "progressBarHook",
+  MSe = FALSE, plots = FALSE)
 }
 \arguments{
-  \item{w}{A \code{msmsWorkspace} to work with.}
+\item{w}{A \code{msmsWorkspace} to work with.}
 
-  \item{filetable}{The path to a .csv-file that contains
-  the columns "files" and "cpdid" supplying the
-  relationships between files and compound IDs. Either this
-  or "files" need to be specified.}
+\item{filetable}{The path to a .csv-file that contains the columns "Files" and "ID" supplying
+the relationships between files and compound IDs. Either this or the parameter "files" need
+to be specified.}
 
-  \item{files}{A vector or list containing the filenames of
-  the files that are to be read as spectra.  For the IDs to
-  be inferred from the filenames alone, there need to be
-  exactly 2 underscores.}
+\item{files}{A vector or list containing the filenames of the files that are to be read as spectra.
+For the IDs to be inferred from the filenames alone, there need to be exactly 2 underscores.}
 
-  \item{cpdids}{A vector or list containing the compound
-  IDs of the files that are to be read as spectra.  The
-  ordering of this and \code{files} implicitly assigns each
-  ID to the corresponding file.  If this is supplied, then
-  the IDs implicitly named in the filenames are ignored.}
+\item{cpdids}{A vector or list containing the compound IDs of the files that are to be read as spectra.
+The ordering of this and \code{files} implicitly assigns each ID to the corresponding file.
+If this is supplied, then the IDs implicitly named in the filenames are ignored.}
 
-  \item{readMethod}{Several methods are available to get
-  peak lists from the files.  Currently supported are
-  "mzR", "xcms", "MassBank" and "peaklist".  The first two
-  read MS/MS raw data, and differ in the strategy used to
-  extract peaks. MassBank will read existing records, so
-  that e.g. a recalibration can be performed, and
-  "peaklist" just requires a CSV with two columns and the
-  column header "mz", "int".}
+\item{readMethod}{Several methods are available to get peak lists from the files.
+Currently supported are "mzR", "xcms", "MassBank" and "peaklist".
+The first two read MS/MS raw data, and differ in the strategy
+used to extract peaks. MassBank will read existing records,
+so that e.g. a recalibration can be performed, and "peaklist"
+just requires a CSV with two columns and the column header "mz", "int".}
 
-  \item{mode}{\code{"pH", "pNa", "pM", "mH", "mM", "mFA"}
-  for different ions ([M+H]+, [M+Na]+, [M]+, [M-H]-, [M]-,
-  [M+FA]-).}
+\item{mode}{\code{"pH", "pNa", "pM", "pNH4", "mH", "mM", "mFA"} for different ions
+([M+H]+, [M+Na]+, [M]+, [M+NH4]+, [M-H]-, [M]-, [M+FA]-).}
 
-  \item{confirmMode}{Defaults to false (use most intense
-  precursor). Value 1 uses the 2nd-most intense precursor
-  for a chosen ion (and its data-dependent scans) , etc.}
+\item{confirmMode}{Defaults to false (use most intense precursor). Value 1 uses
+the 2nd-most intense precursor for a chosen ion (and its data-dependent scans)
+, etc.}
 
-  \item{useRtLimit}{Whether to enforce the given retention
-  time window.}
+\item{useRtLimit}{Whether to enforce the given retention time window.}
 
-  \item{Args}{A list of arguments that will be handed to
-  the xcms-method findPeaks via do.call}
+\item{Args}{A list of arguments that will be handed to the xcms-method findPeaks via do.call}
 
-  \item{settings}{Options to be used for processing.
-  Defaults to the options loaded via
-  \code{\link{loadRmbSettings}} et al. Refer to there for
-  specific settings.}
+\item{settings}{Options to be used for processing. Defaults to the options loaded via
+\code{\link{loadRmbSettings}} et al. Refer to there for specific settings.}
 
-  \item{progressbar}{The progress bar callback to use. Only
-  needed for specialized applications.  Cf. the
-  documentation of \code{\link{progressBarHook}} for
-  usage.}
+\item{progressbar}{The progress bar callback to use. Only needed for specialized applications.
+Cf. the documentation of \code{\link{progressBarHook}} for usage.}
 
-  \item{MSe}{A boolean value that determines whether the
-  spectra were recorded using MSe or not}
+\item{MSe}{A boolean value that determines whether the spectra were recorded using MSe or not}
+
+\item{plots}{A boolean value that determines whether the pseudospectra in XCMS should be plotted}
 }
 \value{
-  The \code{msmsWorkspace} with msms-spectra read.
+The \code{msmsWorkspace} with msms-spectra read.
 }
 \description{
-  The filenames of the raw LC-MS runs are read from the
-  array \code{files} in the global enviroment. See the
-  vignette \code{vignette("RMassBank")} for further details
-  about the workflow.
+The filenames of the raw LC-MS runs are read from the array \code{files}
+in the global enviroment.
+See the vignette \code{vignette("RMassBank")} for further details about the
+workflow.
 }
 \author{
-  Michael Stravs, Eawag <michael.stravs@eawag.ch>
+Michael Stravs, Eawag <michael.stravs@eawag.ch>
 
-  Erik Mueller, UFZ
+Erik Mueller, UFZ
 }
 \seealso{
-  \code{\link{msmsWorkspace-class}},
-  \code{\link{msmsWorkflow}}
+\code{\link{msmsWorkspace-class}}, \code{\link{msmsWorkflow}}
 }
 
diff --git a/man/msmsWorkspace-class.Rd b/man/msmsWorkspace-class.Rd
index 8dfe27a4e645f8abb48c7d3f2a855e4767c48e7c..b580fcdd3bfb85cfd0de83e42f5d07937c388a86 100755
--- a/man/msmsWorkspace-class.Rd
+++ b/man/msmsWorkspace-class.Rd
@@ -1,41 +1,41 @@
-\docType{class}
-\name{msmsWorkspace-class}
-\alias{msmsWorkspace-class}
-\alias{show,msmsWorkspace-method}
-\title{Workspace for \code{msmsWorkflow} data}
-\description{
-  A workspace which stores input and output data for
-  \code{\link{msmsWorkflow}}.
-}
-\details{
-  Slots:
-
-  \describe{ \item{files}{The input file names}
-  \item{specs}{The spectra extracted from the raw files}
-  \item{analyzedSpecs}{The spectra with annotated peaks
-  after workflow step 2.} \item{aggregatedSpecs}{The
-  \code{analyzedSpec} data regrouped and aggregated, after
-  workflow step 3.} \item{rc, rc.ms1}{The recalibration
-  curves generated in workflow step 4.}
-  \item{recalibratedSpecs}{The spectra from \code{specs}
-  recalibrated with the curves from \code{rc, rc,ms1}.}
-  \item{analyzedRcSpecs}{The recalibrated spectra with
-  annotated peaks after workflow step 5.}
-  \item{aggregatedRcSpecs}{The \code{analyzedRcSpec} data
-  regrouped and aggregated, after workflow step 6.}
-  \item{reanalyzedRcSpecs}{The regrouped and aggregated
-  spectra, with added reanalyzed peaks (after step 7, see
-  \code{\link{reanalyzeFailpeaks}}).}
-  \item{refilteredRcSpecs}{Final data to use for MassBank
-  record creation after multiplicity filtering (step 8).} }
-
-  Methods: \describe{ \item{show}{Shows a brief summary of
-  the object. Currently only the included files.} }
-}
-\author{
-  Michael Stravs, Eawag <michael.stravs@eawag.ch>
-}
-\seealso{
-  \code{\link{msmsWorkflow}}
-}
-
+\docType{class}
+\name{msmsWorkspace-class}
+\alias{msmsWorkspace-class}
+\alias{show,msmsWorkspace-method}
+\title{Workspace for \code{msmsWorkflow} data}
+\description{
+A workspace which stores input and output data for \code{\link{msmsWorkflow}}.
+}
+\details{
+Slots:
+
+\describe{
+	\item{files}{The input file names}
+	\item{specs}{The spectra extracted from the raw files}
+ \item{analyzedSpecs}{The spectra with annotated peaks after workflow step 2.}
+ \item{aggregatedSpecs}{The \code{analyzedSpec} data regrouped and aggregated,
+		after workflow step 3.}
+ \item{rc, rc.ms1}{The recalibration curves generated in workflow step 4.}
+ \item{recalibratedSpecs}{The spectra from \code{specs} recalibrated with the curves
+		from \code{rc, rc,ms1}.}
+	\item{analyzedRcSpecs}{The recalibrated spectra with annotated peaks after
+		workflow step 5.}
+	\item{aggregatedRcSpecs}{The \code{analyzedRcSpec} data regrouped and aggregated,
+		after workflow step 6.}
+ \item{reanalyzedRcSpecs}{The regrouped and aggregated spectra, with added reanalyzed
+		peaks (after step 7, see \code{\link{reanalyzeFailpeaks}}).}
+ \item{refilteredRcSpecs}{Final data to use for MassBank record creation after
+		multiplicity filtering (step 8).}
+}
+
+Methods: \describe{
+	\item{show}{Shows a brief summary of the object. Currently only the included files.}
+	}
+}
+\author{
+Michael Stravs, Eawag <michael.stravs@eawag.ch>
+}
+\seealso{
+\code{\link{msmsWorkflow}}
+}
+
diff --git a/man/validate.Rd b/man/validate.Rd
index 21f99e5155253bb156502cb6803950b8ca1433aa..6300c004a302d74cd0ae6dd750656c634f37f10a 100644
--- a/man/validate.Rd
+++ b/man/validate.Rd
@@ -1,21 +1,24 @@
+% Generated by roxygen2 (4.1.0): do not edit by hand
+% Please edit documentation in R/validateMassBank.R
 \name{validate}
 \alias{validate}
 \title{Validate MassBank records with a set of Unit tests}
 \usage{
-  validate(path)
+validate(path, simple = TRUE)
 }
 \arguments{
-  \item{path}{The filepath to a single record, or a
-  directory to search recursively}
+\item{path}{The filepath to a single record, or a directory to search recursively}
+
+\item{simple}{If TRUE the function creates a simpler form of the RUnit .html report, better readable for humans. If FALSE it returns the unchanged RUnit report.}
 }
 \description{
-  Validates a plain text MassBank record, or recursively
-  all records within a directory. The Unit Tests to be used
-  are installed in RMassBank/inst/unitTests and currently
-  include checks for NAs, peaks versus precursor, precursor
-  mz, precursor type, SMILES vs exact mass, total
-  intensities and title versus type. The validation report
-  is saved as "report.html" in the working directory.
+Validates a plain text MassBank record, or recursively all
+records within a directory. The Unit Tests to be used are
+installed in RMassBank/inst/validationTests and currently include
+checks for NAs, peaks versus precursor, precursor mz,
+precursor type, SMILES vs exact mass, total intensities and
+title versus type. The validation report is saved as
+"report.html" in the working directory.
 }
 \examples{
 \dontrun{
diff --git a/vignettes/RMassBank.Rnw b/vignettes/RMassBank.Rnw
index e686da94ff1a8bd52d0994d9102f6478dd43baee..c82abe440e3cccfa92a3eb6b1e60428bcce9e95c 100755
--- a/vignettes/RMassBank.Rnw
+++ b/vignettes/RMassBank.Rnw
@@ -281,30 +281,7 @@ First, create a workspace for the \Rvar{msmsWorkflow}:
 <<>>=
 w <- newMsmsWorkspace()
 @
-
-
-
-Temporary deposit for the script using msmsRead. Build into actual vignette!
-<<eval=FALSE>>=
-
-#####SCRIPT
-library(RMassBank)
-loadRmbSettings("settings_comrecal_QEx_EX.INI")
-loadList("QEx_10_compoundlist.csv")
-msmsmzR <- newMsmsWorkspace()
-msmsXCMS <- newMsmsWorkspace()
-Args <- list(method="centWave", ppm = 5, snthresh = 1.5,
-    peakwidth = c(20,60), integrate = 1, mzdiff = -0.001, mzCenterFun = "meanApex3")
-msmsmzR <- msmsRead(msmsmzR, filetable = "Filelist_QEx.csv", readMethod="mzR", mode="pH", Args=Args)
-
-datadir <- "/vol/data_extern/emma.schymanski@ufz.de/Qexactive/10_centroided_mzMLs"
-files <- list.files(datadir, pattern=".mzML", full.names=TRUE)
-cpdid <- c(3035,2845,3040,3041,139,3046,297,3050,2856,3052)
-msmsXCMS <- msmsRead(msmsXCMS, files=files, cpdids = cpdid, readMethod="xcms",mode="pH",Args=Args)
-@
-
-
-
+
 The full paths of the files must be loaded into the container in the array
 \Rvar{files}:
 
@@ -367,9 +344,12 @@ the mass deviation of MS precursor ions. The graph to the left is a complete xy
 plot while the graph to the right is a 2D histogram (if the package \Rpackage{gplots} is
 installed on the user's computer). 
 
-<<eval=TRUE,fig=TRUE>>=
-w <- msmsWorkflow(w, mode="pH", steps=c(1:4), archivename = 
-				"pH_narcotics")
+TODO: Workflow execution in Chunk 10 is currently disabled, I execute Chunk 11
+instead for steps that are already done.
+
+<<eval=FALSE,fig=TRUE>>=
+#w <- msmsWorkflow(w, mode="pH", steps=c(1:4), archivename = 
+#				"pH_narcotics")
 @
 
 The recalibration can also be plotted at a later stage:
@@ -384,10 +364,10 @@ advised to run the workflow step by step. This is because if an error occurs, yo
 lose all intermediate results from the workflow, which might complicate
 finding the errors. (E.g., if you process steps 2-4 and an error occurs in step
 3, you will lose the results from step 2.) 
-<<eval=FALSE>>=
+<<eval=TRUE>>=
 	w <- msmsWorkflow(w, mode="pH", steps=1)
 	w <- msmsWorkflow(w, mode="pH", steps=2)
-	w <- msmsWorkflow(w, mode="pH", steps=3)
+	#w <- msmsWorkflow(w, mode="pH", steps=3)
 	# etc.
 @
 
diff --git a/vignettes/RMassBankXCMS.Rnw b/vignettes/RMassBankXCMS.Rnw
index 6025482aba8dc5983174da9c097cb66218903f29..d0f070ba6485ed817cecea463900c6f039e44b11 100644
--- a/vignettes/RMassBankXCMS.Rnw
+++ b/vignettes/RMassBankXCMS.Rnw
@@ -87,6 +87,7 @@ rmbo$spectraList <- list(
   list(mode="CID", ces="20eV", ce="20eV", res=12000)
 )
 
+rmbo$multiplicityFilter <- 1
 rmbo$annotations$instrument <- "Bruker micrOTOFq"
 rmbo$annotations$instrument_type <- "LC-ESI-QTOF"
 rmbo$recalibrator$MS1 <- "recalibrate.identity"
@@ -150,9 +151,14 @@ Args <- list(method="centWave",
 
 If you want to utilize XCMS for Step 1 of the workflow, you have to set the readMethod-parameter to "xcms" and - if you don't want to use standard values for findPeaks - pass on findPeaksArgs to the workflow.
 
-<<eval=TRUE>>=
+<<echo=FALSE,eval=TRUE>>=
+par(mfcol=c(2,2))
+@
+
+
+<<eval=TRUE, fig=TRUE>>=
 msmsList <- msmsRead(msmsList, files= msmsList@files, 
-                     readMethod = "xcms", mode = "mH", Args = Args)
+                     readMethod = "xcms", mode = "mH", Args = Args, plots = TRUE)
 msmsList <- msmsWorkflow(msmsList, steps=2:8,
                          mode="mH", readMethod="xcms")
 @