/* ====================================================================
   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.apache.poi.xssf.usermodel;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.TreeMap;

import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.POIDataSamples;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLDocumentPart.RelationPart;
import org.apache.poi.POIXMLException;
import org.apache.poi.POIXMLProperties;
import org.apache.poi.common.usermodel.HyperlinkType;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.openxml4j.util.ZipSecureFile;
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.formula.WorkbookEvaluator;
import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.eval.ValueEval;
import org.apache.poi.ss.formula.functions.Function;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.ss.util.CellUtil;
import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.TempFile;
import org.apache.poi.xssf.XLSBUnsupportedException;
import org.apache.poi.xssf.XSSFITestDataProvider;
import org.apache.poi.xssf.XSSFTestDataSamples;
import org.apache.poi.xssf.model.CalculationChain;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.extensions.XSSFCellFill;
import org.apache.xmlbeans.XmlException;
import org.junit.Ignore;
import org.junit.Test;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcCell;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedNames;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTFontImpl;

public final class TestXSSFBugs extends BaseTestBugzillaIssues {
    public TestXSSFBugs() {
        super(XSSFITestDataProvider.instance);
    }

    /**
     * test writing a file with large number of unique strings,
     * open resulting file in Excel to check results!
     */
    @Test
    public void bug15375_2() throws IOException {
        bug15375(1000);
    }

    /**
     * Named ranges had the right reference, but
     *  the wrong sheet name
     */
    @Test
    public void bug45430() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("45430.xlsx");
        assertFalse(wb.isMacroEnabled());
        assertEquals(3, wb.getNumberOfNames());

        assertEquals(0, wb.getName("SheetAA1").getCTName().getLocalSheetId());
        assertFalse(wb.getName("SheetAA1").getCTName().isSetLocalSheetId());
        assertEquals("SheetA!$A$1", wb.getName("SheetAA1").getRefersToFormula());
        assertEquals("SheetA", wb.getName("SheetAA1").getSheetName());

        assertEquals(0, wb.getName("SheetBA1").getCTName().getLocalSheetId());
        assertFalse(wb.getName("SheetBA1").getCTName().isSetLocalSheetId());
        assertEquals("SheetB!$A$1", wb.getName("SheetBA1").getRefersToFormula());
        assertEquals("SheetB", wb.getName("SheetBA1").getSheetName());

        assertEquals(0, wb.getName("SheetCA1").getCTName().getLocalSheetId());
        assertFalse(wb.getName("SheetCA1").getCTName().isSetLocalSheetId());
        assertEquals("SheetC!$A$1", wb.getName("SheetCA1").getRefersToFormula());
        assertEquals("SheetC", wb.getName("SheetCA1").getSheetName());

        // Save and re-load, still there
        XSSFWorkbook nwb = XSSFTestDataSamples.writeOutAndReadBack(wb);
        assertEquals(3, nwb.getNumberOfNames());
        assertEquals("SheetA!$A$1", nwb.getName("SheetAA1").getRefersToFormula());

        nwb.close();
        wb.close();
    }

    /**
     * We should carry vba macros over after save
     * @throws InvalidFormatException 
     */
    @Test
    public void bug45431() throws IOException, InvalidFormatException {
        XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("45431.xlsm");
        OPCPackage pkg1 = wb1.getPackage();
        assertTrue(wb1.isMacroEnabled());

        // Check the various macro related bits can be found
        PackagePart vba = pkg1.getPart(
                PackagingURIHelper.createPartName("/xl/vbaProject.bin")
        );
        assertNotNull(vba);
        // And the drawing bit
        PackagePart drw = pkg1.getPart(
                PackagingURIHelper.createPartName("/xl/drawings/vmlDrawing1.vml")
        );
        assertNotNull(drw);


        // Save and re-open, both still there
        XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1);
        pkg1.close();
        wb1.close();

        OPCPackage pkg2 = wb2.getPackage();
        assertTrue(wb2.isMacroEnabled());

        vba = pkg2.getPart(
                PackagingURIHelper.createPartName("/xl/vbaProject.bin")
        );
        assertNotNull(vba);
        drw = pkg2.getPart(
                PackagingURIHelper.createPartName("/xl/drawings/vmlDrawing1.vml")
        );
        assertNotNull(drw);

        // And again, just to be sure
        XSSFWorkbook wb3 = XSSFTestDataSamples.writeOutAndReadBack(wb2);
        pkg2.close();
        wb2.close();
        OPCPackage pkg3 = wb3.getPackage();
        assertTrue(wb3.isMacroEnabled());

        vba = pkg3.getPart(
                PackagingURIHelper.createPartName("/xl/vbaProject.bin")
        );
        assertNotNull(vba);
        drw = pkg3.getPart(
                PackagingURIHelper.createPartName("/xl/drawings/vmlDrawing1.vml")
        );
        assertNotNull(drw);

        pkg3.close();
        wb3.close();
    }

    @Test
    public void bug47504() throws IOException {
        XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("47504.xlsx");
        assertEquals(1, wb1.getNumberOfSheets());
        XSSFSheet sh = wb1.getSheetAt(0);
        XSSFDrawing drawing = sh.createDrawingPatriarch();
        List<RelationPart> rels = drawing.getRelationParts();
        assertEquals(1, rels.size());
        assertEquals("Sheet1!A1", rels.get(0).getRelationship().getTargetURI().getFragment());

        // And again, just to be sure
        XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1);
        wb1.close();
        assertEquals(1, wb2.getNumberOfSheets());
        sh = wb2.getSheetAt(0);
        drawing = sh.createDrawingPatriarch();
        rels = drawing.getRelationParts();
        assertEquals(1, rels.size());
        assertEquals("Sheet1!A1", rels.get(0).getRelationship().getTargetURI().getFragment());
        wb2.close();
    }

    /**
     * Excel will sometimes write a button with a textbox
     *  containing &gt;br&lt; (not closed!).
     * Clearly Excel shouldn't do this, but test that we can
     *  read the file despite the naughtyness
     */
    @Test
    public void bug49020() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("BrNotClosed.xlsx");
        wb.close();
    }

    /**
     * ensure that CTPhoneticPr is loaded by the ooxml test suite so that it is included in poi-ooxml-schemas
     */
    @Test
    public void bug49325() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("49325.xlsx");
        CTWorksheet sh = wb.getSheetAt(0).getCTWorksheet();
        assertNotNull(sh.getPhoneticPr());
        wb.close();
    }

    /**
     * Names which are defined with a Sheet
     *  should return that sheet index properly
     */
    @Test
    public void bug48923() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48923.xlsx");
        assertEquals(4, wb.getNumberOfNames());

        Name b1 = wb.getName("NameB1");
        Name b2 = wb.getName("NameB2");
        Name sheet2 = wb.getName("NameSheet2");
        Name test = wb.getName("Test");

        assertNotNull(b1);
        assertEquals("NameB1", b1.getNameName());
        assertEquals("Sheet1", b1.getSheetName());
        assertEquals(-1, b1.getSheetIndex());

        assertNotNull(b2);
        assertEquals("NameB2", b2.getNameName());
        assertEquals("Sheet1", b2.getSheetName());
        assertEquals(-1, b2.getSheetIndex());

        assertNotNull(sheet2);
        assertEquals("NameSheet2", sheet2.getNameName());
        assertEquals("Sheet2", sheet2.getSheetName());
        assertEquals(-1, sheet2.getSheetIndex());

        assertNotNull(test);
        assertEquals("Test", test.getNameName());
        assertEquals("Sheet1", test.getSheetName());
        assertEquals(-1, test.getSheetIndex());

        wb.close();
    }

    /**
     * Problem with evaluation formulas due to
     *  NameXPtgs.
     * Blows up on:
     *   IF(B6= (ROUNDUP(B6,0) + ROUNDDOWN(B6,0))/2, MROUND(B6,2),ROUND(B6,0))
     *
     * TODO: delete this test case when MROUND and VAR are implemented
     */
    @Test
    public void bug48539() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48539.xlsx");
        try {
            assertEquals(3, wb.getNumberOfSheets());
            assertEquals(0, wb.getNumberOfNames());

            // Try each cell individually
            XSSFFormulaEvaluator eval = new XSSFFormulaEvaluator(wb);
            for(int i=0; i<wb.getNumberOfSheets(); i++) {
                Sheet s = wb.getSheetAt(i);
                for(Row r : s) {
                    for(Cell c : r) {
                        if(c.getCellTypeEnum() == CellType.FORMULA) {
                            CellValue cv = eval.evaluate(c);

                            if(cv.getCellType() == CellType.NUMERIC) {
                                // assert that the calculated value agrees with
                                // the cached formula result calculated by Excel
                                String formula = c.getCellFormula();
                                double cachedFormulaResult = c.getNumericCellValue();
                                double evaluatedFormulaResult = cv.getNumberValue();
                                assertEquals(formula, cachedFormulaResult, evaluatedFormulaResult, 1E-7);
                            }
                        }
                    }
                }
            }

            // Now all of them
            XSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
        } finally {
            wb.close();
        }
    }

    /**
     * Foreground colours should be found even if
     *  a theme is used
     */
    @Test
    public void bug48779() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48779.xlsx");
        XSSFCell cell = wb.getSheetAt(0).getRow(0).getCell(0);
        XSSFCellStyle cs = cell.getCellStyle();

        assertNotNull(cs);
        assertEquals(1, cs.getIndex());

        // Look at the low level xml elements
        assertEquals(2, cs.getCoreXf().getFillId());
        assertEquals(0, cs.getCoreXf().getXfId());
        assertEquals(true, cs.getCoreXf().getApplyFill());

        XSSFCellFill fg = wb.getStylesSource().getFillAt(2);
        assertNotNull(fg.getFillForegroundColor());
        assertEquals(0, fg.getFillForegroundColor().getIndexed());
        assertEquals(0.0, fg.getFillForegroundColor().getTint(), 0);
        assertEquals("FFFF0000", fg.getFillForegroundColor().getARGBHex());
        assertNotNull(fg.getFillBackgroundColor());
        assertEquals(64, fg.getFillBackgroundColor().getIndexed());

        // Now look higher up
        assertNotNull(cs.getFillForegroundXSSFColor());
        assertEquals(0, cs.getFillForegroundColor());
        assertEquals("FFFF0000", cs.getFillForegroundXSSFColor().getARGBHex());
        assertEquals("FFFF0000", cs.getFillForegroundColorColor().getARGBHex());

        assertNotNull(cs.getFillBackgroundColor());
        assertEquals(64, cs.getFillBackgroundColor());
        assertEquals(null, cs.getFillBackgroundXSSFColor().getARGBHex());
        assertEquals(null, cs.getFillBackgroundColorColor().getARGBHex());

        wb.close();
    }

    /**
     * Ensure General and @ format are working properly
     *  for integers
     */
    @Test
    public void bug47490() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("GeneralFormatTests.xlsx");
        Sheet s = wb.getSheetAt(1);
        Row r;
        DataFormatter df = new DataFormatter();

        r = s.getRow(1);
        assertEquals(1.0, r.getCell(2).getNumericCellValue(), 0);
        assertEquals("General", r.getCell(2).getCellStyle().getDataFormatString());
        assertEquals("1", df.formatCellValue(r.getCell(2)));
        assertEquals("1", df.formatRawCellContents(1.0, -1, "@"));
        assertEquals("1", df.formatRawCellContents(1.0, -1, "General"));

        r = s.getRow(2);
        assertEquals(12.0, r.getCell(2).getNumericCellValue(), 0);
        assertEquals("General", r.getCell(2).getCellStyle().getDataFormatString());
        assertEquals("12", df.formatCellValue(r.getCell(2)));
        assertEquals("12", df.formatRawCellContents(12.0, -1, "@"));
        assertEquals("12", df.formatRawCellContents(12.0, -1, "General"));

        r = s.getRow(3);
        assertEquals(123.0, r.getCell(2).getNumericCellValue(), 0);
        assertEquals("General", r.getCell(2).getCellStyle().getDataFormatString());
        assertEquals("123", df.formatCellValue(r.getCell(2)));
        assertEquals("123", df.formatRawCellContents(123.0, -1, "@"));
        assertEquals("123", df.formatRawCellContents(123.0, -1, "General"));
        
        wb.close();
    }

    /**
     * A problem file from a non-standard source (a scientific instrument that saves its
     * output as an .xlsx file) that have two issues:
     * 1. The Content Type part name is lower-case:  [content_types].xml
     * 2. The file appears to use backslashes as path separators
     *
     * The OPC spec tolerates both of these peculiarities, so does POI
     */
    @Test
    public void bug49609() throws IOException {
        XSSFWorkbook wb =  XSSFTestDataSamples.openSampleWorkbook("49609.xlsx");
        assertEquals("FAM", wb.getSheetName(0));
        assertEquals("Cycle", wb.getSheetAt(0).getRow(0).getCell(1).getStringCellValue());
        wb.close();

    }

    @Test
    public void bug49783() throws IOException {
        Workbook wb =  XSSFTestDataSamples.openSampleWorkbook("49783.xlsx");
        Sheet sheet = wb.getSheetAt(0);
        FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
        Cell cell;

        cell = sheet.getRow(0).getCell(0);
        assertEquals("#REF!*#REF!", cell.getCellFormula());
        assertEquals(CellType.ERROR, evaluator.evaluateInCell(cell).getCellTypeEnum());
        assertEquals("#REF!", FormulaError.forInt(cell.getErrorCellValue()).getString());

        Name nm1 = wb.getName("sale_1");
        assertNotNull("name sale_1 should be present", nm1);
        assertEquals("Sheet1!#REF!", nm1.getRefersToFormula());
        Name nm2 = wb.getName("sale_2");
        assertNotNull("name sale_2 should be present", nm2);
        assertEquals("Sheet1!#REF!", nm2.getRefersToFormula());

        cell = sheet.getRow(1).getCell(0);
        assertEquals("sale_1*sale_2", cell.getCellFormula());
        assertEquals(CellType.ERROR, evaluator.evaluateInCell(cell).getCellTypeEnum());
        assertEquals("#REF!", FormulaError.forInt(cell.getErrorCellValue()).getString());
        
        wb.close();
    }

    /**
     * Creating a rich string of "hello world" and applying
     *  a font to characters 1-5 means we have two strings,
     *  "hello" and " world". As such, we need to apply
     *  preserve spaces to the 2nd bit, lest we end up
     *  with something like "helloworld" !
     */
    @Test
    public void bug49941() throws IOException {
        XSSFWorkbook wb1 = new XSSFWorkbook();
        XSSFSheet s = wb1.createSheet();
        XSSFRow r = s.createRow(0);
        XSSFCell c = r.createCell(0);

        // First without fonts
        c.setCellValue(
                new XSSFRichTextString(" with spaces ")
        );
        assertEquals(" with spaces ", c.getRichStringCellValue().toString());
        assertEquals(0, c.getRichStringCellValue().getCTRst().sizeOfRArray());
        assertEquals(true, c.getRichStringCellValue().getCTRst().isSetT());
        // Should have the preserve set
        assertEquals(
                1,
                c.getRichStringCellValue().getCTRst().xgetT().getDomNode().getAttributes().getLength()
        );
        assertEquals(
                "preserve",
                c.getRichStringCellValue().getCTRst().xgetT().getDomNode().getAttributes().item(0).getNodeValue()
        );

        // Save and check
        XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1);
        wb1.close();
        s = wb2.getSheetAt(0);
        r = s.getRow(0);
        c = r.getCell(0);
        assertEquals(" with spaces ", c.getRichStringCellValue().toString());
        assertEquals(0, c.getRichStringCellValue().getCTRst().sizeOfRArray());
        assertEquals(true, c.getRichStringCellValue().getCTRst().isSetT());

        // Change the string
        c.setCellValue(
                new XSSFRichTextString("hello world")
        );
        assertEquals("hello world", c.getRichStringCellValue().toString());
        // Won't have preserve
        assertEquals(
                0,
                c.getRichStringCellValue().getCTRst().xgetT().getDomNode().getAttributes().getLength()
        );

        // Apply a font
        XSSFFont f = wb2.createFont();
        f.setBold(true);
        c.getRichStringCellValue().applyFont(0, 5, f);
        assertEquals("hello world", c.getRichStringCellValue().toString());
        // Does need preserving on the 2nd part
        assertEquals(2, c.getRichStringCellValue().getCTRst().sizeOfRArray());
        assertEquals(
                0,
                c.getRichStringCellValue().getCTRst().getRArray(0).xgetT().getDomNode().getAttributes().getLength()
        );
        assertEquals(
                1,
                c.getRichStringCellValue().getCTRst().getRArray(1).xgetT().getDomNode().getAttributes().getLength()
        );
        assertEquals(
                "preserve",
                c.getRichStringCellValue().getCTRst().getRArray(1).xgetT().getDomNode().getAttributes().item(0).getNodeValue()
        );

        // Save and check
        XSSFWorkbook wb3 = XSSFTestDataSamples.writeOutAndReadBack(wb2);
        wb2.close();
        
        s = wb3.getSheetAt(0);
        r = s.getRow(0);
        c = r.getCell(0);
        assertEquals("hello world", c.getRichStringCellValue().toString());
        wb3.close();
    }

    /**
     * Repeatedly writing the same file which has styles
     */
    @Test
    public void bug49940() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("styles.xlsx");
        assertEquals(3, wb.getNumberOfSheets());
        assertEquals(10, wb.getStylesSource().getNumCellStyles());

        ByteArrayOutputStream b1 = new ByteArrayOutputStream();
        ByteArrayOutputStream b2 = new ByteArrayOutputStream();
        ByteArrayOutputStream b3 = new ByteArrayOutputStream();
        wb.write(b1);
        wb.write(b2);
        wb.write(b3);

        for(byte[] data : new byte[][] {
                b1.toByteArray(), b2.toByteArray(), b3.toByteArray()
        }) {
            ByteArrayInputStream bais = new ByteArrayInputStream(data);
            XSSFWorkbook wb2 = new XSSFWorkbook(bais);
            assertEquals(3, wb2.getNumberOfSheets());
            assertEquals(10, wb2.getStylesSource().getNumCellStyles());
            wb2.close();
        }
        
        wb.close();
    }

    /**
     * Various ways of removing a cell formula should all zap the calcChain
     * entry.
     */
    @Test
    public void bug49966() throws IOException {
        XSSFWorkbook wb1 = XSSFTestDataSamples
                .openSampleWorkbook("shared_formulas.xlsx");
        XSSFSheet sheet = wb1.getSheetAt(0);

        XSSFTestDataSamples.writeOutAndReadBack(wb1).close();

        // CalcChain has lots of entries
        CalculationChain cc = wb1.getCalculationChain();
        assertEquals("A2", cc.getCTCalcChain().getCArray(0).getR());
        assertEquals("A3", cc.getCTCalcChain().getCArray(1).getR());
        assertEquals("A4", cc.getCTCalcChain().getCArray(2).getR());
        assertEquals("A5", cc.getCTCalcChain().getCArray(3).getR());
        assertEquals("A6", cc.getCTCalcChain().getCArray(4).getR());
        assertEquals("A7", cc.getCTCalcChain().getCArray(5).getR());
        assertEquals("A8", cc.getCTCalcChain().getCArray(6).getR());
        assertEquals(40, cc.getCTCalcChain().sizeOfCArray());

        XSSFTestDataSamples.writeOutAndReadBack(wb1).close();

        // Try various ways of changing the formulas
        // If it stays a formula, chain entry should remain
        // Otherwise should go
        sheet.getRow(1).getCell(0).setCellFormula("A1"); // stay
        sheet.getRow(2).getCell(0).setCellFormula(null); // go
        sheet.getRow(3).getCell(0).setCellType(CellType.FORMULA); // stay
        XSSFTestDataSamples.writeOutAndReadBack(wb1).close();

        sheet.getRow(4).getCell(0).setCellType(CellType.STRING); // go
        XSSFTestDataSamples.writeOutAndReadBack(wb1).close();

        validateCells(sheet);
        sheet.getRow(5).removeCell(sheet.getRow(5).getCell(0)); // go
        validateCells(sheet);
        XSSFTestDataSamples.writeOutAndReadBack(wb1).close();

        sheet.getRow(6).getCell(0).setCellType(CellType.BLANK); // go
        XSSFTestDataSamples.writeOutAndReadBack(wb1).close();

        sheet.getRow(7).getCell(0).setCellValue((String) null); // go

        XSSFTestDataSamples.writeOutAndReadBack(wb1).close();

        // Save and check
        XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1);
        wb1.close();
        assertEquals(35, cc.getCTCalcChain().sizeOfCArray());

        cc = wb2.getCalculationChain();
        assertEquals("A2", cc.getCTCalcChain().getCArray(0).getR());
        assertEquals("A4", cc.getCTCalcChain().getCArray(1).getR());
        assertEquals("A9", cc.getCTCalcChain().getCArray(2).getR());
        wb2.close();
    }

    @Test
    public void bug49966Row() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples
                .openSampleWorkbook("shared_formulas.xlsx");
        XSSFSheet sheet = wb.getSheetAt(0);

        validateCells(sheet);
        sheet.getRow(5).removeCell(sheet.getRow(5).getCell(0)); // go
        validateCells(sheet);
        
        wb.close();
    }

    private void validateCells(XSSFSheet sheet) {
        for(Row row : sheet) {
            // trigger handling
            ((XSSFRow)row).onDocumentWrite();
        }
    }

    @Test
    public void bug49156() throws IOException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("49156.xlsx");
        FormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();

        Sheet sheet = wb.getSheetAt(0);
        for(Row row : sheet){
            for(Cell cell : row){
                if(cell.getCellTypeEnum() == CellType.FORMULA){
                    formulaEvaluator.evaluateInCell(cell); // caused NPE on some cells
                }
            }
        }
        wb.close();
    }

    /**
     * Newlines are valid characters in a formula
     */
    @Test
    public void bug50440And51875() throws IOException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("NewlineInFormulas.xlsx");
        Sheet s = wb.getSheetAt(0);
        Cell c = s.getRow(0).getCell(0);

        assertEquals("SUM(\n1,2\n)", c.getCellFormula());
        assertEquals(3.0, c.getNumericCellValue(), 0);

        FormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
        formulaEvaluator.evaluateFormulaCellEnum(c);

        assertEquals("SUM(\n1,2\n)", c.getCellFormula());
        assertEquals(3.0, c.getNumericCellValue(), 0);

        // For 51875
        Cell b3 = s.getRow(2).getCell(1);
        formulaEvaluator.evaluateFormulaCellEnum(b3);
        assertEquals("B1+B2", b3.getCellFormula()); // The newline is lost for shared formulas
        assertEquals(3.0, b3.getNumericCellValue(), 0);
        
        wb.close();
    }

    /**
     * Moving a cell comment from one cell to another
     */
    @Test
    public void bug50795() throws IOException {
        XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("50795.xlsx");
        XSSFSheet sheet = wb1.getSheetAt(0);
        XSSFRow row = sheet.getRow(0);

        XSSFCell cellWith = row.getCell(0);
        XSSFCell cellWithoutComment = row.getCell(1);

        assertNotNull(cellWith.getCellComment());
        assertNull(cellWithoutComment.getCellComment());

        String exp = "\u0410\u0432\u0442\u043e\u0440:\ncomment";
        XSSFComment comment = cellWith.getCellComment();
        assertEquals(exp, comment.getString().getString());


        // Check we can write it out and read it back as-is
        XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1);
        wb1.close();
        
        sheet = wb2.getSheetAt(0);
        row = sheet.getRow(0);
        cellWith = row.getCell(0);
        cellWithoutComment = row.getCell(1);

        // Double check things are as expected
        assertNotNull(cellWith.getCellComment());
        assertNull(cellWithoutComment.getCellComment());
        comment = cellWith.getCellComment();
        assertEquals(exp, comment.getString().getString());


        // Move the comment
        cellWithoutComment.setCellComment(comment);


        // Write out and re-check
        XSSFWorkbook wb3 = XSSFTestDataSamples.writeOutAndReadBack(wb2);
        wb2.close();
        
        sheet = wb3.getSheetAt(0);
        row = sheet.getRow(0);

        // Ensure it swapped over
        cellWith = row.getCell(0);
        cellWithoutComment = row.getCell(1);
        assertNull(cellWith.getCellComment());
        assertNotNull(cellWithoutComment.getCellComment());

        comment = cellWithoutComment.getCellComment();
        assertEquals(exp, comment.getString().getString());
        
        wb3.close();
    }

    /**
     * When the cell background colour is set with one of the first
     *  two columns of the theme colour palette, the colours are
     *  shades of white or black.
     * For those cases, ensure we don't break on reading the colour
     */
    @Test
    public void bug50299() throws IOException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("50299.xlsx");

        // Check all the colours
        for(int sn=0; sn<wb.getNumberOfSheets(); sn++) {
            Sheet s = wb.getSheetAt(sn);
            for(Row r : s) {
                for(Cell c : r) {
                    CellStyle cs = c.getCellStyle();
                    if(cs != null) {
                        cs.getFillForegroundColor();
                    }
                }
            }
        }

        // Check one bit in detail
        // Check that we get back foreground=0 for the theme colours,
        //  and background=64 for the auto colouring
        Sheet s = wb.getSheetAt(0);
        assertEquals(0,  s.getRow(0).getCell(8).getCellStyle().getFillForegroundColor());
        assertEquals(64, s.getRow(0).getCell(8).getCellStyle().getFillBackgroundColor());
        assertEquals(0,  s.getRow(1).getCell(8).getCellStyle().getFillForegroundColor());
        assertEquals(64, s.getRow(1).getCell(8).getCellStyle().getFillBackgroundColor());
        
        wb.close();
    }

    /**
     * Excel .xls style indexed colours in a .xlsx file
     */
    @Test
    public void bug50786() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50786-indexed_colours.xlsx");
        XSSFSheet s = wb.getSheetAt(0);
        XSSFRow r = s.getRow(2);

        // Check we have the right cell
        XSSFCell c = r.getCell(1);
        assertEquals("test\u00a0", c.getRichStringCellValue().getString());

        // It should be light green
        XSSFCellStyle cs = c.getCellStyle();
        assertEquals(42, cs.getFillForegroundColor());
        assertEquals(42, cs.getFillForegroundColorColor().getIndexed());
        assertNotNull(cs.getFillForegroundColorColor().getRGB());
        assertEquals("FFCCFFCC", cs.getFillForegroundColorColor().getARGBHex());
        wb.close();
    }

    /**
     * If the border colours are set with themes, then we
     *  should still be able to get colours
     */
    @Test
    public void bug50846() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50846-border_colours.xlsx");

        XSSFSheet sheet = wb.getSheetAt(0);
        XSSFRow row = sheet.getRow(0);

        // Border from a theme, brown
        XSSFCell cellT = row.getCell(0);
        XSSFCellStyle styleT = cellT.getCellStyle();
        XSSFColor colorT = styleT.getBottomBorderXSSFColor();

        assertEquals(5, colorT.getTheme());
        assertEquals("FFC0504D", colorT.getARGBHex());

        // Border from a style direct, red
        XSSFCell cellS = row.getCell(1);
        XSSFCellStyle styleS = cellS.getCellStyle();
        XSSFColor colorS = styleS.getBottomBorderXSSFColor();

        assertEquals(0, colorS.getTheme());
        assertEquals("FFFF0000", colorS.getARGBHex());
        wb.close();
    }

    /**
     * Fonts where their colours come from the theme rather
     *  then being set explicitly still should allow the
     *  fetching of the RGB.
     */
    @Test
    public void bug50784() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50784-font_theme_colours.xlsx");
        XSSFSheet s = wb.getSheetAt(0);
        XSSFRow r = s.getRow(0);

        // Column 1 has a font with regular colours
        XSSFCell cr = r.getCell(1);
        XSSFFont fr = wb.getFontAt( cr.getCellStyle().getFontIndex() );
        XSSFColor colr =  fr.getXSSFColor();
        // No theme, has colours
        assertEquals(0, colr.getTheme());
        assertNotNull( colr.getRGB() );

        // Column 0 has a font with colours from a theme
        XSSFCell ct = r.getCell(0);
        XSSFFont ft = wb.getFontAt( ct.getCellStyle().getFontIndex() );
        XSSFColor colt =  ft.getXSSFColor();
        // Has a theme, which has the colours on it
        assertEquals(9, colt.getTheme());
        XSSFColor themeC = wb.getTheme().getThemeColor(colt.getTheme());
        assertNotNull( themeC.getRGB() );
        assertNotNull( colt.getRGB() );
        assertEquals( themeC.getARGBHex(), colt.getARGBHex() ); // The same colour
        wb.close();
    }

    /**
     * New lines were being eaten when setting a font on
     *  a rich text string
     */
    @Test
    public void bug48877() throws IOException {
        String text = "Use \n with word wrap on to create a new line.\n" +
                "This line finishes with two trailing spaces.  ";

        XSSFWorkbook wb1 = new XSSFWorkbook();
        XSSFSheet sheet = wb1.createSheet();

        Font font1 = wb1.createFont();
        font1.setColor((short) 20);
        Font font2 = wb1.createFont();
        font2.setColor(Font.COLOR_RED);
        Font font3 = wb1.getFontAt((short)0);

        XSSFRow row = sheet.createRow(2);
        XSSFCell cell = row.createCell(2);

        XSSFRichTextString richTextString =
                wb1.getCreationHelper().createRichTextString(text);

        // Check the text has the newline
        assertEquals(text, richTextString.getString());

        // Apply the font
        richTextString.applyFont(font3);
        richTextString.applyFont(0, 3, font1);
        cell.setCellValue(richTextString);

        // To enable newlines you need set a cell styles with wrap=true
        CellStyle cs = wb1.createCellStyle();
        cs.setWrapText(true);
        cell.setCellStyle(cs);

        // Check the text has the
        assertEquals(text, cell.getStringCellValue());

        // Save the file and re-read it
        XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1);
        wb1.close();
        sheet = wb2.getSheetAt(0);
        row = sheet.getRow(2);
        cell = row.getCell(2);
        assertEquals(text, cell.getStringCellValue());

        // Now add a 2nd, and check again
        int fontAt = text.indexOf("\n", 6);
        cell.getRichStringCellValue().applyFont(10, fontAt+1, font2);
        assertEquals(text, cell.getStringCellValue());

        assertEquals(4, cell.getRichStringCellValue().numFormattingRuns());
        assertEquals("Use", cell.getRichStringCellValue().getCTRst().getRArray(0).getT());

        String r3 = cell.getRichStringCellValue().getCTRst().getRArray(2).getT();
        assertEquals("line.\n", r3.substring(r3.length()-6));

        // Save and re-check
        XSSFWorkbook wb3 = XSSFTestDataSamples.writeOutAndReadBack(wb2);
        wb2.close();
        
        sheet = wb3.getSheetAt(0);
        row = sheet.getRow(2);
        cell = row.getCell(2);
        assertEquals(text, cell.getStringCellValue());
        wb3.close();

        // FileOutputStream out = new FileOutputStream("/tmp/test48877.xlsx");
        // wb.write(out);
        // out.close();
    }

    /**
     * Adding sheets when one has a table, then re-ordering
     */
    @Test
    public void bug50867() throws IOException {
        XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("50867_with_table.xlsx");
        assertEquals(3, wb1.getNumberOfSheets());

        XSSFSheet s1 = wb1.getSheetAt(0);
        XSSFSheet s2 = wb1.getSheetAt(1);
        XSSFSheet s3 = wb1.getSheetAt(2);
        assertEquals(1, s1.getTables().size());
        assertEquals(0, s2.getTables().size());
        assertEquals(0, s3.getTables().size());

        XSSFTable t = s1.getTables().get(0);
        assertEquals("Tabella1", t.getName());
        assertEquals("Tabella1", t.getDisplayName());
        assertEquals("A1:C3", t.getCTTable().getRef());

        // Add a sheet and re-order
        XSSFSheet s4 = wb1.createSheet("NewSheet");
        wb1.setSheetOrder(s4.getSheetName(), 0);

        // Check on tables
        assertEquals(1, s1.getTables().size());
        assertEquals(0, s2.getTables().size());
        assertEquals(0, s3.getTables().size());
        assertEquals(0, s4.getTables().size());

        // Refetch to get the new order
        s1 = wb1.getSheetAt(0);
        s2 = wb1.getSheetAt(1);
        s3 = wb1.getSheetAt(2);
        s4 = wb1.getSheetAt(3);
        assertEquals(0, s1.getTables().size());
        assertEquals(1, s2.getTables().size());
        assertEquals(0, s3.getTables().size());
        assertEquals(0, s4.getTables().size());

        // Save and re-load
        XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1);
        wb1.close();
        
        s1 = wb2.getSheetAt(0);
        s2 = wb2.getSheetAt(1);
        s3 = wb2.getSheetAt(2);
        s4 = wb2.getSheetAt(3);
        assertEquals(0, s1.getTables().size());
        assertEquals(1, s2.getTables().size());
        assertEquals(0, s3.getTables().size());
        assertEquals(0, s4.getTables().size());

        t = s2.getTables().get(0);
        assertEquals("Tabella1", t.getName());
        assertEquals("Tabella1", t.getDisplayName());
        assertEquals("A1:C3", t.getCTTable().getRef());


        // Add some more tables, and check
        t = s2.createTable();
        t.setName("New 2");
        t.setDisplayName("New 2");
        t = s3.createTable();
        t.setName("New 3");
        t.setDisplayName("New 3");

        XSSFWorkbook wb3 = XSSFTestDataSamples.writeOutAndReadBack(wb2);
        wb2.close();
        s1 = wb3.getSheetAt(0);
        s2 = wb3.getSheetAt(1);
        s3 = wb3.getSheetAt(2);
        s4 = wb3.getSheetAt(3);
        assertEquals(0, s1.getTables().size());
        assertEquals(2, s2.getTables().size());
        assertEquals(1, s3.getTables().size());
        assertEquals(0, s4.getTables().size());

        t = s2.getTables().get(0);
        assertEquals("Tabella1", t.getName());
        assertEquals("Tabella1", t.getDisplayName());
        assertEquals("A1:C3", t.getCTTable().getRef());

        t = s2.getTables().get(1);
        assertEquals("New 2", t.getName());
        assertEquals("New 2", t.getDisplayName());

        t = s3.getTables().get(0);
        assertEquals("New 3", t.getName());
        assertEquals("New 3", t.getDisplayName());

        // Check the relationships
        assertEquals(0, s1.getRelations().size());
        assertEquals(3, s2.getRelations().size());
        assertEquals(1, s3.getRelations().size());
        assertEquals(0, s4.getRelations().size());

        assertEquals(
                XSSFRelation.PRINTER_SETTINGS.getContentType(),
                s2.getRelations().get(0).getPackagePart().getContentType()
        );
        assertEquals(
                XSSFRelation.TABLE.getContentType(),
                s2.getRelations().get(1).getPackagePart().getContentType()
        );
        assertEquals(
                XSSFRelation.TABLE.getContentType(),
                s2.getRelations().get(2).getPackagePart().getContentType()
        );
        assertEquals(
                XSSFRelation.TABLE.getContentType(),
                s3.getRelations().get(0).getPackagePart().getContentType()
        );
        assertEquals(
                "/xl/tables/table3.xml",
                s3.getRelations().get(0).getPackagePart().getPartName().toString()
        );
        wb3.close();
    }

    /**
     * Setting repeating rows and columns shouldn't break
     *  any print settings that were there before
     */
    @Test
    public void bug49253() throws IOException {
        XSSFWorkbook wb1 = new XSSFWorkbook();
        XSSFWorkbook wb2 = new XSSFWorkbook();
        CellRangeAddress cra = CellRangeAddress.valueOf("C2:D3");

        // No print settings before repeating
        XSSFSheet s1 = wb1.createSheet();
        assertEquals(false, s1.getCTWorksheet().isSetPageSetup());
        assertEquals(true, s1.getCTWorksheet().isSetPageMargins());
        s1.setRepeatingColumns(cra);
        s1.setRepeatingRows(cra);

        assertEquals(true, s1.getCTWorksheet().isSetPageSetup());
        assertEquals(true, s1.getCTWorksheet().isSetPageMargins());

        PrintSetup ps1 = s1.getPrintSetup();
        assertEquals(false, ps1.getValidSettings());
        assertEquals(false, ps1.getLandscape());


        // Had valid print settings before repeating
        XSSFSheet s2 = wb2.createSheet();
        PrintSetup ps2 = s2.getPrintSetup();
        assertEquals(true, s2.getCTWorksheet().isSetPageSetup());
        assertEquals(true, s2.getCTWorksheet().isSetPageMargins());

        ps2.setLandscape(false);
        assertEquals(true, ps2.getValidSettings());
        assertEquals(false, ps2.getLandscape());
        s2.setRepeatingColumns(cra);
        s2.setRepeatingRows(cra);

        ps2 = s2.getPrintSetup();
        assertEquals(true, s2.getCTWorksheet().isSetPageSetup());
        assertEquals(true, s2.getCTWorksheet().isSetPageMargins());
        assertEquals(true, ps2.getValidSettings());
        assertEquals(false, ps2.getLandscape());

        wb1.close();
        wb2.close();
    }

    /**
     * Default Column style
     */
    @Test
    public void bug51037() throws IOException {
        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFSheet s = wb.createSheet();

        CellStyle defaultStyle = wb.getCellStyleAt((short)0);
        assertEquals(0, defaultStyle.getIndex());

        CellStyle blueStyle = wb.createCellStyle();
        blueStyle.setFillForegroundColor(IndexedColors.AQUA.getIndex());
        blueStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
        assertEquals(1, blueStyle.getIndex());

        CellStyle pinkStyle = wb.createCellStyle();
        pinkStyle.setFillForegroundColor(IndexedColors.PINK.getIndex());
        pinkStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
        assertEquals(2, pinkStyle.getIndex());

        // Starts empty
        assertEquals(1, s.getCTWorksheet().sizeOfColsArray());
        CTCols cols = s.getCTWorksheet().getColsArray(0);
        assertEquals(0, cols.sizeOfColArray());

        // Add some rows and columns
        XSSFRow r1 = s.createRow(0);
        XSSFRow r2 = s.createRow(1);
        r1.createCell(0);
        r1.createCell(2);
        r2.createCell(0);
        r2.createCell(3);

        // Check no style is there
        assertEquals(1, s.getCTWorksheet().sizeOfColsArray());
        assertEquals(0, cols.sizeOfColArray());

        assertEquals(defaultStyle, s.getColumnStyle(0));
        assertEquals(defaultStyle, s.getColumnStyle(2));
        assertEquals(defaultStyle, s.getColumnStyle(3));


        // Apply the styles
        s.setDefaultColumnStyle(0, pinkStyle);
        s.setDefaultColumnStyle(3, blueStyle);

        // Check
        assertEquals(pinkStyle, s.getColumnStyle(0));
        assertEquals(defaultStyle, s.getColumnStyle(2));
        assertEquals(blueStyle, s.getColumnStyle(3));

        assertEquals(1, s.getCTWorksheet().sizeOfColsArray());
        assertEquals(2, cols.sizeOfColArray());

        assertEquals(1, cols.getColArray(0).getMin());
        assertEquals(1, cols.getColArray(0).getMax());
        assertEquals(pinkStyle.getIndex(), cols.getColArray(0).getStyle());

        assertEquals(4, cols.getColArray(1).getMin());
        assertEquals(4, cols.getColArray(1).getMax());
        assertEquals(blueStyle.getIndex(), cols.getColArray(1).getStyle());


        // Save, re-load and re-check
        XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb);
        wb.close();
        s = wbBack.getSheetAt(0);
        defaultStyle = wbBack.getCellStyleAt(defaultStyle.getIndex());
        blueStyle = wbBack.getCellStyleAt(blueStyle.getIndex());
        pinkStyle = wbBack.getCellStyleAt(pinkStyle.getIndex());

        assertEquals(pinkStyle, s.getColumnStyle(0));
        assertEquals(defaultStyle, s.getColumnStyle(2));
        assertEquals(blueStyle, s.getColumnStyle(3));
        wbBack.close();
    }

    /**
     * Repeatedly writing a file.
     * Something with the SharedStringsTable currently breaks...
     */
    @Test
    public void bug46662() throws IOException {
        // New file
        XSSFWorkbook wb1 = new XSSFWorkbook();
        XSSFTestDataSamples.writeOutAndReadBack(wb1).close();
        XSSFTestDataSamples.writeOutAndReadBack(wb1).close();
        XSSFTestDataSamples.writeOutAndReadBack(wb1).close();
        wb1.close();

        // Simple file
        XSSFWorkbook wb2 = XSSFTestDataSamples.openSampleWorkbook("sample.xlsx");
        XSSFTestDataSamples.writeOutAndReadBack(wb2).close();
        XSSFTestDataSamples.writeOutAndReadBack(wb2).close();
        XSSFTestDataSamples.writeOutAndReadBack(wb2).close();
        wb2.close();

        // Complex file
        // TODO
    }

    /**
     * Colours and styles when the list has gaps in it
     */
    @Test
    public void bug51222() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("51222.xlsx");
        XSSFSheet s = wb.getSheetAt(0);

        XSSFCell cA4_EEECE1 = s.getRow(3).getCell(0);
        XSSFCell cA5_1F497D = s.getRow(4).getCell(0);

        // Check the text
        assertEquals("A4", cA4_EEECE1.getRichStringCellValue().getString());
        assertEquals("A5", cA5_1F497D.getRichStringCellValue().getString());

        // Check the styles assigned to them
        assertEquals(4, cA4_EEECE1.getCTCell().getS());
        assertEquals(5, cA5_1F497D.getCTCell().getS());

        // Check we look up the correct style
        assertEquals(4, cA4_EEECE1.getCellStyle().getIndex());
        assertEquals(5, cA5_1F497D.getCellStyle().getIndex());

        // Check the fills on them at the low level
        assertEquals(5, cA4_EEECE1.getCellStyle().getCoreXf().getFillId());
        assertEquals(6, cA5_1F497D.getCellStyle().getCoreXf().getFillId());

        // These should reference themes 2 and 3
        assertEquals(2, wb.getStylesSource().getFillAt(5).getCTFill().getPatternFill().getFgColor().getTheme());
        assertEquals(3, wb.getStylesSource().getFillAt(6).getCTFill().getPatternFill().getFgColor().getTheme());

        // Ensure we get the right colours for these themes
        // TODO fix
        // assertEquals("FFEEECE1", wb.getTheme().getThemeColor(2).getARGBHex());
        // assertEquals("FF1F497D", wb.getTheme().getThemeColor(3).getARGBHex());

        // Finally check the colours on the styles
        // TODO fix
        // assertEquals("FFEEECE1", cA4_EEECE1.getCellStyle().getFillForegroundXSSFColor().getARGBHex());
        // assertEquals("FF1F497D", cA5_1F497D.getCellStyle().getFillForegroundXSSFColor().getARGBHex());
        
        wb.close();
    }

    @Test
    public void bug51470() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("51470.xlsx");
        XSSFSheet sh0 = wb.getSheetAt(0);
        XSSFSheet sh1 = wb.cloneSheet(0);
        List<RelationPart> rels0 = sh0.getRelationParts();
        List<RelationPart> rels1 = sh1.getRelationParts();
        assertEquals(1, rels0.size());
        assertEquals(1, rels1.size());

        PackageRelationship pr0 = rels0.get(0).getRelationship();
        PackageRelationship pr1 = rels1.get(0).getRelationship();
        
        assertEquals(pr0.getTargetMode(), pr1.getTargetMode());
        assertEquals(pr0.getTargetURI(), pr1.getTargetURI());
        POIXMLDocumentPart doc0 = rels0.get(0).getDocumentPart();
        POIXMLDocumentPart doc1 = rels1.get(0).getDocumentPart();
        
        assertEquals(doc0, doc1);
        wb.close();
    }

    /**
     * Add comments to Sheet 1, when Sheet 2 already has
     *  comments (so /xl/comments1.xml is taken)
     */
    @Test
    public void bug51850() throws IOException {
        XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("51850.xlsx");
        XSSFSheet sh1 = wb1.getSheetAt(0);
        XSSFSheet sh2 = wb1.getSheetAt(1);

        // Sheet 2 has comments
        assertNotNull(sh2.getCommentsTable(false));
        assertEquals(1, sh2.getCommentsTable(false).getNumberOfComments());

        // Sheet 1 doesn't (yet)
        assertNull(sh1.getCommentsTable(false));

        // Try to add comments to Sheet 1
        CreationHelper factory = wb1.getCreationHelper();
        Drawing drawing = sh1.createDrawingPatriarch();

        ClientAnchor anchor = factory.createClientAnchor();
        anchor.setCol1(0);
        anchor.setCol2(4);
        anchor.setRow1(0);
        anchor.setRow2(1);

        Comment comment1 = drawing.createCellComment(anchor);
        comment1.setString(
                factory.createRichTextString("I like this cell. It's my favourite."));
        comment1.setAuthor("Bob T. Fish");

        anchor = factory.createClientAnchor();
        anchor.setCol1(0);
        anchor.setCol2(4);
        anchor.setRow1(1);
        anchor.setRow2(1);
        Comment comment2 = drawing.createCellComment(anchor);
        comment2.setString(
                factory.createRichTextString("This is much less fun..."));
        comment2.setAuthor("Bob T. Fish");

        Cell c1 = sh1.getRow(0).createCell(4);
        c1.setCellValue(2.3);
        c1.setCellComment(comment1);

        Cell c2 = sh1.getRow(0).createCell(5);
        c2.setCellValue(2.1);
        c2.setCellComment(comment2);


        // Save and re-load
        XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1);
        wb1.close();
        sh1 = wb2.getSheetAt(0);
        sh2 = wb2.getSheetAt(1);

        // Check the comments
        assertNotNull(sh2.getCommentsTable(false));
        assertEquals(1, sh2.getCommentsTable(false).getNumberOfComments());

        assertNotNull(sh1.getCommentsTable(false));
        assertEquals(2, sh1.getCommentsTable(false).getNumberOfComments());
        wb2.close();
    }

    /**
     * Sheet names with a , in them
     */
    @Test
    public void bug51963() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("51963.xlsx");
        Sheet sheet = wb.getSheetAt(0);
        assertEquals("Abc,1", sheet.getSheetName());

        Name name = wb.getName("Intekon.ProdCodes");
        assertEquals("'Abc,1'!$A$1:$A$2", name.getRefersToFormula());

        @SuppressWarnings("deprecation")
        AreaReference ref = new AreaReference(name.getRefersToFormula());
        assertEquals(0, ref.getFirstCell().getRow());
        assertEquals(0, ref.getFirstCell().getCol());
        assertEquals(1, ref.getLastCell().getRow());
        assertEquals(0, ref.getLastCell().getCol());
        wb.close();
    }

    /**
     * Sum across multiple workbooks
     *  eg =SUM($Sheet1.C1:$Sheet4.C1)
     * DISABLED As we can't currently evaluate these
     */
    @Ignore
    @Test
    public void bug48703() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48703.xlsx");
        XSSFSheet sheet = wb.getSheetAt(0);

        // Contains two forms, one with a range and one a list
        XSSFRow r1 = sheet.getRow(0);
        XSSFRow r2 = sheet.getRow(1);
        XSSFCell c1 = r1.getCell(1);
        XSSFCell c2 = r2.getCell(1);

        assertEquals(20.0, c1.getNumericCellValue(), 0);
        assertEquals("SUM(Sheet1!C1,Sheet2!C1,Sheet3!C1,Sheet4!C1)", c1.getCellFormula());

        assertEquals(20.0, c2.getNumericCellValue(), 0);
        assertEquals("SUM(Sheet1:Sheet4!C1)", c2.getCellFormula());

        // Try evaluating both
        XSSFFormulaEvaluator eval = new XSSFFormulaEvaluator(wb);
        eval.evaluateFormulaCellEnum(c1);
        eval.evaluateFormulaCellEnum(c2);

        assertEquals(20.0, c1.getNumericCellValue(), 0);
        assertEquals(20.0, c2.getNumericCellValue(), 0);
        wb.close();
    }

    /**
     * Bugzilla 51710: problems reading shared formuals from .xlsx
     */
    @Test
    public void bug51710() throws IOException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("51710.xlsx");

        final String[] columns = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N"};
        final int rowMax = 500; // bug triggers on row index 59

        Sheet sheet = wb.getSheetAt(0);


        // go through all formula cells
        for (int rInd = 2; rInd <= rowMax; rInd++) {
            Row row = sheet.getRow(rInd);

            for (int cInd = 1; cInd <= 12; cInd++) {
                Cell cell = row.getCell(cInd);
                String formula = cell.getCellFormula();
                CellReference ref = new CellReference(cell);

                //simulate correct answer
                String correct = "$A" + (rInd + 1) + "*" + columns[cInd] + "$2";

                assertEquals("Incorrect formula in " + ref.formatAsString(), correct, formula);
            }

        }
        wb.close();
    }

    /**
     * Bug 53101:
     */
    @Test
    public void bug5301() throws IOException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("53101.xlsx");
        FormulaEvaluator evaluator =
                wb.getCreationHelper().createFormulaEvaluator();
        // A1: SUM(B1: IZ1)
        double a1Value =
                evaluator.evaluate(wb.getSheetAt(0).getRow(0).getCell(0)).getNumberValue();

        // Assert
        assertEquals(259.0, a1Value, 0.0);

        // KY: SUM(B1: IZ1)
        /*double ky1Value =*/
                evaluator.evaluate(wb.getSheetAt(0).getRow(0).getCell(310)).getNumberValue();

        // Assert
        assertEquals(259.0, a1Value, 0.0);
        wb.close();
    }

    @Test
    public void bug54436() throws IOException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("54436.xlsx");
        if(!WorkbookEvaluator.getSupportedFunctionNames().contains("GETPIVOTDATA")){
            Function func = new Function() {
                @Override
                public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
                    return ErrorEval.NA;
                }
            };

            WorkbookEvaluator.registerFunction("GETPIVOTDATA", func);
        }
        wb.getCreationHelper().createFormulaEvaluator().evaluateAll();
        wb.close();
    }

    /**
     * Password Protected .xlsx files should give a helpful
     *  error message when called via WorkbookFactory with no password
     */
    @Test(expected=EncryptedDocumentException.class)
    public void bug55692_poifs() throws IOException {
        // Via a POIFSFileSystem
        POIFSFileSystem fsP = new POIFSFileSystem(
            POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx"));
        try {
            WorkbookFactory.create(fsP);
        } finally {
            fsP.close();
        }
    }

    @Test
    public void bug55692_stream() throws IOException, InvalidFormatException {
        // Directly on a Stream, will go via NPOIFS and spot it's
        //  actually a .xlsx file encrypted with the default password, and open
        Workbook wb = WorkbookFactory.create(
                POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx"));
        assertNotNull(wb);
        assertEquals(3, wb.getNumberOfSheets());
        wb.close();
    }

    @Test
    public void bug55692_npoifs() throws IOException {
        // Via a NPOIFSFileSystem, will spot it's actually a .xlsx file
        //  encrypted with the default password, and open
        NPOIFSFileSystem fsNP = new NPOIFSFileSystem(
                POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx"));
        Workbook wb = WorkbookFactory.create(fsNP);
        assertNotNull(wb);
        assertEquals(3, wb.getNumberOfSheets());
        wb.close();
        fsNP.close();
    }

    @Test
    public void bug53282() throws IOException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("53282b.xlsx");
        Cell c = wb.getSheetAt(0).getRow(1).getCell(0);
        assertEquals("#@_#", c.getStringCellValue());
        assertEquals("http://invalid.uri", c.getHyperlink().getAddress());
        wb.close();
    }

    /**
     * Was giving NullPointerException
     * at org.apache.poi.xssf.usermodel.XSSFWorkbook.onDocumentRead
     * due to a lack of Styles Table
     */
    @Test
    public void bug56278() throws IOException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("56278.xlsx");
        assertEquals(0, wb.getSheetIndex("Market Rates"));

        // Save and re-check
        Workbook nwb = XSSFTestDataSamples.writeOutAndReadBack(wb);
        assertEquals(0, nwb.getSheetIndex("Market Rates"));
        nwb.close();
        wb.close();
    }

    @Test
    public void bug56315() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("56315.xlsx");
        Cell c = wb.getSheetAt(0).getRow(1).getCell(0);
        CellValue cv = wb.getCreationHelper().createFormulaEvaluator().evaluate(c);
        double rounded = cv.getNumberValue();
        assertEquals(0.1, rounded, 0.0);
        wb.close();
    }

    @Test
    public void bug56468() throws IOException, InterruptedException {
        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFSheet sheet = wb.createSheet();
        XSSFRow row = sheet.createRow(0);
        XSSFCell cell = row.createCell(0);
        cell.setCellValue("Hi");
        sheet.setRepeatingRows(new CellRangeAddress(0, 0, 0, 0));

        // small hack to try to make this test stable, previously it failed whenever the two written ZIP files had different file-creation
        // dates stored.
        // We try to do a loop until the current second changes in order to avoid problems with some date information that is written to the ZIP and thus
        // causes differences
        long start = System.currentTimeMillis()/1000;
        while(System.currentTimeMillis()/1000 == start) {
            Thread.sleep(10);
        }

        ByteArrayOutputStream bos = new ByteArrayOutputStream(8096);
        wb.write(bos);
        byte firstSave[] = bos.toByteArray();
        bos.reset();
        wb.write(bos);
        byte secondSave[] = bos.toByteArray();

        /*OutputStream stream = new FileOutputStream("C:\\temp\\poi.xlsx");
        try {
            wb.write(stream);
        } finally {
            stream.close();
        }*/

        assertArrayEquals("Had: \n" + Arrays.toString(firstSave) + " and \n" + Arrays.toString(secondSave),
                firstSave, secondSave);

        wb.close();
    }

    /**
     * ISO-8601 style cell formats with a T in them, eg
     * cell format of "yyyy-MM-ddTHH:mm:ss"
     */
    @Test
    public void bug54034() throws IOException {
        TimeZone tz = LocaleUtil.getUserTimeZone();
        LocaleUtil.setUserTimeZone(TimeZone.getTimeZone("CET"));
        try {
            Workbook wb = XSSFTestDataSamples.openSampleWorkbook("54034.xlsx");
            Sheet sheet = wb.getSheet("Sheet1");
            Row row = sheet.getRow(1);
            Cell cell = row.getCell(2);
            assertTrue(DateUtil.isCellDateFormatted(cell));

            DataFormatter fmt = new DataFormatter();
            assertEquals("yyyy\\-mm\\-dd\\Thh:mm", cell.getCellStyle().getDataFormatString());
            assertEquals("2012-08-08T22:59", fmt.formatCellValue(cell));

            wb.close();
        } finally {
            LocaleUtil.setUserTimeZone(tz);
        }
    }


    @Test
    public void testBug53798XLSX() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("53798_shiftNegative_TMPL.xlsx");
        File xlsOutput = TempFile.createTempFile("testBug53798", ".xlsx");
        bug53798Work(wb, xlsOutput);
        wb.close();
    }

    @Ignore("Shifting rows is not yet implemented in SXSSFSheet")
    @Test
    public void testBug53798XLSXStream() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("53798_shiftNegative_TMPL.xlsx");
        File xlsOutput = TempFile.createTempFile("testBug53798", ".xlsx");
        SXSSFWorkbook wb2 = new SXSSFWorkbook(wb);
        bug53798Work(wb2, xlsOutput);
        wb2.close();
        wb.close();
    }

    @Test
    public void testBug53798XLS() throws IOException {
        Workbook wb = HSSFTestDataSamples.openSampleWorkbook("53798_shiftNegative_TMPL.xls");
        File xlsOutput = TempFile.createTempFile("testBug53798", ".xls");
        bug53798Work(wb, xlsOutput);
        wb.close();
    }

    /**
     * SUMIF was throwing a NPE on some formulas
     */
    @Test
    public void testBug56420SumIfNPE() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("56420.xlsx");

        FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();

        Sheet sheet = wb.getSheetAt(0);
        Row r = sheet.getRow(2);
        Cell c = r.getCell(2);
        assertEquals("SUMIF($A$1:$A$4,A3,$B$1:$B$4)", c.getCellFormula());
        Cell eval = evaluator.evaluateInCell(c);
        assertEquals(0.0, eval.getNumericCellValue(), 0.0001);
        wb.close();
    }

    private void bug53798Work(Workbook wb, File xlsOutput) throws IOException {
        Sheet testSheet = wb.getSheetAt(0);

        testSheet.shiftRows(2, 2, 1);

        saveAndReloadReport(wb, xlsOutput);

        // 1) corrupted xlsx (unreadable data in the first row of a shifted group) already comes about
        // when shifted by less than -1 negative amount (try -2)
        testSheet.shiftRows(3, 3, -1);

        saveAndReloadReport(wb, xlsOutput);

        testSheet.shiftRows(2, 2, 1);

        saveAndReloadReport(wb, xlsOutput);

        // 2) attempt to create a new row IN PLACE of a removed row by a negative shift causes corrupted
        // xlsx file with  unreadable data in the negative shifted row.
        // NOTE it's ok to create any other row.
        Row newRow = testSheet.createRow(3);

        saveAndReloadReport(wb, xlsOutput);

        Cell newCell = newRow.createCell(0);

        saveAndReloadReport(wb, xlsOutput);

        newCell.setCellValue("new Cell in row "+newRow.getRowNum());

        saveAndReloadReport(wb, xlsOutput);

        // 3) once a negative shift has been made any attempt to shift another group of rows
        // (note: outside of previously negative shifted rows) by a POSITIVE amount causes POI exception:
        // org.apache.xmlbeans.impl.values.XmlValueDisconnectedException.
        // NOTE: another negative shift on another group of rows is successful, provided no new rows in
        // place of previously shifted rows were attempted to be created as explained above.
        testSheet.shiftRows(6, 7, 1);   // -- CHANGE the shift to positive once the behaviour of
                                        // the above has been tested

        saveAndReloadReport(wb, xlsOutput);
    }

    /**
     * XSSFCell.typeMismatch on certain blank cells when formatting
     *  with DataFormatter
     */
    @Test
    public void bug56702() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("56702.xlsx");

        Sheet sheet = wb.getSheetAt(0);

        // Get wrong cell by row 8 & column 7
        Cell cell = sheet.getRow(8).getCell(7);
        assertEquals(CellType.NUMERIC, cell.getCellTypeEnum());

        // Check the value - will be zero as it is <c><v/></c>
        assertEquals(0.0, cell.getNumericCellValue(), 0.001);

        // Try to format
        DataFormatter formatter = new DataFormatter();
        formatter.formatCellValue(cell);

        // Check the formatting
        assertEquals("0", formatter.formatCellValue(cell));
        wb.close();
    }

    /**
     * Formulas which reference named ranges, either in other
     *  sheets, or workbook scoped but in other workbooks.
     * Used to fail with with errors like
     * org.apache.poi.ss.formula.FormulaParseException: Cell reference expected after sheet name at index 9
     * org.apache.poi.ss.formula.FormulaParseException: Parse error near char 0 '[' in specified formula '[0]!NR_Global_B2'. Expected number, string, or defined name
     */
    @Test
    public void bug56737() throws IOException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("56737.xlsx");

        // Check the named range definitions
        Name nSheetScope = wb.getName("NR_To_A1");
        Name nWBScope = wb.getName("NR_Global_B2");

        assertNotNull(nSheetScope);
        assertNotNull(nWBScope);

        assertEquals("Defines!$A$1", nSheetScope.getRefersToFormula());
        assertEquals("Defines!$B$2", nWBScope.getRefersToFormula());

        // Check the different kinds of formulas
        Sheet s = wb.getSheetAt(0);
        Cell cRefSName = s.getRow(1).getCell(3);
        Cell cRefWName = s.getRow(2).getCell(3);

        assertEquals("Defines!NR_To_A1", cRefSName.getCellFormula());
        // Note the formula, as stored in the file, has the external name index not filename
        // TODO Provide a way to get the one with the filename
        assertEquals("[0]!NR_Global_B2", cRefWName.getCellFormula());

        // Try to evaluate them
        FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator();
        assertEquals("Test A1", eval.evaluate(cRefSName).getStringValue());
        assertEquals(142, (int)eval.evaluate(cRefWName).getNumberValue());

        // Try to evaluate everything
        eval.evaluateAll();
        wb.close();
    }

    private void saveAndReloadReport(Workbook wb, File outFile) throws IOException {
        // run some method on the font to verify if it is "disconnected" already
        //for(short i = 0;i < 256;i++)
        {
            Font font = wb.getFontAt((short)0);
            if(font instanceof XSSFFont) {
                XSSFFont xfont = (XSSFFont) wb.getFontAt((short)0);
                CTFontImpl ctFont = (CTFontImpl) xfont.getCTFont();
                assertEquals(0, ctFont.sizeOfBArray());
            }
        }

        FileOutputStream fileOutStream = new FileOutputStream(outFile);
        try {
            wb.write(fileOutStream);
        } finally {
            fileOutStream.close();
        }

        FileInputStream is = new FileInputStream(outFile);
        try {
            Workbook newWB = null;
            try {
                if(wb instanceof XSSFWorkbook) {
                    newWB = new XSSFWorkbook(is);
                } else if(wb instanceof HSSFWorkbook) {
                    newWB = new HSSFWorkbook(is);
                } else if(wb instanceof SXSSFWorkbook) {
                    newWB = new SXSSFWorkbook(new XSSFWorkbook(is));
                } else {
                    throw new IllegalStateException("Unknown workbook: " + wb);
                }
                assertNotNull(newWB.getSheet("test"));
            } finally {
                if (newWB != null) {
                    newWB.close();
                }
            }
        } finally {
            is.close();
        }
    }

    @Test
    public void testBug56688_1() throws IOException {
        XSSFWorkbook excel = XSSFTestDataSamples.openSampleWorkbook("56688_1.xlsx");
        checkValue(excel, "-1.0");  /* Not 0.0 because POI sees date "0" minus one month as invalid date, which is -1! */
        excel.close();
    }

    @Test
    public void testBug56688_2() throws IOException {
        XSSFWorkbook excel = XSSFTestDataSamples.openSampleWorkbook("56688_2.xlsx");
        checkValue(excel, "#VALUE!");
        excel.close();
    }

    @Test
    public void testBug56688_3() throws IOException {
        XSSFWorkbook excel = XSSFTestDataSamples.openSampleWorkbook("56688_3.xlsx");
        checkValue(excel, "#VALUE!");
        excel.close();
    }

    @Test
    public void testBug56688_4() throws IOException {
        XSSFWorkbook excel = XSSFTestDataSamples.openSampleWorkbook("56688_4.xlsx");

        Calendar calendar = LocaleUtil.getLocaleCalendar();
        calendar.add(Calendar.MONTH, 2);
        double excelDate = DateUtil.getExcelDate(calendar.getTime());
        NumberEval eval = new NumberEval(Math.floor(excelDate));
        checkValue(excel, eval.getStringValue() + ".0");

        excel.close();
    }

    /**
     * New hyperlink with no initial cell reference, still need
     *  to be able to change it
     * @throws IOException
     */
    @Test
    public void testBug56527() throws IOException {
        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFSheet sheet = wb.createSheet();
        XSSFCreationHelper creationHelper = wb.getCreationHelper();
        XSSFHyperlink hyperlink;

        // Try with a cell reference
        hyperlink = creationHelper.createHyperlink(HyperlinkType.URL);
        sheet.addHyperlink(hyperlink);
        hyperlink.setAddress("http://myurl");
        hyperlink.setCellReference("B4");
        assertEquals(3, hyperlink.getFirstRow());
        assertEquals(1, hyperlink.getFirstColumn());
        assertEquals(3, hyperlink.getLastRow());
        assertEquals(1, hyperlink.getLastColumn());

        // Try with explicit rows / columns
        hyperlink = creationHelper.createHyperlink(HyperlinkType.URL);
        sheet.addHyperlink(hyperlink);
        hyperlink.setAddress("http://myurl");
        hyperlink.setFirstRow(5);
        hyperlink.setFirstColumn(3);

        assertEquals(5, hyperlink.getFirstRow());
        assertEquals(3, hyperlink.getFirstColumn());
        assertEquals(5, hyperlink.getLastRow());
        assertEquals(3, hyperlink.getLastColumn());
        wb.close();
    }

    /**
     * Shifting rows with a formula that references a
     * function in another file
     */
    @Test
    public void bug56502() throws IOException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("56502.xlsx");
        Sheet sheet = wb.getSheetAt(0);

        Cell cFunc = sheet.getRow(3).getCell(0);
        assertEquals("[1]!LUCANET(\"Ist\")", cFunc.getCellFormula());
        Cell cRef = sheet.getRow(3).createCell(1);
        cRef.setCellFormula("A3");

        // Shift it down one row
        sheet.shiftRows(1, sheet.getLastRowNum(), 1);

        // Check the new formulas: Function won't change, Reference will
        cFunc = sheet.getRow(4).getCell(0);
        assertEquals("[1]!LUCANET(\"Ist\")", cFunc.getCellFormula());
        cRef = sheet.getRow(4).getCell(1);
        assertEquals("A4", cRef.getCellFormula());
        wb.close();
    }

    @Test
    public void bug54764() throws IOException, OpenXML4JException, XmlException {
        OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("54764.xlsx");

        // Check the core properties - will be found but empty, due
        //  to the expansion being too much to be considered valid
        POIXMLProperties props = new POIXMLProperties(pkg);
        assertEquals(null, props.getCoreProperties().getTitle());
        assertEquals(null, props.getCoreProperties().getSubject());
        assertEquals(null, props.getCoreProperties().getDescription());

        // Now check the spreadsheet itself
        try {
            new XSSFWorkbook(pkg).close();
            fail("Should fail as too much expansion occurs");
        } catch(POIXMLException e) {
            // Expected
        }
        pkg.close();

        // Try with one with the entities in the Content Types
        try {
            XSSFTestDataSamples.openSamplePackage("54764-2.xlsx").close();
            fail("Should fail as too much expansion occurs");
        } catch(Exception e) {
            // Expected
        }

        // Check we can still parse valid files after all that
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("sample.xlsx");
        assertEquals(3, wb.getNumberOfSheets());
        wb.close();
    }

    /**
     * CTDefinedNamesImpl should be included in the smaller
     *  poi-ooxml-schemas jar
     */
    @Test
    public void bug57176() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57176.xlsx");
        CTDefinedNames definedNames = wb.getCTWorkbook().getDefinedNames();
        List<CTDefinedName> definedNameList = definedNames.getDefinedNameList();
        for (CTDefinedName defName : definedNameList) {
            assertNotNull(defName.getName());
            assertNotNull(defName.getStringValue());
        }
        assertEquals("TestDefinedName", definedNameList.get(0).getName());
        wb.close();
    }

    /**
     * .xlsb files are not supported, but we should generate a helpful
     *  error message if given one
     */
    @Test
    public void bug56800_xlsb() throws IOException, InvalidFormatException {
        // Can be opened at the OPC level
        OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("Simple.xlsb");

        // XSSF Workbook gives helpful error
        try {
            new XSSFWorkbook(pkg).close();
            fail(".xlsb files not supported");
        } catch (XLSBUnsupportedException e) {
            // Good, detected and warned
        }

        // Workbook Factory gives helpful error on package
        try {
            WorkbookFactory.create(pkg).close();
            fail(".xlsb files not supported");
        } catch (XLSBUnsupportedException e) {
            // Good, detected and warned
        }

        // Workbook Factory gives helpful error on file
        File xlsbFile = HSSFTestDataSamples.getSampleFile("Simple.xlsb");
        try {
            WorkbookFactory.create(xlsbFile).close();
            fail(".xlsb files not supported");
        } catch (XLSBUnsupportedException e) {
            // Good, detected and warned
        }
        
        pkg.close();
    }

    private void checkValue(XSSFWorkbook excel, String expect) {
        XSSFFormulaEvaluator evaluator = new XSSFFormulaEvaluator(excel);
        evaluator.evaluateAll();

        XSSFCell cell = excel.getSheetAt(0).getRow(1).getCell(1);
        CellValue value = evaluator.evaluate(cell);

        assertEquals(expect, value.formatAsString());
    }

    @Test
    public void testBug57196() throws IOException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("57196.xlsx");
        Sheet sheet = wb.getSheet("Feuil1");
        Row mod=sheet.getRow(1);
        mod.getCell(1).setCellValue(3);
        HSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
