You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by be...@apache.org on 2012/08/01 21:34:08 UTC

svn commit: r1368211 - in /poi/branches/gsoc2012/src: java/org/apache/poi/hssf/model/ java/org/apache/poi/hssf/record/ java/org/apache/poi/hssf/usermodel/ testcases/org/apache/poi/hssf/usermodel/

Author: berlog
Date: Wed Aug  1 19:34:08 2012
New Revision: 1368211

URL: http://svn.apache.org/viewvc?rev=1368211&view=rev
Log:
code refactoring

Added:
    poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/usermodel/TestPatriarch.java
Modified:
    poi/branches/gsoc2012/src/java/org/apache/poi/hssf/model/InternalSheet.java
    poi/branches/gsoc2012/src/java/org/apache/poi/hssf/record/EscherAggregate.java
    poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFShapeContainer.java
    poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java

Modified: poi/branches/gsoc2012/src/java/org/apache/poi/hssf/model/InternalSheet.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/java/org/apache/poi/hssf/model/InternalSheet.java?rev=1368211&r1=1368210&r2=1368211&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/java/org/apache/poi/hssf/model/InternalSheet.java (original)
+++ poi/branches/gsoc2012/src/java/org/apache/poi/hssf/model/InternalSheet.java Wed Aug  1 19:34:08 2012
@@ -1482,6 +1482,7 @@ public final class InternalSheet {
      *  if none currently exist
      * @param drawingManager The DrawingManager2 for our workbook
      * @param createIfMissing Should one be created if missing?
+     * @return location of EscherAggregate record. if no EscherAggregate record is found return -1
      */
     public int aggregateDrawingRecords(DrawingManager2 drawingManager, boolean createIfMissing) {
         int loc = findFirstRecordLocBySid(DrawingRecord.sid);

Modified: poi/branches/gsoc2012/src/java/org/apache/poi/hssf/record/EscherAggregate.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/java/org/apache/poi/hssf/record/EscherAggregate.java?rev=1368211&r1=1368210&r2=1368211&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/java/org/apache/poi/hssf/record/EscherAggregate.java (original)
+++ poi/branches/gsoc2012/src/java/org/apache/poi/hssf/record/EscherAggregate.java Wed Aug  1 19:34:08 2012
@@ -293,7 +293,7 @@ public final class EscherAggregate exten
     protected HSSFPatriarch patriarch;
 
     /**
-     * if we want to get the same byte array if we open existing file and serialize it we should save 
+     * if we want to get the same byte array if we open existing file and serialize it we should save
      * note records in right order. This list contains ids of NoteRecords in such order as we read from existing file
      */
     private List<Integer> _tailIds = new ArrayList<Integer>();
@@ -306,7 +306,7 @@ public final class EscherAggregate exten
     /**
      * list of "tail" records that need to be serialized after all drawing group records
      */
-     private Map<Integer, NoteRecord> tailRec = new HashMap<Integer, NoteRecord>();
+    private Map<Integer, NoteRecord> tailRec = new HashMap<Integer, NoteRecord>();
 
     public EscherAggregate() {
         buildBaseTree();
@@ -517,9 +517,9 @@ public final class EscherAggregate exten
         // write records that need to be serialized after all drawing group records
         Map<Integer, NoteRecord> tailCopy = new HashMap<Integer, NoteRecord>(tailRec);
         // at first we should save records in correct order which were already in the file during EscherAggregate.createAggregate()
-        for (Integer id : _tailIds){
+        for (Integer id : _tailIds) {
             NoteRecord note = tailCopy.get(id);
-            if (null != note){
+            if (null != note) {
                 pos += note.serialize(pos, data);
                 tailCopy.remove(id);
             }
@@ -539,14 +539,18 @@ public final class EscherAggregate exten
         //First record in drawing layer MUST be DrawingRecord
         if (writtenEscherBytes + drawingData.length > RecordInputStream.MAX_RECORD_DATA_SIZE && i != 1) {
             for (int j = 0; j < drawingData.length; j += RecordInputStream.MAX_RECORD_DATA_SIZE) {
-                ContinueRecord drawing = new ContinueRecord(Arrays.copyOfRange(drawingData, j, Math.min(j + RecordInputStream.MAX_RECORD_DATA_SIZE, drawingData.length)));
+                byte[] buf = new byte[Math.min(RecordInputStream.MAX_RECORD_DATA_SIZE, drawingData.length - j)];
+                System.arraycopy(drawingData, j, buf, 0, Math.min(RecordInputStream.MAX_RECORD_DATA_SIZE, drawingData.length - j));
+                ContinueRecord drawing = new ContinueRecord(buf);
                 temp += drawing.serialize(pos + temp, data);
             }
         } else {
             for (int j = 0; j < drawingData.length; j += RecordInputStream.MAX_RECORD_DATA_SIZE) {
                 if (j == 0) {
                     DrawingRecord drawing = new DrawingRecord();
-                    drawing.setData(Arrays.copyOfRange(drawingData, j, Math.min(j + RecordInputStream.MAX_RECORD_DATA_SIZE, drawingData.length)));
+                    byte[] buf = new byte[Math.min(RecordInputStream.MAX_RECORD_DATA_SIZE, drawingData.length - j)];
+                    System.arraycopy(drawingData, j, buf, 0, Math.min(RecordInputStream.MAX_RECORD_DATA_SIZE, drawingData.length - j));
+                    drawing.setData(buf);
                     temp += drawing.serialize(pos + temp, data);
                 } else {
                     ContinueRecord drawing = new ContinueRecord(Arrays.copyOfRange(drawingData, j, Math.min(j + RecordInputStream.MAX_RECORD_DATA_SIZE, drawingData.length)));
@@ -628,7 +632,7 @@ public final class EscherAggregate exten
         return shapeToObj.put(r, objRecord);
     }
 
-    public void removeShapeToObjRecord(EscherRecord rec){
+    public void removeShapeToObjRecord(EscherRecord rec) {
         shapeToObj.remove(rec);
     }
 
@@ -667,7 +671,7 @@ public final class EscherAggregate exten
         dgContainer.setRecordId(EscherContainerRecord.DG_CONTAINER);
         dgContainer.setOptions((short) 0x000F);
         EscherDgRecord dg = new EscherDgRecord();
-        dg.setRecordId( EscherDgRecord.RECORD_ID );
+        dg.setRecordId(EscherDgRecord.RECORD_ID);
         short dgId = 1;
         dg.setOptions((short) (dgId << 4));
         dg.setNumShapes(0);
@@ -702,7 +706,7 @@ public final class EscherAggregate exten
         dg.setOptions((short) (dgId << 4));
     }
 
-    public void setMainSpRecordId(int shapeId){
+    public void setMainSpRecordId(int shapeId) {
         EscherContainerRecord dgContainer = getEscherContainer();
         EscherContainerRecord spContainer = (EscherContainerRecord) dgContainer.getChildById(EscherContainerRecord.SPGR_CONTAINER).getChild(0);
         EscherSpRecord sp = (EscherSpRecord) spContainer.getChildById(EscherSpRecord.RECORD_ID);
@@ -757,11 +761,11 @@ public final class EscherAggregate exten
         return tailRec.get(cod.getObjectId());
     }
 
-    public void addTailRecord(NoteRecord note){
+    public void addTailRecord(NoteRecord note) {
         tailRec.put(note.getShapeId(), note);
     }
 
-    public void removeTailRecord(NoteRecord note){
+    public void removeTailRecord(NoteRecord note) {
         tailRec.remove(note.getShapeId());
     }
 }

Modified: poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFShapeContainer.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFShapeContainer.java?rev=1368211&r1=1368210&r2=1368211&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFShapeContainer.java (original)
+++ poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFShapeContainer.java Wed Aug  1 19:34:08 2012
@@ -51,4 +51,6 @@ public interface HSSFShapeContainer exte
     public int getX2();
 
     public int getY2();
+
+    public boolean removeShape(HSSFShape shape);
 }

Modified: poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java?rev=1368211&r1=1368210&r2=1368211&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java (original)
+++ poi/branches/gsoc2012/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java Wed Aug  1 19:34:08 2012
@@ -24,6 +24,7 @@ import java.util.List;
 import java.util.TreeMap;
 
 import org.apache.poi.ddf.EscherRecord;
+import org.apache.poi.hssf.model.DrawingManager2;
 import org.apache.poi.hssf.model.HSSFFormulaParser;
 import org.apache.poi.hssf.model.InternalSheet;
 import org.apache.poi.hssf.model.InternalWorkbook;
@@ -52,14 +53,15 @@ import org.apache.poi.util.POILogger;
 
 /**
  * High level representation of a worksheet.
- * @author  Andrew C. Oliver (acoliver at apache dot org)
- * @author  Glen Stampoultzis (glens at apache.org)
- * @author  Libin Roman (romal at vistaportal.com)
- * @author  Shawn Laubach (slaubach at apache dot org) (Just a little)
- * @author  Jean-Pierre Paris (jean-pierre.paris at m4x dot org) (Just a little, too)
- * @author  Yegor Kozlov (yegor at apache.org) (Autosizing columns)
- * @author  Josh Micich
- * @author  Petr Udalau(Petr.Udalau at exigenservices.com) - set/remove array formulas
+ *
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Glen Stampoultzis (glens at apache.org)
+ * @author Libin Roman (romal at vistaportal.com)
+ * @author Shawn Laubach (slaubach at apache dot org) (Just a little)
+ * @author Jean-Pierre Paris (jean-pierre.paris at m4x dot org) (Just a little, too)
+ * @author Yegor Kozlov (yegor at apache.org) (Autosizing columns)
+ * @author Josh Micich
+ * @author Petr Udalau(Petr.Udalau at exigenservices.com) - set/remove array formulas
  */
 public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet {
     private static final POILogger log = POILogFactory.getLogger(HSSFSheet.class);
@@ -76,7 +78,9 @@ public final class HSSFSheet implements 
      * reference to the low level {@link InternalSheet} object
      */
     private final InternalSheet _sheet;
-    /** stores rows by zero-based row number */
+    /**
+     * stores rows by zero-based row number
+     */
     private final TreeMap<Integer, HSSFRow> _rows;
     protected final InternalWorkbook _book;
     protected final HSSFWorkbook _workbook;
@@ -103,7 +107,7 @@ public final class HSSFSheet implements 
      * called by HSSFWorkbook when reading in an exisiting file.
      *
      * @param workbook - The HSSF Workbook object associated with the sheet.
-     * @param sheet - lowlevel Sheet object this sheet will represent
+     * @param sheet    - lowlevel Sheet object this sheet will represent
      * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#createSheet()
      */
     protected HSSFSheet(HSSFWorkbook workbook, InternalSheet sheet) {
@@ -119,10 +123,10 @@ public final class HSSFSheet implements 
         HSSFSheet sheet = new HSSFSheet(workbook, _sheet.cloneSheet());
         int pos = sheet._sheet.findFirstRecordLocBySid(DrawingRecord.sid);
         DrawingRecord dr = (DrawingRecord) sheet._sheet.findFirstRecordBySid(DrawingRecord.sid);
-        if (null != dr){
+        if (null != dr) {
             sheet._sheet.getRecords().remove(dr);
         }
-        if (getDrawingPatriarch() != null){
+        if (getDrawingPatriarch() != null) {
             HSSFPatriarch patr = HSSFPatriarch.createPatriarch(this.getDrawingPatriarch(), sheet);
             sheet._sheet.getRecords().add(pos, patr._getBoundAggregate());
             sheet._patriarch = patr;
@@ -135,7 +139,7 @@ public final class HSSFSheet implements 
      *
      * @return the parent workbook
      */
-    public HSSFWorkbook getWorkbook(){
+    public HSSFWorkbook getWorkbook() {
         return _workbook;
     }
 
@@ -145,7 +149,7 @@ public final class HSSFSheet implements 
     private void setPropertiesFromSheet(InternalSheet sheet) {
 
         RowRecord row = sheet.getNextRow();
-        boolean rowRecordsAlreadyPresent = row!=null;
+        boolean rowRecordsAlreadyPresent = row != null;
 
         while (row != null) {
             createRowFromRecord(row);
@@ -156,9 +160,9 @@ public final class HSSFSheet implements 
         Iterator<CellValueRecordInterface> iter = sheet.getCellValueIterator();
         long timestart = System.currentTimeMillis();
 
-        if (log.check( POILogger.DEBUG ))
+        if (log.check(POILogger.DEBUG))
             log.log(DEBUG, "Time at start of cell creating in HSSF sheet = ",
-                Long.valueOf(timestart));
+                    Long.valueOf(timestart));
         HSSFRow lastrow = null;
 
         // Add every cell to its row
@@ -169,7 +173,7 @@ public final class HSSFSheet implements 
             HSSFRow hrow = lastrow;
 
             if (hrow == null || hrow.getRowNum() != cval.getRow()) {
-                hrow = getRow( cval.getRow() );
+                hrow = getRow(cval.getRow());
                 lastrow = hrow;
                 if (hrow == null) {
                     // Some tools (like Perl module Spreadsheet::WriteExcel - bug 41187) skip the RowRecords
@@ -184,29 +188,28 @@ public final class HSSFSheet implements 
                     hrow = createRowFromRecord(rowRec);
                 }
             }
-            if (log.check( POILogger.DEBUG ))
-                log.log( DEBUG, "record id = " + Integer.toHexString( ( (Record) cval ).getSid() ) );
-            hrow.createCellFromRecord( cval );
-            if (log.check( POILogger.DEBUG ))
-                log.log( DEBUG, "record took ",
-                    Long.valueOf( System.currentTimeMillis() - cellstart ) );
+            if (log.check(POILogger.DEBUG))
+                log.log(DEBUG, "record id = " + Integer.toHexString(((Record) cval).getSid()));
+            hrow.createCellFromRecord(cval);
+            if (log.check(POILogger.DEBUG))
+                log.log(DEBUG, "record took ",
+                        Long.valueOf(System.currentTimeMillis() - cellstart));
 
         }
-        if (log.check( POILogger.DEBUG ))
+        if (log.check(POILogger.DEBUG))
             log.log(DEBUG, "total sheet cell creation took ",
-                Long.valueOf(System.currentTimeMillis() - timestart));
+                    Long.valueOf(System.currentTimeMillis() - timestart));
     }
 
     /**
      * Create a new row within the sheet and return the high level representation
      *
-     * @param rownum  row number
+     * @param rownum row number
      * @return High level HSSFRow object representing a row in the sheet
      * @see org.apache.poi.hssf.usermodel.HSSFRow
      * @see #removeRow(org.apache.poi.ss.usermodel.Row)
      */
-    public HSSFRow createRow(int rownum)
-    {
+    public HSSFRow createRow(int rownum) {
         HSSFRow row = new HSSFRow(_workbook, this, rownum);
         // new rows inherit default height from the sheet
         row.setHeight(getDefaultRowHeight());
@@ -218,12 +221,12 @@ public final class HSSFSheet implements 
     /**
      * Used internally to create a high level Row object from a low level row object.
      * USed when reading an existing file
-     * @param row  low level record to represent as a high level Row and add to sheet
+     *
+     * @param row low level record to represent as a high level Row and add to sheet
      * @return HSSFRow high level representation
      */
 
-    private HSSFRow createRowFromRecord(RowRecord row)
-    {
+    private HSSFRow createRowFromRecord(RowRecord row) {
         HSSFRow hrow = new HSSFRow(_workbook, this, row);
 
         addRow(hrow, false);
@@ -233,17 +236,17 @@ public final class HSSFSheet implements 
     /**
      * Remove a row from this sheet.  All cells contained in the row are removed as well
      *
-     * @param row   representing a row to remove.
+     * @param row representing a row to remove.
      */
     public void removeRow(Row row) {
         HSSFRow hrow = (HSSFRow) row;
         if (row.getSheet() != this) {
             throw new IllegalArgumentException("Specified row does not belong to this sheet");
         }
-        for(Cell cell : row) {
-            HSSFCell xcell = (HSSFCell)cell;
-            if(xcell.isPartOfArrayFormulaGroup()){
-                String msg = "Row[rownum="+row.getRowNum()+"] contains cell(s) included in a multi-cell array formula. You cannot change part of an array.";
+        for (Cell cell : row) {
+            HSSFCell xcell = (HSSFCell) cell;
+            if (xcell.isPartOfArrayFormulaGroup()) {
+                String msg = "Row[rownum=" + row.getRowNum() + "] contains cell(s) included in a multi-cell array formula. You cannot change part of an array.";
                 xcell.notifyArrayFormulaChanging(msg);
             }
         }
@@ -255,12 +258,10 @@ public final class HSSFSheet implements 
                 //should not happen if the input argument is valid
                 throw new IllegalArgumentException("Specified row does not belong to this sheet");
             }
-            if (hrow.getRowNum() == getLastRowNum())
-            {
+            if (hrow.getRowNum() == getLastRowNum()) {
                 _lastrow = findLastRow(_lastrow);
             }
-            if (hrow.getRowNum() == getFirstRowNum())
-            {
+            if (hrow.getRowNum() == getFirstRowNum()) {
                 _firstrow = findFirstRow(_firstrow);
             }
             _sheet.removeRow(hrow.getRowRecord());
@@ -290,13 +291,11 @@ public final class HSSFSheet implements 
      * used internally to refresh the "first row" when the first row is removed.
      */
 
-    private int findFirstRow(int firstrow)
-    {
+    private int findFirstRow(int firstrow) {
         int rownum = firstrow + 1;
         HSSFRow r = getRow(rownum);
 
-        while (r == null && rownum <= getLastRowNum())
-        {
+        while (r == null && rownum <= getLastRowNum()) {
             r = getRow(++rownum);
         }
 
@@ -312,20 +311,16 @@ public final class HSSFSheet implements 
      * @param addLow whether to add the row to the low level model - false if its already there
      */
 
-    private void addRow(HSSFRow row, boolean addLow)
-    {
+    private void addRow(HSSFRow row, boolean addLow) {
         _rows.put(Integer.valueOf(row.getRowNum()), row);
-        if (addLow)
-        {
+        if (addLow) {
             _sheet.addRow(row.getRowRecord());
         }
         boolean firstRow = _rows.size() == 1;
-        if (row.getRowNum() > getLastRowNum() || firstRow)
-        {
+        if (row.getRowNum() > getLastRowNum() || firstRow) {
             _lastrow = row.getRowNum();
         }
-        if (row.getRowNum() < getFirstRowNum() || firstRow)
-        {
+        if (row.getRowNum() < getFirstRowNum() || firstRow) {
             _firstrow = row.getRowNum();
         }
     }
@@ -333,7 +328,8 @@ public final class HSSFSheet implements 
     /**
      * Returns the logical row (not physical) 0-based.  If you ask for a row that is not
      * defined you get a null.  This is to say row 4 represents the fifth row on a sheet.
-     * @param rowIndex  row to get
+     *
+     * @param rowIndex row to get
      * @return HSSFRow representing the row number or null if its not defined on the sheet
      */
     public HSSFRow getRow(int rowIndex) {
@@ -349,6 +345,7 @@ public final class HSSFSheet implements 
 
     /**
      * Gets the first row on the sheet
+     *
      * @return the number of the first logical row on the sheet, zero based
      */
     public int getFirstRowNum() {
@@ -358,13 +355,14 @@ public final class HSSFSheet implements 
     /**
      * Gets the number last row on the sheet.
      * Owing to idiosyncrasies in the excel file
-     *  format, if the result of calling this method
-     *  is zero, you can't tell if that means there
-     *  are zero rows on the sheet, or one at
-     *  position zero. For that case, additionally
-     *  call {@link #getPhysicalNumberOfRows()} to
-     *  tell if there is a row at position zero
-     *  or not.
+     * format, if the result of calling this method
+     * is zero, you can't tell if that means there
+     * are zero rows on the sheet, or one at
+     * position zero. For that case, additionally
+     * call {@link #getPhysicalNumberOfRows()} to
+     * tell if there is a row at position zero
+     * or not.
+     *
      * @return the number of the last row contained in this sheet, zero based.
      */
     public int getLastRowNum() {
@@ -376,14 +374,14 @@ public final class HSSFSheet implements 
      * @param dataValidation The Data validation object settings
      */
     public void addValidationData(DataValidation dataValidation) {
-       if (dataValidation == null) {
-           throw new IllegalArgumentException("objValidation must not be null");
-       }
-       HSSFDataValidation hssfDataValidation = (HSSFDataValidation)dataValidation;
-       DataValidityTable dvt = _sheet.getOrCreateDataValidityTable();
+        if (dataValidation == null) {
+            throw new IllegalArgumentException("objValidation must not be null");
+        }
+        HSSFDataValidation hssfDataValidation = (HSSFDataValidation) dataValidation;
+        DataValidityTable dvt = _sheet.getOrCreateDataValidityTable();
 
-       DVRecord dvRecord = hssfDataValidation.createDVRecord(this);
-       dvt.addDataValidation(dvRecord);
+        DVRecord dvRecord = hssfDataValidation.createDVRecord(this);
+        dvt.addDataValidation(dvRecord);
     }
 
 
@@ -412,7 +410,7 @@ public final class HSSFSheet implements 
      * @deprecated (Sep 2008) use {@link #getColumnWidth(int)}
      */
     public short getColumnWidth(short columnIndex) {
-        return (short)getColumnWidth(columnIndex & 0xFFFF);
+        return (short) getColumnWidth(columnIndex & 0xFFFF);
     }
 
     /**
@@ -424,8 +422,9 @@ public final class HSSFSheet implements 
 
     /**
      * Get the visibility state for a given column.
+     *
      * @param columnIndex - the column to get (0-based)
-     * @param hidden - the visiblity state of the column
+     * @param hidden      - the visiblity state of the column
      */
     public void setColumnHidden(int columnIndex, boolean hidden) {
         _sheet.setColumnHidden(columnIndex, hidden);
@@ -433,6 +432,7 @@ public final class HSSFSheet implements 
 
     /**
      * Get the hidden state for a given column.
+     *
      * @param columnIndex - the column to set (0-based)
      * @return hidden - <code>false</code> if the column is visible
      */
@@ -442,13 +442,13 @@ public final class HSSFSheet implements 
 
     /**
      * Set the width (in units of 1/256th of a character width)
-     *
+     * <p/>
      * <p>
      * The maximum column width for an individual cell is 255 characters.
      * This value represents the number of characters that can be displayed
      * in a cell that is formatted with the standard font (first font in the workbook).
      * </p>
-     *
+     * <p/>
      * <p>
      * Character width is defined as the maximum digit width
      * of the numbers <code>0, 1, 2, ... 9</code> as rendered
@@ -457,7 +457,7 @@ public final class HSSFSheet implements 
      * Unless you are using a very special font, the default character is '0' (zero),
      * this is true for Arial (default font font in HSSF) and Calibri (default font in XSSF)
      * </p>
-     *
+     * <p/>
      * <p>
      * Please note, that the width set by this method includes 4 pixels of margin padding (two on each side),
      * plus 1 pixel padding for the gridlines (Section 3.3.1.12 of the OOXML spec).
@@ -465,23 +465,23 @@ public final class HSSFSheet implements 
      * </p>
      * <p>
      * To compute the actual number of visible characters,
-     *  Excel uses the following formula (Section 3.3.1.12 of the OOXML spec):
+     * Excel uses the following formula (Section 3.3.1.12 of the OOXML spec):
      * </p>
      * <code>
-     *     width = Truncate([{Number of Visible Characters} *
-     *      {Maximum Digit Width} + {5 pixel padding}]/{Maximum Digit Width}*256)/256
+     * width = Truncate([{Number of Visible Characters} *
+     * {Maximum Digit Width} + {5 pixel padding}]/{Maximum Digit Width}*256)/256
      * </code>
      * <p>Using the Calibri font as an example, the maximum digit width of 11 point font size is 7 pixels (at 96 dpi).
-     *  If you set a column width to be eight characters wide, e.g. <code>setColumnWidth(columnIndex, 8*256)</code>,
-     *  then the actual value of visible characters (the value shown in Excel) is derived from the following equation:
-     *  <code>
-            Truncate([numChars*7+5]/7*256)/256 = 8;
-     *  </code>
-     *
-     *  which gives <code>7.29</code>.
+     * If you set a column width to be eight characters wide, e.g. <code>setColumnWidth(columnIndex, 8*256)</code>,
+     * then the actual value of visible characters (the value shown in Excel) is derived from the following equation:
+     * <code>
+     * Truncate([numChars*7+5]/7*256)/256 = 8;
+     * </code>
+     * <p/>
+     * which gives <code>7.29</code>.
      *
      * @param columnIndex - the column to set (0-based)
-     * @param width - the width in units of 1/256th of a character width
+     * @param width       - the width in units of 1/256th of a character width
      * @throws IllegalArgumentException if width > 255*256 (the maximum column width in Excel is 255 characters)
      */
     public void setColumnWidth(int columnIndex, int width) {
@@ -490,6 +490,7 @@ public final class HSSFSheet implements 
 
     /**
      * get the width (in units of 1/256th of a character width )
+     *
      * @param columnIndex - the column to set (0-based)
      * @return width - the width in units of 1/256th of a character width
      */
@@ -500,14 +501,17 @@ public final class HSSFSheet implements 
     /**
      * get the default column width for the sheet (if the columns do not define their own width) in
      * characters
+     *
      * @return default column width
      */
     public int getDefaultColumnWidth() {
         return _sheet.getDefaultColumnWidth();
     }
+
     /**
      * set the default column width for the sheet (if the columns do not define their own width) in
      * characters
+     *
      * @param width default column width
      */
     public void setDefaultColumnWidth(int width) {
@@ -518,7 +522,7 @@ public final class HSSFSheet implements 
     /**
      * get the default row height for the sheet (if the rows do not define their own height) in
      * twips (1/20 of  a point)
-     * @return  default row height
+     * @return default row height
      */
     public short getDefaultRowHeight() {
         return _sheet.getDefaultRowHeight();
@@ -527,45 +531,44 @@ public final class HSSFSheet implements 
     /**
      * get the default row height for the sheet (if the rows do not define their own height) in
      * points.
-     * @return  default row height in points
+     * @return default row height in points
      */
 
-    public float getDefaultRowHeightInPoints()
-    {
-        return ((float)_sheet.getDefaultRowHeight() / 20);
+    public float getDefaultRowHeightInPoints() {
+        return ((float) _sheet.getDefaultRowHeight() / 20);
     }
 
     /**
      * set the default row height for the sheet (if the rows do not define their own height) in
      * twips (1/20 of  a point)
-     * @param  height default row height
+     *
+     * @param height default row height
      */
 
-    public void setDefaultRowHeight(short height)
-    {
+    public void setDefaultRowHeight(short height) {
         _sheet.setDefaultRowHeight(height);
     }
 
     /**
      * set the default row height for the sheet (if the rows do not define their own height) in
      * points
+     *
      * @param height default row height
      */
 
-    public void setDefaultRowHeightInPoints(float height)
-    {
+    public void setDefaultRowHeightInPoints(float height) {
         _sheet.setDefaultRowHeight((short) (height * 20));
     }
 
     /**
      * Returns the HSSFCellStyle that applies to the given
-     *  (0 based) column, or null if no style has been
-     *  set for that column
+     * (0 based) column, or null if no style has been
+     * set for that column
      */
     public HSSFCellStyle getColumnStyle(int column) {
-        short styleIndex = _sheet.getXFIndexForColAt((short)column);
+        short styleIndex = _sheet.getXFIndexForColAt((short) column);
 
-        if(styleIndex == 0xf) {
+        if (styleIndex == 0xf) {
             // None set
             return null;
         }
@@ -576,55 +579,55 @@ public final class HSSFSheet implements 
 
     /**
      * get whether gridlines are printed.
+     *
      * @return true if printed
      */
 
-    public boolean isGridsPrinted()
-    {
+    public boolean isGridsPrinted() {
         return _sheet.isGridsPrinted();
     }
 
     /**
      * set whether gridlines printed.
-     * @param value  false if not printed.
+     *
+     * @param value false if not printed.
      */
 
-    public void setGridsPrinted(boolean value)
-    {
+    public void setGridsPrinted(boolean value) {
         _sheet.setGridsPrinted(value);
     }
 
     /**
      * @deprecated (Aug-2008) use <tt>CellRangeAddress</tt> instead of <tt>Region</tt>
      */
-    public int addMergedRegion(org.apache.poi.ss.util.Region region)
-    {
-        return _sheet.addMergedRegion( region.getRowFrom(),
+    public int addMergedRegion(org.apache.poi.ss.util.Region region) {
+        return _sheet.addMergedRegion(region.getRowFrom(),
                 region.getColumnFrom(),
                 //(short) region.getRowTo(),
                 region.getRowTo(),
                 region.getColumnTo());
     }
+
     /**
      * adds a merged region of cells (hence those cells form one)
+     *
      * @param region (rowfrom/colfrom-rowto/colto) to merge
      * @return index of this region
      */
-    public int addMergedRegion(CellRangeAddress region)
-    {
+    public int addMergedRegion(CellRangeAddress region) {
         region.validate(SpreadsheetVersion.EXCEL97);
 
         // throw IllegalStateException if the argument CellRangeAddress intersects with
         // a multi-cell array formula defined in this sheet
         validateArrayFormulas(region);
 
-        return _sheet.addMergedRegion( region.getFirstRow(),
+        return _sheet.addMergedRegion(region.getFirstRow(),
                 region.getFirstColumn(),
                 region.getLastRow(),
                 region.getLastColumn());
     }
 
-    private void validateArrayFormulas(CellRangeAddress region){
+    private void validateArrayFormulas(CellRangeAddress region) {
         int firstRow = region.getFirstRow();
         int firstColumn = region.getFirstColumn();
         int lastRow = region.getLastRow();
@@ -635,13 +638,13 @@ public final class HSSFSheet implements 
                 if (row == null) continue;
 
                 HSSFCell cell = row.getCell(colIn);
-                if(cell == null) continue;
+                if (cell == null) continue;
 
-                if(cell.isPartOfArrayFormulaGroup()){
+                if (cell.isPartOfArrayFormulaGroup()) {
                     CellRangeAddress arrayRange = cell.getArrayFormulaRange();
                     if (arrayRange.getNumberOfCells() > 1 &&
-                            ( arrayRange.isInRange(region.getFirstRow(), region.getFirstColumn()) ||
-                              arrayRange.isInRange(region.getFirstRow(), region.getFirstColumn()))  ){
+                            (arrayRange.isInRange(region.getFirstRow(), region.getFirstColumn()) ||
+                                    arrayRange.isInRange(region.getFirstRow(), region.getFirstColumn()))) {
                         String msg = "The range " + region.formatAsString() + " intersects with a multi-cell array formula. " +
                                 "You cannot merge cells of an array.";
                         throw new IllegalStateException(msg);
@@ -655,50 +658,51 @@ public final class HSSFSheet implements 
     /**
      * Control if Excel should be asked to recalculate all formulas on this sheet
      * when the workbook is opened.
+     * <p/>
+     * <p>
+     * Calculating the formula values with {@link org.apache.poi.ss.usermodel.FormulaEvaluator} is the
+     * recommended solution, but this may be used for certain cases where
+     * evaluation in POI is not possible.
+     * </p>
+     * <p/>
+     * <p>
+     * It is recommended to force recalcuation of formulas on workbook level using
+     * {@link org.apache.poi.ss.usermodel.Workbook#setForceFormulaRecalculation(boolean)}
+     * to ensure that all cross-worksheet formuals and external dependencies are updated.
+     * </p>
      *
-     *  <p>
-     *  Calculating the formula values with {@link org.apache.poi.ss.usermodel.FormulaEvaluator} is the
-     *  recommended solution, but this may be used for certain cases where
-     *  evaluation in POI is not possible.
-     *  </p>
-     *
-     *  <p>
-     *  It is recommended to force recalcuation of formulas on workbook level using
-     *  {@link org.apache.poi.ss.usermodel.Workbook#setForceFormulaRecalculation(boolean)}
-     *  to ensure that all cross-worksheet formuals and external dependencies are updated.
-     *  </p>
      * @param value true if the application will perform a full recalculation of
-     * this worksheet values when the workbook is opened
-     *
+     *              this worksheet values when the workbook is opened
      * @see org.apache.poi.ss.usermodel.Workbook#setForceFormulaRecalculation(boolean)
      */
-    public void setForceFormulaRecalculation(boolean value)
-    {
+    public void setForceFormulaRecalculation(boolean value) {
         _sheet.setUncalced(value);
     }
+
     /**
      * Whether a record must be inserted or not at generation to indicate that
      * formula must be recalculated when workbook is opened.
+     *
      * @return true if an uncalced record must be inserted or not at generation
      */
-    public boolean getForceFormulaRecalculation()
-    {
+    public boolean getForceFormulaRecalculation() {
         return _sheet.getUncalced();
     }
 
 
     /**
      * determines whether the output is vertically centered on the page.
+     *
      * @param value true to vertically center, false otherwise.
      */
 
-    public void setVerticallyCenter(boolean value)
-    {
+    public void setVerticallyCenter(boolean value) {
         _sheet.getPageSettings().getVCenter().setVCenter(value);
     }
 
     /**
      * TODO: Boolean not needed, remove after next release
+     *
      * @deprecated (Mar-2008) use getVerticallyCenter() instead
      */
     public boolean getVerticallyCenter(boolean value) {
@@ -708,18 +712,17 @@ public final class HSSFSheet implements 
     /**
      * Determine whether printed output for this sheet will be vertically centered.
      */
-    public boolean getVerticallyCenter()
-    {
+    public boolean getVerticallyCenter() {
         return _sheet.getPageSettings().getVCenter().getVCenter();
     }
 
     /**
      * determines whether the output is horizontally centered on the page.
+     *
      * @param value true to horizontally center, false otherwise.
      */
 
-    public void setHorizontallyCenter(boolean value)
-    {
+    public void setHorizontallyCenter(boolean value) {
         _sheet.getPageSettings().getHCenter().setHCenter(value);
     }
 
@@ -727,8 +730,7 @@ public final class HSSFSheet implements 
      * Determine whether printed output for this sheet will be horizontally centered.
      */
 
-    public boolean getHorizontallyCenter()
-    {
+    public boolean getHorizontallyCenter() {
 
         return _sheet.getPageSettings().getHCenter().getHCenter();
     }
@@ -738,8 +740,7 @@ public final class HSSFSheet implements 
      *
      * @param value true for right to left, false otherwise.
      */
-    public void setRightToLeft(boolean value)
-    {
+    public void setRightToLeft(boolean value) {
         _sheet.getWindowTwo().setArabic(value);
     }
 
@@ -748,28 +749,27 @@ public final class HSSFSheet implements 
      *
      * @return whether the text is displayed in right-to-left mode in the window
      */
-    public boolean isRightToLeft()
-    {
+    public boolean isRightToLeft() {
         return _sheet.getWindowTwo().getArabic();
     }
 
     /**
      * removes a merged region of cells (hence letting them free)
+     *
      * @param index of the region to unmerge
      */
 
-    public void removeMergedRegion(int index)
-    {
+    public void removeMergedRegion(int index) {
         _sheet.removeMergedRegion(index);
     }
 
     /**
      * returns the number of merged regions
+     *
      * @return number of merged regions
      */
 
-    public int getNumMergedRegions()
-    {
+    public int getNumMergedRegions() {
         return _sheet.getNumMergedRegions();
     }
 
@@ -779,9 +779,10 @@ public final class HSSFSheet implements 
     public org.apache.poi.hssf.util.Region getMergedRegionAt(int index) {
         CellRangeAddress cra = getMergedRegion(index);
 
-        return new org.apache.poi.hssf.util.Region(cra.getFirstRow(), (short)cra.getFirstColumn(),
-                cra.getLastRow(), (short)cra.getLastColumn());
+        return new org.apache.poi.hssf.util.Region(cra.getFirstRow(), (short) cra.getFirstColumn(),
+                cra.getLastRow(), (short) cra.getLastColumn());
     }
+
     /**
      * @return the merged region at the specified index
      */
@@ -791,17 +792,18 @@ public final class HSSFSheet implements 
 
     /**
      * @return an iterator of the PHYSICAL rows.  Meaning the 3rd element may not
-     * be the third row if say for instance the second row is undefined.
-     * Call getRowNum() on each row if you care which one it is.
+     *         be the third row if say for instance the second row is undefined.
+     *         Call getRowNum() on each row if you care which one it is.
      */
     public Iterator<Row> rowIterator() {
         @SuppressWarnings("unchecked") // can this clumsy generic syntax be improved?
-        Iterator<Row> result = (Iterator<Row>)(Iterator<? extends Row>)_rows.values().iterator();
+                Iterator<Row> result = (Iterator<Row>) (Iterator<? extends Row>) _rows.values().iterator();
         return result;
     }
+
     /**
      * Alias for {@link #rowIterator()} to allow
-     *  foreach loops
+     * foreach loops
      */
     public Iterator<Row> iterator() {
         return rowIterator();
@@ -819,7 +821,7 @@ public final class HSSFSheet implements 
 
     /**
      * whether alternate expression evaluation is on
-     * @param b  alternative expression evaluation or not
+     * @param b alternative expression evaluation or not
      */
     public void setAlternativeExpression(boolean b) {
         WSBoolRecord record =
@@ -830,7 +832,7 @@ public final class HSSFSheet implements 
 
     /**
      * whether alternative formula entry is on
-     * @param b  alternative formulas or not
+     * @param b alternative formulas or not
      */
     public void setAlternativeFormula(boolean b) {
         WSBoolRecord record =
@@ -841,7 +843,7 @@ public final class HSSFSheet implements 
 
     /**
      * show automatic page breaks or not
-     * @param b  whether to show auto page breaks
+     * @param b whether to show auto page breaks
      */
     public void setAutobreaks(boolean b) {
         WSBoolRecord record =
@@ -852,7 +854,7 @@ public final class HSSFSheet implements 
 
     /**
      * set whether sheet is a dialog sheet or not
-     * @param b  isDialog or not
+     * @param b isDialog or not
      */
     public void setDialog(boolean b) {
         WSBoolRecord record =
@@ -864,7 +866,7 @@ public final class HSSFSheet implements 
     /**
      * set whether to display the guts or not
      *
-     * @param b  guts or no guts (or glory)
+     * @param b guts or no guts (or glory)
      */
     public void setDisplayGuts(boolean b) {
         WSBoolRecord record =
@@ -875,7 +877,7 @@ public final class HSSFSheet implements 
 
     /**
      * fit to page option is on
-     * @param b  fit or not
+     * @param b fit or not
      */
     public void setFitToPage(boolean b) {
         WSBoolRecord record =
@@ -886,7 +888,7 @@ public final class HSSFSheet implements 
 
     /**
      * set if row summaries appear below detail in the outline
-     * @param b  below or not
+     * @param b below or not
      */
     public void setRowSumsBelow(boolean b) {
         WSBoolRecord record =
@@ -899,7 +901,7 @@ public final class HSSFSheet implements 
 
     /**
      * set if col summaries appear right of the detail in the outline
-     * @param b  right or not
+     * @param b right or not
      */
     public void setRowSumsRight(boolean b) {
         WSBoolRecord record =
@@ -963,7 +965,7 @@ public final class HSSFSheet implements 
      * </p>
      * @return whether all zero values on the worksheet are displayed
      */
-    public boolean isDisplayZeros(){
+    public boolean isDisplayZeros() {
         return _sheet.getWindowTwo().getDisplayZeros();
     }
 
@@ -975,7 +977,7 @@ public final class HSSFSheet implements 
      * </p>
      * @param value whether to display or hide all zero values on the worksheet
      */
-    public void setDisplayZeros(boolean value){
+    public void setDisplayZeros(boolean value) {
         _sheet.getWindowTwo().setDisplayZeros(value);
     }
 
@@ -1041,26 +1043,32 @@ public final class HSSFSheet implements 
 
     /**
      * Note - this is not the same as whether the sheet is focused (isActive)
+     *
      * @return <code>true</code> if this sheet is currently selected
      */
     public boolean isSelected() {
         return getSheet().getWindowTwo().getSelected();
     }
+
     /**
      * Sets whether sheet is selected.
+     *
      * @param sel Whether to select the sheet or deselect the sheet.
      */
     public void setSelected(boolean sel) {
         getSheet().getWindowTwo().setSelected(sel);
     }
+
     /**
      * @return <code>true</code> if this sheet is currently focused
      */
     public boolean isActive() {
         return getSheet().getWindowTwo().isActive();
     }
+
     /**
      * Sets whether sheet is selected.
+     *
      * @param sel Whether to select the sheet or deselect the sheet.
      */
     public void setActive(boolean sel) {
@@ -1069,11 +1077,12 @@ public final class HSSFSheet implements 
 
     /**
      * Gets the size of the margin in inches.
+     *
      * @param margin which margin to get
      * @return the size of the margin
      */
     public double getMargin(short margin) {
-        switch (margin){
+        switch (margin) {
             case FooterMargin:
                 return _sheet.getPageSettings().getPrintSetup().getFooterMargin();
             case HeaderMargin:
@@ -1085,11 +1094,12 @@ public final class HSSFSheet implements 
 
     /**
      * Sets the size of the margin in inches.
+     *
      * @param margin which margin to get
-     * @param size the size of the margin
+     * @param size   the size of the margin
      */
     public void setMargin(short margin, double size) {
-        switch (margin){
+        switch (margin) {
             case FooterMargin:
                 _sheet.getPageSettings().getPrintSetup().setFooterMargin(size);
                 break;
@@ -1104,8 +1114,10 @@ public final class HSSFSheet implements 
     private WorksheetProtectionBlock getProtectionBlock() {
         return _sheet.getProtectionBlock();
     }
+
     /**
      * Answer whether protection is enabled or disabled
+     *
      * @return true => protection enabled; false => protection disabled
      */
     public boolean getProtect() {
@@ -1116,11 +1128,12 @@ public final class HSSFSheet implements 
      * @return hashed password
      */
     public short getPassword() {
-        return (short)getProtectionBlock().getPasswordHash();
+        return (short) getProtectionBlock().getPasswordHash();
     }
 
     /**
      * Answer whether object protection is enabled or disabled
+     *
      * @return true => protection enabled; false => protection disabled
      */
     public boolean getObjectProtect() {
@@ -1129,13 +1142,16 @@ public final class HSSFSheet implements 
 
     /**
      * Answer whether scenario protection is enabled or disabled
+     *
      * @return true => protection enabled; false => protection disabled
      */
     public boolean getScenarioProtect() {
         return getProtectionBlock().isScenarioProtected();
     }
+
     /**
      * Sets the protection enabled as well as the password
+     *
      * @param password to set for protection. Pass <code>null</code> to remove protection
      */
     public void protectSheet(String password) {
@@ -1147,25 +1163,25 @@ public final class HSSFSheet implements 
      * fraction.  For example to express a zoom of 75% use 3 for the numerator
      * and 4 for the denominator.
      *
-     * @param numerator     The numerator for the zoom magnification.
-     * @param denominator   The denominator for the zoom magnification.
+     * @param numerator   The numerator for the zoom magnification.
+     * @param denominator The denominator for the zoom magnification.
      */
-    public void setZoom( int numerator, int denominator)
-    {
+    public void setZoom(int numerator, int denominator) {
         if (numerator < 1 || numerator > 65535)
             throw new IllegalArgumentException("Numerator must be greater than 1 and less than 65536");
         if (denominator < 1 || denominator > 65535)
             throw new IllegalArgumentException("Denominator must be greater than 1 and less than 65536");
 
         SCLRecord sclRecord = new SCLRecord();
-        sclRecord.setNumerator((short)numerator);
-        sclRecord.setDenominator((short)denominator);
+        sclRecord.setNumerator((short) numerator);
+        sclRecord.setDenominator((short) denominator);
         getSheet().setSCLRecord(sclRecord);
     }
 
     /**
      * The top row in the visible view when the sheet is
      * first viewed after opening it in a viewer
+     *
      * @return short indicating the rownum (0 based) of the top row
      */
     public short getTopRow() {
@@ -1175,6 +1191,7 @@ public final class HSSFSheet implements 
     /**
      * The left col in the visible view when the sheet is
      * first viewed after opening it in a viewer
+     *
      * @return short indicating the rownum (0 based) of the top row
      */
     public short getLeftCol() {
@@ -1184,18 +1201,20 @@ public final class HSSFSheet implements 
     /**
      * Sets desktop window pane display area, when the
      * file is first opened in a viewer.
-     * @param toprow the top row to show in desktop window pane
+     *
+     * @param toprow  the top row to show in desktop window pane
      * @param leftcol the left column to show in desktop window pane
      */
-    public void showInPane(short toprow, short leftcol){
+    public void showInPane(short toprow, short leftcol) {
         _sheet.setTopRow(toprow);
         _sheet.setLeftCol(leftcol);
     }
 
     /**
      * Shifts the merged regions left or right depending on mode
-     * <p>
+     * <p/>
      * TODO: MODE , this is only row specific
+     *
      * @param startRow
      * @param endRow
      * @param n
@@ -1205,26 +1224,26 @@ public final class HSSFSheet implements 
         List<CellRangeAddress> shiftedRegions = new ArrayList<CellRangeAddress>();
         //move merged regions completely if they fall within the new region boundaries when they are shifted
         for (int i = 0; i < getNumMergedRegions(); i++) {
-             CellRangeAddress merged = getMergedRegion(i);
+            CellRangeAddress merged = getMergedRegion(i);
 
-             boolean inStart= (merged.getFirstRow() >= startRow || merged.getLastRow() >= startRow);
-             boolean inEnd  = (merged.getFirstRow() <= endRow   || merged.getLastRow() <= endRow);
+            boolean inStart = (merged.getFirstRow() >= startRow || merged.getLastRow() >= startRow);
+            boolean inEnd = (merged.getFirstRow() <= endRow || merged.getLastRow() <= endRow);
 
-             //don't check if it's not within the shifted area
-             if (!inStart || !inEnd) {
+            //don't check if it's not within the shifted area
+            if (!inStart || !inEnd) {
                 continue;
-             }
+            }
 
-             //only shift if the region outside the shifted rows is not merged too
-             if (!SheetUtil.containsCell(merged, startRow-1, 0) &&
-                 !SheetUtil.containsCell(merged, endRow+1, 0)){
-                 merged.setFirstRow(merged.getFirstRow()+n);
-                 merged.setLastRow(merged.getLastRow()+n);
-                 //have to remove/add it back
-                 shiftedRegions.add(merged);
-                 removeMergedRegion(i);
-                 i = i -1; // we have to back up now since we removed one
-             }
+            //only shift if the region outside the shifted rows is not merged too
+            if (!SheetUtil.containsCell(merged, startRow - 1, 0) &&
+                    !SheetUtil.containsCell(merged, endRow + 1, 0)) {
+                merged.setFirstRow(merged.getFirstRow() + n);
+                merged.setLastRow(merged.getLastRow() + n);
+                //have to remove/add it back
+                shiftedRegions.add(merged);
+                removeMergedRegion(i);
+                i = i - 1; // we have to back up now since we removed one
+            }
         }
 
         //read so it doesn't get shifted again
@@ -1240,17 +1259,18 @@ public final class HSSFSheet implements 
      * Shifts rows between startRow and endRow n number of rows.
      * If you use a negative number, it will shift rows up.
      * Code ensures that rows don't wrap around.
-     *
+     * <p/>
      * Calls shiftRows(startRow, endRow, n, false, false);
-     *
-     * <p>
+     * <p/>
+     * <p/>
      * Additionally shifts merged regions that are completely defined in these
      * rows (ie. merged 2 cells on a row to be shifted).
+     *
      * @param startRow the row to start shifting
-     * @param endRow the row to end shifting
-     * @param n the number of rows to shift
+     * @param endRow   the row to end shifting
+     * @param n        the number of rows to shift
      */
-    public void shiftRows( int startRow, int endRow, int n ) {
+    public void shiftRows(int startRow, int endRow, int n) {
         shiftRows(startRow, endRow, n, false, false);
     }
 
@@ -1258,19 +1278,20 @@ public final class HSSFSheet implements 
      * Shifts rows between startRow and endRow n number of rows.
      * If you use a negative number, it will shift rows up.
      * Code ensures that rows don't wrap around
-     *
-     * <p>
+     * <p/>
+     * <p/>
      * Additionally shifts merged regions that are completely defined in these
      * rows (ie. merged 2 cells on a row to be shifted).
-     * <p>
+     * <p/>
      * TODO Might want to add bounds checking here
-     * @param startRow the row to start shifting
-     * @param endRow the row to end shifting
-     * @param n the number of rows to shift
-     * @param copyRowHeight whether to copy the row height during the shift
+     *
+     * @param startRow               the row to start shifting
+     * @param endRow                 the row to end shifting
+     * @param n                      the number of rows to shift
+     * @param copyRowHeight          whether to copy the row height during the shift
      * @param resetOriginalRowHeight whether to set the original row's height to the default
      */
-    public void shiftRows( int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight) {
+    public void shiftRows(int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight) {
         shiftRows(startRow, endRow, n, copyRowHeight, resetOriginalRowHeight, true);
     }
 
@@ -1278,21 +1299,22 @@ public final class HSSFSheet implements 
      * Shifts rows between startRow and endRow n number of rows.
      * If you use a negative number, it will shift rows up.
      * Code ensures that rows don't wrap around
-     *
-     * <p>
+     * <p/>
+     * <p/>
      * Additionally shifts merged regions that are completely defined in these
      * rows (ie. merged 2 cells on a row to be shifted).
-     * <p>
+     * <p/>
      * TODO Might want to add bounds checking here
-     * @param startRow the row to start shifting
-     * @param endRow the row to end shifting
-     * @param n the number of rows to shift
-     * @param copyRowHeight whether to copy the row height during the shift
+     *
+     * @param startRow               the row to start shifting
+     * @param endRow                 the row to end shifting
+     * @param n                      the number of rows to shift
+     * @param copyRowHeight          whether to copy the row height during the shift
      * @param resetOriginalRowHeight whether to set the original row's height to the default
-     * @param moveComments whether to move comments at the same time as the cells they are attached to
+     * @param moveComments           whether to move comments at the same time as the cells they are attached to
      */
     public void shiftRows(int startRow, int endRow, int n,
-            boolean copyRowHeight, boolean resetOriginalRowHeight, boolean moveComments) {
+                          boolean copyRowHeight, boolean resetOriginalRowHeight, boolean moveComments) {
         int s, inc;
         if (n < 0) {
             s = startRow;
@@ -1301,10 +1323,10 @@ public final class HSSFSheet implements 
             s = endRow;
             inc = -1;
         } else {
-           // Nothing to do
-           return;
+            // Nothing to do
+            return;
         }
-        
+
         NoteRecord[] noteRecs;
         if (moveComments) {
             noteRecs = _sheet.getNoteRecords();
@@ -1315,16 +1337,16 @@ public final class HSSFSheet implements 
         shiftMerged(startRow, endRow, n, true);
         _sheet.getPageSettings().shiftRowBreaks(startRow, endRow, n);
 
-        for ( int rowNum = s; rowNum >= startRow && rowNum <= endRow && rowNum >= 0 && rowNum < 65536; rowNum += inc ) {
-            HSSFRow row = getRow( rowNum );
+        for (int rowNum = s; rowNum >= startRow && rowNum <= endRow && rowNum >= 0 && rowNum < 65536; rowNum += inc) {
+            HSSFRow row = getRow(rowNum);
             // notify all cells in this row that we are going to shift them,
             // it can throw IllegalStateException if the operation is not allowed, for example,
             // if the row contains cells included in a multi-cell array formula
-            if(row != null) notifyRowShifting(row);
+            if (row != null) notifyRowShifting(row);
 
-            HSSFRow row2Replace = getRow( rowNum + n );
-            if ( row2Replace == null )
-                row2Replace = createRow( rowNum + n );
+            HSSFRow row2Replace = getRow(rowNum + n);
+            if (row2Replace == null)
+                row2Replace = createRow(rowNum + n);
 
 
             // Remove all the old cells from the row we'll
@@ -1343,21 +1365,21 @@ public final class HSSFSheet implements 
                 row2Replace.setHeight(row.getHeight());
             }
             if (resetOriginalRowHeight) {
-                row.setHeight((short)0xff);
+                row.setHeight((short) 0xff);
             }
 
             // Copy each cell from the source row to
             //  the destination row
-            for(Iterator<Cell> cells = row.cellIterator(); cells.hasNext(); ) {
-                HSSFCell cell = (HSSFCell)cells.next();
-                row.removeCell( cell );
+            for (Iterator<Cell> cells = row.cellIterator(); cells.hasNext(); ) {
+                HSSFCell cell = (HSSFCell) cells.next();
+                row.removeCell(cell);
                 CellValueRecordInterface cellRecord = cell.getCellValueRecord();
-                cellRecord.setRow( rowNum + n );
-                row2Replace.createCellFromRecord( cellRecord );
-                _sheet.addValueRecord( rowNum + n, cellRecord );
+                cellRecord.setRow(rowNum + n);
+                row2Replace.createCellFromRecord(cellRecord);
+                _sheet.addValueRecord(rowNum + n, cellRecord);
 
                 HSSFHyperlink link = cell.getHyperlink();
-                if(link != null){
+                if (link != null) {
                     link.setFirstRow(link.getFirstRow() + n);
                     link.setLastRow(link.getLastRow() + n);
                 }
@@ -1368,54 +1390,54 @@ public final class HSSFSheet implements 
             // Move comments from the source row to the
             //  destination row. Note that comments can
             //  exist for cells which are null
-            if(moveComments) {
+            if (moveComments) {
                 // This code would get simpler if NoteRecords could be organised by HSSFRow.
                 HSSFPatriarch patriarch = createDrawingPatriarch();
-                for(int i=patriarch.getChildren().size()-1; i>=0; i--){
+                for (int i = patriarch.getChildren().size() - 1; i >= 0; i--) {
                     HSSFShape shape = patriarch.getChildren().get(i);
-                    if (!(shape instanceof HSSFComment)){
+                    if (!(shape instanceof HSSFComment)) {
                         continue;
                     }
                     HSSFComment comment = (HSSFComment) shape;
-                    if (comment.getRow() != rowNum){
+                    if (comment.getRow() != rowNum) {
                         continue;
                     }
                     comment.setRow(rowNum + n);
                 }
             }
         }
-        
+
         // Re-compute the first and last rows of the sheet as needed
-        if(n > 0) {
-           // Rows are moving down
-           if ( startRow == _firstrow ) {
-              // Need to walk forward to find the first non-blank row
-              _firstrow = Math.max( startRow + n, 0 );
-              for( int i=startRow+1; i < startRow+n; i++ ) {
-                 if (getRow(i) != null) {
-                    _firstrow = i;
-                    break;
-                 }
-              }
-           }
-           if ( endRow + n > _lastrow ) {
-              _lastrow = Math.min( endRow + n, SpreadsheetVersion.EXCEL97.getLastRowIndex() );
-           }
+        if (n > 0) {
+            // Rows are moving down
+            if (startRow == _firstrow) {
+                // Need to walk forward to find the first non-blank row
+                _firstrow = Math.max(startRow + n, 0);
+                for (int i = startRow + 1; i < startRow + n; i++) {
+                    if (getRow(i) != null) {
+                        _firstrow = i;
+                        break;
+                    }
+                }
+            }
+            if (endRow + n > _lastrow) {
+                _lastrow = Math.min(endRow + n, SpreadsheetVersion.EXCEL97.getLastRowIndex());
+            }
         } else {
-           // Rows are moving up
-           if ( startRow + n < _firstrow ) {
-              _firstrow = Math.max( startRow + n, 0 );
-           }
-           if ( endRow == _lastrow  ) {
-              // Need to walk backward to find the last non-blank row
-              _lastrow = Math.min( endRow + n, SpreadsheetVersion.EXCEL97.getLastRowIndex() );
-              for (int i=endRow-1; i > endRow+n; i++) {
-                 if (getRow(i) != null) {
-                    _lastrow = i;
-                    break;
-                 }
-              }
-           }
+            // Rows are moving up
+            if (startRow + n < _firstrow) {
+                _firstrow = Math.max(startRow + n, 0);
+            }
+            if (endRow == _lastrow) {
+                // Need to walk backward to find the last non-blank row
+                _lastrow = Math.min(endRow + n, SpreadsheetVersion.EXCEL97.getLastRowIndex());
+                for (int i = endRow - 1; i > endRow + n; i++) {
+                    if (getRow(i) != null) {
+                        _lastrow = i;
+                        break;
+                    }
+                }
+            }
         }
 
         // Update any formulas on this sheet that point to
@@ -1426,7 +1448,7 @@ public final class HSSFSheet implements 
         _sheet.updateFormulasAfterCellShift(shifter, externSheetIndex);
 
         int nSheets = _workbook.getNumberOfSheets();
-        for(int i=0; i<nSheets; i++) {
+        for (int i = 0; i < nSheets; i++) {
             InternalSheet otherSheet = _workbook.getSheetAt(i).getSheet();
             if (otherSheet == this._sheet) {
                 continue;
@@ -1442,12 +1464,12 @@ public final class HSSFSheet implements 
         _sheet.getRecords().addAll(window2Loc, records);
     }
 
-    private void notifyRowShifting(HSSFRow row){
-        String msg = "Row[rownum="+row.getRowNum()+"] contains cell(s) included in a multi-cell array formula. " +
+    private void notifyRowShifting(HSSFRow row) {
+        String msg = "Row[rownum=" + row.getRowNum() + "] contains cell(s) included in a multi-cell array formula. " +
                 "You cannot change part of an array.";
-        for(Cell cell : row){
-            HSSFCell hcell = (HSSFCell)cell;
-            if(hcell.isPartOfArrayFormulaGroup()){
+        for (Cell cell : row) {
+            HSSFCell hcell = (HSSFCell) cell;
+            if (hcell.isPartOfArrayFormulaGroup()) {
                 hcell.notifyArrayFormulaChanging(msg);
             }
         }
@@ -1455,33 +1477,35 @@ public final class HSSFSheet implements 
 
     /**
      * Creates a split (freezepane). Any existing freezepane or split pane is overwritten.
-     *
+     * <p/>
      * <p>
-     *     If both colSplit and rowSplit are zero then the existing freeze pane is removed
+     * If both colSplit and rowSplit are zero then the existing freeze pane is removed
      * </p>
      *
-     * @param colSplit      Horizonatal position of split.
-     * @param rowSplit      Vertical position of split.
-     * @param leftmostColumn   Left column visible in right pane.
-     * @param topRow        Top row visible in bottom pane
+     * @param colSplit       Horizonatal position of split.
+     * @param rowSplit       Vertical position of split.
+     * @param leftmostColumn Left column visible in right pane.
+     * @param topRow         Top row visible in bottom pane
      */
     public void createFreezePane(int colSplit, int rowSplit, int leftmostColumn, int topRow) {
         validateColumn(colSplit);
         validateRow(rowSplit);
-        if (leftmostColumn < colSplit) throw new IllegalArgumentException("leftmostColumn parameter must not be less than colSplit parameter");
-        if (topRow < rowSplit) throw new IllegalArgumentException("topRow parameter must not be less than leftmostColumn parameter");
-        getSheet().createFreezePane( colSplit, rowSplit, topRow, leftmostColumn );
+        if (leftmostColumn < colSplit)
+            throw new IllegalArgumentException("leftmostColumn parameter must not be less than colSplit parameter");
+        if (topRow < rowSplit)
+            throw new IllegalArgumentException("topRow parameter must not be less than leftmostColumn parameter");
+        getSheet().createFreezePane(colSplit, rowSplit, topRow, leftmostColumn);
     }
 
     /**
      * Creates a split (freezepane). Any existing freezepane or split pane is overwritten.
-     *
+     * <p/>
      * <p>
-     *     If both colSplit and rowSplit are zero then the existing freeze pane is removed
+     * If both colSplit and rowSplit are zero then the existing freeze pane is removed
      * </p>
      *
-     * @param colSplit      Horizonatal position of split.
-     * @param rowSplit      Vertical position of split.
+     * @param colSplit Horizonatal position of split.
+     * @param rowSplit Vertical position of split.
      */
     public void createFreezePane(int colSplit, int rowSplit) {
         createFreezePane(colSplit, rowSplit, colSplit, rowSplit);
@@ -1489,23 +1513,25 @@ public final class HSSFSheet implements 
 
     /**
      * Creates a split pane. Any existing freezepane or split pane is overwritten.
+     *
      * @param xSplitPos      Horizonatal position of split (in 1/20th of a point).
      * @param ySplitPos      Vertical position of split (in 1/20th of a point).
-     * @param topRow        Top row visible in bottom pane
-     * @param leftmostColumn   Left column visible in right pane.
-     * @param activePane    Active pane.  One of: PANE_LOWER_RIGHT,
-     *                      PANE_UPPER_RIGHT, PANE_LOWER_LEFT, PANE_UPPER_LEFT
+     * @param topRow         Top row visible in bottom pane
+     * @param leftmostColumn Left column visible in right pane.
+     * @param activePane     Active pane.  One of: PANE_LOWER_RIGHT,
+     *                       PANE_UPPER_RIGHT, PANE_LOWER_LEFT, PANE_UPPER_LEFT
      * @see #PANE_LOWER_LEFT
      * @see #PANE_LOWER_RIGHT
      * @see #PANE_UPPER_LEFT
      * @see #PANE_UPPER_RIGHT
      */
     public void createSplitPane(int xSplitPos, int ySplitPos, int leftmostColumn, int topRow, int activePane) {
-        getSheet().createSplitPane( xSplitPos, ySplitPos, topRow, leftmostColumn, activePane );
+        getSheet().createSplitPane(xSplitPos, ySplitPos, topRow, leftmostColumn, activePane);
     }
 
     /**
      * Returns the information regarding the currently configured pane (split or freeze).
+     *
      * @return null if no pane configured, or the pane information.
      */
     public PaneInformation getPaneInformation() {
@@ -1514,6 +1540,7 @@ public final class HSSFSheet implements 
 
     /**
      * Sets whether the gridlines are shown in a viewer.
+     *
      * @param show whether to show gridlines or not
      */
     public void setDisplayGridlines(boolean show) {
@@ -1522,14 +1549,16 @@ public final class HSSFSheet implements 
 
     /**
      * Returns if gridlines are displayed.
+     *
      * @return whether gridlines are displayed
      */
     public boolean isDisplayGridlines() {
-    return _sheet.isDisplayGridlines();
+        return _sheet.isDisplayGridlines();
     }
 
     /**
      * Sets whether the formulas are shown in a viewer.
+     *
      * @param show whether to show formulas or not
      */
     public void setDisplayFormulas(boolean show) {
@@ -1538,6 +1567,7 @@ public final class HSSFSheet implements 
 
     /**
      * Returns if formulas are displayed.
+     *
      * @return whether formulas are displayed
      */
     public boolean isDisplayFormulas() {
@@ -1546,6 +1576,7 @@ public final class HSSFSheet implements 
 
     /**
      * Sets whether the RowColHeadings are shown in a viewer.
+     *
      * @param show whether to show RowColHeadings or not
      */
     public void setDisplayRowColHeadings(boolean show) {
@@ -1554,6 +1585,7 @@ public final class HSSFSheet implements 
 
     /**
      * Returns if RowColHeadings are displayed.
+     *
      * @return whether RowColHeadings are displayed
      */
     public boolean isDisplayRowColHeadings() {
@@ -1563,7 +1595,7 @@ public final class HSSFSheet implements 
     /**
      * Sets a page break at the indicated row
      * Breaks occur above the specified row and left of the specified column inclusive.
-     *
+     * <p/>
      * For example, <code>sheet.setColumnBreak(2);</code> breaks the sheet into two parts
      * with columns A,B,C in the first and D,E,... in the second. Simuilar, <code>sheet.setRowBreak(2);</code>
      * breaks the sheet into two parts with first three rows (rownum=1...3) in the first part
@@ -1573,7 +1605,7 @@ public final class HSSFSheet implements 
      */
     public void setRowBreak(int row) {
         validateRow(row);
-        _sheet.getPageSettings().setRowBreak(row, (short)0, (short)255);
+        _sheet.getPageSettings().setRowBreak(row, (short) 0, (short) 255);
     }
 
     /**
@@ -1610,7 +1642,7 @@ public final class HSSFSheet implements 
     /**
      * Sets a page break at the indicated column.
      * Breaks occur above the specified row and left of the specified column inclusive.
-     *
+     * <p/>
      * For example, <code>sheet.setColumnBreak(2);</code> breaks the sheet into two parts
      * with columns A,B,C in the first and D,E,... in the second. Simuilar, <code>sheet.setRowBreak(2);</code>
      * breaks the sheet into two parts with first three rows (rownum=1...3) in the first part
@@ -1619,12 +1651,13 @@ public final class HSSFSheet implements 
      * @param column the column to break, inclusive
      */
     public void setColumnBreak(int column) {
-        validateColumn((short)column);
-        _sheet.getPageSettings().setColumnBreak((short)column, (short)0, (short) SpreadsheetVersion.EXCEL97.getLastRowIndex());
+        validateColumn((short) column);
+        _sheet.getPageSettings().setColumnBreak((short) column, (short) 0, (short) SpreadsheetVersion.EXCEL97.getLastRowIndex());
     }
 
     /**
      * Determines if there is a page break at the indicated column
+     *
      * @param column FIXME: Document this!
      * @return FIXME: Document this!
      */
@@ -1634,6 +1667,7 @@ public final class HSSFSheet implements 
 
     /**
      * Removes a page break at the indicated column
+     *
      * @param column
      */
     public void removeColumnBreak(int column) {
@@ -1642,6 +1676,7 @@ public final class HSSFSheet implements 
 
     /**
      * Runs a bounds check for row numbers
+     *
      * @param row
      */
     protected void validateRow(int row) {
@@ -1652,12 +1687,13 @@ public final class HSSFSheet implements 
 
     /**
      * Runs a bounds check for column numbers
+     *
      * @param column
      */
     protected void validateColumn(int column) {
         int maxcol = SpreadsheetVersion.EXCEL97.getLastColumnIndex();
         if (column > maxcol) throw new IllegalArgumentException("Maximum column number is " + maxcol);
-        if (column < 0)    throw new IllegalArgumentException("Minimum column number is 0");
+        if (column < 0) throw new IllegalArgumentException("Minimum column number is 0");
     }
 
     /**
@@ -1670,7 +1706,7 @@ public final class HSSFSheet implements 
         EscherAggregate r = (EscherAggregate) getSheet().findFirstRecordBySid(EscherAggregate.sid);
         List<EscherRecord> escherRecords = r.getEscherRecords();
         PrintWriter w = new PrintWriter(System.out);
-        for (Iterator<EscherRecord> iterator = escherRecords.iterator(); iterator.hasNext();) {
+        for (Iterator<EscherRecord> iterator = escherRecords.iterator(); iterator.hasNext(); ) {
             EscherRecord escherRecord = iterator.next();
             if (fat) {
                 System.out.println(escherRecord.toString());
@@ -1682,49 +1718,22 @@ public final class HSSFSheet implements 
     }
 
     /**
-     * Creates the top-level drawing patriarch.  This will have
-     *  the effect of removing any existing drawings on this
-     *  sheet.
-     * This may then be used to add graphics or charts
-     * @return  The new patriarch.
-     */
-    public HSSFPatriarch createDrawingPatriarch() {
-        if(_patriarch == null){
-            // Create the drawing group if it doesn't already exist.
-            _workbook.initDrawings();
-
-            if(_patriarch == null){
-                _sheet.aggregateDrawingRecords(_book.getDrawingManager(), true);
-                EscherAggregate agg = (EscherAggregate) _sheet.findFirstRecordBySid(EscherAggregate.sid);
-                _patriarch = new HSSFPatriarch(this, agg);
-                _patriarch.afterCreate();
-//                agg.setPatriarch(_patriarch);
-            }
-        }
-        return _patriarch;
-    }
-
-    /**
      * Returns the agregate escher records for this sheet,
-     *  it there is one.
-     * WARNING - calling this will trigger a parsing of the
-     *  associated escher records. Any that aren't supported
-     *  (such as charts and complex drawing types) will almost
-     *  certainly be lost or corrupted when written out.
+     * it there is one.
      */
     public EscherAggregate getDrawingEscherAggregate() {
         _book.findDrawingGroup();
 
         // If there's now no drawing manager, then there's
         //  no drawing escher records on the workbook
-        if(_book.getDrawingManager() == null) {
+        if (_book.getDrawingManager() == null) {
             return null;
         }
 
         int found = _sheet.aggregateDrawingRecords(
                 _book.getDrawingManager(), false
         );
-        if(found == -1) {
+        if (found == -1) {
             // Workbook has drawing stuff, but this sheet doesn't
             return null;
         }
@@ -1735,51 +1744,76 @@ public final class HSSFSheet implements 
     }
 
     /**
-     * Returns the top-level drawing patriach, if there is
-     *  one.
      * This will hold any graphics or charts for the sheet.
-     * WARNING - calling this will trigger a parsing of the
-     *  associated escher records. Any that aren't supported
-     *  (such as charts and complex drawing types) will almost
-     *  certainly be lost or corrupted when written out. Only
-     *  use this with simple drawings, otherwise call
-     *  {@link HSSFSheet#createDrawingPatriarch()} and
-     *  start from scratch!
+     *
+     * @return the top-level drawing patriarch, if there is one, else returns null
      */
     public HSSFPatriarch getDrawingPatriarch() {
-        if(_patriarch != null) return _patriarch;
-        
-        EscherAggregate agg = getDrawingEscherAggregate();
-        if(agg == null) return null;
-
-        _patriarch = new HSSFPatriarch(this, agg);
-//        _patriarch.buildShapeTree();
-
-        //HSSFShapeFactory.createShapeTree();
-        //agg.setPatriarch(_patriarch);
-        //EscherAggregate.createShapeTree(EscherAggregate.getMainSpgrContainer(agg), agg.getPatriarch(), agg);
-
-        // Have it process the records into high level objects
-        //  as best it can do (this step may eat anything
-        //  that isn't supported, you were warned...)
-//        agg.convertRecordsToUserModel();
-
-        // Return what we could cope with
+        _patriarch = getPatriarch(false);
         return _patriarch;
     }
 
     /**
-     * @deprecated (Sep 2008) use {@link #setColumnGroupCollapsed(int, boolean)}
+     * Creates the top-level drawing patriarch.  This will have
+     * the effect of removing any existing drawings on this
+     * sheet.
+     * This may then be used to add graphics or charts
+     *
+     * @return The new patriarch.
      */
+    public HSSFPatriarch createDrawingPatriarch() {
+        _patriarch = getPatriarch(true);
+        return _patriarch;
+    }
+
+    private HSSFPatriarch getPatriarch(boolean createIfMissing) {
+        HSSFPatriarch patriarch = null;
+        if (_patriarch != null) {
+            return _patriarch;
+        }
+        DrawingManager2 dm = _book.findDrawingGroup();
+        if (null == dm) {
+            if (!createIfMissing) {
+                return null;
+            } else {
+                _book.createDrawingGroup();
+                dm = _book.getDrawingManager();
+            }
+        }
+        EscherAggregate agg = (EscherAggregate) _sheet.findFirstRecordBySid(EscherAggregate.sid);
+        if (null == agg) {
+            int pos = _sheet.aggregateDrawingRecords(dm, false);
+            if (-1 == pos) {
+                if (createIfMissing) {
+                    pos = _sheet.aggregateDrawingRecords(dm, true);
+                    agg = (EscherAggregate) _sheet.getRecords().get(pos);
+                    patriarch = new HSSFPatriarch(this, agg);
+                    patriarch.afterCreate();
+                    return patriarch;
+                } else {
+                    return null;
+                }
+            }
+            agg = (EscherAggregate) _sheet.getRecords().get(pos);
+        }
+        return new HSSFPatriarch(this, agg);
+    }
+
+        /**
+         * @deprecated (Sep 2008) use {@link #setColumnGroupCollapsed(int, boolean)}
+         */
+
     public void setColumnGroupCollapsed(short columnNumber, boolean collapsed) {
         setColumnGroupCollapsed(columnNumber & 0xFFFF, collapsed);
     }
+
     /**
      * @deprecated (Sep 2008) use {@link #groupColumn(int, int)}
      */
     public void groupColumn(short fromColumn, short toColumn) {
         groupColumn(fromColumn & 0xFFFF, toColumn & 0xFFFF);
     }
+
     /**
      * @deprecated (Sep 2008) use {@link #ungroupColumn(int, int)}
      */
@@ -1790,8 +1824,8 @@ public final class HSSFSheet implements 
     /**
      * Expands or collapses a column group.
      *
-     * @param columnNumber      One of the columns in the group.
-     * @param collapsed         true = collapse group, false = expand group.
+     * @param columnNumber One of the columns in the group.
+     * @param collapsed    true = collapse group, false = expand group.
      */
     public void setColumnGroupCollapsed(int columnNumber, boolean collapsed) {
         _sheet.setColumnGroupCollapsed(columnNumber, collapsed);
@@ -1800,8 +1834,8 @@ public final class HSSFSheet implements 
     /**
      * Create an outline for the provided column range.
      *
-     * @param fromColumn        beginning of the column range.
-     * @param toColumn          end of the column range.
+     * @param fromColumn beginning of the column range.
+     * @param toColumn   end of the column range.
      */
     public void groupColumn(int fromColumn, int toColumn) {
         _sheet.groupColumnRange(fromColumn, toColumn, true);
@@ -1814,8 +1848,8 @@ public final class HSSFSheet implements 
     /**
      * Tie a range of cell together so that they can be collapsed or expanded
      *
-     * @param fromRow   start row (0-based)
-     * @param toRow     end row (0-based)
+     * @param fromRow start row (0-based)
+     * @param toRow   end row (0-based)
      */
     public void groupRow(int fromRow, int toRow) {
         _sheet.groupRowRange(fromRow, toRow, true);
@@ -1837,18 +1871,18 @@ public final class HSSFSheet implements 
      * Sets the default column style for a given column.  POI will only apply this style to new cells added to the sheet.
      *
      * @param column the column index
-     * @param style the style to set
+     * @param style  the style to set
      */
     public void setDefaultColumnStyle(int column, CellStyle style) {
-        _sheet.setDefaultColumnStyle(column, ((HSSFCellStyle)style).getIndex());
+        _sheet.setDefaultColumnStyle(column, ((HSSFCellStyle) style).getIndex());
     }
 
     /**
      * Adjusts the column width to fit the contents.
-     *
+     * <p/>
      * This process can be relatively slow on large sheets, so this should
-     *  normally only be called once per column, at the end of your
-     *  processing.
+     * normally only be called once per column, at the end of your
+     * processing.
      *
      * @param column the column index
      */
@@ -1858,15 +1892,15 @@ public final class HSSFSheet implements 
 
     /**
      * Adjusts the column width to fit the contents.
-     *
+     * <p/>
      * This process can be relatively slow on large sheets, so this should
-     *  normally only be called once per column, at the end of your
-     *  processing.
-     *
+     * normally only be called once per column, at the end of your
+     * processing.
+     * <p/>
      * You can specify whether the content of merged cells should be considered or ignored.
-     *  Default is to ignore merged cells.
+     * Default is to ignore merged cells.
      *
-     * @param column the column index
+     * @param column         the column index
      * @param useMergedCells whether to use the contents of merged cells when calculating the width of the column
      */
     public void autoSizeColumn(int column, boolean useMergedCells) {
@@ -1874,11 +1908,11 @@ public final class HSSFSheet implements 
 
         if (width != -1) {
             width *= 256;
-            int maxColumnWidth = 255*256; // The maximum column width for an individual cell is 255 characters
+            int maxColumnWidth = 255 * 256; // The maximum column width for an individual cell is 255 characters
             if (width > maxColumnWidth) {
                 width = maxColumnWidth;
             }
-            setColumnWidth(column, (int)(width));
+            setColumnWidth(column, (int) (width));
         }
 
     }
@@ -1888,7 +1922,7 @@ public final class HSSFSheet implements 
      *
      * @return cell comment or <code>null</code> if not found
      */
-     public HSSFComment getCellComment(int row, int column) {
+    public HSSFComment getCellComment(int row, int column) {
         return findCellComment(row, column);
     }
 
@@ -1917,7 +1951,7 @@ public final class HSSFSheet implements 
         int lastColumn = range.getLastColumn();
         int height = lastRow - firstRow + 1;
         int width = lastColumn - firstColumn + 1;
-        List<HSSFCell> temp = new ArrayList<HSSFCell>(height*width);
+        List<HSSFCell> temp = new ArrayList<HSSFCell>(height * width);
         for (int rowIn = firstRow; rowIn <= lastRow; rowIn++) {
             for (int colIn = firstColumn; colIn <= lastColumn; colIn++) {
                 HSSFRow row = getRow(rowIn);
@@ -1944,7 +1978,7 @@ public final class HSSFSheet implements 
             c.setCellArrayFormula(range);
         }
         HSSFCell mainArrayFormulaCell = cells.getTopLeftCell();
-        FormulaRecordAggregate agg = (FormulaRecordAggregate)mainArrayFormulaCell.getCellValueRecord();
+        FormulaRecordAggregate agg = (FormulaRecordAggregate) mainArrayFormulaCell.getCellValueRecord();
         agg.setArrayFormula(range, ptgs);
         return cells;
     }
@@ -1970,20 +2004,20 @@ public final class HSSFSheet implements 
         return result;
     }
 
-	public DataValidationHelper getDataValidationHelper() {
-		return new HSSFDataValidationHelper(this);
-	}
-    
+    public DataValidationHelper getDataValidationHelper() {
+        return new HSSFDataValidationHelper(this);
+    }
+
     public HSSFAutoFilter setAutoFilter(CellRangeAddress range) {
 
 
         InternalWorkbook workbook = _workbook.getWorkbook();
         int sheetIndex = _workbook.getSheetIndex(this);
 
-        NameRecord name = workbook.getSpecificBuiltinRecord(NameRecord.BUILTIN_FILTER_DB, sheetIndex+1);
+        NameRecord name = workbook.getSpecificBuiltinRecord(NameRecord.BUILTIN_FILTER_DB, sheetIndex + 1);
 
         if (name == null) {
-            name = workbook.createBuiltInName(NameRecord.BUILTIN_FILTER_DB, sheetIndex+1);
+            name = workbook.createBuiltInName(NameRecord.BUILTIN_FILTER_DB, sheetIndex + 1);
         }
 
         // The built-in name must consist of a single Area3d Ptg.
@@ -1995,41 +2029,41 @@ public final class HSSFSheet implements 
         AutoFilterInfoRecord r = new AutoFilterInfoRecord();
         // the number of columns that have AutoFilter enabled.
         int numcols = 1 + range.getLastColumn() - range.getFirstColumn();
-        r.setNumEntries((short)numcols);
+        r.setNumEntries((short) numcols);
         int idx = _sheet.findFirstRecordLocBySid(DimensionsRecord.sid);
         _sheet.getRecords().add(idx, r);
 
         //create a combobox control for each column
         HSSFPatriarch p = createDrawingPatriarch();
-        for(int col = range.getFirstColumn(); col <= range.getLastColumn(); col++){
-            p.createComboBox(new HSSFClientAnchor(0,0,0,0,
-                    (short)col, range.getFirstRow(), (short)(col+1), range.getFirstRow()+1));
+        for (int col = range.getFirstColumn(); col <= range.getLastColumn(); col++) {
+            p.createComboBox(new HSSFClientAnchor(0, 0, 0, 0,
+                    (short) col, range.getFirstRow(), (short) (col + 1), range.getFirstRow() + 1));
         }
-        
+
         return new HSSFAutoFilter(this);
     }
 
     protected HSSFComment findCellComment(int row, int column) {
         HSSFPatriarch patriarch = getDrawingPatriarch();
-        if (null == patriarch){
+        if (null == patriarch) {
             patriarch = createDrawingPatriarch();
         }
         return lookForComment(patriarch, row, column);
     }
 
-    private HSSFComment lookForComment(HSSFShapeContainer container, int row, int column){
-        for (Object object: container.getChildren()){
+    private HSSFComment lookForComment(HSSFShapeContainer container, int row, int column) {
+        for (Object object : container.getChildren()) {
             HSSFShape shape = (HSSFShape) object;
-            if (shape instanceof HSSFShapeGroup){
-                HSSFShape res =  lookForComment((HSSFShapeContainer) shape, row, column);
-                if (null != res){
+            if (shape instanceof HSSFShapeGroup) {
+                HSSFShape res = lookForComment((HSSFShapeContainer) shape, row, column);
+                if (null != res) {
                     return (HSSFComment) res;
                 }
                 continue;
             }
-            if (shape instanceof HSSFComment){
+            if (shape instanceof HSSFComment) {
                 HSSFComment comment = (HSSFComment) shape;
-                if (comment.getColumn() == column && comment.getRow() == row){
+                if (comment.getColumn() == column && comment.getRow() == row) {
                     return comment;
                 }
             }

Added: poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/usermodel/TestPatriarch.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/usermodel/TestPatriarch.java?rev=1368211&view=auto
==============================================================================
--- poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/usermodel/TestPatriarch.java (added)
+++ poi/branches/gsoc2012/src/testcases/org/apache/poi/hssf/usermodel/TestPatriarch.java Wed Aug  1 19:34:08 2012
@@ -0,0 +1,40 @@
+package org.apache.poi.hssf.usermodel;
+
+import junit.framework.TestCase;
+import org.apache.poi.ddf.EscherDgRecord;
+import org.apache.poi.hssf.HSSFTestDataSamples;
+import org.apache.poi.hssf.record.EscherAggregate;
+
+/**
+ * @author Evgeniy Berlog
+ * @date 01.08.12
+ */
+public class TestPatriarch extends TestCase {
+
+    public void testGetPatriarch(){
+        HSSFWorkbook wb = new HSSFWorkbook();
+        HSSFSheet sh = wb.createSheet();
+        assertNull(sh.getDrawingPatriarch());
+
+        HSSFPatriarch patriarch = sh.createDrawingPatriarch();
+        assertNotNull(patriarch);
+        patriarch.createSimpleShape(new HSSFClientAnchor());
+        patriarch.createSimpleShape(new HSSFClientAnchor());
+
+        assertSame(patriarch, sh.getDrawingPatriarch());
+
+        EscherAggregate agg = patriarch._getBoundAggregate();
+
+        EscherDgRecord dg = agg.getEscherContainer().getChildById(EscherDgRecord.RECORD_ID);
+        int lastId = dg.getLastMSOSPID();
+        
+        assertSame(patriarch, sh.createDrawingPatriarch());
+        
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        sh = wb.getSheetAt(0);
+        patriarch = sh.createDrawingPatriarch();
+        dg = patriarch._getBoundAggregate().getEscherContainer().getChildById(EscherDgRecord.RECORD_ID);
+
+        assertEquals(lastId, dg.getLastMSOSPID());
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org