merged with trunk r615269

git-svn-id: https://svn.apache.org/repos/asf/poi/tags/REL_3_0_2_BETA3@615279 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml
index f11d64a..b1d8184 100644
--- a/src/documentation/content/xdocs/changes.xml
+++ b/src/documentation/content/xdocs/changes.xml
@@ -36,6 +36,7 @@
 
 		<!-- Don't forget to update status.xml too! -->
         <release version="3.0.2-FINAL" date="2008-??-??">
+            <action dev="POI-DEVELOPERS" type="fix">44293 - Avoid swapping AreaPtgs from relative to absolute</action>
             <action dev="POI-DEVELOPERS" type="fix">44292 - Correctly process the last paragraph in a word file</action>
             <action dev="POI-DEVELOPERS" type="fix">44254 - Avoid some unread byte warnings, and properly understand DVALRecord</action>
             <action dev="POI-DEVELOPERS" type="add">Add another formula evaluation method, evaluateFormulaCell(cell), which will re-calculate the value for a formula, without affecting the formula itself.</action>
diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml
index 73375a3..8221954 100644
--- a/src/documentation/content/xdocs/status.xml
+++ b/src/documentation/content/xdocs/status.xml
@@ -33,6 +33,7 @@
 	<!-- Don't forget to update changes.xml too! -->
     <changes>
         <release version="3.0.2-FINAL" date="2008-??-??">
+            <action dev="POI-DEVELOPERS" type="fix">44293 - Avoid swapping AreaPtgs from relative to absolute</action>
             <action dev="POI-DEVELOPERS" type="fix">44292 - Correctly process the last paragraph in a word file</action>
             <action dev="POI-DEVELOPERS" type="fix">44254 - Avoid some unread byte warnings, and properly understand DVALRecord</action>
             <action dev="POI-DEVELOPERS" type="add">Add another formula evaluation method, evaluateFormulaCell(cell), which will re-calculate the value for a formula, without affecting the formula itself.</action>
diff --git a/src/java/org/apache/poi/hssf/record/formula/AreaPtg.java b/src/java/org/apache/poi/hssf/record/formula/AreaPtg.java
index 32579a6..908c8d5 100644
--- a/src/java/org/apache/poi/hssf/record/formula/AreaPtg.java
+++ b/src/java/org/apache/poi/hssf/record/formula/AreaPtg.java
@@ -43,9 +43,9 @@
     private short             field_3_first_column;
     private short             field_4_last_column;
     