//        FileOutputStream fileOutput = new FileOutputStream("/tmp/57196.xlsx");
//        wb.write(fileOutput);
//        fileOutput.close();
        wb.close();
    }

    @Test
    public void test57196_Detail() throws IOException {
        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFSheet sheet = wb.createSheet("Sheet1");
        XSSFRow row = sheet.createRow(0);
        XSSFCell cell = row.createCell(0);
        cell.setCellFormula("DEC2HEX(HEX2DEC(O8)-O2+D2)");
        XSSFFormulaEvaluator fe = new XSSFFormulaEvaluator(wb);
        CellValue cv = fe.evaluate(cell);

        assertNotNull(cv);
        wb.close();
    }

    @Test
    public void test57196_Detail2() throws IOException {
        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFSheet sheet = wb.createSheet("Sheet1");
        XSSFRow row = sheet.createRow(0);
        XSSFCell cell = row.createCell(0);
        cell.setCellFormula("DEC2HEX(O2+D2)");
        XSSFFormulaEvaluator fe = new XSSFFormulaEvaluator(wb);
        CellValue cv = fe.evaluate(cell);

        assertNotNull(cv);
        wb.close();
    }

    @Test
    public void test57196_WorkbookEvaluator() throws IOException {
        String previousLogger = System.getProperty("org.apache.poi.util.POILogger");
        //System.setProperty("org.apache.poi.util.POILogger", "org.apache.poi.util.SystemOutLogger");
        //System.setProperty("poi.log.level", "3");
        try {
            XSSFWorkbook wb = new XSSFWorkbook();
            XSSFSheet sheet = wb.createSheet("Sheet1");
            XSSFRow row = sheet.createRow(0);
            XSSFCell cell = row.createCell(0);
            cell.setCellValue("0");
            cell = row.createCell(1);
            cell.setCellValue(0);
            cell = row.createCell(2);
            cell.setCellValue(0);

            // simple formula worked
            cell.setCellFormula("DEC2HEX(O2+D2)");

            WorkbookEvaluator workbookEvaluator = new WorkbookEvaluator(XSSFEvaluationWorkbook.create(wb), null, null);
            workbookEvaluator.setDebugEvaluationOutputForNextEval(true);
            workbookEvaluator.evaluate(new XSSFEvaluationCell(cell));

            // this already failed! Hex2Dec did not correctly handle RefEval
            cell.setCellFormula("HEX2DEC(O8)");
            workbookEvaluator.clearAllCachedResultValues();

            workbookEvaluator = new WorkbookEvaluator(XSSFEvaluationWorkbook.create(wb), null, null);
            workbookEvaluator.setDebugEvaluationOutputForNextEval(true);
            workbookEvaluator.evaluate(new XSSFEvaluationCell(cell));

            // slightly more complex one failed
            cell.setCellFormula("HEX2DEC(O8)-O2+D2");
            workbookEvaluator.clearAllCachedResultValues();

            workbookEvaluator = new WorkbookEvaluator(XSSFEvaluationWorkbook.create(wb), null, null);
            workbookEvaluator.setDebugEvaluationOutputForNextEval(true);
            workbookEvaluator.evaluate(new XSSFEvaluationCell(cell));

            // more complicated failed
            cell.setCellFormula("DEC2HEX(HEX2DEC(O8)-O2+D2)");
            workbookEvaluator.clearAllCachedResultValues();

            workbookEvaluator.setDebugEvaluationOutputForNextEval(true);
            workbookEvaluator.evaluate(new XSSFEvaluationCell(cell));

            // what other similar functions
            cell.setCellFormula("DEC2BIN(O8)-O2+D2");
            workbookEvaluator.clearAllCachedResultValues();

            workbookEvaluator = new WorkbookEvaluator(XSSFEvaluationWorkbook.create(wb), null, null);
            workbookEvaluator.setDebugEvaluationOutputForNextEval(true);
            workbookEvaluator.evaluate(new XSSFEvaluationCell(cell));

            // what other similar functions
            cell.setCellFormula("DEC2BIN(A1)");
            workbookEvaluator.clearAllCachedResultValues();

            workbookEvaluator = new WorkbookEvaluator(XSSFEvaluationWorkbook.create(wb), null, null);
            workbookEvaluator.setDebugEvaluationOutputForNextEval(true);
            workbookEvaluator.evaluate(new XSSFEvaluationCell(cell));

            // what other similar functions
            cell.setCellFormula("BIN2DEC(B1)");
            workbookEvaluator.clearAllCachedResultValues();

            workbookEvaluator = new WorkbookEvaluator(XSSFEvaluationWorkbook.create(wb), null, null);
            workbookEvaluator.setDebugEvaluationOutputForNextEval(true);
            workbookEvaluator.evaluate(new XSSFEvaluationCell(cell));
            
            wb.close();
        } finally {
            if(previousLogger == null) {
                System.clearProperty("org.apache.poi.util.POILogger");
            } else {
                System.setProperty("org.apache.poi.util.POILogger", previousLogger);
            }
            System.clearProperty("poi.log.level");
        }
    }

    /**
     * A .xlsx file with no Shared Strings table should open fine
     *  in read-only mode
     */
    @SuppressWarnings("resource")
    @Test
    public void bug57482() throws IOException, InvalidFormatException {
        for (PackageAccess access : new PackageAccess[] {
                PackageAccess.READ_WRITE, PackageAccess.READ
        }) {
            File file = HSSFTestDataSamples.getSampleFile("57482-OnlyNumeric.xlsx");
            OPCPackage pkg = OPCPackage.open(file, access);
            try {
                // Try to open it and read the contents
                XSSFWorkbook wb1 = new XSSFWorkbook(pkg);
                assertNotNull(wb1.getSharedStringSource());
                assertEquals(0, wb1.getSharedStringSource().getCount());

                DataFormatter fmt = new DataFormatter();
                XSSFSheet s = wb1.getSheetAt(0);
                assertEquals("1",  fmt.formatCellValue(s.getRow(0).getCell(0)));
                assertEquals("11", fmt.formatCellValue(s.getRow(0).getCell(1)));
                assertEquals("5",  fmt.formatCellValue(s.getRow(4).getCell(0)));

                // Add a text cell
                s.getRow(0).createCell(3).setCellValue("Testing");
                assertEquals("Testing",  fmt.formatCellValue(s.getRow(0).getCell(3)));

                // Try to write-out and read again, should only work
                //  in read-write mode, not read-only mode
                XSSFWorkbook wb2 = null;
                try {
                    wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1);
                    if (access == PackageAccess.READ) {
                        fail("Shouln't be able to write from read-only mode");
                    }

                    // Check again
                    s = wb2.getSheetAt(0);
                    assertEquals("1",  fmt.formatCellValue(s.getRow(0).getCell(0)));
                    assertEquals("11", fmt.formatCellValue(s.getRow(0).getCell(1)));
                    assertEquals("5",  fmt.formatCellValue(s.getRow(4).getCell(0)));
                    assertEquals("Testing",  fmt.formatCellValue(s.getRow(0).getCell(3)));
                
                } catch (InvalidOperationException e) {
                    if (access == PackageAccess.READ_WRITE) {
                        // Shouldn't occur in write-mode
                        throw e;
                    }
                } finally {
                    if (wb2 != null) {
                        wb2.getPackage().revert();
                    }
                }
                
                wb1.getPackage().revert();
            } finally {
                pkg.revert();
            }
        }
    }

    /**
     * "Unknown error type: -60" fetching formula error value
     */
    @Test
    public void bug57535() throws IOException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("57535.xlsx");
        FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
        evaluator.clearAllCachedResultValues();

        Sheet sheet = wb.getSheet("Sheet1");
        Cell cell = sheet.getRow(5).getCell(4);
        assertEquals(CellType.FORMULA, cell.getCellTypeEnum());
        assertEquals("E4+E5", cell.getCellFormula());

        CellValue value = evaluator.evaluate(cell);
        assertEquals(CellType.ERROR, value.getCellType());
        assertEquals(-60, value.getErrorValue());
        assertEquals("~CIRCULAR~REF~", FormulaError.forInt(value.getErrorValue()).getString());
        assertEquals("CIRCULAR_REF", FormulaError.forInt(value.getErrorValue()).toString());
        
        wb.close();
    }


    @Test
    public void test57165() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57171_57163_57165.xlsx");
        try {
            removeAllSheetsBut(3, wb);
            wb.cloneSheet(0); // Throws exception here
            wb.setSheetName(1, "New Sheet");
            //saveWorkbook(wb, fileName);

            XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb);
            wbBack.close();
        } finally {
            wb.close();
        }
    }

    @Test
    public void test57165_create() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57171_57163_57165.xlsx");
        try {
            removeAllSheetsBut(3, wb);
            wb.createSheet("newsheet"); // Throws exception here
            wb.setSheetName(1, "New Sheet");
            //saveWorkbook(wb, fileName);

            XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb);
            wbBack.close();
        } finally {
            wb.close();
        }
    }

    private static void removeAllSheetsBut(int sheetIndex, Workbook wb)
    {
        int sheetNb = wb.getNumberOfSheets();
        // Move this sheet at the first position
        wb.setSheetOrder(wb.getSheetName(sheetIndex), 0);
        for (int sn = sheetNb - 1; sn > 0; sn--)
        {
            wb.removeSheetAt(sn);
        }
    }

    /**
     * Sums 2 plus the cell at the left, indirectly to avoid reference
     * problems when deleting columns, conditionally to stop recursion
     */
    private static final String FORMULA1 =
            "IF( INDIRECT( ADDRESS( ROW(), COLUMN()-1 ) ) = 0, 0,"
                    + "INDIRECT( ADDRESS( ROW(), COLUMN()-1 ) ) ) + 2";

    /**
     * Sums 2 plus the upper cell, indirectly to avoid reference
     * problems when deleting rows, conditionally to stop recursion
     */
    private static final String FORMULA2 =
            "IF( INDIRECT( ADDRESS( ROW()-1, COLUMN() ) ) = 0, 0,"
                    + "INDIRECT( ADDRESS( ROW()-1, COLUMN() ) ) ) + 2";

    /**
     * Expected:

     * [  0][  2][  4]
     * @throws IOException
     */
    @Test
    public void testBug56820_Formula1() throws IOException {
        Workbook wb = new XSSFWorkbook();
        try {
            FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
            Sheet sh = wb.createSheet();

            sh.createRow(0).createCell(0).setCellValue(0.0d);
            Cell formulaCell1 = sh.getRow(0).createCell(1);
            Cell formulaCell2 = sh.getRow(0).createCell(2);
            formulaCell1.setCellFormula(FORMULA1);
            formulaCell2.setCellFormula(FORMULA1);

            double A1 = evaluator.evaluate(formulaCell1).getNumberValue();
            double A2 = evaluator.evaluate(formulaCell2).getNumberValue();

            assertEquals(2, A1, 0);
            assertEquals(4, A2, 0);  //<-- FAILS EXPECTATIONS
        } finally {
            wb.close();
        }
    }

    /**
     * Expected:

     * [  0] <- number
     * [  2] <- formula
     * [  4] <- formula
     * @throws IOException
     */
    @Test
    public void testBug56820_Formula2() throws IOException {
        Workbook wb = new XSSFWorkbook();
        try {
            FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
            Sheet sh = wb.createSheet();

            sh.createRow(0).createCell(0).setCellValue(0.0d);
            Cell formulaCell1 = sh.createRow(1).createCell(0);
            Cell formulaCell2 = sh.createRow(2).createCell(0);
            formulaCell1.setCellFormula(FORMULA2);
            formulaCell2.setCellFormula(FORMULA2);

            double A1 = evaluator.evaluate(formulaCell1).getNumberValue();
            double A2 = evaluator.evaluate(formulaCell2).getNumberValue(); //<-- FAILS EVALUATION

            assertEquals(2, A1, 0);
            assertEquals(4, A2, 0);
        } finally {
            wb.close();
        }
    }

    @Test
    public void test56467() throws IOException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("picture.xlsx");
        try {
            Sheet orig = wb.getSheetAt(0);
            assertNotNull(orig);

            Sheet sheet = wb.cloneSheet(0);
            Drawing drawing = sheet.createDrawingPatriarch();
            for (XSSFShape shape : ((XSSFDrawing) drawing).getShapes()) {
                if (shape instanceof XSSFPicture) {
                    XSSFPictureData pictureData = ((XSSFPicture) shape).getPictureData();
                    assertNotNull(pictureData);
                }
            }

        } finally {
        	wb.close();
        }
    }

    /**
     * OOXML-Strict files
     * Not currently working - namespace mis-match from XMLBeans
     */
    @Test
    @Ignore("XMLBeans namespace mis-match on ooxml-strict files")
    public void test57699() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("sample.strict.xlsx");
        assertEquals(3, wb.getNumberOfSheets());
        // TODO Check sheet contents
        // TODO Check formula evaluation

        XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb);
        assertEquals(3, wbBack.getNumberOfSheets());
        // TODO Re-check sheet contents
        // TODO Re-check formula evaluation
        
        wb.close();
        wbBack.close();
    }

    @Test
    public void testBug56295_MergeXlslsWithStyles() throws IOException {
        XSSFWorkbook xlsToAppendWorkbook = XSSFTestDataSamples.openSampleWorkbook("56295.xlsx");
        XSSFSheet sheet = xlsToAppendWorkbook.getSheetAt(0);
        XSSFRow srcRow = sheet.getRow(0);
        XSSFCell oldCell = srcRow.getCell(0);
        XSSFCellStyle cellStyle = oldCell.getCellStyle();

        checkStyle(cellStyle);

//        StylesTable table = xlsToAppendWorkbook.getStylesSource();
//        List<XSSFCellFill> fills = table.getFills();
//        System.out.println("Having " + fills.size() + " fills");
//        for(XSSFCellFill fill : fills) {
//        	System.out.println("Fill: " + fill.getFillBackgroundColor() + "/" + fill.getFillForegroundColor());
//        }
        xlsToAppendWorkbook.close();

        XSSFWorkbook targetWorkbook = new XSSFWorkbook();
        XSSFSheet newSheet = targetWorkbook.createSheet(sheet.getSheetName());
        XSSFRow destRow = newSheet.createRow(0);
        XSSFCell newCell = destRow.createCell(0);

		//newCell.getCellStyle().cloneStyleFrom(cellStyle);
        CellStyle newCellStyle = targetWorkbook.createCellStyle();
        newCellStyle.cloneStyleFrom(cellStyle);
        newCell.setCellStyle(newCellStyle);
		checkStyle(newCell.getCellStyle());
        newCell.setCellValue(oldCell.getStringCellValue());

//        OutputStream os = new FileOutputStream("output.xlsm");
//        try {
//        	targetWorkbook.write(os);
//        } finally {
//        	os.close();
//        }

        XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(targetWorkbook);
        XSSFCellStyle styleBack = wbBack.getSheetAt(0).getRow(0).getCell(0).getCellStyle();
        checkStyle(styleBack);
        
        targetWorkbook.close();
        wbBack.close();
    }

    /**
     * Paragraph with property BuFont but none of the properties
     *  BuNone, BuChar, and BuAutoNum, used to trigger a NPE
     * Excel treats this as not-bulleted, so now do we
     */
    @Test
    public void testBug57826() throws IOException {
        XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("57826.xlsx");

        assertTrue("no sheets in workbook", workbook.getNumberOfSheets() >= 1);
        XSSFSheet sheet = workbook.getSheetAt(0);

        XSSFDrawing drawing = sheet.getDrawingPatriarch();
        assertNotNull(drawing);

        List<XSSFShape> shapes = drawing.getShapes();
        assertEquals(1, shapes.size());
        assertTrue(shapes.get(0) instanceof XSSFSimpleShape);

        XSSFSimpleShape shape = (XSSFSimpleShape)shapes.get(0);

        // Used to throw a NPE
        String text = shape.getText();

        // No bulleting info included
        assertEquals("test ok", text);
        
        workbook.close();
    }

	private void checkStyle(XSSFCellStyle cellStyle) {
		assertNotNull(cellStyle);
        assertEquals(0, cellStyle.getFillForegroundColor());
        assertNotNull(cellStyle.getFillForegroundXSSFColor());
        XSSFColor fgColor = cellStyle.getFillForegroundColorColor();
		assertNotNull(fgColor);
		assertEquals("FF00FFFF", fgColor.getARGBHex());

        assertEquals(0, cellStyle.getFillBackgroundColor());
        assertNotNull(cellStyle.getFillBackgroundXSSFColor());
        XSSFColor bgColor = cellStyle.getFillBackgroundColorColor();
		assertNotNull(bgColor);
		assertEquals("FF00FFFF", fgColor.getARGBHex());
	}

    @Test
    public void bug57642() throws IOException {
        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFSheet s = wb.createSheet("TestSheet");
        XSSFCell c = s.createRow(0).createCell(0);
        c.setCellFormula("ISERROR(TestSheet!A1)");
        c = s.createRow(1).createCell(1);
        c.setCellFormula("ISERROR(B2)");

        wb.setSheetName(0, "CSN");
        c = s.getRow(0).getCell(0);
        assertEquals("ISERROR(CSN!A1)", c.getCellFormula());
        c = s.getRow(1).getCell(1);
        assertEquals("ISERROR(B2)", c.getCellFormula());

        wb.close();
    }

    /**
     * .xlsx supports 64000 cell styles, the style indexes after
     *  32,767 must not be -32,768, then -32,767, -32,766
     */
    @SuppressWarnings("resource")
    @Test
    public void bug57880() throws IOException {
        int numStyles = 33000;
        XSSFWorkbook wb = new XSSFWorkbook();
        for (int i=1; i<numStyles; i++) {
            // Create a style and use it
            XSSFCellStyle style = wb.createCellStyle();
            assertEquals(i, style.getUIndex());
        }
        assertEquals(numStyles, wb.getNumCellStyles());

        // avoid OOM in gump run
        File file = XSSFTestDataSamples.writeOutAndClose(wb, "bug57880");
        //noinspection UnusedAssignment
        wb = null;
        // Garbage collection may happen here
        
        // avoid zip bomb detection
        double ratio = ZipSecureFile.getMinInflateRatio();
        ZipSecureFile.setMinInflateRatio(0.00005);
        wb = XSSFTestDataSamples.readBackAndDelete(file);
        ZipSecureFile.setMinInflateRatio(ratio);

        //Assume identical cell styles aren't consolidated
        //If XSSFWorkbooks ever implicitly optimize/consolidate cell styles (such as when the workbook is written to disk)
        //then this unit test should be updated
        assertEquals(numStyles, wb.getNumCellStyles());
        for (int i=1; i<numStyles; i++) {
            XSSFCellStyle style = wb.getCellStyleAt(i);
            assertNotNull(style);
            assertEquals(i, style.getUIndex());
        }
        wb.close();
    }


    @Test
    public void test56574() throws IOException {
        runTest56574(false);
        runTest56574(true);
    }

    private void runTest56574(boolean createRow) throws IOException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("56574.xlsx");

        Sheet sheet = wb.getSheet("Func");
        assertNotNull(sheet);

        Map<String, Object[]> data;
        data = new TreeMap<String, Object[]>();
        data.put("1", new Object[] {"ID", "NAME", "LASTNAME"});
        data.put("2", new Object[] {2, "Amit", "Shukla"});
        data.put("3", new Object[] {1, "Lokesh", "Gupta"});
        data.put("4", new Object[] {4, "John", "Adwards"});
        data.put("5", new Object[] {2, "Brian", "Schultz"});

        int rownum = 1;
        for (Map.Entry<String,Object[]> me : data.entrySet()) {
            final Row row;
            if(createRow) {
                row = sheet.createRow(rownum++);
            } else {
                row = sheet.getRow(rownum++);
            }
            assertNotNull(row);

            int cellnum = 0;
            for (Object obj : me.getValue()) {
                Cell cell = row.getCell(cellnum);
                if(cell == null){
                    cell = row.createCell(cellnum);
                } else {
                    if(cell.getCellTypeEnum() == CellType.FORMULA) {
                        cell.setCellFormula(null);
                        cell.getCellStyle().setDataFormat((short) 0);
                    }
                }
               if(obj instanceof String) {
                    cell.setCellValue((String)obj);
               } else if(obj instanceof Integer) {
                    cell.setCellValue((Integer)obj);
               }
               cellnum++;
            }
        }

        XSSFFormulaEvaluator.evaluateAllFormulaCells((XSSFWorkbook) wb);
        wb.getCreationHelper().createFormulaEvaluator().evaluateAll();

        CalculationChain chain = ((XSSFWorkbook)wb).getCalculationChain();
        for(CTCalcCell calc : chain.getCTCalcChain().getCList()) {
            // A2 to A6 should be gone
            assertFalse(calc.getR().equals("A2"));
            assertFalse(calc.getR().equals("A3"));
            assertFalse(calc.getR().equals("A4"));
            assertFalse(calc.getR().equals("A5"));
            assertFalse(calc.getR().equals("A6"));
        }

        Workbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb);
        Sheet sheetBack = wbBack.getSheet("Func");
        assertNotNull(sheetBack);

        chain = ((XSSFWorkbook)wbBack).getCalculationChain();
        for(CTCalcCell calc : chain.getCTCalcChain().getCList()) {
            // A2 to A6 should be gone
            assertFalse(calc.getR().equals("A2"));
            assertFalse(calc.getR().equals("A3"));
            assertFalse(calc.getR().equals("A4"));
            assertFalse(calc.getR().equals("A5"));
            assertFalse(calc.getR().equals("A6"));
        }

        wbBack.close();
        wb.close();
    }

    /**
     * Excel 2007 generated Macro-Enabled .xlsm file
     */
    @Test
    public void bug57181() throws IOException {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57181.xlsm");
        assertEquals(9, wb.getNumberOfSheets());
        wb.close();
    }

    @Test
    public void bug52111() throws IOException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("Intersection-52111-xssf.xlsx");
        Sheet s = wb.getSheetAt(0);
        assertFormula(wb, s.getRow(2).getCell(0), "(C2:D3 D3:E4)", "4.0");
        assertFormula(wb, s.getRow(6).getCell(0), "Tabelle2!E:E Tabelle2!11:11", "5.0");
        assertFormula(wb, s.getRow(8).getCell(0), "Tabelle2!E:F Tabelle2!11:12", null);
        wb.close();
    }

    private void assertFormula(Workbook wb, Cell intF, String expectedFormula, String expectedResultOrNull) {
        assertEquals(CellType.FORMULA, intF.getCellTypeEnum());
        if (null == expectedResultOrNull) {
            assertEquals(CellType.ERROR, intF.getCachedFormulaResultTypeEnum());
            expectedResultOrNull = "#VALUE!";
        }
        else {
            assertEquals(CellType.NUMERIC, intF.getCachedFormulaResultTypeEnum());
        }

        assertEquals(expectedFormula, intF.getCellFormula());

        // Check we can evaluate it correctly
        FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator();
        assertEquals(expectedResultOrNull, eval.evaluate(intF).formatAsString());
    }

    @Test
    public void test48962() throws IOException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("48962.xlsx");
        Sheet sh = wb.getSheetAt(0);
        Row row = sh.getRow(1);
        Cell cell = row.getCell(0);

        CellStyle style = cell.getCellStyle();
        assertNotNull(style);

        // color index
        assertEquals(64, style.getFillBackgroundColor());
        XSSFColor color = ((XSSFCellStyle)style).getFillBackgroundXSSFColor();
        assertNotNull(color);

        // indexed color
        assertEquals(64, color.getIndexed());
        assertEquals(64, color.getIndex());

        // not an RGB color
        assertFalse(color.isRGB());
        assertNull(color.getRGB());
        wb.close();
    }

    @Test
    public void test50755_workday_formula_example() throws IOException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("50755_workday_formula_example.xlsx");
        Sheet sheet = wb.getSheet("Sheet1");
        for(Row aRow : sheet) {
            Cell cell = aRow.getCell(1);
            if(cell.getCellTypeEnum() == CellType.FORMULA) {
                String formula = cell.getCellFormula();
                //System.out.println("formula: " + formula);
                assertNotNull(formula);
                assertTrue(formula.contains("WORKDAY"));
            } else {
                assertNotNull(cell.toString());
            }
        }
        wb.close();
    }

    @Test
    public void test51626() throws IOException, InvalidFormatException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("51626.xlsx");
        assertNotNull(wb);
        wb.close();

        InputStream stream = HSSFTestDataSamples.openSampleFileStream("51626.xlsx");
        wb = WorkbookFactory.create(stream);
        stream.close();
        wb.close();

        wb = XSSFTestDataSamples.openSampleWorkbook("51626_contact.xlsx");
        assertNotNull(wb);
        wb.close();

        stream = HSSFTestDataSamples.openSampleFileStream("51626_contact.xlsx");
        wb = WorkbookFactory.create(stream);
        stream.close();
        wb.close();
    }

    @Test
    public void test51451() throws IOException {
        Workbook wb = new XSSFWorkbook();
        Sheet sh = wb.createSheet();

        Row row = sh.createRow(0);
        Cell cell = row.createCell(0);
        cell.setCellValue(239827342);

        CellStyle style = wb.createCellStyle();
        //style.setHidden(false);
        DataFormat excelFormat = wb.createDataFormat();
        style.setDataFormat(excelFormat.getFormat("#,##0"));
        sh.setDefaultColumnStyle(0, style);

//        FileOutputStream out = new FileOutputStream("/tmp/51451.xlsx");
//        wb.write(out);
//        out.close();

        wb.close();
    }

    @Test
    public void test53105() throws IOException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("53105.xlsx");
        assertNotNull(wb);


        // Act
        // evaluate SUM('Skye Lookup Input'!A4:XFD4), cells in range each contain "1"
        FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
        double numericValue = evaluator.evaluate(wb.getSheetAt(0).getRow(1).getCell(0)).getNumberValue();

        // Assert
        assertEquals(16384.0, numericValue, 0.0);

        wb.close();
    }


    @Test
    public void test58315() throws IOException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("58315.xlsx");
        Cell cell = wb.getSheetAt(0).getRow(0).getCell(0);
        assertNotNull(cell);
        StringBuilder tmpCellContent = new StringBuilder(cell.getStringCellValue());
        XSSFRichTextString richText = (XSSFRichTextString) cell.getRichStringCellValue();

        for (int i = richText.length() - 1; i >= 0; i--) {
            Font f = richText.getFontAtIndex(i);
            if (f != null && f.getStrikeout()) {
                tmpCellContent.deleteCharAt(i);
            }
        }
        String result = tmpCellContent.toString();
        assertEquals("320 350", result);

        wb.close();
    }

    @Test
    public void test55406() throws IOException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("55406_Conditional_formatting_sample.xlsx");
        Sheet sheet = wb.getSheetAt(0);
        Cell cellA1 = sheet.getRow(0).getCell(0);
        Cell cellA2 = sheet.getRow(1).getCell(0);
        
        assertEquals(0, cellA1.getCellStyle().getFillForegroundColor());
        assertEquals("FFFDFDFD", ((XSSFColor)cellA1.getCellStyle().getFillForegroundColorColor()).getARGBHex());
        assertEquals(0, cellA2.getCellStyle().getFillForegroundColor());
        assertEquals("FFFDFDFD", ((XSSFColor)cellA2.getCellStyle().getFillForegroundColorColor()).getARGBHex());
        
        SheetConditionalFormatting cond = sheet.getSheetConditionalFormatting();
        assertEquals(2, cond.getNumConditionalFormattings());

        assertEquals(1, cond.getConditionalFormattingAt(0).getNumberOfRules());
        assertEquals(64, cond.getConditionalFormattingAt(0).getRule(0).getPatternFormatting().getFillForegroundColor());
        assertEquals("ISEVEN(ROW())", cond.getConditionalFormattingAt(0).getRule(0).getFormula1());
        assertNull(((XSSFColor)cond.getConditionalFormattingAt(0).getRule(0).getPatternFormatting().getFillForegroundColorColor()).getARGBHex());

        assertEquals(1, cond.getConditionalFormattingAt(1).getNumberOfRules());
        assertEquals(64, cond.getConditionalFormattingAt(1).getRule(0).getPatternFormatting().getFillForegroundColor()); 
        assertEquals("ISEVEN(ROW())", cond.getConditionalFormattingAt(1).getRule(0).getFormula1());
        assertNull(((XSSFColor)cond.getConditionalFormattingAt(1).getRule(0).getPatternFormatting().getFillForegroundColorColor()).getARGBHex()); 
        
        wb.close();
    }

    @Test
    public void test51998() throws IOException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("51998.xlsx");
        
        Set<String> sheetNames = new HashSet<String>();
        
        for (int sheetNum = 0; sheetNum < wb.getNumberOfSheets(); sheetNum++)
        {
            sheetNames.add(wb.getSheetName(sheetNum));
        }
        
        for (String sheetName : sheetNames)
        {
            int sheetIndex = wb.getSheetIndex(sheetName);
            
            wb.removeSheetAt(sheetIndex);
            
            Sheet newSheet = wb.createSheet();
            //Sheet newSheet = wb.createSheet(sheetName);
            int newSheetIndex = wb.getSheetIndex(newSheet);
            //System.out.println(newSheetIndex);
            wb.setSheetName(newSheetIndex, sheetName);
            wb.setSheetOrder(sheetName, sheetIndex);
        }
        
        Workbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb);
        wb.close();
        
        assertNotNull(wbBack);
        wbBack.close();
    }
    
    @Test
    public void test58731() throws IOException {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("58731.xlsx");
        Sheet sheet = wb.createSheet("Java Books");
        
        Object[][] bookData = {
                {"Head First Java", "Kathy Serria", 79},
                {"Effective Java", "Joshua Bloch", 36},
                {"Clean Code", "Robert martin", 42},
                {"Thinking in Java", "Bruce Eckel", 35},
        };
 
        int rowCount = 0;
        for (Object[] aBook : bookData) {
            Row row = sheet.createRow(rowCount++);
             
            int columnCount = 0;
            for (Object field : aBook) {
                Cell cell = row.createCell(columnCount++);
                if (field instanceof String) {
                    cell.setCellValue((String) field);
                } else if (field instanceof Integer) {
                    cell.setCellValue((Integer) field);
                }
            }
        }
        
        Workbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb);
        sheet = wb2.getSheet("Java Books");
        assertNotNull(sheet.getRow(0));
        assertNotNull(sheet.getRow(0).getCell(0));
        assertEquals(bookData[0][0], sheet.getRow(0).getCell(0).getStringCellValue());
        
        wb2.close();
        wb.close();
    }
    
    /**
     * Regression between 3.10.1 and 3.13 - 
     * org.apache.poi.openxml4j.exceptions.InvalidFormatException: 
     * The part /xl/sharedStrings.xml does not have any content type 
     * ! Rule: Package require content types when retrieving a part from a package. [M.1.14]
     */
    @Test
    public void test58760() throws IOException {
        Workbook wb1 = XSSFTestDataSamples.openSampleWorkbook("58760.xlsx");
        assertEquals(1, wb1.getNumberOfSheets());
        assertEquals("Sheet1", wb1.getSheetName(0));
        Workbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1);
        assertEquals(1, wb2.getNumberOfSheets());
        assertEquals("Sheet1", wb2.getSheetName(0));
        wb2.close();
        wb1.close();
    }

    @Test
    public void test57236() throws IOException {
        // Having very small numbers leads to different formatting, Excel uses the scientific notation, but POI leads to "0"
        
        /*
        DecimalFormat format = new DecimalFormat("#.##########", new DecimalFormatSymbols(Locale.getDefault()));
        double d = 3.0E-104;
        assertEquals("3.0E-104", format.format(d));
         */
        
        DataFormatter formatter = new DataFormatter(true);

        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("57236.xlsx");
        for(int sheetNum = 0;sheetNum < wb.getNumberOfSheets();sheetNum++) {
            Sheet sheet = wb.getSheetAt(sheetNum);
            for(int rowNum = sheet.getFirstRowNum();rowNum < sheet.getLastRowNum();rowNum++) {
                Row row = sheet.getRow(rowNum);
                for(int cellNum = row.getFirstCellNum();cellNum < row.getLastCellNum();cellNum++) {
                    Cell cell = row.getCell(cellNum);
                    String fmtCellValue = formatter.formatCellValue(cell);
                    
                    System.out.println("Cell: " + fmtCellValue);
                    assertNotNull(fmtCellValue);
                    assertFalse(fmtCellValue.equals("0"));
                }
            }
        }
        
        wb.close();
    }

    private void createXls() throws IOException
    {
        Workbook workbook = new HSSFWorkbook();
        FileOutputStream fileOut = new FileOutputStream("/tmp/rotated.xls");
        Sheet sheet1 = workbook.createSheet();
        Row row1 = sheet1.createRow((short) 0);

        Cell cell1 = row1.createCell(0);

        cell1.setCellValue("Successful rotated text.");

        CellStyle style = workbook.createCellStyle();
        style.setRotation((short) -90);

        cell1.setCellStyle(style);

        workbook.write(fileOut);
        fileOut.close();
        workbook.close();
    }

    private void createXlsx() throws IOException {
        Workbook workbook = new XSSFWorkbook();
        FileOutputStream fileOut = new FileOutputStream("/tmp/rotated.xlsx");
        Sheet sheet1 = workbook.createSheet();
        Row row1 = sheet1.createRow((short) 0);

        Cell cell1 = row1.createCell(0);

        cell1.setCellValue("Unsuccessful rotated text.");

        CellStyle style = workbook.createCellStyle();
        style.setRotation((short) -90);

        cell1.setCellStyle(style);

        workbook.write(fileOut);
        fileOut.close();
        workbook.close();
    }

    @Ignore("Creates files for checking results manually, actual values are tested in Test*CellStyle")
    @Test
    public void test58043() throws IOException {
        createXls();
        createXlsx();
    }

    @Test
    public void test59132() throws IOException {
        Workbook workbook = XSSFTestDataSamples.openSampleWorkbook("59132.xlsx");
        Sheet worksheet = workbook.getSheet("sheet1");

        // B3
        Row row = worksheet.getRow(2);
        Cell cell = row.getCell(1);

        cell.setCellValue((String)null);

        FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();

        // B3
        row = worksheet.getRow(2);
        cell = row.getCell(1);

        assertEquals(CellType.BLANK, cell.getCellTypeEnum());
        assertEquals(CellType._NONE, evaluator.evaluateFormulaCellEnum(cell));

        // A3
        row = worksheet.getRow(2);
        cell = row.getCell(0);

        assertEquals(CellType.FORMULA, cell.getCellTypeEnum());
        assertEquals("IF(ISBLANK(B3),\"\",B3)", cell.getCellFormula());
        assertEquals(CellType.STRING, evaluator.evaluateFormulaCellEnum(cell));
        CellValue value = evaluator.evaluate(cell);
        assertEquals("", value.getStringValue());

        // A5
        row = worksheet.getRow(4);
        cell = row.getCell(0);

        assertEquals(CellType.FORMULA, cell.getCellTypeEnum());
        assertEquals("COUNTBLANK(A1:A4)", cell.getCellFormula());
        assertEquals(CellType.NUMERIC, evaluator.evaluateFormulaCellEnum(cell));
        value = evaluator.evaluate(cell);
        assertEquals(1.0, value.getNumberValue(), 0.1);

        /*FileOutputStream output = new FileOutputStream("C:\\temp\\59132.xlsx");
        try {
            workbook.write(output);
        } finally {
            output.close();
        }*/

        workbook.close();
    }
    
    @Ignore("bug 59442")
    @Test
    public void testSetRGBBackgroundColor() throws IOException {

        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFCell cell = workbook.createSheet().createRow(0).createCell(0);

        XSSFColor color = new XSSFColor(java.awt.Color.RED);
        XSSFCellStyle style = workbook.createCellStyle();
        style.setFillForegroundColor(color);
        style.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
        cell.setCellStyle(style);

        // Everything is fine at this point, cell is red

        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put(CellUtil.BORDER_BOTTOM, CellStyle.BORDER_THIN); //or BorderStyle.THIN
        CellUtil.setCellStyleProperties(cell, properties);
        
        // Now the cell is all black
        XSSFColor actual = cell.getCellStyle().getFillBackgroundColorColor();
        assertNotNull(actual);
        assertEquals(color.getARGBHex(), actual.getARGBHex());
        
        XSSFWorkbook nwb = XSSFTestDataSamples.writeOutAndReadBack(workbook);
        workbook.close();
        XSSFCell ncell = nwb.getSheetAt(0).getRow(0).getCell(0);
        XSSFColor ncolor = new XSSFColor(java.awt.Color.RED);

        // Now the cell is all black
        XSSFColor nactual = ncell.getCellStyle().getFillBackgroundColorColor();
        assertNotNull(nactual);
        assertEquals(ncolor.getARGBHex(), nactual.getARGBHex());
        
        nwb.close();
    }

    @Ignore("currently fails on POI 3.15 beta 2")
    @Test
    public void test55273() {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("ExcelTables.xlsx");
        Sheet sheet = wb.getSheet("ExcelTable");

        Name name = wb.getName("TableAsRangeName");
        assertEquals("TableName[#All]", name.getRefersToFormula());
        // POI 3.15-beta 2 (2016-06-15): getSheetName throws IllegalArgumentException: Invalid CellReference: TableName[#All]
        assertEquals("TableName", name.getSheetName());

        XSSFSheet xsheet = (XSSFSheet) sheet;
        List<XSSFTable> tables = xsheet.getTables();
        assertEquals(2, tables.size()); //FIXME: how many tables are there in this spreadsheet?
        assertEquals("Table1", tables.get(0).getName()); //FIXME: what is the table name?
        assertEquals("Table2", tables.get(1).getName()); //FIXME: what is the table name?
    }
    
    @Test
    public void test57523() {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("57523.xlsx");
        Sheet sheet = wb.getSheet("Attribute Master");
        Row row = sheet.getRow(15);

        int N = CellReference.convertColStringToIndex("N");
        Cell N16 = row.getCell(N);
        assertEquals(500.0, N16.getNumericCellValue(), 0.00001);
        
        int P = CellReference.convertColStringToIndex("P");
        Cell P16 = row.getCell(P);
        assertEquals(10.0, P16.getNumericCellValue(), 0.00001);
    }
    
    /**
     * Files produced by some scientific equipment neglect
     *  to include the row number on the row tags
     */
    @Test
    public void noRowNumbers59746() {
        Workbook wb = XSSFTestDataSamples.openSampleWorkbook("59746_NoRowNums.xlsx");
        Sheet sheet = wb.getSheetAt(0);
        assertTrue("Last row num: "+sheet.getLastRowNum(), sheet.getLastRowNum()>20);
        assertEquals("Checked", sheet.getRow(0).getCell(0).getStringCellValue());
        assertEquals("Checked", sheet.getRow(9).getCell(2).getStringCellValue());
        assertEquals(false, sheet.getRow(70).getCell(8).getBooleanCellValue());
        assertEquals(71, sheet.getPhysicalNumberOfRows());
        assertEquals(70, sheet.getLastRowNum());
        assertEquals(70, sheet.getRow(sheet.getLastRowNum()).getRowNum());
    }

    @Test
    public void testWorkdayFunction() throws IOException {
        XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("59106.xlsx");
        XSSFSheet sheet = workbook.getSheet("Test");
        Row row = sheet.getRow(1);
        Cell cell = row.getCell(0);
        DataFormatter form = new DataFormatter();
        FormulaEvaluator evaluator = cell.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
        String result = form.formatCellValue(cell, evaluator);

        assertEquals("09 Mar 2016", result);
    }
}
