You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by on...@apache.org on 2016/06/10 02:51:45 UTC

svn commit: r1747625 [1/2] - in /poi/branches/xssf_structured_references/src: java/org/apache/poi/hssf/usermodel/ java/org/apache/poi/ss/formula/ java/org/apache/poi/ss/formula/functions/ ooxml/java/org/apache/poi/xssf/usermodel/ testcases/org/apache/p...

Author: onealj
Date: Fri Jun 10 02:51:45 2016
New Revision: 1747625

URL: http://svn.apache.org/viewvc?rev=1747625&view=rev
Log:
whitespace (tabs to spaces)

Modified:
    poi/branches/xssf_structured_references/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java
    poi/branches/xssf_structured_references/src/java/org/apache/poi/ss/formula/FormulaParsingWorkbook.java
    poi/branches/xssf_structured_references/src/java/org/apache/poi/ss/formula/OperationEvaluationContext.java
    poi/branches/xssf_structured_references/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java
    poi/branches/xssf_structured_references/src/java/org/apache/poi/ss/formula/functions/Indirect.java
    poi/branches/xssf_structured_references/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java
    poi/branches/xssf_structured_references/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
    poi/branches/xssf_structured_references/src/testcases/org/apache/poi/hssf/record/TestSharedFormulaRecord.java

