gt: 				resultPtg = FinancialCalculator.calcPRICEMAT( operands );
context: /*
   * --------- BEGIN COPYRIGHT NOTICE ---------
   * Copyright 2002-2012 Extentech Inc.
   * Copyright 2013 Infoteria America Corp.
   * 
   * This file is part of OpenXLS.
   * 
   * OpenXLS is free software: you can redistribute it and/or modify
   * it under the terms of the GNU Lesser General Public License as
   * published by the Free Software Foundation, either version 3 of
   * the License, or (at your option) any later version.
   * 
   * OpenXLS is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU Lesser General Public License for more details.
   * 
   * You should have received a copy of the GNU Lesser General Public
   * License along with OpenXLS.  If not, see
   * <http://www.gnu.org/licenses/>.
   * ---------- END COPYRIGHT NOTICE ----------
   */
  package org.openxls.formats.XLS.formulas;
  
  import org.openxls.formats.XLS.FunctionNotSupportedException;
  import org.openxls.formats.XLS.XLSRecord;
  
  import java.util.Locale;
  
  /**
   * Function Handler takes an array of PTG's with a header PtgFunc or PtgFuncVar, calcuates
   * those ptgs in the determined way, then return a relevant PtgValue
   * <p/>
   * Descriptions of these functions are available on the msdn site,
   * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/office97/html/S88F9.asp
   */
  
  public class FunctionHandler
  {
  
  	/*
  		Calculates the function and returns a relevant Ptg as a value
  		This is the main entry method.
  
  	*/
  	public static final Ptg calculateFunction( Ptg[] ptgs ) throws FunctionNotSupportedException, CalculationException
  	{
  		// the function identifier
  		Ptg funk = ptgs[0];
  		int funkId = 0;   //what function are we calling?
  
  		// if ptgs are missing parent_recs, populate from funk
  		XLSRecord bpar = funk.getParentRec();
  		if( bpar != null )
  		{
  			for( Ptg ptg : ptgs )
  			{
  				if( ptg.getParentRec() == null )
  				{
  					ptg.setParentRec( bpar );
  				}
  			}
  		}
  
  		int oplen = ptgs.length - 1;
  		// the ptgs acted upon by the function
  		Ptg[] operands = new Ptg[oplen];
  		System.arraycopy( ptgs, 1, operands, 0, oplen );
  		if( (funk.getOpcode() == 0x21) || (funk.getOpcode() == 0x41) || (funk.getOpcode() == 0x61) )
  		{  // ptgfunc
  			return calculatePtgFunc( funk, funkId, operands );
  		}
  		if( (funk.getOpcode() == 0x22) || (funk.getOpcode() == 0x42) || (funk.getOpcode() == 0x62) )
  		{ // ptgfuncvar
  			return calculatePtgFuncVar( funk, funkId, operands );
  		}
  		return null;
  	}
  
  	/*
  		Keep the calculation of ptgfunc & ptgfuncvar seperate in case any differences show up
  	*/
  	public static final Ptg calculatePtgFunc( Ptg funk, int funkId, Ptg[] operands ) throws
  	                                                                                 FunctionNotSupportedException,
  	                                                                                 CalculationException
  	{
  		PtgFunc pf = (PtgFunc) funk;
  		funkId = pf.getVal();
  		return parse_n_calc( funk, funkId, operands );
  	}
  
  	/**
  	 * Keep the calculation of ptgfunc & ptgfuncvar seperate in case any differences show up
  	 *
  	 * @throws CalculationException
  	 */
  	public static final Ptg calculatePtgFuncVar( Ptg funk, int funkId, Ptg[] operands ) throws
  	                                                                                    FunctionNotSupportedException,
  	                                                                                    CalculationException
  	{
  		PtgFuncVar pf = (PtgFuncVar) funk;
  		funkId = pf.getVal();
  		// Handle Add-in Formulas - which have a name operand 1st
  		if( funkId == FunctionConstants.xlfADDIN )
  		{  // XL flag that formula is an add-in
  			//	must pop the PtgNameX record to get the correct function id
  			String s = "";
  			boolean foundit = false;
  			if( operands[0] instanceof PtgNameX )
  			{
  				int index = ((PtgNameX) operands[0]).getVal();
  				s = pf.getParentRec().getSheet().getWorkBook().getExternalName( index );
  			}
  			else if( operands[0] instanceof PtgName )
  			{
  				s = ((PtgName) operands[0]).getStoredName();
  			}
  			if( s.startsWith( "_xlfn." ) )
  			{    // Excel "new" functions
  				s = s.substring( 6 );
  			}
  			if( Locale.JAPAN.equals( Locale.getDefault() ) )
  			{
  				for( int y = 0; y < FunctionConstants.jRecArr.length; y++ )
  				{
  					if( s.equalsIgnoreCase( FunctionConstants.jRecArr[y][0] ) )
  					{
  						funkId = Integer.valueOf( FunctionConstants.jRecArr[y][1] );
  						y = FunctionConstants.jRecArr.length;  // exit loop
  						foundit = true;
  					}
  				}
  			}
  			if( !foundit )
  			{
  				for( int y = 0; y < FunctionConstants.recArr.length; y++ )
  				{    // Use FunctionConstants instead of PtFuncVar
  					if( s.equalsIgnoreCase( FunctionConstants.recArr[y][0] ) )
  					{
  						funkId = Integer.valueOf( FunctionConstants.recArr[y][1] );
  						y = FunctionConstants.recArr.length;    // exit loop
  					}
  				}
  			}
  			if( funkId == 255 )// it's not found
  			{
  				throw new FunctionNotSupportedException( s );
  			}
  
  //			now get rid of PtgNameX operand before calling function
  			Ptg[] ops = new Ptg[operands.length - 1];
  			System.arraycopy( operands, 1, ops, 0, operands.length - 1 );
  			operands = new Ptg[ops.length];
  			System.arraycopy( ops, 0, operands, 0, ops.length );
  		}    // end KSC added
  		return parse_n_calc( funk, funkId, operands );
  	}
  
  	/**
  	 * *********************************************************************************
  	 * *
  	 * Your standard big case statement, calling methods based on what the funkid is. *
  	 * You will notice that these are seperated out into packages based on the MS     *
  	 * documentation (Link above).  Each package calls a different class full of      *
  	 * static method calls.   There are a lot of these :-)                            *
  	 * *
  	 * PLEASE:  Remove function from comment list when you enable it!!!!           *
  	 * *
  	 *
  	 * @throws CalculationException ***********************************************************************************
  	 */
  	public static final Ptg parse_n_calc( Ptg function, int functionId, Ptg[] operands ) throws
  	                                                                                     FunctionNotSupportedException,
  	                                                                                     CalculationException
  	{
  		Ptg resultPtg = null;
  		Ptg[] resultArrPtg = null;
  
  		switch( functionId )
  		{
  			/********************************************
  			 *   Database and List package functions    **
  			 ********************************************/
  			case FunctionConstants.xlfDaverage:
  				resultPtg = DatabaseCalculator.calcDAverage( operands );
  				break;
  
  			case FunctionConstants.xlfDcount:
  				resultPtg = DatabaseCalculator.calcDCount( operands );
  				break;
  
  			case FunctionConstants.xlfDcounta:
  				resultPtg = DatabaseCalculator.calcDCountA( operands );
  				break;
  
  			case FunctionConstants.xlfDget:
  				resultPtg = DatabaseCalculator.calcDGet( operands );
  				break;
  
  			case FunctionConstants.xlfDmax:
  				resultPtg = DatabaseCalculator.calcDMax( operands );
  				break;
  
  			case FunctionConstants.xlfDmin:
  				resultPtg = DatabaseCalculator.calcDMin( operands );
  				break;
  
  			case FunctionConstants.xlfDproduct:
  				resultPtg = DatabaseCalculator.calcDProduct( operands );
  				break;
  
  			case FunctionConstants.xlfDstdev:
  				resultPtg = DatabaseCalculator.calcDStdDev( operands );
  				break;
  
  			case FunctionConstants.xlfDstdevp:
  				resultPtg = DatabaseCalculator.calcDStdDevP( operands );
  				break;
  
  			case FunctionConstants.xlfDsum:
  				resultPtg = DatabaseCalculator.calcDSum( operands );
  				break;
  
  			case FunctionConstants.xlfDvar:
  				resultPtg = DatabaseCalculator.calcDVar( operands );
  				break;
  
  			case FunctionConstants.xlfDvarp:
  				resultPtg = DatabaseCalculator.calcDVarP( operands );
  				break;
  
  			/********************************************
  			 *   Date and time functions         *********
  			 ********************************************/
  			case FunctionConstants.xlfDate:
  				resultPtg = DateTimeCalculator.calcDate( operands );
  				break;
  
  			case FunctionConstants.xlfDay:
  				resultPtg = DateTimeCalculator.calcDay( operands );
  				break;
  
  			case FunctionConstants.xlfDays360:
  				resultPtg = DateTimeCalculator.calcDays360( operands );
  				break;
  
  			case FunctionConstants.xlfHour:
  				resultPtg = DateTimeCalculator.calcHour( operands );
  				break;
  
  			case FunctionConstants.xlfMinute:
  				resultPtg = DateTimeCalculator.calcMinute( operands );
  				break;
  
  			case FunctionConstants.xlfMonth:
  				resultPtg = DateTimeCalculator.calcMonth( operands );
  				break;
  
  			case FunctionConstants.xlfYear:
  				resultPtg = DateTimeCalculator.calcYear( operands );
  				break;
  
  			case FunctionConstants.xlfSecond:
  				resultPtg = DateTimeCalculator.calcSecond( operands );
  				break;
  
  			case FunctionConstants.xlfTimevalue:
  				resultPtg = DateTimeCalculator.calcTimevalue( operands );
  				break;
  
  			case FunctionConstants.xlfWeekday:
  				resultPtg = DateTimeCalculator.calcWeekday( operands );
  				break;
  
  			case FunctionConstants.xlfWEEKNUM:
  				resultPtg = DateTimeCalculator.calcWeeknum( operands );
  				break;
  
  			case FunctionConstants.xlfWORKDAY:
  				resultPtg = DateTimeCalculator.calcWorkday( operands );
  				break;
  
  			case FunctionConstants.xlfYEARFRAC:
  				resultPtg = DateTimeCalculator.calcYearFrac( operands );
  				break;
  
  			case FunctionConstants.xlfNow:
  				resultPtg = DateTimeCalculator.calcNow( operands );
  				break;
  
  			case FunctionConstants.xlfTime:
  				resultPtg = DateTimeCalculator.calcTime( operands );
  				break;
  
  			case FunctionConstants.xlfToday:
  				resultPtg = DateTimeCalculator.calcToday( operands );
  				break;
  
  			case FunctionConstants.xlfDatevalue:
  				resultPtg = DateTimeCalculator.calcDateValue( operands );
  				break;
  
  			case FunctionConstants.xlfEDATE:
  				resultPtg = DateTimeCalculator.calcEdate( operands );
  				break;
  
  			case FunctionConstants.xlfEOMONTH:
  				resultPtg = DateTimeCalculator.calcEOMonth( operands );
  				break;
  
  			case FunctionConstants.xlfNETWORKDAYS:
  				resultPtg = DateTimeCalculator.calcNetWorkdays( operands );
  				break;
  
  			/********************************************
  			 *   DDE and External functions           ****
  			 ********************************************/
  
  			/********************************************
  			 *   Engineering functions           *********
  			 ********************************************/
  			case FunctionConstants.xlfBIN2DEC:
  				resultPtg = EngineeringCalculator.calcBin2Dec( operands );
  				break;
  
  			case FunctionConstants.xlfBIN2HEX:
  				resultPtg = EngineeringCalculator.calcBin2Hex( operands );
  				break;
  
  			case FunctionConstants.xlfBIN2OCT:
  				resultPtg = EngineeringCalculator.calcBin2Oct( operands );
  				break;
  
  			case FunctionConstants.xlfDEC2BIN:
  				resultPtg = EngineeringCalculator.calcDec2Bin( operands );
  				break;
  
  			case FunctionConstants.xlfDEC2HEX:
  				resultPtg = EngineeringCalculator.calcDec2Hex( operands );
  				break;
  
  			case FunctionConstants.xlfDEC2OCT:
  				resultPtg = EngineeringCalculator.calcDec2Oct( operands );
  				break;
  
  			case FunctionConstants.xlfHEX2BIN:
  				resultPtg = EngineeringCalculator.calcHex2Bin( operands );
  				break;
  
  			case FunctionConstants.xlfHEX2DEC:
  				resultPtg = EngineeringCalculator.calcHex2Dec( operands );
  				break;
  
  			case FunctionConstants.xlfHEX2OCT:
  				resultPtg = EngineeringCalculator.calcHex2Oct( operands );
  				break;
  
  			case FunctionConstants.xlfOCT2BIN:
  				resultPtg = EngineeringCalculator.calcOct2Bin( operands );
  				break;
  
  			case FunctionConstants.xlfOCT2DEC:
  				resultPtg = EngineeringCalculator.calcOct2Dec( operands );
  				break;
  
  			case FunctionConstants.xlfOCT2HEX:
  				resultPtg = EngineeringCalculator.calcOct2Hex( operands );
  				break;
  
  			case FunctionConstants.xlfCOMPLEX:
  				resultPtg = EngineeringCalculator.calcComplex( operands );
  				break;
  
  			case FunctionConstants.xlfGESTEP:
  				resultPtg = EngineeringCalculator.calcGEStep( operands );
  				break;
  
  			case FunctionConstants.xlfDELTA:
  				resultPtg = EngineeringCalculator.calcDelta( operands );
  				break;
  
  			case FunctionConstants.xlfIMAGINARY:
  				resultPtg = EngineeringCalculator.calcImaginary( operands );
  				break;
  
  			case FunctionConstants.xlfIMREAL:
  				resultPtg = EngineeringCalculator.calcImReal( operands );
  				break;
  
  			case FunctionConstants.xlfIMARGUMENT:
  				resultPtg = EngineeringCalculator.calcImArgument( operands );
  				break;
  
  			case FunctionConstants.xlfIMABS:
  				resultPtg = EngineeringCalculator.calcImAbs( operands );
  				break;
  
  			case FunctionConstants.xlfIMDIV:
  				resultPtg = EngineeringCalculator.calcImDiv( operands );
  				break;
  
  			case FunctionConstants.xlfIMCONJUGATE:
  				resultPtg = EngineeringCalculator.calcImConjugate( operands );
  				break;
  
  			case FunctionConstants.xlfIMCOS:
  				resultPtg = EngineeringCalculator.calcImCos( operands );
  				break;
  
  			case FunctionConstants.xlfIMSIN:
  				resultPtg = EngineeringCalculator.calcImSin( operands );
  				break;
  
  			case FunctionConstants.xlfIMEXP:
  				resultPtg = EngineeringCalculator.calcImExp( operands );
  				break;
  
  			case FunctionConstants.xlfIMSUB:
  				resultPtg = EngineeringCalculator.calcImSub( operands );
  				break;
  
  			case FunctionConstants.xlfIMSUM:
  				resultPtg = EngineeringCalculator.calcImSum( operands );
  				break;
  
  			case FunctionConstants.xlfIMPRODUCT:
  				resultPtg = EngineeringCalculator.calcImProduct( operands );
  				break;
  
  			case FunctionConstants.xlfIMLN:
  				resultPtg = EngineeringCalculator.calcImLn( operands );
  				break;
  
  			case FunctionConstants.xlfIMLOG10:
  				resultPtg = EngineeringCalculator.calcImLog10( operands );
  				break;
  
  			case FunctionConstants.xlfIMLOG2:
  				resultPtg = EngineeringCalculator.calcImLog2( operands );
  				break;
  
  			case FunctionConstants.xlfIMPOWER:
  				resultPtg = EngineeringCalculator.calcImPower( operands );
  				break;
  
  			case FunctionConstants.xlfIMSQRT:
  				resultPtg = EngineeringCalculator.calcImSqrt( operands );
  				break;
  
  			case FunctionConstants.xlfCONVERT:
  				resultPtg = EngineeringCalculator.calcConvert( operands );
  				break;
  
  			case FunctionConstants.xlfERF:
  				resultPtg = EngineeringCalculator.calcErf( operands );
  				break;
  
  			/********************************************
  			 *   Financial functions             *********
  			 ********************************************/
  
  			case FunctionConstants.xlfDb:
  				resultPtg = FinancialCalculator.calcDB( operands );
  				break;
  
  			case FunctionConstants.xlfDdb:
  				resultPtg = FinancialCalculator.calcDDB( operands );
  				break;
  
  			case FunctionConstants.xlfPmt:
  				resultPtg = FinancialCalculator.calcPmt( operands );
  				break;
  
  			// KSC: Added
  			case FunctionConstants.xlfAccrintm:
  				resultPtg = FinancialCalculator.calcAccrintm( operands );
  				break;
  
  			case FunctionConstants.xlfAccrint:
  				resultPtg = FinancialCalculator.calcAccrint( operands );
  				break;
  
  			case FunctionConstants.xlfCoupDayBS:
  				resultPtg = FinancialCalculator.calcCoupDayBS( operands );
  				break;
  
  			case FunctionConstants.xlfCoupDays:
  				resultPtg = FinancialCalculator.calcCoupDays( operands );
  				break;
  
  			case FunctionConstants.xlfNpv:
  				resultPtg = FinancialCalculator.calcNPV( operands );
  				break;
  
  			case FunctionConstants.xlfPv:
  				resultPtg = FinancialCalculator.calcPV( operands );
  				break;
  
  			case FunctionConstants.xlfFv:
  				resultPtg = FinancialCalculator.calcFV( operands );
  				break;
  
  			case FunctionConstants.xlfIpmt:
  				resultPtg = FinancialCalculator.calcIPMT( operands );
  				break;
  
  			case FunctionConstants.xlfCumIPmt:
  				resultPtg = FinancialCalculator.calcCumIPmt( operands );
  				break;
  
  			case FunctionConstants.xlfCumPrinc:
  				resultPtg = FinancialCalculator.calcCumPrinc( operands );
  				break;
  
  			case FunctionConstants.xlfCoupNCD:
  				resultPtg = FinancialCalculator.calcCoupNCD( operands );
  				break;
  
  			case FunctionConstants.xlfCoupDaysNC:
  				resultPtg = FinancialCalculator.calcCoupDaysNC( operands );
  				break;
  
  			case FunctionConstants.xlfCoupPCD:
  				resultPtg = FinancialCalculator.calcCoupPCD( operands );
  				break;
  
  			case FunctionConstants.xlfCoupNUM:
  				resultPtg = FinancialCalculator.calcCoupNum( operands );
  				break;
  
  			case FunctionConstants.xlfDollarDE:
  				resultPtg = FinancialCalculator.calcDollarDE( operands );
  				break;
  
  			case FunctionConstants.xlfDollarFR:
  				resultPtg = FinancialCalculator.calcDollarFR( operands );
  				break;
  
  			case FunctionConstants.xlfEffect:
  				resultPtg = FinancialCalculator.calcEffect( operands );
  				break;
  
  			case FunctionConstants.xlfRECEIVED:
  				resultPtg = FinancialCalculator.calcReceived( operands );
  				break;
  
  			case FunctionConstants.xlfINTRATE:
  				resultPtg = FinancialCalculator.calcINTRATE( operands );
  				break;
  
  			case FunctionConstants.xlfIrr:
  				resultPtg = FinancialCalculator.calcIRR( operands );
  				break;
  
  			case FunctionConstants.xlfMirr:
  				resultPtg = FinancialCalculator.calcMIRR( operands );
  				break;
  
  			case FunctionConstants.xlfXIRR:
  				resultPtg = FinancialCalculator.calcXIRR( operands );
  				break;
  
  			case FunctionConstants.xlfXNPV:
  				resultPtg = FinancialCalculator.calcXNPV( operands );
  				break;
  
  			case FunctionConstants.xlfRate:
  				resultPtg = FinancialCalculator.calcRate( operands );
  				break;
  
  			case FunctionConstants.xlfYIELD:
  				resultPtg = FinancialCalculator.calcYIELD( operands );
  				break;
  
  			case FunctionConstants.xlfPRICE:
  				resultPtg = FinancialCalculator.calcPRICE( operands );
  				break;
  
  			case FunctionConstants.xlfPRICEDISC:
  				resultPtg = FinancialCalculator.calcPRICEDISC( operands );
  				break;
  
  			case FunctionConstants.xlfPRICEMAT:
  