Modified: 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
URL: 
http://svn.apache.org/viewvc/poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java?rev=1625828&r1=1625827&r2=1625828&view=diff
==============================================================================
--- 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
 (original)
+++ 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
 Wed Sep 17 21:12:36 2014
@@ -17,6 +17,9 @@
 
 package org.apache.poi.xssf.usermodel;
 
+import static 
org.apache.poi.xssf.usermodel.helpers.XSSFPaswordHelper.setPassword;
+import static 
org.apache.poi.xssf.usermodel.helpers.XSSFPaswordHelper.validatePassword;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -26,13 +29,13 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.TreeMap;
 
 import javax.xml.namespace.QName;
 
 import org.apache.poi.POIXMLDocumentPart;
 import org.apache.poi.POIXMLException;
-import org.apache.poi.hssf.record.PasswordRecord;
 import org.apache.poi.hssf.util.PaneInformation;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.openxml4j.exceptions.PartAlreadyExistsException;
@@ -40,6 +43,7 @@ import org.apache.poi.openxml4j.opc.Pack
 import org.apache.poi.openxml4j.opc.PackageRelationship;
 import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
 import org.apache.poi.openxml4j.opc.TargetMode;
+import org.apache.poi.poifs.crypt.HashAlgorithm;
 import org.apache.poi.ss.SpreadsheetVersion;
 import org.apache.poi.ss.formula.FormulaShifter;
 import org.apache.poi.ss.formula.SheetNameFormatter;
@@ -60,7 +64,6 @@ import org.apache.poi.ss.util.CellRefere
 import org.apache.poi.ss.util.SSCellRange;
 import org.apache.poi.ss.util.SheetUtil;
 import org.apache.poi.util.Beta;
-import org.apache.poi.util.HexDump;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
@@ -110,7 +113,6 @@ import org.openxmlformats.schemas.spread
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPane;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPaneState;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.STUnsignedShortHex;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorksheetDocument;
 
 /**
@@ -649,6 +651,28 @@ public class XSSFSheet extends POIXMLDoc
         return null;
     }
 
+    @SuppressWarnings("deprecation")
+    private int[] getBreaks(CTPageBreak ctPageBreak) {
+        CTBreak[] brkArray = ctPageBreak.getBrkArray();
+        int[] breaks = new int[brkArray.length];
+        for (int i = 0 ; i < brkArray.length ; i++) {
+            breaks[i] = (int) brkArray[i].getId() - 1;
+        }
+        return breaks;
+    }
+
+    @SuppressWarnings("deprecation")
+    private void removeBreak(int index, CTPageBreak ctPageBreak) {
+        int index1 = index + 1;
+        CTBreak[] brkArray = ctPageBreak.getBrkArray();
+        for (int i = 0 ; i < brkArray.length ; i++) {
+            if (brkArray[i].getId() == index1) {
+                ctPageBreak.removeBrk(i);
+                // TODO: check if we can break here, i.e. if a page can have 
more than 1 break on the same id
+            }
+        }
+    }
+
     /**
      * Vertical page break information used for print layout view, page layout 
view, drawing print breaks
      * in normal view, and for printing the worksheet.
@@ -656,20 +680,8 @@ public class XSSFSheet extends POIXMLDoc
      * @return column indexes of all the vertical page breaks, never 
<code>null</code>
      */
     @Override
-    @SuppressWarnings("deprecation") //YK: getXYZArray() array accessors are 
deprecated in xmlbeans with JDK 1.5 support
     public int[] getColumnBreaks() {
-        if (!worksheet.isSetColBreaks() || 
worksheet.getColBreaks().sizeOfBrkArray() == 0) {
-            return new int[0];
-        }
-
-        CTBreak[] brkArray = worksheet.getColBreaks().getBrkArray();
-
-        int[] breaks = new int[brkArray.length];
-        for (int i = 0 ; i < brkArray.length ; i++) {
-            CTBreak brk = brkArray[i];
-            breaks[i] = (int)brk.getId() - 1;
-        }
-        return breaks;
+        return worksheet.isSetColBreaks() ? 
getBreaks(worksheet.getColBreaks()) : new int[0];
     }
 
     /**
@@ -752,8 +764,7 @@ public class XSSFSheet extends POIXMLDoc
      * @param value true for right to left, false otherwise.
      */
     @Override
