diff --git a/simple/src/main/java/org/odftoolkit/simple/SpreadsheetDocument.java b/simple/src/main/java/org/odftoolkit/simple/SpreadsheetDocument.java
index 12b96b9..550c3a2 100644
--- a/simple/src/main/java/org/odftoolkit/simple/SpreadsheetDocument.java
+++ b/simple/src/main/java/org/odftoolkit/simple/SpreadsheetDocument.java
@@ -1,666 +1,639 @@
-/************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
- * 
- * Copyright 2008, 2010 Oracle and/or its affiliates. All rights reserved.
- * 
- * Use is subject to license terms.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy
- * of the License at http://www.apache.org/licenses/LICENSE-2.0. You can also
- * obtain a copy of the License at http://odftoolkit.org/docs/license.txt
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * 
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ************************************************************************/
-package org.odftoolkit.simple;
-
-import java.awt.Rectangle;
-import java.io.File;
-import java.io.InputStream;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.xml.xpath.XPathConstants;
-
-import org.odftoolkit.odfdom.dom.OdfContentDom;
-import org.odftoolkit.odfdom.dom.element.draw.DrawFrameElement;
-import org.odftoolkit.odfdom.dom.element.office.OfficeSpreadsheetElement;
-import org.odftoolkit.odfdom.dom.element.table.TableTableCellElement;
-import org.odftoolkit.odfdom.dom.element.table.TableTableElement;
-import org.odftoolkit.odfdom.pkg.MediaType;
-import org.odftoolkit.odfdom.pkg.OdfElement;
-import org.odftoolkit.odfdom.pkg.OdfPackage;
-import org.odftoolkit.odfdom.type.CellRangeAddressList;
-import org.odftoolkit.simple.chart.AbstractChartContainer;
-import org.odftoolkit.simple.chart.Chart;
-import org.odftoolkit.simple.chart.ChartContainer;
-import org.odftoolkit.simple.chart.DataSet;
-import org.odftoolkit.simple.table.Cell;
-import org.odftoolkit.simple.table.Table;
-import org.odftoolkit.simple.table.TableContainer;
-import org.w3c.dom.Node;
-
-/**
- * This class represents an empty ODF spreadsheet document.
- * 
- */
-public class SpreadsheetDocument extends Document implements ChartContainer {
-
-	private static final String EMPTY_SPREADSHEET_DOCUMENT_PATH = "/OdfSpreadsheetDocument.ods";
-	static final Resource EMPTY_SPREADSHEET_DOCUMENT_RESOURCE = new Resource(EMPTY_SPREADSHEET_DOCUMENT_PATH);
-	private ChartContainerImpl chartContainerImpl;
-	/**
-	 * This enum contains all possible media types of SpreadsheetDocument
-	 * documents.
-	 */
-	public enum OdfMediaType implements MediaType {
-
-		SPREADSHEET(Document.OdfMediaType.SPREADSHEET), SPREADSHEET_TEMPLATE(Document.OdfMediaType.SPREADSHEET_TEMPLATE);
-		private final Document.OdfMediaType mMediaType;
-
-		OdfMediaType(Document.OdfMediaType mediaType) {
-			this.mMediaType = mediaType;
-		}
-
-		/**
-		 * @return the mediatype of this document
-		 */
-		public String getMediaTypeString() {
-			return mMediaType.getMediaTypeString();
-		}
-
-		/**
-		 * @return the ODF filesuffix of this document
-		 */
-		public String getSuffix() {
-			return mMediaType.getSuffix();
-		}
-
-		/**
-		 * 
-		 * @param mediaType
-		 *            string defining an ODF document
-		 * @return the according OdfMediatype encapuslating the given string and
-		 *         the suffix
-		 */
-		public static Document.OdfMediaType getOdfMediaType(String mediaType) {
-			return Document.OdfMediaType.getOdfMediaType(mediaType);
-		}
-	}
-
-	/**
-	 * Creates an empty spreadsheet document.
-	 * 
-	 * @return ODF spreadsheet document based on a default template*
-	 * @throws java.lang.Exception
-	 *             - if the document could not be created
-	 */
-	public static SpreadsheetDocument newSpreadsheetDocument() throws Exception {
-		return (SpreadsheetDocument) Document.loadTemplate(EMPTY_SPREADSHEET_DOCUMENT_RESOURCE,
-				Document.OdfMediaType.SPREADSHEET);
-	}
-
-	/**
-	 * Creates an empty spreadsheet template.
-	 * 
-	 * @return ODF spreadsheet template based on a default
-	 * @throws java.lang.Exception
-	 *             - if the template could not be created
-	 */
-	public static SpreadsheetDocument newSpreadsheetTemplateDocument() throws Exception {
-		SpreadsheetDocument doc = (SpreadsheetDocument) Document.loadTemplate(EMPTY_SPREADSHEET_DOCUMENT_RESOURCE,
-				Document.OdfMediaType.SPREADSHEET_TEMPLATE);
-		doc.changeMode(OdfMediaType.SPREADSHEET_TEMPLATE);
-		return doc;
-	}
-
-	/**
-	 * To avoid data duplication a new document is only created, if not already
-	 * opened. A document is cached by this constructor using the internalpath
-	 * as key.
-	 */
-	protected SpreadsheetDocument(OdfPackage pkg, String internalPath, SpreadsheetDocument.OdfMediaType odfMediaType) {
-		super(pkg, internalPath, odfMediaType.mMediaType);
-	}
-
-	/**
-	 * Creates an SpreadsheetDocument from the OpenDocument provided by a
-	 * resource Stream.
-	 * 
-	 * <p>
-	 * Since an InputStream does not provide the arbitrary (non sequentiell)
-	 * read access needed by SpreadsheetDocument, the InputStream is cached.
-	 * This usually takes more time compared to the other createInternalDocument
-	 * methods. An advantage of caching is that there are no problems
-	 * overwriting an input file.
-	 * </p>
-	 * 
-	 * <p>
-	 * If the resource stream is not a ODF spreadsheet document,
-	 * ClassCastException might be thrown.
-	 * </p>
-	 * 
-	 * @param inputStream
-	 *            - the InputStream of the ODF spreadsheet document.
-	 * @return the spreadsheet document created from the given InputStream
-	 * @throws java.lang.Exception
-	 *             - if the document could not be created.
-	 */
-	public static SpreadsheetDocument loadDocument(InputStream inputStream) throws Exception {
-		return (SpreadsheetDocument) Document.loadDocument(inputStream);
-	}
-
-	/**
-	 * Loads an SpreadsheetDocument from the provided path.
-	 * 
-	 * <p>
-	 * SpreadsheetDocument relies on the file being available for read access
-	 * over the whole lifecycle of SpreadsheetDocument.
-	 * </p>
-	 * 
-	 * <p>
-	 * If the resource stream is not a ODF spreadsheet document,
-	 * ClassCastException might be thrown.
-	 * </p>
-	 * 
-	 * @param documentPath
-	 *            - the path from where the document can be loaded
-	 * @return the spreadsheet document from the given path or NULL if the media
-	 *         type is not supported by SIMPLE.
-	 * @throws java.lang.Exception
-	 *             - if the document could not be created.
-	 */
-	public static SpreadsheetDocument loadDocument(String documentPath) throws Exception {
-		return (SpreadsheetDocument) Document.loadDocument(documentPath);
-	}
-
-	/**
-	 * Creates an SpreadsheetDocument from the OpenDocument provided by a File.
-	 * 
-	 * <p>
-	 * SpreadsheetDocument relies on the file being available for read access
-	 * over the whole lifecycle of SpreadsheetDocument.
-	 * </p>
-	 * 
-	 * <p>
-	 * If the resource stream is not a ODF spreadsheet document,
-	 * ClassCastException might be thrown.
-	 * </p>
-	 * 
-	 * @param file
-	 *            - a file representing the ODF spreadsheet document.
-	 * @return the spreadsheet document created from the given File
-	 * @throws java.lang.Exception
-	 *             - if the document could not be created.
-	 */
-	public static SpreadsheetDocument loadDocument(File file) throws Exception {
-		return (SpreadsheetDocument) Document.loadDocument(file);
-	}
-
-	/**
-	 * Get the content root of a spreadsheet document.
-	 * 
-	 * @return content root, representing the office:spreadsheet tag
-	 * @throws Exception
-	 *             if the file DOM could not be created.
-	 */
-	@Override
-	public OfficeSpreadsheetElement getContentRoot() throws Exception {
-		return super.getContentRoot(OfficeSpreadsheetElement.class);
-	}
-
-	/**
-	 * Changes the document to the given mediatype. This method can only be used
-	 * to convert a document to a related mediatype, e.g. template.
-	 * 
-	 * @param mediaType
-	 *            the related ODF mimetype
-	 */
-	public void changeMode(OdfMediaType mediaType) {
-		setOdfMediaType(mediaType.mMediaType);
-	}
-
-	/**
-	 * Retrieves sheet by index.
-	 * 
-	 * @param index
-	 *            the index of the retrieved sheet, which starts from 0. If the
-	 *            index value is out of range (index >= sheet count or index <
-	 *            0), this method would return <code>null</code>.
-	 * @since 0.6
-	 */
-	public Table getSheetByIndex(int index) {
-		if (index < 0) {
-			return null;
-		}
-		int count = 0;
-		try {
-			OfficeSpreadsheetElement spreadsheetElement = getContentRoot();
-			Node child = spreadsheetElement.getFirstChild();
-			while ((child != null) && (count <= index)) {
-				if (child instanceof TableTableElement) {
-					if (count == index) {
-						return getTableBuilder().getTableInstance((TableTableElement) child);
-					} else {
-						count++;
-					}
-				}
-				child = child.getNextSibling();
-			}
-		} catch (Exception e) {
-			Logger.getLogger(SpreadsheetDocument.class.getName()).log(Level.SEVERE, null, e);
-		}
-		return null;
-	}
-	
-	/**
-	 * Retrieves sheet by name.
-	 * 
-	 * @param name
-	 *            the name of the retrieved sheet.
-	 * @since 0.6
-	 */
-	public Table getSheetByName(String name) {
-		return getTableByName(name);
-	}
-
-	
-	/**
-	 * Adds a new blank sheet with the specified <code>name</code> to this
-	 * document.
-	 * 
-	 * @param name
-	 *            the name of the new sheet.
-	 * @return added sheet.
-	 * @since 0.6
-	 */
-	public Table appendSheet(String name) {
-		Table newTable = addTable();
-		newTable.setTableName(name);
-		return newTable;
-	}
-
-	/**
-	 * Adds a new sheet with data from existing table.
-	 * <p>
-	 * NOTE: This method copies data from existing table, including linked
-	 * resources and styles, if the source table is not in the target document.
-	 * If these data has dependencies to other data of the source document, the
-	 * data dependencies will not be copied. For example, document A has two
-	 * sheets, "Sheet1" and "Sheet2". In "Sheet2", there is a cell with formula,
-	 * "=sum(Sheet1.A1:Sheet1.A10)". After copy the data of "Sheet2" to the new
-	 * sheet in document B, the result of this formula would be different or
-	 * even invalid in document B.
-	 * 
-	 * @param refTable
-	 *            the reference table, which is the data source of the new
-	 *            sheet.
-	 * @param name
-	 *            the name of the new sheet.
-	 * @return added sheet.
-	 * @since 0.6
-	 */
-	public Table appendSheet(Table refTable, String name) {
-		TableTableElement refTableElement = refTable.getOdfElement();
-		try {
-			OdfContentDom contentDom = getContentDom();
-			TableTableElement newTableEle = (TableTableElement) (refTableElement.cloneNode(true));
-			// not in a same document
-			if (refTableElement.getOwnerDocument() != contentDom) {
-				Document ownerDocument = refTable.getOwnerDocument();
-				copyLinkedRefInBatch(newTableEle, ownerDocument);
-				copyForeignStyleRef(newTableEle, ownerDocument);
-				newTableEle = (TableTableElement) cloneForeignElement(newTableEle, contentDom, true);
-			}
-			updateNames(newTableEle);
-			updateXMLIds(newTableEle);
-			getTableContainerElement().appendChild(newTableEle);
-			Table tableInstance = getTableBuilder().getTableInstance(newTableEle);
-			tableInstance.setTableName(name);
-			return tableInstance;
-		} catch (Exception e) {
-			Logger.getLogger(SpreadsheetDocument.class.getName()).log(Level.SEVERE, null, e);
-		}
-		return null;
-	}
-	
-	/**
-	 * Inserts a new blank sheet before the reference index.
-	 * 
-	 * @param before
-	 *            the reference index, which starts from 0. If the index value
-	 *            is out of range (index >= sheet count or index < 0), this
-	 *            method would return <code>null</code>.
-	 * @return inserted sheet.
-	 * @since 0.6
-	 */
-	public Table insertSheet(int before) {
-		if (before < 0) {
-			return null;
-		}
-		int count = 0;
-		try {
-			OfficeSpreadsheetElement spreadsheetElement = getContentRoot();
-			Node child = spreadsheetElement.getFirstChild();
-			while ((child != null) && (count <= before)) {
-				if (child instanceof TableTableElement) {
-					if (count == before) {
-						Table table = getTableBuilder().newTable();
-						getContentRoot().insertBefore(table.getOdfElement(), child);
-						return table;
-					} else {
-						count++;
-					}
-				}
-				child = child.getNextSibling();
-			}
-		} catch (Exception e) {
-			Logger.getLogger(SpreadsheetDocument.class.getName()).log(Level.SEVERE, null, e);
-		}
-		return null;
-	}
-	
-	/**
-	 * Inserts a new sheet with data from existing table.
-	 * 
-	 * <p>
-	 * NOTE: This method copies data from existing table, including linked
-	 * resources and styles, if the source table is not in the target document.
-	 * If these data has dependencies to other data of the source document, the
-	 * data dependencies will not be copied. For example, document A has two
-	 * sheets, "Sheet1" and "Sheet2". In "Sheet2", there is a cell with formula,
-	 * "=sum(Sheet1.A1:Sheet1.A10)". After copy the data of "Sheet2" to the new
-	 * sheet in document B, the result of this formula would be different or
-	 * even invalid in document B.
-	 * 
-	 * @param refTable
-	 *            the reference table, which is the data source of the new
-	 *            sheet.
-	 * @param before
-	 *            the reference index, which starts from 0 and new sheet would
-	 *            be inserted before it. If the index value is out of range
-	 *            (index >= sheet count or index < 0), this method would return
-	 *            <code>null</code>.
-	 * @return inserted sheet.
-	 * @since 0.6
-	 */
-	public Table insertSheet(Table refTable, int before) {
-		if (before < 0) {
-			return null;
-		}
-		int count = 0;
-		try {
-			OfficeSpreadsheetElement spreadsheetElement = getContentRoot();
-			Node child = spreadsheetElement.getFirstChild();
-			while ((child != null) && (count <= before)) {
-				if (child instanceof TableTableElement) {
-					if (count == before) {
-						TableTableElement refTableElement = refTable.getOdfElement();
-						try {
-							OdfContentDom contentDom = getContentDom();
-							TableTableElement newTableEle = (TableTableElement) (refTableElement.cloneNode(true));
-							//foreign node not in a same document
-							if (refTableElement.getOwnerDocument() != contentDom) {
-								Document ownerDocument = refTable.getOwnerDocument();
-								copyLinkedRefInBatch(newTableEle, ownerDocument);
-								copyForeignStyleRef(newTableEle, ownerDocument);
-								newTableEle = (TableTableElement) cloneForeignElement(newTableEle, contentDom, true);
-							}
-							updateNames(newTableEle);
-							updateXMLIds(newTableEle);
-							newTableEle.setTableNameAttribute(getUniqueSheetName(this));
-							getContentRoot().insertBefore(newTableEle, child);
-							return getTableBuilder().getTableInstance(newTableEle);
-						} catch (Exception e) {
-							Logger.getLogger(SpreadsheetDocument.class.getName()).log(Level.SEVERE, null, e);
-						}
-					} else {
-						count++;
-					}
-				}
-				child = child.getNextSibling();
-			}
-		} catch (Exception e) {
-			Logger.getLogger(SpreadsheetDocument.class.getName()).log(Level.SEVERE, null, e);
-		}
-		return null;
-	}
-
-	/**
-	 * Removes the sheet in the specified <code>index</code>.
-	 * 
-	 * @param index
-	 *            the index of the removed sheet, which starts from 0. If the
-	 *            index value is out of range (index >= sheet count or index <
-	 *            0), this method would do nothing.
-	 * @since 0.6
-	 */
-	public void removeSheet(int index) {
-		if (index < 0) {
-			return;
-		}
-		int count = 0;
-		try {
-			OfficeSpreadsheetElement spreadsheetElement = getContentRoot();
-			Node child = spreadsheetElement.getFirstChild();
-			while ((child != null) && (count <= index)) {
-				if (child instanceof TableTableElement) {
-					if (count == index) {
-						spreadsheetElement.removeChild(child);
-						return;
-					} else {
-						count++;
-					}
-				}
-				child = child.getNextSibling();
-			}
-		} catch (Exception e) {
-			Logger.getLogger(SpreadsheetDocument.class.getName()).log(Level.SEVERE, null, e);
-		}
-	}
-
-	/**
-	 * Returns the sheet count of this document.
-	 * 
-	 * @return the sheet count of this document.
-	 * @since 0.6
-	 */
-	public int getSheetCount() {
-		int count = 0;
-		try {
-			OfficeSpreadsheetElement spreadsheetElement = getContentRoot();
-			Node child = spreadsheetElement.getFirstChild();
-			while (child != null) {
-				if (child instanceof TableTableElement) {
-					count++;
-				}
-				child = child.getNextSibling();
-			}
-		} catch (Exception e) {
-			Logger.getLogger(SpreadsheetDocument.class.getName()).log(Level.SEVERE, null, e);
-		}
-		return count;
-	}
-	
-	public OdfElement getTableContainerElement() {
-		return getTableContainerImpl().getTableContainerElement();
-	}
-	
-	/**
-	 * Creates a new Chart for this spreadsheet document.
-	 * 
-	 * @param title
-	 *            chart title.
-	 * @param dataset
-	 *            chart data set.
-	 * @param rect
-	 *            chart rectangle.
-	 * @return the created chart.
-	 * 
-	 * @since 0.6
-	 */
-	public Chart createChart(String title, DataSet dataset, Rectangle rect) {
-		return getChartContainerImpl().createChart(title, dataset, rect);
-	}
-	
-	/**
-	 * Creates a new Chart for this spreadsheet document.
-	 * 
-	 * @param title
-	 *            chart title.
-	 * @param document
-	 *            the data source spreadsheet document.
-	 * @param cellRangeAddr
-	 *            the cell range address list which is used as chart data set.
-	 * @param firstRowAsLabel
-	 *            whether uses first row as label.
-	 * @param firstColumnAsLabel
-	 *            whether uses first column as label.
-	 * @param rowAsDataSeries
-	 *            whether uses data as series.
-	 * @param rect
-	 *            chart rectangle.
-	 * @return the created chart.
-	 * 
-	 * @since 0.6
-	 */
-	public Chart createChart(String title, SpreadsheetDocument document, CellRangeAddressList cellRangeAddr, boolean firstRowAsLabel,
-			boolean firstColumnAsLabel, boolean rowAsDataSeries, Rectangle rect) {
-		return getChartContainerImpl().createChart(title, document, cellRangeAddr, firstRowAsLabel, firstColumnAsLabel,
-				rowAsDataSeries, rect);
-	}
-	
-	/**
-	 * Creates a new Chart for this spreadsheet document.
-	 * 
-	 * @param title
-	 *            chart rectangle.
-	 * @param labels
-	 *            label strings
-	 * @param legends
-	 *            legend strings
-	 * @param data
-	 *            chart data set.
-	 * @param rect
-	 *            chart rectangle.
-	 * @return the created chart.
-	 * 
-	 * @since 0.6
-	 */
-	public Chart createChart(String title, String[] labels, String[] legends, double[][] data, Rectangle rect) {
-		return getChartContainerImpl().createChart(title, labels, legends, data, rect);
-	}
-	
-	/**
-	 * Creates a new Chart for this spreadsheet document.
-	 * 
-	 * @param title
-	 *            chart rectangle.
-	 * @param document
-	 *            the data source spreadsheet document.
-	 * @param cellRangeAddr
-	 *            the cell range list to be used as chart data.
-	 * @param firstRowAsLabel
-	 *            whether use first row as label.
-	 * @param firstColumnAsLabel
-	 *            whether use first column as label.
-	 * @param rowAsDataSeries
-	 *            whether use row as data series.
-	 * @param rect
-	 *            chart rectangle.
-	 * @param cell
-	 *            the position cell where the new chart is inserted.
-	 * @return the created chart.
-	 * 
-	 * @since 0.6
-	 */
-	public Chart createChart(String title, SpreadsheetDocument document, CellRangeAddressList cellRangeAddr, boolean firstRowAsLabel,
-			boolean firstColumnAsLabel, boolean rowAsDataSeries, Rectangle rect, Cell cell) {
-		return getChartContainerImpl().createChart(title, document, cellRangeAddr, firstRowAsLabel, firstColumnAsLabel,
-				rowAsDataSeries, rect, cell);
-	}
-	
-	public void deleteChartById(String chartId) {
-		getChartContainerImpl().deleteChartById(chartId);
-	}
-
-	public void deleteChartByTitle(String title) {
-		getChartContainerImpl().deleteChartByTitle(title);
-	}
-
-	public Chart getChartById(String chartId) {
-		return getChartContainerImpl().getChartById(chartId);
-	}
-
-	public List<Chart> getChartByTitle(String title) {
-		return getChartContainerImpl().getChartByTitle(title);
-	}
-
-	public int getChartCount() {
-		return getChartContainerImpl().getChartCount();
-	}
-	
-	private static String getUniqueSheetName(TableContainer container) {
-		List<Table> tableList = container.getTableList();
-		boolean notUnique = true;
-		String tablename = "Sheet" + (tableList.size() + 1);
-		while (notUnique) {
-			notUnique = false;
-			for (int i = 0; i < tableList.size(); i++) {
-				if (tableList.get(i).getTableName() != null) {
-					if (tableList.get(i).getTableName().equalsIgnoreCase(tablename)) {
-						notUnique = true;
-						break;
-					}
-				}
-			}
-			if (notUnique) {
-				tablename = tablename + Math.round(Math.random() * 10);
-			}
-		}
-		return tablename;
-	}
-	
-	private ChartContainerImpl getChartContainerImpl() {
-		if (chartContainerImpl == null) {
-			chartContainerImpl = new ChartContainerImpl(this);
-		}
-		return chartContainerImpl;
-	}
-	
-	private class ChartContainerImpl extends AbstractChartContainer {
-		SpreadsheetDocument sdoc;
-		DrawFrameElement drawFrame;
-		protected ChartContainerImpl(Document doc) {
-			super(doc);
-			sdoc = (SpreadsheetDocument) doc;
-		}
-
-		protected DrawFrameElement getChartFrame() throws Exception {
-			OdfContentDom contentDom2 = sdoc.getContentDom();
-			DrawFrameElement drawFrame = contentDom2.newOdfElement(DrawFrameElement.class);
-			TableTableCellElement lastCell = (TableTableCellElement) contentDom2.getXPath().evaluate(
-					"//table:table-cell[last()]", contentDom2, XPathConstants.NODE);
-			lastCell.appendChild(drawFrame);
-			drawFrame.removeAttribute("text:anchor-type");
-			this.drawFrame = drawFrame;
-			return drawFrame;
-		}
-		
-		private Chart createChart(String title, SpreadsheetDocument document, CellRangeAddressList cellRangeAddr, boolean firstRowAsLabel,
-				boolean firstColumnAsLabel, boolean rowAsDataSeries, Rectangle rect, Cell cell) {
-			Chart chart = getChartContainerImpl().createChart(title, document, cellRangeAddr, firstRowAsLabel, firstColumnAsLabel,
-					rowAsDataSeries, rect);
-			cell.getOdfElement().appendChild(this.drawFrame);
-			return chart;
-		}
-	}
-}
+/**
+ * **********************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
+ *
+ * Copyright 2008, 2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0. You can also
+ * obtain a copy of the License at http://odftoolkit.org/docs/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ***********************************************************************
+ */
+package org.odftoolkit.simple;
+
+import java.awt.Rectangle;
+import java.io.File;
+import java.io.InputStream;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.xml.xpath.XPathConstants;
+import org.odftoolkit.odfdom.dom.OdfContentDom;
+import org.odftoolkit.odfdom.dom.element.draw.DrawFrameElement;
+import org.odftoolkit.odfdom.dom.element.office.OfficeSpreadsheetElement;
+import org.odftoolkit.odfdom.dom.element.table.TableTableCellElement;
+import org.odftoolkit.odfdom.dom.element.table.TableTableElement;
+import org.odftoolkit.odfdom.pkg.MediaType;
+import org.odftoolkit.odfdom.pkg.OdfElement;
+import org.odftoolkit.odfdom.pkg.OdfPackage;
+import org.odftoolkit.odfdom.type.CellRangeAddressList;
+import org.odftoolkit.simple.chart.AbstractChartContainer;
+import org.odftoolkit.simple.chart.Chart;
+import org.odftoolkit.simple.chart.ChartContainer;
+import org.odftoolkit.simple.chart.DataSet;
+import org.odftoolkit.simple.table.Cell;
+import org.odftoolkit.simple.table.RepeatedNumberUtils;
+import org.odftoolkit.simple.table.Table;
+import org.odftoolkit.simple.table.TableContainer;
+import org.w3c.dom.Node;
+
+/**
+ * This class represents an empty ODF spreadsheet document.
+ *
+ */
+public class SpreadsheetDocument extends Document implements ChartContainer {
+
+    private static final String EMPTY_SPREADSHEET_DOCUMENT_PATH = "/OdfSpreadsheetDocument.ods";
+    static final Resource EMPTY_SPREADSHEET_DOCUMENT_RESOURCE = new Resource(EMPTY_SPREADSHEET_DOCUMENT_PATH);
+    private ChartContainerImpl chartContainerImpl;
+
+    /**
+     * This enum contains all possible media types of SpreadsheetDocument
+     * documents.
+     */
+    public enum OdfMediaType implements MediaType {
+
+        SPREADSHEET(Document.OdfMediaType.SPREADSHEET), SPREADSHEET_TEMPLATE(Document.OdfMediaType.SPREADSHEET_TEMPLATE);
+        private final Document.OdfMediaType mMediaType;
+
+        OdfMediaType(Document.OdfMediaType mediaType) {
+            this.mMediaType = mediaType;
+        }
+
+        /**
+         * @return the mediatype of this document
+         */
+        public String getMediaTypeString() {
+            return mMediaType.getMediaTypeString();
+        }
+
+        /**
+         * @return the ODF filesuffix of this document
+         */
+        public String getSuffix() {
+            return mMediaType.getSuffix();
+        }
+
+        /**
+         *
+         * @param mediaType string defining an ODF document
+         * @return the according OdfMediatype encapuslating the given string and
+         * the suffix
+         */
+        public static Document.OdfMediaType getOdfMediaType(String mediaType) {
+            return Document.OdfMediaType.getOdfMediaType(mediaType);
+        }
+    }
+
+    /**
+     * Creates an empty spreadsheet document.
+     *
+     * @return ODF spreadsheet document based on a default template
+     *
+     * @throws java.lang.Exception - if the document could not be created
+     */
+    public static SpreadsheetDocument newSpreadsheetDocument() throws Exception {
+        return (SpreadsheetDocument) Document.loadTemplate(EMPTY_SPREADSHEET_DOCUMENT_RESOURCE,
+            Document.OdfMediaType.SPREADSHEET);
+    }
+
+    /**
+     * Creates an empty spreadsheet template.
+     *
+     * @return ODF spreadsheet template based on a default
+     * @throws java.lang.Exception - if the template could not be created
+     */
+    public static SpreadsheetDocument newSpreadsheetTemplateDocument() throws Exception {
+        SpreadsheetDocument doc = (SpreadsheetDocument) Document.loadTemplate(EMPTY_SPREADSHEET_DOCUMENT_RESOURCE,
+            Document.OdfMediaType.SPREADSHEET_TEMPLATE);
+        doc.changeMode(OdfMediaType.SPREADSHEET_TEMPLATE);
+        return doc;
+    }
+
+    /**
+     * To avoid data duplication a new document is only created, if not already
+     * opened. A document is cached by this constructor using the internalpath
+     * as key.
+     */
+    protected SpreadsheetDocument(OdfPackage pkg, String internalPath, SpreadsheetDocument.OdfMediaType odfMediaType) {
+        super(pkg, internalPath, odfMediaType.mMediaType);
+    }
+
+    /**
+     * Creates an SpreadsheetDocument from the OpenDocument provided by a
+     * resource Stream.
+     *
+     * <p>
+     * Since an InputStream does not provide the arbitrary (non sequentiell)
+     * read access needed by SpreadsheetDocument, the InputStream is cached.
+     * This usually takes more time compared to the other createInternalDocument
+     * methods. An advantage of caching is that there are no problems
+     * overwriting an input file.
+     * </p>
+     *
+     * <p>
+     * If the resource stream is not a ODF spreadsheet document,
+     * ClassCastException might be thrown.
+     * </p>
+     *
+     * @param inputStream - the InputStream of the ODF spreadsheet document.
+     * @return the spreadsheet document created from the given InputStream
+     * @throws java.lang.Exception - if the document could not be created.
+     */
+    public static SpreadsheetDocument loadDocument(InputStream inputStream) throws Exception {
+        SpreadsheetDocument document = (SpreadsheetDocument) Document.loadDocument(inputStream);
+        removeDummyCellsFromDocument(document);
+        return document;
+    }
+
+    /**
+     * Loads an SpreadsheetDocument from the provided path.
+     *
+     * <p>
+     * SpreadsheetDocument relies on the file being available for read access
+     * over the whole lifecycle of SpreadsheetDocument.
+     * </p>
+     *
+     * <p>
+     * If the resource stream is not a ODF spreadsheet document,
+     * ClassCastException might be thrown.
+     * </p>
+     *
+     * @param documentPath - the path from where the document can be loaded
+     * @return the spreadsheet document from the given path or NULL if the media
+     * type is not supported by SIMPLE.
+     * @throws java.lang.Exception - if the document could not be created.
+     */
+    public static SpreadsheetDocument loadDocument(String documentPath) throws Exception {
+        SpreadsheetDocument document = (SpreadsheetDocument) Document.loadDocument(documentPath);
+        removeDummyCellsFromDocument(document);
+        return document;
+    }
+
+    /**
+     * Creates an SpreadsheetDocument from the OpenDocument provided by a File.
+     *
+     * <p>
+     * SpreadsheetDocument relies on the file being available for read access
+     * over the whole lifecycle of SpreadsheetDocument.
+     * </p>
+     *
+     * <p>
+     * If the resource stream is not a ODF spreadsheet document,
+     * ClassCastException might be thrown.
+     * </p>
+     *
+     * @param file - a file representing the ODF spreadsheet document.
+     * @return the spreadsheet document created from the given File
+     * @throws java.lang.Exception - if the document could not be created.
+     */
+    public static SpreadsheetDocument loadDocument(File file) throws Exception {
+        SpreadsheetDocument document = (SpreadsheetDocument) Document.loadDocument(file);
+        removeDummyCellsFromDocument(document);
+        return document;
+    }
+
+    /**
+     * Get the content root of a spreadsheet document.
+     *
+     * @return content root, representing the office:spreadsheet tag
+     * @throws Exception if the file DOM could not be created.
+     */
+    @Override
+    public OfficeSpreadsheetElement getContentRoot() throws Exception {
+        return super.getContentRoot(OfficeSpreadsheetElement.class);
+    }
+
+    /**
+     * Changes the document to the given mediatype. This method can only be used
+     * to convert a document to a related mediatype, e.g. template.
+     *
+     * @param mediaType the related ODF mimetype
+     */
+    public void changeMode(OdfMediaType mediaType) {
+        setOdfMediaType(mediaType.mMediaType);
+    }
+
+    /**
+     * Retrieves sheet by index.
+     *
+     * @param index the index of the retrieved sheet, which starts from 0. If
+     * the index value is out of range (index >= sheet count or index < 0), this
+     * method would return <code>null</code>. @since 0.6
+     */
+    public Table getSheetByIndex(int index) {
+        if (index < 0) {
+            return null;
+        }
+        int count = 0;
+        try {
+            OfficeSpreadsheetElement spreadsheetElement = getContentRoot();
+            Node child = spreadsheetElement.getFirstChild();
+            while ((child != null) && (count <= index)) {
+                if (child instanceof TableTableElement) {
+                    if (count == index) {
+                        return getTableBuilder().getTableInstance((TableTableElement) child);
+                    } else {
+                        count++;
+                    }
+                }
+                child = child.getNextSibling();
+            }
+        } catch (Exception e) {
+            Logger.getLogger(SpreadsheetDocument.class.getName()).log(Level.SEVERE, null, e);
+        }
+        return null;
+    }
+
+    /**
+     * Retrieves sheet by name.
+     *
+     * @param name the name of the retrieved sheet.
+     * @since 0.6
+     */
+    public Table getSheetByName(String name) {
+        return getTableByName(name);
+    }
+
+    /**
+     * Adds a new blank sheet with the specified <code>name</code> to this
+     * document.
+     *
+     * @param name the name of the new sheet.
+     * @return added sheet.
+     * @since 0.6
+     */
+    public Table appendSheet(String name) {
+        Table newTable = addTable();
+        newTable.setTableName(name);
+        return newTable;
+    }
+
+    /**
+     * Adds a new sheet with data from existing table.
+     * <p>
+     * NOTE: This method copies data from existing table, including linked
+     * resources and styles, if the source table is not in the target document.
+     * If these data has dependencies to other data of the source document, the
+     * data dependencies will not be copied. For example, document A has two
+     * sheets, "Sheet1" and "Sheet2". In "Sheet2", there is a cell with formula,
+     * "=sum(Sheet1.A1:Sheet1.A10)". After copy the data of "Sheet2" to the new
+     * sheet in document B, the result of this formula would be different or
+     * even invalid in document B.
+     *
+     * @param refTable the reference table, which is the data source of the new
+     * sheet.
+     * @param name the name of the new sheet.
+     * @return added sheet.
+     * @since 0.6
+     */
+    public Table appendSheet(Table refTable, String name) {
+        TableTableElement refTableElement = refTable.getOdfElement();
+        try {
+            OdfContentDom contentDom = getContentDom();
+            TableTableElement newTableEle = (TableTableElement) (refTableElement.cloneNode(true));
+            // not in a same document
+            if (refTableElement.getOwnerDocument() != contentDom) {
+                Document ownerDocument = refTable.getOwnerDocument();
+                copyLinkedRefInBatch(newTableEle, ownerDocument);
+                copyForeignStyleRef(newTableEle, ownerDocument);
+                newTableEle = (TableTableElement) cloneForeignElement(newTableEle, contentDom, true);
+            }
+            updateNames(newTableEle);
+            updateXMLIds(newTableEle);
+            getTableContainerElement().appendChild(newTableEle);
+            Table tableInstance = getTableBuilder().getTableInstance(newTableEle);
+            tableInstance.setTableName(name);
+            return tableInstance;
+        } catch (Exception e) {
+            Logger.getLogger(SpreadsheetDocument.class.getName()).log(Level.SEVERE, null, e);
+        }
+        return null;
+    }
+
+    /**
+     * Inserts a new blank sheet before the reference index.
+     *
+     * @param before the reference index, which starts from 0. If the index
+     * value is out of range (index >= sheet count or index < 0), this method
+     * would return <code>null</code>. @return inserted sheet. @since 0.6
+     */
+    public Table insertSheet(int before) {
+        if (before < 0) {
+            return null;
+        }
+        int count = 0;
+        try {
+            OfficeSpreadsheetElement spreadsheetElement = getContentRoot();
+            Node child = spreadsheetElement.getFirstChild();
+            while ((child != null) && (count <= before)) {
+                if (child instanceof TableTableElement) {
+                    if (count == before) {
+                        Table table = getTableBuilder().newTable();
+                        getContentRoot().insertBefore(table.getOdfElement(), child);
+                        return table;
+                    } else {
+                        count++;
+                    }
+                }
+                child = child.getNextSibling();
+            }
+        } catch (Exception e) {
+            Logger.getLogger(SpreadsheetDocument.class.getName()).log(Level.SEVERE, null, e);
+        }
+        return null;
+    }
+
+    /**
+     * Inserts a new sheet with data from existing table.
+     *
+     * <p>
+     * NOTE: This method copies data from existing table, including linked
+     * resources and styles, if the source table is not in the target document.
+     * If these data has dependencies to other data of the source document, the
+     * data dependencies will not be copied. For example, document A has two
+     * sheets, "Sheet1" and "Sheet2". In "Sheet2", there is a cell with formula,
+     * "=sum(Sheet1.A1:Sheet1.A10)". After copy the data of "Sheet2" to the new
+     * sheet in document B, the result of this formula would be different or
+     * even invalid in document B.
+     *
+     * @param refTable the reference table, which is the data source of the new
+     * sheet.
+     * @param before the reference index, which starts from 0 and new sheet
+     * would be inserted before it. If the index value is out of range (index >=
+     * sheet count or index < 0), this method would return <code>null</code>.
+     * @return inserted sheet.
+     * @since 0.6
+     */
+    public Table insertSheet(Table refTable, int before) {
+        if (before < 0) {
+            return null;
+        }
+        int count = 0;
+        try {
+            OfficeSpreadsheetElement spreadsheetElement = getContentRoot();
+            Node child = spreadsheetElement.getFirstChild();
+            while ((child != null) && (count <= before)) {
+                if (child instanceof TableTableElement) {
+                    if (count == before) {
+                        TableTableElement refTableElement = refTable.getOdfElement();
+                        try {
+                            OdfContentDom contentDom = getContentDom();
+                            TableTableElement newTableEle = (TableTableElement) (refTableElement.cloneNode(true));
+                            //foreign node not in a same document
+                            if (refTableElement.getOwnerDocument() != contentDom) {
+                                Document ownerDocument = refTable.getOwnerDocument();
+                                copyLinkedRefInBatch(newTableEle, ownerDocument);
+                                copyForeignStyleRef(newTableEle, ownerDocument);
+                                newTableEle = (TableTableElement) cloneForeignElement(newTableEle, contentDom, true);
+                            }
+                            updateNames(newTableEle);
+                            updateXMLIds(newTableEle);
+                            newTableEle.setTableNameAttribute(getUniqueSheetName(this));
+                            getContentRoot().insertBefore(newTableEle, child);
+                            return getTableBuilder().getTableInstance(newTableEle);
+                        } catch (Exception e) {
+                            Logger.getLogger(SpreadsheetDocument.class.getName()).log(Level.SEVERE, null, e);
+                        }
+                    } else {
+                        count++;
+                    }
+                }
+                child = child.getNextSibling();
+            }
+        } catch (Exception e) {
+            Logger.getLogger(SpreadsheetDocument.class.getName()).log(Level.SEVERE, null, e);
+        }
+        return null;
+    }
+
+    /**
+     * Removes the sheet in the specified <code>index</code>.
+     *
+     * @param index the index of the removed sheet, which starts from 0. If the
+     * index value is out of range (index >= sheet count or index < 0), this
+     * method would do nothing. @since 0.6
+     */
+    public void removeSheet(int index) {
+        if (index < 0) {
+            return;
+        }
+        int count = 0;
+        try {
+            OfficeSpreadsheetElement spreadsheetElement = getContentRoot();
+            Node child = spreadsheetElement.getFirstChild();
+            while ((child != null) && (count <= index)) {
+                if (child instanceof TableTableElement) {
+                    if (count == index) {
+                        spreadsheetElement.removeChild(child);
+                        return;
+                    } else {
+                        count++;
+                    }
+                }
+                child = child.getNextSibling();
+            }
+        } catch (Exception e) {
+            Logger.getLogger(SpreadsheetDocument.class.getName()).log(Level.SEVERE, null, e);
+        }
+    }
+
+    /**
+     * Returns the sheet count of this document.
+     *
+     * @return the sheet count of this document.
+     * @since 0.6
+     */
+    public int getSheetCount() {
+        int count = 0;
+        try {
+            OfficeSpreadsheetElement spreadsheetElement = getContentRoot();
+            Node child = spreadsheetElement.getFirstChild();
+            while (child != null) {
+                if (child instanceof TableTableElement) {
+                    count++;
+                }
+                child = child.getNextSibling();
+            }
+        } catch (Exception e) {
+            Logger.getLogger(SpreadsheetDocument.class.getName()).log(Level.SEVERE, null, e);
+        }
+        return count;
+    }
+
+    public OdfElement getTableContainerElement() {
+        return getTableContainerImpl().getTableContainerElement();
+    }
+
+    /**
+     * Creates a new Chart for this spreadsheet document.
+     *
+     * @param title chart title.
+     * @param dataset chart data set.
+     * @param rect chart rectangle.
+     * @return the created chart.
+     *
+     * @since 0.6
+     */
+    public Chart createChart(String title, DataSet dataset, Rectangle rect) {
+        return getChartContainerImpl().createChart(title, dataset, rect);
+    }
+
+    /**
+     * Creates a new Chart for this spreadsheet document.
+     *
+     * @param title chart title.
+     * @param document the data source spreadsheet document.
+     * @param cellRangeAddr the cell range address list which is used as chart
+     * data set.
+     * @param firstRowAsLabel whether uses first row as label.
+     * @param firstColumnAsLabel whether uses first column as label.
+     * @param rowAsDataSeries whether uses data as series.
+     * @param rect chart rectangle.
+     * @return the created chart.
+     *
+     * @since 0.6
+     */
+    public Chart createChart(String title, SpreadsheetDocument document, CellRangeAddressList cellRangeAddr, boolean firstRowAsLabel,
+        boolean firstColumnAsLabel, boolean rowAsDataSeries, Rectangle rect) {
+        return getChartContainerImpl().createChart(title, document, cellRangeAddr, firstRowAsLabel, firstColumnAsLabel,
+            rowAsDataSeries, rect);
+    }
+
+    /**
+     * Creates a new Chart for this spreadsheet document.
+     *
+     * @param title chart rectangle.
+     * @param labels label strings
+     * @param legends legend strings
+     * @param data chart data set.
+     * @param rect chart rectangle.
+     * @return the created chart.
+     *
+     * @since 0.6
+     */
+    public Chart createChart(String title, String[] labels, String[] legends, double[][] data, Rectangle rect) {
+        return getChartContainerImpl().createChart(title, labels, legends, data, rect);
+    }
+
+    /**
+     * Creates a new Chart for this spreadsheet document.
+     *
+     * @param title chart rectangle.
+     * @param document the data source spreadsheet document.
+     * @param cellRangeAddr the cell range list to be used as chart data.
+     * @param firstRowAsLabel whether use first row as label.
+     * @param firstColumnAsLabel whether use first column as label.
+     * @param rowAsDataSeries whether use row as data series.
+     * @param rect chart rectangle.
+     * @param cell the position cell where the new chart is inserted.
+     * @return the created chart.
+     *
+     * @since 0.6
+     */
+    public Chart createChart(String title, SpreadsheetDocument document, CellRangeAddressList cellRangeAddr, boolean firstRowAsLabel,
+        boolean firstColumnAsLabel, boolean rowAsDataSeries, Rectangle rect, Cell cell) {
+        return getChartContainerImpl().createChart(title, document, cellRangeAddr, firstRowAsLabel, firstColumnAsLabel,
+            rowAsDataSeries, rect, cell);
+    }
+
+    public void deleteChartById(String chartId) {
+        getChartContainerImpl().deleteChartById(chartId);
+    }
+
+    public void deleteChartByTitle(String title) {
+        getChartContainerImpl().deleteChartByTitle(title);
+    }
+
+    public Chart getChartById(String chartId) {
+        return getChartContainerImpl().getChartById(chartId);
+    }
+
+    public List<Chart> getChartByTitle(String title) {
+        return getChartContainerImpl().getChartByTitle(title);
+    }
+
+    public int getChartCount() {
+        return getChartContainerImpl().getChartCount();
+    }
+
+    private static String getUniqueSheetName(TableContainer container) {
+        List<Table> tableList = container.getTableList();
+        boolean notUnique = true;
+        String tablename = "Sheet" + (tableList.size() + 1);
+        while (notUnique) {
+            notUnique = false;
+            for (int i = 0; i < tableList.size(); i++) {
+                if (tableList.get(i).getTableName() != null) {
+                    if (tableList.get(i).getTableName().equalsIgnoreCase(tablename)) {
+                        notUnique = true;
+                        break;
+                    }
+                }
+            }
+            if (notUnique) {
+                tablename = tablename + Math.round(Math.random() * 10);
+            }
+        }
+        return tablename;
+    }
+
+    private ChartContainerImpl getChartContainerImpl() {
+        if (chartContainerImpl == null) {
+            chartContainerImpl = new ChartContainerImpl(this);
+        }
+        return chartContainerImpl;
+    }
+
+    private class ChartContainerImpl extends AbstractChartContainer {
+
+        SpreadsheetDocument sdoc;
+        DrawFrameElement drawFrame;
+
+        protected ChartContainerImpl(Document doc) {
+            super(doc);
+            sdoc = (SpreadsheetDocument) doc;
+        }
+
+        protected DrawFrameElement getChartFrame() throws Exception {
+            OdfContentDom contentDom2 = sdoc.getContentDom();
+            DrawFrameElement drawFrame = contentDom2.newOdfElement(DrawFrameElement.class);
+            TableTableCellElement lastCell = (TableTableCellElement) contentDom2.getXPath().evaluate(
+                "//table:table-cell[last()]", contentDom2, XPathConstants.NODE);
+            lastCell.appendChild(drawFrame);
+            drawFrame.removeAttribute("text:anchor-type");
+            this.drawFrame = drawFrame;
+            return drawFrame;
+        }
+
+        private Chart createChart(String title, SpreadsheetDocument document, CellRangeAddressList cellRangeAddr, boolean firstRowAsLabel,
+            boolean firstColumnAsLabel, boolean rowAsDataSeries, Rectangle rect, Cell cell) {
+            Chart chart = getChartContainerImpl().createChart(title, document, cellRangeAddr, firstRowAsLabel, firstColumnAsLabel,
+                rowAsDataSeries, rect);
+            cell.getOdfElement().appendChild(this.drawFrame);
+            return chart;
+        }
+    }
+
+    /**
+     * @see RepeatedNumberUtils#removeDummyCellsFromTable(Table)
+     */
+    private static void removeDummyCellsFromDocument(SpreadsheetDocument document) {
+        int sheetCount = document.getSheetCount();
+        for (int n = 0; n < sheetCount; n++) {
+            RepeatedNumberUtils.removeDummyCellsFromTable(document.getSheetByIndex(n));
+        }
+    }
+}
diff --git a/simple/src/main/java/org/odftoolkit/simple/table/RepeatedNumberUtils.java b/simple/src/main/java/org/odftoolkit/simple/table/RepeatedNumberUtils.java
new file mode 100644
index 0000000..4f6ea2d
--- /dev/null
+++ b/simple/src/main/java/org/odftoolkit/simple/table/RepeatedNumberUtils.java
@@ -0,0 +1,248 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.	The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.	See the License for the
+specific language governing permissions and limitations
+under the License.
+ */
+package org.odftoolkit.simple.table;
+
+import org.odftoolkit.odfdom.dom.element.table.TableTableCellElement;
+import org.odftoolkit.odfdom.dom.element.table.TableTableColumnElement;
+import org.odftoolkit.odfdom.dom.element.table.TableTableColumnsElement;
+import org.odftoolkit.odfdom.dom.element.table.TableTableHeaderColumnsElement;
+import org.odftoolkit.odfdom.dom.element.table.TableTableHeaderRowsElement;
+import org.odftoolkit.odfdom.dom.element.table.TableTableRowElement;
+import org.odftoolkit.odfdom.dom.element.table.TableTableRowsElement;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Node;
+
+/**
+ * Utility functions to evaluate the "repeated-number"-Attributes of rows,
+ * columns and cells.
+ *
+ * @author raimund
+ */
+public class RepeatedNumberUtils {
+
+    private static final int LIBRE_OFFICE_WORKAROUND_COLCOUNT = 1024;
+    private static final int LIBRE_OFFICE_WORKAROUND_ROWCOUNT = 1048576;
+    private static final int MS_EXCEL_BINARY_WORKAROUND_ROWCOUNT = 32768;
+
+    /**
+     * Remove unused columns and rows from the end of a table.
+     * <p>
+     * This is a workaround for bug ODFTOOLKIT-388. LibreOffice adds two dummy
+     * rows with "number-rows-repeated" attribute to "blow up" the sheet to
+     * {@value #LIBRE_OFFICE_WORKAROUND_ROWCOUNT} rows as needed by MS Excel
+     * 2010.
+     * <p>
+     * Files converted from MS Excel binary format (*.xls) contain a similar
+     * dummy row to "blow up" the sheet up to
+     * {@value #MS_EXCEL_BINARY_WORKAROUND_ROWCOUNT} rows.
+     * <p>
+     * Same is done for columns - one dummy column is added to get a whole
+     * column count of {@value #LIBRE_OFFICE_WORKAROUND_COLCOUNT}.
+     *
+     * @param table Table to clean.
+     */
+    public static void removeDummyCellsFromTable(Table table) {
+        // First analyze columns and rows; e. g. count them
+        int wholeColumnCount = 0;
+        int wholeRowCount = 0;
+        int maxCellCount = 0;
+        TableTableColumnElement lastColumnNode = null;
+        TableTableRowElement msExcelDummyRow = null;
+        for (Node node : new DomNodeList(table.getOdfElement().getChildNodes())) {
+            // TODO: how about <table:table-column-group>
+            if (node instanceof TableTableHeaderColumnsElement) {
+                wholeColumnCount += _getHeaderColumnCount((TableTableHeaderColumnsElement) node);
+                lastColumnNode = null;
+
+            } else if (node instanceof TableTableColumnsElement) {
+                wholeColumnCount += _getColumnsCount((TableTableColumnsElement) node);
+                lastColumnNode = null;
+
+            } else if (node instanceof TableTableColumnElement) {
+                wholeColumnCount += _getNumberColumnsRepeated((TableTableColumnElement) node);
+                lastColumnNode = (TableTableColumnElement) node;
+            }
+
+            if (node instanceof TableTableHeaderRowsElement) {
+                wholeRowCount += _getHeaderRowCount((TableTableHeaderRowsElement) node);
+                int n = _getCellCountOfRowWithoutDummies(node);
+                maxCellCount = n > maxCellCount ? n : maxCellCount;
+
+            } else if (node instanceof TableTableRowElement) {
+                wholeRowCount += _getNumberRowsRepeated((TableTableRowElement) node);
+                if (wholeRowCount == MS_EXCEL_BINARY_WORKAROUND_ROWCOUNT) {
+                    msExcelDummyRow = (TableTableRowElement) node;
+                }
+                int n = _getCellCountOfRowWithoutDummies(node);
+                maxCellCount = n > maxCellCount ? n : maxCellCount;
+
+            } else if (node instanceof TableTableRowsElement) {
+                for (Node nodeChild : new DomNodeList(node.getChildNodes())) {
+                    if (nodeChild instanceof TableTableRowElement) {
+                        wholeRowCount += _getNumberRowsRepeated((TableTableRowElement) nodeChild);
+                        int n = _getCellCountOfRowWithoutDummies(node);
+                        maxCellCount = n > maxCellCount ? n : maxCellCount;
+                    }
+                }
+            }
+        }
+
+        // Removing the dummy rows at end if needed
+        if (wholeRowCount == LIBRE_OFFICE_WORKAROUND_ROWCOUNT) {
+            boolean done = false;
+            for (int nodeIndex = table.getOdfElement().getChildNodes().getLength() - 1; !done && nodeIndex > 0; nodeIndex--) {
+                Node node = table.getOdfElement().getChildNodes().item(nodeIndex);
+                if (node instanceof TableTableHeaderRowsElement || node instanceof TableTableRowsElement) {
+                    done = true;
+
+                } else if (node instanceof TableTableRowElement) {
+                    if (_isEmptyDummyRow((TableTableRowElement) node)) {
+                        table.getOdfElement().removeChild(node);
+                    } else {
+                        done = true;
+                    }
+                }
+            }
+        }
+
+        // Workaround for files converted from MS Excel
+        if (msExcelDummyRow != null && msExcelDummyRow == table.getOdfElement().getLastChild()) {
+            try {
+                table.getOdfElement().removeChild(msExcelDummyRow);
+            } catch (DOMException e) {
+                // Row may be already removed by code above - just ignore that
+            }
+        }
+
+        // Removing the dummy columns at end if needed.
+        // Warning, we must retain at least one column for each cell,
+        // so it may be needed to just reduce the number-columns-repeated
+        // instead of deleting the cell.
+        if (wholeColumnCount == LIBRE_OFFICE_WORKAROUND_COLCOUNT && lastColumnNode != null) {
+            int n = _getNumberColumnsRepeated(lastColumnNode);
+            if (n > 1) {
+                int realColumnCount = wholeColumnCount - n;
+                if (realColumnCount < maxCellCount) {
+                    lastColumnNode.setTableNumberColumnsRepeatedAttribute(maxCellCount - realColumnCount);
+                } else {
+                    table.getOdfElement().removeChild(lastColumnNode);
+                }
+            }
+        }
+    }
+
+    private static int _getCellCountOfRowWithoutDummies(Node row) {
+        int cellCount = 0;
+        Node lastCell = row.getLastChild();
+        for (Node node : new DomNodeList(row.getChildNodes())) {
+            if (node instanceof TableTableCellElement) {
+                TableTableCellElement cell = (TableTableCellElement) node;
+
+                Integer repCnt = cell.getTableNumberColumnsRepeatedAttribute();
+                if (repCnt == null) {
+                    repCnt = 1;
+                }
+                Integer spanned = cell.getTableNumberColumnsSpannedAttribute();
+                if (spanned == null || spanned == 0) {
+                    spanned = 1;
+                }
+
+                if (node != lastCell || repCnt == 1 || spanned != 1) {
+                    cellCount += repCnt * spanned;
+                }
+            }
+        }
+        return cellCount;
+    }
+
+    private static int _getNumberRowsRepeated(TableTableRowElement rowElement) {
+        int numberRowsRepeated = 0;
+
+        if (rowElement != null) {
+            Integer repCnt = rowElement.getTableNumberRowsRepeatedAttribute();
+            if (repCnt == null) {
+                numberRowsRepeated = 1;
+            } else {
+                numberRowsRepeated = repCnt;
+            }
+        }
+
+        return numberRowsRepeated;
+    }
+
+    static int _getNumberColumnsRepeated(TableTableColumnElement columnElement) {
+        int numberColumnsRepeated = 0;
+
+        if (columnElement != null) {
+            Integer repCnt = columnElement.getTableNumberColumnsRepeatedAttribute();
+            if (repCnt == null) {
+                numberColumnsRepeated = 1;
+            } else {
+                numberColumnsRepeated = repCnt;
+            }
+        }
+
+        return numberColumnsRepeated;
+    }
+
+    private static int _getHeaderColumnCount(TableTableHeaderColumnsElement headers) {
+        int result = 0;
+        if (headers != null) {
+            for (Node n : new DomNodeList(headers.getChildNodes())) {
+                result += _getNumberColumnsRepeated((TableTableColumnElement) n);
+            }
+        }
+        return result;
+    }
+
+    private static int _getColumnsCount(TableTableColumnsElement columns) {
+        int result = 0;
+        if (columns != null) {
+            for (Node n : new DomNodeList(columns.getChildNodes())) {
+                result += _getNumberColumnsRepeated((TableTableColumnElement) n);
+            }
+        }
+        return result;
+    }
+
+    private static int _getHeaderRowCount(TableTableHeaderRowsElement headers) {
+        int result = 0;
+        if (headers != null) {
+            for (Node n : new DomNodeList(headers.getChildNodes())) {
+                if (n instanceof TableTableRowElement) {
+                    result += _getNumberRowsRepeated((TableTableRowElement) n);
+                }
+            }
+        }
+        return result;
+    }
+
+    private static boolean _isEmptyDummyRow(TableTableRowElement row) {
+        boolean dummyRow = true;
+        for (Node child = row.getChildNodes().item(0); dummyRow && child != null; child = child.getNextSibling()) {
+            if (child instanceof TableTableCellElement) {
+                dummyRow = child.getChildNodes().getLength() == 0;
+            } else {
+                dummyRow = false;
+            }
+        }
+
+        return dummyRow;
+    }
+}
diff --git a/simple/src/test/java/org/odftoolkit/simple/SpreadsheetDocumentTest.java b/simple/src/test/java/org/odftoolkit/simple/SpreadsheetDocumentTest.java
index 6f7a244..5f460a1 100644
--- a/simple/src/test/java/org/odftoolkit/simple/SpreadsheetDocumentTest.java
+++ b/simple/src/test/java/org/odftoolkit/simple/SpreadsheetDocumentTest.java
@@ -1,259 +1,284 @@
-/* 
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-package org.odftoolkit.simple;
-
-import java.awt.Rectangle;
-import java.io.File;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import junit.framework.Assert;
-
-import org.junit.Test;
-import org.odftoolkit.simple.Document.OdfMediaType;
-import org.odftoolkit.simple.chart.Chart;
-import org.odftoolkit.simple.chart.ChartType;
-import org.odftoolkit.simple.chart.DataSet;
-import org.odftoolkit.simple.table.Column;
-import org.odftoolkit.simple.table.Table;
-import org.odftoolkit.simple.utils.ResourceUtilities;
-
-public class SpreadsheetDocumentTest {
-	private static final Logger LOG = Logger.getLogger(SpreadsheetDocumentTest.class.getName());
-	private static final String TEST_FILE = "spreadsheetTestTemplate.ots";
-	
-	@Test
-	public void testGetMediaTypeString() throws Exception{
-		
-		try {
-			String spreadDocPath = ResourceUtilities.getAbsolutePath(TEST_FILE);
-			SpreadsheetDocument spreadDoc = SpreadsheetDocument.loadDocument(spreadDocPath);
-			Assert.assertNotNull(spreadDoc);
-			OdfMediaType odfMediaType = spreadDoc.getOdfMediaType();
-			Assert.assertEquals(Document.OdfMediaType.SPREADSHEET_TEMPLATE, odfMediaType);
-		} catch (Exception e) {
-			LOG.log(Level.SEVERE, e.getMessage(), e);
-			Assert.fail(e.getMessage());
-		}
-		
-	}
-	
-	@Test
-	public void testGetSuffix() throws Exception{
-		try {
-			String spreadDocPath = ResourceUtilities.getAbsolutePath(TEST_FILE);
-			SpreadsheetDocument spreadDoc = SpreadsheetDocument.loadDocument(spreadDocPath);
-			Assert.assertNotNull(spreadDoc);
-			OdfMediaType odfMediaType = spreadDoc.getOdfMediaType();
-			String suffix = odfMediaType.getSuffix();
-			Assert.assertEquals("ots", suffix);
-		} catch (Exception e) {
-			LOG.log(Level.SEVERE, e.getMessage(), e);
-			Assert.fail(e.getMessage());
-		}
-	}
-	
-	@Test
-	public void testGetOdfMediaType() throws Exception{
-		
-		try {
-			String spreadDocPath = ResourceUtilities.getAbsolutePath(TEST_FILE);
-			SpreadsheetDocument spreadDoc = SpreadsheetDocument.loadDocument(spreadDocPath);
-			Assert.assertNotNull(spreadDoc);
-			Document.OdfMediaType odfMediaType = SpreadsheetDocument.OdfMediaType.getOdfMediaType(spreadDoc.getMediaTypeString());
-			Assert.assertEquals("ots", odfMediaType.getSuffix());
-		} catch (Exception e) {
-			LOG.log(Level.SEVERE, e.getMessage(), e);
-			Assert.fail(e.getMessage());
-		}
-	}
-	
-	@Test
-	public void testLoadDocument() throws Exception{
-		try {
-			String filePath = ResourceUtilities.getAbsolutePath(TEST_FILE);
-			SpreadsheetDocument spreadDoc = SpreadsheetDocument.loadDocument(filePath);
-			Assert.assertNotNull(spreadDoc);
-			Assert.assertEquals(Document.OdfMediaType.SPREADSHEET_TEMPLATE, spreadDoc.getOdfMediaType());
-		} catch (Exception e) {
-			LOG.log(Level.SEVERE, e.getMessage(), e);
-			Assert.fail(e.getMessage());
-		}
-	}
-	
-	@Test
-	public void testLoadDocumentFile() throws Exception{
-		
-		try {
-			String filePath = ResourceUtilities.getAbsolutePath(TEST_FILE);
-			File fileDoc = new File(filePath);
-			SpreadsheetDocument spreadDoc = SpreadsheetDocument.loadDocument(fileDoc);;
-			Assert.assertNotNull(spreadDoc);
-			Assert.assertEquals(Document.OdfMediaType.SPREADSHEET_TEMPLATE, spreadDoc.getOdfMediaType());
-		} catch (Exception e) {
-			LOG.log(Level.SEVERE, e.getMessage(), e);
-			Assert.fail(e.getMessage());
-		}
-		
-	}
-	
-	@Test
-	public void testCreateChart() throws Exception{
-		try {
-			SpreadsheetDocument spDocument = SpreadsheetDocument.loadDocument(ResourceUtilities.getAbsolutePath(TEST_FILE));
-			String title = "XXXTitle";
-			String[] lables = new String[]{"spring","summer","autumn","autumn"};
-			String[] legends = new String[]{"hello1","hello2","hello3"};
-			double[][] data = new double[][]{{1.2,2.22,3},{2,3,4},{3,4,5},{4,5,6}};
-			DataSet dataset = new DataSet(lables, legends, data);
-			Rectangle rect = new Rectangle();
-			rect.x = 367;
-			rect.y = 389;
-			rect.width = 379;
-			rect.height = 424;
-			Chart spChart = spDocument.createChart(title, dataset, rect);
-			Assert.assertNotNull(spChart);
-			spChart.setChartType(ChartType.AREA);
-			//save
-			spDocument.save(ResourceUtilities.getTestOutput("Chart_"+TEST_FILE));
-			
-			Assert.assertEquals(dataset, spChart.getChartData());
-			Assert.assertEquals("XXXTitle", spChart.getChartTitle());
-			Assert.assertEquals(ChartType.AREA, spChart.getChartType());
-			
-			LOG.log(Level.INFO,"spChart--> " + spChart);
-			
-		} catch (Exception e) {
-			LOG.log(Level.SEVERE, e.getMessage(), e);
-			Assert.fail(e.getMessage());
-		}
-	}
-	
-	@Test
-	public void testGetSheetByIndex() throws Exception{
-		File file = new File(ResourceUtilities.getAbsolutePath("TestSpreadsheetTable.ods"));
-		SpreadsheetDocument spDocument = SpreadsheetDocument.loadDocument(file);
-		//index < 0 , Not expected, table ==null
-		Table tablenull = spDocument.getSheetByIndex(-1);
-		Assert.assertTrue((tablenull == null));
-		//index > 0 
-		//index = 0
-		Table tableSheet0 = spDocument.getSheetByIndex(0);
-		Assert.assertTrue((tableSheet0 != null));
-		Assert.assertEquals("Sheet1", tableSheet0.getTableName());
-		Assert.assertEquals(29, tableSheet0.getColumnCount());
-		//index = 1
-		Table tableSheet1 = spDocument.getSheetByIndex(1);
-		Assert.assertTrue((tableSheet1 != null));
-		Assert.assertEquals("Sheet2", tableSheet1.getTableName());
-		Assert.assertEquals(1, tableSheet1.getColumnCount());
-	}
-	
-	@Test
-	public void testInsertSheet() throws Exception{
-		File file = new File(ResourceUtilities.getAbsolutePath(TEST_FILE));
-		SpreadsheetDocument spDocument = SpreadsheetDocument.loadDocument(file);
-		//index <0 , Not expected
-		Table table = spDocument.insertSheet(-1);
-		Assert.assertNull(table);
-		//index >= sheet count
-		Table tableb = spDocument.insertSheet(11);
-		Assert.assertNull(tableb);
-		
-		//index is within the law
-		Table tab = spDocument.getSheetByName("tabellDemo2");
-		if(tab != null){
-			for(int i=0;i<spDocument.getSheetCount();i++){
-				if(tab.equals(spDocument.getSheetByIndex(i)))
-					spDocument.removeSheet(i);
-			}
-		}
-		Table tablea = spDocument.insertSheet(0);
-		Column col = tablea.appendColumn();
-		col.setWidth(12.99);
-		Column col2 = tablea.appendColumn();
-		col.setWidth(12.);
-		tablea.setTableName("tabellDemo2");
-		Assert.assertEquals("tabellDemo2", tablea.getTableName());
-		spDocument.save(ResourceUtilities.getAbsolutePath(TEST_FILE));
-		
-	}
-	
-	@Test
-	public void testRemoveSheet() throws Exception{
-		File file = new File(ResourceUtilities.getAbsolutePath(TEST_FILE));
-		SpreadsheetDocument spDocument = SpreadsheetDocument.loadDocument(file);
-		//index <0 , Not expected
-		Table table = spDocument.insertSheet(-1);
-		Assert.assertNull(table);
-		//index >= sheet count
-		Table tableb = spDocument.insertSheet(11);
-		Assert.assertNull(tableb);
-		
-		//index is within the law
-		Table tab = spDocument.getSheetByName("tabellDemo2");
-		if(tab != null){
-			for(int i=0;i<spDocument.getSheetCount();i++){
-				if(tab.equals(spDocument.getSheetByIndex(i)))
-					spDocument.removeSheet(i);
-			}
-		}
-		Table tablea = spDocument.insertSheet(0);
-		Column col = tablea.appendColumn();
-		col.setWidth(12.99);
-		Column col2 = tablea.appendColumn();
-		col.setWidth(12.);
-		tablea.setTableName("tabellDemo2");
-		Assert.assertEquals("tabellDemo2", tablea.getTableName());
-		spDocument.removeSheet(0);
-		Table tablem = spDocument.getSheetByIndex(0);
-		Assert.assertNotSame(tablea, tablem);
-		
-		spDocument.save(ResourceUtilities.getAbsolutePath(TEST_FILE));
-	}
-	
-	@Test
-	public void testGetSheetByIndex2() throws Exception{
-		File file = new File(ResourceUtilities.getAbsolutePath(TEST_FILE));
-		SpreadsheetDocument spDocument = SpreadsheetDocument.loadDocument(file);
-		//index <0 , Not expected
-		Table table = spDocument.insertSheet(-1);
-		Assert.assertNull(table);
-		//index >= sheet count
-		Table tableb = spDocument.insertSheet(11);
-		Assert.assertNull(tableb);
-		
-		//index is within the law
-		Table tab = spDocument.getSheetByName("tabellDemo1");
-		if(tab != null)
-			tab.remove();
-		
-		Table taba = spDocument.getSheetByName("Tabelle1");
-		Table tablea = spDocument.insertSheet(taba,0);
-		tablea.setTableName("tabellDemo1");
-		Assert.assertEquals("tabellDemo1", tablea.getTableName());
-		Table tablem = spDocument.getSheetByIndex(0);
-		Assert.assertEquals(tablea, tablem);
-		
-		spDocument.save(ResourceUtilities.getAbsolutePath(TEST_FILE));
-		
-	}
-	
-}
+/* 
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package org.odftoolkit.simple;
+
+import java.awt.Rectangle;
+import java.io.File;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+import org.odftoolkit.simple.Document.OdfMediaType;
+import org.odftoolkit.simple.chart.Chart;
+import org.odftoolkit.simple.chart.ChartType;
+import org.odftoolkit.simple.chart.DataSet;
+import org.odftoolkit.simple.table.Column;
+import org.odftoolkit.simple.table.Table;
+import org.odftoolkit.simple.utils.ResourceUtilities;
+
+public class SpreadsheetDocumentTest {
+	private static final Logger LOG = Logger.getLogger(SpreadsheetDocumentTest.class.getName());
+	private static final String TEST_FILE = "spreadsheetTestTemplate.ots";
+	
+	@Test
+	public void testGetMediaTypeString() throws Exception{
+		
+		try {
+			String spreadDocPath = ResourceUtilities.getAbsolutePath(TEST_FILE);
+			SpreadsheetDocument spreadDoc = SpreadsheetDocument.loadDocument(spreadDocPath);
+			Assert.assertNotNull(spreadDoc);
+			OdfMediaType odfMediaType = spreadDoc.getOdfMediaType();
+			Assert.assertEquals(Document.OdfMediaType.SPREADSHEET_TEMPLATE, odfMediaType);
+		} catch (Exception e) {
+			LOG.log(Level.SEVERE, e.getMessage(), e);
+			Assert.fail(e.getMessage());
+		}
+		
+	}
+	
+	@Test
+	public void testGetSuffix() throws Exception{
+		try {
+			String spreadDocPath = ResourceUtilities.getAbsolutePath(TEST_FILE);
+			SpreadsheetDocument spreadDoc = SpreadsheetDocument.loadDocument(spreadDocPath);
+			Assert.assertNotNull(spreadDoc);
+			OdfMediaType odfMediaType = spreadDoc.getOdfMediaType();
+			String suffix = odfMediaType.getSuffix();
+			Assert.assertEquals("ots", suffix);
+		} catch (Exception e) {
+			LOG.log(Level.SEVERE, e.getMessage(), e);
+			Assert.fail(e.getMessage());
+		}
+	}
+	
+	@Test
+	public void testGetOdfMediaType() throws Exception{
+		
+		try {
+			String spreadDocPath = ResourceUtilities.getAbsolutePath(TEST_FILE);
+			SpreadsheetDocument spreadDoc = SpreadsheetDocument.loadDocument(spreadDocPath);
+			Assert.assertNotNull(spreadDoc);
+			Document.OdfMediaType odfMediaType = SpreadsheetDocument.OdfMediaType.getOdfMediaType(spreadDoc.getMediaTypeString());
+			Assert.assertEquals("ots", odfMediaType.getSuffix());
+		} catch (Exception e) {
+			LOG.log(Level.SEVERE, e.getMessage(), e);
+			Assert.fail(e.getMessage());
+		}
+	}
+	
+	@Test
+	public void testLoadDocument() throws Exception{
+		try {
+			String filePath = ResourceUtilities.getAbsolutePath(TEST_FILE);
+			SpreadsheetDocument spreadDoc = SpreadsheetDocument.loadDocument(filePath);
+			Assert.assertNotNull(spreadDoc);
+			Assert.assertEquals(Document.OdfMediaType.SPREADSHEET_TEMPLATE, spreadDoc.getOdfMediaType());
+		} catch (Exception e) {
+			LOG.log(Level.SEVERE, e.getMessage(), e);
+			Assert.fail(e.getMessage());
+		}
+	}
+	
+	@Test
+	public void testLoadDocumentFile() throws Exception{
+		
+		try {
+			String filePath = ResourceUtilities.getAbsolutePath(TEST_FILE);
+			File fileDoc = new File(filePath);
+			SpreadsheetDocument spreadDoc = SpreadsheetDocument.loadDocument(fileDoc);;
+			Assert.assertNotNull(spreadDoc);
+			Assert.assertEquals(Document.OdfMediaType.SPREADSHEET_TEMPLATE, spreadDoc.getOdfMediaType());
+		} catch (Exception e) {
+			LOG.log(Level.SEVERE, e.getMessage(), e);
+			Assert.fail(e.getMessage());
+		}
+		
+	}
+
+	@Test
+	public void testLoadDocumentFileWithExcelDummyRows0() {
+		testLoadDocumentFileWithExcelDummyRows("ExcelDummyRowProblem_rows0.ods", 0);
+	}
+
+	@Test
+	public void testLoadDocumentFileWithExcelDummyRows1() {
+		testLoadDocumentFileWithExcelDummyRows("ExcelDummyRowProblem_rows1.ods", 1);
+	}
+
+	private void testLoadDocumentFileWithExcelDummyRows(String file, int rowCount) {
+		try {
+			String filePath = ResourceUtilities.getAbsolutePath(file);
+			File fileDoc = new File(filePath);
+			SpreadsheetDocument spreadDoc = SpreadsheetDocument.loadDocument(fileDoc);
+			Assert.assertNotNull(spreadDoc);
+			Table table = spreadDoc.getSheetByIndex(0);
+			Assert.assertNotNull(table);
+			Assert.assertEquals(rowCount, table.getRowCount());
+		} catch (Exception e) {
+			LOG.log(Level.SEVERE, e.getMessage(), e);
+			Assert.fail(e.getMessage());
+		}
+	}
+	
+	@Test
+	public void testCreateChart() throws Exception{
+		try {
+			SpreadsheetDocument spDocument = SpreadsheetDocument.loadDocument(ResourceUtilities.getAbsolutePath(TEST_FILE));
+			String title = "XXXTitle";
+			String[] lables = new String[]{"spring","summer","autumn","autumn"};
+			String[] legends = new String[]{"hello1","hello2","hello3"};
+			double[][] data = new double[][]{{1.2,2.22,3},{2,3,4},{3,4,5},{4,5,6}};
+			DataSet dataset = new DataSet(lables, legends, data);
+			Rectangle rect = new Rectangle();
+			rect.x = 367;
+			rect.y = 389;
+			rect.width = 379;
+			rect.height = 424;
+			Chart spChart = spDocument.createChart(title, dataset, rect);
+			Assert.assertNotNull(spChart);
+			spChart.setChartType(ChartType.AREA);
+			//save
+			spDocument.save(ResourceUtilities.getTestOutput("Chart_"+TEST_FILE));
+			
+			Assert.assertEquals(dataset, spChart.getChartData());
+			Assert.assertEquals("XXXTitle", spChart.getChartTitle());
+			Assert.assertEquals(ChartType.AREA, spChart.getChartType());
+			
+			LOG.log(Level.INFO,"spChart--> " + spChart);
+			
+		} catch (Exception e) {
+			LOG.log(Level.SEVERE, e.getMessage(), e);
+			Assert.fail(e.getMessage());
+		}
+	}
+	
+	@Test
+	public void testGetSheetByIndex() throws Exception{
+		File file = new File(ResourceUtilities.getAbsolutePath("TestSpreadsheetTable.ods"));
+		SpreadsheetDocument spDocument = SpreadsheetDocument.loadDocument(file);
+		//index < 0 , Not expected, table ==null
+		Table tablenull = spDocument.getSheetByIndex(-1);
+		Assert.assertTrue((tablenull == null));
+		//index > 0 
+		//index = 0
+		Table tableSheet0 = spDocument.getSheetByIndex(0);
+		Assert.assertTrue((tableSheet0 != null));
+		Assert.assertEquals("Sheet1", tableSheet0.getTableName());
+		Assert.assertEquals(29, tableSheet0.getColumnCount());
+		//index = 1
+		Table tableSheet1 = spDocument.getSheetByIndex(1);
+		Assert.assertTrue((tableSheet1 != null));
+		Assert.assertEquals("Sheet2", tableSheet1.getTableName());
+		Assert.assertEquals(1, tableSheet1.getColumnCount());
+	}
+	
+	@Test
+	public void testInsertSheet() throws Exception{
+		File file = new File(ResourceUtilities.getAbsolutePath(TEST_FILE));
+		SpreadsheetDocument spDocument = SpreadsheetDocument.loadDocument(file);
+		//index <0 , Not expected
+		Table table = spDocument.insertSheet(-1);
+		Assert.assertNull(table);
+		//index >= sheet count
+		Table tableb = spDocument.insertSheet(11);
+		Assert.assertNull(tableb);
+		
+		//index is within the law
+		Table tab = spDocument.getSheetByName("tabellDemo2");
+		if(tab != null){
+			for(int i=0;i<spDocument.getSheetCount();i++){
+				if(tab.equals(spDocument.getSheetByIndex(i)))
+					spDocument.removeSheet(i);
+			}
+		}
+		Table tablea = spDocument.insertSheet(0);
+		Column col = tablea.appendColumn();
+		col.setWidth(12.99);
+		Column col2 = tablea.appendColumn();
+		col.setWidth(12.);
+		tablea.setTableName("tabellDemo2");
+		Assert.assertEquals("tabellDemo2", tablea.getTableName());
+		spDocument.save(ResourceUtilities.getAbsolutePath(TEST_FILE));
+		
+	}
+	
+	@Test
+	public void testRemoveSheet() throws Exception{
+		File file = new File(ResourceUtilities.getAbsolutePath(TEST_FILE));
+		SpreadsheetDocument spDocument = SpreadsheetDocument.loadDocument(file);
+		//index <0 , Not expected
+		Table table = spDocument.insertSheet(-1);
+		Assert.assertNull(table);
+		//index >= sheet count
+		Table tableb = spDocument.insertSheet(11);
+		Assert.assertNull(tableb);
+		
+		//index is within the law
+		Table tab = spDocument.getSheetByName("tabellDemo2");
+		if(tab != null){
+			for(int i=0;i<spDocument.getSheetCount();i++){
+				if(tab.equals(spDocument.getSheetByIndex(i)))
+					spDocument.removeSheet(i);
+			}
+		}
+		Table tablea = spDocument.insertSheet(0);
+		Column col = tablea.appendColumn();
+		col.setWidth(12.99);
+		Column col2 = tablea.appendColumn();
+		col.setWidth(12.);
+		tablea.setTableName("tabellDemo2");
+		Assert.assertEquals("tabellDemo2", tablea.getTableName());
+		spDocument.removeSheet(0);
+		Table tablem = spDocument.getSheetByIndex(0);
+		Assert.assertNotSame(tablea, tablem);
+		
+		spDocument.save(ResourceUtilities.getAbsolutePath(TEST_FILE));
+	}
+	
+	@Test
+	public void testGetSheetByIndex2() throws Exception{
+		File file = new File(ResourceUtilities.getAbsolutePath(TEST_FILE));
+		SpreadsheetDocument spDocument = SpreadsheetDocument.loadDocument(file);
+		//index <0 , Not expected
+		Table table = spDocument.insertSheet(-1);
+		Assert.assertNull(table);
+		//index >= sheet count
+		Table tableb = spDocument.insertSheet(11);
+		Assert.assertNull(tableb);
+		
+		//index is within the law
+		Table tab = spDocument.getSheetByName("tabellDemo1");
+		if(tab != null)
+			tab.remove();
+		
+		Table taba = spDocument.getSheetByName("Tabelle1");
+		Table tablea = spDocument.insertSheet(taba,0);
+		tablea.setTableName("tabellDemo1");
+		Assert.assertEquals("tabellDemo1", tablea.getTableName());
+		Table tablem = spDocument.getSheetByIndex(0);
+		Assert.assertEquals(tablea, tablem);
+		
+		spDocument.save(ResourceUtilities.getAbsolutePath(TEST_FILE));
+		
+	}
+	
+}
diff --git a/simple/src/test/resources/ExcelDummyRowProblem_rows0.ods b/simple/src/test/resources/ExcelDummyRowProblem_rows0.ods
new file mode 100644
index 0000000..b3add5c
--- /dev/null
+++ b/simple/src/test/resources/ExcelDummyRowProblem_rows0.ods
Binary files differ
diff --git a/simple/src/test/resources/ExcelDummyRowProblem_rows1.ods b/simple/src/test/resources/ExcelDummyRowProblem_rows1.ods
new file mode 100644
index 0000000..8c27b32
--- /dev/null
+++ b/simple/src/test/resources/ExcelDummyRowProblem_rows1.ods
Binary files differ