Modified: poi/branches/xssf_structured_references/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java
URL: http://svn.apache.org/viewvc/poi/branches/xssf_structured_references/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java?rev=1747625&r1=1747624&r2=1747625&view=diff
==============================================================================
--- poi/branches/xssf_structured_references/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java (original)
+++ poi/branches/xssf_structured_references/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java Fri Jun 10 02:51:45 2016
@@ -6,7 +6,7 @@
    (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
+       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,

Modified: poi/branches/xssf_structured_references/src/java/org/apache/poi/ss/formula/FormulaParsingWorkbook.java
URL: http://svn.apache.org/viewvc/poi/branches/xssf_structured_references/src/java/org/apache/poi/ss/formula/FormulaParsingWorkbook.java?rev=1747625&r1=1747624&r2=1747625&view=diff
==============================================================================
--- poi/branches/xssf_structured_references/src/java/org/apache/poi/ss/formula/FormulaParsingWorkbook.java (original)
+++ poi/branches/xssf_structured_references/src/java/org/apache/poi/ss/formula/FormulaParsingWorkbook.java Fri Jun 10 02:51:45 2016
@@ -32,51 +32,51 @@ import org.apache.poi.ss.util.CellRefere
  * @author Josh Micich
  */
 public interface FormulaParsingWorkbook {
-	/**
-	 *  named range name matching is case insensitive
-	 */
-	EvaluationName getName(String name, int sheetIndex);
-	
-	/**
-	 * Return the underlying workbook
-	 */
-	Name createName();
+    /**
+     *  named range name matching is case insensitive
+     */
+    EvaluationName getName(String name, int sheetIndex);
+    
+    /**
+     * Return the underlying workbook
+     */
+    Name createName();
 
-	/**
-	 * XSSF Only - gets a table that exists in the worksheet
-	 */
-	Table getTable(String name);
-	
-	/**
-	 * Return an external name (named range, function, user-defined function) Ptg
-	 */
-	Ptg getNameXPtg(String name, SheetIdentifier sheet);
-	
-	/**
-	 * Produce the appropriate Ptg for a 3d cell reference
-	 */
-	Ptg get3DReferencePtg(CellReference cell, SheetIdentifier sheet);
+    /**
+     * XSSF Only - gets a table that exists in the worksheet
+     */
+    Table getTable(String name);
+    
+    /**
+     * Return an external name (named range, function, user-defined function) Ptg
+     */
+    Ptg getNameXPtg(String name, SheetIdentifier sheet);
+    
+    /**
+     * Produce the appropriate Ptg for a 3d cell reference
+     */
+    Ptg get3DReferencePtg(CellReference cell, SheetIdentifier sheet);
 
     /**
      * Produce the appropriate Ptg for a 3d area reference
      */
     Ptg get3DReferencePtg(AreaReference area, SheetIdentifier sheet);
 
-	/**
-	 * gets the externSheet index for a sheet from this workbook
-	 */
-	int getExternalSheetIndex(String sheetName);
-	/**
-	 * gets the externSheet index for a sheet from an external workbook
-	 * @param workbookName e.g. "Budget.xls"
-	 * @param sheetName a name of a sheet in that workbook
-	 */
-	int getExternalSheetIndex(String workbookName, String sheetName);
+    /**
+     * gets the externSheet index for a sheet from this workbook
+     */
+    int getExternalSheetIndex(String sheetName);
+    /**
+     * gets the externSheet index for a sheet from an external workbook
+     * @param workbookName e.g. "Budget.xls"
+     * @param sheetName a name of a sheet in that workbook
+     */
+    int getExternalSheetIndex(String workbookName, String sheetName);
 
-	/**
-	 * Returns an enum holding spreadhseet properties specific to an Excel version (
-	 * max column and row numbers, max arguments to a function, etc.)
-	 */
-	SpreadsheetVersion getSpreadsheetVersion();
+    /**
+     * Returns an enum holding spreadhseet properties specific to an Excel version (
+     * max column and row numbers, max arguments to a function, etc.)
+     */
+    SpreadsheetVersion getSpreadsheetVersion();
 
 }

Modified: poi/branches/xssf_structured_references/src/java/org/apache/poi/ss/formula/OperationEvaluationContext.java
URL: http://svn.apache.org/viewvc/poi/branches/xssf_structured_references/src/java/org/apache/poi/ss/formula/OperationEvaluationContext.java?rev=1747625&r1=1747624&r2=1747625&view=diff
==============================================================================
--- poi/branches/xssf_structured_references/src/java/org/apache/poi/ss/formula/OperationEvaluationContext.java (original)
+++ poi/branches/xssf_structured_references/src/java/org/apache/poi/ss/formula/OperationEvaluationContext.java Fri Jun 10 02:51:45 2016
@@ -46,199 +46,199 @@ import org.apache.poi.ss.util.CellRefere
  * For POI internal use only
  */
 public final class OperationEvaluationContext {
-	public static final FreeRefFunction UDF = UserDefinedFunction.instance;
-	private final EvaluationWorkbook _workbook;
-	private final int _sheetIndex;
-	private final int _rowIndex;
-	private final int _columnIndex;
-	private final EvaluationTracker _tracker;
-	private final WorkbookEvaluator _bookEvaluator;
-
-	public OperationEvaluationContext(WorkbookEvaluator bookEvaluator, EvaluationWorkbook workbook, int sheetIndex, int srcRowNum,
-			int srcColNum, EvaluationTracker tracker) {
-		_bookEvaluator = bookEvaluator;
-		_workbook = workbook;
-		_sheetIndex = sheetIndex;
-		_rowIndex = srcRowNum;
-		_columnIndex = srcColNum;
-		_tracker = tracker;
-	}
-
-	public EvaluationWorkbook getWorkbook() {
-		return _workbook;
-	}
-
-	public int getRowIndex() {
-		return _rowIndex;
-	}
-
-	public int getColumnIndex() {
-		return _columnIndex;
-	}
-
-	SheetRangeEvaluator createExternSheetRefEvaluator(ExternSheetReferenceToken ptg) {
-		return createExternSheetRefEvaluator(ptg.getExternSheetIndex());
-	}
-	SheetRangeEvaluator createExternSheetRefEvaluator(String firstSheetName, String lastSheetName, int externalWorkbookNumber) {
+    public static final FreeRefFunction UDF = UserDefinedFunction.instance;
+    private final EvaluationWorkbook _workbook;
+    private final int _sheetIndex;
+    private final int _rowIndex;
+    private final int _columnIndex;
+    private final EvaluationTracker _tracker;
+    private final WorkbookEvaluator _bookEvaluator;
+
+    public OperationEvaluationContext(WorkbookEvaluator bookEvaluator, EvaluationWorkbook workbook, int sheetIndex, int srcRowNum,
+            int srcColNum, EvaluationTracker tracker) {
+        _bookEvaluator = bookEvaluator;
+        _workbook = workbook;
+        _sheetIndex = sheetIndex;
+        _rowIndex = srcRowNum;
+        _columnIndex = srcColNum;
+        _tracker = tracker;
+    }
+
+    public EvaluationWorkbook getWorkbook() {
+        return _workbook;
+    }
+
+    public int getRowIndex() {
+        return _rowIndex;
+    }
+
+    public int getColumnIndex() {
+        return _columnIndex;
+    }
+
+    SheetRangeEvaluator createExternSheetRefEvaluator(ExternSheetReferenceToken ptg) {
+        return createExternSheetRefEvaluator(ptg.getExternSheetIndex());
+    }
+    SheetRangeEvaluator createExternSheetRefEvaluator(String firstSheetName, String lastSheetName, int externalWorkbookNumber) {
         ExternalSheet externalSheet = _workbook.getExternalSheet(firstSheetName, lastSheetName, externalWorkbookNumber);
         return createExternSheetRefEvaluator(externalSheet);
     }
-	SheetRangeEvaluator createExternSheetRefEvaluator(int externSheetIndex) {
-		ExternalSheet externalSheet = _workbook.getExternalSheet(externSheetIndex);
+    SheetRangeEvaluator createExternSheetRefEvaluator(int externSheetIndex) {
+        ExternalSheet externalSheet = _workbook.getExternalSheet(externSheetIndex);
         return createExternSheetRefEvaluator(externalSheet);
-	}
-	SheetRangeEvaluator createExternSheetRefEvaluator(ExternalSheet externalSheet) {
-		WorkbookEvaluator targetEvaluator;
-		int otherFirstSheetIndex;
-		int otherLastSheetIndex = -1;
-		if (externalSheet == null || externalSheet.getWorkbookName() == null) {
-			// sheet is in same workbook
-			targetEvaluator = _bookEvaluator;
-			if(externalSheet == null) {
-			    otherFirstSheetIndex = 0;
-			} else {
-			    otherFirstSheetIndex = _workbook.getSheetIndex(externalSheet.getSheetName());
-			}
-			
-			if (externalSheet instanceof ExternalSheetRange) {
-			    String lastSheetName = ((ExternalSheetRange)externalSheet).getLastSheetName();
-			    otherLastSheetIndex = _workbook.getSheetIndex(lastSheetName);
-			}
-		} else {
-			// look up sheet by name from external workbook
-			String workbookName = externalSheet.getWorkbookName();
-			try {
-				targetEvaluator = _bookEvaluator.getOtherWorkbookEvaluator(workbookName);
-			} catch (WorkbookNotFoundException e) {
-				throw new RuntimeException(e.getMessage(), e);
-			}
-			
-			otherFirstSheetIndex = targetEvaluator.getSheetIndex(externalSheet.getSheetName());
+    }
+    SheetRangeEvaluator createExternSheetRefEvaluator(ExternalSheet externalSheet) {
+        WorkbookEvaluator targetEvaluator;
+        int otherFirstSheetIndex;
+        int otherLastSheetIndex = -1;
+        if (externalSheet == null || externalSheet.getWorkbookName() == null) {
+            // sheet is in same workbook
+            targetEvaluator = _bookEvaluator;
+            if(externalSheet == null) {
+                otherFirstSheetIndex = 0;
+            } else {
+                otherFirstSheetIndex = _workbook.getSheetIndex(externalSheet.getSheetName());
+            }
+            
+            if (externalSheet instanceof ExternalSheetRange) {
+                String lastSheetName = ((ExternalSheetRange)externalSheet).getLastSheetName();
+                otherLastSheetIndex = _workbook.getSheetIndex(lastSheetName);
+            }
+        } else {
+            // look up sheet by name from external workbook
+            String workbookName = externalSheet.getWorkbookName();
+            try {
+                targetEvaluator = _bookEvaluator.getOtherWorkbookEvaluator(workbookName);
+            } catch (WorkbookNotFoundException e) {
+                throw new RuntimeException(e.getMessage(), e);
+            }
+            
+            otherFirstSheetIndex = targetEvaluator.getSheetIndex(externalSheet.getSheetName());
             if (externalSheet instanceof ExternalSheetRange) {
                 String lastSheetName = ((ExternalSheetRange)externalSheet).getLastSheetName();
                 otherLastSheetIndex = targetEvaluator.getSheetIndex(lastSheetName);
             }
-			
-			if (otherFirstSheetIndex < 0) {
-				throw new RuntimeException("Invalid sheet name '" + externalSheet.getSheetName()
-						+ "' in bool '" + workbookName + "'.");
-			}
-		}
-		
-		if (otherLastSheetIndex == -1) {
-		    // Reference to just one sheet
-		    otherLastSheetIndex = otherFirstSheetIndex;
-		}
-		
-		SheetRefEvaluator[] evals = new SheetRefEvaluator[otherLastSheetIndex-otherFirstSheetIndex+1];
-		for (int i=0; i<evals.length; i++) {
-		    int otherSheetIndex = i+otherFirstSheetIndex;
-		    evals[i] = new SheetRefEvaluator(targetEvaluator, _tracker, otherSheetIndex); 
-		}
-		return new SheetRangeEvaluator(otherFirstSheetIndex, otherLastSheetIndex, evals);
-	}
-
-	/**
-	 * @return <code>null</code> if either workbook or sheet is not found
-	 */
-	private SheetRefEvaluator createExternSheetRefEvaluator(String workbookName, String sheetName) {
-		WorkbookEvaluator targetEvaluator;
-		if (workbookName == null) {
-			targetEvaluator = _bookEvaluator;
-		} else {
-			if (sheetName == null) {
-				throw new IllegalArgumentException("sheetName must not be null if workbookName is provided");
-			}
-			try {
-				targetEvaluator = _bookEvaluator.getOtherWorkbookEvaluator(workbookName);
-			} catch (WorkbookNotFoundException e) {
-				return null;
-			}
-		}
-		int otherSheetIndex = sheetName == null ? _sheetIndex : targetEvaluator.getSheetIndex(sheetName);
-		if (otherSheetIndex < 0) {
-			return null;
-		}
-		return new SheetRefEvaluator(targetEvaluator, _tracker, otherSheetIndex);
-	}
-
-	public SheetRangeEvaluator getRefEvaluatorForCurrentSheet() {
-		SheetRefEvaluator sre = new SheetRefEvaluator(_bookEvaluator, _tracker, _sheetIndex);
-		return new SheetRangeEvaluator(_sheetIndex, sre);
-	}
-
-
-
-	/**
-	 * Resolves a cell or area reference dynamically.
-	 * @param workbookName the name of the workbook containing the reference.  If <code>null</code>
-	 * the current workbook is assumed.  Note - to evaluate formulas which use multiple workbooks,
-	 * a {@link CollaboratingWorkbooksEnvironment} must be set up.
-	 * @param sheetName the name of the sheet containing the reference.  May be <code>null</code>
-	 * (when <tt>workbookName</tt> is also null) in which case the current workbook and sheet is
-	 * assumed.
-	 * @param refStrPart1 the single cell reference or first part of the area reference.  Must not
-	 * be <code>null</code>.
-	 * @param refStrPart2 the second part of the area reference. For single cell references this
-	 * parameter must be <code>null</code>
-	 * @param isA1Style specifies the format for <tt>refStrPart1</tt> and <tt>refStrPart2</tt>.
-	 * Pass <code>true</code> for 'A1' style and <code>false</code> for 'R1C1' style.
-	 * TODO - currently POI only supports 'A1' reference style
-	 * @return a {@link RefEval} or {@link AreaEval}
-	 */
-	public ValueEval getDynamicReference(String workbookName, String sheetName, String refStrPart1,
-			String refStrPart2, boolean isA1Style) {
-		if (!isA1Style) {
-			throw new RuntimeException("R1C1 style not supported yet");
-		}
-		SheetRefEvaluator se = createExternSheetRefEvaluator(workbookName, sheetName);
-		if (se == null) {
-			return ErrorEval.REF_INVALID;
-		}
-		SheetRangeEvaluator sre = new SheetRangeEvaluator(_sheetIndex, se);
-		
-		// ugly typecast - TODO - make spreadsheet version more easily accessible
-		SpreadsheetVersion ssVersion = ((FormulaParsingWorkbook)_workbook).getSpreadsheetVersion();
-
-		NameType part1refType = classifyCellReference(refStrPart1, ssVersion);
-		switch (part1refType) {
-			case BAD_CELL_OR_NAMED_RANGE:
-				return ErrorEval.REF_INVALID;
-			case NAMED_RANGE:
+            
+            if (otherFirstSheetIndex < 0) {
+                throw new RuntimeException("Invalid sheet name '" + externalSheet.getSheetName()
+                        + "' in bool '" + workbookName + "'.");
+            }
+        }
+        
+        if (otherLastSheetIndex == -1) {
+            // Reference to just one sheet
+            otherLastSheetIndex = otherFirstSheetIndex;
+        }
+        
+        SheetRefEvaluator[] evals = new SheetRefEvaluator[otherLastSheetIndex-otherFirstSheetIndex+1];
+        for (int i=0; i<evals.length; i++) {
+            int otherSheetIndex = i+otherFirstSheetIndex;
+            evals[i] = new SheetRefEvaluator(targetEvaluator, _tracker, otherSheetIndex); 
+        }
+        return new SheetRangeEvaluator(otherFirstSheetIndex, otherLastSheetIndex, evals);
+    }
+
+    /**
+     * @return <code>null</code> if either workbook or sheet is not found
+     */
+    private SheetRefEvaluator createExternSheetRefEvaluator(String workbookName, String sheetName) {
+        WorkbookEvaluator targetEvaluator;
+        if (workbookName == null) {
+            targetEvaluator = _bookEvaluator;
+        } else {
+            if (sheetName == null) {
+                throw new IllegalArgumentException("sheetName must not be null if workbookName is provided");
+            }
+            try {
+                targetEvaluator = _bookEvaluator.getOtherWorkbookEvaluator(workbookName);
+            } catch (WorkbookNotFoundException e) {
+                return null;
+            }
+        }
+        int otherSheetIndex = sheetName == null ? _sheetIndex : targetEvaluator.getSheetIndex(sheetName);
+        if (otherSheetIndex < 0) {
+            return null;
+        }
+        return new SheetRefEvaluator(targetEvaluator, _tracker, otherSheetIndex);
+    }
+
+    public SheetRangeEvaluator getRefEvaluatorForCurrentSheet() {
+        SheetRefEvaluator sre = new SheetRefEvaluator(_bookEvaluator, _tracker, _sheetIndex);
+        return new SheetRangeEvaluator(_sheetIndex, sre);
+    }
+
+
+
+    /**
+     * Resolves a cell or area reference dynamically.
+     * @param workbookName the name of the workbook containing the reference.  If <code>null</code>
+     * the current workbook is assumed.  Note - to evaluate formulas which use multiple workbooks,
+     * a {@link CollaboratingWorkbooksEnvironment} must be set up.
+     * @param sheetName the name of the sheet containing the reference.  May be <code>null</code>
+     * (when <tt>workbookName</tt> is also null) in which case the current workbook and sheet is
+     * assumed.
+     * @param refStrPart1 the single cell reference or first part of the area reference.  Must not
+     * be <code>null</code>.
+     * @param refStrPart2 the second part of the area reference. For single cell references this
+     * parameter must be <code>null</code>
+     * @param isA1Style specifies the format for <tt>refStrPart1</tt> and <tt>refStrPart2</tt>.
+     * Pass <code>true</code> for 'A1' style and <code>false</code> for 'R1C1' style.
+     * TODO - currently POI only supports 'A1' reference style
+     * @return a {@link RefEval} or {@link AreaEval}
+     */
+    public ValueEval getDynamicReference(String workbookName, String sheetName, String refStrPart1,
+            String refStrPart2, boolean isA1Style) {
+        if (!isA1Style) {
+            throw new RuntimeException("R1C1 style not supported yet");
+        }
+        SheetRefEvaluator se = createExternSheetRefEvaluator(workbookName, sheetName);
+        if (se == null) {
+            return ErrorEval.REF_INVALID;
+        }
+        SheetRangeEvaluator sre = new SheetRangeEvaluator(_sheetIndex, se);
+        
+        // ugly typecast - TODO - make spreadsheet version more easily accessible
+        SpreadsheetVersion ssVersion = ((FormulaParsingWorkbook)_workbook).getSpreadsheetVersion();
+
+        NameType part1refType = classifyCellReference(refStrPart1, ssVersion);
+        switch (part1refType) {
+            case BAD_CELL_OR_NAMED_RANGE:
+                return ErrorEval.REF_INVALID;
+            case NAMED_RANGE:
                 EvaluationName nm = ((FormulaParsingWorkbook)_workbook).getName(refStrPart1, _sheetIndex);
                 if(!nm.isRange()){
                     throw new RuntimeException("Specified name '" + refStrPart1 + "' is not a range as expected.");
                 }
                 return _bookEvaluator.evaluateNameFormula(nm.getNameDefinition(), this);
-		}
-		if (refStrPart2 == null) {
-			// no ':'
-			switch (part1refType) {
-				case COLUMN:
-				case ROW:
-					return ErrorEval.REF_INVALID;
-				case CELL:
-					CellReference cr = new CellReference(refStrPart1);
-					return new LazyRefEval(cr.getRow(), cr.getCol(), sre);
-			}
-			throw new IllegalStateException("Unexpected reference classification of '" + refStrPart1 + "'.");
-		}
-		NameType part2refType = classifyCellReference(refStrPart1, ssVersion);
-		switch (part2refType) {
-			case BAD_CELL_OR_NAMED_RANGE:
-				return ErrorEval.REF_INVALID;
-			case NAMED_RANGE:
-				throw new RuntimeException("Cannot evaluate '" + refStrPart1
-						+ "'. Indirect evaluation of defined names not supported yet");
-		}
-
-		if (part2refType != part1refType) {
-			// LHS and RHS of ':' must be compatible
-			return ErrorEval.REF_INVALID;
-		}
-		int firstRow, firstCol, lastRow, lastCol;
-		switch (part1refType) {
-			case COLUMN:
+        }
+        if (refStrPart2 == null) {
+            // no ':'
+            switch (part1refType) {
+                case COLUMN:
+                case ROW:
+                    return ErrorEval.REF_INVALID;
+                case CELL:
+                    CellReference cr = new CellReference(refStrPart1);
+                    return new LazyRefEval(cr.getRow(), cr.getCol(), sre);
+            }
+            throw new IllegalStateException("Unexpected reference classification of '" + refStrPart1 + "'.");
+        }
+        NameType part2refType = classifyCellReference(refStrPart1, ssVersion);
+        switch (part2refType) {
+            case BAD_CELL_OR_NAMED_RANGE:
+                return ErrorEval.REF_INVALID;
+            case NAMED_RANGE:
+                throw new RuntimeException("Cannot evaluate '" + refStrPart1
+                        + "'. Indirect evaluation of defined names not supported yet");
+        }
+
+        if (part2refType != part1refType) {
+            // LHS and RHS of ':' must be compatible
+            return ErrorEval.REF_INVALID;
+        }
+        int firstRow, firstCol, lastRow, lastCol;
+        switch (part1refType) {
+            case COLUMN:
                 firstRow =0;
                 if (part2refType.equals(NameType.COLUMN))
                 {
@@ -252,7 +252,7 @@ public final class OperationEvaluationCo
                     lastCol = parseColRef(refStrPart2);
                 }
                 break;
-			case ROW:
+            case ROW:
                 // support of cell range in the form of integer:integer
                 firstCol = 0;
                 if (part2refType.equals(NameType.ROW))
@@ -265,61 +265,61 @@ public final class OperationEvaluationCo
                     firstRow = parseRowRef(refStrPart1);
                     lastRow = parseRowRef(refStrPart2);
                 }
-				break;
-			case CELL:
-				CellReference cr;
-				cr = new CellReference(refStrPart1);
-				firstRow = cr.getRow();
-				firstCol = cr.getCol();
-				cr = new CellReference(refStrPart2);
-				lastRow = cr.getRow();
-				lastCol = cr.getCol();
-				break;
-			default:
-				throw new IllegalStateException("Unexpected reference classification of '" + refStrPart1 + "'.");
-		}
-		return new LazyAreaEval(firstRow, firstCol, lastRow, lastCol, sre);
-	}
-
-	private static int parseRowRef(String refStrPart) {
-		return CellReference.convertColStringToIndex(refStrPart);
-	}
-
-	private static int parseColRef(String refStrPart) {
-		return Integer.parseInt(refStrPart) - 1;
-	}
-
-	private static NameType classifyCellReference(String str, SpreadsheetVersion ssVersion) {
-		int len = str.length();
-		if (len < 1) {
-			return CellReference.NameType.BAD_CELL_OR_NAMED_RANGE;
-		}
-		return CellReference.classifyCellReference(str, ssVersion);
-	}
-
-	public FreeRefFunction findUserDefinedFunction(String functionName) {
-		return _bookEvaluator.findUserDefinedFunction(functionName);
-	}
-
-	public ValueEval getRefEval(int rowIndex, int columnIndex) {
-	    SheetRangeEvaluator sre = getRefEvaluatorForCurrentSheet();
-		return new LazyRefEval(rowIndex, columnIndex, sre);
-	}
-	public ValueEval getRef3DEval(Ref3DPtg rptg) {
-	    SheetRangeEvaluator sre = createExternSheetRefEvaluator(rptg.getExternSheetIndex());
-		return new LazyRefEval(rptg.getRow(), rptg.getColumn(), sre);
-	}
+                break;
+            case CELL:
+                CellReference cr;
+                cr = new CellReference(refStrPart1);
+                firstRow = cr.getRow();
+                firstCol = cr.getCol();
+                cr = new CellReference(refStrPart2);
+                lastRow = cr.getRow();
+                lastCol = cr.getCol();
+                break;
+            default:
+                throw new IllegalStateException("Unexpected reference classification of '" + refStrPart1 + "'.");
+        }
+        return new LazyAreaEval(firstRow, firstCol, lastRow, lastCol, sre);
+    }
+
+    private static int parseRowRef(String refStrPart) {
+        return CellReference.convertColStringToIndex(refStrPart);
+    }
+
+    private static int parseColRef(String refStrPart) {
+        return Integer.parseInt(refStrPart) - 1;
+    }
+
+    private static NameType classifyCellReference(String str, SpreadsheetVersion ssVersion) {
+        int len = str.length();
+        if (len < 1) {
+            return CellReference.NameType.BAD_CELL_OR_NAMED_RANGE;
+        }
+        return CellReference.classifyCellReference(str, ssVersion);
+    }
+
+    public FreeRefFunction findUserDefinedFunction(String functionName) {
+        return _bookEvaluator.findUserDefinedFunction(functionName);
+    }
+
+    public ValueEval getRefEval(int rowIndex, int columnIndex) {
+        SheetRangeEvaluator sre = getRefEvaluatorForCurrentSheet();
+        return new LazyRefEval(rowIndex, columnIndex, sre);
+    }
+    public ValueEval getRef3DEval(Ref3DPtg rptg) {
+        SheetRangeEvaluator sre = createExternSheetRefEvaluator(rptg.getExternSheetIndex());
+        return new LazyRefEval(rptg.getRow(), rptg.getColumn(), sre);
+    }
     public ValueEval getRef3DEval(Ref3DPxg rptg) {
         SheetRangeEvaluator sre = createExternSheetRefEvaluator(
                 rptg.getSheetName(), rptg.getLastSheetName(), rptg.getExternalWorkbookNumber());
         return new LazyRefEval(rptg.getRow(), rptg.getColumn(), sre);
     }
     
-	public ValueEval getAreaEval(int firstRowIndex, int firstColumnIndex,
-			int lastRowIndex, int lastColumnIndex) {
-	    SheetRangeEvaluator sre = getRefEvaluatorForCurrentSheet();
-		return new LazyAreaEval(firstRowIndex, firstColumnIndex, lastRowIndex, lastColumnIndex, sre);
-	}
+    public ValueEval getAreaEval(int firstRowIndex, int firstColumnIndex,
+            int lastRowIndex, int lastColumnIndex) {
+        SheetRangeEvaluator sre = getRefEvaluatorForCurrentSheet();
+        return new LazyAreaEval(firstRowIndex, firstColumnIndex, lastRowIndex, lastColumnIndex, sre);
+    }
     public ValueEval getArea3DEval(Area3DPtg aptg) {
         SheetRangeEvaluator sre = createExternSheetRefEvaluator(aptg.getExternSheetIndex());
         return new LazyAreaEval(aptg.getFirstRow(), aptg.getFirstColumn(),
@@ -348,8 +348,8 @@ public final class OperationEvaluationCo
         );
         return getExternalNameXEval(externName, workbookName);
     }
-	public ValueEval getNameXEval(NameXPxg nameXPxg) {
-	    ExternalSheet externSheet = _workbook.getExternalSheet(nameXPxg.getSheetName(), null, nameXPxg.getExternalWorkbookNumber());
+    public ValueEval getNameXEval(NameXPxg nameXPxg) {
+        ExternalSheet externSheet = _workbook.getExternalSheet(nameXPxg.getSheetName(), null, nameXPxg.getExternalWorkbookNumber());
         if(externSheet == null || externSheet.getWorkbookName() == null) {
             // External reference to our own workbook's name
             return getLocalNameXEval(nameXPxg);
@@ -363,8 +363,8 @@ public final class OperationEvaluationCo
               nameXPxg.getExternalWorkbookNumber()
         );
         return getExternalNameXEval(externName, workbookName);
-	}
-	
+    }
+    
     private ValueEval getLocalNameXEval(NameXPxg nameXPxg) {
         // Look up the sheet, if present
         int sIdx = -1;
@@ -383,7 +383,7 @@ public final class OperationEvaluationCo
             return new FunctionNameEval(name);
         }
     }
-	private ValueEval getLocalNameXEval(NameXPtg nameXPtg) {
+    private ValueEval getLocalNameXEval(NameXPtg nameXPtg) {
         String name = _workbook.resolveNameXText(nameXPtg);
         
         // Try to parse it as a name
@@ -406,11 +406,11 @@ public final class OperationEvaluationCo
             // Must be an external function
             return new FunctionNameEval(name);
         }
-	}
-	public int getSheetIndex() {
-	    return _sheetIndex;
-	}
-	
+    }
+    public int getSheetIndex() {
+        return _sheetIndex;
+    }
+    
     private ValueEval getExternalNameXEval(ExternalName externName, String workbookName) {
         try {
             // Fetch the workbook this refers to, and the name as defined with that

Modified: poi/branches/xssf_structured_references/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java
URL: http://svn.apache.org/viewvc/poi/branches/xssf_structured_references/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java?rev=1747625&r1=1747624&r2=1747625&view=diff
==============================================================================
--- poi/branches/xssf_structured_references/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java (original)
+++ poi/branches/xssf_structured_references/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java Fri Jun 10 02:51:45 2016
@@ -93,39 +93,39 @@ import org.apache.poi.util.POILogger;
  * @author Thies Wellpott (debug output enhancements)
  */
 public final class WorkbookEvaluator {
-	
-	private static final POILogger LOG = POILogFactory.getLogger(WorkbookEvaluator.class);
+    
+    private static final POILogger LOG = POILogFactory.getLogger(WorkbookEvaluator.class);
 
     private final EvaluationWorkbook _workbook;
-	private EvaluationCache _cache;
-	/** part of cache entry key (useful when evaluating multiple workbooks) */
-	private int _workbookIx;
-
-	private final IEvaluationListener _evaluationListener;
-	private final Map<EvaluationSheet, Integer> _sheetIndexesBySheet;
-	private final Map<String, Integer> _sheetIndexesByName;
-	private CollaboratingWorkbooksEnvironment _collaboratingWorkbookEnvironment;
-	private final IStabilityClassifier _stabilityClassifier;
-	private final AggregatingUDFFinder _udfFinder;
+    private EvaluationCache _cache;
+    /** part of cache entry key (useful when evaluating multiple workbooks) */
+    private int _workbookIx;
+
+    private final IEvaluationListener _evaluationListener;
+    private final Map<EvaluationSheet, Integer> _sheetIndexesBySheet;
+    private final Map<String, Integer> _sheetIndexesByName;
+    private CollaboratingWorkbooksEnvironment _collaboratingWorkbookEnvironment;
+    private final IStabilityClassifier _stabilityClassifier;
+    private final AggregatingUDFFinder _udfFinder;
 
     private boolean _ignoreMissingWorkbooks = false;
 
-	/**
-	 * @param udfFinder pass <code>null</code> for default (AnalysisToolPak only)
-	 */
-	public WorkbookEvaluator(EvaluationWorkbook workbook, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) {
-		this (workbook, null, stabilityClassifier, udfFinder);
-	}
-	/* package */ WorkbookEvaluator(EvaluationWorkbook workbook, IEvaluationListener evaluationListener,
-			IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) {
-		_workbook = workbook;
-		_evaluationListener = evaluationListener;
-		_cache = new EvaluationCache(evaluationListener);
-		_sheetIndexesBySheet = new IdentityHashMap<EvaluationSheet, Integer>();
-		_sheetIndexesByName = new IdentityHashMap<String, Integer>();
-		_collaboratingWorkbookEnvironment = CollaboratingWorkbooksEnvironment.EMPTY;
-		_workbookIx = 0;
-		_stabilityClassifier = stabilityClassifier;
+    /**
+     * @param udfFinder pass <code>null</code> for default (AnalysisToolPak only)
+     */
+    public WorkbookEvaluator(EvaluationWorkbook workbook, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) {
+        this (workbook, null, stabilityClassifier, udfFinder);
+    }
+    /* package */ WorkbookEvaluator(EvaluationWorkbook workbook, IEvaluationListener evaluationListener,
+            IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) {
+        _workbook = workbook;
+        _evaluationListener = evaluationListener;
+        _cache = new EvaluationCache(evaluationListener);
+        _sheetIndexesBySheet = new IdentityHashMap<EvaluationSheet, Integer>();
+        _sheetIndexesByName = new IdentityHashMap<String, Integer>();
+        _collaboratingWorkbookEnvironment = CollaboratingWorkbooksEnvironment.EMPTY;
+        _workbookIx = 0;
+        _stabilityClassifier = stabilityClassifier;
 
         AggregatingUDFFinder defaultToolkit = // workbook can be null in unit tests
                 workbook == null ? null : (AggregatingUDFFinder)workbook.getUDFFinder();
@@ -133,501 +133,501 @@ public final class WorkbookEvaluator {
             defaultToolkit.add(udfFinder);
         }
         _udfFinder = defaultToolkit;
-	}
+    }
+
+    /**
+     * also for debug use. Used in toString methods
+     */
+    /* package */ String getSheetName(int sheetIndex) {
+        return _workbook.getSheetName(sheetIndex);
+    }
+
+    /* package */ EvaluationSheet getSheet(int sheetIndex) {
+        return _workbook.getSheet(sheetIndex);
+    }
+    
+    /* package */ EvaluationWorkbook getWorkbook() {
+        return _workbook;
+    }
+
+    /* package */ EvaluationName getName(String name, int sheetIndex) {
+        EvaluationName evalName = _workbook.getName(name, sheetIndex);
+        return evalName;
+    }
+
+    private static boolean isDebugLogEnabled() {
+        return LOG.check(POILogger.DEBUG);
+    }
+    private static boolean isInfoLogEnabled() {
+        return LOG.check(POILogger.INFO);
+    }
+    private static void logDebug(String s) {
+        if (isDebugLogEnabled()) {
+            LOG.log(POILogger.DEBUG, s);
+        }
+    }
+    private static void logInfo(String s) {
+        if (isInfoLogEnabled()) {
+            LOG.log(POILogger.INFO, s);
+        }
+    }
+    /* package */ void attachToEnvironment(CollaboratingWorkbooksEnvironment collaboratingWorkbooksEnvironment, EvaluationCache cache, int workbookIx) {
+        _collaboratingWorkbookEnvironment = collaboratingWorkbooksEnvironment;
+        _cache = cache;
+        _workbookIx = workbookIx;
+    }
+    /* package */ CollaboratingWorkbooksEnvironment getEnvironment() {
+        return _collaboratingWorkbookEnvironment;
+    }
+
+    /**
+     * Discards the current workbook environment and attaches to the default 'empty' environment.
+     * Also resets evaluation cache.
+     */
+    /* package */ void detachFromEnvironment() {
+        _collaboratingWorkbookEnvironment = CollaboratingWorkbooksEnvironment.EMPTY;
+        _cache = new EvaluationCache(_evaluationListener);
+        _workbookIx = 0;
+    }
+    /**
+     * @return the evaluator for another workbook which is part of the same {@link CollaboratingWorkbooksEnvironment}
+     */
+    /* package */ WorkbookEvaluator getOtherWorkbookEvaluator(String workbookName) throws WorkbookNotFoundException {
+        return _collaboratingWorkbookEnvironment.getWorkbookEvaluator(workbookName);
+    }
+
+    /* package */ IEvaluationListener getEvaluationListener() {
+        return _evaluationListener;
+    }
+
+    /**
+     * Should be called whenever there are changes to input cells in the evaluated workbook.
+     * Failure to call this method after changing cell values will cause incorrect behaviour
+     * of the evaluate~ methods of this class
+     */
+    public void clearAllCachedResultValues() {
+        _cache.clear();
+        _sheetIndexesBySheet.clear();
+    }
+
+    /**
+     * Should be called to tell the cell value cache that the specified (value or formula) cell
+     * has changed.
+     */
+    public void notifyUpdateCell(EvaluationCell cell) {
+        int sheetIndex = getSheetIndex(cell.getSheet());
+        _cache.notifyUpdateCell(_workbookIx, sheetIndex, cell);
+    }
+    /**
+     * Should be called to tell the cell value cache that the specified cell has just been
+     * deleted.
+     */
+    public void notifyDeleteCell(EvaluationCell cell) {
+        int sheetIndex = getSheetIndex(cell.getSheet());
+        _cache.notifyDeleteCell(_workbookIx, sheetIndex, cell);
+    }
+    
+    private int getSheetIndex(EvaluationSheet sheet) {
+        Integer result = _sheetIndexesBySheet.get(sheet);
+        if (result == null) {
+            int sheetIndex = _workbook.getSheetIndex(sheet);
+            if (sheetIndex < 0) {
+                throw new RuntimeException("Specified sheet from a different book");
+            }
+            result = Integer.valueOf(sheetIndex);
+            _sheetIndexesBySheet.put(sheet, result);
+        }
+        return result.intValue();
+    }
+
+    public ValueEval evaluate(EvaluationCell srcCell) {
+        int sheetIndex = getSheetIndex(srcCell.getSheet());
+        return evaluateAny(srcCell, sheetIndex, srcCell.getRowIndex(), srcCell.getColumnIndex(), new EvaluationTracker(_cache));
+    }
+
+    /**
+     * Case-insensitive.
+     * @return -1 if sheet with specified name does not exist
+     */
+    /* package */ int getSheetIndex(String sheetName) {
+        Integer result = _sheetIndexesByName.get(sheetName);
+        if (result == null) {
+            int sheetIndex = _workbook.getSheetIndex(sheetName);
+            if (sheetIndex < 0) {
+                return -1;
+            }
+            result = Integer.valueOf(sheetIndex);
+            _sheetIndexesByName.put(sheetName, result);
+        }
+        return result.intValue();
+    }
+    
+    /* package */ int getSheetIndexByExternIndex(int externSheetIndex) {
+       return _workbook.convertFromExternSheetIndex(externSheetIndex);
+    }
+
+
+    /**
+     * @return never <code>null</code>, never {@link BlankEval}
+     */
+    private ValueEval evaluateAny(EvaluationCell srcCell, int sheetIndex,
+                int rowIndex, int columnIndex, EvaluationTracker tracker) {
+
+        // avoid tracking dependencies to cells that have constant definition
+        boolean shouldCellDependencyBeRecorded = _stabilityClassifier == null ? true
+                    : !_stabilityClassifier.isCellFinal(sheetIndex, rowIndex, columnIndex);
+        if (srcCell == null || srcCell.getCellType() != Cell.CELL_TYPE_FORMULA) {
+            ValueEval result = getValueFromNonFormulaCell(srcCell);
+            if (shouldCellDependencyBeRecorded) {
+                tracker.acceptPlainValueDependency(_workbookIx, sheetIndex, rowIndex, columnIndex, result);
+            }
+            return result;
+        }
+
+        FormulaCellCacheEntry cce = _cache.getOrCreateFormulaCellEntry(srcCell);
+        if (shouldCellDependencyBeRecorded || cce.isInputSensitive()) {
+            tracker.acceptFormulaDependency(cce);
+        }
+        IEvaluationListener evalListener = _evaluationListener;
+        ValueEval result;
+        if (cce.getValue() == null) {
+            if (!tracker.startEvaluate(cce)) {
+                return ErrorEval.CIRCULAR_REF_ERROR;
+            }
+            OperationEvaluationContext ec = new OperationEvaluationContext(this, _workbook, sheetIndex, rowIndex, columnIndex, tracker);
+
+            try {
+
+                Ptg[] ptgs = _workbook.getFormulaTokens(srcCell);
+//                System.out.println("=====");
+//                XSSFCell c = ((XSSFEvaluationCell)srcCell).getXSSFCell();
+//                System.out.println("Formula is "+ c);
+//                System.out.println("The cell is " + c.getSheet().getSheetName()+"!"+c.getReference());
+//                System.out.println("Evaluation tokens : ");  // TODO Dlivshen remove
+//                for (Ptg ptg : ptgs) {  // TODO Dlivshen remove
+//                    System.out.println(ptg);  // TODO Dlivshen remove
+//                } // TODO Dlivshen remove
+//                System.out.println("======"); // TODO Dlivshen remove
+                if (evalListener == null) {
+                    result = evaluateFormula(ec, ptgs);
+                } else {
+                    evalListener.onStartEvaluate(srcCell, cce);
+                    result = evaluateFormula(ec, ptgs);
+                    evalListener.onEndEvaluate(cce, result);
+                }
+
+                tracker.updateCacheResult(result);
+            }
+             catch (NotImplementedException e) {
+                throw addExceptionInfo(e,  sheetIndex, rowIndex, columnIndex);
+             } catch (RuntimeException re) {
+                 if (re.getCause() instanceof  WorkbookNotFoundException && _ignoreMissingWorkbooks) {
+                     logInfo(re.getCause().getMessage() + " - Continuing with cached value!");
+                     switch(srcCell.getCachedFormulaResultType()) {
+                         case Cell.CELL_TYPE_NUMERIC:
+                             result = new NumberEval(srcCell.getNumericCellValue());
+                             break;
+                         case Cell.CELL_TYPE_STRING:
+                             result =  new StringEval(srcCell.getStringCellValue());
+                             break;
+                         case Cell.CELL_TYPE_BLANK:
+                             result = BlankEval.instance;
+                             break;
+                         case Cell.CELL_TYPE_BOOLEAN:
+                             result =  BoolEval.valueOf(srcCell.getBooleanCellValue());
+                             break;
+                         case Cell.CELL_TYPE_ERROR:
+                            result =  ErrorEval.valueOf(srcCell.getErrorCellValue());
+                            break;
+                         case Cell.CELL_TYPE_FORMULA:
+                        default:
+                            throw new RuntimeException("Unexpected cell type '" + srcCell.getCellType()+"' found!");
+                     }
+                 } else {
+                     throw re;
+                 }
+             } finally {
+                tracker.endEvaluate(cce);
+            }
+        } else {
+            if(evalListener != null) {
+                evalListener.onCacheHit(sheetIndex, rowIndex, columnIndex, cce.getValue());
+            }
+            return cce.getValue();
+        }
+        if (isDebugLogEnabled()) {
+            String sheetName = getSheetName(sheetIndex);
+            CellReference cr = new CellReference(rowIndex, columnIndex);
+            logDebug("Evaluated " + sheetName + "!" + cr.formatAsString() + " to " + result.toString());
+        }
+        // Usually (result === cce.getValue())
+        // But sometimes: (result==ErrorEval.CIRCULAR_REF_ERROR, cce.getValue()==null)
+        // When circular references are detected, the cache entry is only updated for
+        // the top evaluation frame
+        return result;
+    }
 
-	/**
-	 * also for debug use. Used in toString methods
-	 */
-	/* package */ String getSheetName(int sheetIndex) {
-		return _workbook.getSheetName(sheetIndex);
-	}
-
-	/* package */ EvaluationSheet getSheet(int sheetIndex) {
-		return _workbook.getSheet(sheetIndex);
-	}
-	
-	/* package */ EvaluationWorkbook getWorkbook() {
-		return _workbook;
-	}
-
-	/* package */ EvaluationName getName(String name, int sheetIndex) {
-	    EvaluationName evalName = _workbook.getName(name, sheetIndex);
-	    return evalName;
-	}
-
-	private static boolean isDebugLogEnabled() {
-		return LOG.check(POILogger.DEBUG);
-	}
-	private static boolean isInfoLogEnabled() {
-		return LOG.check(POILogger.INFO);
-	}
-	private static void logDebug(String s) {
-		if (isDebugLogEnabled()) {
-			LOG.log(POILogger.DEBUG, s);
-		}
-	}
-	private static void logInfo(String s) {
-		if (isInfoLogEnabled()) {
-			LOG.log(POILogger.INFO, s);
-		}
-	}
-	/* package */ void attachToEnvironment(CollaboratingWorkbooksEnvironment collaboratingWorkbooksEnvironment, EvaluationCache cache, int workbookIx) {
-		_collaboratingWorkbookEnvironment = collaboratingWorkbooksEnvironment;
-		_cache = cache;
-		_workbookIx = workbookIx;
-	}
-	/* package */ CollaboratingWorkbooksEnvironment getEnvironment() {
-		return _collaboratingWorkbookEnvironment;
-	}
-
-	/**
-	 * Discards the current workbook environment and attaches to the default 'empty' environment.
-	 * Also resets evaluation cache.
-	 */
-	/* package */ void detachFromEnvironment() {
-		_collaboratingWorkbookEnvironment = CollaboratingWorkbooksEnvironment.EMPTY;
-		_cache = new EvaluationCache(_evaluationListener);
-		_workbookIx = 0;
-	}
-	/**
-	 * @return the evaluator for another workbook which is part of the same {@link CollaboratingWorkbooksEnvironment}
-	 */
-	/* package */ WorkbookEvaluator getOtherWorkbookEvaluator(String workbookName) throws WorkbookNotFoundException {
-		return _collaboratingWorkbookEnvironment.getWorkbookEvaluator(workbookName);
-	}
-
-	/* package */ IEvaluationListener getEvaluationListener() {
-		return _evaluationListener;
-	}
-
-	/**
-	 * Should be called whenever there are changes to input cells in the evaluated workbook.
-	 * Failure to call this method after changing cell values will cause incorrect behaviour
-	 * of the evaluate~ methods of this class
-	 */
-	public void clearAllCachedResultValues() {
-		_cache.clear();
-		_sheetIndexesBySheet.clear();
-	}
-
-	/**
-	 * Should be called to tell the cell value cache that the specified (value or formula) cell
-	 * has changed.
-	 */
-	public void notifyUpdateCell(EvaluationCell cell) {
-		int sheetIndex = getSheetIndex(cell.getSheet());
-		_cache.notifyUpdateCell(_workbookIx, sheetIndex, cell);
-	}
-	/**
-	 * Should be called to tell the cell value cache that the specified cell has just been
-	 * deleted.
-	 */
-	public void notifyDeleteCell(EvaluationCell cell) {
-		int sheetIndex = getSheetIndex(cell.getSheet());
-		_cache.notifyDeleteCell(_workbookIx, sheetIndex, cell);
-	}
-	
-	private int getSheetIndex(EvaluationSheet sheet) {
-		Integer result = _sheetIndexesBySheet.get(sheet);
-		if (result == null) {
-			int sheetIndex = _workbook.getSheetIndex(sheet);
-			if (sheetIndex < 0) {
-				throw new RuntimeException("Specified sheet from a different book");
-			}
-			result = Integer.valueOf(sheetIndex);
-			_sheetIndexesBySheet.put(sheet, result);
-		}
-		return result.intValue();
-	}
-
-	public ValueEval evaluate(EvaluationCell srcCell) {
-		int sheetIndex = getSheetIndex(srcCell.getSheet());
-		return evaluateAny(srcCell, sheetIndex, srcCell.getRowIndex(), srcCell.getColumnIndex(), new EvaluationTracker(_cache));
-	}
-
-	/**
-	 * Case-insensitive.
-	 * @return -1 if sheet with specified name does not exist
-	 */
-	/* package */ int getSheetIndex(String sheetName) {
-		Integer result = _sheetIndexesByName.get(sheetName);
-		if (result == null) {
-			int sheetIndex = _workbook.getSheetIndex(sheetName);
-			if (sheetIndex < 0) {
-				return -1;
-			}
-			result = Integer.valueOf(sheetIndex);
-			_sheetIndexesByName.put(sheetName, result);
-		}
-		return result.intValue();
-	}
-	
-	/* package */ int getSheetIndexByExternIndex(int externSheetIndex) {
-	   return _workbook.convertFromExternSheetIndex(externSheetIndex);
-	}
-
-
-	/**
-	 * @return never <code>null</code>, never {@link BlankEval}
-	 */
-	private ValueEval evaluateAny(EvaluationCell srcCell, int sheetIndex,
-				int rowIndex, int columnIndex, EvaluationTracker tracker) {
-
-		// avoid tracking dependencies to cells that have constant definition
-		boolean shouldCellDependencyBeRecorded = _stabilityClassifier == null ? true
-					: !_stabilityClassifier.isCellFinal(sheetIndex, rowIndex, columnIndex);
-		if (srcCell == null || srcCell.getCellType() != Cell.CELL_TYPE_FORMULA) {
-			ValueEval result = getValueFromNonFormulaCell(srcCell);
-			if (shouldCellDependencyBeRecorded) {
-				tracker.acceptPlainValueDependency(_workbookIx, sheetIndex, rowIndex, columnIndex, result);
-			}
-			return result;
-		}
-
-		FormulaCellCacheEntry cce = _cache.getOrCreateFormulaCellEntry(srcCell);
-		if (shouldCellDependencyBeRecorded || cce.isInputSensitive()) {
-			tracker.acceptFormulaDependency(cce);
-		}
-		IEvaluationListener evalListener = _evaluationListener;
-		ValueEval result;
-		if (cce.getValue() == null) {
-			if (!tracker.startEvaluate(cce)) {
-				return ErrorEval.CIRCULAR_REF_ERROR;
-			}
-			OperationEvaluationContext ec = new OperationEvaluationContext(this, _workbook, sheetIndex, rowIndex, columnIndex, tracker);
-
-			try {
-
-				Ptg[] ptgs = _workbook.getFormulaTokens(srcCell);
-//				System.out.println("=====");
-//				XSSFCell c = ((XSSFEvaluationCell)srcCell).getXSSFCell();
-//				System.out.println("Formula is "+ c);
-//				System.out.println("The cell is " + c.getSheet().getSheetName()+"!"+c.getReference());
-//				System.out.println("Evaluation tokens : ");  // TODO Dlivshen remove
-//				for (Ptg ptg : ptgs) {  // TODO Dlivshen remove
-//				    System.out.println(ptg);  // TODO Dlivshen remove
-//				} // TODO Dlivshen remove
-//				System.out.println("======"); // TODO Dlivshen remove
-				if (evalListener == null) {
-					result = evaluateFormula(ec, ptgs);
-				} else {
-					evalListener.onStartEvaluate(srcCell, cce);
-					result = evaluateFormula(ec, ptgs);
-					evalListener.onEndEvaluate(cce, result);
-				}
-
-				tracker.updateCacheResult(result);
-			}
-			 catch (NotImplementedException e) {
-				throw addExceptionInfo(e,  sheetIndex, rowIndex, columnIndex);
-			 } catch (RuntimeException re) {
-				 if (re.getCause() instanceof  WorkbookNotFoundException && _ignoreMissingWorkbooks) {
- 					logInfo(re.getCause().getMessage() + " - Continuing with cached value!");
- 					switch(srcCell.getCachedFormulaResultType()) {
-	 					case Cell.CELL_TYPE_NUMERIC:
-	 						result = new NumberEval(srcCell.getNumericCellValue());
-	 						break;
-	 					case Cell.CELL_TYPE_STRING:
-	 						result =  new StringEval(srcCell.getStringCellValue());
-	 						break;
-	 					case Cell.CELL_TYPE_BLANK:
-	 						result = BlankEval.instance;
-	 						break;
-	 					case Cell.CELL_TYPE_BOOLEAN:
-	 						result =  BoolEval.valueOf(srcCell.getBooleanCellValue());
-	 						break;
-	 					case Cell.CELL_TYPE_ERROR:
-							result =  ErrorEval.valueOf(srcCell.getErrorCellValue());
-							break;
-	 					case Cell.CELL_TYPE_FORMULA:
-						default:
-							throw new RuntimeException("Unexpected cell type '" + srcCell.getCellType()+"' found!");
- 					}
-				 } else {
-					 throw re;
-				 }
-			 } finally {
-				tracker.endEvaluate(cce);
-			}
-		} else {
-			if(evalListener != null) {
-				evalListener.onCacheHit(sheetIndex, rowIndex, columnIndex, cce.getValue());
-			}
-			return cce.getValue();
-		}
-		if (isDebugLogEnabled()) {
-			String sheetName = getSheetName(sheetIndex);
-			CellReference cr = new CellReference(rowIndex, columnIndex);
-			logDebug("Evaluated " + sheetName + "!" + cr.formatAsString() + " to " + result.toString());
-		}
-		// Usually (result === cce.getValue())
-		// But sometimes: (result==ErrorEval.CIRCULAR_REF_ERROR, cce.getValue()==null)
-		// When circular references are detected, the cache entry is only updated for
-		// the top evaluation frame
-		return result;
-	}
-
-	/**
-	 * Adds the current cell reference to the exception for easier debugging.
-	 * Would be nice to get the formula text as well, but that seems to require
-	 * too much digging around and casting to get the FormulaRenderingWorkbook.
-	 */
-	private NotImplementedException addExceptionInfo(NotImplementedException inner, int sheetIndex, int rowIndex, int columnIndex) {
-
-		try {
-			String sheetName = _workbook.getSheetName(sheetIndex);
-			CellReference cr = new CellReference(sheetName, rowIndex, columnIndex, false, false);
-			String msg =  "Error evaluating cell " + cr.formatAsString();
-			return new NotImplementedException(msg, inner);
-		} catch (Exception e) {
-			// avoid bombing out during exception handling
-		    LOG.log(POILogger.ERROR, "Can't add exception info", e);
-			return inner; // preserve original exception
-		}
-	}
-	/**
-	 * Gets the value from a non-formula cell.
-	 * @param cell may be <code>null</code>
-	 * @return {@link BlankEval} if cell is <code>null</code> or blank, never <code>null</code>
-	 */
-	/* package */ static ValueEval getValueFromNonFormulaCell(EvaluationCell cell) {
-		if (cell == null) {
-			return BlankEval.instance;
-		}
-		int cellType = cell.getCellType();
-		switch (cellType) {
-			case Cell.CELL_TYPE_NUMERIC:
-				return new NumberEval(cell.getNumericCellValue());
-			case Cell.CELL_TYPE_STRING:
-				return new StringEval(cell.getStringCellValue());
-			case Cell.CELL_TYPE_BOOLEAN:
-				return BoolEval.valueOf(cell.getBooleanCellValue());
-			case Cell.CELL_TYPE_BLANK:
-				return BlankEval.instance;
-			case Cell.CELL_TYPE_ERROR:
-				return ErrorEval.valueOf(cell.getErrorCellValue());
-		}
-		throw new RuntimeException("Unexpected cell type (" + cellType + ")");
-	}
+    /**
+     * Adds the current cell reference to the exception for easier debugging.
+     * Would be nice to get the formula text as well, but that seems to require
+     * too much digging around and casting to get the FormulaRenderingWorkbook.
+     */
+    private NotImplementedException addExceptionInfo(NotImplementedException inner, int sheetIndex, int rowIndex, int columnIndex) {
+
+        try {
+            String sheetName = _workbook.getSheetName(sheetIndex);
+            CellReference cr = new CellReference(sheetName, rowIndex, columnIndex, false, false);
+            String msg =  "Error evaluating cell " + cr.formatAsString();
+            return new NotImplementedException(msg, inner);
+        } catch (Exception e) {
+            // avoid bombing out during exception handling
+            LOG.log(POILogger.ERROR, "Can't add exception info", e);
+            return inner; // preserve original exception
+        }
+    }
+    /**
+     * Gets the value from a non-formula cell.
+     * @param cell may be <code>null</code>
+     * @return {@link BlankEval} if cell is <code>null</code> or blank, never <code>null</code>
+     */
+    /* package */ static ValueEval getValueFromNonFormulaCell(EvaluationCell cell) {
+        if (cell == null) {
+            return BlankEval.instance;
+        }
+        int cellType = cell.getCellType();
+        switch (cellType) {
+            case Cell.CELL_TYPE_NUMERIC:
+                return new NumberEval(cell.getNumericCellValue());
+            case Cell.CELL_TYPE_STRING:
+                return new StringEval(cell.getStringCellValue());
+            case Cell.CELL_TYPE_BOOLEAN:
+                return BoolEval.valueOf(cell.getBooleanCellValue());
+            case Cell.CELL_TYPE_BLANK:
+                return BlankEval.instance;
+            case Cell.CELL_TYPE_ERROR:
+                return ErrorEval.valueOf(cell.getErrorCellValue());
+        }
+        throw new RuntimeException("Unexpected cell type (" + cellType + ")");
+    }
 
 
     /**
      * whether print detailed messages about the next formula evaluation
      */
-	private boolean dbgEvaluationOutputForNextEval = false;
+    private boolean dbgEvaluationOutputForNextEval = false;
+
+    // special logger for formula evaluation output (because of possibly very large output)
+    private final POILogger EVAL_LOG = POILogFactory.getLogger("POI.FormulaEval");
+    // current indent level for evalution; negative value for no output
+    private int dbgEvaluationOutputIndent = -1;
+
+    // visibility raised for testing
+    /* package */ ValueEval evaluateFormula(OperationEvaluationContext ec, Ptg[] ptgs) {
+
+        String dbgIndentStr = "";        // always init. to non-null just for defensive avoiding NPE
+        if (dbgEvaluationOutputForNextEval) {
+            // first evaluation call when ouput is desired, so iit. this evaluator instance
+            dbgEvaluationOutputIndent = 1;
+            dbgEvaluationOutputForNextEval = false;
+        }
+        if (dbgEvaluationOutputIndent > 0) {
+            // init. indent string to needed spaces (create as substring vom very long space-only string;
+            // limit indendation for deep recursions)
+            dbgIndentStr = "                                                                                                    ";
+            dbgIndentStr = dbgIndentStr.substring(0, Math.min(dbgIndentStr.length(), dbgEvaluationOutputIndent*2));
+            EVAL_LOG.log(POILogger.WARN, dbgIndentStr
+                               + "- evaluateFormula('" + ec.getRefEvaluatorForCurrentSheet().getSheetNameRange()
+                               + "'/" + new CellReference(ec.getRowIndex(), ec.getColumnIndex()).formatAsString()
+                               + "): " + Arrays.toString(ptgs).replaceAll("\\Qorg.apache.poi.ss.formula.ptg.\\E", ""));
+            dbgEvaluationOutputIndent++;
+        }
+
+        Stack<ValueEval> stack = new Stack<ValueEval>();
+        for (int i = 0, iSize = ptgs.length; i < iSize; i++) {
+
+            // since we don't know how to handle these yet :(
+            Ptg ptg = ptgs[i];
+            if (dbgEvaluationOutputIndent > 0) {
+                EVAL_LOG.log(POILogger.INFO, dbgIndentStr + "  * ptg " + i + ": " + ptg);
+            }
+            if (ptg instanceof AttrPtg) {
+                AttrPtg attrPtg = (AttrPtg) ptg;
+                if (attrPtg.isSum()) {
+                    // Excel prefers to encode 'SUM()' as a tAttr token, but this evaluator
+                    // expects the equivalent function token
+                    ptg = FuncVarPtg.SUM;
+                }
+                if (attrPtg.isOptimizedChoose()) {
+                    ValueEval arg0 = stack.pop();
+                    int[] jumpTable = attrPtg.getJumpTable();
+                    int dist;
+                    int nChoices = jumpTable.length;
+                    try {
+                        int switchIndex = Choose.evaluateFirstArg(arg0, ec.getRowIndex(), ec.getColumnIndex());
+                        if (switchIndex<1 || switchIndex > nChoices) {
+                            stack.push(ErrorEval.VALUE_INVALID);
+                            dist = attrPtg.getChooseFuncOffset() + 4; // +4 for tFuncFar(CHOOSE)
+                        } else {
+                            dist = jumpTable[switchIndex-1];
+                        }
+                    } catch (EvaluationException e) {
+                        stack.push(e.getErrorEval());
+                        dist = attrPtg.getChooseFuncOffset() + 4; // +4 for tFuncFar(CHOOSE)
+                    }
+                    // Encoded dist for tAttrChoose includes size of jump table, but
+                    // countTokensToBeSkipped() does not (it counts whole tokens).
+                    dist -= nChoices*2+2; // subtract jump table size
+                    i+= countTokensToBeSkipped(ptgs, i, dist);
+                    continue;
+                }
+                if (attrPtg.isOptimizedIf()) {
+                    ValueEval arg0 = stack.pop();
+                    boolean evaluatedPredicate;
+                    try {
+                        evaluatedPredicate = IfFunc.evaluateFirstArg(arg0, ec.getRowIndex(), ec.getColumnIndex());
+                    } catch (EvaluationException e) {
+                        stack.push(e.getErrorEval());
+                        int dist = attrPtg.getData();
+                        i+= countTokensToBeSkipped(ptgs, i, dist);
+                        attrPtg = (AttrPtg) ptgs[i];
+                        dist = attrPtg.getData()+1;
+                        i+= countTokensToBeSkipped(ptgs, i, dist);
+                        continue;
+                    }
+                    if (evaluatedPredicate) {
+                        // nothing to skip - true param follows
+                    } else {
+                        int dist = attrPtg.getData();
+                        i+= countTokensToBeSkipped(ptgs, i, dist);
+                        Ptg nextPtg = ptgs[i+1];
+                        if (ptgs[i] instanceof AttrPtg && nextPtg instanceof FuncVarPtg && 
+                                // in order to verify that there is no third param, we need to check 
+                                // if we really have the IF next or some other FuncVarPtg as third param, e.g. ROW()/COLUMN()!
+                                ((FuncVarPtg)nextPtg).getFunctionIndex() == FunctionMetadataRegistry.FUNCTION_INDEX_IF) {
+                            // this is an if statement without a false param (as opposed to MissingArgPtg as the false param)
+                            i++;
+                            stack.push(BoolEval.FALSE);
+                        }
+                    }
+                    continue;
+                }
+                if (attrPtg.isSkip()) {
+                    int dist = attrPtg.getData()+1;
+                    i+= countTokensToBeSkipped(ptgs, i, dist);
+                    if (stack.peek() == MissingArgEval.instance) {
+                        stack.pop();
+                        stack.push(BlankEval.instance);
+                    }
+                    continue;
+                }
+            }
+            if (ptg instanceof ControlPtg) {
+                // skip Parentheses, Attr, etc
+                continue;
+            }
+            if (ptg instanceof MemFuncPtg || ptg instanceof MemAreaPtg) {
+                // can ignore, rest of tokens for this expression are in OK RPN order
+                continue;
+            }
+            if (ptg instanceof MemErrPtg) {
+                continue;
+            }
+
+            ValueEval opResult;
+            if (ptg instanceof OperationPtg) {
+                OperationPtg optg = (OperationPtg) ptg;
+
+                if (optg instanceof UnionPtg) { continue; }
+
+
+                int numops = optg.getNumberOfOperands();
+                ValueEval[] ops = new ValueEval[numops];
+
+                // storing the ops in reverse order since they are popping
+                for (int j = numops - 1; j >= 0; j--) {
+                    ValueEval p = stack.pop();
+                    ops[j] = p;
+                }
+//                logDebug("invoke " + operation + " (nAgs=" + numops + ")");
+                opResult = OperationEvaluatorFactory.evaluate(optg, ops, ec);
+            } else {
+                opResult = getEvalForPtg(ptg, ec);
+            }
+            if (opResult == null) {
+                throw new RuntimeException("Evaluation result must not be null");
+            }
+//            logDebug("push " + opResult);
+            stack.push(opResult);
+            if (dbgEvaluationOutputIndent > 0) {
+                EVAL_LOG.log(POILogger.INFO, dbgIndentStr + "    = " + opResult);
+            }
+        }
+
+        ValueEval value = stack.pop();
+        if (!stack.isEmpty()) {
+            throw new IllegalStateException("evaluation stack not empty");
+        }
+        ValueEval result = dereferenceResult(value, ec.getRowIndex(), ec.getColumnIndex());
+        if (dbgEvaluationOutputIndent > 0) {
+            EVAL_LOG.log(POILogger.INFO, dbgIndentStr + "finshed eval of "
+                            + new CellReference(ec.getRowIndex(), ec.getColumnIndex()).formatAsString()
+                            + ": " + result);
+            dbgEvaluationOutputIndent--;
+            if (dbgEvaluationOutputIndent == 1) {
+                // this evaluation is done, reset indent to stop logging
+                dbgEvaluationOutputIndent = -1;
+            }
+        } // if
+        return result;
+
+    }
+
+    /**
+     * Calculates the number of tokens that the evaluator should skip upon reaching a tAttrSkip.
+     *
+     * @return the number of tokens (starting from <tt>startIndex+1</tt>) that need to be skipped
+     * to achieve the specified <tt>distInBytes</tt> skip distance.
+     */
+    private static int countTokensToBeSkipped(Ptg[] ptgs, int startIndex, int distInBytes) {
+        int remBytes = distInBytes;
+        int index = startIndex;
+        while (remBytes != 0) {
+            index++;
+            remBytes -= ptgs[index].getSize();
+            if (remBytes < 0) {
+                throw new RuntimeException("Bad skip distance (wrong token size calculation).");
+            }
+            if (index >= ptgs.length) {
+                throw new RuntimeException("Skip distance too far (ran out of formula tokens).");
+            }
+        }
+        return index-startIndex;
+    }
 
-	// special logger for formula evaluation output (because of possibly very large output)
-	private final POILogger EVAL_LOG = POILogFactory.getLogger("POI.FormulaEval");
-	// current indent level for evalution; negative value for no output
-	private int dbgEvaluationOutputIndent = -1;
-
-	// visibility raised for testing
-	/* package */ ValueEval evaluateFormula(OperationEvaluationContext ec, Ptg[] ptgs) {
-
-		String dbgIndentStr = "";		// always init. to non-null just for defensive avoiding NPE
-		if (dbgEvaluationOutputForNextEval) {
-			// first evaluation call when ouput is desired, so iit. this evaluator instance
-			dbgEvaluationOutputIndent = 1;
-			dbgEvaluationOutputForNextEval = false;
-		}
-		if (dbgEvaluationOutputIndent > 0) {
-			// init. indent string to needed spaces (create as substring vom very long space-only string;
-			// limit indendation for deep recursions)
-			dbgIndentStr = "                                                                                                    ";
-			dbgIndentStr = dbgIndentStr.substring(0, Math.min(dbgIndentStr.length(), dbgEvaluationOutputIndent*2));
-			EVAL_LOG.log(POILogger.WARN, dbgIndentStr
-			                   + "- evaluateFormula('" + ec.getRefEvaluatorForCurrentSheet().getSheetNameRange()
-			                   + "'/" + new CellReference(ec.getRowIndex(), ec.getColumnIndex()).formatAsString()
-			                   + "): " + Arrays.toString(ptgs).replaceAll("\\Qorg.apache.poi.ss.formula.ptg.\\E", ""));
-			dbgEvaluationOutputIndent++;
-		}
-
-		Stack<ValueEval> stack = new Stack<ValueEval>();
-		for (int i = 0, iSize = ptgs.length; i < iSize; i++) {
-
-			// since we don't know how to handle these yet :(
-			Ptg ptg = ptgs[i];
-			if (dbgEvaluationOutputIndent > 0) {
-				EVAL_LOG.log(POILogger.INFO, dbgIndentStr + "  * ptg " + i + ": " + ptg);
-			}
-			if (ptg instanceof AttrPtg) {
-				AttrPtg attrPtg = (AttrPtg) ptg;
-				if (attrPtg.isSum()) {
-					// Excel prefers to encode 'SUM()' as a tAttr token, but this evaluator
-					// expects the equivalent function token
-					ptg = FuncVarPtg.SUM;
-				}
-				if (attrPtg.isOptimizedChoose()) {
-					ValueEval arg0 = stack.pop();
-					int[] jumpTable = attrPtg.getJumpTable();
-					int dist;
-					int nChoices = jumpTable.length;
-					try {
-						int switchIndex = Choose.evaluateFirstArg(arg0, ec.getRowIndex(), ec.getColumnIndex());
-						if (switchIndex<1 || switchIndex > nChoices) {
-							stack.push(ErrorEval.VALUE_INVALID);
-							dist = attrPtg.getChooseFuncOffset() + 4; // +4 for tFuncFar(CHOOSE)
-						} else {
-							dist = jumpTable[switchIndex-1];
-						}
-					} catch (EvaluationException e) {
-						stack.push(e.getErrorEval());
-						dist = attrPtg.getChooseFuncOffset() + 4; // +4 for tFuncFar(CHOOSE)
-					}
-					// Encoded dist for tAttrChoose includes size of jump table, but
-					// countTokensToBeSkipped() does not (it counts whole tokens).
-					dist -= nChoices*2+2; // subtract jump table size
-					i+= countTokensToBeSkipped(ptgs, i, dist);
-					continue;
-				}
-				if (attrPtg.isOptimizedIf()) {
-					ValueEval arg0 = stack.pop();
-					boolean evaluatedPredicate;
-					try {
-						evaluatedPredicate = IfFunc.evaluateFirstArg(arg0, ec.getRowIndex(), ec.getColumnIndex());
-					} catch (EvaluationException e) {
-						stack.push(e.getErrorEval());
-						int dist = attrPtg.getData();
-						i+= countTokensToBeSkipped(ptgs, i, dist);
-						attrPtg = (AttrPtg) ptgs[i];
-						dist = attrPtg.getData()+1;
-						i+= countTokensToBeSkipped(ptgs, i, dist);
-						continue;
-					}
-					if (evaluatedPredicate) {
-						// nothing to skip - true param follows
-					} else {
-						int dist = attrPtg.getData();
-						i+= countTokensToBeSkipped(ptgs, i, dist);
-						Ptg nextPtg = ptgs[i+1];
-						if (ptgs[i] instanceof AttrPtg && nextPtg instanceof FuncVarPtg && 
-						        // in order to verify that there is no third param, we need to check 
-						        // if we really have the IF next or some other FuncVarPtg as third param, e.g. ROW()/COLUMN()!
-						        ((FuncVarPtg)nextPtg).getFunctionIndex() == FunctionMetadataRegistry.FUNCTION_INDEX_IF) {
-							// this is an if statement without a false param (as opposed to MissingArgPtg as the false param)
-							i++;
-							stack.push(BoolEval.FALSE);
-						}
-					}
-					continue;
-				}
-				if (attrPtg.isSkip()) {
-					int dist = attrPtg.getData()+1;
-					i+= countTokensToBeSkipped(ptgs, i, dist);
-					if (stack.peek() == MissingArgEval.instance) {
-						stack.pop();
-						stack.push(BlankEval.instance);
-					}
-					continue;
-				}
-			}
-			if (ptg instanceof ControlPtg) {
-				// skip Parentheses, Attr, etc
-				continue;
-			}
-			if (ptg instanceof MemFuncPtg || ptg instanceof MemAreaPtg) {
-				// can ignore, rest of tokens for this expression are in OK RPN order
-				continue;
-			}
-			if (ptg instanceof MemErrPtg) {
-				continue;
-			}
-
-			ValueEval opResult;
-			if (ptg instanceof OperationPtg) {
-				OperationPtg optg = (OperationPtg) ptg;
-
-				if (optg instanceof UnionPtg) { continue; }
-
-
-				int numops = optg.getNumberOfOperands();
-				ValueEval[] ops = new ValueEval[numops];
-
-				// storing the ops in reverse order since they are popping
-				for (int j = numops - 1; j >= 0; j--) {
-					ValueEval p = stack.pop();
-					ops[j] = p;
-				}
-//				logDebug("invoke " + operation + " (nAgs=" + numops + ")");
-				opResult = OperationEvaluatorFactory.evaluate(optg, ops, ec);
-			} else {
-				opResult = getEvalForPtg(ptg, ec);
-			}
-			if (opResult == null) {
-				throw new RuntimeException("Evaluation result must not be null");
-			}
-//			logDebug("push " + opResult);
-			stack.push(opResult);
-			if (dbgEvaluationOutputIndent > 0) {
-				EVAL_LOG.log(POILogger.INFO, dbgIndentStr + "    = " + opResult);
-			}
-		}
-
-		ValueEval value = stack.pop();
-		if (!stack.isEmpty()) {
-			throw new IllegalStateException("evaluation stack not empty");
-		}
-		ValueEval result = dereferenceResult(value, ec.getRowIndex(), ec.getColumnIndex());
-		if (dbgEvaluationOutputIndent > 0) {
-			EVAL_LOG.log(POILogger.INFO, dbgIndentStr + "finshed eval of "
-							+ new CellReference(ec.getRowIndex(), ec.getColumnIndex()).formatAsString()
-							+ ": " + result);
-			dbgEvaluationOutputIndent--;
-			if (dbgEvaluationOutputIndent == 1) {
-				// this evaluation is done, reset indent to stop logging
-				dbgEvaluationOutputIndent = -1;
-			}
-		} // if
-		return result;
-
-	}
-
-	/**
-	 * Calculates the number of tokens that the evaluator should skip upon reaching a tAttrSkip.
-	 *
-	 * @return the number of tokens (starting from <tt>startIndex+1</tt>) that need to be skipped
-	 * to achieve the specified <tt>distInBytes</tt> skip distance.
-	 */
-	private static int countTokensToBeSkipped(Ptg[] ptgs, int startIndex, int distInBytes) {
-		int remBytes = distInBytes;
-		int index = startIndex;
-		while (remBytes != 0) {
-			index++;
-			remBytes -= ptgs[index].getSize();
-			if (remBytes < 0) {
-				throw new RuntimeException("Bad skip distance (wrong token size calculation).");
-			}
-			if (index >= ptgs.length) {
-				throw new RuntimeException("Skip distance too far (ran out of formula tokens).");
-			}
-		}
-		return index-startIndex;
-	}
-
-	/**
-	 * Dereferences a single value from any AreaEval or RefEval evaluation
-	 * result. If the supplied evaluationResult is just a plain value, it is
-	 * returned as-is.
-	 *
-	 * @return a {@link NumberEval}, {@link StringEval}, {@link BoolEval}, or
-	 *         {@link ErrorEval}. Never <code>null</code>. {@link BlankEval} is
-	 *         converted to {@link NumberEval#ZERO}
-	 */
-	public static ValueEval dereferenceResult(ValueEval evaluationResult, int srcRowNum, int srcColNum) {
-		ValueEval value;
-		try {
-			value = OperandResolver.getSingleValue(evaluationResult, srcRowNum, srcColNum);
-		} catch (EvaluationException e) {
-			return e.getErrorEval();
-		}
-		if (value == BlankEval.instance) {
-			// Note Excel behaviour here. A blank final final value is converted to zero.
-			return NumberEval.ZERO;
-			// Formulas _never_ evaluate to blank.  If a formula appears to have evaluated to
-			// blank, the actual value is empty string. This can be verified with ISBLANK().
-		}
-		return value;
-	}
+    /**
+     * Dereferences a single value from any AreaEval or RefEval evaluation
+     * result. If the supplied evaluationResult is just a plain value, it is
+     * returned as-is.
+     *
+     * @return a {@link NumberEval}, {@link StringEval}, {@link BoolEval}, or
+     *         {@link ErrorEval}. Never <code>null</code>. {@link BlankEval} is
+     *         converted to {@link NumberEval#ZERO}
+     */
+    public static ValueEval dereferenceResult(ValueEval evaluationResult, int srcRowNum, int srcColNum) {
+        ValueEval value;
+        try {
+            value = OperandResolver.getSingleValue(evaluationResult, srcRowNum, srcColNum);
+        } catch (EvaluationException e) {
+            return e.getErrorEval();
+        }
+        if (value == BlankEval.instance) {
+            // Note Excel behaviour here. A blank final final value is converted to zero.
+            return NumberEval.ZERO;
+            // Formulas _never_ evaluate to blank.  If a formula appears to have evaluated to
+            // blank, the actual value is empty string. This can be verified with ISBLANK().
+        }
+        return value;
+    }
 
 
    /**
@@ -719,7 +719,7 @@ public final class WorkbookEvaluator {
        }
        return eval;
    }
-	
+    
     private ValueEval getEvalForNameRecord(EvaluationName nameRecord, OperationEvaluationContext ec) {
         if (nameRecord.isFunctionName()) {
             return new FunctionNameEval(nameRecord.getNameText());
@@ -734,25 +734,25 @@ public final class WorkbookEvaluator {
     /**
      * YK: Used by OperationEvaluationContext to resolve indirect names.
      */
-	/*package*/ ValueEval evaluateNameFormula(Ptg[] ptgs, OperationEvaluationContext ec) {
+    /*package*/ ValueEval evaluateNameFormula(Ptg[] ptgs, OperationEvaluationContext ec) {
     if (ptgs.length == 1) {
       return getEvalForPtg(ptgs[0], ec);
     }
-	  return evaluateFormula(ec, ptgs);
-	}
+      return evaluateFormula(ec, ptgs);
+    }
+
+    /**
+     * Used by the lazy ref evals whenever they need to get the value of a contained cell.
+     */
+    /* package */ ValueEval evaluateReference(EvaluationSheet sheet, int sheetIndex, int rowIndex,
+            int columnIndex, EvaluationTracker tracker) {
 
-	/**
-	 * Used by the lazy ref evals whenever they need to get the value of a contained cell.
-	 */
-	/* package */ ValueEval evaluateReference(EvaluationSheet sheet, int sheetIndex, int rowIndex,
-			int columnIndex, EvaluationTracker tracker) {
-
-		EvaluationCell cell = sheet.getCell(rowIndex, columnIndex);
-		return evaluateAny(cell, sheetIndex, rowIndex, columnIndex, tracker);
-	}
-	public FreeRefFunction findUserDefinedFunction(String functionName) {
-		return _udfFinder.findFunction(functionName);
-	}
+        EvaluationCell cell = sheet.getCell(rowIndex, columnIndex);
+        return evaluateAny(cell, sheetIndex, rowIndex, columnIndex, tracker);
+    }
+    public FreeRefFunction findUserDefinedFunction(String functionName) {
+        return _udfFinder.findFunction(functionName);
+    }
 
     /**
      * Whether to ignore missing references to external workbooks and

Modified: poi/branches/xssf_structured_references/src/java/org/apache/poi/ss/formula/functions/Indirect.java
URL: http://svn.apache.org/viewvc/poi/branches/xssf_structured_references/src/java/org/apache/poi/ss/formula/functions/Indirect.java?rev=1747625&r1=1747624&r2=1747625&view=diff
==============================================================================
--- poi/branches/xssf_structured_references/src/java/org/apache/poi/ss/formula/functions/Indirect.java (original)
+++ poi/branches/xssf_structured_references/src/java/org/apache/poi/ss/formula/functions/Indirect.java Fri Jun 10 02:51:45 2016
@@ -49,78 +49,78 @@ public final class Indirect implements F
 
     public static final FreeRefFunction instance = new Indirect();
 
-	private Indirect() {
-		// enforce singleton
-	}
-
-	public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
-		if (args.length < 1) {
-			return ErrorEval.VALUE_INVALID;
-		}
-
-		boolean isA1style;
-		String text;
-		try {
-			ValueEval ve = OperandResolver.getSingleValue(args[0], ec.getRowIndex(), ec
-					.getColumnIndex());
-			text = OperandResolver.coerceValueToString(ve);
-			switch (args.length) {
-				case 1:
-					isA1style = true;
-					break;
-				case 2:
-					isA1style = evaluateBooleanArg(args[1], ec);
-					break;
-				default:
-					return ErrorEval.VALUE_INVALID;
-			}
-		} catch (EvaluationException e) {
-			return e.getErrorEval();
-		}
-
-		return evaluateIndirect(ec, text, isA1style);
-	}
-
-	private static boolean evaluateBooleanArg(ValueEval arg, OperationEvaluationContext ec)
-			throws EvaluationException {
-		ValueEval ve = OperandResolver.getSingleValue(arg, ec.getRowIndex(), ec.getColumnIndex());
-
-		if (ve == BlankEval.instance || ve == MissingArgEval.instance) {
-			return false;
-		}
-		// numeric quantities follow standard boolean conversion rules
-		// for strings, only "TRUE" and "FALSE" (case insensitive) are valid
-		return OperandResolver.coerceValueToBoolean(ve, false).booleanValue();
-	}
-
-	private static ValueEval evaluateIndirect(final OperationEvaluationContext ec, String text,
-			boolean isA1style) {
-	    
-	    ec.getRowIndex();
-	    ec.getColumnIndex();
-
-		// Search backwards for '!' because sheet names can contain '!'
-		int plingPos = text.lastIndexOf('!');
-
-		String workbookName;
-		String sheetName;
-		String refText; // whitespace around this gets trimmed OK
-		if (plingPos < 0) {
-			workbookName = null;
-			sheetName = null;
-			refText = text;
-		} else {
-			String[] parts = parseWorkbookAndSheetName(text.subSequence(0, plingPos));
-			if (parts == null) {
-				return ErrorEval.REF_INVALID;
-			}
-			workbookName = parts[0];
-			sheetName = parts[1];
-			refText = text.substring(plingPos + 1);
-		}
+    private Indirect() {
+        // enforce singleton
+    }
+
+    public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
+        if (args.length < 1) {
+            return ErrorEval.VALUE_INVALID;
+        }
+
+        boolean isA1style;
+        String text;
+        try {
+            ValueEval ve = OperandResolver.getSingleValue(args[0], ec.getRowIndex(), ec
+                    .getColumnIndex());
+            text = OperandResolver.coerceValueToString(ve);
+            switch (args.length) {
+                case 1:
+                    isA1style = true;
+                    break;
+                case 2:
+                    isA1style = evaluateBooleanArg(args[1], ec);
+                    break;
+                default:
+                    return ErrorEval.VALUE_INVALID;
+            }
+        } catch (EvaluationException e) {
+            return e.getErrorEval();
+        }
+
+        return evaluateIndirect(ec, text, isA1style);
+    }
 
-		String refStrPart1;
-		String refStrPart2;
+    private static boolean evaluateBooleanArg(ValueEval arg, OperationEvaluationContext ec)
+            throws EvaluationException {
+        ValueEval ve = OperandResolver.getSingleValue(arg, ec.getRowIndex(), ec.getColumnIndex());
+
+        if (ve == BlankEval.instance || ve == MissingArgEval.instance) {
+            return false;
+        }
+        // numeric quantities follow standard boolean conversion rules
+        // for strings, only "TRUE" and "FALSE" (case insensitive) are valid
+        return OperandResolver.coerceValueToBoolean(ve, false).booleanValue();
+    }
+
+    private static ValueEval evaluateIndirect(final OperationEvaluationContext ec, String text,
+            boolean isA1style) {
+        
+        ec.getRowIndex();
+        ec.getColumnIndex();
+
+        // Search backwards for '!' because sheet names can contain '!'
+        int plingPos = text.lastIndexOf('!');
+
+        String workbookName;
+        String sheetName;
+        String refText; // whitespace around this gets trimmed OK
+        if (plingPos < 0) {
+            workbookName = null;
+            sheetName = null;
+            refText = text;
+        } else {
+            String[] parts = parseWorkbookAndSheetName(text.subSequence(0, plingPos));
+            if (parts == null) {
+                return ErrorEval.REF_INVALID;
+            }
+            workbookName = parts[0];
+            sheetName = parts[1];
+            refText = text.substring(plingPos + 1);
+        }
+
+        String refStrPart1;
+        String refStrPart2;
         if (Table.isStructuredReference.matcher(refText).matches()) { // The argument is structured reference
             Area3DPxg areaPtg = null;
             try{
@@ -130,128 +130,128 @@ public final class Indirect implements F
             }
             return ec.getArea3DEval(areaPtg);
         } else { // The argumnet is regular reference
-    		int colonPos = refText.indexOf(':');
-    		if (colonPos < 0) {
-     			refStrPart1 = refText.trim();
-     			refStrPart2 = null;			
-    		} else {
-    			refStrPart1 = refText.substring(0, colonPos).trim();
-    			refStrPart2 = refText.substring(colonPos + 1).trim();
-    		}
-    		return ec.getDynamicReference(workbookName, sheetName, refStrPart1, refStrPart2, isA1style);
-        }
-	}
-
-	/**
-	 * @return array of length 2: {workbookName, sheetName,}.  Second element will always be
-	 * present.  First element may be null if sheetName is unqualified.
-	 * Returns <code>null</code> if text cannot be parsed.
-	 */
-	private static String[] parseWorkbookAndSheetName(CharSequence text) {
-		int lastIx = text.length() - 1;
-		if (lastIx < 0) {
-			return null;
-		}
-		if (canTrim(text)) {
-			return null;
-		}
-		char firstChar = text.charAt(0);
-		if (Character.isWhitespace(firstChar)) {
-			return null;
-		}
-		if (firstChar == '\'') {
-			// workbookName or sheetName needs quoting
-			// quotes go around both
-			if (text.charAt(lastIx) != '\'') {
-				return null;
-			}
-			firstChar = text.charAt(1);
-			if (Character.isWhitespace(firstChar)) {
-				return null;
-			}
-			String wbName;
-			int sheetStartPos;
-			if (firstChar == '[') {
-				int rbPos = text.toString().lastIndexOf(']');
-				if (rbPos < 0) {
-					return null;
-				}
-				wbName = unescapeString(text.subSequence(2, rbPos));
-				if (wbName == null || canTrim(wbName)) {
-					return null;
-				}
-				sheetStartPos = rbPos + 1;
-			} else {
-				wbName = null;
-				sheetStartPos = 1;
-			}
-
-			// else - just sheet name
-			String sheetName = unescapeString(text.subSequence(sheetStartPos, lastIx));
-			if (sheetName == null) { // note - when quoted, sheetName can
-									 // start/end with whitespace
-				return null;
-			}
-			return new String[] { wbName, sheetName, };
-		}
-
-		if (firstChar == '[') {
-			int rbPos = text.toString().lastIndexOf(']');
-			if (rbPos < 0) {
-				return null;
-			}
-			CharSequence wbName = text.subSequence(1, rbPos);
-			if (canTrim(wbName)) {
-				return null;
-			}
-			CharSequence sheetName = text.subSequence(rbPos + 1, text.length());
-			if (canTrim(sheetName)) {
-				return null;
-			}
-			return new String[] { wbName.toString(), sheetName.toString(), };
-		}
-		// else - just sheet name
-		return new String[] { null, text.toString(), };
-	}
-
-	/**
-	 * @return <code>null</code> if there is a syntax error in any escape sequence
-	 * (the typical syntax error is a single quote character not followed by another).
-	 */
-	private static String unescapeString(CharSequence text) {
-		int len = text.length();
-		StringBuilder sb = new StringBuilder(len);
-		int i = 0;
-		while (i < len) {
-			char ch = text.charAt(i);
-			if (ch == '\'') {
-				// every quote must be followed by another
-				i++;
-				if (i >= len) {
-					return null;
-				}
-				ch = text.charAt(i);
-				if (ch != '\'') {
-					return null;
-				}
-			}
-			sb.append(ch);
-			i++;
-		}
-		return sb.toString();
-	}
-
-	private static boolean canTrim(CharSequence text) {
-		int lastIx = text.length() - 1;
-		if (lastIx < 0) {
-			return false;
-		}
-		if (Character.isWhitespace(text.charAt(0))) {
-			return true;
-		}
-		if (Character.isWhitespace(text.charAt(lastIx))) {
-			return true;
-		}
-		return false;
-	}
+            int colonPos = refText.indexOf(':');
+            if (colonPos < 0) {
+                 refStrPart1 = refText.trim();
+                 refStrPart2 = null;            
+            } else {
+                refStrPart1 = refText.substring(0, colonPos).trim();
+                refStrPart2 = refText.substring(colonPos + 1).trim();
+            }
+            return ec.getDynamicReference(workbookName, sheetName, refStrPart1, refStrPart2, isA1style);
+        }
+    }
+
+    /**
+     * @return array of length 2: {workbookName, sheetName,}.  Second element will always be
+     * present.  First element may be null if sheetName is unqualified.
+     * Returns <code>null</code> if text cannot be parsed.
+     */
+    private static String[] parseWorkbookAndSheetName(CharSequence text) {
+        int lastIx = text.length() - 1;
+        if (lastIx < 0) {
+            return null;
+        }
+        if (canTrim(text)) {
+            return null;
+        }
+        char firstChar = text.charAt(0);
+        if (Character.isWhitespace(firstChar)) {
+            return null;
+        }
+        if (firstChar == '\'') {
+            // workbookName or sheetName needs quoting
+            // quotes go around both
+            if (text.charAt(lastIx) != '\'') {
+                return null;
+            }
+            firstChar = text.charAt(1);
+            if (Character.isWhitespace(firstChar)) {
+                return null;
+            }
+            String wbName;
+            int sheetStartPos;
+            if (firstChar == '[') {
+                int rbPos = text.toString().lastIndexOf(']');
+                if (rbPos < 0) {
+                    return null;
+                }
+                wbName = unescapeString(text.subSequence(2, rbPos));
+                if (wbName == null || canTrim(wbName)) {
+                    return null;
+                }
+                sheetStartPos = rbPos + 1;
+            } else {
+                wbName = null;
+                sheetStartPos = 1;
+            }
+
+            // else - just sheet name
+            String sheetName = unescapeString(text.subSequence(sheetStartPos, lastIx));
+            if (sheetName == null) { // note - when quoted, sheetName can
+                                     // start/end with whitespace
+                return null;
+            }
+            return new String[] { wbName, sheetName, };
+        }
+
+        if (firstChar == '[') {
+            int rbPos = text.toString().lastIndexOf(']');
+            if (rbPos < 0) {
+                return null;
+            }
+            CharSequence wbName = text.subSequence(1, rbPos);
+            if (canTrim(wbName)) {
+                return null;
+            }
+            CharSequence sheetName = text.subSequence(rbPos + 1, text.length());
+            if (canTrim(sheetName)) {
+                return null;
+            }
+            return new String[] { wbName.toString(), sheetName.toString(), };
+        }
+        // else - just sheet name
+        return new String[] { null, text.toString(), };
+    }
+
+    /**
+     * @return <code>null</code> if there is a syntax error in any escape sequence
+     * (the typical syntax error is a single quote character not followed by another).
+     */
+    private static String unescapeString(CharSequence text) {
+        int len = text.length();
+        StringBuilder sb = new StringBuilder(len);
+        int i = 0;
+        while (i < len) {
+            char ch = text.charAt(i);
+            if (ch == '\'') {
+                // every quote must be followed by another
+                i++;
+                if (i >= len) {
+                    return null;
+                }
+                ch = text.charAt(i);
+                if (ch != '\'') {
+                    return null;
+                }
+            }
+            sb.append(ch);
+            i++;
+        }
+        return sb.toString();
+    }
+
+    private static boolean canTrim(CharSequence text) {
+        int lastIx = text.length() - 1;
+        if (lastIx < 0) {
+            return false;
+        }
+        if (Character.isWhitespace(text.charAt(0))) {
+            return true;
+        }
+        if (Character.isWhitespace(text.charAt(lastIx))) {
+            return true;
+        }
+        return false;
+    }
 }




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