From f05f66fa82802ef457a4862a9ae87bd5615be646 Mon Sep 17 00:00:00 2001
From: Mark Baker <mark@lange.demon.co.uk>
Date: Mon, 11 Feb 2013 14:11:36 +0000
Subject: [PATCH] Eliminate some code duplication

---
 Classes/PHPExcel/Calculation.php            | 440 ++++++++++----------
 Classes/PHPExcel/Cell.php                   |   5 +-
 Classes/PHPExcel/Chart/DataSeriesValues.php |   2 +-
 3 files changed, 227 insertions(+), 220 deletions(-)

diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php
index 0e4f066..e04fd69 100644
--- a/Classes/PHPExcel/Calculation.php
+++ b/Classes/PHPExcel/Calculation.php
@@ -127,7 +127,7 @@ class PHPExcel_Calculation {
 	 * @access	private
 	 * @var boolean
 	 */
-	private $_calculationCacheEnabled = true;
+	private $_calculationCacheEnabled = TRUE;
 
 
 	/**
@@ -137,10 +137,10 @@ class PHPExcel_Calculation {
 	 * @access	private
 	 * @var array
 	 */
-	private static $_operators			= array('+' => true,	'-' => true,	'*' => true,	'/' => true,
-												'^' => true,	'&' => true,	'%' => false,	'~' => false,
-												'>' => true,	'<' => true,	'=' => true,	'>=' => true,
-												'<=' => true,	'<>' => true,	'|' => true,	':' => true
+	private static $_operators			= array('+' => TRUE,	'-' => TRUE,	'*' => TRUE,	'/' => TRUE,
+												'^' => TRUE,	'&' => TRUE,	'%' => FALSE,	'~' => FALSE,
+												'>' => TRUE,	'<' => TRUE,	'=' => TRUE,	'>=' => TRUE,
+												'<=' => TRUE,	'<>' => TRUE,	'|' => TRUE,	':' => TRUE
 											   );
 
 
@@ -150,10 +150,10 @@ class PHPExcel_Calculation {
 	 * @access	private
 	 * @var array
 	 */
-	private static $_binaryOperators	= array('+' => true,	'-' => true,	'*' => true,	'/' => true,
-												'^' => true,	'&' => true,	'>' => true,	'<' => true,
-												'=' => true,	'>=' => true,	'<=' => true,	'<>' => true,
-												'|' => true,	':' => true
+	private static $_binaryOperators	= array('+' => TRUE,	'-' => TRUE,	'*' => TRUE,	'/' => TRUE,
+												'^' => TRUE,	'&' => TRUE,	'>' => TRUE,	'<' => TRUE,
+												'=' => TRUE,	'>=' => TRUE,	'<=' => TRUE,	'<>' => TRUE,
+												'|' => TRUE,	':' => TRUE
 											   );
 
 	/**
@@ -165,7 +165,7 @@ class PHPExcel_Calculation {
 	 * @var boolean
 	 *
 	 */
-	public $suppressFormulaErrors = false;
+	public $suppressFormulaErrors = FALSE;
 
 	/**
 	 * Error message for any error that was raised/thrown by the calculation engine
@@ -174,7 +174,7 @@ class PHPExcel_Calculation {
 	 * @var string
 	 *
 	 */
-	public $formulaError = null;
+	public $formulaError = NULL;
 
 	/**
 	 * Flag to determine whether a debug log should be generated by the calculation engine
@@ -185,7 +185,7 @@ class PHPExcel_Calculation {
 	 * @var boolean
 	 *
 	 */
-	public $writeDebugLog = false;
+	public $writeDebugLog = FALSE;
 
 	/**
 	 * Flag to determine whether a debug log should be echoed by the calculation engine
@@ -197,7 +197,7 @@ class PHPExcel_Calculation {
 	 * @var boolean
 	 *
 	 */
-	public $echoDebugLog = false;
+	public $echoDebugLog = FALSE;
 
 
 	/**
@@ -237,9 +237,9 @@ class PHPExcel_Calculation {
 
 
 	//	Constant conversion from text name/value to actual (datatyped) value
-	private static $_ExcelConstants = array('TRUE'	=> true,
-											'FALSE'	=> false,
-											'NULL'	=> null
+	private static $_ExcelConstants = array('TRUE'	=> TRUE,
+											'FALSE'	=> FALSE,
+											'NULL'	=> NULL
 										   );
 
 	//	PHPExcel functions
@@ -411,7 +411,7 @@ class PHPExcel_Calculation {
 				'COLUMN'				=> array('category'			=>	PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
 												 'functionCall'		=>	'PHPExcel_Calculation_LookupRef::COLUMN',
 												 'argumentCount'	=>	'-1',
-												 'passByReference'	=>	array(true)
+												 'passByReference'	=>	array(TRUE)
 												),
 				'COLUMNS'				=> array('category'			=>	PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
 												 'functionCall'		=>	'PHPExcel_Calculation_LookupRef::COLUMNS',
@@ -820,7 +820,7 @@ class PHPExcel_Calculation {
 				'HYPERLINK'				=> array('category'			=>	PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
 												 'functionCall'		=>	'PHPExcel_Calculation_LookupRef::HYPERLINK',
 												 'argumentCount'	=>	'1,2',
-												 'passCellReference'=>	true
+												 'passCellReference'=>	TRUE
 												),
 				'HYPGEOMDIST'			=> array('category'			=>	PHPExcel_Calculation_Function::CATEGORY_STATISTICAL,
 												 'functionCall'		=>	'PHPExcel_Calculation_Statistical::HYPGEOMDIST',
@@ -909,7 +909,7 @@ class PHPExcel_Calculation {
 				'INDIRECT'				=> array('category'			=>	PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
 												 'functionCall'		=>	'PHPExcel_Calculation_LookupRef::INDIRECT',
 												 'argumentCount'	=>	'1,2',
-												 'passCellReference'=>	true
+												 'passCellReference'=>	TRUE
 												),
 				'INFO'					=> array('category'			=>	PHPExcel_Calculation_Function::CATEGORY_INFORMATION,
 												 'functionCall'		=>	'PHPExcel_Calculation_Functions::DUMMY',
@@ -1226,8 +1226,8 @@ class PHPExcel_Calculation {
 				'OFFSET'				=> array('category'			=>	PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
 												 'functionCall'		=>	'PHPExcel_Calculation_LookupRef::OFFSET',
 												 'argumentCount'	=>	'3,5',
-												 'passCellReference'=>	true,
-												 'passByReference'	=>	array(true)
+												 'passCellReference'=>	TRUE,
+												 'passByReference'	=>	array(TRUE)
 												),
 				'OR'					=> array('category'			=>	PHPExcel_Calculation_Function::CATEGORY_LOGICAL,
 												 'functionCall'		=>	'PHPExcel_Calculation_Logical::LOGICAL_OR',
@@ -1372,7 +1372,7 @@ class PHPExcel_Calculation {
 				'ROW'					=> array('category'			=>	PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
 												 'functionCall'		=>	'PHPExcel_Calculation_LookupRef::ROW',
 												 'argumentCount'	=>	'-1',
-												 'passByReference'	=>	array(true)
+												 'passByReference'	=>	array(TRUE)
 												),
 				'ROWS'					=> array('category'			=>	PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,
 												 'functionCall'		=>	'PHPExcel_Calculation_LookupRef::ROWS',
@@ -1766,7 +1766,7 @@ class PHPExcel_Calculation {
 	 * @throws	PHPExcel_Calculation_Exception
 	 */
 	public final function __clone() {
-		throw new PHPExcel_Calculation_Exception ('Cloning a Singleton is not allowed!');
+		throw new PHPExcel_Calculation_Exception ('Cloning the calculation engine is not allowed!');
 	}	//	function __clone()
 
 
@@ -1802,10 +1802,10 @@ class PHPExcel_Calculation {
 			($returnType == self::RETURN_ARRAY_AS_ERROR) ||
 			($returnType == self::RETURN_ARRAY_AS_ARRAY)) {
 			self::$returnArrayAsType = $returnType;
-			return true;
+			return TRUE;
 		}
-		return false;
-	}	//	function setExcelCalendar()
+		return FALSE;
+	}	//	function setArrayReturnType()
 
 
 	/**
@@ -1816,7 +1816,7 @@ class PHPExcel_Calculation {
 	 */
 	public static function getArrayReturnType() {
 		return self::$returnArrayAsType;
-	}	//	function getExcelCalendar()
+	}	//	function getArrayReturnType()
 
 
 	/**
@@ -1835,7 +1835,7 @@ class PHPExcel_Calculation {
 	 * @access	public
 	 * @param boolean $pValue
 	 */
-	public function setCalculationCacheEnabled($pValue = true) {
+	public function setCalculationCacheEnabled($pValue = TRUE) {
 		$this->_calculationCacheEnabled = $pValue;
 		$this->clearCalculationCache();
 	}	//	function setCalculationCacheEnabled()
@@ -1845,7 +1845,7 @@ class PHPExcel_Calculation {
 	 * Enable calculation cache
 	 */
 	public function enableCalculationCache() {
-		$this->setCalculationCacheEnabled(true);
+		$this->setCalculationCacheEnabled(TRUE);
 	}	//	function enableCalculationCache()
 
 
@@ -1853,7 +1853,7 @@ class PHPExcel_Calculation {
 	 * Disable calculation cache
 	 */
 	public function disableCalculationCache() {
-		$this->setCalculationCacheEnabled(false);
+		$this->setCalculationCacheEnabled(FALSE);
 	}	//	function disableCalculationCache()
 
 
@@ -1883,7 +1883,7 @@ class PHPExcel_Calculation {
 	public function setLocale($locale='en_us') {
 		//	Identify our locale and language
 		$language = $locale = strtolower($locale);
-		if (strpos($locale,'_') !== false) {
+		if (strpos($locale,'_') !== FALSE) {
 			list($language) = explode('_',$locale);
 		}
 
@@ -1904,14 +1904,14 @@ class PHPExcel_Calculation {
 					//	If there isn't a locale specific function file, look for a language specific function file
 					$functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'functions';
 					if (!file_exists($functionNamesFile)) {
-						return false;
+						return FALSE;
 					}
 				}
 				//	Retrieve the list of locale or language specific function names
 				$localeFunctions = file($functionNamesFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
 				foreach ($localeFunctions as $localeFunction) {
 					list($localeFunction) = explode('##',$localeFunction);	//	Strip out comments
-					if (strpos($localeFunction,'=') !== false) {
+					if (strpos($localeFunction,'=') !== FALSE) {
 						list($fName,$lfName) = explode('=',$localeFunction);
 						$fName = trim($fName);
 						$lfName = trim($lfName);
@@ -1932,7 +1932,7 @@ class PHPExcel_Calculation {
 					$localeSettings = file($configFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
 					foreach ($localeSettings as $localeSetting) {
 						list($localeSetting) = explode('##',$localeSetting);	//	Strip out comments
-						if (strpos($localeSetting,'=') !== false) {
+						if (strpos($localeSetting,'=') !== FALSE) {
 							list($settingName,$settingValue) = explode('=',$localeSetting);
 							$settingName = strtoupper(trim($settingName));
 							switch ($settingName) {
@@ -1946,11 +1946,11 @@ class PHPExcel_Calculation {
 			}
 
 			self::$functionReplaceFromExcel = self::$functionReplaceToExcel =
-			self::$functionReplaceFromLocale = self::$functionReplaceToLocale = null;
+			self::$functionReplaceFromLocale = self::$functionReplaceToLocale = NULL;
 			self::$_localeLanguage = $locale;
-			return true;
+			return TRUE;
 		}
-		return false;
+		return FALSE;
 	}	//	function setLocale()
 
 
@@ -1960,9 +1960,9 @@ class PHPExcel_Calculation {
 		for ($i = 0; $i < $strlen; ++$i) {
 			$chr = mb_substr($formula,$i,1);
 			switch ($chr) {
-				case '{' :	$inBraces = true;
+				case '{' :	$inBraces = TRUE;
 							break;
-				case '}' :	$inBraces = false;
+				case '}' :	$inBraces = FALSE;
 							break;
 				case $fromSeparator :
 							if (!$inBraces) {
@@ -1976,13 +1976,13 @@ class PHPExcel_Calculation {
 	private static function _translateFormula($from,$to,$formula,$fromSeparator,$toSeparator) {
 		//	Convert any Excel function names to the required language
 		if (self::$_localeLanguage !== 'en_us') {
-			$inBraces = false;
+			$inBraces = FALSE;
 			//	If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators
-			if (strpos($formula,'"') !== false) {
+			if (strpos($formula,'"') !== FALSE) {
 				//	So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded
 				//		the formula
 				$temp = explode('"',$formula);
-				$i = false;
+				$i = FALSE;
 				foreach($temp as &$value) {
 					//	Only count/replace in alternating array entries
 					if ($i = !$i) {
@@ -2003,8 +2003,8 @@ class PHPExcel_Calculation {
 		return $formula;
 	}
 
-	private static $functionReplaceFromExcel	= null;
-	private static $functionReplaceToLocale		= null;
+	private static $functionReplaceFromExcel	= NULL;
+	private static $functionReplaceToLocale		= NULL;
 
 	public function _translateFormulaToLocale($formula) {
 		if (self::$functionReplaceFromExcel === NULL) {
@@ -2032,8 +2032,8 @@ class PHPExcel_Calculation {
 	}	//	function _translateFormulaToLocale()
 
 
-	private static $functionReplaceFromLocale	= null;
-	private static $functionReplaceToExcel		= null;
+	private static $functionReplaceFromLocale	= NULL;
+	private static $functionReplaceToExcel		= NULL;
 
 	public function _translateFormulaToEnglish($formula) {
 		if (self::$functionReplaceFromLocale === NULL) {
@@ -2129,7 +2129,7 @@ class PHPExcel_Calculation {
 	 * @return	mixed
 	 * @throws	PHPExcel_Calculation_Exception
 	 */
-	public function calculate(PHPExcel_Cell $pCell = null) {
+	public function calculate(PHPExcel_Cell $pCell = NULL) {
 		try {
 			return $this->calculateCellValue($pCell);
 		} catch (PHPExcel_Exception $e) {
@@ -2147,24 +2147,22 @@ class PHPExcel_Calculation {
 	 * @return	mixed
 	 * @throws	PHPExcel_Calculation_Exception
 	 */
-	public function calculateCellValue(PHPExcel_Cell $pCell = null, $resetLog = true) {
-		if ($resetLog) {
-			//	Initialise the logging settings if requested
-			$this->formulaError = null;
-			$this->debugLog = $this->debugLogStack = array();
-			$this->_cyclicFormulaCount = 1;
-
-			$returnArrayAsType = self::$returnArrayAsType;
-			self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY;
-		}
-
-		//	Read the formula from the cell
+	public function calculateCellValue(PHPExcel_Cell $pCell = NULL, $resetLog = TRUE) {
 		if ($pCell === NULL) {
 			return NULL;
 		}
 
+		$returnArrayAsType = self::$returnArrayAsType;
+		if ($resetLog) {
+			//	Initialise the logging settings if requested
+			$this->formulaError = NULL;
+			$this->debugLog = $this->debugLogStack = array();
+			$this->_cyclicFormulaCount = 1;
+
+			self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY;
+		}
+
 		if ($resetLog) {
-			self::$returnArrayAsType = $returnArrayAsType;
 		}
 		//	Execute the calculation for the cell formula
 		try {
@@ -2174,6 +2172,7 @@ class PHPExcel_Calculation {
 		}
 
 		if ((is_array($result)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) {
+			self::$returnArrayAsType = $returnArrayAsType;
 			$testResult = PHPExcel_Calculation_Functions::flattenArray($result);
 			if (self::$returnArrayAsType == self::RETURN_ARRAY_AS_ERROR) {
 				return PHPExcel_Calculation_Functions::VALUE();
@@ -2194,6 +2193,8 @@ class PHPExcel_Calculation {
 			}
 			$result = array_shift($testResult);
 		}
+		self::$returnArrayAsType = $returnArrayAsType;
+
 
 		if ($result === NULL) {
 			return 0;
@@ -2231,7 +2232,7 @@ class PHPExcel_Calculation {
 	 * @return	mixed
 	 * @throws	PHPExcel_Calculation_Exception
 	 */
-	public function calculateFormula($formula, $cellID=null, PHPExcel_Cell $pCell = null) {
+	public function calculateFormula($formula, $cellID=NULL, PHPExcel_Cell $pCell = NULL) {
 		//	Initialise the logging settings
 		$this->formulaError = null;
 		$this->debugLog = $this->debugLogStack = array();
@@ -2254,6 +2255,25 @@ class PHPExcel_Calculation {
 	}	//	function calculateFormula()
 
 
+    public function getValueFromCache($worksheetName, $cellID, &$cellValue) {
+		// Is calculation cacheing enabled?
+		// Is the value present in calculation cache?
+		$this->_writeDebug('Testing cache value for cell ', $worksheetName, '!', $cellID);
+		if (($this->_calculationCacheEnabled) && (isset($this->_calculationCache[$worksheetName][$cellID]))) {
+			$this->_writeDebug('Retrieving value for cell ', $worksheetName, '!', $cellID, ' from cache');
+			// Return the cached result
+			$cellValue = $this->_calculationCache[$worksheetName][$cellID];
+			return TRUE;
+		}
+		return FALSE;
+    }
+
+    public function saveValueToCache($worksheetName, $cellID, $cellValue) {
+		if ($this->_calculationCacheEnabled) {
+			$this->_calculationCache[$worksheetName][$cellID] = $cellValue;
+		}
+	}
+
 	/**
 	 * Parse a cell formula and calculate its value
 	 *
@@ -2264,11 +2284,10 @@ class PHPExcel_Calculation {
 	 * @throws	PHPExcel_Calculation_Exception
 	 */
 	public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pCell = null) {
-//echo $cellID,PHP_EOL;
 		$cellValue = '';
 
 		//	Basic validation that this is indeed a formula
-		//	We simply return the "cell value" (formula) if not
+		//	We simply return the cell value if not
 		$formula = trim($formula);
 		if ($formula{0} != '=') return self::_wrapResult($formula);
 		$formula = ltrim(substr($formula,1));
@@ -2276,28 +2295,12 @@ class PHPExcel_Calculation {
 
 		$pCellParent = ($pCell !== NULL) ? $pCell->getParent() : NULL;
 		$wsTitle = ($pCellParent !== NULL) ? $pCellParent->getTitle() : "\x00Wrk";
-		// Is calculation cacheing enabled?
-		if ($cellID !== NULL) {
-			if ($this->_calculationCacheEnabled) {
-				// Is the value present in calculation cache?
-				$this->_writeDebug('Testing cache value for cell ', $cellID);
-//echo 'Testing cache value',PHP_EOL;
-				if (isset($this->_calculationCache[$wsTitle][$cellID])) {
-//echo 'Value is in cache',PHP_EOL;
-					$this->_writeDebug('Retrieving value for ', $cellID, ' from cache');
-					// Return the cached result
-					$returnValue = $this->_calculationCache[$wsTitle][$cellID];
-//echo 'Retrieving data value of '.$returnValue.' for '.$cellID.' from cache',PHP_EOL;
-					if (is_array($returnValue)) {
-						$returnValue = PHPExcel_Calculation_Functions::flattenArray($returnValue);
-						return array_shift($returnValue);
-					}
-					return $returnValue;
-				}
-			}
+
+		if (($cellID !== NULL) && ($this->getValueFromCache($wsTitle, $cellID, $cellValue))) {
+			return $cellValue;
 		}
 
-		if ((in_array($wsTitle.'!'.$cellID,$this->debugLogStack)) && ($wsTitle != "\x00Wrk")) {
+		if (($wsTitle{0} !== "\x00") && (in_array($wsTitle.'!'.$cellID,$this->debugLogStack))) {
 			if ($this->cyclicFormulaCount <= 0) {
 				return $this->_raiseFormulaError('Cyclic Reference in Formula');
 			} elseif (($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) &&
@@ -2322,9 +2325,7 @@ class PHPExcel_Calculation {
 
 		// Save to calculation cache
 		if ($cellID !== NULL) {
-			if ($this->_calculationCacheEnabled) {
-				$this->_calculationCache[$wsTitle][$cellID] = $cellValue;
-			}
+			$this->saveValueToCache($wsTitle, $cellID, $cellValue);
 		}
 
 		//	Return the calculated value
@@ -2555,15 +2556,15 @@ class PHPExcel_Calculation {
 		static $matrixReplaceTo = array('MKMATRIX(MKMATRIX(','),MKMATRIX(','))');
 
 		//	Convert any Excel matrix references to the MKMATRIX() function
-		if (strpos($formula,'{') !== false) {
+		if (strpos($formula,'{') !== FALSE) {
 			//	If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators
-			if (strpos($formula,'"') !== false) {
+			if (strpos($formula,'"') !== FALSE) {
 				//	So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded
 				//		the formula
 				$temp = explode('"',$formula);
 				//	Open and Closed counts used for trapping mismatched braces in the formula
 				$openCount = $closeCount = 0;
-				$i = false;
+				$i = FALSE;
 				foreach($temp as &$value) {
 					//	Only count/replace in alternating array entries
 					if ($i = !$i) {
@@ -2606,9 +2607,40 @@ class PHPExcel_Calculation {
 	}	//	function _mkMatrix()
 
 
+	//	Binary Operators
+	//	These operators always work on two values
+	//	Array key is the operator, the value indicates whether this is a left or right associative operator
+	private static $_operatorAssociativity	= array(
+		'^' => 0,															//	Exponentiation
+		'*' => 0, '/' => 0, 												//	Multiplication and Division
+		'+' => 0, '-' => 0,													//	Addition and Subtraction
+		'&' => 0,															//	Concatenation
+		'|' => 0, ':' => 0,													//	Intersect and Range
+		'>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0		//	Comparison
+	);
+
+	//	Comparison (Boolean) Operators
+	//	These operators work on two values, but always return a boolean result
+	private static $_comparisonOperators	= array('>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE);
+
+	//	Operator Precedence
+	//	This list includes all valid operators, whether binary (including boolean) or unary (such as %)
+	//	Array key is the operator, the value is its precedence
+	private static $_operatorPrecedence	= array(
+		':' => 8,																//	Range
+		'|' => 7,																//	Intersect
+		'~' => 6,																//	Negation
+		'%' => 5,																//	Percentage
+		'^' => 4,																//	Exponentiation
+		'*' => 3, '/' => 3, 													//	Multiplication and Division
+		'+' => 2, '-' => 2,														//	Addition and Subtraction
+		'&' => 1,																//	Concatenation
+		'>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0			//	Comparison
+	);
+
 	// Convert infix to postfix notation
-	private function _parseFormula($formula, PHPExcel_Cell $pCell = null) {
-		if (($formula = self::_convertMatrixReferences(trim($formula))) === false) {
+	private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) {
+		if (($formula = self::_convertMatrixReferences(trim($formula))) === FALSE) {
 			return FALSE;
 		}
 
@@ -2616,34 +2648,6 @@ class PHPExcel_Calculation {
 		//		so we store the parent worksheet so that we can re-attach it when necessary
 		$pCellParent = ($pCell !== NULL) ? $pCell->getParent() : NULL;
 
-		//	Binary Operators
-		//	These operators always work on two values
-		//	Array key is the operator, the value indicates whether this is a left or right associative operator
-		$operatorAssociativity	= array('^' => 0,															//	Exponentiation
-										'*' => 0, '/' => 0, 												//	Multiplication and Division
-										'+' => 0, '-' => 0,													//	Addition and Subtraction
-										'&' => 0,															//	Concatenation
-										'|' => 0, ':' => 0,													//	Intersect and Range
-										'>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0		//	Comparison
-								 	  );
-		//	Comparison (Boolean) Operators
-		//	These operators work on two values, but always return a boolean result
-		$comparisonOperators	= array('>' => true, '<' => true, '=' => true, '>=' => true, '<=' => true, '<>' => true);
-
-		//	Operator Precedence
-		//	This list includes all valid operators, whether binary (including boolean) or unary (such as %)
-		//	Array key is the operator, the value is its precedence
-		$operatorPrecedence	= array(':' => 8,																//	Range
-									'|' => 7,																//	Intersect
-									'~' => 6,																//	Negation
-									'%' => 5,																//	Percentage
-									'^' => 4,																//	Exponentiation
-									'*' => 3, '/' => 3, 													//	Multiplication and Division
-									'+' => 2, '-' => 2,														//	Addition and Subtraction
-									'&' => 1,																//	Concatenation
-									'>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0			//	Comparison
-								   );
-
 		$regexpMatchString = '/^('.self::CALCULATION_REGEXP_FUNCTION.
 							   '|'.self::CALCULATION_REGEXP_NUMBER.
 							   '|'.self::CALCULATION_REGEXP_STRING.
@@ -2657,55 +2661,55 @@ class PHPExcel_Calculation {
 		$index = 0;
 		$stack = new PHPExcel_Calculation_Token_Stack;
 		$output = array();
-		$expectingOperator = false;					//	We use this test in syntax-checking the expression to determine when a
+		$expectingOperator = FALSE;					//	We use this test in syntax-checking the expression to determine when a
 													//		- is a negation or + is a positive operator rather than an operation
-		$expectingOperand = false;					//	We use this test in syntax-checking the expression to determine whether an operand
+		$expectingOperand = FALSE;					//	We use this test in syntax-checking the expression to determine whether an operand
 													//		should be null in a function call
 		//	The guts of the lexical parser
 		//	Loop through the formula extracting each operator and operand in turn
-		while(true) {
+		while(TRUE) {
 //echo 'Assessing Expression '.substr($formula, $index),PHP_EOL;
 			$opCharacter = $formula{$index};	//	Get the first character of the value at the current index position
 //echo 'Initial character of expression block is '.$opCharacter,PHP_EOL;
-			if ((isset($comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && (isset($comparisonOperators[$formula{$index+1}]))) {
+			if ((isset(self::$_comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && (isset(self::$_comparisonOperators[$formula{$index+1}]))) {
 				$opCharacter .= $formula{++$index};
-//				echo 'Initial character of expression block is comparison operator '.$opCharacter.'<br />';
+//echo 'Initial character of expression block is comparison operator '.$opCharacter.PHP_EOL;
 			}
 
 			//	Find out if we're currently at the beginning of a number, variable, cell reference, function, parenthesis or operand
 			$isOperandOrFunction = preg_match($regexpMatchString, substr($formula, $index), $match);
-//			echo '$isOperandOrFunction is '.(($isOperandOrFunction) ? 'True' : 'False').'<br />';
-//			var_dump($match);
+//echo '$isOperandOrFunction is '.(($isOperandOrFunction) ? 'True' : 'False').PHP_EOL;
+//var_dump($match);
 
 			if ($opCharacter == '-' && !$expectingOperator) {				//	Is it a negation instead of a minus?
-//				echo 'Element is a Negation operator<br />';
+//echo 'Element is a Negation operator',PHP_EOL;
 				$stack->push('Unary Operator','~');							//	Put a negation on the stack
 				++$index;													//		and drop the negation symbol
 			} elseif ($opCharacter == '%' && $expectingOperator) {
-//				echo 'Element is a Percentage operator<br />';
+//echo 'Element is a Percentage operator',PHP_EOL;
 				$stack->push('Unary Operator','%');							//	Put a percentage on the stack
 				++$index;
 			} elseif ($opCharacter == '+' && !$expectingOperator) {			//	Positive (unary plus rather than binary operator plus) can be discarded?
-//				echo 'Element is a Positive number, not Plus operator<br />';
+//echo 'Element is a Positive number, not Plus operator',PHP_EOL;
 				++$index;													//	Drop the redundant plus symbol
 			} elseif ((($opCharacter == '~') || ($opCharacter == '|')) && (!$isOperandOrFunction)) {	//	We have to explicitly deny a tilde or pipe, because they are legal
 				return $this->_raiseFormulaError("Formula Error: Illegal character '~'");				//		on the stack but not in the input expression
 
 			} elseif ((isset(self::$_operators[$opCharacter]) or $isOperandOrFunction) && $expectingOperator) {	//	Are we putting an operator on the stack?
-//				echo 'Element with value '.$opCharacter.' is an Operator<br />';
+//echo 'Element with value '.$opCharacter.' is an Operator',PHP_EOL;
 				while($stack->count() > 0 &&
 					($o2 = $stack->last()) &&
 					isset(self::$_operators[$o2['value']]) &&
-					@($operatorAssociativity[$opCharacter] ? $operatorPrecedence[$opCharacter] < $operatorPrecedence[$o2['value']] : $operatorPrecedence[$opCharacter] <= $operatorPrecedence[$o2['value']])) {
+					@(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) {
 					$output[] = $stack->pop();								//	Swap operands and higher precedence operators from the stack to the output
 				}
 				$stack->push('Binary Operator',$opCharacter);	//	Finally put our current operator onto the stack
 				++$index;
-				$expectingOperator = false;
+				$expectingOperator = FALSE;
 
 			} elseif ($opCharacter == ')' && $expectingOperator) {			//	Are we expecting to close a parenthesis?
-//				echo 'Element is a Closing bracket<br />';
-				$expectingOperand = false;
+//echo 'Element is a Closing bracket',PHP_EOL;
+				$expectingOperand = FALSE;
 				while (($o2 = $stack->pop()) && $o2['value'] != '(') {		//	Pop off the stack back to the last (
 					if ($o2 === NULL) return $this->_raiseFormulaError('Formula Error: Unexpected closing brace ")"');
 					else $output[] = $o2;
@@ -2713,65 +2717,65 @@ class PHPExcel_Calculation {
 				$d = $stack->last(2);
 				if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) {	//	Did this parenthesis just close a function?
 					$functionName = $matches[1];										//	Get the function name
-//					echo 'Closed Function is '.$functionName.'<br />';
+//echo 'Closed Function is '.$functionName,PHP_EOL;
 					$d = $stack->pop();
 					$argumentCount = $d['value'];		//	See how many arguments there were (argument count is the next value stored on the stack)
-//					if ($argumentCount == 0) {
-//						echo 'With no arguments<br />';
-//					} elseif ($argumentCount == 1) {
-//						echo 'With 1 argument<br />';
-//					} else {
-//						echo 'With '.$argumentCount.' arguments<br />';
-//					}
+//if ($argumentCount == 0) {
+//	echo 'With no arguments',PHP_EOL;
+//} elseif ($argumentCount == 1) {
+//	echo 'With 1 argument',PHP_EOL;
+//} else {
+//	echo 'With '.$argumentCount.' arguments',PHP_EOL;
+//}
 					$output[] = $d;						//	Dump the argument count on the output
 					$output[] = $stack->pop();			//	Pop the function and push onto the output
 					if (isset(self::$_controlFunctions[$functionName])) {
-//						echo 'Built-in function '.$functionName.'<br />';
+//echo 'Built-in function '.$functionName,PHP_EOL;
 						$expectedArgumentCount = self::$_controlFunctions[$functionName]['argumentCount'];
 						$functionCall = self::$_controlFunctions[$functionName]['functionCall'];
 					} elseif (isset(self::$_PHPExcelFunctions[$functionName])) {
-//						echo 'PHPExcel function '.$functionName.'<br />';
+//echo 'PHPExcel function '.$functionName,PHP_EOL;
 						$expectedArgumentCount = self::$_PHPExcelFunctions[$functionName]['argumentCount'];
 						$functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall'];
 					} else {	// did we somehow push a non-function on the stack? this should never happen
 						return $this->_raiseFormulaError("Formula Error: Internal error, non-function on stack");
 					}
 					//	Check the argument count
-					$argumentCountError = false;
+					$argumentCountError = FALSE;
 					if (is_numeric($expectedArgumentCount)) {
 						if ($expectedArgumentCount < 0) {
-//							echo '$expectedArgumentCount is between 0 and '.abs($expectedArgumentCount).'<br />';
+//echo '$expectedArgumentCount is between 0 and '.abs($expectedArgumentCount),PHP_EOL;
 							if ($argumentCount > abs($expectedArgumentCount)) {
-								$argumentCountError = true;
+								$argumentCountError = TRUE;
 								$expectedArgumentCountString = 'no more than '.abs($expectedArgumentCount);
 							}
 						} else {
-//							echo '$expectedArgumentCount is numeric '.$expectedArgumentCount.'<br />';
+//echo '$expectedArgumentCount is numeric '.$expectedArgumentCount,PHP_EOL;
 							if ($argumentCount != $expectedArgumentCount) {
-								$argumentCountError = true;
+								$argumentCountError = TRUE;
 								$expectedArgumentCountString = $expectedArgumentCount;
 							}
 						}
 					} elseif ($expectedArgumentCount != '*') {
 						$isOperandOrFunction = preg_match('/(\d*)([-+,])(\d*)/',$expectedArgumentCount,$argMatch);
-//						print_r($argMatch);
-//						echo '<br />';
+//print_r($argMatch);
+//echo PHP_EOL;
 						switch ($argMatch[2]) {
 							case '+' :
 								if ($argumentCount < $argMatch[1]) {
-									$argumentCountError = true;
+									$argumentCountError = TRUE;
 									$expectedArgumentCountString = $argMatch[1].' or more ';
 								}
 								break;
 							case '-' :
 								if (($argumentCount < $argMatch[1]) || ($argumentCount > $argMatch[3])) {
-									$argumentCountError = true;
+									$argumentCountError = TRUE;
 									$expectedArgumentCountString = 'between '.$argMatch[1].' and '.$argMatch[3];
 								}
 								break;
 							case ',' :
 								if (($argumentCount != $argMatch[1]) && ($argumentCount != $argMatch[3])) {
-									$argumentCountError = true;
+									$argumentCountError = TRUE;
 									$expectedArgumentCountString = 'either '.$argMatch[1].' or '.$argMatch[3];
 								}
 								break;
@@ -2784,7 +2788,7 @@ class PHPExcel_Calculation {
 				++$index;
 
 			} elseif ($opCharacter == ',') {			//	Is this the separator for function arguments?
-//				echo 'Element is a Function argument separator<br />';
+//echo 'Element is a Function argument separator',PHP_EOL;
 				while (($o2 = $stack->pop()) && $o2['value'] != '(') {		//	Pop off the stack back to the last (
 					if ($o2 === NULL) return $this->_raiseFormulaError("Formula Error: Unexpected ,");
 					else $output[] = $o2;	// pop the argument expression stuff and push onto the output
@@ -2792,7 +2796,7 @@ class PHPExcel_Calculation {
 				//	If we've a comma when we're expecting an operand, then what we actually have is a null operand;
 				//		so push a null onto the stack
 				if (($expectingOperand) || (!$expectingOperator)) {
-					$output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => null);
+					$output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL);
 				}
 				// make sure there was a function
 				$d = $stack->last(2);
@@ -2801,8 +2805,8 @@ class PHPExcel_Calculation {
 				$d = $stack->pop();
 				$stack->push($d['type'],++$d['value'],$d['reference']);	// increment the argument count
 				$stack->push('Brace', '(');	// put the ( back on, we'll need to pop back to it again
-				$expectingOperator = false;
-				$expectingOperand = true;
+				$expectingOperator = FALSE;
+				$expectingOperand = TRUE;
 				++$index;
 
 			} elseif ($opCharacter == '(' && !$expectingOperator) {
@@ -2811,8 +2815,8 @@ class PHPExcel_Calculation {
 				++$index;
 
 			} elseif ($isOperandOrFunction && !$expectingOperator) {	// do we now have a function/variable/number?
-				$expectingOperator = true;
-				$expectingOperand = false;
+				$expectingOperator = TRUE;
+				$expectingOperand = FALSE;
 				$val = $match[1];
 				$length = strlen($val);
 //				echo 'Element with value '.$val.' is an Operand, Variable, Constant, String, Number, Cell Reference or Function<br />';
@@ -2825,14 +2829,14 @@ class PHPExcel_Calculation {
 						$ax = preg_match('/^\s*(\s*\))/i', substr($formula, $index+$length), $amatch);
 						if ($ax) {
 							$stack->push('Operand Count for Function '.strtoupper($val).')', 0);
-							$expectingOperator = true;
+							$expectingOperator = TRUE;
 						} else {
 							$stack->push('Operand Count for Function '.strtoupper($val).')', 1);
-							$expectingOperator = false;
+							$expectingOperator = FALSE;
 						}
 						$stack->push('Brace', '(');
 					} else {	// it's a var w/ implicit multiplication
-						$output[] = array('type' => 'Value', 'value' => $matches[1], 'reference' => null);
+						$output[] = array('type' => 'Value', 'value' => $matches[1], 'reference' => NULL);
 					}
 				} elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $val, $matches)) {
 //					echo 'Element '.$val.' is a Cell reference<br />';
@@ -2857,7 +2861,7 @@ class PHPExcel_Calculation {
 					}
 
 					$output[] = array('type' => 'Cell Reference', 'value' => $val, 'reference' => $val);
-//					$expectingOperator = false;
+//					$expectingOperator = FALSE;
 				} else {	// it's a variable, constant, string, number or boolean
 //					echo 'Element is a Variable, Constant, String, Number or Boolean<br />';
 					//	If the last entry on the stack was a : operator, then we may have a row or column range reference
@@ -2865,12 +2869,12 @@ class PHPExcel_Calculation {
 					if ($testPrevOp['value'] == ':') {
 						$startRowColRef = $output[count($output)-1]['value'];
 						$rangeWS1 = '';
-						if (strpos('!',$startRowColRef) !== false) {
+						if (strpos('!',$startRowColRef) !== FALSE) {
 							list($rangeWS1,$startRowColRef) = explode('!',$startRowColRef);
 						}
 						if ($rangeWS1 != '') $rangeWS1 .= '!';
 						$rangeWS2 = $rangeWS1;
-						if (strpos('!',$val) !== false) {
+						if (strpos('!',$val) !== FALSE) {
 							list($rangeWS2,$val) = explode('!',$val);
 						}
 						if ($rangeWS2 != '') $rangeWS2 .= '!';
@@ -2889,14 +2893,14 @@ class PHPExcel_Calculation {
 						}
 					}
 
-					$localeConstant = false;
+					$localeConstant = FALSE;
 					if ($opCharacter == '"') {
 //						echo 'Element is a String<br />';
 						//	UnEscape any quotes within the string
 						$val = self::_wrapResult(str_replace('""','"',self::_unwrapResult($val)));
 					} elseif (is_numeric($val)) {
 //						echo 'Element is a Number<br />';
-						if ((strpos($val,'.') !== false) || (stripos($val,'e') !== false) || ($val > PHP_INT_MAX) || ($val < -PHP_INT_MAX)) {
+						if ((strpos($val,'.') !== FALSE) || (stripos($val,'e') !== FALSE) || ($val > PHP_INT_MAX) || ($val < -PHP_INT_MAX)) {
 //							echo 'Casting '.$val.' to float<br />';
 							$val = (float) $val;
 						} else {
@@ -2907,11 +2911,11 @@ class PHPExcel_Calculation {
 						$excelConstant = trim(strtoupper($val));
 //						echo 'Element '.$excelConstant.' is an Excel Constant<br />';
 						$val = self::$_ExcelConstants[$excelConstant];
-					} elseif (($localeConstant = array_search(trim(strtoupper($val)), self::$_localeBoolean)) !== false) {
+					} elseif (($localeConstant = array_search(trim(strtoupper($val)), self::$_localeBoolean)) !== FALSE) {
 //						echo 'Element '.$localeConstant.' is an Excel Constant<br />';
 						$val = self::$_ExcelConstants[$localeConstant];
 					}
-					$details = array('type' => 'Value', 'value' => $val, 'reference' => null);
+					$details = array('type' => 'Value', 'value' => $val, 'reference' => NULL);
 					if ($localeConstant) { $details['localeValue'] = $localeConstant; }
 					$output[] = $details;
 				}
@@ -2921,9 +2925,9 @@ class PHPExcel_Calculation {
 				++$index;
 			} elseif ($opCharacter == ')') {	// miscellaneous error checking
 				if ($expectingOperand) {
-					$output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => null);
-					$expectingOperand = false;
-					$expectingOperator = true;
+					$output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL);
+					$expectingOperand = FALSE;
+					$expectingOperator = TRUE;
 				} else {
 					return $this->_raiseFormulaError("Formula Error: Unexpected ')'");
 				}
@@ -2959,11 +2963,11 @@ class PHPExcel_Calculation {
 					while($stack->count() > 0 &&
 						($o2 = $stack->last()) &&
 						isset(self::$_operators[$o2['value']]) &&
-						@($operatorAssociativity[$opCharacter] ? $operatorPrecedence[$opCharacter] < $operatorPrecedence[$o2['value']] : $operatorPrecedence[$opCharacter] <= $operatorPrecedence[$o2['value']])) {
+						@(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) {
 						$output[] = $stack->pop();								//	Swap operands and higher precedence operators from the stack to the output
 					}
 					$stack->push('Binary Operator','|');	//	Put an Intersect Operator on the stack
-					$expectingOperator = false;
+					$expectingOperator = FALSE;
 				}
 			}
 		}
@@ -2993,8 +2997,8 @@ class PHPExcel_Calculation {
 	}
 
 	// evaluate postfix notation
-	private function _processTokenStack($tokens, $cellID = null, PHPExcel_Cell $pCell = null) {
-		if ($tokens == false) return false;
+	private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCell = NULL) {
+		if ($tokens == FALSE) return FALSE;
 
 		//	If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent worksheet),
 		//		so we store the parent worksheet so that we can re-attach it when necessary
@@ -3038,12 +3042,12 @@ class PHPExcel_Calculation {
 					//	Binary Operators
 					case ':'	:			//	Range
 						$sheet1 = $sheet2 = '';
-						if (strpos($operand1Data['reference'],'!') !== false) {
+						if (strpos($operand1Data['reference'],'!') !== FALSE) {
 							list($sheet1,$operand1Data['reference']) = explode('!',$operand1Data['reference']);
 						} else {
 							$sheet1 = ($pCellParent !== NULL) ? $pCellParent->getTitle() : '';
 						}
-						if (strpos($operand2Data['reference'],'!') !== false) {
+						if (strpos($operand2Data['reference'],'!') !== FALSE) {
 							list($sheet2,$operand2Data['reference']) = explode('!',$operand2Data['reference']);
 						} else {
 							$sheet2 = $sheet1;
@@ -3077,13 +3081,13 @@ class PHPExcel_Calculation {
 							}
 							$cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow);
 							if ($pCellParent !== NULL) {
-								$cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($sheet1), false);
+								$cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($sheet1), FALSE);
 							} else {
 								return $this->_raiseFormulaError('Unable to access Cell Reference');
 							}
 							$stack->push('Cell Reference',$cellValue,$cellRef);
 						} else {
-							$stack->push('Error',PHPExcel_Calculation_Functions::REF(),null);
+							$stack->push('Error',PHPExcel_Calculation_Functions::REF(),NULL);
 						}
 
 						break;
@@ -3178,7 +3182,7 @@ class PHPExcel_Calculation {
 				}
 
 			} elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $token, $matches)) {
-				$cellRef = null;
+				$cellRef = NULL;
 //				echo 'Element '.$token.' is a Cell reference<br />';
 				if (isset($matches[8])) {
 //					echo 'Reference is a Range of cells<br />';
@@ -3189,7 +3193,7 @@ class PHPExcel_Calculation {
 						$cellRef = $matches[6].$matches[7].':'.$matches[9].$matches[10];
 						if ($matches[2] > '') {
 							$matches[2] = trim($matches[2],"\"'");
-							if ((strpos($matches[2],'[') !== false) || (strpos($matches[2],']') !== false)) {
+							if ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) {
 								//	It's a Reference to an external workbook (not currently supported)
 								return $this->_raiseFormulaError('Unable to access External Workbook');
 							}
@@ -3197,7 +3201,7 @@ class PHPExcel_Calculation {
 //							echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />';
 							$this->_writeDebug('Evaluating Cell Range ', $cellRef, ' in worksheet ', $matches[2]);
 							if ($pCellParent !== NULL) {
-								$cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), false);
+								$cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE);
 							} else {
 								return $this->_raiseFormulaError('Unable to access Cell Reference');
 							}
@@ -3207,7 +3211,7 @@ class PHPExcel_Calculation {
 //							echo '$cellRef='.$cellRef.' in current worksheet<br />';
 							$this->_writeDebug('Evaluating Cell Range ', $cellRef, ' in current worksheet');
 							if ($pCellParent !== NULL) {
-								$cellValue = $this->extractCellRange($cellRef, $pCellParent, false);
+								$cellValue = $this->extractCellRange($cellRef, $pCellParent, FALSE);
 							} else {
 								return $this->_raiseFormulaError('Unable to access Cell Reference');
 							}
@@ -3223,7 +3227,7 @@ class PHPExcel_Calculation {
 						$cellRef = $matches[6].$matches[7];
 						if ($matches[2] > '') {
 							$matches[2] = trim($matches[2],"\"'");
-							if ((strpos($matches[2],'[') !== false) || (strpos($matches[2],']') !== false)) {
+							if ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) {
 								//	It's a Reference to an external workbook (not currently supported)
 								return $this->_raiseFormulaError('Unable to access External Workbook');
 							}
@@ -3231,10 +3235,10 @@ class PHPExcel_Calculation {
 							$this->_writeDebug('Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]);
 							if ($pCellParent !== NULL) {
 								if ($this->_workbook->getSheetByName($matches[2])->cellExists($cellRef)) {
-									$cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), false);
+									$cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE);
 									$pCell->attach($pCellParent);
 								} else {
-									$cellValue = null;
+									$cellValue = NULL;
 								}
 							} else {
 								return $this->_raiseFormulaError('Unable to access Cell Reference');
@@ -3245,10 +3249,10 @@ class PHPExcel_Calculation {
 //							echo '$cellRef='.$cellRef.' in current worksheet<br />';
 							$this->_writeDebug('Evaluating Cell ', $cellRef, ' in current worksheet');
 							if ($pCellParent->cellExists($cellRef)) {
-								$cellValue = $this->extractCellRange($cellRef, $pCellParent, false);
+								$cellValue = $this->extractCellRange($cellRef, $pCellParent, FALSE);
 								$pCell->attach($pCellParent);
 							} else {
-								$cellValue = null;
+								$cellValue = NULL;
 							}
 							$this->_writeDebug('Evaluation Result for cell ', $cellRef, ' is ', $this->_showTypeDetails($cellValue));
 						}
@@ -3338,7 +3342,7 @@ class PHPExcel_Calculation {
 						if ($passCellReference) {
 							$args[] = $pCell;
 						}
-						if (strpos($functionCall,'::') !== false) {
+						if (strpos($functionCall,'::') !== FALSE) {
 							$result = call_user_func_array(explode('::',$functionCall),$args);
 						} else {
 							foreach($args as &$arg) {
@@ -3370,7 +3374,7 @@ class PHPExcel_Calculation {
 					$namedRange = $matches[6];
 //					echo 'Named Range is '.$namedRange.'<br />';
 					$this->_writeDebug('Evaluating Named Range ', $namedRange);
-					$cellValue = $this->extractNamedRange($namedRange, ((null !== $pCell) ? $pCellParent : null), false);
+					$cellValue = $this->extractNamedRange($namedRange, ((NULL !== $pCell) ? $pCellParent : NULL), FALSE);
 					$pCell->attach($pCellParent);
 					$this->_writeDebug('Evaluation Result for named range ', $namedRange, ' is ', $this->_showTypeDetails($cellValue));
 					$stack->push('Named Range',$cellValue,$namedRange);
@@ -3391,7 +3395,7 @@ class PHPExcel_Calculation {
 	}	//	function _processTokenStack()
 
 
-	private function _validateBinaryOperand($cellID,&$operand,&$stack) {
+	private function _validateBinaryOperand($cellID, &$operand, &$stack) {
 		//	Numbers, matrices and booleans can pass straight through, as they're already valid
 		if (is_string($operand)) {
 			//	We only need special validations for the operand if it is a string
@@ -3403,22 +3407,22 @@ class PHPExcel_Calculation {
 				if ($operand > '' && $operand{0} == '#') {
 					$stack->push('Value', $operand);
 					$this->_writeDebug('Evaluation Result is ', $this->_showTypeDetails($operand));
-					return false;
+					return FALSE;
 				} elseif (!PHPExcel_Shared_String::convertToNumberIfFraction($operand)) {
 					//	If not a numeric or a fraction, then it's a text string, and so can't be used in mathematical binary operations
 					$stack->push('Value', '#VALUE!');
 					$this->_writeDebug('Evaluation Result is a ', $this->_showTypeDetails('#VALUE!'));
-					return false;
+					return FALSE;
 				}
 			}
 		}
 
 		//	return a true if the value of the operand is one that we can use in normal binary operations
-		return true;
+		return TRUE;
 	}	//	function _validateBinaryOperand()
 
 
-	private function _executeBinaryComparisonOperation($cellID,$operand1,$operand2,$operation,&$stack,$recursingArrays=false) {
+	private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2, $operation, &$stack, $recursingArrays=FALSE) {
 		//	If we're dealing with matrix operations, we want a matrix result
 		if ((is_array($operand1)) || (is_array($operand2))) {
 			$result = array();
@@ -3440,7 +3444,7 @@ class PHPExcel_Calculation {
 				if (!$recursingArrays) { self::_checkMatrixOperands($operand1,$operand2,2); }
 				foreach($operand1 as $x => $operandData) {
 					$this->_writeDebug('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2[$x]));
-					$this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2[$x],$operation,$stack,true);
+					$this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2[$x],$operation,$stack,TRUE);
 					$r = $stack->pop();
 					$result[$x] = $r['value'];
 				}
@@ -3449,7 +3453,7 @@ class PHPExcel_Calculation {
 			$this->_writeDebug('Comparison Evaluation Result is ', $this->_showTypeDetails($result));
 			//	And push the result onto the stack
 			$stack->push('Array',$result);
-			return true;
+			return TRUE;
 		}
 
 		//	Simple validate the two operands if they are string values
@@ -3488,28 +3492,28 @@ class PHPExcel_Calculation {
 		$this->_writeDebug('Evaluation Result is ', $this->_showTypeDetails($result));
 		//	And push the result onto the stack
 		$stack->push('Value',$result);
-		return true;
+		return TRUE;
 	}	//	function _executeBinaryComparisonOperation()
 
 
 	private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$operation,$matrixFunction,&$stack) {
 		//	Validate the two operands
-		if (!$this->_validateBinaryOperand($cellID,$operand1,$stack)) return false;
-		if (!$this->_validateBinaryOperand($cellID,$operand2,$stack)) return false;
+		if (!$this->_validateBinaryOperand($cellID,$operand1,$stack)) return FALSE;
+		if (!$this->_validateBinaryOperand($cellID,$operand2,$stack)) return FALSE;
 
-		$executeMatrixOperation = false;
+		$executeMatrixOperation = FALSE;
 		//	If either of the operands is a matrix, we need to treat them both as matrices
 		//		(converting the other operand to a matrix if need be); then perform the required
 		//		matrix operation
 		if ((is_array($operand1)) || (is_array($operand2))) {
 			//	Ensure that both operands are arrays/matrices
-			$executeMatrixOperation = true;
+			$executeMatrixOperation = TRUE;
 			$mSize = array();
 			list($mSize[],$mSize[],$mSize[],$mSize[]) = self::_checkMatrixOperands($operand1,$operand2,2);
 
 			//	But if they're both single cell matrices, then we can treat them as simple values
 			if (array_sum($mSize) == 4) {
-				$executeMatrixOperation = false;
+				$executeMatrixOperation = FALSE;
 				$operand1 = $operand1[0][0];
 				$operand2 = $operand2[0][0];
 			}
@@ -3551,7 +3555,7 @@ class PHPExcel_Calculation {
 							//	Trap for Divide by Zero error
 							$stack->push('Value','#DIV/0!');
 							$this->_writeDebug('Evaluation Result is ', $this->_showTypeDetails('#DIV/0!'));
-							return false;
+							return FALSE;
 						} else {
 							$result = $operand1/$operand2;
 						}
@@ -3568,7 +3572,7 @@ class PHPExcel_Calculation {
 		$this->_writeDebug('Evaluation Result is ', $this->_showTypeDetails($result));
 		//	And push the result onto the stack
 		$stack->push('Value',$result);
-		return true;
+		return TRUE;
 	}	//	function _executeNumericBinaryOperation()
 
 
@@ -3601,7 +3605,7 @@ class PHPExcel_Calculation {
 	 * @return  mixed				Array of values in range if range contains more than one element. Otherwise, a single value is returned.
 	 * @throws	PHPExcel_Calculation_Exception
 	 */
-	public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = null, $resetLog=true) {
+	public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog=TRUE) {
 		// Return value
 		$returnValue = array ();
 
@@ -3609,9 +3613,9 @@ class PHPExcel_Calculation {
 		if ($pSheet !== NULL) {
 //			echo 'Passed sheet name is '.$pSheet->getTitle().'<br />';
 //			echo 'Range reference is '.$pRange.'<br />';
-			if (strpos ($pRange, '!') !== false) {
+			if (strpos ($pRange, '!') !== FALSE) {
 //				echo '$pRange reference includes sheet reference<br />';
-				$worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pRange, true);
+				$worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pRange, TRUE);
 				$pSheet = $this->_workbook->getSheetByName($worksheetReference[0]);
 //				echo 'New sheet name is '.$pSheet->getTitle().'<br />';
 				$pRange = $worksheetReference[1];
@@ -3627,7 +3631,7 @@ class PHPExcel_Calculation {
 				if ($pSheet->cellExists($aReferences[0])) {
 					$returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog);
 				} else {
-					$returnValue[$currentRow][$currentCol] = null;
+					$returnValue[$currentRow][$currentCol] = NULL;
 				}
 			} else {
 				// Extract cell data for all cells in the range
@@ -3638,7 +3642,7 @@ class PHPExcel_Calculation {
 					if ($pSheet->cellExists($reference)) {
 						$returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog);
 					} else {
-						$returnValue[$currentRow][$currentCol] = null;
+						$returnValue[$currentRow][$currentCol] = NULL;
 					}
 				}
 			}
@@ -3657,7 +3661,7 @@ class PHPExcel_Calculation {
 	 * @return  mixed				Array of values in range if range contains more than one element. Otherwise, a single value is returned.
 	 * @throws	PHPExcel_Calculation_Exception
 	 */
-	public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = null, $resetLog=true) {
+	public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog=TRUE) {
 		// Return value
 		$returnValue = array ();
 
@@ -3665,9 +3669,9 @@ class PHPExcel_Calculation {
 		if ($pSheet !== NULL) {
 //			echo 'Current sheet name is '.$pSheet->getTitle().'<br />';
 //			echo 'Range reference is '.$pRange.'<br />';
-			if (strpos ($pRange, '!') !== false) {
+			if (strpos ($pRange, '!') !== FALSE) {
 //				echo '$pRange reference includes sheet reference<br />';
-				$worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pRange, true);
+				$worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pRange, TRUE);
 				$pSheet = $this->_workbook->getSheetByName($worksheetReference[0]);
 //				echo 'New sheet name is '.$pSheet->getTitle().'<br />';
 				$pRange = $worksheetReference[1];
@@ -3709,7 +3713,7 @@ class PHPExcel_Calculation {
 				if ($pSheet->cellExists($aReferences[0])) {
 					$returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog);
 				} else {
-					$returnValue[$currentRow][$currentCol] = null;
+					$returnValue[$currentRow][$currentCol] = NULL;
 				}
 			} else {
 				// Extract cell data for all cells in the range
@@ -3720,7 +3724,7 @@ class PHPExcel_Calculation {
 					if ($pSheet->cellExists($reference)) {
 						$returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog);
 					} else {
-						$returnValue[$currentRow][$currentCol] = null;
+						$returnValue[$currentRow][$currentCol] = NULL;
 					}
 				}
 			}
@@ -3744,7 +3748,7 @@ class PHPExcel_Calculation {
 		if (isset(self::$_PHPExcelFunctions[$pFunction])) {
 			return (self::$_PHPExcelFunctions[$pFunction]['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY');
 		} else {
-			return false;
+			return FALSE;
 		}
 	}	//	function isImplemented()
 
diff --git a/Classes/PHPExcel/Cell.php b/Classes/PHPExcel/Cell.php
index ea37c7e..ab8b472 100644
--- a/Classes/PHPExcel/Cell.php
+++ b/Classes/PHPExcel/Cell.php
@@ -288,7 +288,10 @@ class PHPExcel_Cell
 		if ($this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA) {
 			try {
 //				echo 'Cell value for '.$this->getCoordinate().' is a formula: Calculating value<br />';
-				$result = $this->getParent()->getParent()->getCalculationEngine()->calculateCellValue($this,$resetLog);
+				$result = PHPExcel_Calculation::getInstance(
+					$this->getParent()->getParent()
+				)->calculateCellValue($this,$resetLog);
+//				$result = $this->getParent()->getParent()->getCalculationEngine()->calculateCellValue($this,$resetLog);
 //				echo $this->getCoordinate().' calculation result is '.$result.'<br />';
 			} catch ( PHPExcel_Exception $ex ) {
 				if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->_calculatedValue !== NULL)) {
diff --git a/Classes/PHPExcel/Chart/DataSeriesValues.php b/Classes/PHPExcel/Chart/DataSeriesValues.php
index 4a20648..034ac9e 100644
--- a/Classes/PHPExcel/Chart/DataSeriesValues.php
+++ b/Classes/PHPExcel/Chart/DataSeriesValues.php
@@ -279,7 +279,7 @@ class PHPExcel_Chart_DataSeriesValues
 
 	public function refresh(PHPExcel_Worksheet $worksheet, $flatten = TRUE) {
         if ($this->_dataSource !== NULL) {
-        	$calcEngine = PHPExcel_Calculation::getInstance();
+        	$calcEngine = PHPExcel_Calculation::getInstance($worksheet->getParent());
 			$newDataValues = PHPExcel_Calculation::_unwrapResult(
 			    $calcEngine->_calculateFormulaValue(
 			        '='.$this->_dataSource,