-    public void setRightToLeft(boolean value)
-    {
+    public void setRightToLeft(boolean value) {
        CTSheetView view = getDefaultSheetView();
        view.setRightToLeft(value);
     }
@@ -764,10 +775,9 @@ public class XSSFSheet extends POIXMLDoc
      * @return whether the text is displayed in right-to-left mode in the 
window
      */
     @Override
-    public boolean isRightToLeft()
-    {
+    public boolean isRightToLeft() {
        CTSheetView view = getDefaultSheetView();
-       return view == null ? false : view.getRightToLeft();
+       return view != null && view.getRightToLeft();
     }
 
     /**
@@ -804,7 +814,7 @@ public class XSSFSheet extends POIXMLDoc
     @Override
     public boolean isDisplayZeros(){
         CTSheetView view = getDefaultSheetView();
-        return view == null ? true : view.getShowZeros();
+        return view == null || view.getShowZeros();
     }
 
     /**
@@ -826,7 +836,7 @@ public class XSSFSheet extends POIXMLDoc
      */
     @Override
     public int getFirstRowNum() {
-        return _rows.size() == 0 ? 0 : _rows.firstKey();
+        return _rows.isEmpty() ? 0 : _rows.firstKey();
     }
 
     /**
@@ -944,7 +954,7 @@ public class XSSFSheet extends POIXMLDoc
 
     @Override
     public int getLastRowNum() {
-        return _rows.size() == 0 ? 0 : _rows.lastKey();
+        return _rows.isEmpty() ? 0 : _rows.lastKey();
     }
 
     @Override
@@ -1079,9 +1089,9 @@ public class XSSFSheet extends POIXMLDoc
     }
 
     /**
-     * Returns the number of phsyically defined rows (NOT the number of rows 
in the sheet)
+     * Returns the number of physically defined rows (NOT the number of rows 
in the sheet)
      *
-     * @return the number of phsyically defined rows
+     * @return the number of physically defined rows
      */
     @Override
     public int getPhysicalNumberOfRows() {
@@ -1105,7 +1115,7 @@ public class XSSFSheet extends POIXMLDoc
      */
     @Override
     public boolean getProtect() {
-        return worksheet.isSetSheetProtection() && sheetProtectionEnabled();
+        return isSheetLocked();
     }
 
     /**
@@ -1117,10 +1127,9 @@ public class XSSFSheet extends POIXMLDoc
      */
     @Override
     public void protectSheet(String password) {
-
-        if(password != null) {
-            CTSheetProtection sheetProtection = 
worksheet.addNewSheetProtection();
-            sheetProtection.xsetPassword(stringToExcelPassword(password));
+        if (password != null) {
+            CTSheetProtection sheetProtection = safeGetProtectionField();
+            setSheetPassword(password, null); // defaults to xor password
             sheetProtection.setSheet(true);
             sheetProtection.setScenarios(true);
             sheetProtection.setObjects(true);
@@ -1130,19 +1139,28 @@ public class XSSFSheet extends POIXMLDoc
     }
 
     /**
-     * Converts a String to a {@link STUnsignedShortHex} value that contains 
the {@link PasswordRecord#hashPassword(String)}
-     * value in hexadecimal format
-     *
-     * @param password the password string you wish convert to an {@link 
STUnsignedShortHex}
-     * @return {@link STUnsignedShortHex} that contains Excel hashed password 
in Hex format
+     * Sets the sheet password. 
+     * 
+     * @param password if null, the password will be removed
+     * @param hashAlgo if null, the password will be set as XOR password 
(Excel 2010 and earlier)
+     *  otherwise the given algorithm is used for calculating the hash 
password (Excel 2013)
      */
-    private STUnsignedShortHex stringToExcelPassword(String password) {
-        STUnsignedShortHex hexPassword = 
STUnsignedShortHex.Factory.newInstance();
-        
hexPassword.setStringValue(String.valueOf(HexDump.shortToHex(PasswordRecord.hashPassword(password))).substring(2));
-        return hexPassword;
+    public void setSheetPassword(String password, HashAlgorithm hashAlgo) {
+        if (password == null && !isSheetProtectionEnabled()) return;
+        setPassword(safeGetProtectionField(), password, hashAlgo, null);
     }
 
     /**
+     * Validate the password against the stored hash, the hashing method will 
be determined
+     *  by the existing password attributes
+     * @return true, if the hashes match (... though original password may 
differ ...)
+     */
+    public boolean validateSheetPassword(String password) {
+        if (!isSheetProtectionEnabled()) return (password == null);
+        return validatePassword(safeGetProtectionField(), password, null);
+    }
+    
+    /**
      * Returns the logical row ( 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.
      *
@@ -1161,19 +1179,9 @@ public class XSSFSheet extends POIXMLDoc
      * @return row indexes of all the horizontal page breaks, never 
<code>null</code>
      */
     @Override
-    @SuppressWarnings("deprecation") //YK: getXYZArray() array accessors are 
deprecated in xmlbeans with JDK 1.5 support
     public int[] getRowBreaks() {
-        if (!worksheet.isSetRowBreaks() || 
worksheet.getRowBreaks().sizeOfBrkArray() == 0) {
-            return new int[0];
-        }
+        return worksheet.isSetRowBreaks() ? 
getBreaks(worksheet.getRowBreaks()) : new int[0];
 
-        CTBreak[] brkArray = worksheet.getRowBreaks().getBrkArray();
-        int[] breaks = new int[brkArray.length];
-        for (int i = 0 ; i < brkArray.length ; i++) {
-            CTBreak brk = brkArray[i];
-            breaks[i] = (int)brk.getId() - 1;
-        }
-        return breaks;
     }
 
     /**
@@ -1342,8 +1350,9 @@ public class XSSFSheet extends POIXMLDoc
     /**
      * Do not leave the width attribute undefined (see #52186).
      */
+    @SuppressWarnings("deprecation")
     private void setColWidthAttribute(CTCols ctCols) {
-        for (CTCol col : ctCols.getColList()) {
+        for (CTCol col : ctCols.getColArray()) {
             if (!col.isSetWidth()) {
                 col.setWidth(getDefaultColumnWidth());
                 col.setCustomWidth(false);
@@ -1372,21 +1381,22 @@ public class XSSFSheet extends POIXMLDoc
     }
 
     private short getMaxOutlineLevelRows(){
-        short outlineLevel=0;
-        for(XSSFRow xrow : _rows.values()){
-            outlineLevel=xrow.getCTRow().getOutlineLevel()>outlineLevel? 
xrow.getCTRow().getOutlineLevel(): outlineLevel;
+        int outlineLevel = 0;
+        for (XSSFRow xrow : _rows.values()) {
+            outlineLevel = Math.max(outlineLevel, 
xrow.getCTRow().getOutlineLevel());
         }
-        return outlineLevel;
+        return (short) outlineLevel;
     }
 
 
+    @SuppressWarnings("deprecation")
     private short getMaxOutlineLevelCols() {
         CTCols ctCols = worksheet.getColsArray(0);
-        short outlineLevel = 0;
-        for (CTCol col : ctCols.getColList()) {
-            outlineLevel = col.getOutlineLevel() > outlineLevel ? 
col.getOutlineLevel() : outlineLevel;
+        int outlineLevel = 0;
+        for (CTCol col : ctCols.getColArray()) {
+            outlineLevel = Math.max(outlineLevel, col.getOutlineLevel());
         }
-        return outlineLevel;
+        return (short) outlineLevel;
     }
 
     /**
@@ -1394,8 +1404,7 @@ public class XSSFSheet extends POIXMLDoc
      */
     @Override
     public boolean isColumnBroken(int column) {
-        int[] colBreaks = getColumnBreaks();
-        for (int colBreak : colBreaks) {
+        for (int colBreak : getColumnBreaks()) {
             if (colBreak == column) {
                 return true;
             }
@@ -1514,8 +1523,7 @@ public class XSSFSheet extends POIXMLDoc
      */
     @Override
     public boolean isRowBroken(int row) {
-        int[] rowBreaks = getRowBreaks();
-        for (int rowBreak : rowBreaks) {
+        for (int rowBreak : getRowBreaks()) {
             if (rowBreak == row) {
                 return true;
             }
@@ -1523,6 +1531,17 @@ public class XSSFSheet extends POIXMLDoc
         return false;
     }
 
+    private void setBreak(int id, CTPageBreak ctPgBreak, int lastIndex) {
+        CTBreak brk = ctPgBreak.addNewBrk();
+        brk.setId(id + 1); // this is id of the element which is 1-based: <row 
r="1" ... >
+        brk.setMan(true);
+        brk.setMax(lastIndex); //end column of the break
+
+        int nPageBreaks = ctPgBreak.sizeOfBrkArray();
+        ctPgBreak.setCount(nPageBreaks);
+        ctPgBreak.setManualBreakCount(nPageBreaks);
+    }
+
     /**
      * Sets a page break at the indicated row
      * Breaks occur above the specified row and left of the specified column 
inclusive.
@@ -1536,15 +1555,9 @@ public class XSSFSheet extends POIXMLDoc
      */
     @Override
     public void setRowBreak(int row) {
-        CTPageBreak pgBreak = worksheet.isSetRowBreaks() ? 
worksheet.getRowBreaks() : worksheet.addNewRowBreaks();
-        if (! isRowBroken(row)) {
-            CTBreak brk = pgBreak.addNewBrk();
-            brk.setId(row + 1); // this is id of the row element which is 
1-based: <row r="1" ... >
-            brk.setMan(true);
-            brk.setMax(SpreadsheetVersion.EXCEL2007.getLastColumnIndex()); 
//end column of the break
-
-            pgBreak.setCount(pgBreak.sizeOfBrkArray());
-            pgBreak.setManualBreakCount(pgBreak.sizeOfBrkArray());
+        if (!isRowBroken(row)) {
+            CTPageBreak pgBreak = worksheet.isSetRowBreaks() ? 
worksheet.getRowBreaks() : worksheet.addNewRowBreaks();
+            setBreak(row, pgBreak, 
SpreadsheetVersion.EXCEL2007.getLastColumnIndex());
         }
     }
 
@@ -1552,20 +1565,10 @@ public class XSSFSheet extends POIXMLDoc
      * Removes a page break at the indicated column
      */
     @Override
-    @SuppressWarnings("deprecation") //YK: getXYZArray() array accessors are 
deprecated in xmlbeans with JDK 1.5 support
     public void removeColumnBreak(int column) {
-        if (!worksheet.isSetColBreaks()) {
-            // no breaks
-            return;
-        }
-
-        CTPageBreak pgBreak = worksheet.getColBreaks();
-        CTBreak[] brkArray = pgBreak.getBrkArray();
-        for (int i = 0 ; i < brkArray.length ; i++) {
-            if (brkArray[i].getId() == (column + 1)) {
-                pgBreak.removeBrk(i);
-            }
-        }
+        if (worksheet.isSetColBreaks()) {
+            removeBreak(column, worksheet.getColBreaks());
+        } // else no breaks
     }
 
     /**
@@ -1574,22 +1577,46 @@ public class XSSFSheet extends POIXMLDoc
      * @param index of the region to unmerge
      */
     @Override
+    @SuppressWarnings("deprecation")
     public void removeMergedRegion(int index) {
+        if (!worksheet.isSetMergeCells()) return;
+        
         CTMergeCells ctMergeCells = worksheet.getMergeCells();
+        int size = ctMergeCells.sizeOfMergeCellArray();
+        assert(0 <= index && index < size);
+        if (size > 1) {
+            ctMergeCells.removeMergeCell(index);
+        } else {
+            worksheet.unsetMergeCells();
+        }
+    }
 
-        CTMergeCell[] mergeCellsArray = new 
CTMergeCell[ctMergeCells.sizeOfMergeCellArray() - 1];
-        for (int i = 0 ; i < ctMergeCells.sizeOfMergeCellArray() ; i++) {
-            if (i < index) {
-                mergeCellsArray[i] = ctMergeCells.getMergeCellArray(i);
-            }
-            else if (i > index) {
-                mergeCellsArray[i - 1] = ctMergeCells.getMergeCellArray(i);
-            }
+    /**
+     * Removes a number of merged regions of cells (hence letting them free)
+     *
+     * This method can be used to bulk-remove merged regions in a way
+     * much faster than calling removeMergedRegion() for every single
+     * merged region.
+     *
+     * @param indices A set of the regions to unmerge
+     */
+    @SuppressWarnings("deprecation")
+    public void removeMergedRegions(Set<Integer> indices) {
+        if (!worksheet.isSetMergeCells()) return;
+        
+        CTMergeCells ctMergeCells = worksheet.getMergeCells();
+        List<CTMergeCell> newMergeCells = new 
ArrayList<CTMergeCell>(ctMergeCells.sizeOfMergeCellArray());
+
+        int idx = 0;
+        for (CTMergeCell mc : ctMergeCells.getMergeCellArray()) {
+            if (!indices.contains(idx++)) newMergeCells.add(mc);
         }
-        if(mergeCellsArray.length > 0){
-            ctMergeCells.setMergeCellArray(mergeCellsArray);
-        } else{
+        
+        if (newMergeCells.isEmpty()) {
             worksheet.unsetMergeCells();
+        } else{
+            CTMergeCell[] newMergeCellsArray = new 
CTMergeCell[newMergeCells.size()];
+            
ctMergeCells.setMergeCellArray(newMergeCells.toArray(newMergeCellsArray));
         }
     }
 
@@ -1618,18 +1645,10 @@ public class XSSFSheet extends POIXMLDoc
      * Removes the page break at the indicated row
      */
     @Override
-    @SuppressWarnings("deprecation") //YK: getXYZArray() array accessors are 
deprecated in xmlbeans with JDK 1.5 support
     public void removeRowBreak(int row) {
-        if(!worksheet.isSetRowBreaks()) {
-            return;
-        }
-        CTPageBreak pgBreak = worksheet.getRowBreaks();
-        CTBreak[] brkArray = pgBreak.getBrkArray();
-        for (int i = 0 ; i < brkArray.length ; i++) {
-            if (brkArray[i].getId() == (row + 1)) {
-                pgBreak.removeBrk(i);
-            }
-        }
+        if (worksheet.isSetRowBreaks()) {
+            removeBreak(row, worksheet.getRowBreaks());
+        } // else no breaks
     }
 
     /**
@@ -1743,15 +1762,9 @@ public class XSSFSheet extends POIXMLDoc
      */
     @Override
     public void setColumnBreak(int column) {
-        if (! isColumnBroken(column)) {
+        if (!isColumnBroken(column)) {
             CTPageBreak pgBreak = worksheet.isSetColBreaks() ? 
worksheet.getColBreaks() : worksheet.addNewColBreaks();
-            CTBreak brk = pgBreak.addNewBrk();
-            brk.setId(column + 1);  // this is id of the row element which is 
1-based: <row r="1" ... >
-            brk.setMan(true);
-            brk.setMax(SpreadsheetVersion.EXCEL2007.getLastRowIndex()); //end 
row of the break
-
-            pgBreak.setCount(pgBreak.sizeOfBrkArray());
-            pgBreak.setManualBreakCount(pgBreak.sizeOfBrkArray());
+            setBreak(column, pgBreak, 
SpreadsheetVersion.EXCEL2007.getLastRowIndex());
         }
     }
 
@@ -1781,23 +1794,23 @@ public class XSSFSheet extends POIXMLDoc
                 .getOutlineLevel(), true);
 
         // write collapse field
-        setColumn(lastColMax + 1, null, 0, null, null, Boolean.TRUE);
+        setColumn(lastColMax + 1, 0, null, null, Boolean.TRUE);
 
     }
 
-    private void setColumn(int targetColumnIx, Short xfIndex, Integer style,
-            Integer level, Boolean hidden, Boolean collapsed) {
+    @SuppressWarnings("deprecation")
+    private void setColumn(int targetColumnIx, Integer style,
+                           Integer level, Boolean hidden, Boolean collapsed) {
         CTCols cols = worksheet.getColsArray(0);
         CTCol ci = null;
-        int k = 0;
-        for (k = 0; k < cols.sizeOfColArray(); k++) {
-            CTCol tci = cols.getColArray(k);
-            if (tci.getMin() >= targetColumnIx
-                    && tci.getMax() <= targetColumnIx) {
+        for (CTCol tci : cols.getColArray()) {
+            long tciMin = tci.getMin();
+            long tciMax = tci.getMax();
+            if (tciMin >= targetColumnIx && tciMax <= targetColumnIx) {
                 ci = tci;
                 break;
             }
-            if (tci.getMin() > targetColumnIx) {
+            if (tciMin > targetColumnIx) {
                 // call column infos after k are for later columns
                 break; // exit now so k will be the correct insert pos
             }
@@ -1814,36 +1827,32 @@ public class XSSFSheet extends POIXMLDoc
             return;
         }
 
-        boolean styleChanged = style != null
-        && ci.getStyle() != style;
-        boolean levelChanged = level != null
-        && ci.getOutlineLevel() != level;
-        boolean hiddenChanged = hidden != null
-        && ci.getHidden() != hidden;
-        boolean collapsedChanged = collapsed != null
-        && ci.getCollapsed() != collapsed;
-        boolean columnChanged = levelChanged || hiddenChanged
-        || collapsedChanged || styleChanged;
+        boolean styleChanged = style != null && ci.getStyle() != style;
+        boolean levelChanged = level != null && ci.getOutlineLevel() != level;
+        boolean hiddenChanged = hidden != null && ci.getHidden() != hidden;
+        boolean collapsedChanged = collapsed != null && ci.getCollapsed() != 
collapsed;
+        boolean columnChanged = levelChanged || hiddenChanged || 
collapsedChanged || styleChanged;
         if (!columnChanged) {
             // do nothing...nothing changed.
             return;
         }
 
-        if (ci.getMin() == targetColumnIx && ci.getMax() == targetColumnIx) {
+        long ciMin = ci.getMin();
+        long ciMax = ci.getMax();
+        if (ciMin == targetColumnIx && ciMax == targetColumnIx) {
             // ColumnInfo ci for a single column, the target column
             unsetCollapsed(collapsed, ci);
             return;
         }
 
-        if (ci.getMin() == targetColumnIx || ci.getMax() == targetColumnIx) {
+        if (ciMin == targetColumnIx || ciMax == targetColumnIx) {
             // The target column is at either end of the multi-column 
ColumnInfo
             // ci
             // we'll just divide the info and create a new one
-            if (ci.getMin() == targetColumnIx) {
+            if (ciMin == targetColumnIx) {
                 ci.setMin(targetColumnIx + 1);
             } else {
                 ci.setMax(targetColumnIx - 1);
-                k++; // adjust insert pos to insert after
             }
             CTCol nci = columnHelper.cloneCol(cols, ci);
             nci.setMin(targetColumnIx);
@@ -1852,12 +1861,11 @@ public class XSSFSheet extends POIXMLDoc
 
         } else {
             // split to 3 records
-            CTCol ciStart = ci;
             CTCol ciMid = columnHelper.cloneCol(cols, ci);
             CTCol ciEnd = columnHelper.cloneCol(cols, ci);
-            int lastcolumn = (int) ci.getMax();
+            int lastcolumn = (int) ciMax;
 
-            ciStart.setMax(targetColumnIx - 1);
+            ci.setMax(targetColumnIx - 1);
 
             ciMid.setMin(targetColumnIx);
             ciMid.setMax(targetColumnIx);
@@ -1886,14 +1894,16 @@ public class XSSFSheet extends POIXMLDoc
      *                the col info index of the start of the outline group
      * @return the column index of the last column in the outline group
      */
+    @SuppressWarnings("deprecation")
     private int setGroupHidden(int pIdx, int level, boolean hidden) {
         CTCols cols = worksheet.getColsArray(0);
         int idx = pIdx;
-        CTCol columnInfo = cols.getColArray(idx);
-        while (idx < cols.sizeOfColArray()) {
+        CTCol[] colArray = cols.getColArray();
+        CTCol columnInfo = colArray[idx];
+        while (idx < colArray.length) {
             columnInfo.setHidden(hidden);
-            if (idx + 1 < cols.sizeOfColArray()) {
-                CTCol nextColumnInfo = cols.getColArray(idx + 1);
+            if (idx + 1 < colArray.length) {
+                CTCol nextColumnInfo = colArray[idx + 1];
 
                 if (!isAdjacentBefore(columnInfo, nextColumnInfo)) {
                     break;
@@ -1910,17 +1920,19 @@ public class XSSFSheet extends POIXMLDoc
     }
 
     private boolean isAdjacentBefore(CTCol col, CTCol other_col) {
-        return (col.getMax() == (other_col.getMin() - 1));
+        return col.getMax() == other_col.getMin() - 1;
     }
 
+    @SuppressWarnings("deprecation")
     private int findStartOfColumnOutlineGroup(int pIdx) {
         // Find the start of the group.
         CTCols cols = worksheet.getColsArray(0);
-        CTCol columnInfo = cols.getColArray(pIdx);
+        CTCol[] colArray = cols.getColArray();
+        CTCol columnInfo = colArray[pIdx];
         int level = columnInfo.getOutlineLevel();
         int idx = pIdx;
         while (idx != 0) {
-            CTCol prevColumnInfo = cols.getColArray(idx - 1);
+            CTCol prevColumnInfo = colArray[idx - 1];
             if (!isAdjacentBefore(prevColumnInfo, columnInfo)) {
                 break;
             }
@@ -1933,14 +1945,17 @@ public class XSSFSheet extends POIXMLDoc
         return idx;
     }
 
+    @SuppressWarnings("deprecation")
     private int findEndOfColumnOutlineGroup(int colInfoIndex) {
         CTCols cols = worksheet.getColsArray(0);
         // Find the end of the group.
-        CTCol columnInfo = cols.getColArray(colInfoIndex);
+        CTCol[] colArray = cols.getColArray();
+        CTCol columnInfo = colArray[colInfoIndex];
         int level = columnInfo.getOutlineLevel();
         int idx = colInfoIndex;
-        while (idx < cols.sizeOfColArray() - 1) {
-            CTCol nextColumnInfo = cols.getColArray(idx + 1);
+        int lastIdx = colArray.length - 1;
+        while (idx < lastIdx) {
+            CTCol nextColumnInfo = colArray[idx + 1];
             if (!isAdjacentBefore(columnInfo, nextColumnInfo)) {
                 break;
             }
@@ -1953,6 +1968,7 @@ public class XSSFSheet extends POIXMLDoc
         return idx;
     }
 
+    @SuppressWarnings("deprecation")
     private void expandColumn(int columnIndex) {
         CTCols cols = worksheet.getColsArray(0);
         CTCol col = columnHelper.getColumn(columnIndex, false);
@@ -1983,12 +1999,13 @@ public class XSSFSheet extends POIXMLDoc
         // is the enclosing group
         // hidden bit only is altered for this outline level. ie. don't
         // uncollapse contained groups
-        CTCol columnInfo = cols.getColArray(endIdx);
+        CTCol[] colArray = cols.getColArray();
+        CTCol columnInfo = colArray[endIdx];
         if (!isColumnGroupHiddenByParent(idx)) {
-            int outlineLevel = columnInfo.getOutlineLevel();
+            short outlineLevel = columnInfo.getOutlineLevel();
             boolean nestedGroup = false;
             for (int i = startIdx; i <= endIdx; i++) {
-                CTCol ci = cols.getColArray(i);
+                CTCol ci = colArray[i];
                 if (outlineLevel == ci.getOutlineLevel()) {
                     ci.unsetHidden();
                     if (nestedGroup) {
@@ -2002,20 +2019,21 @@ public class XSSFSheet extends POIXMLDoc
         }
         // Write collapse flag (stored in a single col info record after this
         // outline group)
-        setColumn((int) columnInfo.getMax() + 1, null, null, null,
+        setColumn((int) columnInfo.getMax() + 1, null, null,
                 Boolean.FALSE, Boolean.FALSE);
     }
 
+    @SuppressWarnings("deprecation")
     private boolean isColumnGroupHiddenByParent(int idx) {
         CTCols cols = worksheet.getColsArray(0);
         // Look out outline details of end
         int endLevel = 0;
         boolean endHidden = false;
         int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup(idx);
-        if (endOfOutlineGroupIdx < cols.sizeOfColArray()) {
-            CTCol nextInfo = cols.getColArray(endOfOutlineGroupIdx + 1);
-            if (isAdjacentBefore(cols.getColArray(endOfOutlineGroupIdx),
-                    nextInfo)) {
+        CTCol[] colArray = cols.getColArray();
+        if (endOfOutlineGroupIdx < colArray.length) {
+            CTCol nextInfo = colArray[endOfOutlineGroupIdx + 1];
+            if (isAdjacentBefore(colArray[endOfOutlineGroupIdx], nextInfo)) {
                 endLevel = nextInfo.getOutlineLevel();
                 endHidden = nextInfo.getHidden();
             }
@@ -2025,10 +2043,9 @@ public class XSSFSheet extends POIXMLDoc
         boolean startHidden = false;
         int startOfOutlineGroupIdx = findStartOfColumnOutlineGroup(idx);
         if (startOfOutlineGroupIdx > 0) {
-            CTCol prevInfo = cols.getColArray(startOfOutlineGroupIdx - 1);
+            CTCol prevInfo = colArray[startOfOutlineGroupIdx - 1];
 
-            if (isAdjacentBefore(prevInfo, cols
-                    .getColArray(startOfOutlineGroupIdx))) {
+            if (isAdjacentBefore(prevInfo, colArray[startOfOutlineGroupIdx])) {
                 startLevel = prevInfo.getOutlineLevel();
                 startHidden = prevInfo.getHidden();
             }
@@ -2040,6 +2057,7 @@ public class XSSFSheet extends POIXMLDoc
         return startHidden;
     }
 
+    @SuppressWarnings("deprecation")
     private int findColInfoIdx(int columnValue, int fromColInfoIdx) {
         CTCols cols = worksheet.getColsArray(0);
 
@@ -2052,8 +2070,9 @@ public class XSSFSheet extends POIXMLDoc
                     "fromIdx parameter out of range: " + fromColInfoIdx);
         }
 
-        for (int k = fromColInfoIdx; k < cols.sizeOfColArray(); k++) {
-            CTCol ci = cols.getColArray(k);
+        CTCol[] colArray = cols.getColArray();
+        for (int k = fromColInfoIdx; k < colArray.length; k++) {
+            CTCol ci = colArray[k];
 
             if (containsColumn(ci, columnValue)) {
                 return k;
@@ -2078,16 +2097,18 @@ public class XSSFSheet extends POIXMLDoc
      * @param idx
      * @return a boolean represented if the column is collapsed
      */
+    @SuppressWarnings("deprecation")
     private boolean isColumnGroupCollapsed(int idx) {
         CTCols cols = worksheet.getColsArray(0);
+        CTCol[] colArray = cols.getColArray();
         int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup(idx);
         int nextColInfoIx = endOfOutlineGroupIdx + 1;
-        if (nextColInfoIx >= cols.sizeOfColArray()) {
+        if (nextColInfoIx >= colArray.length) {
             return false;
         }
-        CTCol nextColInfo = cols.getColArray(nextColInfoIx);
+        CTCol nextColInfo = colArray[nextColInfoIx];
 
-        CTCol col = cols.getColArray(endOfOutlineGroupIdx);
+        CTCol col = colArray[endOfOutlineGroupIdx];
         if (!isAdjacentBefore(col, nextColInfo)) {
             return false;
         }
@@ -2294,7 +2315,7 @@ public class XSSFSheet extends POIXMLDoc
      */
     private int findStartOfRowOutlineGroup(int rowIndex) {
         // Find the start of the group.
-        int level = getRow(rowIndex).getCTRow().getOutlineLevel();
+        short level = getRow(rowIndex).getCTRow().getOutlineLevel();
         int currentRow = rowIndex;
         while (getRow(currentRow) != null) {
             if (getRow(currentRow).getCTRow().getOutlineLevel() < level)
@@ -2305,7 +2326,7 @@ public class XSSFSheet extends POIXMLDoc
     }
 
     private int writeHidden(XSSFRow xRow, int rowIndex, boolean hidden) {
-        int level = xRow.getCTRow().getOutlineLevel();
+        short level = xRow.getCTRow().getOutlineLevel();
         for (Iterator<Row> it = rowIterator(); it.hasNext();) {
             xRow = (XSSFRow) it.next();
 
@@ -2352,10 +2373,10 @@ public class XSSFSheet extends POIXMLDoc
         // is the enclosing group
         // hidden bit only is altered for this outline level. ie. don't
         // un-collapse contained groups
+        short level = row.getCTRow().getOutlineLevel();
         if (!isRowGroupHiddenByParent(rowNumber)) {
             for (int i = startIdx; i < endIdx; i++) {
-                if (row.getCTRow().getOutlineLevel() == getRow(i).getCTRow()
-                        .getOutlineLevel()) {
+                if (level == getRow(i).getCTRow().getOutlineLevel()) {
                     getRow(i).getCTRow().unsetHidden();
                 } else if (!isRowGroupCollapsed(i)) {
                     getRow(i).getCTRow().unsetHidden();
@@ -2374,7 +2395,7 @@ public class XSSFSheet extends POIXMLDoc
      * @param row the zero based row index to find from
      */
     public int findEndOfRowOutlineGroup(int row) {
-        int level = getRow(row).getCTRow().getOutlineLevel();
+        short level = getRow(row).getCTRow().getOutlineLevel();
         int currentRow;
         for (currentRow = row; currentRow < getLastRowNum(); currentRow++) {
             if (getRow(currentRow) == null
@@ -2630,11 +2651,11 @@ public class XSSFSheet extends POIXMLDoc
         for (int i = fromRow; i <= toRow; i++) {
             XSSFRow xrow = getRow(i);
             if (xrow != null) {
-                CTRow ctrow = xrow.getCTRow();
-                short outlinelevel = ctrow.getOutlineLevel();
-                ctrow.setOutlineLevel((short) (outlinelevel - 1));
+                CTRow ctRow = xrow.getCTRow();
+                int outlineLevel = ctRow.getOutlineLevel();
+                ctRow.setOutlineLevel((short) (outlineLevel - 1));
                 //remove a row only if the row has no cell and if the outline 
level is 0
-                if (ctrow.getOutlineLevel() == 0 && xrow.getFirstCellNum() == 
-1) {
+                if (outlineLevel == 1 && xrow.getFirstCellNum() == -1) {
                     removeRow(xrow);
                 }
             }
@@ -2746,13 +2767,11 @@ public class XSSFSheet extends POIXMLDoc
      *  so we can decide about writing it to disk or not
      */
     public boolean hasComments() {
-        if(sheetComments == null) { return false; }
-        return (sheetComments.getNumberOfComments() > 0);
+        return sheetComments != null && sheetComments.getNumberOfComments() > 
0;
     }
 
     protected int getNumberOfComments() {
-        if(sheetComments == null) { return 0; }
-        return sheetComments.getNumberOfComments();
+        return sheetComments == null ? 0 : sheetComments.getNumberOfComments();
     }
 
     private CTSelection getSheetTypeSelection() {
@@ -2851,7 +2870,7 @@ public class XSSFSheet extends POIXMLDoc
             CTCellFormula sf = (CTCellFormula)f.copy();
             CellRangeAddress sfRef = CellRangeAddress.valueOf(sf.getRef());
             CellReference cellRef = new CellReference(cell);
-            // If the shared formula range preceeds the master cell then the 
preceding  part is discarded, e.g.
+            // If the shared formula range precedes the master cell then the 
preceding  part is discarded, e.g.
             // if the cell is E60 and the shared formula range is C60:M85 then 
the effective range is E60:M85
             // see more details in 
https://issues.apache.org/bugzilla/show_bug.cgi?id=51710
             if(cellRef.getCol() > sfRef.getFirstColumn() || cellRef.getRow() > 
sfRef.getFirstRow()){
@@ -2929,304 +2948,392 @@ public class XSSFSheet extends POIXMLDoc
      * @return true when Autofilters are locked and the sheet is protected.
      */
     public boolean isAutoFilterLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && 
worksheet.getSheetProtection().getAutoFilter();
+        return isSheetLocked() && safeGetProtectionField().getAutoFilter();
     }
 
     /**
      * @return true when Deleting columns is locked and the sheet is protected.
      */
     public boolean isDeleteColumnsLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && 
worksheet.getSheetProtection().getDeleteColumns();
+        return isSheetLocked() && safeGetProtectionField().getDeleteColumns();
     }
 
     /**
      * @return true when Deleting rows is locked and the sheet is protected.
      */
     public boolean isDeleteRowsLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && 
worksheet.getSheetProtection().getDeleteRows();
+        return isSheetLocked() && safeGetProtectionField().getDeleteRows();
     }
 
     /**
      * @return true when Formatting cells is locked and the sheet is protected.
      */
     public boolean isFormatCellsLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && 
worksheet.getSheetProtection().getFormatCells();
+        return isSheetLocked() && safeGetProtectionField().getFormatCells();
     }
 
     /**
      * @return true when Formatting columns is locked and the sheet is 
protected.
      */
     public boolean isFormatColumnsLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && 
worksheet.getSheetProtection().getFormatColumns();
+        return isSheetLocked() && safeGetProtectionField().getFormatColumns();
     }
 
     /**
      * @return true when Formatting rows is locked and the sheet is protected.
      */
     public boolean isFormatRowsLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && 
worksheet.getSheetProtection().getFormatRows();
+        return isSheetLocked() && safeGetProtectionField().getFormatRows();
     }
 
     /**
      * @return true when Inserting columns is locked and the sheet is 
protected.
      */
     public boolean isInsertColumnsLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && 
worksheet.getSheetProtection().getInsertColumns();
+        return isSheetLocked() && safeGetProtectionField().getInsertColumns();
     }
 
     /**
      * @return true when Inserting hyperlinks is locked and the sheet is 
protected.
      */
     public boolean isInsertHyperlinksLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && 
worksheet.getSheetProtection().getInsertHyperlinks();
+        return isSheetLocked() && 
safeGetProtectionField().getInsertHyperlinks();
     }
 
     /**
      * @return true when Inserting rows is locked and the sheet is protected.
      */
     public boolean isInsertRowsLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && 
worksheet.getSheetProtection().getInsertRows();
+        return isSheetLocked() && safeGetProtectionField().getInsertRows();
     }
 
     /**
      * @return true when Pivot tables are locked and the sheet is protected.
      */
     public boolean isPivotTablesLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && 
worksheet.getSheetProtection().getPivotTables();
+        return isSheetLocked() && safeGetProtectionField().getPivotTables();
     }
 
     /**
      * @return true when Sorting is locked and the sheet is protected.
      */
     public boolean isSortLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && 
worksheet.getSheetProtection().getSort();
+        return isSheetLocked() && safeGetProtectionField().getSort();
     }
 
     /**
      * @return true when Objects are locked and the sheet is protected.
      */
     public boolean isObjectsLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && 
worksheet.getSheetProtection().getObjects();
+        return isSheetLocked() && safeGetProtectionField().getObjects();
     }
 
     /**
      * @return true when Scenarios are locked and the sheet is protected.
      */
     public boolean isScenariosLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && 
worksheet.getSheetProtection().getScenarios();
+        return isSheetLocked() && safeGetProtectionField().getScenarios();
     }
 
     /**
      * @return true when Selection of locked cells is locked and the sheet is 
protected.
      */
     public boolean isSelectLockedCellsLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && 
worksheet.getSheetProtection().getSelectLockedCells();
+        return isSheetLocked() && 
safeGetProtectionField().getSelectLockedCells();
     }
 
     /**
      * @return true when Selection of unlocked cells is locked and the sheet 
is protected.
      */
     public boolean isSelectUnlockedCellsLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && 
worksheet.getSheetProtection().getSelectUnlockedCells();
+        return isSheetLocked() && 
safeGetProtectionField().getSelectUnlockedCells();
     }
 
     /**
      * @return true when Sheet is Protected.
      */
     public boolean isSheetLocked() {
-        createProtectionFieldIfNotPresent();
-        return sheetProtectionEnabled() && 
worksheet.getSheetProtection().getSheet();
+        return worksheet.isSetSheetProtection() && 
safeGetProtectionField().getSheet();
     }
 
     /**
      * Enable sheet protection
      */
     public void enableLocking() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setSheet(true);
+        safeGetProtectionField().setSheet(true);
     }
 
     /**
      * Disable sheet protection
      */
     public void disableLocking() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setSheet(false);
+        safeGetProtectionField().setSheet(false);
     }
 
     /**
      * Enable Autofilters locking.
-     * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * @deprecated use {@link #lockAutoFilter(boolean)}
      */
     public void lockAutoFilter() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setAutoFilter(true);
+        lockAutoFilter(true);
     }
 
     /**
-     * Enable Deleting columns locking.
+     * Enable or disable Autofilters locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link 
#enableLocking()}
+     */
+    public void lockAutoFilter(boolean enabled) {
+        safeGetProtectionField().setAutoFilter(enabled);
+    }
+
+    /**
+     * Enable Deleting columns locking.
+     * @deprecated use {@link #lockDeleteColumns(boolean)}
      */
     public void lockDeleteColumns() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setDeleteColumns(true);
+        lockDeleteColumns(true);
     }
 
     /**
-     * Enable Deleting rows locking.
+     * Enable or disable Deleting columns locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link 
#enableLocking()}
+     */
+    public void lockDeleteColumns(boolean enabled) {
+        safeGetProtectionField().setDeleteColumns(enabled);
+    }
+
+    /**
+     * Enable Deleting rows locking.
+     * @deprecated use {@link #lockDeleteRows(boolean)}
      */
     public void lockDeleteRows() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setDeleteRows(true);
+        lockDeleteRows(true);
     }
 
     /**
-     * Enable Formatting cells locking.
+     * Enable or disable Deleting rows locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link 
#enableLocking()}
+     */
+    public void lockDeleteRows(boolean enabled) {
+        safeGetProtectionField().setDeleteRows(enabled);
+    }
+
+    /**
+     * Enable Formatting cells locking.
+     * @deprecated use {@link #lockFormatCells(boolean)}
      */
     public void lockFormatCells() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setDeleteColumns(true);
+        lockFormatCells(true);
     }
 
     /**
-     * Enable Formatting columns locking.
+     * Enable or disable Formatting cells locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link 
#enableLocking()}
+     */
+    public void lockFormatCells(boolean enabled) {
+        safeGetProtectionField().setFormatCells(enabled);
+    }
+
+    /**
+     * Enable Formatting columns locking.
+     * @deprecated use {@link #lockFormatColumns(boolean)}
      */
     public void lockFormatColumns() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setFormatColumns(true);
+        lockFormatColumns(true);
     }
 
     /**
-     * Enable Formatting rows locking.
+     * Enable or disable Formatting columns locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link 
#enableLocking()}
+     */
+    public void lockFormatColumns(boolean enabled) {
+        safeGetProtectionField().setFormatColumns(enabled);
+    }
+
+    /**
+     * Enable Formatting rows locking.
+     * @deprecated use {@link #lockFormatRows(boolean)}
      */
     public void lockFormatRows() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setFormatRows(true);
+        lockFormatRows(true);
     }
 
     /**
-     * Enable Inserting columns locking.
+     * Enable or disable Formatting rows locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link 
#enableLocking()}
+     */
+    public void lockFormatRows(boolean enabled) {
+        safeGetProtectionField().setFormatRows(enabled);
+    }
+
+    /**
+     * Enable Inserting columns locking.
+     * @deprecated use {@link #lockInsertColumns(boolean)}
      */
     public void lockInsertColumns() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setInsertColumns(true);
+        lockInsertColumns(true);
     }
 
     /**
-     * Enable Inserting hyperlinks locking.
+     * Enable or disable Inserting columns locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link 
#enableLocking()}
+     */
+    public void lockInsertColumns(boolean enabled) {
+        safeGetProtectionField().setInsertColumns(enabled);
+    }
+
+    /**
+     * Enable Inserting hyperlinks locking.
+     * @deprecated use {@link #lockInsertHyperlinks(boolean)}
      */
     public void lockInsertHyperlinks() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setInsertHyperlinks(true);
+        lockInsertHyperlinks(true);
     }
 
     /**
-     * Enable Inserting rows locking.
+     * Enable or disable Inserting hyperlinks locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link 
#enableLocking()}
+     */
+    public void lockInsertHyperlinks(boolean enabled) {
+        safeGetProtectionField().setInsertHyperlinks(enabled);
+    }
+
+    /**
+     * Enable Inserting rows locking.
+     * @deprecated use {@link #lockInsertRows(boolean)}
      */
     public void lockInsertRows() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setInsertRows(true);
+        lockInsertRows(true);
     }
 
     /**
-     * Enable Pivot Tables locking.
+     * Enable or disable Inserting rows locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link 
#enableLocking()}
+     */
+    public void lockInsertRows(boolean enabled) {
+        safeGetProtectionField().setInsertRows(enabled);
+    }
+
+    /**
+     * Enable Pivot Tables locking.
+     * @deprecated use {@link #lockPivotTables(boolean)}
      */
     public void lockPivotTables() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setPivotTables(true);
+        lockPivotTables(true);
     }
 
     /**
-     * Enable Sort locking.
+     * Enable or disable Pivot Tables locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link 
#enableLocking()}
+     */
+    public void lockPivotTables(boolean enabled) {
+        safeGetProtectionField().setPivotTables(enabled);
+    }
+
+    /**
+     * Enable Sort locking.
+     * @deprecated use {@link #lockSort(boolean)}
      */
     public void lockSort() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setSort(true);
+        lockSort(true);
     }
 
     /**
-     * Enable Objects locking.
+     * Enable or disable Sort locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link 
#enableLocking()}
+     */
+    public void lockSort(boolean enabled) {
+        safeGetProtectionField().setSort(enabled);
+    }
+
+    /**
+     * Enable Objects locking.
+     * @deprecated use {@link #lockObjects(boolean)}
      */
     public void lockObjects() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setObjects(true);
+        lockObjects(true);
     }
 
     /**
-     * Enable Scenarios locking.
+     * Enable or disable Objects locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link 
#enableLocking()}
+     */
+    public void lockObjects(boolean enabled) {
+        safeGetProtectionField().setObjects(enabled);
+    }
+
+    /**
+     * Enable Scenarios locking.
+     * @deprecated use {@link #lockScenarios(boolean)}
      */
     public void lockScenarios() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setScenarios(true);
+        lockScenarios(true);
     }
 
     /**
-     * Enable Selection of locked cells locking.
+     * Enable or disable Scenarios locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link 
#enableLocking()}
+     */
+    public void lockScenarios(boolean enabled) {
+        safeGetProtectionField().setScenarios(enabled);
+    }
+
+    /**
+     * Enable Selection of locked cells locking.
+     * @deprecated use {@link #lockSelectLockedCells(boolean)}
      */
     public void lockSelectLockedCells() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setSelectLockedCells(true);
+        lockSelectLockedCells(true);
     }
 
     /**
-     * Enable Selection of unlocked cells locking.
+     * Enable or disable Selection of locked cells locking.
      * This does not modify sheet protection status.
-     * To enforce this locking, call {@link #enableLocking()}
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link 
#enableLocking()}
+     */
+    public void lockSelectLockedCells(boolean enabled) {
+        safeGetProtectionField().setSelectLockedCells(enabled);
+    }
+
+    /**
+     * Enable Selection of unlocked cells locking.
+     * @deprecated use {@link #lockSelectUnlockedCells(boolean)}
      */
     public void lockSelectUnlockedCells() {
-        createProtectionFieldIfNotPresent();
-        worksheet.getSheetProtection().setSelectUnlockedCells(true);
+        lockSelectUnlockedCells(true);
     }
 
-    private void createProtectionFieldIfNotPresent() {
-        if (worksheet.getSheetProtection() == null) {
-            
worksheet.setSheetProtection(CTSheetProtection.Factory.newInstance());
+    /**
+     * Enable or disable Selection of unlocked cells locking.
+     * This does not modify sheet protection status.
+     * To enforce this un-/locking, call {@link #disableLocking()} or {@link 
#enableLocking()}
+     */
+    public void lockSelectUnlockedCells(boolean enabled) {
+        safeGetProtectionField().setSelectUnlockedCells(enabled);
+    }
+
+    private CTSheetProtection safeGetProtectionField() {
+        if (!isSheetProtectionEnabled()) {
+            return worksheet.addNewSheetProtection();
         }
+        return worksheet.getSheetProtection();
     }
 
-    private boolean sheetProtectionEnabled() {
-        return worksheet.getSheetProtection().getSheet();
+    /* package */ boolean isSheetProtectionEnabled() {
+        return (worksheet.isSetSheetProtection());
     }
 
     /* package */ boolean isCellInArrayFormulaContext(XSSFCell cell) {
@@ -3403,10 +3510,7 @@ public class XSSFSheet extends POIXMLDoc
      * Returns any tables associated with this Sheet
      */
     public List<XSSFTable> getTables() {
-       List<XSSFTable> tableList = new ArrayList<XSSFTable>(
-             tables.values()
-       );
-       return tableList;
+        return new ArrayList<XSSFTable>(tables.values());
     }
 
     @Override
@@ -3529,21 +3633,20 @@ public class XSSFSheet extends POIXMLDoc
         String c = "";
         String r = "";
 
-        if(startC == -1 && endC == -1) {
-        } else {
+        if (startC != -1 || endC != -1) {
           c = escapedName + "!$" + colRef.getCellRefParts()[2]
               + ":$" + colRef2.getCellRefParts()[2];
         }
 
-        if (startR == -1 && endR == -1) {
-
-        } else if (!rowRef.getCellRefParts()[1].equals("0")
-            && !rowRef2.getCellRefParts()[1].equals("0")) {
-           r = escapedName + "!$" + rowRef.getCellRefParts()[1]
-                 + ":$" + rowRef2.getCellRefParts()[1];
+        if (startR != -1 || endR != -1) {
+            if (!rowRef.getCellRefParts()[1].equals("0")
+                && !rowRef2.getCellRefParts()[1].equals("0")) {
+               r = escapedName + "!$" + rowRef.getCellRefParts()[1]
+                     + ":$" + rowRef2.getCellRefParts()[1];
+            }
         }
 
-        StringBuffer rng = new StringBuffer();
+        StringBuilder rng = new StringBuilder();
         rng.append(c);
         if(rng.length() > 0 && r.length() > 0) {
           rng.append(',');

Modified: 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheetConditionalFormatting.java
URL: 
http://svn.apache.org/viewvc/poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheetConditionalFormatting.java?rev=1625828&r1=1625827&r2=1625828&view=diff
==============================================================================
--- 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheetConditionalFormatting.java
 (original)
+++ 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheetConditionalFormatting.java
 Wed Sep 17 21:12:36 2014
@@ -19,21 +19,21 @@
 
 package org.apache.poi.xssf.usermodel;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.hssf.record.cf.CellRangeUtil;
+import org.apache.poi.ss.SpreadsheetVersion;
+import org.apache.poi.ss.usermodel.ComparisonOperator;
 import org.apache.poi.ss.usermodel.ConditionalFormatting;
 import org.apache.poi.ss.usermodel.ConditionalFormattingRule;
 import org.apache.poi.ss.usermodel.SheetConditionalFormatting;
-import org.apache.poi.ss.usermodel.ComparisonOperator;
 import org.apache.poi.ss.util.CellRangeAddress;
-import org.apache.poi.ss.SpreadsheetVersion;
-import org.apache.poi.hssf.record.cf.CellRangeUtil;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfRule;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCfType;
 import 
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTConditionalFormatting;
-import 
org.openxmlformats.schemas.spreadsheetml.x2006.main.STConditionalFormattingOperator;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
-
-import java.util.List;
-import java.util.ArrayList;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCfType;
+import 
org.openxmlformats.schemas.spreadsheetml.x2006.main.STConditionalFormattingOperator;
 
 /**
  * @author Yegor Kozlov
@@ -115,6 +115,7 @@ public class XSSFSheetConditionalFormatt
         return rule;
     }
 
+    @SuppressWarnings("deprecation")
     public int addConditionalFormatting(CellRangeAddress[] regions, 
ConditionalFormattingRule[] cfRules) {
         if (regions == null) {
             throw new IllegalArgumentException("regions must not be null");
@@ -130,21 +131,15 @@ public class XSSFSheetConditionalFormatt
         if (cfRules.length > 3) {
             throw new IllegalArgumentException("Number of rules must not 
exceed 3");
         }
-        XSSFConditionalFormattingRule[] hfRules;
-        if(cfRules instanceof XSSFConditionalFormattingRule[]) hfRules = 
(XSSFConditionalFormattingRule[])cfRules;
-        else {
-            hfRules = new XSSFConditionalFormattingRule[cfRules.length];
-            System.arraycopy(cfRules, 0, hfRules, 0, hfRules.length);
-        }
+
         CellRangeAddress[] mergeCellRanges = 
CellRangeUtil.mergeCellRanges(regions);
         CTConditionalFormatting cf = 
_sheet.getCTWorksheet().addNewConditionalFormatting();
         List<String> refs = new ArrayList<String>();
         for(CellRangeAddress a : mergeCellRanges) refs.add(a.formatAsString());
         cf.setSqref(refs);
 
-
         int priority = 1;
-        for(CTConditionalFormatting c : 
_sheet.getCTWorksheet().getConditionalFormattingList()){
+        for(CTConditionalFormatting c : 
_sheet.getCTWorksheet().getConditionalFormattingArray()){
             priority += c.sizeOfCfRuleArray();
         }
 
@@ -220,7 +215,7 @@ public class XSSFSheetConditionalFormatt
     */
     public void removeConditionalFormatting(int index) {
         checkIndex(index);
-        _sheet.getCTWorksheet().getConditionalFormattingList().remove(index);
+        _sheet.getCTWorksheet().removeConditionalFormatting(index);
     }
 
     private void checkIndex(int index) {

Modified: 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java
URL: 
http://svn.apache.org/viewvc/poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java?rev=1625828&r1=1625827&r2=1625828&view=diff
==============================================================================
--- 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java
 (original)
+++ 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java
 Wed Sep 17 21:12:36 2014
@@ -128,13 +128,14 @@ public class XSSFTable extends POIXMLDoc
         * 
         * @return the xpath of the table's root element
         */
+    @SuppressWarnings("deprecation")
        public String getCommonXpath() {
                
                if(commonXPath == null){
                
                String[] commonTokens ={};
                
-               for(CTTableColumn column 
:ctTable.getTableColumns().getTableColumnList()){
+               for(CTTableColumn column 
:ctTable.getTableColumns().getTableColumnArray()){
                        if(column.getXmlColumnPr()!=null){
                                String xpath = 
column.getXmlColumnPr().getXpath();
                                String[] tokens =  xpath.split("/");
@@ -173,11 +174,12 @@ public class XSSFTable extends POIXMLDoc
        }
 
        
+    @SuppressWarnings("deprecation")
        public List<XSSFXmlColumnPr> getXmlColumnPrs() {
                
                if(xmlColumnPr==null){
                        xmlColumnPr = new ArrayList<XSSFXmlColumnPr>();
-                       for (CTTableColumn 
column:ctTable.getTableColumns().getTableColumnList()){
+                       for (CTTableColumn 
column:ctTable.getTableColumns().getTableColumnArray()){
                                if (column.getXmlColumnPr()!=null){
                                        XSSFXmlColumnPr columnPr = new 
XSSFXmlColumnPr(this,column,column.getXmlColumnPr());
                                        xmlColumnPr.add(columnPr);
@@ -285,6 +287,7 @@ public class XSSFTable extends POIXMLDoc
      * Headers <em>must</em> be in sync, otherwise Excel will display a
      * "Found unreadable content" message on startup.
      */
+    @SuppressWarnings("deprecation")
     public void updateHeaders(){
         XSSFSheet sheet = (XSSFSheet)getParent();
         CellReference ref = getStartCellReference();
@@ -296,7 +299,7 @@ public class XSSFTable extends POIXMLDoc
 
         if (row != null && row.getCTRow().validate()) {
             int cellnum = firstHeaderColumn;
-            for (CTTableColumn col : 
getCTTable().getTableColumns().getTableColumnList()) {
+            for (CTTableColumn col : 
getCTTable().getTableColumns().getTableColumnArray()) {
                 XSSFCell cell = row.getCell(cellnum);
                 if (cell != null) {
                     col.setName(cell.getStringCellValue());

Modified: 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
URL: 
http://svn.apache.org/viewvc/poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java?rev=1625828&r1=1625827&r2=1625828&view=diff
==============================================================================
--- 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
 (original)
+++ 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
 Wed Sep 17 21:12:36 2014
@@ -17,6 +17,9 @@
 
 package org.apache.poi.xssf.usermodel;
 
+import static 
org.apache.poi.xssf.usermodel.helpers.XSSFPaswordHelper.setPassword;
+import static 
org.apache.poi.xssf.usermodel.helpers.XSSFPaswordHelper.validatePassword;
+
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -47,6 +50,7 @@ import org.apache.poi.openxml4j.opc.Pack
 import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
 import org.apache.poi.openxml4j.opc.PackagingURIHelper;
 import org.apache.poi.openxml4j.opc.TargetMode;
+import org.apache.poi.poifs.crypt.HashAlgorithm;
 import org.apache.poi.ss.formula.SheetNameFormatter;
 import org.apache.poi.ss.formula.udf.IndexedUDFFinder;
 import org.apache.poi.ss.formula.udf.UDFFinder;
@@ -1366,6 +1370,7 @@ public class XSSFWorkbook extends POIXML
      * @param pos the position that we want to insert the sheet into (0 based)
      */
     @Override
+    @SuppressWarnings("deprecation")
     public void setSheetOrder(String sheetname, int pos) {
         int idx = getSheetIndex(sheetname);
         sheets.add(pos, sheets.remove(idx));
@@ -1377,8 +1382,9 @@ public class XSSFWorkbook extends POIXML
         newcts.set(cts);
 
         //notify sheets
-        for(int i=0; i < sheets.size(); i++) {
-            sheets.get(i).sheet = ct.getSheetArray(i);
+        CTSheet[] sheetArray = ct.getSheetArray();
+        for(int i=0; i < sheetArray.length; i++) {
+            sheets.get(i).sheet = sheetArray[i];
         }
     }
 
@@ -1410,10 +1416,11 @@ public class XSSFWorkbook extends POIXML
         }
     }
     
+    @SuppressWarnings("deprecation")
     private void reprocessNamedRanges() {
         namedRanges = new ArrayList<XSSFName>();
         if(workbook.isSetDefinedNames()) {
-            for(CTDefinedName ctName : 
workbook.getDefinedNames().getDefinedNameList()) {
+            for(CTDefinedName ctName : 
workbook.getDefinedNames().getDefinedNameArray()) {
                 namedRanges.add(new XSSFName(ctName, this));
             }
         }
@@ -1735,60 +1742,108 @@ public class XSSFWorkbook extends POIXML
         * Locks the structure of workbook.
         */
        public void lockStructure() {
-               createProtectionFieldIfNotPresent();
-               workbook.getWorkbookProtection().setLockStructure(true);
+           safeGetWorkbookProtection().setLockStructure(true);
        }
 
        /**
         * Unlocks the structure of workbook.
         */
        public void unLockStructure() {
-               createProtectionFieldIfNotPresent();
-               workbook.getWorkbookProtection().setLockStructure(false);
+           safeGetWorkbookProtection().setLockStructure(false);
        }
 
        /**
         * Locks the windows that comprise the workbook.
         */
        public void lockWindows() {
-               createProtectionFieldIfNotPresent();
-               workbook.getWorkbookProtection().setLockWindows(true);
+           safeGetWorkbookProtection().setLockWindows(true);
        }
 
        /**
         * Unlocks the windows that comprise the workbook.
         */
        public void unLockWindows() {
-               createProtectionFieldIfNotPresent();
-               workbook.getWorkbookProtection().setLockWindows(false);
+           safeGetWorkbookProtection().setLockWindows(false);
        }
 
        /**
         * Locks the workbook for revisions.
         */
        public void lockRevision() {
-               createProtectionFieldIfNotPresent();
-               workbook.getWorkbookProtection().setLockRevision(true);
+           safeGetWorkbookProtection().setLockRevision(true);
        }
 
        /**
         * Unlocks the workbook for revisions.
         */
        public void unLockRevision() {
-               createProtectionFieldIfNotPresent();
-               workbook.getWorkbookProtection().setLockRevision(false);
+           safeGetWorkbookProtection().setLockRevision(false);
        }
 
-       private boolean workbookProtectionPresent() {
-               return workbook.getWorkbookProtection() != null;
+       /**
+        * Sets the workbook password. 
+        * 
+        * @param password if null, the password will be removed
+        * @param hashAlgo if null, the password will be set as XOR password 
(Excel 2010 and earlier)
+        *  otherwise the given algorithm is used for calculating the hash 
password (Excel 2013)
+        */
+       public void setWorkbookPassword(String password, HashAlgorithm 
hashAlgo) {
+        if (password == null && !workbookProtectionPresent()) return;
+        setPassword(safeGetWorkbookProtection(), password, hashAlgo, 
"workbook");
        }
 
-       private void createProtectionFieldIfNotPresent() {
-               if (workbook.getWorkbookProtection() == null){
-                       
workbook.setWorkbookProtection(CTWorkbookProtection.Factory.newInstance());
-               }
+    /**
+     * Validate the password against the stored hash, the hashing method will 
be determined
+     *  by the existing password attributes
+     * @return true, if the hashes match (... though original password may 
differ ...)
+     */
+    public boolean validateWorkbookPassword(String password) {
+        if (!workbookProtectionPresent()) return (password == null);
+        return validatePassword(safeGetWorkbookProtection(), password, 
"workbook");
+    }
+
+    /**
+     * Sets the revisions password.
+     * 
+     * @param password if null, the password will be removed
+     * @param hashAlgo if null, the password will be set as XOR password 
(Excel 2010 and earlier)
+     *  otherwise the given algorithm is used for calculating the hash 
password (Excel 2013)
+     */
+    public void setRevisionsPassword(String password, HashAlgorithm hashAlgo) {
+        if (password == null && !workbookProtectionPresent()) return;
+        setPassword(safeGetWorkbookProtection(), password, hashAlgo, 
"revisions");
+    }
+
+    /**
+     * Validate the password against the stored hash, the hashing method will 
be determined
+     *  by the existing password attributes
+     * @return true if the hashes match (... though original password may 
differ ...)
+     */
+    public boolean validateRevisionsPassword(String password) {
+        if (!workbookProtectionPresent()) return (password == null);
+        return validatePassword(safeGetWorkbookProtection(), password, 
"revisions");
+    }
+    
+    /**
+     * Removes the workbook protection settings
+     */
+    public void unLock() {
+        if (workbookProtectionPresent()) {
+            workbook.unsetWorkbookProtection();
+        }
+    }
+    
+       private boolean workbookProtectionPresent() {
+               return workbook.isSetWorkbookProtection();
        }
 
+    private CTWorkbookProtection safeGetWorkbookProtection() {
+        if (!workbookProtectionPresent()){
+            return workbook.addNewWorkbookProtection();
+        }
+        return workbook.getWorkbookProtection();
+    }
+       
     /**
      *
      * Returns the locator of user-defined functions.

Modified: 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/ColumnHelper.java
URL: 
http://svn.apache.org/viewvc/poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/ColumnHelper.java?rev=1625828&r1=1625827&r2=1625828&view=diff
==============================================================================
--- 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/ColumnHelper.java
 (original)
+++ 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/ColumnHelper.java
 Wed Sep 17 21:12:36 2014
@@ -19,7 +19,6 @@ package org.apache.poi.xssf.usermodel.he
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Comparator;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -50,52 +49,39 @@ public class ColumnHelper {
         cleanColumns();
     }
     
+    @SuppressWarnings("deprecation")
     public void cleanColumns() {
         this.newCols = CTCols.Factory.newInstance();
 
         CTCols aggregateCols = CTCols.Factory.newInstance();
-        List<CTCols> colsList = worksheet.getColsList();
-        assert(colsList != null);
+        CTCols[] colsArray = worksheet.getColsArray();
+        assert(colsArray != null);
         
-        for (CTCols cols : colsList) {
-            for (CTCol col : cols.getColList()) {
+        for (CTCols cols : colsArray) {
+            for (CTCol col : cols.getColArray()) {
                 cloneCol(aggregateCols, col);
             }
         }
         
         sortColumns(aggregateCols);
         
-        CTCol[] colArray = new CTCol[aggregateCols.getColList().size()];
-        aggregateCols.getColList().toArray(colArray);
+        CTCol[] colArray = aggregateCols.getColArray();
         sweepCleanColumns(newCols, colArray, null);
         
-        int i = colsList.size();
+        int i = colsArray.length;
         for (int y = i - 1; y >= 0; y--) {
             worksheet.removeCols(y);
         }
         worksheet.addNewCols();
         worksheet.setColsArray(0, newCols);
     }
-    
-    private static class CTColByMaxComparator implements Comparator<CTCol> {
-
-        public int compare(CTCol arg0, CTCol arg1) {
-            if (arg0.getMax() < arg1.getMax()) {
-                return -1;
-            } else {
-                if (arg0.getMax() > arg1.getMax()) return 1;
-                else return 0;
-            }
-        }
-        
-    }
 
     /**
      * @see <a href="http://en.wikipedia.org/wiki/Sweep_line_algorithm";>Sweep 
line algorithm</a>
      */
     private void sweepCleanColumns(CTCols cols, CTCol[] flattenedColsArray, 
CTCol overrideColumn) {
         List<CTCol> flattenedCols = new 
ArrayList<CTCol>(Arrays.asList(flattenedColsArray));
-        TreeSet<CTCol> currentElements = new TreeSet<CTCol>(new 
CTColByMaxComparator());
+        TreeSet<CTCol> currentElements = new 
TreeSet<CTCol>(CTColComparator.BY_MAX);
         ListIterator<CTCol> flIter = flattenedCols.listIterator();
         CTCol haveOverrideColumn = null;
         long lastMaxIndex = 0;
@@ -103,7 +89,8 @@ public class ColumnHelper {
         while (flIter.hasNext()) {
             CTCol col = flIter.next();
             long currentIndex = col.getMin();
-            long nextIndex = (col.getMax() > currentMax) ? col.getMax() : 
currentMax;
+            long colMax = col.getMax();
+            long nextIndex = (colMax > currentMax) ? colMax : currentMax;
             if (flIter.hasNext()) {
                 nextIndex = flIter.next().getMin();
                 flIter.previous();
@@ -116,10 +103,10 @@ public class ColumnHelper {
             }
             if (!currentElements.isEmpty() && lastMaxIndex < currentIndex) {
                 // we need to process previous elements first
-                insertCol(cols, lastMaxIndex, currentIndex - 1, 
currentElements.toArray(new CTCol[]{}), true, haveOverrideColumn);
+                insertCol(cols, lastMaxIndex, currentIndex - 1, 
currentElements.toArray(new CTCol[currentElements.size()]), true, 
haveOverrideColumn);
             }
             currentElements.add(col);
-            if (col.getMax() > currentMax) currentMax = col.getMax();
+            if (colMax > currentMax) currentMax = colMax;
             if (col.equals(overrideColumn)) haveOverrideColumn = 
overrideColumn;
             while (currentIndex <= nextIndex && !currentElements.isEmpty()) {
                 Set<CTCol> currentIndexElements = new HashSet<CTCol>();
@@ -130,26 +117,21 @@ public class ColumnHelper {
                     CTCol currentElem = currentElements.first();
                     currentElemIndex = currentElem.getMax();
                     currentIndexElements.add(currentElem);
-                    
-                    for (CTCol cc : currentElements.tailSet(currentElem)) {
-                        if (cc == null || cc.getMax() == currentElemIndex) 
break;
-                        currentIndexElements.add(cc);
-                        if (col.getMax() > currentMax) currentMax = 
col.getMax();
+
+                    while (true) {
+                        CTCol higherElem = currentElements.higher(currentElem);
+                        if (higherElem == null || higherElem.getMax() != 
currentElemIndex)
+                            break;
+                        currentElem = higherElem;
+                        currentIndexElements.add(currentElem);
+                        if (colMax > currentMax) currentMax = colMax;
                         if (col.equals(overrideColumn)) haveOverrideColumn = 
overrideColumn;
                     }
-
-                    // JDK 6 code
-                    // while (currentElements.higher(currentElem) != null && 
currentElements.higher(currentElem).getMax() == currentElemIndex) {
-                    //     currentElem = currentElements.higher(currentElem);
-                    //     currentIndexElements.add(currentElem);
-                    //     if (col.getMax() > currentMax) currentMax = 
col.getMax();
-                    //     if (col.equals(overrideColumn)) haveOverrideColumn 
= overrideColumn;
-                    // }
                 }
                 
                 
                 if (currentElemIndex < nextIndex || !flIter.hasNext()) {
-                    insertCol(cols, currentIndex, currentElemIndex, 
currentElements.toArray(new CTCol[]{}), true, haveOverrideColumn);
+                    insertCol(cols, currentIndex, currentElemIndex, 
currentElements.toArray(new CTCol[currentElements.size()]), true, 
haveOverrideColumn);
                     if (flIter.hasNext()) {
                         if (nextIndex > currentElemIndex) {
                             currentElements.removeAll(currentIndexElements);
@@ -170,10 +152,10 @@ public class ColumnHelper {
         sortColumns(cols);
     }
 
+    @SuppressWarnings("deprecation")
     public static void sortColumns(CTCols newCols) {
-        CTCol[] colArray = new CTCol[newCols.getColList().size()];
-        newCols.getColList().toArray(colArray);
-        Arrays.sort(colArray, new CTColComparator());
+        CTCol[] colArray = newCols.getColArray();
+        Arrays.sort(colArray, CTColComparator.BY_MIN_MAX);
         newCols.setColArray(colArray);
     }
 
@@ -198,46 +180,46 @@ public class ColumnHelper {
      *  as 1 based.
      */
     public CTCol getColumn1Based(long index1, boolean splitColumns) {
-        CTCols colsArray = worksheet.getColsArray(0);
+        CTCols cols = worksheet.getColsArray(0);
         
         // Fetching the array is quicker than working on the new style
         //  list, assuming we need to read many of them (which we often do),
         //  and assuming we're not making many changes (which we're not)
         @SuppressWarnings("deprecation")
-        CTCol[] cols = colsArray.getColArray();
-        
-        for (int i = 0; i < cols.length; i++) {
-            CTCol colArray = cols[i];
-            if (colArray.getMin() <= index1 && colArray.getMax() >= index1) {
+        CTCol[] colArray = cols.getColArray();
+
+        for (CTCol col : colArray) {
+            long colMin = col.getMin();
+            long colMax = col.getMax();
+            if (colMin <= index1 && colMax >= index1) {
                 if (splitColumns) {
-                    if (colArray.getMin() < index1) {
-                        insertCol(colsArray, colArray.getMin(), (index1 - 1), 
new CTCol[]{colArray});
+                    if (colMin < index1) {
+                        insertCol(cols, colMin, (index1 - 1), new 
CTCol[]{col});
                     }
-                    if (colArray.getMax() > index1) {
-                        insertCol(colsArray, (index1 + 1), colArray.getMax(), 
new CTCol[]{colArray});
+                    if (colMax > index1) {
+                        insertCol(cols, (index1 + 1), colMax, new 
CTCol[]{col});
                     }
-                    colArray.setMin(index1);
-                    colArray.setMax(index1);
+                    col.setMin(index1);
+                    col.setMax(index1);
                 }
-                return colArray;
+                return col;
             }
         }
         return null;
     }
-    
+
+    @SuppressWarnings("deprecation")
     public CTCols addCleanColIntoCols(CTCols cols, CTCol col) {
         CTCols newCols = CTCols.Factory.newInstance();
-        for (CTCol c : cols.getColList()) {
+        for (CTCol c : cols.getColArray()) {
             cloneCol(newCols, c);
         }
         cloneCol(newCols, col);
         sortColumns(newCols);
-        CTCol[] colArray = new CTCol[newCols.getColList().size()];
-        newCols.getColList().toArray(colArray);
+        CTCol[] colArray = newCols.getColArray();
         CTCols returnCols = CTCols.Factory.newInstance();
         sweepCleanColumns(returnCols, colArray, col);
-        colArray = new CTCol[returnCols.getColList().size()];
-        returnCols.getColList().toArray(colArray);
+        colArray = returnCols.getColArray();
         cols.setColArray(colArray);
         return returnCols;
     }
@@ -272,9 +254,11 @@ public class ColumnHelper {
     public boolean columnExists(CTCols cols, long index) {
         return columnExists1Based(cols, index+1);
     }
+
+    @SuppressWarnings("deprecation")
     private boolean columnExists1Based(CTCols cols, long index1) {
-        for (int i = 0; i < cols.sizeOfColArray(); i++) {
-            if (cols.getColArray(i).getMin() == index1) {
+        for (CTCol col : cols.getColArray()) {
+            if (col.getMin() == index1) {
                 return true;
             }
         }
@@ -343,20 +327,24 @@ public class ColumnHelper {
         return -1;
     }
 
+    @SuppressWarnings("deprecation")
     private boolean columnExists(CTCols cols, long min, long max) {
-        for (int i = 0; i < cols.sizeOfColArray(); i++) {
-            if (cols.getColArray(i).getMin() == min && 
cols.getColArray(i).getMax() == max) {
+        for (CTCol col : cols.getColArray()) {
+            if (col.getMin() == min && col.getMax() == max) {
                 return true;
             }
         }
         return false;
     }
-    
-    public int getIndexOfColumn(CTCols cols, CTCol col) {
-        for (int i = 0; i < cols.sizeOfColArray(); i++) {
-            if (cols.getColArray(i).getMin() == col.getMin() && 
cols.getColArray(i).getMax() == col.getMax()) {
+
+    @SuppressWarnings("deprecation")
+    public int getIndexOfColumn(CTCols cols, CTCol searchCol) {
+        int i = 0;
+        for (CTCol col : cols.getColArray()) {
+            if (col.getMin() == searchCol.getMin() && col.getMax() == 
searchCol.getMax()) {
                 return i;
             }
+            i++;
         }
         return -1;
     }

Modified: 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java
URL: 
http://svn.apache.org/viewvc/poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java?rev=1625828&r1=1625827&r2=1625828&view=diff
==============================================================================
--- 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java
 (original)
+++ 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java
 Wed Sep 17 21:12:36 2014
@@ -18,7 +18,9 @@
 package org.apache.poi.xssf.usermodel.helpers;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.poi.ss.formula.FormulaParseException;
 import org.apache.poi.ss.formula.FormulaParser;
@@ -43,6 +45,7 @@ import org.openxmlformats.schemas.spread
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfRule;
 import 
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTConditionalFormatting;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType;
 
 /**
@@ -66,8 +69,10 @@ public final class XSSFRowShifter {
      */
     public List<CellRangeAddress> shiftMerged(int startRow, int endRow, int n) 
{
         List<CellRangeAddress> shiftedRegions = new 
ArrayList<CellRangeAddress>();
+        Set<Integer> removedIndices = new HashSet<Integer>();
         //move merged regions completely if they fall within the new region 
boundaries when they are shifted
-        for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
+        int size = sheet.getNumMergedRegions();
+        for (int i = 0; i < size; i++) {
             CellRangeAddress merged = sheet.getMergedRegion(i);
 
             boolean inStart = (merged.getFirstRow() >= startRow || 
merged.getLastRow() >= startRow);
@@ -84,10 +89,13 @@ public final class XSSFRowShifter {
                 merged.setLastRow(merged.getLastRow() + n);
                 //have to remove/add it back
                 shiftedRegions.add(merged);
-                sheet.removeMergedRegion(i);
-                i = i - 1; // we have to back up now since we removed one
+                removedIndices.add(i);
             }
         }
+        
+        if(!removedIndices.isEmpty()) {
+            sheet.removeMergedRegions(removedIndices);
+        }
 
         //read so it doesn't get shifted again
         for (CellRangeAddress region : shiftedRegions) {
@@ -213,28 +221,29 @@ public final class XSSFRowShifter {
         }
     }
 
+    @SuppressWarnings("deprecation")
     public void updateConditionalFormatting(FormulaShifter shifter) {
         XSSFWorkbook wb = sheet.getWorkbook();
         int sheetIndex = wb.getSheetIndex(sheet);
 
-
         XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb);
-        List<CTConditionalFormatting> cfList = 
sheet.getCTWorksheet().getConditionalFormattingList();
-        for(int j = 0; j< cfList.size(); j++){
-            CTConditionalFormatting cf = cfList.get(j);
+        CTWorksheet ctWorksheet = sheet.getCTWorksheet();
+        CTConditionalFormatting[] conditionalFormattingArray = 
ctWorksheet.getConditionalFormattingArray();
+        // iterate backwards due to possible calls to 
ctWorksheet.removeConditionalFormatting(j)
+        for (int j = conditionalFormattingArray.length - 1; j >= 0; j--) {
+            CTConditionalFormatting cf = conditionalFormattingArray[j];
 
             ArrayList<CellRangeAddress> cellRanges = new 
ArrayList<CellRangeAddress>();
             for (Object stRef : cf.getSqref()) {
                 String[] regions = stRef.toString().split(" ");
-                for (int i = 0; i < regions.length; i++) {
-                    cellRanges.add(CellRangeAddress.valueOf(regions[i]));
+                for (String region : regions) {
+                    cellRanges.add(CellRangeAddress.valueOf(region));
                 }
             }
 
             boolean changed = false;
             List<CellRangeAddress> temp = new ArrayList<CellRangeAddress>();
-            for (int i = 0; i < cellRanges.size(); i++) {
-                CellRangeAddress craOld = cellRanges.get(i);
+            for (CellRangeAddress craOld : cellRanges) {
                 CellRangeAddress craNew = shiftRange(shifter, craOld, 
sheetIndex);
                 if (craNew == null) {
                     changed = true;
@@ -249,7 +258,7 @@ public final class XSSFRowShifter {
             if (changed) {
                 int nRanges = temp.size();
                 if (nRanges == 0) {
-                    cfList.remove(j);
+                    ctWorksheet.removeConditionalFormatting(j);
                     continue;
                 }
                 List<String> refs = new ArrayList<String>();
@@ -257,14 +266,14 @@ public final class XSSFRowShifter {
                 cf.setSqref(refs);
             }
 
-            for(CTCfRule cfRule : cf.getCfRuleList()){
-                List<String> formulas = cfRule.getFormulaList();
-                for (int i = 0; i < formulas.size(); i++) {
-                    String formula = formulas.get(i);
+            for(CTCfRule cfRule : cf.getCfRuleArray()){
+                String[] formulaArray = cfRule.getFormulaArray();
+                for (int i = 0; i < formulaArray.length; i++) {
+                    String formula = formulaArray[i];
                     Ptg[] ptgs = FormulaParser.parse(formula, fpb, 
FormulaType.CELL, sheetIndex);
                     if (shifter.adjustFormula(ptgs, sheetIndex)) {
                         String shiftedFmla = 
FormulaRenderer.toFormulaString(fpb, ptgs);
-                        formulas.set(i, shiftedFmla);
+                        cfRule.setFormulaArray(i, shiftedFmla);
                     }
                 }
             }

Modified: 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/util/CTColComparator.java
URL: 
http://svn.apache.org/viewvc/poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/util/CTColComparator.java?rev=1625828&r1=1625827&r2=1625828&view=diff
==============================================================================
--- 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/util/CTColComparator.java
 (original)
+++ 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xssf/util/CTColComparator.java
 Wed Sep 17 21:12:36 2014
@@ -21,26 +21,26 @@ import java.util.Comparator;
 
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol;
 
-public class CTColComparator implements Comparator<CTCol>{
+public class CTColComparator {
 
-    public int compare(CTCol o1, CTCol o2) {
-        if (o1.getMin() < o2.getMin()) {
-            return -1;
-        }
-        else if (o1.getMin() > o2.getMin()) {
-            return 1;
+    private CTColComparator() {}
+
+    public static final Comparator<CTCol> BY_MAX = new Comparator<CTCol>() {
+        @Override
+        public int compare(CTCol col1, CTCol col2) {
+            long col1max = col1.getMax();
+            long col2max = col2.getMax();
+            return col1max < col2max ? -1 : col1max > col2max ? 1 : 0;
         }
-        else {
-            if (o1.getMax() < o2.getMax()) {
-                return -1;
-            }
-            if (o1.getMax() > o2.getMax()) {
-                return 1;
-            }
-            return 0;
+    };
+
+    public static final Comparator<CTCol> BY_MIN_MAX = new Comparator<CTCol>() 
{
+        @Override
+        public int compare(CTCol col1, CTCol col2) {
+            long col11min = col1.getMin();
+            long col2min = col2.getMin();
+            return col11min < col2min ? -1 : col11min > col2min ? 1 : 
BY_MAX.compare(col1, col2);
         }
-    }
-    
-    
-    
+    };
+
 }

Modified: 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xwpf/model/XWPFCommentsDecorator.java
URL: 
http://svn.apache.org/viewvc/poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xwpf/model/XWPFCommentsDecorator.java?rev=1625828&r1=1625827&r2=1625828&view=diff
==============================================================================
--- 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xwpf/model/XWPFCommentsDecorator.java
 (original)
+++ 
poi/branches/xml_signature/src/ooxml/java/org/apache/poi/xwpf/model/XWPFCommentsDecorator.java
 Wed Sep 17 21:12:36 2014
@@ -33,13 +33,15 @@ public class XWPFCommentsDecorator exten
        public XWPFCommentsDecorator(XWPFParagraphDecorator nextDecorator) {
                this(nextDecorator.paragraph, nextDecorator);
        }
+
+       @SuppressWarnings("deprecation")
        public XWPFCommentsDecorator(XWPFParagraph paragraph, 
XWPFParagraphDecorator nextDecorator) {
                super(paragraph, nextDecorator);
 
                XWPFComment comment;
                commentText = new StringBuffer();
 
-               for(CTMarkupRange anchor : 
paragraph.getCTP().getCommentRangeStartList())
+               for(CTMarkupRange anchor : 
paragraph.getCTP().getCommentRangeStartArray())
                {
                        if((comment = 
paragraph.getDocument().getCommentByID(anchor.getId().toString())) != null)
                                commentText.append("\tComment by " + 
comment.getAuthor()+": "+comment.getText());



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to