diff --git a/xtandempipeline/.classpath b/xtandempipeline/.classpath
index d012119feb98ac1c8d364379090b519379be9314..76d3be6e834bd9ddcfd8f4931cb926510977cc74 100644
--- a/xtandempipeline/.classpath
+++ b/xtandempipeline/.classpath
@@ -32,5 +32,7 @@
 	<classpathentry kind="lib" path="lib/swt/swt-gtk-linux-x86_64.jar"/>
 	<classpathentry kind="lib" path="lib/cxf-common-utilities-2.2.4.jar"/>
 	<classpathentry kind="lib" path="lib/mascotdatfile-3.3.jar"/>
+	<classpathentry kind="lib" path="lib/ods2csv.jar"/>
+	<classpathentry kind="lib" path="lib/javacsv.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/xtandempipeline/CMakeLists.txt b/xtandempipeline/CMakeLists.txt
index fe77b981120771fb1cdd09309d425d6723be8803..a8d7bbe4d5e83ba9e1f333d887cb3f4e4af24d55 100644
--- a/xtandempipeline/CMakeLists.txt
+++ b/xtandempipeline/CMakeLists.txt
@@ -175,6 +175,8 @@ INSTALL(FILES ${CMAKE_BINARY_DIR}/share/xtandempipeline/XtandemPipeline.jar DEST
 INSTALL(FILES ${CMAKE_BINARY_DIR}/share/xtandempipeline/libproteomicsvg.jar DESTINATION share/xtandempipeline)
 INSTALL(FILES ${CMAKE_BINARY_DIR}/share/xtandempipeline/libodsstream.jar DESTINATION share/xtandempipeline)
 INSTALL(FILES ${CMAKE_BINARY_DIR}/share/xtandempipeline/${MASCOT_DAT_FILE_JAR} DESTINATION share/xtandempipeline)
+INSTALL(FILES ${CMAKE_BINARY_DIR}/share/xtandempipeline/ods2csv.jar DESTINATION share/xtandempipeline)
+INSTALL(FILES ${CMAKE_BINARY_DIR}/share/xtandempipeline/javacsv.jar DESTINATION share/xtandempipeline)
 
 INSTALL(FILES ${CMAKE_BINARY_DIR}/share/xtandempipeline/cxf-common-utilities-2.2.4.jar DESTINATION share/xtandempipeline)
 INSTALL(FILES ${CMAKE_BINARY_DIR}/share/xtandempipeline/PPClient.jar DESTINATION share/xtandempipeline)
diff --git a/xtandempipeline/build_ubuntu.xml.cmake b/xtandempipeline/build_ubuntu.xml.cmake
index e01bae61a96fd6012f0ca52e26d35ae1bd2675a0..857e4dd7993566b20f29add069ba9356ddd511c8 100644
--- a/xtandempipeline/build_ubuntu.xml.cmake
+++ b/xtandempipeline/build_ubuntu.xml.cmake
@@ -19,6 +19,19 @@
 	<property name="confDir" location="src/conf/release" />
 	<property name="docDir" location="doc" />
 
+	<target name="updateSharedLibraries">
+
+		<copy file="@CMAKE_SOURCE_DIR@/lib/javacsv.jar" tofile="${share}/xtandempipeline/javacsv.jar" overwrite="true" />
+		<copy file="@CMAKE_SOURCE_DIR@/lib/ods2csv.jar" tofile="${share}/xtandempipeline/ods2csv.jar" overwrite="true" />
+		<copy file="@CMAKE_SOURCE_DIR@/lib/libproteomicsvg.jar" tofile="${share}/xtandempipeline/libproteomicsvg.jar" overwrite="true" />
+		<copy file="@CMAKE_SOURCE_DIR@/lib/libodsstream.jar" tofile="${share}/xtandempipeline/libodsstream.jar" overwrite="true" />
+		<copy file="@CMAKE_SOURCE_DIR@/lib/PPClient.jar" tofile="${share}/xtandempipeline/PPClient.jar" overwrite="true" />
+		<copy file="@CMAKE_SOURCE_DIR@/lib/mascotdatfile-3.3.jar" tofile="${share}/xtandempipeline/mascotdatfile-3.3.jar" overwrite="true" />
+		<copy file="@CMAKE_SOURCE_DIR@/lib/cxf-common-utilities-2.2.4.jar" tofile="${share}/xtandempipeline/cxf-common-utilities-2.2.4.jar" overwrite="true" />
+		
+	</target>
+
+
 	<target name="reset">
 		<!-- reset the build and dist directory -->
 		<delete dir="${build}" />
@@ -26,13 +39,6 @@
 		<mkdir dir="${build}" />
 		<mkdir dir="${dist}" />
 		<mkdir dir="${confDest}" />
-
-
-		<copy file="@CMAKE_SOURCE_DIR@/lib/libproteomicsvg.jar" tofile="${share}/xtandempipeline/libproteomicsvg.jar" overwrite="true" />
-		<copy file="@CMAKE_SOURCE_DIR@/lib/libodsstream.jar" tofile="${share}/xtandempipeline/libodsstream.jar" overwrite="true" />
-		<copy file="@CMAKE_SOURCE_DIR@/lib/PPClient.jar" tofile="${share}/xtandempipeline/PPClient.jar" overwrite="true" />
-		<copy file="@CMAKE_SOURCE_DIR@/lib/mascotdatfile-3.3.jar" tofile="${share}/xtandempipeline/mascotdatfile-3.3.jar" overwrite="true" />
-		<copy file="@CMAKE_SOURCE_DIR@/lib/cxf-common-utilities-2.2.4.jar" tofile="${share}/xtandempipeline/cxf-common-utilities-2.2.4.jar" overwrite="true" />
 		
 	</target>
 
@@ -45,6 +51,8 @@
 	<path id="classpath">
 		<!--xml-apis-ext.jar xml-apis.jar xercesImpl.jar xalan2.jar swt.jar batik.jar  liblog4j1.2-java -->
 		<fileset dir="${sys.dir}" includes="commons-httpclient.jar commons-codec.jar commons-logging.jar log4j-1.2.jar xml-apis-ext.jar xml-apis.jar xercesImpl.jar xalan2.jar swt.jar batik.jar" />
+		<fileset dir="${share.dest}/xtandempipeline" includes="javacsv.jar" />
+		<fileset dir="${share.dest}/xtandempipeline" includes="ods2csv.jar" />
 		<fileset dir="${share.dest}/xtandempipeline" includes="libproteomicsvg.jar" />
 		<fileset dir="${share.dest}/xtandempipeline" includes="libodsstream.jar" />
 		<fileset dir="${share.dest}/xtandempipeline" includes="PPClient.jar" />
@@ -55,6 +63,8 @@
 
 	<target name="compile" depends="init" description="compile the source and put in build directory">
 		<!-- Compile the java code from ${src} into ${build} -->
+		<copy file="${share}/xtandempipeline/javacsv.jar" todir="${share.dest}/xtandempipeline" overwrite="true" />
+		<copy file="${share}/xtandempipeline/ods2csv.jar" todir="${share.dest}/xtandempipeline" overwrite="true" />
 		<copy file="${share}/xtandempipeline/libproteomicsvg.jar" todir="${share.dest}/xtandempipeline" overwrite="true" />
 		<copy file="${share}/xtandempipeline/libodsstream.jar" todir="${share.dest}/xtandempipeline" overwrite="true" />
 		<copy file="${share}/xtandempipeline/PPClient.jar" todir="${share.dest}/xtandempipeline" overwrite="true" />
@@ -89,7 +99,7 @@
 			<!--<fileset file=".classpath" />-->
 			<manifest>
 				<attribute name="Main-Class" value="fr.inra.pappso.xtandempipeline.XtandemPipelineMain" />
-				<attribute name="Class-Path" value="${sys.dir}/commons-httpclient.jar ${sys.dir}/commons-codec.jar ${sys.dir}/commons-logging.jar ${sys.dir}/log4j-1.2.jar ${sys.dir}/xml-apis-ext.jar ${sys.dir}/xml-apis.jar ${sys.dir}/xercesImpl.jar ${sys.dir}/xalan2.jar ${sys.dir}/swt.jar ${sys.dir}/batik.jar ${usr.dir}/share/xtandempipeline/libproteomicsvg.jar ${usr.dir}/share/xtandempipeline/libodsstream.jar ${usr.dir}/share/xtandempipeline/PPClient.jar ${usr.dir}/share/xtandempipeline/@MASCOT_DAT_FILE_JAR@ ${usr.dir}/share/xtandempipeline/cxf-common-utilities-2.2.4.jar" />
+				<attribute name="Class-Path" value="${usr.dir}/share/xtandempipeline/ods2csv.jar ${usr.dir}/share/xtandempipeline/javacsv.jar ${sys.dir}/commons-httpclient.jar ${sys.dir}/commons-codec.jar ${sys.dir}/commons-logging.jar ${sys.dir}/log4j-1.2.jar ${sys.dir}/xml-apis-ext.jar ${sys.dir}/xml-apis.jar ${sys.dir}/xercesImpl.jar ${sys.dir}/xalan2.jar ${sys.dir}/swt.jar ${sys.dir}/batik.jar ${usr.dir}/share/xtandempipeline/libproteomicsvg.jar ${usr.dir}/share/xtandempipeline/libodsstream.jar ${usr.dir}/share/xtandempipeline/PPClient.jar ${usr.dir}/share/xtandempipeline/@MASCOT_DAT_FILE_JAR@ ${usr.dir}/share/xtandempipeline/cxf-common-utilities-2.2.4.jar" />
 			</manifest>
 		</jar>
 
@@ -104,6 +114,8 @@
 	</target>
 
 	<target name="copyInShare" description="copies jar needed by the ubuntu package into the share directory">
+		<copy file="@xtandempipeline_SOURCE_DIR@/lib/javacsv.jar" todir="${share}/xtandempipeline" overwrite="true" />
+		<copy file="@xtandempipeline_SOURCE_DIR@/lib/ods2csv.jar" todir="${share}/xtandempipeline" overwrite="true" />
 		<copy file="@xtandempipeline_SOURCE_DIR@/lib/libproteomicsvg.jar" todir="${share}/xtandempipeline" overwrite="true" />
 		<copy file="@xtandempipeline_SOURCE_DIR@/lib/libodsstream.jar" todir="${share}/xtandempipeline" overwrite="true" />
 		<copy file="@xtandempipeline_SOURCE_DIR@/lib/PPClient.jar" todir="${share}/xtandempipeline" overwrite="true" />
diff --git a/xtandempipeline/lib/javacsv.jar b/xtandempipeline/lib/javacsv.jar
new file mode 100644
index 0000000000000000000000000000000000000000..ceb59eb464c3b059ae28007e79994b4fbbb960b5
Binary files /dev/null and b/xtandempipeline/lib/javacsv.jar differ
diff --git a/xtandempipeline/lib/ods2csv.jar b/xtandempipeline/lib/ods2csv.jar
new file mode 100644
index 0000000000000000000000000000000000000000..9fb0da05b12e721e72d0cf5ce9485fd14a06597a
Binary files /dev/null and b/xtandempipeline/lib/ods2csv.jar differ
diff --git a/xtandempipeline/share/xtandempipeline/xtandempipeline.jnlp.cmake b/xtandempipeline/share/xtandempipeline/xtandempipeline.jnlp.cmake
index a8171ccacebc3cfab7126135b95511d539de718b..fac932e25391a1f70e3e8221acfa7da224cbf4a5 100644
--- a/xtandempipeline/share/xtandempipeline/xtandempipeline.jnlp.cmake
+++ b/xtandempipeline/share/xtandempipeline/xtandempipeline.jnlp.cmake
@@ -61,6 +61,8 @@
     
     <jar href="lib/libproteomicsvg.jar" main="false" download="eager" />
     <jar href="lib/libodsstream.jar" main="false" download="eager" />
+    <jar href="lib/javacsv.jar" main="false" download="eager" />
+    <jar href="lib/ods2csv.jar" main="false" download="eager" />
   </resources>
    
   <resources os="Windows" arch="x86">
diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/filter_print/print_peptide_list_to_phosphopeptide.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/filter_print/print_peptide_list_to_phosphopeptide.java
index c23fe188ecaa50b0d2fc55967912572415faeb22..da2433280bd1b1d6697ee3bcebbfeba597a18b90 100644
--- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/filter_print/print_peptide_list_to_phosphopeptide.java
+++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/filter_print/print_peptide_list_to_phosphopeptide.java
@@ -5,7 +5,6 @@ import java.util.Collection;
 import java.util.TreeSet;
 
 import fr.inra.pappso.xtandempipeline.class_msms.Match;
-import fr.inra.pappso.xtandempipeline.class_msms.Modifs;
 import fr.inra.pappso.xtandempipeline.class_msms.MapDb.Peptide;
 import fr.inra.pappso.xtandempipeline.grouping.Group;
 import fr.inra.pappso.xtandempipeline.grouping.HashSampleScan;
diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/filter_print/print_protein_to_phosphopeptide.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/filter_print/print_protein_to_phosphopeptide.java
index eb8ed4be1ae541bf953ec9a5c78e53e6d5875946..bb626d7ef8688dccdd1c39a4654be2d27bcffe2f 100644
--- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/filter_print/print_protein_to_phosphopeptide.java
+++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/filter_print/print_protein_to_phosphopeptide.java
@@ -5,7 +5,6 @@ import fr.inra.pappso.xtandempipeline.grouping.Group;
 import fr.inra.pappso.xtandempipeline.grouping.HashSampleScanSetPhospho;
 import fr.inra.pappso.xtandempipeline.grouping.HashSampleScanSetProt;
 import fr.inra.pappso.xtandempipeline.grouping.SubGroup;
-import fr.inra.pappso.xtandempipeline.grouping.interfaces.GrpProtMatch;
 import fr.inra.pappso.xtandempipeline.sax_parse.msms_output;
 
 public class print_protein_to_phosphopeptide extends print_base {
diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/CsvRedundantPeptideOutput.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/CsvRedundantPeptideOutput.java
new file mode 100644
index 0000000000000000000000000000000000000000..4114ea64dad729d14b3bc58dca28d84d4ed0caac
--- /dev/null
+++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/CsvRedundantPeptideOutput.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Olivier Langella <Olivier.Langella@moulon.inra.fr>.
+ * 
+ * This file is part of XTandemPipeline.
+ * 
+ *     XTandemPipeline is free software: you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * 
+ *     XTandemPipeline is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ * 
+ *     You should have received a copy of the GNU General Public License
+ *     along with XTandemPipeline.  If not, see <http://www.gnu.org/licenses/>.
+ * 
+ * Contributors:
+ *     Benoit Valot <Benoit.Valot@moulon.inra.fr>
+ *     Olivier Langella <Olivier.Langella@moulon.inra.fr>
+ ******************************************************************************/
+
+package fr.inra.pappso.xtandempipeline.output;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.stream.XMLStreamException;
+
+import org.apache.log4j.Logger;
+
+import fr.inra.pappso.csv2ods.Ods2Csv;
+import fr.inra.pappso.libodsstream.OdsDocWriter;
+import fr.inra.pappso.xtandempipeline.MsException.MSMSException;
+
+public class CsvRedundantPeptideOutput extends OdsRedundantPeptideOutput {
+	private static final Logger logger = Logger
+			.getLogger(CsvRedundantPeptideOutput.class);
+	private Ods2Csv ods2csv;
+
+	public CsvRedundantPeptideOutput(OutputStream outputStream)
+			throws MSMSException {
+		try {
+
+			PipedOutputStream pos = new PipedOutputStream();
+			PipedInputStream pis = new PipedInputStream(pos);
+
+			odsTable = new OdsDocWriter(pos);
+
+			ods2csv = new Ods2Csv();
+			ods2csv.setSourceInputStream(pis);
+			ods2csv.setSinkOutputStream(outputStream);
+			//ods2csv.setSeparator('\t');
+			 (new Thread(ods2csv)).start();
+			//ods2csv.run();
+		} catch (IOException e) {
+			String message = "IOException " + e.getMessage();
+			logger.error(message);
+			throw new MSMSException(message);
+		} catch (XMLStreamException e) {
+			String message = "XMLStreamException " + e.getMessage();
+			logger.error(message);
+			throw new MSMSException(message);
+		} catch (DatatypeConfigurationException e) {
+			String message = "DatatypeConfigurationException " + e.getMessage();
+			logger.error(message);
+			throw new MSMSException(message);
+		}
+	}
+
+}
diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/IndentingXMLStreamWriter.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/IndentingXMLStreamWriter.java
new file mode 100644
index 0000000000000000000000000000000000000000..2daea8d784b635911852a3e6f8bdcbbc0f7588a4
--- /dev/null
+++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/IndentingXMLStreamWriter.java
@@ -0,0 +1,177 @@
+package fr.inra.pappso.xtandempipeline.output;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.cxf.staxutils.DelegatingXMLStreamWriter;
+
+import java.util.Stack;
+
+/**
+ * @author Kohsuke Kawaguchi
+ */
+public class IndentingXMLStreamWriter extends DelegatingXMLStreamWriter {
+	private final static Object SEEN_NOTHING = new Object();
+	private final static Object SEEN_ELEMENT = new Object();
+	private final static Object SEEN_DATA = new Object();
+
+	private Object state = SEEN_NOTHING;
+	private Stack<Object> stateStack = new Stack<Object>();
+
+	private String indentStep = "  ";
+	private int depth = 0;
+
+	public IndentingXMLStreamWriter(XMLStreamWriter writer) {
+		super(writer);
+	}
+
+	/**
+	 * Return the current indent step.
+	 * 
+	 * <p>
+	 * Return the current indent step: each start tag will be indented by this
+	 * number of spaces times the number of ancestors that the element has.
+	 * </p>
+	 * 
+	 * @return The number of spaces in each indentation step, or 0 or less for
+	 *         no indentation.
+	 * @see #setIndentStep(int)
+	 * 
+	 * @deprecated Only return the length of the indent string.
+	 */
+	public int getIndentStep() {
+		return indentStep.length();
+	}
+
+	/**
+	 * Set the current indent step.
+	 * 
+	 * @param indentStep
+	 *            The new indent step (0 or less for no indentation).
+	 * @see #getIndentStep()
+	 * 
+	 * @deprecated Should use the version that takes string.
+	 */
+	public void setIndentStep(int indentStep) {
+		StringBuilder s = new StringBuilder();
+		for (; indentStep > 0; indentStep--)
+			s.append(' ');
+		setIndentStep(s.toString());
+	}
+
+	public void setIndentStep(String s) {
+		this.indentStep = s;
+	}
+
+	private void onStartElement() throws XMLStreamException {
+		stateStack.push(SEEN_ELEMENT);
+		state = SEEN_NOTHING;
+		if (depth > 0) {
+			super.writeCharacters("\n");
+		}
+		doIndent();
+		depth++;
+	}
+
+	private void onEndElement() throws XMLStreamException {
+		depth--;
+		if (state == SEEN_ELEMENT) {
+			super.writeCharacters("\n");
+			doIndent();
+		}
+		state = stateStack.pop();
+	}
+
+	private void onEmptyElement() throws XMLStreamException {
+		state = SEEN_ELEMENT;
+		if (depth > 0) {
+			super.writeCharacters("\n");
+		}
+		doIndent();
+	}
+
+	/**
+	 * Print indentation for the current level.
+	 * 
+	 * @exception org.xml.sax.SAXException
+	 *                If there is an error writing the indentation characters,
+	 *                or if a filter further down the chain raises an exception.
+	 */
+	private void doIndent() throws XMLStreamException {
+		if (depth > 0) {
+			for (int i = 0; i < depth; i++)
+				super.writeCharacters(indentStep);
+		}
+	}
+
+	public void writeStartDocument() throws XMLStreamException {
+		super.writeStartDocument();
+		super.writeCharacters("\n");
+	}
+
+	public void writeStartDocument(String version) throws XMLStreamException {
+		super.writeStartDocument(version);
+		super.writeCharacters("\n");
+	}
+
+	public void writeStartDocument(String encoding, String version)
+			throws XMLStreamException {
+		super.writeStartDocument(encoding, version);
+		super.writeCharacters("\n");
+	}
+
+	public void writeStartElement(String localName) throws XMLStreamException {
+		onStartElement();
+		super.writeStartElement(localName);
+	}
+
+	public void writeStartElement(String namespaceURI, String localName)
+			throws XMLStreamException {
+		onStartElement();
+		super.writeStartElement(namespaceURI, localName);
+	}
+
+	public void writeStartElement(String prefix, String localName,
+			String namespaceURI) throws XMLStreamException {
+		onStartElement();
+		super.writeStartElement(prefix, localName, namespaceURI);
+	}
+
+	public void writeEmptyElement(String namespaceURI, String localName)
+			throws XMLStreamException {
+		onEmptyElement();
+		super.writeEmptyElement(namespaceURI, localName);
+	}
+
+	public void writeEmptyElement(String prefix, String localName,
+			String namespaceURI) throws XMLStreamException {
+		onEmptyElement();
+		super.writeEmptyElement(prefix, localName, namespaceURI);
+	}
+
+	public void writeEmptyElement(String localName) throws XMLStreamException {
+		onEmptyElement();
+		super.writeEmptyElement(localName);
+	}
+
+	public void writeEndElement() throws XMLStreamException {
+		onEndElement();
+		super.writeEndElement();
+	}
+
+	public void writeCharacters(String text) throws XMLStreamException {
+		state = SEEN_DATA;
+		super.writeCharacters(text);
+	}
+
+	public void writeCharacters(char[] text, int start, int len)
+			throws XMLStreamException {
+		state = SEEN_DATA;
+		super.writeCharacters(text, start, len);
+	}
+
+	public void writeCData(String data) throws XMLStreamException {
+		state = SEEN_DATA;
+		super.writeCData(data);
+	}
+}
diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/MassChroQmlOutput.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/MassChroQmlOutput.java
similarity index 98%
rename from xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/MassChroQmlOutput.java
rename to xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/MassChroQmlOutput.java
index ccaae2d2f1b8993a008aaa072924ca27b48dd852..7c3b038e17a0d7fa8d7d87e40e07620c36b213fc 100644
--- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/MassChroQmlOutput.java
+++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/MassChroQmlOutput.java
@@ -21,7 +21,7 @@
  *     Olivier Langella <Olivier.Langella@moulon.inra.fr>
  ******************************************************************************/
 
-package fr.inra.pappso.xtandempipeline.sax_parse;
+package fr.inra.pappso.xtandempipeline.output;
 
 import java.io.IOException;
 import java.io.OutputStream;
diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/MassChroQmlWriter.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/MassChroQmlWriter.java
similarity index 97%
rename from xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/MassChroQmlWriter.java
rename to xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/MassChroQmlWriter.java
index aaa2a3f2152487843ab475b961d80f90443e9b44..f20cfb84db0baf205ea22ae9962fde9b33802756 100644
--- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/MassChroQmlWriter.java
+++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/MassChroQmlWriter.java
@@ -21,7 +21,7 @@
  *     Olivier Langella <Olivier.Langella@moulon.inra.fr>
  ******************************************************************************/
 
-package fr.inra.pappso.xtandempipeline.sax_parse;
+package fr.inra.pappso.xtandempipeline.output;
 
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -294,7 +294,7 @@ public class MassChroQmlWriter {
 		logger.debug("write begin");
 		try {
 			writer.writeStartElement("rawdata");
-			for (MsRun sample : ident.get_samples().getMsRunList()) {
+			for (MsRun sample : ident.getMsRunSet().getMsRunList()) {
 				String id_samp = "samp" + this.sample2xmlId.size();
 				// ajout dans les hashtable
 				sample2xmlId.put(sample, id_samp);
@@ -328,7 +328,7 @@ public class MassChroQmlWriter {
 			writer.writeEmptyElement("group");
 			writer.writeAttribute("id", this.groupe_id);
 			String raw_list = "";
-			for (MsRun sample : ident.get_samples().getMsRunList()) {
+			for (MsRun sample : ident.getMsRunSet().getMsRunList()) {
 				raw_list = raw_list + " " + sample2xmlId.get(sample);
 			}
 			writer.writeAttribute("data_ids", raw_list.trim());
@@ -401,10 +401,10 @@ public class MassChroQmlWriter {
 					Match top = (Match) sgList.get(0)
 							.getHashSampleScanSetProtList().get(0)
 							.getGrpProtMatch();
-					Peptide pep = (Peptide) top.getBestPeptideToHashSampleScan(hash);
+					Peptide pep = (Peptide) top
+							.getBestPeptideToHashSampleScan(hash);
 
-					String seqMod = pep
-							.get_LI_sequenceModifsWithoutMs3();
+					String seqMod = pep.get_LI_sequenceModifsWithoutMs3();
 					if (seqMod2protIds.containsKey(seqMod)) {
 					} else {
 						// Add new peptide id
@@ -419,8 +419,8 @@ public class MassChroQmlWriter {
 						HashSet<String> temp = new HashSet<String>();
 						seqMod2protIds.put(seqMod, temp);
 
-						seqMod2PeptideList.put(seqMod,
-								new ArrayList<Peptide>());
+						seqMod2PeptideList
+								.put(seqMod, new ArrayList<Peptide>());
 					}
 
 					seqMod2PeptideList.get(seqMod).add(pep);
diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/OdsRedundantPeptideOutput.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/OdsRedundantPeptideOutput.java
new file mode 100644
index 0000000000000000000000000000000000000000..e9d41ba6500ee5b8971d1fb17b11c06394ada388
--- /dev/null
+++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/OdsRedundantPeptideOutput.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Olivier Langella <Olivier.Langella@moulon.inra.fr>.
+ * 
+ * This file is part of XTandemPipeline.
+ * 
+ *     XTandemPipeline is free software: you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * 
+ *     XTandemPipeline is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ * 
+ *     You should have received a copy of the GNU General Public License
+ *     along with XTandemPipeline.  If not, see <http://www.gnu.org/licenses/>.
+ * 
+ * Contributors:
+ *     Benoit Valot <Benoit.Valot@moulon.inra.fr>
+ *     Olivier Langella <Olivier.Langella@moulon.inra.fr>
+ ******************************************************************************/
+
+package fr.inra.pappso.xtandempipeline.output;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.stream.XMLStreamException;
+
+import org.apache.log4j.Logger;
+
+import fr.inra.pappso.libodsstream.OdsDocWriter;
+import fr.inra.pappso.xtandempipeline.MsException.MSMSException;
+import fr.inra.pappso.xtandempipeline.class_msms.Identification;
+import fr.inra.pappso.xtandempipeline.class_msms.Match;
+import fr.inra.pappso.xtandempipeline.class_msms.Protein;
+import fr.inra.pappso.xtandempipeline.class_msms.MapDb.Peptide;
+import fr.inra.pappso.xtandempipeline.grouping.Group;
+import fr.inra.pappso.xtandempipeline.grouping.HashSampleScanSetProt;
+import fr.inra.pappso.xtandempipeline.grouping.SubGroup;
+
+public class OdsRedundantPeptideOutput {
+	private static final Logger logger = Logger
+			.getLogger(OdsRedundantPeptideOutput.class);
+
+	protected OdsDocWriter odsTable;
+
+	protected OdsRedundantPeptideOutput() {
+
+	}
+
+	public OdsRedundantPeptideOutput(OutputStream outputStream)
+			throws MSMSException {
+		try {
+			odsTable = new OdsDocWriter(outputStream);
+		} catch (IOException e) {
+			String message = "IOException " + e.getMessage();
+			logger.error(message);
+			throw new MSMSException(message);
+		} catch (XMLStreamException e) {
+			String message = "XMLStreamException " + e.getMessage();
+			logger.error(message);
+			throw new MSMSException(message);
+		} catch (DatatypeConfigurationException e) {
+			String message = "DatatypeConfigurationException " + e.getMessage();
+			logger.error(message);
+			throw new MSMSException(message);
+		}
+	}
+
+	public void close() throws MSMSException {
+		try {
+			odsTable.close();
+		} catch (Exception e) {
+			String message = "Exception closing OdsRedundantPeptideOutput "
+					+ e.getMessage();
+			logger.error(message);
+			throw new MSMSException(message);
+		}
+	}
+
+	public void write(Identification ident) throws MSMSException {
+		try {
+			odsTable.writeSheet("peptides");
+
+			this.writeHeaders();
+			for (Group group : ident.getGrouping().getGroupList()) {
+				for (SubGroup sg : group.getSubGroupSet().getSubGroupList()) {
+
+					for (HashSampleScanSetProt hashProt : sg
+							.getHashSampleScanSetProtList()) {
+						Protein prot = (Protein) hashProt.getGrpProtMatch()
+								.getGrpProtein();
+						// peptidesHitRef
+						for (Peptide peptide : ((Match) hashProt
+								.getGrpProtMatch())
+								.get_peptide_order_inclus_redon()) {
+
+							this.writeOnePeptide(group, sg, prot, peptide);
+						}
+					}
+				}
+			}
+			odsTable.writeLine();
+			odsTable.writeLine();
+
+		} catch (XMLStreamException e) {
+			String message = "XMLStreamException in write(Identification ident) "
+					+ e.getMessage();
+			logger.error(message);
+			throw new MSMSException(message);
+		}
+	}
+
+	private void writeHeaders() throws MSMSException {
+		try {
+			odsTable.writeLine();
+			odsTable.writeCell("Group");
+			odsTable.writeCell("Subgroup");
+			odsTable.writeCell("Protein accession");
+			odsTable.writeCell("Protein description");
+			odsTable.writeCell("MS Sample");
+			odsTable.writeCell("Scan");
+			odsTable.writeCell("Rt (s)");
+			odsTable.writeCell("Sequence");
+			odsTable.writeCell("Modifs");
+			odsTable.writeCell("Start");
+			odsTable.writeCell("Stop");
+
+			odsTable.writeCell("E-value");
+			odsTable.writeCell("Charge");
+			odsTable.writeCell("MH+ Obs");
+			odsTable.writeCell("MH+ theo");
+			odsTable.writeCell("DeltaMH+");
+			odsTable.writeCell("Delta-ppm");
+		} catch (XMLStreamException e) {
+			String message = "XMLStreamException in writeHeaders() "
+					+ e.getMessage();
+			logger.error(message);
+			throw new MSMSException(message);
+		}
+
+	}
+
+	private void writeOnePeptide(Group group, SubGroup sg, Protein prot,
+			Peptide peptide) throws MSMSException {
+		try {
+			odsTable.writeLine();
+			odsTable.writeCell(group.getNumber());
+			odsTable.writeCell(sg.getNumber());
+			odsTable.writeCell(prot.getAccession());
+			odsTable.writeCell(prot.get_description());
+			odsTable.writeCell(peptide.get_sample());
+			odsTable.writeCell(peptide.getSampleScan().getScan());
+			odsTable.writeCell(peptide.get_RT_in_sec());
+			odsTable.writeCell(peptide.getSequence());
+			odsTable.writeCell(peptide.get_Modifs_formater());
+			odsTable.writeCell(peptide.get_start());
+			odsTable.writeCell(peptide.get_stop());
+
+			odsTable.writeCell(peptide.get_evalue());
+			// S.append("\t" + pep.get_evalue());
+			odsTable.writeCell(peptide.get_charge());
+			// S.append("\t" + pep.get_charge());
+			odsTable.writeCell(peptide.get_mhplus_obser());
+			// S.append("\t" + pep.get_mhplus_obser());
+			odsTable.writeCell(peptide.get_mhplus_theo());
+			// S.append("\t" + pep.get_mhplus_theo());
+			odsTable.writeCell(peptide.get_deltamass());
+			// S.append("\t" + pep.get_deltamass());
+			odsTable.writeCell(((peptide.get_deltamass() / peptide
+					.get_mhplus_theo()) * 1000000));
+
+		} catch (XMLStreamException e) {
+			String message = "XMLStreamException in writeOnePeptide(Group group, SubGroup sg, Protein prot,	Peptide peptide) "
+					+ e.getMessage();
+			logger.error(message);
+			throw new MSMSException(message);
+		} catch (Exception e) {
+			String message = "Exception in writeOnePeptide(Protein prot, Peptide peptide) "
+					+ e.getMessage();
+			logger.error(message);
+			throw new MSMSException(message);
+		}
+	}
+}
diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/ProticDbMlOutput.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/ProticDbMlOutput.java
similarity index 98%
rename from xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/ProticDbMlOutput.java
rename to xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/ProticDbMlOutput.java
index ae9c3d9983372197cecdb5d0b29f22f2def4834e..e63e3e22daf13ee81bc62f1b5e094f4ca8c719af 100644
--- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/ProticDbMlOutput.java
+++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/ProticDbMlOutput.java
@@ -21,7 +21,7 @@
  *     Olivier Langella <Olivier.Langella@moulon.inra.fr>
  ******************************************************************************/
 
-package fr.inra.pappso.xtandempipeline.sax_parse;
+package fr.inra.pappso.xtandempipeline.output;
 
 import java.io.IOException;
 import java.io.OutputStream;
diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/ProticDbMlWriter.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/ProticDbMlWriter.java
similarity index 94%
rename from xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/ProticDbMlWriter.java
rename to xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/ProticDbMlWriter.java
index 72db150ca05517e94c1216618c687dd8423e0686..51a1109b52f800717af17765cb065223f1e35264 100644
--- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/ProticDbMlWriter.java
+++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/ProticDbMlWriter.java
@@ -21,7 +21,7 @@
  *     Olivier Langella <Olivier.Langella@moulon.inra.fr>
  ******************************************************************************/
 
-package fr.inra.pappso.xtandempipeline.sax_parse;
+package fr.inra.pappso.xtandempipeline.output;
 
 import java.util.ArrayList;
 import java.util.Hashtable;
@@ -285,7 +285,8 @@ public class ProticDbMlWriter {
 								writer.writeAttribute("display_id", prot
 										.get_description().substring(0, 59));
 							} else {
-								writer.writeAttribute("display_id",
+								writer.writeAttribute(
+										"display_id",
 										prot.get_description()
 												.substring(
 														0,
@@ -296,10 +297,10 @@ public class ProticDbMlWriter {
 							// dbname="AGI_LocusCode"></dbxref>
 							if (prot.get_dbxref_type().equals("no") == false) {
 								writer.writeStartElement("dbxref");
-								writer.writeAttribute("key", prot
-										.get_dbxref_accession());
-								writer.writeAttribute("dbname", prot
-										.get_dbxref_type());
+								writer.writeAttribute("key",
+										prot.get_dbxref_accession());
+								writer.writeAttribute("dbname",
+										prot.get_dbxref_type());
 								writer.writeEndElement();// dbxref
 							}
 							writer.writeStartElement("description");
@@ -403,9 +404,8 @@ public class ProticDbMlWriter {
 			writer.writeAttribute("value", ""
 					+ XtandemPipelineSession.getInstance().getConfig()
 							.get_peptide_number());
-			writer
-					.writeAttribute("name",
-							"X!TandemPipeline filter on minimal number of peptide per protein");
+			writer.writeAttribute("name",
+					"X!TandemPipeline filter on minimal number of peptide per protein");
 			writer.writeAttribute("cvLabel", "PROTICdbO");
 			writer.writeAttribute("accession", "PROTICdbO:0000325");
 			writer.writeEndElement();// cvParam
@@ -435,19 +435,15 @@ public class ProticDbMlWriter {
 		String pep_hit_id = "pep" + pep_to_id.size();
 		// param par default
 		writer.writeStartElement("peptideHit");
-		writer
-				.writeAttribute("calc_mr", ""
-						+ (pep.get_mhplus_theo() - 1.00794));
+		writer.writeAttribute("calc_mr", "" + (pep.get_mhplus_theo() - 1.00794));
 		double exp_mz = (pep.get_mhplus_obser() + (1.00794 * (pep.get_charge() - 1)))
 				/ pep.get_charge();
 		writer.writeAttribute("exp_mz", "" + exp_mz);
 		writer.writeAttribute("delta", "" + pep.get_deltamass());
-		writer
-				.writeAttribute("exp_mr", ""
-						+ (pep.get_mhplus_obser() - 1.00794));
+		writer.writeAttribute("exp_mr", "" + (pep.get_mhplus_obser() - 1.00794));
 		writer.writeAttribute("acq_number", "" + pep.get_scan());
-		writer.writeAttribute("ms_run_id", ""
-				+ msrun_to_id.get(pep.get_sample()));
+		writer.writeAttribute("ms_run_id",
+				"" + msrun_to_id.get(pep.get_sample()));
 		writer.writeAttribute("id", pep_hit_id);
 		writer.writeAttribute("exp_z", "" + pep.get_charge());
 
@@ -612,9 +608,11 @@ public class ProticDbMlWriter {
 						for (MsRun sample : match.get_sample_matchs()) {
 							if (!view.containsKey(sample.getSampleName())) {
 								writer.writeStartElement("matchSample");
-								writer.writeAttribute("sample_id", ""
-										+ sample_to_id.get(sample
-												.getSampleName()));
+								writer.writeAttribute(
+										"sample_id",
+										""
+												+ sample_to_id.get(sample
+														.getSampleName()));
 								String name = sample.getSampleName();
 								name = name.replaceAll(".xml", "");
 								writer.writeAttribute("name", "" + name);
@@ -631,8 +629,8 @@ public class ProticDbMlWriter {
 						writer.writeStartElement("proteinHit");
 						Protein prot = (Protein) hashProt.getGrpProtMatch()
 								.getGrpProtein();
-						writer.writeAttribute("sequence_id", ""
-								+ prot_to_id.get(prot.get_description()));
+						writer.writeAttribute("sequence_id",
+								"" + prot_to_id.get(prot.get_description()));
 						// proteinHit.setAttribute("score", "");
 						writer.writeAttribute("rank", "" + k);
 
@@ -660,9 +658,12 @@ public class ProticDbMlWriter {
 						if (samples.size() == 1) {
 							writer.writeStartElement("cvParam");
 
-							writer.writeAttribute("value", ""
-									+ ((Match) hashProt.getGrpProtMatch())
-											.get_coverage());
+							writer.writeAttribute(
+									"value",
+									""
+											+ ((Match) hashProt
+													.getGrpProtMatch())
+													.get_coverage());
 							writer.writeAttribute("name",
 									"Coverage determination by Benuch");
 							writer.writeAttribute("cvLabel", "PROTICdbO");
@@ -681,20 +682,19 @@ public class ProticDbMlWriter {
 						for (Peptide pep : ((Match) hashProt.getGrpProtMatch())
 								.get_peptide_order_inclus_redon()) {
 							writer.writeStartElement("peptideHitRef");
-							writer
-									.writeAttribute(
-											"peptide_hit_id",
-											""
-													+ pep_to_id
-															.get(pep
-																	.get_sample_scan_sequencepeptide_cle()));
+							writer.writeAttribute(
+									"peptide_hit_id",
+									""
+											+ pep_to_id.get(pep
+													.get_sample_scan_sequencepeptide_cle()));
 
 							writer.writeStartElement("fromSeq");
-							writer.writeAttribute("seq_id", ""
-									+ prot_to_id.get(prot2.get_description()));
-							writer
-									.writeAttribute("start", ""
-											+ pep.get_start());
+							writer.writeAttribute(
+									"seq_id",
+									""
+											+ prot_to_id.get(prot2
+													.get_description()));
+							writer.writeAttribute("start", "" + pep.get_start());
 							writer.writeAttribute("stop", "" + pep.get_stop());
 							String res1 = pep.get_pre();
 							res1 = res1.replaceAll("]", "-");
diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/IndentingXMLStreamWriter.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/IndentingXMLStreamWriter.java
deleted file mode 100644
index e0e30ec9ea194119b296de44da74b2bf5bb9316f..0000000000000000000000000000000000000000
--- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/IndentingXMLStreamWriter.java
+++ /dev/null
@@ -1,173 +0,0 @@
-package fr.inra.pappso.xtandempipeline.sax_parse;
-
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-
-import org.apache.cxf.staxutils.DelegatingXMLStreamWriter;
-
-import java.util.Stack;
-
-/**
- * @author Kohsuke Kawaguchi
- */
-public class IndentingXMLStreamWriter extends DelegatingXMLStreamWriter {
-    private final static Object SEEN_NOTHING = new Object();
-    private final static Object SEEN_ELEMENT = new Object();
-    private final static Object SEEN_DATA = new Object();
-
-    private Object state = SEEN_NOTHING;
-    private Stack<Object> stateStack = new Stack<Object>();
-
-    private String indentStep = "  ";
-    private int depth = 0;
-
-    public IndentingXMLStreamWriter(XMLStreamWriter writer) {
-        super(writer);
-    }
-
-    /**
-     * Return the current indent step.
-     *
-     * <p>Return the current indent step: each start tag will be
-     * indented by this number of spaces times the number of
-     * ancestors that the element has.</p>
-     *
-     * @return The number of spaces in each indentation step,
-     *         or 0 or less for no indentation.
-     * @see #setIndentStep(int)
-     *
-     * @deprecated
-     *      Only return the length of the indent string.
-     */
-    public int getIndentStep() {
-        return indentStep.length();
-    }
-
-
-    /**
-     * Set the current indent step.
-     *
-     * @param indentStep The new indent step (0 or less for no
-     *        indentation).
-     * @see #getIndentStep()
-     *
-     * @deprecated
-     *      Should use the version that takes string.
-     */
-    public void setIndentStep(int indentStep) {
-        StringBuilder s = new StringBuilder();
-        for (; indentStep > 0; indentStep--) s.append(' ');
-        setIndentStep(s.toString());
-    }
-
-    public void setIndentStep(String s) {
-        this.indentStep = s;
-    }
-
-    private void onStartElement() throws XMLStreamException {
-        stateStack.push(SEEN_ELEMENT);
-        state = SEEN_NOTHING;
-        if (depth > 0) {
-            super.writeCharacters("\n");
-        }
-        doIndent();
-        depth++;
-    }
-
-    private void onEndElement() throws XMLStreamException {
-        depth--;
-        if (state == SEEN_ELEMENT) {
-            super.writeCharacters("\n");
-            doIndent();
-        }
-        state = stateStack.pop();
-    }
-
-    private void onEmptyElement() throws XMLStreamException {
-        state = SEEN_ELEMENT;
-        if (depth > 0) {
-            super.writeCharacters("\n");
-        }
-        doIndent();
-    }
-
-    /**
-     * Print indentation for the current level.
-     *
-     * @exception org.xml.sax.SAXException If there is an error
-     *            writing the indentation characters, or if a filter
-     *            further down the chain raises an exception.
-     */
-    private void doIndent() throws XMLStreamException {
-        if (depth > 0) {
-            for (int i = 0; i < depth; i++)
-                super.writeCharacters(indentStep);
-        }
-    }
-
-
-    public void writeStartDocument() throws XMLStreamException {
-        super.writeStartDocument();
-        super.writeCharacters("\n");
-    }
-
-    public void writeStartDocument(String version) throws XMLStreamException {
-        super.writeStartDocument(version);
-        super.writeCharacters("\n");
-    }
-
-    public void writeStartDocument(String encoding, String version) throws XMLStreamException {
-        super.writeStartDocument(encoding, version);
-        super.writeCharacters("\n");
-    }
-
-    public void writeStartElement(String localName) throws XMLStreamException {
-        onStartElement();
-        super.writeStartElement(localName);
-    }
-
-    public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {
-        onStartElement();
-        super.writeStartElement(namespaceURI, localName);
-    }
-
-    public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
-        onStartElement();
-        super.writeStartElement(prefix, localName, namespaceURI);
-    }
-
-    public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException {
-        onEmptyElement();
-        super.writeEmptyElement(namespaceURI, localName);
-    }
-
-    public void writeEmptyElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
-        onEmptyElement();
-        super.writeEmptyElement(prefix, localName, namespaceURI);
-    }
-
-    public void writeEmptyElement(String localName) throws XMLStreamException {
-        onEmptyElement();
-        super.writeEmptyElement(localName);
-    }
-
-    public void writeEndElement() throws XMLStreamException {
-        onEndElement();
-        super.writeEndElement();
-    }
-
-    public void writeCharacters(String text) throws XMLStreamException {
-        state = SEEN_DATA;
-        super.writeCharacters(text);
-    }
-
-    public void writeCharacters(char[] text, int start, int len) throws XMLStreamException {
-        state = SEEN_DATA;
-        super.writeCharacters(text, start, len);
-    }
-
-    public void writeCData(String data) throws XMLStreamException {
-        state = SEEN_DATA;
-        super.writeCData(data);
-    }
-}
diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/individual.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/individual.java
index e87f0c4d8e8da56b4975e12e9dc59efa5888c561..53df785da0a6e65757935f514feab8e69cfb348a 100644
--- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/individual.java
+++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/individual.java
@@ -4,7 +4,6 @@ import java.util.ArrayList;
 import java.util.Vector;
 
 import fr.inra.pappso.xtandempipeline.XtandemPipelineSession;
-import fr.inra.pappso.xtandempipeline.MsException.MSMSException;
 import fr.inra.pappso.xtandempipeline.MsException.StopException;
 import fr.inra.pappso.xtandempipeline.class_msms.MsRun;
 import fr.inra.pappso.xtandempipeline.class_msms.MsRunSet;
@@ -46,7 +45,7 @@ public class individual extends process {
 			// Is sample exist? Get previous identification
 			Identification identtemp = null;
 			for (int m = 0; m < identifications.size(); m++) {
-				logger.debug("identifications.size() "+identifications.size());
+				logger.debug("identifications.size() " + identifications.size());
 				MsRunSet samples = identifications.get(m).getMsRunSet();
 				for (MsRun sample : samples) {
 					logger.debug("msRun name : " + sample.getSampleName());
@@ -67,7 +66,8 @@ public class individual extends process {
 			// identifications.add(handler.get_identifications());
 
 			// Load identification from datasource
-			identifications.add(dataSourceToParse.loadIdentification(identtemp));
+			identifications
+					.add(dataSourceToParse.loadIdentification(identtemp));
 
 			// verification pas arreté
 			if (this.isStop())
@@ -81,7 +81,7 @@ public class individual extends process {
 			// filtering
 			this.set_view("Analysing file : " + (j + 1) + "/"
 					+ identifications.size() + "\n" + "Filtering file : "
-					+ ident.get_samples().getMsRunList().get(0).getSampleName());
+					+ ident.getMsRunSet().getMsRunList().get(0).getSampleName());
 
 			// on mets à jour les liens
 			ident.filtered_match(new filter_index_and_order_match_scan());
diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_base.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_base.java
index 05ab57d13a887372c216e1087d868cbc589ab0f8..907552a866b2ed16acb2de41aea13efc6c5dd03e 100644
--- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_base.java
+++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_base.java
@@ -17,8 +17,10 @@ import fr.inra.pappso.xtandempipeline.filter_print.calculation_protein_fdr_distr
 import fr.inra.pappso.xtandempipeline.filter_print.filter_isotopic_modifs;
 import fr.inra.pappso.xtandempipeline.filter_print.print_fasta;
 import fr.inra.pappso.xtandempipeline.filter_print.print_pepnovo;
-import fr.inra.pappso.xtandempipeline.sax_parse.MassChroQmlOutput;
-import fr.inra.pappso.xtandempipeline.sax_parse.ProticDbMlOutput;
+import fr.inra.pappso.xtandempipeline.output.CsvRedundantPeptideOutput;
+import fr.inra.pappso.xtandempipeline.output.MassChroQmlOutput;
+import fr.inra.pappso.xtandempipeline.output.OdsRedundantPeptideOutput;
+import fr.inra.pappso.xtandempipeline.output.ProticDbMlOutput;
 import fr.inra.pappso.xtandempipeline.sax_parse.msms_output;
 
 public class printing_base extends process {
@@ -54,8 +56,7 @@ public class printing_base extends process {
 			this.set_view("Printing Open Document Spreadsheet file results");
 
 			OdsDocWriter doc = this.ods_specific_printing(this.getfileout()
-					.getAbsolutePath()
-					+ ".ods");
+					.getAbsolutePath() + ".ods");
 			doc.close();
 
 		}
@@ -64,8 +65,7 @@ public class printing_base extends process {
 			this.set_view("Printing PROTICdbML file results");
 
 			FileOutputStream outputStream = new FileOutputStream(new File(this
-					.getfileout().getAbsolutePath()
-					+ "_protic.xml"));
+					.getfileout().getAbsolutePath() + "_protic.xml"));
 
 			ProticDbMlOutput protidDbMlOutput = new ProticDbMlOutput();
 			protidDbMlOutput.open(outputStream);
@@ -109,7 +109,7 @@ public class printing_base extends process {
 					+ "<tandem_to_pepnovo>" + "\n");
 			for (Identification ident : this.identifications) {
 				ident.print_result(new print_pepnovo(output, ident
-						.get_samples()));
+						.getMsRunSet()));
 			}
 			output.write("</tandem_to_pepnovo>" + "\n");
 			output.close();
@@ -146,19 +146,38 @@ public class printing_base extends process {
 			this.set_view("Printing MassChroQ xml file results");
 			Identification ident = this.identifications.get(0);
 			// modification isotopic
-			ident
-					.filtered_match(new filter_isotopic_modifs(
-							this.isotopic_mods));
+			ident.filtered_match(new filter_isotopic_modifs(this.isotopic_mods));
 
 			MassChroQmlOutput massChroQmlOutput = new MassChroQmlOutput(
 					this.isotopic_mods, ident);
 			FileOutputStream outputStream = new FileOutputStream(new File(this
-					.getfileout().getAbsolutePath()
-					+ ".masschroqML"));
-			;
+					.getfileout().getAbsolutePath() + ".masschroqML"));
+
 			massChroQmlOutput.write(outputStream);
 		}
 
+		// redundant peptide output (containing start and stop positions on
+		// proteins)
+		if (true) {
+			FileOutputStream outputStream = new FileOutputStream(new File(this
+					.getfileout().getAbsolutePath() + "_pep_redundant.ods"));
+			OdsRedundantPeptideOutput odsRedOutput = new OdsRedundantPeptideOutput(
+					outputStream);
+			for (Identification ident : this.identifications) {
+				odsRedOutput.write(ident);
+			}
+			odsRedOutput.close();
+
+			FileOutputStream csvStream = new FileOutputStream(new File(this
+					.getfileout().getAbsolutePath() + "_pep_redundant.csv"));
+			CsvRedundantPeptideOutput csvRedOutput = new CsvRedundantPeptideOutput(
+					csvStream);
+			for (Identification ident : this.identifications) {
+				csvRedOutput.write(ident);
+			}
+			csvRedOutput.close();
+		}
+
 		if (this.isStop())
 			throw new StopException("");
 		this.add_current_progress();
diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_combine.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_combine.java
index b1f4f14e7f0cad0746f0bd5f47b62c15ff46d8d6..9ae88a6e00f9c1c7c02b17d2ebe4dac1b8d033bb 100644
--- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_combine.java
+++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_combine.java
@@ -18,21 +18,22 @@ public class printing_combine extends printing_base {
 		super(conf);
 	}
 
-	protected OdsDocWriter ods_specific_printing(String filename) throws Exception {
+	protected OdsDocWriter ods_specific_printing(String filename)
+			throws Exception {
 		logger.info("Print combine results in ODS");
 		OdsDocWriter odsDoc = new OdsDocWriter(filename);
 
 		this.set_view("Printing protein file results");
-		
+
 		odsDoc.writeSheet("proteins");
-		//msms_output output = new msms_output();
-		//output.open(this.getfileout().getAbsolutePath() + "_protein.txt");
+		// msms_output output = new msms_output();
+		// output.open(this.getfileout().getAbsolutePath() + "_protein.txt");
 		// protein view
 		for (Identification ident : this.identifications) {
 			ident.print_result(new print_ods_protein_to_combined(odsDoc));
 		}
 
-		//output.close();
+		// output.close();
 
 		// Verification pas arrete
 		if (this.isStop())
@@ -41,13 +42,13 @@ public class printing_combine extends printing_base {
 
 		this.set_view("Printing peptide file results");
 		odsDoc.writeSheet("peptides");
-		//output.open(this.getfileout().getAbsolutePath() + "_peptide.txt");
+		// output.open(this.getfileout().getAbsolutePath() + "_peptide.txt");
 
 		// peptide list
 		for (Identification ident : this.identifications) {
 			ident.print_result(new print_ods_peptide_list(odsDoc));
 		}
-		//output.close();
+		// output.close();
 
 		// Verification pas arrete
 		if (this.isStop())
@@ -55,17 +56,17 @@ public class printing_combine extends printing_base {
 		this.add_current_progress();
 
 		this.set_view("Printing compar file results");
-		//odsDoc.writeSheet("compar");
-		//output.open(this.getfileout().getAbsolutePath() + "_compar.txt");
+		// odsDoc.writeSheet("compar");
+		// output.open(this.getfileout().getAbsolutePath() + "_compar.txt");
 		for (Identification ident : this.identifications) {
-			ident.print_result(new print_ods_compar(odsDoc, ident.get_samples()));
+			ident.print_result(new print_ods_compar(odsDoc, ident.getMsRunSet()));
 		}
-		//output.close();
+		// output.close();
 
 		this.add_current_progress();
 		return odsDoc;
 	}
-	
+
 	protected void specific_printing() throws Exception {
 		logger.info("Print combine results");
 
@@ -101,7 +102,7 @@ public class printing_combine extends printing_base {
 		this.set_view("Printing compar file results");
 		output.open(this.getfileout().getAbsolutePath() + "_compar.txt");
 		for (Identification ident : this.identifications) {
-			ident.print_result(new print_compar(output, ident.get_samples()));
+			ident.print_result(new print_compar(output, ident.getMsRunSet()));
 		}
 		output.close();
 
diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_indiv.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_indiv.java
index 448e899c62784040f64dd81fd957470042d80109..259aabc2ba83a6dd6a9bb14c068aa8165f90db72 100644
--- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_indiv.java
+++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_indiv.java
@@ -1,6 +1,5 @@
 package fr.inra.pappso.xtandempipeline.thread;
 
-
 import fr.inra.pappso.libodsstream.OdsDocWriter;
 import fr.inra.pappso.xtandempipeline.MsException.StopException;
 import fr.inra.pappso.xtandempipeline.class_msms.config;
@@ -11,23 +10,24 @@ import fr.inra.pappso.xtandempipeline.filter_print.print_peptide_list;
 import fr.inra.pappso.xtandempipeline.filter_print.print_protein_to_indiv;
 import fr.inra.pappso.xtandempipeline.sax_parse.msms_output;
 
-
 public class printing_indiv extends printing_base {
 
 	public printing_indiv(config conf) {
 		super(conf);
 	}
-	
-	protected OdsDocWriter ods_specific_printing(String filename) throws Exception {
+
+	protected OdsDocWriter ods_specific_printing(String filename)
+			throws Exception {
 		logger.info("Print individual results in ODS");
 		OdsDocWriter odsDoc = new OdsDocWriter(filename);
-		
+
 		this.set_view("Printing protein file results");
-		
+
 		odsDoc.writeSheet("proteins");
 		// protein view
 		for (Identification ident : this.identifications) {
-			ident.print_result(new print_ods_protein_to_indiv(odsDoc, ident.get_samples()));
+			ident.print_result(new print_ods_protein_to_indiv(odsDoc, ident
+					.getMsRunSet()));
 		}
 
 		// Verification pas arrete
@@ -46,19 +46,20 @@ public class printing_indiv extends printing_base {
 		if (this.isStop())
 			throw new StopException("");
 		this.add_current_progress();
-		
+
 		return odsDoc;
 	}
 
-	protected void specific_printing () throws Exception {
+	protected void specific_printing() throws Exception {
 		logger.info("Print individual results");
-		
+
 		this.set_view("Printing protein file results");
 		msms_output output = new msms_output();
 		output.open(this.getfileout().getAbsolutePath() + "_protein.txt");
 		// protein view
 		for (Identification ident : this.identifications) {
-			ident.print_result(new print_protein_to_indiv(output, ident.get_samples()));
+			ident.print_result(new print_protein_to_indiv(output, ident
+					.getMsRunSet()));
 		}
 
 		output.close();
diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_phosphopeptide.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_phosphopeptide.java
index ef274d8325039994b4d162458a57627f84560e0b..cbae3ca8f2141e871cee575a46625ba4f7400962 100644
--- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_phosphopeptide.java
+++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_phosphopeptide.java
@@ -18,20 +18,21 @@ public class printing_phosphopeptide extends printing_base {
 		super(conf);
 	}
 
-	protected OdsDocWriter ods_specific_printing(String filename) throws Exception {
+	protected OdsDocWriter ods_specific_printing(String filename)
+			throws Exception {
 		OdsDocWriter odsDoc = new OdsDocWriter(filename);
 		logger.info("Print phophopeptide results ODS");
 
 		this.set_view("Printing protein file results");
 		odsDoc.writeSheet("proteins");
-		//msms_output output = new msms_output();
-		//output.open(this.getfileout().getAbsolutePath() + "_protein.txt");
+		// msms_output output = new msms_output();
+		// output.open(this.getfileout().getAbsolutePath() + "_protein.txt");
 		// protein view
 		for (Identification ident : this.identifications) {
 			ident.print_result(new print_ods_protein_to_phosphopeptide(odsDoc));
 		}
 
-		//output.close();
+		// output.close();
 
 		// Verification pas arrete
 		if (this.isStop())
@@ -39,14 +40,15 @@ public class printing_phosphopeptide extends printing_base {
 		this.add_current_progress();
 
 		this.set_view("Printing peptide file results");
-		//output.open(this.getfileout().getAbsolutePath() + "_peptide.txt");
+		// output.open(this.getfileout().getAbsolutePath() + "_peptide.txt");
 		odsDoc.writeSheet("peptides");
 
 		// peptide list
 		for (Identification ident : this.identifications) {
-			ident.print_result(new print_ods_peptide_list_to_phosphopeptide(odsDoc));
+			ident.print_result(new print_ods_peptide_list_to_phosphopeptide(
+					odsDoc));
 		}
-		//output.close();
+		// output.close();
 
 		// Verification pas arrete
 		if (this.isStop())
@@ -54,13 +56,13 @@ public class printing_phosphopeptide extends printing_base {
 		this.add_current_progress();
 
 		this.set_view("Printing compar file results");
-		//odsDoc.writeSheet("compar");
-		//output.open(this.getfileout().getAbsolutePath() + "_compar.txt");
+		// odsDoc.writeSheet("compar");
+		// output.open(this.getfileout().getAbsolutePath() + "_compar.txt");
 		for (Identification ident : this.identifications) {
 			ident.print_result(new print_ods_compar_phospho(odsDoc, ident
-					.get_samples()));
+					.getMsRunSet()));
 		}
-		//output.close();
+		// output.close();
 
 		this.add_current_progress();
 		return odsDoc;
@@ -101,7 +103,7 @@ public class printing_phosphopeptide extends printing_base {
 		output.open(this.getfileout().getAbsolutePath() + "_compar.txt");
 		for (Identification ident : this.identifications) {
 			ident.print_result(new print_compar_phospho(output, ident
-					.get_samples()));
+					.getMsRunSet()));
 		}
 		output.close();