-    private BitField         rowRelative = BitFieldFactory.getInstance(0x8000);
-    private BitField         colRelative = BitFieldFactory.getInstance(0x4000);
-    private BitField         column      = BitFieldFactory.getInstance(0x3FFF);
+    private final static BitField   rowRelative = BitFieldFactory.getInstance(0x8000);
+    private final static BitField   colRelative = BitFieldFactory.getInstance(0x4000);
+    private final static BitField   columnMask      = BitFieldFactory.getInstance(0x3FFF);
 
     protected AreaPtg() {
       //Required for clone methods
@@ -157,7 +157,7 @@
      */
     public short getFirstColumn()
     {
-        return column.getShortValue(field_3_first_column);
+        return columnMask.getShortValue(field_3_first_column);
     }
 
     /**
@@ -204,7 +204,7 @@
      */
     public void setFirstColumn(short column)
     {
-        field_3_first_column = column;   // fixme
+    	field_3_first_column=columnMask.setShortValue(field_3_first_column, column);
     }
 
     /**
@@ -220,7 +220,7 @@
      */
     public short getLastColumn()
     {
-        return column.getShortValue(field_4_last_column);
+        return columnMask.getShortValue(field_4_last_column);
     }
 
     /**
@@ -269,7 +269,7 @@
      */
     public void setLastColumn(short column)
     {
-        field_4_last_column = column;   // fixme
+    	field_4_last_column=columnMask.setShortValue(field_4_last_column, column);
     }
 
     /**
diff --git a/src/testcases/org/apache/poi/hssf/data/SimpleWithChoose.xls b/src/testcases/org/apache/poi/hssf/data/SimpleWithChoose.xls
new file mode 100755
index 0000000..96a8e74
--- /dev/null
+++ b/src/testcases/org/apache/poi/hssf/data/SimpleWithChoose.xls
Binary files differ
diff --git a/src/testcases/org/apache/poi/hssf/record/formula/TestAreaPtg.java b/src/testcases/org/apache/poi/hssf/record/formula/TestAreaPtg.java
new file mode 100644
index 0000000..522a5bc
--- /dev/null
+++ b/src/testcases/org/apache/poi/hssf/record/formula/TestAreaPtg.java
@@ -0,0 +1,114 @@
+        
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.formula;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.hssf.model.FormulaParser;
+
+/**
+ * Tests for {@link AreaPtg}.
+ *
+ * @author Dmitriy Kumshayev
+ */
+public class TestAreaPtg extends TestCase
+{
+
+	AreaPtg relative;
+	AreaPtg absolute;
+	
+	protected void setUp() throws Exception
+	{
+		super.setUp();
+		short firstRow=5;
+		short lastRow=13;
+		short firstCol=7;
+		short lastCol=17;
+		relative = new AreaPtg(firstRow,lastRow,firstCol,lastCol,true,true,true,true);
+		absolute = new AreaPtg(firstRow,lastRow,firstCol,lastCol,false,false,false,false);
+	}
+
+	public void testSetColumnsAbsolute()
+	{
+		resetColumns(absolute);
+		validateReference(true, absolute);
+	}
+	public void testSetColumnsRelative()
+	{
+		resetColumns(relative);
+		validateReference(false, relative);
+	}
+
+	private void validateReference(boolean abs, AreaPtg ref)
+	{
+		assertEquals("First column reference is not "+(abs?"absolute":"relative"),abs,!ref.isFirstColRelative());
+		assertEquals("Last column reference is not "+(abs?"absolute":"relative"),abs,!ref.isLastColRelative());
+		assertEquals("First row reference is not "+(abs?"absolute":"relative"),abs,!ref.isFirstRowRelative());
+		assertEquals("Last row reference is not "+(abs?"absolute":"relative"),abs,!ref.isLastRowRelative());
+	}
+
+
+	public void resetColumns(AreaPtg aptg)
+	{
+		short fc = aptg.getFirstColumn();
+		short lc = aptg.getLastColumn();
+		aptg.setFirstColumn(fc);
+		aptg.setLastColumn(lc);
+		assertEquals(fc , aptg.getFirstColumn() );
+		assertEquals(lc , aptg.getLastColumn() );
+	}
+	
+	public void testFormulaParser()
+	{
+		String formula1="SUM($E$5:$E$6)";
+		String expectedFormula1="SUM($F$5:$F$6)";
+		String newFormula1 = shiftAllColumnsBy1(formula1);
+		assertEquals("Absolute references changed", expectedFormula1, newFormula1);
+		
+		String formula2="SUM(E5:E6)";
+		String expectedFormula2="SUM(F5:F6)";
+		String newFormula2 = shiftAllColumnsBy1(formula2);
+		assertEquals("Relative references changed", expectedFormula2, newFormula2);
+	}
+	
+	private String shiftAllColumnsBy1(String  formula)
+	{
+		int letUsShiftColumn1By1Column=1;
+		
+		FormulaParser parser = new FormulaParser(formula,null);
+		parser.parse();
+
+		final Ptg[] ptgs = parser.getRPNPtg();
+		for(int i=0; i<ptgs.length; i++)
+		{
+			Ptg ptg = ptgs[i];
+			if (ptg instanceof AreaPtg )
+			{
+				AreaPtg aptg = (AreaPtg)ptg;
+				aptg.setFirstColumn((short)(aptg.getFirstColumn()+letUsShiftColumn1By1Column));
+				aptg.setLastColumn((short)(aptg.getLastColumn()+letUsShiftColumn1By1Column));
+			}
+		}
+		String newFormula = parser.toFormulaString(ptgs);
+		return newFormula;
+	}
+	
+	
+
+}
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java
index d0dc720..824715b 100644
--- a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java
+++ b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java
@@ -1008,9 +1008,27 @@
 
         wb = new HSSFWorkbook(new ByteArrayInputStream(out.toByteArray()));
         assertTrue("No Exceptions while reading file", true);
-
     }
 
+	/**
+	 * Bug 42618: RecordFormatException reading a file containing
+	 * 	=CHOOSE(2,A2,A3,A4)
+	 */
+    public void test42618() throws Exception {
+        FileInputStream in = new FileInputStream(new File(cwd, "SimpleWithChoose.xls"));
+        HSSFWorkbook wb = new HSSFWorkbook(in);
+        in.close();
+
+        assertTrue("No Exceptions while reading file", true);
+
+        //serialize and read again
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        wb.write(out);
+        out.close();
+
+        wb = new HSSFWorkbook(new ByteArrayInputStream(out.toByteArray()));
+        assertTrue("No Exceptions while reading file", true);
+    }
 }